web-dev-qa-db-ja.com

sys / queue.hからのリストの使用方法

現在、私は次のようにシングルリンクリストを実装しています:

struct PeerNode {
     struct Peer* cargo;
     struct PeerNode* next;
};

...そして私はこれらのリンクされたリストのいくつかを含む構造体を持っています:

struct Torrent {
     ...
     struct PeerNode* peer_list;
     struct PeerNode* unchoked_peers;
     ...
}

sys/queue.hが提供するマクロを使用してこれを置き換えたいと思います。私は自分のコードを次のようなものに置き換えることができると収集しました:

struct Torrent {
     ...
     LIST_ENTRY(PeerNode, Peer) peer_list;
     struct PeerNode* unchoked_peers;
     ...
}

次に、man queueを見ると、次のようにしてリストを初期化すると思います。

LIST_INIT(&peer_list);
LIST_INIT(unchoked_peers);

ただし、LIST_ENTRYがリストの使用にどのように影響するかはわかりません。 manページから、「マクロLIST_ENTRYはリスト内の要素を接続する構造体を宣言しています」とありますが、これが何を意味するのか本当にわかりません。

リストの要素を接続するための構造を宣言したいのはなぜですか?最初のリンクリストの実装のように、各ノードをポインターを介して次のノードに接続する必要はありませんか?リンクリストをsys/queue.hが提供する実装に置き換えるにはどうすればよいですか?リストに要素を挿入するにはどうすればよいですか?

25
rps

LIST_ENTRYは、要素をリンクするのに適した構造に入れるフィールドを作成するので、これらのポインターの詳細を気にする必要はありません。

struct foo {
    int a, b, c;
    /* This is instead of "struct foo *next" */
    LIST_ENTRY(foo) pointers;
};

次にリストを作成するには、LIST_HEAD()を使用します。

struct Torrent {
    LIST_HEAD(foo_list, foo) bar;
};

LIST_INIT()を使用してリストヘッダーを初期化できます。

struct Torrent t;
LIST_INIT(&t.bar);

LIST_INSERT _ *()マクロを使用して要素を挿入できます:

struct foo *item = malloc(sizeof(struct foo));
LIST_INSERT_HEAD(&t.bar, item, pointers);

これはすべて http://www.manpagez.com/man/3/queue/ のmanページのリストの例から取られました

34
tinman