【问题标题】:How does the pre/post-increment operator behave before variable allocation?前/后增量运算符在变量分配之前如何表现?
【发布时间】:2016-12-28 18:17:59
【问题描述】:
int x=3, y=4, n=0;
int n = x * y / --x;

这段代码计算n 为6,但我认为它是4;因为--x 是一个预递减运算符,优先级高于*/,所以它是2 * 4 / 2 我假设它是2*4 而不是3*4,因为x 已经递减了,所以我在这里想念什么? here 提出了同样的问题,但答案是特定于 PHP 的。

【问题讨论】:

  • @kbunarjo 这没有回答我的问题。
  • x 在到达 --x 之前已经被计算过了,因此 x 仍然是 3。
  • 你确定吗?顺便说一句,那是 C#。现在谈到 C++,我继续在 Xcode 中尝试了这个,它给了我一个警告:“未排序的修改和访问 'x'”。
  • C# 规范非常清楚,关联性、优先级和评估顺序都是不同的东西。像xy--x 这样的表达式是从左到右计算的。我确定这个问题有重复。

标签: c# operators operator-precedence


【解决方案1】:

如果我们编译这段代码然后使用 ildasm 检查它,我们会得到以下指令(使用https://en.wikipedia.org/wiki/List_of_CIL_instructions 翻译):

 IL_0000:  nop          // I compiled in debug mode, this does nothing
 IL_0001:  ldc.i4.3     // Push 3 onto the stack as int32.  
 IL_0002:  stloc.0      // Pop a value from stack into local variable 0.
 IL_0003:  ldc.i4.4     // Push 4 onto the stack as int32.  
 IL_0004:  stloc.1      // Pop a value from stack into local variable 1.
 IL_0005:  ldloc.0      // Load local variable 0 onto stack.
 IL_0006:  ldloc.1      // Load local variable 1 onto stack.
 IL_0007:  mul          // Multiply values.
 IL_0008:  ldloc.0      // Load local variable 0 onto stack.
 IL_0009:  ldc.i4.1     // Push 1 onto the stack as int32.  
 IL_000a:  sub          // Subtract value2 from value1, returning a new value.
 IL_000b:  dup          // Duplicate the value on the top of the stack.
 IL_000c:  stloc.0      // Pop a value from stack into local variable 0.    
 IL_000d:  div          // Divide two values to return a quotient or floating-point result. 
 IL_000e:  stloc.2      // Pop a value from stack into local variable 2.
 IL_000f:  ret          // Return from method, possibly with a value.   

这表明表达式是从左到右计算的,即使 --x*/ 之前。

这也记录在 C# 语言规范中(第 7.3 节操作符):

表达式中运算符的求值顺序由 运算符的优先级和关联性(第 7.3.1 节)。

表达式中的操作数从左到右计算。为了 例如,在 F(i) + G(i++) * H(i) 中,方法 F 使用旧的 i 的值,然后使用 i 的旧值调用方法 G,并且, 最后,使用 i 的新值调用方法 H。这是分开的 from 且与运算符优先级无关。

【讨论】:

  • 您能否举一个不使用函数,仅使用运算符的 LTR 评估示例?
  • 你的例子就是一个。操作数被评估为 LTR(x,然后是 y,然后是 --x)。 操作的顺序由运算符优先级决定,但操作数本身是从左到右计算的。
  • @D Stanley 写的正是我要说的。操作数和运算符是有区别的。运算符优先级定义了处理操作数的顺序,但在处理表达式之前,所有操作数都从左到右求值,与表达式中的运算符无关。
猜你喜欢
  • 2016-05-19
  • 2023-03-17
  • 2016-02-02
  • 2011-03-12
  • 1970-01-01
  • 2012-10-17
  • 2015-08-20
  • 2023-01-14
相关资源
最近更新 更多