I'm afraid you are mistaking two things here:
- the use of address operator
&.
- the use of arrays in C.
The address of & operator allows you to construct a pointer to value from a variable of same type as value. That means that, when you write:
p = &var1;
C gets the address of variable var1 and stores that value into pointer variable p.
When you refer to an array by name, the value you get is the address of the first element, so
int *p = A;
is the same as take the address of the first element of A and assign that value to the pointer to int variable p.
When you do:
int *p = &A;
you are doing an assignment from a pointer to array of int into a variable of type array of int, which is a different type. Historically, the compiler automatically converted the type and didn't give any indication, but as it is incorrect, it can confuse more than one. It gives a warning on my compiler, although:
$ make pru2.o
cc -O -pipe -c pru2.c -o pru2.o
pru2.c:5:6: warning: incompatible pointer types initializing 'int *' with an expression of type 'int (*)[20]'
[-Wincompatible-pointer-types]
int *q = &A;
^ ~~
1 warning generated.
This is manifested in the code you post later:
printf("%d\n", A); /* this is the same ass &A[0] */
printf("%d\n", *A); /* dereference that, as *(&A[0]) == A[0] */
Here, it is important (when using arrays) to differentiate clearly that
&A
and
A
Are different expressions, that give (normally, as thinking otherwise is Undefined Behaviour) the same address value, but as a pointer to different type.
&A
is the address of array A, and as such is defined as type
int (*)[sizeof A / sizeof A[0]]
while
A
represents the address of the first element of A, and as such it is defined as type
int *
(pointer to int) This can be shown, by simply printing the sizes of the pointed to dereferences, as in:
int A[20];
...
printf("sizeof *(&A) == %z\n", sizeof *(&A));
and
printf("sizeof *A == %z\n", sizeof *A);
(the first will give you the size of the complete array, demonstrating that the address of an array A is a pointer to an array of 20 ints, while the second will give you the size of the first element of A, demonstrating that it points to a single int element)
In general, arrays are used in a very limited way in C, as they are assimilated to pointers in many situations, they cannot be passed by value ---using the array name as a parameter to a function passes a pointer to the first element, using the address of the array makes the compiler to pass the same value, but as a pointer to array of n elements--- this will be treated as a simple pointer value by the called function, as the unspecified array suffix [] will be converted into a pointer definition by the compiler.