#pragma pack(8)
int main()
{
struct data
{
int dog;
double cat;
int cow;
} too;
printf("%d\n", sizeof(struct data));
return 0;
}
首先
#pragma pack(8)
代表该文件强制执行8位对齐,可以看出总共占用了24个内存(字节Byte)大小
dog | dog | dog | dog | null | null | null | null |
---|---|---|---|---|---|---|---|
cat | cat | cat | cat | cat | cat | cat | cat |
cow | cow | cow | cow | null | null | null | null |
#pragma pack(4)
代表该文件强制执行4位对齐,可以看出总共占用了16个内存(字节Byte)大小
dog | dog | dog | dog |
---|---|---|---|
cat | cat | cat | cat |
cat | cat | cat | cat |
cow | cow | cow | cow |
若是不加#pragma pack(4)则会以字节最长的类型来确定位数,该结构体最长的是double,8位。
其次
#pragma pack(8)
int main()
{
struct data
{
int dog;
int cat;
int cow;
} too;
printf("%d\n", sizeof(struct data));
return 0;
}
dog | dog | dog | dog |
---|---|---|---|
cat | cat | cat | cat |
cow | cow | cow | cow |
此时虽然定义了#pragma pack(8),但是该结构体最大的字节类型是int,所以实际是4字节对齐,最终结果是12(字节Byte).
int main()
{
struct data
{
char a;
short b;
int c;
char d;
long long e;
} too;
printf("%d\n", sizeof(struct data));
return 0;
}
注意:该表格第一列的数据为序号,并非有效数据
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|
a | null | b | b | c | c | c | c |
d | null | null | null | null | null | null | null |
e | e | e | e | e | e | e | e |
该结构体内存分布如下,
因为有long long 类型,所以是8字节对齐;
蓝色的null,说明每个类型的首位地址都是以该类型字节的倍数来定的;
也就是,char 是以1的倍数;short是2的倍数;int是以4的倍数;long long 是以8的倍数,来作为首位地址。
因此short b 要从如图所示位置,作为起始点;long long e 同样道理 ,总共需要24个内存(字节Byte)大小;
位域
struct MyStruct
{
unsigned int a : 31;
unsigned int b : 2;
unsigned int c : 31;
}s1;
struct MyStruct
{
unsigned int a : 30;
unsigned int b : 2;
unsigned int c : 31;
}s2;
int main()
{
printf("s1 = %d\n", sizeof(s1));//12
printf("s2 = %d\n", sizeof(s2));//8
return 0;
}
注意在C语言中一个int占4个字节,每个字节是8bit,总共就是32位,
在上面的示例中结构体s1中a是31位,b是2位,相加以后超过了32,
所以b需要占用下一块内存空间,b和c之间同样的关系,
最终需要3个int,结果为12。
而在s2中,a+b为32,刚好等于一个int,故可以共用一个int,
最终需要2个int,结果为8