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

时间:2018-06-06 08:12:11

标签: 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(sizeof(list));
    p.data = x;
    p.next = l;
    l = p; 
}

3 个答案:

答案 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节点。