C语言操作符面试变态题

文章目录

  • 一、不创建临时变量交换两个数的值
  • 二、求一个整数在内存中存储的二进制中1的个数
  • 总结


一、不创建临时变量交换两个数的值

        看到这道题我们第一思路肯定是创建变量c进行交换但是题中已经要求了不能创建临时变量所以我们需要换其他的思路。

        思考以后我们可能会想到用加法的方法

int a = 5;
int b = 3;
a = a + b;
b = a - b; //b = a
a = a - b; //a = a + b - a = b

         这种方法看似可以,但这是道面试题肯定不会出的这么正常,如果这两个数很大的话a+b就会超出整型下面今天的主角操作符就登场了。首先介绍个异或操作符'^',二进制中两数相同为0不同为1.

0 ^ 1 = 1;
1 ^ 1 = 0;
0 ^ 0 = 0;

        这里有两个特性任何数与它本身异或结果为0,任何数与0异或都是该数本身

a ^ a = 0;
0 ^ a = a;
0 ^ b = b;

        讲到这里大家肯定对刚才的题又有点思路了


a = a ^ b;  //a' = a ^ b;
b = a ^ b;  //b' = a' ^ b = a ^ b ^ b = a ^ 0 = a;
a = a ^ b;  // a = a' ^ b'= a ^ b ^ a = b; 

        怎么样这道题的解法确实有点不太好想吧,有点变态吧。

二.求一个整数在内存中存储的二进制中1的个数

        这道题第一思路肯定是%2判断是否等1然后/2。

int count_1 (int n){
    int count = 0;
    while(n){
        if(n % 2 == 1){
        count++;
            }
        n = n / 2;
    }
return count;
}

        但面试官想要的肯定不是这种结果,下面思考位运算的方法。我们把二进制的最后一位与1进行且'&'运算,然后再进行右移操作。我们先粗略说下‘&’且运算,二进制同为1才为1其他全为0.

1 & 1 = 1;
0 & 1 = 0;
0 & 0 = 0;

然后我们开始编写这道题的代码

int count_1 (int n){
    int count = 0;
    for(int i = 0; i < 32; i++){//int类型4字节32位
        if( n & (1 << i) )
        count++;
    }
return count;
}

这个方法已经使用位运算了但是还是不够高效,面试官想要的肯定是更高效的方法。

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

上面这种方法看着是不是可懵逼,下面来给大家解释下

拿 n = 15 举例子 

  15的二进制1111(内存中32位这里我们先只取后4位)  
     n = 1111
 n - 1 = 1110
n&(n-1)= 1110
n值变为1110

     n = 1110
 n - 1 = 1101
n&(n-1)= 1100
n值变为1100

     n = 1100
 n - 1 = 1011
n&(n-1)= 1000
n值变为1000

     n = 1000
 n - 1 = 0111
n&(n-1)= 0000
n值变为0000
循环终止count = 4

神奇吧,这种方法还有个算法名“布莱恩·柯尼根算法”


总结

第一次发博客肯定有许多不足的地方请大家多多包涵,我的博客质量一定会越来越高的。

你可能感兴趣的:(面试,职场和发展)