In contrast, if you declare extern char *p, it tells the compiler that p is a pointer (a four-byte
object on many contemporary machines), and the object pointed to is a character. To get the char, you
have to get whatever is at address p, then use that as an address and get whatever is there. Pointer
accesses are more flexible, but at the cost of an extra fetch instruction, as shown in Diagram B.
Figure B. A Pointer Reference
What Happens When You "Define as Pointer/Reference as Array"
We now can see the problem that arises when an external array is defined as a pointer and referenced
as an array. The indirect type of memory reference that is done for a pointer (see Diagram B) occurs
when we really want a direct memory reference (as shown in Diagram A). This occurs because we
told the compiler that we had a pointer, and is shown in Diagram C.
Figure C. A Subscripted Pointer Reference
Contrast the access shown in Diagram C on page 101
char * p = "abcdefgh"; ... p[3]
with Diagram A on page 99
char a[] = "abcdefgh"; ... a[3]
They both get you a character 'd' but they get there by very different look-ups.
When you write extern char *p, then reference it as p[3], it's essentially a combination of
Diagrams A and B. You do an indirect reference as in diagram 2, then you step forward to the offset
represented by the subscript as in diagram 1. More formally, the compiler emits code to: