Search code examples
c++carrayspointersinitialization

Difference of value of **(ptr+1) in char and int


Please help me out as to why in below code outputs are different:

int z[][3] = { 1, 2, 3, 4, 5, 6 };
printf("\n**(z+1): %d", **(z + 1));

Output: (z+1): 4

char y[][3] = { "A", "F", "G", "J", "M", "P" };
printf("\n**(y+1): %c", **(y+1));

Output: (y+1): F

Why in the above two outputs, first is checking the 4th index while in second output prints 2nd index ?


Solution

  • Why in the above two outputs, first is checking the 4th index while in second output prints 2nd index ?

    That's not actually close to describing what is happening.

    To understand what is happening, write the examples into their actual meaning

    int z[][3] = { 1, 2, 3, 4, 5, 6 };
    printf("\n**(z+1): %d", **(z + 1));
    

    is actually

    int z[][3] = { {1, 2, 3}, {4, 5, 6} };
    printf("\n**(z+1): %d", **(z + 1));
    

    where z[0] is an array of three elements initialised with {1, 2, 3} and z[1] is an array of three elements initialised with {4,5,6}.

    In this z + 1 is equal to &z[0] + 1 which is equal to &z[1] (the address of an array of three int). So *(z+1) is (a reference to) z[1] (an array of three elements) and **(z+1) is z[1][0]. Since z[1] is an array initialised as elements {4,5,6}, z[1][0] is the first element of that array. This has a value of 4.

    In comparison,

    char y[][3] = { "A", "F", "G", "J", "M", "P" };
    printf("\n**(y+1): %c", **(y+1));
    

    each of the string literals is initialised as an array of two elements e.g. "A" is initialised as {'A', '\0'}.

    Now y is an array of arrays of three char. If an array of three elements is given an initialiser with two char, as is the case here, the values that are not explicitly initialialised are zero-initialised. So

    char y[][3] = { "A", "F", "G", "J", "M", "P" };
    

    is equivalent to

    char y[][3] = { {'A', '\0', '\0'}, {'F', '\0', '\0'}, {'G', '\0', '\0'}, {'J', '\0', '\0'}, {'M', '\0', '\0'}, {'P', '\0', '\0'}};
    

    So y is array of six elements, each of which is an array of three char.

    Using the same logic as in the discussion of z above, y + 1 is equal to &y[1] where y[1] is an array of three char that is initialized as {'F', '\0', '\0'}. So *(y + 1) is (a reference to) y[1], and **(y + 1) is y[1][0]. This has a value of 'F'.