软考软件设计师函数参数传递怎么考?传值调用与传引用调用的本质区别,从栈帧到C语言指针陷阱一篇讲透

分类: 软考中级、 软件设计师 发表时间:2026年08月27日 00:52 修改时间:2026年08月31日 08:00 阅读量:3

软考软件设计师函数参数传递怎么考?传值调用与传引用调用的本质区别,从栈帧到C语言指针陷阱一篇讲透

一、概念定义:形参、实参与两种参数传递机制的精确边界

函数参数传递是程序设计语言基础里的高频考点,也是软件设计师上午题里几乎年年都会触碰的题目。它表面考的是"调用函数时参数怎么传",本质考的是考生对内存模型、变量绑定与函数调用约定三者的理解是否扎实。许多考生背过结论却仍然做错,根源在于没有把"传值"与"传引用"这两个词还原到语言实现的底层机制上去。

形参与实参:两个不能混用的术语

首先要厘清一对基础概念。形参是函数定义时括号内声明的参数,它只是一个占位符,在函数被调用之前并不占用任何实际内存,或者说它并不对应任何真实存在的变量。实参是函数调用时括号内传入的具体值或变量,它必须有确定的取值,是形参在本次调用中将要"接管"的数据来源。

区分这两者的意义在于:所有关于"参数传递"的讨论,本质上都是在回答一个问题——形参和实参之间究竟建立了一种什么样的联系。是复制一份值,还是绑定同一个存储单元,还是共享同一段名字到值的映射,这个问题的答案就决定了参数传递方式的类别。

值传递与引用传递的判定标准

传值调用,也写作按值调用,其语义是:把实参的值复制一份,赋给形参。函数体内对形参的一切读写操作,都只作用于这份副本,与实参本身完全隔离。因此,无论函数内部把形参改写成什么样子,调用结束后实参的值保持不变。

传引用调用,也写作按引用调用,其语义是:形参并不拥有独立的存储空间,而是直接成为实参的别名,二者共享同一个存储单元。函数体内通过形参对变量的任何修改,都会同步反映到实参身上。

判定一个语言到底采用哪一种传递方式,有一个非常实用的标准:看"函数内对形参重新赋值,是否会影响调用方的实参"。如果会影响,是引用传递;如果不会,就是值传递。这条标准在后面的真题分析和误区剖析中会反复用到。

教材与标准文档中的术语定位

在软件设计师考试所依据的教材体系中,参数传递通常被置于"程序设计语言基础"这一章的"函数与过程调用"一节之下。教材对传值调用的标准表述强调"实参与形参各占独立的存储空间",对传引用调用的标准表述强调"形参是实参的别名"。考生在作答时应当尽量贴近教材术语,避免用口语化的"传过去""带回来"这类含糊说法,否则在判断"传地址调用"与"传引用调用"的细微差别时容易出错。教材还会提到传名调用与传地址调用这两个补充概念,它们共同构成参数传递方式的完整分类框架。

传引用调用,也写作按引用调用,其语义是:形参并不拥有独立的存储空间,而是直接成为实参的别名,二者共享同一个存储单元。函数体内通过形参对变量的任何修改,都会同步反映到实参身上。

判定一个语言到底采用哪一种传递方式,有一个非常实用的标准:看"函数内对形参重新赋值,是否会影响调用方的实参"。如果会影响,是引用传递;如果不会,就是值传递。这条标准在后面的真题分析和误区剖析中会反复用到。

二、原理机制:栈帧、复制语义与指针的"伪引用"

函数调用栈帧:参数传递发生的物理现场

要理解参数传递,必须先理解函数调用时内存里发生了什么。当程序执行到一次函数调用,系统会在调用栈上为被调函数分配一块新的存储区域,这块区域就叫栈帧。一个典型的栈帧里依次存放着:实参、返回地址、调用方的栈基址指针、局部变量,以及可能被使用的寄存器保存区。栈基址指针的作用尤其关键,它标记了当前栈帧的起始位置,函数内的所有局部变量和参数都是相对这个指针的偏移量来寻址的。理解了这一点,就能明白为什么说"参数本质上是一种特殊的局部变量"——它和函数体内声明的普通局部变量一样,都在当前栈帧内占据一个偏移位置,区别只在于它的初值来自调用方。

参数传递的第一步,就是把实参按照约定的顺序压入栈帧中参数区的位置。这里有一个容易被忽略的细节:不同语言、不同调用约定,参数入栈的顺序并不相同。C语言默认的调用约定是从右向左依次压入实参,这样最左边的参数恰好落在栈顶附近;而部分语言或约定采用从左向右的顺序。入栈顺序本身不是考点,但它说明了"参数传递"从来不是一个抽象概念,而是一套具体的、与硬件和编译器实现绑定的机制。

值传递的底层:复制是唯一动作

在传值调用中,压栈动作的真实含义是"复制"。对于基本类型,复制的是数值本身;对于指针或引用类型,复制的则是指针变量里保存的那个地址值。无论复制的是什么,关键特征只有一个:形参拿到的是实参的一份拷贝,形参与实参在内存里是两个互不相干的存储单元。

正因为如此,函数体内形参被重新赋值时,改变的是形参自己那一份存储单元的内容,实参所在的存储单元纹丝不动。这就是为什么传值调用天然具有"安全"的特性——被调函数无法通过参数这个通道去篡改调用方的变量。

C语言指针的真相:传的是地址值,不是引用

这是最容易引发混淆的地方。C语言里函数要修改外部变量,通常的做法是传指针。很多考生据此认为"C语言传指针就是传引用",这个说法是错的。C语言只有一种参数传递方式,就是值传递;所谓"传指针",本质上是把指针变量里存放的那个地址值复制一份传给形参。

为了把这一点讲透,不妨构造一个经典场景:一个交换函数想要交换两个整数。如果直接把两个整数作为参数传入并试图交换,函数返回后调用方的两个变量根本不会改变,因为函数交换的只是两份副本;正确做法是把两个整数的指针传进去,函数通过解引用操作去修改指针指向的存储单元,才能把交换效果传回。但如果进一步让函数去交换两个指针本身,也就是试图让形参指针互相交换指向,那么返回后调用方的指针依旧纹丝不动——因为形参指针只是地址值的拷贝。这三个层次一层比一层隐蔽,正是命题人层层加码的地方。

二者的差别在如下场景中立刻显现:如果函数内部对指针形参本身重新赋值,让它指向另一个对象,那么调用方的那个指针变量并不会跟着改变,因为它只是一个值的拷贝。函数能修改外部变量,靠的不是"引用传递",而是通过复制过来的地址值去间接访问那个地址所指向的对象。这个对象并不在参数传递的通道里,参数传递的通道里只有那个地址值。

Java与Python的"引用"其实都是值传递

Java官方文档和多数权威著作都把Java的参数传递明确界定为值传递。对基本类型,复制的是数值;对引用类型,复制的是引用变量里保存的对象引用,也就是对象在堆上的地址标识。函数内通过这个引用的副本去修改对象的内容,外部能看到变化,因为副本指向的还是同一个对象;但函数内若把引用形参重新指向一个新对象,外部的引用变量不受影响。这正是值传递的典型特征。

这里可以借助一个通俗但准确的模型来记忆:把"引用变量"想象成一张写有对象地址的纸条,把"对象"想象成堆上的一栋房子。传参时复制的是纸条,而不是房子。函数拿到纸条的副本后,依然能循着上面的地址找到同一栋房子,所以往房子里搬家具,调用方看得见;但如果函数把这张副本纸条上的地址擦掉、改写成另一栋房子的地址,那么调用方手里那张原纸条上的地址并没有被改动,调用方仍然指向原来的房子。这个"复制纸条、不复制房子"的模型,能够一次性解释清楚Java、Python乃至C#中引用类型参数传递的全部表象。

Python的情况与此高度相似。Python里一切皆对象,变量名本质上是指向对象的引用。函数传参时复制的是这个引用本身。对于不可变对象,任何"修改"其实都是重新绑定到一个新对象,外部不受影响;对于可变对象,通过引用副本调用其修改方法,会作用在同一个底层对象上,外部就能观察到变化。理解了"复制的是引用而非对象"这一点,Java和Python的种种表象就能统一到同一个框架下。

三、分类与应用:四种参数传递方式的完整图谱

传值调用与传地址调用

传值调用是绝大多数现代语言里最常见的形式,C语言、Java、Python、Go中按值传递的标量类型都属于这一类。它的优点是语义清晰、安全性高,调用方不用担心自己的变量被函数悄悄修改;缺点是当需要传递大对象时会产生复制开销,且无法通过参数直接把修改结果传回。

传地址调用常被视作C语言传指针这一做法的学名。它传的仍然是值,只是这个值是地址。它本质上依然是值传递的一种工程实践,只不过借由地址这个"钥匙",函数获得了间接访问和修改调用方对象的能力。在软考的语境里,传地址调用与传引用调用往往被并列讨论,考生需要明确它们并非同一件事。

传引用调用

传引用调用在C++中以引用符号显式声明,形参成为实参的别名,不产

本篇完!

本文为付费内容,请输入 VIP 码查解锁本站全部文章!
点击此处获得 VIP 码
你可能也喜欢这些文章
 

《论无服务器架构及其应用》考点详解?
02-05
软考CRC循环冗余校验码怎么学?从模二除法到生成多项式层层拆解,检错能力与突发长度一篇讲透
06-30
深度解析《论软件系统架构评估》知识点
10-25
软考论文《论无服务器架构及其应用》精选试读
11-24
《论信息系统项目的干系人管理》论文写作思路
08-15
B2B和B2C到底有什么区别?电商设计师必考的6种商务模式底层逻辑一次讲透
07-29
《信息系统运维管理》满分技巧
01-20
软考网工虚电路交换与数据报交换到底怎么区分?分组交换两种方式的底层原理与真题陷阱一篇讲透
08-26
深度解析《论系统安全架构设计及其应用》知识点
11-25
《论分布式事务及其解决方案》精彩试读
09-23
软考系统架构师架构风格选择题总丢分?五大分类底层原理与历年真题陷阱一篇搞懂
06-28
25年11月软考架构真题《论秒杀场景及其技术解决方案》考后复盘总结
11-15
《论基于构件的软件开发方法及其应用》适合写什么项目?
11-24
《论富互联网应用的客户端开发技术》写作心得
02-04
软考软件设计师必考:海明码纠错原理深度解析——从奇偶校验到ECC内存的完整知识体系
08-09
软考信息安全工程师蜜罐技术怎么学?主动防御诱骗系统底层原理与低交互高交互分类一篇讲透
08-29
扫码获取 VIP 码
添加管理员微信获取 VIP 码
微信二维码