为什么我们需要" - ' 0'"修改数组?

时间:2015-10-25 10:47:38

标签: c

这是来自C by Dennis Ritchie的代码,第34章"数组":

#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);
}

为什么我们在这一行需要-'0'

++ndigit[c-'0'];

如果我将其更改为++ndigit[c],则该程序无法正常运行。为什么我们不能写++ndigit[c]

我已经阅读了这本书的解释,但我不明白。

  

这仅适用于&#39; 0&#39; 1&#39; 1&#39;,...,&#39; 9&#39;有连续增加的价值。幸运的是,对于所有字符集都是如此。根据定义,字符只是小整数,因此char变量和常量与算术表达式中的int相同。这很自然方便;例如c - &#39; 0&#39;是一个整数表达式,其值介于0和9之间,对应于字符&#39; 0&#39;到&#39; 9&#39;存储在c中,因此是数组ndigit的有效下标

2 个答案:

答案 0 :(得分:4)

理解为什么我们需要“-'0”你首先需要理解ASCII表 - http://www.asciitable.com/

现在您需要了解C中的每个字符都由0到127之间的数字表示(扩展为255)。

例如,如果你打印字符'0'作为他的数值:

printf( "%d", '0' );

  

输出:48

现在您已声明了一个大小为10的数组 - ndigit[ 10 ],其中n单元格表示数字n作为输入的次数。

因此,如果您收到“0”作为输入,则需要执行ndigit[ 0 ]++,因此您需要将char转换为整数。你可以通过减去48(='0')

来做到这一点

这就是我们使用第++ndigit[c-'0'];

的原因

如果c ='5',我们将得到

++ndigit['5' - '0']

++ndigit[ 53 - 48 ]

++ndigit[ 5 ]

完全像我们想要的那样

答案 1 :(得分:3)

c = getchar()会将读取的字符代码存储到c,它与字符所代表的整数不同。

引自N1256 5.2.1字符集

  

。在源和执行基本字符集中,   上述小数位数列表中0后的每个字符的值应大于1   以前的价值。

如图所示,十进制数字的字符代码是连续的,因此您可以将十进制数字的字符代码转换为字符代表的整数,方法是减去'0' 0' s字符代码,来自字符代码。

总之,c-'0'产生c中的字符所代表的整数。