尝试使用2D阵列

时间:2018-08-05 06:40:00

标签: c++ multidimensional-array function-parameter

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

我正在编写一个函数来计算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 ++对2D数组有很深的成见,不喜欢它们并且拒绝使用它们,但是我所读的一切都建议通过将大小N指定为应该起作用的参数来建议。确实如此。在C99中。但是不能使用g ++编译器(既不是C ++ 99也不是C ++ 11)。

我必须使用一些特定的编译器标志吗?还是其他方法可以做到这一点?

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

如果可能的话,我想避免使用1D数组制作2D数组。我知道如何使用1D阵列执行此操作,我只想以更自然,更优雅的方式执行此操作。

谢谢。

编辑:而且我知道您会建议我使用vector <>代替。使用vector <>并不是最佳选择,因为所有这些都应该进入一个更大的程序中,该程序在大约20,000行处仅使用数组。

编辑2:The GNU compiler documentation说,它以C ++的形式扩展了VLA。过去的其他几张海报都发布了VLA起作用的惊奇消息,并询问如何关闭该功能。但是如何打开它?

1 个答案:

答案 0 :(得分:2)

在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