下面的 for 循环有什么作用?程序什么时候跳出循环?
for (c = 0; n; c++) {
/* . . . */
}
这是关于 SO 的这个答案中的这种 for 循环的示例。
循环将在n
变为时中断0
(换句话说,循环不会在n
变为时停止0
)。这可能发生在循环内(循环体设置n
为0
最终),也可能由于某些外部事件而发生。外部事件的示例是共享内存更新或信号处理程序的修改。变量的c
增量与循环进入循环体的次数一样多for
。c
变量初始化0
为。
从技术上讲,您的代码片段不是问题标题和帖子已被修改。for
循环,而只是for
循环语句的控制结构。片段缺少循环体。但这没关系,因为您的问题标题是关于“这个for
循环结构”的。
您在不同的答案中链接到一个函数,但您似乎已经明白该函数的目的是计算一个数字中设置的位数。
编辑:这个答案是对错误给出的链接问题中的按位运算的解释。它仍然解释了最后的终止。
链接代码如下:
long count_bits(long n) {
unsigned int c; // c accumulates the total bits set in v
for (c = 0; n; c++)
n &= n - 1; // clear the least significant bit set
return c;
}
这里有趣的一行是n &= n - 1;
. 这设置n
为n & (n - 1)
,其中&
是按位与运算符。该示例说它清除了最低有效位,即将最低单位位设置为 0,这正是它所做的,这就是原因。
想象一下这个例子,我们有数字,例如:
01010100
如果我们递减(取 1),我们得到:
01010011
***
每次我们递减最低位时,都会删除最低位,并且下面的位变为 1。这就是减法的工作原理,它相当于十进制的 1000 - 1 = 999,但使用两位而不是十位。
现在当我们和他们在一起时:
01010100
&01010011
=01010000
***
如果两个输入的位都是 1,则按位 & 仅将一个位设置为 1。
因此,正如您所看到的,该操作总是删除最低设置位,因为在减法后最低位变为 0,而在减法之前,以下位为 0:所有这些位在 & 操作中都没有两个数字 1,因此评估为 0 . 所有其他设置位都不变,所以给两个 1 进行操作并保持它们的值。
当条件n
为假时循环终止,即当n
是0
(所有位都被删除,值00000000
)。所以这是在删除每个位之后,并c
留下 中的位数的值n
。
请记住,在 C 中,当数字形式为非零时,布尔值被认为是“真”,而当数字为零时,布尔值被认为是“假”。
for
C 标准规定子句中的“中间事物”是一个表达式。只要该表达式的计算结果为非零,循环就会继续。n
一个将导致循环终止的表达式也是n
零。更明确的形式是
for (c = 0; n != 0; c++)
任何体面的编译器都会编译成相同的代码。
事实上,作为一种特殊情况,C 标准允许“中间事物”为空,在这种情况下,它被认为是true。这就是为什么我们可以将无限循环写成
for (;;) { ... }
而不是丑陋至极的可憎之物while(1)
。
简单来说,它相当于for( c = 0; n != 0; c++)
呵呵..
[案例 1] - 没有循环的迭代
int c, n = &c;
for (c = 0; n; c++) {
/* . . . */
}
[案例 2] - 没有循环的迭代
int c, n = 0;
for (c = 0; n; c++) {
/* . . . */
}
[案例 3] - 无限循环的迭代
int c, n = ...; // any value, except 0
for (c = 0; n; c++) {
/* . . . */
}
还有其他情况吗?
附言。当然是开玩笑。。