A couple of things...
First, a
doesn't store the location of a[0]
. There is no object a
that is separate from the array element a[0]
. Basically what you have in memory is
Address
------- +------+
0x1000 a: | 0x01 | a[0]
+------+
In other words, the address of an array is the same as the address of its first element.
Unless it is the operand of the sizeof
or unary &
operators, the expression a
will be converted ("decay") from type "1-element array of int
" (int [1]
) to "pointer to int
" (int *
) and the value of the expression will be the address of the first element in the array.
This means that the expressions &a
, a
, and &a[0]
all yield the same address value; it's just the types of the expressions are different:
Expression Type Decays to
---------- ---- ---------
&a int (*)[1]
a int [1] int *
&a[0] int *
Which brings us to this line:
int* ptr = &arr; // int * = int (*)[1] - assignment of incompatible types
The compiler should have yelled at you about that line. You may want to dial up the warning level.