There seems to be some misunderstanding in how pointers and arrays work together.
The expression &a is a pointer to the array itself, and has the type int (*)[5].
What you seem to expect is to get a pointer to the first element, which would be &a[0], or plain a (as that decays to a pointer to the arrays first element):
int *p = a;
That it works is not a coincidence, because a pointer to the array just happens to point to the same address as the location of the first element. The addresses are equal, but the types of &a and &a[0] are different. This semantic difference really is crucial.
Regarding the issue about the ++ operator, it's simply how it works.
The result of the suffix increase or decrease operators is the old value. So when you do p++ you get the old pointer, before the increase.
If we take
i = *p++;
it's (somewhat simplified) equivalent to
int *temporary_old_p = p;
p = p + 1;
i = *temporary_old_p;
Furthermore, the "%u" format for a pointer is invalid. To print a void * pointer (a cast is really needed to be correct) you should use the "%p" format specifier.
Mismatching format-specifier and argument type leads to undefined behavior.
Regarding the problem with *(&a + 1), lets draw the array a how it looks in memory, with a few arrows to show pointers:
+------+------+------+------+------+------
| a[0] | a[1] | a[2] | a[3] | a[4] | ....
+------+------+------+------+------+------
^ ^
| |
&a[0] |
| |
&a &a + 1
Since the type of &a is int (*)[5], then it follows that the type of &a + 1 should also be int (*)[5].
If we dereference the pointer &a (as in *(&a)) then we get the actual array a. Arrays, like a, decay to a pointer to its first element, &a[0]. This pointer is pointing to the same location as &a (as shown in the "drawing" above).
If we change &a to &a + 1, then we get *(&a + 1) in the dereference. It's the "second" array (is it existed). Just like *(&a) is an array of five int, so is *(&a + 1). This array decays to a pointer to its first element &(*(&a + 1))[0].
Or perhaps think that &a is equal to &a + 0. Then it would be easy to see that *(&a) would be equal to *(&a + 0). And we know that *(&a) is equal to a which is equal to &a[0], which also means that *(&a + 0) have to be equal to &(*(&a + 0))[0]. That should make it easy to see what &(*(&a + 1))[0] might be.