在用 C 编写代码时,我通常会忽略使用宏,但我认为我了解它们的基础知识。当我阅读 linux 内核中 list 的源代码时,我看到了这样的东西:
#define LIST_HEAD_INIT(name) { &(name), &(name) }
#define LIST_HEAD(name) \
struct list_head name = LIST_HEAD_INIT(name)
(您可以从 here. 访问代码的剩余部分)
我不理解 LIST_HEAD_INIT 中 & 符号的功能(我不认为它们是这里操作数的地址),因此在代码中使用 LIST_HEAD_INIT。如果有人能启发我,我将不胜感激。
最佳答案
要知道实际发生了什么,我们需要定义 struct list_head
:
struct list_head {
struct list_head *next, *prev;
};
现在考虑宏:
#define LIST_HEAD_INIT(name) { &(name), &(name) }
#define LIST_HEAD(name) struct list_head name = LIST_HEAD_INIT(name)
如果在我编写的代码中 LIST_HEAD(foo)
它会扩展为:
struct list_head foo = { &(foo) , &(foo)}
表示一个带有头节点的空双向链表,其中next
和prev
指针指向头节点本身。
这等同于:
struct list_head foo;
foo.next = &foo;
foo.prev = &foo;
这些宏非常有效地提供了一种初始化双向链表的方法。
是的,&
在这里用作运算符的地址。
编辑:
这是一个working example
在您提供的链接中。你有:
struct list_head test = LIST_HEAD (check);
这是不正确的。你应该:
LIST_HEAD (check);
关于Linux 内核代码中的 C 宏扩展,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2673728/