mil*_*des 13 c increment postfix-operator
我不明白为什么下面的代码没有按预期工作:
#include <stdio.h>
int main() {
int i = 0, size = 9, oneOrZero[] = {1,1,1,1,1,1,1,1,0};
while (i < size && oneOrZero[i++]);
if (i == size) printf("All ones"); else printf("Has a zero");
}
Run Code Online (Sandbox Code Playgroud)
Terminal: All ones.
Run Code Online (Sandbox Code Playgroud)
当增加循环内的索引时,代码按预期运行:
#include <stdio.h>
int main() {
int i = 0, size = 9, oneOrZero[] = {1,1,1,1,1,1,1,1,0};
while (i < size && oneOrZero[i]) {i++;}
if (i == size) printf("All ones"); else printf("Has a zero");
}
Run Code Online (Sandbox Code Playgroud)
Terminal: Has a zero.
Run Code Online (Sandbox Code Playgroud)
有人可以解释这两者之间的区别吗?
ana*_*ciu 17
在第一个代码中, when iis 8,oneOrZero[i]将计算为false因为oneOrZero[8] == 0,但无论如何i都会增加到9,增量不依赖于表达式的真实性,它会随着表达式的计算而发生多次。
所以很自然地,当i == size被评估时它是9 == 9,这当然是true,因此"All ones"会打印出来给你错误的输出。
在第二个代码i在条件表达式的主体内递增,这意味着它只会在满足条件时递增,因此 when iis 8,oneOrZero[i]将评估为false并且i不递增,保留其8值。
在下一行语句i == size将是8 == 9which isfalse并且"Has a zero"将被打印,为您提供正确的输出。
当一个迭代索引i也用于检查(与 比较size)时,这是一个典型的逐一错误。不用担心,几乎每个人都会遇到这种情况。
问题在于,即使条件失败,我们已经改变了,结果(i中)oneOrZero[i++]。我们的第二个变体不会落入这个陷阱,因为条件和索引增量是解耦的。
我们可以用一个更简单的例子来复制这种行为:
#include <stdio.h>
int main() {
int i = 0, size = 1, oneOrZero[] = {0};
while (i < size && oneOrZero[i++]);
if (i == size) printf("All ones"); else printf("Has a zero");
}
Run Code Online (Sandbox Code Playgroud)
现在,让我们手动检查条件:
i < size 很好,所以我们继续评估右侧。i++ 增量 i至1(又名size)oneOrZero[0]是0,因此条件失败在这个单次迭代之后i == size,我们打印All ones。
将此与其他变体进行比较:
int main() {
int i = 0, size = 1, oneOrZero[] = {0};
while (i < size && oneOrZero[i]) {i++;}
if (i == size) printf("All ones"); else printf("Has a zero");
}
Run Code Online (Sandbox Code Playgroud)
再次,我们检查条件:
i < size 很好oneOrZero[0] == 0,所以我们停下来。i 永远不会增加因此i < size,我们打印Has a zero.
请注意,可以将条件更改为
int i = -1;
while(++i < size && oneOrZero[i]);
Run Code Online (Sandbox Code Playgroud)
但这需要仔细的文档。