【C语言】异或操作符‘^’

今天我们来详详细细的介绍一下异或操作符(^)
异或(^)操作符同与(&)操作符、或(|)操作符一样,都是来操作二进制底层的,是通过二进制每一数位来进行操作,所以他们也统称为–位操作符。
异或(^)操作符:相同为1,不同为0.
简单跟大家举个例子

int main()
{
	int a = 15;
//15二进制:0000 0000 0000 0000 0000 0000 0000 1111
	int b = 10;
//10二进制:0000 0000 0000 0000 0000 0000 0000 1010
	int c = a ^ b;
//a ^ b :  0000 0000 0000 0000 0000 0000 0000 1111
//         0000 0000 0000 0000 0000 0000 0000 1010
//结果 :   0000 0000 0000 0000 0000 0000 0000 0101
//因为符号位是0,是正数,所以原码反码补码都相同,101就等于5
	printf("%d\n",c);// 5
	return 0 ;
}

他按照每一位来进行运算,相同则这一位的结果为0,不同 这一位的结果为1.这就是按位异或的计算思想
学了按位异或,我们来用按位异或解答一道题
题目:给定两个数字分别用a和b来接收,在不创建第三方变量的情况下,交换两个数字。
如果我们能创建第三方变量,那就非常简单,关键就是不能创建第三方变量。这里我们就能很巧妙的运用到异或操作符
我们先来看代码

int main()
{
	int a = 10;
	int b = 20;
	a = a ^ b;
	b = a ^ b;
	a = a ^ b;
	printf("a = %d \nb = %d\n", a, b);
	return 0;
}

运行结果如下
在这里插入图片描述
他是怎么实现交换的呢?我们来详细分析

为了方便我们只取8个字节来讲解  前面的都是0对结果不影响
a ^ b
a(10)二进制:0000 1010
b(20)二进制:0001 0100
a = a ^ b   : 0001 1110
这时候a里面存放的就是(0001 1110)不再是10的二进制位了
       a   :0001 1110
       b   :0001 0100
b = a ^ b  :0000 1010
这个时候把得出来的结果(0000 1010)存入到b当中,
就能发现这个结果其实就是原来的a,这里就完成了把
a的值给b这一步
接着   a   :0001 1110
       b   :0000 1010
a = a ^ b  :0001 0100
把得出来的结果(0001 0100)放入a当中,对比上面刚开始的b,
就是这个二进制位
这样一来就完成了a和b的交换

想必第一次见到的会感到特别神奇,就好像博主刚开始学习c语言接触到异或一样,这就是异或的魅力
但是为什么这么神奇呢?我再带大家换一种思路来解答

我们先来想一下

  1. 0^a = ?
  2. a^a = ?
int a = 10;
0 ^ a
0的二进制      :0000 0000
a的二进制(10):0000 1010
     ^        : 0000 1010
 就等于a,所以我们得出结论:0和任何一个值异或(^)结果
 都是本身
int a = 10;
a ^ a
a的二进制    :0000 1010
              0000 1010
              0000 0000
很显然,两个相同的值异或(^)结果等于0

我们搞清楚了上面的两个特殊的关系,再来看原先的代码

int main()
{
	int a = 10;
	int b = 20;
	a = a ^ b;
	b = a ^ b;
	  //等号右边的a 相当于是a ^ b  所以可以写成
	  //b = a ^ b ^ b;两个b异或等于0,0再去跟a
	  //异或就等于a,这样就能很好地解释第二个表达式
	a = a ^ b;
	  //同理,这里的b = a,所以表达式可以写成 a = a ^ b ^ a;
	  //同样能得到a = b 所以就完成了交换。
	printf("a = %d \nb = %d\n", a, b);
	return 0;
}

从上面也能看得出,异或(^)是满足交换律的。
当我们从上面这种直观的解释理解之后,我们再换一个角度

	a = 10;
	b = 20;
	a ^ b
	0000 1010
	0001 0100
	0001 1110
	a = a ^ b;
	//我们第一次求出来的a(0001 1110),其实可以当作一个密码子,
	//当我们用b去异或这个密码子的时候,他会得到a,如果用a去异或这
	//这个密码子,他会得到b
	b = a ^ b;
	a = a ^ b;

上面的例子我们得出结论,一个数,在异或运算当中,异或两次得出的结果,是参与异或运算的其他数的异或结果
我们通过这个结论,就可以很好的排除,数组当中两个重复的数字
例如下面的一道OJ题
消失的数字

我们就可以用异或来解答,会非常的简单,我们只需要把数组当中所有的数字全部异或一遍,之后再生成1-n的数字,再次异或,最后得出来的,就是缺失的数字。
在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值