对于下面的代码:
main() {
int i = 1 ;
cout << i << ++i << i++ ;
}
为什么我得到的输出是 331 而不是预期的 122 ?
(即使我使用printf
而不是 cout 也是如此?)
对于下面的代码:
main() {
int i = 1 ;
cout << i << ++i << i++ ;
}
为什么我得到的输出是 331 而不是预期的 122 ?
(即使我使用printf
而不是 cout 也是如此?)
<<
是一个函数,类似于ostream& operator<<(ostream& lhs, RhsType rhs)
.
cout << a;
相当于
operator<<(cout, a);
该函数返回lhs,即return lhs
-,所以在上面的例子cout
中是返回的。
所以你的例子
cout << i << ++i << i++ ;
相当于
operator<<(operator<<(operator<<(cout, i), ++i), i++);
更正C++ 没有指定执行递增操作的顺序。对你和我来说,最嵌套的优先级似乎是合乎逻辑的,但就编译器而言,它可以随时自由地执行增量。它与函数的行为相同,例如myFunc(cout, i++, ++i, i)
计算增量的顺序未定义。唯一可以保证的是功能是从内到外评估的。
编译器可以自由更改评估顺序。您在同一个状态上多次更改 i ,这会导致未定义的行为。
这就是为什么你不应该编写这样的代码的原因。我相信这会给你不同的编译器不同的结果。使用 Visual C++,当在 Debug 和 Release 版本中运行时,这会为您提供不同的输出。
您观察到的输出可以用这种方式解释:表达式在传递到或用于输出之前从右到左进行评估。cout
printf
起始值为 1
i++ 是后增量,即它会打印值 (1) 然后递增到 2:输出 1
++i 是预先递增的,所以在打印之前 2 变成了 3:输出 3
最后,打印 i (3) 的当前值:输出 3
这些各自的值被传递给输出例程。
为了澄清,我的回答只是试图解释观察到的行为,而不是为编译器或输出例程如何排序它们的评估/操作制定硬性规则。
话虽如此,这种类型的代码不是好的做法,很可能会导致各种可以避免的问题。