函数与宏定义
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语言程序中简单的结构,能设计出一些简单的算法,但对复杂的程序还是有点问题,计划将此前的内容抠细节,复习基础的知识,掌握基本语法,回顾经典案例