将指针传递给函数

Passing a pointer to a function

本文关键字:函数 指针      更新时间:2023-10-16

我试图使用c++实现BST,所以我尝试了这个:

    #include <iostream>
    #include <stdlib.h>
    struct node
    {
      int value;
      node* left;
      node* right;
    };
    void insert(node *cur , int val)
    {
      if(!cur)
      {
        cur = new node;
        cur->value = val;
        cur->left = NULL;
        cur->right = NULL;
        return;
      }
      if(val <= cur->value)
        insert(cur->left , val);
      else
        insert(cur->right , val);
    }
    using namespace std;
    int main()
    {
      node *root = NULL;

      insert(root , 20);
      insert(root , 21);
      cout<<(*root).value;
      return 0;
    }

但我有一个问题,我的insert()函数工作良好,但cur的变化似乎没有反映到root指针,因为root在' insert()函数调用后仍然是NULL。这里出了什么问题?

编辑:感谢你所有的答案,使指针指向指针似乎是丑陋和乏味的,有没有其他的方法,实现这与其他一些设计?

这里,root本身已经通过值传递传递给insert()。因此,从insert()开始,不能修改root的值。换句话说,curinsert()函数的本地函数。对cur本身所做的任何更改都不会影响传递的实际参数。

如果要从insert()修改root的值,需要从main()传递一个指向root的指针。

详细说明,可以从insert()更改cur指向的地址处的值。因此,按照同样的类比,如果更改

  1. insert(&root , 20);
  2. void insert(node **cur , int val)
  3. cur*cur的所有出现

你应该可以走了

如果你想让函数在指针外的上操作,而不是在本地拷贝上操作,你需要通过引用传递:

void insert(node*& cur, int val)
{
    // ... 
}

否则,函数将在复制指针的上工作,并且变量外部的保持不变。

错误的是您通过值传递指针,更改该值,但调用者不知道它。改为

void insert(node **cur , int val)
{
if(!*cur)
{
    *cur = new node;
    (*cur)->value = val;
    (*cur)->left = NULL;
    (*cur)->right = NULL;
    return;
}
if(val <= (*cur)->value)
    insert((*cur)->left , val);
else
    insert((*cur)->right , val);
}

并相应地更改函数调用(…exercise!)

c++将函数调用作为按值调用。所以它复制了一个指针并把它传递给函数。如果传递该指针,则可以访问该指针所指向的数据,但不能访问函数本身之外的指针,因为只复制该指针所指向的地址。

如果你想修改指针本身(这将是C的尝试),你需要传递一个指针到指针,或者通过引用传递,这是c++能够做到的。

如果你想使用C的尝试:

void insert(node ** cur , int val)
if(!(*cur))
{
    (*cur) = new node;
    (*cur)->value = val;
    (*cur)->left = NULL;
    (*cur)->right = NULL;
    return;
}

或者c++的尝试(这里你只需要修改cur的类型,其他的都保持原样):

void insert(node *& cur , int val)

如果您在insert中将cur重新分配给一个新节点,这并不意味着root被分配了该值(特别是root根本不是地址,而是NULL)。

传递一个指向空节点的指针,以便在初始化时插入(并用相关数据更新它),或者返回一个新节点(并将其赋值给main中的root)。