Search code examples
cpointersmultidimensional-arrayimplicit-conversionpointer-arithmetic

dereferencing 2D array using arithmetic


int main(void) 
{
    short arr[3][2]={3,5,11,14,17,20};
    printf("%d %d",*(arr+1)[1],**(arr+2));
    return 0;
}

Hi. In above code as per my understanding ,*(arr+1)[1] is equivalent to *(*(arr+sizeof(1D array)*1)+sizeof(short)*1)=>arr[1][1] i.e 14. But the program output is arr[2][0]. can someone please explain how dereferencing the array second time adds sizeof(1Darray) i.e *(*(arr+sizeof(1D array)*1)+sizeof(1D array)*1)=>arr[2][0]


Solution

  • From the C Standard (6.5.2.1 Array subscripting)

    2 A postfix expression followed by an expression in square brackets [] is a subscripted designation of an element of an array object. The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2))). Because of the conversion rules that apply to the binary + operator, if E1 is an array object (equivalently, a pointer to the initial element of an array object) and E2 is an integer, E1[E2] designates the E2-th element of E1 (counting from zero).

    So the expression

    *(arr+1)[1]
    

    can be rewritten like

    * ( *( arr + 1 + 1 ) )
    

    that is the same as

    *( *( arr + 2 ) )
    

    arr + 2 points to the third "row" of the array. Dereferencing the pointer expression you will get the "row" itself of the type short[2] that used in the expression *( arr[2] ) is converted to pointer to its first element. So the expression equivalent to arr[2][0] yields the value 17.

    Thus these two expressions

    *(arr+1)[1],
    

    and

    **(arr+2)
    

    are equivalent each other.

    Note: pay attention to that there is a typo in your code

    printf("%d %d",*(arr+1)[1],**(arr+2);
    

    You need one more parenthesis

    printf("%d %d",*(arr+1)[1],**(arr+2) );