Home > Mobile >  Is this a correct way to define array of pointers to array?
Is this a correct way to define array of pointers to array?

Time:09-12

Is this a correct way to define array of pointers to array in C programming language?

int* ptr[2];

int n1[5] = { 2,3,4,5,6 };
int n2[5] = { 2,3,4,5,6 };
ptr[0] = &n1;
ptr[1] = &n2;

I am getting errors like:

epi_2.c:20:12: warning: incompatible pointer types assigning to 'int *' from 'int (*)[5]' [-Wincompatible-pointer-types]
    ptr[1] = &n2;

CodePudding user response:

You have to write

ptr[0] = n1;
ptr[1] = n2;

Array designators used in expressions with rare exceptions are converted to pointers to their first elements.

That is in the above statements expressions n1 and n2 have the type int * - the type of the left side expressions.

As for these statements

ptr[0] = &n1;
ptr[1] = &n2;

then the right side expressions have the type int ( * )[5] that is not compatible with the type int * of the left side expressions. So the compiler issues messages.

Otherwise you need to declare the array of pointers like

int ( * ptr[2] )[5];
//...
ptr[0] = &n1;
ptr[1] = &n2;

Here is a demonstration program.

#include <stdio.h>

int main( void ) 
{
    int* ptr[2];

    int n1[5] = { 2,3,4,5,6 };
    int n2[5] = { 2,3,4,5,6 };

    ptr[0] = n1;
    ptr[1] = n2;

    for ( size_t i = 0; i < 2;   i )
    {
        for ( size_t j = 0; j < 5; j   )
        {
            printf( "%d ", ptr[i][j] );
        }
        putchar( '\n' );
    }
}

The program output is

2 3 4 5 6 
2 3 4 5 6 

And here is another demonstration program.

#include <stdio.h>

int main( void ) 
{
    int ( * ptr[2] )[5];

    int n1[5] = { 2,3,4,5,6 };
    int n2[5] = { 2,3,4,5,6 };

    ptr[0] = &n1;
    ptr[1] = &n2;

    for ( size_t i = 0; i < 2;   i )
    {
        for ( size_t j = 0; j < 5; j   )
        {
            printf( "%d ", ( *ptr[i] )[j] );
        }
        putchar( '\n' );
    }
}

The program output is the same as shown above

2 3 4 5 6 
2 3 4 5 6 

CodePudding user response:

Is this a correct way to define array of pointers to array?

&n1 does return a pointer to an array.

But ptr[0] is not a pointer to an array. It's a pointer to an int.

You have two options.


Change ptr[0] to be a pointer to an array

By using the following, ptr becomes an array of pointers to arrays of 5 ints.

int ( *ptr[2] )[5] = { &n1, &n2 };

Change &1n to something that returns a pointer to int

But we rarely deal with pointer to arrays. We usually work with pointers to the first element of the array.

int *ptr[2] = { &( n1[0] ), &( n2[0] ) };

Because an array degenerates into a pointer to its first element, the following is equivalent but shorter:

int *ptr[2] = { n1, n2 };

In both cases, you end up with a pointer to the same address. But the type of the pointer is different. About the only difference is that sizeof( *ptr[0] ) will vary.

#include <stdio.h>

int main( void ) {
   int ( *ptrA[2] )[5];
   int *ptrB[2];
   printf( "%zu\n", sizeof( *ptrA[0] ) );  // 20, size of array of 5 `int`.
   printf( "%zu\n", sizeof( *ptrB[0] ) );  //  4, size of one `int`.
}

CodePudding user response:

In C, there are two kinds of pointers to arrays:

  1. Pointers that point to the first element of the array.
  2. Pointers that point to the array as a whole.

If you have an array

int arr[5] = { 2,3,4,5,6 };

then you can create a pointer to the first element of the array the following way:

int *ptr = arr;

In the line above, the expression arr will automatically decay to &arr[0], i.e. to a pointer to the first element of the array.

You can create a pointer to the array as a whole the following way:

int (*ptr)[5] = &arr;

In C, it is more common to use the first kind of pointer. However, which kind of pointer you want depends on the situation.

For example, do you want sizeof *ptr to evaluate to the size of the entire array? Or do you want that expression to evaluate to the size of a single element of the array?

Also, how do you want ptr to behave? Do you want the pointer jump to the next element of the array? Or do you want the pointer to jump over the entire array (for example because you are using an array of arrays)?

If you want sizeof *ptr to evaluate to the size of a single element and want ptr to jump to the next element of the array, then you want the first kind of pointer. However, if you want sizeof *ptr to evaluate to the size of the entire array and want ptr to jump to the next array, then you want the second kind of pointer.

If in doubt, I recommend that you chose the first kind of pointer, because that kind of pointer is easier to handle and more common.

Once you have decided which kind of pointer you want, you can then create an array of these pointers.

If you want an array of the first kind of pointer, then you can define that array like this:

int *ptrs[2];

ptrs[0] = n1;
ptrs[1] = n2;

If you instead want an array of the second kind of pointer, then you can define that array like this:

int (*ptrs[2])[5];

ptrs[0] = &n1;
ptrs[1] = &n2;
  • Related