传递矩阵作为参数时出错

时间:2016-01-13 18:51:39

标签: c++ matrix

我试图了解如何在C ++中使用矩阵。底部的代码应该采用输入矩阵并返回0的位置。但是,我收到以下错误:

 matrix.cpp:47:3: error: no matching function for call to 'make_zero'  make_zero(i,j,l);
     ^~~~~~~~~
    matrix.cpp:8:6: note: candidate function not viable: no known conversion from 'double [i][j]' to
      'double (*)[col]' for 3rd argument
    void make_zero(int row, int col, double matrix[row][col])
     ^
    1 error generated.

当我尝试运行以下代码时:

// Matrix

#include <iostream> 
#include <stdio.h>

using namespace std;

void make_zero(int row, int col, double matrix[row][col])
  {
     int k,l;  
 for(k=0;k<row;k++)
    for(l=0;l<col;l++)
    {
        if(matrix[k][l]==0)
           printf("%d %d\n",k,l);
    }

 }



int main ()
{
  int i = 0,j = 0;

  cout << "Enter no of rows of the matrix";
  cin >> i;
  cout << "Enter no of columns of the matrix";
  cin >> j;

  double l[i][j];

  int p = 0, q = 0;

  while (p < i) {
while (q < j) {
  cout << "Enter the" << p + 1 << "*" << q + 1 << "entry";
  cin >> l[p][q];

  q = q + 1;
}
p = p + 1;
q = 0;
  }
  cout << l << "\n";

  make_zero(i,j,l);
}

任何帮助将不胜感激。感谢。

2 个答案:

答案 0 :(得分:1)

void make_zero(int row, int col, double ** matrix)

请注意,您还需要单独传递矩阵的大小。

您也可以使用

std::vector<std::vector<double> >

而是通过引用,指针传递此对象,或者只是复制。

实际上,它有效,但你在这一行中的问题也是:

double l[i][j];

i,j在编译期间是未知的。 你有两种方式。

1)动态分配内存

2)使用std::vector<std::vector<double> >。默认构造函数已设置零值。但你可以像这样手动完成:

#include <iostream>
#include <vector>

void make_zero(std::vector<std::vector<double> > & to_zero) {
    for (int i = 0; i < to_zero.size(); ++i) {
        for (int j = 0; j < to_zero[i].size(); ++j) {
            to_zero[i][j] = 0;
        }
    }
}


void print_double_vector(const std::vector<std::vector<double> > & to_print) {
    for (int i = 0; i < to_print.size(); ++i) {
        for (int j = 0; j < to_print[i].size(); ++j) {
            std::cout << to_print[i][j] << " ";
        }
        std::cout << std::endl;
    }
    std::cout << std::endl;
}


int main() {
    // your code goes here
    int n, m;
    std::cin >> n >> m;
    std::vector<std::vector<double> > d(n, std::vector<double>(m));
    print_double_vector(d);
    make_zero(d);
    print_double_vector(d);
    return 0;
}

http://ideone.com/0X53Yj

答案 1 :(得分:1)

使用指针有很多方法可以做到这一点。最常见的是

void make_zero(int row, int col, double ** matrix)

为指针(通常是列)定义指针(通常是行)。不幸的是

double l[i][j]; 

没有定义指向指针的指针。如果编译器支持这种语法,并且编译器不需要允许可变长度的数组,则很可能定义指向1D数组(double l[i*j];)的指针并隐藏用于将数组转换为的数组的索引算法两个维度。无论如何,它不能传递给double **,因为它不是double **

尝试传递为数组很麻烦

void make_zero(int row, int col, double matrix[][NUMBER_OF_COLUMNS])

必须知道数组中的列数才能执行索引算法,并将其提供给使用它调用的任何函数。这意味着在运行时无法更改列数,因为函数使用的索引将变为无效。

解决这个问题需要对编译器进行更改,以便进一步推动C ++标准。一个坏主意,因为有许多简单的方法来调用多维数组的函数。大多数都依赖于数组数组或std::vector s的std::vector

就这些解决方案而言,就我而言,最好的不是。我不打算掩盖它们。

表示维度的数组都不能保证与内存中的其他数组接近,这限制了CPU读取和缓存的能力。没有缓存并且能够向前看,现代CPU处于严重的性能劣势。 (阅读更多信息:Why is it faster to process a sorted array than an unsorted array?

所以你想要的是1 D阵列,那些很容易传递。索引数学也很容易,行号*列的大小+列号,但是你需要至少传递列的大小。而不是像这样分散书籍:

void make_zero(int row, int col, std::vector<double> matrix)

制作一个这样的包装类:

class Matrix
{
private:
    std::vector<double> myArray;
    size_t nrRows;
    size_t nrColumns;

public:
    Matrix(size_t rows, size_t columns) :
            myArray(rows * columns), // allocate vector to store matrix. 
            nrRows(rows), 
            nrColumns(columns)
    {

    }
    size_t getNrRows() const
    {
        return nrRows;
    }
    size_t getNrColumns() const
    {
        return nrColumns;
    }

    // gets value at row, column and returns a reference so caller can 
    // modify the value
    double& operator()(size_t row, size_t column)
    {
        // note: No sanity check for row >= nrRows or column > nrColumns
        return myArray[row * nrColumns + column];
    }

    // gets value at row, column and returns a copy so caller cannot
    // change the contents of the Matrix
    double operator()(size_t row, size_t column) const
    {
        return myArray[row * nrColumns + column];
    }
};

使用vector通过管理自己的内存来解决许多常见的指针到数组的问题。不需要析构函数,Matrix可以复制和移动,无需特殊处理,因为vector为我们执行了所有繁重的工作。

作为一个用法示例,让我们创建一个打印矩阵的函数:

std::ostream & operator<<(std::ostream &  out, const Matrix & in)
{
    for (size_t i = 0; i < in.getNrRows(); i++)
    {
        for (size_t j = 0; j < in.getNrColumns(); j++)
        {
            out << in(i,j) << ' ';
        }
        out << "\n";
    }

    return out;
}

修改OP main函数以使用Matrix我们得到:

int main()
{
    int i = 0, j = 0;

    cout << "Enter no of rows of the matrix";
    cin >> i;
    cout << "Enter no of columns of the matrix";
    cin >> j;

    Matrix matrix(i,j);

    int p = 0, q = 0;

    while (p < i)
    {
        while (q < j)
        {
            cout << "Enter the" << p + 1 << "*" << q + 1 << "entry";
            cin >> matrix(p,q);

            q = q + 1;
        }
        p = p + 1;
        q = 0;
    }
    cout << matrix << "\n";

    make_zero(matrix);
}