我正在解决删除链表中所有元素的程序,我遇到了以下问题:
当我使用返回类型为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
答案 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)
,它可以让你传递指向列表的指针,这样你就可以修改列表。
目前,您只是将链表的副本传递给函数,因此不会仅仅将副本的值更改为实际列表的值。因此,当您返回副本时,您会看到结果