Смущен двойным указателем обхода связанного списка - PullRequest
0 голосов
/ 10 января 2019

Итак, я смотрел этот разговор Теда с Линусом Торвальдсом, в котором он обрисовал следующий пример: 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 голосов
/ 10 января 2019

Чтобы понять строку:

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 
}
0 голосов
/ 10 января 2019
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"
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...