13.2.3 函数、方法和数组

要向函数或方法传递单个数组元素,使用常规方式将数组元素指定为参数。因此,如果有一个用来计算平方根的函数squareRoot,并且想要计算averages[i]的平方根并将结果赋给名为sq_root_result的变量,使用如下表达式即可:


sq_root_result=squareRoot(averages[i]);


向函数或方法传递整个数组是完全不同的情况。要传递数组,只需在函数调用或者方法调用中列出数组名称,并且不需要任何下标。举个例子,如果假设前面将grade_scores定义为包含100个元素的数组,那么下面的表达式:


minimum(grade_scores)


实际上将数组grade_scores中的100元素都传递给名为minimum的函数。很自然,从另一方面讲,函数minimum必须使用整个数组作为参数,也必须有适当的形参声明。

下面有一个函数,它寻找包含指定元素个数的数组中的最小整数值:


//Function to find the minimum in an array

int minimum(int values[],int numElements)

{

int minValue, i;

minValue=values[0];

for(i=1;i<numElements;++i)

if(values[i]<minValue)

minValue=values[i];

return(minValue);

}


函数minimum定义为带有两个参数:第一个是要查找最小数的数组,第二个是数组中的元素个数。在函数头中,values之后的一对方括号用来告知Objective-C编译器:values是整型数组。编译器并不关心这个数组有多大。

形参numElements用做for语句的上限。这样,for语句依次查找values[1]到数组最后一个元素,即values[numElements-1]。

如果函数或者方法更改了数组元素的值,那么这个变化将影响到传递到该函数或方法的原始数组,而且这个变化在函数或方法执行完之后依然有效。

值得讨论一下数组的行为和单个变量或数组元素(函数或方法不能更改它们的值)不同的原因。我们说过,调用函数或方法时,作为参数传递的值将被复制到相应的形参中。这个论述依然是有效的。但是,使用数组时,并非将整个数组的内容复制到形参数组中。而是传递一个指针,它表示数组所在的计算机内存地址。所以,对形参数组所作的所有更改实际上都是对原始数组而不是数组的副本执行的。因此,函数或方法返回时,这些变化仍然有效。

多维数组

多维数组元素可以像任何普通变量或一维数组元素那样传递给函数或方法。语句


result=squareRoot(matrix[i][j]);


调用squareRoot函数,同时传递matrix[i][j]中包含的值作为参数。

整个多维数组可以像一维数组那样当作参数传递:只要列出数组名称即可。比如,如果将矩阵measuredValues声明为整型二维数组,那么Objective-C语句


scalarMultiply(measuredValues, constant);


可以用来调用一个函数,它通过值constant求出该矩阵每个元素的乘积。当然这暗示该函数本身可以更改数组measuredValues中的值。关于一维数组的讨论在这里也适用:在函数中任何对形参数组元素的赋值操作都会永久地更改向该函数传递的数组。

将一个单维数组声明为形参时,规定不需指定数组的实际大小。简单地使用一对空方括号来告知编译器这个参数实际上是个数组就足够了。这并不完全适用于多维数组的情况。对于二维数组,数组的行数可以省略,但是声明必须包括数组的列数。如下声明


int arrayValues[100][50]



int arrayValues[][50]


对于100行50列的形参数组arrayValues都是合法声明;但是下面的声明


int arrayValues[100][]



int arrayValues[][]


就不是合法声明,因为必须指明数组的列数。