奇怪的数组参数恢复

时间:2017-02-07 23:37:42

标签: c++ c function multidimensional-array

我试图理解一些将多维数组传递给函数的代码。但是这个功能的原型引起了我的兴趣。

该程序创建了这个"标签"变量:

#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变量是无缘无故的。

如果你能解释一下,谢谢你的时间!

The original code

2 个答案:

答案 0 :(得分:1)

float tab[N][N];

N定义N数组。我不打算使用行或列,因为数组如何面向程序逻辑可能与数组在内存中的表示方式无关。只要知道它将是一个N * N long的内存块,可以使用mat[0..N-1][0..N-1]进行访问。尺寸是已知的并且是恒定的。定义数组时,它必须知道它的大小,并且此大小不能更改。如果您不知道尺寸,请使用std::vectorstd::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=3COL=3。然后,如果编译器必须找出写入tab[2][1]的位置,那么它必须占用行大小的2倍+ 1(其中行大小实际上是列COL的数量)。因此,对于寻址单元格,知道行的大​​小是相关的,而在一行中,只需要添加列索引。因此,像tab[][N]这样的声明就足够了,因为N定义了列数 - 即行的大小 - 并让编译器正确地寻址每个单元格。

希望它有所帮助。