C中数字字符的数字值

时间:2010-09-05 20:56:08

标签: c primitive-types

我刚刚开始阅读The C Programming Language并且我无法理解其中的一部分。以下是第24页的摘录:

#include<stdio.h>

/*countdigits,whitespace,others*/

main()
{
  intc,i,nwhite,nother;
  intndigit[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']; //THIS IS THE LINE I AM WONDERING ABOUT
      else if(c==''||c=='\n'||c=='\t')
          ++nwhite;
      else
          ++nother;

  printf("digits=");
  for(i=0;i<10;++i)
      printf("%d",ndigit[i]);
  printf(",whitespace=%d,other=%d\n",
      nwhite,nother);
}
     

此程序的输出本身就是

digits=9300000001,whitespace=123,other=345
     

声明

intndigit[10];
     

将ndigit声明为10个整数的数组。数组下标总是从C开始为零,因此元素是

ndigit[0], ndigit[ 1], ..., ndigit[9]
     

这反映在初始化和打印数组的for循环中。下标可以是任何整数表达式,包括整数变量,如i和整数常量。此特定程序依赖于数字的字符表示的属性。例如,测试

if(c>='0'&&c<='9')
     

确定c中的字符是否为数字。如果是,则该数字的数值为

c-'0'`
     

仅当'0','1',...,'9'具有连续增加的值时才有效。幸运的是,对于所有字符集都是如此。根据定义,字符只是小整数,因此char变量和常量与算术表达式中的int相同。这很自然方便;例如

c-'0'
     

是一个整数表达式,其值介于0和9之间,对应于存储在c中的字符“0”到“9”,因此是数组ndigit的有效下标。

我无法理解的部分是-'0'部分在表达式c-'0'中是必要的原因。如果一个字符是作者所说的小整数,并且数字字符对应于它们的数值,则-'0'做什么?

5 个答案:

答案 0 :(得分:7)

数字字符与其数字值不对应。它们对应于它们的编码值(在本例中为ASCII)。

IIRC,ascii'0'是值48.而且,幸运的是,对于此示例和大多数字符集,“0”到“9”的值按字符集顺序存储。

因此,从任何ASCII数字中减去“0”的ASCII值会返回其“0”的“真实”值。

答案 1 :(得分:3)

字符的数值是(在大多数系统上)其ASCII值。 ASCII值“0”为48,“1”为49,等等。

通过从字符'0'的值减去48变为0,'1'变为1,等等。通过将其写为c - '0',您实际上不需要知道'0的ASCII值是什么'是(或系统正在使用ASCII - 它可能正在使用EBCDIC)。唯一重要的是值是连续增加的整数。

答案 2 :(得分:0)

它从键盘上'0'键的ASCII码转换为零值。

如果你做了int x ='0'+'0',结果就不会为零。

答案 3 :(得分:0)

在大多数字符编码中,所有数字都连续放在字符集中。例如,在ASCII中,它们以'0' 0x30开头'1'0x31'2'0x32,等等。如果您想要给定数字的数值,您可以从中减去'0'并获得正确的值。使用'0'而不是特定值的优点是,您的代码可以轻松地移植到其他字符集。

答案 4 :(得分:0)

如果您通过字符访问字符串,您将获得ASCII值,即使字符恰好是数字。

幸运的是,设计该字符表的人确保0到9的字符是连续的,因此您可以通过减去ASCII值“0”简单地从ASCII转换为数字。

这就是代码的作用。我不得不承认,当你第一次看到它时会让人感到困惑,但这不是火箭科学。

ASCII字符值“0”为48,“1”为49,“2”为50,依此类推。

这里有一个很好的ASCII图表参考:

http://www.sciencelobby.com/ascii-table/images/ascii-table1.gif