C语言 链表的初始化

dzjeubhm  于 2022-12-02  发布在  其他
关注(0)|答案(2)|浏览(205)

我有一个学校的项目,我需要排序数字使用链接列表。我有一些麻烦,初始化我的链接列表,有人给了我以下的解决方案,但我真的不明白什么是发生在一行,我想一些启示。
下面是完整的函数:

void stack_ini(t_lst **list_ptr, char **nbr)
{
    for (; *nbr; ++nbr)
    {
        // Create a new node.
        t_lst *node = malloc(sizeof(t_lst));
        node->content = ft_atoi(*nbr);
        node->next = NULL;

        // Insert it into the list.
        *list_ptr = node;
        list_ptr = &node->next;
    }
}

要完成此操作,请使用下面的t_lst结构:

typedef struct s_lst
{
    int             content;
    int             position;
    int             index;
    struct s_lst    *next;
}   t_lst;

在最后一行之前发生的一切我都差不多明白了:
list_ptr = &node->next;
我不明白为什么我需要把list_ptr赋给node-〉next的地址。node-〉next不是应该是未初始化的吗?这样会引发segfault吗?同样,如果node和list_ptr未赋给它们的... -〉next,这不应该只是像重写它们的当前值一样吗?
对不起,我的英语,谢谢你的回答。

qvsjd97n

qvsjd97n1#

在最后一行之前发生的一切我都差不多明白了:

list_ptr = &node->next;

我不明白为什么我需要把list_ptr赋给node-〉next的地址。node-〉next不应该是未初始化的,从而引发segfault吗?
不,node->next被显式地初始化为空指针。而且,即使它没有被初始化,它的 address&node->next)也被很好地定义。这可以被计算而不管node->next的初始化状态或值。

  • 在该点(*node->next)取消引用 * node->next将产生未定义的行为,因为其值是空指针,这很可能表现为程序因segfault而崩溃,但没有执行取消引用。

同样,如果node和list_ptr没有被赋值给它们的... -〉next,这不应该只是像覆盖它们的当前值一样吗?
添加节点后,list_ptr被设置为指向该节点的next成员,该成员的值最初为空。(然后-)前一个节点的next。之后,循环重复,从更新list_ptr以指向最近添加的节点的next成员开始。
因此,通过list_ptr赋值确实会替换它所指向的指针的值,但对于每个节点,这种情况最多发生一次,因为在更新之后,list_ptr本身会更新为指向另一个节点的next成员。

sd2nnvve

sd2nnvve2#

让我们假设最初指向main中声明的头节点的指针被设置为NULL,类似于

t_lst *head = NULL;

这个指针是通过引用间接传递给函数stack_ini的。

void stack_ini(t_lst **list_ptr, char **nbr);
               ^^^^^^^^^^^^^^^^

第一次解引用参数list_ptr(如*list_ptr)时,我们可以访问main中声明的原始指针head,并可以更改它。
所以在函数的for循环的第一次迭代中

*list_ptr = node;

将原始指针X1 M4 N1 X设置为指向新分配的节点的指针X1 M5 N1 X的值。
然后将参数list_ptr设置为数据成员head->next的地址,这相当于在此语句中使用node->next

list_ptr = &node->next;

所以现在指针list_ptr指向数据成员next,它可以在for循环的下一次迭代中被改变。
初始化数据成员node->next

node->next = NULL;

那就是在这个声明中

list_ptr = &node->next;

你并没有将数据成员node-〉的值赋给指针list_ptr,而是将指针list_ptr指向当前创建的节点的数据成员next,使用list_ptr可以在for循环的下一次迭代中更改该数据成员的值。

相关问题