Code:
#include <stdio.h>
int main(void)
{
int arr[2][3] = {{1,2,3},{4,5,6}};
int i, j;
for(i = 0; i < 2; i++)
{
for(j = 0; j < 3; j++)
{
printf("%d ", *((*arr+(i*3))+j));
}
printf("\n");
}
return 0;
}
I'm surprised how the above code gives the output:
1 2 3
4 5 6
I know that *(arr+i) == arr[i]
and also that I should be using arr[i][j]
instead of making everything more complicated, but I don't understand how *((*arr+(i*3))+j)
works.
In my understanding, *((*arr+(i*3))+j)
can be simplified to *((*arr)+(i*3)+j)
since the *
(indirection operator) has the most precedence here.
So, when i
is zero and j
iterates through, 0 to 2, the expression is the same as arr[0][j]
which prints the integers of the first subarray.
My confusion builds up when i
becomes 1. The next three expressions will be *((*arr)+(1*3)+0)
, *((*arr)+(1*3)+1)
and *((*arr)+(1*3)+2)
which can be simplified to arr[0][3]
, arr[0][4]
and arr[0][5]
.
How does this print the last three values?
int arr[2][3] = {{1,2,3},{4,5,6}};
In memory :
1 | 2 | 3 | 4 | 5 | 6
each number on an adjacent memory "cell" the size of an int, in this order
Second line : i = 1 j = 0
*((*arr+(i*3))+j)) means *((*arr + 3) + 0)-> *({1, 2, 3} + 3) -> *({4, 5, 6}) = 4
Keep in mind that x[n]
is equivalent to *(x + n)
, whatever x
or n
. (This also means arr[1]
is equivalent to *(arr + 1)
, *(1 + arr)
and so 1[arr]
which I find funny)
Here arr[1][0]
: x
is arr[1]
and n
is 0
so first equivalence: *(arr[1] + 0)
Second x
is arr
and n
is 1
so *(*(arr + 1) + 0)
.
Finally arr + 1
means the adress at arr + sizeof(*arr)
, which means:
(arr + 1)
is equivalent to (*arr + 3)
because *arr
is arr[0]
which is of type int[3]