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

发布于 2024-12-12 01:41:13 字数 171 浏览 0 评论 0原文

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

int x = 7;
x = x++;

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

What happens (behind the curtains) when this is executed?

int x = 7;
x = x++;

That is, when a variable is post incremented and assigned to itself in one statement? I compiled and executed this. x is still 7 even after the entire statement. In my book, it says that x is incremented!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(18

愁杀 2024-12-19 01:41:13
x = x++;

相当于

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

is equivalent to

int tmp = x;
x++;
x = tmp;
混浊又暗下来 2024-12-19 01:41:13

x 确实会增加。但是您正在将 x 的旧值分配回其自身。


x = x++;
  1. x++ 递增 x 并返回其旧值。
  2. x = 将旧值分配回自身。

所以最后,x 被分配回其初始值。

x does get incremented. But you are assigning the old value of x back into itself.


x = x++;
  1. x++ increments x and returns its old value.
  2. x = assigns the old value back to itself.

So in the end, x gets assigned back to its initial value.

合久必婚 2024-12-19 01:41:13

该语句:

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.

简而言之,该语句没有任何作用。

要点:

  • 后缀递增/递减表达式的值是递增/递减发生之前操作数的值。 (在前缀形式的情况下,该值是操作数之后运算的值,)

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

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


如果它还不是很明显:

  • “x = x++;”几乎可以肯定任何程序中都会有一个错误。
  • OP(对于最初的问题!)可能意味着“x++;”而不是“x = x++;”。
  • 在同一变量上结合自动递增/递减和赋值的语句很难理解,因此无论其正确性如何,都应该避免。根本不需要编写这样的代码。

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

The statement:

x = x++;

is equivalent to:

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.

In short, the statement has no effect.

The key points:

  • The value of a Postfix increment/decrement expression is the value of the operand before the increment/decrement takes place. (In the case of a Prefix form, the value is the value of the operand after the operation,)

  • the RHS of an assignment expression is completely evaluated (including any increments, decrements and/or other side-effects) before the value is assigned to the LHS.

Note that unlike C and C++, the order of evaluation of an expression in Java is totally specified and there is no room for platform-specific variation. Compilers are only allowed to reorder the operations if this does not change the result of executing the code from the perspective of the current thread. In this case, a compiler would be permitted to optimize away the entire statement because it can be proved that it is a no-op.


In case it is not already obvious:

  • "x = x++;" is almost certainly a mistake in any program.
  • The OP (for the original question!) probably meant "x++;" rather than "x = x++;".
  • Statements that combine auto inc/decrement and assignment on the same variable are hard to understand, and therefore should be avoided irrespective of their correctness. There is simply no need to write code like that.

Hopefully, code checkers like FindBugs and PMD will flag code like this as suspicious.

梦忆晨望 2024-12-19 01:41:13
int x = 7;
x = x++;

它在 C 中具有未定义的行为,对于 Java,请参见 这个答案。这取决于编译器会发生什么。

int x = 7;
x = x++;

It has undefined behaviour in C and for Java see this answer. It depends on compiler what happens.

躲猫猫 2024-12-19 01:41:13

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< /code>,与诸如此类的表达式不同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++)的微妙之处,它很容易引入难以追踪的微妙错误。

A construct like x = x++; indicates you're probably misunderstanding what the ++ operator does:

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

Let's rewrite this to do the same thing, based on removing the ++ operator:

// 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

Now, let's rewrite it to do (what I think) you wanted:

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

The subtlety here is that the ++ operator modifies the variable x, unlike an expression such as x + x, which would evaluate to an int value but leave the variable x itself unchanged. Consider a construct like the venerable for loop:

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

Notice the i++ in there? It's the same operator. We could rewrite this for loop like this and it would behave the same:

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

I also recommend against using the ++ operator in larger expressions in most cases. Because of the subtlety of when it modifies the original variable in pre- versus post-increment (++x and x++, respectively), it is very easy to introduce subtle bugs that are difficult to track down.

惯饮孤独 2024-12-19 01:41:13

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

两次赋值都会增加x,但不同的是时间当值被压入堆栈时

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 索引:1 类型:int

According to Byte code obtained from the class files,

Both assignments increment x, but difference is the timing of when the value is pushed onto the stack

In Case1, Push occurs (and then later assigned) before the increment (essentially meaning your increment does nothing)

In Case2, Increment occurs first (making it 8) and then pushed onto the stack(and then assigned to x)

Case 1:

int x=7;
x=x++;

Byte Code:

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

Case 2:

int x=7; 
x=++x;

Byte Code

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 here refers to Operand Stack, local: x index: 1 type: int
泪之魂 2024-12-19 01:41:13

后递增运算符的工作原理如下:

  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 的值将被覆盖为其先前的值。

Post Increment operator works as follows:

  1. Store previous value of operand.
  2. Increment the value of the operand.
  3. Return the previous value of the operand.

So the statement

int x = 7;
x = x++; 

would be evaluated as follows:

  1. x is initialized with value 7
  2. post increment operator stores previous value of x i.e. 7 to return.
  3. Increments the x, so now x is 8
  4. Returns the previous value of x i.e. 7 and it is assigned back to x, so x again becomes 7

So x is indeed increased but since x++ is assigning result back to x so value of x is overridden to its previous value.

十年不长 2024-12-19 01:41:13

它在“x = x++;”之后递增。如果执行“x = ++x;”,则为 8。

It's incremented after "x = x++;". It would be 8 if you did "x = ++x;".

焚却相思 2024-12-19 01:41:13

递增发生在调用 x 之后,因此 x 仍然等于 7。当调用 x 时,++x 将等于 8

The incrementing occurs after x is called, so x still equals 7. ++x would equal 8 when x is called

最冷一天 2024-12-19 01:41:13

当您重新分配 x 的值时,它仍然是 7。尝试 x = ++x,您将得到 8,否则可以

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

When you re-assign the value for x it is still 7. Try x = ++x and you will get 8 else do

x++; // don't re-assign, just increment
System.out.println(x); // prints 8
洋洋洒洒 2024-12-19 01:41:13

因为 x++ 在将值分配给变量后递增该值。
依此类推,在执行该行期间:

x++;

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

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

将为您提供 8。

如果您想在您的代码上使用 x 的增量值赋值语句,使用

++x;

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

[编辑]
而不是 x = x++,它只是 x++;前者将 x 的原始值分配给自身,因此它实际上在那一行上不执行任何操作。

because x++ increments the value AFTER assigning it to the variable.
so on and during the execution of this line:

x++;

the varialbe x will still have the original value (7), but using x again on another line, such as

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

will give you 8.

if you want to use an incremented value of x on your assignment statement, use

++x;

This will increment x by 1, THEN assign that value to the variable x.

[Edit]
instead of x = x++, it's just x++; the former assigns the original value of x to itself, so it actually does nothing on that line.

蹲在坟头点根烟 2024-12-19 01:41:13

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

答-> x++表示先用x的值进行表达式,然后将其加1。
这就是你的情况发生的情况。将右侧 x 的值复制到左侧变量 x,然后将 x 的值加 1。

同样,++x 表示 -> code> 先将 x 的值加一,然后在表达式中使用。
因此,在您的情况下,如果您执行 x = ++x ; // 其中 x = 7
您将得到值 8。

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

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

What happens when int x = 7; x = x++;?

ans -> x++ means first use value of x for expression and then increase it by 1.
This is what happens in your case. The value of x on RHS is copied to variable x on LHS and then value of x is increased by 1.

Similarly ++x means -> increase the value of x first by one and then use in expression .
So in your case if you do x = ++x ; // where x = 7
you will get value of 8.

For more clarity try to find out how many printf statement will execute the following code

while(i++ <5)   
  printf("%d" , ++i);   // This might clear your concept upto  great extend
高速公鹿 2024-12-19 01:41:13

++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 is pre-increment -> x is incremented before being used
x++ is post-increment -> x is incremented after being used

int x = 7; -> x get 7 value <br>
x = x++; -> x get x value AND only then x is incremented
眉目亦如画i 2024-12-19 01:41:13

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

非常依赖编译器!

So this means:
x++ is not equal to x = x+1

because:

int x = 7; x = x++;
x is 7

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

and now it seems a bit strange:

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

very compiler dependent!

沒落の蓅哖 2024-12-19 01:41:13

最简单的解释!

这是因为 ++ 在操作数使其后递增之后,意味着首先将值分配给变量 &然后递增。如果您期望 x 值为 8,那么您应该像下面提到的方式预先递增它:
输入图片此处描述

Most simplest explanation!

This is because ++ after the operand makes post increment it, means first the value got assigned to the variable & then incremented. While if you're expecting x value to be 8 then you should pre increment it like the way mentioned below:
enter image description here

仲春光 2024-12-19 01:41:13

x = x++;

这是后置自增运算符。应该理解为“使用操作数的值,然后递增操作数”。

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

x = ++x;

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

x = x++;

This is the post-increment operator. It should be understood as "Use the operand's value and then increment the operand".

If you want the reverse to happen i.e "Increment the operand and then use the operand's value", you must use the pre-increment operator as shown below.

x = ++x;

This operator first increments the value of x by 1 and then assigns the value back to x.

对你的占有欲 2024-12-19 01:41:13

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

考虑 i++ & ++i 作为函数,例如 Func1 &功能2。

现在我=7;
Func1(i++) 返回 7,Func2(++i) 返回 8(每个人都知道这一点)。在内部,这两个函数都将 i 增加到 8 ,但它们返回不同的值。

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

因此最终 7 被分配给 i。 (所以最后,i = 7)

I think this controversy can be resolved without going into code & just thinking.

Consider i++ & ++i as functions, say Func1 & Func2.

Now i=7;
Func1(i++) returns 7, Func2(++i) returns 8 (everybody knows this). Internally both the functions increment i to 8 , but they return different values.

So i = i++ calls the function Func1. Inside the function i increments to 8, but on completion the function returns 7.

So ultimately 7 gets allocated to i. (So in the end, i = 7)

谜泪 2024-12-19 01:41:13

这是因为您使用了后递增运算符。
在下面的代码行中

x = x++;

,您将 x 的值分配给 x。 x++ 在将 x 的值赋给 x 后递增 x。这就是后自增运算符的工作原理。它们在执行语句后起作用。因此,在您的代码中,首先返回 x,然后再递增。

如果您这样做,

x = ++x;

答案将为 8,因为您使用了预自增运算符。在返回 x 的值之前,首先增加该值。

This is because you used a post-increment operator.
In this following line of code

x = x++;

What happens is that, you're assigning the value of x to x. x++ increments x after the value of x is assigned to x. That is how post-increment operators work. They work after a statement has been executed. So in your code, x is returned first after then it is afterwards incremented.

If you did

x = ++x;

The answer would be 8 because you used the pre-increment operator. This increments the value first before returning the value of x.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文