我编写了一个以一维数组作为输入的函数。在 main() 部分中,我需要将二维数组的行作为输入传递给该函数。我不知道这是否可能以及如何(在 Matlab 中是可能的,但在 C++ 中,我不知道)。所以,如果有人能告诉我,我将不胜感激。
3 回答
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.
我想你的函数看起来像这样:
void function(int row[]) { ... }
首先要理解的是,没有数组类型的参数这样的东西。上面的row
参数可能看起来像一个数组,但它不是。实际上,它是一个等价于int* row
.
第二件事要理解的是,数组的名称可以隐式转换为指向其第一个元素的指针。假设您有一个数组int array[] = {1, 2, 3, 4, 5};
,您可以将function(array)
其传递给函数。但是,您实际上并没有传递数组。真正发生的是array
被传递的参数被转换为指向其第一个元素的指针 - 因此是指向1
数组中值的指针。正如我们刚刚看到的,函数参数row
实际上是一个指针,因此可以将此指针传递给它的第一个元素。
现在,我想你有一个看起来像这样的二维数组:
int array[N][M] = { ... };
如果我们考虑N
行M
数和列数(您可以任意想象,但这与您的 matlab 知识一致),您知道array[0][1]
将访问第一行的第二个元素(因为我们在 C++ 中从 0 开始索引)。如果您只提供一个下标,例如array[0]
,这表示二维矩阵的一整行。那个表达式 ,array[0]
是一个int
s 的数组。由于这个int
s 数组可以转换为指向其第一个元素的指针,因此您可以传递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
和其他标准容器类型提供了获取大小的机制。
将列传递给函数可以很容易地完成:
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
。