-5
int main()
{
    static int a[2][2] = {1, 2, 3, 4};
    int i, j;
    static int *p[] = {(int*)a, (int*)a+1, (int*)a+2};
    for(i=0; i<2; i++)
    {
        for(j=0; j<2; j++)
        {
            printf("%d, %d, %d, %d\n", *(*(p+i)+j), *(*(j+p)+i),
            *(*(i+p)+j), *(*(p+j)+i));
        }
    }
    return 0;
}

When I run this code the output is:

1, 1, 1, 1  
2, 2, 2, 2  
2, 2, 2, 2  
3, 3, 3, 3

Can someone please explain how this code works?

ani627
  • 5,578
  • 8
  • 39
  • 45
Shashank
  • 87
  • 1
  • 2
  • 6
  • 2
    Compile with all warnings and debug info (`gcc -Wall -g`). Then **use the debugger** (`gdb`) to run your program step by step, displaying the relevant variables inside the debugger. – Basile Starynkevitch Sep 22 '14 at 12:45
  • Are you sure you want to initialize `p` like you do? Maybe `(int*)a+1` should be `a[1]` ? – Basile Starynkevitch Sep 22 '14 at 12:47
  • the op asked for explanation please don't neglect that – Tushar Gupta Sep 22 '14 at 12:49
  • 1
    What do you want to achieve with this code. Are you not getting it. Have you tried some intermediate prints? – Mohit Jain Sep 22 '14 at 12:49
  • @TusharGupta As per First comment OP can look all variable in inside debugger. you can try to explain OP. – Jayesh Bhoi Sep 22 '14 at 12:55
  • That was an interview question.So, no changes in the question and the code works perfectly. I just want explanation of each step that how pointers works. – Shashank Sep 22 '14 at 12:59
  • @user3482643 You can play with [this code](http://ideone.com/gPfWRR) and (click on fork and) add more prints to understand what exactly is going on. If you don't understand something specific, feel free to ask. As starter, I would ask interviewer to prefer `static int a[2][2] = { {1, 2}, {3, 4} };` (notice extra pair of braces), remove unnecessary casts and avoid things like `a+1` etc. – Mohit Jain Sep 22 '14 at 13:00
  • @mohit jain what will be the values in*p[]? – Shashank Sep 22 '14 at 13:02
  • 1
    @Shashank Because (int *) couples tighter than `+`, it would contain address of 0th, 1st and second element of array. (If the behaviour is well defined). Notice that `(int *)a+1` is not same as `(int *)(a+1)` – Mohit Jain Sep 22 '14 at 13:04

1 Answers1

1

The four pointer operations in the printf:

*(*(p+i)+j)
*(*(j+p)+i)
*(*(i+p)+j)
*(*(p+j)+i)

Evaluate to the following:

*(*(p+i)+j) -> *(p[i]+j) 
*(*(j+p)+i) -> *(p[j]+i)
*(*(i+p)+j) -> *(i[p]+j) 
*(*(p+j)+i) -> *(j[p]+i)

p[n] is the same as n[p] as the pointer logic (as seen above) is commutitive around +.
see this question for more details.

So there are really only two statements:

*(p[i]+j) 
*(p[j]+i)

Of course, this is just p + offset [x] + offset. So really, it is only one statement:

*p[i+j]

Which is of course, the value stored in the p array at offset i+j.

Because of the nested loops, the values of i and j are as follows:

i j  i+j
0,0   0
0,1   1
1,0   1
1,1   2

So it prints in turn, the values in each location of p (1,2, 2and3) four times.

Community
  • 1
  • 1
Baldrickk
  • 4,291
  • 1
  • 15
  • 27