目录
大家好,今天介绍操作符中较难理解的移位操作符和位操作符
移位操作符
<< 左移操作符
>> 右移操作符
对象是整数的补码,二进制位
<< 左移操作符
移位规则 比较简单
左边丢掉,右边补0
int a=10;
a=a<<1;
a的二进制是000000000000000000000000000001010 左移一位
移位之后 是000000000000000000000000000010100
>> 右移操作符
移位规则,分两种:
1.逻辑移位 左边用0填充,右边丢弃
2.算术移位 左边用该原值的符合位填充,右边丢弃
编译器中一般都是算术移位
int a=-1;
a=a>>1;
算术右移:左边用符号位填充,由于是负数,符号位是1,左边补1。
-1二进制是11111111111111111111111111111111 右移一位
移位之后 是11111111111111111111111111111111
逻辑右移:左边补0,不补符号位了
-1二进制是11111111111111111111111111111111 右移一位
移位之后 是01111111111111111111111111111111
看看在VS2022中的结果
说明它用算术移位
警告:不要移动负数位,这个是标准未定义的
int a=1;
a=a>>-1;error
位操作符
& 按位与
| 按位或
^ 按位异或
它们操作数都是整数并且都是补码操作
& 按位与
对应的二进制位有0为0,两个同时为1才为1
| 按位或
对应二进制位有1为1,两个同时为0才为0
^ 按位异或
对应二进制位相同为0,相异为1
按位异或^中的一些规律
a^a=0
a^0=a
a^b^a=b ,因此按位异或^满足交换律
例题
一道变态的面试题
不能创建变量(第三个变量),实现两个数的交换。
小伙伴们想想…………
你们可能会想到
但是这个不是最优的,因为,假如给的a b很大,那a+b可能会超过最大范围,导致截断 ,以至结果不对
最优方法是:用按位异或^,你们又可以想想怎么实现
第二题
求一个整数存储在内存的二进制中1的个数。
你们又想想…………,想想刚学的知识怎么用
给你们一个思路:二进制位一位一位与1按位与&,从最低位开始寻找1的个数,比完向右移
方法1
那有没有更好的呢?再想想
方法2
这种方法太难想到了。
一些问题表达式
表达式1
a*b+c*d+e*f
在计算中只能保证乘法比加法先算,但不能保证第三个*比第一个+早执行
表达式2
answer计算你只能保证*比+先运算,但你不能保证函数调用先后
总结
当表达式没有唯一确定的计算路径,那么就有问题
本文总结
今天学习了移位操作符和位操作符,它们都是作用于二进制位,要灵活运用它们,可能会有意想不到的结果,有些题你可能不会做,可能就是要用到它们,还有不要写出问题表达式
今天的分享到这里