最近經常被問道sizeof和strlen的區別,所以現在來總結一下:
1、sizeof是運算符,而strlen是函數。運算符是內置於語言的,函數是所帶的庫裏面的。當然是前者的效率要高一些,不存在函數調用。本質上,運算符應該也算是函數,從運算符重載中可以看出來。
2、sizeof操作符的結果類型是size_t,他在頭文件的typedef爲unsigned int類型,該類型保證能容納實現所建立的最大對象的字節大小。
3、sizeof可以用類型做參數,strlen只能用char*做參數,且必須是以“\0”結尾的,sizeof還可以用函數做參數,此時,以函數的返回類型作爲sizeof的實際參數。
4、數組做sizeof的參數時不退化,傳遞給strlen時就退化爲指針。
5、大部分編譯程序在編譯的時候把sizeof計算過了,是類型或是變量的長度,這就是sizeof(x)可以用來定義數組維數的原因。而strlen的結果要在運行時才能計算出來,用來計算字符串的長度,而不是類型佔內存的大小。
例如:如下代碼能正常通過編譯:
<span style="font-size:18px;">char arrays[sizeof(array)];
cout << sizeof(arrays) << endl;</span>
輸出結果如下:
而如下的寫法將不同能通過編譯:
<span style="font-size:18px;">char arrays[strlen(array)];</span>
編譯器將提示:表達式必須含有常量值。
6、sizeof後如果是類型必須加括號,如果是變量名可以不加括號,這是因爲sizeof是操作符而不是函數。
如下代碼將可以通過編譯:
<span style="font-size:18px;">int b = 0;
cout << sizeof b << endl;</span>
執行結果如下:
而
<span style="font-size:18px;">cout << strlen array << endl;</span>
將提示編譯錯誤。7、當使用了結構類型或者變量時,sizeof返回實際的大小,當使用一靜態的空間數組時,sizeof返回全部數組的大小,sizeof操作符不能返回被動態分配的數組或外部的數組的尺寸。如下代碼的返回結果是4,即將數組作爲指針處理。
<span style="font-size:18px;">int * array = new int[100];
cout << sizeof(array) << endl;</span>
8、sizeof操作符不能用於函數類型、不完全類型、或位字段。不完全類型指具有未知存儲大小的數據類型,未知存儲大小的數組類型、未知內容的結構或者聯合類型。
9、sizeof(表達式),表達式中的內容不會被執行。如
<span style="font-size:18px;">int b = 0;
cout << sizeof(b = 7) << endl;
cout << b << endl;</span>
上邊的語句執行完之後,b的值仍然是0,結果如下圖。
10、sizeof計算棧中分配的大小,不計算全局數據區中分配的大小。(2015/08/30補充)
定義如下的一個結構體Mystruct和MyClass;
struct MyStruct
{
static int a;
double b;
};
class MyClass
{
public:
MyClass();
~MyClass();
public:
int a;
static int b;
private:
};
使用sizeof的輸出結果如圖:
由上圖可知,sizeof在計算是並沒有將static分配的內存計算在內。