C程序有趣的行为

时间:2012-09-29 06:57:07

标签: c for-loop

我偶然发现了一段代码,在调试别人的程序时产生了一些有趣的结果。

我创建了一个小程序来说明这种行为:

#include <stdio.h>

int main()
{
        char* word = "foobar"; int i, iterator = 0;
        for (i = 0; i < 6; i++ && iterator++)
          printf("%c", word[iterator]);
        return 0;
}

我知道这不是打印字符串的正确方法。这仅用于演示目的。

在这里,我预计输出显然是“foobar”,而是“ffooba”。基本上它会两次读取第一个字符,就像第一次执行iterator++时没有任何事情发生。

有人可以解释为什么会这样吗?

4 个答案:

答案 0 :(得分:11)

事情是iterator++实际上第一次没有执行。 ++运算符返回变量的当前值,然后递增它,因此第一次i++将等于0&&短路,因此第一次不执行iterator++

要解决此问题,您可以使用逗号运算符无条件地评估两者,而不是短路&&

答案 1 :(得分:5)

i++的结果是i的当前值,在第一次迭代时为零。这意味着iterator++在第一次迭代时不会因为短暂的循环而执行(如果左侧是“真”,则&&的右侧仅执行

要解决此问题,您可以使用逗号运算符(如已建议的那样)或{)使用++i,这将在递增后返回i的值(尽管逗号运算符更明显,必须始终评估两者) )。

答案 2 :(得分:3)

你真的应该学会使用像这样的调试器。 gdb并编译警告和调试信息,如gcc -Wall -g(假设Linux系统)。最近的gcc -Wall会在&&操作之前向您发出有关计算值未使用的警告。

for循环的增量部分很奇怪。它是i++ && iterator++(但它应该是i++, iterator++)。

i为0时(在第一次迭代时),i++给出0作为结果,因此它为假,因此iterator++不会被执行。

答案 3 :(得分:2)

我正在阅读关于逻辑运算符的K&amp; R,让我引用本书的原始词,这可以解释你的问题。 “由&amp;&amp;或||连接的表达式从左到右评估,并且 一旦知道结果的真实性或虚假性,评估就会停止。“ 对这些有很好的理解,输出不会谜。