Преобразование многомерных массивов в указатели в C ++

это невозможно, насколько я знаю. Но вы можете реализовать свой собственный контроль, чтобы сделать это возможным.

Посмотрите на эту статью .

Надеюсь, что это поможет.

Кстати, это вопрос, который он заслуживает google перед публикацией. Вы можете найти много таких вещей уже в Интернете.

14
задан Alex319 18 October 2009 в 05:33
поделиться

7 ответов

Нет, нет правильного способа сделать это конкретно. Массив double [4] [4] не может быть преобразован в указатель double ** . Это два альтернативных несовместимых способа реализации 2D-массива. Что-то нужно изменить: либо интерфейс функции, либо структуру массива, переданного в качестве аргумента.

Самый простой способ сделать последнее, то есть сделать существующий double [4] [4] ] массив, совместимый с функцией, предназначен для создания временного «индекса»

24
ответ дан 1 December 2019 в 09:13
поделиться

Можно определенно сделать что-то как код ниже. Я не знаю, насколько большой идея это все же.

template <typename T, int n>
class MatrixP
{
public:
    MatrixP operator()(T array[][n])
    {
        for (auto i = 0; i < n; ++i) {
            v_[i] = &array[i][0];
        }

        return *this;
    }

    operator T**()
    {
        return v_;
    }

private:
    T* v_[n] = {};
};

void foo(int** pp, int m, int n)
{
    for (auto i = 0; i < m; ++i) {
        for (auto j = 0; j < n; ++j) {
            std::cout << pp[i][j] << std::endl;
        }
    }
}

int main(int argc, char** argv)
{
    int array[2][2] = { { 1, 2 }, { 3, 4 } };
    auto pa = MatrixP<int, 2>()(array);

    foo(pa, 2, 2);
}
0
ответ дан 1 December 2019 в 09:13
поделиться

По той причине, что двумерный массив (один непрерывный блок памяти) и массив указателей (не смежных) - очень разные вещи, вы не можете передать двумерный массив в функция, работающая с указателем на указатель.

Одна вещь, которую вы могли бы сделать: шаблоны. Сделайте размер второго измерения параметром шаблона.

#include <iostream>

template <unsigned N>
void print(double a[][N], unsigned order)
{
    for (unsigned y = 0; y < order; ++y) {
        for (unsigned x = 0; x < N; ++x) {
            std::cout << a[y][x] << ' ';
        }
        std::cout << '\n';
    }
}

int main()
{
    double arr[3][3] = {{1, 2.3, 4}, {2.5, 5, -1.0}, {0, 1.1, 0}};
    print(arr, 3);
}

Другой, немного более неуклюжий способ может заключаться в том, чтобы заставить функцию принимать указатель на одномерный массив с указанием ширины и высоты в качестве аргументов и вычислять индексы в двумерное представление.

#include <iostream>

void print(double *a, unsigned height, unsigned width)
{
    for (unsigned y = 0; y < height; ++y) {
        for (unsigned x = 0; x < width; ++x) {
            std::cout << a[y * width + x] << ' ';
        }
        std::cout << '\n';
    }
}

int main()
{
    double arr[3][3] = {{1, 2.3, 4}, {2.5, 5, -1.0}, {0, 1.1, 0}};
    print(&arr[0][0], 3, 3);
}

Естественно, матрица заслуживает отдельного класса (но вышесказанное может быть актуальным, если вам нужно написать вспомогательные функции).

5
ответ дан 1 December 2019 в 09:13
поделиться

Двумерный массив не является указателем на указатель или чем-то подобным. Правильный тип для startMatrix - double (*) [4] . Для вашей функции подпись должна быть такой:

MatrixInversion( double (*A)[4], int order, double (*B)[4] );
1
ответ дан 1 December 2019 в 09:13
поделиться

с помощью хорошей кодировки для c ++:

struct matrix {
    double m[4][4];
};

matrix startMatrix;
matrix inverseMatrix;

, поэтому интерфейс будет

void MatrixInversion(matrix &A, int order, matrix &B);

] и использовать его

MatrixInversion(startMatrix, 4, inverseMatrix);

Благо

  1. интерфейс очень простой и понятный.
  2. если нужно изменить "m" матрицы внутри, вам не нужно обновлять интерфейс.

Или так

struct matrix {
    void Inversion(matrix &inv, int order) {...}
protected:
    double m[4][4];
};

matrix startMatrix;
matrix inverseMatrix;
...

Уродливый способ в c

void MatrixInversion(void *A, int order, void *B);
MatrixInversion((void*)startMatrix, 4, (void*)inverseMatrix);

EDIT: справочный код для MatrixInversion, который не будет сбой:

void MatrixInversion(void *A, int order, void *B)
{
    double _a[4][4];
    double _b[4][4];

    memcpy(_a, A, sizeof _a);
    memcpy(_b, B, sizeof _b);
    // processing data here

    // copy back after done
    memcpy(B, _b, sizeof _b);
}
-2
ответ дан 1 December 2019 в 09:13
поделиться

Поскольку вы используете C ++, правильным способом сделать что-то подобное было бы с помощью специального класса и некоторых шаблонов. Следующий пример довольно грубый, но он дает основную точку зрения.

#include <iostream>

using namespace std;

template <int matrix_size>
class SquareMatrix
{
    public:
        int size(void) { return matrix_size; }
        double array[matrix_size][matrix_size];
        void copyInverse(const SquareMatrix<matrix_size> & src);
        void print(void);
};

template <int matrix_size>
void SquareMatrix<matrix_size>::copyInverse(const SquareMatrix<matrix_size> & src)
{
    int inv_x;
    int inv_y;

    for (int x = 0; x < matrix_size; x++)
    {
        inv_x = matrix_size - 1 - x;
        for (int y = 0; y < matrix_size; y++)
        {
            inv_y = matrix_size - 1 - y;
            array[x][y] = src.array[inv_x][inv_y];
        }
    }
}

template <int matrix_size>
void SquareMatrix<matrix_size>::print(void)
{
    for (int y = 0; y < 4; y++)
    {
        for (int x = 0; x < 4; x++)
        {
            cout << array[x][y] << " ";
        }   
        cout << endl;
    }
}

template <int matrix_size>
void Initialize(SquareMatrix<matrix_size> & matrix);

int main(int argc, char * argList[])
{
    SquareMatrix<4> startMatrix;
    SquareMatrix<4> inverseMatrix;

    Initialize(startMatrix);

    inverseMatrix.copyInverse(startMatrix);

    cout << "Start:" << endl;
    startMatrix.print();

    cout << "Inverse:" << endl;
    inverseMatrix.print();

    return 0;
}

template <int matrix_size>
void Initialize(SquareMatrix<matrix_size> & matrix)
{
    for (int x = 0; x < matrix_size; x++)
    {
        for (int y = 0; y < matrix_size; y++)
        {
            matrix.array[x][y] = (x+1)*10+(y+1);
        }
    }
}
2
ответ дан 1 December 2019 в 09:13
поделиться

Проблема в том, что двумерный массив - это не то же самое, что массив указателей. Двумерный массив хранит элементы одна строка за другой, поэтому, когда вы передаете такой массив, дается только указатель на начало. Функция приема может определить, как найти любой элемент массива, но только если она знает длину каждой строки .

Итак, ваша функция приема должна быть объявлена ​​как void MatrixInversion ( double A [4] [], порядок int, double B [4] []) .

-1
ответ дан 1 December 2019 в 09:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: