我的代码有以下循环:
for (i = A[x]; i < N; i = i | (i + 1))
和
for (i = A[x]; i >= 0; i = (i & (i + 1)) -1 )
我真的不明白这些更新语句。这些聪明的做事方式是否微不足道?
答案 0 :(得分:6)
当代码让您感到困惑时,请对其进行试验。
$ cat test.c
#include <stdio.h>
int main(void)
{
for (unsigned int i = 0; i < 256; i = i | (i + 1))
printf(" %04x", i);
putchar('\n');
return 0;
}
$ gcc -std=c99 test.c
$ ./a.out
0000 0001 0003 0007 000f 001f 003f 007f 00ff
所以第一个让你感到困惑的表达式(i = i | (i + 1)
)正在从底部位向上构造连续的位掩码。
您可以使用相同的技术来确定第二个表达式的作用。
答案 1 :(得分:2)
对于第一个,让我们检查i
最初为零时的作用:
第一次迭代i
为零,二进制0000
。然后你来到更新表达式,它在零和零加一:0000 | 0001
之间进行按位OR,得到值1
。
第二次迭代我们0001
并使用2
(二进制0010
)与3
(0011
)结果。
您拥有0011
的第三次迭代(即值3
),您或0100
(4
的值为3+1
),导致{ {1}}(即值0111
)。
它继续这样,将所有位从最低有效位设置为最多。