c++ - C ++:引用二维数组?为什么这个功能有效
问题描述
参数 printArray(int (&a)[n][m]) 是什么意思?为什么括号是必需的,为什么只需要向 printArray 函数提供 1 个值?函数调用时如何知道 n 和 m?
template <size_t n, size_t m>
void printArray(int (&a)[n][m]) {
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
cout << a[i][j] << " ";
}
cout << endl;
}
}
int main(int argc, char* argv[])
{
cout << "Example I:" << endl;
int ab[2][5];
printArray(ab);
cout << "Example II:" << endl;
int b[2][5] = {{1, 2, 3}};
printArray(b);
cout << "Example III:"<< endl;
int c[][5] = {1, 2, 3, 4, 5, 6, 7};
printArray(c);
cout << "Example IV:" << endl;
int d[][5] = {{1, 2, 3, 4}, {5, 6}, {7}};
printArray(d);
}
解决方案
参数
printArray(int (&a)[n][m])
是什么意思?
这意味着这a
是对类型对象的引用int[n][m]
。是类型对象int[n][m]
的数组。是类型对象的数组。因此,是对具有维度和的二维数组的引用。m
int[n]
int[n]
n
int
a
n
m
n
并且m
是在 . 中声明的模板参数template <size_t n, size_t m>
。两个参数的类型都是size_t
,它是一个整数类型。
为什么需要括号
因为 &-token 绑定到左边。int&
是对 int 的引用。int& a[n]
在语法上意味着这a
是一个引用数组(尽管不允许这样的数组)。括号用于区分 &-token 是声明对 int 的(数组)引用还是对数组的引用。
为什么只需要向 printArray 函数提供 1 个值?
该函数只有一个参数:a
. 如果您传递一个可以绑定到适当类型的数组引用的值,那么它就可以工作。在您的所有示例中,参数都是二维整数数组,因此它们是正确的。
函数调用时如何知道 n 和 m?
编译器知道,因为数组的大小是数组类型的一部分。并且由于模板参数推导。当模板参数没有明确指定时,它可以从函数的参数中推导出来。在这种情况下,如果您传递类型为 的参数int[2][5]
,则n
推断为 2 并m
推断为 5。
你甚至可以添加一个模板类型参数,然后推导出来:
template <size_t n, size_t m, typename T>
void printArray(T (&a)[n][m])
T
int
如果您要传递一个二维整数数组,则推断为。
如果不允许引用数组,为什么编译器不能推断出括号是不必要的。
如果int &a[n]
意味着对数组的引用,因为不能有引用数组,那么它会使程序员感到困惑int *a[n]
,因为它不是指向数组的指针,因为可以存在指针数组。
此外,这会通过为不必要的引用添加特殊情况而使语言复杂化。
为什么不是形式: printArray(int[n][m] &a)
更简单的说,为什么数组不能用int[n] a
instead of来声明int a[n]
。因为后一种语法是由 C 语言的设计者(大概是丹尼斯·里奇当时)选择的。
推荐阅读
- python-3.x - 为特定数据选择 ε 有什么问题?
- ruby-on-rails - 如何扩展 ActionView::Template::Types
- xamarin - 使用 Real To Tap() 警报上的“确定”按钮
- arrays - 使用循环获取一组元素
- c++ - LOKI C++:“ScatterHierarchyTag”如何解决继承歧义?
- oracle - Oracle Pl/SQL 循环仅在记录插入表时返回
- regex - perl 单行中转义和捕获的正确语法是什么?
- python-3.x - 将字符串添加到列表正在创建字符列表
- sql-server - TSQL - 枢轴不返回所有行
- excel-formula - 在 Excel 中搜索后查找最后一个值