函数调用时实参向形式参数传递相应类型的值,则称为是传值调用。这种方式下形式参数不能向实参传递信息。实参可以是变量,也可以是常量和表达式。引用调用的实质是将实参变量的地址传递给形参,因此,形参是指针类型,而实参必须具有左值。变量具有左值,常量没有左值。被调用函数对形参的访问和修改实际上就是针对相应实际参数所作的访问和改变,从而实现形参和实参间双向传递数据的效果。
朋友的操作:他可以在复印件上任意涂改、做笔记。
对你原件的影响:没有任何影响。你手里的原件还是原来那份,干干净净。
在编程中的体现:函数内部修改的是“复印件”(形参),而外部的原始数据(实参)完全不变。实参可以是任何数据(变量、数字5、一个算式的结果)。
引用调用(就像“共享电子文档链接”)
做法:你把文件存储在云盘(如Google Docs),然后只把文件的访问链接(地址) 发给朋友。
朋友的操作:他点击这个链接,打开的就是你电脑里的那个唯一原件。他做的任何修改都会直接保存到这份原件上。
对你原件的影响:直接影响。你再打开文件,看到的就是他修改后的版本。
在编程中的体现:函数内部通过“链接”(地址)直接操作外部的原始数据(实参)。为了实现这一点:
实参必须是一个“有位置的变量”(就像一个实际存在的云盘文件)。你不能把一个纯数字(比如5)或者一句话的链接发给别人,因为这些东西没有“存储位置”可供修改。
这也就是解析里说的,实参必须有 “左值” (可以简单理解为 “是一个可以存放东西的容器/位置”)。
为什么只有变量才有存储位置
问题简单来说就是内存寻址的概念。计算机中,程序运行时,数据需要存储在内存中特定的位置(地址)。变量在程序中定义时,编译器或解释器会为它分配一块内存空间,因此变量有存储位置(地址)。而常量和表达式的结果(除非被赋给变量)通常是临时性的,它们可能存放在寄存器或临时栈空间,但程序通常不提供直接访问其地址的机制(尤其是常量,往往在编译时就确定了值,可能直接嵌入指令中,没有运行时内存地址)。对于引用调用(传递地址),需要实参有一个固定的、可寻址的内存位置,以便形参(指针)能够指向它,从而通过指针修改其内容。常量没有可修改的内存位置(常量通常存储在只读内存区或直接编码在指令中),表达式的结果是临时值,也没有持久的内存地址(除非先赋给变量)。因此,只有变量(或更广义的左值)才能进行引用传递。
左值(lvalue)是一个历史术语,意指可以出现在赋值语句左边的表达式,即它标识了一个可存储对象的位置。变量是典型的左值。常量和算术表达式的结果是右值(rvalue),它们没有可标识的存储位置(或者说是临时值)。引用调用需要左值,因为需要取地址。
举例:假设有函数 void f(int &x) { x = 10; }
调用时:int a = 5; f(a); // 正确,a是变量,有地址
f(5); // 错误,5是常量,没有可修改的地址
f(a+1); // 错误,a+1是表达式结果,临时值,没有持久地址
因此,引用调用要求实参必须是左值(变量)。
评论 (0)