C++对C的扩充(三)

news2024/11/30 15:31:28

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.coloradmin.cn/o/1555750.html

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

相关文章

嵌入式下C/C++调用sqlite3简单开发

交叉编译sqlite3请关注我第一篇博文 sqlite3 交叉编译-CSDN博客 sqlite3的命令的简单使用&#xff08;增删改查&#xff0c;创建/删除表&#xff09;请关注我的上一篇博文 sqlite3嵌入式使用以及C/C代码开发-CSDN博客 一、新建文件夹 此文件夹用于放置工程&#xff0c;比如…

MySQl on和where条件的区别?

MySQ L on和where条件的区别&#xff1f; on会生成临时表&#xff0c;不满足条件会置空 where 过滤数据&#xff0c;不满足的数据不会显示

推荐算法策略需求-rank model优化

1.pred_oobe (base) [rusxx]$ pwd /home/disk2/data/xx/icode/baidu/oxygen/rus-pipeline/pipeline-migrate/UserBaseActiveStatPipeline/his_session (base) [rusxx]$ sh test.sh 2. user_skill_history_dict_expt2包含userid [workxx]$ vim /home/work/xx/du-rus/du_rus_o…

在Windows上交叉编译STM32(环境搭建)

在Windows上交叉编译STM32 Keil 虽然好用&#xff0c;但是是收费的&#xff0c;不想破解怎么办~ 使用交叉编译工具&#xff01; 交叉编译工具下载 官方交叉编译工具下载连接 下载解压好后将 bin 目录写入 PATH&#xff0c; 使用命令行检测是否安装成功。 Windows 安装 make …

Docker搭建LNMP环境实战(08):安装php-fpm

1、编写php测试文件 在文件夹&#xff1a;/mnt/hgfs/dockers/test_site/www目录下创建文件&#xff1a;test.php&#xff0c;内容为&#xff1a; <?phpecho "hello world!!!!!! From test.php"; ?>2、编写php-fpm部署配置文件 在文件夹&#xff1a;/mnt/h…

鸿蒙 UIAbility和Compent 生命周期

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

linux提权笔记

1 linux提权简介 Linux提权&#xff0c;简单来说&#xff0c;就是用户尝试获取高于其当前权限级别的系统访问权限的过程。在Linux系统中&#xff0c;root用户拥有最高的权限&#xff0c;能够执行任何操作&#xff0c;包括修改系统文件、安装软件、管理用户账户等。而普通用户通…

用html写一个贪吃蛇游戏

<!DOCTYPE html> <html> <head><title>贪吃蛇</title><meta charset"UTF-8"><meta name"keywords" content"贪吃蛇"><meta name"Description" content"这是一个初学者用来学习的小…

智慧公厕厂家如何选择?光明源智能科技打造一流智慧公厕项目

在当今城市化进程中&#xff0c;智慧公厕已经成为提升城市品质、改善市民生活的重要一环。然而&#xff0c;要打造一流的智慧公厕项目&#xff0c;选择合适的厂家显得尤为重要。作为行业领军者&#xff0c;光明源智能科技在智慧公厕领域具有丰富的经验和卓越的技术实力。今天&a…

使用倒模耳机壳UV树脂胶液制作HIFI耳机隔音降噪耳机壳推荐的材料和工艺流程?

对于使用倒模耳机壳UV树脂胶液制作HIFI耳机隔音降噪耳机壳&#xff0c;以下是一些推荐的材料和工艺流程&#xff1a; 材料&#xff1a; UV树脂胶液&#xff1a;选择适合倒模工艺的UV树脂胶液&#xff0c;要求具有高透明度、良好的流动性和固化性能。模具材料&#xff1a;根据…

SpringCloudAlibaba服务消费者调用nacos服务报错:java.net.UnknownHostException: xxx

确保服务情况正常 通过服务名字调用(注意不需要添加端口号) RequestMapping("/add") public String add() {String url "http://stock-nacos/stock/reduce";String result restTemplate.getForObject(url, String.class);System.out.println("下单…

【电子取证篇】哈希校验值的变与不变

【电子取证篇】哈希校验值的变与不变 哈希值&#xff08;散列值&#xff09;是针对电子数据内容来计算的&#xff0c;内容变则哈希变&#xff1b;但计算对象的文件名、文件时间等属性改变不会影响散列值&#xff01;&#xff01;&#xff01;—【蘇小沐】 &#xff08;一&…

软件设计不是CRUD(16):低耦合模块设计理论——行为抽象与设计模式(下)

(接上文《软件设计不是CRUD(15):低耦合模块设计理论——行为抽象与设计模式(中)》) 3.2.4、之前的业务逻辑需要关注后续逻辑的执行成败,并调整自身执行的情况 这个场景在之前场景的基础上增加了新的控制要求,具体来说就是之前已经完成的控制逻辑执行,需要在后续控制…

【讲解下go和java的区别】

&#x1f525;博主&#xff1a;程序员不想YY啊&#x1f525; &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家&#x1f4ab; &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 &#x1f308;希望本文对您有所裨益&#xff0c;如有…

基于java+springboot+vue实现的电商个性化推荐系统(文末源码+Lw+ppt)23-389

摘 要 伴随着我国社会的发展&#xff0c;人民生活质量日益提高。于是对电商个性化推荐进行规范而严格是十分有必要的&#xff0c;所以许许多多的信息管理系统应运而生。此时单靠人力应对这些事务就显得有些力不从心了。所以本论文将设计一套电商个性化推荐系统&#xff0c;帮…

uniapp-打包IOS的APP流程

打包前所需配置 在manifest文件内配置 1. APP图标 2. 启动界面 有三种启动界面配置 第一种是 HBuilderX 官方给的通用启动界面&#xff0c;页面单一&#xff0c;屏幕中间就一个圆框图标 第二种是自定义的启动图&#xff0c;无法通过AppStore的审核 第三种是自定义storyboard启动…

数据结构:单调栈和单调队列

文章目录 一、单调栈1.1、栈的思想1.2、单调栈1.2.1、单调栈的基本应用&#xff1a;找出数组中每个元素右侧第一个更大的元素1.2.2、单调栈的基本应用&#xff1a;找出数组中每个元素左侧第一个更大的元素1.2.3、单调栈拓展1.2.4、单调栈LeetCode题单 二、单调队列2.1、队列的思…

C++项目——集群聊天服务器项目(八)用户登录业务

在第&#xff08;7&#xff09;节中&#xff0c;已经实现用户注册模块&#xff0c;本节来实现用户登录模块 项目流程 1、项目环境搭建 C项目——集群聊天服务器项目(一)项目介绍、环境搭建、Boost库安装、Muduo库安装、Linux与vscode配置_c集群聊天服务器-CSDN博客 2、Jso…

Linux(5)底层分析-常见问题-经典笔试面试题整理

六、底层分析 1、linux 目录 Linux各路径的解释&#xff1a; /bin存放二进制可执行文件(ls,cat,mkdir等)&#xff0c;常用命令一般都在这里/home存放所有用户文件的根目录&#xff0c;是用户主目录的基点&#xff0c;比如用户user的主目录是/home/user&#xff0c;可以用~us…

iOS - Runtime - Class-方法缓存(cache_t)

文章目录 iOS - Runtime - Class-方法缓存(cache_t)1. 散列表的存取值 iOS - Runtime - Class-方法缓存(cache_t) Class内部结构中有个方法缓存&#xff08;cache_t&#xff09;&#xff0c;用散列表&#xff08;哈希表&#xff09;来缓存曾经调用过的方法&#xff0c;可以提高…