Harsh Sinha
Harsh Sinha

Reputation: 13

How is the element denoted by *(arr+i)[1] and **(arr+i) being determined?

I can't understand how the following elements are getting determined:

  1. *(arr+1)[1] - 7 is printed.

  2. **(arr+1) - 4 is printed.

#include <stdio.h>
int main()
{
    int arr[3][3]={1,2,3,4,5,6,7,8,9};
    printf("%d %d",*(arr+1)[1],**(arr+1));
    return 0;
}

Upvotes: 1

Views: 496

Answers (2)

melpomene
melpomene

Reputation: 85767

By definition, a[b] is equivalent to *(a + b).

[] (postfix) has higher precedence than * (prefix), so *a[b] parses as *(a[b]).

  1. *(arr+1)[1] parses as *((arr+1)[1]).

    *((arr+1)[1]) is equivalent to *(*(arr+1+1)).

    *(*(arr+1+1)) reduces to **(arr+2).

    **(arr+2) is equivalent to *(arr[2]).

    *(arr[2]) is equivalent to *(arr[2]+0).

    *(arr[2]+0) is equivalent to arr[2][0].

  2. **(arr+1) is equivalent to *(arr[1]).

    *(arr[1]) is equivalent to *(arr[1]+0).

    *(arr[1]+0) is equivalent to arr[1][0].

As for the actual data:

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

is a bit hard to read. Better:

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

In the first case, arr[2][0] gives you the first element (7) of the third subarray (7,8,9) while in the second case, arr[1][0] gives you the first element (4) of the second subarray (4,5,6).

Upvotes: 5

John Zwinck
John Zwinck

Reputation: 249193

arr can be more intuitively written like this:

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

*(arr+1)[1] is equivalent to **(arr+2) because a[n] is equivalent to *(a+n). arr+2 skips two rows, giving a pointer to {{7,8,9}}, then the two stars dereference the first of those values.

**(arr+1) works the same way.

Upvotes: 1

Related Questions