C++的函数:形式参数可传入实参的值,也可能获得实参的地址

沃尔特·萨维奇的书 《Problem Solving with C++ 》第五章里提到,能返回值的函数需要实参作为“输入”,产生返回值作为“输出”。函数的名字就是对函数“功能与返回值”的提示(比如一个返回费用的函数可以就叫做fee()),而使用函数的人只要关心这些描述,而不应知道实现细节。

如果把一个函数原型比作通向该函数代码的大门,那么每次调用就是一次推门而入(当然最后还要出来退回原地,一般带着返回值)的动作;这么说,可以把函数原型里的参数(形参)比作看门的“铁将军”。门能不能顺利推开,取决于钥匙能不能打开铁锁;函数能不能顺利调用,取决于调用时传入的“实参”是不是符合参数列表里的“形参”。

原文是:形参在声明原型时列出,在定义的函数体里使用。形参既是函数体中可以访问的“局部变量”,又是被调用时才置入实际数值的“占位符号”。

这里一直强调的“调用”与“传参”,实际上有两种机制,一种是实参“传值”给形参,另一种是实参“传引用”给形参。如果我们能认识到,函数调用时产生的所有变量都会在函数返回时被抹消(它们只作用于局部),包括列在函数头的列表里的参数,我们就会把函数的作用局限于“提供返回值”。为了拓展应用场景(让函数在调用后可以留下更多变化),函数需要获得实参所存储的具体地址,而不是仅仅知道实参的值。这样,即使调用后的形参已经被销毁,但形参在函数体内经历的一切变化都作用在实参所存储的单元上。调用结束,仅仅是形参参数名的失效,形参和那个地址的内存单元失去了联系,而那个内存单元仍然可以靠原先的实参变量名进行访问。

如果函数在调用时,形式参数只获得了实际参数的值,这就是“传值调用”。此时形式参数在函数体内产生的一切变化都和调用时使用的实际参数无关。而如果形式参数获得了实际参数的存储地址,可以认为调用时的形式参数就是实参的一个别名,它们在内存中指向同一个实体,不因为调用的结束与形参的废弃而撤销函数运行时产生的变动;这时,这个作为别名的形参也被称为实参的“引用”。

实参把自己的地址复制给形参,称为 “传引用调用”

下面是一个使用传引用的方式编写函数而完成的项目实例,注意如果用传值的方式,是无法对实参进行修改的,也就无法实现“把键盘的输入写进传入的参数”和“交换两个传入的参数里包含的值”这些功能。


//  演示如何适当的使用 传参数的“引用”的函数

#include <iostream>

void getInput(int& input1, int& input2); 
// 键盘输入两个数字,分别写入 input1 和 input2

void swapValues(int& variable1, int& variable2);
// 交换 variable1 和 variable2 的值

void order(int& n1, int& n2);
// 返回的 n1 <= n2; 即将 n1、n2按 增序 排列

void giveResults(int output1, int output2);
// 输出 output1 和 output2 的值
// 充分条件:output1 <= output2

int main()
{
	int first_num, second_num;
	
	getInput(first_num, second_num);
	order(first_num, second_num);
	giveResults(first_num, second_num);
	return 0;
}

// getInput() 使用 iostream 来读入输入、写进参数里
void getInput(int& input1, int& input2)
{
	using namespace std;
	cout << "请输入 2 个整数:" ;
	cin >> input1 >> input2;
}

void swapValues(int& variable1, int& variable2)
{
	int temp;

	temp = variable1;
	variable1 = variable2;
	variable2 = temp;
}

void order(int& n1, int& n2)
{
	if (n1 > n2)
		swapValues(n1, n2);
}

// giveResults() 使用 iostream 来读出参数的值,并输出到屏幕
void giveResults(int output1, int output2)
{
	using namespace std;
	cout << "按增序排列,输入的数字是:" 
		 << output1 << " " << output2 << endl;
}

结果如图示:

image

大致如此。

posted @ 2025-07-28 10:34  吴萝卜  阅读(13)  评论(0)    收藏  举报