sizeof解析C語言

來源:互聯網
上載者:User

sizeof是C語言中判斷資料類型或者運算式長度符;不是一個函數,位元組數的計算在程式編譯時間進行,而不是在程式執行的過程中才計算出來。

文章來源:http://blog.sina.com.cn/s/blog_5c717fa001012ml7.html

sizeof函數功能:計算資料空間的位元組數

1.與strlen()比較
strlen計算字元數組的字元數,以"\0"為結束判斷,不計算為'\0'的數組元素。
sizeof計算資料(包括數組、變數、類型、結構體等)所佔記憶體空間,用位元組數表示(當然用在字元數組計算"\0"的大小)。
2.指標與靜態數組的sizeof操作
指標均可看為變數類型的一種。所有指標變數的sizeof 操作結果均為4。

執行個體1::char *p;
sizeof(p)=4;
sizeof(*p) = 1;  //相當於sizeof(char);  
執行個體2:  
對於靜態數組,sizeof可直接計算數組大小;
例:int a[10];
char b[]="hello";
sizeof(a)等於4*10=40;
sizeof(b)等於6;

void  fun(char p[])
{
 sizeof(p);        //等於4,數組做型參時,數組名稱當作指標使用!!
}

執行個體3(經典考題):
double* (*a)[3][6];
cout<<sizeof(a)<<endl;// 4 a為指標
cout<<sizeof(*a)<<endl;// 72 *a為一個有3*6個指標元素的數組
cout<<sizeof(**a)<<endl;// 24 **a為數組一維的6個指標
cout<<sizeof(***a)<<endl;// 4 ***a為一維的第一個指標
cout<<sizeof(****a)<<endl;// 8 ****a為一個double變數
問題解析:
a是一個很奇怪的定義,他表示一個指向double*[3][6]類型數組的指標。既然是指標,所以sizeof(a)就是4。
既然a是執行double*[3][6]類型的指標,*a就表示一個double*[3][6]的多維陣列類型,因此sizeof(*a)=3*6*sizeof(double*)=72。
同樣的,**a表示一個double*[6]類型的數組,sizeof(**a)=6*sizeof (double*)=24。
***a就表示其中的一個元素,也就是double*了,所以sizeof(***a)=4。
****a,就是一個double了,所以sizeof(****a)=sizeof(double)=8。

3.格式的寫法
sizeof操作符,對變數或對象可以不加括弧,但若是類型,須加括弧。
4.使用sizeof時string的注意事項
string s="hello";
sizeof(s)等於string類的大小(32),sizeof(s.c_str())得到的是與字串長度(4)。
5.union 與struct的空間計算
總體上遵循兩個原則:
(1)整體空間是佔用空間最大的成員(類型)所佔位元組的整數倍
(2)資料對齊原則----資料在記憶體中按照結構成員先後順序進行排序,當排到該成員變數時,其前面已擺放的空間大小必須是該成員類型大小的整倍數,如果不夠則補齊,以此向後類推。。。。。
注意:數組按照單個變數一個一個的擺放,而不是看成整體。如果成員中有自訂的類、結構體,也要注意數組問題。
執行個體4:[引用其他文章的內容]
因為對齊問題使結構體的sizeof變得比較複雜,看下面的例子:(預設對齊下)
struct s1
{
 char a;
 double b;
 int c;
 char d;
};

struct s2
{
 char a;
 char b;
 int c;
 double d;
};

cout<<sizeof(s1)<<endl;// 24
cout<<sizeof(s2)<<endl;// 16

同樣是兩個char類型,一個int類型,一個double類型,但是因為對齊問題,導致他們的大小不同。計算結構體大小可以採用元素擺放法,我舉例子說明一下:首先,CPU判斷結構體的對界,根據上一節的結論,s1和s2的對界都取最大的元素類型,也就是double類型的對界8。然後開始擺放每個元素。
對於s1,首先把a放到8的對界,假定是0,此時下一個閒置地址是1,但是下一個元素b是double類型,要放到8的對界上,離1最接近的地址是8了,所以b被放在了8,此時下一個空閑地址變成了16,下一個元素c的對界是4,16可以滿足,所以c放在了16,此時下一個空閑地址變成了20,下一個元素d需要對界1,也正好落在對界上,所以d放在了20,結構體在地址21處結束。由於s1的大小需要是8的倍數,所以21-23的空間被保留,s1的大小變成了24。
對於s2,首先把a放到8的對界,假定是0,此時下一個空閑地址是1,下一個元素的對界也是1,所以b擺放在1,下一個空閑地址變成了2;下一個元素c的對界是4,所以取離2最近的地址4擺放c,下一個空閑地址變成了8,下一個元素d的對界是8,所以d擺放在8,所有元素擺放完畢,結構體在15處結束,佔用總空間為16,正好是8的倍數。

這裡有個陷阱,對於結構體中的結構體成員,不要認為它的對齊就是他的大小,看下面的例子:
執行個體5:
struct s1
{
 char a[8];
};

struct s2
{
 double d;
};

struct s3
{
 s1 s;
 char a;
};

struct s4
{
 s2 s;
 char a;
};
cout<<sizeof(s1)<<endl;// 8
cout<<sizeof(s2)<<endl;// 8
cout<<sizeof(s3)<<endl;// 9
cout<<sizeof(s4)<<endl;// 16;
s1和s2大小雖然都是8,但是s1的對齊是1,s2是8(double),所以在s3和s4中才有這樣的差異。
所以,在自己定義結構體的時候,如果空間緊張的話,最好考慮對齊因素來排列結構體裡的元素。

   相關常數:
   sizeof int:4
   sizeof short:2
   sizeof long:4
   sizeof float:4
   sizeof double:8
   sizeof char:1
   sizeof p:4
   sizeof WORD:2
   sizeof DWORD:4

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.