指针运算和转换
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+5
将 ptr
递增 5 * sizeof(short)
字节。
ptr2 - ptr
的结果是5,因为编译器知道ptr
和ptr2
指向的是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。它甚至无法编译。您不能将两个指针相加,但可以取两个指针之间的差值(并获取元素的数量)。
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
andQ
point to, respectively, elementsx[i]
andx[j]
of the same array objectx
, the expressionP - Q
has the valuei − j
; otherwise, the behavior is undefined.
当然,无论如何,这在你的案例中是一个有争议的问题,因为根据那句话,你正在做的是未定义的行为。指针减法未定义,除非两个指针都在同一数组内(或超出所述数组一个字节)。
指针运算是根据所指向的类型的元素来表示的。
ptr+5
将 ptr
递增 5 * sizeof(short)
字节。
ptr2 - ptr
的结果是5,因为编译器知道ptr
和ptr2
指向的是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。它甚至无法编译。您不能将两个指针相加,但可以取两个指针之间的差值(并获取元素的数量)。