C語言拾遺 C語言關鍵字 sizeof

2021-09-25 02:31:32 字數 3480 閱讀 1622

摘要:sizeof是c語言中保留關鍵字,也可以認為是一種運算子,單目運算子。用於計算物件所佔的位元組數,通常用來檢視變數、陣列或結構體等所佔位元組個數的操作運算子。

sizeof是c/c++中的乙個操作符(operator),簡單的說其作用就是返回乙個物件或者型別所佔的記憶體位元組數。

msdn上的解釋為:

the sizeof keyword gives the amount of storage, in bytes, associated with a variable or a type(including aggregate types). this keyword returns a value of type size_t.

其返回值型別為size_t,在標頭檔案stddef.h中定義。這是乙個依賴於編譯系統的值,一般定義為

typedef unsigned int size_t;
sizeof一般有以下兩種語法形式:

sizeof(type_name);//sizeof(型別);

sizeof object; //sizeof物件;

所以

int i;

sizeof(i);//ok

sizeof i;//ok

sizeof(int);//ok

sizeof int;//error

sizeof計算物件的大小也是轉換成對物件型別的計算,也就是說,同種型別的不同物件其sizeof值都是一致的。sizeof對乙個表示式求值,編譯器根據表示式的最終結果型別來確定大小,一般不會對表示式進行計算。如:

sizeof(2);//2的型別為int,所以等價於sizeof(int);

sizeof(2+3.14);的型別為double,2也會被提公升成double型別,所以等價於sizeof(double);

sizeof的計算發生在編譯時刻,所以它可以被當作常量表示式使用,如:

char ary[sizeof(int)*10];//ok
最新的c99標準規定sizeof也可以在執行時刻進行計算,如下面的程式在dev-c++中可以正確執行:

int n;

n=10;//n動態賦值

char ary[n];//c99也支援陣列的動態定義

printf("%d\n",sizeof(ary));//ok.輸出10

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

基本資料型別的sizeof

這裡的基本資料型別指short、int、long、float、double這樣的簡單內建資料型別,由於它們都是和系統相關的,所以在不同的系統下取值可能不同,這務必引起我們的注意,盡量不要在這方面給自己程式的移植造成麻煩。一般的,在32位編譯環境中,sizeof(int)的取值為4。

指標變數的sizeof

學過資料結構的你應該知道指標是乙個很重要的概念,它記錄了另乙個物件的位址。在32位計算機中,乙個指標變數的返回值通常是4(注意結果是以位元組為單位),在64位系統中指標變數的sizeof通常為8。

char*pc="abc";

int*pi;

string*ps;

char**ppc=&pc;

void(*pf)();//函式指標

sizeof(pc);//結果為4

sizeof(pi);//結果為4

sizeof(ps);//結果為4

sizeof(ppc);//結果為4

sizeof(pf);//結果為4

指標變數的sizeof值與指標所指的物件沒有任何關係,正是由於所有的指標變數所佔記憶體大小相等,所以mfc訊息處理函式使用兩個引數wparam、lparam就能傳遞各種複雜的訊息結構(使用指向結構體的指標)。

陣列的sizeof

陣列的sizeof值等於陣列所占用的記憶體位元組數,如:

char a1 = "abc"; 

int a2[3];

sizeof( a1 ); // 結果為4,字元末尾還存在乙個null終止符

sizeof( a2 ); // 結果為3*4=12(依賴於int)

一些朋友剛開始時把sizeof當作了求陣列元素的個數,如今你應該知道這是不對的,那麼應該怎麼求陣列元素的個數呢,通常有下面兩種寫法:

int c1=sizeof(a1)/sizeof(char);//總長度/單個元素的長度  char型

int c2=sizeof(a2)/sizeof(a2[0]);//總長度/第乙個元素的長度 int型

寫到這裡,提一問,下面的c3,c4值應該是多少呢

void foo3(char a3[3])

void foo4(char a4)

也許當你試圖回答c4的值時已經意識到c3答錯了,是的,c3!=3。這裡函式引數a3已不再是陣列型別,而是蛻變成指標,相當於char* a3,為什麼仔細想想就不難明白,我們呼叫函式foo3時,程式會在棧上分配乙個大小為3的陣列嗎不會!陣列是「傳址」的,呼叫者只需將實參的位址傳遞過去,所以a3自然為指標型別(char*),c3的值也就為4。

結構體的sizeof

求結構體的sizeof要注意記憶體對齊,這裡不做過多說明,可參考這裡。

聯合體的sizeof

結構體在記憶體組織上是順序式的,聯合體則是重疊式,各成員共享一段記憶體,所以整個聯合體的sizeof也就是每個成員sizeof的最大值的對齊結果。結構體的成員也可以是復合型別,這裡,復合型別成員是被作為整體考慮的。

所以,下面例子中,u的sizeof值等於sizeof(s)。

union u

;

函式的sizeof

sizeof也可以對乙個函式呼叫求值,其結果是函式返回型別的大小,函式並不會被呼叫,我們來看乙個完整的例子:

char foo()

int main()

c99標準規定,函式、不能確定型別的表示式以及位域(bit-field)成員不能被計算sizeof值,即下面這些寫法都是錯誤的:

sizeof(foo);//error

void foo2(){}

sizeof(foo2());//error

struct s

;sizeof(s.f1);//error

C語言拾遺 C語言關鍵字 for

摘要 除了while迴圈,c語言中還有 for 迴圈,它的使用更加靈活,完全可以取代while迴圈。for 語句的一般形式為 for 表示式1 表示式2 表示式3 它的執行過程如下圖 for 迴圈中的 表示式1 初始化條件 表示式2 迴圈條件 和 表示式3 自增或自減 都是可選項。這三個表示式,可以...

C語言拾遺 C語言關鍵字 extern

摘要 extern是c語言中四個儲存型別關鍵字之一,可修飾全域性變數和函式。乙個工程可以包含若干個原始檔,乙個原始檔可以包含若干個函式,定義在函式外的變數被稱為全域性變數。全域性變數可以為本檔案中的其他函式所共用,它的有效範圍為從定義變數的位置開始到本原始檔結束。如果乙個不在該全域性變數有效範圍內 ...

C語言拾遺 C語言關鍵字 register

摘要 register是c語言中四個儲存型別關鍵字之一,用register宣告的變數是暫存器變數。由於cpu對暫存器的訪問速度遠大於對記憶體的訪問速度,所以把一些頻繁被使用的變數宣告為暫存器變數會提高 的執行速度。但有一些問題需要注意。注意 早期的c編譯程式不會把變數儲存在暫存器中,除非你命令它這樣...