【问题标题】:Pointer to a pointer as an argument for functions that manipulate linked lists指向作为参数的指针,用于操作链表的函数
【发布时间】:2014-03-14 04:13:01
【问题描述】:

我正在努力复习我的 C 语言,并且一直在复习数据结构和指针操作。有人可以向我解释为什么需要在这个链表反向函数中使用指向头指针的指针吗?由于 head 在函数中总是被解引用一次 (*head),我们不能只接受一个普通的 Node* 作为这个函数的参数并放弃解引用吗?提前致谢!

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



struct Node* reverse(struct Node** head){
    Node *parent = *head;
    Node *me = parent->next;
    Node *child = me->next;

    parent->next = NULL;
    while(child) {
        me->next = parent;
        parent = me;
        me = child;
        child = child->next;
    }
    me->next = parent;
    *head = me;
    return *head;
}

【问题讨论】:

  • 注意这段代码是C,不是C++
  • @Manu343726 这个概念对于 C++ 仍然完全有效。我认为您不应该删除 C++ 标签,因为 OP 明确表示他正在研究 C++

标签: c pointers linked-list


【解决方案1】:

如果你没有传入 Node** 参数而只是使用了 Node* 参数,那么这一行

 *head = me;

需要实现为

 head = me;

但是由于head 将被按值 传递,这导致head副本 被传递给函数。然后修改你的函数 makea 将只适用于这个副本,而不是你传递的参数。

当你需要一个函数来修改一个参数时,你需要通过引用或指针来传递它。在您的情况下,您需要Node** 来修改它指向的Node*

您还可以使用对 Node* 参数的引用。

作为一个荒谬的例子考虑这个函数

void ChangePointer(int* x)
{
    x = NULL;
}

void ChangePointer_2(int** x)
{
    *x = NULL;
}

int main()
{
    int* p = new int(1);
    ChangePointer(p); 
    // p is not NULL. The function changed the copy
    // of p because it was passed by value.

    ChangePointer_2(&p);
    // now p == NULL;
}

【讨论】:

  • 首先,我相信你,我知道这是真的,但我只是想正确理解。所以,如果我使用Node* 作为参数,指向节点的 pointer 将按值传递......既然这仍然是一个指针,为什么函数中的更改不会影响实际参数传入?
  • @MRT89 你可以通过解引用改变指针指向的东西,但不能改变指针本身的值(即它的地址)。编写一个接受指针参数(按值)的函数,并尝试将其设置为 NULL。当您检查函数返回后传递的参数的地址时,它不会为 NULL。您更改了副本的值,而不是指针本身。
  • @MRT89 我添加了一个示例,希望能更好地说明我想说的话。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-08-12
  • 1970-01-01
  • 1970-01-01
  • 2011-10-24
  • 1970-01-01
  • 1970-01-01
  • 2021-12-10
相关资源
最近更新 更多