In C language, language supported array names themselves pointers to those arrays.
For example,
int arr[10]; Here, arr is a pointer.
char x[20]; Here x is character pointer. Because of this reason only while reading data into a string using scanf we dont use address operator.
scanf(%s", x);
However, these pointer can be critically called as constant pointers. That is, we can not apply increment or decrement operators on them unlike dynamic pointers. That is, when an array is declared some memory is allocated and its address is assigned the array names. We can not make it to change to some other memory later.
int *p;
p=(int*) malloc(100);
This is dynamic pointer on that we can do p++, p-- etc.
However,
int q[10];
Though q is a pointer, we can not do q++ or q--;
Thus in your printf statement arr value is printed 0023FF40 while p+n where n is 5 has returned as 0023FF54. It is acceptable, on your machine integer might be taking 4 bytes. Thus, 0023FF40+4*5=0023FF54. Hexadecimal addition. That is
0x0023FF40
0x00000014
----------------
0x0023FF54