Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为什么插入列表需要指向指针的指针_C_Pointers - Fatal编程技术网

C 为什么插入列表需要指向指针的指针

C 为什么插入列表需要指向指针的指针,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

教科书是这样描述插入算法的,我的问题是,它不能由第二个函数来完成吗,如下所示,它不包括指向指针的指针,而是使用*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(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++中是非法的。