tags:

views:

209

answers:

7

When we subtract a pointer from another the diffrence is not equal to how many bytes they are apart but equal to how many integers(if pointing to integers) they are apart.Why so?

+6  A: 

So that the answer is the same even on platforms where integers are different lengths.

ptomato
So how do i remmber this stinky fact :( Drives me dead :(
fahad
But when u perform addition in pointers like *p+2 if its an int pointer it moves 4 positions forward..Why ?
fahad
@fahad: if you want the byte count between two addresses, you can cast the two addresses to `char *` and then take the difference. Where do you get the idea that the alternative is better? Did you program in assembler before C? The C mechanism is sound - array indexing depends on it (because a subscripting operation adds N to the base address, but that is N units of the size of what is in the array).
Jonathan Leffler
@fahad: Your '*p+2' example: if p is a 'short **p', then '*p+2' would move forward 4 bytes on most machines (all where sizeof(short)==2). If you meant '*(p+2)' which is equivalent to 'p[2]', then if your declaration is 'short *p', the address would be 4 bytes forward. Note that 'a[i]' === *(a+i)' (and, for the IOCCC fanatics, 'a[i] === i[a]').
Jonathan Leffler
@fahad - *p+2 will add 2 to the contents of memory pointed by p. *(p+2) you can access the contents of memory pointed by (p + 2*sizeof(datatype of p)). It depends on the datatype of the pointer p.
Praveen S
it makes life a lot easier for the programmer, consider how much more work it would be if it was the alternative: if something in the program would change or you want to make it run correctly on different systems...
Emile Vrijdags
+15  A: 

The idea is that you're pointing to blocks of memory

+----+----+----+----+----+----+
| 06 | 07 | 08 | 09 | 10 | 11 | mem
+----+----+----+----+----+----+
| 18 | 24 | 17 | 53 | -7 | 14 | data
+----+----+----+----+----+----+

If you have int* p = &(array[5]) then *p will be 14. Going p=p-3 would make *p be 17.

So if you have int* p = &(array[5]) and int *q = &(array[3]), then p-q should be 2, because the pointers are point to memory that are 2 blocks apart.

When dealing with raw memory (arrays, lists, maps, etc) draw lots of boxes! It really helps!

glowcoder
By the way, if I can stress one thing, `pointers are hard`. Yes, seasoned C++ veterans can whip them in shape with ease, but learning exactly when and how to use them effectively is not just a simple task.
glowcoder
@glowcoder: so can seasoned C coders - which is perhaps more apposite in a question tagged C.
Jonathan Leffler
@glowcoder I've *always* found pointers trivially easy, and so have most of the programmers I've known and those I've taught.
anon
Paul R
@Neil: FWIW, it took me a fair amount of thinking to "get" pointers, and I felt like I was doing something not quite normal for at least months afterwards. This was after learning about four assembly languages, so it wasn't a lack of knowledge of the underlying mechanism. Of course, this was in Pascal, where pointers looked like afterthoughts and tended not to be mentioned much in the books.
David Thornley
@David I learned assembler before C, and the transition seemed very simple. I still have dificulties with them when I go back to Delphi though - mostly trying to remember the wretched syntax.
anon
@Paul you're right, because I'm using array syntax, it automatically dereferences it for me... I'll fix that :-) @Jonathan You're absolutely right on that! @Neil You're probably a smart guy, who is fortunate enough to deal with other smart guys. That doesn't change the fact that pointers are hard. :-)
glowcoder
@glowcoder: True; in fact, even seasoned C veterans have troubles with pointers sometimes, though they'd never admit it. They'd also never admit how insanely often they spend hours tracking down pointer-related bugs (yes, even *with* Valgrind)...
BlueRaja - Danny Pflughoeft
@glowcoder: you don't need the braces, e.g. `int *p = ` is perfectly fine, as is `int *p = array + 5;`.
Paul R
@David Thornley:Then no wonder you had trouble getting them. Pointers in Pascal have horrible syntax which makes them a nightmare to use. When I first tried to learn pointers (this was in Pascal), I tried for **four months** and had to give up, as I simply couldn't get what this all was about. Then, about a year later I learned C. The pointers were simply there, and I grokked them with ease, without really thinking about it. They just *made sense* from the beginning. Sometimes I wonder, do all these people who complain about pointers being "hard" have a Pascal background?
slacker
@slacker no, they either have a Java background, or they have no background. Note the homework tag. :-)
glowcoder
@glow: i think the two pointers are only 1 variable apart in your example ..
fahad
+4  A: 

Say you have an array of 10 integers:

int intArray[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

Then you take a pointer to intArray:

int *p = intArray;

Then you increment p:

p++;

What you would expect, because p starts at intArray[0], is for the incremented value of p to be intArray[1]. That's why pointer arithmetic works like that. See the code here.

Jeff Kelley
+1 Good point :)
Binary Worrier
A: 

When applying arithmetic operations on pointers of a specific type, you always want the resulting pointer to point to a "valid" (meaning the right step size) memory-address relative to the original starting-point. That is a very comfortable way of accessing data in memory independently from the underlying architecture.

If you want to use a different "step-size" you can always cast the pointer to the desired type:

int a = 5;
int* pointer_int = &a;
double* pointer_double = (double*)pointer_int; /* totally useless in that case, but it works */
das_weezul
+7  A: 

Because everything in pointer-land is about offsets. When you say:

int array[10];
array[7] = 42;

What you're actually saying in the second line is:

*( &array[0] + 7 ) = 42;

Literally translated as:

* = "what's at"
(
  & = "the address of"
  array[0] = "the first slot in array"
  plus 7
)
set that thing to 42

And if we can add 7 to make the offset point to the right place, we need to be able to have the opposite in place, otherwise we don't have symmetry in our math. If:

&array[0] + 7 == &array[7]

Then, for sanity and symmetry:

&array[7] - &array[0] == 7
eruciform
A: 

"When you subtract two pointers, as long as they point into the same array, the result is the number of elements separating them"

Check for more here.

Praveen S
nice quote :) i want its explanation ;P
fahad
@fahad: because pointers do not point to bytes necessarily, they point to objects of the type used in defining them. Pointer arithmetic is done in terms of numbers of those objects too.
JeremyP
@fahad - Probably you may want to tell us what is the size of basic datatypes according to you?int, char and float to start with. Based on that you can dig into pointer arithmetic which is different than normal arithmetic. (not fully but it has its rules ;))
Praveen S
A: 

@fahad Pointer arithmetic goes by the size of the datatype it points.So when ur pointer is of type int you should expect pointer arithmetic in the size of int(4 bytes).Likewise for a char pointer all operations on the pointer will be in terms of 1 byte.

The Stig