I think you meant

Code:
int a[5] = { 1, 2, 3, 4, 5 };
int * p = a + 1;

printf("%d %d", *(a + 1), *(p - 1));
The variable a can become a pointer in pointer contexts, rather than an array. The expression (&a + 1) results in a pointer to pointer, which explains why you needed the cast.

You're assigning p to an area after the end of the array, and when you dereference *(p - 1) you get your output because of pointer arithmetic. I think the compiler decided to backtrack by the size of your array.

This question is one example why it's not smart to cast in C unless you're sure it's right.