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

mrfwxfqh  于 2021-06-26  发布在  Java
关注(0)|答案(17)|浏览(684)

当这个被执行时(在窗帘后面)会发生什么?

int x = 7;
x = x++;

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

vlf7wbxs

vlf7wbxs1#

后增量运算符的工作方式如下:
存储操作数的上一个值。
递增操作数的值。
返回操作数的上一个值。
所以声明

int x = 7;
x = x++;

评估如下:
x用值7初始化
后增量运算符存储x的前一个值,即返回7。
增加x,所以现在x是8
返回x的前一个值,即7,并将其赋值回x,因此x再次变为7
所以x确实增加了,但由于x++将结果赋值回x,所以x的值被重写为它以前的值。

q1qsirdb

q1qsirdb2#

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

4ktjp1zp

4ktjp1zp3#

x 不会递增。但你是在给 x 回到它自己。

x = x++;
``` `x++` 增量 `x` 并返回其旧值。 `x =` 将旧值赋回自身。
所以最后, `x` 返回其初始值。
uxhixvfz

uxhixvfz4#

像这样的构造 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);
}

我还建议不要使用 ++ 在大多数情况下,在较大的表达式中使用运算符。因为它在增量前后修改原始变量时的微妙之处( ++x 以及 x++ ,很容易引入难以追踪的细微缺陷。

g0czyy6m

g0czyy6m5#

int x = 7;
x = x++;

它在c语言中有未定义的行为,对于java来说,可以看到这个答案。这取决于发生了什么。

jm81lzqq

jm81lzqq6#

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

x = x++;

结果是,你把x的值赋给x。x++将x的值赋给x后,x递增x。这就是后增量运算符的工作方式。它们在语句执行后工作。所以在代码中,x先返回,然后再递增。
如果你这么做了

x = ++x;

答案是8,因为您使用了pre-increment操作符。这将在返回x的值之前先递增该值。

du7egjpx

du7egjpx7#

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

非常依赖编译器!

5hcedyr0

5hcedyr08#

我认为这场争论不需要进入代码就可以解决&只需思考。
把i++&i看作函数,比如func1&func2。
现在i=7;
func1(i
)返回7,func2(i)返回8(大家都知道这一点)。在内部,这两个函数都将i增加到8,但它们返回不同的值。
所以i=i
调用函数func1。在函数内部,i递增到8,但函数完成时返回7。
所以最终7被分配给i(最后,i=7)

daolsyd0

daolsyd09#

根据从类文件中获取的字节码,
两个赋值都增加x,但不同的是 when the value is pushed onto the stackCase1 ,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

omvjsjqw

omvjsjqw10#

声明:

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这样的代码检查器能将这样的代码标记为可疑代码。

ni65a41a

ni65a41a11#

什么时候会发生 int x = 7; x = x++; ?
答案-> x++ 表示首先使用x的值作为表达式,然后将其增加1。
你的情况就是这样。rhs上的x值被复制到lhs上的变量x,然后 x 增加1。
同样地 ++x 手段 -> 先将x的值增加1,然后在表达式中使用。
如果你这样做了 x = ++x ; // where x = 7 你将得到值8。
为了更清楚,请尝试找出有多少printf语句将执行以下代码

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

wvmv3b1j12#

“之后递增” x = x++; ". 如果你这样做的话,那就是8” x = ++x; ".

juud5qan

juud5qan13#

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

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

inkz8wg914#

x = x++;

相当于

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

h6my8fg215#

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

x++;

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

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

我给你8英镑。
如果要在赋值语句中使用递增的x值,请使用

++x;

这将使x增加1,然后将该值赋给变量x。
[编辑]不是x=x++,而是x++;前者将x的原始值赋给它自己,所以它实际上在这条线上什么也不做。

相关问题