在 C 语言中,数组与函数结合 是非常核心的用法,但由于数组传参的特殊性(退化为指针),需要掌握关键规则和常见场景。下面从「传参原理」「核心用法」「常见场景」三个维度详细讲解:
一、数组传参的核心原理
C 语言中数组不能直接按值传递,将数组名作为函数参数时,数组名会退化为「指向数组首元素的指针」。
- 函数无法通过
sizeof(arr)获取原数组的长度(只能得到指针的大小,如 4/8 字节); - 函数对数组元素的修改会直接作用于原数组(因为操作的是同一块内存)。
关键结论:
传递数组时,必须额外传递数组长度(除非数组以固定值结尾,如字符串的 \0)。
二、数组与函数结合的核心用法
1. 基础:函数打印数组(最常用)
目标:编写通用函数,打印任意长度的 int 数组。
c
运行
#include <stdio.h>
// 打印数组:参数1=数组指针,参数2=数组长度
void printArr(int arr[], int len) {
for (int i = 0; i < len; i++) {
printf("%d ", arr[i]);
}
printf("\n");
}
int main() {
int arr1[] = {1, 2, 3, 4, 5};
int arr2[] = {7, 8, 9};
// 计算数组长度:sizeof(数组)/sizeof(单个元素)
int len1 = sizeof(arr1) / sizeof(arr1[0]);
int len2 = sizeof(arr2) / sizeof(arr2[0]);
printArr(arr1, len1); // 输出:1 2 3 4 5
printArr(arr2, len2); // 输出:7 8 9
return 0;
}
2. 进阶 1:函数修改数组元素
目标:编写函数,将数组所有元素乘以 2。
c
运行
// 修改数组:将每个元素×2
void multiplyArr(int arr[], int len) {
for (int i = 0; i < len; i++) {
arr[i] *= 2; // 直接修改原数组(指针特性)
}
}
int main() {
int arr[] = {1, 2, 3};
int len = sizeof(arr) / sizeof(int);
multiplyArr(arr, len);
printArr(arr, len); // 输出:2 4 6(原数组已被修改)
return 0;
}
3. 进阶 2:函数返回数组(注意陷阱)
C 语言中函数不能直接返回数组,但可以通过以下 2 种方式实现 “返回数组” 的效果:
- 方式 1:传入一个空数组,函数填充数据(推荐);
- 方式 2:返回指向静态数组 / 动态数组的指针(注意内存泄漏)。
示例(方式 1:填充数组):
c
运行
// 填充数组:生成 1~n 的连续整数
void fillArr(int arr[], int n) {
for (int i = 0; i < n; i++) {
arr[i] = i + 1;
}
}
int main() {
int res[5]; // 空数组
fillArr(res, 5);
printArr(res, 5); // 输出:1 2 3 4 5
return 0;
}
三、常见坑点与避坑指南
-
坑点 1:硬编码数组长度错误写法(固定长度 5,适配性差):
c
运行
void printArr(int arr[]) { for (int i = 0; i < 5; i++) { // 硬编码,数组长度≠5时会越界 printf("%d ", arr[i]); } }避坑:必须显式传递数组长度。
-
坑点 2:在函数内计算数组长度错误写法(sizeof 计算的是指针大小):
c
运行
void printArr(int arr[]) { int len = sizeof(arr) / sizeof(int); // 错误!arr是指针,len=1(32位)/2(64位) for (int i = 0; i < len; i++) { printf("%d ", arr[i]); } }避坑:仅能在数组定义的作用域(如 main)中用
sizeof计算长度。 -
坑点 3:返回局部数组的指针错误写法(局部数组出函数后销毁,指针失效):
c
运行
int* createArr() { int arr[5] = {1,2,3,4,5}; // 局部数组,栈内存 return arr; // 错误!返回野指针 }避坑:改用动态数组(
malloc)或传入外部数组。
四、经典应用场景
- 数组排序:函数接收数组 + 长度,实现冒泡 / 选择排序;
- 数组查找:函数接收数组 + 长度 + 目标值,返回目标值下标;
- 数组求和 / 平均值:函数接收数组 + 长度,返回计算结果。
示例(数组求和):
c
运行
int sumArr(int arr[], int len) {
int sum = 0;
for (int i = 0; i < len; i++) {
sum += arr[i];
}
return sum;
}
int main() {
int arr[] = {1,2,3,4,5};
int len = sizeof(arr)/sizeof(int);
printf("数组和:%d\n", sumArr(arr, len)); // 输出:15
return 0;
}
总结
C 语言中函数操作数组的核心是:
- 数组传参退化为指针,必须传长度;
- 函数可直接修改原数组(指针特性);
- 避免返回局部数组指针,优先传入外部数组
#include<stdio.h>
void printArr(int arr[], int n){
for(int i=0;i<n;i++){
printf("%d\n", arr[i]);
}
}
int main(){
// int 类型的数组
int arr1[]={1,2,3,4,5,8,9};
// 计算数组的元素个数:用数组的整体大小/单个元素大小
int n_arr1= sizeof(arr1)/sizeof(int);
printf("%d\n",n_arr1);
printArr(arr1, n_arr1);
int arr2[]={7,8,9};
printArr(arr2,3);
}
#include<stdio.h>
//数组和
int getArrSum(int arr[], int len) {
int sum = 0;
for (int i = 0; i < len; i++) {
sum += arr[i];
}
return sum;
}
// 任务2:求数组最大值
int getArrMax(int arr[], int len) {
int max = arr[0];
for (int i = 1; i < len; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
return max;
}
// 任务3:查找数组元素,返回下标(找不到返回-1)
int findArrValue(int arr[],int len,int val){
for (int i = 0; i < len; i++) {
if (arr[i] == val) {
return i;
}
}
}
int main() {
int arr[3] = {1,2,3};
printf("%d\n", getArrSum(arr, 3));
printf("数组最大值:%d\n", getArrMax(arr, 3));
printf("元素2的下标:%d\n", findArrValue(arr, 3, 2));
}
运行结果如下: