1. 程式人生 > >C/C++中各種 資料型別、結構體、類 佔用位元組數分析與總結

C/C++中各種 資料型別、結構體、類 佔用位元組數分析與總結

一、基本資料型別在不同編譯器下佔用位元組數比較與總結,測試過程不詳述了,直接看下錶結論!

下表中右側總結部分是依據佔用位元組數進行著色,同一種顏色型別的資料成員佔用位元組數要麼一致,要麼具有同樣的性質,這樣比較容易理解的記憶。

佔用位元組數

16位編譯器

32位編譯器

64位編譯器

總結

char

1

1

1

char一直佔1個字元,任何編譯器都只佔一個位元組

char*

2

4

8

char*是指標變數,N位系統含有N個bit,即佔用N/8個位元組

short int

2

2

2

short int一直佔2個位元組

int

2

4

4

int在X86和X64都是4位,僅在16位系統是2位元組

unsigned int

2

4

4

無符號int與int本身的佔位一樣,不區分編譯器

float

4

4

8

float由於帶浮點至少需要4位元組,在X64編譯器裡面是8位元組

double

8

8

8

double一直佔8個位元組

long

4

4

8

long 是 long int 的簡寫,位元組長度一直等同於 float

long long

8

8

8

long long 一直佔8個位元組,同double

unsigned long

4

4

8

無符號long與long本身佔位一樣,不區分編譯器

二、結構體佔用位元組數總結:

遵循補齊原則,以最長的資料型別作為補齊標準,最後統計有多少個補齊後的資料單元。

注意:空的結構體佔用位元組數為1,非空的結構體舉例如下圖所示:

三、類佔用位元組數總結:

  • 空類和空結構體類似,都會佔用一個位元組;
  • 類中的資料成員也存在補齊,與結構體中情況類似,但補齊的標準長度不僅看子類,也看父類的最大對齊長度;
  • 靜態的資料成員不佔用位元組;
  • 建構函式、解構函式、成員函式都不佔用位元組;

對於虛擬函式、純虛擬函式需要額外注意:

  • 虛擬函式和純虛擬函式都不佔用位元組,但會申請指標,此時佔用的空間為一個指標長度;  
  • 虛擬函式和純虛擬函式   “位元組佔用數”  一樣;
  • 無繼承時,多個虛擬函式、純虛擬函式共享一個指標,佔用位元組為一個指標長度;
  • 有繼承時,有幾個父類存在虛擬函式就需要多少個指標,此時子類的虛擬函式、純虛擬函式不再佔用位元組;

程式碼舉例:

class A   
{   
};  
 
class B   
{
	char ch;   
	virtual void func0()  {  } 
}; 
 
class C  
{
	char ch1;
	char ch2;
	virtual void func()  {  }  
	virtual void func1()  {  } 
};
 
class D: public A, public C
{   
	int d;   
	virtual void func()  {  } 
	virtual void func1()  {  }
};   
 
class E: public B, public C
{   
	int e;   
	virtual void func0()  {  } 
	virtual void func1()  {  }
};
 
int main(void)
{
	cout<<"A="<<sizeof(A)<<endl;    //result=1
	cout<<"B="<<sizeof(B)<<endl;    //result=8    
	cout<<"C="<<sizeof(C)<<endl;    //result=8
	cout<<"D="<<sizeof(D)<<endl;    //result=12
	cout<<"E="<<sizeof(E)<<endl;    //result=20
	return 0;
}

四、最後分析下記憶體中實際資料佔記憶體情況:

舉例兩個類,定義如下,Fruit  和  Apple  的記憶體情況分析如下:

class Fruit {
	int no;
	double weight;
	char key;
public:
	void print() {   }
	virtual void process() {   }
};


class Apple : public Fruit {
	int size;
	char type;
public:
	void save() {   }
	virtual void process() {   }
};

    

上面兩圖是32位編譯器環境下, Fruit(左)  和  Apple(右) 記憶體分佈情況。

在64位編譯器下,唯一的區別是 虛擬函式表指標從佔四位變成了佔八位,這和普通指標佔位規律一樣。

—— END ——

總結完畢,規律如上,其中的部分例子圖是引用自其它文章,連線如下: