0

我试图理解链表的代码。我理解他们是如何工作的。我正在查看一些与动态内存和链表有关的代码,我在这里对其进行了简化:

 #include <stdio.h>
 #include <stdlib.h>

 typedef struct node {
     char *word;
     struct node *next;
 } node;

 void display_word(node *start) {
     node *start_node = start;
     puts("");
     for(; start_node != NULL; start_node = start_node->next) {
         printf("%s", start_node->word);
     }
 }

 node* create_node(char *input) {
     node *n = malloc(sizeof(node));;
     n->word = strdup(input);
     n->next = NULL;
     return n;
 }

 int main() {
     node *start_node = NULL;
     node *n = NULL;
     node *next_node = NULL;
     char word_holder[20];
     for(; fgets(word_holder,80,stdin) != NULL; n = next_node) {
         next_node = create_node(word_holder);
         if(start_node == NULL)
            start_node = next_node;
    if(n != NULL)
        n->next = next_node;
    }
    display_word(start);
 }

因此,程序会为用户输入的每个单词创建一个链接列表,然后将其打印出来。我不明白的是在 main() 函数中,next_node 每次都分配给一个新节点以创建一个新节点,但是 start_node 指向 next_node,所以它将指向 next_node 每次创建的每个新节点?那么怎么可能仍然保留列表呢?我们不应该每次都丢失旧节点吗?

有人可以解释一下吗。

4

3 回答 3

2

当第一个节点被创建时,一个指向它的指针被保存在 start 中。

在循环的每次迭代之后,“n”被设置为刚刚创建的节点,因为 for 循环的最后一段 (;n = next) 在循环的每次迭代之后执行。所以中间循环执行“n”将始终指向前一个节点。因此,语句 n->next = next 将前一个节点的“next”指针设置为新节点。

因此,在循环的第二次迭代中,n = start,并且 start->next 设置为“下一个”您刚刚创建的节点。

于 2013-06-19T18:46:20.343 回答
2
  1. 创建第一个节点时,指向它的指针保存在start.

  2. 创建后续节点时,它们被添加到列表的末尾,因此start仍然指向第一个节点,并通过它指向列表的其余部分。

使用调试器单步执行代码,或者拿出铅笔和纸,画出你在大脑中单步执行时正在发生的事情,你会看到它们是如何组合在一起的。

于 2013-06-19T18:21:06.883 回答
1

我希望这能回答您的问题 - 每次您更新“下一个”时,您都将其设置为另一个新节点。每个节点都有自己的“下一个”,通向下一个节点,所以这样做不会丢失任何东西。我实际上并没有测试您的代码,但由于“开始”始终指向第一个节点,因此您不会在此过程中丢失任何节点。如果您想了解更多有关其工作原理的信息,调试器应该会有所帮助!

于 2013-06-19T18:22:54.800 回答