交换两数(不使用中间变量)

引出问题: 

说到交换两数的值,对大家来说应该是一个非常简单的任务,但是,我们最常用的方法就是创建一个临时变量,再通过这个临时变量来改变两值,如下:

int temp = a;
a = b;
b = temp;

但是,难道交换两个变量就只有这一种做法吗?

方法1

其实不然,不创建临时变量也可以交换两数,我们可以把a+b的值赋给a,然后将a减去b赋给b,这时候就等价于

这时,我们就发现b的值变成了a,然后再用a的值减去b,又会发现

 总结一下,就得到了不使用中间变量交换两值的方法,如下:

int main()
{
	int a = 0;
	int b = 3;
	printf("交换前:%d %d", a, b);
	a = a + b;
	b = a - b;
	a = a - b;
	printf("交换后:%d %d", a, b);
}

但是,这种方法有一个缺陷,那就是如果这两个数太大,相加在一起就会出现溢出的现象,可以把这两个数定义为长整型,那么,还有没有别的方法呢?

答案是有!!!这个方法非常巧妙,这里运用到了异或操作符。

方法二

        这里首先先简单带大家了解一下异或操作符  '^' ,这个操作符是作用于二进制位上的,如果两个数的相同位上二进制数相同,那么该操作符就会返回0,如果不同就会返回1,那么这个操作符有什么特点呢?要用这个操作符来做到交换两数又要知道他的什么特点呢?

1. 对同一个数进行异或操作会得到0

这很容易理解,两个相同的数每个位上的二进制数都相同,所以返回的每一位都是0。

2. 0和任何数进行异或操作都得到该数本身

这只要思考一下也很容易得出,0的每个二进制位都是0,0^1 = 1 , 0^0 = 0,从这里就可以看出,不管这个数的二进制位是什么,异或一个0都不会改变他的二进制位,所以0^任何数都得到本身。

3. 异或操作符满足交换律

这个只要实际操作一下就能得出结论,暂时也不知道有什么解释的好方法,有知道解释方法的大佬评论区留言一下啊哈哈!!!

那么,根据这三个理论,我们就能进行下面交换两数的操作了,先上代码,再来进行解释!

int main()
{
	int a = 0;
	int b = 0;
	printf("交换前:%d %d", a, b);
	a = a ^ b;
	b = a ^ b;
	a = a ^ b;
	printf("交换后:%d %d", a, b);
	return 0;
}

怎么理解这段代码呢?

是的,第一个式子把a^b赋给 a,那么第二个式子就可以等价于a^b^b,相当于a^(b^b)=a^0=a,也就是说第二个式子的结果就是把a赋给了b,那么最后一个式子用同样的方法解释就可以发现最后得到的是a=b。

        可以用通俗的话语来讲,a^b就可以相当于一个钥匙,其^b就得到b,其^a就得到a。

是不是觉得非常神奇!但是我们需要注意这一段代码的缺点,二进制操作的效率是不高的,并且这段代码只适用于整数,对于浮点数是不能进行这个操作的,并且这个代码的可读性很差,所以,大家不要看这个代码很精妙就滥用!!

  • 14
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

暮雨清秋.L

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值