2014-03-01 33 views
0

我工作的一個網絡項目,我碰到這個結構的骨架代碼來到我工作的結構體遇到問題:理解用C

struct sr_icmp_hdr { 
    uint8_t icmp_type; 
    uint8_t icmp_code; 
    uint16_t icmp_sum; 
} __attribute__ ((packed)) ; 
typedef struct sr_icmp_hdr sr_icmp_hdr_t; 

有人能解釋代碼的結構如下是什麼?什麼是__attribute__typedef

我已經習慣了在C++中看到的是:

struct hi{ 
    int thisIsAnInt; 
    double thisIsADouble; 
} 

,並宣佈這樣的結構:

hi hello; 
cout << hello.thisIsAnInt; 

在C有何不同?

回答

2

在C++中,當您定義或聲明類或結構時,標記名稱將自動用作類型名稱。

在C,這不會發生,因此要獲得同樣的效果,如C++,你必須添加:

typedef struct xxx xxx; 

有些人喜歡保持標籤從類型名稱分隔結構,但他們'在單獨的命名空間中,這是沒有必要的。我幾乎總是對標籤和類型名稱使用相同的名稱來強調它們指的是相同的類型。

因此:

struct sr_icmp_hdr { 
    uint8_t icmp_type; 
    uint8_t icmp_code; 
    uint16_t icmp_sum; 
} __attribute__ ((packed)); 

這定義struct sr_icmp_hdr;屬性是噪音。該屬性不是C的標準化部分,但在GCC中實現。它確保結構中沒有填充字節,儘管佈局是這樣的,只有不正當的編譯器會首先添加填充字節。因此我把它描述爲「噪音」。 (我用C編碼相當長一段時間,並沒有導致使用它。顯然,其他人有不同的經驗和它不會是在編譯器)。

typedef struct sr_icmp_hdr sr_icmp_hdr_t; 

這定義類型名稱sr_icmp_hdr_t這是struct sr_icmp_hdr的別名。更一般地說,typedef爲類型引入了一個替代名稱。例如,uint8_t是在C中的<stdint.h>中定義的typedef;同樣uint16_t。一般來說,這些名稱被用於促進便攜性。

請注意,即使沒有必要,C++也允許typedef struct xxx xxx;

+0

我不會調用屬性「noise」;這是一個gcc特定的擴展(儘管在這種情況下它可能沒有效果)。 –

+0

我正在編輯屬性評論,因爲你評論。我認爲這是噪音,但我已經給出了它更完整的特徵,以及爲什麼我認爲它是噪音。 –

1

1)屬性包裝是GCC特定聲明(不是C標準的一部分)。這裏描述:http://gcc.gnu.org/onlinedocs/gcc/Type-Attributes.html

這個特殊的屬性是編譯器使用盡可能小的內存來存儲所描述的結構的對象的提示。

2)和C++不同,在C,沒有說typedef會你就必須申報給定結構的對象爲:

struct sr_icmp_hdr mystruct;

0

對於你的問題的最後一部分,C沒有超載輸出的運算符,但你可以去:

hi hello = { 2, 1. }; 
printf("%d\n", hello.thisIsAnInt);