【问题标题】:Assignement of variable to reference inside a function.将变量分配给函数内部的引用。
【发布时间】:2015-07-10 08:13:41
【问题描述】:

我正在尝试使用 C++ 引用并遇到以下情况: 考虑以下代码

void foo(float &y)
{
    float k = 0.0;
    k += 20.1;
    y = k;
    cout << "y = " << y << endl;
} 



int main() {

    float  i;
    foo(i);
    i+=10.00;
    cout<<"value of I after returning is :: "<<i<<endl;

    return 0;
}

程序编译并运行。输出是:

y = 20.1
value of i after returning is :: 30.1

现在发生这种情况,我的困境是......在函数“foo”中,我们将 y(它是对 i 的引用)分配为 k。而 k 的作用域只在那个函数中。所以一旦函数返回,k 应该被销毁并且 i 的值应该是一些未定义的值。 但出乎我的意料,函数后 i 的值为 k。

我是否遗漏了什么或理解不同的东西......?对理解这里发生的事情有什么帮助吗? 提前致谢。

【问题讨论】:

  • 尝试 foo(float* y) 和主 foo(&i)
  • “所以一旦函数返回,k应该被销毁并且i的值应该是一些未定义的值。” y = k;它会被复制,不用担心。
  • 我 100% 确定这已经被覆盖过:一个引用只能被“设置”到它的被引用对象一次——在这种情况下是在调用 foo 时。 y=k 仅将maini 的值设置为fook 的值。
  • 您已为 y 分配了一个新值,但此处未显示参考。
  • Different question 有类似的答案

标签: c++ memory reference arguments return-value


【解决方案1】:

我认为您将 C++ 引用与指针混淆了。它们是不同的东西!一旦将引用设置为引用某个对象,就永远不能将其更改为引用另一个对象。并且对引用执行的任何操作实际上都是对引用对象的值进行的。在这种情况下,赋值y = k实际上将y引用的对象的值设置为k。

为了让事情更具体一点,我将用 cmets 对您给出的示例进行注释,以描述正在发生的事情:

void foo(float &y)
{
    float k = 0.0;
    k += 20.1;
    y = k;  /* The value of the object referred to by y (i, in this program)
               is set to k (20.1f) */
    cout << "y = " << y << endl; /* When we write y in this way, we are 
               really referring to the value of the object referred to by y. 
               This is why it prints 20.1 instead of some memory address. */
} 

int main() {
    float  i;
    foo(i);   /* i is passed as a reference to foo */
    i+=10.00; /* The value of i was modified in foo. */
    cout<<"value of I after returning is :: "<<i<<endl;

    return 0;
}

相比之下,这里是使用指针而不是引用的类似代码(有一个错误——它分配指针 y,而不是更改 y 指向的值):

void foo(float *y)
{
    float k = 0.0;
    k += 20.1;
    y = &k;
    cout << "y = " << *y << endl;
} 

int main() {
    float  i = 0;
    foo(&i);   /* i is passed as a reference to foo */
    i+=10.00; /* The value of i was modified in foo. */
    cout<<"value of I after returning is :: "<<i<<endl;

    return 0;
}

在这种情况下会发生什么?好吧,我们打印出 y = 20.1,返回后 i 的值为 10.00。在这个例子中,当我们分配y = &amp;k 时,我们正在改变变量 y,它是 foo 的局部变量,以引用 k。这对 i 没有影响(我们没有修改 y 指向的值),所以退出 foo 后 i 不变。如果你想在 foo 之后将 i 更改为等于 k,我们必须将行更改为 *y = k

希望这能消除 C++ 引用和指针之间的一些差异!有很多很好的教程可以很好地解释这个主题。

【讨论】:

    【解决方案2】:
    float &y = k;  // Or float &y argument of a function initialized with i
    

    很不一样
    float &y = something;
    ...
    y = k;
    

    在以前的版本中,yk 的引用。

    在以后的版本中,y 仍然是某个东西的引用,而y = k 将值分配给ky 别名或something

    永远记住不能重新分配引用。

    例如:

    int x = 10;
    int &y = x;
    int z = 20;
    
    y = z;  // x= 20, y(x) = 20, z = 20
    x = 15; // x= 15, y(x) = 15, z = 20
    y= 25;  // x= 25, y(x) = 25, z = 20
    z= 30;  // x= 25, y(x) = 25, z = 30
    // Also note that &x and &y (addresses) are same. But &z would be different
    

    【讨论】:

      【解决方案3】:

      引用是指针的语法糖。您的代码等效于以下内容:

      void foo(float * const y)
      {
          float k = 0.0;
          k += 20.1;
          *y = k;
          cout << "y = " << *y << endl;
      } 
      int main() {
          float  i;
          foo(&i);
          i+=10.00;
          cout<<"value of I after returning is :: "<<i<<endl;
          return 0;
      }
      

      基本上,您只能在初始化时设置引用的目标。如果您之后分配给引用,那么这些将分配给引用的值。

      【讨论】:

      • 您更喜欢float *const y 而不是float *y?此外参考是not just语法糖并提供更强的保证?
      • void foo(float *y)void foo(float&amp; y) 不同,一个是指向浮点数的指针,一个是对浮点数的引用.. 我可以将空值传递给一个,我不能传递给另一个
      • @MohitJain 确实,改变了。我正在寻找标准中的确切措辞,但找不到。感谢您的链接。
      • 在最新的草稿中找不到它,我敢肯定我曾经在标准(“句法变体”或类似的东西)中读到过一些关于这个的东西,也许是在旧版本中。
      猜你喜欢
      • 2022-11-27
      • 2012-08-01
      • 1970-01-01
      • 2023-02-10
      • 1970-01-01
      • 1970-01-01
      • 2013-11-12
      • 1970-01-01
      • 2022-07-02
      相关资源
      最近更新 更多