C 为什么插入列表需要指向指针的指针
教科书是这样描述插入算法的,我的问题是,它不能由第二个函数来完成吗,如下所示,它不包括指向指针的指针,而是使用*l和lC 为什么插入列表需要指向指针的指针,c,pointers,C,Pointers,教科书是这样描述插入算法的,我的问题是,它不能由第二个函数来完成吗,如下所示,它不包括指向指针的指针,而是使用*l和l void insert (list **l, int d) { list *p; p = malloc(sizeof(list)); p.data = x; p.next = *l; *l = p; } void insert1 (list *l, int d){ list *p; p = malloc(siz
void insert (list **l, int d)
{
list *p;
p = malloc(sizeof(list));
p.data = x;
p.next = *l;
*l = p;
}
void insert1 (list *l, int d){
list *p;
p = malloc(sizeof(list));
p.data = x;
p.next = l;
l = p;
}
不,你不能。
insert1
的问题如下所示:
l = p;
这会将l
的值设置为p
,但l
只是一个函数局部变量,用于保存指向列表的指针的值。在此处更改l
不会在功能之外产生任何影响。所以如果我有一个代码,比如:
list *myList = /* ... */;
insert1(myList, 0);
此处的指针myList
不会更改。另一方面,代码:
list *myList = /* ... */;
insert(&myList, 0);
指针
myList
将被更新以指向新插入的值。所有内容都是通过C中的值传递的。这包括指针。所以,当你说l=p
在函数末尾,这对insert1()
的调用者无效。您只是在修改一个局部变量insert1()
(它恰好包含一个指针)
然而,当你说*l=p
在insert()
的末尾,您正在将指针写入由调用方控制的内存位置。调用者通常会执行类似的操作:
list* myList = ...;
insert(&myList, ...);
这样,*l=p
直接修改调用者中myList
的值,允许调用者实际看到效果。为什么插入列表需要指向指针的指针?这是因为如果您在*l
中进行修改,也会影响调用函数中的函数&如果您想要链接节点,这就是我们的意图。这*l=p代码>在下面的代码中将修改调用
函数中的头
节点
void插入(列表**l,int x){
/*. .. */
}
若像在第二个代码中一样只传递指针,*l
不会在调用函数中被修改。这l=p
不会更改调用函数中的head
节点。因为传入C的参数是按值传递的。此外,您可能需要检查malloc
是否返回NULL。感谢您的回复!为了澄清,C/C++中的函数不能修改参数值,但可以修改指针引用的地址吗?@ DrWyYu,不可以,但是在C++中,可以使用引用,(代码>空格FO(int and bar)…<代码> >)DrWYU函数可以修改指针引用的内存。在双指针参数(list**l
)的情况下,该内存恰好是指针变量myList
,这仅仅是因为我们用&myList
传递它的地址。因此,当insert()
更改*l
的值时,它会更改myList
的值。由于myList
本身确实是一个指针,因此它的值实际上也是一个地址。但这只是巧合,与价值传递的讨论无关。请记住:如果,并且只有当我通过指针时,被调用方可能改变任何内存在后面。“DrWuYu也,正如JabBrWOKKY正确注释,C和C++在这方面表现得非常不同。在C语言中,intfoo=42;酒吧(富);;断言(foo==42)代码>保证会成功。在C++中,没有这样的保证。这不是两种语言之间唯一的区别。我知道C认为C只是C++的一个子集很有诱惑力,我自己做的时间太长了。我认为最好更快地把C和C++看作不同的语言,这样可以帮你节省一些令人吃惊的惊喜。例如,list*p=malloc(sizeof(*p)),但C++中是非法的。