函数的设计与应用.ppt
《函数的设计与应用.ppt》由会员分享,可在线阅读,更多相关《函数的设计与应用.ppt(98页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、第第5 5章章 函数的设计与应用函数的设计与应用5.1 5.1 5.2 5.2 5.3 5.3 5.4 5.4 5.5 5.5 函数的递归函数的递归5.6 5.6 内联函数内联函数5.7 5.7 数组参数及函数间传递数据的五种常用方式数组参数及函数间传递数据的五种常用方式(渠道渠道)5.8 5.8 标识符的作用域标识符的作用域5.9 5.9 变量与函数的存储类别变量与函数的存储类别5.10 5.10 编译预处理编译预处理1问题问题1 1,为什么要用函数,为什么要用函数2 2,使用函数的程序和顺序程序有什么,使用函数的程序和顺序程序有什么区别?区别?课本课本p116p1162 函数调用的堆栈函数
2、调用的堆栈 堆栈堆栈Main()cuberoot(x)参数传递、返回值参数传递、返回值保护现场、恢复现场保护现场、恢复现场调用调用返回返回35.5 5.5 函数的递归函数的递归5.5.1 5.5.1 使用递归求累乘积与累加和使用递归求累乘积与累加和5.5.2“5.5.2“三色冰激凌三色冰激凌”程序程序 5.5.3 5.5.3 HanoiHanoi塔问题塔问题4 C+C+允允许许函函数数自自己己调调用用自自己己(如如A A函函数数可可以以调调用用A A函函数数本本身身,称称为为直直接接递递归归)。也也允允许许A A函函数数调调用用B B函函数数,而而后后B B函函数数又又调调用用A A函函数数(
3、从从而而形形成成间间接接递递归归)。但但不不论论使使用用哪哪种种递递归归,程程序序员员都都应应保保障障递递归归函函数数在在执执行行若若干干次次后后能能够够“退退出出”递递归归(不再进行递归调用,也即能够实现递归出口不再进行递归调用,也即能够实现递归出口)。55.5.1 5.5.1 使用递归求累乘积与累加和使用递归求累乘积与累加和 1.1.求求n n的阶乘的递归函数的阶乘的递归函数prodprod -参看书p124的5.2.6小节的2使程序执行后的输出结果为使程序执行后的输出结果为:Input a positive integer:Input a positive integer:6 6p=1*
4、.*6=720p=1*.*6=720在数学中,可按如下方式对在数学中,可按如下方式对n!n!进行递归定义:进行递归定义:当当n=1n=1时,时,n!=1n!=1;当当n1n1时,时,n!=n*(n-1)!n!=n*(n-1)!这正是我们编写求这正是我们编写求n n的阶乘的递归函数的阶乘的递归函数prodprod的基础。的基础。6#include#include long long prod(intprod(int n)/n)/注意用的是注意用的是longlong,课本课本p131p131(3 3)if(n=1)if(n=1)return return 1;1;/n/n等等于于1 1时时,递递归
5、归出出口口(“(“退退出出”递递归归)else elsereturn n*return n*prod(n-1)prod(n-1);/n/n大于大于1 1时的返回值时的返回值(n!)n!)为为n n乘以乘以n-1n-1的阶乘的阶乘/(/(使用自递归调用使用自递归调用“prod(n-1)prod(n-1)”来求出来求出(n-1)!)n-1)!)7void main()void main()intint n;n;coutcoutInput a positive integer:;n;n;/输入的正整数放入输入的正整数放入n n中中 long p=prod(n);/long p=prod(n);/求出
6、求出n n的阶乘放入的阶乘放入p p中中 coutcoutp=1*.*n=pp=1*.*n=pendlendl;/输出结果输出结果p p 8 上上述述求求阶阶乘乘的的递递归归函函数数中中,当当主主函函数数通通过过prod(3)prod(3)对对 递递 归归 函函 数数 prodprod进进 行行 调调 用用 时时,它它 的的 返返 回回 值值 为为3*3*prod(2)prod(2),此此时时系系统统将将再再一一次次对对prodprod本本身身进进行行调调用用而形成递归调用。而形成递归调用。但但注注意意后后一一次次调调用用的的实实参参为为2 2,比比上上一一次次的的实实参参3“3“下下降降”了
7、了1 1。而而计计算算prod(2)prod(2)时时,它它的的返返回回值值为为2*2*prod(1)prod(1),此此时时系系统统将将再再一一次次对对prodprod本本身身进进行行递递归归调用,但此时的实参又调用,但此时的实参又“下降下降”了了1 1。9 正正是是通通过过这这种种实实参参的的逐逐次次“下下降降”,可可保保障障递递归归函函数数在在执执行行若若干干次次后后(此此时时的的求求阶阶乘乘问问题题当当“下下降降”到到1 1时时),能能够够“退退出出”递递归归(不不再再进进行行递递归归调调用,也即实现了递归出口用,也即实现了递归出口)。由由于于prod(1)prod(1)的的返返回回值
8、值为为1 1,系系统统进进一一步步算算出出2*2*prod(1)prod(1)的的值值(即即prod(2)prod(2)的的值值)为为2*1=22*1=2,再再进进一一步步算算出出3*3*prod(2)prod(2)的的值值为为3*2=63*2=6,这这正正是是prod(3)prod(3)的调用返回值的调用返回值(也即求出了也即求出了3!=3*2*1=6)3!=3*2*1=6)。10 虽虽然然上上述述执执行行过过程程是是由由系系统统自自动动完完成成的的,但但程程序序员员要要理理解解并并熟熟知知这这种种调调用用机机制制与与系系统统实实现现方方法法,从从而而才才能能编编写写出出逻逻辑辑正正确确且且
9、简简明明易易懂懂的的递递归归处处理理程程序。序。另另外外注注意意,递递归归处处理理程程序序的的执执行行速速度度通通常常要要比比非递归处理方法慢。非递归处理方法慢。问题:为什么会慢?问题:为什么会慢?11 2.2.求出求出1 1到到n n之累加和的递归函数之累加和的递归函数sumsum 使程序执行后的输出结果为使程序执行后的输出结果为:Input a positive integer:Input a positive integer:100100s=1+.+100=5050s=1+.+100=505012#include include intint sum(intsum(int n)n)/递归
10、函数递归函数sumsum if(n=1)if(n=1)/n/n等于等于1 1时,递归出口时,递归出口return 1;return 1;else else return n+return n+sum(n-1)sum(n-1);/n/n大于大于1 1时的返回值时的返回值(累加和累加和)为为n n加上加上“从从1 1累加到累加到/n-1/n-1的的和和”(”(要要使使用用递递归归调调用用求求出出前前n-1n-1个个数数的的累累加加和和)13 void main()void main()intint n;n;coutcoutInput a positive integer:;n;n;intint s
11、=sum(n);/s=sum(n);/求出从求出从1 1累加到累加到n n的和放的和放s s中中 coutcouts=1+.+n=ss=1+.+n=sendlendl;145.5.2 5.5.2“三色冰激凌三色冰激凌”程序程序 -参看书参看书p130p130的的5.4.15.4.1小节小节 由由冰冰激激凌凌商商提提出出的的问问题题:有有2828种种颜颜色色的的原原料料,可可以以组组合合成成多多少少种种3 3色色冰冰激激凌凌。问问题题归归结结为为计计算算排排列数与组合数。列数与组合数。本本示示例例计计算算排排列列数数A(elements,selections)A(elements,selecti
12、ons)及及组合数组合数C(elements,selections)C(elements,selections)。如如:A(3,2)=6,A(3,2)=6,C(3,2)=3;C(3,2)=3;A(28,3)=19656,A(28,3)=19656,C(28,3)=3276C(28,3)=3276。15 由于排列数由于排列数A(ele,selA(ele,sel)与组合数与组合数C(ele,selC(ele,sel)间有如间有如下的关系:下的关系:C(ele,selC(ele,sel)=)=A(ele,sel)/selA(ele,sel)/sel!程序中编制了一个求阶乘的递归函数程序中编制了一个求
13、阶乘的递归函数factorialfactorial,可用于求出可用于求出selsel的阶乘。的阶乘。使程序执行后的显示结果如下:使程序执行后的显示结果如下:Number of selections:Number of selections:3 3Out of how many elements:Out of how many elements:2828A(28,3)=19656A(28,3)=19656C(28,3)=3276C(28,3)=327616#include include long long factorial(intfactorial(int number);/number);
14、/函数原型函数原型void main()void main()intint i,selections,elements;i,selections,elements;/计算计算A(elements,selections)A(elements,selections)/以及以及C(elements,selections)C(elements,selections)coutcoutNumber of selections:;selections;/selections;/输入整数输入整数selectionsselectionscoutcoutOut of how many elements:;elem
15、ents;/elements;/输入整数输入整数elementselementsdouble answer=elements;double answer=elements;intint eleele=elements;=elements;17/求排列数求排列数A A:共进行共进行sel-1sel-1次乘法次乘法/A(ele,selA(ele,sel)=)=eleele*(ele-1)*.*(ele-sel+1)*(ele-1)*.*(ele-sel+1)for(i=1;iselections;i+)/for(i=1;iselections;i+)/循环循环sel-1sel-1次次 answer
16、*=-answer*=-eleele;/最终的最终的answeranswer值即为所要求的值即为所要求的A(ele,selA(ele,sel)coutcoutA(elements,selections)=;A(elements,selections)=;coutcoutansweranswerendlendl;/输出排列数输出排列数A(ele,selA(ele,sel)之结果之结果 18 /组合数组合数C C的求法:的求法:/C(ele,selC(ele,sel)=)=A(ele,sel)/selA(ele,sel)/sel!answer/=factorial(selections);answ
17、er/=factorial(selections);/对递归函数调用,求阶乘对递归函数调用,求阶乘coutcoutC(elements,selections)=;C(elements,selections)=;coutcoutansweranswerendlendl;/输出组合数输出组合数C(ele,selC(ele,sel)之结果之结果 19 long long factorial(intfactorial(int number)number)/递归函数递归函数factorialfactorial,用于算出用于算出numbernumber的阶乘的阶乘 if(number=1)if(numbe
18、r=1)return 1;/return 1;/递归出口递归出口(“退出退出”递归递归)else else return number*return number*factorial(number-1)factorial(number-1);/自递归调用自递归调用,注意实参不同注意实参不同(每次降每次降1)1)20当然也可编出非递归的用于算出当然也可编出非递归的用于算出numbernumber之阶乘的函数之阶乘的函数factorialfactoriallong long factorial(intfactorial(int number)/number)/非递归函数非递归函数 long p=1
19、;long p=1;for(for(intint i=2;i=number;i+)i=2;i pnumber=preturn p;return p;/返回的返回的p p即为即为numbernumber之阶乘之阶乘 215.5.3 Hanoi5.5.3 Hanoi塔问题塔问题 -参看书p132的5.4.2小节 古印度的著名智力测验问题:有三个立柱古印度的著名智力测验问题:有三个立柱A A、B B、C C,在在A A柱上穿有大小不等的圆盘柱上穿有大小不等的圆盘6464个,较大的圆个,较大的圆盘在下,较小者在上。要求借助于盘在下,较小者在上。要求借助于B B柱将柱将A A柱上的柱上的6464个圆盘移
20、到个圆盘移到C C柱,规则为:柱,规则为:(1)(1)每次只能把一个柱上最上面的圆盘移至另每次只能把一个柱上最上面的圆盘移至另一个柱的最上面一个柱的最上面;(2)(2)每个柱上总保持较大的圆盘在下,较小者每个柱上总保持较大的圆盘在下,较小者在上。在上。编制程序编制程序,实现将任意实现将任意n n个圆盘从个圆盘从A A柱借助于柱借助于B B柱移到柱移到C C柱柱,并显示出全部移动过程。并显示出全部移动过程。22 总任务总任务(“(“度度”为为n n的任务的任务):把把A A柱上的柱上的n n个圆盘,借助于个圆盘,借助于B B柱,按规则柱,按规则移到移到C C柱上柱上(移动规则:一次移一片,大片不
21、可移动规则:一次移一片,大片不可压小片压小片)。靠调用自定义函数靠调用自定义函数hanoihanoi来完成:来完成:hanoi(n,A,B,Chanoi(n,A,B,C););23 总任务可分解为与其等价的总任务可分解为与其等价的三个子任务三个子任务(的的“合合集集”)(“”)(“度度”小于等于小于等于n-1n-1的三个子任务的三个子任务):(1)(1)把把A A柱上最上面柱上最上面n-1n-1个圆盘个圆盘,借助于,借助于C C柱,按柱,按规则移到规则移到B B柱上柱上(一次递归调用一次递归调用);(2)(2)把把A A柱上留下的柱上留下的(最大的最大的)圆盘圆盘移到移到C C柱上柱上(一一步
22、可完成的步可完成的“本原任务本原任务”)”);(3)(3)把把B B柱上的柱上的n-1n-1个圆盘个圆盘,借助于,借助于A A柱,按规则柱,按规则移到移到C C柱上柱上(又一次递归调用又一次递归调用)。24 靠下面的三个调用语句来完成:靠下面的三个调用语句来完成:hanoi(n-1,A,C,B);hanoi(n-1,A,C,B);move(A,C);move(A,C);hanoi(n-1,B,A,C);hanoi(n-1,B,A,C);25移动次序移动次序:1 1A B C26移动次序移动次序:2 2A B C27移动次序移动次序:3 3A B C28移动次序移动次序:4 4A B C29移动
23、次序移动次序:5 5A B C30移动次序移动次序:6 6A B C31移动次序移动次序:7 7A B C32移动次序移动次序:8 8A B C33使程序执行后的显示结果如下:使程序执行后的显示结果如下:Input the number of disks:Input the number of disks:3 3The step of moving 3 disks:The step of moving 3 disks:A=CA=CA=BA=BC=BC=BA=CA=CB=AB=AB=CB=CA=CA=C34具体程序如下:具体程序如下:#include include void void hano
24、i(inthanoi(int,char,char,char);/,char,char,char);/hanoihanoi函数原型函数原型void main()void main()intint m;m;/欲移动的圆盘个数欲移动的圆盘个数m mcoutcoutInput the number of disks:;m;m;/输入圆盘个数输入圆盘个数m mcoutcoutendlendlThe step of moving m disks:;The step of moving m disks:;hanoi(m,A,B,Chanoi(m,A,B,C););/调用自定义函数调用自定义函数hanoiha
25、noi,移移m m片,从片,从A A,借助借助B B,到到C Ccoutcoutendlendl;35 void move(char from,char to)void move(char from,char to)/移移1 1片,从片,从fromfrom,到到to(“to(“本原任务本原任务”)”)coutcoutendlendlfromto;fromto;/显示显示 移步信息移步信息 36void void hanoi(inthanoi(int n,char a,char b,char c)n,char a,char b,char c)/自递归函数自递归函数hanoihanoi,移移n n
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 函数 设计 应用
限制150内