さまざまな用途は、型がインターフェイスで使用されるかどうか (のみ)、または構造情報を知る必要があるかどうかを反映しています。
表記:
typedef struct some_obj_s some_obj_t;
some_obj_s
tagと typedef nameを持つ構造体型があることをコンパイラに伝えますsome_obj_t
。この型がユーザーにとって不透明な型である場合、構造の詳細を指定する必要はありません。some_obj_t *
パラメーター (修飾されている可能性があります) を受け取ったり、そのような値を返したりする関数は、詳細情報なしで宣言して使用できます。extern
(コンパイラは主にアドレスを必要とするため、この種の型の変数を宣言することもできます。) 型は不完全 (不透明とも呼ばれます) ですが、完全にすることができます。
実装のどこかに、次のような構造型の定義があります (最も異常な状況を除く)。
struct some_obj_s
{
...members defined...
};
この宣言 (定義) がスコープ内にある場合、型some_obj_t
または型の変数、および型struct some_obj_s
へのポインターを作成できます。コードは、構造体のメンバーを使用できます。
表記:
typedef struct /* no tag */
{
...
} another_obj_t;
タグなしの構造体型を定義します。タイプの詳細が記載されているので、タイプは完成です。
以下も表示される場合があります。
typedef struct yao_s
{
...members defined...
} yao_t;
これは両方とも、そのタグと typedef を使用して構造体の型を宣言します。
個別の typedef には、リストなどの自己参照構造で利点があります。
typedef struct GenericList GenericList;
struct GenericList
{
void *data;
GenericList *next;
GenericList *prev;
};
別の行がなければ、構造体の中typedef
に書く必要があります。struct GenericList
同じ意味です。あなたはまだそれを書くことができます。ただし、個別の typedef を使用すると、後で参照するのと同じ表記法を構造体で使用できます。
POSIX では、実装のために終了する型名が予約されていることに注意してください。_t
つまり、独自のコードでその規則を使用するのは危険な場合があります。
タグと typedef に別々の名前を使用する必要はありませんが (例で示されていGenericList
ます)、サフィックス_s
と_t
サフィックスもかなりよく知られている規則です。C++ は、明示的な typedef を必要とせずにタグを自動的に型名にします (ただし、明示的な typedef は許可されます)。そのため、通常はタグと型に同じ名前を使用します。