W
Wonder
Keith said:Note that we considered this conversion rule in two different
contexts. For p, the prefix to the indexing operator, the rule
doesn't apply, because p is already a pointer (to an array of 3 ints).
For p[0], an array of 3 ints, the rule does apply, and it's converted
to a pointer-to-int.
In fact, after reading your program and explain, I doubt the compiler
just output the address of a pointer points to, no matter you are using
p or &p. The following program can prove it:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *p = NULL;
p = malloc(sizeof *p);
if (p == NULL)
{
exit(EXIT_FAILURE);
}
*p = 10;
printf("p=%p\n", (void*)p);
printf("&p=%p\n", (void*)p);
printf("*p=%d\n", *p);
free(p);
return 0;
}
It can be compiled by gcc on Linux, and the output is:
p=0x8049678
&p=0x8049678
*p=10
In the second printf, we apply the "&" (address-of) operator to p[0].
This is one of the contexts in which the conversion to pointer
*doesn't* take place. (Another is the operand of the sizeof
operator.) So &p[0] is the address of an array-of-3-ints. p[0] and
&p[0] have different types, but they yield the same raw pointer value
when converted to void* and printed with "%p".
Could you explain in which contexts such conversion doesn't take place?
And in your original program, p[1] actually refers to *another* array
of 3 ints, the second element of the array of arrays-of-3-ints to
which p points. In my version of your program, I only allocated
enough memory for a single array-of-3-ints; if I wanted to play with
p[1], I'd have to allocate more memory.
So, does that mean we have 3 pointers p[0], p[1], p[2], and each one
points
to an array of 3 integers? But we are not defining an array of
pointers, right?
This all seems confusing because, frankly, it is. I went down a
couple of blind alleys while writing this, and I'm not at all certain
that there are no errors in what I've written.
There really aren't many cases where it makes sense to have a pointer
to an array of 3 ints. Usually it makes much more sense to have a
pointer to int, which can be used to access an array of ints. If you
really need an array of items, where each item contains 3 ints, you
might be better off wrapping the array-of-3-ints in a struct and
declaring a pointer to the struct type. Even if you can keep the
complications of a pointer-to-fixed-size-array-of-whatever straight in
your head, the next person to read your code may not be able to.
For a better general understanding of the relationship between arrays
and pointers, read section 6 of the C FAQ,
<http://www.eskimo.com/~scs/C-faq/faq.html>. (In fact, read the whole
thing if you haven't already.)
And before assuming that everything I've written here is correct, wait
a while until the other regulars have had a chance to pick it apart.
You are absolutely right. I never use pointers to an array. Here I just
want to make the concept clear.
Thanks a lot. You are so nice!