啊我摔倒了..有没有人扶我起来学习....
@TOC
前言
异或也叫半加运算,其运算法则相当于不带进位的二进制加法:二进制下用1表示真,0表示假,则异或的运算法则为:0+0=0
,1+0=1
,0+1=1
,1+1=0
(==相同为0
,相异为1
==),这些法则与加法是相同的,只是不带进位,所以异或常被认作不进位加法。
一、问题的引出
- 异或本身不是什么难点,但却有它独到的用处。我们先来讨论下述问题要怎么解决
- 假如给出两个变量并赋初值,然后我要交换这两个变量的值
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
int a = 10;
int b = 20;
int tmp = a;
a = b;
b = tmp;
printf("a = %d;b = %d", a, b);
return 0;
}
输出结果:
- 很简单嘛~那如果不能定义第三个变量呢?要怎么解决?我们试试看把
a
和b
加起来构成一个和
对应代码:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
int a = 10;
int b = 20;
a = a + b;
b = a - b;
a = a - b;
printf("a = %d;b = %d", a, b);
return 0;
}
输出结果:
- 上述是挺巧妙的,但是有一个问题,如果
a
和b
都是很大的数,那相加起来就容易超过最大值的限制,那还有什么方法能够既不多定义变量,又能不超过上限,还能交换两变量的值吗?
二、异或实现俩变量值的交换
- 我们先来分析分析异或的规律,假如我们在32位操作系统下有两个数3和5
十进制 | 二进制补码 |
---|---|
3 |
00000000 00000000 00000000 00000011 |
5 |
00000000 00000000 00000000 00000101 |
- 我们知道,
3 ^ 3 = 0
,5 ^ 5 = 0
;所以3 ^ 3 ^ 5 = 5
,5 ^ 3 ^ 5 = 3
。应该不难理解吧?(异或满足交换律) - 我们单独拿出分析下这两个式子
表达式 | 结果 |
---|---|
3 ^ 3 ^ 5 |
5 |
5 ^ 3 ^ 5 |
3 |
- 我们可以看出来,有点像转换的感觉
- 于是我们就把
3
和5
的异或即3 ^ 5
当做这个洗衣机。哦不,转换器
- 用这个方法试试我们一开始的问题
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
int a = 10;
int b = 20;
a = a ^ b;
b = a ^ b;
a = a ^ b;
printf("a = %d;b = %d", a, b);
return 0;
}
输出结果:
- 成功啦~实在是妙!接下来需要铁汁们去尝试别的场景了
三、总结
- 巧妙归巧妙,但是代码的可读性剧烈下降!还是推荐第一种,定义第三个变量进行交换,本文讲这些只是为了让铁汁们多了解一些干货,修炼内功!加油