语言基础-函数

来源:互联网 发布:标题优化的好处 编辑:程序博客网 时间:2024/06/07 10:12

参数传递

将引用作为函数参数的特点:

  • 在被调函数中对形参变量的操作就是对其相应的目标对象的操作。
  • 在内存中没有产生实参的副本,它是直接对实参进行操作;而使用一般变量传递函数的参数,当发生函数调时,需要给形参分配存储单元,如果传递的是对象,还要调用拷贝构造函数。因此,当参数传递的数据较大时,用引用比用一般的变量传递参数的效率和所占空间都好。
  • 虽然使用指针也能达到引用的效果,但是在函数调用时同样要给形参分配存储单元,而且程序容易产生错误,阅读性差。

传递指针的引用

例子:

void ptrswap(int *&v1, int *&v2){  int *tmp = v2;  v2 = v1;  v1 = tmp;}

形参int *&v1的定义从右往左理解:v1是一个引用,与指向int类型对象的指针相关联。也就是说,v1只是传递进ptrswap函数的任意int型指针的别名。

内联函数

用inline修饰,有两种形式:

  • 在类中定义的成员函数全部默认为内联函数,可以显示地加上inline标识符,或者不加。
  • 普通函数声明或定义前加上inline成为内联函数。

在编译时,调用内联函数的地方,将不进行函数调用,而是使用函数体替换调用处的函数名,形式类似宏替换,这种替换成为内联扩展,可以消除函数调用时的时间开销。

注意,宏定义与内联函数的区别:1. 宏定义是在预处理阶段进行代码替换,而内联函数是在编译阶段插入代码;2. 宏定义没有类型检查,而内联函数有类型检查。

函数重载

函数重载用来命名一组功能相似的函数,这样减少函数名的数量,避免名字空间的污染。

函数重载,同名,参数个数不同,或参数类型不同,不能仅仅基于不同的返回类型而重载。

函数模板与泛型

泛型编程与面向对象编程一样,有依赖于每种形式的多态性。模板是泛型的基础。

例子:模板加内联

#include <iostream>using namespace std;template <typename T>inline T AddNums(const T &a, const T &b){    return a + b;}int main(){    cout << AddNums(3, 5) << "," << AddNums(3.2, 5.3) << endl;    return 0;}

例子:类模板

template <class Type> class Queue {public:    Queue();    void push(const Type &);private:    // ...};

使用类模板时,必须为模板形参显示制定实参。Queue<int> q;

函数的递归

递归必须满足两个条件:

  • 递归表达式(递归体)
  • 边界条件(递归出口)

递归的精髓在于能否将原始问题转换为属性相同但规模较小的问题。

递归的优点是减少程序的代码量,缺点是通常情况下效率不高。

例:斐波那契递归实现

int Fib(n) {  if(n == 0)    return 0;  else if(n == 1)    return 1;  else    return Fib(n-1)+Fib(n-2);}

将递归转换为非递归,通常需要借助来实现。

附:斐波那契动态规划实现

int DPFib(int n){    int ret = 0,dpA, dpB;    if(n==1)        return 1;    else if(n==2)        return 2;    dpA = 1;    dpB = 2;    for(int i = 3; i <= n; ++i){        ret = dpB + dpA;        dpA = dpB;        dpB = ret;    }    return ret;}
0 0
原创粉丝点击