结构体是⼀些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。
1.结构体类型的声明
1.1结构的声明
struct Stu
{
char name[20];//名字
int age;//年龄
char sex[5];//性别
int id[20];//学号
}; //分号不能丢
通过上面代码,便生成了一个名为Stu的结构体,其内含有4个成员变量;
1.2结构体的初始化(对其内部成员进行赋值)
struct Stu s = { "张三", 20, "男", 20230818001 };
如果我们想要只对结构体中的一个变量进行修改,那么可以使用如下代码
结构体名称.成员变量命名 = 要赋的值
注意,如果为结构体指针的话,那么.改为->
2.结构体的自引用
比如,我们定义一个链表中的节点:
struct Node
{
int data;
struct Node next;
};
我们在结构体中又定义了一个结构体,这个代码是否正确呢?
其实,这种自引用是错误的,因为⼀个结构体中再包含⼀个同类型的结构体变量,这样结构体变量的大小就会无穷的的,是不合理的。
那么正确的自引用是咋样的呢?
struct Node
{
int data;
struct Node* next;
};
这便是正确的自引用,我们通过在结构体内定义一个结构体指针来完成。如果无需指向其他结构体,那么我们只需将next指针指向NULL便可以了,这种方法不会创建一个又一个结构体,导致程序崩溃
当然,我们也可以用typedef进行重命名,使代码更简洁
typedef struct Node
{
int data;
struct Node* next;
}Node;
通过重命名后,我们边将结构体重新命名为Node。
3.结构体的内存对齐
结构体的对齐规则:
1. 结构体的第⼀个成员对齐到和结构体变量起始位置偏移量为0的地址处
2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
对齐数 = 编译器默认的⼀个对齐数 与 该成员变量大小的较小值。
注(VS2022中默认对齐数的大小为8)
3. 结构体总大小为最大对齐数(结构体中每个成员变量都有⼀个对齐数,所有对齐数中最大的)的 整数倍。
4.如果嵌套了结构体的情况,嵌套的结构体成员对⻬到⾃⼰的成员中最⼤对⻬数的整数倍处,结构 体的整体⼤⼩就是所有最⼤对⻬数(含嵌套结构体中成员的对⻬数)的整数倍。
如下结构体:
struct S1
{
char c1;
int i;
char c2;
};
我们可以看到,其大小为12
那么为什么不为6呢?这便是因为内存对齐的原因:
请看下图
因此如果我们在设计结构体的时候,我们既要满足对齐,又要节省空间,那么让占用空间小的成员尽量集中在⼀起,是一个可行的方法
4.结构体转参c
一般来说传参有两种方式,一个是直接传结构体,一个是传结构体的地址,那么那个方法好一些呢?
答案是传结构体的地址,因为函数传参的时候,参数是需要压栈,会有时间和空间上的系统开销。 如果传递⼀个结构体对象的时候,结构体过大,参数压栈的的系统开销比较大,所以会导致性能的下 降。而传地址则不会,因此函数体传参的时候,我们优选传结构体的地址。(&结构体)