C 语言中,函数参数默认是按值传递(pass-by-value),即函数接收到的是实参的副本。如果需要按引用传递(pass-by-reference),可以通过指针来实现。通过指针,可以实现在 C 语言中“按引用传递”参数,使得函数能够修改实参的值。

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;
}

推荐文档