书接上回,这篇博客之中我提到了不创建第三个变量但实现两个数的交换的两种方法,今天就来讲解一下:
#include<stdio.h>
int main()
{
int a, b;
scanf("%d %d", &a, &b);//输入两个数
a = a ^ b;//a的值等于a与b按位异或
b = a ^ b;//b的值等于a与b按位异或后的值与b按位异或
a = a ^ b;//a的值等于a与b按位异或的值与a与b按位异或后的值与b按位异或的值按位异或
printf("%d %d", a, b);
return 0;
}
注释应该是很难理解的,但没关系,我们展开细说。
按位异或操作符^
按位异或^操作符是c语言中的一种操作符,顾名思义,可以对操作数按位异或,但我们都知道在电脑中存储的是二进制位,所以说实际上是对其32位二进制位进行按位异或的,那么具体是怎么操作的呢,让我们举个例子——5^8。5的32位二进制位是00000000000000000000000000000101,8的32位二进制是00000000000000000000000000001000,我们现在对两个操作数按位异或——“相同则为0,相异则为1”——00000000000000000000000000001101,这就是5^8的结果,算出来等于13,让我们来验证一下:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{
int a = 5;
int b = 8;
printf("%d\n", a ^ b);
return 0;
}
发现果然是13,那么我们现在就已经学会了按位异或操作符的使用方法,如何对此展开使用呢?
按位异或操作符的推导使用 、
这里有两个“推论”:1,a^a=0; 2.a^0=a;
我们对其证明:假如a=5,其二进制表示为00000000000000000000000000000101,假如5^5,则是00000000000000000000000000000101
00000000000000000000000000000101,我们看到两个数完全相同,所以说对其按位异或出来的结果就是00000000000000000000000000000000(就是0),所以说a^a=0。
假如5^0呢?00000000000000000000000000000101 (5的二进制)
00000000000000000000000000000000(0的二进制)
对其计算 00000000000000000000000000000101(5^0),所以说a^0=a。
有了这两个推论,我们就可以解释这上面的代码了
#include<stdio.h>
int main()
{
int a, b;
scanf("%d %d", &a, &b);//输入两个数
a = a ^ b;//a的值等于a与b按位异或
b = a ^ b;//b的值等于a与b按位异或后的值与b按位异或
a = a ^ b;//a的值等于a与b按位异或的值与a与b按位异或后的值与b按位异或的值按位异或
printf("%d %d", a, b);
return 0;
}
先将a=a^b存在a中,b就等于a^b^b,所以说等于a,然后b等于a了;a等于a^b^a=b,a就等于b了,就实现两个数的交换了。