实验八 函数(二) |
u 实验目的1、掌握定义函数的方法。 2、掌握函数实参与形参的对应关系以及“值传递”的方式。 3、掌握函数的嵌套调用和递归调用的方法。 4、掌握全局变量和局部变量动态变量、静态变量的概念和使用方法。 5、学习对多文件程序的编译和运行。 u 预习内容 见教材第八章 u 实验重点 1、掌握定义函数的方法。 2、掌握函数实参与形参的对应关系以及“值传递”的方式。 u 实验难点 1、掌握函数实参与形参的对应关系以及“值传递”的方式。 2、掌握函数的嵌套调用和递归调用的方法。 u 实验内容 1、求两个整数的最大公约数和最小公倍数。用一个函数求最大公约数,用另一函数根据求出的最大公约数求最小公倍数。 A 不用全局变量,分别用两个函数求最大公约数和最小公倍数。两个整数在主函数中输入,并传送给函数1,求出的最大公约数返回主函数,然后在与两个整数一起作为实参传递给函数2,以求出最小公倍数,再返回到主函数输出最大公约数和最小公倍数。 B 用全局变量的方法,分别用两个函数求最大公约数和最小公倍数,但其值不由函数带回。将最大公约数和最小公倍数都设为全局变量,在主函数输出它们的值。 2、写一函数,输入一个十六进制数,输出相应的十进制数。 u 参考例题 【例】用铉截法求一元三次方程的根 #include <math.h> ( float y; y=((x-5.0)*x+16.0)*x-80.0; return(y);( } fioat xpoint(float x1,float x2) { float y; y=(x1*f(x2)-x2*f(x1))/(f(x2)-f(x1)); return(y); } float root(float x1,float x2) / { float x,y,y1; y1=f(x1); do {
x=xpoint(x1,x2); y=f(x); if(y*y1>0) {y1=y; x1=x;} else x2=x; }while(fabs(y)>=0.0001); retunt(x); } main() { float x1,x2,f1,f2,x; do { printf(“input x1,x2:\n”);}f scanf(“%f,%f”,&x1,&x2); f1=f(x1); f2=f(x2); }while(f1*f2>=0); x=root(x1,x2); printf(“A root of equation is%8.4f’’,x); } 【例】用递归法计算n! 用递归法计算n!可用下述公式表示: n!=1 (n=0,1) n×(n-1)! (n>1) 按公式可编程如下: long fac(int n) { long f; if(n<0) printf("n<0,input error"); else if(n==0||n==1) f=1; else f=fac(n-1)*n; return(f); } main() { int n; long y; printf("\ninput a inteager number:\n"); scanf("%d",&n); y=fac(n); printf("%d!=%ld",n,y); } 【例】Hanoi塔问题 一块板上有三根针,A,B,C。A针上套有64个大小不等的圆盘,大的在下,小的在上。要把这64个圆盘从A针移动C针上,每次只能移动一个圆盘,移动可以借助B针进行。但在任何时候,任何针上的圆盘都必须保持大盘在下,小盘在上。求移动的步骤。 本题算法分析如下,设A上有n个盘子。 如果n=1,则将圆盘从A直接移动到C。 当n大于等于2时,移动的过程可分解为三个步骤: 第一步 把A上的n-1个圆盘移到B上; 第二步 把A上的一个圆盘移到C上; 第三步 把B上的n-1个圆盘移到C上;其中第一步和第三步是类同的。 显然这是一个递归过程,据此算法可编程如下: void move(char x,char y) { printf("%c-->%c\n",x,y); } void hanoi(int n,char one,char two,char three) { if(n==1) move(one,three); else { hanoi(n-1,one,three,two); move(one,three); hanoi(n-1,two,one,three); } } main() { int m; printf("\ninput number:\n"); scanf("%d",&m); printf("the step to moving %2d diskes:\n",m); hanoi(m,'a','b','c'); }
我们还可以将程序略作修改,如下: move(int n,int x,int y,int z) { if(n==1) printf("%c-->%c\n",x,z); else { move(n-1,x,z,y); printf("%c-->%c\n",x,z); move(n-1,y,x,z); } } main() { int h; printf("\ninput number:\n"); scanf("%d",&h); printf("the step to moving %2d diskes:\n",h); move(h,'a','b','c'); } 从程序中可以看出,move函数是一个递归函数,它有四个形参n,x,y,z。n表示圆盘数,x,y,z分别表示三根针。move 函数的功能是把x上的n个圆盘移动到z上。当n==1时,直接把x上的圆盘移至z上,输出x→z。如n!=1则分为三步:递归调用move函数,把n-1个圆盘从x移到y;输出x→z;递归调用move函数,把n-1个圆盘从y移到z。在递归调用过程中n=n-1,故n的值逐次递减,最后n=1时,终止递归,逐层返回。当n=3 时程序运行的结果为: input number: 3 the step to moving 3 diskes: a→c a→b c→b a→c b→a b→c a→c |
|