sizeof 總結

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

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章