c 中sizeof 運算子的的深入理解

2021-10-08 07:08:18 字數 4432 閱讀 2156

簡 述:c / c++中的sizeof()運算子的一些深入思考;

昨晚看到一題,雖然可以輕易得到結果,但是突然深入思考一些,這是為什麼?

#

include

#include

intmain

(int argc,

char

*ar**)

思考:這裡的sizeof("hello"),sizeof(str1),sizeof(str2),sizeof(p1),sizeof(p2)列印出來的值是多少?

下面一列表的abcdsizeof(unsigned int)sizeof(int)列印出來的值又是多少?

理解分析:

win 10 + vs2015x86模式下,執行結果如下:

上一組的結果執行和分析如下:

sizeof("hello")的值是 6, 等價於"hello\0"應在記憶體中佔 6 個位元組,且"hello"char [6]型別(由截圖可知),但為什麼不是char *const char *呢?那就不知道了,反正編譯器的規則就是這麼定的;

sizeof(str1)的值是 6, 等價於sizeof(char [6]),在記憶體中一共分配 1*6 個位元組;下標裡面的中的 6 是根據賦值語句,編譯器自己推算出來的;

sizeof(str2)的值是 100, 等價於sizeof(char [100]),在記憶體中一共分配 1*100 個位元組;

sizeof(p1)的值是 4,等價於sizeof(char *),等價於sizeof(指標)

sizeof(p2)的值是 4,等價於sizeof(const char *),等價於sizeof(指標)

下一組的結果執行和分析如下:

a的值是 10, 等價於sizeof(char [10]),在記憶體中一共分配 1*10 個位元組;

b的值在不同系統,不同編譯器上,結果是不一樣的(eg: mac10.14.6 + qtcretor5.12.8 && win10 + vs2015); 結果不一直的原因是 無法判定"123456789"+1到底應該是char [10] + int之後,應該是什麼型別?只能夠根據自己的編譯器實際決定;且還有一中觀點: 此行是在編譯時刻就已經被替換為具體的數值了,然後這一行的**也會被刪除掉,更加不會被執行,所以其 sizeof 的***是不會實現的(如sizeof(++i)其實只能夠等價於sizeof(物件(變數 i )的型別),其執行時刻在計算其值是不存在的)

注意一點即可,有乙個誤區,以前的 類似於int x1 = 3 + 'b'能夠順利進行隱式轉換,是因為知道最後應該轉換為 等式 的左側 的 int 型別;而我們這裡系統沒有 左值,故無法知道轉換為什麼型別,所以出現如下截圖,此上下文不支援;

c的值是 9,沒有什麼好講的,該函式的實現,是遇到第乙個'\0'就停止;

d的值是 8 ?(兩個不同環境都是 8,有點費解),這個不明所以;檢視原始碼 strlen() 的實現如下size_t strlen(const char *__s);,按照我的理解,應該是等價於d = strlen((const char *)("123456789"+1))的,顯示結果依舊為 8;這個結果為啥是 8, 有點費解,不過覺得沒有**的必要,也不是本文談論的重點;此行多**無意義,且這樣寫,有點 「無中生有」,「惹是生非」,「搞事情」 的感覺

sizeof(unsigned int)的值是 4,不用解釋

sizeof(int)的值是 4,不用解釋

下面是另外角度來思考此問題:

[角度 1]:

sizeof()是 返回乙個型別的在記憶體中說佔的位元組數。 是屬於運算子, 同為 運算子 的還有+-*/%等。而這個是在編譯時候就被執行,而非執行時候執行,一開始就已經是計算機被知道的。

c 標準和實際上的 編譯器 一開始就定義好了,在 32 位電腦中,int佔據 4 位元組,char佔據 1 位元組;

對於內建的基本資料型別來說,下面是很容易理解,覺得一開始就被編譯機在記憶體裡面分配了這麼多的變數:

sizeof

(int)--

> 顯示 4 位元組

sizeof

(char)--

> 顯示 1 位元組

而 對於復合資料型別來求位元組大小,其是需要根據 組合的基本資料型別 來給出實際的記憶體中所佔的位元組大小,比如自定義 類:

sizeof

(自定類)

--> 顯示 位元組對齊後的 位元組

sizeof

(陣列)

--> 顯示 符合型別的陣列 位元組

sizeof

(int[4

])--> 顯示 4

*4 位元組 // 這樣就容易理解了

[角度 2]:

[p101] 類似於都是指代 《c++ primer 中文版 第5 版》一書的頁碼

忽然發覺有點不簡單,str1是陣列型別,屬於復合型別[p101],表示式右側"hello"是什麼型別(是charchar *還是const char *呢?),其實也並不重要(雖然知道了是char [6]型別 );但是它一定是給 陣列str1賦值的;且定義的賦值寫法如此

[角度 3]:

有人自己使用如下兩個巨集,來實現了該sizeof()的實現;注意的是,這是網友自己使用巨集來實現的,而非 編譯器 就是這樣實現的,但是對於我的理解有所幫助;

//適用於非陣列

#define

_sizeof

(t)(

(size_t)

((t*)0

+1))

//適用於陣列

#define

array_sizeof

(t)(

(size_t)

(&t+1)

-(size_t)

(&t)

)

[角度 4]:

sizeof運算子,實際上有兩種使用方式,且書上明確有說sizeof實際上並不會去計算其運算子物件的值 [p139]sizeof運算時候,也不會將數組成指標來處理;

sizeof

(type)

// 返回 型別 在記憶體中所佔的位元組大小

sizeof expression // 返回 表示式結果的 型別 在記憶體中所佔的位元組大小

c 中的sizeof 運算子

sizeof是乙個操作符 operator 其作用是返回乙個物件或型別所佔的記憶體位元組數。sizeof有三種語法形式 1 sizeof object sizeof 物件 2 sizeof object sizeof 物件 3 sizeof type name sizeof 型別 物件可以是各種型別...

C語言 sizeof 運算子

今天看了一篇文章叫 c c 刁鑽問題各個擊破之細說sizeof 然後自己想寫一寫。sizeof的作用 1.求基本型別和復合型別所佔的記憶體位元組數 如 sizeof int sizeof int 2.求某個變數或者常量所佔的記憶體位元組數 如 int i sizeof i sizeof 5 size...

c語言中的sizeof運算子

sizeof運算子在編譯期間執行 除非運算元是乙個可變長度陣列 所以不會導致執行時開銷 sizeof運算元是乙個陣列名時返回的是該陣列所佔位元組總個數,而非陣列元素。sizeof運算子求陣列長度 int a 5 sizeof a sizeof a 0 sizeof運算子的運算元只有是乙個真實的陣列名...