C-创建链表的函数只返回第一个节点

C-创建链表的函数只返回第一个节点,c,linked-list,singly-linked-list,C,Linked List,Singly Linked List,我发现了其他类似但不完全相同的问题,如果我错了,请留下链接:) 我一直在尝试用C实现一个shell,在使用管道进行解析时,我考虑使用char**args的链接列表 我的解析函数在返回整个列表时遇到问题。我使用tmp节点在创建新节点时保持移动,但是当我想要返回原始头部时,它的next为NULL,我认为tmp指向我头部的指针应该只是一个指针,必须在我头部进行更改 这里是简化的代码,只有这个问题 #include <stdio.h> #include <stdlib.h> ty

我发现了其他类似但不完全相同的问题,如果我错了,请留下链接:)

我一直在尝试用C实现一个shell,在使用管道进行解析时,我考虑使用
char**args
的链接列表

我的解析函数在返回整个列表时遇到问题。我使用tmp节点在创建新节点时保持移动,但是当我想要返回原始头部时,它的next为NULL,我认为tmp指向我头部的指针应该只是一个指针,必须在我头部进行更改

这里是简化的代码,只有这个问题

#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
    int data;
    struct node* next;
} node ;
node* foo()
{
    node* head=malloc(sizeof(node));
    node* tmp=head;
    int i=0;
    for(i=0;i<5;i++)
    {
        tmp=tmp->next;
        tmp=malloc(sizeof(node));
        tmp->data=i;
    }
    return head;
}
int main()
{
    node* list=foo();
    while(list)
    {
        printf("this is your %d\n",list->data);
        list=list->next;
    }
}
#包括
#包括
类型定义结构节点
{
int数据;
结构节点*下一步;
}节点;
node*foo()
{
node*head=malloc(sizeof(node));
节点*tmp=头部;
int i=0;
对于(i=0;不精确;
tmp=malloc(sizeof(node));
tmp->data=i;
}
回流头;
}
int main()
{
node*list=foo();
while(列表)
{
printf(“这是您的%d\n”,列表->数据);
列表=列表->下一步;
}
}

如果你能给我指出正确的方向,或者告诉我我做错了什么,那就太好了。

在分配给tmp之前,你需要
malloc
tmp->next,如下所示:

for(i=0;i<5;i++)
{
    tmp->next = malloc(sizeof(node));
    tmp=tmp->next;
    tmp->data=i;
    tmp->next = NULL;
}
node*head=malloc(sizeof(node));
节点*tmp=头部;
int i=0;
对于(i=0;不精确;
tmp=malloc(sizeof(node));
tmp->data=i;
}
回流头;

在这里,您创建了head并提供了空间,但在初始化它之前从未初始化它并返回它

函数没有意义,因为每个分配节点的下一个数据成员没有初始化。在循环中更改的是变量
tmp

该函数可以按以下方式显示

node* foo()
{
    const int N = 5;
    node *head = NULL;

    node **current = &head;

    for ( int i = 0; i < N; i++ )
    {
        *current = malloc(sizeof( node ) );

        if ( *current )
        {
            ( *current )->data = i;
            ( *current )->next = NULL;
            current = &( *current )->next;
        }
    }

    return head;
}
考虑到指针列表主要在循环中被覆盖。因此您将无法再次访问该列表,因为头节点的地址将丢失。请使用中间变量。例如

node* foo( size_t n, int init_value )
{
    node *head = NULL;

    node **current = &head;

    for ( size_t i = 0; i < n; i++ )
    {
        *current = malloc(sizeof( node ) );

        if ( *current )
        {
            ( *current )->data = init_value++;
            ( *current )->next = NULL;
            current = &( *current )->next;
        }
    }

    return head;
}
int main( void )
{
    node *list = foo();
    for ( node *current = list; current != NULL; current = current->next )
    {
        printf("this is your %d\n", current->data);
    }
}
根据C标准,无参数的主要功能应声明如下

int main( void )

你第一次来这里:
tmp=tmp->next
tmp->next
从来没有初始化过。我后来用
tmp=malloc(sizeof(node))
对它进行了malloc,这就是问题所在。你后来对它进行了malloce处理。你可能对编程的工作方式有严重的误解。还有
tmp=tmp=tmp->next;tmp=malloc(sizeof(node));
没有意义,它就像写
a=5;a=10
…和
tmp->next=0;
因为
malloc
不会初始化内存(因此你不知道列表的结尾).所以每次我都需要将tmp->next设置为NULL?虽然比原来的程序好一点,但这仍然是错误的。Reda,您当前分配了一个长度为5的列表,以便知道长度。我假设这是为了测试,所以在“现实生活”中你可以添加一个节点,做一些事情,附加一个节点,等等。任何在列表中运行的进程都会想知道e的终点在哪里,也就是
next
为零的地方。因此,你可以在完成的地方将
next
设置为零。这是否是“每次”或者在某一点上,我把逻辑留给你们。我编辑了我的答案,添加了@PaulOgilvie提到的
next
的初始化。我认为完全没有必要进行双重间接寻址。只需malloc head,然后tmp=head,然后返回head就可以了。是的,在我的实际程序中,我这样做了,我只是简化了以强调问题,而不是发布我的全部代码的广告:P@PaulOgilvie该功能可以以不同的方式实现。这并不意味着如果存在其他方式来实现该功能,则当前方式不正确。:)抱歉,Vlad,我同意这一点;但是,对于目前已经在挣扎的uder来说,你用双重间接法把事情弄得太复杂了。更喜欢KISS。@Paulogilvi你错了。我的实现很简单,没有局部案例。而且,它可以变得更一般,而不需要改变逻辑,正如我在第二个函数实现。程序员的资格越低,其代码包含的部分情况就越多。另一方面,程序员的资格越高,其编写的代码就越通用。
int main( void )
{
    node *list = foo();
    for ( node *current = list; current != NULL; current = current->next )
    {
        printf("this is your %d\n", current->data);
    }
}
int main( void )