2015-12-14 80 views
2

基本上,我的问题是:我有用户定义的2D阵列的大小(N,M),然后我声明:传递未知大小的2D阵列的函数C++

INT矩阵[N ] [M];

那么我就需要这个未初始化的矩阵传递给从.csv文件中读取一些数据,并把它放入矩阵的功能,所以我尝试:

void readwrite(int &matrix[N][], const int N, const int M){....}; 


int main(){ 
.... 
cin>>N; 
cin>>M; 

int matrix[N][M]; 
readwrite(matrix,N,M); 
}; 

然而,当我编译它,它给我以下错误:“N没有在此范围内声明”。

如何使这项工作的任何想法?

谢谢你们!

+2

题外话:'INT矩阵[N] [M];'具有可变'N'和'M'是不合法的C++。它可以在一些编译器中进行扩展。谨慎并且不要指望它在移植到不同的编译器时工作。 – user4581301

+0

也许这会有帮助吗? http://stackoverflow.com/questions/936687/how-do-i-declare-a-2d-array-in-c-using-new –

回答

0

int &matrix[N][] - N必须是一个编译时常量,而不仅仅是const而且根本不是一个参数。并且对数组的引用声明如下:int (&matrix)[size]

尝试传递int **matrix,并且还需要更改创建此数组的方式。 Variable lenght arrays are not supported in C++,您需要动态分配内存。或者说,如果您知道编译时的大小,请坚持使用std::vector,std::array

+0

你试过编译过吗? – juanchopanza

+0

int&matrix [N] []'并不意味着一个建议。 – LogicStuff

+0

但是你的主导语句暗示,如果'N'是一个编译时常量,这就是确定的,这就是我问的原因。 – juanchopanza

0

什么OP正在尝试是如此令人讨厌的难以得到正确的做法,并且与成本相比,拉动它的好处是微不足道的......好吧,我会引用经典。

The only winning move is not to play.

-Joshua,战争游戏

你不能安全地通过在C++中动态分配二维数组到一个函数,因为你总是要在编译时知道至少有一个尺寸。

我可以指向Passing a 2D array to a C++ function,因为这看起来像一个很好的重复。我不会因为它指的是静态分配的数组。

你可以玩愚蠢的铸造游戏来强制数组进入函数,然后将其重新投射到里面。我不会解释如何做到这一点,因为它是史诗级的愚蠢,应该是一个射击罪。

您可以将指针传递给指针int **,但构造和销毁逻辑是一个奇怪的集合new和循环。此外,最终结果会散布RAM周围的已分配内存,削弱处理器在预测和缓存方面的尝试。在现代处理器上,如果你无法预测和缓存,你会抛弃CPU的大部分性能。

你想要做的是保持一维。一维数组很容易通过。索引算法非常简单,易于预测。这都是一个内存块,所以缓存命中更有可能不会。

制作一维数组很简单:不要。改为使用std::vector

std::vector<int> arr(rows*columns); 

如果您必须因为赋值规范说“无向量!”那么你卡住了。

int * arr = new int[rows*columns]; 

注意我使用rowscolumnsMN。当遇到MN这是哪个?谁知道,谁在乎,为什么这样对自己首先呢?给你的变量提供一个好的描述性的名字,并且在稍后调试时能够节省读取代码的时间。

使用的胆与阵列和矢量相同:

int test = arr[row * columns + column]; 

将在[row][column]恢复在二维空间中的元件。我不应该解释这些变量的含义。死亡至MN

定义函数是:

void function (std::vector<int> & arr, size_t rows, size_t columns) 

或(呸)

void function (int * arr, size_t rows, size_t columns) 

注意rowscolumnssize_t类型。 size_t是无符号数(负数组大小不是你想要的,所以为什么允许它?),并且它保证足够大以保存可以使用的最大可能数组索引。换句话说,它比int更合适。但为什么到处通过rowscolumns?在这一点上做的聪明的事情是围绕数组及其控制变量进行封装,然后使用几个函数来使事情更易于使用。

template<class TYPE> 
class Matrix 
{ 
private: 
    size_t rows, columns; 
    std::vector<TYPE> matrix; 
public: 
    // no default constructor. Matrix is BORN ready. 

    Matrix(size_t numrows, size_t numcols): 
     rows(numrows), columns(numcols), matrix(rows * columns) 
    { 
    } 
// vector handles the Rule of Three for you. Don't need copy and move constructors 
// a destructor or assignment and move operators 

    // element accessor function 
    TYPE & operator()(size_t row, size_t column) 
    { 
     // check bounds here 
     return matrix[row * columns + column]; 
    } 

    // constant element accessor function 
    TYPE operator()(size_t row, size_t column) const 
    { 
     // check bounds here 
     return matrix[row * columns + column]; 
    } 

    // stupid little getter functions in case you need to know how big the matrix is 
    size_t getRows() const 
    { 
     return rows; 
    } 
    size_t getColumns() const 
    { 
     return columns; 
    } 

    // and a handy-dandy stream output function 
    friend std::ostream & operator<<(std::ostream & out, const Matrix & in) 
    { 
     for (int i = 0; i < in.getRows(); i++) 
     { 
      for (int j = 0; j < in.getColumns(); j++) 
      { 
       out << in(i,j) << ' '; 
      } 
      out << '\n'; 
     } 

     return out; 
    } 

}; 

粗糙的阵列版本将不得不看起来像只是为了显示允许向量来做它的工作的好处。未经测试。可能包含咯咯声。重点在于更多的代码和更多的错误空间。

template<class TYPE> 
class ArrayMatrix 
{ 
private: 
    size_t rows, columns; 
    TYPE * matrix; 
public: 
    ArrayMatrix(size_t numrows, size_t numcols): 
     rows(numrows), columns(numcols), matrix(new TYPE[rows * columns]) 
    { 
    } 

    // Array version needs the copy and move constructors to deal with that damn pointer 
    ArrayMatrix(const ArrayMatrix & source): 
     rows(source.rows), columns(source.columns), matrix(new TYPE[rows * columns]) 
    { 
     for (size_t i = 0; i < rows * columns; i++) 
     { 
      matrix[i] = source.matrix[i]; 
     } 
    } 

    ArrayMatrix(ArrayMatrix && source): 
     rows(source.rows), columns(source.columns), matrix(source.matrix) 
    { 
     source.rows = 0; 
     source.columns = 0; 
     source.matrix = nullptr; 
    } 

    // and it also needs a destructor 
    ~ArrayMatrix() 
    { 
     delete[] matrix; 
    } 

    TYPE & operator()(size_t row, size_t column) 
    { 
     // check bounds here 
     return matrix[row * columns + column]; 
    } 

    TYPE operator()(size_t row, size_t column) const 
    { 
     // check bounds here 
     return matrix[row * columns + column]; 
    } 

    // and also needs assignment and move operator 
    ArrayMatrix<TYPE> & operator=(const ArrayMatrix &source) 
    { 
     ArrayMatrix temp(source); 
     swap(*this, temp); // copy and swap idiom. Read link below. 
     // not following it exactly because operator=(ArrayMatrix source) 
     // collides with operator=(ArrayMatrix && source) of move operator 
     return *this; 
    } 

    ArrayMatrix<TYPE> & operator=(ArrayMatrix && source) 
    { 
     delete[] matrix; 
     rows = source.rows; 
     columns = source.columns; 
     matrix = source.matrix; 

     source.rows = 0; 
     source.columns = 0; 
     source.matrix = nullptr; 

     return *this; 
    } 

    size_t getRows() const 
    { 
     return rows; 
    } 
    size_t getColumns() const 
    { 
     return columns; 
    } 
    friend std::ostream & operator<<(std::ostream & out, const ArrayMatrix & in) 
    { 
     for (int i = 0; i < in.getRows(); i++) 
     { 
      for (int j = 0; j < in.getColumns(); j++) 
      { 
       out << in(i,j) << ' '; 
      } 
      out << std::endl; 
     } 

     return out; 
    } 

    //helper for swap. 
    friend void swap(ArrayMatrix& first, ArrayMatrix& second) 
    { 
     std::swap(first.rows, second.rows); 
     std::swap(first.columns, second.columns); 
     std::swap(first.matrix, second.matrix); 
    } 

}; 

创建,其中之一是

Matrix<int> arr(rows, columns); 

现在通过阵列周围是

void func(Matrix & arr); 

使用数组是

int test = arr(row, column); 

所有索引数学是隐藏从视线。

其它参考文献:

What is the copy-and-swap idiom?

What is The Rule of Three?