Pointer to array of elements when dereferenced return an address. Since it is holding the address of the first element of the array, dereferencing it should return a value.
Here is a simple, less technical explanation.
How are you setting p? = arr;
How are you setting ptr? = &arr;
Your question really has nothing to do with arrays at all. arr could be literally any type and the answer would be the same: & gets the address of arr, so whatever arr is, ptr is storing its address while p is storing arr itself.
If you do *ptr, you will dereference that address and thus get a value equal to p.
int arr = 3;
// clearly these are different!
int p = arr;
int* ptr = &arr;
Similarly
int x = 3;
int* arr = &x;
// clearly these are different!
int* p = arr;
int** ptr = &arr;
// so of course they dereference differently
printf("*p = %d, *ptr = %p\n", *p, *ptr);