关于正确设置结构指针的简单链表

About a simple linked list to set struct pointer correctly

这段代码创建了一个动态链表,它也可以正确分配和释放内存,但是有一小步我很困惑。它似乎没有将第一个结构指针 start->next 设置为下一个,我认为应该这样做。但是当我尝试 运行 它时,它运行良好。然后我尝试添加 start->next=next; 它也很好用。请帮我看看并告诉我原因。

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

typedef struct island {
    char *name;
    char *opens;
    char *closes;
    struct island *next;
} island;

island* create(char *name) {
    island *i = malloc(sizeof(island));
    i->name = strdup(name);
    i->opens = "09:00";
    i->closes = "17:00";
    i->next = NULL;
    return i;
}

void display(island *start) {
    island *i = start;
    for (; i != NULL; i = i->next) {
        printf("Name: %s open: %s-%s\n", i->name, i->opens, i->closes);
    }
}

void release(island *start) {
    island *i = start;
    island *next = NULL;
    for (; i != NULL; i = next) {
        next = i->next;
        free(i->name);
        free(i);
    }
}

int main() {

    island *start = NULL;
    island *i = NULL;
    island *next = NULL;
    char name[80];
    for (; fgets(name, 80, stdin) != NULL; i = next) {
        next = create(name);
        if (start == NULL)
            start = next;  //change this line to {start = next;start->next=next;} also works.
        if (i != NULL)
            i->next = next;
    }

    display(start);
    release(start);

    return 0;
}

我想知道里面到底发生了什么,所以我画了这个来帮助自己理解。

我不是 100% 确定你的问题是什么,但是 main.c 中有一个巨大的逻辑错误。在 for(;fgets(... 循环中,您没有保持良好的列表头部。它应该更像

for(;fgets(...);...); {
   island *temp=create (name);
   if(temp==NULL) exit(1);
   if(start==NULL) start=temp;
   else {
      temp->next=start;
      start=temp; }
   }

两种方式都是"same",唯一的区别是第二种方式({start = next;start->next=next;})你设置的是'next'在第一次迭代中指向相同的节点(一些没有意义的东西),无论如何这并不重要,因为在下一次迭代中它将被这句话覆盖:"i->next = next;"(记住 'i'指向上一次迭代的 'next' 节点。

进一步澄清:

假设你刚才分配的第一个风景只"start = next;"

第一个循环:

  • 'start' 是 NULL 所以它分配了指向最近创建的节点的指针。 'start->next' 为 NULL。

  • if (i != NULL) 仅在第一次迭代中评估为 false。

  • 'i' 赋值指向 'next'

第二个循环:

  • 'start' 不为 NULL,因此跳过此步骤。

  • 'i'指向上一次迭代(下一次)最后创建的节点,所以"i->next = next;"从本次迭代一直执行到最后一次。是在这一步,你会覆盖之前保存的值(start->next=next)