很抱歉问你一个愚蠢的问题,但我就是不明白为什么我一直得到这个输出。
所以这是我的代码:
#include <cstdio>
#include <iostream>
using namespace std;
unsigned n = 4242;
int getRemainderOf(int m, int n, int& quotient);
static int l = 0;
int main()
{
int quotient; // the value of which should be changed after calling the func.
for(int i=-1; i<=1; ++i)
{
for(int j=-1; j<=1; ++j)
{
if( i && j )
{
cout << "("<< i*3 << "," << j*7 << ") " <<( getRemainderOf(i*3, 7*j, quotient) ) << " " << quotient <<endl;
cout << "("<< i*7 << "," << j*3 << ") " << getRemainderOf(i*7, 3*j, quotient) << " "; cout << quotient <<endl;
}
}
}
return 0;
}
int getRemainderOf(int m, int n, int& quotient)
{
++l;
cout << l <<endl;
quotient = m / n;
cout << " quotient " << quotient <<endl;
return m % n;
}
所以我期望在输出的第一行中看到的是余数,然后是调用函数 getRemainderOf() 后得到的商。但是,当我像这样计算商的值时,我发现商的值是一个垃圾值。因此,即使我使用引用将变量的值传递给函数,变量的值也不会更改。
有趣的是,如果我分别计算余数(通过调用函数获得)和商,我就会得到正确的结果。
我发现问题可能在于将函数作为运算符
您刚刚发现的是 C++ 怪癖之一的经典示例。您的程序实际上可以分解为这个简单的示例:
int i = 10;
f(i, ++i);
编译器可以选择从左到右对函数参数求值,但这并不能保证。这是一些标准文本:
5.2/4 后缀表达式 [expr.post]
当调用函数时,每个参数都应使用其相应的实参进行初始化。 [Note:这种初始化彼此之间的顺序是不确定的 (1.9) -end note]
因为它们的顺序不确定,所以编译器可以自由地评估++i
在第一个参数之前并用相应的函数参数初始化它,然后评估i
接下来用其各自的参数初始化它。
函数调用参数求值歧义在这里适用的原因是operator<<()
是一个函数,但它只是用运算符语法调用。例如,如果我们使用operator-id语法,您的代码如下所示:
std::operator<<(std::operator<<(std::operator<<(std::cout, "(").operator<<(i*3), ",").operator<<(j*7), ")").operator<<(getRemainderOf(i*3, 7*j, quotient)).operator<<(quotient);
这些只是带有参数的函数调用链,它们遵循与上面相同的规则。
解决方案是对修改对象并在应用中使用它的行为进行排序operator<<()
称呼。您已经通过分区实现了这一点operator<<()
用分号调用两个语句;
,因此该函数保证在之前被调用quotient
被打印。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)