这个数组索引如何工作?

时间:2009-11-01 19:07:07

标签: c arrays

我试图理解这是如何起作用的(我知道它的作用,我只是不明白如何)。 据我所知,这会读取一个字符,直到达到EOF,如果它是一个数字,则把它放在数组中:

while ((c = getchar()) != EOF)
  if (c >= '0' && c <= '9')
    ++ndigit[c-'0'];

我知道我可以像这样索引一个数组:

some_array[1] = 12;

将把12放在第二个元素中。

c-'0'做了什么?

(我从K&amp; R的C编程语言第2版中得到了这个)

4 个答案:

答案 0 :(得分:5)

'0'是char,当强制转换为整数时,其小数值为48。它的工作原理是因为char是一种内置的序数类型。

如果您查看反汇编,您可以看到这一点:

      if (c >= '0' && c <= '9')
004135E3  movsx       eax,byte ptr [ebp-9] 
004135E7  cmp         eax,30h 
004135EA  jl          wmain+6Eh (41360Eh) 
004135EC  movsx       eax,byte ptr [ebp-9] 
004135F0  cmp         eax,39h 
004135F3  jg          wmain+6Eh (41360Eh) 

请注意,我们将比较30个十六进制和39个十六进制,而不是“0”和“9”。

答案 1 :(得分:3)

实际上,正在做的是计算每个数字计算的次数。所以你有一个像:

这样的数组
int ndigit[10] = { 0 }; // Start with all zeros

给定从'0''9'的ASCII数字,c-'0'将其从ASCII数字转换为从0到9的简单整数。即,字符'0'从每个字符中减去48的ASCII,因此它们从48到57变为0到9。

然后,这个数字0到9用作数组的索引,并且该索引加1。因此ndigit计算每个数字的输入次数。

答案 2 :(得分:1)

根据ASCII table,字符0是值48的ASCII表示。由于字符09是数字48到57的表示,您可以通过减去48将每个字符转换为实际数字。

因此,不是编写ndigit[c-48],而是将其写为ndigit[c-'0'],以表示您正在将字符的ASCII值转换为数字。

您可以轻松查看:

 char c = '0';
 printf("%d", c); // prints 48
 printf("%d", c - `0`); // prints 0 -- that's what we are looking for

答案 3 :(得分:0)

c是一个char,可以使用扩展转换将其转换为int(在您的平台上,int有8位到多个位)。

c - '0'从整数值'c'中减去整数值'0'。

字符“0”到“9”的ASCII值是连续的,因此对于范围“0”到“9”的字符,从c的值中减去“0”的值会得到一个整数范围0 - 9.