When you allocate an array in C, what you get is something like the following:
          +---+ 
  arr[0]: |   |
          +---+
  arr[1]: |   |
          +---+
           ...
          +---+
arr[N-1]: |   |
          +---+
That's it.  There's no separate memory location set aside for an object named arr to store the address of the first element of the array.  Thus, the address of the first element of the array (&arr[0]) is the same value as the address of the array itself (&arr).  
Except when it is the operand of the sizeof or unary & operators, or is a string literal being used to initialize another array in a declaration, an expression of type "N-element array of T" will be converted ("decay") to an expression of type "pointer to T" and the value of the expression will be the address of the first element of the array.
So the type of the expression arr in the first printf call is char [10]; by the rule above, the expression "decays" to type char *, and the value is the address of arr[0].  
In the expression &arr, arr is the operand of the unary & operator, so the conversion isn't applied; instead of getting an expression of type char **, you get an expression of type char (*)[10] (pointer to 10-element array of char).  Again, since the address of the first element of the array is the same as the address of whole array, the expressions arr and &arr have the same value.