Преобразовать указатель в указатель в многомерный массив - PullRequest
0 голосов
/ 18 ноября 2018

Можно ли преобразовать одномерный const int *const p указатель размера A B C в указатель на многомерный массив размером [A][B][C]?

Ответы [ 2 ]

0 голосов
/ 18 ноября 2018

Обычно это невозможно.

В первом случае (многомерный массив int[A][B][C]) все ваши данные непрерывно размещаются в памяти, а p[10][20][30] просто означает *(p + B * C * 10 + B * 20 + 30). Но указатель нацелен на массив указателей; и каждый из этих указывает на другой массив указателей; и только эти вторые массивы указывают на данные. Данные и массивы указателей второго уровня могут не быть последовательными. Так что вы, конечно, не можете взять адрес первого элемента данных и использовать смещение, чтобы получить то, что вы ищете.

Исключением является случай, когда кто-то действительно позаботится о последовательном размещении всех данных, причем массивы указателей будут указывать на них в соответствующих положениях. В этом случае вы можете принять &( *(*(*multidim_ptr))), то есть &( *(*multidim_ptr)), в качестве одномерного указателя, который можно использовать как p.

0 голосов
/ 18 ноября 2018

Вот пример того, как это сделать. Ключ использует typedef для установки вашего указателя на массив указателей, чтобы вы не запутались.

typedef int (*pint3)[A][B];

В этой строке мы устанавливаем тип, который указывает на двумерный массив указателей на int. 2D-массив имеет размеры, равные двум измерениям, которые вы изначально рассматривали.

Как уже упоминалось в комментариях, этот метод нарушает алиасинг. Этот тип переназначения указателей подвержен ошибкам, и его, вероятно, следует избегать.

#include <iostream>

int main() {

    int A = 2;
    int B = 2;
    int C = 3;

    int array[]{1, 1, 1, 1, 2, 2, 2,2, 3,3,3,3};



    const int *const p = array;

    typedef int (*pint3)[A][B];

    auto threeDArray = (pint3) p;

    std::cout << "Printing 3D array:  " << std::endl;
    for(int i = 0; i < C; i++ ) {
        for(int j = 0; j < B; j++) {
            for (int k = 0; k < A; k++) {
                std::cout << threeDArray[i][j][k];
            }
            std::cout << std::endl;
        }
        std::cout << std::endl;

    }
}

Выход:

Printing array:  
11
11

22
22

33
33


Process finished with exit code 0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...