隐秘的for循环更新语句

时间:2014-08-03 02:50:14

标签: c idioms

我的代码有以下循环:

for (i = A[x]; i < N; i = i | (i + 1))

for (i = A[x]; i >= 0; i = (i & (i + 1)) -1 )

我真的不明白这些更新语句。这些聪明的做事方式是否微不足道?

2 个答案:

答案 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)与30011)结果。

您拥有0011的第三次迭代(即值3),您或01004的值为3+1),导致{ {1}}(即值0111)。

它继续这样,将所有位从最低有效位设置为最多。