C语言入门系列:从内存原理看函数的值传递和引用传递


函数参数用于向函数传递数据,C语言支持两种传递方式:值传递和引用传递。

一,值传递

传递参数的副本,函数内对参数的修改不影响原变量。

void swapByValue(int x, int y) {
    int temp = x;
    x = y;
    y = temp; // 交换操作仅影响局部副本
}

int main() {
    int a = 5, b = 10;
    swapByValue(a, b);
    printf("a = %d, b = %d\n", a, b); // 输出不变:a = 5, b = 10
}

上述代码,通过值传递调用函数swapByValue(int x, int y),表面上起到了交换a和b的值的作用,实则并未改变a和b的值。

这是因为调用函数时是将ab的值复制一份后,赋值给形参变量xy,之后对xy的操作不会影响ab的值。

二,引用传递

传递参数的地址,通过指针实现,函数内可通过地址修改原变量。

void swapByReference(int* x, int* y) {
    int temp = *x;
    *x = *y;
    *y = temp; // 实际交换变量的值
}

int main() {
    int a = 5, b = 10;
    swapByReference(&a, &b);
    printf("a = %d, b = %d\n", a, b); // 输出交换后:a = 10, b = 5
}

上述代码,通过值传递调用函数swapByValue(int* x, int* y),表面上起到了交换a和b的值的作用,实际上的确起到了这个作用。

这是因为调用函数时是将ab的地址传递给了指针变量xy,函数体内通过运算符*xy进行运算,本质上操作xy指向的内存中的数据,也即是变量ab的数据。

三,从内存原理看值传递和引用传递的区别

C代码在执行时,以函数为单位创建栈帧,栈帧中为变量分配内存空间,值传递和引用传递的根本区别在于变量的内存空间存储的数据不同。

1 值传递内存示意图

void swapByValue(int x, int y) {
    int temp = x;
    x = y;
    y = temp; // 交换操作仅影响局部副本
}

int main() {
    int a = 5, b = 10;
    swapByValue(a, b);
    printf("a = %d, b = %d\n", a, b); // 输出不变:a = 5, b = 10
}

对于上述值传递代码,如下图所示,main函数调用swapByValue函数,采用值传递,相当于把main栈帧变量ab的内存中的值copy到swapByValue栈帧中变量xy的内存区域,之后swapByValue函数中操作xy的内存中存储的值,并不会影响main栈帧中变量ab的内存中的值。

在这里插入图片描述

2 引用传递内存示意图

void swapByReference(int* x, int* y) {
    int temp = *x;
    *x = *y;
    *y = temp; // 实际交换变量的值
}

int main() {
    int a = 5, b = 10;
    swapByReference(&a, &b);
    printf("a = %d, b = %d\n", a, b); // 输出交换后:a = 10, b = 5
}

对于如上引用传递代码,如下图所示,传递给swapByValue栈帧中变量xy的值是main栈帧中变量ab的地址,swapByValue函数中通过星号运算符*结合xy中存储的地址值,找到main栈帧中变量ab,并对其进行读写,所以main栈帧中变量ab的值会交换。

在这里插入图片描述

参考文献

1,https://blog.csdn.net/qq_40507857/article/details/114966115?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522171918705616800222879077%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=171918705616800222879077&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2blogbaidu_landing_v2~default-3-114966115-null-null.nonecase&utm_term=%E5%80%BC%E4%BC%A0%E9%80%92%E5%92%8C%E5%BC%95%E7%94%A8%E4%BC%A0%E9%80%92c&spm=1018.2226.3001.4450

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小手追梦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值