位运算操作符(移位操作符)
移位操作符移动的是存储在内存中的补码的二进制序列
<< 左移操作符
>> 右移操作符
& 按位与操作符
| 按位或操作符
^ 按位异或操作符
~ 按位取反操作符
- 这些位运算的操作符,只适⽤于整数,不能应⽤于其他数据类型(char类型也属于整型家族,字符是以ascil码值存储的)
左移操作符
正数
10左移1位变成了20,针对正数,左移1位有乘2的效果
#include <iostream>
using namespace std;
int main()
{
int num = 10;
int n = num << 1;
cout << "n = " << n << endl; //n = 20
cout << "num = " << num << endl; //num = 10
return 0;
}
正数的原反补码都一样
10 = 00000000 00000000 00000000 00001010 num的二进制的表示
20 = 00000000 00000000 00000000 00010100 num<<1的结果,但是num的值是不变的
^左边丢一位 ^右边补一位
- 移位规则:左边抛弃、右边补 0
负数
负数左移先把负数写出原反补码再左移,打印出来还要再算出原码
#include <iostream>
using namespace std;
int main()
{
int num = -10;
//10000000 00000000 00000000 00001010 -10的原码
//11111111 11111111 11111111 11110101 -10的反码
//11111111 11111111 11111111 11110110 -10的补码
int n = num << 1;
//11111111 11111111 11111111 11101100 n的补码
//10000000 00000000 00000000 00010011 n的反码
//10000000 00000000 00000000 00010110 n的原码
cout << "n = " << n << endl; //n = -20
cout << "num = " << num << endl; //num = -10
return 0;
}
右移操作符
右移运算分两种:逻辑右移和算术右移,具体采⽤哪种右移⽅式取决于编译器,⼤部分的编译器采⽤ 的是算术右移。两种移位⽅式的规则如下:
- 逻辑右移:左边⽤ 0 填充,右边丢弃
- 算术右移:左边⽤原该值的符号位填充,右边丢弃
#include <iostream>
using namespace std;
int main()
{
int num = -1;
int n = num >> 1;
cout << "n = " << n << endl; //n = -1
cout << "num = " << num << endl; //num = -1
return 0;
}
- 逻辑右移补0进去,num会变成一个非常大的正数,但这里还是-1,说明在gcc编译器上,采用的是算术右移
右移是否有乘2的效果?
- 对于正数,右移一位有除2的效果
警告
- 对于移位运算符,不要移动负数位,这个是标准未定义的
int num = 10;
num >> -1;//error