6

这种结构用作链表的头部:

struct lista
{
    struct lista* next;
    struct lista* prev;
};

当 next 和 prev 都指向 struct 本身时,列表为空。以下宏可用于初始化结构:

#define LISTA_INIT_EMPTY(list) { .next = (list), .prev = (list) }

这边走:

struct lista my_list = LISTA_INIT_EMPTY(&my_list);

但是,有没有办法通过以下方式做同样的事情,没有宏参数?:

struct lista my_list = LISTA_INIT_EMPTY;

我尝试了以下方法,但它导致了编译错误:

#define LISTA_INIT_EMPTY     { .next = &.next, .prev = &.next }
4

5 回答 5

6

好吧,我看到的唯一方式是不愉快:

#define LISTA_INIT_EMPTY     { .next = (&my_list), .prev = (&my_list) }

一点都不好,因为它仅在您的变量被调用时才有效my_list。并且没有thisC 中不存在的好方法。

为什么不使用NULL而不是指向“this”?如果这不令人满意,保留参数化宏可能是最好的。

编辑:(感谢 R 在下面的评论,我终于明白了需要):

由于没有“this”并且只输入一次变量的名称,我建议使用这样的宏:

#define CREATE_EMPTY_LISTA(name) struct lista name = { .next=&name, .prev=&name }

稍后在代码中:

CREATE_EMPTY_LISTA(my_list); // creates and initializez my_list at the same time
于 2011-08-23T13:52:51.827 回答
2

请注意,您的列表初始化技术与 Linux 内核源代码中用于链接列表 ( include/linux/list.h) 的技术相似。

在声明列表头时初始化列表,而不是尝试执行以下操作:

// won't work:
struct lista my_list = /* something or other */;

Linux 使用一个宏来执行声明和初始化(因此用户仍然必须只使用一次名称)。对于您struct lista来说,它可能看起来像:

#define LISTA_HEAD struct lista name = LISTA_INIT_EMPTY(name)

// this is all the user needs to do to both declare and initialize a list:
LISTA_HEAD(my_list);

看看include/linux/list.h所有的细节。对于列表操作的工作方式也有很好的解释(并非所有内容都是直观的):

于 2011-08-23T14:56:27.650 回答
0

并不真地!如果您将空定义为 NULL 而不是“本身”,那么您可以通过以下方式进行:

#define LISTA_INIT_EMPTY {NULL,NULL}

于 2011-08-23T13:50:03.757 回答
0

显然这是不可能的,因为块需要知道实例。

由于类型不匹配,也.next = &.next将不起作用。(struct lista*struct lista**

于 2011-08-23T13:53:12.013 回答
0

不,您的初始化程序创建 astruct lista然后分配my_list给它。在这种情况下,您对 a 的想法this没有意义,my_list直到它被分配后才会指向。

于 2011-08-23T13:53:42.647 回答