An array is an object in memory. It has an address and a size. It's also true that in certain contexts, an array decays into a pointer to its first element. So numerically, if both a
and &a
are compared as pointer values, they compare as equal, since they both point to the same address in memory. But they have different data types: a
has type int[4]
("array 4 of int
"), or int*
("pointer to int
") in certain contexts, whereas &a
always has type int (*)[4]
("pointer to array 4 of int
").
&a points here
|
V
+------+------+------+------+
| a[0] | a[1] | a[2] | a[3] | sizeof(a) == 16
+------+------+------+------+
^
|
&a[0] also points here
In certain contexts, 'a' means &a[0]
Hence, (void *)a == (void *)&a
.
Also note that because a
and &a
point to different data types (and in particular, the pointed-to types have different sizes), doing pointer arithmetic will yield different results. a+1
will point to &a[1]
(advances by one int
value), whereas &a+1
will point to just past the end of the array at &a[4]
, since it advances by one "array 4 of int
" unit:
&a+1 points here
|
V
+------+------+------+------+
| a[0] | a[1] | a[2] | a[3] |
+------+------+------+------+
^
|
a+1 points here