函数参数可以接收 int、指针,同样也能接收数组。接下来我们看数组传入函数的写法,对比它和传递单个元素的区别,再讲解二维数组的传参方式,同时理清一个核心难点:数组传入函数后为何会退化为指针。
传单个数组元素
把数组的某个元素传给函数,跟传普通变量一样,传的是那个元素的值:
#include <stdio.h>
void display(int age1, int age2) {
printf("%d\n", age1);
printf("%d\n", age2);
}
int main() {
int ageArray[] = {2, 8, 4, 12};
// 把第二个和第三个元素传给 display()
display(ageArray[1], ageArray[2]);
return 0;
}输出:
8
4传整个数组
把整个数组传给函数,只需要把数组名当参数传进去,函数定义里用 float age[] 这种带方括号的写法接收:
// 程序通过函数计算数组元素总和
#include <stdio.h>
float calculateSum(float age[]);
int main() {
float result, age[] = {23.4, 55, 22.6, 3, 40.5, 18};
// age 数组传给 calculateSum()
result = calculateSum(age);
printf("结果 = %.2f", result);
return 0;
}
float calculateSum(float age[]) {
float sum = 0.0;
for (int i = 0; i < 6; ++i) {
sum += age[i];
}
return sum;
}输出:
结果 = 162.50调用时只写数组名 calculateSum(age);定义处 float age[] 告诉编译器你传进来的是一个一维数组。
传二维数组
二维数组同样只传数组名,函数定义里第二维的大小必须写出来:
#include <stdio.h>
void displayNumbers(int num[2][2]);
int main() {
int num[2][2];
printf("输入4个数字:\n");
for (int i = 0; i < 2; ++i)
for (int j = 0; j < 2; ++j)
scanf("%d", &num[i][j]);
// 把二维数组传给函数
displayNumbers(num);
return 0;
}
void displayNumbers(int num[2][2]) {
printf("Displaying:\n");
for (int i = 0; i < 2; ++i) {
for (int j = 0; j < 2; ++j) {
printf("%d\n", num[i][j]);
}
}
}输出:
输入4个数字:
2
3
4
5
Displaying:
2
3
4
5二维数组传参时第二维大小不能省,因为编译器要根据它计算每一行的偏移。
重点:数组在函数里退化成指针
把数组传给函数,传的其实是数组首元素的地址,也就是一个指针。所以:
- 函数里修改数组元素,会直接改到调用方的数组(传的是地址,不是拷贝)。
float age[]只是float *age的一种写法,两者等价。- 因为数组名退化成指针,函数内部用
sizeof(age)得到的是指针大小,不是数组长度,这也是为什么传数组时通常还要再传一个长度参数。
// 更规范的写法:同时传数组和长度
int sum(int arr[], int n) {
int s = 0;
for (int i = 0; i < n; ++i) s += arr[i];
return s;
}
int main() {
int a[] = {1, 2, 3, 4, 5};
printf("%d\n", sum(a, 5));
return 0;
}注意:C 语言里能把数组传给函数,但不能从函数返回整个数组(返回的是首元素指针,且指向的局部数据可能已失效)。
数组传给函数传的是首地址,函数内改数组等于改原数组;记得同时把长度传过去,别在函数里用 sizeof 数长度。