问题
short x = 5;
short*ptr = &x;
short *ptr2 = ptr+5;
cout << ptr2 - ptr << endl;
cout << (long) ptr2 - (long)ptr << endl;
I understand that pointers store addresses, but I don't understand why the answer for both lines isn't 10.
Isn't ptr2 = address of pointer + sizeof(short) * 5?
回答1:
Pointer arithmetic is expressed in terms of elements of the type that is being pointed at.
ptr+5
increments ptr
by 5 * sizeof(short)
bytes.
The result of ptr2 - ptr
is 5, because the compiler knows that ptr
and ptr2
are pointing at short
elements, and so it divides the difference of the two memory addresses by sizeof(short)
. The number of short
elements between those 2 memory addresses is 5.
Whereas (long) ptr2 - (long)ptr
is not pointer arithmetic, it is just plain ordinary integer arithmetic. It calculates the difference of the 2 memory addresses as-is, without regard to what they are pointing at. Since there are 5 short
elements between the 2 memory addresses , and sizeof(short)
is clearly 2 bytes in your case, the distance between the 2 memory addresses is 10 bytes.
回答2:
The memory addresses may be ten bytes apart but that's not how pointer addition/subtraction works. The values used are scaled based on the size of the data type so, for a two-byte short
, values will be half of what you would expect from the actual memory addresses (if your data type was the one byte char
, it would work as you seem to expect).
It's really no different to a pointer + 4
addition which gives you the address of the fifth element in the array, not the address five bytes befond the pointer.
This is covered in the [expr.add]
section of the standard (text from 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.
Of course, this is a moot point in your case anyway since, as per that quote, what your are doing is undefined behaviour. Pointer subtraction is not defined unless both pointers are within the same array (or one byte beyond said array).
回答3:
Pointer arithmetic does behave algebraically.
if y = x + 5, then y - x = 5. This is true if x and y are integers, or x and y are pointers to the same type.
Note that you can not do z = y + x with pointers. z does NOT equal 2x + 5. It does not even compile. You cannot add two pointers, but you can take the difference between two pointers (and get the count of elements).
来源:https://stackoverflow.com/questions/53623664/pointer-arithmetic-and-casting