轉載自:http://blog.csdn.net/wxwtj/article/details/6636220
sizeof簡介:是一個算符,大部分編譯程序在編譯的時候(最新標準是在運行時也可以計算了)就把sizeof計算過了,計算的是棧中(注意只計算棧上的)類型或者變量的類型的長度(其實是編譯器分配的內存大小,所以與編譯器有關)。
而strlen是一個函數,在運行的時候計算的,只能計算字符串的長度,參數只能是char*,且必須以”\0”結尾。
本人比較懶,喜歡記結論:
1.基本類型的大小(默認32位系統)
bool:1 char:1 short:2 float:4 int:4 long:4 double:8
int a[100]={1,2} ;對這句,不要認為a是地址,所以sizeof(a)=4!答案是40,因為你那樣寫,編譯器就給數組a留了40個字節的空間
2.指針:
指針就是一個指向另一個對象的地址,32位系統的地址總線32根,所以為4個字節。
針對指針再多說兩句,只要你確定X是指針,sizeof(X)就=4;這種題需要注意的是你一下沒看出來是指針的情況,如:
Char var[10]
int test (char var[])
{
Return sizeof(var)
}
答案為4,因為數組作為參數傳給函數時傳的是指針(數組的首地址)var[]等價于*var,已經退化成一個指針了。呵呵,熟悉MFC消息結構的朋友應該很清楚:MFC消息處理函數使用兩個參數WPARAM、LPARAM就能傳遞各種復雜的消息結構(使用指向結構體的指針)。
3.編譯階段替換:
sizeof()中()內的內容在編譯過程中是不會被編譯的,而是被替代類型。
如int a;sizeof(a)在編譯過程中不論a等于多少都會被替換成sizeof(int); sizeof(a=8)執行之后,a會等于6么?答案是否定的,才說了是不會被編譯的,如果sizeof()括號里面是個表達式,編譯器根據表達式的最終結果類型來確定大小,不會對表達式進行計算
如果是函數的話,在編譯階段會被函數韓返回值取代,不會執行函數,如:int f1{return 0;} sizeof(f1)會被替換成sizeof(int);
4.結構體
為了性能考慮,編譯器會對結構體進行對齊。具體原因參看百度百科http://baike.baidu.com/view/4786260.htm
VC規定:
- 各成員變量存放的起始地址相對于結構的起始地址的偏移量必須為該變量的類型所占用的字節數的倍數。
- 為了確保結構的大小為結構的字節邊界數(即:該結構中占用最大空間的類型所占用的字節數)的倍數,所以在為了最后一個成員變量申請空間后,還會根據需要自動填充空缺的字節。
舉3個例子:例1:
#include "stdafx.h"
#include"iostream"
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
struct
{ int b;//4
double a;//8
char c;//1
}A;
cout<<sizeof(A);
return 0;
}
輸出為24,因為sizeof(b)等于4,而到sizeof(a)=8時根據規定1,a相對于結構體的地址偏移量要為8的整數倍,所以補齊4個字節,到c時,sizeof(c)=1,但是此時結構體大小為17,不是8的整數倍,所以還要補齊7個字節,所以等于24.內存布局如下:
|<<<b=4>>>|補齊4個字節|<<<<<<<a=8>>>>>>>>|<c=1>|<<補齊7個字節>>|
例2:
把例1中的struct變為
struct
{ double a;
int b;
char c;
}A;
后輸出為16:
因為sizeof(a)等于8,而到sizeof(b)=4時根據規定1,a相對于結構體的地址偏移量要為4的整數倍,滿足條件不用補齊,到c時,sizeof(c)=1,但是此時結構體大小為13,不是8的整數倍,所以還要補,3個字節,所以等于16.內存布局如下:
|<<<<<<<<<<<a=8>>>>>>>>>>|<<<<b=4>>>>|<c=1>|<<補齊3個字節>>|
例3:
union u
{
int a[4];
char b;
double c;
};
struct s
{
int a;
u b;
};
u是聯合體,共用體表示幾個變量共用一個內存位置,在不同的時間保存不同的數據類型和不同長度的變量。在union中,所有的共用體成員共用一個空間,并且同一時間只能儲存其中一個成員變量的值。當一個共用體被聲明時, 編譯程序自動地產生一個變量, 其長度為聯合中最大的變量長度。所以sizeof(u)的大小為16字節。S是個結構體,s中a占4個字節,加上u的16字節,總共是20字節。但是根據VC規定的第二條,需要補充為double 字節的倍數,所以會添加4字節。總共是24字節。
5.類:
空類大小:1(空類也要實例化,所謂類的實例化就是在內存中分配一塊地址,每個實例在內存中都有獨一無二的地址。同樣空類也會被實例化,所以編譯器會給空類隱含的添加一個字節,這樣空類實例化之后就有了獨一無二的地址了。所以空類的sizeof為1。解釋源自:http://blog.csdn.net/hairetz/article/details/4171769暫且認同了,懶得深究了。
我總結的只需要記住兩條規則:
- 類的大小為類的非靜態成員數據的類型大小與虛指針(如果有的話)之和,也就是說靜態成員數據和普通成員函數不作考慮。具體原因可以參考《深度探索C++對象模型》一書中關于C++對象模型的解釋,只有非靜態成員數據和虛指針是放在一起的,其他的都不放在一起。
- 類的總大小也遵守類似結構體字節對齊的調整規則。
幾種簡單情況需要記住:空類為1,單一繼承的空類空間也為1,多重繼承的空類空間還是為1。但是虛繼承的空類設計到虛表(虛指針),所以為4。程序員面試寶典也就到此為止。其他情況,沒有親自試驗過不敢亂說。