計算結構體大小

char類型的長度被定義爲一個8位字節,這很簡單。

short類型的長度至少爲兩字節。在有些計算機上,對於有些編譯程序,short類型的長度可能爲4字節,或者更長。

int類型是一個整數的「天然」大小,其長度至少爲兩字節,而且至少要和short類型同樣長。在16位計算機上,int類型的長度可能爲兩字節;在32位計算機上,可能爲4字節;當64位計算機流行起來後,int類型的長度可能會達到8字節。這裏說的都是「可能」,例如,早期的Motorala 68000是一種16/32位的混合型計算機,依賴於不一樣的命令行選項,一個68000編譯程序能產生兩字節長或4字節長的int類型。

long類型至少和int類型同樣長(所以,它也至少和short類型同樣長)。long類型的長度至少爲4字節。32位計算機上的編譯程序可能會使short,int和long類型的長度都爲4字節——也可能不會。html

 

結構體中的成員能夠是不一樣的數據類型,成員按照定義時的順序依次存儲在連續的內存空間。和數組不同的是,結構體的大小不是全部成員大小簡單的相加,須要考慮到系統在存儲結構體變量時的地址對齊問題。 
        經過下面這個計算結構體大小的示例來理解與學習如何計算結構體的大小。 
struct stu 

       int i; 
       char c; 
       int j; 
}; 
        首先介紹一個相關的概念——偏移量。偏移量指的是結構體變量中成員的地址和結構體變量地址的差。而後給出結構體大小的定義:結構體大小等於最後一個成員的偏移量加上最後一個成員的大小。顯然,結構體變量中第一個成員的地址就是結構體變量的首地址。所以,第一個成員i的偏移量爲0。第二個成員c的偏移量是第一個成員的偏移量加上第一個成員的大小(0+4),其值爲4;第三個成員j的偏移量是第二個成員的偏移量加上第二個成員的大小(4+1),其值爲5。 
        實際上,因爲存儲變量時地址對齊的要求,編譯器在編譯程序時會遵循三條原則: 
1、結構體變量中成員的偏移量必須是該成員大小的整數倍(0被認爲是任何數的整數倍) 。 
2、結構體大小必須是全部成員大小的整數倍。
3、若是結構體中的成員又是另一種結構體,只需把其展開便可。但有一點須要注意,展開後的結構體的第一個成員的偏移量應當是被展開的結構體中最大的成員的整數倍。
 
注:以上三條原則僅適用於VC,gcc關於內存對齊有不一樣的機制。
 
        對照第一條,上面的例子中前兩個成員的偏移量都知足要求,但第三個成員的偏移量爲5,並非自身(int)大小的整數倍。編譯器在處理時會在第二個成員後面補上3個空字節,使得第三個成員的偏移量變成8。 
        對照第二條,結構體大小等於最後一個成員的偏移量加上其大小,上面的例子中計算出來的大小爲12,知足第二條原則,因此該結構體的大小即是12. 

        再看一個知足第一條,不知足第二條的狀況 
struct stu_2 

       int k; 
       short t; 
}; 
        成員k的偏移量爲0;成員t的偏移量爲4,都不須要調整。但計算出來的大小爲6,顯然不是成員k大小的整數倍。所以,編譯器會在成員t後面補上2個字節,使得結構體的大小變成8從而知足第二個要求。因此該結構體的大小爲8. 
因而可知,你們在定義結構體類型時須要考慮到字節對齊的狀況,不一樣的順序會影響到結構體的大小。對比下面兩種定義順序。 
struct stu_3 

       char c1; 
       int i; 
       char c2; 
}; 

struct stu_4 

       char c1; 
       char c2; 
       int i; 
}; 
        雖然結構體stu3和stu4中成員都同樣,但sizeof(struct stu3)的值爲12而sizeof(struct stu4)的值爲8。 

若是結構體中的成員又是另一種結構體類型時應該怎麼計算呢?只需把其展開便可。但有一點須要注意,展開後的結構體的第一個成員的偏移量應當是被展開的結構體中最大的成員的整數倍。看下面的例子: 
struct stu_5 

       short i; 
       struct 
       { 
              char c; 
              int j; 
       }ss; 
       int k; 
}; 
        結構體stu5的成員ss.c的偏移量應該是4,而不是2。整個結構體大小應該是16。 
如何給結構體變量分配空間由編譯器決定,以上狀況針對的是Windows XP下的VC 6.0。其餘平臺的C編譯器可能會有不一樣的處理。 
示例代碼:數組

# include  <stdio.h >
 
struct  stu
{
     int  i;
     char  c;
     int  k;
};    //大小爲12
 
struct  stu_2
{
     int  k;
     short  t;
};    //大小爲8
 
struct  stu_3
{
     char  c1;
     int  i;
     char  c2;
};    //大小爲12
 
struct  stu_4
{
     char  c1;
     char  c2;
     int  i;
};    //大小爲8
 
struct  stu_5
{
     short  i;
     struct
    {
         char  c;
         int  j;
    } ss;
     int  k;
};    //大小爲16
 
struct stu_6
{
     int i;
     char j;
     char k;
};  //大小爲8
 
轉自:http://www.cnblogs.com/ppboy_dxh/archive/2013/08/21/3273376.html
相關文章
相關標籤/搜索