提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
记录下 位与(&) 位或(|) 异或(^) 的学习
提示:以下是本篇文章正文内容,下面案例可供参考
基本信息
代码如下(示例):
#include <stdio.h>
// & 按(2进制)位与
// | 按(2进制)位或
// ^ 按(2进制)位异或
main()
{
int a = 3;
int b = -5;
//内存中按补码存储 int是4字节也就是32bit
// 最高位(最左位是符号位 0为正数 1为负数)
// 正数 原码 反码 补码 相同
// 0000 0000 0000 0000 0000 0000 0000 0011 原码3
// 0000 0000 0000 0000 0000 0000 0000 0011 反码3
// 0000 0000 0000 0000 0000 0000 0000 0011 补码3
// 1000 0000 0000 0000 0000 0000 0000 0101 原码-5
// 负数 符号位不动 其他取反
// 1111 1111 1111 1111 1111 1111 1111 1010 反码-5
// 补码 最后一位+1
// 1111 1111 1111 1111 1111 1111 1111 1011 补码-5
// 位与操作 每位对比 0 1为0 1 1为1
int c = a & b;
// 0000 0000 0000 0000 0000 0000 0000 0011 补码3
// 1111 1111 1111 1111 1111 1111 1111 1011 补码-5
// 0000 0000 0000 0000 0000 0000 0000 0011 返回3的补码
printf("c=%d\n", c);
int d = a | b;
//位或操作 0 1为1 0 0为0
// 0000 0000 0000 0000 0000 0000 0000 0011 补码3
// 1111 1111 1111 1111 1111 1111 1111 1011 补码-5
// 1111 1111 1111 1111 1111 1111 1111 1011 返回补码-5
// 1111 1111 1111 1111 1111 1111 1111 1010 反码 补码-1
// 1000 0000 0000 0000 0000 0000 0000 0101 原码 -5
// 1 0 1
// 1*2(2次方) 0*2(1次方) 1*2(0次方)
// 4 + 0 + 1
// -5
printf("d=%d\n", d);
int e = a ^ b;
//异或操作 相同为0 相异(不同)为1
// 0000 0000 0000 0000 0000 0000 0000 0011 补码3
// 1111 1111 1111 1111 1111 1111 1111 1011 补码-5
// 1111 1111 1111 1111 1111 1111 1111 1000 返回补码
// 1111 1111 1111 1111 1111 1111 1111 0111 返回反码 补码-1
// 1000 0000 0000 0000 0000 0000 0000 1000 返回原码结果-8
printf("e=%d\n", e);
return 0;
}
运行结果
异或的应用
//不创建临时变量 交换2个数
printf("交换前 a=%d b=%d\n", a, b);
//异或 a^0 = a a^a =0
//还支持换位置 -5^3^-5 == -5^-5^3
a = a ^ b; //a=3^-5
b = a ^ b; //3^-5^-5 --> b=3
a = a ^ b;//3^-5^3 --> a=-5
printf("交换后 a=%d b=%d\n", a, b);
运行结果