-6

I input a bunch of digit characters, 3 4 5 6 6. And the code returns me this result

digits = 0 0 0 1 1 1 2 0 0 0, white space = 5
, other = 0.

I don't understand why the "digits" return me such a result 0 0 0 1 1 1 2 0 0 0. Can anyone explain why does the computer do that?

#include<stdio.h>

main()
{
int c, i, nwhite, nother;
int ndigit[10];

nwhite = nother = 0;
for (i = 0; i < 10; ++ i)
    ndigit[i] = 0;
while ((c = getchar()) != EOF)
    if (c >= '0' && c <= '9')
        ++ndigit[c-'0'];
    else if (c == ' ' || c == '\n' || c == '\t')
        ++nwhite;
    else
        ++nother;

    printf("digits =");
    for (i = 0; i < 10; ++i)
        printf(" %d", ndigit[i]);
    printf(", white space = %d\n, other = %d\n", nwhite, nother);
}
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Bill Cao
  • 1
  • 1

1 Answers1

2

They key to understanding this problem is in this statement: ++ndigit[c-'0'];

The program begins by creating an array:

int ndigit[10]; /* creates an array of size 10 */

In c when you create an array, you just get a block of memory. What's in that memory is undefined. In more modern languages you may get an array of 10 zeros, but in c you could have garbage data in there when you first create it.

Walking through you code you should be able to identify how the program prepares the array for use. It makes sure each value at each index in the array is set to 0.

At this point your array and its indices looks something like this:

[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] /* array   */
  0  1  2  3  4  5  6  7  8  9   /* indices */

So if you were to run ndigit[0] you would get back the value at index 0, which is 0

c = getChar() is getting 1 character from the input (the numbers you typed). But at this point the program just sees those numbers as type char, not int. This is where you need to understand ASCII. Your first char input is '3'. This has an ASCII value of 51. The program performs this math: '3'-'0'. It is subtracting two chars. This is possible because c is just subtracting the ASCII value of these chars which is really 51-48 which equals 3.

The ++ operator increments a value: ie. ++0 increments 0 to 1. I won't get into pre vs post increment because you will learn that later.

Now that you have all of that, my suggestion is to draw a picture of what the array ndigit with its values and indices and the value of c (the current char) looks like at the end of each iteration of the while loop. Do this for each iteration of the while loop and you will see why the output you are seeing makes sense.

ie:

c = 3
[ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 ] /* array   */
  0  1  2  3  4  5  6  7  8  9   /* indices */

c = 4
...
...

/* and so on */

Here's a link to a useful ASCII table guide: http://www.asciitable.com/

Wilson
  • 251
  • 3
  • 9
  • 1
    Also worth referring him to [C11 Standard §5.1.2.2.1 Program startup p1 (draft n1570)](http://port70.net/~nsz/c/c11/n1570.html#5.1.2.2.1p1). See also: [See What should main() return in C and C++?](http://stackoverflow.com/questions/204476/) (P.S. well formatted and good effort) – David C. Rankin Feb 02 '18 at 05:43