第六章 函数和宏定义实验(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),并在主程序中实现输入输出 - 写出解决该问题的递归算法: ![](https://img2018.cnblogs.com/blog/1617039/201905/1617039-20190518091420521-392191465.png) - 在递归函数中,使用数字1作为回归条件 - 在递归函数中,使用if-else语句根据条件的真假来决定是递推还是回归 ####6.4.3.2 编写计算学生年龄的递归函数 - 写出解决该问题的递归算法: 递归公式如下,根据公式容易写出递归程序。 ![](https://img2018.cnblogs.com/blog/1617039/201905/1617039-20190518091807009-1625751680.png) - 在递归函数中,使用数字1作为回归条件 - 在递归函数中,使用if-else语句根据条件的真假来决定是递推还是回归 ####6.4.3.3 编写递归函数实现Ackman函数 - 根据递归公式编写递归函数 - 在递归函数中,使用if-else语句根据条件的真假来决定是递推还是回归 ##二、实验内容 ###6.4.2:模块化程序设计 ####实验练习2:利用复化梯形公式计算定积分 - 问题的简单描述: (1)编写一个函数sab(a,b,n),其功能为利用复化梯形公式计算定积分 ![](https://img2018.cnblogs.com/blog/1617039/201905/1617039-20190518092243053-1490352187.png) 其中n为对区间[a,b]的等分数。要求改函数在一个独立的文件中。 (2)编制一个主函数以及计算被积函数值的函数f(x),在主函数中调用(1)中的函数sab(a,b,n)计算并输出下列积分值 ![](https://img2018.cnblogs.com/blog/1617039/201905/1617039-20190518092609012-2057392390.png) 要求主函数与函数f(x)在同一文件中。 (3)编制另一个主函数以及计算被积函数值的函数f(x),在主函数中调用(1)中的函数sab(a,b,n)计算并输出下列积分值 ![](https://img2018.cnblogs.com/blog/1617039/201905/1617039-20190518092809688-1542214895.png) 同样要求主函数与函数f(x)在同一文件中。 (4)要求画出模板sab()的流程图。 方法说明: 设定积分为 ![](https://img2018.cnblogs.com/blog/1617039/201905/1617039-20190518092933551-893938124.png) 则复化梯形求积公式为 ![](https://img2018.cnblogs.com/blog/1617039/201905/1617039-20190518093003518-420510.png) 其中 ![](https://img2018.cnblogs.com/blog/1617039/201905/1617039-20190518093027538-1605707702.png) - 程序流程图: ![](https://img2018.cnblogs.com/blog/1617039/201905/1617039-20190518125355325-358457372.png) - 实验代码1: ``` /*sab.h*/ #include 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 #include #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 #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头文件单独拉出来是为了让代码看起来不会那么繁杂,要在不同文件中引用的话也不用再打一遍代码,只要加上一个头文件即可,然后按照流程图一步一步地走即可运行成功。 - 程序运行如下: ![](https://img2018.cnblogs.com/blog/1617039/201905/1617039-20190518093834012-1507528397.png) ![](https://img2018.cnblogs.com/blog/1617039/201905/1617039-20190518093852987-1932957060.png) ####实验练习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为非负整数,且 ![](https://img2018.cnblogs.com/blog/1617039/201905/1617039-20190518095241914-1074538567.png) - 程序流程图: ![](https://img2018.cnblogs.com/blog/1617039/201905/1617039-20190518132650749-1483009722.png) - 实验代码: ``` #include 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这三个变量的要求是非负整数,所以在输入之前要有提示并检查输入数据的合理性。 - 程序运行如下: ![](https://img2018.cnblogs.com/blog/1617039/201905/1617039-20190518095604065-870023883.png) ###6.4.3:函数的递归调用 ####实验练习1:编程计算x的y次幂的递归函数getpower(int x,int y),并在主程序中实现输入输出 - 问题的简单描述:编写程序,分别从键盘输入数据x和y,计算x和y次幂并输出。 - 程序流程图: ![](https://img2018.cnblogs.com/blog/1617039/201905/1617039-20190518133635245-1521780510.png) - 实验代码: ``` #include 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变量的时候要判断输入的数是否为整数,在这个提示上我研究了很久,结果还是研究不怎么 清楚,不知道判断是否为整数的条件语句到底该怎么写。 - 程序运行如下: ![](https://img2018.cnblogs.com/blog/1617039/201905/1617039-20190518101506726-262053380.png) ####实验练习2:编写计算学生年龄的的递归函数 - 问题的简单描述:用递归方法计算学生的年龄。已知第一位学生的年龄最小为10岁,其余学生一个比一个大2岁,求第5位学生的年龄。 - 程序流程图: ![](https://img2018.cnblogs.com/blog/1617039/201905/1617039-20190518134520557-424714084.png) - 实验代码: ``` #include 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); } ``` - 问题分析: 这个程序根据递归问题描述写出递归问题描述很容易写出递归公式,进而写出递归程序。 - 程序运行结果如下: ![](https://img2018.cnblogs.com/blog/1617039/201905/1617039-20190518101847090-1065321154.png) ####实验练习3:编写递归函数实现Ackman函数 - 问题的简单描述:定义递归函数实现下列Ackman函数: ![](https://img2018.cnblogs.com/blog/1617039/201905/1617039-20190518101957523-1405229198.png) 其中m、n为正整数。设计创新求Acm(2,1),Acm(3,2)。 - 程序流程图: ![](https://img2018.cnblogs.com/blog/1617039/201905/1617039-20190518135501780-239776663.png) - 实验代码: ``` #include 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语句根据条件的真假来决定是递推还是回归。 - 程序运行结果如下: ![](https://img2018.cnblogs.com/blog/1617039/201905/1617039-20190518102158769-1879218415.png) ##三、实验小结(在本次实验中收获与不足) 这节实验课还是函数和宏定义的实验,在这次实验中大部分的都是关于递归函数的调用问题,要注意什么时候是递推,什么时候是回归,要对递归函数概念有一定的理解,但对于一些算法我还是不太清楚,课后还需花些时间去弄明白。然后就是流程图问题,流程图真的很重要,所以拿到一个题目我们要尝试着自己画出它的流程图,然后看看根据自己画的流程图看看能不能运行出这个程序,不能的话要不断地进行修改,直到程序运行成功。
posted @ 2019-05-18 19:12  longmeiluo  阅读(238)  评论(0编辑  收藏  举报