我有以下代码。这个输出的原因是什么?
int x=80;
int &y=x;
x++;
cout<<x<<" "<<--y;
输出结果是80 80.我不明白怎么回事。我认为x的输出是81,但我对y没有任何了解。参考变量如何受减量运算符影响。有人可以解释吗?
我有以下代码。这个输出的原因是什么?
int x=80;
int &y=x;
x++;
cout<<x<<" "<<--y;
输出结果是80 80.我不明白怎么回事。我认为x的输出是81,但我对y没有任何了解。参考变量如何受减量运算符影响。有人可以解释吗?
关于重定向操作符<<
的一个令人讨厌的事情是,它们直观地传达了确实不存在的“顺序计算”的缺陷。
当你写
std::cout << f() << g() << std::endl;
的输出将首先显示的f()
结果,然后g()
的结果,而是g()
实际调用可以调用f()
之前发生。
它甚至会比这更糟糕......这不是该序列是不可预测的,但确实序列的概念本身是无效的。在
std::cout << f(g()) << h(i()) << std::endl;
它例如法律的第一个函数被调用为g()
,其次为i()
,其次是h()
最后由f()
。甚至不保证所有调用的顺序都是相同的(不是因为编译器制造商喜欢嘲笑你,而是因为代码可以内联,并且如果包含函数在不同的上下文中内联,编译器可以决定不同的顺序)。
唯一C++运算符,在所述评价顺序保证的序列是:
&&
:首先评估左侧且仅当结果为“真”的计算结果的右侧||
:首先评估只有在结果为“假”时评估右侧?:
:首先评估条件,然后仅评估第二或第三个操作数,
:逗号运算符...评估左侧,丢弃该值,然后评估并返回右侧。注:函数参数之间的逗号不是逗号运算符,也不会执行评估命令。而且这guaratee只针对预定义的运算符有效。如果您的班级中存在&&
,||
或,
,他们只是普通的操作员,对评估顺序没有任何特殊限制。
任何其他运营商不征收评估顺序任何限制,这包括<<
即便利用某种技巧,你以为。
计算表达式为:
((cout << x) << " ") << --y;
有左手侧的评估和表达式的右手侧时,编译器可以输出代码之间没有序列点(或排序)作为第一步评估--y
。
由于y
是x
这里的参考,这是因为你无论从阅读和中间没有顺序点在同一个表达式写入x
实际上未定义的行为。
请检查编辑的代码这肯定与指针算术有关。当我们说y有一个地址x即80,并尝试和减少y时,它也不会在我的系统上递减。 –
@SanyamGoel:这是未定义的行为。不同的编译器可以(也将会)输出不同的东西。 LHS和RHS的评估顺序是实现定义的,加上对'x'的读取和写入,没有顺序点=>未定义的行为(即它不是合适的C++,它可以做任何事情)。 – Mat
建议编辑:*“请参阅[本SO线程](http://stackoverflow.com/questions/4176328/undefined-behavior-and-sequence-points)的详细解释。“* – jrok
这是未定义的行为,C/C++标准没有定义该参数的方式被压入堆栈,和通常的说法是按相反的顺序这里推动时,例如:
func(1, 2)
将被评估喜欢的东西:
push 2
push 1
call func
所以你的情况,--y
进行评估,并推动x
不前。正是在这个例子清楚:
#include <iostream>
int a() { std::cout << "a" << std::endl ; return 1; }
int b() { std::cout << "b" << std::endl ; return 2; }
int main(void) {
std::cout << a() << " " << b() << std::endl;
return 0;
}
从第一次看
,它应该打印:
a
b
1 2
但它打印:
b
a
1 2
x++
增量X并产生作为表达式的结果是x的原始值。
特别是,对于x ++,没有时间顺序暗示增加和产生x的原始值。编译器可以自由发出产生x的原始值的机器码,例如,它可能出现在某个寄存器中,并且延迟增量直到表达式结束(下一个序列点)。虽然x++
似乎增加x到,它不会直到打印。根据--y
,它将获得增加的值(81)并在打印之前将其减少,因为它是前缀运算符。
也许这个问题应该有助于澄清你:什么是C++指针变量和引用变量之间的区别是什么? (http://stackoverflow.com/questions/57483/what-are-the-differences-between-pointer-variable-and-reference-variable-in-c) – yasouser
这类似于(到http://stackoverflow.com /问题/ 18426473 /预增 - 不工作,AS-I-期望/ 18426505#18426505)。 你缺少一个序列点。 –