0

リンクリストを学びに来ました。しかし、連結リストを構造体で宣言するいくつかの方法にかなり混乱しています。

これは一つの方法であり、

typedef struct Nodetag {
int dataNum;
struct Nodetag* nextNode;
} NODE;

これは typedef を使用しない別の方法です

struct NODE {
int dataNum;
struct NODE* nextNode;
};

で宣言しているとき、コンパイラに何が何であるかを知らせるためtypedefにが使用されていることを知っています。しかし、では、の実際の識別子は何ですか? または?ある場合、いつ使用されますか?Nodetagstruct Nodetag* nextNode;structNodetagNODENodetagNODE

4

4 に答える 4

6

struct Nodetagまたはのように、必要に応じて構造体にタグを付けることができますstruct NODE。これらのタグ (およびユニオン タグと列挙型タグ) は、通常の識別子とは別の名前空間にあります。

typedefバージョンは次のエイリアスを作成しstruct Nodetagます。

typedef struct Nodetag { ... } NODE;

NowNODEは、 のシノニムまたはエイリアスである、通常の識別子名前空間の型名ですstruct Nodetag

次のように書くこともできます。

typedef struct Nodetag NODE;

struct Nodetag
{
    int   dataNum;
    NODE *nextNode;
};

最初の行は、「タグ付きの構造型が存在し、この型のエイリアスです」Nodetagと述べています。NODE2 番目のブロックは、「これらのアイテムで構成されている」と述べ、aをメンバーの 1 つとしてstruct Nodetagリストしています。NODE *


C と C++ は 2 つの異なる言語です

この質問には C のタグが付けられており、C の回答が直接得られていることに注意してください (これは良いことです)。ただし、C++ に遭遇したことがある場合は、次のことがわかります。

struct Nodetag
{
    int      dataNum;
    Nodetag *nextNode;
};

は有効な C++でありNodetag、通常の識別子の名前空間 (およびNodetag(構造) タグの名前空間のタグ) に型名を生成します。これは C では有効ではありません。最終的に C++ コンパイラを使用して C をコンパイルすると、混乱する可能性があります。コードですが。

于 2013-03-21T00:13:25.957 に答える
3

これ:

struct Nodetag {
    /* ... */
};

という名前のタイプを作成しますstruct Nodetag。同様に、これは:

struct NODE {
    /* ... */
};

という名前のタイプを作成しますstruct NODE

どちらの場合でも、その宣言を宣言でラップしてtypedef、同じ型の 2 番目の名前を作成できます。

typedef struct S {
    /* ... */
} T;

struct Sこれにより、タイプを asまたは asとして参照できますT。(ただ呼び出すことはできませんSが、C ではなく C++ でプログラミングしている場合は呼び出すことができます。)

上記を同等に書くと、次のようになります。

struct S {
    /* ... */
};
typedef struct S T;

構造体タグと typedef 名は異なる名前空間にあることに注意してください (「名前空間」という言葉の C++ の意味ではありません)。構造体タグはキーワードの後に​​のみ続くことができるためstructです。したがって、それらを区別する必要はありません。

typedef struct Node {
    /* ... */
} Node;

struct Nodeこれで、タイプを asまたはas として参照できるようになりましたNode

このように typedef を追加しても大きな利点はありません。必要に応じて、省略して型を として参照できますstruct Node。(しかし、多くの C プログラマーは、型に 1 語の名前を使用できることを好み、typedef はそれを行う唯一の良い方法です (a#defineはそれを行う別の方法ですが、良い方法ではありません。)

タグ名を省略して typedef のみを使用することもできます。

typedef struct {
    /* ... */
} Node;

これにより、匿名の構造体型が得られ、それを参照する名前がすぐに作成Nodeされます。しかし、このアプローチではNode、構造体の定義が終了するまで名前が表示されないため、構造体にそれ自体へのポインターを含めることはできません。

于 2013-03-21T00:16:15.247 に答える
0

最初の構造体が呼び出されstruct Nodetag、2 番目の構造体が呼び出されstruct NODEます。

最初の例では、 の「エイリアス」となる typedef が定義されていますがNODEstruct Nodetag構造体の名前は変更されません。それが行うことは、たとえば、NODE*ではなく入力できるようにすることですstruct Nodetag*。それは省略形であり、それ以上のものではありません。

于 2013-03-21T00:09:51.667 に答える
0

構造体のタグと型は、異なる名前空間に存在します。struct nodeaと typeを持つことができますnodestruct構造タグは、それらを区別するために指定子/接頭辞とともに使用する必要があります。あなたがするとき:

typedef struct Nodetag {
int dataNum;
struct Nodetag* nextNode;
} NODE;

新しいタイプを定義し、構造タグも定義していますが、便宜上、タイプを定義する必要はありません。構造体定義内では、コンパイラはその部分を読み取るまで型を認識しない} NODE;ため、構造体タグを使用して定義している構造体を参照する必要があります。

于 2013-03-21T00:12:52.867 に答える