只是一个简单的问题;我一直在研究K& R,数字/空白/其他计数器的代码工作得很好。然而,在试图了解else
的功能时,我遇到了一些无法正常工作的事情。
本书的代码如下:
#include <stdio.h>
/* count digits, white space, others */
main()
{
int c, i, nwhite, nother;
int ndigit[10];
nwhite = nother = 0;
for (i = 0; i < 10; ++i)
ndigit[i] = 0;
while ((c = getchar()) != EOF)
if (c >= '0' && c <= '9')
++ndigit[c-'0'];
else if (c == ' ' || c == '\n' || c == '\t')
++nwhite;
else
++nother;
printf("digits =");
for (i = 0; i < 10; ++i)
printf(" %d", ndigit[i]);
printf(", white space = %d, other = %d\n", nwhite, nother);
}
如果我然后修改while
循环,则显示为:
while ((c = getchar()) != EOF)
if (c >= '0' && c <= '9')
++ndigit[c-'0'];
if (c == ' ' || c == '\n' || c == '\t')
++nwhite;
它应该仍然具有与原始代码相同的功能,除了它不会计算“其他”字符的事实。然而我实际得到的实际上只是'数字'部分工作,无论输入是什么,'nwhite'都返回零。我觉得这种差异可能是由于对if
陈述如何发挥作用的基本误解。
答案 0 :(得分:10)
while ((c = getchar()) != EOF)
if (c >= '0' && c <= '9')
++ndigit[c-'0'];
if (c == ' ' || c == '\n' || c == '\t')
++nwhite;
第二个if
语句不再出现在循环中。使用{
和}
括起循环语句。
答案 1 :(得分:2)
while ((c = getchar()) != EOF)
if (c >= '0' && c <= '9')
++ndigit[c-'0'];
if (c == ' ' || c == '\n' || c == '\t')
++nwhite;
相当于
while ((c = getchar()) != EOF) {
if (c >= '0' && c <= '9')
++ndigit[c-'0'];
}
if (c == ' ' || c == '\n' || c == '\t')
++nwhite;
只有循环或分支构造后面的第一个语句“属于”该构造。这就是为什么原来的if-else if-else链没有大括号的原因。每个语句链接到前一个语句,第一个if / else语句属于while循环,第二个if / else属于第一个if / else。以这种方式表达逻辑以避免不必要的缩进是惯用的。
使用大括号可视化代码
while ((c = getchar()) != EOF) {
if (c >= '0' && c <= '9') {
++ndigit[c-'0'];
}
else {
if (c == ' ' || c == '\n' || c == '\t') {
++nwhite;
}
else {
++nother;
}
}
}