指针运算和转换

Pointer arithmetic and casting

short x = 5;        
short*ptr = &x;     
short *ptr2 = ptr+5; 

cout << ptr2 - ptr << endl;
cout << (long) ptr2 - (long)ptr << endl;

我知道指针存储地址,但我不明白为什么这两行的答案都不是 10。

不是ptr2 = 指针地址+ sizeof(short) * 5吗?

内存地址可能相隔十个字节,但这不是指针addition/subtraction的工作方式。使用的值是 scaled 基于数据类型的大小,因此,对于双字节 short,值将是实际内存地址的一半(如果您的数据类型是单字节 char,它会像您预期的那样工作)。

它与 pointer + 4 加法并没有什么不同,后者为您提供数组中第五个元素的地址,而不是 指针后五个字节的地址。

这包含在标准的 [expr.add] 部分(文本来自 C++17):

When two pointers to elements of the same array object are subtracted, the type of the result is an implementation-defined signed integral type; this type shall be the same type that is defined as std::ptrdiff_t in the <cstddef> header (21.2).

If the expressions P and Q point to, respectively, elements x[i] and x[j] of the same array object x, the expression P - Q has the value i − j; otherwise, the behavior is undefined.


当然,无论如何,这在你的案例中是一个有争议的问题,因为根据那句话,你正在做的是未定义的行为。指针减法未定义,除非两个指针都在同一数组内(或超出所述数组一个字节)。

指针运算是根据所指向的类型的元素来表示的。

ptr+5ptr 递增 5 * sizeof(short) 字节。

ptr2 - ptr的结果是5,因为编译器知道ptrptr2指向的是short个元素,所以把sizeof(short) 的两个内存地址。这两个内存地址之间 short 个元素的数量是 5.

(long) ptr2 - (long)ptr不是指针运算,它只是普通的整数运算。它按原样计算 2 个内存地址的差异,而不考虑它们指向的内容。由于 2 个内存地址之间有 5 个 short 元素,并且 sizeof(short) 在您的情况下显然是 2 个字节,因此 2 个内存地址之间的距离为 10 个字节。

指针运算确实表现得像代数。

如果 y = x + 5,则 y - x = 5。如果 x 和 y 是整数,或者 x 和 y 是指向同一类型的指针,则为真。

请注意,您不能使用指针执行 z = y + x。 z 不等于 2x + 5。它甚至无法编译。您不能将两个指针相加,但可以取两个指针之间的差值(并获取元素的数量)。