首页 > 知识百科 > 正文

C语言第三十弹---自定义类型:结构体(上) 原创

个人主页: 熬夜学编程的小林

💗系列专栏:< /span> 【C语言详解】 【数据结构详解】< /p>

结构体

< p id="1%E3%80%81%E7%BB%93%E6%9E%84%E4%BD%93%E7%B1%BB%E5%9E%8B%E7%9A%84%E5% A3%B0%E6%98%8E-toc" style="margin-left:0px;">1、结构体类型的声明

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、对齐规则

编辑

总结


1、结构体类型的声明

前面我们在学习操作符的时候,已经学习了结构体的知识,这里稍微复习一下。

1.1、结构体回顾

结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。

1.1.1、结构的声明

struct tag{ member-list;//列表成员}variable-list ;//全局变量列表
例如描述一个同学:
struct Stu{ char name[20] ;//姓名 int age;//年龄 char sex[5];//性别 char id[20];//学号}; //分号不能丢

1.1.2、结构体变量的创建和初始化

#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;}

1.2、结构的特殊声明

在声明结构的时候,可以不完全的声明。 比如:
//匿名结构体类型struct{ int a;字符b;浮动c; }x;结构{ int a;字符b; float c;}a[20], *p;
上面的两个结构在声明的时候省掉了结构体标签(tag) 问题来了?
//在上面代码的基础上,那么下面的代码合法吗?p =&x;
警告: 编译器会把上面的两个个声明当组成完全不同的两个类型,所以是非法的。 匿名的结构体类型,如果没有对结构体类型重命名的话,基本上只能用一次。

1.3、结构的自引用

在结构中包含一致性个类型为该结构本身的成员是否可以呢? 比如,定义一致性个链表的节点< /span>
struct Node{ int 数据; struct Node next;};
上述代码正确吗?如果正确,那就 sizeof(struct Node) 是多少? 仔细分析,其实是不行的,因为一个结构体中再包含同一类型的结构体变量,这样结构体变量的大小就会无穷大,是不合理的。 正确的自引用方式:
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;

2、结构体内存对齐

我们已经掌握了结构体的基本使用了。 现在我们深入讨论一个问题:计算结构 这也是一个特别热门的考点:结构体内存调整

2.1、颜规则

首先掌握结构体的颜规则:
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的地址处,即上图第一个绿色框。

2、其他成员变量要偶数到某个数字(偶数)的整数倍的地址处。偶数 = 编译器默认的偶数单色数与成员变量大小的较小值。char 类型单色数为1,VS默认单色数为8,因此单色数为1的整数倍,即上图橙色方框。

3、其他成员变量要对齐到某个数字(对齐数ÿ)int 类型对齐数为4,VS默认对齐数为8,因此对齐到4的整数倍,即上图蓝色方框。

4、结构体总大小为最大对齐数(结构体中每个成员变量都有一个偶数,所有偶数中最大的)的整数倍。最大偶数为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语言第三十弹---自定义类型:结构体(上) 原创

Copyright © 2012-2023 普诚元亨工作室 版权所有

*本站部分网页素材及相关资源来源互联网,如有侵权请速告知,我们将会在24小时内删除*

Z-BlogPHP 1.7.3 琼ICP备2022020219号