You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言函数参数传递行为解析:值传递临时修改原理

C语言函数参数传递机制差异解析

你观察到的两段代码运行结果差异,本质是C语言默认参数传递规则的直接体现,以下针对两个疑问逐一解释:

两段测试代码复现

值传递版本(第一段代码)

#include <stdio.h>
int mutate(int a){
    a+=1;
    printf("%d\n", a);
}
void main(){
    int b = 1;
    mutate(b);
    printf("%d", b);
}

运行输出:

2
1

指针传参版本(第二段代码)

#include <stdio.h>
int mutate(int *a){
    *a+=1;
    printf("%d\n", *a);
}
void main(){
    int b = 1;
    mutate(&b);
    printf("%d", b);
}

运行输出:

2
2

疑问解答

1. 为什么未使用指针的第一段代码中,函数内部会出现参数值的修改?

  • C语言的函数形参是被调函数的局部变量,程序在发起函数调用时,会在被调函数独立的栈帧内存中,为每个形参分配专属的存储位置。
  • 第一段代码调用mutate(b)时,程序会把main函数中实参b存储的数值1,直接拷贝到mutate函数为形参a分配的内存空间里。
  • 你在函数内部执行a+=1,本质是修改mutate函数栈帧内局部变量a的存储值,把拷贝过来的1改成2,后续函数内的printf读取的就是这个修改后的局部值,自然会输出2——这是完全合法的局部变量读写操作,没有任何语法限制。

2. 为什么这种修改是临时性的,函数执行结束后外部实参的值不会发生改变?

  • 核心原因是:值传递场景下,形参和外部实参是存储在完全独立内存地址的两个无关变量,传参过程只做一次性的数值拷贝,两者后续没有任何绑定关系。
  • 当mutate函数执行完毕,它对应的栈帧会被系统回收,形参a占用的内存也会被标记为可复用,你对a做的所有修改,从始至终都没有访问过main函数栈帧中存储实参b的内存块,因此b的值始终保持初始化的1,不会被函数内的操作影响。

你已经理解的指针传参版本,本质上依然是值传递:只不过这次拷贝给形参的不是普通数值,而是外部变量b的内存地址。形参(指针变量)本身还是mutate的局部变量,但通过*a解引用操作,程序可以直接定位到main栈帧中b的存储位置做修改,因此改动会同步反映到外部变量上。

可以把普通值传递理解为你给朋友发了一份本地文档的副本:朋友在副本上做的任何编辑,都不会影响你电脑里存储的原文件。指针传参相当于你把原文件的在线编辑权限链接发给了朋友,朋友打开链接修改的就是你持有的原文件,改动会直接保留。


内容的提问来源于stack exchange,提问作者PuuRaidur

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 06:15:35