C++编程学习(第18天)

C++内置函数、重载、模板及默认参数详解

内置函数

由于调用函数时需要一定的时间和空间开销。C++提供一种提高效率的方法,即在编译时将所调用的函数的代码直接嵌入到主调函数中,而不是将流程转出去。这种嵌入到主调函数中的函数称为内置函数,又称内嵌函数。

指定内置函数时,在函数首行的左端加一个关键字inline即可。

例:求三个数中最大者。

#include <iostream>
using namespace std;

inline int max(int, int, int);	//声明内置函数
int main()
{
	int i = 10, j = 20, k = 30, m;
	m = max(i, j, k);
	cout << "max = " << m << endl;
	return 0;
}

inline int max(int a, int b, int c)	//定义内置函数
{
	if (a < b)
		a = b;
	if (a < c)
		a = c;
	return a;
}

//结果为:max = 30

需要注意的是,可以在声明函数和定义函数时同时写inline,也可以只在函数声明时加inline,而定义函数时不加inline。只要在调用该函数之前把inline的信息告知编译系统,编译系统就会在处理函数调用时按内置函数处理。

使用内置函数可以节省运行时间,但增加了目标程序长度。因此只将规模很小,一般为5个语句以下的,使用频繁的函数声明为内置函数。在函数规模很小的情况下,函数调用的时间开销可能相当于甚至超过执行函数本身的时间,把它定义为内置函数,可大大减少程序运行的时间。

内置函数不能包括复杂的控制语句,如循环语句和switch语句。

需要注意,对函数作inline声明,只是程序设计者对编译系统提出的一个建议,也就是说,它是建议性的,而不是指令性的。并非一经指定为inline,编译系统就必须这样做,编译系统会根据具体情况决定是否这样做。

包含循环语句和switch语句的函数或一个递归函数是无法进行代码置换的,一个1000行的函数,也不大可能在调用点展开,此时编译系统就会忽略inline声明,而按普通函数处理。

归纳起来,只有那些规模较小而又被频繁调用的简单函数,才适合声明为inline函数。

函数的重载

C++允许用同一函数名定义多个函数,而这些函数的参数类型、参数个数或参数顺序至少有一种不能相同,这就是函数的重载。即对一个函数名重新赋予它新的含义,使一个函数名可以多用。所谓重载,其实就是一物多用。

在使用重载函数时,同名函数的功能应当相同或相近,不要用同一函数名去实现完全不相干的功能,虽然程序也能运行,但可读性不好,易使人莫名其妙。

例:分别对整型、双精度型和长整型类型的三个数据求最大值。

#include <iostream>
using namespace std;

int main()
{
	int max(int a, int b, int c);
	double max(double a, double b, double c);
	long max(long a, long b, long c);

	cout << "请输入三个整数:";
	int i, i1, i2, i3;
	cin >> i1 >> i2 >> i3;
	i = max(i1, i2, i3);
	cout << "i_max =" << i << endl;

	cout << "请输入三个双精度数:";
	double d, d1, d2, d3;
	cin >> d1 >> d2 >> d3;
	d = max(d1, d2, d3);
	cout << "d_max =" << d << endl;

	cout << "请输入三个长整型数:";
	long l, l1, l2, l3;
	cin >> l1 >> l2 >> l3;
	l = max(l1, l2, l3);
	cout << "l_max =" << l << endl;
}
int max(int a, int b, int c)
{
	if (a < b)
		a = b;
	if (a < c)
		a = c;
	return a;
}
double max(double a, double b, double c)
{
	if (a < b)
		a = b;
	if (a < c)
		a = c;
	return a;
}
long max(long a, long b, long c)
{
	if (a < b)
		a = b;
	if (a < c)
		a = c;
	return a;
}

结果如下:

函数模板

所谓函数模板,实际上是建立一个通用函数,其函数类型和形参类型不具体指定,用一个虚拟的类型来代表,这个通用函数就称为函数模板。

凡是函数体相同的函数都可以用这个模板来代替,不必定义多个函数,只须在模板中定义一次即可。在调用函数时,系统会根据实参的类型来取代模板中的虚拟类型,从而实现不同函数的功能。

定义函数的一般形式为

template <typename T>
通用函数定义

template <class T>
通用函数定义

例:

#include <iostream>
using namespace std;
template <typename T>	//模板声明,其中的T为类型参数
T max(T a, T b, T c)	//定义一个通用函数,用T作为虚拟的类型名
{
	if (a < b)
		a = b;
	if (a < c)
		a = c;
	return a;
}

int main()
{
	int i, i1 = 12, i2 = 32, i3 = 23;
	double d, d1 = 12.12, d2 = 13.13, d3 = 11.11;
	long l, l1 = 12345678, l2 = 23456789, l3 = 87654321;

	i = max(i1, i2, i3);
	d = max(d1, d2, d3);
	l = max(l1, l2, l3);

	cout << "i_max = " << i << endl;
	cout << "d_max = " << d << endl;
	cout << "l_max = " << l << endl;
	return 0;
}

//结果为:
i_max = 32
d_max = 13.13
l_max = 87654321

template的含义是模板,尖括号中先写关键字typename或class,后面跟一个类型参数T,这个类型参数实际上是一个虚拟的类型名,表示模板中出现的T是一个类型名,但是现在并未指定它是哪一种具体的类型。在函数定义时用T来定义变量a,b,c,显然变量a,b,c的类型也是未确定的,要等到函数调用时根据实参的数据类型来确定T是什么类型。其实也可以不用T而用任何一个标识符,许多人习惯用T,T是type的首字母大写,以与实际的类型名相区别。

class和typename的作用相同,都是表示类型名,二者可以互换。

以前的C++程序习惯用class,typename是新增到标准C++中的,用class容易与C++中的类混淆,而用typename的含义很清楚,是数据类型名。

类型参数可以不止一个,可以根据需要定义多个

template<class T1,typename 2>

需要注意的是,函数模板只适用于函数体相同,函数参数个数相同而数据类型不同的情况,如果参数个数不同,不能用函数模板。

有默认参数的函数

一般情况下,在函数调用时形参从实参那里取值,因此实参的个数应与形参相同。当用同样的实参多次调用同一函数时,C++提供了简单的处理办法,给形参一个默认值,这样形参就不必一定要从实参取值了。

如果有多个形参,可以使每个形参都有一个默认值,也可以只对一部分形参指定默认值,另一部分形参不指定默认值。

形参与实参的结合是从左至右顺序进行的,第一个实参必然与第一个形参结合,第二个实参必然与第二个形参结合...,因此指定默认值的参数必须放在形参表列中的最右端,否则出错。

需要注意的是

1、如果函数的定义在函数调用之前,则应在函数定义中给出默认值。

2、如果函数的定义在函数调用之后,则在函数调用之前需要有函数声明,此时必须在函数声明中给出默认值,在函数定义时可以不给出默认值,也就是说必须在函数调用之前将默认值的信息通知编译系统。

3、如果在声明函数时已对形参给出了默认值,而在定义函数时又对形参给出默认值,有的编译系统会给出“重复指定默认值”的报错信息,有的编译系统对此不报错,甚至允许在声明时和定义时给出的默认值不同,此时编译系统以先遇到的为准。由于函数声明在函数定义之前,因此以声明时给出的默认值为准,而忽略定义函数时给出的默认值。

4、一个函数不能既作为重载函数,又作为有默认参数的函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

武当豆豆

为国家GDP快速增长做贡献

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

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

打赏作者

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

抵扣说明:

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

余额充值