如果我说,
int a[] = {1, 2, 3, 4, 5};
int *p = a;
现在,如果我写p + 1 + 2
它会和((p + 1) + 2)
?有任何标准参考证明这是错误的吗?
如果我说,
int a[] = {1, 2, 3, 4, 5};
int *p = a;
现在,如果我写p + 1 + 2
它会和((p + 1) + 2)
?有任何标准参考证明这是错误的吗?
只要你不超出范围。例如,在这个:
int a[] = {1, 2, 3, 4, 5};
int *p = (a + 10) - 9;
int *q = a + (10 - 9);
赋值p
调用未定义的行为,而赋值q
不调用。
但是,只要您保持在范围内,您就会期望关联性保持不变。
顺便说一句,请注意,在您的问题中,您给出的两件事根据定义是相同的,因为加法(好吧,无论如何,范围内的加法)是左关联的。也就是说,x + y + z == (x + y) + z
,不是x + (y + z)
。
§3.7.4.3
2
A pointer value is a safely-derived pointer to a dynamic object only if it has pointer-to-object type and it is one of the following: ... the result of well-defined pointer arithmetic (5.7) using a safely-derived pointer value;
§ 5.7
3
The result of the binary + operator is the sum of the operands.
对我来说听起来很合法。
指针和整数之间的加法在 C++11 中定义如下 (5.7/5):
如果表达式 P 指向数组对象的第 i 个元素,则表达式 (P)+N(等效于 N+(P))和 (P)-N(其中 N 的值为 n)分别指向,数组对象的 i + n-th 和 i - n-th 元素,前提是它们存在。
下一句讨论了数组末尾的指针。
因此,涉及指针的加法与涉及索引的加法“相同”,这当然是关联的。由此您可以推断,如果数组元素存在(或超过末尾),那么涉及指针的加法是关联的。
如果您的算术超出了指针指向的数组的边界,那么行为是未定义的,因此特别不需要是关联的。
我相信在实践中是的,但在理论上可能不是。
您要问是否与标准p + 3
相同,((p + 1) + 2)
但标准说指针运算仅在数组内部或仅在其末尾之后的一个元素中才有意义。
指针实际上只是数字,所以是的,加法将以您描述的方式关联。
编辑:请参阅下面来自 delnan 的评论 - 虽然是的,加法将是关联的,但我关于指针只是数字的说法并不完全正确。