如果将每个单元存储为设置位,则该程序应该确定变量c_val
的值中存储了多少单位。
我的问题是:作者为什么写if (c % 2 == 1) count++;
然后将c
移到右边,使用此语句c = c >> 1;
?
#include <stdio.h>
#include <cstdlib>
int main(){
unsigned char c_val;
printf("char value = ");
scanf("%c", &c_val);
int count = 0;
unsigned char c = c_val;
while(c){
if (c % 2 == 1) count++;
c = c >> 1;
}
printf("%d bits are set", count);
system("pause");
}
答案 0 :(得分:6)
char类型的数据大小总是一个字节 - 没有例外。但是,此代码会在c_val
中计算popcount - 即1位数。
我们可以翻译
中的相关代码while (c) {
if (c % 2 == 1) count++;
c = c >> 1;
}
到
while (c != 0) {
if (c & 0x1 == 1) count++; /* if the rightmost bit of c is 1, then count++ */
c = c / 2;
}
我做的最后一次更改是有效的,因为右移无符号整数数据类型(在这种情况下,unsigned char
)相当于除以2,具有向零舍入的语义。
我们可以将c
视为比特的传送带 - 从左边进入零比特,在每次循环迭代时有一个比特从右边下降。如果最右边的位是1,我们将计数增加1,否则计数保持不变。因此,一旦c
填充零位,我们就知道我们已经计算了所有的一位,恰好是一位,所以count
包含c_val
中的一位数。
答案 1 :(得分:3)
这不是确定char
类型实例的“大小”的函数,而是确定字符中设置为1的位数。
表达式
c % 2 == 1
确定最低有效位是否为1。
移位使倒数第二位进入最后位置,以便进行测试。
条件while (c)
表示继续计数1并移位直到整个字节都为零。
答案 2 :(得分:2)
您的代码只是编码char c中的多少1位。 “c%2 === 1”检查“c”中的最后一位是否为1.所以我们必须使用“c = c&gt;&gt; 1”将“c”中的其他位移到最后一位。 / p>
答案 3 :(得分:0)
其他方式:
#include <stdio.h>
#include <conio.h>
unsigned int f (unsigned int a , unsigned int b);
unsigned int f (unsigned int a , unsigned int b)
{
return a ? f ( (a&b) << 1, a ^b) : b;
}
int bitcount(int n) {
int tot = 0;
int i;
for (i = 1; i <= n; i = i<<1)
if (n & i)
++tot;
return tot;
}
int bitcount_sparse_ones(int n) {
int tot = 0;
while (n) {
++tot;
n &= n - 1;
}
return tot;
}
int main()
{
int a = 12;
int b = 18;
int c = f(a,b);
printf("Sum = %d\n", c);
int CountA = bitcount(a);
int CountB = bitcount(b);
int CntA = bitcount_sparse_ones(a);
int CntB = bitcount_sparse_ones(b);
printf("CountA = %d and CountB = %d\n", CountA, CountB);
printf("CntA = %d and CntB = %d\n", CntA, CntB);
getch();
return 0;
}