1. 数组作为函数参数传递的核心概念
数组作为函数参数传递是编程中的基础操作,但不同语言的处理方式差异很大。理解这些差异对于编写高效、安全的代码至关重要。在C语言中,数组名本质上是一个指向数组首元素的指针,这个特性决定了数组传递的基本行为。
当我们在C语言中声明一个数组时,比如int arr[5],arr这个标识符在大多数上下文中会被编译器解释为&arr[0]。这种设计带来了高效的内存访问,但也带来了一些需要特别注意的行为特征。
1.1 数组名与指针的关系
在C语言中,数组名和指针有着微妙的区别和联系。虽然数组名在很多情况下会退化为指针,但它们并不完全相同。关键区别在于:
- 数组名是一个常量指针,不能重新赋值
- sizeof操作符对数组名返回整个数组的大小,对指针返回指针本身的大小
- &操作符对数组名返回指向整个数组的指针,类型为数组指针
c复制int arr[5] = {1,2,3,4,5};
int *ptr = arr;
// 以下表达式都为真
arr == &arr[0]
*arr == arr[0]
arr + 1 == &arr[1]
// 但有以下区别
sizeof(arr) == 20 // 假设int为4字节
sizeof(ptr) == 4或8 // 取决于系统
1.2 数组作为函数参数的本质
当数组作为函数参数传递时,C语言实际上传递的是数组首元素的地址。这意味着函数内部接收到的是一个指针,而不是整个数组的副本。这种设计有两个重要影响:
- 函数可以修改原始数组的内容
- 函数内部无法直接获取数组的长度信息
c复制void modifyArray(int arr[], int size) {
// arr实际上是指针
// 可以修改原始数组内容
for(int i=0; i<size; i++) {
arr[i] *= 2;
}
}
这种传递方式非常高效,特别是对于大型数组,因为它避免了不必要的数据拷贝。但同时也要求程序员必须小心处理,避免意外的修改。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. C语言中数组传递的详细实现
2.1 基本语法形式
在C语言中,函数声明接受数组参数有几种等效的写法:
c复制// 以下三种声明方式完全等效
void func(int arr[10]);
void func(int arr[]);
void func(int *arr);
无论采用哪种形式,编译器都会将其处理为指针参数。第一种形式中的数组大小10会被忽略,这只是一种文档化的手段,告诉程序员期望的数组大小。
2.2 多维数组的传递
多维数组的传递更为复杂,但原理相同。对于二维数组,第一维的大小可以省略,但后续维度的大小必须指定:
c复制void process2DArray(int arr[][5], int rows) {
for(int i
