arrayscpointersanonymous

why I am not able to initialize array of pointers providing 2d array


enter image description here

int *p = ( int[] ){ 1, 2, 3, 4 };

Doing this I am able to initialize a anonymous array to a pointer p. In a similar way I want to assign arrays of array (i.e. probably 2D array) in array of pointers. And so I have tried the following code:

int *p[]= (int [][3]) { {1,2,3},{10,20,30} };

But it goes wrong, anyway if I assign it to a pointer to whole Array( as int (*p)[]= (int [][3]) { {1,2,3},{10,20,30} }; ) it works fine. I am in confused that if a pointer can get assigned a anonymous array why the array of pointers could not get assigned to 2d array?


Solution

  • The compound literal

    (int [][3]) { {1,2,3},{10,20,30} };
    

    has the type

    int [2][3]
    

    i.e. array of 2 elements, each consisting of 3 int elements.

    When used in the line

    int *p[]= (int [][3]) { {1,2,3},{10,20,30} };
    

    the array will decay to a pointer to the first element. This pointer will therefore have the type "pointer to array of 3 int elements`.

    However, you cannot assign this data type to p, because the types are different. You declared p as an array of pointers. That is why your code is not working.

    If you want p to be an array of pointers in which every pointer points to its array of int elements, then you will need to use several compound literals, one for each of these arrays:

    int *p[] = {
        ( int[] ){  1,  2,  3,  4 },
        ( int[] ){  5,  6,  7,  8 },
        ( int[] ){  9, 10, 11, 12 }
    };
    

    Here is a small test program:

    #include <stdio.h>
    
    int main( void )
    {
        int *p[] = {
            ( int[] ){  1,  2,  3,  4 },
            ( int[] ){  5,  6,  7,  8 },
            ( int[] ){  9, 10, 11, 12 }
        };
    
        printf( "%d\n", p[1][2] );
    }
    

    This program has the output 7.

    EDIT:

    According to your remarks in the comments section of this answer, it seems that you have several 2D arrays and want to create an array of pointers to these arrays. In that case, you can do the following:

    #include <stdio.h>
    
    int main( void )
    {
        //define first 2D array
        int arr1[][4] = {
            {  1,  2,  3,  4},
            {  5,  6,  7,  8},
            {  9, 10, 11, 12}
        };
    
        //define second 2D array
        int arr2[][4] = {
            { 13,  14, 15, 16},
            { 17,  18, 19, 20},
            { 21,  22, 23, 24}
        };
    
        //define array of 2 pointers that point to the first
        //rows of arr1 and arr2
        int (*p[])[4] = { arr1, arr2 };
    
        //use pointer array to get the 4th element in the
        //3rd row of the second 2D array
        printf( "%d\n", p[1][2][3] );
    }
    

    This program will give you the correct output 24.

    If you find the declaration int (*p[])[4] hard to understand, then you may want to read this page on how these declarations are to be interpreted. Also, this site may be useful.

    You can also simplify your declarations by using a typedef, so that the type arrow_row represents an array of 4 int elements (i.e. a row of a 2D array) like this:

    typedef int array_row[4];
    

    Now, you can simplify the declaration

    int (*p[])[4] = { arr1, arr2 };
    

    to:

    array_row *p[] = { arr1, arr2 };