我偶然发现了一段代码,在调试别人的程序时产生了一些有趣的结果。
我创建了一个小程序来说明这种行为:
#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++
时没有任何事情发生。
有人可以解释为什么会这样吗?
答案 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;或||连接的表达式从左到右评估,并且 一旦知道结果的真实性或虚假性,评估就会停止。“ 对这些有很好的理解,输出不会谜。