1

我编写了一个以一维数组作为输入的函数。在 main() 部分中,我需要将二维数组的行作为输入传递给该函数。我不知道这是否可能以及如何(在 Matlab 中是可能的,但在 C++ 中,我不知道)。所以,如果有人能告诉我,我将不胜感激。

4

3 回答 3

2

Assuming your function signature is void foo(int a[N]) and your input array is defined as int x[M][N], you can pass the rows of it to foo by calling foo(x[i]), where i denotes the line number of your 2D array.

于 2013-03-16T15:25:47.677 回答
1

我想你的函数看起来像这样:

void function(int row[]) { ... }

首先要理解的是,没有数组类型的参数这样的东西。上面的row参数可能看起来像一个数组,但它不是。实际上,它是一个等价于int* row.

第二件事要理解的是,数组的名称可以隐式转换为指向其第一个元素的指针。假设您有一个数组int array[] = {1, 2, 3, 4, 5};,您可以将function(array)其传递给函数。但是,您实际上并没有传递数组。真正发生的是array被传递的参数被转换为指向其第一个元素的指针 - 因此是指向1数组中值的指针。正如我们刚刚看到的,函数参数row实际上是一个指针,因此可以将此指针传递给它的第一个元素。

现在,我想你有一个看起来像这样的二维数组:

int array[N][M] = { ... };

如果我们考虑NM数和列数(您可以任意想象,但这与您的 matlab 知识一致),您知道array[0][1]将访问第一行的第二个元素(因为我们在 C++ 中从 0 开始索引)。如果您只提供一个下标,例如array[0],这表示二维矩阵的一整行。那个表达式 ,array[0]是一个ints 的数组。由于这个ints 数组可以转换为指向其第一个元素的指针,因此您可以传递array[0]并且函数将接收row指向第一行(或0第 th 行)的第一个元素的指针。

所以你可以这样做:

function(array[0]);

但是,因为row确实是一个指针,所以在函数内部,您对数组的实际大小一无所知。通常同时传递数组的大小:

void function(int row[], int size);

function(array[0], M);

但是,在惯用的 C++ 中,使用这样的数组类型通常不是最佳实践。我们更喜欢使用标准库提供的容器。例如,astd::array<std::array<int, M>, N>是一个很好的固定大小的二维数组模拟:

void function(std::array<int, M> row);

std::array<std::array<int, M>, N> array;
// Fill array...
function(array[0]);

现在您不必传递数组的大小,因为std::array和其他标准容器类型提供了获取大小的机制。

于 2013-03-16T15:32:33.090 回答
1

将列传递给函数可以很容易地完成:

void gimmeColumn(int x[]) {}

int main() {
    int table[10][10];
    int columnToPass = 3;
    gimmeColumn( table[columnToPass] );
}

但是,不可能以类似的方式传递一行。您可以考虑编写自己的类来促进这种行为。

template<type T>
class SelectableTable {
private:
    T** table;
    int rows, columns;
public:
    SelectableTable( int numRows, int numColumns )
    :
        rows( numRows ),
        columns( numColumns )
    {
        table = new T*[columns];
        for( int i=0; i<columns; i++ )
            table[i] = new T[rows];
    }

    ~SelectableTable() {
        for( int i=0; i<columns; i++ )
            delete[] table[i];
        delete[] table;
    }

    T* operator[](int column) {
        return table[column];
    }

    int getRows() {
        return rows;
    }

    int getColumns() {
        return columns;
    }

    TableRow selectRow(int row) {
        return TableRow<T>( *this, row );
    }
};

template<type T>
class TableRow {
private:
    int row;
    SelectableTable<T>& table;
public:
    TableRow( SelectableTable<T>& fromTable, int selectedRow )
    :
        table(fromTable),
        row(selectedRow)
    {}

    T& operator[](int column) {
        return table[column][row];
    }

    int size() {
        return table.getColumns();
    }
};

然后你可以简单地使用它:

void gimmeRow( TableRow<int> row ) {
    for( int i=1; i<row.size(); i++ )
        row[i] = row[i-1];
}

int main() {
    SelectableTable<int> table(10,10);
    int rowToPass = 3;
    gimmeRow( table.selectRow(rowToPass) );
}

当然,要让这段代码工作,你应该添加一些前向声明,最好使用标题。为了统一起见,您还可以实现一个 class TableColumn

于 2013-03-16T15:51:47.750 回答