我到处都读到,如果你从事计算机科学,C 是大学毕业前必须掌握的语言。我拿起了教授推荐的《里奇和克尼汉》第二版。我对这个程序是如何工作的感到很困惑。如果有人能解释一下那就太好了!该程序计算每个数字、空格和其他字符的出现次数。我为我已经理解的事情写了评论,并在我不明白它是如何工作的地方添加了问题。
#include <stdio.h>
int main()
{
int c, i, nwhite, mother; //Declaring variables
int ndigit[10]; //Declaring an array that holds indexes from 0-9
nwhite = nother = 0; //Initializes two variables to 0
for (i = 0; i < 10; ++i) //Does this for loop keep going through and for each index
ndigit[i] = 0; //0-9 set the value of it to 0?
white ((c = getchar()) !=EOF) //While loop to check if char at EOF
{
if (c>='0' && c <= '9') //Completely lost on how this works?
++ndigit[c - '0'];
else if (c == ' ' || c == '\n' || c == '\t') //Checks for white space
++nwhite;
else //If nothing else increment char variable
++nother;
printf("digits "); //First for loop traverses and prints each value of
for (i=0; i<10; ++i) //the index. The next printf prints white space and
printf(" %d", ndigit[i]); //other characters
printf(", white space = %d, other = other = %d\n", nwhite, nother);
}
最佳答案
int ndigit[10]; //Declaring an array that holds indexes from 0-9
for (i = 0; i < 10; ++i) //Does this for loop keep going through and for each index
在 C 中,数组的索引是从 0 开始的,因此在这种情况下,ndigit
的有效索引是 0 到 9(含)。 for 循环从 i = 0
开始并将 i
递增一个 ( ++i
) 只要 i < 10
,因此循环体将针对 i
的值从 0 到 9 执行,包括 0 和 9。
在这个程序中,留给读者去弄清楚这两个 10
字面值是同一个东西;可以说,将 #define
设为常量并在两个地方都使用它会更好(但在这种情况下,它可能会被原谅,因为小数位数为 10 常量)。
while ((c = getchar()) !=EOF) //While loop to check if char at EOF
getchar
返回从标准输入读取的一个字符,或 EOF
(其值不同于任何 char
)如果标准输入位于文件末尾。没有 EOF
字符表示这种情况。
if (c>='0' && c <= '9') //Completely lost on how this works?
十进制数字 0 到 9 的字符值在 ASCII 和大多数其他字符集中是连续的,因此此代码利用了这一点并检查 c
是否等于或大于 '0'
和 (&&
) 也等于或小于 '9'
。换句话说,这会检查 c
是否在 '0'
和 '9'
之间(含)。 '0'
和 '9'
是字 rune 字,它们具有字符集中相应字符的整数值——这样程序员就不必知道并写入它们的值 if (c>=48 && c<=57)
,只要数字字符连续,代码就可以处理不兼容的字符集值(value)观。
++ndigit[c - '0'];
这会计算每个数字出现的次数。同样,由于表示数字的字符是连续的,因此从读取的字符中减去第一个数字 ('0'
) 的值会导致相应字符的值从 0 到 9,这也是数组 ndigit
的有效索引,如上所述.当然,这个减法只适用于数字字符,这就是前面的 if
检查它的原因。
例如,在 ASCII 中 '0'
的值为 48,'1'
为 49,等等。因此,如果 c
为 '1'
,则减去 c - '0'
的结果为 '1'-'0'
,即 49-48,或 1
++
运算符递增 ndigit
数组相应索引中的值。 (第一个 for
循环将 ndigit
中的初始值设置为零。)
关于Ritchie 和 Kernighan 混淆的 C 程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21959168/