有关通过引用传递指针的说明



这有点愚蠢,但我无法真正解释为什么会发生这种情况。作为练习,我想反转单链列表,我通过定义方法来实现这一点:

class solution {
void reverseLinkedList(Node*& head) {
Node* curr = head;
Node* prev = NULL;
while (curr != NULL) {
Node* _next = curr->next;
curr->next = prev;
prev = curr;
curr = _next;
}
head = prev;
}

在我的主要功能中,我打电话

solution s;
s.reverseLinkedList(head);
Node* iterator = head;
while (iterator != NULL) {
std::cout<<iterator->data<<std::endl;
iterator = iterator->next;
}

我之前定义我的头指向某个链接列表的地方。while 循环用于打印我的链表,该函数可以正常工作。这仅在我通过引用传递头节点后才有效;我最初试图在开始时传递 Node* head 而不是 Node*&head,它只打印了我的 linkedlist 的第一个元素(并且没有反转它(。例如,如果我没有通过列表 1->2->3 的引用传递,我将只打印出 1。

我以为传递指针就足够了?为什么我没有得到如此奇怪的行为而不通过参考>

C++中的局部变量(存储在堆栈中(具有块作用域,即在执行定义它们的块后它们超出作用域。

将指针传入函数时,将创建指针的副本,该副本就是传递的副本。执行函数后,函数工作区中的变量将超出范围。在函数中创建的任何非静态自动变量都将被销毁。

当您通过引用传入时,您不会传入变量的副本,而是传入实际变量,因此对变量所做的任何更改都会反映在传递给函数的实际变量上(通过引用(。

我想指出的是,指向下一个节点的指针存储在内存中,并且具有指向其存储位置的地址。因此,如果您不想通过引用传入,您可以这样做:

使用指向指针的指针
  1. ,该指针指向存储指向下一个节点的指针变量(地址(的内存位置
  2. 将此传递给函数(不通过引用(
  3. 取消引用指针并存储要指向的新地址。

我知道这有点令人困惑,但请查看将节点添加到链表的一小段代码。

void addNode(Node** head, int newData)
{
Node* newNode = new Node;
newNode->data = newData; // Can also be done using (*newNode).data
newNode->next = *head;
*head = newNode;
}

我认为传递指针就足够了?

void reverseLinkedList(Node* head) // pass pointer by value
// head is a copy here

按值传递pointer会创建一个要在函数内部使用的副本。

在函数内对该指针所做的任何更改只会反映在函数作用域中。
因为这些更改仅反映在指针的副本中,而不反映在原始指针中。

一旦pointer(副本(超出范围,这些更改就会因生命周期结束而被"丢弃"。

因此,您需要一个参考。

void reverseLinkedList(Node&* head) // changes made in head will be
// reflected in original head pointer

当您定期传递指针(按值传递 IE(时,它会创建指针的副本。对此指针所做的任何更改都不会影响原始指针。

通过引用传递指针就是发送对该指针的引用(与将指针传递指针非常相似(,因此对该指针所做的任何更改都会影响其"原始"状态。

例如:

//WRONG does not modify the original pointer, causes memory-leak.
void init(Object* ptr, int sz) {
ptr = new T[sz]; 
}

//Correct original pointer is a set to a new block of memory
void init(Object*& ptr, int sz) {
ptr = new T[sz]; 
}

in

void reverseLinkedList(Node* head)

指针按值传递。

这听起来很傻,这是一个可怕的指针,对吧?按引用传递的定义。好吧,所指向Node是通过引用传递的。指针本身head只是另一个恰好包含其他变量地址的变量,并且它不是通过引用传递的。

因此head包含用于调用reverseLinkedListNode指针的副本,并且与按值传递的所有参数一样,对副本的任何修改(指向head其他地方(都不会在调用函数中表示。

相关内容

  • 没有找到相关文章

最新更新