【问题标题】:Passing a pointer to a function传递指向函数的指针
【发布时间】:2015-08-05 11:15:29
【问题描述】:

我试图使用 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函数调用。这里有什么问题?

编辑:感谢您的所有回答,使指向指针的指针看起来既丑陋又乏味,有没有其他方法可以通过其他设计来实现这一点?

【问题讨论】:

  • 参数按值传递(函数接收参数值的副本)。所以cur 是调用参数的本地副本,这就是cur = whatever 修改本地参数的原因。您需要通过引用传递它,即node *&amp;cur

标签: c++ function pointers pass-by-value


【解决方案1】:

在这里,root 本身已使用 pass-by-value 传递给 insert()。因此,从insert() 开始,root 的值无法更改。换句话说,curinsert() 函数的本地函数。对cur 本身所做的任何更改都不会影响传递的实际参数。

如果您想将root 的值从insert() 更改为,您需要从main() 传递一个指向root 的指针。

要 elabotare,您可以将cur 指向的地址处的值insert() 更改。所以,按照同样的比喻,如果你改变了

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

你应该一切顺利。

【讨论】:

  • 使用void insert(node *&amp; cur, int val) 会更好,它将指针作为引用传递...
【解决方案2】:

错误是您按值传递指针,更改该值但调用者不知道它。改成

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);
}

并相应地更改函数调用(...练习!)

【讨论】:

    【解决方案3】:

    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)
    

    【讨论】:

      【解决方案4】:

      如果您在插入时将 cur 重新分配给新节点,这并不意味着为 root 分配了该值(尤其是 root 根本不是地址,而是 NULL)。

      要么传递一个指向空节点的指针以在初始化时插入(并用相关数据更新它),要么返回一个新节点(并将其分配给 main 中的根)。

      【讨论】:

        【解决方案5】:

        如果你希望函数在外部指针而不是本地副本上进行操作,你需要通过引用传递:

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

        否则该函数对指针的副本起作用,而outside变量保持不变。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-06-27
          • 1970-01-01
          • 1970-01-01
          • 2010-10-31
          • 2021-07-17
          • 2013-06-06
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多