第三次试验报告

实验项目函数与宏定义
姓名:杨伟宏      实验时间: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、加深了对函数的了解及使用,明白了模块用法的好处及便利,充分的了解了局部变量和全局的变量的不同;

五、学习小结

本学期学习了很多东西,但总的来说还是比较浅显,而且还不能够完全做到用自己的思路去打代码,而且速度也比较慢;复习知识点则需要对过去笔记以及书上知识点的回顾,但是对于代码则是需要多加练习,或者去看书上的案例,但是最好的方法还是需要自己动手去完成课后习题,这样才能加深自己对代码的认识,如果学有余力,则应该“走在老师前面”。

posted on 2021-06-02 12:53  睦晨  阅读(89)  评论(1编辑  收藏  举报