C# 中的求值行为和顺序

发布于 2024-10-11 08:03:30 字数 476 浏览 4 评论 0 原文

可能的重复:
C#:函数求值顺序(与 C 相比)

代码片段:

i += ++i;
a[++i] = i;
int result =  fun() - gun();
//statement of similar kind

是他们的行为在 C# 中定义良好?在 C++ 中,此类代码会调用未定义/未指定的行为。另请在回复中引用语言规范中的相关部分!

Possible Duplicate:
C#: Order of function evaluation (vs C)

Code snippet:

i += ++i;
a[++i] = i;
int result =  fun() - gun();
//statement of similar kind

Are their behavior well-defined in C#? In C++, such code invokes undefined/unspecified behavior. Please also quote the relevant sections from the language specification in your response!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

放手` 2024-10-18 08:03:30

这里的关键是“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()-、赋值。

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:

  • Except for the assignment operators,
    all binary operators are
    left-associative, meaning that
    operations are performed from left to
    right. For example, x + y + z is
    evaluated as (x + y) + z.
  • The
    assignment operators and the
    conditional operator (?:) are
    right-associative, meaning that
    operations are performed from right to
    left. For example, x = y = z is
    evaluated as x = (y = z).

The first is logically expanded (or: use the associativity rules) as:

i = i + ++i;

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.

a[++i] = i;

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:

    int[] a = { 0, 0, 0, 0, 0 };
    int i = 2;
    a[++i] = i;

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.

初见 2024-10-18 08:03:30

人们总是对此感到困惑,这是不幸的,因为在 C# 中它非常简单。规则是:

  • 从执行线程、周期、故事结尾观察时,观察到子表达式是从左到右计算的。 (如果其他线程正在观察副作用,则允许其他线程观察到评估顺序不同。)

  • 运算符执行的顺序由它们的优先级和关联性决定。

这是唯一的两个相关规则,它们完全定义了您给出的代码的行为。 首先对

i += ++i; 

i 求值,然后对 ++i 求值,然后执行 += 。

a[++i] = i; 

首先评估 'a',然后评估 ++i,然后运行索引运算符,然后评估 i,然后进行赋值。

int result =  fun() - gun(); 

首先计算结果,然后是 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

i += ++i; 

first i is evaluated, then ++i is evaluated, and then the += is executed.

a[++i] = i; 

First 'a' is evaluated, then ++i is evaluated, then the indexing operator runs, then i is evaluated, then the assignment happens.

int result =  fun() - gun(); 

first result is evaluated, then fun, then gun, then the subtraction, then the assignment.

Please also quote the relevant sections from the language specification in your response!

You are perfectly capable of looking in the table of contents. It's not hard to find.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文