【问题标题】:C linked-list append to head or tail?C链表追加到头部还是尾部?
【发布时间】:2016-01-17 22:25:15
【问题描述】:

我正在查看这段代码,实现了在双向链表中插入元素的操作。我试图理解为什么LIST_APPEND 宏将它附加到列表的末尾,但是,我总是向自己解释它是领先的。代码:

struct link {
    struct link *prev;
    struct link *next;
};

void insert(struct link *prev, struct link *new, struct link *next)
{
    prev->next = new;
    new->prev = prev;
    next->prev = new;
    new->next = next;
}

#define LIST_APPEND(member, list, new)    \
    insert(list.prev, &(new->member), &list)

我的考虑:

首先,C-Preprocessor 在实际代码中替换宏的内容后,我们得到

void insert(list.prev, &(new->member), &list)
{
    (list.prev)->next = (new->member);    //1.
    (new->member)->prev = list.prev;      //2.
    list->prev = (new->member);           //3.
    (new->member)->next = list;           //4.
}

对应于:
1.list.prev的next指向(new->member)
2. (new->member)的prev现在是list.prev
3. list的prev现在是(new->member)
4.(new->member)的下一个是list

如果我的逻辑中有流动,它们可能就在这里。

现在为了说明这一点,这里是一个可能的(据我理解)插入的描述。

问题:到底追加是在头部还是尾部?如果是后者,我哪里错了?

【问题讨论】:

  • 您能否提供一个如何调用宏的示例?你作为“成员”传递了什么?
  • 你应该保护扩展中的宏参数:`#define LIST_APPEND(member, list, new) insert((list).prev, &((new)->member), &(list) )
  • "首先,在 C 预处理器在实际代码中替换宏的内容后,我们得到......" - 不是??预处理器不会改变insert。它将LIST_APPEND(a, b, c) 更改为insert(b.prev, &(c->a), &b)。
  • @immibis 是的,当然。这就是我所说的(意思)。 insert 已定义。它只是用宏参数调用它
  • 完全偏离主题,但建议您不要调用变量new,因为这是一个 C++ 关键字。如果你想在未来转向 C++,你只会造成混乱和挖洞。

标签: c insert linked-list macros


【解决方案1】:

在你上面给出的代码中

struct link {
struct link *prev;
struct link *next;
};

void insert(struct link *prev, struct link *new, struct link *next)
{
prev->next = new;
new->prev = prev;
next->prev = new;
new->next = next;
}

#define LIST_APPEND(member, list, new)    \
insert(list.prev, &(new->member), &list)

这里insert(struct link *prev, struct link *new, struct link *next)函数在前一个节点和下一个节点之间插入一个新节点。

这里insert()函数struct link *prev, struct link *new, struct link *next是struct link类型的指针变量

在双向链表中,不需要在头部或尾部附加节点。这完全取决于程序员选择在双向链表中添加新节点的位置。

【讨论】:

  • 是的,原来封闭结构是空的(宏中的“list”),所以确实如图所示,但是由于“list”是空的,所以是tail。下一个元素将是“new->member”的“prev”。简而言之,这真的取决于使用情况。经验教训。
猜你喜欢
  • 2011-11-06
  • 1970-01-01
  • 2019-07-17
  • 2020-06-23
  • 2012-09-22
  • 2018-01-27
  • 1970-01-01
  • 1970-01-01
  • 2017-08-05
相关资源
最近更新 更多