链表头双指针传递
我在一些书/教程中看到过这一点。
当您将(链表的)头指针传递给函数时,您需要将其作为双指针传递。
例如: // 这是反转链表,其中头指向第一个节点。
void nReverse(digit **head)
{
digit *prev=NULL;
digit *curr=*head;
digit *next;
while(curr!=NULL)
{
next=curr->next;
curr->next=prev;
prev=curr;
curr=next;
}
*head=prev;
return;
}
这很好用。
当我使用单指针时它也有效,例如
void nReverse(digit *head)
{
digit *prev=NULL;
digit *curr=head;
digit *next;
while(curr!=NULL)
{
next=curr->next;
curr->next=prev;
prev=curr;
curr=next;
}
head=prev;
return;
}
我尝试使用头指针打印列表。这两个功能都运行良好。
我错过了什么吗?
谢谢,
I have seen this in some book/ tutorial.
When you pass in the head pointer (of linked list) into a function, you need to pass it as a double pointer.
For eg:
// This is to reverse a linked list where head points to first node.
void nReverse(digit **head)
{
digit *prev=NULL;
digit *curr=*head;
digit *next;
while(curr!=NULL)
{
next=curr->next;
curr->next=prev;
prev=curr;
curr=next;
}
*head=prev;
return;
}
This works fine.
It also works when I use single pointer like,
void nReverse(digit *head)
{
digit *prev=NULL;
digit *curr=head;
digit *next;
while(curr!=NULL)
{
next=curr->next;
curr->next=prev;
prev=curr;
curr=next;
}
head=prev;
return;
}
I tried printing the list by using the head pointer. Both the functions work fine.
Am I missing something ?
Thanks,
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
这是非常类似 C 的代码,而不是 C++。
基本上,当某些内容按值传递时,函数会对数据的副本进行操作:
在 C 中,您可以传递一个指向变量的指针,并且可以以这种方式更改它:
对于您来说,而不是 int code> 这是一个
数字*
。 (产生指向指针的指针。)在 C++ 中,引入了引用。引用是另一个对象的别名。所以你会做这样的事情:
引用通常是首选,因为它强制你实际引用一个对象,并简化调用和操作代码。
当然,在 C++ 中,您不会自己实现列表,而是使用
std::list
。This is very C-like code, not C++.
Basically, when something is passed by-value the function operates on a copy of the data:
In C, you instead pass a pointer to the variable, and can change it that way:
For you, instead of an
int
it's adigit*
. (Resulting in a pointer to pointer.)In C++, references were introduced. A reference is an alias to another object. So you'd do something like this:
A reference is generally preferred, since it enforces that you actually refer to an object, and simplifies both calling and operating code.
Of course in C++ you wouldn't implement a list yourself, you'd use
std::list
.最后一个
head=prev;
不会更改第二个示例中传递的指针的值。对于此功能而言,该行是否是必需的取决于您。但有一个区别。您如何测试它“工作正常”?您是否能够迭代列表并打印出节点的值并看到它们实际上已被反转?第一个函数(大概被称为
nReverse(&list);
changeslist
指向的内容,第二个函数则不会(所以对于第二个函数你怎么知道哪个节点是列表的开头,毕竟它刚刚被更改......)。That last
head=prev;
does not change the passed pointer's value in the second example. Whether or not that line is necessary for the purposes of this function is up to you. But there is a difference.How did you test that it "worked fine"? Were you able to iterate the list and print out the node's values and see that they had in fact been reversed? The first function (presumably called like
nReverse(&list);
changes whatlist
points to, the second do not (so for the second how do you know which node is the beginning of the list, after all it was just changed...).在第一个示例中,您传入的内容仍然指向列表的“开头”。
在第二个示例中,它指向列表的末尾(这是您开始时的开头,但后来已移动)。
In the first example, what you passed in still points to the "beginning" of the list.
In the second example, it points to the end of the list (which was the beginning when you started, but has since moved).
双重间接寻址的原因是
nReverse
可以修改调用者的指针,因为在反转列表之后,列表的头现在是一个不同的节点。在第二个版本中,您正在修改函数本地的
head
副本,因此调用者仍然拥有对旧头节点(现在是尾部)的引用。The reason for the double indirection is so
nReverse
can modify the caller's pointer, since after reversing the list, the head of the list is now a different node.In the second version, you are modifying the copy of
head
that is local to the function, so the caller still has a reference to the old head node, which is now the tail.使用双指针传递(第一个示例)的原因是您想要更改列表的头部。由于您要反转列表,因此在完成反转后,头应该指向列表的最后一个元素。
如果不使用双指针,那么 list 仍将指向原来的第一个元素,而 next 现在指向 NULL,因为它是反转后的最后一个元素。所以你失去了所有其他元素。
The reason for having double pointer passing (the first example) is that you want to change the head of the list. Since you are reversing the list, the head should point to the last element of the list after you have done the reversing.
If you don't use double pointers, then list will still point to the original first element which next now points to NULL because its the last element after the reversing. So you loose all your other elements.