This is how pointer arithmetic works. Consider:
p1 = (x*)100; // invalid memory address, just an example!
p2 = p1 + 1;
At this point, p2
will not have the value 101
, but rather 100 + sizeof(x)
(which let's say is 8, so 108). It has been incremented not by one, but by one multiple of sizeof(x)
! Conversely, subtracting an integer from a pointer actually subtracts multiples of sizeof(the pointed to type)
.
So now if you do int diff = p2 - p1
, you would certainly expect to get 1
back, not 8
! Otherwise, subtracting the number you just added would not yield the original value. Therefore, subtracting one pointer from another yields not the difference in memory addresses but the number of elements between the two pointers.
Moreover, the standard mandates that pointer subtraction is meaningless unless the two pointers point to elements in the same array (more correctly, it's undefined behavior and you are also allowed to use a pointer to "one past the last element" even if there is no such object there).
Finally, what if the compiler does not know the size of the pointed to type (i.e. the pointers are void*
)? In this case, pointer arithmetic is not allowed at all. For example:
void* p = 100;
void* x = p + 1; // does not compile1
1 Some compilers may provide pointer arithmetic on void*
as an extension to the language specification. In this case this statement can indeed compile and the result would depend on the specification of said extension (e.g. gcc would end up with the value 101).
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…