这段代码循环的行为是什么?

时间:2016-11-03 18:49:10

标签: c assembly arm

int main() 
{
    int i;
    int v = 5;
    for (i = 0; v; i++)
    {
        v &= (v - 1);
        printf("%d\n", v);
    }
    return 0;
}

我知道它会在两次迭代后退出,但为什么呢?

2 个答案:

答案 0 :(得分:4)

你需要查看二进制表示,并记住&是一个按位运算符:

v = 5 = 101b
// First loop
v = 5 & (5-1) = 5 & 4 = 101b & 100b = 100b = 4
// Second loop
v = 4 & (4-1) = 4 & 3 = 100b & 011b = 000b = 0
// No more loops

答案 1 :(得分:2)

循环有一个从零开始的计数器(i)。它在内部运行行,而不满足停止条件(即,vdifferent than 0`)。

在每次迭代中,v都会在AND&之间收到按位vv-1)的结果。

然后,在每次迭代结束时打印v的值。

如果您在for (i = 0; v; i++) {之后添加以下语句,您将能够看到每次迭代中的操作:

printf("i=%d, v=%d, v-1=%d, v & (v-1) = %d\n", i, v, v-1, v & (v - 1));

输出:

  

i = 0,v = 5,v-1 = 4,v& (v-1)= 4

     

4

     

i = 1,v = 4,v-1 = 3,v& (v-1)= 0

     

0

您可以在线试用here

在第一次迭代中,v = 5 & (5 - 1) = 5 & (4) = 4。从v != 0开始,循环继续。

在第二次迭代中,v = 4 & (4 - 1) = 4 & (3) = 0。自v == 0以来,循环停止。

正如我在评论中所述,在一个较低的层次中,“正在进行比较,可能是通过BNZ(分支,如果不是零)ASM指令。如果没有设置零标志,则继续; ELSE,分支。您可以找到更详细的信息herehere。“