1、静态局部变量和静态全局变量的区别
主要是作用域方面的差别:
- 静态局部变量只在定义它的函数内有效,只是程序仅分配一次内存,函数返回后,该变量不会消失,只被初始化一次,自从第一次被初始化直到程序运行结束都一直存在。
- 静态全局变量只在定义它的文件内有效,不能作用到其它文件里,即被static关键字修饰过的全局变量具有文件作用域。
2、递归函数有何利弊?斐波拉契数列不用递归应该如何写?
利:
(1)代码更简洁,可读性更高;
(2)将复杂问题拆分成简单的小问题;
弊:
(1)时间空间消耗大。每一次函数调用都需要在内存栈中分配空间以保存参数,返回地址以及临时变量,而且数据入栈和出栈都需要时间。
(2)存在重复计算。递归本质是把一个问题分解成两个或者多个小问题,多个小问题存在相互重叠的部分,存在重复计算。(考虑剪枝操作,提高效率)
(3)调用栈可能会溢出。每一次函数调用会在内存栈中分配空间,而每个进程的栈的容量是有限的,当调用的层次太多时,就会超出栈的容量,从而导致栈溢出。
斐波那契数列不用递归写法:
#include<iostream>
using namespace std;
int main(){
int a = 1;
int b = 1;
int n;
cout<<"Please enter a number:";
cin>>n;
for(int i=0;i<n-1;i++){
int temp = a;
a = b;
b = b + temp;
}
cout<<"斐波那契数列的第"<<n<<"个数字是"<<a<<endl;
}
运行结果:
3、如何避免函数重载的二义性
(1)注意函数重载参数的设置
a. 若变量个数相同,只有类型不同时,注意变量类型的隐式转换尽量使用参数个数不同且参数类型不同的重载函数(或者可以使用explicit关键字来避免隐式转换)。
b. 函数参数表有缺省参数(默认参数)的情况下,避免使用重载函数。
(2)显性调用函数/访问函数
a. 使用 “类名::变量名” 显性访问
汉诺塔实验报告
一、 实验目的
掌握递归函数的使用。
二、 环境配置(使用vscode)
(1)先在官网下载vscode
(2)下载安装mingw64(离线包,速度较快)
(3)将gcc.exe路径添加到系统环境变量
(4)在vscode中安装中文包
三、 问题分析
题目:
利用递归思想,汉诺塔问题可拆分为简单问题
四、 程序调试设计
思路:
- 使用递归,三个柱分为起始柱A、中间柱B和目标柱C。
- 盘子的移动可看作将n-1个盘子移动到中间柱B,再将第n个盘子移动到目标柱C的过程,最后将B上的n-1个盘子移动到目标柱C的过程。
1、设计move函数移动盘子(实现移动盘子功能)
void move(int n,char beg,char des){
cout<<n<<':'<<beg<<"-->"<<des<<endl; //将1个盘子从起始柱移动到目标柱
}
2、设计递归函数
void hanoi(int n, char a, char b, char c){
if(n == 1) move(n,a,b); //基例,剩下一盘子时,将盘子从起始柱移动到目标柱
else{
hanoi(n-1,a,b,c); //先将n-1个盘子从a移动到b,借助c
move(n,a,c); // 将第n个盘子从a移动到c
hanoi(n-1,b,c,a); //再将n-1个盘子从b移动到c,借助a
}
}
3、主函数
int main()
{
int n;
cin>>n; //输入盘子的个数
hanoi(n,'A','B','C');
//一共n个盘子,柱的名称分别为A、B、C
return 0;
}
4、完整代码
# include<iostream>
using namespace std;
void move(int n,char beg,char des){
cout<<n<<':'<<beg<<"-->"<<des<<endl;
}
void hanoi(int n, char a, char b, char c){
if(n == 1) move(n,a,b);
else{
hanoi(n-1,a,b,c);
move(n,a,c);
hanoi(n-1,b,c,a);
}
}
int main()
{
int n;
cin>>n;
hanoi(n,'A','B','C');
return 0;
}