我试图理解一些将多维数组传递给函数的代码。但是这个功能的原型引起了我的兴趣。
该程序创建了这个"标签"变量:
#define N 8
float tab[N][N];
tab[0][0] = 2; tab[0][1] = 3; tab[0][2] = -1;
tab[1][0] = 3; tab[1][1] = 1; tab[1][2] = -4;
tab[2][0] = 1; tab[2][1] = 2; tab[2][2] = 3;
hello(tab);
我们有这个功能:
function hello(float mat[][N]) {
我不明白为什么hello函数使用空[]然后用[N]获取tab变量。它有什么变化?我不明白......为什么不选择[] []?
代码似乎是由优秀的开发人员制作的,所以我不认为N变量是无缘无故的。
如果你能解释一下,谢谢你的时间!
答案 0 :(得分:1)
float tab[N][N];
按N
定义N
数组。我不打算使用行或列,因为数组如何面向程序逻辑可能与数组在内存中的表示方式无关。只要知道它将是一个N * N long的内存块,可以使用mat[0..N-1][0..N-1]
进行访问。尺寸是已知的并且是恒定的。定义数组时,它必须知道它的大小,并且此大小不能更改。如果您不知道尺寸,请使用std::vector
或std::vector<std::vector<YOUR TYPE HERE>>
float tab[][];
是非法的,因为数组的大小未知。编译器不知道要为阵列分配多少存储空间,也无法生成功能(即使有缺陷)的程序。
将数组传递给
等函数时function hello(float mat[][N])
数组衰减成指针。更多信息:What is array decaying?一旦数组衰减,第一个维度的大小就会丢失。要安全地使用数组,您必须已经知道数组的大小或将其作为另一个参数提供。例如:
function hello(float mat[][N], size_t matLen)
问题是,大小为N
。你知道它是N
,你可以安全地打电话给
hello(mat);
不提供任何大小调整,只需在函数内部使用N
作为边界。 N不是一个狡猾的magic number,但可以给它一个更具描述性的名称。
您也可以完全明确
function hello(float mat[N][N])
并消除任何歧义以及使用大小为M到N的数组的函数的能力。有时它是值得做出的权衡。
答案 1 :(得分:0)
让我解释一下“非技术性”,但可能是全面的:
将float tab[ROW][COL]
视为浮点数的二维数组,其中“ROW”代表行,“COL”代表列,并认为数组映射到内存一个完整的行跟随另一个,即
r0c0,r0c1,r0c2
r1c0,r1c1,r1c2
r2c0,r2c1,r2c2
代表ROW=3
和COL=3
。然后,如果编译器必须找出写入tab[2][1]
的位置,那么它必须占用行大小的2倍+ 1(其中行大小实际上是列COL
的数量)。因此,对于寻址单元格,知道行的大小是相关的,而在一行中,只需要添加列索引。因此,像tab[][N]
这样的声明就足够了,因为N
定义了列数 - 即行的大小 - 并让编译器正确地寻址每个单元格。
希望它有所帮助。