> 文档中心 > 移位运算、位运算、逻辑运算学不会?一篇文章带你吃透它们(含面试真题解析)

移位运算、位运算、逻辑运算学不会?一篇文章带你吃透它们(含面试真题解析)

移位运算、位运算、逻辑运算学不会?一篇文章带你吃透它们(含面试真题解析)

hello,大家好,今天我为大家带来的是移位运算、位运算以及逻辑运算,为了方便大家理解和掌握这三个知识点,我会在文章中附上一系列的图解和练习题,Let is go ! 🚀🚀🚀

移位运算、位运算、逻辑运算学不会?一篇文章带你吃透它们(含面试真题解析)

文章目录

  • 🚀原码、反码、补码
  • 🚀移位操作
    • 🎈1、左移操作符
    • 🎈2、右移操作符
  • 🚀位操作符
    • 🎈1、基本运算
    • 🎈2、按位异或的几个结论
  • 🚀相关练习题
    • 🎈1、变态笔试题
    • 🎈2、求二进制中1的个数
    • 🎈3、求二进制中不同位的个数
    • 🎈4、打印整数的奇偶二进制位
  • 🚀逻辑操作符
  • 🚀相关练习题
    • 🎈1、360笔试题
    • 🎈2、笔试题变式1
    • 🎈3、笔试变式题2

🚀原码、反码、补码

我们知道计算机只能识别二进制数据,所以整数要存入计算机中就必须转化为相应的二进制数,同时整数在内存中的二进制表现形式有三种,分别是原码、反码和补码。在内存中,计算机对数据进行运算的时候用的都是整数的补码。

对于正整数来说:原码 = 反码 = 补码;

对于负整数来说:原码符号位不变、其他位按位取反得到反码;反码加1得到补码;

下面我们以5和-5举例:

移位运算、位运算、逻辑运算学不会?一篇文章带你吃透它们(含面试真题解析)


🚀移位操作符

🎈1、左移操作符

< 向左移动数据的二进制位,高位舍弃,低位直接补0。

移位运算、位运算、逻辑运算学不会?一篇文章带你吃透它们(含面试真题解析)

其实,二进制位向左移动一位,数据的值就会变为原来的2倍,所以我们可以通过一位来实现一个数的n次方。

🎈2、右移操作符

右移和左移有一点区别,因为二进制位向右移动之后,由于最高位代表符号位,所以最高位补0还是补1影响一个数是整数还是负数。

右移分为逻辑右移和算术右移:逻辑右移,最高位直接补0;算术右移,最高位补原符号位。

移位运算、位运算、逻辑运算学不会?一篇文章带你吃透它们(含面试真题解析)

移位运算、位运算、逻辑运算学不会?一篇文章带你吃透它们(含面试真题解析)


🚀位操作符

🎈1、基本运算

按位与(&):对两个数的二进制位进行计算,如果对应位置的两个数的二进制位都为1,结果就为1;否则,结果就为0;

按位或(|):对两个数的二进制位进行计算,如果对应位置的两个数的二进制位有一个为1,结果就为1;如果两个都为0,结果就为0;

按位异或(^):对两个数的二进制位进行计算,如果对应位置的两个数的二进制位不同,结果就为1;相同,结果就为0;

移位运算、位运算、逻辑运算学不会?一篇文章带你吃透它们(含面试真题解析)

🎈2、按位异或的几个结论

  1. 两个相同的数异或的结果一定为0;

  2. 任何数与0异或都等于它自己;

  3. 异或满足交换律;

上面这三个结论证明很简单,只需要带一个数进去即可,所以这里不做赘述。


🚀相关练习题

🎈1、变态笔试题

不能创建临时变量(第三个变量),实现两个数的交换:

法一:求和相减移位运算、位运算、逻辑运算学不会?一篇文章带你吃透它们(含面试真题解析)

缺点:当 a 和 b 很大时,把 a+b 的结果放在 a 中,可能会导致a存放不下溢出而发生截断,从而损失精度

法二:重复异或(^)

移位运算、位运算、逻辑运算学不会?一篇文章带你吃透它们(含面试真题解析)

这里就需要我们熟悉按位异或的三个结论了:相同两个数异或为0,0与任意数异或为任意数、异或满足交换律。


🎈2、求二进制中1的个数

编写代码实现:求一个整数存储在内存中的二进制中1的个数:

法一:循环便利

移位运算、位运算、逻辑运算学不会?一篇文章带你吃透它们(含面试真题解析)

这里我们用每次整除二倍的方式计算,其实这种方法是由问题的,它只能求出整数二进制中一的个数,而不能求负数的。

法二:移位相与

移位运算、位运算、逻辑运算学不会?一篇文章带你吃透它们(含面试真题解析)

这里for循环的作用是让num的每一位二进制位都与1按位求与,如果求得的结果为1(即对应二进制位为1)就让count++;由于这是直接对内存中的二进制位进行操作,所以它既可以求正数,也可以求负数,弥补了上面那种方法的不足,但是我们可以看到,这种方法必须循环32次,那么有没有更优的方法呢?请看方法三。

法三:与n-1按位求与

移位运算、位运算、逻辑运算学不会?一篇文章带你吃透它们(含面试真题解析)

大家可以看到,这种方法既可以做到对内存中的二进制位直接进行操作,又可以减少循环次数,达到了优化的目的;但是要想到这种方法十分困难,而且也不好理解,一般我们掌握第二种方法即可,对这种方法感兴趣的同学可以自己研究一下,说不定以后有机会在面试的时候展示出来。


🎈3、求二进制中不同位的个数

编写代码实现:求两个数二进制中不同位的个数:([牛客网链接](两个整数二进制位不同个数__牛客网 (nowcoder.com)))

思路分析:求二进制中不同位的个数,那么我们首先应该想到的就是让这两个数异或,,由于异或的特点是相同位为0,不同位位为1,所以异或后形成的新的整数得二进制中1的个数即是这两个数二进制中不同位的个数。

代码实现:

移位运算、位运算、逻辑运算学不会?一篇文章带你吃透它们(含面试真题解析)


🎈4、打印整数的奇偶二进制位

编写代码实现:获取一个整数二进制序列中所有的偶数位和奇数位,分别打印出二进制序列:

思路分析:对于打印一个整数的二进制位,我们可以也是使用移位操作符和位操作符,然后配合循环来实现;但是这里需要注意的是:屏幕上先打印的应该是二进制中的高位,这样才符合我们阅读数字的习惯,所以循环变量的初始值要设置为高。

代码实现:

移位运算、位运算、逻辑运算学不会?一篇文章带你吃透它们(含面试真题解析)


🚀逻辑操作符

逻辑操作符一共分为两类:逻辑与(&&) 和 逻辑或(||);

逻辑与:当两个条件都为真时,执行后面的语句;当两个条件有一个或者都为假时,语句不执行。

逻辑或:当两个条件有一个及以上为真时,执行后面的语句;当两个条件都为假时,语句不执行。

移位运算、位运算、逻辑运算学不会?一篇文章带你吃透它们(含面试真题解析)

注意:逻辑操作符在特定情况下会发生"短路",即当条件1 && 条件2,若条件1为假时,此时整个逻辑表达式直接为假,条件2将不会被执行;当条件1 || 条件2,若条件1为真时,此时整个逻辑表达式直接为真,条件2将不会被执行;这个是逻辑表达式在学校期末、校招、面试中的重要考点,一定要掌握,具体细节及考察形式在下面的题目中来进行说明。


🚀相关练习题

🎈1、360笔试题

请问下面程序输出的结果是什么:(大家可以先自己做一下再看解析)

移位运算、位运算、逻辑运算学不会?一篇文章带你吃透它们(含面试真题解析)

移位运算、位运算、逻辑运算学不会?一篇文章带你吃透它们(含面试真题解析)

大家看到这个答案是不是很疑惑,不要慌,接下来我来为大家一步一步分析:

首先,这里我们定义并初始化了 i、a、b、c、d这四个元素,然后 a、b、d搭配++运算符和逻辑运算符求值;

a++:这里是后置++,先使用后++,所以a++的返回值是0,返回之后a++变成1;

a++ && ++b:由于这里是逻辑与操作符,并且a返回0,那么由我们上面学习的逻辑操作符的"短路"现象,我们就可以知道,++b && d++这些语句根本不会被执行,所以最终只有a被++了一次,b、c、d保持不变


🎈2、笔试题变式1

接下来我们看一道上面笔试题的变式:(先自己思考后再看答案哦)

移位运算、位运算、逻辑运算学不会?一篇文章带你吃透它们(含面试真题解析)

移位运算、位运算、逻辑运算学不会?一篇文章带你吃透它们(含面试真题解析)

这里和原题差不多,只不过是把逻辑与操作符变成了逻辑或操作符而已;

a++:这里是后置++,先使用后++,所以a++的返回值是0,返回之后a++变成1;

a++ || ++b:由于这里是逻辑或,所以a为假时整个逻辑表达式并不一定为假,会继续往后面执行

++b:这里是前置++,先++再使用,所以b++之后变为3,再返回3;

++b || d++:我们知道,前面语句执行后 a=1、b=3,因为a++ && ++b = 1,所以这句逻辑表达式就变为了 1 || d++,即这里又会发生短路现象,最后的d++不会被执行,所以最终a被++了一次,b被++了一次,c、d保持不变。


🎈3、笔试变式题2

最后我们再来对这道笔试题进行一次变式:(注意先自己思考再看答案和解析)

移位运算、位运算、逻辑运算学不会?一篇文章带你吃透它们(含面试真题解析)

移位运算、位运算、逻辑运算学不会?一篇文章带你吃透它们(含面试真题解析)

这里和原题唯一不一样的地方就是a被初始化1,而不是0;

此时a++会先返回a的值为1,再让a++变为2;1不为0,逻辑与不会发生短路,代码继续往后执行

++b:先让b++变为3,再返回b的值为3;此时a++ && ++b 1 && 3 = 1;

所以a++ && ++b && d++ 1 && d++,不会发生短路,代码继续往下执行;d++,先返回4,再让d++变成6。

所以最终a、b、d均被++一次,c不变。