一. 移位操作符>> <<
1. 整数的二进制表示
Ps:怎么确定一个数在内存中占几位呢? 2. <<左移操作符3. >>右移操作符 二. 位操作符& |^
1. &按(二进制)位与2. |按(二进制)位或3. ^按(二进制)位异或
1.异或用在解题中用到的性质:2.位操作符的应用
(1) 使特定位翻转(2)不用中间变量,实现两个数的交换(3) 找到只出现特定次数的数字
一. 移位操作符>> <<1. 整数的二进制表示操作数只能是整数
对于移位运算符,不要移动负数位,这是标准未定义的
num>>-1//ERROR
整数的二进制有3种表示:
1. 原码 1. 反码 1. 补码
最高位是符号位,0表示为正数,1表示为负数
Ps:怎么确定一个数在内存中占几位呢?比如int型整数,占4个字节,每个字节是8比特,所以占4*8=32比特位
int 5的原码:00000000 00000000 00000000 00000101
int -5的原码:10000000 00000000 00000000 00000101
同理,char型是1个字节,就占8位
| 正整数 | 负整数 | |
|---|---|---|
| 原码 | 数在内存中的二进制,最高位为0 | 最高位为1 |
| 补码 | 与原码相同 | 原码符号位不变,其他位按位取反 |
| 反码 | 与原码相同 | 反码+1 |
int a = -5
原码:10000000 00000000 00000000 00000101
反码:11111111 11111111 11111111 11111010
补码:11111111 11111111 11111111 11111011
整数在内存里存储的是补码,打印出来的值是原码
2. <<左移操作符移位规则:
左边抛弃、右边补0
int a = -10;
int b = a<<1;//左移一位
printf("%dn",a);
printf("%dn",b);
结果是:
-10
-20
注意:a本身值是不变的
左移n位就是把原数值*2的n次方
一整个计算过程是这样的
这是负数的情况,如果是正数,原、补、反码都一样,到了第4步就不必再-1、取反了。
3. >>右移操作符移位规则:
右移有两种:
算数右移:右边丢弃,左边补原符号位逻辑右移:右边丢弃,左边补0
是算数右移还是逻辑右移取决于编译器
二. 位操作符& |^1. &按(二进制)位与操作数只能是整数
int a = 3; int b = -5; int c = a&b;
a和b的补码相运算
对应二进制位上,a和b中只有一个有0就为0,两个都为1时才为1
真值表:
| & | 0 | 1 |
|---|---|---|
| 0 | 0 | 0 |
| 1 | 0 | 1 |
00000000 00000000 00000000 00000011 -> a=3的补码 11111111 11111111 11111111 11111011 -> b=-5的补码 00000000 00000000 00000000 00000011 -> c的补码 同样,输出是原码,这里最高位是0,是正数,所以原码和补码相同
2. |按(二进制)位或c=3
int a = 3; int b = -5; int c = a|b;
对应二进制位上,a和b中有1就为1
真值表:
| | | 0 | 1 |
|---|---|---|
| 0 | 0 | 1 |
| 1 | 1 | 1 |
00000000 00000000 00000000 00000011 -> a=3的补码 11111111 11111111 11111111 11111011 -> b=-5的补码 11111111 11111111 11111111 11111011 -> c的补码 我们来求c的输出 11111111 11111111 11111111 11111010 -> c的反码 10000000 00000000 00000000 00000101 -> c的原码
3. ^按(二进制)位异或c=-5
int a = 3; int b = -5; int c = a^b;
对应二进制位上,相同为0,相异为1
真值表:
| ^ | 0 | 1 |
|---|---|---|
| 0 | 0 | 1 |
| 1 | 1 | 0 |
00000000 00000000 00000000 00000011 -> a=3的补码 11111111 11111111 11111111 11111011 -> b=-5的补码 11111111 11111111 11111111 11111000 -> c的补码 我们来求c的输出 11111111 11111111 11111111 11110111 -> c的反码 10000000 00000000 00000000 00001000 -> c的原码
1.异或用在解题中用到的性质:c=-8
- 任何数与0异或仍是它本身任何数与1异或等于将其取反任何数与自己异或,等于把自己置0异或满足交换律、结合律
比如:01111010,想使其低4位翻转,即1变为0,0变为1。可以将它与00001111进行^运算
(2)不用中间变量,实现两个数的交换#include(3) 找到只出现特定次数的数字int main() { int a = 10; int b = 20; a = a^b;//1 b = a^b;//2 a = a^b;//3 printf("a = %d b = %dn", a, b); return 0; } //可以这样理解,将1代入2 //b = a^b^b //b = a //将2代入3 //a = a^a^b //a = b
一道面试题大家可以试着做做看:https://leetcode-cn.com/problems/missing-number-lcci
参考:https://blog.csdn.net/wwt18811707971/article/details/



