BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / cpp / #16719同步于 2008/11/26
该镜像源已超过 30 天没有更新,可能在源站已被删除。
CPP机器人发帖

用对齐原则求结构体长度小结(别人的回帖看不懂 火大了)

nightelf
2008/11/26镜像同步7 回复
花两个多小时总结的 写的不对的 请站内我 多多指教。 希望对大家有帮组 1.熟悉Win32下VC6.0各种基本数据长度: size of int is: 4 size of char is: 1 size of short int is: 2 size of double is: 8 size of unsigned int is: 4 size of float is: 4 size of long double is: 8 size of long int is: 4 size of long int is: 4 size of unsigned char is: 1 size of signed char is: 1 size of unsigned long int is: 4 size of signed int is: 4 size of unsigned short int is: 2 size of signed short int is: 2 size of signed int is: 4 size of signed long int is: 4 sizeof 指针 is 4; 2. 结构体长度求法: a.成员都相同时(或含数组且数组数据类型同结构体其他成员数据类型): 结构体长度=成员数据类型长度×成员个数(各成员长度之和); 结构体中数组长度=数组数据类型长度×数组元素个数; b 成员不同且不含其它结构体时; (1).分析各个成员长度; (2).找出最大长度的成员长度M(结构体的长度一定是该成员的整数倍); (3).并按最大成员长度出现的位置将结构体分为若干部分; (4).各个部分长度一次相加,求出大于该和的最小M的整数倍即为该部分长度 (5).将各个部分长度相加之和即为结构体长度 c含有其他结构体时: (1).分析各个成员长度; (2).对是结构体的成员,其长度按b来分析,且不会随着位置的变化而变化; (3).分析各个成员的长度(成员为结构体的分析其成员长度),求出最大值; (4).若长度最大成员在为结构体的成员中,则按结构体成员为分界点分界; 其他成员中有最大长度的成员,则该成员为分界点; 求出各段长度,求出大于该和的最小M的整数倍即为该部分长度 (5).将各个部分长度相加之和即为结构体长度 3. 举例来说: (1). struct test1 { int a; int b[4]; }; sizeof(test1)=sizeof(int)+4*sizeof(int)=4+4*4=20; (2)struct test2 { char a; int b; double c; bool d; }; 分析:该结构体最大长度double型,长度是8,因此结构体长度分两部分: 第一部分是a、 b、 c的长度和,长度分别为1,4,8,则该部分长度和为13,取8的大于13的最小倍数为16; 第二部分为d,长度为1,取大于1的8的最小倍数为8, 两部分和为24,故sizeof(test2)=24; (3)struct test3 { char a; test2 bb;//见上题 int cc; } 分析:该结构体有三个成员,其中第二个bb是类型为test2的结构体,长度为24,且该结构体最大长度成员类型为double型,以后成员中没有double型,所以按bb分界为两部分: 第一部分有a 、bb两部分,a长度为1,bb长度为24,取8的大于25的最小倍数32; 第二部分有cc,长度为4,取8的大于4的最小倍数为8; 两部分之和为40,故sizeof(test3)=40; (4)struct test4 { char a; int b; }; struct test5 { char c; test4 d; double e; bool f; }; 求sizeof(test5) 分析:test5明显含有结构体test4,按例2容易知道sizeof(test4)=8,且其成员最大长度为4;则结构体test5的最大成员长度为8(double 型),所以e是分界点,分test5为两部分: 第一部分由c 、d、e组成,长度为1、8、8,故和为17,取8的大于17的最小倍数为24; 第二部分由f组成,长度为1,取8的大于1的最小倍数为8, 两部分和为32,故sizeof(test5)=24+8=32; 在VC6.0下程序验证 结果是正确的。 还有一种就是含有自身的递归定义的结构体,现在还没做总结,有达人总结了话 分享下
订阅后,新回复会通过你的通知中心匿名送达。
7 条回复
Xer机器人#1 · 2008/11/26
这个应该跟对齐方式有关,gcc下的情况跟lz的结果不太一样 char=1 int=4 double=8 bool=1 test1=20 test2=20 test3=28 test4=8 test5=24 lz可以看一下这个: http://forum.byr.edu.cn/wForum/disparticle.php?boardName=CPP&ID=7946&pos=4 【 在 nightelf (悠悠左月) 的大作中提到: 】 : 花两个多小时总结的 : 写的不对的 请站内我 多多指教。 : 希望对大家有帮组 : ...................
jokerlee机器人#2 · 2008/11/26
gcc对齐规则 (unsigned)char使用一字节对齐 任何2字节大小的数据类型(比如short)的对齐模数是2, 而其它所有超过2字节的数据类型(比如long,double)都以4为对齐模数。 VC对齐有些差异。大于等于8字节的数据类型使用8字节对齐。
nightelf机器人#3 · 2008/11/26
谢谢两位的补充
jokerlee机器人#4 · 2008/11/26
还有一点 GCC的对齐方式可以改变,如: #pragma pack(push, 4) int main() { ...... } #pragma pack(pop)
wangzai机器人#5 · 2008/11/26
原创应该默认的是4字节对齐方式。设置不同的对齐方式后,结果会是不一样的。VC里是#pragma pack。
nightelf机器人#6 · 2008/11/27
【 在 wangzai 的大作中提到: 】 : 原创应该默认的是4字节对齐方式。设置不同的对齐方式后,结果会是不一样的。VC里是#pragma pack。 MS应该是 #pragma pack(8)
nightelf机器人#7 · 2008/11/27
谢谢各位的回帖 现在已经基本上在知道#pragma pack(n)的时候怎么口算得出结构体长度了