C++函数:函数声明、内置函数、函数重载、函数模板

目录

1.对被调用函数的声明和函数原型

(1)在一个函数中调用被调用函数需要具备的条件

(2)函数定义和函数声明的区别

2.内置函数 

3.函数重载

4.函数模板


1.对被调用函数的声明和函数原型

(1)在一个函数中调用被调用函数需要具备的条件

    1.被调用的函数必须是已经存在的函数(是库函数或者是用户自己定义的函数)。

    2.如果使用库函数,还需要在本文件开头用#include指令将有关头文件“包含”到本文件中来。

    3.如果使用用户自定义函数,而该函数与主调函数在同一个程序单位中,且位置在主调函数之后,则必须在调用此函数之前对被调用的函数作声明。

(2)函数定义和函数声明的区别

     所谓函数声明(declaration),就是在函数尚未定义的情况下,事先将该函数的有关信息通知编译系统,以便使编译能正常进行。对函数的定义和声明不是同一回事。定义是指对函数功能的确立,包括指定函数名、函数类型、形参及其类型、函数体等,它是一个完整的、独立的函数单位。而声明的作用则是把函数的名字、函数类型以及形参的个数、类型和顺序(不包含函数体)通知编译系统,以便在对包含函数调用的语句进行编译时,据此对其进行对照检查(例如函数名是否正确,实参和形参的类型和个数是否一致等)。

   下面是一个包含函数声明和函数定义的实例。 

#include <iostream>
using namespace std;

int main()
{
    float add(float x,float y);  //对add函数作声明
    float a,b,c;

    cout << "Please enter a,b:";
    cin >> a >> b;
    c = add(a,b);
    cout << "sum = " << c << endl;

    return 0;
}

float add(float x,float y){  //定义add函数
    float z;
    z = x+y;
    return z;
}

      其中,函数声明部分float add(float x,float y);也可以写成float add(float,float); 以上的函数声明称为函数原型(function prototype)。使用函数原型是C和C++的一个重要特点。它的作用主要是:根据函数原型在程序编译阶段对调用函数的合法性进行全面检查。

      注意:如果被调用函数的定义出现在主调函数之前,可以不必加以声明;函数声明的位置可以在调用函数所在的函数体中,也可以在函数体之外。如果函数声明放在函数的外部,并且在所有函数定义之前(即对函数的外部声明),则在各个主调函数中不必对所调用的函数再作声明,其作用域是整个文件。

2.内置函数 

        调用函数时需要一定的时间和空间开销。函数调用的过程:1.程序先执行函数调用之前的语句;2.流程的控制转移到被调用函数的入口处,同时进行参数传递;3.执行被调用函数中函数体的语句;4.流程返回到调用函数的下一条指令处,并将函数返回值带回;5.执行主调函数中未执行的语句。

        这就要求在转去被调用函数之前,要记下当时执行的指令的地址,还要“保护现场”(即记下当时有关的信息),以便在函数调用之后继续执行。在函数调用后,流程返回到先前记下的地址处,并且根据记下的信息“恢复现场”,然后继续执行。这些都要花费一定的时间。如果有的函数需要频繁调用,则所用时间会很长,从而降低程序的执行效率。有些实用程序对效率是有要求的,要求系统的响应时间短,这就希望尽量压缩时间的开销。

        C++提供一种提高效率的方法,即在编译时将所调用函数的代码直接嵌入到主调函数中,而不是将流程转移出去。这种嵌入到主调函数中的函数称为内置函数(inline function),或称为内嵌函数、内联函数。指定内置函数的方法是在函数首行的左端加一个关键字inline。

       下面是一个将函数指定为内置函数的实例。

#include <iostream>
using namespace std;

inline int maxVal(int.int,int);  //声明内置函数

int main()
{
   int i=10, j=20, k=30, m;
   m = maxVal(i,j,k);
   cout << "max = " << m << endl;
   return 0;
}

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

       程序分析:由于在定义函数时指定它为内置函数,因此编译系统在遇到函数调用“maxVal(i,j,k)”时,就用maxVal函数体的代码代替“maxVal(i,j,k)”,同时将实参代替形参。这样,程序中的“m = maxVal(i,j,k);”就被置换为  

if(j>i) i=j;
if(k>i) i=k;
m = i;

        可以在声明函数和定义函数时同时写inline,也可以只在函数声明时加inlne,而定义函数时不加inline。只要在调用该函数之前把inline的信息告知编译系统,编译系统就会在处理函数调用时按内置函数处理。使用内置函数可以节省运行时间,但增加了目标代码的长度。因此只将规模很小(一般为5个语句以下)而使用频繁的函数(如定时采集数据的函数)声明为内置函数。在函数规模很小的情况下,函数调用的时间开销可能相当于甚至超过执行函数本身的时间,把它定义为内置函数,可以大大减少程序运行的时间。归纳起来就是,只有那些规模较小而又被频繁调用的简单函数,才适合于声明为inline函数。

3.函数重载

        C++允许用同一函数名定义多个函数,而这些函数的参数个数和参数类型可以不同。这就是函数重载(function overloading)。即对一个函数名重新赋予它新的含义,使一个函数名可以多用。重载函数的参数个数、参数类型和参数顺序三者中必须至少有一种不同,函数返回值类型不能作为函数重载的条件,即函数返回值类型可以相同也可以不相同。

        下面是一个函数重载的实例。

#include <iostream>
using namespace std;

int main()
{
    int maxVal(int a,int b,int c);  //函数声明
    int maxVal(int a,int b);        //函数声明
    int a = 8, b = -12, c = 27;
    cout << "max(a,b,c) = " << maxVal(a,b,c) << endl;  //输出3个整数中的最大数
    cout << "max(a,b) = " << maxVal(a,b) << endl;      //输出2个整数中的最大数
    return 0;
}

int maxVal(int a,int b,int c)
{
    if(b>a)
        a=b;
    if(c>a)
        a=c;
    return a;
}

int maxVal(int a,int b)
{
    if(a>b)
        return a;
    else
        return b;
}

4.函数模板

        所谓函数模板(function template),实际上是建立一个通用函数,其函数类型和形参类型不具体指定,用一个虚拟的类型代表。这个通用函数就称为函数模板。凡是函数体相同的函数都可以用这个模板来代替,不需要定义多个函数,只须在模板中定义一次即可。在调用函数时会根据实参的类型来取代模板中的虚拟类型,从而实现不同函数的功能。
       

#include <iostream>
using namespace std;

template<typename T>      //模板声明,其中T为类型参数
T maxVal(T a, T b, T c){  //定义一个通用函数,用T作函数的类型名
    if(b>a)
        a=b;
    if(c>a)
        a=c;
    return a;
}

int main()
{
    int i1 = 8, i2 = -12, i3 = 27, i;
    double d1 = 56.87, d2 = 90.24, d3 = -3214.78, d;
    long g1 = 67854, g2 = -912456, g3 = 673456, g;

    i = maxVal(i1,i2,i3);  //调用模板函数,此时T被int取代
    d = maxVal(d1,d2,d3);  //调用模板函数,此时T被double取代
    g = maxVal(g1,g2,g3);  //调用模板函数,此时T被long取代

    cout << "i_max = " << i << endl;
    cout << "d_max = " << d << endl;
    cout << "g_max = " << g << endl;
    return 0;
}

        类型参数可以不止一个,可以根据需要确定个数,如 template<class T1, typename T2>。可以看到,用函数模板比函数重载更方便,程序更简洁。但应注意它只适用于函数体相同、函数的参数个数相同而类型不同的情况,如果重载函数的参数个数不同,就不能用函数模板来代替。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值