1

次のコードがあるとします。

typedef struct elementT {
  int data;
  struct elementT *next;
} element;

なぜそれを行う必要があり、構造体宣言自体の中でstruct elementT *next行うことができないのですか? element *nextまだ発表されてないからじゃない?

4

4 に答える 4

3

が定義されたtypedef後にのみ実行されます。struct次のコードを検討してください。構文は無効ですが、順序/優先順位が示されていることを期待しています。

typedef (struct {
  int field1, field2;
}) item;

つまり、struct{...}はタイプを表す「式」です。はtypedef、名前を付けることでそのタイプを操作します。

対照的に、

struct foo {
    foo *next;
};

Cの2つの特別なルールのために機能します:struct <name>タイプを定義するだけでstructなく、それにタグを与え、そのタグはstruct宣言の残りの部分の中にすぐに表示されます(明白な理由:リンクリスト、ツリーなどはこれらのルールなしで実装するのは非常に苦痛です)。

于 2013-01-14T21:26:48.283 に答える
2

Cがそう言ったので:

(C99、6.2.1p7)「[...]他の識別子には、宣言子の完了直後に開始するスコープがあります。」

于 2013-01-14T21:26:41.933 に答える
2

型nameelementTの一部である name はstruct elementT、コンパイラが 2 つの tokens を認識するとすぐに (不完全な型として) 見えるようになるstruct elementTため、構造体定義内で型名として使用できます。

typedef名elementである name は、識別子が表示されるまで表示されませんelement。これは、構造体定義の終了 (終了) の後です。}したがって、まだ存在しないという理由だけで、構造体定義内で使用することはできません。

私自身の個人的な好み (そして、多くの非常に賢い人々はこの点で私とは異なります) は、まったく使用typedefしないことです。型にはすでに完全に適切な名前がありstruct ElementTます。なぜ2番目のものを追加するのですか?私はちょうど書くだろう:

struct element {
    int data;
    struct element *next;
};

タイプを として参照しstruct elementます。

型に 1 単語の名前を付けることが十分に役立つと思われる場合は、もちろん、引き続き typedef を使用できます。typedef 名は、宣言が終了するまで表示されないことに注意してください。また、2 つの異なる識別子を使用する必要はありません。

typedef struct element {
    int data;
    struct element *next;
} element;

struct elementこれで、型を asまたは asとして参照できますelement

struct(C++ には異なるルールがあることに注意してください。 (またはunion、、classまたはenum) 型の暗黙的な typedef を効果的に作成します。C++ では、typedefは不要ですが無害です。)

于 2013-01-14T21:30:42.383 に答える
1

構造体宣言をその定義から分離すると、この動作を実現できます。

struct ElementT;                   // not strictly needed

typedef struct ElementT element;   // this declares "struct ElementT" as well

struct ElementT
{
    element * next;
};
于 2013-01-14T21:29:06.367 に答える