"devils are in the details."
c語言中的sizeof,在我看來,就是乙個能容納很多魔鬼、令人頭疼的細節。
在頭疼也要上,誰讓咱們是程式設計師呢。
首先要明白,sizeof是c/c++中定義的操作符,而不是函式,完成的操作是返回被運算元所占用的記憶體空間空間大小(單位是位元組)。
其次,sizeof的運算結果必須在編譯時就確定下來,因此可以視之結果為常量。最新的c99標準規定sizeof的結果也可以在執行時才確定,例如,可以在執行時在堆中動態分配乙個陣列,並用sizeof操作符求這個陣列所佔的記憶體空間。
sizeof的運算元可以是基本型別、陣列、結構、聯合、類、變數以及物件。以陣列為操作時,返回整個陣列的空間,而不是陣列元素的大小。以聯合為運算元時,結果等於其所有成員中占用空間最大者的大小。還可以以函式呼叫為運算元,例如
int foo (void) ;
void foo2(void);
sizeof
( foo() );
//合法
sizeof
( foo )
//不合法
sizeof(foo2() )
//不合法
注意上面的sizeof在計算時,並不真正的呼叫函式。
sizeof最令人疑惑的結果,就是運算元為結構的時候——這裡的主要問題是編譯器在分配空間時考慮到記憶體訪問的效率,預設情況下會通過填充無用位元組的方式來實現結構成員的位址對齊。
對齊的細節與硬體(32位or64位機器)、作業系統、編譯器實現相關。
基本的原則是:
(1).在結構中各成員按其宣告順序在記憶體中順序儲存, 第乙個成員的位址即結構的位址.
(2).整個結構的寬度是最大對齊量的整數倍, 不足的在後面補齊.
(3).結構體變數的首位址能夠被其最寬基本型別成員的大小所整除.
(4).結構體每個成員相對於結構體首位址的偏移量(offset)都是成員大小的整數倍,如有需要編譯器會在成員之間加上填充字街.
聽起來有些頭暈吧。簡單的概括起來,就是結構體的大小是最大成員(基本單元)的倍數,各個成員依次放入當前單元,無法放入當前單元的成員,為之再分配乙個單元,並用無用資料填充當前單元的剩餘空間。
因此,結構的大小不僅與成員的組成有關,還與其順序有關。
例如struct s1;
struct s2;
sizeof(a)的結果為8,而sizeof(b)的結果為12,用前面介紹的方法不難分析結果是如何得出的。
C語言 結構體宣告與sizeof計算結構體大小
1.結構體的宣告 struct 結構體名 成員表列 例如 struct student int main struct student s2 struct student s3 struct student malloc sizeof struct student scanf s d c s2.na...
c語言sizeof求結構體的大小
運算子sizeof可以計算出給定型別的大小,對於32位系統來說,sizeof char 1 sizeof int 4。基本資料型別的大小很好計算,我們來看一下如何計算構造資料型別的大小。c語言中的構造資料型別有三種 陣列 結構體和共用體。陣列是相同型別的元素的集合,只要會計算單個元素的大小,整個陣列...
c語言sizeof求結構體的大小
運算子sizeof可以計算出給定型別的大小,對於32位系統來說,sizeof char 1 sizeof int 4。基本資料型別的大小很好計算,我們來看一下如何計算構造資料型別的大小。c語言中的構造資料型別有三種 陣列 結構體和共用體。陣列是相同型別的元素的集合,只要會計算單個元素的大小,整個陣列...