Сохранение 2D-массивов в массиве указателей - PullRequest
2 голосов
/ 30 сентября 2019

У меня есть 2D-массивы разных размеров, и я хочу сохранить их все в массиве указателей

int test0[][2] = {{0, 2},
                  {1, 3}};
int test1[][3] = {{10, 20, 30},
                  {40, 50, 60},
                  {70, 80, 90}};

int *t = malloc(2*sizeof(int));

t[0] = (int) test0;
t[1] = (int) test1;

free(t);

Так что теперь адреса указателей test1 и test2 хранятся в t[0] и t[1] соответственно

Но я не могу получить к ним доступ как t[0][0][0]

Возможно ли это, и как бы вы это сделали, пожалуйста?

Ответы [ 2 ]

4 голосов
/ 30 сентября 2019

Вы не можете создать массив объектов разного типа / размера, и в вашем случае массивы отличаются по размеру.

Вам нужно что-то вроде:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    int test0[][3] = {{0, 2},
                      {1, 3}};
    int test1[][3] = {{10, 20, 30},
                      {40, 50, 60},
                      {70, 80, 90}};

    int (**t)[3] = malloc(sizeof(*t) * 2);

    t[0] = test0;
    t[1] = test1;

    printf("t[1][1][1] = %d\n", t[1][1][1]);

    free(t);

    return 0;
}

Вывод:

50

Но обратите внимание, что вам не нужно использовать динамическую память (malloc):

int (*t[2])[3]; // array 2 of pointer to array 3 of int

также будет работать.

1 голос
/ 30 сентября 2019

Если у вас есть такой массив

int test0[][2] = { /*...*/ };

, то указатель на элементы массива выглядит следующим образом

int ( *p )[2] = test0;

или

int test1[][3] = { /*...*/ };
int ( *p )[3] = test1;

и вы можете обращаться к элементам массива, используя указатель так же, как вы делаете с массивом, например, p[i][j].

Обратите внимание, что этот фрагмент кода

t[0] = (int) test0;
t[1] = (int) test1;

небезопасно и не имеет смысла. Размер указателя может быть больше, чем размер типа int. Более того, объекты t[0] и t[1] не являются указателями. Они являются целыми числами.

Вы можете определить массив указателей типа void *, а затем явно привести каждый элемент массива к требуемому типу.

Например,

#include <stdio.h>
#include <stdlib.h>

int main(void) 
{
    enum { N0 = 2, N1 = 3 };
    int test0[N0][N0] = 
    { 
        { 0, 2 }, 
        { 1, 3 }
    };

    int test1[N1][N1] = 
    {
        { 10, 20, 30 },
        { 40, 50, 60 },
        { 70, 80, 90 }
    };

    void **t = malloc( 2 * sizeof( void * ) );
    t[0] = test0;
    t[1] = test1;

    for ( size_t i = 0; i < N0; i++ )
    {
        for ( size_t j = 0; j < N0; j++ )
        {
            printf( "%d ", ( ( int ( * )[N0] )t[0] )[i][j] );
        }
        putchar( '\n' );
    }

    putchar( '\n' );

    for ( size_t i = 0; i < N1; i++ )
    {
        for ( size_t j = 0; j < N1; j++ )
        {
            printf( "%d ", ( ( int ( * )[N1] )t[1] )[i][j] );
        }
        putchar( '\n' );
    }

    putchar( '\n' );

    free( t );

    return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...