c语言中的异或运算_java中的异或运算符

c语言中的异或运算_java中的异或运算符今天看到一位大神的博客,深受感触。决定也发一篇博客,证明一下我还活着。于是我翻看以前学习时做的一些笔记,整理了一下,得到了一个关于异或运算交换变量变量值的笔记。首先来看下面三组表达式,看起来他们都能实现交换两个变量的值。a=a^b;b=a^b;a=a^b;a=a^(b=b^(a=a^b));a^=b^=a^=b;可实际的情况是,前面2组表…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

今天看到一位大神的博客,深受感触。决定也发一篇博客,证明一下我还活着。于是我翻看以前学习时做的一些笔记,整理了一下,得到了一个关于异或运算交换变量变量值的笔记。

首先来看下面三组表达式,看起来他们都能实现交换两个变量的值。

a = a ^ b;

b = a ^ b;

a = a ^ b;

a = a ^ (b = b ^ (a = a ^ b));

a ^= b ^= a ^= b;

可实际的情况是,前面2组表达式,在C、C++、Java中都能顺利完成变量值的交换。而第3组表达式,却只在C、C++中通过了,而在Java中却得到了意料之外的结果。请看下面的截图

在C、C++中得到了想要的结果

eabbffa03db80b7348894858bcd0a224.png

而在Java中,却得到了这样的结果

6df9a31a223879bb31f28d135d8c4048.png

怎么样,是不是很惊讶,在java中,a的值,换给了b,但不管怎么做,a的值都是0,怎么会这样?百思不得其解。这事就此搁了下来。

过了很长时间之后,在意个偶然的机会中,我在一个关于Java谜题的手册中看到了这个问题,原来这还是Java比较经典的谜题之一了。

原来,事情是这样的。

很久以前,当中央处理器只有少数寄存器时,人们发现可以通过利用异或操作符(^)的属性(x ^ y ^ x) == y来避免使用临时变量,这个惯用法曾经在C编程语言中被使用过,并进一步被融入到了C++中,但是它并不保证都可以正确运行。但是有一点可以肯定:它在Java中肯定是不能正确运行的。

Java语言规范描述到:操作符的操作数是从左向右求值的。为了求表达式 x ^= expr的值,x的值是在计算expr之前被提取的,并且这两个值的异或结果被赋给变量x。在OprDemo程序中,变量x的值被提取了两次——每次在表达式中出现时都提取一次——但是两次提取都发生在所有的赋值操作之前。

下面的代码可以很好的解释其原理,并且解释了为什么会得到这样的结果

// Java中x^= y^= x^= y的实际行为

int tmp1 = x ; // x在表达式中第一次出现

int tmp2 = y ; // y的第一次出现

int tmp3 = x ^ y ; // 计算x ^ y

x = tmp3 ; // 最后一个赋值:存储x ^ y 到 x

y = tmp2 ^ tmp3 ; // 第二个赋值:存储最初的x值到y中

x = tmp1 ^ y ; // 第一个赋值:存储0到x中

从上面的代码可以看出,其实a之所以会为0,是因为a^a造成的,我们知道,两个相同的值异或其值为0.

在C和C++中,并没有指定表达式的计算顺序。当运行表达式x^=expr时,许多C和C++编译器是在计算expr之后才提取x的值的,这使得上述的做法可以得到正确的结果。

那么在Java中,有没有办法使得不使用中间变量的单个表达式来达到这个目的呢?这是可以的,请看下面的代码。

y = (x^= (y^= x))^ y ;这句代码就能够做到

写这么多,最后想说的就是在单个的表达式中不要对同一变量赋值两次,赋值次数多了,就会引起混乱。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/188958.html原文链接:https://javaforall.net

(0)
上一篇 2026年4月15日 上午8:01
下一篇 2026年4月15日 上午8:07


相关推荐

  • 带宽与并发数

    带宽与并发数如有转载请注明出处哦 目的 做并发测试的时候 我们要根据自己的带宽看看网络能承受我们每秒到底能发送出多少个数据包 本篇博文是 介绍带宽与我们每秒最多发送的数据包的关系先说推出的结果并发数 带宽 Mb 67 2 数包大小 KB 注意这里的带宽 Mb 发送出的数据大小单位是 KB 下面为推到过程 首先要分清一下单位一个字节的等于八个位 位就是我们常说的二进制

    2026年3月20日
    2
  • Hunyuan-MT-7B部署教程:vLLM显存优化技巧让7B模型在24G GPU运行

    Hunyuan-MT-7B部署教程:vLLM显存优化技巧让7B模型在24G GPU运行

    2026年3月13日
    2
  • 谁知道怎么在国内用 Grok 3 模型?

    谁知道怎么在国内用 Grok 3 模型?

    2026年3月17日
    2
  • LabVIEW顺序结构

    LabVIEW顺序结构LabVIEW 最大的特点是数据流驱动 所以程序不一定会按图形代码的先后顺序执行 这是和传统的文本编程语言最大的不同之处 如果一定要指定某段代码的先后执行顺序 则可以用顺序结构来实现 顺序结构包含一个或多个按顺序执行的子程序框图或帧 程序中用帧结构来控制程序的执行顺序 执行完某一帧中的程序以后再执行下一帧中的程序 Labview 中的顺序结构有两种形式 平铺式顺序结构和层叠式顺序结构 它们的功能是相同的 只是形式不同 层叠式可以节省更多的空间 让整个程序代码看上去更加整齐 平铺式顺序结构

    2026年3月18日
    2
  • AutoEventWireup

    AutoEventWireup
      Google了一番,大家讨论AutoEventWireup问题可不少,Page指令的AutoEventWireup属性被设置为true(或者如果缺少此属性,因为它默认为true),该页框架将自动调用页事件,即Page_Init、Page_Load等14个方法,在这种情况下,不需要任何显式的Handles子句或委托。但这是怎么实现的呢?.net又怎样根据AutoEventWireup属性来动态编译或者预编译页面呢?我在Google上没有找到答案。
     

    2022年5月28日
    37
  • OpenClaw 多实例与分布式配置实战:基于腾讯云 Lighthouse 的隔离与扩容方案

    OpenClaw 多实例与分布式配置实战:基于腾讯云 Lighthouse 的隔离与扩容方案

    2026年3月13日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号