函数与宏定义实验报告(2)

C语言程序设计

 

实验项目:函数与宏定义

姓名:许鑫琪    实验地点:第一教学楼514教室   实验时间:5月16日

一、实验目的与要求

1、模块化程序设计

  • 利用负化梯形公式计算定积分。  
  • 计算Ackeman函数。

2、函数的递归

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

 

 

 

 二、实验内容

实验练习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()的流程图。
方法说明:
设定积分为

 


则复化梯形求积公式为:

 

实验流程图:

 

 

实验代码:

     /*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;
    int k;
    h=(b-a)/n;
    x1=f(a);
    x2=f(b);
    for ( k=1;k<=n-1;k++)
    { 
    t=a+k*h;
     x3=x3+f(t);
     }  
    result=h*(x1+x2)/2+h*x3;
    return result;
   }

 

/*2-1*/

#include <stdio.h>
#include <math.h>
#include "sab.h"
double f(double x)
{
    double result ;
    result =x*x*exp(x);
    return result ;    
}
main ()
{   
    double a,b,result; 
    int n;
    printf("please enter a、b、n:");
    scanf("%lf%lf%d",&a,&b,&n);
    result=sab(a,b,n);
    printf("%lf",result);
} 
/*2-2*/
#include <stdio.h>
#include"sab.h"
double f(double x)
{
    double result;
    result=1/(25+x*x);
    return result;    
}
main ()
{
    double a,b,result;
    int n;
    printf("please enter a、b、n:");
    scanf("%lf,%lf,%d",&a,&b,&n);
    result=sab(a,b,n);
    scanf("sab(%lf,%lf,%d)=%lf",a,b,n,result);
    return 0;
}

         

的运行结果为:

    

 的运行结果:

 

 

问题分析:

                    1、没有定义K就对其赋值了;

                    2、直接看着书上写了f(x)=1/(25+x*x),而自己定义

                          了的“result”却没有用,导致程序报错;

 


 

 

 

实验练习3:计算Ackeman函数。

 

问题描述:

具体要求如下:
(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) 
    a=x+1;
    else if (n==1&&y==0)
    a=x;
    else if (n==2&&y==0)
    a=0;
    else if (n==3&&y==0)
    a=1;
    else if (n>=4&&y==0)
    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 enter n、x、y:\n");
    scanf("%d,%d,%d",&n,&x,&y);
    if (n<=0||x<=0||y<=0)
    printf("your enter is error ,please repeat right! ");
    result=Ack(n,x,y);
    printf("Ack(%d,%d,%d)=%d\n",n,x,y,result);
}

 

 

运行结果:

 

问题分析:1、在if的分支结构中,没有写else,使得不管输入什么

                结果都是:

              2、对于“=”与“==”的使用较为混乱,概念不清:a=x+1,a=x,a==0,a==1,

                   应全部用一个“=”,进行赋值,不是说只要是数字就是==;

6.4.3函数的递归

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

 

问题描述:编写程序,分别从键盘输入数据X与Y,计算X的Y次幂并输出;

 

实验流程图:

    

 

                                               

实验代码: 

#include "stdio.h"
long getpower(int x,int y)
  {  
    int m;
      if (y==1)
        m=x;
    else 
       m=x*getpower(x,y-1);
  }
main()
{
    int num,power;
    long answer;
    printf("please enter a int num:");
    scanf("%d",&num);
    printf("请输入一个幂次方 ");
    scanf("%d",&power);
     answer=getpower(num,power);
    printf("结果是:%ld\n",answer);
}

 

 

运行结果:

 

 

问题分析:1、该程序主要是明确递归条件算法,根据条件的真假来决定是递推还是回归;

                  2、了解了函数递归的结构,坚决这道题并不难;

 

 

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

 

问题描述:用递归方法计算学生的年龄。已知第一位学生年龄最小为10岁,其余学生一个比一个大2岁,求第5位学生的年龄。

 

实验流程图:

                                    

 

 

实验代码:

#include <stdio.h>
int age (int n)
{
    int c;
    if(n==1)
    c=10;
    else
    c=age(n-1)+2;
    return c;
}
main ()
{   
 int n=5;
    int answer;
    answer=age(n);
    printf("第五位同学的年龄是:%d\n",answer);
}

 

 

 

 

运行结果:

 

 

 

问题分析:这道程序我把“c=10”写为了“c==10”,使赋值变成了等于

                  导致 一直得不到正确的结果;

 

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

 

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

 

 

 

 

其中m,n为正整数。设计程序求Ack (2,1),Ack (3,2)。

 

实验流程图:

            

 

实验代码:

#include <stdio.h>
Acm(int m,int n)
{ 
    int answer;
    if (m==0)
    answer=n+1;
    else if(n==0)
    answer=Acm(m-1,1);
    else if(n>0&&m>0)
    answer=Acm(m-1,Acm(m,n-1));
    return answer;
}
int main ()
{
    int answer1,answer2;
    answer1=Acm(2,1);
    answer2=Acm(3,2);
    printf("Acm(2,1)=%d\nAcm(3,2)=%d",Acm(2,1),Acm(3,2));
}

 

 

 

 

运行结果:

 

 

问题分析:根据前面对于递归函数的结构,完成这道题并不难,

                  但是还是老问题,if后面没有跟上对应的else;

 

 

三、实验小结:

收获:1、这一部分的学习,对于模块化的思想有了更深理解,对于一些固定的算法

                可以建立一个函数库,要用时直接调出,减少了实验代码的繁琐与重复;

           2、函数递归就是调用函数本身,不管是老师还是书上都在强调,但是并未真

                正理解,自己动手做了才了解了,果然实践才是最好的老师;

           3、写一个程序时应该提醒使用者去如何使用,根据其输入给出相应的反馈,

                才能算得上是一个完整的程序;

           4、对于函数的类型这方面更加注意了,我们要考虑题目要求,输出值大小等因素;

 

不足:1、对于基本的赋值与等于没有去思考,总相当然的认为后面接的是一个具体的数

                就要用“==”,是一个字符就要用“=”,这个应该经过思考,具体情况具体分析;

           2、if-else的分支结构,使用不完整,总是漏了else,使得程序输出错误,在写一

                 个程序前,应先知道干什么,用到哪些算法结构,怎么写都要在脑子里过一遍

                 (简而言之,再脑子里面构思一下流程图);

          

 

posted @ 2019-05-19 09:46  Avery墨念  阅读(498)  评论(0编辑  收藏  举报