If you compile the first program you will get a compiler warning:
warning: initialization from incompatible pointer type
Because the type of p
is pointer to integer but the type of &a
is pointer to array of integer. Compiling the second program is fine, because again
phas type
int*and
ahas type
int[]` (i.e., array of integer) but in C, you can pass/assign an integer array to an integer pointer just fine. The value of the pointer is assigned the starting address of the array.
When you define an array with square brackets in C, the array is placed immediately in the stack or data section, so the starting address of the array is the same as the address of the array variable itself! This is different from arrays created with malloc
.
What this means for you is this: Suppose the variable a
is allocated at address 4e78ccba. This means that &a
is 4e78ccba. But in C, the value of a
when passed/assigned to a pointer is by definition the address of the beginning of the array, so this is also 4e78ccba.
Again, if you set things up with malloc things will be different. (Try it!!) And by the way, pay attention to the warnings. :) This is an interesting question because C is so weakly typed it only gave you a warning in the first case. A stronly typed language would not have liked the mixing of an integer pointer with an integer array pointer.
ADDENDUM
Here is some code that shows how you can actually differentiate the pointer to the first element and the pointer to the whole array:
#include <stdio.h>
int main() {
/* a is an array of ints, but can be used as a pointer to int */
int a[] = {11, 2, 3};
/* Using a as an int pointer */
int* p = a;
printf("%d\n", *(p+1));
/* Now here is how to make a pointer to the array itself! */
int (*q)[] = &a;
printf("%d\n", (*q)[2]);
return 0;
}
This program outputs
2
3