explanation of a program required please

B

Buck Rogers

Hi guys! Love your work!

The below program is from K&R2, p22.

=================================
#include <stdio.h>

/* count digits, white space, others */
main()
{
int c, i, nwhite, nother;
int ndigit[10];

nwhite = nother = 0;
for (i = 0; i < 10; ++i)
ndigit = 0;

while ((c = getchar()) != EOF)
if (c >= '0' && c <= '9')
++ndigit[c - '0']; <---------------------- /* where I am
confused */
else if (c == ' ' || c == '\n' || c == '\t')
++nwhite;
else
++nother;

printf("digits =");
for ( i = 0; i < 10; ++i)
printf(" %d", ndigit); <--------------------- /* where I am
confused */
printf(", white space = %d, other = %d\n",
nwhite, nother);
return 0;
}
========================================

I can't get my head around what "++ndigit[c - '0']"
means. I understand what c - '0' is for, but ++indigit[]?
That's not incrementing through elements in an array ie. indigit[i++]
(where is is a declared integer)??
If not, what does it mean? Is it incrementing an actual array(not
elements of the array), which I can't figure out.

I just can't figure out how the program can keep a tab on what
digit(s) were entered and then actually prints the number of times
each digit was entered, spaced correctly along the "index".

Can someone please explain the exact code which achieves this to me?
I think this program does alot for such little code!

Thanks in advance!

Buck.
 
O

osmium

Buck said:
The below program is from K&R2, p22.

=================================
#include <stdio.h>

/* count digits, white space, others */
main()
{
int c, i, nwhite, nother;
int ndigit[10];

nwhite = nother = 0;
for (i = 0; i < 10; ++i)
ndigit = 0;

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


Say that c has the value '3'.

Then:
++ndigit['3'-0]
yields ++ndigit[3]
ndigit points at ndigit[0] so
ndigit[3] points at ndigit[3]
If this is the first encounter, ndigit[3] has the value 0.
++ndigit[3] increments the value therein, which was 0 on the first encounter
So it works as promised.

Nasty stuff! Following it through a debugger might help.
I think the most effective way to attack things like this, for me, is a
numeric example.

<snip>
 
A

Alexander Bartolich

begin followup to Buck Rogers:
I can't get my head around what "++ndigit[c - '0']"
means. I understand what c - '0' is for, but ++indigit[]?

++ndigit[c - '0'];

is equivalent to

ndigit[c - '0'] = ndigit[c - '0'] + 1;
[...] I just can't figure out how the program can keep a tab on what
digit(s) were entered and then actually prints the number of times
each digit was entered, spaced correctly along the "index".

int ndigit[10];

This defines ten counters, for each digit.
ndigit[0] is the counter for character '0',
ndigit[1] is the counter for character '1',
ndigit[2] is the counter for character '2',
etc.

The absolute lame way to handle this is

if (c == '0')
ndigit[0]++;
else if (c == '1')
ndigit[1]++;
etc.

Instead you have to realise that there is a 1-to-1 mapping between
character codes ('0' to '9') and array indices (0 to 9).
 
B

Barry Schwarz

Hi guys! Love your work!

The below program is from K&R2, p22.

=================================
#include <stdio.h>

/* count digits, white space, others */
main()
{
int c, i, nwhite, nother;
int ndigit[10];

nwhite = nother = 0;
for (i = 0; i < 10; ++i)
ndigit = 0;

while ((c = getchar()) != EOF)
if (c >= '0' && c <= '9')
++ndigit[c - '0']; <---------------------- /* where I am
confused */


C guarantees that the characters '0' through '9' are represented in
the character set by values that increase by 1 as you pass through the
range. '0'+1 will always equal '1'. (This is not true for letters.
In ASCII, 'i'+1 will equal 'j' but in EBCDIC 'i'+8 is 'j').

Therefore, the if insures that c is a digit character (as opposed to
letter, punctuation, etc) and the expression c-'0' converts the
character for digit n to the integer value n (if c is '3', then c-'0'
is 3).

Since the ten elements of the array ndigit (ndigit[0] through
ndigit[9]) are intended to count the occurrences of the ten digits
('0' through '9'), this insures the proper element is accessed for the
current value of c. The ++ then simply increments this particular
element.
else if (c == ' ' || c == '\n' || c == '\t')
++nwhite;
else
++nother;

printf("digits =");
for ( i = 0; i < 10; ++i)
printf(" %d", ndigit); <--------------------- /* where I am
confused */


ndigit is a count of the number of times the i-th digit appeared in
c. printing it with a %d prints it as a common integer (no leading 0,
only as many spaces as needed, etc).
printf(", white space = %d, other = %d\n",
nwhite, nother);
return 0;
}
========================================

I can't get my head around what "++ndigit[c - '0']"
means. I understand what c - '0' is for, but ++indigit[]?
That's not incrementing through elements in an array ie. indigit[i++]
(where is is a declared integer)??

Correct, it is not. It is accessing one particular element of the
array and incrementing it.
If not, what does it mean? Is it incrementing an actual array(not
elements of the array), which I can't figure out.

You cannot increment an array, only an element of the array.
I just can't figure out how the program can keep a tab on what
digit(s) were entered and then actually prints the number of times
each digit was entered, spaced correctly along the "index".

I give up, what is "index"? The printf statement makes no effort to
space text "correctly". If ndigit is less than 10, it will print
in one column. If it is less than 100, then 2 columns. Etc. In
fact, you could argue that this printf is designed to be "ragged". If
you want each ndigit to be properly spaced, you would need to put a
length modifier in the %d.



<<Remove the del for email>>
 
P

Peter Shaggy Haywood

Groovy hepcat Buck Rogers was jivin' on Tue, 23 Dec 2003 21:37:36
+1100 in comp.lang.c.
explanation of a program required please's a cool scene! Dig it!
The below program is from K&R2, p22.

=================================
#include <stdio.h>

/* count digits, white space, others */
main()
{
int c, i, nwhite, nother;
int ndigit[10];

nwhite = nother = 0;
for (i = 0; i < 10; ++i)
ndigit = 0;

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


The expression c - '0' converts the (digit) character value in c to
its numerical value. Next, the coresponding element of the array
ndigit is incremented. So, if c is '3', for example, then c - '0' is
3, then ndigit[3] (the fourth element of ndigit) is incremented.
confused */
else if (c == ' ' || c == '\n' || c == '\t')
++nwhite;
else
++nother;

printf("digits =");
for ( i = 0; i < 10; ++i)
printf(" %d", ndigit); <--------------------- /* where I am


Well, what don't you understand about that? It simply prints the
element of the array indicated by the index i. When i is 0 it prints
the value of ndigit[0] (the first element). When i is 1 it prints the
value of ndigit[1] (the second element). And when i is 2 it prints the
value of ndigit[2] (the third element). And so on.
confused */
printf(", white space = %d, other = %d\n",
nwhite, nother);
return 0;
}
========================================

I can't get my head around what "++ndigit[c - '0']"
means. I understand what c - '0' is for, but ++indigit[]?
That's not incrementing through elements in an array ie. indigit[i++]
(where is is a declared integer)??

ndigit[c - '0'] is the declared integer. It's one of the elements of
the array ndigit.
If not, what does it mean? Is it incrementing an actual array(not
elements of the array), which I can't figure out.

Of course not. You cannot increment an array. That doesn't make
sense. It is incrementing an element of the array.
I just can't figure out how the program can keep a tab on what
digit(s) were entered and then actually prints the number of times
each digit was entered, spaced correctly along the "index".

It's simple. Each element in the array represents a digit. Each
element is initialised to 0 indicating that no digits have been
entered yet. As a digit is entered, the array element that represents
that digit is incremented. At the end, you have an array containing
the number of times each element has been entered.
Can someone please explain the exact code which achieves this to me?

As I said above, the expression c - '0' converts a digit to its raw
numerical value. For example, it converts '1' to 1, '7' to 7 and '0'
to 0. I'm sure I don't have to explain this further, since you say you
understand it.
An expression such as x[y], where x is the name of an array and y is
an integer expression (or vice versa, but I don't want to confuse you
further, so just don't worry about that), yields the element of the
array x numbered y (the y+1'th element). So, ndigit[2], for example,
is the third element of the array ndigit. And ndigit['2' - '0'] is the
third element of ndigit. So, if c contains the digit '2', then
ndigit[c - '0'] also gives us the third element of ndigit. Are you
with me so far?
So, basically what this does is finds the array element that
coresponds to the entered digit.
Now, the ++ operator increments its operand. That's simple enough.
In the code you posted, its operand is the element of the array
coresponding to the entered digit (ndigit[c - '0']). Now do you
understand?
I think this program does alot for such little code!

It doesn't really do much. It just calculates which array element to
increment based solely on the entered digit. It's the simplest
calculation to find the right array element. There's nothing to it.

--

Dig the even newer still, yet more improved, sig!

http://alphalink.com.au/~phaywood/
"Ain't I'm a dog?" - Ronny Self, Ain't I'm a Dog, written by G. Sherry & W. Walker.
I know it's not "technically correct" English; but since when was rock & roll "technically correct"?
 
P

Peter Shaggy Haywood

Groovy hepcat osmium was jivin' on Tue, 23 Dec 2003 07:16:49 -0800 in
comp.lang.c.
Re: explanation of a program required please's a cool scene! Dig it!
ndigit points at ndigit[0] so
ndigit[3] points at ndigit[3]

Sorry, but no. You're wrong. Perhaps it's just your terminology, but
still, if your terminology's off it can confuse people.
ndigit[3] does not point at ndigit[3]. It doesn't point at anithing.
ndigit is an array of int, and ndigit[3] is the fourth int in that
array.
For that matter, ndigit doesn't point at anithing either, since it
is an array, not a pointer. It is converted to a pointer in certain
contexts, of course, but still, you don't want to confuse people. It's
an array and does not point. The value it is converted to points at
ndigit[0]. And I'm sure that's what you meant. But, like I said, your
terminology needs to be right, otherwise it can be confusing.
Sorry for being overly pedantic, but you know how we are in this
news group. :)

--

Dig the even newer still, yet more improved, sig!

http://alphalink.com.au/~phaywood/
"Ain't I'm a dog?" - Ronny Self, Ain't I'm a Dog, written by G. Sherry & W. Walker.
I know it's not "technically correct" English; but since when was rock & roll "technically correct"?
 
J

Joona I Palaste

Alexander Bartolich said:
begin followup to Buck Rogers:
I can't get my head around what "++ndigit[c - '0']"
means. I understand what c - '0' is for, but ++indigit[]?
++ndigit[c - '0'];
is equivalent to
ndigit[c - '0'] = ndigit[c - '0'] + 1;

Nitpick: Not *exactly* equivalent. For the purposes of this K&R sample
program, it's equivalent, but generally, it's not. There is a difference
on how many times ndigt[c - '0'] is evaluated. If it involves side
effects, the latter form might cause undefined behaviour.

To the OP: you don't have to care about this until you try programs that
return pointer values from functions.

--
/-- Joona Palaste ([email protected]) ------------- Finland --------\
\-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
"You have moved your mouse, for these changes to take effect you must shut down
and restart your computer. Do you want to restart your computer now?"
- Karri Kalpio
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top