1. ホーム
  2. c

[解決済み】typedef struct と struct の定義 【重複】typedef struct と struct の定義。

2022-02-21 03:51:24

質問

私はC言語プログラミングの初心者なのですが、このように typedef を使用しない場合と、構造体を定義する際に typedef . 私には、両者に違いはなく、同じ目的を達成するように思えるのです。

struct myStruct{
    int one;
    int two;
};

vs.

typedef struct{
    int one;
    int two;
}myStruct;

解決方法は?

一般的な慣用句は、両方を使うことです。

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;
}