結構體(struct) 的 sizeof 大小

C語言中,sizeof的Semantics(語義)如下:The sizeof operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized

C語言中,,sizeof的Semantics(語義)如下:

The sizeof operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type. The size is determined from the type of the operand. The result is an integer.If the type of the operand is a variable length array type, the operand is evaluated; otherwise, the operand is not evaluated and the result is an integer constant.

When applied to an operand that has type char, unsigned char,or signed char,(or a qualied version thereof) the result is 1. When applied to an operand that has array type, the result is the total number of bytes in the array.When applied to an operand that has structure or union type, the result is the total number of bytes in such an object,including internal and trailing padding.

在計算結構體的sizeof當中經常會遇到一些問題,就是我們計算的大小和sizeof的結果往往不太一致,比如:

#include <stdio.h> 
struct b { 
   float f; 
   char p; }; 
int main(void) 
{   
 printf("sizeof(struct(b))=%d\n",sizeof(struct b));
 return 0; 
 }

於是計算一下其大小:

= (sizeof(float)) + 2*(sizeof(int)) + (sizeof(char))
=4+2*4+1
=4+8+1
=13 

而打印結果卻是16!很顯然13不等於16。
爲什麼呢?
在網上問了問高手,這裏設計到編譯器的字節對齊(編譯器自動優化),在計算機處理數據過程中,由於內存的容量已經比較大了,所以編譯器們通常考慮到了執行速度的優化,讓程序儘可能快的訪問內存。現代計算機中內存空間都是按照byte劃分的,從理論上講似乎對任何類型的變量的訪問可以從任何地址開始,但實際情況是在訪問特定類型變量的時候經常在特定的內存地址訪問,這就需要各種類型數據按照一定的規則在空間上排列,而不是順序的一個接一個的排放,這就是對齊。
各個硬件平臺對存儲空間的處理上有很大的不同。一些平臺對某些特定類型的數據只能從某些特定地址開始存取。比如有些架構的CPU在訪問 一個沒有進行對齊的變量的時候會發生錯誤,那麼在這種架構下編程必須保證字節對齊.其他平臺可能沒有這種情況,但是最常見的是如果不按照適合其平臺要求對 數據存放進行對齊,會在存取效率上帶來損失。比如有些平臺每次讀都是從偶地址開始,如果一個int型(假設爲32位系統)如果存放在偶地址開始的地方,那 麼一個讀週期就可以讀出這32bit,而如果存放在奇地址開始的地方,就需要2個讀週期,並對兩次讀出的結果的高低字節進行拼湊才能得到該32bit數據。
其實字節對齊的細節和具體編譯器實現相關,但一般而言,滿足三個準則:

1)結構體變量的首地址能夠被其最寬基本類型成員的大小所整除;   
2)結構體每個成員相對於結構體首地址的偏移量都是成員大小的整數倍,如有需要編譯器會在成員之間加上填充字節;例如上面第二個結構體變量的地址空間。   
3)結構體的總大小爲結構體最寬基本類型成員大小的整數倍,如有需要編譯器會在最末一個成員之後加上填充字節。例如上面第一個結構體變量。

綜上所訴:在結構體b中char類型的p只佔1個字節,而編譯器會在其後面加上3的填充字節,所以該結構的大小就是16了。
加入把結構體定義爲:

struct
{
    float f;
    int a[2];
    char p,q,r;
}

轉自:http://www.68idc.cn/help/buildlang/ask/20150319287102.html

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