C# 中的求值行为和顺序
可能的重复:
C#:函数求值顺序(与 C 相比)
代码片段:
i += ++i;
a[++i] = i;
int result = fun() - gun();
//statement of similar kind
是他们的行为在 C# 中定义良好?在 C++ 中,此类代码会调用未定义/未指定的行为。另请在回复中引用语言规范中的相关部分!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这里的关键是“1.4表达式”和“7.3.1运算符优先级和结合性”中的表。我不会重复 1.4 中的表格,而是引用 7.3.1 中的表格:
第一个是逻辑扩展(或:使用结合性规则)为:
这里,顺序(来自表)是预递增,然后是加法,然后是赋值 - 所以我们应该期望 i 加倍一。事实上,使用
i=6
,我们得到了预期的 13。再次从表中,顺序应该是数组访问、预递增、赋值 - 所以我期望第 i+1 个值是 i+1。事实上,检查一下:
我们确实得到了
{0, 0, 0, 3, 0}
。最后,方法调用优先于减法,然后是从左到右;所以它应该是
fun()
、gun()
、-
、赋值。The key here is the table in "1.4 Expressions", and "7.3.1 Operator precedence and associativity". I won't duplicate the table from 1.4, but to quote 7.3.1:
The first is logically expanded (or: use the associativity rules) as:
here, the order (from the table) is pre-increment, then additive, then assignment - so we should expect i to double plus one. And indeed, with
i=6
, we get 13 as expected.again from the table, order should be array access, pre-increment, assignment - so I would expect the i+1'th value to be i+1. And indeed, checking:
we do indeed get
{0, 0, 0, 3, 0}
.With the last, method invocation takes priority over subtraction, then it is left-to-right; so it should be
fun()
,gun()
,-
, assignment.人们总是对此感到困惑,这是不幸的,因为在 C# 中它非常简单。规则是:
从执行线程、周期、故事结尾观察时,观察到子表达式是从左到右计算的。 (如果其他线程正在观察副作用,则允许其他线程观察到评估顺序不同。)
运算符执行的顺序由它们的优先级和关联性决定。
这是唯一的两个相关规则,它们完全定义了您给出的代码的行为。 首先对
i 求值,然后对 ++i 求值,然后执行 += 。
首先评估 'a',然后评估 ++i,然后运行索引运算符,然后评估 i,然后进行赋值。
首先计算结果,然后是 fun,然后是gun,然后是减法,然后是赋值。
您完全有能力查看目录。不难找到。
People always get this so confused, which is unfortunate because in C# it is extremely straightforward. The rules are:
subexpressions are observed to be evaluated left to right when observed from the executing thread, period, end of story. (Order of evaluation is permitted to be observed to be different by some other thread if some other thread is watching the side effects.)
the order in which the operators execute is determined by their precedence and associativity.
Those are the only two relevant rules, and they completely define the behaviour of the code you give. In
first i is evaluated, then ++i is evaluated, and then the += is executed.
First 'a' is evaluated, then ++i is evaluated, then the indexing operator runs, then i is evaluated, then the assignment happens.
first result is evaluated, then fun, then gun, then the subtraction, then the assignment.
You are perfectly capable of looking in the table of contents. It's not hard to find.