web-dev-qa-db-ja.com

それ自体へのポインタを含むtypedef構造体を定義する方法は?

私はCでLinkedListを書いています、以下のコードは私のNodeの定義を表します。

typedef struct {
    int value;
    struct Node* next;
    struct Node* prev;
} Node;

struct Nodetypedef struct Nodeと同じではないことを理解しています(またはそうすると思います)。コードが想定どおりにコンパイルおよび実行されることを認めたが、nextおよびprev(警告:互換性のないポインター型からの割り当て)を割り当てると、多くの警告が表示されます。これは、Node構造でそれらを定義する方法に関係していると推測しています。完全なソースをアップロードしました here

それで、もしそれが本当に問題であれば、どのようにnextprevtypedef struct Nodeの中に定義すべきでしょうか?

これは再投稿かもしれないと心配していましたが、探しているものを見つけることができませんでした。ありがとう。

33
Kenny Cason

次の順序で実行する必要があります。

typedef struct Node Node;

struct Node
{
  int value;
  Node *next;
  Node *prev;
};

それはあなたが要求したことを正確にはしませんが、それは問題を解決し、これが一般的に行われる方法です。もっと良い方法はないと思います。

この種の前方宣言には、データ隠蔽における2番目の使用法があります。リストがライブラリに実装されている場合、次のような関数とともに、パブリックヘッダーにtypedefだけを含めることができます。

Node * list_new(void);
Node * list_append(Node *head, Node *new_tail);
size_t list_length(const Node *head);

この方法では、ライブラリのユーザーはライブラリの内部、つまりNode構造体のフィールドに簡単にアクセスできません。

64
unwind

OPのコードへの変更を最小限に抑えた別の受け入れ可能な方法は次のとおりです。

typedef struct NodeT {
    int value;
    struct NodeT * next;
    struct NodeT * prev;
} Node;

NodeTが導入されるまで、nextの導入とprevNodeでの使用に注意してください。

25
Arun