繁体   English   中英

在C中使用双指针插入链接列表

[英]Insertion into a Linked list using double pointer in C

void insert(list **l, int x)
{
       list *p;
       p = malloc(sizeof(list));
       p->item = x;
       p->next = *l;
       *l=p;
}

为什么使用双指针? 我们可以使用单个指针完成同样的事情吗? 我在《算法设计手册》(第2版)第69页中看到了此示例。

列表基本上是节点,仅供参考。

我们可以使用单个指针完成同样的事情吗?

您可以使用单个指针进行较小的更新来完成此操作。

返回分配的指针,并确保正确更改了函数调用。

list* insert(list *l, int x)
{
   // list = *p
   // What was that? That is not valid code.

   list* p = malloc(sizeof(list));
   p->item = x;
   p->next = l;
   return p;
}

并用作

list* l = NULL;
l = insert(l, 10);

这里使用双指针是合理的,因为在函数中您将节点插入到列表的标题中,因此变量l将使用新的标题*l=p;进行更改*l=p;

*l->|node1|->|node2| //initial value
p->|nodeP| //after p = malloc(sizeof(list)); p->item = x;
p->|nodeP|->|node1|->|node2| //p->next = *l;
*l->|nodeP|->|node1|->|node2| //after *l=p

在这种情况下,函数的调用方式如下:

list *head;
insert(&head, 4);

对于您的问题:

我们可以使用单个指针完成同样的事情吗?

是的,该函数将如下所示:

list *insert(list *l, int x)
{
       list *p;
       p = malloc(sizeof(list));
       p->item = x;
       p->next = l;
       return p;
}

您可以在这种情况下调用函数,如下所示:

list *head;
head = insert(head, 4);

C中的参数按值传递。 因此,为了对函数中的变量进行一些更改,我们必须告诉该函数变量的地址 这使得它可以通过将数据写入相应的存储器来间接更改变量的值。

结果,要修改一个int ,您必须传递一个int * 在您的情况下,要修改list *p->next的类型),您必须传递list **

Basically u might be calling the insert function using insert(&head,x);
Previously head would have stored the address of your first node in the
linked list and u give the address of the head node to l and to access the
address of a u need to dereference it once and to change its value u need to 
dereference it twice.

and obviously u can do it without double pointers just giving the value of   
head to l  insert(head,x)....and in the function declaring insert(int *l,int 
x) 
suppose

address of a(first node)=123

value of head=123

address of head =456

l(storing address of head)=456

In order to get the address of the first node dereference once

*l=123
in order to change value or to go to the next node you dereference it twice
for visual satisfaction have a look at the diagram image i tried to figure
out for your better understanding.


----------

[这里有个图表,可以让您清楚地知道如何使用双指针
在这里工作] [1] [1]: http : //i.stack.imgur.com/HQOaa.jpg

在此示例中,您需要使用双指针,因为您还想更改列表的起始节点。 因此,基本上,当您插入新元素时,您还希望使包含该元素的节点成为列表的第一个。 如果仅传递单个指针( list *l )并将新创建的节点( p )分配给它,则更改(并且通过更改,我的意思是它将成为列表的第一个节点)将仅可用在函数内部,并且不会在函数外部传播。

更清楚地说,如果您使用简单的指针( list *l ),则基本上是将函数外部的list*变量存储的地址复制到新创建的指针( l参数)中。 因此,函数内的l变量是一个不同的指针(与函数外的指针变量相比,在内存中的位置不同),其地址与函数外的指针相同。 这就是为什么将新创建的元素分配给此l单指针将仅使新插入的元素成为唯一的局部(函数作用域)。

与采用双指针( list **l )时的替代方法相比,实际发生的情况是,通过将外部指针变量传递给函数,实际上是在传递外部指针的地址,而不是与指针包含的地址混淆。 (请注意,因为您将不得不调用如下函数: insert(&l, 2) )。 这样,通过将其解引用并将其用作rvalue( p->next = *l ),您仍将拥有外部指针所包含的地址,并且同时具有外部变量的地址,因此当您进行*l = p (注意, *l在这里用作左值),实际上是在取消引用双指针,因此,您将获得实数变量(外部变量)的地址,并为其分配新创建的节点。 换句话说,您实际上是将新创建的节点设置为起始节点,但是这次也是在函数之外。

真希望这不会引起极大的混乱。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM