C 什么';这是代码的行为';s循环?
我知道它将在两次迭代后退出,但为什么?循环有一个从零开始的计数器(C 什么';这是代码的行为';s循环?,c,assembly,arm,C,Assembly,Arm,我知道它将在两次迭代后退出,但为什么?循环有一个从零开始的计数器(I)。当不满足停止条件时(即v不同于0`),它在中运行行 在每次迭代中,v接收v和v-1之间按位和(&)的结果 然后,在每次迭代结束时打印v的值 如果您在(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 四, i=1,v=4,v-
I
)。当不满足停止条件时(即v
不同于0`),它在中运行行
在每次迭代中,v
接收v
和v-1
之间按位和(&
)的结果
然后,在每次迭代结束时打印v
的值
如果您在(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
四,
i=1,v=4,v-1=3,v&(v-1)=0
0
你可以在网上试试
在第一次迭代中,v=5&(5-1)=5&(4)=4
。由于v!=0
,循环继续
在第二次迭代中,v=4&(4-1)=4&(3)=0
。由于v==0
,循环停止
正如我在评论中所说的,在较低的lewel中,“正在进行比较,可能是通过BNZ(分支如果不是零)ASM指令进行的。如果未设置零标志,则继续;否则,进行分支。您可以找到更详细的信息和信息。”您需要查看二进制表示,并记住&
是一个位智能and运算符:
int main()
{
int i;
int v = 5;
for (i = 0; v; i++)
{
v &= (v - 1);
printf("%d\n", v);
}
return 0;
}
当v变为false时,即0?添加更多的打印并自己解释调试器也是您的朋友。这里有机会在一个简单的示例中使用它,然后一直使用它。提示…5在二进制中是101,4在二进制中是100。因此5和4(按位和)is 4我知道你已经否决了几个似乎正确的答案。如果人们没有给你你想要的答案,你需要问一个不同的问题。嘿,Marcelo,谢谢,但你所解释的是c-Chibble的。我的问题不同。我知道代码会发生什么,否则会很愚蠢。问,我是concerned什么因素会使for循环停止?就像预处理器之后一样,c编译器中隐含的bool文件,例如gcc,当该代码闪现到某个ARM MCU时,它将如何在运行时结束循环?一些机器操作代码是这样做的,还是怎样做的?我不理解。你明确地问“为什么循环在两次迭代后退出”。我回答“因为在第二次迭代中满足停止条件”。这背后没有火箭科学,只是整数之间的比较。如果您需要更多详细信息,请编辑您的问题并提供必要的信息。正如您所说,“因为v==0,循环停止。”“是的,我确切的问题是“为什么会这样?”,哪个指令集会这样?或者更准确地说,这是在编译器端还是在机器指令集端完成的?有人能解释吗?嘿,“这背后没有火箭科学,只是整数之间的比较”…没有比较发生。只有“v”状态被监控。归零后,它会停止循环,所以我需要知道原因。对于问题的错误开始,我可能没有简要解释。@J循环控制的的三个部分中的第二部分计算为true
或false
。在C中,任何非0值都计算为true
,而0
的计算结果为false
。因此v
是true
,直到它具有值0
。表达式v
是显式v!=0
的隐式代码。嘿,谢谢,但我知道这一点。总之,v&(v-1)
清除最低的设置位。对于所有设置位,都有C表达式+英文描述,因此它实际上可以作为参考,即使您不关心它如何在x86上使用-mbmi
编译。哦,太好了。谢谢Peter。
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