函数与宏定义

c语言程序设计

实验项目:函数与宏定义的实验

姓名:谢垚

实验地点:一教524教室

实验时间:2021年5月27日

一、实验目的及要求

1.掌握函数的定义方法和调用规则
2.掌握在c语言程序中主调函数和被调函数之间进行数据传递的规则
3.了解函数的返回值及其类型并正确应用
4.了解局部变量和全局变量的作用域及他们与存储分类的关系,理解变量的存在性和可见性的概念
5.理解递归函数的使用
6.理解宏定义的概念,掌握定义无参宏和带参宏的方法
7.理解文件的概念并掌握其用法
8.理解内部函数和外部函数,掌握外部函数的编译和链接方法

二、实验内容

1.实验练习:求两个整数的最大约数

1.问题描述:编写程序,从键盘输入两个整数,调用gcd()函数求它的公约数
2.实验代码:

#include<stdio.h>
int gcd(int a,int b)
{
	int temp;
	int remainder;
	if(a<b)
	{
		temp=a;
		a=b;
		b=temp;
	}
	remainder=b%a;
	while(remainder!=0)
	{
		remainder=a%b;
		a=b;
		b=remainder;
	}
	return a;
}
main()
{
	int x,y;
	int fac;
	printf("Please input two integers:");
	scanf("%d,%d",&x,&y);
	fac=gcd(x,y);
	printf("The great common divsor is%d",fac);
}


3.问题分析:设计一个gcd函数,该函数运用辗转相除法构建,通过判断其余数是否为0来判断何时得到最大公因数

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

1.问题描述:编制一个函数sab(a,b,n),其功能为利用复化梯形公式计算定积分,编制一个主函数及计算被积函数值的函数f(x),在主函数中调用(1)中的函数sab(a,b,n)计算并输出0到1的积分。编制另一个主函数及计算被积函数值的函数f(x),在主函数中调用(1)中的函数sab(a,b,n)计算并输出-1到1的积分。
2.实验代码:
1.sab函数

#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.第一个主函数

#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的值");
	scanf("%lf,%lf,%d",&a,&b,&n);
	result=sab(a,b,n);
	printf("sab(%lf,%lf,%d)=%lf",a,b,n,result);
	return 0; 
}

3.第二个主函数

#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的值");
	scanf("%lf,%lf,%d",&a,&b,&n);
	result=sab(a,b,n);
	printf("sab(%lf,%lf,%d)=%lf",a,b,n,result);
	return 0; 
}



3.问题描述
设计一个sab函数,运用复化梯形公式构建,把它以.h的后缀名储存,放入一个文件夹中。设计被积函数的程序,包含sab.h的头文件,返回值为result,即可求出所要求出函数的积分

3.实验练习:Ackerman函数

1.问题描述:编制计算Ackerman函数的递归函数ACK(n,x,y)
2.实验代码:

#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
	a=Ack(n-1,Ack(n,x,y-1),x);
	return a;
}
main()	
{
	int n,x,y,result;
	printf("Please input n,x,y:");
	scanf("%d,%d,%d",n,x,y);
	if(x<0||y<0||n<0)
	printf("输入错误,请重新输入");
	else
	printf("Ack(%d,%d,%d)=%d\n",n,x,y,result);
}


3.问题分析:在根据递归公式编写递归程序时有5个回归条件以此进行层层递归,返回值为a

4.实验练习:编写计算x的y次幂的递归函数,并在主程序中实现输入和输出

1.问题描述:编写程序,分别从键盘输入数据x和y,计算x的y次幂并输出。
2.实验代码:

#include<stdio.h>
long getpower(int x,int y)
{
	long s;
	if(y==1)
	    s=x;
	else
	   s=x*getpower(x,y-1);
	return s;   
}
main()
{
    int num,power;
    long answer;
	printf("输入一个数:");
	scanf("%d",&num);
	printf("输入幂次方:");
	scanf("%d",&power);
	answer=getpower(num,power);
	printf("%d^%d=%ld\n",num,power,answer); 
}


3.问题分析:运用函数的递归,使大于1的数不断自乘,直到y的值等于1时进行回溯,以此得到所需的程序。

三、什么是辗转相除法

辗转相除法, 又名欧几里德算法(Euclidean algorithm),是求最大公约数的一种方法。它的具体做法是:用较小数除较大数,再用出现的余数(第一余数)去除除数,再用出现的余数(第二余数)去除第一余数,如此反复,直到最后余数是0为止。如果是求两个数的最大公约数,那么最后的除数就是这两个数的最大公约数。
—————————————百度百科

四、实验小结

通过本次实验了解了辗转相除法的使用,认识了模块化程序的设计方法,巩固了递归函数的概念,但面对一些简单问题总会产生错误,对算法的核心不太了解,复杂的程序时常一筹莫展

五、个人学习小结

学到了一些c语言程序中简单的结构,能设计出一些简单的算法,但对复杂的程序还是有点问题,计划将此前的内容抠细节,复习基础的知识,掌握基本语法,回顾经典案例

posted @ 2021-06-02 11:26  模拟的  阅读(116)  评论(0编辑  收藏  举报