应对高校C++考试(二) : 函数

这节讲c++的某些特殊函数语法糖,主要讲 函数递归调用,默认参数,函数重载。

目录

函数声明

你应该很熟悉声明一个函数的方法

<返回值类型>  <函数名字>(变量类型){
.....
return <返回值类型相同的值>
}

尖括号中是你需要替换的东西。

为什么要引入函数呢? 如果你经常编程,你会发现有很多好处:

  1. 当你有很多相同语义的代码的时候,可以改成函数,这样避免每次都去复制粘贴
  2. 要更改代码,只需要更改函数中的内容就行 了,调用处不用更改。

当然以上内容并不影响考试

函数的递归调用

这个理解起来很简单,比如下面的计算阶乘的函数


int fact(int n){
    if(n == 1)return 1;
    else return n*fact(n-1);
}

//迭代写法
int fact_diedai(int n){
    int ret =n;
    while(--n)ret*=n;
    return ret;
}

函数内部,第3行又调用了这个函数,但可以知道,这种调用时不能无限的,否则就要 栈溢出了 也就是一定要达到某个条件后能够终止这种递归调用,这里就是 n==1 的时候。可以发现递归的写法很简单,你只需要描述清楚这个函数递归调用步骤就行了,迭代写法就比较麻烦了,你必须想清楚什么时候迭代完成。类似下面一种写法。

递归调用的原理是什么呢?要搞清楚这个,最好的办法就是设置断点,手动跟踪一下。
我这里简单讲讲:

扫描二维码关注公众号,回复: 2349651 查看本文章

这里写图片描述

程序运行时有一个 (你可以将他理解为内存)来进行计算,也就是说计算到fact(3) 时,他会将参数3 压倒栈中,然后执行fact那段代码,执行到第二行判断不为1,于是继续执行第三行调用fact(2), 这时又开一段内存(栈)来维护fact(2) 的调用信息,继续计算,直到返回。

可以发现,这个调用过程会产生额外的时间和空间开销 (压栈),并且还要额外的内存,因此计算机是不能无限执行下去的,你必须在适当的时候能让他返回,不然就栈溢出了。最后我强烈建议你自己能设置断点跟踪一下(不会? 出门搜索一下吧)。应该说递归是比较好写了一种编程方法。递归节约的是人力而迭代节约的是算力,显然人力更值钱。

这是很重要的知识点,强力建议理解下面两个问题:

  1. 编写汉诺塔,并跟踪理解程序
  2. 写一个dfs 遍历一个图

这两个都很经典,你可以出门搜到源代码,有时间强烈建议跟踪并理解调用过程。

默认参数

这个就是一个语法糖有他没他对编程都不会有什么影响,这里简单说一下。所谓默认参数就是在函数声明的时候指明参数的值,这样调用的时候就可以 少传一个参数,例如:

#include<iostream>
using namespace std;

int fact(int n =5){
    if(n == 1)return 1;
    else return n*fact(n-1);
}

int main(){
    cout << fact() << "\n";
    return 0;
}

默认计算 fact(5), 不过要注意如果有多个参数,默认参数一定要在后面,不能在前面,例如:

#include<iostream>
using namespace std;

// int fact(int n =5){
//     if(n == 1)return 1;
//     else return n*fact(n-1);
// }

int fact(int n,bool printProcess=true){
    if(printProcess){
        cout << "now call n = " << n <<"\n";
    }
    if(n == 1)return 1;
    else return n*fact(n-1,printProcess);
}


int main(){
    cout << fact(5) << "\n";
    return 0;
}

如果将第9行改为 int fact(bool printProcess=true,int n), 就会编译错误了,不信你试试

函数重载

这个也是一个语法糖,就是说c++里面怎么认为函数是不一样的呢?他认为只要你名字以及参数是不相同的就行了,也就是说两个函数是可以同名的,但是同名函数参数必须不同(可以是参数变量类型,也可以是参数个数), 比如上面一个程序,我将注释部分解开也是能编译通过的。

#include<iostream>
using namespace std;

int fact(int n =5){
    if(n == 1)return 1;
    else return n*fact(n-1);
}

int fact(int n,bool printProcess=true){
    if(printProcess){
        cout << "now call n = " << n <<"\n";
    }
    if(n == 1)return 1;
    else return n*fact(n-1,printProcess);
}


int main(){
    cout << fact(5,true) << "\n";
    return 0;
}

后续运算符重载也如此。

例题,编写比较函数 cmp ,比较两个 int/double/bool 类型变量

下一节讲 指针数组和引用。

猜你喜欢

转载自blog.csdn.net/dylan_frank/article/details/80563217