C++函数新特征与递归函数

来源:互联网 发布:mac怎么彻底删除战网 编辑:程序博客网 时间:2024/06/02 05:53

地址:http://blog.csdn.net/sxhelijian/article/details/40947993

【项目1- 阅读程序】阅读下列程序,写出程序的运行结果。上机时运行程序,与你的预期进行对照、理解。如果对运行结果和其背后的原理仍不理解,请通过单步执行的手段跟踪理解。
(1)阅读下面两个有静态局部变量的程序,阅读中画出其中各变量的变化过程,以掌握静态变量的存储特征,对照实际运行结果检验学习成果。必要时记得看书及课件。

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. #include <iostream>  
  2. using namespace std;  
  3. int f(int n);  
  4. int main()  
  5. {  
  6.     cout<<f(5)<<"  ";  
  7.     cout<<f(8)<<endl;  
  8.     return 0;  
  9. }  
  10. int f(int n)  
  11. {  
  12.     static int a=2;  
  13.     int b=0;  
  14.     a+=n;  
  15.     b+=a;  
  16.     return b;  
  17. }  
预计运行结果是:__________________
实际运行结果是:__________________


[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. #include <iostream>  
  2. using namespace std;  
  3. int func (int a,  int b)  
  4. {  
  5.     static int m=0, i=2;  
  6.     i+=m+1;  
  7.     m=i+a+b;  
  8.     return m;  
  9. }  
  10. int main()  
  11. {  
  12.     int k=4, m=1, p;  
  13.     p=func(k, m);  
  14.     cout<<p<<endl;  
  15.     p=func(k, m);  
  16.     cout<<p<<endl;  
  17.     return 0;  
  18. }  
预计运行结果是:__________________
实际运行结果是:__________________


  (2)阅读下面两个有全局变量的程序,阅读中画出其中各变量的变化过程,以掌握全变量的存储特征,对照实际运行结果检验学习成果。必要时记得看书及课件。
[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. #include <iostream>  
  2. using namespace std;  
  3. int  a=3, b=5;  
  4. int max(int a, int b)  
  5. {  
  6.     int c;  
  7.     c=a>b? a:b;  
  8.     return  c;  
  9. }  
  10. int main()  
  11. {  
  12.     int a=8; //若无这一句,又将如何?  
  13.     cout<<max(a,b)<<endl;  
  14.     return 0;  
  15. }  
预计运行结果是:__________________
实际运行结果是:__________________

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. #include <iostream>  
  2. using namespace std;  
  3. void cude();  
  4. int main()  
  5. {  
  6.     extern int x;//去掉extern及本行全删除会怎样?  
  7.     x=5; //去掉这一句呢?  
  8.     cude();  
  9.     cout<<x<<endl;  
  10.     return 0;  
  11. }  
  12. int x=10;  
  13. void cude()  
  14. {  
  15.     x=x*x*x;  
  16. }  
预计运行结果是:__________________
实际运行结果是:__________________

(3)阅读下面两个包含有递归函数的程序,要求按课堂演示,画出调用过程,并列出运行结果。对照实际运行结果检验学习成果。必要时记得看书及课件。
[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. #include <iostream>  
  2. using namespace std;  
  3. void f(int);  
  4. int main()  
  5. {  
  6.     int i=1234;  
  7.     f(i);  
  8.     return 0;  
  9. }  
  10. void f(int n)  
  11. {  
  12.     if(n==0)  
  13.         return;  
  14.     else  
  15.     {  
  16.         f(n/10);  
  17.         cout<<n%10;  
  18.         return;  
  19.     }  
  20. }  
预计运行结果是:__________________
实际运行结果是:__________________
[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. #include <iostream>  
  2. using namespace std;  
  3. int sub(int);  
  4. int main()  
  5. {  
  6.    int i=5;  
  7.    cout<<sub(i)<<endl;  
  8. }  
  9. int sub(int n)  
  10. {  
  11.    int a;  
  12.    if (n==1)  
  13.        return 1;  
  14.    a=n+sub(n-1);  
  15.    return a;  
  16. }  
预计运行结果是:__________________
实际运行结果是:__________________ 
 
(4)理解函数的默认参数:运行程序,利用调试功能,观察变量和函数参数的值,结合课堂讲解,品味默认参数的作用。
[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. #include <iostream>  
  2. using namespace std;  
  3. const double pi=3.1415926;  
  4. float area(float r=6.5);//指定r的默认值为6.5  
  5. float volume(float h,float r=6.5); //指定r的默认值为6.5  
  6. int main( )  
  7. {  
  8.     cout<<area()<<endl; //相当于area(6.5);  
  9.     cout<<area(7.5)<<endl; //形参得到的值为7.5,而不是6.5  
  10.     cout<<volume(45.6)<<endl; //相当于volume(45.6,6.5)  
  11.     cout<<volume(34.2,10.4)<<endl; //h的值为34.2,r的值为10.4  
  12.     return 0;  
  13. }  
  14. float area(float r)  
  15. {  
  16.     return pi*r*r;  
  17. }  
  18. float volume(float h,float r)  
  19. {  
  20.     return pi*r*r*h;  
  21. }  
① 去掉第4行的“=6.5”试试,出错的原因是____________________;
② 将第14行改为“float area(float r=6.5)”,出错的原因是__________________;
③ 将第5行“float h,float r=6.5”改为“float h=1,float r”,出错的原因是_____________;
④ 将第5行改为“float volume(float h=0,float r=6.5)”,带来的改变将是____________________。

(5)理解函数模板:运行程序,结合课堂讲解,品味函数模板的意义。利用codeBlocks中的Debug功能,Step Into到函数内部,观察每次调用时函数的参数值,体会类型参数T每次调用时被不同实际类型替代。
[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. #include <iostream>  
  2. using namespace std;  
  3. template<typename T>        //模板声明,其中T为类型参数  
  4. T max(T a,T b,T c)          //定义一个通用函数,用T作虚拟的类型名  
  5. {  
  6.     if(b>a) a=b;  
  7.     if(c>a) a=c;  
  8.     return a;  
  9. }  
  10. int main( )  
  11. {  
  12.     int i1=185,i2=-76,i3=567;  
  13.     double d1=56.87,d2=90.23,d3=-3214.78;  
  14.     long g1=67854,g2=-912456,g3=673456;  
  15.     cout<<"i_max="<<max(i1,i2,i3)<<endl; //调用模板函数,此时T被int取代  
  16.     cout<<"f_max="<<max(d1,d2,d3)<<endl; //调用模板函数,此时T被double取代  
  17.     cout<<"g_max="<<max(g1,g2,g3)<<endl; //调用模板函数,此时T被long取代  
  18.     cout<<"c_max="<<max('1','a','A')<<endl; //调用模板函数,此时T被long取代  
  19.     return 0;  
  20. }  

提示1:在单步执行中,采用step into后,可以将T像待观察的变量一样,放在watch窗口中进行察看,如图所示,可以发现T取不同的类型。


提示2:若这个程序编译时出错,原因是命名空间std中已经定义过了max,从而产生了冲突。修改的方法有两种:(1)将程序中的max函数名改为mymax,避免这种冲突;或者(2)取消using namespace std;一行,但需要在程序中,将cout、cin、endl前加上std::,如std::cout<<...<<....<<std::endl;


【项目2-OJ平台题目中多种输入形式的处理】
看教学视频或“OJ平台题目中不同形式输入的处理”,完成平台中的一组题目,分别对应不同输入的形式的问题。

A: N组数的最大公约数

Description

计算一组数的最大公约数

Input

第一行是数据的组数N,从第二行是N组由两个整数(ab)构成的输入,ab之间用空格隔开,每组输入单独占一行

Output

每组的两个整数(ab)的最大 公约数,每个结果独占一行

Sample Input

3

98 72

80 36

12 144

Sample Output

2

4

12

  

B:分离正整数中的各位数

Description

输出正整数的各位数

Input

若干个用空格隔开的正整数(输入个数不确定,键盘输入时,以CTRL-Z结束)

Output

每个正整数的各位数字,个位数在前,十位数紧随,最高位在最后,每位数后面有一个空格。每个正整数对应的输出占一行。

Sample Input

123 9523 89

Sample Output

3 2 1 

3 2 5 9 

9 8

 

C:刑警的射击成绩

Description

刑警培训结束,进行了射击科检验。教官要对学员射击的成绩进行分析,得出各分数段人数统计。

Input

输入若干个0-10间的整数(最高10环,脱靶为0)表示成绩,人数不确定,输入以一个0-10以外的数作为。

Output

各分数段(A:9环以上,B:7环以上,C:5环以上,D:不足5环)的人数,每项成绩占一行

Sample Input

9 7 3 5 8 5 6 7 9 10 0 6 99

Sample Output

A:3

B:3

C:4

D:2


【项目3-用递归方法求解】
(1)编写递归函数求出n的阶乘(自定义main函数,调用定义的递归函数)
(2)写出求1*3*...*n的递归式,并编写出递归函数求解。
(3)编程序,用递归函数求出两个数的最大公约数。(包括编main函数,调用定义的递归函数)
(4)编制递归函数fib(int n)返回第n个Fibnacci数,以此输出Fibnacci序列的第20个数。
[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. #include <iostream>  
  2. using namespace std;  
  3. int fib(int n);  
  4. int main(){  
  5.    cout<<fib(20)<<endl; //输出  
  6.    return 0;        
  7. }  
  8. //返回Fibnacci序列中的第n个数  
  9. int fib(int n)  
  10. { }  
(5)输入一个整数n,要求输出对应的二进制形式,请用递归函数实现。
[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. #include <iostream>  
  2. using namespace std;  
  3. int main()  
  4. {   
  5.     int n;  
  6.     cout<<"请输入一个整数:";  
  7.     cin>>n;  
  8.     cout<<n<<"对应的二进制形式为:";  
  9.     dec2bin(n);  //输出n对应的二进制串  
  10.     cout<<endl;  
  11.     return 0;        
  12. }  
  13. void dec2bin(int n)  
  14. { }  
提示:二进制整数n转换为二进制的方法是“除2取余法”,即将n除以2后得到的余数,由后到前“串”起来,得到对应的二进制数,如图。


(6)汉诺塔
汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。古代有一个梵塔,塔内有三个座A、B、C,A座上有64个盘子,盘子大小不等,大的在下,小的在上。有一个和尚想把这64个盘子从A座移到C座,但每次只能允许移动一个盘子,并且在移动过程中,3个座上的盘子始终保持大盘在下,小盘在上。在移动过程中可以利用B座,下面左图给出了移动方法的提示。请编制递归函数输出盘子数为4时(程序调试后,试试15个、20个,直至64个,看看会如何),移动的方案。图为盘子数为3时的输出供参考。

参考代码如下:
[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. int main()  
  2. {   
  3.     move(4,'A','B','C');  
  4.     return 0;  
  5. }  
  6. //有n个盘子,  
  7. void move(int n, char A, char B,char C)  
  8. {  
  9. }  

【项目4 - 银行系统】
这是我们要做的一个真正的项目!涉及到的技术都用过了,只不过,程序真的要长得多了。
  在学习中,总是想要些成就感的。当你没有做过一些事情的时候,总是不能知道所学知识究竟能干些什么。在学习过程中,完成一个像样的项目,那是一件很酷的事情,也让我们更有激情。做好思想准备,中间可能会有些困难,但相信沉下心来还是可以完成的。
  要做项目的需求最好能和大家的生活实践联系起来,我们想得到。另外,还能和我们的课程同步上。两厢结合,我们就开个银行,做个自动取款机吧。
  如果没有用过自动取款机,先用你的银行卡取一次钱去吧,权当作调研。
  我们首先插卡,输密码。做纯软件模拟,我们没有读卡机,好吧,认为卡已经插好了。
  为了让大家一点一点地做出来,我试图分解其中的工作,我们逐渐完善,“增量式”地完成工作。你可以每做完一个任务,就发一篇博文,将这样一个成长的阶段记录下来。
任务1——搭一个框架
  你的程序运行后的界面如图:
  
  • 用const定义全局的常变量PASSWORD,作为银行卡的密码(真银行卡的密码可不是这样,它要分别记住各个帐户的密码,我们现在认为所有卡都这个密码)。
  • 判断输入的密码是否正确,如果不正确,提示:“你这个笨脑瓜!”并退出程序,(注意,真银行可不敢骂人,你的银行这样写写无妨。)否则,继续下面的工作。
  • 用户如图输入功能选择,根据给出的答复,用switch多分支完成下面的显示:
    • a. 输入1,显示“您的余额是xxxx.xx元。”(想过瘾,用你觉得足够大的数当余额)
    • b. 输入2-4的提示自编;
    • c. 输入0,显示“谢谢,欢迎下次再来!”(好有礼貌)
    • d. 输入不是0-4,提示“输错,不要急!”
  只要输入不是0,循环处理业务。
  写完程序后,请将之发布为博文(程序中的注释自己加,程序前要有,中间也来些必要的)。


任务2——引入函数改善程序结构
  1、数据
  仍然只支持一位用户,所以用户帐号不必存储。
  要用全局变量存储:(1)用户密码(由于支持改密码功能,所以用变量,暂先用整型,声明时赋初值);(2)帐户余额(用浮点数表示,声明时赋初值)
  2、在输入密码环节,实现有限次密码输入的限制,如果三次都没有输入正确,程序将直接退出,不允许用户继续操作。
查验密码功能做成一个函数。例如:

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. bool pass()  
  2. {  
  3.   int 次数=0;  
  4.   bool 是否密码正确=false;   //先假设密码不正确,以便能进入do-while循环  
  5.   do{  
  6.     输入密码;  
  7.     次数++;  
  8.     if(相符)是否密码正确=true;  
  9.   }while(密码不正确且尝试次数不足3次);  
  10.   return 是否密码正确;  //上面密码正确为true,反之……  
  11. }  
  3、main()函数的结构将如下所示,work函数用于处理业务。
[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. main()  
  2. {  
  3.   ……  
  4.     if(pass())  
  5.         work();  
  6.     else  
  7.         输出“请到柜台办理密码查询后再来”。  
  8.     return 0;  
  9. }      
  4、办理业务的函数work的结构如下:
[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. void work()  
  2. {  
  3.   //循环显示功能菜单:1.查询、2.取款、3.存款、4.转帐、5.改密、0.退出  
  4.   //选择后办理各种业务,再显示菜单,直到选择了0。  
  5.    
  6. }  
  其中,各项业务分别编制一个函数完成。提示功能菜单(1.查询、2.取款、3.存款、4.转帐、5.改密、0.退出)后,由用户输入功能选择,用switch多分支完成对应的功能(有的功能依然只输出一句话提示即可)。图示给出建议(鼓励在合理范围内别出心裁):

  • 输入1(查询),调用函数showbalance(),显示“您的余额是xxxx.xx元。”
  • 输入2(取款),调用drawmoney(),完成取款。要求输入取款金额,若余额不够,提示不能取款,否则,帐户余额减少。取款后给出提示:“你的余额还有XXX.XX元”。
    在实际业务中,还涉及到计算的问题。本题暂不考虑,作为拓展建议,可以在此处考虑计息。
  • 输入3(存款):调用deposit(),完成存款,余额增加(过瘾吧,想存多少存多少)。存款后给出提示:“你的余额是XXX.XX元”。
  • 输入4(转帐):调用transferAccounts(),完成转帐,只支持转出功能。要求输入对方帐号和转帐金额,若金额充足,完成转帐,当前帐户的余额减少,对方帐户余额增加。由于本题只有一个帐号,故对方帐户增加的操作先不做了。
  • 输入5(改密):调用updatePassword()改变密码。要求先输入旧密码,对了以后才能改密。新密码要输入两次,只有两次完全相同时才可以完成修改。
  • 输入0,显示“谢谢,欢迎下次再来!”退出循环,返回调用函数。
  • 输入不是0-5,提示“输错了,不要急!”
  以后我们再做支持多个帐户的银行系统。


任务3——将程序用多文件组织
  将任务2中的代码,涉及密码、帐户的函数放在一个文件中,完成各项功能的函数放在另一个文件中,main函放也单独一个文件。


0 0
原创粉丝点击