#include "stdio.h"
int main()
{
int *pI, *values[2];
int i1[] = {1, 2}, i2[][2] = {{5, 10}, {20, 30}};
// SOME LINES ARE EDITED, AFTER READING COMMENTS
*values = i2[*i1]; // i2[1] = 20 // values[0] = &i2[1][0];
values[1] = i1; // values[1] = 1
pI = &i2[0][0]; //pI = 5
printf(" %d %d\n", **values, *&values[1][1]); //...
// (Edited) expectation: **values = 20 *&values[1][1] = 2
// Result: **values = 20 *&values[1][1] = 2
*pI += pI[i1[1]]; // pI[0] += pI[2] = 5 + 20 = 25
*values = pI; // values points to the 25 (pI)
*(i1 + 1) *= *(values[1] + 1); // i1[1]=2 // i1[1] *= i1[1] = 2*2
printf(" %d %d\n", **values, *&values[1][1]);
// (Edited) expectation: **values = 25 *&values = 4
// Result: **values = 25 *&values = 4
return 0;
}
As you can see my understanding of this code is not the yellow from the egg. But I would like to understand the steps, that i can solve it by myself the next time
The expression *values
is the same as values[0]
due to the definition of the subscript operator.
Thus this statement
*values = i2[*i1];
may be rewritten the following way
values[0] = i2[i1[0]];
As i1[0] yields the value 1 then
values[0] = i2[1];
The expression i2[1] yields the second element of the array i2 that is the one-dimensional array of the type int[2]
with values {20, 30}
.
Array designators used in expression with rare exceptions are converted to pointers to their first elements. So you may write
values[0] = &i2[1][0];
Thus the value of the expression **values
is equal to 20.
Again in this statement
values[1] = i1;
the array designator i1 is converted to pointer to its first element. That is you may write
values[1] = &i1[0];
In this expression *&values[1][1]
the pair of operators *& in fact does not have an effect. You may write values[1][1]
. So this expression yields the second element of the array i1
that is equal to 2
.
The variable pI
pI = &i2[0][0];
points to the element &i2[0][0]
. This record may be interpreted as
pI = ( int * )i2;
This statement
*pI += pI[i1[1]];
may be rewritten like
*pI += pI[2];
The value of pI[2] is 20 (the third element of the type int
of the array i2
.
SP you have
*pI += 20;
As a result the element i2[0][0]
will contain 25
.
This statement
*values = pI;
is equivalent to
values[0] = pI;
So now the pointer values[0]
points to the element i2[0][0]
that is to the value 25
that is outputted using the expression **values
.
This expression statement
*(i1 + 1) *= *(values[1] + 1);
may be rewritten like
i1[1] *= *( values[1] + 1 );
Due to the statement above
values[1] = i1;
values[1]
points to the first element of the array i1
. So the expression values[1] + 1
points to the second element of the array i1
that is equal to 2
.
So you have
i1[1] *= 2;
As a result i1[1]
is equal to 4
.
This value is outputted by the expression *&values[1][1]
that as it was mentioned above is equivalent to values[1][1]
To understand the pointer arithmetic and the implicit conversion of array designators to pointers to their first elements there is no need to write such an obfuscated code.