我會要求API用戶鍵入「*」,即typedef結構,而不是指向結構的指針。這是GLib中廣泛使用的風格,它是更受歡迎的C棧之一。
它工作得很好,因爲它是重要的是要知道你是否有一個指向結構或結構本身的指針。例如,你可以將NULL存儲在類型的變量中嗎?如果隱藏某個對象是一個指針,則必須創建一個特殊的NIL_NODE或其他值來替換NULL。如果你只是把它作爲一個指針,那麼人們可以像一個對待它。
另一個重要的好處是可以將實際的結構定義置於某處,即在.c文件中而不是頭文件中。你可以在頭文件中只放入typedef,同時保持結構本身對API用戶不透明。這要求人們只使用您提供的導出方法來操縱結構。這也意味着如果您更改結構字段,則不必重建世界。
採取這種方式的另一個原因是,有時您確實需要一個可以複製的結構,而您仍然想要typedef。拿一個東西一樣GdkPoint:
typedef struct {
int x, y;
} GdkPoint;
這是非常有用的,允許直接結構訪問,如:
GdkPoint point = { 10, 10 };
GdkPoint copy = point;
do_stuff_with_point(©);
但是,如果你的約定是「GdkPoint」的typedef將是一個指針,你」將不得不不一致。
如果您可以告訴指針是什麼,什麼不指定,那麼代碼就更清晰了,如果您沒有在頭文件中放置結構定義,代碼會更好地封裝(對於代表抽象,不透明數據類型的結構也許是最常見的一種)。
爲C數據類型我的默認模板是這樣的標題:
typedef struct MyType MyType;
MyType* my_type_new(void);
void my_type_unref(MyType *t);
void my_type_ref(MyType *t);
然後在.c文件的實際「結構的MyType」,用新的UNREF一起,任何類型上的操作。
例外情況是類型如點,矩形,顏色,它是「普通的舊數據」和直接字段訪問是理想的;如果你不需要refcounting,另一個變種是有一個my_type_free()而不是_unref()。
無論如何,這是一種風格,基本上是GLib風格,它被廣泛使用,並且被認爲運作良好。
類似的問題:http://stackoverflow.com/questions/3781932/is-typedefing-a-pointer-type-considered-bad-practice – 2011-02-24 00:03:17
或兩者都不... :) – alternative 2011-02-24 00:16:56