Reputation: 123
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.
Upvotes: 5
Views: 30603
Reputation: 7162
The formula used by pointer substraction is:
( p2 - p1 ) == ( addr( p2 ) - addr( p1 ) ) / sizeof( T )
with T
being the type of both p1
and p2
.
int array[10];
int* p1 = array + 2;
int* p2 = array + 5;
ptrdiff_t a = p2 - p1; // 3
ptrdiff_t b = p1 - p2; // -3
Upvotes: 3
Reputation: 1
int a=5,b=6;
int *ptr=&a,*diff;
diff=ptr;
printf("%p\n",diff);
ptr++;ptr++;ptr++;ptr++;ptr++;ptr++;ptr++;ptr++;ptr++;ptr++;
printf("%p\n",ptr);
printf("diff==%td\n",(ptr-diff)*sizeof(int));
(diff-ptr) will provide the distance between two variables, but will not provide the memory gap between two pointers. Important: only the same type of pointer can be subtracted.
Upvotes: 0
Reputation: 206577
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.
Upvotes: 5
Reputation: 1
The subtraction of two pointers in array will give the distance between the two elements.
Let the address of first element i.e., is 1000 then address of second element a+1
will be 1004. Hence p1 = 1000
and p2 =1004
.
p2-p1 = (1004- 1000) /size of int = (1004-1000)/4 =4/4 =1
Upvotes: -1
Reputation: 11
The subtraction of 2 pointers give the distance in between the 2 variables. For eg.
//let the address of a is 1000 then of a+1 will be 1004
int a[]={1,2,3};
int *p1=a;
int *p2=a+1;
printf("%u",p2-p1);
The result of this will be 1 not 4. Same here in your case the the location of x and y are consecutive that is why the ans. is 1.
Upvotes: 1
Reputation: 100
Pointer arithmetic works like that. It doesn't give you differences between two addresses. Instead it will show difference between two variables as if they are stored in an array. so, no matter if your variables (of same type ) are 4 bytes, 8 bytes or 1 byte, if stored in adjacent memory location their pointer subtraction will always result in 1 or -1.
Upvotes: 1
Reputation: 32576
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.)
Upvotes: 19