Re: K&R 5.7



In article <1176060208.128343.284030@xxxxxxxxxxxxxxxxxxxxxxxxxxxx>
mdh <mdeh@xxxxxxxxxxx> wrote:
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] == i.)

int main () {
int i;
for (i=1; i<=12; i++)
/**printf("%d\n", mnths[i]); **/ 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).
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
.



Relevant Pages

  • Re: char **argv & char *argv[]
    ... "pointer to pointer to char". ... >> pointer)) pointing to the first element of an array. ... so we have to start adding more context. ... type "pointer to char", rather than "array MISSING_SIZE of char". ...
    (comp.lang.c)
  • Re: why cannot assign to function call
    ... hypothetical C-like languages, ... sizeof business would still indicate that a pointer was being passed. ... talk about variables of an array type. ... the earlier version of the standard didn't have numbered ...
    (comp.lang.python)
  • Re: multi dimensional arrays as one dimension array
    ... please - where does the standard say that such a conversion ... Pointer conversion yields a pointer to the same object as ... exist only where there are array declarations. ...
    (comp.lang.c)
  • Re: Pointer Equality for Different Array Objects
    ... Pointers to the same object are pointers to the same region of data storage. ... A pointer comaprison (for exact equality, ... we have the vague ("if the array is large enough"). ...
    (comp.lang.c)
  • Re: Evaluating unary *
    ... 'arr' exists, ... value can be used with the same syntax as would be used to access a 2D array of the kind you're referring to, but that 2D array is just a different way of looking as the same object that was already created by the definition of 'arr'. ... to me, it makes sense to return a pointer to the first value of an array, but to return the address of the pointer to the first value of an array, is not directly possible as such. ... lea eax, ...
    (comp.std.c)