6

この種の構造体は、リンクリストの先頭として使用されます。

struct lista
{
    struct lista* next;
    struct lista* prev;
};

nextとprevの両方がそれ自体を構造化することを指している場合、リストは空です。構造を初期化するには、次のマクロを使用できます。

#define LISTA_INIT_EMPTY(list) { .next = (list), .prev = (list) }

こちらです:

struct lista my_list = LISTA_INIT_EMPTY(&my_list);

しかし、マクロパラメータなしで次の方法で同じことを行う方法はありますか?:

struct lista my_list = LISTA_INIT_EMPTY;

次のことを試しましたが、コンパイルエラーが発生しました。

#define LISTA_INIT_EMPTY     { .next = &.next, .prev = &.next }
4

5 に答える 5

6

まあ、私が見る唯一の方法は不快です:

#define LISTA_INIT_EMPTY     { .next = (&my_list), .prev = (&my_list) }

変数が呼び出された場合にのみ機能するため、まったく良くありませんmy_list。そしてthis、C に存在しないような良い方法はありません。

NULL「これ」を指す代わりに使用しないのはなぜですか?これで満足できない場合は、パラメーター化されたマクロを維持するのがおそらく最善です。

編集:(以下のRのコメントのおかげで、私は最終的に必要性を理解しました):

「this」がなく、変数の名前を一度だけ入力するため、次のようなマクロを使用することをお勧めします。

#define CREATE_EMPTY_LISTA(name) struct lista name = { .next=&name, .prev=&name }

そしてコードの後半:

CREATE_EMPTY_LISTA(my_list); // creates and initializez my_list at the same time
于 2011-08-23T13:52:51.827 に答える
2

リストの初期化手法は、リンクされたリストの Linux カーネル ソースで使用されているものと似ていることに注意してください ( include/linux/list.h)。

次のようなことを試みる代わりに、リストの先頭が宣言されているときのリストの初期化の場合:

// won't work:
struct lista my_list = /* something or other */;

Linux は、宣言と初期化の両方を実行するマクロを使用します (したがって、ユーザーは名前を一度だけ使用する必要があります)。あなたの場合、次のstruct listaようになります。

#define LISTA_HEAD struct lista name = LISTA_INIT_EMPTY(name)

// this is all the user needs to do to both declare and initialize a list:
LISTA_HEAD(my_list);

include/linux/list.hすべての詳細については、をご覧ください。リスト操作がどのように機能するかについての素晴らしい説明もあります (すべてが直感的というわけではありません)。

于 2011-08-23T14:56:27.650 に答える
0

あまり!空を「それ自体」ではなく NULL として定義する場合は、次の方法で実行できます。

#define LISTA_INIT_EMPTY {NULL,NULL}

于 2011-08-23T13:50:03.757 に答える
0

ブロックはインスタンスを知る必要があるため、明らかにこれは不可能です。

また.next = &.next、型が一致しないため動作しません。(struct lista*struct lista**)

于 2011-08-23T13:53:12.013 に答える
0

いいえ、イニシャライザは を作成してstruct listaから割り当てmy_listます。あなたの a の考えは、thisこのコンテキストでは意味がありませんmy_list。それが割り当てられるまで指し示すことはありません。

于 2011-08-23T13:53:42.647 に答える