
一、结构体的定义结构体(struct)是一种用户自定义的复合数据类型允许将多个不同类型的数据项组合成一个逻辑相关的数据单元。可以将结构体看作是一个包含了一组变量的集合这些变量被称为结构体的成员(member)或字段(field)struct Stu//Stu是结构体的名称 { char name[20];//名字 int age;//年龄 char sex[5];//性别 char id[20];//学号 }; //分号不能丢二、结构体变量的创建和初始化还有在前创建变量都是struct Stu 类型的变量s1 s2但都各自有属于变量本身的内存空间可以通过结构体变量加. 号的方式来访问结构体当中的成员变量/字段三、结构体的自引用在结构体内部引用自己1.typedeftypedef其实就是“起别名”定义结构体不要使用匿名结构体!四、结构体内存对齐内存对齐是计算机硬件特别是CPU对内存中数据存放位置的一种要求。指的是数据的起始内存地址必须是其自身大小的整数倍。其实就是CPU 要求数据在内存里必须 “站在自己身高的整数倍地址上”比如一个 4 字节的int它的起始地址必须是 0、4、8、12… 这样 4 的倍数不能是 1、2、3。因为CPU 读取内存不是 “一个字节一个字节” 读的而是按固定块大小比如 4 字节、8 字节批量读取。这样让 CPU 能高效、快速地读取内存数据避免多次访问和拼接。对齐规则1.结构体的第1个成员对齐到和结构体变量起始位置偏移量为0的地址处。2.从第2个成员变量开始都要对齐到某个对齐数的整数倍的地址处。对齐数编译器默认的一个对齐数 与 该成员变量大小的较小值。VS中默认的值为8Linux中gcc没有默认对齐数对齐数就是成员自身的大小3.结构体总大小为最大对齐数结构体中每个成员变量都有一个对齐数所有对齐数中最大的的整数倍。4.如果嵌套了结构体的情况嵌套的结构体成员对齐到自己的成员中最大对齐数的整数倍处结构体的整体大小就是所有最大对齐数含嵌套结构体中成员的对齐数的整数倍。计算结构体大小举例这就是计算结构体字节数大小的方法结构体成员类型相同但所占空间大小不同struct S1 { char c1; int i; char c2; }; struct S2 { char c1; char c2; int i; };S1和S2类型的成员一模一样但是S1和S2所占空间的大小有了一些区别。修改默认对齐数#pragma这个预处理指令所有以# 开头的都叫做预处理指令可以改变编译器的默认对齐数。(一般修改为1、4、8等#include stdio.h #pragma pack(1)//设置默认对齐数为1 struct S { char c1; int i; char c2; }; #pragma pack()//取消设置的对齐数还原为默认 int main() { //输出的结果是什么 printf(%d\n, sizeof(struct S));//输出结果为6 return 0; }五、结构体传参结构体传参可以传结构体也可以通过指针传结构体地址struct S { int data[1000]; int num; }; struct S s {{1,2,3,4}, 1000}; //结构体传参 void print1(struct S s) { printf(%d\n, s.num); } //结构体地址传参 void print2(struct S* ps) { printf(%d\n, ps-num); }调用print1函数和print2函数结果都是打印1000那么肯定首选print2函数函数传参的时候参数是需要压栈会有时间和空间上的系统开销。如果传递一个结构体对象的时候结构体过大参数压栈的的系统开销比较大所以会导致性能的下降。结论结构体传参要传结构体的地址-叫作指向符要通过指针访问结构体成员的数据有*p. 和 p-两种方法