#include <stdio.h> int main() { union u1 { double a; int b; }u1; union u2 { char a[13]; int b; }u2; union u3 { char a[13]; char b; }u3; union u4 { char a[13]; int b; }u4; union u5 { char a[13]; char b; }u5; struct s1 { char a; double b; int c; char d; }s1; struct s2 { char a; char b; int c; double d; }s2; struct s11 { char a[8]; }s11; struct s22 { double d; }s22; struct s33 { struct s11 s; char a; }s33; struct s44 { struct s22 s; char a; }s44; printf("size of u1 is %d.\n",sizeof(u1));//8 printf("size of u2 is %d.\n",sizeof(u2));//16 printf("size of u3 is %d.\n",sizeof(u3));//13 printf("size of u4 is %d.\n",sizeof(u4));//16 printf("size of u5 is %d.\n",sizeof(u5));//13 printf("size of s1 is %d.\n",sizeof(s1));//24 printf("size of s2 is %d.\n",sizeof(s2));//16 printf("size of s11 is %d.\n",sizeof(s11));//8 printf("size of s22 is %d.\n",sizeof(s22));//8 printf("size of s33 is %d.\n",sizeof(s33));//9 printf("size of s44 is %d.\n",sizeof(s44));//16 return 0; }
结论:复合数据类型,如union,struct,class的对齐方式为成员中对齐方式最大的成员的对齐方式。
结论1:都知道union的大小取决于它所有的成员中,占用空间最大的一个成员的大小。所以对于u1来说,大小就是最大的double类型成员a了,所以 sizeof(u1)=sizeof(double)=8。但是对于u2和u3,最大的空间都是char[13]类型的数组,为什么u3的大小是13,而 u2是16呢?关键在于u2中的成员int b。由于int类型成员的存在,使u2的对齐方式变成4,也就是说,u2的大小必须在4的对界上,所以占用的空间变成了16(最接近13的对界)。
结论2 :struct 里面的元素是顺序存储的,每个元素占用的字节数根据对齐字节数N(struct 里占用字节最多的元素与CPU对齐字节数中较小的一个)进行调整.如果从左至右M个元素加起来的字节数大于N,则按从右至左舍去K个元素直至M-K个元素 加起来的字节数小于等于N,如果等于N则不用字节填充,小于N则把M-K-1的元素填充直至=N.
附:设置对齐方式
一 #pragma pack ( [ show ] | [ push | pop ] [, identifier ] , n )
[]里面的是可有可无的但是n一定要指定,如果没有编译器默认n=8
使用方法:
1. #pragma pack(push) //保存对齐状态 2. #pragma pack(1)//设定为1字节对齐 3. #pragma pack(show); //编译的时候会在警告信息里面体现具体的字长的设置信息 4. struct test 5. { 6. 7. char m1; 8. 9. double m4; 10. int m3; 11. }; 12. #pragma pack(pop)
test将不再以double的大小为准则,开始用1个字节的对齐方式。
二 另外一种设置对齐方式的是:
__declspec( align( # ) )
里面#必须的是2的n次方,从1,2,4,8,16到8192,这样的话,如果定义一个结构体,他将以结构体的大小为准,补足到最临近的#的的整数倍。
比如:
__declspec(align(8)) struct Str1{ int a, b, c, d, e; char f; char *g; }; //本身是25个字节补足到最近的8的倍数也就是32 __declspec(align(4)) struct Str1{ int a, b, c, d, e; char f; char *g; }; //本身是25个字节补足到最近的4的倍数也就是28
另外,需要注意。
另外有一点要注意的就是GCC编译的程序,最大就是以4字节对齐,,不管你怎么弄,或者说怎么设置,它是不可能以8比如double来对齐的,比如:
struct test { char m1; double m4; }
gcc编译的话,那么他的大小是多少呢?如果不设置对齐的话是12,4个字节对齐的结果.
但是如果设置了:
#pragma pack(8)
是什么效果?
依旧是4个字节对齐,而且 #pragma pack()是属于c语言的,跟系统无关,不管是windows还是linux!