FET
FET

Reputation: 942

Clear explanation of ndigit[c - '0']

I've finally started to read the K&R, and I've just arrived to the Array part. But in the example of this section, there's a piece of code I really don't understand completely, so I'd like to ask you for a clear explanation of it, as I wanna understand every concept of C as I know it's the fundamental for a fast learning of C++.

By the way I already have a decent knowledge of JAVA, hope this will help you in your explanation setup.

Question:

In this piece of code ndigit[c - '0'] I don't understand what it's trying to do, I know from other Stack Overlfow questions that 0 should refer to the ASCI standards and should be 48, but still don't understand what c and that 0 have in relationship.

Upvotes: 2

Views: 1205

Answers (3)

Tanzin
Tanzin

Reputation: 71

Short answer:

by ndigit[c-'0'] you are not doing normal arithmetic e.g [5+5] = [10]. Rather you are first converting your characters into character code. Then doing arithmetic with character code.

To say simply- we represent five in english with this "5" sign. Other languages have their own sign for five i.e 五 is five in japanise. Likewise Computer represent five with 53(assuming ascii, ascii is like a language). So with ndigit[c-'0'], its first being converted to character code then doing arithmetic.

Long answer:

Lets go through ndigit[c - '0'] first.

  • ndigit = name of the array

  • [ ] = index, used for specifying total elements number.

  • c - '0' = arithmetic operation. c is a variable. - is minus.And '0' is not 0 but 48.

now let me add additional code from the from the book -

int ndigit[10];
...//fill in the array with 0s
while((c = getchar()) != EOF)
    if(c >= '0' && c <= '9')
         ++ndigit[c - '0']; //<== unable to understand this part

here something to note of is getchar(). getchar() return int type data. even though it return int type but it wont return the character rather it will return character code. Let me give a example-

#include <stdio.h>

int main(){
    int c;
    c = getchar();
    printf("%d\n", c);
    }

output:

@mix:~
$ cc test.c
@mix:~
$ ./a.out
5          ;wrote 5 in terminal
53         ; printed 53 instead of 5

5 is the character. And 53 is the character code of 5.

Now lets back to our main topic ndigit[c - '0']. c is getting a value from getchar(). and getchar() reads from input. lets say the input is 5 . Now due to getchar() function behaviour instead of 5, c will contain 53. So

ndigit[c - '0'] == `ndigit[53 - '0']` != `ndigit[5 - '0']`

Also notice we are not using 0. Rather '0'. means the arithmetic -

    ndigit[53 - '0']
   =ndigit[53]       ;**wrong**

using '0' means we meant to use character code(used single quote). Like described above '0' = 48 (according to ascii). so

ndigit[53 - '0']

= ndigit[53 - 48]

= ndigit[5]

Now we get back our character which was read by getchar(). But why should we get back our character? Will ndigit[c] instead of ndigit[c - '0'] work?

ndigit[c] wont work because at the start of our code we wrote ndigit[10] . Our ndigit[10] array can hold 10 elements at max. As a result c cant be greater than 10 or ndigit[53] is invalid as its size is 53 and surpassing 10 . Thats why we use ndigit[c - '0'] to do character code subtraction and get a value under 10.

IF still unclear, search and learn about the following-

  1. charater encoding
  2. array in c

Upvotes: 6

sepp2k
sepp2k

Reputation: 370132

As you said '0' is equal to 48 (assuming ASCII encoding). Thus the other digits are equal to 49 through 57 respectively. So '1' is equal to 49, '2' to 50 etc. Thus '1' - '0' is equal to '49 - 48', which is 1 and '2' - '0' is equal to '50 - 48', which is 2 and so on.

In other words c - '0' converts a digit like '5' to its integer equivalent (which would be 5 for '5').

Upvotes: 0

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726569

In this code c is a char, presumably representing a digit. In C a char is an integral type, so you can perform arithmetic operations on them.

Digits are encoded with numbers from a consecutive range: if the code for '0' is k, the code for '1' is k+1, the code for '2' is k+2, and so on. That is why by subtracting '0' from a character representing a digit you get the numeric value of that digit.

For example, by subtracting '5'-'0' you get a numeric 5 instead of character '5'.

If you make an array ndigit[10], then ndigit[c - '0'] lets you access an array element corresponding to the digit. This can be used, for example, to count the number of different digits in the input.

Upvotes: 1

Related Questions