C++ 指针运算与转换 short x=5; 短*ptr=&x; 短*ptr2=ptr+5; cout
内存地址可能相隔十个字节,但指针加法/减法不是这样工作的。使用的值根据数据类型的大小进行缩放,因此,对于两字节C++ 指针运算与转换 short x=5; 短*ptr=&x; 短*ptr2=ptr+5; cout,c++,pointer-arithmetic,C++,Pointer Arithmetic,内存地址可能相隔十个字节,但指针加法/减法不是这样工作的。使用的值根据数据类型的大小进行缩放,因此,对于两字节短,值将是实际内存地址预期值的一半(如果您的数据类型是一字节字符,它将按照您的预期工作) 它与指针+4加法没有什么不同,它给出了数组中第五个元素的地址,而不是指针前五个字节的地址 这在标准的[expr.add]部分(来自C++17的文本)中有介绍: 当减去指向同一数组对象的元素的两个指针时,结果的类型是实现定义的有符号整数类型;该类型应与标题(21.2)中定义为std::ptrdiff_
短
,值将是实际内存地址预期值的一半(如果您的数据类型是一字节字符
,它将按照您的预期工作)
它与指针+4
加法没有什么不同,它给出了数组中第五个元素的地址,而不是指针前五个字节的地址
这在标准的[expr.add]
部分(来自C++17
的文本)中有介绍:
当减去指向同一数组对象的元素的两个指针时,结果的类型是实现定义的有符号整数类型;该类型应与
标题(21.2)中定义为std::ptrdiff_t
的类型相同
如果表达式p
和Q
分别指向同一数组对象x
的元素x[i]
和x[j]
,则表达式p-Q
的值为i− j
否则,行为未定义
当然,在你的情况下,这是一个没有意义的观点,因为根据那句话,你正在做的是未定义的行为。除非两个指针都在同一数组内(或超出该数组一个字节),否则不定义指针减法。指针算术是用指向的类型的元素表示的
ptr+5
按5*sizeof(short)
字节递增ptr
ptr2-ptr
的结果是5,因为编译器知道ptr
和ptr2
指向short
元素,因此它将两个内存地址的差除以sizeof(short)
。这两个内存地址之间的short
元素数为5
而
(long)ptr2-(long)ptr
不是指针算法,它只是普通的整数算法。它按原样计算两个内存地址的差异,而不考虑它们指向的是什么。由于在两个内存地址之间有5个short
元素,并且在您的情况下sizeof(short)
显然是2个字节,因此两个内存地址之间的距离是10个字节。指针算法的行为是代数的
如果y=x+5,那么y-x=5。如果x和y是整数,或者x和y是指向同一类型的指针,则为真
请注意,不能使用指针执行z=y+x。z不等于2x+5。它甚至不编译。您不能添加两个指针,但您可以计算两个指针之间的差异(并获得元素的计数)。很好奇您是如何理解
ptr+5
在元素数量而不是字节数方面起作用的,但对ptr2-ptr
也起作用感到惊讶。如果(ptr+N)-ptr
不等于N
,这不是更令人惊讶吗?是的,我确实这样想,但我认为有一个更好的解释。请注意,上一次计算的结果不能保证为10;将指针强制转换为long
的结果不一定是有意义的关键是将两个指针强制转换为长整数,然后执行减法运算。另一方面,ptr2-ptr
必须与元素的大小对齐。您不希望ptr+1前进一个字节。你想让它进入下一个元素。哦,我明白了!所以当我把它铸造成long时,它不再是指针算术了
short x = 5;
short*ptr = &x;
short *ptr2 = ptr+5;
cout << ptr2 - ptr << endl;
cout << (long) ptr2 - (long)ptr << endl;