I was playing with pointers in order to fully get the concept and then wanted to subtract two pointers expecting the distance between these two addresses or something, but apparently I was wrong, so here is my code.
int x = 5, y = 7;
int *p = &y;
int *q = &x;
printf("p is %d\nq is %d\np - q is %d", p, q, (p - q));
Why does the program output p - q is 1
? Thank you.
It is undefined behavior. According to the standard (N1570
):
6.5.6 Additive operators
....
9 When two pointers are subtracted, both shall point to elements of the same array object, or one past the last element of the array object; the result is the difference of the subscripts of the two array elements.
Note that when allowed, the result is the subscripts difference. So if pointers point to two sequential elements of the same type, the subtraction gives 1
, regardless of the size of the type. (This is perhaps the reason why you get 1
in your concrete case.)
Your particular case is cause for undefined behavior since p
and q
point to unrelated objects.
You can make sense of p-q
only if p
and q
point to the same array/one past the last element of the same array.
int array[10];
int* p = &array[0];
int* q = &array[5];
ptrdiff_t diff1 = q - p; // Valid. diff1 is 5
ptrdiff_t diff2 = p - q; // Valid. diff2 is -5
q - p
is 5 in this case since they point to elements of the array that are 5 elements apart.
Put another way, p+5
is equal to q
. If you start from p
and step over 5 elements of the array, you will point to the same element of the array that q
points to.
As an aside, don't use the format specifier %d
for printing pointers. Use %p
. Use %td
for ptrdiff_t
.
printf(" p is %p\n q is %p\n p-q is :%td", p, q, p-q);`
// ^^ ^^
See http://en.cppreference.com/w/c/io/fprintf for the valid format specifiers for the different types.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With