目录
一、不能创建一个临时变量(即第三个变量), 实现两个数的交换。
根据之前的博客,今天来介绍一下操作符的一些特殊的题目。
一、不能创建一个临时变量(即第三个变量), 实现两个数的交换。
第一种方法
以下是第二种方法:
注:结合上面的两种方法来看,都有一些的缺陷,第一种方法是需要学会的知识稍微多一点,可读性不一定很好,第二种则是可读性可以,但是在遇到大的数的时候则不容易运算了,如果在遇到没有明确不能使用第三方变量的时候 ,还是最好生成第三方变量,这样代码的可读性和效果都会很好的。
二、求一个整数储存在内存中的二进制中的1的个数
许多人也许会对求二进制中的1起到疑惑,其实把二进制当成十进制就很好理解了。
其实就相当于对要求的进行取10和除10,换成二进制的就取2和除2了,最后的结果看取的数就可以了。
既然明白了如何使用二进制去计算每一位的值,那求整数储存在内存中的二进制中的1的个数 就有了方法了。
int main()
{
int num = -1;
int count = 0;
while (num)
{
if ((num % 2) == 1)//通过之前的方法可以看出只要不能整除的余数就为1;
{
count++;
}
num /= 2;
}
printf("%d\n", count);
return 0;
}
这个代码得出的结果为6,根据之前的方法可以知道123 的二进制为0111 1101,可以知道确实是6个1.
但是不要高兴的太早了,这里了会有一点bug,如果我输入的是负数(下面以-1为列子)会怎么办了?
可以看出当输入的数字是-1的时候结果会是0。
那我们应该如果挽救这个代码了?
第一种方法:
将num换成无符号整数,就可以以后输入的负数就可以把他当成整数执行了
因为-1在内存中储存是32个1,换成无符号整数后,就识别为32个1。
第二种方法:
根据之前说过的按位操作符和移位操作可以得出结果。
第三种方法
第三种方法是使用了算法的原理,让人不好想到。
num=num&(num-1)就是那个神奇的算法。它可以将num的二进制最右边的1去掉。下面的那个图就是这个算法的原理。
接下来就可以上代码了:
三、如何判断一个数是否是2的次方数
其实对于这个题目可以使用题目二的第三种方法,也相当于是它的一种新的理解,废话少说,代码启动。
对于这个代码可以这样理解就是n为2的n次方数(为1000...)使用了算法就相当于把去除了一个1和0去比较,如果是0则是2的n次方,不是则不是。n& n-1 就是去掉二进制中的一个1,如果是2的n次方,其实二进制里面就一个1 .去掉自然是0。
如果使用题目二的那种方法(将count==1即可)则会感觉有点繁琐。
四、二进制位置0或置1
编写代码将13二进制序列的第5位修改为1,然后再改为0;
根据题目就可以得出一共有2步:
//13的二进制位为:00000000 00000000 00000000 00001101
//将第5位置为1后:00000000 00000000 00000000 00011101
//将第5位置为0后:00000000 00000000 00000000 00001101
第一步:
//13的二进制位为:00000000 00000000 00000000 00001101
//对1进行移位1<<4:00000000 00000000 00000000 00010000
//再对13进行按位或:00000000 00000000 00000000 00001101
// 得出: 00000000 00000000 00000000 00011101
第二步:
//对1进行移位1: 00000000 00000000 00000000 00010000
//再对1进行取反: 11111111 11111111 11111111 11101111
// 00000000 00000000 00000000 00011101
//将取反后的1与13进行按位与得出:
// 00000000 00000000 00000000 0000110
结合这两步可以写出代码:
五、求两个数二进制中不同位的个数
编程实现:两个int(32位)整数m和n的二进制表达中,有多少个位(bit)不同?
输入例子:
1999 2299
输出例子:7
首先来看一下代码:
先把a和b使用按位异或得出一个记录不同位的数,在使用算法把不同位求出来。
六、单身狗
在一个整型数组中,只有一个数字出现一次,其他数组都是成对出现的,请找出那个只出现一次的数字。例如:
数组中有:1 2 3 4 5 1 2 3 4,只有5出现一次,其他数字都出现2次,找出5
七、打印整数二进制的奇数位和偶数位
获取一个整数二进制序列中所有的偶数位和奇数位,分别打印出二进制序列
根据题目来说就相当于是把这个数的二进制一分为二,一个从0索引开始,到30索引结束,另一个从1索引开始,到31索引结束。再次期间使用按位或将这个数或1,从而得出最后区分奇数和偶数的值,
总结一下:
本博客讲述了一些关于操作符的题目,有的题目会有一些的复杂,所以在做这些题的时候可以多去敲一下,多多思考总结,就可以得出更好的理解。有的时候还是需要去看看一些厉害的代码的。下一篇就开始迈入指针的关卡了哦,加油。
如果觉得写的不错的话,记得来个三连哦。