第三次试验报告
实验项目:函数与宏定义
姓名:杨伟宏 实验时间:2021年5月27日
一、实验目的与要求
1、掌握函数的调用方法和定义规则;
2、掌握在C语言程序中主调函数与被调函数之间数据传递的规则;
3、了解函数的返回值与类型,并将其正确使用;
4、了解局部变量与全局变量的作用域与它们与储存分类的关系,理解变量的存在性和可见性的概念;
5、熟悉练习递归函数的使用;
6、理解宏的概念,掌握定义无参宏和有参宏的方法;
7、理解文件的概念,并掌握其用法;
8、理解内部函数和外部函数,掌握外部函数的编译方法和连接方法;
二、实验内容
1、实验6.3.1.4
#include<stdio.h>
void trangle(int n)
{
int i,j;
for(i=1;i<=n;i++)
{
for(j=0;j<n-i;j++)
printf(" ");
for(j=0;j<2*i-1;j++)
printf("*");
putchar('\n');
}
}
main()
{
int n;
printf("输入一个整数n\n");
scanf("%d",&n);
printf("\n");
trangle(n);
}
运行图:
问题描述:定义一个函数,函数里面用for循环搭建图形,然后将结果返回函数,并在主函数中调用该函数,使用图形呈现。
注意:从零开始的变量会比从一开始的变量多一个数,则有可能使空格多一个,进而导致星星数少一个。
2、实验6.3.2.2:利用复化梯形公式计算定积分
头文件:
#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;
}
函数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("输入a,b,n\n");
scanf("%lf,%lf,%d",&a,&b,&n);
result=sab(a,b,n);
printf("result=%lf",result);
}
函数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("输入a,b,n\n");
scanf("%lf,%lf,%d",&a,&b,&n);
result=sab(a,b,n);
printf("result=%lf",result);
}
运行图:
问题描述:先建立一个头部文件,将需要的复化梯形函数写在其中,然后分别在两个主函数里调用该文件里的函数。同时也要在被调函数所在的头部文件里要声明主函数中出现的函数。
注意:为了使函数调用成功,且能够寻找的被调函数所在的文件,需将头部文件与两个主函数所在的文件放在同一个文件夹中。
3、实验6.3.2.3:
#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>=4&&y==0)
a=2;
else
a=Ack(n-1,Ack(n,x,y-1),x);
return a;
}
main()
{
int n,x,y,result;
printf("输入整数n,x,y\n");
while(1)
{
scanf("%d,%d,%d",&n,&x,&y);
if(n<0||x<0||y<0)
printf("输入错误,重新输入");
else
break;
}
result=Ack(n,x,y);
printf("Ack(%d,%d,%d)=%d\n",n,x,y,result);
}
运行图:
实验问题:先定义一个递归函数,并在函数使用if...else语句,使用该语句构成分支结构,是数据能够回溯,并将结果返回给函数本身;然后在主函数调用该函数,但是在调用之前要确保使用的参数都是大于零的整数,如果出现错误,则需要出现错误提示。
注意:使用if....else语句构成分支结构的同时也要特别注意if.....else的配对。
4、实验6.3.3
#include<stdio.h>
int gcd(int a,int b)
{
int temp;
int remainder;
if(a<b)
{
temp=a;
a=b;
b=temp;
}
remainder=a%b;
while(remainder!=0)
{
a=b;
b=remainder;
remainder=a%b;
}
return b;
}
main()
{
int x,y;
int fac;
printf("输入两个整数\n");
scanf("%d%d",&x,&y);
fac=gcd(x,y);
printf("最大公约数是%d",fac);
}
运行结果:
问题描述:在主函数前定义一个辗转相除的函数,在函数用if语句来判断a,b的大小,并让其相除,例如:a>b,如果a能被b整除,最大公约数就是b,如果a除b的余数为c,则继续用b除c,如此反复,直到最后余数为零,则最后一个非零的除数就是最大公约数。函数中是利用while循环使其实现辗转相除,并将结果返回给了b。
注意:在被调函数中出现了数值调换,在调换需要出现“空位置”,故而需要加上一个没有初始值的变量来完成调换,而且while循环的结束条件也要明确清楚。
三、辗转相除法
辗转相除法, 又名欧几里德算法(Euclidean algorithm),是求最大公约数的一种方法。它的具体做法是:用较大数除以较小数,再用出现的余数(第一余数)去除除数,再用出现的余数(第二余数)去除第一余数,如此反复,直到最后余数是0为止。
如果是求两个数的最大公约数,那么最后的除数就是这两个数的最大公约数。另一种求两数的最大公约数的方法是更相减损法。
-----参考来源:百度百科
四、实验小结
1、通过本次实验了解了辗转相除法的使用,认识了模块化程序的设计方法,巩固了递归函数的概念;
2、在实验中可以发现自己的不足并且可以自己完整的将代码编写出了。而且在实验中学习到了在课本上没有的知识,巩固经验;
3、加深了对函数的了解及使用,明白了模块用法的好处及便利,充分的了解了局部变量和全局的变量的不同;
五、学习小结
本学期学习了很多东西,但总的来说还是比较浅显,而且还不能够完全做到用自己的思路去打代码,而且速度也比较慢;复习知识点则需要对过去笔记以及书上知识点的回顾,但是对于代码则是需要多加练习,或者去看书上的案例,但是最好的方法还是需要自己动手去完成课后习题,这样才能加深自己对代码的认识,如果学有余力,则应该“走在老师前面”。