void insert(list **l, int x)
{
list *p;
p = malloc(sizeof(list));
p->item = x;
p->next = *l;
*l=p;
}
为什么我们使用双指针?我们可以使用单指针做同样的事情吗?我在“算法设计手册”第69页第2版中看到了这个例子。
列表基本上是节点,仅供参考。
答案 0 :(得分:2)
我们可以使用单指针做同样的事情吗?
您可以使用带有次要更新的单个指针完成此操作。
返回已分配的指针,并确保正确更改了函数调用。
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);
答案 1 :(得分:1)
在这里使用双指针是合理的,因为在函数中,您在列表的头部插入节点,因此变量l将使用新的标题*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);
答案 2 :(得分:1)
C中的参数按值传递。因此,为了对函数中的变量进行一些更改,我们必须告诉该函数变量的地址。这使它能够通过将数据写入相应的内存来更改变量间接的值。
因此,要修改int
,您必须传递int *
。在您的情况下,要修改list *
(p->next
的类型),您必须传递list **
。
答案 3 :(得分:0)
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
答案 4 :(得分:0)
在此示例中,您需要使用双指针,因为您还希望更改列表的起始节点。因此,基本上当您插入新元素时,您还希望将包含它的节点作为列表中的第一个。如果只传递一个指针(list *l
)并为其分配新创建的节点(p
),则更改(并且通过更改我的意思是它将是第一个节点list)只能在你的函数中使用,并且不会在它之外传播。
为了更清楚,如果您使用简单的指针(list *l
),您基本上会复制list*
变量所存储的地址。坐在你的函数之外,在新创建的指针(l
参数)中。因此,函数内的l
变量是一个不同的指针(内存中与函数外部的指针变量不同的位置),包含与函数外部指针相同的地址。因此,将新创建的元素分配给此l
单指针的原因只会使新插入的元素成为第一个本地(函数范围)。
与你使用双指针(所以list **l
)时的替代方法相比,真正发生的是通过将外部指针变量传递给函数,你实际上已经通过外部指针的地址,不要与指针所包含的地址混淆。 (注意,因为你必须调用这样的函数:insert(&l, 2)
)。这样,通过解除引用并将其用作rvalue(p->next = *l
)并同时使用外部变量的地址,您仍将拥有外部指针所包含的地址,因此当您进行制作时*l = p
(注意*l
在这里被用作左值),你实际上是取消引用双指针,结果你将获得真实变量的地址(外部变量),分配给它是新创建的节点。换句话说,您实际上是将新创建的节点设置为起始节点,但这次也在函数之外。
真的希望这不是非常混乱。