全面解析sizeof(上),全面解析sizeof(

來源:互聯網
上載者:User

全面解析sizeof(上),全面解析sizeof(

以下代碼使用平台是Windows7 64bits+VS2012。

sizeof是C/C++中的一個操作符(operator),其作用就是返回一個對象或者類型所佔的記憶體位元組數,使用頻繁,有必須對齊有個全面的瞭解。

1.sizeof的基本文法

sizeof有三種文法形式,如下:
(1)sizeof( object ); // sizeof( 對象 );
(2) sizeof( type_name ); // sizeof( 類型 );
(3)sizeof object; // sizeof 對象;
第三種文法結構雖然正確,為簡單統一,均使用一、二中寫法。例如:

int i;sizeof( i );   // oksizeof i;      // oksizeof( int ); // oksizeof int;    // error
2.sizeof計算基本類型與表示式

sizeof計算對象的大小也是轉換成對物件類型的計算,也就是說,同種類型的不同對象其sizeof值都是一致的。這裡,對象可以進一步延伸至運算式,即sizeof可以對一個運算式求值,編譯器根據運算式的最終結果類型來確定大小,sizeof是編譯時間進行運算,與運行時無關,不會對錶達式進行計算。
考察如下代碼:

#include <iostream>using namespace std;int main(int argc,char* argv[]){    cout<<"sizeof(char)="<<sizeof(char)<<endl;    cout<<"sizeof(short)="<<sizeof(short int)<<endl;    cout<<"sizeof(int)="<<sizeof(int)<<endl;    cout<<"sizeof(long)="<<sizeof(long int)<<endl;    cout<<"sizeof(long long)="<<sizeof(long int int)<<endl;    cout<<"sizeof(float)="<<sizeof(float)<<endl;    cout<<"sizeof(double)="<<sizeof(double)<<endl;    int i=8;    cout<<"i="<<i<<endl;    cout<<"sizeof(i)="<<sizeof(i)<<endl;    cout<<"sizeof(i)="<<sizeof(i=5)<<endl;    cout<<"i="<<i<<endl;}

在64bits的Windows下運行結果是

sizeof(char)=1
sizeof(short)=2
sizeof(int)=4
sizeof(long)=4
sizeof(long long)=4
sizeof(float)=4
sizeof(double)=8
i=8
sizeof(i)=4
sizeof(i)=4
i=8
注意兩點,
(1)i的值並未發生改變,表明sizeof括弧內的運算式並沒有執行,sizeof在編譯時間求其運算式的運算結果的類型,sizeof運算與運行時無關。sizeof(i)等價於sizeof(int),sizeof(i=5)等價於sizeof(int),也就是說在可執行代碼中,並不包含i=5這個運算式,它早在編譯階段就被處理了。
(2)long int是否佔8位元組,與編譯器的實現有關,Visual C++在VS2012中使用的編譯器是cl.exe,在64bits的Windows下仍然將long編譯為4位元組,要想使用8位元組長整型,保險起見,使用long long型。

3.sizeof計算指標變數

指標是C、C++的靈魂,它記錄了另一個對象的地址。既然是來存放地址的,那麼它當然等於電腦內部地址匯流排的寬度。所以在32位電腦中,一個指標變數的傳回值必定是4(以位元組為單位),可以推導,在將來的64位系統中指標變數的sizeof結果為8。

char* pc = "abc";int* pi=new int[10];string* ps;char** ppc = &pc;void (*pf)(); // 函數指標char testfunc(){return ‘k’;}sizeof( pc ); // 結果為4sizeof( pi ); // 結果為4sizeof( ps ); // 結果為4sizeof( ppc ); // 結果為4sizeof( pf ); // 結果為4sizeof( &testfunc ); // 結果為4sizeof( testfunc ()); // 結果為1sizeof(*( testfunc) ()); // 結果為1

考察以上代碼,得出如下結論:
(1) 指標變數的sizeof值與指標所指的物件類型沒有任何關係,與指標申請多少空間沒有關係,所有的指標變數所佔記憶體大小均相等。那為什麼在本機64bits系統下,指標變數大小仍然是4個位元組,因為使用32位編譯器編譯得到程式是32位,故指標大小是4位元組,可自行修改編譯器版本,不再贅述。
(2) &testfunc代表一個函數指標,指標大小是4,所以sizeof(&testfunc)==4。testfunc()代表一次函數調用,傳回值類型是char,所以sizeof(testfunc())==sizeof(char)==1。testfunc名本身就是一個函數指標,所以(*testfunc)()也是一次函數調用,sizeof((*testfunc)())==sizeof(char)==1。

4.sizeof計算數組

當sizeof作用於數組時,求取的是數組所有元素所佔用的大小。參考如下代碼:

int A[3][5];    char c[]="123456";    double*(*d)[3][6];    cout<<sizeof(A)<<endl;      //輸出60    cout<<sizeof(A[4])<<endl;   //輸出20    cout<<sizeof(A[0][0])<<endl;//輸出4    cout<<sizeof(c)<<endl;      //輸出7    cout<<sizeof(d)<<endl;      //輸出4    cout<<sizeof(*d)<<endl;     //輸出72    cout<<sizeof(**d)<<endl;    //輸出24    cout<<sizeof(***d)<<endl;   //輸出4    cout<<sizeof(****d)<<endl;  //輸出8

考察以上代碼,得出如下結論:
(1)A的資料類型是int[3][5],A[4]的資料類型是int[5],A[0][0]資料類型是int。所以
sizeof(A)==sizeof(int[3][5])==3*5*sizeof(int)==60,sizeof(A[4])==sizeof(int[5])=5*sizeof(int)==20,sizeof(A[0][0])==sizeof(int)==4。儘管A[4]的下標越界,但不會造成執行階段錯誤,因為sizeof運算只關心資料類型,在編譯階段就已經完成。
(2)由於字串以Null 字元’\0’結尾,所以c的資料類型是char[7],所以sizeof(c)=sizeof(char[7])==7。
(3)d是一個指標,不管它指向的西鄉是什麼資料類型,自身大小永遠是4,。所以sizeof(d)==4。sizeof(*d)的資料類型是double*[3][6],所以sizeof(*d)==sizeof(double*[3][6])==3*6*sizeof(double*)==18*4==72。同理,可以推算出sizeof(**d)==sizeof(double*[6])==6*sizeof(double*)==24,sizeof(***d)==sizeof(double*)==4,sizeof(****d)=sizeof(double)==8。

當數組作為函數形參時,下面的i和j的值應該是多少呢?

void foo1(char a1[3]){    int i = sizeof( a1 ); // i == ?}void foo2(char a2[]){    int j = sizeof( a2); // j == ?}

也許當你試圖回答j的值時已經意識到i答錯了,是的,i!=3。這裡函數參數a1已不再是數群組類型,而是蛻變成指標,相當於char* a1,為什嗎?仔細想想就不難明白,我們調用函數foo1時,程式會在棧上分配一個大小為3的數組嗎?不會!數組是“傳址”的,調用者只需將實參的地址傳遞過去,所以a1自然為指標類型(char*),i的值也就為4,同樣j也是4。

錯誤、不足,在所難免,歡迎同行留言批評指正!

參考文獻

[1]陳剛.C++進階進階教程[M].武漢:武漢大學出版社,2008.
[2]http://blog.csdn.net/freefalcon/article/details/54839

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.