p is a pointer to an array of three elements, such as:
βββββββ¬ββββββ¬ββββββ
β β β β
βββββββ΄ββββββ΄ββββββ
^
ββ p
Note that it points to the entire array, and not to one of its elements.
The expression is *p[i]considered as *(p[i])due to the priority of the operator (which is equivalent *(*(p + i))). This means that you are indexing a pointer to an array. If you do p[1], for example, you move the pointer to the "next" array and try to dereference it:
βββββββ¬ββββββ¬ββββββ
β β β β
βββββββ΄ββββββ΄ββββββ
^
ββ p + 1
, , undefined. , (*p)[i] ( *((*p) + i)), , . , . , :
βββββββ¬ββββββ¬ββββββ
β β β β
βββββββ΄ββββββ΄ββββββ
^
ββ *p
, . , , (*p)[1], :
βββββββ¬ββββββ¬ββββββ
β β β β
βββββββ΄ββββββ΄ββββββ
^
ββ (*p) + 1
const char*, cout.