計算結構體大小

        結構體中的成員能夠是不一樣的數據類型,成員按照定義時的順序依次存儲在連續的內存空間。和數組不同的是,結構體的大小不是全部成員大小簡單的相加,須要考慮到系統在存儲結構體變量時的地址對齊問題。
        經過下面這個計算結構體大小的示例來理解與學習如何計算結構體的大小。
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
 
int  main( void )
{
     int  a, b, c, d, e, f;
 
    a =   sizeof ( struct  stu);
    b =   sizeof ( struct  stu_2);
    c =   sizeof ( struct  stu_3);
    d =   sizeof ( struct  stu_4);
    e =   sizeof ( struct  stu_5);
    f = sizeof ( struct stu_6);
    printf( "size of struct stu   = %d\n" , a);     //12
    printf( "size of struct stu_2 = %d\n" , b);     //8
    printf( "size of struct stu_3 = %d\n" , c);     //12
    printf( "size of struct stu_4 = %d\n" , d);     //8
    printf( "size of struct stu_5 = %d\n" , e);     //16
    printf( "size of struct stu_6 = %d\n" , f);     //8
     return   0;
}


相關文章
相關標籤/搜索