詳解sizeof與strlen

由以下幾個例子我們說明sizeof和strlen之間的區別: 

(1) 
char* ss ="0123456789"; 
sizeof(ss)爲4, ss是指向字符串常量的字符指針 
strlen(*ss)爲1,*ss是第一個字符 
(2) 
char ss[] = "0123456789"; 
sizeof(ss)爲11, ss是數組,計算到'\0'的位置,因此是(10+1) 
sizeof(*ss)爲1,*ss是第一個字符 
(3) 
char ss[100] = "0123456789"; 
sizeof(ss)爲100,ss表示在內存中預分配的大小,100*1。 
strlen(ss)爲10, 它的內部實現是用一個循環計算字符串的長度,直到'\0'爲止。 
(4) 
int ss[100]="0123456789"; 
sizeof(ss)爲400,ss表示在內存中的大小,100*4。 
strlen(ss)錯誤,strlen的參數只能是char*,且必須是以'\0'結尾的。 
(5) 
class X 

int i; 
int j; 
char k; 
}; 

X x; 
cout<<sizeof(X)<<endl; //結果爲12, 內存補齊 
cout<<sizeof(x)<<endl; //結果爲12 


兩者的區別:

(1) sizeof操作符的結果類型是size_t,它在頭文件 中的typedef爲unsinged 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 
int b = sizeof(str); //而b=20 
(6) strlen的結果要在運行的時候才能計算出來。用來計算字符串的長度,而不是類型佔用內存的大小。 
(7) sizeof後如果是類型必須加括號,如果是變量名可以不加括號,這是因爲sizeof是個操作符而不是個函數。 
(8)當使用了一個結構類型或變量時,sizeof返回實際的大小。當使用一靜態的空間數組時,sizeof返回全部數組的尺寸。sizeof操作符不能返回被動態分配的數組或外部的數組的尺寸。 
(9) 數組作爲參數傳給函數時傳的是指針而不是數組,傳遞的是數組的首地址,如:fun(char[8])、fun(char[])都等價於 fun(char*)。在C++裏傳遞數組永遠都是傳遞指向數組首元素的指針,編譯器不知道數組的大小。如果在函數內知道數組的大小,需要這樣做:進入函 數後用memcpy將數組拷貝出來,長度由另一個形參傳進去。代碼如下: 
fun(unsigned char*p1, int len) 

unsigned char *buf = new unsigned char[len+1]; 
memcpy(buf, p1, len); 


(10) 計算結構變量的大小就必須討論數據對齊問題。爲了使CPU存取的首都最快(這同CPU取數操作有關,詳細的介紹可以參考計算機組成原理),C++在處理數 據時經常把結構變量中的成員的大小按照4或8的倍數計算,這就叫數據對齊(data alignment)。這樣做可能會浪費一些內存,但在理論上CPU速度快了。當然,這樣的設置會在讀寫一些別的應用程序生成的數據文件或交換數據時帶來 不便。MS VC++中的對齊設定,有時候sizeof得到的實際不等。一般在VC++中加上#program pack(n)的設定即可。或者如果要按字節存儲,而不進行數據對齊,可以在Options對話框中修改Advanced Compiler選項卡中的"Data Alginment"爲按字節對齊。 
(11)sizeof操作符不能用於函數類型、不完全類型或位字段。不完全類型指具有位置存儲大小數據的數據類型嗯,如未知存儲大小的數組類型嗯,未知內容的結構或聯合類型,void類型等。 
5. 說明sizeof的使用場合 
(1)sizeof操作符的一個主要用途是與存儲分配和I/0系統那樣的例程進行通信。例如: 
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給出其指針的大小。 
6. How many bytes will be occupied for the variable (definition: int **a[3][4])? 
A. 64   B.12    C.48   D.128 
答案:C 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章