Mic*_*ael 273 java operators post-increment
执行此操作后会发生什么(窗帘后面)?
int x = 7;
x = x++;
Run Code Online (Sandbox Code Playgroud)
也就是说,当一个变量后期递增并在一个语句中赋值给自己时?我编译并执行了这个.在整个声明之后x
仍然是7 .在我的书中,它说增加了!x
Pri*_*ley 380
x = x++;
Run Code Online (Sandbox Code Playgroud)
相当于
int tmp = x;
x++;
x = tmp;
Run Code Online (Sandbox Code Playgroud)
Mys*_*ial 292
x
确实增加了.但是你要将旧的值分配x
回自身.
x = x++;
Run Code Online (Sandbox Code Playgroud)
x++
递增x
并返回其旧值.x =
将旧值分配给自己.所以最后,x
被分配回其初始值.
Ste*_*n C 257
该声明:
x = x++;
Run Code Online (Sandbox Code Playgroud)
相当于:
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.
Run Code Online (Sandbox Code Playgroud)
简而言之,该声明无效.
关键点:
Postfix递增/递减表达式的值是增量/减量发生之前的操作数的值.(在Prefix表单的情况下,该值是操作后操作数的值,)
在将值分配给LHS 之前,完全评估赋值表达式的RHS(包括任何增量,减量和/或其他副作用).
请注意,与C和C++不同,Java中表达式的求值顺序是完全指定的,并且没有特定于平台的变化的空间.如果这不会从当前线程的角度更改执行代码的结果,则只允许编译器对操作重新排序.在这种情况下,允许编译器优化掉整个语句,因为可以证明它是无操作.
如果还不是很明显:
希望像FindBugs和PMD这样的代码检查器会将这样的代码标记为可疑.
use*_*092 33
int x = 7;
x = x++;
Run Code Online (Sandbox Code Playgroud)
它在C和Java中有未定义的行为,请参阅此答案.这取决于编译器会发生什么.
FMM*_*FMM 16
像这样的结构x = x++;
表明你可能误解了++
运算符的作用:
// original code
int x = 7;
x = x++;
Run Code Online (Sandbox Code Playgroud)
让我们根据删除++
运算符重写这个来做同样的事情:
// 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
Run Code Online (Sandbox Code Playgroud)
现在,让我们重写它(我认为)你想要的:
// original code
int x = 7;
x++;
Run Code Online (Sandbox Code Playgroud)
这里的细微之处在于++
运算符修改变量x
,不像表达式那样x + x
,它将计算为int值但x
保持变量本身不变.考虑像古老for
循环这样的构造:
for(int i = 0; i < 10; i++)
{
System.out.println(i);
}
Run Code Online (Sandbox Code Playgroud)
请注意i++
那里?它是同一个运营商.我们可以for
像这样重写这个循环,它会表现得一样:
for(int i = 0; i < 10; i = i + 1)
{
System.out.println(i);
}
Run Code Online (Sandbox Code Playgroud)
++
在大多数情况下,我还建议不要在较大的表达式中使用运算符.由于微妙的时候它会修改对预后的增量(原始变量++x
和x++
,分别),这是很容易引入微妙的错误是难以追查.
eve*_*ime 13
两个赋值都递增x,但差异是时间 when the value is pushed onto the stack
In Case1
,在增量之前发生推送(然后再指定)(本质上意味着你的增量什么都不做)
在Case2
,增量首先发生(使其成为8),然后推入堆栈(然后分配给x)
情况1:
int x=7;
x=x++;
Run Code Online (Sandbox Code Playgroud)
字节代码:
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
Run Code Online (Sandbox Code Playgroud)
案例2:
int x=7;
x=++x;
Run Code Online (Sandbox Code Playgroud)
字节代码
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
Run Code Online (Sandbox Code Playgroud)
重新分配值时,x
它仍然是7.尝试x = ++x
,你会得到其他8
x++; // don't re-assign, just increment
System.out.println(x); // prints 8
Run Code Online (Sandbox Code Playgroud)
Post Increment运算符的工作方式如下:
所以声明
int x = 7;
x = x++;
Run Code Online (Sandbox Code Playgroud)
评估如下:
所以x确实增加了,但是因为x ++将结果赋给x,所以x的值被覆盖到它之前的值.
因为x ++会在将值赋给变量后递增值.所以在执行这一行时:
x++;
Run Code Online (Sandbox Code Playgroud)
变量x仍将具有原始值(7),但在另一行上再次使用x,例如
System.out.println(x + "");
Run Code Online (Sandbox Code Playgroud)
会给你8.
如果要在赋值语句中使用递增的x值,请使用
++x;
Run Code Online (Sandbox Code Playgroud)
这会将x递增1,然后将该值赋给变量x.
[编辑]而不是x = x ++,它只是x ++; 前者将x的原始值分配给它自己,所以它实际上在该行上没有任何作用.
归档时间: |
|
查看次数: |
36360 次 |
最近记录: |