2013-03-09 73 views
3

我正在看Barnyard2的sf_ip.h source code。我不瞭解sfip_t stuct,特別是聯盟塊。不懂struct Barnyard2的sf_ip頭文件

typedef struct _ip { 
    int family; 
    int bits; 

    /* see sfip_size(): these address bytes 
* must be the last field in this struct */ 
    union 
    { 
     u_int8_t u6_addr8[16]; 
     u_int16_t u6_addr16[8]; 
     u_int32_t u6_addr32[4]; 
// u_int64_t u6_addr64[2]; 
    } ip; 
    #define ip8 ip.u6_addr8 
    #define ip16 ip.u6_addr16 
    #define ip32 ip.u6_addr32 
// #define ip64 ip.u6_addr64 
} sfip_t; 

爲什麼使用數組?我試圖尋找文檔,但谷歌一直沒有運氣。任何人都可以解釋這裏正在做什麼嗎?

+0

聯合意味着你可以使用三種方式來指定帶有字節,字和雙字數組的ip地址。他們保留16個字節來保存IP地址。你爲什麼擔心? – AnatolyS 2013-03-09 12:01:05

回答

3

C中的聯合使用相同的內存塊的所有元素。這與元素在內存中連續的結構不同。

所以,雖然struct {int x; int y;}將由此奠定了,如果你的變量開始在內存位置0x40000000

  +-------------+ 
0x40000000 | x (4 bytes) | 
      +-------------+ 
0x40000004 | y (4 bytes) | 
      +-------------+ 

相關union {int x; int y;}存在這樣的:

Address 
      +-------------+-------------+ 
0x40000000 | x (4 bytes) | y (4 bytes) | 
      +-------------+-------------+ 

換句話說,它只能用於一個東西在技術上,它是未定義的行爲使用y當您上次使用x到設置變量 - 雖然在這種情況下,你很可能會發現它會起作用,因爲兩種可能性是相同的類型。

你的具體情況,您有以下內存佈局(假設你的變量是位於0x40000000):

  +--------------+--------------+--------------+ 
0x40000000 | u6_addr8[ 0] |    |    | 
      +--------------+ u6_addr16[0] |    | 
0x40000001 | u6_addr8[ 1] |    |    | 
      +--------------+--------------+ u6_addr32[0] | 
0x40000002 | u6_addr8[ 2] |    |    | 
      +--------------+ u6_addr16[1] |    | 
0x40000003 | u6_addr8[ 3] |    |    | 
      +--------------+--------------+--------------+ 
0x40000004 | u6_addr8[ 4] |    |    | 
      +--------------+ u6_addr16[2] |    | 
0x40000005 | u6_addr8[ 5] |    |    | 
      +--------------+--------------+ u6_addr32[1] | 
0x40000006 | u6_addr8[ 6] |    |    | 
      +--------------+ u6_addr16[3] |    | 
0x40000007 | u6_addr8[ 7] |    |    | 
      +--------------+--------------+--------------+ 
0x40000008 | u6_addr8[ 8] |    |    | 
      +--------------+ u6_addr16[4] |    | 
0x40000009 | u6_addr8[ 9] |    |    | 
      +--------------+--------------+ u6_addr32[2] | 
0x4000000a | u6_addr8[10] |    |    | 
      +--------------+ u6_addr16[5] |    | 
0x4000000b | u6_addr8[11] |    |    | 
      +--------------+--------------+--------------+ 
0x4000000c | u6_addr8[12] |    |    | 
      +--------------+ u6_addr16[6] |    | 
0x4000000d | u6_addr8[13] |    |    | 
      +--------------+--------------+ u6_addr32[3] | 
0x4000000e | u6_addr8[14] |    |    | 
      +--------------+ u6_addr16[7] |    | 
0x4000000f | u6_addr8[15] |    |    | 
      +--------------+--------------+--------------+ 

假設您瞭解您的特定C實現如何勾畫出不同類型,這提供了一種方法以不同的方式參考相同的數據。

+0

現在感謝更清晰:) – Goaler444 2013-05-28 11:13:07