求一个数的二进制的位数
#include <stdarg.h>
#include <stdio.h>
int ripple(int n, ...)
{
int i, j, k;
va_list p;
k = 0;
j = 1;
va_start(p, n);
for (; j < n; ++j)
{
i = va_arg(p, int);
for (; i; i &= i - 1)
++k;
}
va_end(p);
return k;
}
int main(void)
{
printf("%d\n", ripple(3, 5, 7));
return 0;
}
答案为:
5
The va_arg
macro produces the arguments passed as the “...
” part of a variadic function. In
ripple
it will be called twice, setting i
first to 5, then to 7.
The expression i &= i - 1
resets the right-most 1 bit in
i
. For example, if i
is 6 (binary 110), i & i - 1
is 4 (binary 100). The inner
for
loop executes until i
is 0, so k
is increased by the number of 1 bits in
i
.
There are two 1 bits in 5 (binary 101) and three in 7 (binary 111), so
ripple
returns 5.
这道题也是两个知识点,一个是可变参数函数定义以及如何实现,va_arg会把5,7依次取出来。另一个知识点是i &= i-1,实际上是计算了i二进制形式中1的个数,每次计算都会消减掉最低有效位上的1。比如7二进制表示为111。i &= i –1的计算结果依次为110,100, 000 (也就是0)。在hacker's Delights这本书里介绍了很多类似技巧。