C语言中的函数-数组作为函数参数-学习笔记-18

数组作为函数参数

在使用有参函数是,我们需要向函数提供参数,参数分为实参和形参。其中实参可以是常量、变量或者表达式,而数组元素和变量用法相同,使用变量时可以使用数组元素代替。所以,数组元素也可以代替函数中的参数,向形参传递数据。

数组元素作为函数的实参

因为数组元素可以代替变量使用,所以在函数参数中的变量,也可以使用元数组素代替使用。但是,数组元素不能作为形参使用,因为形参是函数被调用时的临时分配的存储单元。可以这么理解,函数中的形参,就是一个接收地址,不能是具体的值,随时待命接收实参单向传递来的信息。

例子

我们从一个例子里来看看,数组元素如何作为实参来使用的。
问题:向一个数组中输入10个数,要求设计并使用一个 max 函数,输出其中的最大值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>
int main(){
int max(int a, int b);
int num[10];
int big;
printf("请输入10个数,程序将返回其中的最大值:\n");
for (int i=0;i<10;i++){
scanf("%d",&num[i]);
}
big=max(num[0],num[1]);
for (int i = 2;i<10;i++){
big=max(big,num[i]); //这里我们使用 num 数组元素作为 max 函数的实参
}
printf("输入的10个数的最大值是:%d\n",big);
}

int max(int a, int b){
int z;
z=a>b ? a:b;
return (z);
}

上面,我们使用了 num[i] 这样一个数组元素作为函数的实参,然后将其传给 max 函数的形参,并且通过循环将最大值和下一个数组元素进行比较,得到最终的结果。

数组名作为函数参数

上面我们讲了,如何使用数组元素作为函数的实参,并且讲了为什么不能用数组元素作为函数的形参。其实出了数组元素外,我们还可以使用数组名作为函数的参数,可以是形参或者实参

原理

使用数组元素作为实参时,我们知道参数传递过程是实参向形参进行的单向传递,传递的是数组元素,是一个具体的值
而使用数组名作为函数参数时,实参传给形参的不是具体的值,而是数组首元素的地址

例子

同样我们来举例说明这个变化,在一个一维数组中,存储着10个考生的成绩,我们来计算这些成绩的平均值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <stdio.h>
int main(){
float score[10];
// 声明了一个用于存放学生成绩的数组
float average( float array[10] );
// 初始化求平均数的函数
printf("请输入10个学生的成绩:\n");
for (int i=0;i<10;i++){
scanf("%f",&score[i]);
}
//获取10个成绩
printf("10个学生的平均成绩是:%2.1f\n",average(score));
//引用平均数函数,并输出
}

float average( float array[10] ){
float scoreAverage, sum=array[0];
for(int i=1;i<10;i++){
sum=sum+array[i];
}
//将接收到的数组的各个元素累加
scoreAverage=sum/10;
//求平均数
return (scoreAverage);
//返回平均数到主调函数中
}

解释

上面的参数传递过程,我们可以理解为,实参还是单向传递数据给形参,但是此时传递的不是具体的数,而是整个数组,而传递的内容是数组的首元素地址,所以我们可以在函数中使用接收到的这个数组的所有元素。
也可以这么理解,以前传递的数组元素具体的数值,现在传递的数组名一堆数据,以前是一个数据,现在是一个数组内的全部数据。以前的一个数据只能在实参里面,现在数组名可以当做实参或者形参使用。

注意

因为我们这里传递给形参的是实参的数组首地址,所以形参在改变数组元素是,世界上也是改了实参的数据,因为他们的地址是相同的,所以这里形参也变相的改变了实参的数据。

多维数组名作为函数参数

和之前的一维数组名作为函数的参数类似,我们也可以将多维数组名作为函数的参数,这里包括实参和形参

原理

使用原理和之前的一维数组名类似,但是需要注意的是,在使用多维数组名作为函数参数时,需要将可以省略第一维数组大小,但是不能省略第二纬度。例如:

1
2
3
4
5
6
int test[5][2];
//这样是合法的,一共有5行,每行2列
int test[][2];
//这样也是合法的,虽然不知道多少行,但是我在初始化数组的时候就知道了,所以没关系,但是如果不声明列数,则会报错。
int test[][];
//这样就不合法了

例题

我们同样使用一个例题来说明用法。在一个3X4的多维数组中,找到其中的最大值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
int main(){
int max( int bignum[][4] );
int num[3][4]={{44563,2,3,4},{4,5,54,3},{33,332,1,23333}};
printf("最大值是:%d\n",max(num));
}
int max(int bignum[][4]){
int big=0;
for(int i=0;i<3;i++){
for(int k=0;k<4;k++){
if (bignum[i][k]>big){
big=bignum[i][k];
}
}
}
return (big);
}

注意
刚才我犯了一个错误,因为没有使用scanf 函数获取值,而是直接给二维数组赋值的时候,记得必须在定义数组的时候赋值,之后你在使用num[3][4]赋值是不合法的,因为这就是该数组的一个具体的元素了。

解释

声明自定义函数时参数栏写的是一个二维数组,我们可以将第一纬的大小省略,所以我们可以输入很大的一个二维数组。但是第二维不能省略。
调用自定义函数时,我们直接将数组名填入即可,因为数组名就包含了该数组的首地址。
定义函数时,我们同样需要写一个忽略第一维大小的形参,然后我们在接收到实参传递过来的地址后,就可以遍历这个二维数组,然后获取最大值即可。

尾巴

这是我的个人学习笔记,主要是应付考研复习使用,充斥着一些吐槽和个人观点,并不严谨,欢迎大家参考、指正。


-------------The End-------------
欢迎请我喝咖啡哦~!