對於乙個結構體型別,可以利用sizeof來計算它的大小。可是我們發現,當結構體中成員的順序不同時,所計算出它的大小也不相同。接下來,我們來詳細討論其不同型別的大小。首先看如下例子:
《一》
#include struct s1 //按成員中最大的int型別對齊:4位元組
;struct s2
;struct s //按成員中最大的double型別對齊:8位元組
;void main()
可以看到
struct s1
和struct s2
中僅僅是成員之間的順序發生改變,但其結構體大小分別是12和
8。為了說明這一現象,我們先來了解一下偏移量和記憶體對齊,了解這些之後我們才能更好的明白作業系統是如何計算結構體的大小。首先,偏移量是指把儲存單元的實際位址與其所在段的段位址之間的距離,就是相對於起始位址的偏移量;記憶體對齊即編譯器為程式中的每個
「資料單元」安排在適當的位置上,記憶體對齊是為了訪問資料的時候速率的提公升,是用空間來換時間。關於記憶體對齊有如下規則: 1.
資料型別自身的對齊值:對於
char
型資料,其自身對齊值為
1,對於
short型為2
,對於int,float,double
型別,其自身對齊值為
4,單位位元組。
2.結構體或者類的自身對齊值:其成員中自身對齊值最大的那個值。 3.
指定對齊值:
#pragma pack (value)
時的指定對齊值
value,其中#
為預編譯指令。 4.
資料成員、結構體和類的有效對齊值:自身對齊值和指定對齊值中小的那個值。 並且
1.結構體變數中成員的偏移量必須是成員大小的整數倍(0被認為是任何數的整數倍);
2.結構體大小必須是所有成員大小的整數倍。
原則1中所說
成員的偏移量必須是成員大小的整數倍,
表明struct
s1中ch1偏移量為0,i偏移量為4,ch2偏移量為8
;struct
s2中ch1偏移量為0,ch2偏移量為1,ch2偏移量為4;
我們可以發現
結構體大小必須是所有成員大小的整數倍,且自身對齊值為成員中自身對齊值最大的那個值,所以上述
struct s1以及
struct s2均以4個位元組為單位對齊,且結構體大小是1和4的整數倍。由偏移量以及對齊方式可知兩者對於成員的存放是不一樣的,因此引起結構體大小的不同。
《二》指定對齊值
#include /*
#pragma pack(100); //自身對齊大小為double型別:8位元組;指定對齊方式:100位元組
struct s
;void main()
#pragma pack(2); //按2對齊,且為每個成員的倍數,故為10
struct s
;void main()
*/#pragma pack(5); //按5對齊,且為每個成員的倍數,故為16
struct s
;void main()
由以上分析可知:
結構體的有效對齊值為自身對齊值和指定對齊值中小的那個值。(對齊規則4)
指定對齊大小 < 自身對齊大小 以指定對齊大小為準
指定對齊大小 > 自身對齊大小 以自身對齊大小為準
《三》結構體套結構體(以結構體中最大的成員型別去對齊)
#include //結構體套結構體 以結構體中最大的成員型別去對齊
struct s1
;}; //sizeof:24(用最大的成員型別double去對齊,即8位元組對齊)
//並不是將子struct型別作為最大的成員型別16對齊,所以不是32
struct s2
;}; //sizeof:12(用最大的成員型別int去對齊,即4位元組對齊)
void main()
《四》結構體套聯合體
(1)無陣列
#include //結構體套聯合體(聯合體共用乙個空間,大小為其成員最大的型別)
struct s1
;}; //sizeof:8
struct s2
;}; //sizeof:16
void main()
(2)聯合體中成員有陣列#include //結構體套聯合體(聯合體中有陣列,按聯合體之外的最大型別對齊)
struct s1
;}; //按int型別對齊 sizeof:16
struct s2
x;}; //按char型別對齊 sizeof:11
void main()
計算結構體大小
運算子sizeof可以計算出給定型別的大小,對於32位系統來說,sizeof char 1 sizeof int 4。基本資料型別的大小很好計算,我們來看一下如何計算構造資料型別的大小。c語言中的構造資料型別有三種 陣列 結構體和共用體。陣列是相同型別的元素的集合,只要會計算單個元素的大小,整個陣列...
計算結構體大小
include include include define uint32 unsigned int define uint16 unsigned short define uint8 unsigned char define bool unsigned char 位元組型別列舉 enum type...
結構體大小的計算
位元組對齊原則 結構體預設的位元組對齊一般滿足三個準則 1 結構體變數的首位址能夠被其最寬基本型別成員的大小所整除 2 結構體每個成員相對於結構體首位址的偏移量 offset 都是成員大小的整數倍,如有需要編譯器會在成員之間加上填充位元組 internal adding 3 結構體的總大小為結構體最...