在最近的Slashdot访谈中, Linus Torvalds举例说明了一些人如何以某种方式使用指针,这表明他们并不真正了解如何正确使用它们。
不幸的是,由于我是他所谈论的人之一,所以我也无法理解他的榜样:
我见过太多的人通过跟踪“上一个”条目来删除单链接列表条目,然后删除该条目,例如执行以下操作
if (prev) prev->next = entry->next; else list_head = entry->next;
每当我看到这样的代码时,我都会说“这个人不理解指针”。可悲的是,这很普遍。了解指针的人只使用“指向入口指针的指针”,并使用list_head的地址对其进行初始化。然后,当他们遍历列表时,只需执行以下操作即可删除条目,而无需使用任何条件
*pp = entry->next
有人可以提供更多关于这种方法为什么更好的解释,以及在没有条件语句的情况下如何工作的更多解释吗?
一开始,你会
pp = &list_head;
并且,当你遍历列表时,可以使用
pp = &(*pp)->next;
这样,你始终可以跟踪“你来自”的点,并且可以修改居住在那里的指针。
因此,当你找到要删除的条目时,你可以
*pp = entry->next
这样,你就可以处理Afaq在另一个答案中提到的所有3种情况,从而有效地消除了对的NULL
检查prev
。
这里真的需要&*吗?似乎有点多余。
@FUZxxl它是必需的,它是
pp
指向节点指针的指针。因此,我们首先必须取消引用它,然后next
以通常的方式访问,然后再次获取其地址。如果您删除列表的尾部节点,则需要
tail
使用此方法来跟踪其操作方式pp
?@glglgl,这个(* pp)->下一个不足以使该地址存储在pp中吗,为什么&?
@ZianLai不。您想
pp
指向其他地方,而不要更改pp
指向的数据。