数组名作为函数参数传递,C语言数组作为函数参数传递详解

本节开始,先问大家一个问题:“要确定一个一维数组需要知道哪些信息?”一个是数组的首地址,另一个是数组的长度。这样就可以唯一地确定一个一维数组。因为数组是连续存放的,只要知道数组的首地址和数组的长度就能找到这个数组中所有的元素。

因此,要想通过实参和形参将一个数组从主调函数传到被调函数,那么只需要传递这两个信息即可。对于一维数组来说,其数组名就表示一维数组的首地址。所以只需要传递数组名和数组长度这两个参数就可以将数组从主调函数传入被调函数中。

当数组名作为函数的实参时,形参列表中也应定义相应的数组(或用指针变量),且定义数组的类型必须与实参数组的类型一致,如果不一致就会出错。但形参中定义的数组无须指定数组的长度,而是再定义一个参数用于传递数组的长度。所以在传递实参的时候,数组名和数组长度也只能用两个参数分开传递,而不能写在一起。因为即使写在一起,系统在编译时也只是检查数组名,并不会检查数组长度。所以数组长度要额外定义一个变量进行传递。

综上所述,当将数组从一个函数传到另一个函数中时,并不是将数组中所有的元素一个一个传过来(那样效率就太低了)。而是将能够唯一确定一个数组的信息传过来,即数组名(数组首地址)和数组长度。此时主调函数和被调函数操作的就是同一个数组。

下面来写一个程序:
# include <stdio.h>
int AddArray(int array[], int n);  //函数声明
int main(void)
{
    int a[] = {1, 2, 3, 4, 5, 6, 7, 8};
    int size = sizeof(a) / sizeof(a[0]);  /*数组所占内存总大小除以该数组中一个元素所占内存的大小, 从而得到数组元素的个数*/
    printf("sum = %d\n", AddArray(a, size));
    return 0;
}
int AddArray(int array[], int n)  //形参数组中不需要写长度
{
    int i, sum = 0;
    for (i=0; i<n; ++i)
    {
        sum += array[i];
    }
    return sum;
}
输出结果是:
sum = 36

再问大家一个问题:“前面讲过,当对数组名使用 sizeof 时可以求出整个数组在内存中所占的字节数。那么上面这个程序中,对被调函数 AddArray 中的数组 array 使用 sizeof 得到的值会是多少?”

有人会说,实参数组 a 占 32 字节,实参 a 传给形参 array,所以 array 也占 32 字节。但实际上,array 只占 4 字节。下面写一个程序看一下:
# include <stdio.h>
int AddArray(int array[]);  //函数声明
int main(void)
{
    int a[] = {1, 2, 3, 4, 5, 6, 7, 8};
    AddArray(a);
    return 0;
}
int AddArray(int array[])
{
    printf("sizeof(array) = %d\n", sizeof(array));
    return 0;
}
输出结果是:
sizeof(array) = 4

因为数组名做函数参数时,只是将实参数组的“首地址”传给了形参数组。此时被调函数 AddArray 中的数组 array 本质上是一个指针变量,里面存放的是主调函数中数组 a 的地址。指针变量也是一个变量类型。不同于前面所讲的其他变量类型,指针变量里面存放的不是一般的数据,而是地址。在 C 语言中,指针变量所占的字节数都是 4。所以对 array 使用 sizeof 求出的就是 4(但有些显示求出的可能是 8,这跟操作系统有关)。