Ritchie 和 Kernighan 混淆的 C 程序

标签 c

我到处都读到,如果你从事计算机科学,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/

相关文章:

c - 如何使用 "cat > "将信息写入终端中的 sitin.txt 然后它会输出

c - 如何指向一个指针的指针

c - 在 Bison 出错后释放留在堆栈上的指针

c - 带 EOF 的额外循环

c++ - Waf:递归收集源文件并包含路径

c++ - 将正符号变量替换为无符号变量

c - 在 C 中打开文件

c - LED 8x8 的程序在 Arduino Uno 中不起作用。我没有使用 pinMode() 方法。我正在使用另一种方法进行规范

c - 给定函数标识符,是否有命令行程序或库函数提供存储在 elf 文件中的地址

c - 如何从函数返回地址并在 main 中收集?