私は C プログラミングの初心者ですが、typedef
構造体を定義するときに を使用する場合と使用しない場合の違いは何なのか疑問に思っていましたtypedef
。 実際には違いはなく、同じ目的を達成しているように思えます。
struct myStruct{
int one;
int two;
};
対
typedef struct{
int one;
int two;
}myStruct;
ベストアンサー1
一般的な慣用句では、両方を使用します。
typedef struct S {
int x;
} S;
これらは異なる定義です。議論をより明確にするために、文を分割します。
struct S {
int x;
};
typedef struct S S;
最初の行では、構造体の名前空間内で識別子を定義していますS
(C++ の意味ではありません)。これを使用して、引数の型を次のように定義することで、新しく定義された型の変数または関数の引数を定義できますstruct S
。
void f( struct S argument ); // struct is required here
2 行目は、グローバル名前空間に型エイリアスを追加するS
ので、次のように記述できます。
void f( S argument ); // struct keyword no longer needed
両方の識別子の名前空間は異なるため、S
構造体とグローバル空間の両方を定義してもエラーにはなりません。これは、同じ識別子を再定義するのではなく、別の場所に別の識別子を作成するためです。
違いをより明確にするために:
typedef struct S {
int x;
} T;
void S() { } // correct
//void T() {} // error: symbol T already defined as an alias to 'struct S'
typedef
識別子は異なるスペースに保持されるため、構造体と同じ名前の関数を定義することはできますが、識別子が衝突するため、構造体と同じ名前の関数を定義することはできません。
C++ では、シンボルを見つけるためのルールが微妙に変更されたため、少し異なります。C++ では、2 つの異なる識別子空間が保持されますが、C とは異なり、クラス識別子空間内でのみシンボルを定義する場合は、struct/class キーワードを指定する必要はありません。
// C++
struct S {
int x;
}; // S defined as a class
void f( S a ); // correct: struct is optional
変更されるのは検索ルールであり、識別子が定義されている場所ではありません。コンパイラはグローバル識別子テーブルを検索し、S
見つからない場合はS
クラス識別子内で検索します。
前に紹介したコードも同じように動作します。
typedef struct S {
int x;
} T;
void S() {} // correct [*]
//void T() {} // error: symbol T already defined as an alias to 'struct S'
S
2 行目の関数の定義の後、構造体S
はコンパイラによって自動的に解決できず、オブジェクトを作成したりその型の引数を定義したりするには、次のキーワードを含める必要がありますstruct
。
// previous code here...
int main() {
S();
struct S s;
}