#include<stdio.h> int obMo(unsigned int n); //写一个函数求a的二进制中有几个1 //思路1:先写逻辑,我们用取模的方式,每当模2时,会得到一个1 缺点:如果我们输入-1时, //由于-1在计算机中以补码的形式存在 //原码 1000 0000 0000 0000 0000 0000 0000 0001 //反码 1111 1111 1111 1111 1111 1111 1111 1110 //补码 1111 1111 1111 1111 1111 1111 1111 1111 //即为32个1 //如何解决这个问题? //我们可以将其定义为无符号数unsign类型,即将其"符号位"定义为"数字位" int obYu(int n); //思路2:先写逻辑,我们之前学了用操作符<<,我们将二进制0000...0001与目标值二进制按位与进行循环比对,得出结果 int obwhile(int n); //思路3:先写思路,我们可以考虑 13的二进制为1101 ,n & (n -1) //如果让其减1 变为12的二进制为1100, 1101 & 1100 = 1100 // 在让其减1 变为11的二进制为1011, 1100 & 1011 = 1000 // 在让其减1 变为10的二进制为0111, 1000 & 0111 = 0000 //只要执行一次就去掉一个1 int main() { int n = 0; scanf("%d",&n); //int count = obMo(n);//思路1 //int count1 = obYu(n);//思路2 int count2 = obwhile(n); printf("%d",count2); //printf("%d\n",count); //printf("%d",count1); } int obwhile(int n) { int count = 0; while(n) { n = n & (n - 1); count++; } return count; } int obYu(int n) { int i; int count = 0; for (i = 0 ;i < 32;i++) { if (1 == ((n >> i) & 1)) //一开始自己的错误出现在1 == ((1 >> i) & n), // 这样就使得 // 1111...1111...1111 // 0000...0100...0000 // 得出结果0100...000不等于1而等于比1大的数,所以循环不会等于1 { count++; } } return count; } int obMo(unsigned int n) { int count = 0; while (n) { if (1 == n % 2) { count++; } n = n / 2; } return count; }