变量占用位数的自动补齐规则程序设计
#pragma pack(8)
struct s1
{
short a;
long b;

};

struct s2
{
char c;
s1 d;
};
结果sizeof(s2)=12
如果直接把s1代入
struct s2
{
char c;
short a;
long b;
};
结果sizeof(b)=8
两者到底有什么区别,包含在另一个结构体中的结构体有什么对齐规则?

结果应该是在32位机器上的。
解释如下:
s1
short是2个字节,long是4个字节。补齐一个机器字,大小就成了8字节。
s2
char是一个字节,照样补齐一个机器字,再加上s1,大小是12字节。
最后一个不妨改为s3
这个是不会和s2一样的。s2包含用户自定义的数据结构,而s3都是系统默认的。
还是按则整机器字节的分配方案,因此大小为8字节。

2+(2)+4=8

1+(3)+8=12

1+(1)+2+4=8

括号里数字是为了补齐一个机器字而增加的。其中,short 2个字节,long 4个字节,char 1个字节。

struct s2
{
char c;
double d;
};
double d也占8字节,按字节对齐原则,sizeof(s2)=16
原题中,
struct s2
{
char c;
s1 d;
};
因sizeof(s1)=8,若也按字节对齐的话,sizeof(s2)=16才对,为什么是12呢??? 

如果一个结构体作为另一个结构体的成员时,对齐方式按成员中最大成员所占字节数对齐,如上例中,因为char c是一个字节,而S1中的最大字节是4,所以应按4字节对齐,而非8字节,如有

不清楚,可以查看MSDN。


其实可用一句话概括:struct结构体中各成员变量存放的起始地址相对于结构体起始地址的偏移量必须为该变量类型所占字节的整数倍。同时必须满足另外一个条件:结构体的大小为结构的字

节边界数(即该结构中占用最大空间的类型所占用的字节数)的倍数。(两个条件)

听起来有点拗口,用例子说明:

struct test{

   double dvar1;

   char chvar2;

   int ivar3;

}

为上面的结构分配空间的时候,VC根据成员变量出现的顺序和对齐方式,先为第一个成员 dvar1分配空间,其起始地址跟结构的起始地址相同(刚好偏移量0刚好为sizeof(double)的倍数),

该成员变量占用 sizeof(double)=8个字节;接下来为第二个成员chvar2分配空间,这时下一个可以分配的地址对于结构的起始地址的偏移量为8,是 sizeof(char)的倍数,所以把chvar2存放

在偏移量为8的地方满足对齐方式,该成员变量占用 sizeof(char)=1个字节;接下来为第三个成员ivar3分配空间,这时下一个可以分配的地址对于结构的起始地址的偏移量为9,不是 sizeof

(int)=4的倍数,为了满足对齐方式对偏移量的约束问题,VC自动填充3个字节(这三个字节没有放什么东西),这时下一个可以分配的地址对于结构的起始地址的偏移量为12,刚好是sizeof

(int)=4的倍数,所以把ivar3存放在偏移量为12的地方,该成员变量占用sizeof(int)=4 个字节;这时整个结构的成员变量已经都分配了空间,总的占用的空间大小为:8+1+3+4=16,刚好为结

构的字节边界数(即结构中占用最大空间的类型所占用的字节数sizeof(double)=8)的倍数,所以没有空缺的字节需要填充。所以整个结构的大小为:sizeof(MyStruct)=8+1+ 3+4=16,其中有

3个字节是VC自动填充的,没有放任何有意义的东西。

如果对上面的例子稍作调整,结果就大不同了:

struct test{

   char chvar2;

   double dvar1;

   int ivar3;

}
整个结构体占用的空间大小为24个字节,可按照前面的总结推算出来。

此外,VC提供了#pragma pack(n)来屏蔽系统默认的对齐方式,使用自定义对齐方式。n为要对齐的字节数。

n字节对齐就是说变量存放的起始地址的偏移量有两种情况:第一、如果n大于等于该变量所占用的字节数,那么偏移量必须满足默认的对齐方式,第二、如果n小于该变量的类型所占用的字节

数,那么偏移量为n的倍数,不用满足默认的对齐方式。结构的总大小也有个约束条件,分下面两种情况:如果n大于所有成员变量类型所占用的字节数,那么结构的总大小必须为占用空间最大

的变量占用的空间数的倍数;

Type
Alignment
char
在字节边界上对齐
short (16-bit)
在双字节边界上对齐
int and long (32-bit)
在4字节边界上对齐
float
在4字节边界上对齐
double
在8字节边界上对齐
structures
单独考虑结构体的个成员,它们在不同的字节边界上对齐。
其中最大的字节边界数就是该结构的字节边界数。