采用以下代码(可用作控制台应用程序):
static void Main(string[] args) { int i = 0; i += i++; Console.WriteLine(i); Console.ReadLine(); }
结果i为0。我期望为2(就像我的一些同事一样)。编译器可能会创建某种导致i零的结构。
i
我期望2的原因是,按照我的观点,将首先评估右手陈述,将i加1。然后将其加到i。因为我已经是1,所以它将1加1。所以1 + 1 =2。显然,这不是正在发生的事情。
您能解释一下编译器做什么或在运行时发生什么吗?为什么结果为零?
免责声明:我绝对知道您不会(也许不应该)使用此代码。 我知道我永远不会。不过,我发现知道为什么以这种方式起作用以及正在发生的事情很有趣。
这个:
int i = 0; i += i++
可以在您做的时候看到(以下是过于简化的情况):
int i = 0; i = i + i; // i=0 because the ++ is a postfix operator and hasn't been executed i + 1; // Note that you are discarding the calculation result
实际发生的事情比这还涉及更多-看一下MSDN,7.5.9 Postfix递增和递减运算符:
x ++或x–形式的后缀递增或递减操作的运行时处理包括以下步骤: 如果x被分类为变量: 计算x以产生变量。 x的值被保存。 使用保存的x值作为参数调用选定的运算符。 操作员返回的值存储在x的求值给出的位置。 x的保存值成为运算结果。
x ++或x–形式的后缀递增或递减操作的运行时处理包括以下步骤:
如果x被分类为变量:
请注意,由于优先顺序的原因,后缀++发生 在之前 +=,但是结果最终未使用(因为使用了的先前值i)。
++
+=
更透彻的分解,i += i++它是由零件都需要一个人知道这两个+=和++不是原子(即,没有一个是单人操作),即使它们看起来像他们。这些实现的方式涉及临时变量,i即操作发生之前的副本- 每个操作一个。(我将使用的名称iAdd和iAssign所使用的临时变量++和+=分别)。
i += i++
iAdd
iAssign
因此,更接近发生的事情是:
int i = 0; int iAdd = i; // Copy of the current value of i, for ++ int iAssign = i; // Copy of the current value of i, for += i = i + 1; // i++ - Happens before += due to order of precedence i = iAdd + iAssign;