内置函数
由于调用函数时需要一定的时间和空间开销。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、一个函数不能既作为重载函数,又作为有默认参数的函数。
C++内置函数、重载、模板及默认参数详解

被折叠的 条评论
为什么被折叠?



