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

执行时(幕后)会发生什么?

int x = 7;
x = x++;

也就是说,当一个变量在一条语句中被递增并分配给自己时?我编译并执行了这个。x仍然是7 甚至在整个声明之后。在我的书中,它说x是递增的!

50121 次浏览

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

x会被递增。但是你是在将x的旧值赋回自身。


x = x++;
  1. x++增加x并返回其旧值。
  2. x =将旧值赋回给自己。

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

x = x++;

等于

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

增量发生在x被调用之后,所以x仍然等于7。当调用x时,++x将等于8

当你为x重新赋值时,它仍然是7。尝试x = ++x,你会得到8个其他做

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

int x = 7; x = x++;?

ans -> x++表示首先使用x的值作为表达式,然后将其增加1 这就是你的情况。RHS上的x的值被复制到LHS上的变量x,然后x的值加1。< / p > 类似地,++x表示->先将x的值加1,然后在表达式中使用 所以在你的例子中,如果你执行x = ++x ; // where x = 7
你会得到8的值。< / p >

为了更清楚,请尝试找出有多少printf语句将执行以下代码

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

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

所以这意味着: 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

非常依赖于编译器!

,因为x++在将值赋值给变量后会增加值。 在这一行的执行过程中:

x++;

变量x仍然有原始值(7),但是在另一行再次使用x,例如

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

结果是8。

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

++x;

这将使x增加1,然后将该值赋给变量x。

< p >[编辑] 不是x = x++,而是x++;前者将x的原始值赋给自己,因此实际上它在这一行上什么也不做

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

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

声明:

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.

简而言之,这个声明没有任何效果。

重点:

  • 后置自增/自减表达式的值是操作数在发生自增/自减之前的值。(在Prefix形式的情况下,值是操作数操作,)

  • 赋值表达式的RHS被完全计算(包括任何增量、减量和/或其他副作用)之前的值被赋给LHS。

注意,与C和c++不同,Java中表达式的求值顺序是完全指定的,没有平台特定的变化空间。编译器只允许重新排序操作,前提是从当前线程的角度来看,这不会改变执行代码的结果。在这种情况下,编译器将被允许优化掉整个语句,因为可以证明它是一个无操作。


如果还不明显的话:

  • "x = x++;"在任何程序中几乎都是错误的。
  • OP(对于最初的问题!)可能意味着“x++;”而不是“x = x++;”。
  • 将auto inc/ decentation和赋值结合在一起的语句很难理解,因此应该避免不管它们是否正确。根本没有必要编写这样的代码。

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

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++;

这里的微妙之处在于++操作符修改变量x,不像x + x这样的表达式,后者将计算为int值,但变量x本身不变。考虑像古老的for循环这样的构造:

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

注意到里面的i++了吗?这是同一个算子。我们可以像这样重写这个for循环,它的行为是一样的:

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

在大多数情况下,我也建议不要在较大的表达式中使用++操作符。由于的微妙之处,它会在增量前和增量后修改原始变量(分别是++xx++),因此很容易引入难以追踪的微妙错误。

我认为这个争议可以在不涉及代码的情况下得到解决。只是思考。

考虑i++ &++i作为函数,比如Func1 &Func2。

< p >现在我= 7;< br > Func1(i++)返回7,Func2(++i)返回8(大家都知道)。在内部,这两个函数都将i增加到8,但它们返回的值不同

i = i++调用函数Func1。在函数内部,i增加到8,但完成后函数返回7。

所以最终7被分配给i(最后i = 7)

后增量算子的工作原理如下:

  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,但不同之处在于when the value is pushed onto the stack的时间

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

Case2中,Increment首先发生(使其为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
  • Stack在这里指的是操作数Stack, local: x index: 1 type: int

X = x++;

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

如果你想要发生相反的情况,即“增加操作数,然后使用操作数的值”,你必须使用预增加操作符,如下所示。

X = ++ X;

这个运算符首先将x的值加1,然后将值赋回给x。

这是因为您使用了后增量操作符。 在下面这行代码中

x = x++;

实际发生的情况是,你将x的值赋给x, x++在x赋给x后对x加1,这就是后加操作符的工作方式。它们在语句执行之后工作。所以在你的代码中,x先被返回然后再被递增。

如果你有

x = ++x;

答案是8,因为你使用了前增量操作符。这将在返回x值之前先对值进行递增。

最简单的解释!

这是因为++在操作数进行后加1之后,意味着该值首先被赋值给变量&然后增加。而如果你期望x值为8,那么你应该像下面提到的那样预先增加它: enter image description here < / p >