[Someone questioned the statement, ``If you really need to declare a pointer to an entire array, use something like int (*ap)[N];''. This was my response.]

From: scs@eskimo.com (Steve Summit)
Subject: Re: question about answer to 6.13
Date: Mon, 25 Mar 2002 23:17:44 -0500
Message-Id: <2002Mar25.2317.scs.001@aeroroot.scs.ndip.eskimo.net>

You wrote:
> i was wondering about something stated in the answer
> to question 6.13 of the c-faq:
>
> ``If you really need to declare a pointer to an entire
> array, use something like int (*ap)[N]; where N is
> the size of the array.''
>
> doesn't (int (*ap)[n]) mean ``array of pointers to int''?

Nope!

> if not, how why and how would you declare an
> array of pointers to int, then.

That'd be simply

	int *ap[N];
The difference is in the parentheses. In C, there are precedence relationships in declarations, too, and when the default precedence isn't what you want, you use explicit parentheses to override it.

To see very clearly how this works, let's first look at two examples from the world of expressions, one simple, one a bit more complicated.

When you write

	x = 1 + 2 * 3;
how is that interpreted? Multiplication has higher precedence than addition, so 2 is multiplied by 3 and the result added to 1. If you wanted 1 to be added to 2 and then multiplied by 3, you'd use parentheses:

	x = (1 + 2) * 3;
When you write

	int a[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
	int *ip = &a[5];

	x = *ip++;

how is that interpreted? Does *ip++ mean to follow the pointer (that is, take the pointed-to contents of) ip and increment what it points to, or increment the pointer ip and (because this is the postincrement form) take the contents of what it used to point to? Postfix ++ has higher precedence than unary prefix *, so the interpretation is that the pointer is incremented -- x gets set to 5, and ip ends up pointing to a[6]. If you wanted to increment the pointed-to location, you'd again use explicit parentheses to override the default precedence: saying

	x = (*ip)++;
sets x to 5, and leaves ip pointing at a[5], and increments a[5] to contain 6.

(This is probably not the best example, because you may have a hard time seeing that x gets set to 5 in both cases, not 6. Trust me, it does. Postfix ++ means that the ``old'' value of the thing being incremented always gets used, whether the thing being incremented is the pointer ip or the pointed-to array element a[5].)

Finally, let's look at declarations. If you write

	 int *ap[10];
are you declaring an array of pointers, or a pointer to an array? In declarations, the brackets [] which describe arrays have higher precedence than the * which describes pointers. It looks like the * and the [] are both next to the identifier ap, but since [] has higher precedence it means that the brackets are ``closer'' -- ap is an array first, and what it's an array of is pointers. If you really wanted a pointer to an array (though usually you do not) you once again override the default precedence using explicit parentheses:

	 int (*pa)[10];
says that pa is a pointer first, and what it's a pointer to is an array.

Fortunately (and this is no accident) pointers to arrays are much, much rarer than arrays of pointers, so the natural syntax (without the parentheses) is almost always what you want. (Outside of examples for the FAQ list, I'm not sure I've used a pointer to an array in all my years of C programming.)