混淆链表的双指针遍历

时间:2019-01-10 04:16:01

标签: c pointers linked-list

因此,我正在观看这个带Linus Torvalds的Ted Talk,其中他概述了以下示例: https://www.youtube.com/watch?v=o8NPllzkFhE&t=14m26s

我对此很感兴趣,所以我想为自己编写代码:

void remove_node(node* entry) {
  node** indirect = &head;

  while (*indirect != entry) {
    indirect = &(*indirect)->next;
  }

  *indirect = entry->next;

  free(entry);
}

我几乎了解所有内容,但是我对这一行深感困惑:

indirect = &(*indirect)->next;

&(*indirect)似乎采用了取消引用indirect的地址,我认为这会互相抵消,而我们仅以纯indirect结尾。尽管这显然是不正确的,但我不完全理解为什么。

如果这是不正确的(不是),那么当涉及到->时,也许我只是没有正确理解操作的分组/顺序。但是,无论我如何尝试将其分开,它都无法正常工作:

node* blegh;
while (*indirect != entry) {
  // Doesn't work.
  blegh = (*indirect)->next;
  indirect = &blegh;
}

如果有人可以帮助我将弱智的大脑缠起来,将不胜感激。

2 个答案:

答案 0 :(得分:2)

indirect = &(*indirect)->next;

等同于

indirect = &((*indirect)->next);

因此,“下一个”元素的地址在此处分配为“间接”。

以下内容无效。

  blegh = *indirect->next;
  indirect = &blegh;

因为indirect = &blegh;将本地变量“ blegh”的地址存储为“间接”。

尝试执行以下操作。

  node* indirect = head; //Use single pointer "indirect" 

  while (indirect != entry) {
    indirect = &indirect->next; //Assign "next" pointer to "indirect"
  }

答案 1 :(得分:2)

为了了解这一行:

indirect = &(*indirect)->next;

您需要了解运算符的优先级,即了解各个运算符的执行顺序。例如:&是在->之前还是之后执行的?

您可以在此处获得答案:https://en.cppreference.com/w/c/language/operator_precedence

它将告诉您您的行与以下行相同:

indirect = &((*indirect)->next);

所以代码要做的是在当前节点中下一个指针的地址。因此,*indirect将是下一个指针(也就是指向下一个节点的指针)的值。

您尝试重写代码是错误的,因为blegh不属于列表,因此blegh的地址也不属于列表中的任何内容。但是,您可以这样做:

node* blegh;
while (*indirect != entry) {
  blegh = *indirect;         // Pointer to current node
  indirect = &blegh->next;   // Get address of next-pointer in current node 
}