我正在使用Classic K& R Book“The C Programming Language”,第二版。
我在第24页的练习中遇到了关于阵列的问题。
练习说(从PDF复制并粘贴):
#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);
}
在这种情况下,书中说运行程序后输出如下。
此时这本书令人困惑,因为它并没有说出打字的人......
该程序本身的输出是数字= 9 3 0 0 0 0 0 0 0 1, 空格= 123,其他= 345
好的,现在我将把我复制的代码放在书中
这是我从Eclipse中复制并粘贴的练习:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
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(" After ");
printf(" Var c %d \n", c);
printf(" Var i %d \n", i);
printf(" Var nwhite %d \n", nwhite);
printf(" Var nother %d \n", nother);
printf(" Digits are = ");
for (i = 0; i < 10; ++i)
printf(" %d ", ndigit[i]);
return EXIT_SUCCESS;
}
当我运行它并键入以下内容时:
abc def ghi jkl 123
我获得了这个输出:
Var c -1 Var i 10 Var nwhite 4 Var nother 13 数字= 0 1 1 1 0 0 0 0 0 0
我的代码只与最后一行中的原始代码不同,因为我使用此printf来查看变量的值。
我重命名/ || c =='\ n' /因为不想把它算作nwhite。
其余的我认为这是相同的,似乎工作得很好,就像书的例子。
为什么他们告诉我的例子的价值?
我的问题是我不理解这个输出方式或者它与我输入的信息有关:
输入:abc def ghi jkl 123
输出:位数= 0 1 1 1 0 0 0 0 0 0
我很感激有关这一点的任何解释,这本书对我来说并不清楚,并且不太明白这些价值观正在显示。
解决我的怀疑。
Firts
首先,我要感谢大家对这个问题的帮助(本书的链接),我认为这是在公共领域。我会考虑将来考虑这一点。
非常感谢:WhozCraig和Amir的宝贵意见,感谢他们终于能够理解这次演习。
当然,为了确保我理解下一步是执行附加的验证,以帮助未来的读者澄清这篇文章:
验证我明白我做了以下测试:
在这个新案例中,我们将介绍以下系列;
ab cd ef gh 1234136
After Var c -1
Var i 10
Var nwhite 4
Var nother 9
Digits = 0 2 1 2 1 0 1 0 0 0
确实是0,现在有2个(1个)(2个)2个(三个)1个(4个),我故意省略了5个检查0(五个是OK),最后是1个(六个), 7,8和9的下一个是empy。
多数民众赞成是!!!
答案 0 :(得分:2)
分析输出:
After Var c -1 Var i 10 Var nwhite 4 Var nother 13 Digits are =0 1 1 1 0 0 0 0 0 0
c -1
:您已完成阅读循环,c
等同于EOF,在您的平台上为-1
。i 10
:当for (i = 0; i < 10; ++i)
不再为真时,循环i < 10
就会中断。最后一次触摸的是最终增量++i
,导致i
成为10
,此后一直没有被触及。nwhite 4
:您输入的字符序列中有四个空格非换行(因为您已将其删除)字符:abc def ghi jkl 123
nother 13
:根据您的修改,换行计为“其他”字符,数字不是。因此,abcdefghijkl\n
是促成这种积累的十三个价值。留下最后一项:
Digits are =0 1 1 1 0 0 0 0 0 0
当您浏览输入数据循环时,遇到数字字符('0'..'9'
)时,其ASCII值(或者,如果您在iSeries或zSeries上运行其EBCDIC值),则减去char '0'
的值,为10个整数的数组创建一个从零开始的索引。这是有效的,因为标准要求数字字符的每个代码点都是顺序和连续,所有平台(包括EBCDIC)都要遵守这一点。数组中该索引处的计数器随着相应数字char的每次遇到而递增。完成后,生成的数组内容将转储到stdout。您有'1'
,'2'
和'3'
各一位数。数组中的第一个插槽用于'0'
,下一个用于'1'
等。0 1 1 1 ...
表示零,一,二,三等的数量。
有关ASCII值see this table的更多信息。如果倾向于看到与EBCDIC的差异see this table,并注意在两者中,尽管实际数值不同,但完整序列'0'..'9'
是连续的。
希望有所帮助。好的问题,顺便说一句。特别是你的第一篇文章。
答案 1 :(得分:1)
我现在正在读这本书,这就是我对此的理解。
您获得的输出是正确的:
c = -1
因为,当(c = getchar())
到达EOF
时,while循环退出(知道EOF等于-1),并记住你正在{{{}存储getchar() 1}}在与c
比较之前,因为括号具有更高的优先级。因此,条件为:c = EOF,然后将getchar()与EOF进行比较并退出while循环
EOF
,因为您使用for循环进行循环,当i = 10
达到10时,它应该停止。因此,i
中的最后一个值存储为10。
i
意味着,你有
0 1 1 1 0 0 0 0 0 0
PS:这本书很棒!!