实验八 函数(二)

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塔问题

    一块板上有三根针,ABCA针上套有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,zn表示圆盘数,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

公告通知
教学日历
疑难留言
同学你好!对本课程有哪些建议?