C語言 sizeof(struct)講解

2021-08-20 03:22:57 字數 2956 閱讀 6392

struct mystruct 

; 對結構mystruct採用sizeof會出現什麼結果呢?sizeof(mystruct)為多少呢?也許你

會這樣求: 

sizeof(mystruct)=sizeof(double)+sizeof(char)+sizeof(int)=13 

但是當在vc中測試上面結構的大小時,你會發現sizeof(mystruct)為16。你知道為什

麼在vc中會得出這樣乙個結果嗎? 

其實,這是vc對變數儲存的乙個特殊處理。為了提高cpu的儲存速度,vc對一些變數的

起始位址做了「對齊」處理。在預設情況下,vc規定各成員變數存放的起始位址相對於結

構的起始位址的偏移量必須為該變數的型別所占用的位元組數的倍數。下面列出常用型別的

對齊方式(vc6.0,32位系統)。

型別      對齊方式(變數存放的起始位址相對於結構的起始位址的偏移量) 

char      偏移量必須為sizeof(char)即1的倍數 

short     偏移量必須為sizeof(short)即2的倍數 

int         偏移量必須為sizeof(int)即4的倍數 

float      偏移量必須為sizeof(float)即4的倍數 

double   偏移量必須為sizeof(double)即8的倍數 

各成員變數在存放的時候根據在結構中出現的順序依次申請空間,同時按照上面的對

齊方式調整位置,空缺的位元組vc會自動填充。同時vc為了確保結構的大小為結構的位元組邊

界數(即該結構中占用最大空間的型別所占用的位元組數)的倍數

,所以在為最後乙個成員

變數申請空間後,還會根據需要自動填充空缺的位元組。

下面用前面的例子來說明vc到底怎麼樣來存放結構的。 

struct mystruct 

; 為上面的結構分配空間的時候,vc根據成員變數出現的順序和對齊方式,先為第乙個

成員dda1分配空間,其起始位址跟結構的起始位址相同(剛好偏移量0剛好為sizeof(doub

le)的倍數),該成員變數占用sizeof(double)=8個位元組;接下來為第二個成員dda分配空

間,這時下乙個可以分配的位址對於結構的起始位址的偏移量為8,是sizeof(char)的倍數

,所以把dda存放在偏移量為8的地方滿足對齊方式,該成員變數占用 sizeof(char)=1個字

節;接下來為第三個成員type分配空間,這時下乙個可以分配的位址對於結構的起始位址

的偏移量為9,不是sizeof (int)=4的倍數,為了滿足對齊方式對偏移量的約束問題,vc自

動填充3個位元組(這三個位元組沒有放什麼東西),這時下乙個可以分配的位址對於結構的起

始位址的偏移量為12,剛好是sizeof(int)=4的倍數,所以把type存放在偏移量為12的地方

,該成員變數占用sizeof(int)=4個位元組;這時整個結構的成員變數已經都分配了空間,總

的占用的空間大小為:8+1+3+4=16,剛好為結構的位元組邊界數(即結構中占用最大空間的

型別所占用的位元組數sizeof(double)=8)的倍數,所以沒有空缺的位元組需要填充。所以整

個結構的大小為:sizeof(mystruct)=8+1+ 3+4=16,其中有3個位元組是vc自動填充的,沒有

放任何有意義的東西。 

下面再舉個例子,交換一下上面的mystruct的成員變數的位置,使它變成下面的情況 

struct mystruct 

; 這個結構占用的空間為多大呢?在vc6.0環境下,可以得到sizeof(mystruc)為24。結

合上面提到的分配空間的一些原則,分析下vc怎麼樣為上面的結構分配空間的。(簡單說

明) struct mystruct 

;//所有成員變數都分配了空間,空間總的大小為1+7+8+4=20,不是結構 

//的節邊界數(即結構中占用最大空間的型別所占用的位元組數sizeof 

//(double)=8)的倍數,所以需要填充4個位元組,以滿足結構的大小為 

//sizeof(double)=8的倍數。 

所以該結構總的大小為:sizeof(mystruc)為1+7+8+4+4=24。其中總的有7+4=11個位元組

是vc自動填充的,沒有放任何有意義的東西。

vc對結構的儲存的特殊處理確實提高cpu儲存變數的速度,但是有時候也帶來了一些麻

煩,我們也遮蔽掉變數預設的對齊方式,自己可以設定變數的對齊方式。

vc 中提供了#pragma pack(n)來設定變數以n位元組對齊方式。n位元組對齊就是說變數存

放的起始位址的偏移量有兩種情況:第

一、如果n大於等於該變數所占用的位元組數,那麼偏

移量必須滿足預設的對齊方式,第

二、如果n小於該變數的型別所占用的位元組數,那麼偏移

量為n的倍數,不用滿足預設的對齊方式。結構的總大小也有個約束條件,分下面兩種情況

:如果n大於所有成員變數型別所占用的位元組數,那麼結構的總大小必須為占用空間最大的

變數占用的空間數的倍數; 

否則必須為n的倍數。下面舉例說明其用法。 

#pragma pack(push) //儲存對齊狀態 

#pragma pack(4)//設定為4位元組對齊 

struct test 

; #pragma pack(pop)//恢復對齊狀態

以上結構的大小為16,下面分析其儲存情況,首先為m1分配空間,其偏移量為0,滿足

我們自己設定的對齊方式(4位元組對齊),m1占用1個位元組。接著開始為 m4分配空間,這時

其偏移量為1,需要補足3個位元組,這樣使偏移量滿足為n=4的倍數(因為sizeof(double)大

於n),m4占用8個位元組。接著為m3分配空間,這時其偏移量為12,滿足為4的倍數,m3占用

4個位元組。這時已經為所有成員變數分配了空間,共分配了16個位元組,滿足為n的倍數。如

果把上面的#pragma pack(4)改為#pragma pack(16),那麼我們可以得到結構的大小為24。

C語言結構體 sizeof struct

這個內容也是很重要的乙個,所以,這裡對一些問題和規律做乙個總結。涉及到的幾個概念 記憶體對齊 現代計算機中記憶體空間都是按照byte劃分的,從理論上講似乎對任何型別的變數的訪問可以從任何位址開始,但實際情況是在訪問特定變數的時候經常在特定的記憶體位址訪問,這就需要各型別資料按照一定的規則在空間上排列...

sizeof struct 大小討論

2009 11 08 14 05 51 分類 c語言雜記 舉報 字型大小 訂閱 struct 結構大小和順序 progma pack引數有關係 針對位元組對齊,環境使用的gcc version 3.2.2編譯器 32位x86平台 為例。char 長度為1個位元組,short 長度為2個位元組,int...

sizeof struct 大小討論

struct 結構大小和順序 progma pack引數有關係 針對位元組對齊,環境使用的 gcc version 3.2.2 編譯器 32位 x86平台 為例。char 長度為1個位元組,short 長度為2個位元組,int 長度為4個位元組。struct 子項在記憶體中的按順序排列,在沒有 pr...