When you add 1 to a pointer, the result is the location of the next object in a sequence of objects of the pointed-to type (i.e., an array). If p
points to an int
object, then p + 1
will point to the next int
in a sequence. If p
points to a 5-element array of int
(in this case, the expression &a
), then p + 1
will point to the next 5-element array of int
in a sequence.
Subtracting two pointers (provided they both point into the same array object, or one is pointing one past the last element of the array) yields the number of objects (array elements) between those two pointers.
The expression &a
yields the address of a
, and has the type int (*)[5]
(pointer to 5-element array of int
). The expression &a + 1
yields the address of the next 5-element array of int
following a
, and also has the type int (*)[5]
. The expression *(&a + 1)
dereferences the result of &a + 1
, such that it yields the address of the first int
following the last element of a
, and has type int [5]
, which in this context "decays" to an expression of type int *
.
Similarly, the expression a
"decays" to a pointer to the first element of the array and has type int *
.
A picture may help:
int [5] int (*)[5] int int *
+---+ +---+
| | <- &a | | <- a
| - | +---+
| | | | <- a + 1
| - | +---+
| | | |
| - | +---+
| | | |
| - | +---+
| | | |
+---+ +---+
| | <- &a + 1 | | <- *(&a + 1)
| - | +---+
| | | |
| - | +---+
| | | |
| - | +---+
| | | |
| - | +---+
| | | |
+---+ +---+
This is two views of the same storage - on the left, we're viewing it as a sequence of 5-element arrays of int
, while on the right, we're viewing it as a sequence of int
. I also show the various expressions and their types.
Be aware, the expression *(&a + 1)
results in undefined behavior:
...
If the result points one past the last element of the array object, it
shall not be used as the operand of a unary * operator that is evaluated.
C 2011 Online Draft, 6.5.6/9
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…