一:计算结构体大小
1、计算结构体大小的时候结构体本身有一个对齐参数,我们可以通过#pragma pack(n)[n必须是2的整数次幂]进行设置。
2、在给结构体的每一个成员分配地址的时候,每个成员自己也有一个自己的对齐参数,对于基本数据类型,就是其该类型所占用字节的大小,对于结构体,则是成员里边占用字节数最大的成员所占字节数的大小和默认的对齐参数【通过#pragma pack(n)设置】的较小的那个,但是给每个成员分配地址的时候,该成员的对齐大小应该是该类型成员的对齐参数大小和系统默认值【通过#pragma pack(n)】中较小的那一个。
3、vc和gcc(和dev)的区别:
vc计算结构体的大小都按上述两个规则计算,但是在gcc(和dev)中,系统默认对齐参数【可通过#pragma pack(n)设置】最大为4,即使显式指定它大于4,也会按照4来计算。
例:
struct A
{char a;
long b;
} ;
struct C
{char a;
struct A b;
double c;
};
struct D
{
char a;
struct A b;
double c;
int d;
};
VC:sizoef(C):24 sizeof(D):32
GCC:sizeof(C):20 sizeof(D):24
二、计算位域大小:
1)如果相邻位域字段的类型相同,且位宽之和小于该类型所占字节数,则后面的字段紧邻前一个字段存储;
2)如果相邻位域字段的类型相同呢,但是位宽之和大于该类型所占字节数,则后面的字段从新的存储单元开始;
3)如果相邻位域字段类型不同,则不采取压缩方式(指不同位域字段存放在不同的位域类型字节中)【这是VC和GCC的区别】
如:
struct s1
{
int i:8;
char j:4;
int a:20;
double b;
}
struct s2
{
int i:8;
char j:4;
int a:21;
double b;
}
vc:
sizeof(s1):24
sizeof(s2):12
gcc:
sizeof(s1):24
sizeof(s2):16
4)如果位域字段之间穿插着非位域字段,则不进行压缩
struct s
{
char c:2;
double i;
int a:4;
}
gcc:16
vc:24
5)整个结构体的总大小为最宽基本类型成员大小的整数倍。