Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/149.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将多维数组转换为c+中的指针+;_C++_Pointers_Multidimensional Array - Fatal编程技术网

C++ 将多维数组转换为c+中的指针+;

C++ 将多维数组转换为c+中的指针+;,c++,pointers,multidimensional-array,C++,Pointers,Multidimensional Array,我有一个如下所示的程序: double[4][4] startMatrix; double[4][4] inverseMatrix; initialize(startMatrix) //this puts the information I want in startMatrix void MatrixInversion(double** A, int order, double** B) 现在我想计算startMatrix的逆矩阵,并将其放入inverseMatrix。我有一个用于此目的的

我有一个如下所示的程序:

double[4][4] startMatrix;
double[4][4] inverseMatrix;
initialize(startMatrix) //this puts the information I want in startMatrix
void MatrixInversion(double** A, int order, double** B)
现在我想计算startMatrix的逆矩阵,并将其放入inverseMatrix。我有一个用于此目的的库函数,其原型如下:

double[4][4] startMatrix;
double[4][4] inverseMatrix;
initialize(startMatrix) //this puts the information I want in startMatrix
void MatrixInversion(double** A, int order, double** B)
这取A的倒数,然后把它放在B中。问题是我需要知道如何将double[4][4]转换成double**来赋予函数。我试着用“显而易见的方式”来做:


但这似乎不起作用。这真的是正确的方法吗?

二维数组不是指向指针的指针或类似的东西。startMatrix的正确类型是
double(*)[4]
。对于您的功能,签名应如下所示:

MatrixInversion( double (*A)[4], int order, double (*B)[4] );

不,没有正确的方法可以做到这一点。
double[4][4]
数组不能转换为
double**
指针。这是实现二维阵列的两种可选的、不兼容的方法。有些东西需要更改:要么是函数的接口,要么是作为参数传递的数组的结构

实现后者的最简单方法,即使现有的
double[4][4]
数组与函数兼容,是创建类型为
double*[4]
的临时“索引”数组,指向每个矩阵中每行的开头

double *startRows[4] = { startMatrix[0], startMatrix[1], startMatrix[2] , startMatrix[3] };
double *inverseRows[4] = { /* same thing here */ };
并传递这些“索引”数组

MatrixInversion(startRows, 4, inverseRows);

函数完成工作后,您可以忘记
startRows
inverseRows
数组,因为结果将正确地放入原始
inverseMatrix
数组中。

问题在于二维数组与指针数组不同。二维数组一行接一行地存储元素——因此,当您传递这样一个数组时,只给出一个指向开始的指针。接收函数可以计算出如何查找数组中的任何元素,但是只有在它知道每行的长度时才可以


<> P> >,您的接收函数应该声明为“代码> ValueMatRIXVALUE(double A[4 ][],INTION,双B[4 ][])/<代码>

< P>因为您使用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);
        }
    }
}
#包括
使用名称空间std;
模板
类平方矩阵
{
公众:
int size(void){返回矩阵_size;}
双数组[矩阵大小][矩阵大小];
void copyInverse(常数平方矩阵和src);
作废打印(作废);
};
模板
void SquareMatrix::copyInverse(常数SquareMatrix和src)
{
int inv_x;
国际投资;
对于(int x=0;x
struct matrix {
    double m[4][4];
};

matrix startMatrix;
matrix inverseMatrix;
因此,接口将是

void MatrixInversion(matrix &A, int order, matrix &B);
并使用它

MatrixInversion(startMatrix, 4, inverseMatrix);
好处

  • 界面非常简单明了
  • 一旦需要在内部修改矩阵的“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);
    
    编辑:不会崩溃的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);
    }
    

    由于二维数组(一个连续的内存块)和指针数组(不连续)是非常不同的东西,所以不能将二维数组传递给使用指针对指针的函数

    你可以做一件事:模板。将第二维度的大小作为模板参数

    #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);
    }
    
    #包括
    模板
    无效打印(双a[][N],未签名订单)
    {
    for(无符号y=0;ystd::cout有一个解决方案,使用指向逐点的指针

    William Sherif(BOBOBOBOO)使用C版本,我只想展示BBOBOBOO的C++版本。

    int numRows = 16 ;
    int numCols = 5 ;
    int **a ;
    
    a = new int*[ numRows* sizeof(int*) ];
    for( int row = 0 ; row < numRows ; row++ )
    {
        a[row] = new int[ numCols*sizeof(int) ];
    }
    
    int numRows=16;
    int numCols=5;
    国际**a;
    a=新的整数*[numRows*sizeof(整数*)];
    for(int行=0;行

    代码的其余部分与Bobo的相同。

    如果您愿意,您完全可以执行下面的代码

    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);
    }
    
    模板
    类MatrixP
    {
    公众:
    MatrixP运算符()(T数组[][n])
    {
    用于(自动i=0;istd::cout&startMatrix,4,&inverseMatrix为什么不创建一个矩阵类,而不是用C语言处理?(将对象传递到函数中,而不是调用对象上的方法)@GMan:既然OP说该函数是“库函数”,他很可能没有更改接口的自由。无论是否有类,在某个时候他都必须获得适当的“double**”才能传递给函数。函数的可能副本显然是使用任何大小(顺序)的方阵。仅将其限制为4x4矩阵是很难接受的。而且,现在传递“顺序”也没有意义。@AndreyT,我只是在向他/她演示如何执行此操作。如果我希望它是通用的,我可以向他演示如何拥有一个表示矩阵的类。在方形矩阵中,行计数与列计数相同。您将列计数硬编码为4。否w再也没有必要传递行数了-行数也必须是4,而且只有4。OP将该函数称为“库函数”。这通常意味着没有更改函数接口的自由。@AndreyT,好的,我没有看到它是库函数。如果你知道arra的大小