Given this code:
int *p, *q;
p = (int *) 1000;
q = (int *) 2000;
What is q - p
and how?
Given this code:
int *p, *q;
p = (int *) 1000;
q = (int *) 2000;
What is q - p
and how?
It's actually undefined, according to the standard. Pointer arithmetic is not guaranteed to work unless the pointers are pointing to either an element in the same array or just beyond the last element of the array.
The relevant section of the standard is 6.5.6:9 (n1362 draft of c1x but this hasn't changed since c99) which states:
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.
You'll most likely get 250 if your int
datatype is 4 bytes but there's no guarantee. Undefined behaviour (unlike implementation-defined behaviour) means just that. Anything can happen, up to an including the total destruction of a large proportion of space-time.
A refresher course:
q - p is 250.
2000 - 1000 = 1000
1000 / sizeof(int) = 250
pointer arithmetic, assuming sizeof(int) is 4.
struct foo { int ar[1000]; } big[10];
char small[10];
struct foo *fs, *fe;
char *ss, *se;
fs = &big[0]; fe = &big[9];
ss = &small[0]; se = &small[9];
fe - fs == se - ss;
That is, the difference between the two pointers in this case is the number of array elements between them. In this case it is 0, 1, ... 8 or 9 elements.
Those are pointers ... assigned to the address 1000, and 2000 ... looking for troubles?
q-p
supposed to return how many steps with increment you should do to go from p
to q
. Which is 1000 / sizeof(int)
and equals 250. Remember q++
will actually go to the next element of type int, not in the middle of it, so it should add 4 to the actual value of the pointer. Hence the result.
The answer:
q-p is going to be 250, assuming you're on a machine where an int
is 4 bytes.
The calculation is:
q - p = 1000 1000 / 4 (size of an int) = 250
The idea behind it:
The idea behind pointer arithmetic is that, if you have an int
pointer to 1000 and an int
pointer to 2000, and ask for the difference, you're not asking what's 2000-1000. What you're asking is, how many int
's can I fit between the two.
This is very convenient for all sorts of operations, for example:
int *i = 100;
i++; // This is **not** 101, it is 104, cause you actually want the next place an int could fit in memory.
This especially comes in handy when dealing with arrays. An array of ints (defined int arr[10]
) is basically treated like a pointer. When you write arr[5]
, the compiler translates it to *(arr + 5)
, i.e., add 5 to the int
pointer called arr
, and get the value at that address.
The reason this works, is because arr + 5
does not mean "add 5 to the value of arr", it means "add whatever is neceassary to the value of arr to go forward 5 int
s", or, more precisely, "add 5 * sizeof(int)
to the value of arr"