1

On page 24 of K and R - C programming book,
there is this code from a program to count digits and other input.

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

I am not understanding the last line of the code. What does [c - '0'] mean?
Entire program from the book: https://i.stack.imgur.com/zRLiD.jpg

user2656
  • 33
  • 4
  • `[c-'0']` is the ASCII value of `c` (the character the user inputs) - the ASCII value of `'0'` (48). For example, if the input is `1`, it'll be 49 (ASCII value of 1) - 48. – JASLP doesn't support the IES Jul 23 '21 at 06:10
  • Why are the authors writing [c - '0'] in the context of this program? I don't understand it intuitively. – user2656 Jul 23 '21 at 06:19
  • It is counting the digit frequency, in array elements `[0]` to `[9]`. – Weather Vane Jul 23 '21 at 06:22
  • @user2656 check sonicwave's answer, `[c-'0']` will give you the corresponding integer value. – JASLP doesn't support the IES Jul 23 '21 at 06:23
  • In the book it is explained like this: "The numeric value of that digit is c - '0'. This works only if '0', '1', ..., '9' have consecutive increasing values. Fortunately this is true for all character sets." Can you explain this? – user2656 Jul 23 '21 at 06:23
  • 1
    duplicates: [What's the real use of using `n[c-'0']`?](https://stackoverflow.com/q/7403741/995714), [What does it mean to subtract '0' from a variable in C?](https://stackoverflow.com/q/34832074/995714), [C array push, why subtract '0'?](https://stackoverflow.com/q/21617298/995714), [Can someone explain the `- '0'`](https://stackoverflow.com/q/15519781/995714) – phuclv Jul 23 '21 at 06:25
  • @user2656 It means if the input is between `0` and `9`, `c-'0'` will always result in the corresponding integer value. Here's an example with their ASCII values, ASCII of 0 is 48, ASCII of 1 is 49... ASCII of 9 is 57 (they have consecutive increasing values), so '8'-'0' will always be 8, '5'-'0' will always be 5, the same goes for any character between and including '0' and '9'. – JASLP doesn't support the IES Jul 23 '21 at 06:30

3 Answers3

4

Every character has a numeric value; that means if you input the character "0" you're not actually inputting the number "0". You're inputting the character "0" which its value is 48 in the ASCII table (it may be different in other character sets...)

so when you input the character "0" you get the actual number zero in the following (According to the ASCII table):

c - '0' means c - 48
'0' - '0' means 48 - 48 = 0
'1' - '0' means 49 - 48 = 1
'2' - '0' means 50 - 48 = 2
and so on...

notice that the code is designed to work with different character sets. not just ASCII. Search "ASCII table" in google to see the chart in order to understand it better.

3

'0' is the ASCII character 0, with a decimal value of 48. (See https://www.asciitable.com for a full listing.)

Since the numerals 0-9 are all guaranteed by the C standard to have consecutive values (in this case, decimal values from 48 to 57), by subtracting the character 0 from the input character, you arrive at the corresponding integer value, that you can then use in further processing.

'0' - '0' = 0
'1' - '0' = 1
'2' - '0' = 2
...
'9' - '0' = 9

In this case, the further processing is then used to index into the ndigit array.

sonicwave
  • 5,952
  • 2
  • 33
  • 49
2

C language mandates the code representation for numbers to be consecutive. That means that even if you do not use ASCII (EBCDIC used to be another common charset) you can be sure that the code for '5' will be the code for '0' + 5.

So the idiom c - '0' is guaranteed to be portable across any conformant system, while c - 48 (or c - 0x30) will only work on ASII (or ASCII derivatives like latin1, cp1252, utf8, etc.) systems.

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252