C,C ++,Java和C#中的前后增量运算符行为

Pre & post increment operator behavior in C, C++, Java, & C#

本问题已经有最佳答案,请猛点这里访问。

免责声明:这不是一个真实的例子。这只是这些语言如何工作的一个理论问题。

当涉及到邮政和预增值运营商时,C/C++、C语言和Java的区别究竟是什么?

这就是我在VC++ 10、Java 1.6和C 4中所得到的。

1
2
3
4
5
6
7
8
9
10
11
12
13
int a = 2;
int b = a++ + a++;
int c = ++a + a++ + a++;

      +-----+------+------+----+
      |  C  | C++  | Java | C# |
+-----+-----+------+------+----+
| a   |  7  |  7   |   7  |  7 |
+-----+-----+------+------+----+
| b   |  4  |  4   |   5  | 5  |
+-----+-----+------+------+----+
| c   | 15  |  15  |  16  | 16 |
+-----+-----+------+------+----+


JAVA和C语言评估从左到右的表达式,并且副作用是立即可见的。

在C++中,未指定子表达式的评估顺序,并且在没有中间序列点的情况下修改同一对象两次是未定义的行为。


我没有时间详细描述C++、C、C和Java之间的区别。我只想说,增量前后操作符的c行为是完全指定的(在单线程场景中;如果你想知道它的原子性,保证在多处理器弱内存模型中观察读写顺序等等,你可以自己做这项研究。)它在c和an中没有完全指定。一个编译器有宽大的毅力去做任何事情,并重新排序副作用。我从来没有使用过Java,所以我不会冒险猜测Java是做什么的。

有关C的更多信息,请阅读C规范。简单来说,请阅读我对这个问题的回答:

我++和我的区别是什么?

对于更短的拍摄时间:

C表达式中的子表达式按优先级和关联性进行逻辑分组,然后从左到右进行计算,不管如何。(例如,a()+b()*c()计算a(),然后b(),然后c()。乘法"先于"加法的事实是不相关的;子表达式总是从左到右进行计算。)

如果子表达式的计算由于增量前或增量后的子表达式而导致副作用,则副作用会在生成结果之前立即发生。


在C++中至少有这种未定义的行为。引用C++标准:

Between the previous and next sequence point a scalar object shall have its stored value modified at most once by the evaluation of an expression.


在C++中,这是未定义的行为,所以任何答案都是正确的。有关详细信息,请参见未定义的行为和序列点。

不确定其他语言,但我希望这里的代码也不正确。

编辑:参见埃里克·利珀特关于C的回答。他反驳了我对C的行为的假设。


我喜欢这个问题,并找到了很好的解释,但我只想用它的价值来解释这个问题,它是如何被评价的:

我只会谈论Java和C/C++,因为我对C语言一无所知。

语句的评估方法如下

在爪哇

声明124124124124124124124124124124124124124124124124124124124124124124124124124124124\\124124__trace

1
2
3
4
5
6
7
8
int a= 2;                     a=2
int b= a++ + a++;             a=2, a=3

here value of a=4

int c = ++a + a++ + a++;      a=5, a=5, a=6

here value of a=7

在C/C++中

语句跟踪

1
2
3
4
5
6
7
8
int a= 2;                     a=2
int b= a++ + a++;             a=2, a=2

here value of a=4

int c = ++a + a++ + a++;      a=5, a=5, a=5

here value of a=7

简而言之,Java表达式左到右,因此在第二"A"中它将获得新的值,而在C/C++中,它将首先评估整个表达式,然后递增语句的所有操作数。


Java内存模型确保了加载和存储完成的顺序,所以它应该在任何JVM上都是相同的(我相信)。

看起来C++具有相同的操作顺序,但是一旦你在一行上使用了两次,你就开始运行其他的东西(弗拉德就在那里)。如果你尝试其他C++编译器,你可能会发现他们有不同的答案。

我确信C的操作顺序相同,但我猜想他们有一个内存模型(比如Java)来确保一致性,但是我这里没有很多知识。