結果の型のポインターの性質が重要でない場合にのみ、ポインター型定義を使用します。たとえば、たまたまポインターとして実装されているが、ユーザーがポインターとして使用できるとは想定されていない不透明な「ハンドル」型を宣言したい場合、ポインター typedef は正当化されます。
typedef struct HashTableImpl *HashTable;
/* 'struct HashTableImpl' is (or is supposed to be) an opaque type */
上記の例でHashTable
は、ハッシュ テーブルの「ハンドル」です。ユーザーは、最初にそのハンドルを関数などから受け取り、CreateHashTable
それを関数などに渡しHashInsert
ます。HashTable
ユーザーは、それがポインターであることを気にする必要はありません (または知っていることさえありません) 。
しかし、型が実際にはポインターであり、ポインターとして使用できることをユーザーが理解している場合、ポインターの型定義はコードを大幅に難読化しています。私はそれらを避けます。ポインターを明示的に宣言すると、コードが読みやすくなります。
C 標準ライブラリがそのようなポインタの型定義を回避していることに注目するのは興味深いことです。たとえば、FILE
は明らかに不透明な型として使用されることを意図しています。これは、ライブラリが常に使用するのではtypedef FILE <some pointer type>
なく、として定義できたことを意味しFILE *
ます。しかし、何らかの理由で、彼らはそうしないことにしました。