在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]的数组的值,但在调用代码中数组的大小较小。由于函数不知道实际的大小,因此发生了缓冲区溢出并损坏了内存。