C语言将数组作为函数参数

一个函数的形参是普通的局部变量。当发生函数调用时,程序创建这些形参,然后用对应的实参来初始化这些形参。形参的作用域就是函数块。函数内可以改变形参的值,而不会影响调用上下文中实参的值。

如果需要将一个数组当作实参传入函数,则应把对应的形参声明成下面的形式:

类型 名称[ ]


因为,当把数组名作为函数实参时,它会自动被转换为指针。所以上面的声明等同于下面的声明:

类型 *名称


当使用数组来声明函数参数时,方括号 [] 内的任何常量表达式都会被忽略。在函数块内,数组参数名是一个指针变量,并且数组的值可以在该函数内被修改。例 1 中的函数 addArray()将两个数组中对应索引元素的值相加。

【例1】函数 addArray()
// addArray() 将第二个数组中每个元素的值加到第一个数组对应元素上
//(例如,“array1 += array2”)
// 参数:两个float类型的数组,以及它们共同的长度
// 返回值:无
void addArray( register float a1[ ], register const float a2[ ], int len )
{
  register float *end = a1 + len;
  for ( ; a1 < end; ++a1, ++a2 )
    *a1 += *a2;
}

对于函数中的数组参数使用另一种表示法,上述函数 addArray()可等效为以下形式:
void addArray( register float *a1, register const float *a2, int len )
{  /* 函数块内容与前述一样 */ }

使用方括号 [] 声明函数数组参数的一个优点就是可读性好,它可以显著地标识出函数将该参数作为指向数组的指针,而不是一个独立的 float 变量。在参数声明时,数组风格的表示法还有两个特点:

(1) 在参数声明时(也只有在该情况下),C99 允许将类型限定符 const、volatile 和 restrict 放在方括号内。这个功能允许声明具有限定符指针类型的参数。

(2) 而且,在 C99 中,也可以将存储类修饰符 static 连带整数常量表达式一起放在方括号内。这种方法表示,在函数调用的时数组内元素数量至少等于该常量表达式。

下面一个示例展示了上述这些特点:
int func( long array[const static 5] )
{ /* ... */ }

在这里所定义的函数中,参数 array 是一个指向 long 类型的常量指针,所以不能被修改。它指向一个至少有 5 个元素的数组。

C99 同时允许将数组参数声明成可变长度的数组。方法是将一个非常量的、且为正数的整数表达式放在方括号之间。在这种情况下,数组参数仍然是指向第一个数组元素的指针。不同之处在于,数组元素本身也允许长度可变。

在例 2 中,函数 maximum()的第 3 个参数是一个二维数组,其长度可变。

【例2】函数 maximum()
// 函数 maximum() 获得double类型二维数组中的最大值
// 参数:行数、列数、二维数组
// 返回值:最大元素的值
double maximum( int nrows, int ncols, double matrix[nrows][ncols] )
{
  double max = matrix[0][0];
  for ( int r = 0; r < nrows; ++r )
    for ( int c = 0; c < ncols; ++c )
      if ( max < matrix[r][c] )
        max = matrix[r][c];
  return max;
}

参数 matrix 是一个指针,它指向一个具有 ncols 个元素的数组。