(一)第一個例子:
char* ss = "0123456789";sizeof(ss) ; //結果 4 ===》ss是指向字串常量的字元指標sizeof(*ss) ; //結果 1 ===》*ss是第一個字元char ss[] = "0123456789";sizeof(ss) ; //結果 11 ===》ss是數組,計算到/0位置,因此是10+1sizeof(*ss); // 結果 1 ===》*ss是第一個字元char ss[100] = "0123456789";sizeof(ss); // 結果是100 ===》ss表示在記憶體中的大小 100×1strlen(ss); // 結果是10 ===》strlen是個函數內部實現是用一個迴圈計算到/0為止之前int ss[100] = "0123456789";sizeof(ss); //結果 400 ===》ss表示再記憶體中的大小 100×4strlen(ss); // 錯誤 ===》strlen的參數只能是char* 且必須是以''/0''結尾的char q[]="abc";char p[]="a/n";sizeof(q); //結果為4,表明自動以字串 + '/0'來結束未定義長度的字串的空間長度
strlen(q); //結果為3,表明字串長度為3
sizeof(p); //結果為3,字串由'a'+一個逸出字元(斷行符號)+'/0'組成,因此佔用的空間為3
strlen(p); //結果為2,字串實際的長度為2(不包括結束符'/0')
(二)第二個例子:
class X{int i;int j;char k;};X x;cout<<sizeof(X)<<endl; 結果 12 ===》記憶體補齊cout<<sizeof(x)<<endl; 結果 12 同上
(三)第三個例子:
char szPath[MAX_PATH]
如果在函數內這樣定義,那麼sizeof(szPath)將會是MAX_PATH,但是將szPath作為虛參聲明時(void fun(char szPath[MAX_PATH])),sizeof(szPath)卻會是4(指標大小)
三、sizeof深入理解。
- 1.sizeof操作符的結果類型是size_t,它在標頭檔中typedef為unsigned int類型。該類型保證能容納實現所建立的最大對象的位元組大小。
- 2.sizeof是算符,strlen是函數。
- 3.sizeof可以用類型做參數,strlen只能用char*做參數,且必須是以''/0''結尾的。sizeof還可以用函數做參數,比如:
short f();printf("%d/n", sizeof(f()));輸出的結果是sizeof(short),即2(函數的傳回型別的大小)。
- 4.數組做sizeof的參數不退化,傳遞給strlen就退化為指標了。
- 5.大部分編譯器 在編譯的時候就把sizeof計算過了,是類型或是變數的長度這就是sizeof(x)可以用來定義數組維數的原因
char str[20]="0123456789";int a=strlen(str); //a=10,a已經退化為指標char *strint b=sizeof(str); //而b=20,str還是代表整個數組,不會退化為指標
- 6.strlen的結果要在啟動並執行時候才能計算出來,是用來計算字串的長度,不是類型占記憶體的大小。
- 7.sizeof後如果是類型必須加括弧,如果是變數名可以不加括弧。這是因為sizeof是個操作符不是個函數。
- 8.當適用了於一個結構類型時或變數, sizeof 返回實際的大小,當適用一靜態地空間數組, sizeof 歸還全部數組的尺寸。 sizeof 操作符不能返回動態地被指派了的數組或外部的數組的尺寸
- 9.數組作為參數傳給函數時傳的是指標而不是數組,傳遞的是數組的首地址,如:
fun(char [8])fun(char [])
都等價於 fun(char *) 在C++裡傳遞數組永遠都是傳遞指向數組首元素的指標,編譯器不知道數組的大小如果想在函數內知道數組的大小, 需要這樣做:進入函數後用memcpy拷貝出來,長度由另一個形參傳進去
fun(unsiged char *p1, int len){ unsigned char* buf = new unsigned char[len+1] memcpy(buf, p1, len);}有關內容見: C++ PRIMER?
- 10.計算結構變數的大小就必須討論資料對齊問題。為了CPU存取的速度最快(這同CPU取數操作有關,詳細的介紹可以參考一些電腦原理方面的書),C++在處理資料時經常把結構變數中的成員的大小按照4或8的倍數計算,這就叫資料對齊(data alignment)。這樣做可能會浪費一些記憶體,但理論上速度快了。當然這樣的設定會在讀寫一些別的應用程式產生的資料檔案或交換資料時帶來不便。MS VC++中的對齊設定,有時候sizeof得到的與實際不等。一般在VC++中加上#pragma pack(n)的設定即可.或者如果要按位元組儲存,而不進行資料對齊,可以在Options對話方塊中修改Advanced compiler頁中的Data alignment為按位元組對齊。
- 11.sizeof操作符不能用於函數類型,不完全類型或位欄位。不完全類型指具有未知儲存大小的資料類型,如未知儲存大小的數群組類型、未知內容的結構或等位型別、void類型等。如以下的情況都是非法的:
int max(); sizeof(max); //非法,不能用於函數類型
char str[MAX]; sizeof(str); //非法,因為MAX未知,則str大小未知
sizeof(void); //非法,無類型
四、結束語
sizeof使用場合。
- 1.sizeof操作符的一個主要用途是與儲存分配和I/O系統那樣的常式進行通訊。例如:
void *malloc(size_t size), size_t fread(void * ptr,size_t size,size_t nmemb,FILE * stream)。
- 2.用它可以看看一類型的對象在記憶體中所佔的單元位元組。
void * memset(void * s,int c,sizeof(s))
- 3.在動態分配一對象時,可以讓系統知道要分配多少記憶體。
- 4.便於一些類型的擴充,在windows中就有很多結構內型就有一個專用的欄位是用來放該類型的位元組大小。
- 5.由於運算元的位元組數在實現時可能出現變化,建議在涉及到運算元位元組大小時用sizeof來代替常量計算。
- 6.如果運算元是函數中的數組形參或函數類型的形參,sizeof給出其指標的大小。
===================================================
上面的內容掌握了,擴充還可以看看以下的網頁:
http://blog.pfan.cn/wenzhuo316/19802.html
http://www.cnblogs.com/yizhu2000/archive/2008/03/20/1115426.html
http://dev.yesky.com/143/2563643.shtml