2013-10-10 166 views
0

我參考了下面的教程,後來認識到這是使用typedef聲明結構的錯誤方法。Typedef結構錯誤聲明?

typedef struct 

{ 
    char name[namesize]; 
    char address[addresssize]; 
    int YearOfBirth; 
    int MonthOfBirth; 
    int DayOfBirth; 
} PersonalData; 

然後聲明:

PersonalData x; 

但是,我認爲,正確的做法是

typedef struct personaldataStruct 
{ 
    char name[namesize]; 
    char address[addresssize]; 
    int YearOfBirth; 
    int MonthOfBirth; 
    int DayOfBirth; 
    } PersonalData; 

然後聲明:

PersonalData x; 

作者是否誤導了我?或者兩種方式都是正確的?請確認。 這裏是教程http://www.iu.hio.no/~mark/CTutorial/CTutorial.html

+1

恕我直言,兩種方式都是正確的。 –

+0

我也在想這個.. – noufal

回答

2

這兩種方法都沒有正式的「不正確」。

前者爲該結構類型聲明一個無標籤結構類型和一個typedef名稱PersonalData。後者爲該結構類型聲明一個結構類型struct personaldataStruct和同義類型定義名稱PersonalData。聲明的personaldataStruct部分通常被稱爲「結構標籤」。

只要你使用PersonalData的typedef名指的是結構類型,如

PersonalData x; 

你不會看到這兩個聲明之間的任何差別。在這兩種情況下,x將被相同地聲明。

後一種方法爲您提供了另一種引用相同結構類型的方法 - struct personaldataStruct - 如果由於某種原因您希望這樣做。例如。使用後聲明時,你也可以聲明x作爲

struct personaldataStruct x; 

這是完全等同於PersonalData x;聲明。我個人更喜歡使用帶有結構標籤的方法,因爲它爲我提供了另一種引用類型的方法,這在某些情況下可能會派上用場(例如,當結構類型必須引用自身時) 。但是在大多數非自我指稱的情況下,對於前一種方法來說,情況會很好。

+0

完美,你不僅回答了我的問題,而且還舉了一個例子「(例如,當結構類型必須引用自己)。」這就是我問這個的原因。我以前的方法遇到鏈接列表節點聲明問題。 –

0

兩者都是正確的。第一種形式(沒有標籤)唯一的問題是,因爲typedef名稱在定義結束之前不可見,所以沒有辦法從它自己的定義中引用該結構。這是一個共同的要求;例如,鏈接列表,樹或其他類似圖形的數據結構中的節點通常需要指向相同類型的其他對象。

由於結構標記和typedef名稱不同命名空間(不要與C++命名空間混淆),因此不需要將它們區分開來。這是完全可以接受的使用上是相同的標識:

typedef struct PersonalData { 
    /* ... */ 
    struct PersonalData *next; 
} PersonalData; 

或者,只要你將有兩個標籤和一個typedef無論如何,你可以轉發聲明的typedef:

typedef struct PersonalData PersonalData; 
/* At this point, "struct PersonalData is an incomplete type. */ 
struct PersonalData { 
    /* ... */ 
    PersonalData *next; 
}; 
/* And now "struct PersonalData" is a complete type. */ 

(但拼寫錯誤可以讓你用typedef仍然指的是不完整的類型是從來沒有完成,它可以引發的錯誤,可能很難追查。複製粘貼是你的朋友。)

還有是另一種選擇。您定義的類型已有一個名稱:struct PersonalData。所有的typedef確實給這個相同的類型一個不同的名字。能夠使用單個標識符作爲類型名稱是很好的,但它確實沒有必要。我自己的偏好是省略typedef乾脆,只是指類型struct PersonalData

struct PersonalData { 
    /* ... */ 
    struct PersonalData *next; 
}; 
struct PersonalData *head; 
struct PersonalData fred; 

除非PersonalData意味着是一個不透明的類型(也就是說,使用它並不需要知道它的代碼一個結構體),在顯式中有一些優點。

在這一點上,很多人都非常反對我,並且真的很喜歡在結構中使用typedef,因爲您可能會在評論中看到。使用像這樣的typedefs沒有任何問題;這是沒有必要的。你應該準備閱讀別人用任何一種風格寫的代碼。

+0

謝謝Keith!我已經選擇了答案,但是你的答案和其他答案一樣好。 –

+0

@DavidPrun:謝謝。 http://meta.stackexchange.com/a/5235/167210 –