In most (though not all) contexts an array "decays" into a pointer to its first element. This is why ch
and &ch[0]
are the same in your example (array element access has higher precedence than the "address of" operator, so the latter could also be written as &(ch[0])
).
The remaining &ch
is one case where the array does not decay into a pointer; instead, you get the address of the array. Naturally enough, this is the same as the address of the first element of the array - however, importantly, it has a different type; it is of type char (*)[7]
, i.e. a pointer to an array of char with 7 elements. The other two pointers are of type char *
, i.e. a pointer to an individual char
.
Since sptr
is a pointer, &sptr
is the address of that pointer and naturally will be different. &sptr[0]
is equivalent to sptr + 0
, which is of course equal to sptr
.
That you do not see why sptr
and &sptr
yield different addresses indicates a misunderstanding of what a pointer is. A pointer is a fixed-size object with a value that can refer to (point at) some arbitrary object of a particular type. Because it is an object itself, a pointer can be made to point at a different object. An array variable, on the other hand, always (during its lifetime) refers to the same array object.
In your example output:
00037CD0 00FDFD5C 00037CD0
The first value, 00037CD0, is the location to which sptr
points - that is, it is the location in memory of the string constant "132456". The second value, 00FDFD5C, is the address of the sptr
variable itself. What this shows is that there is a pointer object at address 00FDFD5C which holds the value 00037CD0.
Essentially, the difference between the two cases boils down to this:
- The address of an array is the same as the address of its first element
- The address of a pointer, on the other hand, bears no relation to what the pointer currently points to.