我试图了解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;
};
我在这里缺少什么?
感谢。
答案 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
来定义此对象类型。