2009-06-11 170 views
2

我正在使用這樣的結構。我不喜歡typedef,因爲我已經告訴它可以隱藏錯誤。 但是,我正在查看一些示例代碼,並且我看到了像這樣聲明的結構。這是我聲明它們的正常方式。使用這樣聲明結構的差異

struct person 
{ 
    int age; 
    char name[32]; 
}; 

struct person person_a; 
    person_a.age = 20; 
    etc. 

聲明如下不過,我所看到的結構:

struct 
{ 
    int age; 
    char name[32]; 
}person; 

struct _person 
{ 
    int age; 
    char name[32]; 
}person; 

是所有這些的區別不同的技術,以及如何決定何時最好使用每一個特定的一個。

非常感謝您的任何建議,

+2

我很想知道爲什麼typedefs可以隱藏錯誤。我傾向於更喜歡typedefs - 至少因爲你不能遇到使用'extern void func(struct something * xxx)'的問題;'沒有事先聲明「結構化」。也就是'extern void func(something * xxx)';'需要typedef來「編譯」所有東西。替代編譯 - 但沒有做你期望的(儘管大體上,你會擺脫它)。 – 2009-06-11 04:32:51

回答

17

此:

struct 
{ 
    int age; 
    char name[32]; 
}person; 

聲明一個變量,person這是一個structstruct沒有名稱,但仍以相同方式使用person變量。

struct _person 
{ 
    int age; 
    char name[32]; 
}person; 

這是相同的:

struct _person 
{ 
    int age; 
    char name[32]; 
}; 
struct _person person; 

它聲明一個struct名爲_person然後使一個稱爲struct _person類型的person變量。

1

沒有什麼神奇的,真的,

struct person 
{ 
    int age; 
    char name[32]; 
} var; 

是同一件事:

struct person 
{ 
    int age; 
    char name[32]; 
}; 
struct person var; 
1

的第一代碼只是創建人結構。
第二個代碼創建person結構person_a的一個實例。
第三個代碼創建一個未命名的結構和一個名爲person的實例。 第4個代碼創建一個名爲_person的結構和一個名爲person的實例。

1

如果結構定義的目的是聲明一個邏輯數據結構,這個結構在本地模塊之外有意義,那麼你會希望在頭文件中看到第一個結構。

在現實世界的C代碼中,結構經常被聲明爲範圍局部的purley實用性原因。例如,格式化將被複制到緩衝區中的數據。在這些情況下,合併結構類型和變量聲明非常方便且合乎邏輯。此外,對結構類型使用匿名聲明可以避免使用不需要的名稱混淆名稱空間。

我確實對這些例子有一個批評:在C中,帶有前導下劃線的名字按照慣例被認爲是爲編譯器供應商保留的。所以我認爲最後一個例子不符合最佳實踐。

2

在最後兩個結構中,您都爲稱爲person的結構分配了存儲。

我的意思,如果你有這樣的事情是:

struct person 
{ 
    int age; 
    char name[32]; 
}; 

這只是一個聲明;沒有變量分配,因此不能在代碼中使用。您已聲明後,可以按如下方式開始使用這樣的結構:

struct person p1; 

然後,P1可以利用p1.age或p1.name等

在真實世界的代碼方面,而不是

struct _person 
{ 
    int age; 
    char name[32]; 
}person; 

我們通常看到

typedef struct _person 
{ 
    int age; 
    char name[32]; 
} person_t; 

在這種情況下,我們可以節省打字更重要的是在S結構的行爲與其他任何內置類型(如int等)相同。 例如,

person_t p1;

person_t * p1;

等等。

2

對於第一個例子(第二個例子),如果你確定你確實需要另一個對象用於這個結構,你將使用這種方法。這看起來乾淨,速度快的代碼:)

因爲你有一個現成的對象名爲「人」的第二種情況和選項以後創建一個對象作爲

struct _person object2 

這是解釋爲什麼你將使用任一種方法。它們之間的區別已經在上面解釋清楚了。