什么是“x = x ++”之后的x?

当这个被执行时会发生什么(幕后)?

int x = 7; x = x++; 

也就是说,当一个variables是增加后分配给自己在一个语句? 我编译并执行了这个。 即使在整个陈述之后, x仍然是7。 在我的书中,它说x是递增的!

x确实增加了。 但是,您将x的旧值重新分配给自己。

 x = x++; 

x++递增x并返回其旧值。 x =将旧值赋给自己。

所以最后, x被赋值回到它的初始值。

 x = x++; 

相当于

 int tmp = x; x++; x = tmp; 

该声明:

 x = x++; 

相当于:

 tmp = x; // ... this is capturing the value of "x++" x = x + 1; // ... this is the effect of the increment operation in "x++" which // happens after the value is captured. x = tmp; // ... this is the effect of assignment operation which is // (unfortunately) clobbering the incremented value. 

总之,这个陈述没有任何效果。

关键点:

  • 后缀增量/减量expression式的值是增量/减量发生操作数的值。 (在前缀forms的情况下,该值是操作之后的操作数的值)

  • 在赋值给LHS 之前 ,赋值expression式的RHS被完全评估(包括任何增量,减量和/或其他副作用)。

请注意,与C和C ++不同的是,Java中expression式的评估顺序是完全指定的,没有平台特定变体的空间。 只有当编译器不会从当前线程的angular度改变执行代码的结果时,才允许编译器重新sorting。 在这种情况下,编译器将被允许优化整个语句,因为可以certificate它是无操作的。


如果还不是很明显:

  • “x = x ++;” 在任何程序中几乎肯定是一个错误。
  • OP(对于原始问题!)可能意味着“x ++” 而不是“x = x ++;”。
  • 在同一个variables上结合自动增加/减less和赋值的语句很难理解, 因此应该避免它们的正确性 。 没有必要写这样的代码。

希望像FindBugs和PMD这样的代码检查器将这样的代码标记为可疑。

 int x = 7; x = x++; 

它在C和Java中有未定义的行为,看到这个答案 。 这取决于编译器发生了什么。

x = x++;构造x = x++; 表示您可能误解了++运算符的作用:

 // original code int x = 7; x = x++; 

让我们重写这个来做同样的事情,基于删除++运算符:

 // behaves the same as the original code int x = 7; int tmp = x; // value of tmp here is 7 x = x + 1; // x temporarily equals 8 (this is the evaluation of ++) x = tmp; // oops! we overwrote y with 7 

现在,让我们重写它做的(我想)你想要的:

 // original code int x = 7; x++; 

这里的微妙之处在于, ++运算符修改variablesx ,不像x + x这样的expression式,它将求值为一个int值,但保持variablesx本身不变。 考虑一个像古老for循环一样的结构:

 for(int i = 0; i < 10; i++) { System.out.println(i); } 

注意那里的i++ ? 这是同一个运营商。 我们可以像这样重写这个循环,它的行为是一样的:

 for(int i = 0; i < 10; i = i + 1) { System.out.println(i); } 

在大多数情况下,我还build议不要在较大的expression式中使用++运算符。 由于修改前后variables(分别为++xx++ )中原始variables的细微之处,很容易引入难以追踪的细微错误。

它在“ x = x++; ”之后递增。 如果你做了“ x = ++x; ”,那将是8。

根据从类文件中获取的字节代码 ,

两个赋值都是递增x,但差值是when the value is pushed onto the stack

Case1 ,Push在增量之前发生(然后在之后被赋值)(本质上意味着你的增量什么都不做)

在情况Case2 ,增量首先发生(使其为8),然后推入堆栈(然后分配给x)

情况1:

 int x=7; x=x++; 

字节代码:

 0 bipush 7 //Push 7 onto stack 2 istore_1 [x] //Pop 7 and store in x 3 iload_1 [x] //Push 7 onto stack 4 iinc 1 1 [x] //Increment x by 1 (x=8) 7 istore_1 [x] //Pop 7 and store in x 8 return //x now has 7 

案例2:

 int x=7; x=++x; 

字节码

 0 bipush 7 //Push 7 onto stack 2 istore_1 [x] //Pop 7 and store in x 3 iinc 1 1 [x] //Increment x by 1 (x=8) 6 iload_1 [x] //Push x onto stack 7 istore_1 [x] //Pop 8 and store in x 8 return //x now has 8 
  • 这里的栈指的是操作数堆栈,本地:x索引:1types:int

在x被调用后发生递增,所以x仍然等于7. ++调用x时,x等于8

当你重新分配x的值时,它仍然是7.尝试x = ++x ,你将得到8个else

 x++; // don't re-assign, just increment System.out.println(x); // prints 8 

因为x ++会在赋值给variables之后递增值。 如此以及在执行这一行时:

 x++; 

variablesx仍然具有原始值(7),但在另一行上再次使用x,例如

 System.out.println(x + ""); 

会给你8。

如果您想在您的赋值语句中使用递增的x值,请使用

 ++x; 

这将使x递增1,然后将该值赋给variablesx。

[编辑]而不是x = x ++,它只是x ++; 前者将x的原始值赋给自己,所以它实际上什么也不做。

int x = 7; x = x++;时会发生什么int x = 7; x = x++; int x = 7; x = x++;

ans – > x++表示首先使用xexpression式的值,然后增加1。
这是发生在你的情况。 RHS上的x的值被复制到LHS上的variablesx,然后x值增加1。

同样, ++x意思是->增加x的值,然后在expression式中使用。
所以在你的情况下,如果你做x = ++x ; // where x = 7 x = ++x ; // where x = 7
你会得到8的价值。

为了更清楚地了解多lessprintf语句将执行下面的代码

 while(i++ <5) printf("%d" , ++i); // This might clear your concept upto great extend 

++x是预增量-> x 使用之前递增
x++是后增量-> x 使用递增

 int x = 7; -> x get 7 value <br> x = x++; -> x get x value AND only then x is incremented 

Post Increment操作符如下所示:

  1. 存储操作数的前一个值。
  2. 增加操作数的值。
  3. 返回操作数的前一个值。

所以声明

 int x = 7; x = x++; 

将被评估如下:

  1. x用值7初始化
  2. 后增量操作符存储x的前一个值即7返回。
  3. 增加x, 所以现在x是8
  4. 返回x的前一个值,例如7,它被分配回x,所以x再次变成7

所以x确实增加了,但是因为x ++将结果赋值给x,所以x的值被覆盖到它以前的值。

所以这意味着: x++不等于x = x+1

因为:

 int x = 7; x = x++; x is 7 int x = 7; x = x = x+1; x is 8 

现在看起来有点奇怪:

 int x = 7; x = x+=1; x is 8 

非常依赖编译器!

我认为这个争议可以在不进入代码和思考的情况下得到解决。

考虑我作为function++和++我Fun1&Fun2。

如果我= 7;
i ++函数(Fun1)返回7,++ i函数(Fun2)返回8(这个大家都知道)。 在内部这两个函数递增我8,但他们返回不同的值。

所以我= i ++调用函数Fun1。 函数内部增加到8,但完成后函数返回7。

所以最终得到7分配给我。 (所以最后我= 7;执行)

x = x ++;

这是后增量操作符。 应该理解为“使用操作数的值,然后增加操作数”。

如果您希望发生相反情况,即“递增操作数,然后使用操作数的值”,则必须使用预增加操作符,如下所示。

x = ++ x;

该运算符首先将x的值递增1,然后将值赋给x。