int *p = new int;
int a = 10;
cout << a+p;
cout << a-p;
打印a+p,p+a,p-a会给出一个地址,但a-p会给我一个错误。为什么会这样?指针地址不是整数吗?如果是的话,a-p不应该给我一个负值吗?
就指针算术而言,指针并不等同于"表示某个地址的整数"。即使添加也没那么简单:
- 不能将指针添加到指针
- 写入
p+1
并不意味着"从p变量中获取地址值并将其增加一"。实际的地址增量取决于指向变量的大小,因此递增int64_t *p
会得到与递增int8_t *p
不同的结果
为什么我们对指针的加法和减法有这样的"奇怪行为"?简单的答案:因为它在C++标准中是这样定义的:
5.7加法运算符
对于加法,两个操作数都应具有算术或无范围枚举类型,或者一个操作数应为指向完全定义的对象类型的指针,而另一个应具有整型或无范围枚举类型。
对于减法,应符合以下条件之一:
--两个操作数都具有算术或非范围枚举类型;或
--两个操作数都是指向相同完全定义的对象类型的cv限定或cv不限定版本的指针;或
--左操作数是指向完全定义的对象类型的指针,而右操作数具有整型或非量程枚举类型。
但这一限制背后有原因(实际上在标准的同一页上有描述)。指针算术用于以下用途:如果p
指向数组中的某个元素,则p+1
指向下一个元素,p-1
指向上一个元素并且p1-p2
显示p1和p2之间的元素数。在这些术语中,p1+p2
没有任何意义,1-p
也是如此,因此它们被视为语法错误。