C++对C的扩充(三)

本文介绍了C++中带缺省参数的函数、引用类型的使用以及内置函数的概念。通过实例展示了如何利用这些特性提高代码的灵活性和减少运行时的函数调用开销,尽管内置函数可能导致目标程序体积增大。
摘要由CSDN通过智能技术生成

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函数的长度。因此只用于规模很小而使用频繁的函数,可大大提高运行速度。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阳光向日葵之沈阳

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值