#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
void count1(int n) {
int count = 0;
while (n) {
count += n & 1;
n >>= 1;
}
printf("%d", count);
}
int main() {
int n;
scanf("%d", &n);
count1(n);
return 0;
}
但是你应该知道,while(n)这个循环条件对负数是无效的
他右移是补1,而不是补0,这导致循环不会正常结束
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
void count1(unsigned int n) {
int count = 0;
while (n) {
count += n & 1; // 检查 n 的最低位是否为 1
n >>= 1; // 右移 n,去掉最低位
}
printf("%d\n", count); // 打印 1 的个数
}
int main() {
int n;
printf("请输入一个整数: ");
scanf("%d", &n); // 从标准输入读取一个整数
count1((unsigned int)n); // 将 n 转换为无符号整数并传递给 count1
return 0; // 返回 0,表示程序正常结束
}
//位运算符是聪明的,他知道怎么处理负数
//当你将一个负数强制转换为无符号整数时,其二进制表示(即补码)并不会改变,改变的是编译器对他的解释方式
解释方式的变化
- 负数的解释:在补码表示中,
11111111 11111111 11111111 11111111
被解释为-1
。这是因为最高位(符号位)为1
,表示这是一个负数 - 无符号整数的解释:当你将其转换为
unsigned int
时,计算机不再考虑符号位,而是将所有位都视为有效的数值位。因此,11111111 11111111 11111111 11111111
被解释为4294967295
所以,在这里,强制转换后,右移运算符是在前面补0,而不是补1,这就可以让循环正常结束了
Comments NOTHING