C、C++、Java 和 C# 中的前后增量运算符行为
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6457130/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Pre & post increment operator behavior in C, C++, Java, & C#
提问by Nick
DISCLAIMER:This is not a real-world example. It is just a theoretical question of how these languages work.
免责声明:这不是真实世界的例子。这只是这些语言如何工作的理论问题。
What exactly are the differences between C/C++, C#, and Java when it comes to post & pre increment operators?
C/C++、C# 和 Java 之间在 post 和 pre 增量运算符方面到底有什么区别?
This is what I get with VC++10, Java 1.6, and C# 4
这就是我使用 VC++10、Java 1.6 和 C#4 得到的结果
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 |
+-----+-----+------+------+----+
回答by fredoverflow
Java and C# evaluate expressions from left to right, and the side-effects are visible immediately.
Java 和 C# 从左到右计算表达式,副作用立即可见。
In C++, the order of evaluation of subexpressions is unspecified, and modifying the same object twice without an intervening sequence point is undefined behavior.
在 C++ 中,子表达式的求值顺序是未指定的,在没有中间序列点的情况下修改同一个对象两次是未定义的行为。
回答by Eric Lippert
I don't have the time to write up a detailed description of the differencesbetween C++, C, C# and Java. I will merely say that the C# behaviour of the pre and post increment operators is fully specified(in single-threaded scenarios; if you want to know about its atomicity, guarantees about observations of read and write orders in multi-processor weak memory models and so on, you're on your own to do that research.) It is not fully specified in C and C++; a compiler has broad lattitude to do whatever it pleases with re-ordering side effects. I have never used Java so I'm not going to hazard a guess as to what Java does.
我没有时间详细描述C++、C、C# 和 Java 之间的差异。我只会说 C# 的前后增量操作符的行为是完全指定的(在单线程场景中;如果你想知道它的原子性,保证在多处理器弱内存模型中观察读写顺序和依此类推,你自己来做那个研究。)它在 C 和 C++ 中没有完全指定;编译器有很大的自由度可以随心所欲地重新排序副作用。我从未使用过 Java,所以我不会冒险猜测 Java 的作用。
For more information on what C# does you should read the C# specification. For a short take on it, read my answer to this question:
有关 C# 功能的更多信息,您应该阅读 C# 规范。简要介绍一下,请阅读我对这个问题的回答:
What is the difference between i++ and ++i?
For an even shorter take:
对于更短的拍摄:
Subexpressions in a C# expression are logically grouped by precedence and associativity, and then evaluated from left to rightregardless. (So for example, A() + B() * C() evaluates A(), then B(), then C(). The fact that the multiplication "comes before" the addition is irrelevant; the subexpressions are always evaluated left to right.)
C# 表达式中的子表达式按优先级和关联性在逻辑上分组,然后不管从左到右求值。(例如,A() + B() * C() 计算 A(),然后是 B(),然后是 C()。乘法“先于”加法这一事实无关紧要;子表达式总是被计算左到右。)
If the evaluation of a subexpression causes a side effect because of a pre or post increment subexpression then the side effect happens immediately beforethe result is produced.
如果子表达式的计算由于前或后自增子表达式而导致副作用,则副作用会在结果产生之前立即发生。
回答by Vlad
In C++, this is undefined behaviour, so anyanswer would be correct. See Undefined behavior and sequence pointsfor further details.
在 C++ 中,这是未定义的行为,因此任何答案都是正确的。有关更多详细信息,请参阅未定义行为和序列点。
Not sure about other languages, but I would expect this code to be incorrect there, too.
不确定其他语言,但我希望这段代码在那里也不正确。
EDIT:
See Eric Lippert's answer about C#. He disproves my assumption about C#'s behaviour.
编辑:
请参阅 Eric Lippert 对 C# 的回答。他反驳了我对 C# 行为的假设。
回答by GWW
In C++ at least this undefined behaviour. Quoting the C++ standard:
在 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.
在前一个和下一个序列点之间,一个标量对象的存储值最多应通过表达式的评估修改一次。
回答by MBCook
The Java memory model ensures the order the loads and stores are done, so it should come out the same on any JVM (I believe).
Java 内存模型确保加载和存储完成的顺序,因此它在任何 JVM 上都应该是相同的(我相信)。
It looks like C++ has the same order of operations, but once you use it twice on a line you start running into other stuff (Vlad is right there). If you try other C++ compilers, you may find they come up with different answers.
看起来 C++具有相同的操作顺序,但是一旦您在一行上使用它两次,您就会开始遇到其他东西(Vlad 就在那里)。如果您尝试其他 C++ 编译器,您可能会发现它们给出了不同的答案。
I'm sure C# has the same order of operations, but my guess is they have a memory model (like Java) that ensures consistency, but I don't have a lot of knowledge here.
我确信 C# 具有相同的操作顺序,但我猜他们有一个内存模型(如 Java)来确保一致性,但我在这里没有很多知识。
回答by commit
I like this question and found very good explanations but I just want to explain this question by it's value how it is evaluated:
我喜欢这个问题并找到了很好的解释,但我只想通过它的价值来解释这个问题是如何评估的:
I will only talk about java and c/C++ as I have no knoledge about C#
我只谈 java 和 c/C++,因为我对 C# 一无所知
Statements are evaluated in following ways
语句的评估方式如下
In java
在 Java 中
Statement ||||||||||||||||||||||||||||||||||||||||||||||||||||||| Trace
声明 |||||||||||||||||||||||||||||||||||||||||||||| |||||| 痕迹
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
In C/C++
在 C/C++ 中
Statement Trace
语句跟踪
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
In short in java expression goes left to right so at the 2nd "a" it will fetch new value and in c/c++ it will first evaluate whole expression and then increment all operands of statement.
简而言之,java 表达式从左到右,因此在第二个“a”处,它将获取新值,而在 c/c++ 中,它将首先评估整个表达式,然后增加语句的所有操作数。