Reputation: 2027
I'm trying to understand how this exactly works (I know what it does, I just don't understand how). As far as I know, this reads a char until EOF is reached, and if its a digit, put it in the array:
while ((c = getchar()) != EOF)
if (c >= '0' && c <= '9')
++ndigit[c-'0'];
I understand I can index an array like this:
some_array[1] = 12;
which will put 12 in the second element.
What does the c-'0'
do ?
(I got this from the book The C programming language 2nd edition from K&R)
Upvotes: 1
Views: 815
Reputation: 51312
According to the ASCII table, character 0
is the ASCII representation of the value 48. Since characters 0
to 9
are representations of numbers 48 to 57, you can convert each character to the actual digit by subtracting 48.
So, instead of writing ndigit[c-48]
, common practice is to write it as ndigit[c-'0']
to indicate that you are converting the ASCII value of your character to a digit.
You can easily check this:
char c = '0';
printf("%d", c); // prints 48
printf("%d", c - `0`); // prints 0 -- that's what we are looking for
Upvotes: 1
Reputation: 7529
c is a char, which can be converted to an int using a widening conversion (8 bits to however many bits an int has on your platform).
c - '0' subtracts the integer value of '0' from the integer value of 'c'.
The ASCII values for the characters '0' to '9' are sequential, so for characters in the range '0' to '9', subtracting the value of '0' from the value of c gives you an integer in the range 0 - 9.
Upvotes: 0
Reputation: 362187
Actually what that's doing is counting how many times you count each digit. So you have an array like:
int ndigit[10] = { 0 }; // Start with all zeros
Given an ASCII digit from '0'
to '9'
, c-'0'
converts it from an ASCII digit to a simple integer from 0 to 9. That is, the character '0'
which is 48 in ASCII is subtracted from each character, so they go from 48 through 57 to 0 through 9.
Then this number 0 through 9 is used an an index into the array, and that index is incremented by one. Thus ndigit
counts how many times each digit is typed.
Upvotes: 3
Reputation: 54640
'0' is a char
which has a decimal value of 48 when coerced to an integer. It works because char is a built-in ordinal type.
If you look at the disassembly, you can see this in action:
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)
Notice we're comparing against 30 hex and 39 hex, not '0' and '9'.
Upvotes: 5