C++对C的扩充(三)

5 带缺省参数的函数

一般情况下,实参个数应与形参个数相同。C++允许实参个数与形参个数不同。办法是在形参表列中对一个或几个形参指定缺省值(或称默认值)。例如某一函数的首部可用如下形式:

void fun(int a, int b,int c=100)

在调用此函数时如写成fun(2,4,6),则形参a,b,c的值分别为2,4,6(这是与过去一样的)。如果写成fun(2,4),即少写了最后一个参数,由于在函数定义时已指定了c的缺省值为100,因此a,b,c的值分别为2,4,100。请注意:赋予缺省值的参数必须放在形参表列中的最右端。例如:

void f1(float a, int b, int c=0, char d='a') (正确)

void f2(float a, int c=0, char d='a', int b) (不正确)

利用这一特性,可以使函数的使用更加灵活。例如例14.4求两个数或3个数中的最大数。也可以不用重载函数,而将函数max的首行写成

int max(int a, int b,int c=-32768)

如果只想从两个数中找大者,则可以在调用时写成max(100,675),c的值自动取 -32768,由于一32768是最小整数,因此从100,675,-32768中选大者和从100,675中选大者的结果是一样的。

注意:不要同时使用重载函数和缺省参数的函数,因为当调用函数时少写一个参数,系统无法判定是利用重载函数还是利用缺省参数的函数,会发生错误。

6变量的引用类型

6.1 引用的概念

“引用”(reference)是C++的一种新的变量类型,是对C的一个重要扩充。它的作用是为一个变量起一个别名。假如有一个变量a,想给它起一个别名b,可以这样写:

int a;

int&b=a:

这就声明了b是a的“引用”,即a的别名。经过这样的声明后,使用a或b的作用相同,都代表同一变量。注意:在上述声明中,&是“引用声明符”,并不代表地址。不要理解为“把 a的值赋给b的地址”。声明引用并不另开辟内存单元,b和a都代表同一变量单元。在声明一个引用型变量时,必须同时使之初始化,即声明它代表哪一个变量,在声明一个变量的引用后,在本函数执行期间,该引用一直与其代表的变量相联系,不能再作为其他变量的别名。下面的用法不对:

int al,a2;

int&b=a1;

int&b=a2; (企图使b变成a2的引用(别名)是不行的)

6.2 引用的简单使用

通过下面的例子可以了解引用的简单使用。

例14.5 了解引用和变量的关系。

# include <iostream.h>

# include <iomanip.h>

void main( )

{inta=10;

int &b=a; //声明b是a的引用

a=a*a; //a的值变化了,b的值也应一起变化

cout<<a<<setw(6)<<b;

b=b/5; //b的值变化了,a的值也应一起变化

cout<<b<<setw(6)<<a;

}

a 的值开始为10,b是a的引用,它的值当然也应该是10,当a的值变为100(a*a的值)时,b

的值也随之变为100。在输出a和b的值后,b的值变为20,显然a的值也应为20(见图14.1)。运行记录如下:

100 100

  1. 20

6.3 引用作为函数参数

有了变量名,为什么还需要一个别名呢?C++之所以增加“引用”,主要是把它作为函数参数,以扩充函数传递数据的功能。

在C语言中,函数的参数传递有以下两种情况。

(1)将变量名作为实参。这时传给形参的是变量的值。传递是单向的,在执行函数期间形参值发生变化并不传回给实参,因为在调用函数时,形参和实参不是同一个存储单元。下面的程序无法实现两个变量的值互换。

例14.6错误的程序。

# include <iostream.h>

void swap(int a, int b)

{int temp;

temp=a;

a=b;

b=temp; //实现a和b的值互换

}

void main( )

{int i=3,j=5;

swap(i,j);

cout<<i<<","<<j<<endl; //i和j的值未互换

}

输出i和j的值仍为3和5。见图14.2示意。图14.2(a)表示调用函数时的数据传递,图14.2(b) 是执行swap函数体后的情况,a和b值的改变不会改变i和j的值。

为了解决这个问题,在第10章介绍了传递变量地址的方法。

  1. 传递变量的指针。使形参得到一个变量的地址,这时形参指针变量指向实参变量单元。程序见例14.7。

例14.7 使用指针变量作形参,实现两个变量的互换。

# include <iostream.h>

void swap(int* p1,int *p2)

{int temp;

temp=*pl;

*p1=*p2;

p2=temp;

}

void main( )

{int i=3,j=5;

swap(&i.&j);

cout<<i<<"."<<j<<endl;

}

形参与实参的结合见图14.3示意。调用函数时把变量;和j的地址传送给形参p1和 p2(它们是指针变量),因此*p1和i为同一内存单元,*p2和j为同一内存单元,图14.3(a)表示刚调用swap函数时的情况,图14.3(b)表示执行完函数体语句时的情况,显然,i和j的值改变了。

这种方法其实也是采用“值传递”方式,向一个指针变量传送一个地址。然后再通过指针变量访问有关变量。这样做能得到正确结果,但是在概念上“兜了一个圈子”,不那么直截了当。在PASCAL语言中有“值形参”和“变量形参”(即var形参),对应两种不同的传递方式,前者采用值传递方式,后者采用地址传递方式(传送的是变量的地址而不是变量的值,使形参指向一个变量)。在C语言中,只有“值形参”而无“变量形参”,全部采用值传递方式。C+十把引用型变量作为函数形参,就弥补了这个不足。

C++提供了向函数传递数据的第三种方法,即传送变量的别名。

例14.8 利用“引用形参”实现两个变量的值互换。

#include <iostream.h>

void swap (int &a,int &b)

{int temp;

temp=a;

a=b;

b=temp;

}

void main( )

{inti=3,j=5;

swap(i,j);

cout<<"i="<<i<<""<<j<<" <<endl;

}

输出结果为 i=5 j=3

        在swap函数的形参表列中声明变量a和b是整型的引用变量(和其他变量一样,既可以在函数体中声明变量的类型,也可以在定义函数时在形参表列中声明变量的类型)。请注意:在此处&a 不是“a 的地址”,而是指“a是一个引用型变量”。但是此时并未对它们初始化,即未指定它们是哪个变量的别名。当 main 函数调用swap函数时由实参把变 量名传给形参。i的名字传给引用变量a,这样a就成了i的别名。同理,b成为j的别名。a和i代表同一个变量,b和j代表同一个变量。在swap函数中使a和b的值对换,显然,i和j的值同时改变了(见图14.4示意,其中(a)是刚开始执行swap函数时的情况,(b)是执行完函数体语句时的情况)。在main函数中输出i和j已改变了的值。

        实际上,实参传给形参的是变量的地址,也就是使形参a具有变量i的地址,从而使a和i共享同一单元。为便于理解,我们说把变量i的名字传给引用变量a,使a成为i的别名。请注意这种传递方式和使用指针变量作形参时有什么不同?分析例14.8(对比例14.7),可以发现:①不必在swap函数中设立指针变量,指针变量要另外开辟内存单元、其内容是地址。而引用变量不是一个独立的变量,不单独占内存单元,在本例中其值为一整数。②在main函数中调用swap函数时实参不必在变量名前加&.以表示地址。这种传递方式相当于PASCAL语言中的“变量形参”,系统传送的是实参的地址而不是实参的值。显然,这种用法比使用指针变量简单、直观、方便。

的前面有类型符时(如int&a),它必然是对引用的声明;如果前面无类型符(如&a),则是取变量的地址。

7内置函数

        调用函数时需要一定的时间,如果有的函数需要频繁使用,则所用时间会很长,从而降低程序的执行效率。C++提供一种提高效率的方法,即在编译时将所调用函数的代码嵌人到主调函数中。这种嵌入到主调函数中的函数称为内置函数(inline function),又称内嵌函数。在有些书中把它译成“内联函数”。

        指定内置函数的方法很简单,只需在函数首行的左端加一个关键字inline即可。

例 14.9 将函数指定为内置函数。

# include <iostream.h>

inline int max(int a,int b,int c) //这是一个内置函数,求3个整数中的最大者

{ if(b>a)a=b;

 if(c>a)a=c;

 return a;

}

void main( )

{int i=7,j=10,k=25,m;

m=max(i,j,k):

cout<<" max="<<m<<endl;

}

由于在定义函数时指定它为内置函数,因此编译系统在遇到函数调用max(i,j,k)时,就用max函数体的代码代替max(i,j,k),同时将实参代替形参。这样,m=max(i,j, k)就被置换成

if(>i)i=j;

if(k>i)i=k;

m=it

内置函数与宏替换有些相似,但不完全相同。宏替换是在编译前由预处理程序进行预处理.它只作简单的字符替换而不作语法检查。而内置函数是在编译时处理的,编译程序能识别内置函数,对它进行语法检查。有些问题既可以用宏来处理,也可以用内置函数处理,显然,内置函数优于宏替换,它不会出现宏替换中可能产生的副作用。

使用内置函数可以节省运行时间,但却增加了目标程序的长度。假设要调用10次 max函数,则在编译时先后10次将max的代码复制并插人main函数,大大增加了main函数的长度。因此只用于规模很小而使用频繁的函数,可大大提高运行速度。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/780602.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

信号量或互斥锁

在使用信号量或互斥锁时&#xff0c;调用mutex_lock或sem_wait的程序会被挂起&#xff0c;进入等待状态&#xff0c;直到另一个线程调用unlock或sem_post来唤醒它。这种等待不是死循环&#xff0c;也不会一直消耗 CPU。 具体来说&#xff0c;当一个线程调用mutex_lock或sem_wa…

kubernetes(K8S)学习(五):K8S进阶(Lifecycle......偏理论)

K8S进阶&#xff08;Lifecycle......偏理论&#xff09; 一、Pod进阶学习之路1.1 Lifecycle1.2 重启策略1.3 静态Pod1.4 健康检查1.5 ConfigMap1.6 Secret1.7 指定Pod所运行的Node 二、Controller进阶学习之路2.1 Job & CronJob2.2 StatefulSet2.3 DaemonSet2.4 Horizontal…

Adobe Illustrator 2023 for Mac/Win:创意无限,设计无界

在数字艺术与设计领域&#xff0c;Adobe Illustrator 2023无疑是一颗璀璨的明星。这款专为Mac和Windows用户打造的矢量图形设计软件&#xff0c;以其强大的功能和卓越的性能&#xff0c;赢得了全球设计师的广泛赞誉。 Adobe Illustrator 2023在继承前代版本优点的基础上&#…

python——遍历网卡并禁用/启用

一、遍历网卡 注意&#xff1a;只能遍历到启用状态的网卡&#xff0c;如果网卡是禁止状态&#xff0c;则遍历不到&#xff01;&#xff01;&#xff01; import os import time import psutil import loggingdef get_multi_physical_network_card():physical_nic_list []try:…

线性代数笔记25--复数矩阵、快速傅里叶变换

1. 复数矩阵 复向量 Z [ z 1 z 2 z 3 z 4 ⋯ ] Z\begin{bmatrix} z_1\\z_2\\z_3\\z_4\\ \cdots \end{bmatrix} Z ​z1​z2​z3​z4​⋯​ ​ 复向量的模长 ∣ z ∣ z ‾ ⊤ z [ z ‾ 1 z ‾ 2 z ‾ 3 ] [ z 1 z 2 z 3 ] \lvert z\rvert\overline z^{\top}z \begin{bmatrix…

鸿蒙 UIAbility和Compent 生命周期

一、UIAbility的生命周期 在UIAbility的使用过程中&#xff0c;会有多种生命周期状态&#xff0c;掌握UIAbility的生命周期&#xff0c;对于应用的开发非常重要。 1、UIAbility的生命周期 UIAbility的生命周期主要分为以下4个&#xff1a; Create---Foreground---Background---…

【Golang星辰图】数据处理的航海家:征服数据海洋的航行工具

数据处理的建筑师&#xff1a;用Go语言中构建稳固的数据分析建筑物 前言 数据处理和分析是现代计算机科学中的关键任务之一&#xff0c;而Go语言作为一门现代化的编程语言&#xff0c;也需要强大的数据处理和分析库来支持其在这一领域的应用。本文将介绍几款优秀的数据处理和…

多模态大模型:解析未来智能汽车的新引擎

多模态大模型&#xff1a;解析未来智能汽车的新引擎 1. 多模态大模型简介2. 多模态大模型在智能汽车中的应用2.1 感知与认知2.2 智能驾驶辅助2.3 智能交互 随着人工智能技术的不断进步&#xff0c;智能汽车已经从概念变成了现实&#xff0c;成为了当今科技领域的焦点之一。而在…

大模型预测,下一个token何必是文字?

太快了太快了… 大模型的生成技能&#xff0c;已经到了普通人看不懂的境界&#xff01; 它可以根据用户过去5年的体检报告&#xff0c;生成未来第1年、第2年、第3年的体检报告。 你看&#xff0c;这个生成的过程&#xff0c;是不是像极了ChatGPT&#xff0c;根据历史单词预测…

顺序栈、链式栈、顺序队列、链式队列的ADT及其实现

顺序栈ADT及其实现 链式栈ADT及其实现 顺序队列的ADT及其实现 在数组中队首队尾的分配方案 第三中方案&#xff0c;即达到入队出队操作的时间代价是O&#xff08;1&#xff09; 同时可充分利用空间&#xff0c;不会出现空间似乎用完了的假象 时间性能和空间性能发挥到最大 链…

快速上手Spring Cloud 九:服务间通信与消息队列

快速上手Spring Cloud 一&#xff1a;Spring Cloud 简介 快速上手Spring Cloud 二&#xff1a;核心组件解析 快速上手Spring Cloud 三&#xff1a;API网关深入探索与实战应用 快速上手Spring Cloud 四&#xff1a;微服务治理与安全 快速上手Spring Cloud 五&#xff1a;Spring …

短视频矩阵系统---开发源头交付

短视频矩阵系统---开发源头交付 短视频矩阵系统的核心开发步骤包括以下几个方面&#xff1a; 1. 系统设计&#xff1a;根据需求分析&#xff0c;设计出相应的系统架构&#xff0c;包括数据库设计、系统功能模块设计等。 2. 开发基础功能&#xff1a;基础功能包括短视频的上传、…

数据库工具——DBeaver的安装及使用

目录 一、DBeaver介绍 1.定义 2.支持的数据库 3.支持的操作系统 4.特点 二、DBeaver安装及使用 1.服务启动 2.查看连接类型 3.演示连接Mysql数据库 4.连接配置 5.成功连接 6.远程控制 6.1新建数据库 6.2新建数据表 6.3添加字段列 6.4使用SQL编辑器进行编辑 一…

版本 23.0.0 , docker 安装 , docker目录迁移正确方法

docker 安装 docker 安装&#xff0c; https://docs.docker.com/engine/install/ubuntu/ # Add Dockers official GPG key: sudo apt-get update sudo apt-get install ca-certificates curl sudo install -m 0755 -d /etc/apt/keyrings sudo curl -fsSL https://download.do…

前端理论总结(jq)——jQuery九种选择器

(1)、基本选择器 #id&#xff0c;class&#xff0c;element&#xff0c;* (2)、层次选择器 parent > child&#xff0c;prev next &#xff0c;prev ~ siblings (3)、基本过滤器选择器 :first&#xff0c;:last &#xff0c;:not &#xff0c;:even &#xff0c;:odd &…

吉时利KEITHLEY2460数字源表

181/2461/8938产品概述&#xff1a; Keithley 2460 高电流源表源测量单元 (SMU) 将先进的触摸、测试和发明技术带到您的指尖。Keithley 2460 将创新的图形用户界面 (GUI) 与电容式触摸屏技术相结合&#xff0c;使测试变得直观并最大限度地缩短学习曲线&#xff0c;从而帮助工程…

提取单选框的值,并通过ajax传值到后台

<!DOCTYPE html> <html lang"zh" xmlns:th"http://www.thymeleaf.org" xmlns:shiro"http://www.pollix.at/thymeleaf/shiro"> <head><th:block th:include"include :: header(日库存更新提示)" /> </head&…

双向长短期BiLSTM的回归预测-附MATLAB代码

BiLSTM是一种带有正反向连接的长短期记忆网络&#xff08;LSTM&#xff09;。 BiLSTM通过两个独立的LSTM层&#xff0c;一个按时间顺序处理输入&#xff0c;另一个按时间倒序处理输入&#xff0c;分别从正向和反向两个方向捕捉输入序列的特征。具体地&#xff0c;正向LSTM按时…

蓝桥杯物联网竞赛_STM32L071_13_定时器

CubeMx配置LPTIM: counts internal clock events 计数内部时钟事件 prescaler 预分频器 updata end of period 更新期末 kil5配置&#xff1a; 中断回调函数完善一下&#xff1a; void HAL_LPTIM_AutoReloadMatchCallback(LPTIM_HandleTypeDef *hlptim){if(cnt ! 10) cnt…

Python:执行py命令,提示: Can‘t find a default Python.

1.Python运行环境罢工 今天&#xff0c;要运行一个前年用python编写的爬虫程序&#xff0c;先检测python运行环境是否正常&#xff1a; D:\Python38-32\works>c:\windows\py.exe Cant find a default Python. 再试&#xff1a; D:\Python38-32\works>py --list Installe…