sizeof是一個操做符,返回一條表達式或一個類型名字所佔的字節數。返回值一個常量表達式,類型爲size_t。ios
size_t sizeof(type)數組
size_t sizeof expr安全
在sizeof的運算對象中解引用一個無效指針仍然是一種安全的行爲,由於指針實際上並無被真正使用,sizeof並不須要真的解引用指針也能知道它所指對象的類型。函數
sizeof對C++的全部內置類型求其所佔空間的大小:測試
環境:win7 64-bits, Code::Blocks 16.01, GUN GCC Compiler with C++11 ISO Standardspa
Type操作系統 |
Number of bytes指針 |
boolcode |
1對象 |
char |
1 |
wchar_t |
2 |
char16_t |
2 |
char32_t |
4 |
short |
2 |
int |
4 |
long |
4 |
long long |
8 |
float |
4 |
double |
8 |
long double |
12 |
std::string |
4 |
1. sizeof對數組
傳入數組頭指針,返回每一個元素所佔的字節數乘以數組的長度。
2. sizeof對C風格字符串
傳入頭指針,返回的是字符串長度加上末尾結束符’\0’的總長度。
C風格字符串有兩種,一種是指針形式:const char* s = 「hello」; 將s傳入給sizeof,會認爲s爲一個指針,返回的是指針所佔的字節數。
另外一種是數組形式:const char c_str[] = 「hello」; 將頭指針c_str傳給sizeof,是按數組形式的計算所佔字節數,返回的是字符串長度加上末尾結束符的總長度。
3. sizeof對指針
傳入任意類型的指針,返回值由計算機內存地址總線的寬度決定,32-bits的操做系統返回4,64-bits的操做系統返回8。
4. sizeof對結構體(類)
空的結構體(沒有任何成員),返回1,表示僅含佔位符;當要構造一個結構體(類)對象時,首先找出所佔字節數最長的數據成員,好比是設爲x,而後根據全部成員的所佔字節數的總和來計算,所申請的字節數最少n個x就能保存完全部數據,則實際對象所佔內存字節數爲n*x;而且數據成員儲存的順序是根據在結構體內聲明的順序來儲存的;對於含有虛函數的結構體(類),其額外包括一個成員——指向虛函數表的虛表指針,在32位的機器上,佔4個字節,在64位的機器上,佔8個字節,同時也會根據其它數據成員補齊。另外,不考慮函數成員所佔的內存,函數成員會儲存在代碼區,而不是棧區,因此不考慮。
#include <iostream> using std::cout; using std::cin; using std::endl; struct A { int a1; short a2; char a3; }; struct B { char b1; int b2; int b3; double b4; }; struct C { char c1; virtual void fun() {} }; int main() { A a; cout << sizeof(a) << endl; //輸出8 //最長int爲4,2*4 >= 4 + 2 + 1 //前4個字節儲存a1,緊跟着2個字節儲存a2,再緊跟着1個字節儲存a3 //後面還有1個字節爲空,什麼也不儲存 cout << &a.a1 << " " << &a.a2 << " " << &a.a3 << endl; B b; cout << sizeof(b) << endl; //輸出24 C c; cout << sizeof(c) << endl; //輸出8 return 0; }
5. sizeof對聯合體(union)
union在內存中儲存是層疊式的,各成員共享一段內存,所以返回的是所佔字節數最長的成員的字節數。例如最長的成員爲double,其它不管還有多少個成員且任意小於double的類型,返回的值均爲8。
6. sizeof對函數
sizeof對函數操做其實是求其返回值類型所佔的字節數。求值時必須完整地寫出函數調用的形式,但並不實際調用函數。
示例程序:
//測試C++中的sizeof() #include <iostream> using std::cout; using std::cin; using std::endl; size_t getPtrSize(char* cptr) { return sizeof(cptr); } struct NoMember { }; struct S_int_char { char c; int i; }; struct S_int_short { short s; //sizeof(short) == 2 int i; }; struct S_int_func { int i; double ret_i() //不考慮 { return i; } }; struct S_ONLY_func { double func() { return 0; } }; //聯合體 union my_u { int a; float b; double c; char d; }; //函數 short func_short() { return 0; } float func_float(int a, int b) { return 1.1; } int main() { //C風格字符串的測試 char c_str[] = "Hello!"; cout << sizeof(char) << " " << sizeof(c_str) << " " << getPtrSize(c_str) << endl; //數組測試 double d_arr[20]; cout << sizeof(d_arr) << endl; //返回值爲80,4*10 == 80 //指針的測試 char* p; cout << sizeof(p) << endl; //返回值是4,由計算機內存地址總線的寬度決定 //與所指對象無關 //結構體的sizeof測試 NoMember nm; cout << sizeof(nm) << endl; S_int_char sic; cout << sizeof(sic) << endl; //int是4,char是1, //爲了c與i的空間對齊,對c日後相鄰的3個內存加入填充字節 //是空間對齊,則總的空間爲i的4加上c的4,獲得8 S_int_short sis; cout << sizeof(sis) << endl; //一樣須要內存對齊,返回的也是8 S_int_func sif; cout << sizeof(sif) << endl; //返回值爲4,不考慮成員函數所佔的空間 S_ONLY_func sof; cout << sizeof(sof) << endl; //返回值爲1,不考慮成員函數所佔的空間 //聯合體的測試 my_u u; cout << sizeof(u) << endl; //返回值爲最大的成員所佔空間長度,最大爲double,返回8 //函數的測試 cout << sizeof(func_short()) << endl; cout << sizeof(func_float(1, 2)) << endl; return 0; }
strlen函數定義在頭文件cstring.h中,用於計算字符串的長度,但空字符’\0’不計算在內。參數爲C風格字符串的頭指針,返回值是字符串的長度,空字符不計算在內。計算原理是順着頭指針向後找,直到遇到空字符才停下來。注意,若是字符數組沒有以空字符結尾,調用strlen()函數可能產生重大錯誤,由於會不斷向前找直到遇到空字符。例如:
char ca[] = {‘a’, ‘b’, ‘c’}; //不以空字符結束 cout << strlen(ca) << endl; //嚴重錯誤
示例程序:
#include <iostream> #include <cstring> int main() { //騰訊實習軟開 2016-04-03 const char* s = "hello tencent.\0"; const char c_str[] = "hello tencent.\0"; cout << sizeof(s) << " " << strlen(s) << " " << sizeof(c_str) << endl; return 0; }
測試輸出: