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.