9

试图理解此页面上的示例使我的大脑皱巴巴: http ://answers.yahoo.com/question/index?qid=20091103170907AAxXYG9

更具体地说,这段代码:

int j = 4;
cout << j++ << j << ++j << endl;

给出输出:566

现在,如果表达式从右到左求值,这对我来说是有意义的,但是在 Java 中是一个类似的表达式:

int j = 4;
System.out.print("" + (j++) + (j) + (++j));

给出的输出:456

哪个更直观,因为这表明它是从左到右评估的。在各个站点上对此进行了研究,似乎对于 C++,编译器之间的行为有所不同,但我仍然不相信我理解。Java 和 C++ 之间的这种评估差异的解释是什么?谢谢。

4

3 回答 3

11

当一个操作有副作用时,C++ 依赖序列点规则来决定副作用(例如增量、组合赋值等)何时必须生效。逻辑and-then/ or-else(&&||) 运算符、三元?问号运算符和逗号创建序列点;+, -,<<等等不。

相反,Java 在进行进一步评估之前会完成副作用。

当您在没有序列点的情况下多次使用具有副作用的表达式时,所产生的行为在 C++ 中是未定义的。任何结果都是可能的,包括没有逻辑意义的结果。

于 2012-06-21T19:30:34.783 回答
5

Java 保证运算符的操作数看起来是以特定的评估顺序进行评估的,即从左到右。在评估右侧操作数的任何部分之前,二元运算符的左侧操作数似乎已被完全评估。Java 还保证在执行操作本身的任何部分之前,运算符的每个操作数(条件运算符 、 和 除外&&||似乎?:都已被完全评估。有关更多详细信息,请参阅 Java 语言规范 §15.7。

另一方面,如果表达式不明确,C++ 很高兴让您摆脱未定义的行为,因为语言本身不保证子表达式的任何求值顺序。有关详细信息,请参阅序列点。

于 2012-06-21T19:33:22.823 回答
3

在 C++ 中,子表达式的求值顺序不是从左到右也不是从右到左。它是未定义的。

于 2012-06-21T19:30:09.947 回答