news 2026/1/24 17:14:52

函数—C++的编程模块(函数参数和按值传递)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
函数—C++的编程模块(函数参数和按值传递)

函数参数和按值传递

下面详细介绍一下函数参数。C++通常按值传递参数,这意味着将数值参数传递给函数,而后者将其
赋给一个新的变量。例如,程序清单7.2 包含下面的函数调用:

double volume=cube(side);

其中,side 是一个变量,在前面的程序运行中,其值为5。cube( )的函数头如下:

double cube(double x)

被调用时,该函数将创建一个新的名为x 的double 变量,并将其初始化为5。这样,cube( )执行的操
作将不会影响main( )中的数据,因为cube( )使用的是side 的副本,而不是原来的数据。稍后将介绍一个实
现这种保护的例子。用于接收传递值的变量被称为形参。传递给函数的值被称为实参。出于简化的目的,
C++标准使用参数(argument)来表示实参,使用参量(parameter)来表示形参,因此参数传递将参量赋
给参数(参见图7.2)。

被调用时,该函数将创建一个新的名为x 的double 变量,并将其初始化为5。这样,cube( )执行的操
作将不会影响main( )中的数据,因为cube( )使用的是side 的副本,而不是原来的数据。稍后将介绍一个实
现这种保护的例子。用于接收传递值的变量被称为形参。传递给函数的值被称为实参。出于简化的目的,
C++标准使用参数(argument)来表示实参,使用参量(parameter)来表示形参,因此参数传递将参量赋
给参数(参见图7.2)。

在函数中声明的变量(包括参数)是该函数私有的。在函数被调用时,计算机将为这些变量分配内存;
在函数结束时,计算机将释放这些变量使用的内存(有些C++文献将分配和释放内存称为创建和毁坏变量,
这样似乎更激动人心)。这样的变量被称为局部变量,因为它们被限制在函数中。前面提到过,这样做有助于确保数据的完整性。这还意味着,如果在main( )中声明了一个名为x 的变量,同时在另一个函数中也声
明了一个名为x 的变量,则它们将是两个完全不同的、毫无关系的变量,这与加利福尼亚州的Albany 与纽
约的Albany 是两个完全不同的地方是一样的道理(参见图7.3)。这样的变量也被称为自动变量,因为它们
是在程序执行过程中自动被分配和释放的。

多个参数

n_chars('R',25);

上述函数调用将两个参数传递给函数n_chars( ),我们将稍后定义该函数。
同样,在定义函数时,也在函数头中使用由逗号分隔的参数声明列表:

void n_chhhars(char c,int n) //two arguments

该函数头指出,函数n_char( )接受一个char 参数和一个int 参数。传递给函数的值被赋给参数c 和n。
如果函数的两个参数的类型相同,则必须分别指定每个参数的类型,而不能像声明常规变量那样,将声明
组合在一起:

void fifi(float a ,float b) //declare each variable separately void fufu(float a,b) //NOT acceptable

和其他函数一样,只需添加分号就可以得到该函数的原型:

void n__chars(char c,int n); //prototype,style 1

和一个参数的情况一样,原型中的变量名不必与定义中的变量名相同,而且可以省略:

void n_chars(char,int); //prototype style2

然而,提供变量名将使原型更容易理解,尤其是两个参数的类型相同时。这样,变量名可以提醒参量
和参数间的对应关系:

double melon_density(double weight,double volume);

程序清单7.3 演示了一个接受两个参数的函数,它还表明,在函数中修改形参的值不会影响调用程序
中的数据。

#include <iostream> using namespace std; void n_chars(char, int); int main() { int times; char ch; cout << "Enter a character:"; cin >> ch; while (ch != 'q') { cout<< "Enter an integer:"; cin>>times; n_chars(ch, times); cout<<"\nEnter another character or press the" <<"q-key to quit:"; cin>>ch; } cout<<"The value of times is "<<times<<"."<<endl; cout<<"Bye"<<endl; return 0; } void n_chars(char c, int n) { while (n-- > 0) cout << c; }

运行结果

Enter a character:W Enter an integer: 50 WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW Enter another character or press theq-key to quit:20 Enter an integer: Enter another character or press theq-key to quit:q The value of times is 0. Bye

程序清单7.3中的main()函数使用一个whlle循环提供重复输入(并让读者温习使用循环的技巧),它
使用cm>>ch,而不是cinget(ch)或ch=cm.get()来读取一个字符。这样做是有原因的。前面讲过,这两
个cin.get()函数读取所有的输入字符,包括空格和换行符,而>>跳过空格和换行符。当用户对程序提示
作出响应时,必须在每行的最后按Enter键,以生成换行符。cin>>ch方法可以轻松地跳过这些换行符,但
当输入的下一个字符为数字时,cin.get()将读取后面的换行符。可以通过编程来避开这种麻烦,但比较简
便的方法是像该程序那样使用cin。

n_char( )函数接受两个参数:一个是字符c,另一个是整数n。然后,它使用循环来显示该字符,显示
次数为n:

while(n-->0) //continue until n reachs 0 cout<<c;

程序通过将n 变量递减来计数,其中n 是参数列表的形参,main( )中times 变量的值被赋给该变量。
然后,while 循环将n 递减到0,但前面的运行情况表明,修改n 的值对times 没有影响。即使您在函数main( )
中使用名称n 而不是times,在函数n_chars()中修改n 的值时,也不会影响函数main( )中n 的值。

另外一个接受两个参数的函数

下面创建另一个功能更强大的函数,它执行重要的计算任务。另外,该函数将演示局部变量的用法,
而不是形参的用法。

首先,需要一个公式。假设必须从51 个数中选取6 个,而获奖的概率为1/R,则R 的计算公式如下:

选择6 个数时,分母为前6 个整数的乘积或6 的阶乘。分子也是6 个连续整数的乘积,从51 开始,依
次减1。推而广之,如果从numbers 个数中选取picks 个数,则分母是picks 的阶乘,分子为numbers 开始
向前的picks 个整数的乘积。可以用for 循环进行计算:

long double result=1.0; for(n==numbers,p=picks;p>0;n--,p--) result=result*n/p;

循环不是首先将所有的分子项相乘,而是首先将1.0 与第一个分子项相乘,然后除以第一个分母项。
然后下一轮循环乘以第二个分子项,并除以第二个分母项。这样得到的乘积将比先进行乘法运算得到的小。
例如,对于(10 * 9)/(2 * 1)和45。这两大时,这种交替进行乘除运算的策略可以防止中间结果超出最大的浮点数。

程序清单7.4 在probability( )函数中使用了这个公式。由于选择的数目和总数目都为正,因此该程
序将这些变量声明为unsigned .int 类型(简称unsigned)。将若干整数相乘可以得到相当大的结果,因
此lotto.cpp 将该函数的返回值声明为long double 类型。另外,如果使用整型,则像49/6 这样的运算
将出现舍入误差。

#include <iostream> long double probability(unsigned numbers, unsigned picsks); int main() { using namespace std; double total, choices; cout<<"Enter the total number of choices on the game card and\n" <<"the number of picks you want: \n"; while ((cin >> total >> choices) && choices <= total) { cout<<"You have one chance in"; cout << probability(total, choices); cout << "of winning.\n"; cout<<"Next two numbers(q to quit):"; } cout << "bye\n"; return 0; } long double probability(unsigned numbers, unsigned picks) { long double result = 1.0; long double n; unsigned p; for (n = numbers, p = picks; p > 0; n--, p--) result = result * n / p; return result; }

运行结果

Enter the total number of choices on the game card and the number of picks you want: 49 6 You have one chance in1.39838e+07of winning. Next two numbers(q to quit):51 6 You have one chance in1.80095e+07of winning. Next two numbers(q to quit):q bye

请注意,增加游戏卡中可供选择的数字数目,获奖的可能性将急剧降低。
程序说明
程序清单7.4 中的probability( )函数演示了可以在函数中使用的两种局部变量。首先是形参(number
和picks),这是在左括号前面的函数头中声明的;其次是其他局部变量(result、n 和p),它们是在将函数
定义括起的括号内声明的。形参与其他局部变量的主要区别是,形参从调用probability( )的函数那里获得
自己的值,而其他变量是从函数中获得自己的值。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/1/5 5:29:11

C++函数参数详解:值传递、多参数与局部变量

C函数参数详解&#xff1a;值传递、多参数与局部变量 值传递的基本概念 C默认使用按值传递&#xff08;pass by value&#xff09;的方式传递函数参数。这意味着当调用函数时&#xff0c;传递给函数的是实际参数的副本&#xff0c;而不是参数本身。 double volume cube(side);…

作者头像 李华
网站建设 2026/1/22 16:13:24

Chrome for Testing:构建稳定自动化测试环境的完整指南

在现代Web开发流程中&#xff0c;自动化测试已成为确保产品质量的关键环节。然而传统浏览器在测试环境中面临诸多挑战&#xff1a;版本频繁更新导致测试环境不稳定、用户信息同步干扰测试结果、复杂界面增加自动化脚本复杂度。Chrome for Testing项目正是针对这些痛点而生的专业…

作者头像 李华
网站建设 2025/12/24 8:57:10

从脚本执行到智能涌现:开启软件测试新篇章‌

对于广大的软件测试从业者而言&#xff0c;“测试自动化”早已不是一个陌生词汇。从早期的录制回放&#xff0c;到基于代码的框架&#xff08;如Selenium、Appium、Pytest&#xff09;普及&#xff0c;再到如今基于CI/CD的流水线集成&#xff0c;自动化测试已然成为提升测试效率…

作者头像 李华
网站建设 2026/1/18 10:42:01

创意二维码艺术化制作全攻略:让黑白方块变身视觉盛宴

还在为千篇一律的黑白二维码发愁吗&#xff1f;&#x1f914; 想让你的产品包装、活动海报瞬间脱颖而出&#xff1f;今天就来分享一个超实用的技巧——用Controlnet QR Code Monster v2把普通二维码变成既好看又能扫的艺术品&#xff01; 【免费下载链接】control_v1p_sd15_qrc…

作者头像 李华
网站建设 2026/1/24 3:08:22

Unity WebGL输入法终极指南:彻底解决多平台输入兼容性问题

Unity WebGL输入法终极指南&#xff1a;彻底解决多平台输入兼容性问题 【免费下载链接】WebGLInput IME for Unity WebGL 项目地址: https://gitcode.com/gh_mirrors/we/WebGLInput 你是否曾经在Unity WebGL项目中遇到这样的困扰&#xff1a;精心设计的登录界面在浏览器…

作者头像 李华
网站建设 2025/12/24 8:56:25

GPT-SoVITS语音合成A/B测试框架搭建

GPT-SoVITS语音合成A/B测试框架搭建 在虚拟主播、有声读物和智能客服等应用日益普及的今天&#xff0c;用户对语音合成质量的要求已从“能听”转向“像人”。尤其是个性化音色克隆——让机器说出你熟悉的声音——正成为下一代交互体验的关键。然而&#xff0c;一个现实问题是&a…

作者头像 李华