C++与C#运算符的优先级

C++ vs C# operators precedence

本文关键字:优先级 运算符 C++      更新时间:2023-10-16

我在visual studio C++和C#上有相同的代码,每个编译器都有不同的输出,尽管两者具有相同的优先级和关联性

关于C++

int i = 10;  
int a = i++ + ++i + i--;  
printf("a=%un",a);
i = 10;
a = i++ + i;
printf("a=%un",a);
int x=2,y=3;
int z=((x++)*(x++))+((++y)*(++y));
printf("x=%u , y=%u , z=%u n",x,y,z);

输出是

a=33
a=20
x=4 , y=5 , z=29

关于C#

int i = 10;
int a = i++ + ++i + i--;
Console.WriteLine("a={0}",a);
i = 10;
a = i++ + i;
Console.WriteLine("a={0}", a);
int x = 2, y = 3;
int z=((x++)*(x++))+((++y)*(++y));
Console.WriteLine("x={0} , y={1} , z={2}",x,y,z);

输出是

a=34
a=21
x=4 , y=5 , z=26

在C#中,我发现运算遵循优先级表,后增量的优先级高于前增量,因此它将值放在后增量对此我找不到任何合乎逻辑的解释。有人能解释一下吗?

这不是优先级的问题,而是操作数求值顺序和副作用排序的问题。在C++中,求值顺序是未指定的,您还可以从变量的未排序修改中获得未定义的行为。

我不知道C#是否指定了这种疯狂代码的行为,但你不应该用任何语言写这种无稽之谈。

在C++中,代码具有未定义的行为,因为后增量运算符的副作用相对于其他操作没有完全排序。

在C#中有这样一个概念:DAS(定义分配状态);表达式i之前的DAs必须等于表达式i - 1之后的DAs。

表达式x++x--的计算顺序如下。

  1. 计算并保存x的值
  2. 该值用于计算x++x--并保存
  3. 此保存的结果将成为操作的结果

所以考虑语句

int a = i++ + ++i + i--;

第一个表达式是i++。对CCD_ 9进行了评价。其值为10。它将保存为表达式的值。然后应用操作CCD_ 11。运算结果为11。因此CCD_ 13的输出DAS等于CCD_。它是下一个表达式++i的输入DAS。这里CCD_ 16被评估是因为存在预增量运算符。值为12,并且i的输出DAS为12。CCD_ 20的评价顺序与CCD_ 21相同。所以我们有

10 + 12 + 12 = 34

表达式的CCD_ 22的输出DAS是CCD_。

也许这不是很清楚,但C++和C#之间的区别在于,C#使表达式的评估过程更加确定和清晰,以避免未定义的行为。