2009-02-05 47 views
5

我遇到了一些讀碼何時不需要typedef?

typedef enum eEnum { c1, c2 } tagEnum; 

typedef struct { int i; double d; } tagMyStruct; 

我聽到傳言,這些結構從C.日期在C++中,你可以很容易地編寫

enum eEnum { c1, c2 }; 
struct MyStruct { int i; double d; }; 

是真的嗎?你什麼時候需要第一個變體?

回答

10

首先,這兩個聲明在C和C++都是合法的。但是,在C語言中,它們有稍微不同的語義。 (特別是,你後來引用結構體的方式會有所不同)。

理解的關鍵概念是在C中,結構存在於一個單獨的名稱空間中。 所有內置類型以及typedef都存在於「默認」命名空間中。也就是說,當我輸入int時,編譯器只檢查這個「默認」命名空間。如果我在你的例子中鍵入「tagMyStruct」,編譯器也只檢查這個命名空間。但是,根據您使用哪種類型的聲明,該結構可能不存在於該名稱空間中。

結構不同,存在於單獨的名稱空間中。所以,如果我做如下聲明:

struct mystruct {}; 

簡單地將其稱爲MYSTRUCT。相反,我必須指定我想要存在於struct命名空間中的mystruct:

void foo(struct mystruct bar); // Declare a function which takes a mystruct as its parameter 

從長遠來看,它有點冗長和尷尬。相反,你可以的typedef它變成默認的命名空間:

typedef struct mystruct mystruct; // From now on, 'mystruct' in the normal namespace is an alias for 'mystruct' in the struct namespace 

,現在,我的功能,可以在簡單的方式聲明:

void foo(mystruct bar); 

所以,你的第一個例子簡單合併這兩個步驟一起:聲明一個結構,並將一個別名放入常規名稱空間。當然,因爲無論如何我們都在對它進行typedeff,所以我們不需要「原始」名稱,所以我們可以使結構匿名。所以,你的宣言

typedef struct { int i; double d; } tagMyStruct; 

後,我們有沒有名字,已Typedef的在默認命名空間「tagMyStruct」一個結構。

這就是C如何對待它。這兩種聲明都是有效的,但是不會在「默認」命名空間中創建別名,所以每次引用該類型時都必須使用struct關鍵字。

在C++中,單獨的struct命名空間不存在,所以它們的意思是相同的。 (但較短的版本是首選)。

編輯要明確,不,C沒有名稱空間。不是通常意義上的。 C只需將標識符置於兩個預定義的名稱空間之一中。我記得結構體(和枚舉)的名稱被放在一箇中,而所有其他標識符放在另一箇中。從技術上講,這些是命名空間,因爲它們是單獨的「容器」,其中放置名稱以避免衝突,但它們當然不是C++/C#意義上的命名空間。

+0

好的解釋 – Eclipse 2009-02-05 16:49:49

1

這只是速記。

在第二種情況下,申報你會做這樣結構用:

struct MyStruct a; 

在第一變,你會這樣寫:

tagMyStruct a; 
+0

它也是C的縮寫嗎?或者你只提到C++? – xtofl 2009-02-05 15:58:03

0

第二個變體還存在於C.

,只要你希望把你的類型,例如可以使用第一種變體:

tagEnum myFunc(tagMyStruct * myArg); 
0

第一個可能在C++中不方便,因爲你不能在一個頭文件中轉發它。

10

在C,如果你寫

struct MyStruct { int i; double d; }; 

,只要你想引用類型,你必須指定你在談論一個結構:

struct MyStruct instanceOfMyStruct; 
struct MyStruct *ptrToMyStruct; 

隨着typedef的版本:

typedef struct { int i; double d; } tagMyStruct; 

你只需要編寫:

tagMyStruct instanceOfMyStruct; 
tagMyStruct *ptrToMyStruct; 

typedef'd版本的另一個重大優勢是,您可以在C和C++中以相同的方式引用結構,而在第二個版本中,它們在C中的引用與C++中的不同。

+0

將「只需要寫入」版本是「tagMyStruct ...」ISO「MyStruct」?或者這是正確的? (這是違反直覺的......) – xtofl 2009-02-05 15:57:29