第六章:函数与宏定义

C程序设计实验报告

姓名:杨怡程 实验地点:522教室 实验时间:6.1

一、实验目的与要求
1、掌握函数的调用方法和定义规则
2、掌握在C语言程序中主调函数与被调函数之间数据传递的规则
3、了解函数的返回值与类型,并将其正确使用
4、了解局部变量与全局变量的作用域与它们与储存分类的关系,理解变量的存在性和可见性的概念
5、熟悉练习递归函数的使用
6、理解宏的概念,掌握定义无参宏和有参宏的方法
7、理解文件的概念,并掌握其用法
8、理解内部函数和外部函数,掌握外部函数的编译方法和连接方法

二、实验内容

  • 实验一
    问题描述:编写程序,从键盘输入两个整数,调用gcd()函数求它们的最大公约数,并输出结果。

代码:

#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=remiander;
	}
	return b;
}
main()
{
	int x,y;
	int fac;
	printf("输入两个整数\n");
	scanf("%d%d",&x,&y);
	fac=gcd(x,y);
	printf("最大公约数是%d",fac);
}

问题分析:程序的关键是使用循环体,用辗转相除法求公约数。对辗转相除和gcd()函数的陌生,通过了解之后才大概知道什么意思。

*实验二
问题描述:计算Ackerman函数的递归函数Ack(n,x,y)。

代码:

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

问题分析:递归函数的实现需要用到Xn=X*X(n-1)的计算思想。

  • 实验三
    问题描述:利用复化梯形公式计算定积分

代码:

头文件:
#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);
}

问题分析::Ⅰ、首先需要设计一个sab.h的文件,一定要命名sab.h,因为后面需要引用这个文件。
Ⅱ、准确理解#include<>和#include“”的区别,当include后是<>时,优先引用库函数,当include后为“”时,优先引用自己的文件。
Ⅲ、double对应的格式字符是%lf。
刚开始时对复化梯形公式不了解也不知道他的作用是什么,只是看着流程图把这个代码编写出来了。之后在百度中搜索了才对其运算机制有所了解。

  • 实验四
    问题描述:输入整数n,输出高度为n的等边三角形。

代码:

#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);
}

问题分析:对putchar()函数的不熟悉,它的作用是直接向终端输出一个字符,在这里就是换行。

三、什么是辗转相除法
欧几里得算法又称辗转相除法,是指用于计算两个非负整数a,b的最大公约数。应用领域有数学和计算机两个方面。计算公式gcd(a,b) = gcd(b,a mod b)。
扩展欧几里得算法可用于RSA加密等领域。
假如需要求 1997 和 615 两个正整数的最大公约数,用欧几里得算法,是这样进行的:
1997 / 615 = 3 (余 152)
615 / 152 = 4(余7)
152 / 7 = 21(余5)
7 / 5 = 1 (余2)
5 / 2 = 2 (余1)
2 / 1 = 2 (余0)
至此,最大公约数为1
以除数和余数反复做除法运算,当余数为 0 时,取当前算式除数为最大公约数,所以就得出了 1997 和 615 的最大公约数 1。
来源:百度百科

四、实验小结
通过本次实验,发现自己很多不足,感觉现在不看实验指导书和所给流程图没法做出实验,要靠自己编写出一个完整的程序很难很难,还有编写程序的重点也就是在算法结构上,如果这个掌握好了,那要编写出来就相对轻松。经历这几次实验,感觉还是要对程序中的代码要多思考,理解透彻才行,不能直接看书上的流程图。

五、近期个人学习小结
1.现在编写代码能力有所提升,但逻辑思维能力有所欠缺。
2.现在课本上面的题目还没有完全的吃透。
3.我想通过写课本后面的编程题来进行复习,并与寝室同学讨论,同时将未理解的题目在电脑上展示出来分析。

posted @ 2021-06-03 19:58  逆刃  阅读(79)  评论(1编辑  收藏  举报