前言
函数调用分类:嵌套调用、递归调用
堆栈:理解为管理信息调用的一个东西
3.3.1嵌套调用
应该是一个函数里面调用另一个函数,里面再层层调用函数。先执行最后一个调用的函数,执行完后继续执行倒数第二个函数,以此类推。
3.3.2递归调用
就是调用自身。常常需要设置一个递归终止的情况。(if....(通常是递归终止条件) return... else... return...)
例题:求n!
#include<iostream>
using namespace std;
long fact(int n) //注意long和int!!
{
if (n == 0) return 1; //1是直接呈现出来的结果吧。。应该不是永真
else return n*fact(n - 1);//注意不要省略掉“n*”!!!
}
int main()
{
int n;
while (cin >> n)
{
cout << n << "!=" << fact(n) << endl;
}
return 0;
}
注意:需要从n开始递归,最后一项是1!
例题:反序输出一串字符
#include<iostream>
using namespace std;
void fact()
{
char ch; //局部变量
cin >> ch; //手动输入变量值,不要忘了!
if (ch != '.') //即终止条件是=0
fact();
cout << ch; //输入了“.”时,就会终止最后一个函数,然后继续执行完倒数第二个函数,即输出用户输入的字符
}
int main()
{
fact();
return 0;
}
例题:反序输出正整数字串
#include<iostream>
using namespace std;
void fact(long n)
{
cout << n % 10; //取余!输出最右边的数字
if (n / 10 != 0) //只有0.几的小数满足
fact(n / 10); //取整求商,递归!!
}
int main()
{
long k;
cin >> k;
fact(k);
return 0;
}
例题:斐波那契数列(又是你!)
但是要注意题目要你干什么!!
#include<iostream>
using namespace std;
long fb(int n)//n代表项数
{
if (n == 0||n==1) return n; //前两项定义好了,规定第0项是0!!!
else return fb(n - 1) + fb(n - 2); //递推公式
}
int main()
{
long n;
while (cin >> n)
{
cout << fb(n) << endl; //显示的是每一项
}
return 0;
}
例题:汉诺塔问题
主体思路:先把最大的盘子移到C中,再移动剩下的n-1个盘子,然后剩下的n-1个盘子也是如此,以此类推。构成递归,感受一下吧!
借助B作为过度体
要想把最大的盘子挪走,那么得先挪走小的盘子,然后将大盘挪到C,暂时先用B来存放小盘。
先把n-1个盘子挪到B上,在把最大那个挪到C上,然后再将那n-1个盘子挪到C上
#include<iostream>
using namespace std;
void move(int n,char a,char b,char c)//n代表几个盘子,abc代表三个柱子。实际上,最左边的a代表起点
//最右边代表终点,中间是过度量。
{
if (n >0) //这样比书上的更简化,n=1时函数就不执行了,直接执行cout
{
move(n - 1, a, c, b); //先把那n-1个盘子从A开始,经过c,挪到b
//括号里的已经是传进去的实参
cout << a<<"-->" << c << endl; //最底边的盘子从A到C
move(n - 1, b, a, c); //再把n-1个盘子从B挪到C
}
}
int main()
{
int m;
while (cin >> m)
{
move(m, 'A', 'B', 'C'); //'A'等直接输入,是那个变量值,不是变量,所以不用被定义
}
return 0;
}