點當試圖發現在一些開源的C項目的代碼什麼的,我經常看到這樣的typedef:只是不明白這些類型定義
typedef struct _StructA StructA;
typedef struct _LinusTorvalds LinusTorvalds;
爲什麼不直接定義和使用StructA ,只是StructA,而不是定義_DINDOWS_DINDOWS_MODE,然後「typedef」呢?
這個「_」技術有什麼意義?
點當試圖發現在一些開源的C項目的代碼什麼的,我經常看到這樣的typedef:只是不明白這些類型定義
typedef struct _StructA StructA;
typedef struct _LinusTorvalds LinusTorvalds;
爲什麼不直接定義和使用StructA ,只是StructA,而不是定義_DINDOWS_DINDOWS_MODE,然後「typedef」呢?
這個「_」技術有什麼意義?
在C語言中,一個結構必須被用作:
struct _StructA my_variable;
...即,必須鍵入struct
不僅在定義struct
,而且每次使用它。當你使用它時,typedef
消除了struct
的鍵入(但是當你定義它的時候沒有:沒有辦法消除它)。隨着typedef
然後,宣告struct
的實例就變成了:
StructA my_variable;
現在,這並不能完全解釋_StructA
/StructA
業務在struct
/typedef
的定義,你可以這樣做:
typedef struct {
...
} StructA;
...在這裏,我們採取匿名struct
並立即將其送到typedef
。但是使用這種方法,你不能在內部使用struct
,因爲它沒有名字。爲此,您需要類似於:
typedef struct _Foo {
int data;
struct _Foo *next;
} Foo;
它可以減少對某個數據結構的依賴性。例如。如果您想要使用StructB
(可能包含更多字段)而不是StructA
,則只需更改一行而不是幾百行。
它提供了每次聲明結構變量時不使用關鍵字struct
的便利。
沒有的typedef:
struct _StructA obj;
用typedef:
StructA obj;
在C中,當你定義一個結構類型:
struct StructA {
int foo;
double bar;
};
類型的名字是struct StructA
,而不僅僅是StructA
。 (C++可以讓你把類型稱爲StructA
; C++是一種不同的語言
如果你堅持要有一個單詞的名字,你可以使用typedef(我們應該注意到,它會創建一個新的命名爲現有的類型,而不是一個新的類型):
typedef struct StructA StructA;
現在,你可以參考的類型無論是作爲StructA
或struct StructA
。
這些可以合併成一個單一的聲明:
typedef struct StructA {
int foo;
double bar;
} StructA;
注意,我使用的相同的標識符標籤結構和用於typedef的。由於它們在不同的命名空間中,所以這是完全有效的。
另一方面,我自己的選擇是完全省略typedef,只是指類型爲struct StructA
。
順便說一下,您的問題中的名稱_StructA
和_LinusTorvalds
保留給實施,不應在您自己的代碼中使用。一般來說,應避免以下劃線開頭的標識符。 (使用這種標識符的情況並不少見,但這是錯誤的,除非代碼是C實現本身的一部分。)
總結:只有當您希望爲類型指定一個單詞時,typedef纔是必需的(這不是真的需要) - 如果你使用typedef,沒有真正的理由爲typedef和struct標籤使用不同的標識符。
+1,但是你在第三個snipset中忘了'typedef'。作爲一個挑選,類型也是C++中的struct StructA。如果沒有歧義,C++只允許你省略'struct',也就是說沒有其他標識符在同一個範圍內聲明。以'struct stat'爲例。 –
@JensGustedt:感謝nitpicks! –
這種類型的typedef廣泛用於Glib/Gtk和ibus庫的源代碼: – perfwill
請注意,下劃線與此技術無關。 'typedef struct StructA StructA;'也可以。 C使用'標籤'命名結構,而這些標籤可以與typedef'd類型具有相同的名稱。 – Matthew
我認爲LinusTorvalds typedef是個不好的例子,因爲他不喜歡typedefs:http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=blob;f= Documentation/CodingStyle#l268 :) –