结构体详解
结构体是什么?
结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。
看了这个概念你有没有联想到其他,跟数组定义很类似,数组的是 相同类型元素的集合。
语法
1.结构体的声明
C语言的内置类型(int ,char , float…)无法描述一个复杂的变量,比如我需要描述一个人,需要姓名,年龄,性别这些信息,所以我们需要创建一个结构体类型来描述一个学生。
struct student
{
char name[20];
int age;
char sex[5];
}
关键词是struct, 括号里面是结构体的成员列表。在这要注意一点,结构体声明的时候不能初始化。
匿名结构体
这是一种特殊的结构体声明,如图所示
struct
{
char name[20];
int age;
char sex[5];
}s1={0};
需要注意的是匿名结构体声明只能用一次,看下面的代码。
struct
{
int a;
char c;
float f;
}x;
struct
{
int a;
char c;
float f;
}*p;
请问能不能写成
p=&x;
答案是不行,因为编译器会认为p和 x是两个完全不同的类型。
结构体的自引用
结构体里面能不能包含自己本身呢?当然可以,不过需要注意的是,得写成指针得形式
struct s
{
int a;
char c;
struct s z;
}//error
struct s
{
int a;
char c;
struct s* ps;
}
如果写成第一种的形式,用sizeof(struct s)计算这个结构体的大小就可以看出这是完全不行的。
2.结构体的定义和初始化
struct student
{
char name[20];
int age;
char sex[5];
}s1={"zhangsan",21,"male"};
int main()
{
struct student s2={.age=21,.name="lisi",.sex="male"};
return 0;
}
s1和s2都是定义的结构体变量,这两个的区别就是s1是全局变量,s2是局部变量。
. 操作符可以访问结构的成员变量,如果不按顺序初始化可以用.操作符
3.结构体的大小
这里涉及到内存对齐,先来看一下内存对齐的规则
1.结构体的第一个成员永远相较与结构体起始变量位置的偏移量为0的位置
2.从第二个成员开始,往后的每个成员都要对齐到某个对齐数的整数倍处
对齐数:结构体成员自身的大小和默认对齐数的较小值
3.结构体的总大小,必须是最大对齐数的整数倍(最大对齐数是所有成员的对齐数中最大的值)
这里简单举个例子
#include <stdio.h>
struct s
{
int a;//对齐数是4;
char b;//对齐数是1
int c;//对齐数是4
};
int main()
{
printf("%d\n", sizeof(struct s));
return 0;
}
问结构体的大小是多少,看图
很简单,对照着规则应该很容易看懂
可以验证一下
4.结构体传参
这里简单说一下两者的区别
struct s
{
int a;
char b;
int c;
};
int main()
{
struct s s1={12, 'c', 41};
print(s1);//传参
print(&s1);传址
return 0;
}
用人话讲大概就是传址更节省空间,毕竟一个地址只有4/8个字节,而如果传参就是要重新开辟一个结构体大小的空间。