我在C#和C ++中尝试过以下内容:
int a = 5;
int b = (a++)+(++a)+(a--)+(--a);
我试图在C#和C ++中获得b的结果。 但我在两者中得到了不同的答案。
我在C#中获得23分,在C ++中获得20分。
所以,请回答我为什么会这样?可能是什么原因?
答案 0 :(得分:7)
C#从左到右对此进行评估。在C ++中,诸如你的funny expressions会调用undefined behavior,因为您正在更改变量并在没有干预sequence point的情况下再次阅读它。
这意味着允许不同的编译器(甚至具有不同优化设置的相同编译器)(通常将)为(a++)+(++a)+(a--)+(--a)
生成不同的结果。
答案 1 :(得分:4)
表达式在C#中有明确定义的行为(从左到右评估)
在C#中,输出为24(不是23)
int b = (a++)+(++a)+(a--)+(--a);
// 5 + 7 + 7 + 5 = 24
在C ++中,表达式调用Undefined Behaviour,因为a
在两个sequence points之间被多次修改。
答案 2 :(得分:0)
查看here以获取C ++的完整列表。正如FredOverflow所说,C#从左到右进行评估
答案 3 :(得分:0)
无论如何都需要查看这个,所以我想在这里发布它。
来自C#5.0 Spec
5.3.3.21具有嵌入式表达式的表达式的一般规则
以下规则适用于这些类型的表达式:带括号的表达式(第7.6.3节),元素访问表达式(第7.6.6节),带索引的基本访问表达式(第7.6.8节),递增和递减表达式(§ 7.6.9,§7.7.5),强制转换表达式(§7.7.6),一元+, - ,〜,*表达式,二进制+, - ,*,/,%,<<,>>, <,< =,>,> =,==,!=,is,as,&,|,^表达式(§7.8,§7.9,§7.10,§7.11),复合赋值表达式(§ 7.17.2),检查和未检查的表达式(第7.6.12节),以及数组和委托创建表达式(第7.6.10节)。
这些表达式中的每一个都有一个或多个子表达式,这些子表达式无条件地以固定顺序(强调我的)进行评估。例如,二进制%运算符计算运算符的左侧,然后是右侧。索引操作评估索引表达式,然后按从左到右的顺序计算每个索引表达式。
每种表达式的详细规则在第7节中。我不会在这里列出所有表达式,但是启发式是按代码编写的。 E.g。
7.5.1.2参数列表的运行时评估
参数列表的表达式始终按其编写顺序进行计算。因此,例子
class Test { static void F(int x, int y = -1, int z = -2) { System.Console.WriteLine("x = {0}, y = {1}, z = {2}", x, y, z); } static void Main() { int i = 0; F(i++, i++, i++); F(z: i++, x: i++); } }
产生输出
x = 0, y = 1, z = 2 x = 4, y = -1, z = 3