目录
什么是结构体?
用来描述复杂类型,比如一个人要有名字、年龄、性别等。
结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。
1、结构体的声明
结构体在使用之前需要先声明(定义)
语法:
struct tag//结构体关键字(struct) 标签名(tag)
{
member-list;//成员列表
}variable-list;//变量列表
//声明的时候可以不创建变量列表
struct tag//结构体关键字(struct) 标签名(tag)
{
member-list;//成员列表
};//但是这里的分号不能少
结构体在声明的时候可以不创建变量列表,而在使用的时候直接创建变量。
注意:在声明的时候就进行变量的创建,此时创建的结构体变量是全局变量。
结构体的成员变量可以是数组、指针、变量或者其他结构体。
结构体的初始化
struct Piont
{
int x;
int y;
};
struct book//(标签名字)
{//成员列表
char name[20];
double price;
struct Piont p;//嵌套调用结构体
//结构体里面嵌套的结构体需要给定变量名
};//变量列表可以在声明的时候不创建
int main()
{
struct Piont p1 = { 1,2 };
printf("%d %d\n",p1.x,p1.y);
struct book b2 = { "小黑子",15.52,{10,20} };
printf("%s %lf %d %d\n",b2.name,b2.price,b2.p.x,b2.p.y);
//嵌套结构体当中,打印结构体里面的结构体的时候,需要先找到
//结构体里面的结构体变量,然后再找对应的成员
return 0;
}
注意:当结构体里面嵌套结构体的时候,需要调用内层结构体里面的成员变量的时候,先通过外层结构体找到内层结构体然后再调用内层结构体的成员变量。
结构体的不完全初始化,或者说是指定初始化:
int main()
{
struct book b3 = { .name = "坤坤",.p.x = 10 };
printf("%s %lf %d %d\n", b3.name, b3.price, b3.p.x, b3.p.y);
return 0;
}
不完全初始化的时候,对于未指定的成员变量编译器会给定初始值——0
其次指定初始化的时候直接通过.成员变量=数据来给定值
2、结构体成员的访问
- 结构体变量访问成员
结构变量的成员是通过点操作符(.)访问的。点操作符接受两个操作数。
使用方法:结构体变量名 . 成员名
- 结构体指针访问指向变量的成员
有时候我们得到的不是一个结构体变量,而是指向一个结构体的指针。
使用方法:结构体指针 -> 成员变量
3、结构体传参
struct list
{
char name[20];
int data[10];
};
void Print1(struct list s)
{
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d ",s.data[i]);
//通过.来找成员变量
}
}
void Print2(struct list* ps)
{
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d ", ps->data[i]);
//通过->找成员变量
}
}
int main()
{
struct list a = { "giegie",{1,2,3} };
Print1(a);//值传递
Print2(&a);//址传递
return 0;
}
可以看到跟函数的传参一样,但是因为我们的结构体本身空间的占用就比较大,函数传参的时候,参数是需要压栈的。如果传递一个结构体对象的时候,结构体过大,参数压栈的的系统开销比较大,所以会导致性能的下降。所以一般情况下为了节省空间会使用址传递的i形式对结构体进行传参,但是这种方法会有一个缺陷,对于址传递容易改变里面的数据,所以使用的时候要注意,不准备改变里面的数据的时候不要随意对数据进行改变。