K&R 5.7

M

mdh

A happy and safe Easter to all.

I am tackling this, and in the process, wrote this little bit of code.

#include <stdio.h>

static char mnths[] = {0,1,2,3,4,5,6,7,8,9,10,11,12};

int main () {
int i;
for (i=1; i<=12; i++)
/**printf("%d\n", mnths); **/ works
printf("%d\n", *mnths++); <<<-------error:rong type code to increment
return 0;
}

I thought that an array was passed to printf as a pointer, but I am
obviously missing something.
 
C

Chris Torek

static char mnths[] = {0,1,2,3,4,5,6,7,8,9,10,11,12};

(Of course, this is just an example, but I note that it is
kind of silly to have mnths == i.)
int main () {
int i;
for (i=1; i<=12; i++)
/**printf("%d\n", mnths); **/ works
printf("%d\n", *mnths++); <<<-------error:rong type code to increment
return 0;
}

I thought that an array was passed to printf as a pointer, but I am
obviously missing something.


This is a little tricky.

An array never "is" a pointer (nor vice versa).

An array name, in some cases, *becomes* a pointer *value*. ("But
isn't that the same thing?" The answer is: no, not quite. The
"some cases" thing is very important, as is the "becomes", which
might better be termed "produces" or "computes".)

When you do get a pointer, the pointer value is *computed*, in much
the same way as:

printf("%d\n", 5 + 4);

has to *compute* the sum (9). Although the sum is always actually
9, there is no literal 9 here, just a 4 and a 5. Clearly, the fact
that the sum is 9 does not mean that either 4 or 5 is nine. :)
Likewise, when you attempt to pass an "array value" to a function,
the compiler computes a pointer value that points to the first
element of the array.

The reason "*mnths++" does not work is that the "++" operator is
applied to "mnths", which is the name of the array. (Remember that
*mnths++ "means" *(mnths++), so the ++ applies to the array name,
not the result of the "*".) The "++" operator demands an object
(or more loosely speaking, a "variable"), not a value.

The transformation of array name to pointer value occurs *only*
when you ask for the "value" of an array. Since "++" needs an
object, not a value, the transformation simply does not happen.

What you can do, if you like, is create a separate pointer variable
(i.e., an "object") and make it point to the first element of
the "mnths" array:

char *p = mnths; /* or: char *p = &mnths[0]; */

The right hand side of an "=" operator needs a value. Here, we
have "mnths", an array. That transformation, from array name to
pointer value, now occurs -- the compiler computes &mnths[0],
just as if you had asked for it explicitly.

Once you have a variable, you can apply the "++" operator to it:

printf("%d\n", *p++);

Here the ++ operator works on the object p, and the value stored
there. It obtains the original value, adds 1, schedules the new
value to be stored back into p, and produces, as its result, the
old value. The "*" operator then takes this value (which is, as
it must be, a pointer) and follows the pointer to whatever it
points to.

The first time you do this, you will get mnths[0] -- so this is
like looping from 0, not from 1. Note that your commented-out
version prints mnths[1], then mnths[2], and so on. If we do:

int i;
char *p = mnths;

for (i = 1; i <= 12; i++)
printf("%d\n", *p++);

you will print mnths[0], then mnths[1], and so on. The mnths[]
array has 13 elements, numbered 0 through 12 inclusive, so it is
OK to do either one, but the output will be different.

Note, by the way, that transformation from "array object" to "pointer
value" happens *extremely* often. It happens so often, it tends
to confuse beginners -- and sometimes even non-beginners -- into
thinking that it always happens. But it does not. An even better
example occurs when using the sizeof operator:

printf("%u\n", (unsigned int)sizeof mnths);

which prints 13 -- the size of the array -- and not the size of a
pointer (generally 2, 4, or 8 on most machines today).
 

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,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top