目录
练习1: 写一个函数返回参数二进制中1的个数
方法1:使用位移操作符
>>使我们能够将补码向右移动i位
m>>i 并不会使m的值改变
int count_bit(int m)
{
int i = 0;
int count = 0;
for (i = 0; i < 32; i++)
{
if (1 == ((m >> i) & 1))//m向右移动i位,m本身不发生变化
{
count++;
}
}
return count;
}
方法2:使用%
如果输入进来是-1
他的补码是 11111111111111111111111111111111
在这里我们需要使用无符号数 unsigned int,这样我们在内存里看到的补码就是他的源码
为什么使用%:
10进制 1234%10=4
2进制 15%2=7...1
15/2=7
7%2=3...1
...得到4个为1的余数
int count_bit(unsigned int m)
//如果输入进来是-1,11111111111111111111111111111111
//无符号数,我们在内存里看到的补码就是他的源码
{
//10进制 1234%10=4
//2进制 15%2=7...1
//15/2=7
//7%2=3...1
//...得到4个1 余数
int count = 0;
while (m)
{
if (m % 2 == 1)
{
count++;
}
m /= 2;
}
return count;
}
方法3:使用位移操作符
方法1和3本质相似,使用相同的操作符
方法3循环32次,每次都要改变m的值,每次向右移动1位
方法2循环32次,每次不改变m的值,每次向右移动 i 位
int count_bit(int m)
{
int i = 0;
int count = 0;
for (i = 0; i < 32; i++)
{
if (m & 1 == 1)
count++;
m >>= 1; //m=m>>1
}
}
方法4:使用按位与操作符
int count_bit(int m)
{
int count = 0;
while (m)
{
m = m & (m - 1);
count++;
}
return count;
}
//n=11
//n=n&(n-1)
//1011-n
//1010 n-1
//1010 n
//1001 n-1
//1000 n
//0111 n-1
//0000 n
主函数:
int main()
{
int n = 0;
scanf("%d", &n);
int num = count_bit(n);
printf("%d\n", num);
return 0;
}
练习2:求两个数二进制中不同位的个数
方法一:按位异或
异或的特点是相同为0,不同为1
然后使用练习1的方式去数1的个数
#include<stdio.h>
int count_diff_bit(int m, int n)
{
int ret = m ^ n;
//异或的特点是相同为0,不同为1
int count = 0;
while (ret)
{
ret = ret & (ret - 1);
count++;
}
return count;
}
//0111
//1010
//1101
//有3个1说明3个不同
int main()
{
int m = 0;
int n = 0;
scanf("%d %d", &m, &n);
int i = 0;
int count = 0;
count = count_diff_bit(m, n);
printf("%d\n", count);
return 0;
}
方法二:和1按位与
#include<stdio.h>
int main()
{
int m = 0;
int n = 0;
scanf("%d %d", &m, &n);
int i = 0;
int count = 0;
for (i = 0; i < 32; i++)
{
if (((m >> i) & 1) != ((n >> i) & 1))
{
count++;
}
}
printf("%d\n", count);
return 0;
}
练习3: 交换两个变量(不创建临时变量)
#include<stdio.h>
int main()
{
int a = 0;
int b = 0;
scanf("%d %d", &a, &b);
a = a ^ b;
b = a ^ b;
a = a ^ b;
printf("%d %d\n", a, b);
return 0;
}