是的,在C语言中,当数组名作为参数传入函数后,在函数内修改数组元素会直接修改原数组数据。这是因为C语言中数组名作为函数参数传递时,实际上传递的是数组首元素的地址(指针),而不是数组的副本。这种机制的本质是指针传递,具体如下:
1. 数组名的本质是指针
- 数组名在大多数情况下会退化为指向数组首元素的指针。例如:
int arr[5] = {1, 2, 3, 4, 5};
此时 arr 等价于 &arr[0](即首元素 1 的地址)。
- 当数组名作为参数传入函数时,函数接收的是该地址值(数组名也表示数组的首地址),而不是整个数组的拷贝
void modify(int arr[], int size) {
arr[0] = 100; // 修改首元素
}
此处 arr 实际是 int* 类型(指针),而非整个数组。
2. 函数内通过指针直接操作原始内存
函数内部通过接收到的指针(即数组首地址)访问数组元素时,实际是在直接读写原始数组的内存。例如:
void modify(int *ptr, int size) {
for (int i = 0; i < size; i++) {
*(ptr + i) *= 2; // 通过指针算术运算修改元素
}
}
此操作直接修改了原数组的内容,而非操作副本。
3. 与普通变量的值传递对比
- 普通变量(如
int):传递的是值的副本,函数内修改不影响原始变量:
void change(int x) { x = 10; } // 不影响外部变量
- 数组:传递的是地址,函数内通过地址修改的是同一块内存:
void changeArray(int arr[]) { arr[0] = 10; } // 直接影响原数组
这种差异源于 C 语言的设计选择:为避免复制大型数组的开销,采用指针传递。
4. 多维数组的传递机制
- 二维数组作为参数时,同样传递首地址:
void modifyMatrix(int matrix[][4], int rows) {
matrix[0][0] = 100; // 直接修改原始数据
}
需指定除第一维外的其他维度大小(如 [][4]),以便编译器计算地址偏移。
5,核心原因
函数通过接收到的指针直接读写原始数组的内存地址,而非操作副本。这种“按地址传递”(Pass by Address)机制是 C 语言高效处理数组的核心设计,但也要求开发者谨慎管理内存与边界。
#include <stdio.h>
void modify(int arr[])
{
arr[0] = 100; // 直接修改原数组的首元素
}
void modify_array(int * ptr, int size)
{
for (int i = 0; i < size; i++)
{
*(ptr + i) *= 2;
}
}
void print_array(int *ptr, int size)
{
for (int i = 0; i < size; i++)
{
printf("%d -> %d\n", i, *(ptr + i));
}
}
int main()
{
int a[3] = {1, 2, 3};
modify(a);
printf("%d\n", a[0]); // 输出 100(而非 1)
modify_array(a, 3);
print_array(a, 3);
return 0;
}
100
0 -> 200
1 -> 4
2 -> 6
1564

被折叠的 条评论
为什么被折叠?



