C '的语法和不同含义&书信电报;信>';
我正在从K&R手册中学习C,我偶然发现了计算空白字符(空白、制表符、换行符)和所有其他字符出现次数的代码。C '的语法和不同含义&书信电报;信>';,c,arrays,C,Arrays,我正在从K&R手册中学习C,我偶然发现了计算空白字符(空白、制表符、换行符)和所有其他字符出现次数的代码。 代码如下所示: #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)
代码如下所示:
#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);
}
上面的陈述有什么作用?为什么不在这里取c的ASCII值?
因为如果我们这样做了,它应该被写成
['c'-'0']
1。
C是一个字符,不是整数。因此,我们需要将它们与ASCII值进行比较。整数0和9对应于Nul
和Tab
,而不是我们正在寻找的东西
二,。
通过减去ASCII值,与整数对应的索引将增加。例如,如果我们的号码是'1'
。然后'1'-'0'=1
因此增加了1处的索引,这是跟踪字符的方便方法。我们不放['c'-'0']
,因为我们关心的是变量c
而不是字符'c'
此表显示了字符的表示方式,它们不同于整数。主要外卖是'1'!=1
对于当前的C标准,这将是本地化广泛输入的完美练习: 在Linux、*BSD或Mac计算机上,您可以使用
gcc -std=c99 -Wall -Wextra -pedantic example.c -o example
printf 'Bengali decimal digit five is ৫.\n' | ./example
或
并使用例如
gcc -std=c99 -Wall -Wextra -pedantic example.c -o example
printf 'Bengali decimal digit five is ৫.\n' | ./example
哪个输出
Read 33 wide characters total.
25 letters
0 zeros (equivalent to '0')
0 ones (equivalent to '1')
0 twos (equivalent to '2')
0 threes (equivalent to '3')
0 fours (equivalent to '4')
1 fives (equivalent to '5')
0 sixes (equivalent to '6')
0 sevens (equivalent to '7')
0 eights (equivalent to '8')
0 nines (equivalent to '9')
6 whitespaces (including newlines and tabs)
1 punctuation characters
0 other printable characters
上述代码完全符合ISO C99(以及ISO C标准的更高版本),并且应该是完全可移植的
但是,请注意,并非所有C库都完全支持C99;人们对Microsoft C有意见的主要问题是。我自己不使用Windows,但如果您使用,请尝试使用UTF-8代码页(
chcp 65001
)。这完全是微软的问题,因为它显然可以通过一些非标准的Windows扩展支持UTF-8输入。他们只是不想让你写可移植的代码,似乎。我需要问两个问题。
第一个问题:我非常清楚“0”和“9”分别表示0和9的ASCII值。但我似乎不明白为什么我们甚至需要使用ASCII值而不是整数本身。比如为什么我们不能简单地使用
if (c >= 0 && c <= 9)
if (c >= 0 && c <= 9)
在任何分类问题中,通常都会使用一个初始化为全零的数组,该数组中至少有足够的元素(此处为字符集)。您可以将它们拆分为十个元素的数组,以容纳数字、大写字母、小写字母等
您的ndigit
数组开始初始化为全零,计划是在每次读取过程中遇到数字时增加数组中的适当元素。这是使用ASCII值作为数字底部的位置'0'
(48)。由于每次遇到一个数字时,ndigit
数组很可能被索引为0-9
,因此必须将它缩放(或映射)到ndigit
的正确索引中(这样'0'
被映射到0
,'1'
被映射到1
,等等)
上面通过您的测试,我们确定,在本例中,c持有一个数字,因此为了对该数字进行分类并将其映射到ndigit
数组的正确元素,我们使用c-'0'
。如果c
中的数字是'3'
(ASCII51
),则递增
++ndigit[c-'0'];
实际上是索引
++ndigit[51 - 48];
或
这样,当您完成时,ndigit
数组将保存在您的输入中找到的0、1、2、3、4、
位数的确切数字。您需要花一点时间来理解这个方案,但总而言之,您只需要从零开始计数,以存储每个字符、数字、标点符号、所见和a的总数为字符集调整大小的rray将在您完成时准确保存这些值,因为每个字符都已分类,并且相应的++ndigits[]
元素会随着您的操作而递增以捕获信息
在一般意义上,它们被称为频率数组,因为它们用于存储集合中单个成员出现的频率。除了简单地对字符进行分类之外,它们还有很多应用程序
请仔细查看所有答案,如果您仍然感到困惑,请告诉我,我非常乐意进一步提供帮助
getchar()
返回字符代码和哨兵值(EOF)。因此,我们知道c
在循环中保存字符代码c-'0'
是字符代码“数字行”上从c(字符代码)的值到“0”的代码的距离。根据c标准,字符代码必须具有连续顺序为“0”、“1”、“2”、“3”、“4”、“5”、“6”、“7”、“8”、“9”的数字。因此,表达式计算数字字符的整数值getchar
返回一个ASCII值,该值存储在变量c
中。请修复和的代码格式,而正文不带{}
正在为将来出现的讨厌的bug做好准备。将来,请采纳Stephen的建议。错误的代码格式和错误的标识将使您感到困惑,隐藏错误,使调试更加困难,并使其他有帮助的潜在提问者感到烦恼。我把blueCat的建议算在其中,跳过是捷径(当然不需要){}
实际上也是这样。“我正在从K&R的书中学习C”
。这让我很难过。给你这本书的人并没有帮你一个忙。请不要读这本70年代完全过时的书。特别是,不要采用他们可怕、危险、不可读的编码风格。
if (c >= 0 && c <= 9)
++ndigit[c-'0']
++ndigit[c-'0'];
++ndigit[51 - 48];
++ndigit[3]; /* since c was 3, we no increment ndigit[3] adding one more
occurrence of '3' to the data stored at ndigit[3] */