C语言 函数与宏定义实验报告

C语言程序设计

实验项目:函数与宏定义

姓名:蒋多清    实验地点:一教524     实验时间:5月27日

一、实验目的与要求

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

二、实验内容

实验一

  • 问题描述 :

编写求N的阶乘的函数。
  • 实验代码
#include "stdio.h"
#define N 5
long function(int i)
{
	static int f = 1;
	f = f * i;
	return f;
}
void main()
{
	long product;
	int i;
	for (i = 1; i <= N; i++)
	{
		product = function(i);
		printf("%d!=%ld\n", i, product);
	}
}
  • 效果截图
    image

  • 问题分析

1.设计思路:
定义符号常量N,便于修改以根据需要求不同数的阶乘值,使程序具有通用性。
局部静态变量static的值具有继承性。
利用for循环将i从1~N变化
2、算法分析:
调用function()函数求阶乘值,并赋给product且输出i!=producct,形参i的阶乘值存放在局部静态变量f中,利用for循环改变i的值并重复上述过程,直到i>N时,跳出循环,程序结束。

实验二

  • 问题描述 :

利用辗转相除法求最大公约数。
  • 实验代码
#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 a, b;
	int fac;
	printf("请输入两个整数:");
	scanf("%d,%d", &a, &b);
	fac = gcd(a, b);
	printf("这两个数的最大公约数是:%d", fac);
}
  • 效果截图
    image

  • 问题分析

1.设计思路:
用if语句确保a>=b
用while循环找出最大公约数。
利用辗转相除法求最大公约数。例如,a>b,a能被b整除,则最大公约数就是b。如果a除以b的余数是c,则继续用b除以c,如此反复,直到余数为0,则最后一个非0除数就是a,b的最大公约数。
2、算法分析:
输入两个整数后,调用gcd()函数,利用辗转相除法得出最大公约数并赋值给fac且输出该最大公约数的值。

实验三

  • 问题描述 :

输入整数n,输出高度为n的等边三角形。
  • 实验代码
#include <stdio.h>
void trangle(int n)
{
    int i, j;
    for (i = 0; i < n; i++)
    {
        for (j = 0; j < n - i; j++)
            printf(" ");
        for (j = 0; j <= 2 * i; j++)
            printf("*");
        putchar('\n');
    }
}
void main()
{
    int n;
    printf("请输入一个整数:");
    scanf("%d", &n);
    printf("\n");
    trangle(n);
}
  • 效果截图
    image

  • 问题分析

1.设计思路:
用for循环的嵌套分别打印每一行的空格和*
2、算法分析:
i=0时,输出4个空格和一个*,i每加1,空格少一个,*多两个。

实验四

  • 问题描述 :

求500以内的亲密对数。
  • 实验代码
#include <stdio.h>
int facsum(int m)
{
	int sum = 1, f = 2;
	while (f <= m / 2)
	{
		if (m % f == 0)
			sum = sum + f;
		f = f + 1;
	}
	return sum;
}
main()
{
	int m = 3, n, k;
	while (m <= 500)
	{
		n = facsum(m);
		k = facsum(n);
		if (m == k && m <= n)
			printf("%d,%d\n", m, n);
		m++;
	}
}
  • 效果截图
    image

  • 问题分析

用while循环求出m的所有因子,并将它们的和作为返回值。
用if语句判断m是否有亲密对数且从小到大排序并去掉重复的亲密对数。

三、什么是辗转相除法

  辗转相除法,又被称为欧几里德(Euclidean)算法, 是求最大公约数的算法。辗转相除法首次出现于欧几里得的《几何原本》(第VII卷,命题i和ii)中,而在中国则可以追溯至东汉出现的《九章算术》。
  两个数的最大公约数是指能同时整除它们的最大正整数。辗转相除法的基本原理是:两个数的最大公约数等于它们中较小的数和两数之差的最大公约数。例如,252和105的最大公约数是21(252 = 21 × 12;105 = 21 × 5);因为252 − 105 = 147,所以147和105的最大公约数也是21。在这个过程中,较大的数缩小了,所以继续进行同样的计算可以不断缩小这两个数直至其中一个变成零。这时,所剩下的还没有变成零的数就是两数的最大公约数。由辗转相除法也可以推出,两数的最大公约数可以用两数的整数倍相加来表示,如21 = 5 × 105 + (−2) × 252。这个重要的等式叫做贝祖等式(Bézout's identity)。
  辗转相除法法原先只用来处理自然数,但在19世纪,辗转相除法被推广至其他类型的数,如高斯整数和一元多项式。另外,还被用来解决丢番图方程(Diophantine equations)和构造连分数等。

四、实验小结

本次实验更熟悉了函数的声明、定义和调用并渐渐体会到了程序的模块化思想。

五、近期个人学习小结

本学期学到了很多,比如结构化程序设计的三大结构、函数等,但对于较复杂的算法理解起来比较困难。复习时以书本为纲,抓住重难点,回顾课本知识并做一些代码训练。

posted on 2021-06-01 02:36  寒枫润暮雨  阅读(200)  评论(1编辑  收藏  举报