实验五 算法过程模拟——真假话问题的算法设计      实验报告下载

一、实验目的

      通过对函数作用域的程序的分析、递归函数程序的填空和函数的值传递练习,认识函数中形参的作用域和递归的原理,理解函数中形参的正确使用、递归的正确使用和递归的优缺点。

      

二、实验内容

      1、题目:观察程序中的各变量,分析函数中形参的作用域。

      实验分析及提示:

      本题目里,在程序的不同位置出现了不同的变量,这些变量的变量名都为x,在程序中用序号【1】【2】【3】……将其逐个标出。在每个变量x的后面都有一个printf 函数,对变量x进行屏幕显示,用序号A、B、C……将printf函数逐个标出。请观察C程序的输出结果,分析各printf语句打印出的结果对应哪个变量x,以及各变量x的作用域,填写表1。

      本实验中x的变量类型包括:全局变量、局部变量、静态变量。

      

      程序1:

      

      #include <stdio.h>

      #include <stdlib.h>

      

      void useLocal(void);

      void useStaticLocal(void);

      void useGlobal(void);

      

      int x = 1; /*【1】*/

      int main(void)

      {

        int x = 5; /*【2】*/

        printf("local x in outer scope of main is %d\n",x); /*( A )*/

        {/*start a new scope*/

          int x = 7; /*【3】*/

          printf("local x in outer scope of main is %d\n",x); /* ( B )*/

        }/*end new scope*/

      

        useLocal();/*( C )*/

        useStaticLocal();/*( D )*/

        useGlobal();/*( E )*/

      

        useLocal();/*( F )*/

        useStaticLocal();/*( G )*/

        useGlobal();/*( H )*/

      

        printf("\nlocal x in main is %d\n",x); /*( I )*/

        system("pause");

        return 0;

      }

      

      void useLocal(void)

      {

        int x = 25;【4】

        printf("\nlocal x in useLocal is %d after entering useLocal\n",x); /* ( C1,F1 )*/

        x++;

        printf("local x in useLocal is %d before exiting useLocal\n",x); /*( C2,F2 )*/

      }

      void useStaticLocal(void)

      {

        static int x = 50;【5】

        printf("\nlocal static x is %d on entering useStaticLocal\n",x); /*( D1,G1 )*/

        x++;

        printf("local static x is %d on exiting useStaticLocal\n",x); /*( D2,G2 )*/

      }

      void useGlobal(void)

      {

        printf("\nglobal x is %d on entering useGlobal\n",x); /*( E1,H1 )*/

        x*=10;

        printf("global x is %d on exiting useGlobal\n",x); /*( E2,H2 )*/

      }

      

      2、题目:汉诺塔程序

      现在有三根相邻的柱子,标号为A,B,C,A柱子上从下到上按金字塔状叠放着n个不同大小的圆盘,现在把所有盘子一个一个移动到柱子C上,并且每次移动同一根柱子上都不能出现大盘子在小盘子上方,程序求出至少需要多少次移动和盘子移动的顺序。

      

      请完成程序填空,填写表2,并观察程序输出结果,完成表3。根据表2表3的实验结果,回答表3后面的问题。

      

      实验分析及提示:

      

      首先把柱子A上面n-1个盘子移动到柱子B上,然后把最大的一块放在C上,最后把B上的所有盘子移动到C上。

      程序2:

      

      #include <stdio.h>

      #include <stdlib.h>

      

      【1】;

      【2】;

      int count=0;/*计算函数hanoi的调用次数*/

      

      int void main()

      {

        int number;/*disk number*/

        printf("please input the number of discs:\n");

        scanf("%d",&number);

        printf("the steps to moving is:\n");

        hanoi(number,'A','B','C');

        printf("The complexity is %d\n",count);

        system("pause");

        return;

      }

      void hanoi(int n, char A ,char B ,char C)/*把n个盘子从柱子A借助柱子B移动到C*/

      {

        【3】;

        if(n==1)

          move(A,C);

        else {

          【4】;

          move(A,C);

          【5】;

        }

      }

      void move(char a,char b)

      {

        printf("%c-->%c\n",a,b);

      }

      

      

      3、题目:函数的值传递

      从键盘任意输入两个整数,编程实现将其交换后再重新输出。观察程序3并运行,记录运行结果,分析程序3能否实现这一功能,完成表4。

      程序3:

      

      #include <stdio.h>

      void Swap(int a, int b);

      int main()

      {

        int a, b;

        printf("Input a, b:");

        scanf("%d,%d", &a, &b);

        Swap(a, b);

        printf("In main():a = %d, b = %d\n", a, b);

        return 0;

      }

      void Swap(int a, int b)

      {

        int temp;

        temp = a;

        a = b;

        b = temp;

        printf("In Swap():a = %d, b = %d\n", a, b);

      }

三、实验方法

      1、针对问题画出流程图(可不交);

      2、按照流程图和输出要求,将程序补充完整,观察输出结果,并按照表格要求进行结果记录。

      

四、实验报告

      

      1、回答问题:

      

      根据程序1,试分析:

      1.1全局变量、局部变量、静态变量的特点是什么

      ________________________________________________________________________

      ________________________________________________________________________

      ________________________________________________________________________

      

      根据程序2,试分析:

      

      2.1 根据盘子数的增长,hanoi函数被调用的次数是如何变化的?

      ________________________________________________________________________

      ________________________________________________________________________

      ________________________________________________________________________

      

      2.2 设盘子的移动次数为H(n)。汉诺塔问题的递归表达式:

      H⑴ = 1

      H(n) = 2*H(n-1)+1 (n>1)

      那么就能得到H(n)的一般式:

      H(n) = 2^n - 1 (n>0)

      根据一般式,可以不使用递归,就能得到盘子的移动次数。

      请根据这一现象,分析递归方法的优缺点。

      ________________________________________________________________________

      ________________________________________________________________________

      ________________________________________________________________________

      

      2.3 请比较递归与迭代两种方法,包括控制结构,终止测试,计算代价,程序直观度。

      ________________________________________________________________________

      ________________________________________________________________________

      ________________________________________________________________________

      

      根据程序3,试分析:

      

      3.1 函数swap能否实现对main函数中的a,b值的交换呢?为什么?

      

      3.2 如果把Swap中的a和b分别改成x和y,会发生什么变化吗?如果将它们换成别的名称呢?函数的形参名需要和main函数中的实参名保持一致吗?

      

      3.3 请你编写一个新的swap函数,要求使用传递变量地址的方法,实现对main函数中a,b值的交换。

      

      2、完成下列表格。

表1   程序1的变量说明

      

Printf语句的序号变量X的序号变量X的值变量x的类型变量x的作用域
A
B
C1
C2
D1
D2
E1
E2
F1
F2
G1
G2
H1
H2
I

      

表2   程序2的空缺语句
序号语句
【1】
【2】
【3】
【4】
【5】

      

表3   程序2的运行情况分析
项数numberHanoi函数的调用次数
0
1
2
3
4
5
6
7
10
15

      

表4   程序3的运行分析
步骤变量a的值变量b的值
1main函数(调用swap前)
2swap函数(return语句之前)
3main函数(调用swap后)