C++ sizeof的使用總結

說明:以下代碼在VS2008中通過,在32位操作系統下。

1.      定義

sizeof是一個操作符(operator)。

其作用是返回一個對象或類型所佔的內存字節數。

其返回值類型爲size_t。(size_t在頭文件stddef.h中定義,它依賴於編譯系統的值,一般定義爲 typedef unsigned int size_t;

2.      語法

sizeof有三種語法形式:

1)  sizeof (object);  //sizeof (對象)

2)  sizeof object;   //sizeof 對象

3)  sizeof (type_name);  //sizeof (類型)

對象可以是各種類型的變量,以及表達式(一般sizeof不會對表達式進行計算)。

sizeof對對象求內存大小,最終都是轉換爲對對象的數據類型進行求值。

sizeof (表達式); //值爲表達式的最終結果的數據類型的大小

 

例子:(32位機器下)

 

  

最新的C99標準規定sizeof也可以在運行時刻進行計算。

如下面的程序在Dev-C++中可以正確執行:

但在沒有完全實現C99標準的編譯器中就行不通了,上面的代碼在VC6中就通不過編譯。所以我們最好還是認爲sizeof是在編譯期執行的,這樣不會帶來錯誤,讓程序的可移植性強些。

1.      基本數據類型的sizeof

這裏的基本數據類型是指shortintlongfloatdouble這樣的簡單內置數據類型。

由於它們的內存大小是和系統相關的,所以在不同的系統下取值可能不同。

2.      結構體的sizeof

結構體的sizeof涉及到字節對齊問題。

爲什麼需要字節對齊?計算機組成原理教導我們這樣有助於加快計算機的取數速度,否則就得多花指令週期了。爲此,編譯器默認會對結構體進行處理(實際上其它地方的數據變量也是如此),讓寬度爲2的基本數據類型(short等)都位於能被2整除的地址上,讓寬度爲4的基本數據類型(int等)都位於能被4整除的地址上,依次類推。這樣,兩個數中間就可能需要加入填充字節,所以整個結構體的sizeof值就增長了。

字節對齊的細節和編譯器的實現相關,但一般而言,滿足三個準則:

1)  結構體變量的首地址能夠被其最寬基本類型成員的大小所整除。

2)  結構體的每個成員相對於結構體首地址的偏移量(offset)都是成員大小的整數倍,如有需要,編譯器會在成員之間加上填充字節(internal adding)。

3)  結構體的總大小爲結構體最寬基本類型成員大小的整數倍,如有需要,編譯器會在最末一個成員後加上填充字節(trailing padding)。

    注意:空結構體(不含數據成員)的sizeof值爲1。試想一個“不佔空間“的變量如何被取地址、兩個不同的“空結構體”變量又如何得以區分呢,於是,“空結構體”變量也得被存儲,這樣編譯器也就只能爲其分配一個字節的空間用於佔位了。

例子:

3.      聯合體的sizeof

結構體在內存組織上市順序式的,聯合體則是重疊式,各成員共享一段內存;所以整個聯合體的sizeof也就是每個成員sizeof的最大值。

例子:

4.      數組的sizeof

數組的sizeof值等於數組所佔用的內存字節數。

注意:1)當字符數組表示字符串時,其sizeof值將’/0’計算進去。

            2)當數組爲形參時,其sizeof值相當於指針的sizeof值。 

例子1

例子2:

5.      指針的sizeof

指針是用來記錄另一個對象的地址,所以指針的內存大小當然就等於計算機內部地址總線的寬度。

32位計算機中,一個指針變量的返回值必定是4

指針變量的sizeof值與指針所指的對象沒有任何關係。

      例子:

  

6.      函數的sizeof

sizeof也可對一個函數調用求值,其結果是函數返回值類型的大小,函數並不會被調用。

對函數求值的形式:sizeof(函數名(實參表))

注意:1)不可以對返回值類型爲空的函數求值。 

            2)不可以對函數名求值。

           3)對有參數的函數,在用sizeof時,須寫上實參表。

      例子:

  

發佈了54 篇原創文章 · 獲贊 64 · 訪問量 74萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章