int **p
This is a pointer to pointer to int
. So p
could point to a single pointer, or an array of pointers. In turn *p
could point to a single int
, or an array of int
. Exactly what is behind p
is not expressed in its type.
int *p2[5]
This is an array, of length 5, of pointer to int
. Here, p2
is an array of length 5. No doubt about that. But what about p2[i]
? They could be pointers to a single int
, or pointers to an array. Again, the information is not present in the type.
In the question you state:
p2
is a pointer.
That statement is not correct. p2
is an array, and not a pointer. In certain contexts, p2
may decay to a pointer, but it is not in itself a pointer.
Note that if you start with the variable p2
, then you can assign it to p
like this:
p = p2;
This is an array, p2
, decaying to a pointer. At this point you know that p
points to an array of pointer to int
.
However, if all you have is some p
of type int**
then you do not know the p
points to an array. It might not. In other words, the type of a pointer does not fully describe what it points to.
You seem to be getting quite confused about the difference between an array and a pointer. They are not the same. An array is not a pointer. An array can decay to a pointer. A pointer can point at an array.
Perhaps the key difference is that an array always refers to the same variables. On the other hand, a pointer can be made to point at different variables. Another obvious difference is that an array variable defines storage. On the other hand, a defining a pointer variable does not. You must always assign the pointer to the address of some other object.