✨个人主页: 熬夜学编程的小林
💗系列专栏:< /span> 【C语言详解】 【数据结构详解】< /p> 结构体
1.1、结构体回顾
< p id="1.1.1%E3%80%81%E7%BB%93%E6%9E%84%E7%9A%84%E5%A3%B0%E6%98%8E-toc" style="margin -left:80px;">1.1.1、结构的声明1.1.2、结构体变量的创建和初始化
1.2、结构的特殊声明
1.3、结构的自引用
2、结构体内存对齐
2.1、对齐规则
编辑
总结 p>
struct tag{ member-list;//列表成员}variable-list ;//全局变量列表
例如描述一个同学: struct Stu{ char name[20] ;//姓名 int age;//年龄 char sex[5];//性别 char id[20];//学号}; //分号不能丢
#include struct Stu{ char name[20];//姓名 int Age;//年龄 char sex[5] ;//性别 char id[20];//学号};int main(){ //按照结构体成员的顺序初始化 struct Stu s = { "张三", 20, "男", "20230818001" } ; printf("姓名: %s\n", s.name); printf("年龄: %d\n", s.age); printf("sex : %s\n", s.sex); printf("id : %s\n", s.id); // 按照指定的顺序初始化 struct Stu s2 = { .age = 18, .name = "lisi", .id = "20230818002", .sex = "⼥ printf("姓名: %s\n", s2.name); printf("年龄: %d\n", s2.age); printf("性别:%s\n", s2.sex); printf("id : %s\n", s2.id);返回0;}
//匿名结构体类型struct{ int a;字符b;浮动c; }x;结构{ int a;字符b; float c;}a[20], *p;
上面的两个结构在声明的时候省掉了结构体标签(tag) 问题来了? //在上面代码的基础上,那么下面的代码合法吗?p =&x;
警告: 编译器会把上面的两个个声明当组成完全不同的两个类型,所以是非法的。 匿名的结构体类型,如果没有对结构体类型重命名的话,基本上只能用一次。 struct Node{ int 数据; struct Node next;};
上述代码正确吗?如果正确,那就 sizeof(struct Node) 是多少? 仔细分析,其实是不行的,因为一个结构体中再包含同一类型的结构体变量,这样结构体变量的大小就会无穷大,是不合理的。 正确的自引用方式: span> struct Node{ int data; struct Node* next;};
在结构体自引用使用的过程中,夹杂了 typedef 对匿名资金结构体类型重命名,也容易引入问题,看看 下面的代码,可行吗? typedef struct{ int data; Node* next;}Node;
答案是不行的,因为 Node是对前面的匿名结构体类型的重命名产生的,但是在匿名结构体内部提前使用Node类型来创建成员变量,这是不行的。 解决方案如下:定义结构体不要使用匿名结构体了 typedef struct Node{ int d阿塔; struct Node* next;}Node;
1.结构体的第一个成员对准到和结构体指针初始位置偏移量为0的地址处 2.其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。 对齐数 = 编译器默认的同一对齐数与成员变量大小的较小值。 3.结构体总大小为最大对齐数(结构体中每个成员变量都有一个对齐数,所有对齐数中最大的)的整数倍。 4.如果读取了结构体的情况,则曼哈顿的结构体成员扫描到自己的成员中最大扫描数的整数倍处,结构体的整体大小就是所有最大扫描数(含描绘结构体中成员的扫描数) )的整数倍。
- VS 中默认的值为 8 - Linux中gcc没有默认色彩数,色彩数就是成员自身的大小
//练习1struct S1{ 字符 c1;整数我; char c2;};printf("%d\n", sizeof(struct S1));
1、根据结构体对齐的规则,结构体的第一个成员对齐到和结构体指针初始位置偏移量为0的地址处,即上图第一个绿色框。
2、其他成员变量要对齐到某个数字(对齐数字)的整数倍的地址处。对齐数字 = 编译器默认的一个偶数与该成员变量大小的较小值。int 类型偶数为4,VS默认偶数为8,因此曼哈顿到4的整数倍,即上图橙色方框。
3、其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。char 类型对齐数为1,默认VS对齐数为8,因此对齐到1的整数倍,即上图蓝色方框。
4、结构体总大小为最大对齐数(结构体中每个成员变量都有一个对齐数,所有对齐数中最大的) 最大扫描数为4,此时结构体大小9不是4的倍数,因此会再多浪费3个字节(上图x是浪费的空间),因此大小为12字节。
//练习2struct S2{ char c1;字符c2; int i;};printf("%d\n", sizeof(struct S2));
1、根据结构体对齐的规则,结构体的第三个成员对齐到和结构体指针初始位置偏移量为0的地址处,即上图第一个绿色框。
2、其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。对齐数= 编译器默认的单一单色数与成员变量大小的较小值。char 类型单色数为1,VS 单色数默认数为8,因此安东尼到1的整数倍,即上图橙色方框。
< p>3、其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。char 类型对齐数为1,VS默认对齐数为8,因此对齐到1的整数倍,即上图蓝色方框。4、结构体总大小为最大对齐数(结构体中每个成员变量都有一个对齐数,所有对齐数中最大的)的整数倍。最大对齐数为4,此时结构体大小8是4的倍数,因此大小为8字节。
//练习3struct S3 { 双 d;字符c; int i;};printf("%d\n", sizeof(struct S3));
1 、根据结构体对齐的规则,结构体的第一个成员对齐到和结构体指针初始位置偏移量为0的地址处,即上图 span>第一个绿色框。
2、其他成员变量要偶数到某个数字(偶数)的整数倍的地址处。偶数 = 编译器默认的偶数单色数与成员变量大小的较小值。char 类型单色数为1,VS默认单色数为8,因此单色数为1的整数倍,即上图橙色方框。
3、其他成员变量要对齐到某个数字(对齐数ÿ)int 类型对齐数为4,VS默认对齐数为8,因此对齐到4的整数倍,即上图蓝色方框。
4、结构体总大小为最大对齐数 strong>(结构体中每个成员变量都有一个偶数,所有偶数中最大的)的整数倍。最大偶数为8,此时结构体大小16是8的倍数,因此大小为16字节。
//练习4-结构体读取问题struct S4{ char c1;结构体S3 s3; double d;};printf("%d\n", sizeof(struct S4));
1、根据结构体对齐的规则,结构体的第一个成员个成员对齐到和结构体变量开始位置偏移量为0的地址处,即上图第一个绿色框。
2、如果镂空了结构体的情况,镂空的结构体成员扫描到自己的成员中最大扫描数的整数倍处, 结构体的整体大小就是所有最大对齐数(含凹结构体中成员的对齐数)的整数倍。
其他成员要对齐到某个数字(对齐数)的整数倍的地址处。< strong>单色数 = 编译器默认的同一偶数与成员变量大小的较小值。双类型对齐数为8,VS默认对齐数为8,因此对齐到8的整数倍,即上图橙色
3、其他成员标记要对齐到某个数字(对齐数)的整数倍的地址处。char 类型对齐数为1,默认VS对齐数为8,因此对齐到1的整数倍,即上图蓝色方框。
4、其他成员标记要对齐到某个数字(对齐数)的整数倍的地址处。 int 类型偶数为4,VS默认偶数为8,偶数到4的整数倍,即上图绿色方框。上图绿色方框。 span>
5、其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。double 类型对齐数为8,VS对齐数为8,因此对齐到8的整数倍,即上图橙色方框。默认< /强g>
6、结构体的整体大小就是所有最大扫描数(含雕刻结构体中成员的扫描数)的整数倍。最大扫描数为8,此时结构体大小32是8的倍数,因此大小为32字节。
本篇博客就结束啦,谢谢大家的观看,如果少年公主们有好的建议可以留言哦,谢谢大家啦!
C语言第三十弹---自定义类型:结构体(上) 原创由知识百科栏目发布,感谢您对的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“C语言第三十弹---自定义类型:结构体(上) 原创”