【问题标题】:Unary Operations fused with assignment一元运算与赋值融合
【发布时间】:2013-04-27 22:13:56
【问题描述】:

以下代码中的可疑结果:

public static void main (String[] args)
{ 
int i = 2;
i = i+=2 + i++;
System.out.println(i); }

期望 8 作为输出,因为 'i+=2' 应该 更新 i,但它的行为并非如此。

输出:6

我推断简写赋值运算符按预期返回 4,但没有更新变量 i 中的相同值。任何解释将不胜感激。

【问题讨论】:

  • 这是 C/C++ 中未定义的行为。有充分的理由。你不应该在任何地方这样做。
  • @JanDvorak 当然,但在 Java 中它定义的,虽然你不应该在实践中这样做,但这是一个有趣的学术问题。
  • @berry120:感谢贝里爵士的精通解释。 :)

标签: java assignment-operator unary-operator binary-operators


【解决方案1】:

i++ 是一个后缀增量——它增加 i,然后本质上返回 i 的旧值。等效的前缀运算符++i 将返回“更新”值,但这不是这里使用的。

i+=2 的工作方式不同,但它本质上等同于 i+2,因为它确实返回更新后的值。

但是,我认为出现混淆的地方在于您是这样看待它的:

i = (i += 2) + i++;

...确实给出了您预期的结果。 i+=2 给出 4,然后将 i 更新为 4,然后 i++ 返回 4(而不是 5,因为它是后增量。)但是,当您将运算符优先级带入等式时,Java 实际上像这样“括号”它默认情况下:

i = i += (2 + i++);

为了消除混淆,Java 以这种方式计算它,因为 += 运算符 has least precedence in this example,因此首先计算加法表达式 (+)。

这个括号内的陈述本质上等同于:

i = (i = i + (2 + i++));

这又简化为:

i = i + (2 + i++);

所以给定上面的语句,从左到右求值,我们首先取 i(2) 的值,然后加上 2+i++ 的值;后者给出 4(因为后缀增量)。所以我们最终的结果是2+4,也就是6。

【讨论】:

  • 为什么返回8:i = 2; i = (i+=2) + i++;??
  • 啊,你改了答案..!!我正要指出这个缺陷。
  • @AhmedKRAIEM 现在更新解释!
  • @Ravi 是的,我一写就意识到我写的不太对..!
  • 子表达式从左到右求值,因此+= 左侧的i 在增量之前被读取。增量实际上是对i 的最后一次读取。 (并不是说我能记住所有的规则!)
猜你喜欢
  • 1970-01-01
  • 2011-11-16
  • 1970-01-01
  • 1970-01-01
  • 2020-08-10
  • 2017-11-21
  • 2013-06-28
  • 2020-12-01
相关资源
最近更新 更多