Home > Enterprise >  "C" Trying to understand **pointer and how to access all values of value[][]
"C" Trying to understand **pointer and how to access all values of value[][]

Time:06-03

#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.

  • Related