先来看一个不优雅的写法:
remove_list_entry(entry)
{
prev = NULL;
walk = head;
while (walk != entry) {
prev = walk;
walk = walk->next;
}
if (!prev)
head = entry->next;
else
prev->next = entry->next;
}
之所以说上面的代码不够优雅,相信大家肯定能感觉出来,主要就是需要对是否是头结点进行额外的判断,
因为使用了prev这个变量来辅助,那么怎么写才算是优雅呢?如下:
remove_list_entry(entry)
{
indirect = &head;
while ((*indirect) != entry)
indirect = &((*indirect)->next);
*indirect = entry->next;
}
这个代码是不是比上面的更简洁呢。不需要进行额外的处理,同样可以移除节点。
下面简单解释一下,
可以把indirect作为一个指向每个元素next成员的地址,注意不是下一个元素的地址!
(next成员也是元素的一部分,它也占有空间,也有地址)
下一个成员的地址是(*indirect)->next.
那么删除下一个元素节点,直接修改*indirect = new_elem就好了。(最后一行代码)
就是修改了当前节点next的指向。
当要移除head时,indirect为&head, *indirect = entry->next,就让head指向了下一个节点(移除了head).
不从进行额外的处理。
无论是在开始时,还是中间某个结点,indirect都是有意义的,不为NULL, 所以最后一行才可直接修改。
当然,indirect不论指向head还是next域,都是一个二级指针(类型一定)
如下图:
head是个指针,并非链表中的数据内容。
上面的两个代码片段是Linus大神在TED访谈时作的比较。