如何计算结构体及共用体大小
http://blog.sina.com.cn/s/blog_640e171401014ykc.html
如何计算结构体及共用体大小
(声明:以下均为我一个字一个字打上去的,来源于大一上学期所作笔记) 对于结构体 首先理解字节对齐机制: (1),结构体变量的首地址能够被其最宽基本类型成员大小所整除。 (2),结构体每个成员相对于结构体首地址的偏移量(offset)都是该成员大小的整数倍,如有需要,编译器会在成员之间加上中间填充字节。 (3)结构体总大小为结构体最宽基本类型成员大小的整数倍,如有需要,编译器会在最末一个成员之后加上末尾填充字节。 第(2)、(3)条准则决定了结构体变量占据内存空间的大小。 基本类型指:char,short,int,float,double。 数据宽度即其sizeof的大小。
eg:struct {char c;short s;float f;}A,struct{char c;float f;short s;}B; 则sizeof(A)=?,sizeof(B)=? 解:A中,char占1字节,short占2,则short相对于结构体首地址的offset(偏移量)=1,为满足准则(2),必须添加中间填充字节1;float占4字节,相对于结构体首地址offset=(1+1+2)即4,满足准则(2)。此时结构体大小为(1+1+2+4)=8,是最宽基本类型float整数倍,满足(3)。所以可得出:sizeof(A)=8;
对于B:B中,char占1,float占4,则float相对于结构体首地址的offset=1,为满足准则(2),必须添加中间填充字节3;short占2,相对于结构体首地址offset=(1+3+4)即8,是short所占字节的整数倍,满足准则(2)。此时结构体大小为(1+3+4+2)=10,不是最宽基本类型float的整数倍,这时,末尾必须添加末尾填充字节2,所以最后总大小为12;
总结:分析时只要这样即可: 对于A:1 1 2 4 (红色为插入部分,写时,中间要留够空格) 对于B:1 3 4 2 2 这样就可以直观的得到结构体大小。
迁移eg:struct{float f;int I;short s;}C; 则sizeof(C)=?(答案:12)
知识扩展1:若出现结构体嵌套,则准则(2)、(3)应改为: (2),复合成员相对于结构体首地址的偏移量是复合成员中最宽基本类型成员大小的整数倍。 (3),结构体总大小为结构体最宽基本类型成员大小整数倍。 eg: struct { float f; char c; double d; struct { double d1; float f1; double d2; char c1; }A }B; 则sizeof(B)=? 解:先计算A大小:8 4 4 8 1 7(红色为插入部分),得到为32; 所以对于B,一开始排列为: 4 1 8 32; 1的offset=4,所以4与1间要添上3。变为: 4 3 1 8 32; 此时8的offset=8,满足准则2,32的offset=16,是A中最宽基本类型double所占字节的整数倍,满足准则2;此时B大小为48,是B中最宽基本类型double的整数倍,满足准则3.所以最后sizeof(B)=48;
知识扩展2,若结构体内部出现数组,则准则2应为: (2),数组相对于结构体首地址的offset是该数组成员大小的整数倍。 eg :struct {double d[2];char*c;}C; 则sizeof(C)=? 解:double大小为8字节,所以double[2]为16;而指针大小均为4, 所以C可排列为: 16 44 得到sizeof(C)=24;
对于共用体: 原则上,共用体大小取决于占据最多内存的成员的长度。但字节对齐准则(3)仍然成立。Eg: Union { char c; double d; }e; 则sizeof(e)=16;