Jishan
Jishan

Reputation: 1684

Using negative number as array index

I came along a competitive question that asks the output of the following:

#include <stdio.h>
int main()
{
    int a[] = {0,1,2,3,4};
    int i, *ptr;
    for(ptr = a+4, i=0; i <=4; i++)
    printf("%d", ptr[-i]);
    return 0;
}

I did read this topic: Are negative array indexes allowed in C? However it was unclear to me how the -ve symbol generates the array in the reverse order, ie. 4, 3, 2, 1, 0.

Upvotes: 24

Views: 4244

Answers (6)

frogatto
frogatto

Reputation: 29285

As I mentioned in my comment in C/C++

a[b] == *(a+b) == b[a]

For your case all of these is fine

printf("%d", *(a + 4 - i));
printf("%d", a[4 - i]);
printf("%d", 4[a - i]);
...

Upvotes: 2

Jerry Coffin
Jerry Coffin

Reputation: 490098

a+4 gives a pointer to the fifth element of a. So ptr refers to that location.

Then the loop counts i from 0 up to (and including) 4.

The dereference ptr[-i] is equivalent to *(ptr - i) (by definition). So, since i is 0 and ptr is a+4, it's equivalent to a+4-0, then a+4-1, then a+4-2, and so on until a+4-4, which is (obviously enough) equal to a.

Upvotes: 3

Vlad from Moscow
Vlad from Moscow

Reputation: 310940

In is for statement

for(ptr = a+4, i=0; i <=4; i++)

pointer ptr is set to a+4 It could be done also the following way

ptr = &a[4];

If you tray to output the value pointed to by the pointer as for example

printf( "%d\n", *ptr );

you will get 4. That is the pointer points to the last element of the array.

Inside the loop there is used expression ptr[-i] . for i equal to 0 it is equivalent to ptr[0] or simply to *ptr that is the last element of the array will be outputed. For i equal to 1 expression ptr[-i] is equivalent to a[4 - 1] or simply a[3]. When iequal to 2 when expression ptr[-i] is equivalent to a[4 - i] that is a[4 - 2] that in turn is a[2] and so on. SO you will get

4321

Upvotes: 3

macfij
macfij

Reputation: 3209

ptr[-i] decays into *(ptr + (-i)). At the first iteration, when i = 0, ptr[-i] accesses last element of a array, because initially ptr was set to be equal a + 4, which means - take address of beginning of a and add 4 * sizeof(int) (because ptr was of size int). On every next iteration, when i is incremented, previous element of array is accessed.

Upvotes: 3

QuinnFTW
QuinnFTW

Reputation: 554

The reason it works is because the [] operator does pointer addition.

When you reference

a[x]

Whats actually happening is its taking the memory address of a and adding the sizeof(int)*x

So if you set ptr to a+4, you are going to a+sizeof(int)*4

then, when you put in a negative value, you move backwards through the memory address.

Upvotes: 4

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726489

First, recall that in C the expression ptr[index] means the same thing as *(ptr+index).

Now let's look at your expression again: ptr is set to a+4 before the loop; then you apply -i index to it. Therefore, the equivalent pointer arithmetic expression would be as follows:

printf("%d", *(a+4-i));

This expression iterates the array backwards, producing the results that you see.

Upvotes: 26

Related Questions