![](/img/trans.png)
[英]Original C hello, world program from Kernighan and Ritchie not compiling
[英]C program confusing from Ritchie and Kernighan
我到处都读到,如果您是计算机科学专业的学生,那么在大学毕业之前,C是必不可少的语言。 我已经拿到了我的教授推荐的Ritchie and Kernighan第二版。 我对该程序的工作方式感到困惑。 如果有人可以解释,那就太好了! 该程序计算每个数字,空格和其他字符的出现次数。 我为已经了解的事情写了评论,并且在不了解它如何工作的地方添加了问题。
#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);
}
是的,这会遍历整个ndigit数组并将每个元素设置为0。
for (i = 0; i < 10; ++i)
ndigit[i] = 0;
这里:
if (c>='0' && c <= '9')
++ndigit[c - '0'];
条件(上如果直插式)可能是最困难的事情理解:
像这样成像:
if( A and B)
...
有:
A = c>'0'
和
B = c<= '9'
也就是说,如果c
在0到9之间(包括)。
希望这可以帮助。
(c >= '0' && c <= '9') //Completely lost on how this works?
C语言中的char
类型只是一个8位整数,通常是带符号的。 字符(如1
和9
与整数(如63)之间的对应关系由ASCII码定义。 如果c
是数字,则上面截断的代码的值为1。 用C写'1'
等效于写49
。
声明的整数数组的类型为auto,在C自动存储类中,整数数组将具有垃圾值。 因此,这些分配为零。
for (i = 0; i < 10; ++i)
ndigit[i] = 0;
对于if语句,您正在检查给定字符是否在0-9之间。 由于其getchar()-(获取字符),因此将值与单引号进行比较
if (c>='0' && c <= '9')
您也可以将此语句更改为
if (c>=48 && c <= 57)
由于ASCII 字符 “ 0”为48,而“ 9”为57
++ndigit[c - '0'];
您要对输入到数组中的数字进行计数,即假设输入为5,则将索引5处的数组计数增加1。
这里提到c-'0'
是因为,如上所述,'5'的ASCII字符为53。因此,以上语句的结果为c-'0'
= 5 (数组的索引5)
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(含0和9)。 for循环开始从i = 0
和增量i
被一个( ++i
),只要i < 10
,所以循环体获取的值来执行i
从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'
。 '0'
和'9'
是字符文字,具有字符集中相应字符的整数值–这样, if (c>=48 && c<=57)
,程序员不必知道并写入它们的值。该代码适用于不兼容的字符集,只要数字字符具有连续的值即可。
++ndigit[c - '0'];
这将计算每个数字出现的次数。 同样,由于代表数字的字符是连续的,因此从读取的字符中减去第一个数字的值( '0'
)得出对应字符的值0到9,这也是数组ndigit
的有效索引,如以上讨论。 当然,该减法仅适用于数字字符,这就是前面的if
对此进行检查的原因。
例如,在ASCII中, '0'
值为48, '1'
为49,依此类推。因此,如果c
为'1'
,则减法c - '0'
为'1'-'0'
,即,49-48或1。
++
运算符增加ndigit
数组的相应索引中的ndigit
。 (第一个for
循环将ndigit
的初始值设置为零。)
EOF
End-of-file
的缩写-是在stdio.h
头文件中定义的宏。 宏是已命名的代码片段。 无论在何处使用该名称,该名称都将替换为宏的内容。 它是一个值,表示当无法从源中读取更多字符时的条件,在这种情况下,该源为stdin
标准输入流,通常是键盘。 简而言之,对于任何字符c
,条件ch == EOF
始终为false。 因此,在您通过* nix系统上的Ctrl+D
和Windows系统上的Ctrl+Z
发出EOF
信号之前,以下条件将一直从stdin
读取:
white((c = getchar()) != EOF) {
}
接下来,此条件检查读取的字符c
是否为数字字符,即十进制数字。
if(c>='0' && c <= '9') { // check if c is a numeric character.
}
C
中的字符实际上是整数值(认为它们是1-byte
整数),并且等于相应字符的ASCII码(尽管C标准没有强制要求)。 在ASCII中,字符0
到9
的代码值按升序排列。 因此,如果满足上述条件,则意味着c
是数字字符。
++ndigit[c - '0'];
在上面的语句中, c - '0'
是转换为整数值的数字字符。 因此,如果c
的值为'8'
,则c - '0'
计算结果为8
。 接下来,它在索引为8
的数组ndigit
中获取值,该值保留数字8
计数,并将其递增1
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.