如何在C ++中准确地引用指针,以及何时需要它们(在链表的情况下) [英] How does reference to pointer exactly work in C++, and when do we need them (in the case of linked list)

查看:95
本文介绍了如何在C ++中准确地引用指针,以及何时需要它们(在链表的情况下)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道指针保存变量的地址.并且引用指向符号表中的相同地址(即,它们被分配给的变量的相同地址).

I know that pointers hold the address of a variable. And references point to the same address in the symbol table (that is, the same address of the variable, that they are assigned to).

我的问题是,如何正确引用指针.以及何时需要它们,而不是单独使用指针(而不是使用对指针的引用).如果您可以向我解释关于单链接列表的指针引用的使用,将对您有所帮助.

My question is, how do reference to pointers exactly work. And when do we need them, as opposed to using pointer alone (and not using reference to pointer). It will be helpful if you could explain me the use of reference to pointer, with respect to a singly linked list.

我有以下代码,使用函数删除链接列表的头指针:

I have the following code that deletes the head pointer of a linked list using a function:

struct Node
{
    int data;
    Node* next;
};

struct Node* newNode(int data)
{
    Node* temp = new Node;
    temp->data = data;
    temp->next = nullptr;
    return temp;
}

Node* deleteHead(Node* &head)
{
    if (head)
    {
        Node* temp = head;
        head = head->next;
        delete temp;
    }
    return head;
}

int main()
{
    Node* head = newNode(1);
    head->next = newNode(6);
    head->next->next = newNode(4);
    head->next->next->next = newNode(8);

    head = deleteHead(head);
    Node* temp = head;
    while (temp != nullptr)
    {
        cout << temp->data << " " << endl;
        temp = temp->next;
    }
    return 0;
}

deleteHead(Node* &head)函数中,该函数接受参数Node* &head.但是,即使参数为Node* head,代码也可以正常工作.在什么情况下,我们需要在链接列表中传递Node* &而不是Node*?

In the deleteHead(Node* &head) function, the function takes the argument, Node* &head. But, the code works fine, even when the argument is Node* head. for what cases do we need to pass Node* & instead of Node* in a linked list?

以下是上面的deleteHead(Node* &head)函数,如果我们仅使用Node* head作为参数而不是Node* &head-

Following is the deleteHead(Node* &head) function above, which works the same, if we only use Node* head as the argument, instead of Node* &head -

推荐答案

基于引用传递非指针的原因与基于引用传递非指针的原因相同:要让函数修改其值.

You pass a pointer by reference for the same reason you pass a non-pointer by reference: To let the function modify its value.

让我用一个简单的例子

#include <iostream>

void foo(int*& x) {
    *x = 42;        // change the value of the int x points to
    x = nullptr;    // change the value of x
}

第一行修改x指向的值(但不修改x).第二行修改x本身.

The first line modifies the value x points to (but it does not modify x). The second line modifies x itself.

int main() {
    int y = 42;
    int* y_ptr = &y;
    foo(y_ptr);
    if (y_ptr == &y) std::cout << "cannot happen";
}

因为我们设置了x = nullptr,所以通话后y_ptr将不再指向y.

Because we set x = nullptr, y_ptr will not point to y anymore after the call.

现在,如果我们将foo修改为不引用,则会得到:

Now if we modify foo to not take a reference we get:

#include <iostream>

void foo(int* x) {
    *x = 42;        // change the value of the int x points to
    x = nullptr;    // change the value of x
}

同样,第一行修改了x指向的int.但是,现在第二行仅对函数本地的x有影响.

Again the first line modifies the int pointed to by x. However, now the second line only has an effect on x local to the function.

int main() {
    int y = 42;
    int* y_ptr = &y;
    foo(y_ptr);
    if (y_ptr == nullptr) std::cout << "cannot happen";
}

y_ptr的值不能通过将其传递给foo来更改,因为它是按值传递的.

The value of y_ptr cannot change by passing it to foo, because it is passed by value.

您的代码中有

Node* deleteHead(Node* &head)
{
    if (head)
    {
        Node* temp = head;
        head = head->next;
        delete temp;
    }
    return head;
}

当您编写head = deleteNode(head)时,发生了两件事:

And when you write head = deleteNode(head) two things are happening:

  • 该函数修改head(因为它通过引用传递)以指向head->next.
  • 该函数还返回此新"头(指向head->next),并将其分配给head.
  • the function modifies head (because it is passed by reference) to point to head->next.
  • the function also returns this "new" head (pointing to head->next) and that is assigned to head.

因此,您基本上两次分配给head.因为head由引用传递,所以deleteNode将做正确的事情而不使用返回值:

So you basically asign to headtwice. Because head is passed by reference deleteNode would do the right thing without using the return value:

deleteNode(head);  // this already does modify head 

...或反过来说:如果您从功能中返回新"头(head->next)并将其分配给head,那么通过引用传递指针也没关系,因为在函数内部完成分配具有相同的效果.

...or put the other way around: If you return the "new" head (head->next) from the fucntion and assign it to head, then it does not matter if you pass the pointer by reference, because the assignment done inside the function has the same effect.

您的代码类似于

int* bar(int*& x) {
   x = nullptr;
   return x;
}

然后通过

int y = 42;
int* y_ptr = &y;
y_ptr = bar(y_ptr);

,通过不使用返回值bar(y_ptr)可以达到相同的效果.还是没有指针的情况相同(因为指针在这里实际上没有任何区别):

where the same effect could be achieved by not using the returned value bar(y_ptr). Or the same without pointers (because pointers really make no difference here):

int moo(int& x) {
    x = 0;
    return x;
}

int x = 42;
x = moo(x);     // same as `moo(x)`

PS:您不需要两者(返回指针并已在函数中分配它),因此最好使函数返回void.

PS: You dont need both (return the pointer and assign it already in the function), so better make the function return void.

这篇关于如何在C ++中准确地引用指针,以及何时需要它们(在链表的情况下)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆