#include "stdio.h"
int main()
{
int *pI, *values[2];
int i1[] = {1, 2}, i2[][2] = {{5, 10}, {20, 30}};
*values = i2[*i1]; // i2[1] = 20
values[1] = i1; // values[1] = 1
pI = &i2[0][0]; //pI = 5
printf(" %d %d\n", **values, *&values[1][1]); //...
// My expectation: **values = 20 *&values = 30 ,...
// Result: **values = 20 *&values = 2
*pI = pI[i1[1]]; // *pI = pI[2] = 20
*values = pI; // *values = 20
*(i1 1) *= *(values[1] 1); // ???
printf(" %d %d\n", **values, *&values[1][1]);
// My expectation: **values = ?? *&values = 30 ,...
// 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
CodePudding user response:
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.
