Arrays can be implicitly cast to a pointer to the first element of the array. It's allowed for convenience:
1 2 3 4
int* p = x; // <- this is just short-hand for...
int* p = &x; // <- this
You can use the & operator on array names, but the type is different. You get a pointer to the array itself, not to the first element in the array.
This is easier to visualize by typedefing the array:
1 2 3 4 5 6 7
typedefint int5; // make a new type 'int5'
int foo; // <- now this...
int5 foo; // <- is the same as this
int* bad = &foo; // this fails because 'foo' is an int5, not an int
int5* good = &foo; // this works
In your second case, you do not need the address of operator because the array name automatically decays to a pointer to the first element of your array. In other words, your pointer p is pointing to x.
However, if you use the address of operator with the array name, it will give you the address of the array containing the 10 integer elements and NOT to the first element of the array. Therefore, you cannot assign that address to a pointer to a single integer element. This is why your compiler is throwing an error. The correct assignment in this case would be as follows.
int (*p) = &x;
However, in both cases, p will display the same address. You will see the difference only when you perform pointer arithmetic. For instance, when you increment p, p will increment by an element in the first case where as it will increment by 10 elements in the second case.