sizeof浅析(一)——求结构体大小
来源:互联网 发布:淘宝密码忘了怎么办 编辑:程序博客网 时间:2024/05/20 09:43
运算符sizeof可以计算出给定类型的大小,对于32位系统来说,sizeof(char) = 1; sizeof(int) = 4。基本数据类型的大小很好计算,我们来看一下如何计算构造数据类型的大小。
C语言中的构造数据类型有三种:数组、结构体和共用体。
数组是相同类型的元素的集合,只要会计算单个元素的大小,整个数组所占空间等于基础元素大小乘上元素的个数。结构体中的成员可以是不同的数据类型,成员按照定义时的顺序依次存储在连续的内存空间。和数组不一样的是,结构体的大小不是所有成员大小简单的相加,需要考虑到系统在存储结构体变量时的地址对齐问题。看下面这样的一个结构体:
- struct stu1
- {
- int i;
- char c;
- int j;
- };
用sizeof求该结构体的大小,发现值为12。int占4个字节,char占1个字节,结果应该是9个字节才对啊,为什么呢?
先介绍一个相关的概念——偏移量。偏移量指的是结构体变量中成员的地址和结构体变量地址的差。结构体大小等于最后一个成员的偏移量加上最后一个成员的大小。显然,结构体变量中第一个成员的地址就是结构体变量的首地址。因此,第一个成员i的偏移量为0。第二个成员c的偏移量是第一个成员的偏移量加上第一个成员的大小(0+4),其值为4;第三个成员j的偏移量是第二个成员的偏移量加上第二个成员的大小(4+1),其值为5。
然而,在实际中,存储变量时地址要求对齐,编译器在编译程序时会遵循两条原则:
(1)结构体变量中成员的偏移量必须是成员大小的整数倍(0被认为是任何数的整数倍)
(2)结构体大小必须是所有成员大小的整数倍,也即所有成员大小的公倍数。
上面的例子中前两个成员的偏移量都满足要求,但第三个成员的偏移量为5,并不是自身(int)大小的整数倍。编译器在处理时会在第二个成员后面补上3个空字节,使得第三个成员的偏移量变成8。结构体大小等于最后一个成员的偏移量加上其大小,上面的例子中计算出来的大小为12,满足要求。再来看另外一个例子:
- struct stu2
- {
- int k;
- short t;
- };
由此可见,结构体类型需要考虑到字节对齐的情况,不同的顺序会影响结构体的大小。
对比下面两种定义顺序:
- struct stu3
- {
- char c1;
- int i;
- char c2;
- }
- struct stu4
- {
- char c1;
- char c2;
- int i;
- }
对于嵌套的结构体,需要将其展开。对结构体求sizeof时,上述两种原则变为:
(1)展开后的结构体的第一个成员的偏移量应当是被展开的结构体中最大的成员的整数倍。
(2)结构体大小必须是所有成员大小的整数倍,这里所有成员计算的是展开后的成员,而不是将嵌套的结构体当做一个整体。
看下面的例子:
- struct stu5
- {
- short i;
- struct
- {
- char c;
- int j;
- } ss;
- int k;
- }
结构体stu5的成员ss.c的偏移量应该是4,而不是2。整个结构体大小应该是16。
下述代码测试原则2:
- struct stu5
- {
- char i;
- struct
- {
- char c;
- int j;
- } ss;
- char a;
- char b;
- char d;
- char e;
- char f;
- }
结构体ss单独计算占用空间为8,而stu5的sizeof则是20,不是8的整数倍,这说明在计算sizeof(stu5)时,将嵌套的结构体ss展开了,这样stu5中最大的成员为ss.j,占用4个字节,20为4的整数倍。如果将ss当做一个整体,结果应该是24了。
另一个特殊的例子是结构体中包含数组,其sizeof应当和处理嵌套结构体一样,将其展开,如下例子:
- struct ss
- {
- float f;
- char p;
- int adf[3];
- };
- cout<<sizeof(ss)<<endl;
其值为20。float占4个字节,到char p时偏移量为4,p占一个字节,到int adf[3]时偏移量为5,扩展为int的整数倍,而非int adf[3]的整数倍,这样偏移量变为8,而不是12。结果是8+12=20,是最大成员float或int的大小的整数倍。
如何给结构体变量分配空间由编译器决定,以上情况针对的是Linux下的GCC。在Windows下的VC平台也是这样,至于其他平台,可能会有不同的处理。
- sizeof浅析(一)——求结构体大小
- sizeof浅析(一)——求结构体大小
- sizeof浅析(一)——求结构体大小
- sizeof浅析——求结构体大小
- sizeof浅析——求结构体大小
- sizeof浅析——求结构体大小
- sizeof 浅析-----求结构体大小
- sizeof浅析,求结构体大小
- sizeof浅析(三)——求类的大小
- sizeof——求结构体的大小
- sizeof求结构体大小
- sizeof求结构体大小
- sizeof浅析——求类的大小
- C/C++ sizeof函数解析——解决sizeof求结构体大小的问题
- C/C++ sizeof函数解析——解决sizeof求结构体大小的问题
- 关于sizeof的问题(2)——求结构体大小
- sizeof运算求结构体大小
- c语言 sizeof()求结构体大小
- unity ulua之lua调用c#
- Spark生态顶级项目汇总
- [Gradle Retrolambda]Android Studio使用lambda表达式
- Android 平滑图片加载和缓存库 Glide 使用详解
- 诡异的解决了诡异的错误---Win10+Kali linux 2.0 双系统 以及 grub 修复(上)
- sizeof浅析(一)——求结构体大小
- adb强制打开“未知来源”
- 数据结构---线性表----顺序存储结构
- 【原创】k8s源码分析------kube-apiserver分析(1)
- 【机器学习详解】KNN分类的概念、误差率及其问题
- 获取时间Calendar、使用 Date 和 SimpleDateFormat 类表示时间
- Android官网教你如何系统学习
- Android 图片拖拽、放大缩小的自定义控件
- PHP Mail