第六章 函数和宏定义实验(2)

C程序设计实验报告

实验项目:

6.4.2、模块化程序设计

  • 利用复化梯形公式计算定积分
  • 计算Ackerman函数

    6.4.3 函数的递归调用

  • 编程计算x的y次幂的递归函数getpower(int x,int y),并在主程序中实现输入输出
  • 编写计算学生年龄的递归函数
  • 编写递归函数实现Ackman函数

    姓名:罗龙妹 实验地点: 514实验室 实验时间:2019年5月16日

    一、实验目的与要求

    6.4.2、模块化程序设计

    6.4.2.2 利用复化梯形公式计算定积分

  • 掌握C语言中定义函数的方法
  • 掌握通过“值传递”调用函数的方法

    6.4.2.3 计算Ackerman函数

  • 掌握递归函数的设计方法
  • 进一步练习阅读检查与的调试修改C程序的方法

    6.4.3 函数的递归调用

    6.4.3.1 编程计算x的y次幂的递归函数getpower(int x,int y),并在主程序中实现输入输出

  • 写出解决该问题的递归算法:
  • 在递归函数中,使用数字1作为回归条件
  • 在递归函数中,使用if-else语句根据条件的真假来决定是递推还是回归

    6.4.3.2 编写计算学生年龄的递归函数

  • 写出解决该问题的递归算法:
    递归公式如下,根据公式容易写出递归程序。
  • 在递归函数中,使用数字1作为回归条件
  • 在递归函数中,使用if-else语句根据条件的真假来决定是递推还是回归

    6.4.3.3 编写递归函数实现Ackman函数

  • 根据递归公式编写递归函数
  • 在递归函数中,使用if-else语句根据条件的真假来决定是递推还是回归

    二、实验内容

    6.4.2:模块化程序设计

    实验练习2:利用复化梯形公式计算定积分

  • 问题的简单描述:
    (1)编写一个函数sab(a,b,n),其功能为利用复化梯形公式计算定积分

    其中n为对区间[a,b]的等分数。要求改函数在一个独立的文件中。
    (2)编制一个主函数以及计算被积函数值的函数f(x),在主函数中调用(1)中的函数sab(a,b,n)计算并输出下列积分值

    要求主函数与函数f(x)在同一文件中。
    (3)编制另一个主函数以及计算被积函数值的函数f(x),在主函数中调用(1)中的函数sab(a,b,n)计算并输出下列积分值

    同样要求主函数与函数f(x)在同一文件中。
    (4)要求画出模板sab()的流程图。
    方法说明:
    设定积分为

    则复化梯形求积公式为

    其中
  • 程序流程图:
  • 实验代码1:
/*sab.h*/
#include<stdio.h>
double f(double x);
double sab(double a,double b,int n)
{
    double h,result,x1,x2,x3=0,t,k;
    h=(b-a)/n;/*求h的值*/
    x1=f(a);/*求f(a)的值*/
    x2=f(b); /*求f(b)的值*/
    for(k=1;k<=n-1;k++)/*for循环的循环体*/
    {
        t=a+k*h;
        x3=x3+f(t);
     } 
        result=h*(x1+x2)/2+h*x3;
     return result; 
}
  • 实验代码2:
#include<stdio.h>
#include<math.h>
#include"sab.h"
double f(double x)
{
    double result;
    result=x*x*exp(x);/*f(x)=x*x*exp(x)的程序段*/
    return result;
}
main() 
{
    double a,b,result;
    int n;
    printf("please input double a,b and integer n:");/*提示输入a,b,n*/
    scanf("%lf,%lf,%d",&a,&b,&n);/*输入a,b,n*/
    result=sab(a,b,n);/*调用sab(a,b,n)求积分*/
    printf("sab(%lf,%lf,%d)=%f",a,b,n,result);/*输出结果*/
    return 0; 
}
  • 实验代码3:
#include<stdio.h>
#include"sab.h"
double f(double x)
{
    double result;
    result=1/(25+x*x);/*f(x)=1/(25+x*x);f(x)=1/(25+x*x)的程序段*/ 
    return result;
}
main()
{
    double a,b,result;
    int n;
    printf("please input double a,b and integer n:");/*提示输入a,b,n*/
    scanf("%lf,%lf,%d",&a,&b,&n);/*输入a,b,n*/
    result=sab(a,b,n);/*调用sab(a,b,n)求积分*/
    printf("sab(%lf,%lf,%d)=%f",a,b,n,result);/*输出结果*/
    return 0;
}
  • 问题分析:(重点分析在实验过程中出现的问题,及解决方法。)
    这个程序需要建立三个独立文件,首先要建好sab.h头文件,然后在另外两个文件中要记得加上这个sab.h头文件,不然程序是运行不出来的,将sab.h头文件单独拉出来是为了让代码看起来不会那么繁杂,要在不同文件中引用的话也不用再打一遍代码,只要加上一个头文件即可,然后按照流程图一步一步地走即可运行成功。
  • 程序运行如下:


    实验练习3:计算Ackerman函数

  • 问题的简单描述:
    具体要求如下:
    (1)根据方法说明,编制计算Ackerman函数的递归函数ack(n,x,y)。
    (2)编制一个主函数,由键盘输入n,x,y,调用(1)中的函数ack(n,x,y),计算Ackerman函数
    (3)在主函数中,输入之前要有提示,并检查输入数据的合理性。若输入的数据不合理,则输出出错信息。输出要有文字说明。
    (4)输入(n,x,y)=(2,3,1)运行该程序。然后自定义几组数据在运行该程序。
    方法说明:
    Ackerman函数的定义如下:
    n,x,y为非负整数,且
  • 程序流程图:
  • 实验代码:
#include<stdio.h>
int Ack(int n,int x,int y)
{
    int a;
       if (n==0)/*判断回归条件1的if语句头部*/
        a=x+1;
       else if (n==1&&y==0)/*判断回归条件2的if语句头部*/
        a=x;
       else if (n==2&&y==0)/*判断回归条件3的if语句头部*/
        a=0;
       else if (n==3&&y==0)/*判断回归条件4的if语句头部*/
        a=1;
       else if (n>=4&&y==0)/*判断回归条件4的if语句头部*/
        a=2;
       else if (n!=0&&y!=0)/*进一步递推的语句*/
        a=Ack(n-1,Ack(n,x,y-1),x);
        return a;
}
main()
{
    int n,x,y,result;
    printf("please input n,x,y:");/*提示输入n,x,y*/ 
    scanf("%d,%d,%d",&n,&x,&y);/*输入n,x,y*/
    if(n<0||x<0||y<0)
        printf("error!");/*如果输入不合法,输出错误提示信息并重新输入*/ 
    else 
    {
        result=Ack(n,x,y);/*用输入的两个数据,调用递归函数*/
        printf("Ack(%d,%d,%d)=%d\n",n,x,y,result);
    }
}
  • 问题分析:
    这个程序是对递归函数的调用,用if嵌套语句来判断5个回归条件,要特别注意n,x,y这三个变量的要求是非负整数,所以在输入之前要有提示并检查输入数据的合理性。
  • 程序运行如下:

    6.4.3:函数的递归调用

    实验练习1:编程计算x的y次幂的递归函数getpower(int x,int y),并在主程序中实现输入输出

  • 问题的简单描述:编写程序,分别从键盘输入数据x和y,计算x和y次幂并输出。
  • 程序流程图:
  • 实验代码:
#include<stdio.h>
long getpower(int x,int y)
{
    if(y==1)/*判断回归条件的if语句头部*/
      return x;
     else 
      return x*getpower(x,y-1);/*进一步递推的语句*/ 
}
main()
{
    int num,power;
    long answer;
    if (num%2==0||num%2==1)
    {
        printf("输入一个数:");/*提示输入一个数*/ 
        scanf("%d",&num);/*输入一个整数*/
    }
    else printf("输入出错!");
    if (power%2==0||power%2==1)
    {
        printf("输入幂次方:");/*提示输入幂次方*/ 
        scanf("%d",&power);/*输入一个整数*/ 
    }
    else printf("输入出错!");
    answer=getpower(num,power);/*用输入的两个数据,调用递归函数*/ 
    printf("结果是:%ld\n",answer);
}

3问题分析:(重点分析在实验过程中出现的问题,及解决方法。)
这个程序是一个涉及递归算法的数学模型,用if-else语句根据条件的真假来决定是递归还是回归。在主函数中,变量answer可能要存放较大的数,所以将它的类型定义为long型;在求幂的递归函数getpower()可能要存放较大的数,所以也定义为long型;在输出结果的printf()函数中,由于要输入长整型数据,所以其输出格式要为“%ld”。在输入x和y变量的时候要判断输入的数是否为整数,在这个提示上我研究了很久,结果还是研究不怎么 清楚,不知道判断是否为整数的条件语句到底该怎么写。

  • 程序运行如下:

    实验练习2:编写计算学生年龄的的递归函数

  • 问题的简单描述:用递归方法计算学生的年龄。已知第一位学生的年龄最小为10岁,其余学生一个比一个大2岁,求第5位学生的年龄。
  • 程序流程图:
  • 实验代码:
#include<stdio.h>
int age(int n)
{
    int c;
    if(n==1)/*判断回归条件if语句头部*/
    c=10;
    else
    return age(n-1)+2;/*进一步递推的语句*/
    return c; 
}
main()
{
    int result,n=5; 
    result=age(n);
    printf("age(%d)=%d",n,result);
}
  • 问题分析:
    这个程序根据递归问题描述写出递归问题描述很容易写出递归公式,进而写出递归程序。
  • 程序运行结果如下:

    实验练习3:编写递归函数实现Ackman函数

  • 问题的简单描述:定义递归函数实现下列Ackman函数:

    其中m、n为正整数。设计创新求Acm(2,1),Acm(3,2)。
  • 程序流程图:
  • 实验代码:
#include<stdio.h>
Acm(int m,int n)
{
    if(m==0)
     return n+1;
    else if(n==0)
     return Acm(m-1,1);
    else 
    return Acm(m-1,Acm(m,n-1));
    return 0;
}
main()
{
    int x,y;
    x=Acm(2,1);
    y=Acm(3,2);
    printf("Acm(2,1)=%d\n",x);
    printf("Acm(3,2)=%d\n",y);
    return 0;
}
  • 问题分析:(重点分析在实验过程中出现的问题,及解决方法。)
    这个程序也是一个递归函数的调用问题,也要使用if-else语句根据条件的真假来决定是递推还是回归。
  • 程序运行结果如下:

    三、实验小结(在本次实验中收获与不足)

    这节实验课还是函数和宏定义的实验,在这次实验中大部分的都是关于递归函数的调用问题,要注意什么时候是递推,什么时候是回归,要对递归函数概念有一定的理解,但对于一些算法我还是不太清楚,课后还需花些时间去弄明白。然后就是流程图问题,流程图真的很重要,所以拿到一个题目我们要尝试着自己画出它的流程图,然后看看根据自己画的流程图看看能不能运行出这个程序,不能的话要不断地进行修改,直到程序运行成功。

猜你喜欢

转载自www.cnblogs.com/luolongmei/p/10884871.html
今日推荐