【问题标题】:Passing multidimensional arrays (without initially defining its dimensions) into a function in C++将多维数组(没有最初定义其维度)传递给 C++ 中的函数
【发布时间】:2015-01-31 08:50:02
【问题描述】:

我一直在寻找有关如何创建矩阵行列式计算器的代码,我从 (Matrix determinant algorithm C++) 找到了代码。

我采用代码进行尝试,但我意识到我不知道如何将多维数组传递给函数,而没有先定义它的维度(我出错了)。

那么,您能否告诉我如何在不先定义其维度的情况下将多维数组传递给函数(即int a[MAX][MAX] 是一个参数,什么是“MAX”)。

希望我的问题很清楚,谢谢你的帮助。

这是(编辑的)代码: - 样本输入将是方阵及其大小

int determinant(int oMat[][], int n){

    int sMat[n][n]; //Temporary matrix
    int det = 0; //Initializing 'det'.

    if(n==1){
        det = oMat[0][0]; //Calculating.
        return det;
    }else if(n==2){
        det = oMat[0][0]*oMat[1][1] - oMat[1][0]*oMat[0][1]; //Formula for 2x2.
        return det;
    }else{

        for(int p=0; p<n; p++){ //Selecting 'oMat' row one.
            int k=0; //'sMat' rows.
            int m=0; //'sMat' columns.

            //Creating the temporary matrix 'sMat'.
            for(int i=1; i<n; i++){ //for 'oMat' rows.
                for(int j=0; j<n; j++){

                    if(j==p){
                        continue;
                    }

                    sMat[k][m] = oMat[i][j]; m++;


                    if(m==n-1){
                        k++; //Go to the next row.
                        m = 0; //Start at column one (index 0).
                    }
                }
            }

            det = det + oMat[0][p] * pow(-1,p) * determinant(sMat, n-1);

        }
        return det;
    }
}

【问题讨论】:

  • 你的意思一定是如何传递多维度数组而不是解析?
  • 如何通过 我的意思是,我刚刚编辑了它。谢谢。
  • 请编辑问题以包含示例输入、您实际尝试过的代码、代码的实际和预期输出以及尽可能多的其他详细信息。
  • 尝试将模板函数写成template T dterm(T (&my_matrix)[R][C]){...}

标签: c++


【解决方案1】:

您可以通过引用传递一个数组,并让函数计算出矩阵的大小。为此,请使用如下模板

template <int R>
int determ(int (&a)[R][R]) {
//now R is the number of rows
std::cout << R << std::endl;
// rest of code here
}

【讨论】:

    【解决方案2】:

    如果您将二维数组传递给函数 determ() as

    int a[MAX][MAX];
    determ(a, int n);
    

    函数声明应该是:

    determ(int a[][MAX], int n) { .. }
    

    在上面的声明中不需要指定行数,因为我们没有为数组分配内存,因此可以忽略。数组的维度需要列数。

    【讨论】:

    • 这是最合理的答案,因为我以前用过这个
    • @IrrationalPerson 这仍然允许您传递错误大小的矩阵。与int determ(int (*a)[MAX]); 相同。更好的解决方案是通过引用传递矩阵。
    • 好吧,那么“MAX”到底是什么?我需要定义它吗...它是预处理器的一部分吗?
    • @ATM 绝对不是预处理器宏。你应该定义它。
    • @ATM 必须是编译时间常数。
    【解决方案3】:

    有两种方式:

    1) 按原样声明你的函数:

    int determ(int** a, int size, int n) {...} // 'size' aka 'MAX'
    

    2) 使用动态容器,例如 std::vector:

    int determ(const vector<vector<int>>& a, int n) {...}
    

    【讨论】:

    • 请注意,向量的向量与二维数组完全不同。它更像是一个指向数组的指针数组。
    • @Alexey:我会尝试,但如果我可以问,int** 是什么意思。
    • @ATM,它称为“指向指针的指针”,本质上是对编译器的提示。问题是,使用指针 'int* a' 你可以写 'a[2] = 2' 类似地,使用 "int **a" - 'a[2][2] = 2'
    • 我做了什么:int determinant(int** oMat, int n) 但后来我在这一行出现错误det = det + oMat[0][p] * pow(-1,p) * determinant(sMat, n-1)
    • @juanchopanza,是的,我提出了一个更好的设计解决方案,但你绝对正确:在底层它们完全不同
    【解决方案4】:

    您有多种选择:

    1. 使用像MAX 这样的编译时大小,并据此声明您的数组参数:

      int determinant(int (*oMat)[MAX], int n) {
      

      这样您就可以将指针传递给二维数组的第一个元素(= 行)。 std::array&lt;&gt; 模板也可以做到这一点:

      int determinant(array<array<int, MAX>, MAX> *oMat, int n) {
      

      但是,在这两种情况下,MAX 都必须是编译时间常数。您可以将MAX 作为模板参数传入,允许不同的代码处理不同大小的矩阵,但问题仍然是MAX 需要是编译时间常数。

    2. 如果你想在 C++ 中使用动态大小,你有两个选择:首先你可以使用向量的向量

      int determinant(vector<vector<int> > *oMat, int n) {
      

      这允许最大的灵活性,但是,它并不强制行具有相同的大小。 oMat 可能是一个参差不齐的二维数组。另一种方法是使用一维数组并自己计算索引:

      int determinant(int size, int *oMat, int n) {
          for(int i = 0; i < size; i++)
              for(int j = 0; j < size; j++)
                  //Access the individual elements with
                  oMat[size*i + j];
      
    3. 第三种方法是退回到 C,因为与 C++ 相比,C 允许真正的动态二维数组:

      int determinant(int size, int (*oMat)[size], int n) {
          for(int i = 0; i < size; i++)
              for(int j = 0; j < size; j++)
                  //Access the individual elements with
                  oMat[i][j];
      

      您将创建数组并像这样调用函数:

      int n = /*whatever*/;
      int (*matrix)[n] = malloc(n*sizeof(*matrix));
      fillMatrix(n, matrix);
      determinant(n, matrix, n);
      free(matrix);    //Don't forget the cleanup.
      

    【讨论】:

    • 我想尝试选项一,但是什么是编译时间大小?怎么用...我定义MAX...?
    • 编译时间常数意味着编译器在编译程序时必须知道该值,它不能依赖于只有在程序运行时才知道的任何东西。通常,这些编译时常量要么是具有全局、命名空间或静态类范围的 const 变量,要么是像 7 这样的普通文字,要么是作为模板参数传递给模板的。 array&lt;7&gt;7 作为这样的模板参数传递给 array&lt;&gt; 模板。但是,传递给模板参数的值本身必须是编译时常量,即。 array&lt;n&gt; 不行。
    • 感谢cmaster的解释。
    猜你喜欢
    • 2016-01-30
    • 2014-01-15
    • 1970-01-01
    • 2014-11-19
    • 2014-03-16
    • 2011-09-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多