左移和右移操作符
注:移位操作符的操作数只能是整数。
左移操作符 <<
#include<stdio.h>
int main()
{
int a = -3 << 1;
int b = 5 << 1;
printf("a = %d b = %d",a,b);
return 0;
}
整数在内存中存储的是补码,不论是左移还是右移都移动二进制位,也就是移动内存中的补码,- 3往左移动一个二进制位:
-3的原码是:1000000 0000000 0000000 00000011
-3的反码是:11111111 11111111 11111111 11111100
-3的补码是:11111111 11111111 11111111 11111101
那么5的原码是:00000000 00000000 00000000 00000101
整数原,反,补码相同
向左移动一个二进制位:
所以-3向左移动一位是 -6
5向左移动一位是 10
我们来验证一下:
-3左移一位是-6,5左移一位是10,可以发现左移1位有乘2的效果
再次来验证一下:
右移操作符>>
将数字的补码向右移动一个二进制位
我们还是拿-3和5来举例
注意:向右移动的时候,大部分编译器都是补符号位
- 逻辑移位
左边用0填充,右边丢弃 - 算术移位
左边用原该值的符号位填充,右边丢弃
对于移位运算符,不要移动负数位,这个是标准未定义的。
5向右移动一位:
来验证一下:
位操作符
1,按位与 &
两个操作数都为1,结果才是1
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{
int a = -3 & 5;
int b = 5 & -3;
printf("a = %d b = %d",a,b);
return 0;
}
验证一下:
2,按位或 |
两个操作数都为0,结果才是0
还是用-3和5举例:
验证一下:
3,按位异或 ^
两个操作数相同,结果是0,两个操作数不相同,结果是1
还是用-3和5举例:
验证一下:
我们再通过一个经典的题目来仔细分析一下按位异或
现在有一个变量a = 10,变量b = 20
怎样再不创建新的变量的条件下,交换两个变量的数据
首先我们会想到:
a = a + b;
b = a - b;
a = a - b;
讲到异或,那我们肯定是用异或的方式来交换:
#define _CRT_SECURE_NO_WARNINGS
#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 等于 10 ^ 20得到30,可以把30看做是一个密码
当用a去异或b的时候,也就是30 ^ 20得到10
再用a ^ b,也就是30 ^ 10,得到20,如何赋值给a
达到一个交换的效果
4,按位取反 ~
按位取相反数 0变成1,1变成0
还是用-3和5举例:
验证: