不兼容的指针类型 - 为什么?

时间:2012-04-06 05:49:05

标签: c

我试图了解Freebsd中queue (3)宏的内部工作原理。我之前询问了question关于同一主题的问题,这是一个跟进问题。

我正在尝试定义一个将元素插入队列的函数。 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; 
};

我在这里缺少什么?

感谢。

1 个答案:

答案 0 :(得分: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来定义此对象类型。