【问题标题】:C++ passing by reference function [closed]C ++通过引用函数传递[关闭]
【发布时间】:2015-08-15 18:44:19
【问题描述】:

sn-p代码如下

#include <iostream>
using namespace std;

int a(int m)
{
    return ++m;
}
int b(int &m)
{
    return ++m;
}
int c(int &m)
{
    return ++m;
}
int main(void)
{
    int p=0,q=0,r=0;
    p+=a(b(p));
    q+=b(a(q));
    r+=a(c(r));
    cout<<p<<q<<r;
    return 0;
}

发生的错误是在 q+=b(a(q)) 处从“int”类型的右值对“int&”类型的非常量引用进行无效初始化。如何解决该错误,以便该程序打印所需的输出

【问题讨论】:

  • 请正确格式化您的代码示例!
  • b 和 c 不一样吗?
  • 你想要的输出是什么?
  • 实际上这是 Timothy J Williams Technical MCQs book 的问题,给出的答案是 322
  • @soul 这个答案是否包含实际编译的代码?

标签: c++ pass-by-reference


【解决方案1】:

蒂莫西·J·威廉姆斯是以下一种或两种:

  • 错了;
  • 只教授与 Visual Studio 相关的 C++,而不否认它,这是不明智的。

引用不能绑定到临时对象。在 C++ 中是不允许的。 Visual Studio 允许它作为非标准扩展,但仅此而已。有些人感到困惑并认为这意味着它是有效的 C++。不是。

在通过引用将它们传递到任何地方之前,您必须将函数调用的结果(如 b(1))存储到命名变量中。

int main()
{
    int p = 0, q = 0, r = 0;

    int result_of_b_p = b(p);
    p += a(result_of_b_p);

    int result_of_a_q = a(q);
    q += b(result_of_a_q);

    int result_of_c_r = c(r);
    r += a(result_of_c_r);

    std::cout << p << q << r << '\n';
}

我还应该指出,引用的代码令人困惑,除了人为的“测试你的知识”挑战之外似乎没有任何其他用途。我不会太在意这一点,而是从a proper book 学习 C++。毕竟,Timothy Williams 声称上述程序输出 322; it doesn't.

【讨论】:

    【解决方案2】:

    你不能通过引用传递一个常量。

    分解您的代码。

    int a(int m){
       return ++m;
    }
    

    这将返回一个 int(常量,例如 5)

    然后在

    int b(int &m){
        return ++m;
    }
    

    您现在在技术上将整数(常量)而不是变量传递给 B。您必须将 B 作为变量传递。

    试试你所拥有的,但传入

    int x = a(your_number_here);
    int z = b(x);
    

    编辑:

    int main(void){
    
        int p=0,q=0;
        int x = 5;
    
        p = a(x);
        q = b(p);
    
       cout << q << endl;
       return 0;
    }
    

    返回 7。

    【讨论】:

    • 这里没有“常数”。不知道你为什么认为有。
    • @LightnessRacesinOrbit 绝对有常数......您不仅不正确,而且我上面的帖子解决了他的问题。他返回的是右值而不是左值。
    • 显示一个常数。您没有提到的初始化程序 0 和 5 不算在内。
    • 然后阅读我的答案。
    • @LightnessRacesinOrbit int a(int m) 返回一个常数。问问你自己这个。这可以在“=”符号的两侧还是仅在右侧?如果答案是“右侧”,那么它不是具有内存地址的变量。因此是一个只能赋值的常量。
    【解决方案3】:

    该错误是由于尝试调用一个带有值的引用的函数的结果。这就像使用值文字 b(1) 调用 b。那不行……

    【讨论】:

    • 其实这是 George Summers Technical MCQs book 的问题,给出的答案是 322
    • @soul:你为什么对每一个答案都重复同样的评论?我们懂了。你从一本书中得到这个。然而,这本书是错误的。
    • b(1) 不是“文字”。
    • @LightnessRacesinOrbit - 为什么是not?
    • 完成你的句子:那行不通....因为函数参数不是 const (也就是说,如果参数被声明并被视为 const,它可以并且将会工作)
    【解决方案4】:

    函数调用是您通过引用传递的地方。见下文:

    void foo (int* m)
    {
        (*m)++;
    }
    
    int main (void)
    {
        int a = 0;
        foo (&a);
        cout  << a << endl; // prints 1
    }
    

    【讨论】:

    • 其实这是 George Summers Technical MCQs book 的问题,给出的答案是 322
    • -1:这个答案是错误的。此代码传递一个指针(以及a 的地址)。 OP 通过引用传递。 Type&amp; 和 &amp;expression 是两个不同的东西。
    【解决方案5】:

    所以这里b(int&amp; m) 引用一个整数。这样想吧。引用是编译器自动处理取消引用操作的“安全指针”。

    a(int m) 的返回值是一个临时值,即它是一个临时值,一旦函数返回并且它的值已以某种方式被利用,它就会超出范围。所以你可以做x = a(15);,x 将成为返回的16 的副本。这就是 r 值。一种“临时”(r,因为它位于表达式的右侧)。所以当你有一个指向临时值的指针时,在大多数情况下它是没有意义的。比如下面的代码

    int* return_local() {
        int a = 10;
        return &a;
    }
    

    这会给你一个编译器警告。因为您不想将指针绑定到超出范围的值。同样,您不希望在函数返回并使用其值后立即超出范围的对象的引用。这就是您的代码中有错误的原因。 a(int m) 返回一个 r 值,当您执行 b(a(q) 时,您正在尝试将引用绑定到一个 r 值

    现在有一种称为右值引用的东西,其语法形式为void some_func(int&amp;&amp; rvalue_reference)。 &amp;&amp; 表示 r 值引用不是对引用的引用。有兴趣的可以去看看。

    【讨论】:

      【解决方案6】:

      不允许将 r 值作为非常量引用参数传递。这发生在您以 a(q) 作为参数调用函数 b 的行中,这是一个 r 值(不是简单变量的表达式)。 所以你需要先调用a并将它的值存储在一个变量中,然后把这个变量传递给b:

      int main(void)
      {
          int p=0,q=0,r=0;
          p+=a(b(p));
          int t=a(q);
          q+=b(t);
          r+=a(c(r));
          cout<<p<<q<<r;
          return 0;
      }
      

      【讨论】:

        猜你喜欢
        • 2018-06-09
        • 2012-10-15
        • 2014-09-11
        • 1970-01-01
        • 2012-06-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-07-14
        相关资源
        最近更新 更多