C语言-数据的存储(结构体、位段、联合体)

结构体

结构体内存对齐规则
1.第一个成员在制结构体变量偏移量为0的地址处。
2.其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。

对齐数=编译器默认的一个对齐数与该成员大小的较小值。

●VS中默认的值为8

3.结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。
4.如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

了解了结构体内存对齐规则
1.接下来看这样一道题:
在这里插入图片描述
分析过程:
在这里插入图片描述
输出结果:
在这里插入图片描述
2.接下来再看一道关于结构体镶嵌的题
在这里插入图片描述
分析过程:
在这里插入图片描述
输出结果:
在这里插入图片描述
3.最后我们再来看一道成员变量定义的先后影响结构体大小的题
在这里插入图片描述
分析过程:

在这里插入图片描述
输出结果:
在这里插入图片描述
由此可见,我们在定义结构体成员变量的时候应该把类型一样的定义在一起,这样可以节约空间

位段

位段与结构体
在讲解位段的存储方式之前,我们再来简单的介绍一下位段:
1.位段的成员必须是 int、unsigned int、signed int。
2.位段的成员名后边有一个冒号和一个数字。

通过下面这张图,我们来简单对比一下位段与结构体:
在这里插入图片描述
在这里插入图片描述
那么,位段成员变量后面的冒号+数字到底有什么用呢?又为什么会有位段的出现呢?

*注意:特别补充一点,位段成员变量也可以是char类型

位段的存储
其实,位段成员变量后面的冒号+数字表示了该变量一共占多少个比特位,注意是比特位,而不是字节哦!

接下来我们探讨一下位段是如何存储的,看接下来这道题:
在这里插入图片描述
分析过程:
在这里插入图片描述
输出结果:
在这里插入图片描述
虽然我们得到了上一道题的答案,但如果你仔细想想就会发现,我只说了要存放d就要再开辟4个字节,但并没有说d的30个比特位到底该如何存放?究竟是先填满之前剩下的?还是直接存放在新开辟的4个字节?

其实,上述问题的答案取决于编译器。
位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使用位段!

位段的跨平台问题

1.int位段被当成有符号数还是无符号数是不确定的。
2.位段中最大位的数目不能确定。( 16位机器最大16,32位机器最大32 ,写成27,在16位机器会出问题)
3.位段中的成员在内存中从左向右分配,还是从右向左分配标准尚未定义。
4.当一个结构包含两个位段,第二个位段成员比较大,无法容纳于第一个位段剩余的位时,是舍弃剩余的位还是利用,这是不确定的。

总结:
跟结构相比,位段可以达到同样的效果,但是可以很好的节省空间,但是有跨平台的问题存在。

联合体

在介绍联合体存储方式之前,我们先来看一道题:
在这里插入图片描述
输出结果:
在这里插入图片描述
当你初次看到这样一道题,你就算猜也肯定会猜一个不小于5的答案。可当你看到答案时,你懵了……

接下来我们来看:
在这里插入图片描述

这里你会发现,联合体s和变量a、b的起始地址居然一样!其实成员变量a和b是共用同一块空间。联合体也被称为共用体。
在这里插入图片描述

联合的特点

联合的成员是共用一块内存空间的,这样一个联合变量的大小,至少是最大成员的大小。因为联合至少得有能力保存最大的那个成员
联合体在同一时间只能使用一个成员,一般不各自初始化,而是值初始化其中一个。

在我们知道了联合体成员是共用同一块空间之后,难道联合体的总大小就只是最大成员的大小吗?

联合体的计算

●联合的大小至少是最大成员的大小。
●当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。

例如:
在这里插入图片描述
在你清楚了联合体的大小以及特点之后,你肯定会想,这玩意有啥用啊,接下来我讲个简单的应用

联合体的简单应用

我之前介绍过大小端存储模式,那我想问:如何写一个简单代码来判断自己的编译器是大端存储还是小端存储
大小端模式请参见: link

代码如下:
在这里插入图片描述
分析过程:
在这里插入图片描述

本次分享到这里也就结束啦,如果各位看官有收获的话还希望给个三连支持一波,有什么意见或者建议也请评论区指出,谢谢大家!
在这里插入图片描述

  • 8
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值