编程系统程序员

您能详细讲解一下C语言中函数参数传递机制:值传递和指针传递吗?请举例说明每种方法的使用时机。

用 Hintsage AI 助手通过面试

答案。

在C语言中,函数的参数始终按值传递——也就是说,从调用代码中传递的是值的副本。如果需要在函数外修改变量的值,则使用指针传递。

按值传递

在传递标量(例如int)时,函数获得的是其副本:

void foo(int a) { a = 10; } int main() { int x = 5; foo(x); // x == 5, 不会改变! }

按指针传递

要修改变量的值,需要使用指针:

void foo(int* a) { *a = 10; } int main() { int x = 5; foo(&x); // x == 10, 值已改变! }

何时使用指针

  • 需要返回多个值。
  • 修改大型结构(节省时间和内存,不需要复制)。
  • 处理数组(数组总是作为指针传递)。

误导性问题。

数组是按引用传递的函数参数吗?

许多人回答“按引用”,但在C语言中,数组在函数签名中不能按引用传递,实际上它降级为指针。

正确答案:

当数组传递给函数时,实际上传递的是指向其第一个元素的指针。也就是说,被调用的函数并不知道数组的实际大小,对数组元素的任何更改都会反映在原始数组上。

void foo(int arr[]) { arr[0] = 100; } int main() { int a[3] = {1,2,3}; foo(a); // a[0] 将是100! }

历史


在一个项目中,函数更新名为int arr[10]的数组的值,但在调用代码中数组的大小较小。由于函数不知道实际的大小,因此发生了缓冲区溢出并损坏了内存。


在另一个情况下,由于按值传递结构给函数,整个大型内存块被复制了多次,导致应用程序性能下降。


开发者期望通过“引用”传递标量(通过指针)来保证原始值的不变性,但错误地在作用域外通过指针修改了内存(指针算术中的错误),导致了不可预测的结果。