逻辑运算符号也是一种运算符号,比如&&(与)、||(或)和!(非)。

一般自己在写C/C++程序的时候,通常用逻辑运算符做判断,if(A且B)或者while(A或B),很少用他们做算数运算。因为用逻辑运算符做算数运算,就要涉及到二进制数的每一个bit的值了。今天在找分段树算法的时候发现几个有趣的面试题,关于逻辑运算符的例子。

 

第一个是y=x&&(-x)。这个式子的返回值是最后一位“1”以及其后所有“0”组成的数。比如,设x=40,用二进制表达就是x=00101000。-x=-40,负数在计算机里是用补码表示的(补码就是反码加一,反码是原码取反),-x=11011000。这两个数按位与的结果就是y=00001000,即十进制的8(2^3)。这样就很方便的找出了最低位的“1”,是从低到高第4位。又如x=20, y=x&&(-x)=4=2^2,最低位的“1”在右起第3位。

第二个是y=x&&(x-1)。这是某公司的一道面试题。假设有函数function:

    int function(int n){
         int count=0;
         while(n){
            count++;
            n=n&&(n-1);
         return count;
         }

问function(9999)的值是多少。如果拿一个数带入函数试几次,就会发现每次运算都把最后一位“1”移去,直到n=0为止。所以最后的结果就是9999二进制表达式中“1”的个数,答案是8还是9(忘记了。。。)。当然,如果传入的参数是负数,返回值就是其补码的“1”的个数。

再来一个,不用if, while 和‘+’写一段代码输出1-100。过程如下:

    int print(int x){
         x&&print(x-1);
         x&&printf("%d",x);
         }