尝试使用二维数组

Trying to use 2D arrays

我知道有人问过这个问题,但我还没有真正看到对我有意义的答案。

我正在编写一个用 C++ 计算行列式的函数。为此,我需要传递一个矩阵。

我的代码如下所示:

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

double determinant(int N, double M[N][N]);

int main(){
    double myMatrix[3][3] = {{1,2,3}, {4,5,6}, {3,6,1}};
    double okay = determinant(4, myMatrix);
    printf("determinant = %f\n", okay);
}


double determinant(int N, double M[N][N]){
    double det=0.0;
    //if N=2 matrix, use the easy formula
    if(N==2){
        det = M[0][0]*M[1][1] - M[0][1]*M[1][0];
    }
    //otherwise, find minor matrices, multiply by top row
    else {
        double Mminor[N-1][N-1];
        double sign = 1.0;
        for(int i=0; i<N; i++){
            //get the minor matrix
            for(int a=1;a<N;a++){
                int m=0;
                for(int b=0;b<N;b++){
                    if(b!=i){
                        Mminor[a-1][m] = M[a][b];
                        m++;
                    }
                }
            }
            //add top row element times determinant of its minor
            det += sign*M[0][i]*determinant(N-1, Mminor);
            //swap the sign
            sign *= -1.0;
        }
    }
    return det;
}

如果我将其编译为 C 并使用 C99 编译器,它运行良好且没有任何问题,为几个不同的测试矩阵提供了正确的值。

但是我不需要它来编译为 C,我需要它来编译为 C++。而且它不会编译为 C++。 GNU 编译器给出以下错误:

determinant.c:25:24: error: no matching function for call to 'determinant'
                        det += sign*M[0][i]*determinant(N-1, Mminor);
                                            ^~~~~~~~~~~
determinant.c:5:8: note: candidate function not viable: no known conversion from 'double [N - 1][N - 1]' to
      'double (*)[N]' for 2nd argument
double determinant(int N, double M[N][N]){
       ^
determinant.c:36:16: error: no matching function for call to 'determinant'
        double okay = determinant(4, myMatrix);
                      ^~~~~~~~~~~
determinant.c:5:8: note: candidate function not viable: no known conversion from 'double [4][4]' to 'double (*)[N]'
      for 2nd argument
double determinant(int N, double M[N][N]){

我知道 C 和 C++ 对二维数组有很深的偏见并且不喜欢它们并拒绝使用它们,但是我读过的所有内容都表明通过指定大小 N 作为参数它应该管用。确实如此。在 C99 中。但不适用于 g++ 编译器(既不是 C++99 也不是 C++11)。

我必须使用一些特定的编译器标志吗?或者其他一些方法来做到这一点?

明确一点:我需要矩阵的大小是灵活的,因为每次调用函数时它都会不同。

如果可能的话,我想避免使用一维数组来制作二维数组。我知道如何使用一维数组执行此操作,但我宁愿以更自然和优雅的方式执行此操作。

谢谢。

编辑:我知道您会建议我改用 vector<>。使用 vector<> 不是最佳选择,因为这一切都应该进入一个更大的程序,大约 20,000 行,只使用数组。

编辑 2:The GNU compiler documentation 说它在 C++ 中实现 VLA 作为语言的扩展。其他几位过去的发帖人对 VLA 的工作感到惊讶,并询问如何关闭该功能。但是如何开启它呢?

在 C++ 中,您可以使用模板:

#include <iostream>

double determinant(const double (&M)[2][2]){
    return M[0][0] * M[1][1] - M[0][1] * M[1][0];
}

template <std::size_t N>
double determinant(const double (&M)[N][N]){
    double det=0.0;

    double Mminor[N - 1][N - 1];
    double sign = 1.0;
    for (int i = 0; i < N; i++) {
        //get the minor matrix
        for (int a = 1; a < N; a++) {
            int m=0;
            for (int b = 0; b < N; b++) {
                if (b != i) {
                    Mminor[a - 1][m] = M[a][b];
                    m++;
                }
            }
        }
        //add top row element times determinant of its minor
        det += sign * M[0][i] * determinant(Mminor);
        //swap the sign
        sign *= -1.0;
    }
    return det;
}

int main(){
    const double myMatrix[3][3] = {{1,2,3}, {4,5,6}, {3,6,1}};
    double okay = determinant(myMatrix);
    std::cout << "determinant = " << okay << std::endl;
}

Demo