【问题标题】:C++ Parameter ReferenceC++ 参数参考
【发布时间】:2008-11-26 02:54:34
【问题描述】:

void (int a[]) { a[5] = 3; // 这是错的吗? }

可以这样修改传入的数组吗?

抱歉删了,这里有点新意……

我还有一个问题可以回答我的问题:

如果我有

void Test(int a) {
}

void Best(int &a) {
}

这两个语句是等价的吗?

Test(a);
Best(&a);

【问题讨论】:

  • 请添加到问题中,不要替换它,否则对原始问题的一些好的答案可能看起来是错误的。
  • 新代码的唯一问题是函数没有名称。否则语法是正确的。
  • 我不想强调一点,但费德里科是对的。您可以添加到您的问题或打开一个新问题,只要合适即可。
  • 同意:Jeremy Ruten。请参阅下面的更多细节。添加函数名称。

标签: c++ parameters reference


【解决方案1】:
void Test(int a[]) 
{
    a[5] = 3;
}

只是替代语法:

void Test(int* a) 
{
    *(a+5) = 3;
}

没有传递数组,只是一个指针。原来的数组被修改了。

至于您的第二次修订,给定:

void Test(int a) 
{
}

void Best(int &a) 
{
}

然后

Test(aa);      // Passes aa by value.  Changes to a in Test() do not effect aa
Best(aa);      // Passes aa by reference; Changes to a DO effect aa
Best(&aa);     // Is a syntax error: Passing a pointer instead of an int.

【讨论】:

  • 您应该在 8827 James 上了解更多。更喜欢数组索引(你可以在指针上做)而不是指针算术!!!!!!
  • 谢谢。我已经修复了丢失的函数名称(我从也有错误的问题中复制了它)。而且我从来没有说过哪种语法更好。我只是说它们是等价的。 (我也更喜欢数组语法)
【解决方案2】:

如果不是通过引用而不是指针获取变量,则意味着该函数本质上是孤立的,获得了 a 的临时副本。无论您做什么(不尝试破解堆栈或类似的事情),您都无法在调用上下文中访问该值。

如果您对调用上下文有所了解,则可以根据对堆栈内容的一些预期来做事,但这通常是个坏主意。

如果您的方法采用本质上是 a* 的 [],那么是的,您可以更改 a 指向的单元格的内容,但您将无法更改 a(指针)本身以指向别的东西。

【讨论】:

    【解决方案3】:

    没有。

    您从函数外部更改值的选项是通过引用调用 f(int& a)、通过指针调用 f(int* a) 以及使用全局(颤抖...)变量。

    【讨论】:

    • 我什至没有想过使用全局! :)
    • @Bill:这可能是最好的!
    【解决方案4】:

    阅读此处给出的答案,了解参数列表中int[]int* 的区别:Difference between char* and char[]。我真的在这个答案中投入了太多的爱! :)

    关于您对TestBest 函数的问题,James Curran 提供了一个很好的答案。

    【讨论】:

      【解决方案5】:

      你原来的函数应该可以工作。
      如果你给它一个名字:

      #include <iostream>
      
      // Arrays always de-generate to pointers.
      void plop(int a[])  // Make sure this function has a name.
      {
          a[5]    = 3;
      }
      
      int main()
      {
          int test[]  = { 1,1,1,1,1,1,1,1};
      
          plop(test);
      
          std::cout << test[5] << std::endl;
      }
      

      这是因为数组在作为参数传递给函数时总是退化为指针。所以这应该总是按预期工作。假设您没有超出数组末尾的索引。在 plop 内部无法确定传递的数组的大小。

      【讨论】:

        【解决方案6】:

        通过引用传递数组的主要动机是防止堆栈溢出和大对象的不必要复制。例如,想象一下如果我有这样的函数:

        void foo(int x[500000000000]);
        

        如果所有数组都是按值传递的,那么第一次调用函数时堆栈可能会溢出(但这当然是明显的夸张)。

        这将在使用面向对象的方法时变得有用。假设你有这个而不是数组:

        void foo(SomeClass x);
        

        其中 SomeClass 是具有 500000000000 个数据成员的类。如果你调用这样的方法,编译器会一点一点地复制 x,这至少可以说是一个很长的过程。您在数组中使用的相同概念仍然适用,但您必须手动指定这是通过引用来使用的:

        void foo(SomeClass &x);
        

        (除非您有 64 位机器和大量 RAM,否则不要尝试创建一个 500000000000 元素数组开始)

        【讨论】:

        • void foo(int x[500000000000]);与 void foo(int x[1]); 相同在 C / C++ 中:)
        • void foo(int x[500000000000]);相当于 void foo(int *x);
        • 也许我不够清楚。我知道所有数组都是通过引用传递的。我试图解释为什么数组是通过引用传递的。
        猜你喜欢
        • 2010-12-12
        • 2018-10-01
        • 2010-11-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-07-12
        • 2018-01-05
        • 1970-01-01
        相关资源
        最近更新 更多