X = X ++有什么区别 vs X ++;?

你曾经尝试过吗?

static void Main(string[] args) { int x = 10; x = x++; Console.WriteLine(x); } 

输出:10。

但对于

 static void Main(string[] args) { int x = 10; x++; Console.WriteLine(x); } 

输出:11。

谁能解释为什么这个?

X ++将增加该值,但返回其旧值。

所以在这种情况下:

 static void Main(string[] args) { int x = 10; x = x++; Console.WriteLine(x); } 

你在11处有X,然后回到10,因为10是(x ++)的返回值。

你可以改为做同样的结果:

 static int plusplus(ref int x) { int xOld = x; x++; return xOld; } static void Main(string[] args) { int x = 10; x = plusplus(x); Console.WriteLine(x); } 

另外值得一提的是,如果你愿意的话,你会得到11的预期结果:

 static void Main(string[] args) { int x = 10; x = ++x; Console.WriteLine(x); } 

在赋值x = x++首先提取x = x++的旧值,用于计算右侧expression式,在本例中为x。 然后,将x递增1.最后,通过赋值语句将expression式求值(10)的结果赋值给x

也许一个相同的代码会使困境清楚:

 var tmp = x; x++; x = tmp; 

这相当于C#中的x = x++代码。

x ++的行为是增加x,但在增量之前返回值。 由于这个原因,它被称为后期增量。

所以x = x ++; 简单地把意志

1.返回值 ,然后

然后增加x

3.将x的​​原始值(在步骤1中返回)分配给x

x = ++ x

将等于11。

 x++; 

做以下事情:

 int returnValue = x; x = x+1; return returnValue; 

正如你所看到的,原始值被保存,x被增加,然后原始值被返回。

结果是把值10保存在某个地方,设置x等于11,然后返回10,这导致x被设置回10.注意,x在几个周期内实际上变为11(假设没有编译器优化) 。

这不直接回答这个问题,但为什么在世界上任何人都会使用

 x = x++; 

这完全违背了后增加/预增加运算符的目的。

你可以这样想:

 int x = 10; 

X是一个容器,包含一个值10。

 x = x++; 

这可以分解为:

 1) increment the value contained in x now x contains 11 2) return the value that was contained in x before it was incremented that is 10 3) assign that value to x now, x contains 10 

现在,打印x中包含的值

 Console.WriteLine(x); 

而且,毫不奇怪,它打印出10。

根据定义,x ++返回x的值,然后递增x。

http://blogs.msdn.com/lucabol/archive/2004/08/31/223580.aspx

你做的第一件事就是所谓的“后期增量”

  int x = 10; x++; //x still is 10 Console.WriteLine(x); //x is now 11(post increment) 

所以当你分配x = x ++; x仍然是10你可以做什么,如果你需要x在这一行写11 ++ x(认为它被称为前增量纠正我,如果我错了)…或者右x ++; 并且比x = x ++;

问题,是依赖于行还是在语句上,意思是说在它之后会增加; ?

尝试调用++ x,看看是否有效。

将增量运算符放在variables后面意味着计算expression式之后发生增量和赋值…因此原始语句x = x ++; 转换为1.评估x和存储在瞬变存储器中的值…现在执行由++运算符调用的代码….(步骤2和3)2. x的递增值(在瞬态存储器中)3.分配递增值到x的存储位置…现在,继续行的其余部分,在左边,有一个=符号… 5.因此,将在步骤1中存储的值(未增值)分配给=符号左边的expression式。这是x

也许我是不对的,但是我更容易理解类似例子的结果:

 public static void main(String[] args) { int x = 10; int y = 0; y = x + x++; //1, 2, 3, 4 x += x; //5 System.out.println("x = " + x + "; y = " + y); //6 } 

让我们看看操作y = x + x ++一步一步:

  1. 计算机取x的值并将其加到x的值(10 + 10 = 20)
  2. 计算机将结果打到临时variables(temp = 20)
  3. 计算机增加x(10 + 1 = 11)
  4. 计算机将存储在正确的侧面操作的结果存储在variablesy(20)
  5. 计算机取x的值并将其加到x的值(11 + 11 = 22)
  6. 最终的结果是:x = 22; y = 20

现在让我们回到我们的例子,并做出相同的步骤:

 public static void main(String[] args) { int x = 10; x = x++; //1, 2, 3, 4 System.out.println(x); //5 } 
  1. 计算机取x(10)的值
  2. 计算机将结果提供给临时variables(temp = 10)
  3. 计算机增加x(10 + 1 = 11)
  4. 计算机将正确操作的结果存储在variablesx(10)中,
  5. 最终的结果是:x = 10

我知道有很多答案,也是一个可以接受的答案,但我仍然会为了另一个观点而投入我的两分钱。

我知道这个问题是C#,但我认为像一个后缀运算符它没有不同的行为比C:

 int main(){ int x = 0; while (x<1) x = x++; } 

编译器生成的程序集(是的,我编辑它使其更具可读性)显示

 ... mov -8(rbp), 0 ; x = 0 L1: cmp -8(rbp), 1 ; if x >= 1, jge L2 ; leave the loop mov eax, -8(rbp) ; t1 = x mov ecx, eax ; t2 = t1 add ecx, 1 ; t2 = t2 + 1 mov -8(rbp), ecx ; x = t2 (so x = x + 1 !) mov -8(rbp), eax ; x = t1 (kidding, it's the original value again) jmp L1 L2: ... 

等价地,循环做的是这样的:

 t = x x = x + 1 x = t 

边注意:打开任何优化给你一些汇编结果是这样的:

 ... L1: jmp L1 ... 

它甚至懒得存储你告诉它给x的价值!

作为一个独立的声明, x++; 既是增量又是分配。 似乎对于什么时候会发生一些混淆。 如果我们有

 int x = 10; int y = (x++) + 2; 

我们将得到x = 11y = 12 。 分配x的当前值, 然后进行x的增量和重新分配。 所以,当使用相同的variables时,

 int x = 10; // Create a variable x, and assign an initial value of 10. x = x++; // First, assign the current value of x to x. (x = x) // Second, increment x by one. (x++ - first part) // Third, assign the new value of x to x. (x++ - second part) 

任何你看它的方式,x的新值是11。

我完全错了。

简单的解释:

x ++是一个后缀增量。

编译器做了什么:

a)将x的值赋值给x b)增加x的临时值(我猜它可能会被优化掉)c)丢掉x的临时值

如果你想要代码返回11与作业,写:

x = ++ x;

分配的结果

 x = x++; 

在C和C ++中是没有定义的,我也会用C#来猜测。

所以,发生的实际操作顺序取决于编译器如何决定实现它,不能保证分配或增量是否会先发生。 (这在C#中已经有了很好的定义,正如Jon Skeet在评论中指出的那样,尽pipe我现在觉得这个答案现在的价值要低很多,但是我要保留这个post,因为OP的问题和评论中的答案没有被删除。

然而,在这种情况下,似乎发生的操作顺序是:

  1. x的旧值(10)被保存
  2. x的++部分递增
  3. 旧值现在分配给x的分配

这样,虽然增量发生了,但是被旧值赋值所取代,从而保持x在10。

HTH