基础:
要了解位操作符就要先了解关于计算机存储整数的知识。
计算机中的数都用二进制来表示,整数分为有符号整数和无符号整数;
无符号整数最左边为0,一定是正数,而有符号整数可能为正、也可能为负。
简单来说就是,无符号整数所有位都用来表示这个数字的大小,而有符号整数最左边一位用0/1来判断正负。
举个例子:
数字255 ,正数 二进制为1111 1111
数字-1, 负数 二进制也为 1111 1111
为什么-1 不是 1000 0001 呢?
原因是任何数在计算机中都是以补码的形式存储的
原码:直接根据数值写出的二进制序列就是原码
反码:原码的符号位不变,其他位按位取反
补码:反码 + 1
补码表示法则让我们可以对正数和负数实现加法,无需去考虑数字正负问题,大大提高了硬件的效率
位运算符
移位操作符
<<:左边丢弃,右边补0
#include<stdio.h>
int main()
{
int a = 3;
int b = a << 1;
printf("%d", b);
return 0;
}
分析: a为 0000 0011,移位操作后b的值为 0000 0110,b的值为6
>>:1.算术右移:右边丢弃、左边补原来的符号位
2.逻辑右移:右边丢弃、左边补0
#include<stdio.h>
int main()
{
int a = 8;
int b = a >> 2;
printf("%d", b);
return 0;
}
分析:a 为 0000 1000, 右移后 为 0000 0010 所以b的值为2
注意:左右移操作符移动后,原来数据的值并不会改变
按位与 &
规则:相同为1,不同为0
#include<stdio.h>
int main()
{
int a = 3;
int b = 5;
int c = a & b;
printf("%d", c);
return 0;
}
分析: a为 0000 00011
b为 0000 00101
所以 c为 0000 00001 c输出为1
按位或 |
规则:有1为1,无1为0
#include<stdio.h>
int main()
{
int a = 3;
int b = 5;
int c = a | b;
printf("%d", c);
return 0;
}
分析: a为 0000 00011
b为 0000 00101
所以 c为 0000 00111 c输出为7
按位异或 ^
规则:相同为0,相异为1
#include<stdio.h>
int main()
{
int a = 3;
int b = 5;
int c = a ^ b;
printf("%d", c);
return 0;
}
分析: a为 0000 00011
b为 0000 00101
所以 c为 0000 00110 c输出为 6
有趣的 ^的应用:不引入其他变量,交换两个变量的值
简单的想法:
int a = 3;
a ^ a = a;
0 ^ a = a;
这样a就又返回了原来的值
利用这个思路我们就可以实现我们交换变量的值
#include<stdio.h>
int main()
{
int a = 3;
int b = 5;
printf("a = %d b = %d\n", a, b);
a = a ^ b;
b = a ^ b;
a = a ^ b;
printf("a = %d b = %d", a, b);
return 0;
}
输出: