为什么我在此C ++代码中有无法理解的不同输出?

时间:2018-11-23 13:07:07

标签: c++ function oop c++11

即使调试后,我也无法理解该程序的输出,特别是在其中找到“ f(:: x)= h(x)”的那一行是什么意思? 有人可以帮我理解C ++程序以及如何运行以了解输出。

#include<iostream>
using namespace std;
int x = 6;
int h(int & x)
{
    x = 2*x; 
    return x;
}
int g(int m)
{
    return x++;
}
int& f(int &x)
{
    x+=::x; 
    return x;
}

int main()
{
   int x = -1;
    f(::x) = h(x);
    cout<<f(x)<<" "<<g(x)<<" "<<h(x)<<" "<<x<<" "<<::x<<endl;
    f(::x) = g(x);
    cout<<f(x)<<" "<<g(x)<<" "<<h(x)<<" "<<x<<" "<<::x<<endl;
    return 0;
}

编译后的输出为:
-5 -2 -4 -2 -2
-11 -2 -10 -5 -2

3 个答案:

答案 0 :(得分:5)

让我们重写一下,以免名称冲突。请注意,这些函数中的许多函数都会修改它们传递的对象,因此在输出值时,它们会发生变化。由于这些变化的发生顺序不确定,因此两次评估之间的总体结果可能会有所不同。

#include<iostream>

int global = 6;

int h(int & h_param){ h_param = 2 * h_param; return h_param; }
int g(int ){ return global++; }
int & f(int & f_param){ f_param += global; return f_param; }

int main()
{
    int local = -1;
    f(global) = h(local);
    std::cout << f(local) << " " << g(local) << " " << h(local) << " " << local << " " << global << std::endl;
    f(global) = g(local);
    std::cout << f(local) << " " << g(local) << " " << h(local) << " " << local << " " << global << std::endl;
    return 0;
}

答案 1 :(得分:3)

Thera是两个具有相同名称 x 的变量。全局x:“ :: x”和局部“ x”。

f(::x) = h(x);

此行转换为3个操作:

  • h(x)-> -1 * 2->返回-2并且x = -2
  • f(:: x)-> f(6)-> :: x = 12并返回对':: x'的引用
  • :: x = -2
cout << f(x) << " " << g(x) << " " << h(x) << " " << x << " " << ::x << endl;

在此行中,未指定呼叫的评估顺序,因此控制台上显示的值可能会有所不同。 例如,我的输出是:

-5 -2 -4 -5 -1
-10 -1 -10 -10 0

您应该了解基本规则:

int h(int &x);

int&x -表示 x 不是副本,它是引用。如果您在函数内部更改了这些变量-它将在外部更改。

int g(int m);

int m -表示 m 是副本。内部功能的更改不会影响外部功能

int & f(int &x);

这意味着函数返回对某些变量的引用。

答案 2 :(得分:3)

部分问题是代码是用非常混乱的样式编写的。特别是,有一个名为x的全局变量,还有一个在main中名为x的局部变量。在f(::x) = h(x)中,::表示f的参数是全局的,而h的参数是局部的。让我们首先重命名所有变量:

#include<iostream>
using namespace std;
int x = 6;
int h(int &y){y = 2*y; return y;}
int g(int m){return x++;}
int & f(int &z){z+=x; return z;}
int main()
{
    int w = -1;
    f(x) = h(w);
    cout<<f(w)<<" "<<g(w)<<" "<<h(w)<<" "<<w<<" "<<x<<endl;
    f(x) = g(w);
    cout<<f(w)<<" "<<g(w)<<" "<<h(w)<<" "<<w<<" "<<x<<endl;

    return 0;
}

现在,h修改其参数,g修改全局参数,f修改其参数并使用全局参数变得更加明显。

标准未定义输出,因为您不知道函数的调用顺序。


f(x) = h(w)

手段:

  • 调用函数h,并通过引用将值w传递给该函数。返回时,w将保留-2,这也将是函数结果。
  • 调用函数f,并通过引用将值x传递给该函数。返回时,x将保留12,函数将通过引用返回x。请注意,这可能在调用h之前或之后发生。
  • h(-2)返回的值分配给f返回的引用。

因为这都是在函数调用内发生的,所以没有未定义的行为,但是有惊人的大量可能的输出。