gpt4 book ai didi

C: sys/queue.h - 如何将指向 TAILQ_HEAD() 的指针传递给函数,而不是让 TAILQ_HEAD() 成为全局函数?

转载 作者:太空宇宙 更新时间:2023-11-04 06:51:04 24 4
gpt4 key购买 nike

这里是 C 的新手。我正在使用 sys/queue.h做一个简单的队列。我在 SO 和 Google 上搜索了很多,但找不到解决这个特定问题的方法。

这很好用:

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

TAILQ_HEAD(, q_item) head;

typedef struct q_item {
int value;
TAILQ_ENTRY(q_item) entries;
} q_item;

void enqueue(int n) {
// enqueue the node with value n
q_item *item;
item = malloc(sizeof(q_item));
item->value = n;
printf("queued %d\n", item->value);
TAILQ_INSERT_TAIL(&head, item, entries);
}

void dequeue() {
q_item *returned_item;
returned_item = TAILQ_FIRST(&head);
printf("dequeued %d\n", returned_item->value);
TAILQ_REMOVE(&head, returned_item, entries);
free(returned_item);
}

int main() {

TAILQ_INIT(&head);

enqueue(1);
enqueue(2);
enqueue(3);

dequeue();

return 0;
}

我知道一般来说应该避免使用全局变量。虽然我也知道 TAILQ_HEAD() 是一个宏,所以也许这会改变我对此的看法。无论如何,这不会编译:

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

typedef struct q_item {
int value;
TAILQ_ENTRY(q_item) entries;
} q_item;

void enqueue(int n, TAILQ_HEAD(, q_item) * head) {
// enqueue the node with value n
q_item *item;
item = malloc(sizeof(q_item));
item->value = n;
printf("queued %d\n", item->value);
TAILQ_INSERT_TAIL(head, item, entries);
}

void dequeue(TAILQ_HEAD(, q_item) * head) {
q_item *returned_item;
returned_item = TAILQ_FIRST(head);
printf("dequeued %d\n", returned_item->value);
TAILQ_REMOVE(head, returned_item, entries);
free(returned_item);
}

int main() {

TAILQ_HEAD(, q_item) head; // <-- I've moved TAILQ_HEAD into main()
TAILQ_INIT(&head);

enqueue(1, &head);
enqueue(2, &head);
enqueue(3, &head);

dequeue(&head);

return 0;
}

当我尝试编译后者时,出现以下错误。它们没有帮助,因为我无法区分 ‘struct <anonymous> *’‘struct <anonymous> *’ .

test_tailq_noglobal.c:32:13: warning: passing argument 2 of ‘enqueue’ from incompatible pointer type [-Wincompatible-pointer-types]
enqueue(1, &head);
^
test_tailq_noglobal.c:10:6: note: expected ‘struct <anonymous> *’ but argument is of type ‘struct <anonymous> *’
void enqueue(int n, TAILQ_HEAD(, q_item) * head) {
^~~~~~~

我知道 TAILQ_HEAD 的手册页显示您可以定义以下内容:

TAILQ_HEAD(tailhead, entry) head;
struct tailhead *headp; /* Tail queue head. */

但我不确定如何处理这个 struct tailhead *headp .我试过将它作为指针传递而不是 &head如下所示,但这似乎也不起作用:

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

typedef struct q_item {
int value;
TAILQ_ENTRY(q_item) entries;
} q_item;

void enqueue(int n, struct headname *headp) {
// enqueue the node with value n
q_item *item;
item = malloc(sizeof(q_item));
item->value = n;
printf("queued %d\n", item->value);
TAILQ_INSERT_TAIL(headp, item, entries);
}

void dequeue(struct headname *headp) {
q_item *returned_item;
returned_item = TAILQ_FIRST(headp);
printf("dequeued %d\n", returned_item->value);
TAILQ_REMOVE(headp, returned_item, entries);
free(returned_item);
}

int main() {

TAILQ_HEAD(headname, q_item) head;
struct headname *headp;
TAILQ_INIT(headp);

enqueue(1, headp);
enqueue(2, headp);
enqueue(3, headp);

dequeue(headp);

return 0;
}

错误:

test_tailq_headp.c: In function ‘dequeue’:
test_tailq_headp.c:21:18: error: dereferencing pointer to incomplete type ‘struct headname’
returned_item = TAILQ_FIRST(headp);
^
test_tailq_headp.c: In function ‘main’:
test_tailq_headp.c:33:13: warning: passing argument 2 of ‘enqueue’ from incompatible pointer type [-Wincompatible-pointer-types]
enqueue(1, headp);
^~~~~
test_tailq_headp.c:10:6: note: expected ‘struct headname *’ but argument is of type ‘struct headname *’
void enqueue(int n, struct headname *headp) {
^~~~~~~

有人可以告诉我我做错了什么,无论是在我的代码中还是在我思考这个问题的方式中?谢谢。

最佳答案

我从来没有使用过这个队列,但我发现的一种方法是在 q_item 本身中添加 TAILQ_HEAD() 。它有助于避免全局使用 head。

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

typedef struct q_item {
int value;
TAILQ_ENTRY(q_item) entries;
TAILQ_HEAD(, q_item) head;
} q_item;

void enqueue(int n, q_item *q) {
// enqueue the node with value n
q_item *item;
item = malloc(sizeof(q_item));
item->value = n;
printf("queued %d\n", item->value);
TAILQ_INSERT_TAIL(&q->head, item, entries);
}

void dequeue(q_item *q) {
q_item *returned_item;
returned_item = TAILQ_FIRST(&q->head);
printf("dequeued %d\n", returned_item->value);
TAILQ_REMOVE(&q->head, returned_item, entries);
free(returned_item);
}

int main() {

q_item q;
TAILQ_INIT(&q.head);

enqueue(1, &q);
enqueue(2, &q);
enqueue(3, &q);

dequeue(&q);
dequeue(&q);

return 0;
}

查看这个宏如何扩展可能也很有用,只需使用 gcc 编译即可。使用 -E选项,你会看到例如 TAILQ_HEAD(, qitem) head扩展到

struct {
struct q_item *tqh_first;
struct q_item **tqh_last;
} head;

您也可以在 <sys/queue.h> 中找到它header

/*
* Tail queue definitions.
*/
#define TAILQ_HEAD(name, type) \
struct name { \
struct type *tqh_first; /* first element */ \
struct type **tqh_last; /* addr of last next element */ \
}

这就是为什么你尝试使用 void enqueue(int n, TAILQ_HEAD(, q_item) * head)没有工作,因为预处理器进行了简单的替换。

关于C: sys/queue.h - 如何将指向 TAILQ_HEAD() 的指针传递给函数,而不是让 TAILQ_HEAD() 成为全局函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51290070/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com