mkdreamer 2021-12-14 17:25 采纳率: 80%
浏览 39
已结题

在学习java位运算符的时候,遇到了关于使用^交换数据的值

设有两个整数变量x与y
x ^= y;
y ^= x;
x ^= y;
能成功交换x与y的值。

为什么将上面的式子改成
x ^= y ^= x ^= y
不能成功交换?

甚至
y ^= x ^= y;
x ^= y;
也能实现。

  • 写回答

2条回答 默认 最新

  • 俺不理解 2021-12-14 18:29
    关注

    java的编译规则赋值优化。举个例子

    a = 10;
    a = 20;

    连续的两次赋值,且中间没发现对a的读取,那么java编译器在编译时会将第一个赋值删掉。


    再回到这次的问题:
    b ^= a ^= b; 在编译后的 class文件中,这一行应该是先将a 与 b 做一次 ^=,a的结果再与 b 做一次 ^=
    看下class文件,的确如此:

    img

    img


    现在我们把它们写成一行

    img

    其实可以看到,这个时候编译器已经告诉我们警告(第二个a是灰色)编译器认为这一行代码会被编译成

    img

    我们再来看看此时的 class 文件

    img

    通过编译后的文件,我们可以很清晰的知道为什么 执行完这一行,a = 0、b = 10,那么为什么编译器会这样执行呢?

    这就回到刚开篇的赋值优化问题了, 对于 a ^= b,这对a是一次赋值的过程,也读取了一次a的值,但是 对于 a^= (b ^= a ^= b) 的外层 a ^= 操作来说,java编译器认为后边括号里的内容是一次赋值,且与a无关,所以 内部的一次 ^= 操作被编译器优化掉了。

    事实上,a^= (b ^= a ^= b) 会被优化成如下代码:

    img

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 12月22日
  • 已采纳回答 12月14日
  • 创建了问题 12月14日

悬赏问题

  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥15 c++头文件不能识别CDialog