首页 理论教育使用二维数组作函数参数

使用二维数组作函数参数

【摘要】:二维数组在存储时也是有序地占用一片连续的内存区域,数组的名字表示这段存储区域的首地址。为了提高函数的通用性,可以借助一维数组作为形式参数时可以不指定长度的特点,使用一维数组样式的形式参数接收二维数组实参。重新设计例6.16中的函数max,使其能够处理任意行列的二维数组,并用相应的主函数进行测试。

二维数组在存储时也是有序地占用一片连续的内存区域,数组的名字表示这段存储区域的首地址。需要特别注意的是,二维数组起始地址有多种表示方法,而且这些表示方法在物理含义上还有表示平面起始地址和表示线性起始地址之分,所以在使用二维数组的起始地址时必须注意区分需要用哪一种起始地址。以二维数组a为例,二维数组起始地址的表示方法以及各种表示方法的级别(包含的物理含义)有:

·数组名:a,表示二维数组的起始地址,二级地址;

·数组首元素地址:&a[0][0],表示二维数组的线性起始地址,一级地址;

·数组0号行名字:a[0],表示二维数组的线性起始地址,一级地址;

·数组名指针运算后的地址:*a,表示二维数组的线性起始地址,一级地址;

由于二维数组的起始地址有一级地址和二级地址之分,所以二维数组作为函数调用实际参数时可以分为二级地址参数和一级地址参数两种。

图6.10 实际参数为二维数组名字

1.用二维数组名作为实际参数

用二维数组名作为函数参数实现的是“传地址值调用”,其本质仍然是在函数调用期间实际参数数组将它的全部存储区域提供给形式参数数组共享,即形参数组与实参数组是同一存储区域。直观地说,就是同一个数组在主调函数和被调函数中有两个不同(甚至相同)的名字。由于此时函数调用的实际参数是二维数组名,被调函数中的形式参数需要使用二维数组样式,数组存储区域全部共享时形参数组与实参数组的关系如图6.10所示。

【例6.16】 编写求二维矩阵最大元素的函数(假定矩阵为3行4列),用相应主函数进行测试。

例6.16程序的函数max中使用了二维数组样式的形式参数接收从主调函数中传递过来的二维数组首地址,使得形参数组v共享实参数组a的存储区域;然后通过对形参数组v的操作达到操作参数a的目的,即在形参数组v中寻找最大值实质上是在实参数组a中寻找最大值,程序执行的结果为:

Max value is:789。

2.用二维数组起始地址的一级地址形式作为实际参数(www.chuimin.cn)

例6.16程序的致命弱点是只能求列数是N列矩阵的最大元素。在实际应用程序设计中,有时需要能够处理任意行列大小的二维数组的函数(例如,要求上例中的函数max能够查找任意二维数组中的最大元素),此时直接用二维数组作为形式参数的设计形式就不太适合。为了提高函数的通用性,可以借助一维数组作为形式参数时可以不指定长度的特点,使用一维数组样式的形式参数接收二维数组实参。这种参数传递实质上就是要用线性数据的处理方法来处理平面形式的数据(读者可以在此基础上考虑更高维数组的处理),实现这种参数传递时须注意以下两点:

·数调用时的实际参数必须是二维数组起始地址的一级地址形式,同时还应将二维数组的构造信息(行数和列数)传递到被调函数中。

·被调函数中只知道被处理二维数组的起始地址,所以在处理过程中二维数组每一行的长度由程序员根据参数表中传递过来的信息自行控制。

【例6.17】 重新设计例6.16中的函数max,使其能够处理任意行列的二维数组,并用相应的主函数进行测试。

程序中函数max用一维数组样式的形式参数v来接收从主调函数中传递过来的二维数组首地址,注意到二维数组的名字表示的是二级地址,所以被传递的二维数组首地址要使用3种一级地址形式之一,本示例中使用的是a[0],还可以使用&a[0][0]和*a形式。在被调函数中将传递过来的二维数组当作一维数组处理,其元素对应关系应该是:a[i][j]→v[i*n+j]。程序执行的结果为:

Max value is:789。