资源描述
单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,*,*,第,7,章 用函数实现模块化程序设计,7.1,为什么要用函数,7.2,怎样定义函数,7.3,调用函数,7.4,对被调用函数的声明和函数原型,7.5,函数的嵌套调用,7.6,函数的递归调用,7.7,数组作为函数参数,7.8,局部变量和全局变量,7.9,变量的存储方式和生存期,7.10,关于变量的声明和定义,7.11,内部函数和外部函数,7.1,为什么要用函数,问题:,如果程序的功能比较多,规模比较大,把所有代码都写在,main,函数中,就会使主函数变得庞杂、头绪不清,阅读和维护变得困难,有时程序中要多次实现某一功能,就需要多次重复编写实现此功能的程序代码,,,这使程序冗长,不精炼,7.1,为什么要用函数,解决的方法:用,模块化程序设计的思路,采用“组装”的办法简化程序设计的过程,事先编好一批实现各种不同功能的函数,把它们保存在函数库中,,,需要时,直接用,7.1,为什么要用函数,解决的方法:用,模块化程序设计的思路,函数就是功能,每一个函数用来实现一个特定的功能,函数的名字应反映其代表的功能,7.1,为什么要用函数,在设计一个较大的程序时,往往把它分为若干个程序模块,每一个模块包括一个或多个函数,每个函数实现一个特定的功能,程序可由一个主函数和若干个其他函数构成,主函数调用其他函数,其他函数也可以互相调用,同一个函数可以被一个或多个函数调用任意多次,7.1,为什么要用函数,main,a,b,c,f,g,h,d,e,i,e,7.1,为什么要用函数,可以使用库函数,可以使用自己编写的函数,在程序设计中要善于利用函数,可以减少重复编写程序段的工作量,同时可以方便地实现模块化的程序设计,7.1,为什么要用函数,例,7.1,输出以下的结果,用函数调用实现。,*,How do you do!,*,7.1,为什么要用函数,解题思路:,在输出的文字上下分别有一行“,*,”号,显然不必重复写这段代码,用一个函数,print_star,来实现输出一行“,*,”号的功能。,再写一个,print_message,函数来输出中间一行文字信息,用主函数分别调用这两个函数,#include,int,main(),void,print_star,();,void,print_message,();,print_star,();,print_message,();,print_star,();,return 0;,void,print_star,(),printf,(“*n”);,void,print_message,(),printf,(“How do you do!n”);,输出,16,个,*,输出一行文字,#include,int,main(),void,print_star,();,void,print_message,();,print_star,();,print_message,();,print_star,();,return 0;,void,print_star,(),printf,(“*n”);,void,print_message,(),printf,(“How do you do!n”);,声明函数,定义函数,#include,int,main(),void,print_star,();,void,print_message,();,print_star,();,print_message,();,print_star,();,return 0;,void,print_star,(),printf,(“*n”);,void,print_message,(),printf,(“How do you do!n”);,说明:,(1),一个程序由一个或多个程序模块组成,每一个程序模块作为一个源程序文件。对较大的程序,一般不希望把所有内容全放在一个文件中,而是将它们分别放在若干个源文件中,由若干个源程序文件组成一个,C,程序。这样便于分别编写、分别编译,提高调试效率。一个源程序文件可以为多个,C,程序共用。,(2),一个源程序文件由一个或多个函数以及其他有,关内容(如预处理指令、数据声明与定义等)组,成。一个源程序文件是一个编译单位,在程序编译,时是以源程序文件为单位进行编译的,而不是以函,数为单位进行编译的。,说明:,(3),程序的执行是从,main,函数开始的,如果在,main,函数中调用其他函数,在调用后流程返回到,main,函数,在,main,函数中结束整个程序的运行。,(4),所有函数都是平行的,即在定义函数时是分别进,行的,是互相独立的。一个函数并不从属于另一,个函数,即函数不能嵌套定义。函数间可以互相,调用,但不能调用,main,函数。,main,函数是被操作,系统调用的。,说明:,(5),从用户使用的角度看,函数有两种。,库函数,它是由系统提供的,用户不必自己定义而直接使用它们。应该说明,不同的,C,语言编译系统提供的库函数的数量和功能会有一些不同,当然许多基本的函数是共同的。,用户自己定义的函数。它是用以解决用户专门需要的函数。,说明:,(6),从函数的形式看,函数分两类。,无参函数。无参函数一般用来执行指定的一组操作。无参函数可以带回或不带回函数值,但一般以不带回函数值的居多。,有参函数。在调用函数时,主调函数在调用被调用函数时,通过参数向被调用函数传递数据,一般情况下,执行被调用函数时会得到一个函数值,供主调函数使用。,7.2,怎样定义函数,7.2.1,为什么要定义函数,7.2.2,定义函数的方法,7.2.1,为什么要定义函数,C,语言要求,在程序中用到的所有函数,必须“,先定义,后使用,”,指定,函数,名字,、函数,返回值类型,、函数实现的,功能,以及,参数的个数与类型,,将这些信息通知编译系统。,7.2.1,为什么要定义函数,指定函数的名字,以便以后按名调用,指定函数类型,即函数返回值的类型,指定函数参数的名字和类型,以便在调用函数时向它们传递数据,指定函数的功能。这是最重要的,这是在函数体中解决的,7.2.1,为什么要定义函数,对于,库函数,程序设计者只需用,#include,指令把有关的头文件包含到本文件模块中即可,程序设计者需要在程序中自己定义想用的而库函数并没有提供的函数,7.2.2,定义函数的方法,1.,定义无参函数,定义无参函数的一般形式为,:,类型名,函数名,(,void),函数体,类型名,函数名,(),函数体,包括声明部分和语句部分,包括声明部分和语句部分,7.2.2,定义函数的方法,1.,定义无参函数,定义无参函数的一般形式为,:,类型名,函数名,(,void),函数体,类型名,函数名,(),函数体,指定函数值的类型,指定函数值的类型,7.2.2,定义函数的方法,2.,定义有参函数,定义有参函数的一般形式为,:,类型名 函数名(形式参数表列),函数体,7.2.2,定义函数的方法,3.,定义空函数,定义,空,函数的一般形式为,:,类型名 函数名(,),先用空函数占一个位置,以后,逐步,扩充,好处:,程序结构清楚,可读性好,以后扩充新功能方便,对程序结构影响不大,7.3,调用函数,7.3.1,函数调用的形式,7.3.2,函数调用时的数据传递,7.3.3,函数调用的过程,7.3.4,函数的返回值,7.3.1,函数调用的形式,函数调用的一般形式为:,函数名(实参表列),如果是调用无参函数,则“实参表列”可以没有,但括号不能省略,如果实参表列包含多个实参,则各参数间用逗号隔开,7.3.1,函数调用的形式,按函数调用在程序中出现的形式和位置来分,可以有以下,3,种函数调用方式,:,.,函数调用语句,把函数调用单独作为一个语句,如,printf_star,(),;,这时不要求函数带回值,只要求函数完成一定的操作,7.3.1,函数调用的形式,按函数调用在程序中出现的形式和位置来分,可以有以下,3,种函数调用方式,:,.,函数表达式,函数调用出现在另一个表达式中,如,c=,max(a,b,);,这时要求函数带回一个确定的值以参加表达式的运算,7.3.1,函数调用的形式,按函数调用在程序中出现的形式和位置来分,可以有以下,3,种函数调用方式,:,.,函数参数,函数调用作为另一函数调用时的实参,如,m,max(a,max(b,c,);,其中,max(b,c,),是一次函数调用,它的值作为,max,另一次调用的实参,7.3.2,函数调用时的数据传递,1.,形式参数和实际参数,在调用有参函数时,主调函数和被调用函数之间有数据传递关系,定义函数时函数名后面的变量名称为“形式参数”(简称“形参”),主调函数中调用一个函数时,函数名后面参数称为“实际参数”(简称“实参”),实际参数可以是常量、变量或表达式,7.3.2,函数调用时的数据传递,2.,实参和形参间的数据传递,在调用函数过程中,系统会把实参的值传递给被调用函数的形参,或者说,形参从实参得到一个值,该值在函数调用期间有效,可以参加,被调,函数中的运算,7.3.2,函数调用时的数据传递,例,7.2,输入两个整数,要求输出其中值较大者。要求用函数来找到大数。,解题思路:,(1),函数名应是见名知意,今定名为,max,(2),由于给定的两个数是整数,返回主调函数的值,(即较大数),应该是整型,(3)max,函数应当有两个参数,以便从主函数接收两个整数,,因此,参数的类型应当是整型,7.3.2,函数调用时的数据传递,先编写,max,函数:,int,max(int,x,int,y),int,z;,z=x,y?x:y,;,return(z,);,7.3.2,函数调用时的数据传递,在,max,函数上面,,,再编写主函数,#include,int,main(),int,max(int,x,int,y);,int,a,b,c,;,printf(“two,integer numbers:);,scanf(“%d,%d”,&a,&b,);,c=,max(a,b,),;,printf(“max,is%,dn”,c,);,实参可以是常量、变量或表达式,7.3.2,函数调用时的数据传递,c=,max(a,b,);,(,main,函数),int,max(int,x,int,y),(,max,函数),int,z;,z=x,y?x:y,;,return(z,);,7.3.3,函数调用的过程,在定义函数中指定的形参,在未出现函数调用时,它们并不占内存中的存储单元。在发生函数调用时,函数,max,的形参被临时分配内存单元。,2,a,3,b,x,y,2,3,实参,形参,7.3.3,函数调用的过程,调用结束,形参单元被释放,实参单元仍保留并维持原值,没有改变,如果在执行一个被调用函数时,形参的值发生改变,不会改变主调函数的实参的值,2,a,3,b,x,y,2,3,实参,形参,7.3.4.,函数的返回值,通常,希望通过函数调用使主调函数能得到一个确定的值,这就是函数值,(,函数的返回值,),函数的返回值是通过函数中的,return,语句获得的。,一个函数中可以有一个以上的,return,语句,执行到哪一个,return,语句,哪一个,就,起作用,return,语句后面的括号可以不要,7.3.4.,函数的返回值,通常,希望通过函数调用使主调函数能得到一个确定的值,这就是函数值,(,函数的返回值,),(2),函数值的类型。应当在定义函数时指定函数值的类型,7.3.4.,函数的返回值,通常,希望通过函数调用使主调函数能得到一个确定的值,这就是函数值,(,函数的返回值,),(3),在定义函数时指定的函数类型一般应该和,return,语句中的表达式类型一致,如果函数值的类型和,return,语句中表达式的值不一致,则以函数类型为准,7.3.4.,函数的返回值,例,7.3,将例,7.2,稍作改动,将在,max,函数中定义的变量,z,改为,float,型。函数返回值的类型与指定的函数类型不同,分析其处理方法。,解题思路:如果函数返回值的类型与指定的函数类型不同,按照赋值规则处理。,#include,int,main(),int,max(float,x,float,y);,float,a,b,;,int,c;,scanf(%f,%f,&a,&b,);,c=,max(a,b,);,printf(max,is%,dn,c,);,return 0;,int,max(float,x,float,y),float z;,z=x,y?x:y,;,return(z);,1.5,2.6,2.6,2,变为,2,7.4,对被调用函数的声明和函数原型,在一个函数中调用另一个函数需要具备如下条件:,(1),被调用函数必须是已经定义的函数(是库函数或用户自己定义的函数),;,(2),如果使用库函数,应该在本文件开头,加相应的,#include,指令,;,(3),如果使用自己定义的函数,而该函数的位置在调用它的函数后面,应该声明,。声明的作用是把函数名、函数参数的个数和参数类型等信息通知编译系统,以在函数调用时编译系统能正确识别函数并检查调用是否合法。,7.4,对被调用函数的声明和函数原型,例,7.4,输入两个实数,用一个函数求出它们之和。,解题思路:用,add,函数实现。首先要定义,add,函数,它为,float,型,它应有两个参数,也应为,float,型。特别要注意的是:要对,add,函数进行声明。,7.4,对被调用函数的声明和函数原型,分别编写,add,函数和,main,函数,它们组成一个源程序文件,main,函数的位置在,add,函数之前,在,main,函数中对,add,函数进行声明,#include,int,main(),float,add(float,x,float y);,float,a,b,c,;,printf(Please,enter a and b:);,scanf(%f,%f,&a,&b,);,c=,add(a,b,);,printf(sum,is%,fn,c,);,return 0;,float,add(float,x,float,y),float z;,z=,x+y,;,return(z,);,求两个实数之和,函数值也是实型,对,add,函数声明,#include,int,main(),float,add(float,x,float y);,float,a,b,c,;,printf(Please,enter a and b:);,scanf(%f,%f,&a,&b,);,c=,add(a,b,);,printf(sum,is%,fn,c,);,return 0;,float,add(float,x,float,y),float z;,z=,x+y,;,return(z,);,只差一个分号,#include,int,main(),float,add(float,x,float y);,float,a,b,c,;,printf(Please,enter a and b:);,scanf(%f,%f,&a,&b,);,c=,add(a,b,);,printf(sum,is%,fn,c,);,return 0;,float,add(float,x,float,y),float z;,z=,x+y,;,return(z,);,定义,add,函数,调用,add,函数,函数,原型,一般形式有两种,:,如,float,add(float,x,float y),;,float,add(float,float),;,原型说明可以放在文件的开头,这时所有函数都可以使用此函数,#include,#define N 3,int,arrayNN,;,int,main(),void,convert(int,array3);,int,i,j,;,printf(input,array:n);,for(i=0;i,N;i,+),for(j=0;j,N;j,+),scanf(%d,&arrayij,);,printf(noriginal,array:n);,for(i=0;i,N;i,+),for(j=0;j,N;j,+),printf(%5d,arrayij);,printf(n,);,convert(array,);,printf(convert,array:n);,for(i=0;i,N;i,+),for(j=0;j,N;j,+),printf(%5d,arrayij);,printf(n,);,return 0;,void,convert(int,array3),int,i,j,t,;,for(i=0;i,N;i,+),for(j=i+1;j,N;j,+),t=,arrayij,;,arrayij,=,arrayji,;,arrayji,=t;,#include,int,main(),int,hcf(int,int,);,int,lcd(int,int,int,);,int,u,v,h,l,;,scanf(%d,%d,&u,&v,);,h=,hcf(u,v,);,printf(H.C.F,=%,dn,h,);,l=,lcd(u,v,h,);,printf(L.C.D,=%,dn,l,);,return 0;,int,hcf(int,u,int,v),int,t,r,;,if(vu),t=,u;u,=,v;v,=t;,while(r=,u%v,)!=0),u=v;,v=r;,return(v,);,int,lcd(int,u,int,v,int,h),return(u,*,v/h,);,#include,int,Hcf,Lcd,;,int,main(),void,hcf(int,int,);,void,lcd(int,int,);,int,u,v,;,scanf(%d,%d,&u,&v,);,hcf(u,v,);,lcd(u,v,);,printf(H.C.F,=%,dn,Hcf,);,printf(L.C.D,=%,dn,Lcd,);,return 0;,void,hcf(int,u,int,v),int,t,r,;,if(vu),t=,u;u,=,v;v,=t;,while(r=,u%v,)!=0),u=v;,v=r;,Hcf,=v;,void,lcd(int,u,int,v),Lcd,=u*,v/Hcf,;,7.5,函数的嵌套调用,语言的函数定义是互相平行、独立的,即,函数不能嵌套定义,但可以嵌套调用函数,即,调用一个函数的过程中,又,可以,调用另一个函数,7.5,函数的嵌套调用,所有函数都是平行的,即在定义函数时是分别进行的,是互相独立的。一个函数并不从属于另一个函数,即函数不能嵌套定义。,但可以嵌套调用,函数,,即在调用一个函数的过程中,又调用另一个函数。,7.5,函数的嵌套调用,main,函数,调用,a,函数,结束,a,函数,调用,b,函数,b,函数,7.5,函数的嵌套调用,例,7.5,输入,4,个整数,找出其中最大的数。用函数的嵌套调用来处理。,解题思路:,main,中调用,max4,函数,找,4,个数中最大者,max4,中再调用,max2,,,找两个数中的大者,max4,中多次调用,max2,,可找,4,个数中的大者,然后把它作为函数值返回,main,函数,main,函数中输出结果,#include,int,main(),int,max4(int,a,int,b,int,c,int,d);,int,a,b,c,d,max,;,printf(“4,interger,numbers:);,scanf(%d%d%d%d,&a,&b,&c,&d,);,max=,max4,(a,b,c,d);,printf(max,=%d,n,max,);,return 0;,主函数,对,max4,函数声明,#include,int,main(),int,max4(int,a,int,b,int,c,int,d);,int,a,b,c,d,max,;,printf(“4,interger,numbers:);,scanf(%d%d%d%d,&a,&b,&c,&d,);,max=,max4,(a,b,c,d);,printf(max,=%d,n,max,);,return 0;,主函数,输入,4,个整数,#include,int,main(),int,max4(int,a,int,b,int,c,int,d);,int,a,b,c,d,max,;,printf(“4,interger,numbers:);,scanf(%d%d%d%d,&a,&b,&c,&d,);,max=,max4,(a,b,c,d);,printf(max,=%d,n,max,);,return 0;,主函数,调用后肯定是,4,个数中最大者,输出最大者,int,max4(int,a,int,b,int,c,int,d),int,max2(int,a,int,b);,int,m;,m=,max2,(a,b);,m=,max2,(m,c);,m=,max2,(m,d);,return(m,);,max4,函数,对,max2,函数声明,int,max4(int,a,int,b,int,c,int,d),int,max2(int,a,int,b);,int,m;,m=,max2,(a,b);,m=,max2,(m,c);,m=,max2,(m,d);,return(m,);,max4,函数,a,b,中较大者,a,b,c,中较大者,a,b,c,d,中最大者,int,max4(int,a,int,b,int,c,int,d),int,max2(int,a,int,b);,int,m;,m=,max2,(a,b);,m=,max2,(m,c);,m=,max2,(m,d);,return(m,);,max4,函数,int,max2(int,a,int,b),if(a,=b),return a;,else,return b;,max2,函数,找,a,b,中较大者,int,max4(int,a,int,b,int,c,int,d),int,max2(int,a,int,b);,int,m;,m=,max2,(a,b);,m=,max2,(m,c);,m=,max2,(m,d);,return(m,);,max4,函数,int,max2(int,a,int,b),if(a,=b),return a;,else,return b;,max2,函数,return(a,b?a:b,);,int,max4(int,a,int,b,int,c,int,d),int,max2(int,a,int,b);,int,m;,m=,max2,(a,b);,m=,max2,(m,c);,m=,max2,(m,d);,return(m,);,max4,函数,int,max2(int,a,int,b),return(a,b?a:b,);,int,max4(int,a,int,b,int,c,int,d),int,max2(int,a,int,b);,int,m;,m=,max2,(a,b);,m=,max2,(m,c);,m=,max2,(m,d);,return(m,);,max4,函数,m=max2(max2(a,b),c);,int,max2(int,a,int,b),return(a,b?a:b,);,int,max4(int,a,int,b,int,c,int,d),int,max2(int,a,int,b);,int,m;,m=,max2,(a,b);,m=,max2,(m,c);,m=,max2,(m,d);,return(m,);,max4,函数,m=max2(max2(max2(a,b),c),d);,int,max2(int,a,int,b),return(a,b?a:b,);,int,max4(int,a,int,b,int,c,int,d),int,max2(int,a,int,b);,int,m;,m=,max2,(a,b);,m=,max2,(m,c);,m=,max2,(m,d);,return(m,);,max4,函数,return max2(max2(max2(a,b),c),d);,int,max2(int,a,int,b),return(a,b?a:b,);,int,max4(int,a,int,b,int,c,int,d),int,max2(int,a,int,b);,return max2(max2(max2(a,b),c),d);,int,max2(int,a,int,b),return(a,b?a:b,);,#include,int,main(),max=max4(a,b,c,d);,7.6,函数的递归调用,在调用一个函数的过程中又出现直接或间接地调用该函数本身,称为函数的,递归调用,。,语言的特点之一就在于允许函数的递归调用。,f2,函数,调用,f1,函数,7.6,函数的递归调用,int,f(int,x),int,y,z,;,z=,f(y,);,return(2*z);,f,函数,调用,f,函数,f1,函数,调用,f2,函数,应使用,if,语句控制结束调用,直接调用本函数,间接调用本函数,7.6,函数的递归调用,例,7.6,有,5,个学生坐在一起,问第,5,个学生多少岁?他说比第,4,个学生大,2,岁,问第,4,个学生岁数,他说比第,3,个学生大,2,岁,问第,3,个学生,又说比第,2,个学生大,2,岁,问第,2,个学生,说比第,1,个学生大,2,岁,最后问第,1,个学生,他说是,10,岁,请问第,5,个学生多大,7.6,函数的递归调用,解题思路:,要求第个年龄,就必须先知道第个年龄,要求第个年龄必须先知道第个年龄,第个年龄又取决于第个年龄,第个年龄取决于第个年龄,每个学生年龄都比其前个学生的年龄大,7.6,函数的递归调用,解题思路:,age(5)=age(4)+2,age(4)=age(3)+2,age(3)=age(2)+2,age(2)=age(1)+2,age(1)=10,age(5),=age(4)+2,age(4),=age(3)+2,age(3),=age(2)+2,age(2),=age(1)+2,age(1),=10,age(2),=12,age(3),=14,age(4),=16,age(5),=18,回溯阶段,递推阶段,age(5),=age(4)+2,age(4),=age(3)+2,age(3),=age(2)+2,age(2),=age(1)+2,age(1),=10,age(2),=12,age(3),=14,age(4),=16,age(5),=18,回,溯,阶段,递推阶段,结束递归的条件,#include,int,main(),int,age(int,n);,printf(NO.5,age:%dn,age,(5);,return 0;,int,age,(int,n),int,c;,if(n,=1)c=10;,else c=,age,(n-1)+2;,return(c,);,age(5),输出,age(5),main,c=age(4)+2,age,函数,n=5,c=age(3)+2,age,函数,n=4,c=age(1)+2,age,函数,n=2,c=age(2)+2,age,函数,n=3,c=10,age,函数,n=1,age(1)=10,age(2)=12,age(3)=14,age(4)=16,age(5)=18,18,例,7.7,用递归方法求!。,解题思路:,求!可以用递推方法,:,即从开始,乘,再乘一直乘到。,递推法的特点是从一个已知的事实,(,如,1!=1),出发,按一定规律推出下一个事实,(,如,2!=1!*2),,再从这个新的已知的事实出发,再向下推出一个新的事实,(3!=3*2!),。,n!=n*(n-1)!,。,例,7.7,用递归方法求!。,解题思路:,求!也可以用递归方法,即!等于!,而!,!,可用下面的递归公式表示:,#include,int,main(),int,fac(int,n);,int,n;,int,y;,printf(input,an integer number:);,scanf(%d,&n,);,y=,fac,(n,);,printf(%d,!=%,dn,n,y,);,return 0;,int,fac,(int,n),int,f;,if(n,0),printf(n,0,data error!);,else,if(n,=0|n=1),f=1;,else f=,fac,(n-1)*n;,return(f,);,注意溢出,fac(5),输出,fac(5),main,f=fac(4)5,fac,函数,n=5,f=fac(3),4,fac,函数,n=4,f=fac(1),2,fac,函数,n=2,f=fac(2),3,fac,函数,n=3,f=1,fac,函数,n=1,fac(1)=1,fac(2)=2,fac(3)=6,fac(4)=24,fac(5)=120,120,例,7.8 Hanoi,(汉诺)塔问题。古代有一个梵塔,塔内有,3,个座,A,、,B,、,C,,开始时座上有,64,个盘子,盘子大小不等,大的在下,小的在上。有一个老和尚想把这,64,个盘子从座移到座,但规定每次只允许移动一个盘,且在移动过程中在,3,个座上都始终保持大盘在下,小盘在上。在移动过程中可以利用,B,座。要求编程序输出移动盘子的步骤。,A,B,C,解题思路:,要把,64,个盘子从,A,座移动到,C,座,需要移动大约,2,64,次盘子。一般人是不可能直接确定移动盘子的每一个具体步骤的,老和尚会这样想:假如有另外一个和尚能有办法将上面,63,个盘子从一个座移到另一座。那么,问题就解决了。此时老和尚只需这样做:,解题思路:,(1),命令第,2,个和尚将,63,个盘子从,A,座移到,B,座,(2),自己将,1,个盘子(最底下的、最大的盘子)从,A,座移到,C,座,(3),再命令第,2,个和尚将,63,个盘子从,B,座移到,C,座,A,B,C,将,63,个从,A,到,B,第,1,个和尚的做法,A,B,C,将,63,个从,A,到,B,第,1,个和尚的做法,A,B,C,将,1,个从,A,到,C,第,1,个和尚的做法,A,B,C,将,1,个从,A,到,C,第,1,个和尚的做法,A,B,C,将,63,个从,B,到,C,第,1,个和尚的做法,A,B,C,将,63,个从,B,到,C,第,1,个和尚的做法,A,B,C,将,62,个从,A,到,C,第,2,个和尚的做法,A,B,C,将,62,个从,A,到,C,第,2,个和尚的做法,A,B,C,将,1,个从,A,到,B,第,2,个和尚的做法,A,B,C,将,1,个从,A,到,B,第,2,个和尚的做法,A,B,C,将,62,个从,C,到,B,第,2,个和尚的做法,A,B,C,将,62,个从,C,到,B,第,2,个和尚的做法,第,3,个和尚的做法,第,4,个和尚的做法,第,5,个和尚的做法,第,6,个和尚的做法,第,7,个和尚的做法,第,63,个和尚的做法,第,64,个和尚仅做:将,1,个从,A,移到,C,A,B,C,将,3,个盘子从,A,移到,C,的全过程,将,2,个盘子从,A,移到,B,A,B,C,将,3,个盘子从,A,移到,C,的全过程,将,2,个盘子从,A,移到,B,A,B,C,将,3,个盘子从,A,移到,C,的全过程,将,1,个盘子从,A,移到,C,A,B,C,将,3,个盘子从,A,移到,C,的全过程,将,1,个盘子从,A,移到,C,A,B,C,将,3,个盘子从,A,移到,C,的全过程,将,2,个盘子从,B,移到,C,A,B,C,将,3,个盘子从,A,移到,C,的全过程,将,2,个盘子从,B,移到,C,A,B,C,将,2,个盘子从,A,移到,B,的过程,将,1,个盘子从,A,移到,C,A,B,C,将,2,个盘子从,A,移到,B,的过程,将,1,个盘子从,A,移到,C,A,B,C,将,2,个盘子从,A,移到,B,的过程,将,1,个盘子从,A,移到,B,A,B,C,将,2,个盘子从,A,移到,B,的过程,将,1,个盘子从,A,移到,B,A,B,C,将,2,个盘子从,A,移到,B,的过程,将,1,个盘子从,C,移到,B,A,B,C,将,2,个盘子从,A,移到,B,的过程,将,1,个盘子从,C,移到,B,A,B,C,将,2,个盘子从,B,移到,C,的过程,A,B,C,将,2,个盘子从,B,移到,C,的过程,A,B,C,将,2,个盘子从,B,移到,C,的过程,A,B,C,将,2,个盘子从,B,移到,C,的过程,由上面的分析可知:将,n,个盘子从,A,座移到,C,座可以分解为以下,3,个步骤:,(1),将,A,上,n-1,个盘借助,C,座先移到,B,座上,(2),把,A,座上剩下的一个盘移到,C,座上,(3),将,n-1,个盘从,B,座借助于座移到,C,座上,可以将第,(1),步和第,(3),步表示为:,将“,one,”座上,n-1,个盘移到“,two,”座,(,借助“,three,”座,),。,在第,(1),步和第,(3),步中,,one,、,two,、,three,和,A,、,B,、,C,的对应关系不同。,对第,(1),步,对应关系是,one,对应,A,,,two,对应,B,,,three,对应,C,。,对第,(3),步,对应关系是,one,对应,B,,,two,对应,C,,,three,对应,A,。,把上面,3,个步骤分成两类操作:,(1),将,n-1,个盘从一个座移到另一个座上(,n,1,)。这就是大和尚让小和尚做的工作,它是一个递归的过程,即和尚将任务层层下放,直到第,64,个和尚为止。,(2),将,1,个盘子从一个座上移到另一座上。这是大和尚自己做的工作。,编写程序。,用,hanoi,函数实现第,1,类操作(即模拟小和尚的任务),用,move,函数实现第,2,类操作(模拟大和尚自己移盘),函数调用,hanoi(n,one,two.three,),表示将,n,个盘子从“,one,”座移到“,three,”座的过程,(,借助“,two,”座,),函数调用,move(x,y,),表示将,1,个盘子从,x,座移到,y,座的过程。,x,和,y,是代表,A,、,B,、,C,座之一,根据每次不同情况分别取,A,、,B,、,C,代入,#include,int,main(),void,hanoi(int,n,char,one,char,two,char,three);,int,m;,printf(“the,number of,diskes,:);,scanf(%d,&m,);,printf(move,%d,diskes:n,m,);,hanoi,(m,A,B,C,);,void,hanoi,(int,n,char,one,char,two,char three),void,move(char,x,char,y);,if(n,=1),move,(one,three,);,else,hanoi,(n-1,one,three,two);,move,(one,three,);,hanoi,(n-1,two,one,three);,void,move,(char,x,char,y),printf(%c,-%,cn,x,y,);,7.13,用递归方法求,n,阶勒让德多项式的值,递归公式为:,#include,int,main(),int,x,n,;,float,p(int,int,);,printf,(“input n,scanf(“%d,%d”,&n,&x,);,printf(“n,=%,d,x,=%,dn”,n,x,);,printf(“P,=%6.2fn”,p(n,x);,return 0;,float,p(int,n,int,x),if(n=0),return(1);,else if(n=1),return(x,);,else,return(2*n-1)*x-
展开阅读全文