引言
结构体是一种自定义的数据类型,用结构体可以创建结构体变量。结构体变量也是变量,是变量就有内存地址,有地址就需要用指针,用指针来存放地址。在C++中,用不同类型的指针存放不同类型变量的地址,对结构体来说也一样。
基本语法
// 结构体定义
struct car
{
char brand[15];
int speed;
double acceleration;
};
car p1{"porsche", 300, 3.2}; // 声明结构体变量
car* p1_ptr = &p1; // 创建结构体指针
通过结构体指针访问结构体成员
方式一:(*指针名).成员变量名
在方法一中,圆点.
的优先级高于*
,(*指针名)
两边的括号不能少。
方式二:指针名->成员变量名
程序员用的较多的是方式二。
#include <iostream>
using namespace std;
struct car
{
char brand[15];
int speed;
double acceleration;
};
int main() {
car p1{"porsche", 300, 3.2};
cout << p1.brand << " " << p1.speed << " " << p1.acceleration << endl;
car* p1_ptr = &p1; // 创建结构体指针
cout << "方式1:" << (*p1_ptr).brand << " " << (*p1_ptr).speed << " " << (*p1_ptr).acceleration << endl;
cout << "方式2:" << p1_ptr->brand << " " << p1_ptr->speed << " " << p1_ptr->acceleration << endl;
return 0;
}
结构体指针的用途
用于函数的参数
如果要把结构体传递给函数,实参取结构体变量的地址,函数的形参用结构体指针。直接看如下代码:
#include <iostream>
using namespace std;
struct car
{
char brand[15];
int speed;
double acceleration;
};
void func(car* ptr) {
cout << "func ~~~ " << ptr->brand << " " << ptr->speed
<< " " << ptr->acceleration << endl;
}
int main() {
car p1{"porsche", 300, 3.2};
cout << p1.brand << " " << p1.speed << " " << p1.acceleration << endl;
func(&p1);
return 0;
}
在函数func()
中,传进来的是实参的地址&p1
,函数的形参用结构体指针的第二种方式箭头->
,运行结果如下:
porsche 300 3.2
func ~~~ porsche 300 3.2
既然,在函数func()
中,传进来的是实参的地址&p1
,那就可以通过结构体指针修改实参的值,代码如下:
#include <iostream>
#include <cstring>
using namespace std;
struct car
{
char brand[15];
int speed;
double acceleration;
};
void func(car* ptr) {
cout << "func ~~~ " << ptr->brand << " " << ptr->speed
<< " " << ptr->acceleration << endl;
// ptr->brand = "Ferrari"; // brand是C风格的字符串,不能用等号“=”直接复制。
// 正确做法是使用 strcpy() 函数,需要引入必要的头文件<cstring>
strcpy(ptr->brand, "Ferrari");
ptr->speed = 320;
cout << "change ~~~ " << ptr->brand << " " << ptr->speed
<< " " << ptr->acceleration << endl;
}
int main() {
car p1{"porsche", 300, 3.2};
cout << p1.brand << " " << p1.speed << " " << p1.acceleration << endl;
func(&p1);
return 0;
}
运行结果如下:
porsche 300 3.2
func ~~~ porsche 300 3.2
change ~~~ Ferrari 320 3.2
如果不希望在函数中修改结构体变量的值,可以对形参加const约束。大家可以自行实验一下,将函数void func(car* ptr) {...}
修改成void func(const car* ptr) {...}
。再把修改成员变量brand
和speed
的代码注释或删除,才可成功编译运行。
用于动态分配内存
直接看如下代码:
int main() {
car *p_ptr = new car;
memset(p_ptr, 0, sizeof(car));
cout << "p_ptr ~~~ " << p_ptr->brand << " " << p_ptr->speed
<< " " << p_ptr->acceleration << endl;
delete p_ptr;
return 0;
}
car *p_ptr = new car;
这行代码的意思是:不创建结构体变量,而是创建结构体指针p_ptr
;再new
一个car
结构体出来,让指针指向这个结构体。
memset(p_ptr, 0, sizeof(car));
这行代码是给指针p_ptr
初始化,初始化的值是0
。值得注意的是,第三个参数,sizeof()
里面应该填结构体变量名或结构体数据类型,现在没有结构体变量,故只能用结构体类型名car
。如果sizeof()
里面填写p_ptr
,会出现乱七八糟的数据。因为,对指针名用sizeof()
的结果永远都是8
。
delete p_ptr;
动态分配出来的内存,应该手动释放。
感谢浏览,一起学习!