我遇到了一些讀碼何時不需要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; };
是真的嗎?你什麼時候需要第一個變體?
我遇到了一些讀碼何時不需要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; };
是真的嗎?你什麼時候需要第一個變體?
首先,這兩個聲明在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#意義上的命名空間。
這只是速記。
在第二種情況下,申報你會做這樣結構用:
struct MyStruct a;
在第一變,你會這樣寫:
tagMyStruct a;
它也是C的縮寫嗎?或者你只提到C++? – xtofl 2009-02-05 15:58:03
第二個變體還存在於C.
,只要你希望把你的類型,例如可以使用第一種變體:
tagEnum myFunc(tagMyStruct * myArg);
第一個可能在C++中不方便,因爲你不能在一個頭文件中轉發它。
在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++中的不同。
將「只需要寫入」版本是「tagMyStruct ...」ISO「MyStruct」?或者這是正確的? (這是違反直覺的......) – xtofl 2009-02-05 15:57:29
好的解釋 – Eclipse 2009-02-05 16:49:49