2

Freebsdのキュー(3)マクロの内部動作を理解しようとしています。同じトピックについて以前に質問しましたが、これはフォローアップの質問です。

要素をキューに挿入する関数を定義しようとしています。queue(3)STAILQ_INSERT_HEADは、キューの先頭へのポインター、キュー内のアイテムのタイプ、および挿入されるアイテムを必要とするマクロを提供します。私の問題は私が得ているということです

stailq.c:31: warning: passing argument 1 of 'addelement' from incompatible pointer type

のアドレスを関数に渡そうとするとエラーが発生しheadます。完全なソースコードは次のとおりです。

#include <stdio.h>
#include <stdlib.h>
#include <sys/queue.h>

struct stailq_entry {
        int value;
        STAILQ_ENTRY(stailq_entry) entries;
};

STAILQ_HEAD(stailhead, stailq_entry);

int addelement(struct stailhead *h1, int e){
        struct stailq_entry *n1;
        n1 = malloc(sizeof(struct stailq_entry));
        n1->value = e;
        STAILQ_INSERT_HEAD(h1, n1, entries);
        return (0);
}
int main(void)
{
        STAILQ_HEAD(stailhead, stailq_entry) head = STAILQ_HEAD_INITIALIZER(head);
        struct stailq_entry *n1;
        unsigned i;
        STAILQ_INIT(&head);                     /* Initialize the queue. */

        for (i=0;i<10;i++){
                addelement(&head, i);
        }
        n1 = NULL;

        while (!STAILQ_EMPTY(&head)) {
                n1 = STAILQ_LAST(&head, stailq_entry, entries);
                STAILQ_REMOVE(&head, n1, stailq_entry, entries);
                printf ("n2: %d\n", n1->value);
                free(n1);
        }

        return (0);
}

私が知る限り、headは型struct stailheadであり、addelement関数はへのポインタも期待していますstruct stailhead

STAILQ_HEAD(stailhead, stailq_entry);に展開:

struct stailhead {
  struct stailq_entry *stqh_first;
  struct stailq_entry **stqh_last; 
};

ここで何が欠けていますか?

ありがとう。

4

1 に答える 1

2

main関数の最初の行をから変換する必要があります

STAILQ_HEAD(stailhead, stailq_entry) head = STAILQ_HEAD_INITIALIZER(head);

struct stailhead head = STAILQ_HEAD_INITIALIZER(head);

何が起こっているのかというSTAILQ_HEADと、それは新しいタイプを定義するマクロであり、最初のパラメーターの名前と2番目のパラメーターのエントリータイプを持つデータ構造体である構造体です。

構造体のタイプSTAILQ_HEADを定義するために1回だけ呼び出すことになっています。次に、そのタイプ名を使用して、このタイプの新しいデータ構造を作成します。

コードサンプルで行ったことは単純です。2stailhead回という名前の構造体を定義しました。1回はグローバルスコープで、もう1回はmain関数のスコープで行いました。stailhead次に、同じ名前のグローバル型を受け入れる関数へのローカルへのポインターを渡していました。

両方の構造体は同一ですが、それらは2つの異なるストレージスコープにあり、コンパイラーはそれらを別個の型として扱います。main::stailheadタイプからタイプに変換していることを警告していますglobal::stailhead(私はこの表記を作成したばかりであり、それが標準であるとは思わないことに注意してください)。

すでに行ったファイルの先頭でマクロを1回だけstailhead呼び出すことで定義する必要があり、そこからこのタイプのオブジェクトを定義するために使用します。STAILQ_HEADstruct stailhead

于 2012-04-06T06:05:43.013 に答える