1

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?

Andreas Wenzel
  • 22,760
  • 4
  • 24
  • 39
  • 2
    Please elaborate "it goes wrong" and provide a [mre] each for both described cases. Also pleas explain what you intend to do this way. I suspect that there is a better way. Compare https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem – Yunnosch Jul 04 '22 at 05:52
  • If X is a type, then an array of X [decays](https://stackoverflow.com/questions/1461432/what-is-array-to-pointer-decay) to a pointer of X. Now say X is array-of-Y. An array of X still decays to a pointer to X, that is, a pointer to an array-of-Y. It does not decay to an array of pointers to anything, nor to a pointer to a pointer to anything. – n. m. could be an AI Jul 04 '22 at 06:10

2 Answers2

1

int *p[] is an array of pointers, not a pointer to an array.

You'll need to do:

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

The reason why is that an array, whenever used in an expression, decays into a pointer to the first element. So no matter the array type, your pointer will need to correspond to the pointer to the first element.

In case of an int[], the element type is int and a pointer to it would be int*.

In case of an int[][3], the element type is int[3] and a pointer to it would be int (*p)[3].

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • Please have a look at my image too. All I am saying is that if I can assign a array or address of an array(whatever it treats internally) to a pointer (p) why can't I assign a collection of those array which is in fact 2D array in a array of similar pointers. – Anup Adhikari Jul 04 '22 at 06:44
  • @AnupAdhikari Because in that case you need to do `int* p [] = { arr[0], arr[1], ...}` which would be a rather cumbersome and generally pointless array to have. – Lundin Jul 04 '22 at 06:50
  • Good to say that `int (*p)[] = (int [][3]) { {1,2,3},{10,20,30} };` is also valid, is a pointer to an array with unspecified bounds, as such you can not use `sizeof` nor dereference this kind of pointers without a cast, in your case `((int (*)[3])p)[1][1]` will give you 20. – David Ranieri Jul 04 '22 at 07:15
  • @Lundin could you please elaborate and show me coding – Anup Adhikari Jul 04 '22 at 07:17
  • @DavidRanieri could you please elaborate and show me coding? – Anup Adhikari Jul 04 '22 at 07:18
  • @DavidRanieri Yes but I omitted that for pedagogic reasons, since the decayed pointer to the first element is a `int(*)[3]` and not a `int(*)[]`. – Lundin Jul 04 '22 at 08:04
1

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 };
Andreas Wenzel
  • 22,760
  • 4
  • 24
  • 39
  • Doing this, Your are assigning different 1D arrays to an array of pointers. Thanks for this. Also suggest me how could I assign 2D array in an array of pointers. – Anup Adhikari Jul 04 '22 at 07:09
  • @AnupAdhikari: How exactly do you want a 2D array assigned to an array of pointers? Do you want every element of the array of pointers to point to the start of a row in the 2D array? – Andreas Wenzel Jul 04 '22 at 07:30
  • yeah , all I was saying exactly the same you are taking about so that I could access 2D array – Anup Adhikari Jul 04 '22 at 07:37
  • @AnupAdhikari: You can construct such an array of pointers in a loop. See [this working code example](https://godbolt.org/z/azsPvM6nh). You could also hard-code the pointer array, like this: `int *p[] = { arr[0], arr[1], arr[2] };`, but then you would have to change this definition whenever the number of rows changes. If you use the code I posted in the link, then it will adapt to the number of lines automatically, and you will never have to change the definition of `p`. – Andreas Wenzel Jul 04 '22 at 07:54
  • @AnupAdhikari: Note that what you are asking for is rather strange. I therefore suspect that you are asking about an [XY problem](https://xyproblem.info/). You may want to explain what your ultimate goal is. – Andreas Wenzel Jul 04 '22 at 08:08
  • It is not a kind of XY problem or whatever it is, the actual problem is I have several 2D arrays and instead of creating pointers one by one, I wanna create array of such pointers which is capable of pointing all my 2D Arrays. And how many 2D Array is not constant and so I want implicit declaration instead assigning subsequently. – Anup Adhikari Jul 04 '22 at 09:36
  • The commented line states that I have assigned a 2D array to a pointer but I want array of such pointers which could store numbers of 2D Array. – Anup Adhikari Jul 04 '22 at 09:45
  • @AnupAdhikari: In your previous comment, you wrote: "but I want array of such pointers which could store numbers of 2D Array" -- This statement does not make sense. A pointer cannot "store numbers", it can only point to "numbers". – Andreas Wenzel Jul 05 '22 at 00:18
  • @AnupAdhikari: I have now added another program to the bottom of my answer, which defines two 2D arrays and creates an array of two pointers which each point to one of the 2D arrays. – Andreas Wenzel Jul 05 '22 at 00:48
  • Andreas Wenzel, Thanks exactly the same I was seeking for. Also suggest me, `char *p="String Literal";` with this statement I am able to assign the string to the pointer variable now suppose I want a character to assign without declaring variable for character as I did in string than is there some way? If yes then please let me know. – Anup Adhikari Jul 05 '22 at 02:30
  • @AnupAdhikari: I am not sure if this is what you want, but you can create a `char` as a [compound literal](https://en.cppreference.com/w/c/language/compound_literal) (i.e. as an anonymous variable) and then initialize a pointer `p` to point to that `char`, like this: `char *p = &(char){'A'};` However, this is a very strange thing to do. I have never seen anyone ever do this. Why do you want to do this? I suspect that there is a better way to achieve your ultimate goal. – Andreas Wenzel Jul 05 '22 at 04:26