Siy*_*ual 35 c# pre-increment post-increment
我理解它们之间的区别i++ and ++i,但我不太清楚为什么我得到以下结果:
static void Main(string[] args)
{
int c = 42;
c = c++;
Console.WriteLine(c); //Output: 42
}
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,因为这是将变量赋值给自己然后递增值,我希望结果是43.然而,它正在回归42.使用时也得到相同的结果c = c--;.
我意识到我可以简单地使用c++;并完成它,但我更好奇它为什么表现得如此.谁能解释一下这里发生了什么?
pok*_*oke 34
我们来看看中间语言代码:
IL_0000: nop
IL_0001: ldc.i4.s 2A
IL_0003: stloc.0 // c
IL_0004: ldloc.0 // c
Run Code Online (Sandbox Code Playgroud)
这会将常量整数加载42到堆栈中,然后将其存储到变量中c,并立即将其加载到堆栈中.
IL_0005: stloc.1
IL_0006: ldloc.1
Run Code Online (Sandbox Code Playgroud)
这会将值复制到另一个寄存器中,并再次加载它.
IL_0007: ldc.i4.1
IL_0008: add
Run Code Online (Sandbox Code Playgroud)
这会将常量1添加到加载的值
IL_0009: stloc.0 // c
Run Code Online (Sandbox Code Playgroud)
...并将结果(43)存储到变量中c.
IL_000A: ldloc.1
IL_000B: stloc.0 // c
Run Code Online (Sandbox Code Playgroud)
然后加载另一个寄存器的值(仍然是42!)并存储到变量中c.
IL_000C: ldloc.0 // c
IL_000D: call System.Console.WriteLine
IL_0012: nop
IL_0013: ret
Run Code Online (Sandbox Code Playgroud)
然后从变量加载值(42)并打印.
因此,您可以从中看到,虽然在返回结果后将c++变量递增1,但在将值赋给变量之前仍然会发生递增.所以序列更像是这样的:
ccc这应该解释为什么你得到那个结果:)
要添加另一个示例,因为在删除后的注释中提到了这一点:
c = c++ + c;
Run Code Online (Sandbox Code Playgroud)
这非常相似:假设初始值为2,则首先评估加法的左侧.因此,从变量(2)读取值,然后c递增(c变为3).然后评估添加的右侧.c读取的值(现在为3).然后进行加法(2 + 3),并将结果(5)分配给变量.
从中可以看出,您应该避免在正常表达式中混合递增和递减操作.虽然行为定义非常明确且具有绝对意义(如上所示),但有时仍难以绕过它.特别是当您将某些内容分配给在表达式中递增的同一变量时,这会很快变得混乱.所以你自己和别人一个忙,并避免增加/减少操作,当他们不完全靠自己:)
Com*_*hip 20
根据C#运算符上的MSDN页面,赋值运算符(=)的优先级低于任何主运算符,例如++x或x++.这意味着在线
c = c++;
Run Code Online (Sandbox Code Playgroud)
首先评估右侧.表达c++增量c到43,然后返回原始值42作为结果,其用于分配.
作为您链接到州的文档,
[第二种形式是]后缀增量操作.操作的结果是操作数增加之前的值.
换句话说,您的代码相当于
// Evaluate the right hand side:
int incrementResult = c; // Store the original value, int incrementResult = 42
c = c + 1; // Increment c, i.e. c = 43
// Perform the assignment:
c = incrementResult; // Assign c to the "result of the operation", i.e. c = 42
Run Code Online (Sandbox Code Playgroud)
将此与前缀表单进行比较
c = ++c;
Run Code Online (Sandbox Code Playgroud)
哪个会评估为
// Evaluate the right hand side:
c = c + 1; // Increment c, i.e. c = 43
int incrementResult = c; // Store the new value, i.e. int incrementResult = 43
// Perform the assignment:
c = incrementResult; // Assign c to the "result of the operation", i.e. c = 43
Run Code Online (Sandbox Code Playgroud)
文档说明后缀状态:
操作的结果是操作数增加之前的值.
这意味着当你这样做时:
c = c++;
Run Code Online (Sandbox Code Playgroud)
你实际上是重新分配42到c,这就是为什么你看到控制台打印42.但如果你这样做:
static void Main(string[] args)
{
int c = 42;
c++;
Console.WriteLine(c);
}
Run Code Online (Sandbox Code Playgroud)
你会看到它输出43.
如果查看编译器生成的内容(在调试模式下),您将看到:
private static void Main(string[] args)
{
int num = 42;
int num2 = num;
num = num2 + 1;
num = num2;
Console.WriteLine(num);
}
Run Code Online (Sandbox Code Playgroud)
这更清楚地显示了覆盖.如果查看发布模式,您将看到编译器优化整个调用:
private static void Main(string[] args)
{
Console.WriteLine(42);
}
Run Code Online (Sandbox Code Playgroud)