Assume that
int array[16];
There is standard conversion called array-to-pointer conversion, so array
would be converted implic
That is how array names behave in C
.
The name of the array variable represents the address of the first element of the array.
so,
void *p = array; //array name, gives address of the first element.
and
void *q = &array; //adress-of-array name, also gives address of the first element
// actually &array is of type int (*)[16] which is decayed to int *
// and casted to void * here
P.S. Even, FWIW,
void *r = &array[0]; //address of the first element
will also give you the same address.
This will give out the same address and no compiling error.
They are indeed same value, and here compiler has nothing to scream about.
Point to note: once you assign the address(es) to a void pointer, you'll lose the type information associated with them.
The type of &array
is int (*)[16]
(a pointer to an array of 16 integers). The type of array
, when left to decay, is int*
(a pointer to an integer). They both point to the same location, but have a different meaning to the compiler.
If you do (&array)[0]
, the value you end up with is the original array of 16 integers, that you can subscript again, like (&array)[0][0]
. (&array)[1]
would be the next array of 16 integers, if there was one.
If you do array[0]
, the value you end up with is an integer, which you can't subscript again. array[1]
is just the next integer. (This is true regardless of if array
is a int[16]
or a int*
.)
Obviously, if you then turn your pointers into void
pointers, you lose any semantic difference there could have been.
An array in C behaves as a pointer to the address of the first element in memory.
Because you're basically saying the same thing in these two lines:
void *p = array; // Pointer to array, which is an address
void *q = &array; // Pointer to reference to an array, which is basically saying "A pointer to the same address as the pointer".
In other words:
void *p;
Is the same as:
&array;