c# - 自赋值后递增

标签 c# post-increment pre-increment

我了解 i++ and ++i 之间的区别,但我不太确定为什么会得到以下结果:

static void Main(string[] args)
{
    int c = 42;
    c = c++;
    Console.WriteLine(c);   //Output: 42
}

在上面的代码中,因为这是将变量分配给自身然后递增值,所以我希望结果为 43。但是,它返回 42。我在使用 c = c--; 时也得到了相同的结果。

我意识到我可以简单地使用 c++; 并完成它,但我更好奇为什么它会以现在的方式运行。谁能解释这里发生了什么?

最佳答案

让我们看一下中间语言代码:

IL_0000:  nop
IL_0001:  ldc.i4.s    2A
IL_0003:  stloc.0     // c
IL_0004:  ldloc.0     // c

这会将常量整数 42 加载到堆栈上,然后将其存储到变量 c 中,并立即再次将其加载到堆栈上。

IL_0005:  stloc.1
IL_0006:  ldloc.1

这会将值复制到另一个寄存器,并再次加载它。

IL_0007:  ldc.i4.1
IL_0008:  add

这会将常量 1 添加到加载的值

IL_0009:  stloc.0     // c

... 并将结果 (43) 存储到变量 c 中。

IL_000A:  ldloc.1
IL_000B:  stloc.0     // c

然后加载另一个寄存器的值(仍然是 42!)并存储到变量 c 中。

IL_000C:  ldloc.0     // c
IL_000D:  call        System.Console.WriteLine
IL_0012:  nop
IL_0013:  ret

然后从变量中加载值 (42) 并打印出来。


因此您可以从中看到,虽然 c++ 在返回结果后 将变量递增 1,但递增仍然发生在将值赋给变量之前.所以序列更像这样:

  1. c获取值
  2. 后自增c
  3. 将之前读取的值赋给c

这应该可以解释为什么你会得到这个结果 :)


再添加一个示例,因为在一条已删除的评论中提到了这一点:

c = c++ + c;

这非常相似:再次假设初始值为 2,首先计算加法的左侧。所以值是从变量 (2) 中读取的,然后 c 递增(c 变为 3)。然后计算加法的右侧。 c 的值被读取(现在是 3)。然后进行加法 (2 + 3),并将结果 (5) 赋值给变量。


由此得出的结论是,您应该避免在普通表达式中混合递增和递减运算。虽然该行为定义明确且绝对有意义(如上所示),但有时您仍然难以理解它。特别是当您将某些内容分配给您在表达式中递增的同一个变量时,这很快就会变得困惑。所以帮自己和别人一个忙,避免在他们不完全独立时进行递增/递减操作:)

关于c# - 自赋值后递增,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33783989/

相关文章:

javascript - 更新值不会在 Javascript 中递增

c# - for循环中的前缀和后缀递增

c - C 中后置和前置增量运算符的奇怪行为

c# - 虚函数

c# - 通过吞掉异常将 WPF 文本框限制为整数

c - 如果在函数中使用, "b"中 "return b++"的增量会怎样?

c - 运算符结合性、优先级

c# - 为什么事件处理程序的返回类型总是 void?

c# - 如何以编程方式调用事件?

java - 如何在计算中使用增量?