sizeof總結
本文轉載自:http://blog.csdn.net/chief1985/archive/2009/10/23/4720191.aspx
一.基本數據的長度
char:1(有符號無符號同)
short:2(有符號無符號同)
int:4(有符號無符號同)
long:4(有符號無符號同)
float:4
double:8
二.對齊的作用和原因:
各個硬件平臺對存儲空間的處理上有很大的不同。一些平臺對某些特定類型的數據只能從某些特定地址開始存取。比如有些架構的CPU在訪問 一個沒有進行對齊的變量的時候會發生錯誤,那麼在這種架構下編程必須保證字節對齊.其他平臺可能沒有這種情況,但是最常見的是如果不按照適合其平臺要求對 數據存放進行對齊,會在存取效率上帶來損失。比如有些平臺每次讀都是從偶地址開始,如果一個int型(假設爲32位系統)如果存放在偶地址開始的地方,那 麼一個讀週期就可以讀出這32bit,而如果存放在奇地址開始的地方,就需要2個讀週期,並對兩次讀出的結果的高低字節進行拼湊才能得到該32bit數 據。顯然在讀取效率上下降很多。
三.一些常見的和需要注意的sizeof
char* a= "abc"; //sizeof(a)=4
==============================================
char b[100]; //sizeof(b)=100;
==============================================
char* c=(char*)malloc(100); //sizeof(c)=100
==============================================
char d[] = "abc"; //sizeof(d)=4
==============================================
int e[100]; //求數組的元素個數int c2 = sizeof( e ) / sizeof( e[0] ); // 總長度/第一個元素的長度
==============================================
void foo3(char f[3])
{
int c3 = sizeof( f); // c3 =4 char*
}
==============================================
void foo4(char g[])
{
int c4 = sizeof( g); // c4 =4 char*
}
==============================================
int a = 1, b =2; 執行sizeof (a = b)
之後爲什麼a=1, 而不是2. 爲什麼沒有執行賦值操作? (淘寶筆試題)
(1)sizeof (type-name) 是求變量類型的大小 ,在編譯期執行 ,因爲sizeof 是在編譯期內執行而不是在運行期 所以 sizeof (a = b) 是不會運行a = b 這個操作的。
(2)sizeof是一個運算符而不是一個函數。 編譯器會查符號表求出值大小,而不會執行裏面的表達式
(3)sizeof 是如何來看待 a = b的?
sizeof 是按照類型計算字節的,與值無關。 在編譯器中,上句等價於 sizeof( int = int ),
結果按照“左值”計算字節數
你可以試試
int a=1;
double b=2.0;
cout < <sizeof(a=b); //等價於 sizeof(int= double) 自動cast
cout < <sizeof(b=a); //等價於 sizeof(double = int)
一個結果是 4,一個是8
(4)sizeof(1) 1 是int類型 所以4
sizeof(1.1) 1.1 爲double 所以8
當然這個根據機器不同結果也不一樣
四.結構體和類的規則
1.數據類型自身的對齊值:
對於char型數據,其自身對齊值爲1,對於short型爲2,對於int,float,double類型,其自身對齊值爲4,單位字節。
2.結構體或者類的自身對齊值:其成員中自身對齊值最大的那個值。
3.指定對齊值:#pragma pack (value)時的指定對齊值value。
4.數據成員、結構體和類的有效對齊值:自身對齊值和指定對齊值中小的那個值。
上面包含兩層意思,一是結構體(類)裏面的成員地址要按照自身的大小對齊,也就是addressof(struct.number)%sizeof(struct.number)=0;二是整個結構體(類)要按照成員中自身對齊值最大(N)的那個值進行對齊,也就是sizeof(struct)%N=0。
五.例子
#include "stdio.h"
typedef struct {
char a; // 1 byte
int b; // 4 bytes
short c; // 2 bytes
char d; // 1 byte
} struct_a;
typedef struct {
char a; // 1 byte
char _pad0[3]; // padding to put 'b' on 4-byte boundary
int b; // 4 bytes
short c; // 2 bytes
char d; // 1 byte
char _pad1[1]; // padding to make sizeof(x_) multiple of 4
}struct_b;
//struct_x強制 模1 對齊.
# pragma pack (1)
typedef struct
{
char a; // 1 byte
int b; // 4 bytes
short c; // 2 bytes
} struct_c;
# pragma pack ()
//struct_x被強制 模2 對齊.
# pragma pack (2)
typedef struct
{
char a; // 1 byte
int b; // 4 bytes
short c; // 2 bytes
} struct_d;
# pragma pack ()
//struct_x被強制 模8對齊.
# pragma pack (8)
typedef struct
{
char a; // 1 byte
int b; // 4 bytes
short c; // 2 bytes
} struct_e;
# pragma pack ()
typedef struct
{
char a;
short b;
char c;
}struct_f;
typedef struct
{
char a;
char c;
short b;
}struct_g;
typedef struct
{
char b;
int a;
short c;
}struct_h;
typedef struct{
unsigned incon: 8; /*incon佔用低字節的0~7共8位*/
unsigned txcolor: 4;/*txcolor佔用高字節的0~3位共4位*/
unsigned bgcolor: 3;/*bgcolor佔用高字節的4~6位共3位*/
unsigned blink: 1; /*blink佔用高字節的第7位*/
}struct_i;
class CLASS_A{
char x;
void func();
};
class CLASS_B{
char x;
virtual void func();
};
class CLASS_C{
char x;
char y;
virtual void func();
};
class CLASS_D{
char x;
char* z;
char y;
virtual void func();
};
class CLASS_E{
char x;
CLASS_A a;
void func();
};
class CLASS_F{
char x;
int y;
};
class CLASS_G{
char x;
CLASS_F f;
void func();
};
class CLASS_H{
char x;
CLASS_F* f;
void func();
};
#define NAMEOF(x) #x
#define PRINT_SIZEOF(x) do{printf("sizeof(%s)=%d/n",NAMEOF(x),sizeof(x));}while(0)
int main(){
PRINT_SIZEOF(struct_a);
PRINT_SIZEOF(struct_b);
PRINT_SIZEOF(struct_e);
PRINT_SIZEOF(struct_f);
PRINT_SIZEOF(struct_g);
PRINT_SIZEOF(struct_h);
PRINT_SIZEOF(struct_i);
PRINT_SIZEOF(CLASS_A);
PRINT_SIZEOF(CLASS_B);
PRINT_SIZEOF(CLASS_C);
PRINT_SIZEOF(CLASS_D);
PRINT_SIZEOF(CLASS_E);
PRINT_SIZEOF(CLASS_F);
PRINT_SIZEOF(CLASS_G);
PRINT_SIZEOF(CLASS_H);
return 0;
}
六.例子結果
sizeof(struct_a)=12
sizeof(struct_b)=12
sizeof(struct_c)=7
sizeof(struct_d)=8
sizeof(struct_e)=12
sizeof(struct_f)=6
sizeof(struct_g)=4
sizeof(struct_h)=12
sizeof(struct_i)=2
sizeof(struct_j)=2
sizeof(struct_k)=4
sizeof(struct_l)=4
sizeof(CLASS_A)=1
sizeof(CLASS_B)=8
sizeof(CLASS_C)=8
sizeof(CLASS_D)=16
sizeof(CLASS_E)=2
sizeof(CLASS_F)=8
sizeof(CLASS_G)=12
sizeof(CLASS_H)=8
sizeof(CLASS_I)=8
七.顯示class的對象佈局
VC8的隱含編譯項/d1reportSingleClassLayout和/d1reportAllClassLayout可以看對象的佈局。例如你需要看CLASS_G的對象佈局,就在編譯參數裏面加上/d1reportSingleClassLayoutCLASS_G。更加詳細的介紹請參考下面的第3個網址。下面是CLASS_G的對象佈局:
class CLASS_G size(12):
+---
0 | x
| <alignment member> (size=3)
4 | CLASS_F f
+---
八.參考:
http://blog.chinaunix.net/u/20828/showart_438003.html
http://www.yuanma.org/data/2006/0723/article_1213.htm
http://blog.sina.com.cn/s/blog_59b189220100a49h.html
http://www.cnblogs.com/neoragex2002/archive/2007/11/01/VC8_Object_Layout_Secret.html