可能重复:
C#:函数评估的顺序(vs C)
代码片段:
i += ++i;
a[++i] = i;
int result = fun() - gun();
//statement of similar kind
他们的行为在 C# 中是否明确定义?在 C++ 中,此类代码会调用未定义/未指定的行为。还请在您的回复中引用语言规范中的相关部分!
可能重复:
C#:函数评估的顺序(vs C)
代码片段:
i += ++i;
a[++i] = i;
int result = fun() - gun();
//statement of similar kind
他们的行为在 C# 中是否明确定义?在 C++ 中,此类代码会调用未定义/未指定的行为。还请在您的回复中引用语言规范中的相关部分!
这里的关键是“1.4 表达式”和“7.3.1 运算符优先级和关联性”中的表格。我不会复制 1.4 中的表格,而是引用 7.3.1:
- 除赋值运算符外,所有二元运算符都是左结合的,这意味着运算是从左到右执行的。例如,x + y + z 被计算为 (x + y) + z。
- 赋值运算符和条件运算符 (?:) 是右结合的,这意味着操作是从右到左执行的。例如,x = y = z 被计算为 x = (y = z)。
第一个在逻辑上扩展(或:使用关联规则)为:
i = i + ++i;
在这里,顺序(从表中)是预先递增的,然后是加法的,然后是赋值的——所以我们应该期望 i 加倍加一。事实上,有了i=6
,我们得到了 13 的预期。
a[++i] = i;
再次从表中,顺序应该是数组访问、预增量、赋值 - 所以我希望第 i+1 个值是 i+1。事实上,检查:
int[] a = { 0, 0, 0, 0, 0 };
int i = 2;
a[++i] = i;
我们确实得到了{0, 0, 0, 3, 0}
。
最后,方法调用优先于减法,然后是从左到右;所以应该是fun()
, gun()
, -
, 赋值。
人们总是对此感到困惑,这是不幸的,因为在 C# 中它非常简单。规则是:
当从执行线程、句点、故事结尾观察时,观察到子表达式从左到右进行评估。(如果其他线程正在观察副作用,则允许其他线程观察到评估顺序不同。)
运算符的执行顺序由它们的优先级和关联性决定。
这些是仅有的两个相关规则,它们完全定义了您提供的代码的行为。在
i += ++i;
首先计算 i,然后计算 ++i,然后执行 +=。
a[++i] = i;
首先评估 'a',然后评估 ++i,然后运行索引运算符,然后评估 i,然后进行分配。
int result = fun() - gun();
评估第一个结果,然后是 fun,然后是 gun,然后是减法,然后是作业。
还请在您的回复中引用语言规范中的相关部分!
您完全有能力查看目录。不难找到。