goulashsoup goulashsoup - 1 month ago 6
C Question

Understanding special type of access C++/C array

I have the following code snippet:

int ndigit[10] = {0,0,0,0,0,0,0,0,0,0};

void count() {
char c;
while (cin.get(c)) {
if (c>='0' && c<='9') {
ndigit[c-'0']++;
}
}


So
c
has to be between 0 and 9 (with 0 and 9), so why it is necessary to index the array like
ndigit[c-'0']
instead of just
ndigit[c]
?

If I am right, in both cases a
c
value can occur more then once, so a the value of
ndigit[c-'0']
gets overwritten anyway...

I appreciate your wisdom!

Answer

"So c has to be between 0 and 9"

No! c has to be between '0' and '9', and it makes the difference.

Every character has appropriate numeric value (ASCII code), e. g.:

  • 'A' has 65
  • 'B' has 66
  • 'a' has 98

In C language characters are simply numbers, e. g. 'A' + 'B' is a perfectly valid expression and means 65 + 66.

If we want display or read a digit (0, 1, ..., 9), we actually use its symbolic representation, i. e. an character ('0', '1', ..., '9'). And these characters amazingly have not ASCII values 0, 1, ..., 9, but 48, 49, ... 57 - they are all shifted by 48.

So for converting a digit symbol, e. g. '7' (which has ASCII value 55 - as 7 + 48) into a number which we people see in it (i. e. 7 - without apostrophes), we need simply subtract this shifting number 48 from its ASCII value:

    (7 + 48) - 48

which is the same as to subtract '0' (= 48) from '7' (=55):

    '7' - '0'

and witch is exactly what does the expression

    c - '0'

in your code.

Comments