实验六 函数

一、实验目的

1.掌握函数定义与调用的方法。
2.掌握实参和形参的对应关系以及函数调用时的数据传递方式。
3.了解函数的嵌套调用和递归调用。
4.掌握局部变量、全局变量、自动变量和静态局部变量的使用方法。

二、实验学时

三、实验内容

1.运行下面的程序,分析结果
(1) #include<stdio.h>
int main(){
long fac(int);
for(int i=1;i<10;i++)
printf(“%d!=%ld\n”,i,fac(i));
}
long fac(int x){
static long p=1;
return p=p*x;
}
分析:局部静态变量离开函数,值仍保留
在这里插入图片描述

(2) #include<stdio.h>
int main(){
long fac(int);
for(int i=1;i<10;i++)
printf(“%d!=%ld\n”,i,fac(i));
}
long fac(int x) {
long p=1;//或 auto long p=1;
return p=p*x;
}
分析:局部自动变量离开函数,值会消失
在这里插入图片描述

(3) #include<stdio.h>
long p=1;
int main(){
long fac(int);
for(int i=1;i<10;i++)
printf(“%d!=%ld\n”,i,fac(i));
}
long fac(int x) {
return p=p*x;
}
分析:全局变量离开函数,函数值不会消失
在这里插入图片描述

2.编写函数 int fac(int x)计算 x!的值。在主函数中输入 n 和 m 的值,通过调用函
数 fac 计算Cmn 的值(要求分别用递归和非递归的方法编写函数 fac)。
非递归法:

#include<stdio.h>
int fac(int x)
{
int i;
long result=1;
for(i=2;i<=x;i++)
result*=i;
return result;
}
int main(){
double p;
int m,n;
do{
scanf("%d %d",&n,&m);
}while(n<m||m<0||n<0);
p=(double)fac(n)/(fac(m)*fac(n-m));printf("p=%.0f\n",p);
}

递归法:

#include<stdio.h>
int fac(int x);
int main() {
	double p;
	int m,n;
	scanf("%d %d",&n,&m);
	p=(double)fac(n)/(fac(m)*fac(n-m));
	printf("p=%.0f\n",p);}
int fac(int x){
	if(x<0)
	return -1;
	else if(x==0||x==1)
	return 1;
	else
	return(x*fac(x-1));
}

运行结果
在这里插入图片描述

3.编写一个递归函数计算两个正整数的最大公约数。在主函数中输入两个正整数
m 和 n 的值,计算两个数的最大公约数和最小公倍数并输出。
(算法参考教材 P186 P7.7)

#include<stdio.h>
int gcd(int a,int b){
	int i;
	for(i=a;i>=1;i--)
	if(a%i==0&&b%i==0)
	break;
	return i;
}
int lcm(int a,int b)
{
	return a*b/gcd(a,b);
}
int main() {
	int m,n;
	scanf("%d %d",&m,&n);
	printf("最大公约数%d,最小公倍数%d\n",gcd(m,n),lcm(m,n));
	return 1;
}

在这里插入图片描述

4.编写一个判别素数(质数)的函数 int isPrime(int x)。在 main 函数中,输入一
个正整数 n,输出 1~n 之间的所有素数以及素数的个数
(算法参考教材 P187 P7.13)

#include<stdio.h>
int isPrime(int x)
{
int i;
if(x==1)
return 0;
for(i=2;i<x;i++)
if(x%i==0)
return 0;
return 1;
}
int main() {
	int n,i,sum=0;
	scanf("%d",&n);
	for(i=1;i<=n;i++){
	if(isPrime(i)){
	printf("%d ",i);
	sum++;}
	}
	printf("素数的个数:%d\n",sum);
	return 1;
}

在这里插入图片描述

5.在 main 函数中,输入一个正整数 n。对于 2~n 之间的每一个数,如果是合数,
则输出每个合数的所有质因子(利用上一题的 isPrime 函数)
如:n=12
输出: 4=2×2
6=2×3
8=2×2×2
9=3×3
10=2×5
12=2×2×3

#include<stdio.h>
int isPrime(int n)
{
	int i;
	if(n==1)
    return 0;
	for(i=2;i*i<=n;i++)
	        if(n%i==0)
		return 0;
	return 1;
}
void OutputPrimeFactor(int n)
{
	int i;
	printf("%d=",n);
	for(i=2;n>1;i++)
	{
		while(n%i==0)
		{
			printf("%d",i);
			n=n/i;
			if(n>1)
			     printf("×");

		}
	}
	printf("\n");
}
int main()
{
	int i,n;
	scanf("%d",&n);
	for(i=2;i<=n;i++)
	{
		if(isPrime(i)==0)
			OutputPrimeFactor(i);
	}
	return 0;
}

在这里插入图片描述

6、5 个水手在岛上发现了一堆椰子,先有第一个水手把椰子分成等量的 5 堆,还
剩了 1 个给了猴子,自己藏起一堆。然后第 2 个水手把剩下的 4 堆混合后重新分
为等量的 5 堆,还剩了 1 个给了猴子,自己藏起一堆。以后第三、四个水手依次
按此方法处理。最后,第 5 个水手把剩下的椰子分成等量的 5 堆后,同样剩下 1
个给了猴子。请用迭代法编程计算并输出原来这堆椰子至少有多少个?

#include<stdio.h>
int candivide(int x){
	int i;
	for(i=1;i<=5;i++){
		if((x-1)%5!=0)
		return 0;
        x=(x-1)/5*4;
	}
	return 1;
}
int main() {
	int i;
	for(i=1;;i++){
		if(candivide(i)){
		printf("%d",i);
		break;
		}
	}
}

在这里插入图片描述

7、在上题中,如果第 5 水手分得 255 个椰子,用递归的方法计算原来这堆椰子
的个数。

#include<stdio.h>
int beforeDivide(int n)
{
	if(n==5)
		return 255*5+1; 
	else
		return beforeDivide(n+1)/4*5+1;
 } 
int main()
{
	printf("%d\n",beforeDivide(1));
} 

在这里插入图片描述

8.有 m 个 A 和 n 个 B,用递归方法计算有多少种排列。
提示:假设用 P(m,n)表示 m 个 A 和 n 个 B 的排列数。假设第一个是 A,
则剩下 m-1 个 A 和 n 个 B,剩下的字母排列数是 p(m-1,n)。如果第 1 个是 B,
则剩下 m 个 A 和 n-1 个 B,剩下的排列数是 p(m,n-1)。所以有:
p(0,n) = 1
p(m,0)=1
p(m, n) = p(m-1,n) + (m, n-1)

#include<stdio.h>
int f(int x,int y)
{
if(!x||!y)
return 1;
return f(x-1,y)+f(x,y-1);
}
int main(){
while(1)
{
int n,m;
scanf("%d%d",&n,&m);
printf("%d\n",f(n,m));
break;
} 
return 0;
}

在这里插入图片描述

四、实验小结

在实验报告中记录各题实验代码及运行结果,针对实验中遇到的问题及其解
决方法、或尚未解决的问题、实验收获等,仔细撰写实验报告。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值