C 筆記(5) 關於sizeof運算子

2021-09-26 13:50:16 字數 4869 閱讀 9887

注:參考自《王道程式設計師求職寶典》。

sizeof是乙個單目運算子,並不是乙個函式。sizeof用來計算運算元在記憶體中所佔的位元組數。sizeof的計算發生在編譯時,所以它可以被當作常量表示式使用,需要注意的是,它會忽略括號內的各種運算,如sizeof(a++);中的++就不會被執行。

sizeof的返回型別為size_t,它被定義為unsigned int 型別。

sizeof的使用形式有兩種:1)sizeof(var);2)sizeof var

3.1 sizeof(內建變數)

在32位環境中,有

sizeof

(int):

4sizeof

(short):

2sizeof

(long):

4sizeof

(float):

4sizeof

(double):

8sizeof

(char):

1sizeof

(p):

4(p為指標, 64位環境下為8

)

3.2 sizeof(函式)

sizeof可以對乙個函式呼叫求值,其結果為函式返回型別的大小。函式並不會被呼叫

#include

char

foo(

)int

main()

執行結果為:1。未列印"func has been called."。

【注】在對函式求sizeof時,需要注意的是,函式名不能確定型別的表示式以及位域成員不能被計算sizeof。

如:

int

foo(

)sizeof

(foo)

;

錯誤。函式名不能被計算sizeof。

void

foo(

)sizeof

(foo()

);

錯誤。不能確定型別的表示式 不能被計算sizeof。

struct s

;sizeof

(s.f1)

;

錯誤。位域成員不能被計算sizeof。

3.3 sizeof(指標)

sizeof(指標)在32位系統下結果為4,在64位系統下結果為8。

int

* p;

sizeof

(p)為4。

3.4 sizeof(引用)

引用變數的sizeof等同於被引用物件的sizeof。

int a[6]

=;int(

&p)[6]

= a;

sizeof

(p)為24。

3.5 sizeof(漢字)

windows環境下乙個漢字佔兩個位元組。linux環境下當使用utf-8編碼,每個漢字用3個位元組表示。

sizeof

("abc漢字"

)為8。

3.6 sizeof(陣列)

sizeof直接計算陣列所佔的位元組大小。

int a[10]

;char b=

"hello"

;sizeof

(a)為40, sizeof

(b)為6。

【注】陣列作為形參或者陣列是動態分配時,陣列名當作指標使用。

void

fun1

(char a1[3]

)void

fun2

(char a2)

int* b = new int[10

];sizeof

(b)為4。

3.7 sizeof(struct)

struct的空間計算較為複雜,總體上遵循兩個原則:

1)整體空間是占用空間最大的成員(的型別)所佔位元組數的整數倍,但在32位linux+gcc環境下,若最大成員型別所佔位元組數超過4,如double是8,則整體空間是4的倍數即可。

2)資料對齊原則——記憶體按結構體成員的先後順序排列,當排到該成員變數時,其前面已擺放的空間大小必須是該成員型別大小的整數倍,如果不夠則補齊,依次向後類推,但在linux+gcc環境下,若某成員型別所佔位元組數超過4,如double是8,則前面已擺放的空間大小是4的整數倍即可,不夠則補齊。

struct s1

;struct s2

;sizeof

(s1)為24,sizeof

(s2)為16。

3.7.1 結構體中包含結構體

兩個原則應修改為:

1)整體空間是子結構體與父結構體中占用空間最大的成員(的型別)所佔位元組數的整數倍;但在linux+gcc環境下,若最大成員型別所佔位元組數超過4,如double是8,則整體空間是4的倍數即可。

2)資料對齊原則——父結構體內存按結構體成員的先後順序排列,當排到子結構體成員時,其前面已擺放的空間大小必須是該子結構體成員中最大型別大小的整數倍,如果不夠則補齊,依次向後類推。但在linux+gcc環境下,若某成員型別所佔位元組數超過4,如double是8,則前面已擺放的空間大小是4的整數倍即可,不夠則補齊。

struct s1

;struct s2

;sizeof

(s2)為16。

3.7.2 結構體中包含陣列

在結構體中,陣列是按照單個變數乙個乙個進行擺放,而不是視為整體。

struct s

;sizeof

(s)為8。

3.7.3 結構體中含位域

前面有提到位域成員不能單獨計算sizeof值,不過我們這裡要討論的是含有位域的結構體的sizeof值。

大致規則為:

1)如果相鄰位域字段的型別相同,且其位寬之和小於型別的sizeof大小,則後面的字段將緊鄰前乙個字段儲存,知道不能容納為止;

2)如果相鄰位域字段的型別相同,但其位寬之和大於型別的sizeof大小,則後面的字段將從新的儲存單元開始,其偏移量位其型別大小的整數倍;

3)如果相鄰位域字段的型別不同,不同的編譯器具有不同的實現方式,vc6採取不壓縮方式,dev-c++與gcc採取壓縮方式;

4)如果相鄰位域字段之間穿插著非位域字段,則不進行壓縮;

5)整個結構體的總大小為最寬基本型別成員大小的整數倍。

struct s1

;struct s2

;struct s3

;sizeof

(s1)在windows+dev-c++下為4,在windows+vc6下為8。

sizeof

(s2)為2,因為1byte=

8bit,而f1+f2=

7bit,f3+

7>

8bit,因此f3需要從下乙個位元組開始儲存。

sizeof

(s3)為3。

3.7.4 使用「#pragma pack」

#pragma pack(n):編譯器將按照n個位元組對齊;

#pragma pack():取消自定義位元組對齊方式。

以上兩種指令通常應搭配使用。

3.7.5 空結構體

「空結構體」(不含資料成員)的大小不為0,而是1。因為「空結構體」也需要被儲存,以便當存在多個空結構體時便於區分和取位址,編譯器就只能分配乙個位元組的空間儲存。

3.8 sizeof(union)

union的sizeof即為每個成員sizeof值中的最大值

struct s

;union u

;sizeof

(u)為8。

3.9 sizeof(enum)

enum只是定義了乙個常量集合,裡面沒有「元素」,而列舉型別是當作int型別儲存的,故列舉型別的sizeof值都為4

struct w1

;enum day

;} w1;

struct w2

today;

enum day now;

} w2;

sizeof

(w1)為1,因為w為空結構體。

sizeof

(w1:

:week)為4,sizeof

(w::day)為4。

sizeof

(w2)為8。

我們知道c/c++中所有的字串常量都會有編譯器自動在末尾新增乙個空字元』\0』。

char ch1=

;char ch2=

;

對於以上兩個字串分別求得sizeof(ch1)=3, sizeof(ch2)=4,而strlen(ch1)結果未知, strlen(ch2)=3

【注】sizeof("\0")=2

關於sizeof運算子

1 sizeof運算子 sizeof是乙個特殊的運算子,它有兩種形式 sizeof 表示式和sizeof 型別名 對於sizeof運算子要注意幾點 1 如果是表示式的話,括號可以省略,但是對於型別,括號不能省 2 sizeof求算的是所佔的空間,如果作用於表示式,這個表示式是不進行求值的,只根據型別...

C語言 sizeof 運算子

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

關於C語言sizeof運算子和strlen 函式

c primer plus總結 1.不同點 sizeof運算子是以位元組為單位返回運算子物件的大小 strlen 函式給出字串中的字元長度 2.相同點 sizeof運算子和strlen 函式返回型別可以用 zd轉換 不識別 zd,嘗試換成 u或者 lu sizeof運算子和strlen 函式返回的實...