C代碼中定義的結構體是一塊連續內存,各成員按照定義的順序依次在其中存放。編譯器在完成語法分析後,需要計算它的大小,然後才能正確地爲結構體分配空間。爲了讓結構體的所有成員都能正確、快速地訪問,需要字節對齊。
字節對齊體現爲:
在成員之間可能增加補齊字節,以調整每個成員的偏移;
結構體末尾,也可能增加補充字節。所有補齊字節計入結構體的大小。
我們通過以下幾個例子認識結構體大小知識:
1、
struct B
{
char a;//1+3
int b;//4
}; //8
printf("%d\n",sizeof(struct B));
因爲考慮內存對齊,此時struct B 的大小爲8。
2、
struct C
{
char a;//1+1
short b;//2
int c;//4
};//8
struct D
{
char a;//1+3
int b;//4
short c;//2
};//10+2
通過結構體C和結構體D看出,不同數據類型存放順序不同,結構體大小不同。
3、
struct A
{
int a;//4
char b;//1
};//5+3
105不能被4整除,在其末尾添加填充3字節。注意與結構體B區別。
同等情況案例:
struct H
{
char a;//1+3
int b;//4
double c;//8
int *d;//4
};//20+4
4、
struct II
{
int a;
char b;
};
struct I
{
float x;//4
//struct II y;//8
double y;
};//12 單個最大類型
結構體總的大小要是其成員中最大size的整數倍,如果不是編譯器會在其末尾添加填充字節
總結:
- 結構體第一個成員的地址和結構體的首地址相同
- 結構體每個成員地址相對於結構體首地址的偏移量(offset)是該成員大小的整數倍,如果不是則編譯器會在成員之間添加填充字節(internal adding)。
- 結構體總的大小要是其成員中最大size的整數倍,如果不是編譯器會在其末尾添加填充字節。