删除c中的链接列表

时间:2013-07-23 19:24:53

标签: c linked-list

我正在解决删除链表中所有元素的程序,我遇到了以下问题:

当我使用返回类型为void的delete函数,并检查main中的开始指针是否为NULL时,它不是并且给出了荒谬的结果

代码:

void deletes(struct node *start)
{
    struct node *current,*next;
    current=start;
    while(current!=NULL)
    {
        next=current->link;
        free(current);
        start=next;
        current=next;
    }
    start=NULL;
    return ;
} 

但是,如果我更改返回类型,它可以正常工作:

struct node *deletes(struct node *start)
{
    struct node *current,*next;
    current=start;
    while(current!=NULL)
    {
        next=current->link;
        free(current);
        start=next;
        current=next;
    }
    start=NULL;
    return start;
}

为什么start = NULL在第一个代码中工作?

我的整个代码是here

3 个答案:

答案 0 :(得分:4)

这是因为在第一个版本中,您按值传递列表标题,这意味着复制了指向头部的指针,并且您只更改了函数中的副本。函数返回后,这些更改不可见,因为未对原始副本进行任何更改。

要么像在第二个版本中一样,返回结果,要么通过引用传递指针,这意味着你使用地址传递指针的地址(或指向指针的指针) - 运营商。当然这意味着您还必须更改功能:

void deletes(struct node **start)
{
    struct node *current = *start;

    /* Deleting the list... */

    *start = NULL;
}

称之为

struct node *list_head = ...;

deletes(&list_head);

答案 1 :(得分:2)

因为在C中,函数参数是按值传递的。如果在函数内部写start = NULL;,那么在该函数之外它将无效(它只会将start指针设置为NULL,这实际上只是传递的指针值的副本in,它是函数的本地。)。

如果要修改函数参数,则必须传递指向它的指针。所以,

void delete(struct node **start)
{
    // ... delete ...
    *start = NULL;
}

然后

delete(&list);

会起作用。

答案 2 :(得分:0)

这是因为你应该有(struct node **start),它可以让你传递指向列表的指针,这样你就可以修改列表。

目前,您只是将链表的副本传递给函数,因此不会仅仅将副本的值更改为实际列表的值。因此,当您返回副本时,您会看到结果