論及測試基礎是Windows 32位平台,VS2008開發工具: 測試基本類型 1.基本規則 sizeof 操作符的作用是返回一個對象或類型名所占的內存字節數,返回值的類型為size_t,長度的單位是字節,在編譯而不是運行時確定。 • 對引用類型做sizeof操作將返回存放此引用類型對象所需的內在空間大小。 • 對指針做sizeof操作將返回存放指針所需的內在大小;注意,如果要獲取該指針所指向對象的大小,則必須對指針進行引用。 因為 sizeof 返回整個數組在內存中的存儲長度,所以用 sizeof 數組的結果除以sizeof 其元素類型的結果,即可求出數組元素的個數: 例如: int ia[8]; int sz =sizeof(ia)/sizeof(*ia); cout << sz<< endl; //8 2.sizeof與strlen的區別和聯系? (2.1)sizeof操作符的結果類型是size_t,它在頭文件中typedef為unsigned int類型,該類型保證能容納實現所建立的最大對象的字節大小。 (2.2)sizeof是操作符,strlen是函數。sizeof後如果是類型必須加括弧,如果是變量名可以不加括弧。 (2.3) 數組名作為函數參數時,退化為指針,數組名作為sizeof()參數時,數組名不退化,因為sizeof不是函數。 (2.4)sizeof可以用類型做參數,strlen只能用char*做參數,且必須是以”\0”結尾的。 (2.5)大部分編譯程序在編譯的時候就把sizeof計算過了,這就是sizeof(x)可以用來定義數組維數的原因。strlen的結果要在運行的時候才能計算出來,是用來計算字符串的實際長度,不是類型占內存的大小。
(2.6)當作用於結構類型或變量,sizeof返回實際的大小,sizeof如用於數組,只能測出靜態數組的大小,無法檢測動態分配的或外部數組大小。 //對於靜態數組的處理: char str[11]="0123456789";//注意這裡str大小應該等於,應考慮’\0’在內,否則編譯器會報錯 cout << strlen(str) << endl;//10 strlen計算字符串的長度,以結束符x00為字符串結束。 cout << sizeof(str) << endl;//11 sizeof計算的則是分配的數組str[11]所占的內存空間的大小,不受裡面存儲的內容改變。 (2.7)數組作為參數傳給函數時傳的是指針而不是數組,傳遞的是數組的首地址,如: fun(char [8]) fun(char []) 都等價於fun(char*) void Func( char str[100]) { cout << sizeof(str) << endl; } void *p =malloc(100); cout << sizeof(p) << endl; 所以sizeof(str)和sizeof(p)都為4。 在C++裡參數傳遞數組永遠都是傳遞指向數組首元素的指針,編譯器不知道數組的大小,如果想在函數內知道數組的大小,需要這樣做:進入函數後用memcpy拷貝出來,長度由令一個形參傳進去。 void fun(unsigned char *p1,int len) { unsigned char* buf = new unsigned char[len + 1]; memcpy(buf,p1,len); } //對於指針的處理: char *ss= "0123456789"; cout << sizeof(ss) << endl;//4 ss是指向字符串常量的字符指針,sizeof獲得的是一個指針所占的空間,應該是長整型 cout << sizeof(*ss) << endl;//1 *ss是第一個字符其實就是獲得了字符串的第一位’’所占的內存空間,是char類型的,占了位 cout << strlen(ss) << endl;//10,如果要獲得這個字符串的長度,則一定要使用strlen //另外,下面的方法可以用於確定該靜態數組可以容納元素的個數 int a[3]= {1,2,3}; cout << sizeof a/sizeof(typeid(a[0]).name());//3 (2.8) sizeof()和初不初始化,沒有關系,strlen()和初始化有關。比較: 3.簡單結構體的sizeof 結構體每個變量分開占用空間。 字節對齊的細節和編譯器實現相關,但一般而言,滿足三個准則: 1) 結構體變量的首地址能夠被其最寬基本類型成員的大小所整除; 2) 結構體每個成員相對於結構體首地址的偏移量(offset)都是成員大小的整數倍,如有需要編譯器會在成員之間加上填充字節(internal adding); 3) 結構體的總大小為結構體最寬基本類型成員大小的整數倍,如有需要編譯器會在最末一個成員之後加上填充字節(trailing padding)。 看內存情況:字節對齊需要在中間補3個字節的CC。 可以用pack指令用來調整結構體對齊方式的,#pragmapack的基本用法為:#pragmapack( n ),n為字節對齊數,其取值為1、2、4、8、16。 “空結構體”(不含數據成員)的大小不是0,而是1。 “空結構體”變量也得被存儲。 4. union的sizeof union 變量公用空間。 解析:裡面最大的變量類型是int[5], 占用20個字節. 所以它的大小是20