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);
}

据我所知,headis 类型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一个定义新类型的宏,一个结构,它是您的数据结构,第一个参数的名称和第二个参数的条目类型。

您应该只调用STAILQ_HEAD一次来定义结构的类型- 然后您使用该类型名从那里创建这种类型的新数据结构。

您在代码示例中所做的很简单:您定义了一个名为stailhead两次的结构 - 一次在全局范围内,一次在main函数范围内。然后,您将指向本地的指针传递给stailhead接受具有相同名称的全局类型的函数。

尽管两个结构相同,但它们位于两个不同的存储范围内,编译器将它们视为不同的类型。它警告您您正在从类型转换main::stailhead为类型global::stailhead(请注意,我刚刚编造了这个符号,我不相信它是佳能)。

您只需要在文件顶部stailhead调用STAILQ_HEAD一次宏来定义,然后从那里使用struct stailhead来定义这种类型的对象。

于 2012-04-06T06:05:43.013 回答