# pointer arithmetic

Discussion in 'C Programming' started by barikat@gmail.com, Jun 23, 2006.

1. ### Guest

int a[5];
int *Ptr1, *Ptr2;

Ptr1 = a;
Ptr1++;
Ptr2 = a;

printf("Ptr1 : %p\n", Ptr1);
printf("Ptr2 : %p\n\n", Ptr2);

Ptr1 = Ptr1 - Ptr2;

---------------------
Ptr1 : 0012FF6C
Ptr2 : 0012FF68

Ptr1 : 00000001
Ptr2 : 0012FF68
----------------------

i couldnt understand, Ptr1 = Ptr1 - Ptr2; line is a pointer arithmetic,
and Ptr1 should be 0012FF6C, because Ptr1 is a[1] and Ptr2 is a[0]
a[1] - a[0] should be a[1] so 0012FF6C
probably i am wrong but i wanted to ask
, Jun 23, 2006

2. ### Joshua ShinavierGuest

wrote:
> a[1] - a[0] should be a[1] so 0012FF6C
> probably i am wrong but i wanted to ask

Yes, that's wrong.
Joshua Shinavier, Jun 23, 2006

3. ### Walter RobersonGuest

In article <>,
<> wrote:
> int a[5];
> int *Ptr1, *Ptr2;

> Ptr1 = a;
> Ptr1++;
> Ptr2 = a;

> printf("Ptr1 : %p\n", Ptr1);
> printf("Ptr2 : %p\n\n", Ptr2);

> Ptr1 = Ptr1 - Ptr2;

Ptr1 - Ptr2 is an arithmetic value which is the difference in offsets
in units of the type pointed to.

>Ptr1 : 0012FF6C
>Ptr2 : 0012FF68

difference is sizeof(int), and to calculate the offset difference
you have to take the raw address difference and divide it by the
sizeof(int), so the pointer difference will turn out to be 4/4 = 1.

But then you take that arithmetic value 1, and you assign it into
a pointer, which is going to lead to implementation-defined behaviour.

>Ptr1 : 00000001
>Ptr2 : 0012FF68

>i couldnt understand, Ptr1 = Ptr1 - Ptr2; line is a pointer arithmetic,

Right, *pointer* arithmetic, not *address* arithmetic.

>and Ptr1 should be 0012FF6C, because Ptr1 is a[1] and Ptr2 is a[0]

Ptr1 is not a[1], Ptr1 is &a[1] which is (&a + 1) in pointer arithmetic,
which is (unsigned char *)&a + 1 * sizeof(int) in address arithmetic.
Similarily, Ptr2 is not a[0], Ptr2 is &a[0], which is (&a + 0) in
pointer arithmetic, which is (unsigned char *)&a + 0 * sizeof(int)

>a[1] - a[0] should be a[1] so 0012FF6C

a[1] - a[0] would be the -contents- of a[1] (an uninitialized integer)
minus the -contents- of a[0] (another uninitilized integer).

&a[1] - &a[0] would be (&a + 1) - (&a + 0) in pointer arithemetic,
which simplifies to 1 in pointer arithmetic. In address arithmetic,
it would come out as 4 (sizeof int) on your particular machine.
--
Prototypes are supertypes of their clones. -- maplesoft
Walter Roberson, Jun 23, 2006
4. ### Guest

wrote:
> int a[5];
> int *Ptr1, *Ptr2;
>
> Ptr1 = a;
> Ptr1++;
> Ptr2 = a;
>
> printf("Ptr1 : %p\n", Ptr1);
> printf("Ptr2 : %p\n\n", Ptr2);
>
> Ptr1 = Ptr1 - Ptr2;
>
> ---------------------
> Ptr1 : 0012FF6C
> Ptr2 : 0012FF68
>
> Ptr1 : 00000001
> Ptr2 : 0012FF68
> ----------------------
>
> i couldnt understand, Ptr1 = Ptr1 - Ptr2; line is a pointer arithmetic,
> and Ptr1 should be 0012FF6C, because Ptr1 is a[1] and Ptr2 is a[0]
> a[1] - a[0] should be a[1] so 0012FF6C
> probably i am wrong but i wanted to ask

First of all a[1] - a[0] is not the same thing as Ptr1 - Ptr2. a[1] and
a[0] refer to the values of the int's stored in the first and second
elements of the array a. Ptr1 and Ptr2 are pointers to the locations of
the first and second elemts of the array a. If what you wanted was the
same thig as a[1] - a[0] you need *Ptr1 - *Ptr2.

Secondly the subtraction of one pointer from another is not going to
give you a pointer to the location that the first pointer is pointing
to, which is what you seem to be saying you were expecting although I
am not sure.
, Jun 23, 2006
5. ### Neil FergusonGuest

<> wrote in message
news:...
> int a[5];
> int *Ptr1, *Ptr2;
>
> Ptr1 = a;
> Ptr1++;
> Ptr2 = a;
>
> printf("Ptr1 : %p\n", Ptr1);
> printf("Ptr2 : %p\n\n", Ptr2);
>
> Ptr1 = Ptr1 - Ptr2;
>
> ---------------------
> Ptr1 : 0012FF6C
> Ptr2 : 0012FF68
>
> Ptr1 : 00000001
> Ptr2 : 0012FF68
> ----------------------
>
> i couldnt understand, Ptr1 = Ptr1 - Ptr2; line is a pointer arithmetic,
> and Ptr1 should be 0012FF6C, because Ptr1 is a[1] and Ptr2 is a[0]
> a[1] - a[0] should be a[1] so 0012FF6C
> probably i am wrong but i wanted to ask
>

If you live at 301 Elm Street and your friend lives at 303 Elm Street and
houses on your side of the street are odd-numbered, how many houses away
from you does your friend live?

N
Neil Ferguson, Jun 23, 2006
6. ### Keith ThompsonGuest

writes:
> int a[5];
> int *Ptr1, *Ptr2;
>
> Ptr1 = a;
> Ptr1++;
> Ptr2 = a;
>
> printf("Ptr1 : %p\n", Ptr1);
> printf("Ptr2 : %p\n\n", Ptr2);
>
> Ptr1 = Ptr1 - Ptr2;
>
> ---------------------
> Ptr1 : 0012FF6C
> Ptr2 : 0012FF68
>
> Ptr1 : 00000001
> Ptr2 : 0012FF68
> ----------------------
>
> i couldnt understand, Ptr1 = Ptr1 - Ptr2; line is a pointer arithmetic,
> and Ptr1 should be 0012FF6C, because Ptr1 is a[1] and Ptr2 is a[0]
> a[1] - a[0] should be a[1] so 0012FF6C
> probably i am wrong but i wanted to ask

Compile with warnings enabled.

The "%p" format expects an argument of type void*, which is not
compatible with int*. It may happen to work if void* and int* happen
to have the same representation (which they very commonly do), but you
can avoid any possible problems by converting the argument:

printf("Ptr1 : %p\n", (void*)Ptr1);
printf("Ptr2 : %p\n\n", (void*)Ptr2));

This is one of the few cases where a cast is actually appropriate.

Subtracting one pointer from another yields a result of the integer
type ptrdif_t. (This is valid only if both pointers point to elements
of the same array, which is the case here; otherwise it invokes
undefined behavior.) So you're trying to assign an integer value to a
pointer variable. The language allows you to convert an integer value
to a pointer type (the result is implementation-defined and very
likely not useful), but you can only do so with a cast; there is no
implicit conversion from integers to pointers (other than the special
case of a null pointer constant). So your assignment is a constraint
violation, and the compiler is required to issue a diagnostic message.
(If yours did so, you didn't bother to tell us.) The diagnostic can
be just a warning (if the compiler supports this implicit conversion
as an extension), but it's required for any conforming compiler. You
example enabling certain warnings, to make it conforming.

Also, you posted only a code fragment; in particular, you didn't show
us all the code that produces the output you showed us. Next time, if
at all possible, please post a small, complete, self-contained,
compilable program. The fragment you posted happened to be clear
enough, but you can never be sure of that; quite often the seemingly
irrelevant piece of code that someone thinks isn't worth posting is
just the thing that causes or explains the problem.

--
Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Keith Thompson, Jun 23, 2006
7. ### Guest

Neil Ferguson wrote:
> <> wrote in message
> news:...
> > int a[5];
> > int *Ptr1, *Ptr2;
> >
> > Ptr1 = a;
> > Ptr1++;
> > Ptr2 = a;
> >
> > printf("Ptr1 : %p\n", Ptr1);
> > printf("Ptr2 : %p\n\n", Ptr2);
> >
> > Ptr1 = Ptr1 - Ptr2;
> >
> > ---------------------
> > Ptr1 : 0012FF6C
> > Ptr2 : 0012FF68
> >
> > Ptr1 : 00000001
> > Ptr2 : 0012FF68
> > ----------------------
> >
> > i couldnt understand, Ptr1 = Ptr1 - Ptr2; line is a pointer arithmetic,
> > and Ptr1 should be 0012FF6C, because Ptr1 is a[1] and Ptr2 is a[0]
> > a[1] - a[0] should be a[1] so 0012FF6C
> > probably i am wrong but i wanted to ask
> >

> If you live at 301 Elm Street and your friend lives at 303 Elm Street and
> houses on your side of the street are odd-numbered, how many houses away
> from you does your friend live?
>
> N

Depends on the direction you go
, Jul 1, 2006
8. ### Guest

wrote:
> Neil Ferguson wrote:
> > <> wrote in message
> > news:...
> > > int a[5];
> > > int *Ptr1, *Ptr2;
> > >
> > > Ptr1 = a;
> > > Ptr1++;
> > > Ptr2 = a;
> > >
> > > printf("Ptr1 : %p\n", Ptr1);
> > > printf("Ptr2 : %p\n\n", Ptr2);
> > >
> > > Ptr1 = Ptr1 - Ptr2;
> > >
> > > ---------------------
> > > Ptr1 : 0012FF6C
> > > Ptr2 : 0012FF68
> > >
> > > Ptr1 : 00000001
> > > Ptr2 : 0012FF68
> > > ----------------------
> > >
> > > i couldnt understand, Ptr1 = Ptr1 - Ptr2; line is a pointer arithmetic,
> > > and Ptr1 should be 0012FF6C, because Ptr1 is a[1] and Ptr2 is a[0]
> > > a[1] - a[0] should be a[1] so 0012FF6C
> > > probably i am wrong but i wanted to ask
> > >

> > If you live at 301 Elm Street and your friend lives at 303 Elm Street and
> > houses on your side of the street are odd-numbered, how many houses away
> > from you does your friend live?
> >
> > N

> Depends on the direction you go

Not really, you both always live at the same location relative to each
other. But you are right that you can take the long way to get there
but that does not make your houses any farther apart.
, Jul 1, 2006