【问题标题】:pass by reference and value with pointers [duplicate]用指针传递引用和值[重复]
【发布时间】:2011-06-14 03:27:39
【问题描述】:

我不明白为什么将指针传递给函数并不会改变传入的数据。如果函数原型看起来像这样:

void func( int *p ); 

而func给p分配了内存,为什么不能在函数外使用呢?我以为指针是地址?

【问题讨论】:

    标签: c++ pass-by-reference parameter-passing pass-by-value


    【解决方案1】:

    虽然这样的事情符合您的预期:

    void func(int *p)
    {
        *p = 1;
    }
    
    int a = 2;
    func(&a);
    // a is now 1
    

    这不是

    void func(int *p)
    {
        p = new int;
    }
    
    int *p = NULL;
    func(p);
    // p is still NULL
    

    在这两种情况下,函数都使用原始指针的副本。不同之处在于,在第一个示例中,您尝试操作底层整数,因为您有它的地址,所以它起作用了。在第二个示例中,您直接操作指针,这些更改仅适用于 副本

    对此有多种解决方案;这取决于你想做什么。

    【讨论】:

    • 所以最好做一个这样的函数原型:func(int **p);或函数(int *&p); ?有什么真正重要的区别吗?
    • @TheFuzz:这只是我的个人观点,其他人可能会强烈反对,所以请谨慎对待:我倾向于只在绝对必要的地方使用引用,例如在运算符重载等。在其他位置,它们可能会引起混淆(因为仅通过查看函数调用,您无法判断它是按引用传递还是按值传递),并且它们比指针更受限制(不能为 NULL,不能重新就位)。
    【解决方案2】:

    C 和 C++ 中的参数按值传递。这意味着如果参数的类型是指向int 的指针,则函数接收实际指针参数的副本,同时仍然能够更改被指向的int .

    【讨论】:

    • C++ 中的参数是按值传递的...除非你通过引用传递 ;)
    • @FredOverflow 在这种情况下引用是按值传递的,对吧?
    • @San:不,因为引用既不是对象也不是值。从技术上讲,您根本无法传递它们 :) 引用在 C++ 中非常特殊。没有引用的“价值”之类的东西,你不能引用引用等。
    • @FredOverflow 够公平的;我只是傻傻的。然而,你可以整天争论语义。指针既不是对象也不是值。然而,一个指针可以point 指向一个对象并且包含一个表示对象地址的value。以同样的方式,可以将引用视为包含一个值(可能实现为地址);它只是一个具有不同规则的值,因此您无法修改或读取地址。当您通过引用传递某些东西时,如果没有交换值,函数如何知道您“引用”的是哪个对象?
    【解决方案3】:

    真的很难说,你在问什么..

    我的猜测 - 您可以更改指针 p 指向的内存,但您不能“重定向”或删除指针(或分配内存)?如果是这样,请将指针作为参考传递给您:
    void func( int &*p )
    或者作为双指针
    void func( int **p )
    能够改变它(我说的是指针)

    【讨论】:

      【解决方案4】:

      指针地址。如果将指针传递给函数,则该函数可以修改在函数范围之外创建的数据。但是,如果要在函数内部分配内存以在函数外部使用,则需要传入一个双指针。原因是指针是按值传递的,分配给新分配的块的指针分配一个新值。但是当函数返回时,这个新值就会丢失。但是您可以使用此方法来做您需要的事情:

      void func(int * * pp)
      {
          * pp = new int;
      }
      

      这样使用函数:

      int * myPointer;
      func(& myPointer);
      // do stuff with myPointer
      delete myPointer;
      

      【讨论】:

        【解决方案5】:

        我不同意 Nikolai 的回答。在 C++ 中,有 两种 方式来传递参数。

        f(Type Name)
        

        是你的情况,其中 Typeint*Namep(注意 int *p 实际上是指 int* p)。在这种情况下,您的函数 Name 内部是您传递给函数的对象的副本

        第二种方式

        f(Type & Name)
        

        不进行复制,而是为对象创建一个别名,以便您可以修改原始对象。

        在您的情况下,对象是int* 类型的指针。当您使用第一种语法传递它时,您会得到一个您修改的副本,并且原始指针保持不变。如果你想改变原来的指针,那么你应该通过引用传递它,所以对于 Type=int*Name=p 你会得到

        f(int*& p)
        

        【讨论】:

          猜你喜欢
          • 2012-01-24
          • 2014-10-12
          • 2016-08-26
          • 2015-10-09
          • 2013-01-13
          • 2015-02-11
          • 2022-01-16
          • 1970-01-01
          相关资源
          最近更新 更多