织梦网站专题模板门户网站开发模板
织梦网站专题模板,门户网站开发模板,数字广东网络建设有限公司天眼查,谷歌推广目录
1、 结构体的内存对齐
1.1、对齐规则
1.2、练习1、练习2#xff08;演示对齐规则1、2、3、4#xff09;
2、为什么存在内存对齐
2.1、平台原因#xff08;移植原因#xff09;
2.2、性能原因
2.3、那么如何即满足对齐#xff0c;又要节省空间呢#xff1f;
…
目录
1、 结构体的内存对齐
1.1、对齐规则
1.2、练习1、练习2演示对齐规则1、2、3、4
2、为什么存在内存对齐
2.1、平台原因移植原因
2.2、性能原因
2.3、那么如何即满足对齐又要节省空间呢
3、修改默认对齐数
4、结构体传参
4.1、将结构体传到函数print中
4.2、将地址传到函数print中
4.3、区别
5、结构体实现位段
5.1、什么是位段
5.2、位段的内存分配
5.3、注意事项
6、谢谢观看 上一篇博客写了结构体变量的创建、初始化和声明等内容今天的这篇博客来带大家深入理解结构体的知识点。希望大家多多支持。 正文
1、 结构体的内存对齐
首先抛一个问题结构体的大小如何计算
要知道这个题的答案首先要了解结构体内存对齐。
1.1、对齐规则 1、结构体的第一个成员对齐到和结构体变量起始位置偏移量为0的地址处 2、其他成员变量要对齐到某一个数字对齐数的整数倍的地址处 3、结构体总大小为最大对齐数的整数倍 4、如果嵌套了结构体嵌套的结构体成员对齐到自己的成员中最大对齐数的整数倍处结构体的整体大小就是所有最大对齐数中的最大值的整数倍 偏移量字节与结构体变量开始存放位置之间相偏移的值 对齐数编译器默认的一个对齐数与该成员变量大小相比 二者之中取。较小值 VS中默认的一个对齐数是 8 Linux中gcc 没有默认对齐数对齐数就是成员自身的大小 最大对齐数结构体中每个成员变量都有一个对齐数所有对齐数中最大的数 1.2、练习1、练习2演示对齐规则1、2、3、4
求结构体的大小
练习1、
演示对齐规则1、2 、3 找对齐数 对齐数 编译器默认的一个对齐数与该成员变量大小 相比 二者之中取较小值。 c1 的对齐数是 1 i 的对齐数是4 c2 的对齐数是1 对齐规则1 结构体的第一个成员对齐到和结构体变量起始位置偏移量为0的地址处
如下图第一个成员变量c1 放在偏移量为0的位置 对齐规则2其他成员变量要对齐到其对齐数的整数倍的地址处
成员 i 的对齐数是 4i 从偏移量为4的倍数的位置开始存放按本题即从偏移量为4的位置开始向后存放4个字节。 成员 c2 的对齐数是 1 c2 从偏移量为1的倍数的位置开始存放按本题即从偏移量为8的位置开始向后存放1个字节。 对齐规则3 结构体总大小为最大对齐数的整数倍 结构体中三个成员的对齐数分别为 1、4、1则最大对齐数是 4 那么结构体总大小为 4 的整数倍 由上图三个成员已经占了9个字节的空间所以不能少于4的2倍为8 则结构体总大小为 4*312, 4的3倍 练习2、
演示对齐规则4 对齐规则4 如果嵌套了结构体嵌套的结构体成员对齐到自己的成员中最大对齐数的整数倍处结构体的整体大小就是所有最大对齐数中的最大值的整数倍
对于 struct S2 内嵌结构体其结构体总大小为2*816
内嵌结构体的最大对齐数是 8 内嵌结构体的最大对齐数是 8 则在结构体S3中该结构体的对齐数为8 大小为16 由上图该结构体的大小为 4*832
2、为什么存在内存对齐
2.1、平台原因移植原因
不是所有的硬件平台都能访问任意地址上的任意数据的某些硬件平台只能在某些地址处取某些特定类型的数据否则抛出硬件异常。
举例说明有些平台上结构体成员中 int类型的数据只能存在4的倍数的内存中此时就需要有内存对齐。
2.2、性能原因
数据结构特别是栈应该尽可能的在自然边界上对齐。原因为了访问未对齐的内存 处理器需要做两次内存访问而对齐的内存访问只需要一次。
例如
在32为平台下一次访问4个字节成员i 在对齐的情况下能被一次读完。
不对齐的情况下按顺序存放 所以说内存对齐损耗了空间但节省了时间结构体的内存对齐是拿空间来换取时间的做法。
2.3、那么如何即满足对齐又要节省空间呢
请看下面的例子两个结构体中只是更改了成员的顺序 struct S1中 两个占空间小的char 类型的成员分散排列。
而 struct S2中 两个占空间小的char 类型的成员集中在一起排列。
所以要即满足对齐又要节省空间的方法是让占用空间小的成员尽量集中在一起。
3、修改默认对齐数 使用 #pragma 这个预处理命令可以修改编译器的默认对齐数。 具体使用
设置默认对齐数为1相当于不对齐的情况所占字节是所有成员的字节大小。
结构体在对齐方式不合适的时候我们可以自己更改默认对齐数。
4、结构体传参
结构体传参可以传结构体也可以传地址。但我们首选传地址。
4.1、将结构体传到函数print中 4.2、将地址传到函数print中 4.3、区别
传结构体在传结构体时需要创建临时结构体来储存如果结构体中有成员占内存过大会在传递时产生时间和空间的巨大开销。 正经解释 函数传参的时候参数需要压栈会有时间和空间上的系统开销。 如果传递一个结构体对象的时候结构体过大参数压栈的系统开销较大所以会导致性能下降。 故结构体传参的时候要传结构体的地址。
5、结构体实现位段
结构体具有实现位段的能力。
5.1、什么是位段 位段成员必须是int、unsigned int或 signed int在C99中位段成员类型也可以选择其他类型。 基本形式位段成员名后面有一个冒号和一个数字。数字代表该成员所占的bit位数。 这里的A就是位段类型。
5.2、位段的内存分配 位段的空间上是按照以4个字节或1个字节的方式来开辟的。位段涉及很多的不确定因素是不能跨平台的。 详细开辟方式如结构体。
5.3、注意事项 不能对位段的成员使用操作符这样就不能使用scanf直接给位段的成员输入值只能是先输入放在一个变量中然后赋值给位段成员。
如下 6、谢谢观看
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/90392.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!