1、按值传递
在 C 中,当将一个变量传递给函数时,函数接收到的是该变量值的 副本。对参数的任何修改 不会 影响函数外部的原始变量。这就是所谓的 "按值传递"。
#include <stdio.h> void foo(int a) { a = 10; // 这只会修改 'a' 的局部副本 printf("Inside foo: a = %d\n", a); // 输出: 10 } int main() { int x = 5; printf("Before foo: x = %d\n", x); // 输出: 5 foo(x); // 函数调用后,x 的值依然是 5 printf("After foo: x = %d\n", x); // 输出: 5 return 0; }
2、C 中模拟按引用传递
C 不直接支持 按引用传递(像 C++ 中那样),但是可以通过 指针 来 模拟 按引用传递。通过传递变量的指针,函数可以修改指针所指向的变量的实际值。
#include <stdio.h> void foo(int *a) { *a = 10; // 解引用指针,修改实际变量的值 } int main() { int x = 5; printf("Before calling foo: %d\n", x); // 输出: 5,x 的初始值 foo(&x); // 传递 x 的地址到函数 printf("After calling foo: %d\n", x); // 输出: 10,因为 x 的值已被修改 return 0; }
3、模拟按引用传递的原因
通过引用传递(即通过指针)可以避免复制大型结构体或数组,减少内存开销。通过引用传递允许函数直接修改外部变量的值,这对于需要更新外部变量状态的场景非常有用。另外确保传递给函数的指针不是 NULL
。解引用空指针会导致未定义的行为,甚至崩溃程序。使用指针时需要特别注意内存分配和释放,尤其是动态内存(例如使用 malloc()
和 free()
时)。
#include <stdio.h> void swap(int *a, int *b) { int temp = *a; // 通过解引用获得a指向的值 *a = *b; // 修改a指向的值 *b = temp; // 修改b指向的值 } int main() { int x = 5, y = 10; printf("Before swap: x = %d, y = %d\n", x, y); // 输出: x = 5, y = 10 // 通过传递x和y的地址实现交换 swap(&x, &y); printf("After swap: x = %d, y = %d\n", x, y); // 输出: x = 10, y = 5 return 0; }
4、C++ 中的引用
C++ 支持 真正的按引用传递,通过引用变量(使用 &
符号)来简化传递过程。
#include<iostream> using namespace std; // 按引用传递参数 void foo(int &a) { a = 10; // 直接修改原始变量 'a' } int main() { int x = 5; foo(x); // 按引用传递 'x' printf("%d\n", x); // 输出: 10 return 0; }