第7章 用函数实现模块化程序设计

发布于:2022-11-09 ⋅ 阅读:(17) ⋅ 点赞:(0) ⋅ 评论:(0)

某不知名学校(dgut)C语言作业 这次的作业感觉比上次难一点

而且 这个输入输出是真的恶心 这次老师也没有答案 我只能发自己代码了

这次考的大部分都是数学感觉 语法上的难度不高

第一题

计算函数

按下列要求分别写出两个函数。

(1) 计算n!,计算公式为n!=1×2×3×……×n,函数原型为double fac(int n);

(2) 调用上述函数计算

计算公式如下,函数原型为double cmk(int m, int k);在主函数中调用这两个函数计算 的结果。

分析:求阶乘是一个经典的递归用法 所以这里我也用了递归 当然 用循环也可以写(推荐去尝试一波 感受二者的差别) 不过代码没那么简洁(装13) 重点是函数的实现 假设5的阶乘就是5*4*3*2*1 所以我们依次乘以当前数的n-1就好

在函数里面调用 函数 就是递归 上课应该讲了

个人代码如下

# include <stdio.h>

double fac(int n){
	if(n==1)return 1;
	else return n*fac(n-1);//这里是递归
}

double cmk(int m, int k){
  
	return fac(m)/(fac(k)*fac(m-k));//这里是调用函数
	 
}



int main()
{
	int n,m,k;
	scanf("%d%d",&m,&k);
	
	printf("%.0lf",cmk(m,k));//保留整数
	

	return 0;
}

输出要整数 我懒得强制转化就直接.0f了 所以说这个作业不过输入输出是真的恶心

第二题

【提高题】找零金额

设人民币的面额有(以元为单位):1分、2分、5分、1角、2角、5角、1元、2元、5元、10元、20元、50元。编写函数void change(double m,double c);其中m为商品价格,c为顾客付款,函数能输出应给顾客找零金额的各种面额人民币的张数,且张数之和为最小。要求在主函数中输入商品价格和顾客付款,调用函数得到结果。

分析:题目说了可以用贪心算法(但是tnnd你让大二过来大二都还没学贪心)贪心是一种基础算法

有兴趣的可以去逝逝,总之我感觉现在才学到函数就让学生用贪心 怕不是要上天

另一个做法是啥 它说了是枚举 也就是用循环一个个遍历一遍 蠢方法 但也确确实实做得出来

个人枚举方法如下:所以面额化成分 然后依次从大到小计数 

代码如下

#include<stdio.h>

void change(double m,double c){
    double sum=c-m;
    
    int  cnt1=0,cnt2=0,cnt3=0,cnt4=0,cnt5=0,cnt6=0,cnt7=0,cnt8=0,cnt9=0,cnt10=0,cnt11=0,cnt12=0;
    sum*=100;//转化成 分 为单位
    //printf("%lf\n",sum);
    while(sum>=5000){
        sum=sum-5000;cnt1++;//每个cnt单独计数不同纸币面额
        if(sum==0)break;
    }
    while(sum>=2000){
        sum=sum-2000;cnt2++;
        if(sum==0)break;
    }
    while(sum>=1000){
        sum=sum-1000;cnt3++;
        if(sum==0)break;
    }
    while(sum>=500){
        sum=sum-500;cnt4++;
        if(sum==0)break;
    }
    while(sum>=200){
       sum=sum-200;cnt5++;
       if(sum==0)break;
    }
    while(sum>=100){
        sum=sum-100;cnt6++;
        if(sum==0)break;
    }
    while(sum>=50){
        sum=sum-50;cnt7++;
        if(sum==0)break;
    }
    while(sum>=20){
        sum=sum-20;cnt8++;
    }
    while(sum>=10){
        sum=sum-10;cnt9++;
        if(sum==0)break;
    }
    while(sum>=5){
        sum=sum-5;cnt10++;
        if(sum==0)break;
    }
    while(sum>=2){
        sum=sum-2;cnt11++;
        if(sum==0)break;
    }
    while(sum>=1){
        sum=sum-1;cnt12++;
        if(sum==0)break;
    }
    printf("50元:%d\n20元:%d\n10元:%d\n5元:%d\n2元:%d\n1元:%d\n5角:%d\n2角:%d\n1角:%d\n5分:%d\n2分:%d\n1分:%d\n",cnt1,cnt2,cnt3,cnt4,cnt5,cnt6,cnt7,cnt8,cnt9,cnt10,cnt11,cnt12);
    
}//shi山代码写得想吐 这老师还故意多几种面额给你 然后到时自己再用贪心在学生面前装一下

int main(){
    double m,c;
    scanf("%lf%lf",&m,&c);
    change(m,c);
    
    
    
    
    return 0;
}

跟shi山一样的代码哈哈哈哈 等我有时间补个贪心写法的代码

第三题

回文数

寻找300以内的所有的对称回文数并输出。回文数是指某数与其反序数相等,如5、131、1551、345676543.对称回文数指某数与其平方都是回文数。例如,n=11时,112=121;n=111时,1112=12321。 编写函数int huiwen(long n),判断n是否回文数,如是返回1,否则返回0。 在main函数中遍历300以内的数,寻找对称回文数并输出。

分析:这一题有很多种方法做 比如用/或者%取分割数字 或者用数组存储再倒序 或者直接当作字符翻转 如果是c++更是直接用reverse函数 这里先用一个最简单的方法

下面是个人代码(分割数字实现

#include <stdio.h>


int huiwen(long n) {
	int g, k;
	g = 0;
	k = n;
	while (k) {
		g = g * 10 + k % 10;//分别取出单个数字 详情见上次作业
		k = k / 10;
	}
	if (g == n)//组合成的数组还跟原来一样 则是回文数
		return 1;
	else
		return 0;
}





int main() {
	for (int i = 1; i < 301; i++) {
		if (huiwen(i) && huiwen(i * i))//返回1则执行if语句 这是简便写法
			printf("%d ", i); //i*i是回文数的平方 也要满足是回文数的条件
	}

	return 0;
}

第四题

寻找[0,100]区间内所有的孪生素数

寻找[0,100]区间内所有的孪生素数并输出。孪生素数是指差为2的两个素数,例如,3和5,5和7。 编写函数int prime(int n),判断素数。 编写main函数,接收键盘输入的m和n的值,寻找[m,n]区间内所有的孪生素数并输出,并将孪生素数的对数输出,若区间内没有孪生素数,则输出无孪生素数信息。

分析:听起来很复杂 但是实际上也就是要写一个判断素数的函数而已 (只能被1和自己整除)

因此我们我们可以遍历2~n-1 看看有没有它的因数 有则不是素数返回0 没有则是素数返回1

最后在遍历一遍1~100 满足是素数和相隔为2 的条件即可

个人代码如下

#include <stdio.h>



int prime(int n) {
	for (int i = 2; i < n  ; i++) {
		if (n % i == 0)//有因数 返回0
			return 0;
	}
	return 1;//没有 返回1
}


int main() {

	for (int i = 0; i <= 98; i++) {  //遍历到98就行 因为i+2等于100
		if (prime(i) && prime(i + 2))//返回1则执行if语句 这是简便写法
			printf("%d,%d\n", i, i + 2);
	}

	return 0;
}

第五题

哥德巴赫猜想

任何一个大于4的偶数都可以表示为两个素数之和。验证[6,50]之间的偶数 写函数void guest(int n),找到并输出所有素数对,每个素数对之和均等于偶数n。 编写main函数,遍历[6,50]间所有的偶数,调用guest函数查找并输出素数对。 输出格式如下: 40=3+3740=11+2940=17+23(换行)

分析 这题也是看起来复杂 但其实就是要写一个判断素数的函数 跟上一题一样的函数(你也可以用sqrt和n/i来减少遍历时间 不过好像c里面的sqrt函数每次遍历都会被调用 效率还更慢了

另一个难点是输出 要保证字典序输出 就是小数字在大的前面 这里就需要注意自己的循环输出了

个人代码如下:

#include<stdio.h>
#include<math.h> //开方函数头文件
int prime(int m)//该函数判断m是否为素数,如果是则返回1,
{
	int i,flag=1;
	for(i=2;i<=sqrt(m)&&flag==1;i++)
	if(m%i==0)flag=0;
	return flag;
}
int main()
{
    int m,n;
	for(int i=6;i<=50;i+=2){  //题目范围i+=2 保证为偶数
	    for(m=2;m<50;m++){    //暴力查找素数
	        for(n=50-m;n>=m;n--){  //注意循环方向
	            if(prime(m)&&prime(n)&&i==m+n){
	                printf("%-d=%d+%d ",i,m,n);//-是为了输出对齐 可能系统会卡你输出
	                
	                
	            }
	        }
	    }printf("\n");//每行回车 注意回车位置
	    
	}
	
  
	
	return 0;
}

第六题

计算吃货协会来了几个新人

学校里的“吃货协会”准备搞一个聚会,已经知道现有会员N人,把会员从1到N编号,其中会长的号码是N号,凡是和会长是老朋友的,那么该会员的号码肯定和N有大于1的公约数,否则都是新朋友,现在会长想知道究竟有几个新朋友?请你编程序帮会长计算出来(N用键盘输入)。 编写函数int gcd(int a,int b),求a和b的最大公约数。 编写main函数,接收键盘输入的N的值,寻找[1,N-1]区间内的与N的最大公约数为1的数字,输出个数。

分析:本题意图很简单 就是要写一个判断公约数的函数 关于判断的方法—辗转相除法(欧几里得算法)已经在上一次作业写过了 这里就不过多赘述

个人代码如下

 # include <stdio.h>
 
 int gcd(int a,int b){
 		
	int r=a%b;	//辗转相除
	while(r!=0){
	r=a%b;
	a = b;
	b = r;
	r = a%b;
}
	
	return b;/返回最后一个除数
 }

int main()
{
	int n;
	int cnt=0;//计数器
	scanf("%d",&n);
	for(int i=1;i<n;i++){
		if(gcd(n,i)==1){  //如果为1 则是新朋友
			cnt++;//一个新朋友就+1
		}
	}
	printf("%d",cnt);

	return 0;
}

第七题

用函数输出字符

输出以下结果,用函数调用实现 ****************** How do you do! *****************

分析:越往后面题目越简单 但老师偏偏搞个闯关模式必须先做前面的题 恶心一下同学们

其实这输出要换行 题目也不说 

个人代码如下:

# include <stdio.h>

void print(){
	printf("******************\n  How do you do!\n******************");
}


int main()
{
	print();

	return 0;
}

第八题

用函数求两数之和

输入两个实数,用一个函数求出它们之和,保留两位小数

分析:后面几题都很水 感觉没什么好分析的了 看看代码就明白了 同时写的时候注意一下数据类型就好

个人代码如下:

# include <stdio.h>

double add(double a,double b){
	return a+b;
}


int main()
{
	double a,b;
	scanf("%lf %lf",&a,&b);
	printf("%.2lf",add(a,b));

	return 0;
}

第九题

编写函数计算圆柱体体积

编写自定义函数 volume_cy,功能是求圆柱体的体积(v=3.14*r2*h),要求圆柱体的高 h 和底半径 r 在主函数中输入,圆柱体的体积在主函数中做输出。h,r 均为 float型变量。

分析:水题 注意一定要用float就行

个人代码如下:

# include <stdio.h>
#define pi 3.14

float volume_cy(float h,float r){
	return pi*r*r*h;
}


int main()
{
	float h,r;
	scanf("%f %f",&r,&h);
	printf("%f",volume_cy(h,r));

	return 0;
}

第十题

编写函数求梯形面积

定义函数 areaT,功能是求梯形面积。要求在主函数中输入上底(用变量 a存储)、下底(用变量 b 存储)、和高(用变量 h 存储),在主函数中调用函数 areaT,输出梯形面积(用变量 s 存储)的值。其中,变量 a,b,h,s 数据类型均为 double。公式:s=(a+b)*h/2

分析:水题 看代码

# include <stdio.h>


double areaT(double a,double b,double h){

	
	return (a+b)*h/2.0;//注意加括号
}


int main()
{
	double a,b,h;
	scanf("%lf %lf %lf",&a,&b,&h);
	//areaT(a,b,h);
	printf("%.2lf",areaT(a,b,h));

	return 0;
}

感觉对你有帮助的话 动动小手点个赞呗~

作业做完了 耶耶耶!