简体   繁体   English

C ++通过引用传递不更改参数

[英]C++ Passing By Reference Not Changing Argument

I've been staring at this for about an hour and I honestly have no idea what I'm missing. 我一直盯着这个看了一个小时,老实说,我不知道我要缺少什么。

#include <iostream>

using namespace std;

void callChain();

double chain(int, int &, int &);

int main()
{
    callChain();
}

void callChain() {
    int totalInches = 53;
    int feet;
    int inches;

    cout << "\nTesting chain for 53 inches: \nExpected result: 15.46 feet: 4 inches: 5" << endl;
    cout << "Actual result: " << chain(totalInches, feet, inches) << " feet: " << feet << " inches: " << inches << endl;
}

double chain(int totalInches, int &feet, int &inches) {
    feet = totalInches / 12;
    inches = totalInches % 12;

    return (feet) * 3.49 + (inches) * .30;
}

The return is correct, so obviously the function is working, but for the life of me I can't figure out why feet and inches aren't changing. 返回值是正确的,因此显然该功能可以正常工作,但是对于我一生来说,我无法弄清楚为什么脚和英寸没有变化。 Everything is spelled right, I have all my ampersands, but for some reason, the display is showing feet as 8 and inches as 7. I have no idea where those numbers are even coming from. 一切拼写正确,我有所有的“&”号,但由于某种原因,显示屏显示的英尺数为8,英寸显示为7。我什至不知道这些数字从何而来。

Remember that << is syntatic sugar for a function call and the order of evaluation of these functions is not necessarily in the order that you think it is. 请记住, <<是函数调用的语法糖,并且这些函数的求值顺序不一定与您认为的顺序相同。 In fact C++ doesn't actually specify the order. 实际上,C ++实际上并未指定顺序。 So the final parts of you second cout are printing out the starting values of feet and inches . 所以你第二次的最后部分cout打印出的起始值feetinches

Call chain(totalInches, feet, inches) in an intermediate step before the second cout , perhaps even in this way (Acknowledge @DavidSchwartz): 在第二个cout之前的中间步骤中调用chain(totalInches, feet, inches) ,甚至可以这样(Acknowledge @DavidSchwartz):

cout << "Actual result: " << chain(totalInches, feet, inches);
cout << " feet: " << feet << " inches: " << inches << endl;

The evaluation order is unspecified in the ISO C++ standard, according to ostream chaining, output order 根据ostream链,输出顺序 ,ISO C ++标准中未指定评估顺序

To ensure the function is called before those variables are accessed, separate the output chain: 为了确保在访问这些变量之前调用该函数,请分离输出链:

cout << "Actual result: " << chain(totalInches, feet, inches);
cout << " feet: " << feet << " inches: " << inches << endl;

Just for better illustration of the answers given so far (giving some more details): 只是为了更好地说明到目前为止给出的答案(给出更多详细信息):

std::cout << x is syntactic sugar for operator<<(std::cout, x) ; std::cout << xoperator<<(std::cout, x)语法糖; as operator<< returns its first argument, std::cout << x << y; as operator<<返回其第一个参数, std::cout << x << y; gets: 得到:

operator<<(operator<<(std::cout, x), y);

Obviously, the first argument to the outer call will be evaluated (eg the inner call executed) before the the outer call actually is performed – and this is where any guarantees already end, ie as order of argument evaluation is unspecified, the compiler is quite well allowed to evaluate y before the call to the inner operator – including the evaluation of the latter's arguments! 显然,外部调用的第一个参数将在实际执行外部调用之前进行评估(例如,执行内部调用)–这是所有保证都已结束的地方,即,由于未指定参数评估的顺序,因此编译器相当允许在调用内部运算符之前对y进行评估-包括对后者的参数进行评估!

operator<<(operator<<(std::cout, f(x)), x);

Similarly now, the only guarantees here are that f(x) is called before the inner operator is called and the inner operator being called before the outer one; 现在,类似地,唯一的保证是f(x)在内部运算符被调用之前被调用,内部运算符在外部运算符之前被调用; still, the raw x can be evaluated at very first... 不过,原始x可以在第一时间进行评估...

Obviously, your compiler starts evaluating the arguments from last to first, most likely due to the calling convention in use (quite likely cdecl ; on Windows possibly stdcall )... 显然,您的编译器从最后到第一个开始评估参数,这很可能是由于使用了调用约定(很可能是cdecl ;在Windows上可能是stdcall )。

The change in the accepted answer introduces a sequence point between the function calls (old, pre-C++11 wording), which ensures that all effects of the previous call are completed before the call to the next function, ie (using new C++11 wording): 可接受答案的更改引入了函数调用之间的顺序点(旧的C ++ 11以前的措辞),从而确保了上一个调用的所有效果在调用下一个函数之前即(使用新C ++ 11措辞):

operator<<(std::cout, f(x)); // is sequenced  b e f o r e  next line
operator<<(std::cout, x);    // is sequenced  a f t e r  previous line

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM