0

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

当我使用返回类型为 void 的删除函数并检查主指针中的开始指针是否为 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 在第一个代码中起作用?

我的整个代码在这里

4

3 回答 3

4

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

要么像在第二个版本中那样做,返回结果,要么通过引用传递指针,这意味着你使用 address-of 运算符传递指针的地址(或指向指针的指针)。当然,这意味着您还必须更改函数:

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

    /* Deleting the list... */

    *start = NULL;
}

像这样称呼它

struct node *list_head = ...;

deletes(&list_head);
于 2013-07-23T19:27:51.873 回答
2

因为在 C 中,函数参数是按值传递的。如果您start = NULL;在函数内部编写,则在该函数外部将无效(它只会将start指针设置为NULL,它本质上只是传入的指针值的副本,并且它是函数的本地。)。

如果你想修改一个函数参数,你必须传递一个指向它的指针。所以,

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

然后

delete(&list);

会工作。

于 2013-07-23T19:28:17.280 回答
0

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

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

于 2013-07-23T19:28:07.500 回答