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 int
s, 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.