尝试使用2D阵列

Trying to use 2D arrays

本文关键字:2D 阵列      更新时间:2023-10-16

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

我正在编写一个函数来计算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 = %fn", 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阵列,我只想用一种更自然、更优雅的方式来做这件事。

谢谢。

编辑:我知道你会建议我使用向量<>相反使用矢量<>并不是最优的,因为这一切都应该进入一个更大的程序,大约20000行,只使用数组。

编辑2:GNU编译器文档说,它在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;
}

演示