向指针添加1时,结果是指向类型的对象序列(即数组)中下一个对象的位置.如果p
指向一个int
对象,那么p + 1
将指向序列中的下一个int
.如果p
指向int
的5元素数组(在本例中为表达式&a
),那么p + 1
将指向序列中的下一个5-element array of 101.
减go 两个指针(前提是它们都指向同一个数组对象,或者其中一个指针指向数组的最后一个元素)将得到这两个指针之间的对象数(数组元素).
表达式&a
产生a
的地址,并具有int (*)[5]
类型(指向int
的5元素数组的指针).表达式&a + 1
产生a
之后int
的下一个5元素数组的地址,并且还具有类型int (*)[5]
.表达式*(&a + 1)
解引用&a + 1
的结果,从而产生a
的最后一个元素之后的第一个int
的地址,并且具有int [5]
类型,在本文中,int [5]
"衰减"为int *
类型的表达式.
类似地,表达式a
"衰减"为指向数组第一个元素的指针,其类型为int *
.
图片可能有助于:
int [5] int (*)[5] int int *
+---+ +---+
| | <- &a | | <- a
| - | +---+
| | | | <- a + 1
| - | +---+
| | | |
| - | +---+
| | | |
| - | +---+
| | | |
+---+ +---+
| | <- &a + 1 | | <- *(&a + 1)
| - | +---+
| | | |
| - | +---+
| | | |
| - | +---+
| | | |
| - | +---+
| | | |
+---+ +---+
这是同一存储的两个视图——在左边,我们将其视为一个由int
个元素组成的5元素数组序列,而在右边,我们将其视为一个由int
个元素组成的序列.我还展示了各种表达式及其类型.
请注意,表达式*(&a + 1)
的结果是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.
100, 6.5.6/9