首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >分配中的意外后增量行为

分配中的意外后增量行为
EN

Stack Overflow用户
提问于 2015-01-17 05:51:17
回答 7查看 267关注 0票数 6

请您帮助我理解为什么变量a在第一种情况下不是递增的,而是在第二种情况下增加的?

案例1:

代码语言:javascript
运行
复制
int a = 10;            
a = a++;
Console.WriteLine(a); //prints 10

案例2:

代码语言:javascript
运行
复制
int a = 10;                        
int c = a++;
Console.WriteLine(a); //prints 11

我曾经历过其他类似的问题,但找不到任何细节。

更新1:我认为程序是如何流动的

案例1:

代码语言:javascript
运行
复制
1. 'a' is assigned 10
2. 'a' is assigned 10 before increment happens
3. 'a' is incremented by 1 (Why doesn't this step affect the final value of 'a'?)
4. 'a' is printed --> 10

案例2:

代码语言:javascript
运行
复制
1. 'a' is assigned 10
2. 'c' is assigned 10 before 'a' is incremented
3. 'a' is incremented by 1 (Why does the increment of 'a' work here?)
4. 'a' is printed --> 11

更新2:感谢所有的答案,我想我已经理解了,如果我错了,请纠正我。

案例1:

代码语言:javascript
运行
复制
1. `a` is assigned 10
2. Compiler evaluates `a++`, stores old value 10 and new value 11 as well. Since it's a post increment operation, assigns the old value to `a`. What i thought was, compiler would assign the old value 10 first and evaluate the `++` operation later. This is where i was wrong, compiler evaluates the RHS beforehand and assigns the value based on the operator.
4. 'a' is printed --> 10

案例2:

代码语言:javascript
运行
复制
1. `a` is assigned 10
2. Compiler evaluates `a++`, stores old value 10 and new value 11 as well. Since it's a post increment operation, assigns the old value to `c` but value of `a` is preserved with `11`.
4. 'a' is printed --> 11
EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2015-01-17 06:13:48

对我来说,了解某些行为的最好方法是检查产生的IL。在你的第一个案例中

代码语言:javascript
运行
复制
IL_0001:  ldc.i4.s    0A // stack: 10
IL_0003:  stloc.0     // a = 10, stack: empty
IL_0004:  ldloc.0     // stack: 10
IL_0005:  dup         // stack: 10, 10
IL_0006:  ldc.i4.1    // stack: 10, 10, 1
IL_0007:  add         // stack: 10, 11
IL_0008:  stloc.0     // a = 11, stack: 10
IL_0009:  stloc.0     // a = 10, stack: empty
IL_000A:  ldloc.0     // stack: 10
IL_000B:  call        System.Console.WriteLine

您可以看到堆栈上仍然挂着原始值,因此创建的11最终会被覆盖。

让我用简单的话解释一下。

当您将一个值赋值给一个变量(a = a++)时,首先计算赋值的整个右侧,以确保正确的值,这就是它的情况。因此,没有什么像您得到10,应用程序继续,并增加值时,您执行下一行。

现在,想象后增量是一个人,他首先增加了一个值,但给了你他的世界,你将从表达式中获得原始值。现在你应该知道为什么11被覆盖了。增量先行,最后得到承诺的原始值(正如IL所证明的)。

票数 7
EN

Stack Overflow用户

发布于 2015-01-17 06:03:32

第一种情况是a = a++后增量。这意味着将1添加到a,但返回a的前一个值,然后将前一个结果存储回a中。这基本上是个禁止行动。

如果它是预增量,a = ++a,那么a是11.

票数 6
EN

Stack Overflow用户

发布于 2015-01-17 06:07:26

这里没有未定义的行为,就像有人在评论中描述的那样。

这是明确定义的行为。要理解正在发生的事情,您必须首先了解前后增量操作符是如何工作的。

Case1:

a++(post增量)将增加a的值并将其存储在a中,然后在增量之前返回该值。

因此,在执行a++;之后,a的值将是11,但运算符将返回10

然后a = a++;,分配部分变成a = 10;

Case2:

Sameway a++;将把a的值增加到11,并返回前一个值(10)。它将被分配给cc为10,而a为11,因为在本例中,您没有覆盖a的值。

您的Case1等于:

代码语言:javascript
运行
复制
int a = 10;
int temp = a;//10
a = a + 1;  //11
a = temp;   //10
Console.WriteLine(a);//10

Case2等于:

代码语言:javascript
运行
复制
int a = 10;
int temp = a;//10
a = a + 1;   //11
int c = temp;//10
Console.WriteLine(a);//11

我希望现在应该清楚为什么你会看到你所看到的。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27996608

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档