Type of pointer matters while doing pointer airthmatic.
Here, $p$ is an array of $5$ integers, although &p, p or &p[0] give same result i.e., base addresses of array (or) address of $1^{st}$ element when printed, but they behave differently when airthmatic is performed.
int p[5] = {10, 11, 12, 13, 14}; // p is an array of 5 ints
Let array be stored like in the picture below :
printf("%d %d %d",p,&p,&p[0]); // all print same address (200)
But when pointer airthematic is performed on these, then $\Rightarrow$
p + 1 = 204 // increment by an element
&p[0] + 1 = 204 // increment by an element
&p + 1 = 220 // increment by sizeof(array)
//Code has been modified a bit to make point clear
int main() {
int p[5] = {10, 11, 12, 13, 14}; // let p = 200
int *ptr = (int *)(&p + 1); // ptr stores 220
int *ptr1 = (int *)(p + 1); // ptr1 stores 204
printf("%d %d %d",*(p + 1),*(ptr- 1),*(ptr1-1));
// Output : 11 14 10
return 0;
}
$\color{navy}{*(p+1) = *(204) = 11}$
$ \color{navy}{ *(ptr - 1) = *(220 -1*sizeof(int)) = *(216) = 14}$ // ptr is a pointer to int
$ \color{navy}{ *(ptr1 - 1) = *(204 - 1*sizeof(int)) = *(200) = 10}$ // ptr1 is a pointer to int