教科书以这种方式描述插入算法,我的问题是,它不能通过第二个函数来完成,如下所示,它不包含指向指针的指针,而是使用* 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;
}
答案 0 :(得分:5)
所有内容都以C中的值传递。这包括您的指针。因此,当您在函数结尾处说l = p;
时,这对insert1()
的调用者没有影响。您只是修改insert1()
的局部变量(碰巧有一个指针)。
但是,当您在*l = p;
结尾处说insert()
时,您正在编写指向由调用者控制的内存位置的指针。调用者通常会执行与此类似的操作:
list* myList = ...;
insert(&myList, ...);
有了这个,*l = p;
直接修改了调用者中myList
的值,允许调用者实际看到效果。
答案 1 :(得分:4)
不,你不能。 insert1
的问题在以下行中:
l = p;
这会将l
的值设置为p
,但l
只是一个函数局部变量,其中包含指向列表的指针值。在此处更改l
将不会对该功能产生任何影响。所以,如果我有一个代码:
list *myList = /* ... */;
insert1(myList, 0);
这里的指针myList
不会改变。另一方面,使用代码:
list *myList = /* ... */;
insert(&myList, 0);
指针myList
将更新为指向新插入的值。
答案 2 :(得分:3)
为什么插入列表需要一个指向指针的指针?它是因为如果你在*l
进行修改会影响调用函数&这就是我们想要链接节点的意图。以下代码中的*l = p;
将修改head
函数中的calling
节点main()
。
void insert (list **l, int x) {
/*. .. */
}
如果只传递指针,就像你在第二个代码*l
中那样,在调用函数时没有被修改。此l = p;
在调用函数时不会更改head
节点。