elsereturn(a);
}
思考:
在此题中,如果将读入 n个数的过程也放到被调函数中,程序应如何设计?
(提示,可将求最大数与最小数合平为一个函数进行考虑。
)
7-11编写程序,求两个数的最大的公约数及最小公倍数,要求用函数完成。
解:
#include"stdio.h"
voidmain()
{
inta,b,n1,n2;
intfun1(int,int),fun2(int,int,int);/*对函数的声明*/
printf("请输入两个数:
");
scanf("%d,%d",&a,&b);
n1=fun1(a,b);
n2=fun2(a,b,n1);/*此处n1为a,b的最大公约数*/
printf("%d和%d的最大公约数为%d\n",a,b,n1);
printf("%d和%d的最大公倍数为%d\n",a,b,n2);
}
fun1(inta,intb)
{
intt;
if(b>a){t=b;b=a;a=t;}
while(b!
=0)
{
t=a%b;
a=b;
b=t;
}
return(a);
}
fun2(inta,intb,intn)
{
return(a*b/n);
}
运行结果:
请输入两个数:
45,25
45和25的最大公约数为5
45和25的最大公倍数为225
思考:
如果将fun1函数与fun2函数放在main()函数的前面,对函数的声明是否可以略去?
7-12编写程序,分离出一个实数的整数部分与小数部分,要求用函数完成。
解:
#include"stdio.h"
voidmain()
{
intn;
floatf,x;
intfun1(float);
floatfun2(float,int);
printf("请输入实数x的值:
");
scanf("%f",&x);
n=fun1(x);
f=fun2(x,n);
printf("整数部分为%d,小数部分为%.6f\n",n,f);
}
intfun1(floatx)
{
intn;
n=x;//利用n的int数据类型实现取得x的整数部分
return(n);
}
floatfun2(floatx,intn)
{
floatf;
f=x-n;
return(f);
}
7-13编写程序,读一组正整数,输出每个数除1和本身的所有因子,如无因子则输出这个数的素数,要求用函数完成。
解:
#include"stdio.h"
voidmain()
{
inta,n,i;
voidfun1(int);
printf("请输入这组数的个数n的值:
");
scanf("%d",&n);
for(i=1;i<=n;i++)
{
printf("请输入第%d个数:
",i);
scanf("%d",&a);
fun1(a);
}
}
voidfun1(inta)
{
voidfun2();
inti,p=0;
for(i=2;i<=a/2;i++)
if(a%i==0){p=1;printf("%d",i);}
if(p==0)fun2();
printf("\n");
}
voidfun2()
{
printf("这个数是素数");
}
运行结果:
请输入这组数的个数n的值:
3
请输入第一个数:
10
25(第一个数的因子)
请输入第2个数:
24
2346812(第二个数的因子)
请输入第三个数:
19
这个数是素数
思考:
在main()函数中调用了fun1函数,在fun1函数中又调用了fun2函数,如何理解这种调用关系?
7-14编写程序,计算1!
+2!
+3!
+…+n!
的值,要求用函数完成。
解:
#include"stdio.h"
voidmain()
{
intn;
longs=0;
intfun(int);
printf("请输入n的值:
");
scanf("%d",&n);
s=fun(n);
printf("s=%d\n",s);
}
fun(intn)
{
longs=0,t=1;
inti;
for(i=1;i<=n;i++)
{
t=t*i;
s=s+t;
}
return(s);
}
运行结果:
请输入n的值:
5
s=153
思考:
当n的值很大时,阶乘累加式的值可能会超出计算机所表示的范围,应如何防止这种情况的发生呢?
7-15编写程序,计算排列组合的值,要求用函数完成。
解:
#include"stdio.h"
longintjf(intn)
{
inti;
longintt;
for(t=1,i=1;i<=n;i++)
t=t*i;
return(t);
}
longintcmn(intm,intn)
{
return(jf(m)/(jf(n)*jf(m-n)));
}
voidmain()
{
inti,n;
longsum=0;
printf("请输入n的值:
");
scanf("%d",&n);
for(i=3;i<=n;i++)
sum=sum+cmn(i,i-1);
printf("sum=%ld\n",sum);
}
运行结果:
请输入n的值:
8
sum=88
思考:
在此题中,cmn(intm,intn)函数完成了什么工作?
在main()函数中为何没有对它进行声明?
7-16编写四则运算(+、-、*、/)的训练程序,要求用函数完成。
解:
#include"stdio.h"
voidmain()
{
floata,b,d;
charc;
floatfun(float,float,char);
p:
printf("请输入操作数1,操作符,操作数2:
\n");
scanf("%f,%c,%f",&a,&c,&b);
if(c!
='+'&&c!
='-'&&c!
='*'&&c!
='/')
{
printf("输入格式错误\n");
gotop;
}
d=fun(a,b,c);
printf("%f%c%f=%f\n",a,c,b,d);
}
floatfun(floata,floatb,charc)
{
floatf;
switch(c)
{
case'+':
f=a+b;break;
case'-':
f=a-b;break;
case'*':
f=a*b;break;
case'/':
f=a/b;break;
}
return(f);
}
运行结果:
请输入操作数1,操作符,操作数2;
18.2,+,1.3
18.2+1.3=19.5
思考:
在此程序中“p:
--gotop;”是什么结构?
可否用循环语句替代实现?
起什么作用?
7-17编写程序,计算任意两个整数之间的素数,完数的个数,要求用函数完成。
解:
#include"stdio.h"
#include"math.h"
voidmain()
{
inta,b;
intfun1(int,int);
intfun2(int,int);
printf("请输入两个整数a,b(a
");
scanf("%d,%d",&a,&b);
fun1(a,b);
fun2(a,b);
}
fun1(inta,intb)//求两个数之间的素数
{
inti,j,k,p=0;
for(i=a;i<=b;i++)
{
k=(int)sqrt(i);
for(j=2;j<=k;j++)
if(i%j==0)break;
if(j>=k+1)p=p+1;
}
printf("素数的个数为%d\n",p);
}
fun2(inta,intb)//求两个数之间的完数
{
inti,j,s,m=0;
for(i=a;i<=b;i++)
{
for(s=0,j=1;j
if(i%j==0)s=s+j;
if(s==i)m=m+1;
}
printf("完数的个数为%d\n",m);
}
思考:
如果要把所有的素数和完数也输出,程序应如何修改?
7-18编写成绩处理程序,求100个同学4们课程的总成绩与平均成绩,要求用函数完成。
解:
#include"stdio.h"
voidmain()
{
floats=0,average,a;
inti;
floatfun1(float,float);
for(i=1;i<=100;i++)
{
scanf("%f",&a);
s=fun1(s,a);
}
average=s/100;
printf("总成绩为%8.2f,平均成绩为%6.2f\n",s,average);
}
floatfun1(floats,floata)
{
s=s+a;
return(s);
}
思考:
此程序值实现了一门课程的成绩处理功能,若要对4门课程的成绩同时进行处理,应如何设计?
如果将计算平均成绩的语句也放在fun()函数中,会遇到什么问题?
7-19编写程序,用递归方法求两个数的最大公约数。
解:
#include"stdio.h"
voidmain()
{
inta,b,c;
intfun(int,int);
printf("请输入两个数:
");
scanf("%d,%d",&a,&b);
c=fun(a,b);
printf("%d和%d的最大公约数是%d\n",a,b,c);
}
fun(inta,intb)
{
intt;
if(b>a)
{
t=a;
a=b;
b=t;
}
t=a%b;
a=b;
b=t;
if(b==0)return(a);
a=fun(a,b);
}
运行结果:
请输入两个数:
36,24
36和24的最大公约数是12
思考:
递归函数的两个主要特点是什么?
7-20编写程序,用递归方法求Fibonacci数列的前n项。
解:
#include"stdio.h"
voidmain()
{
intn,i;
intfun(int);
printf("请输入n的值:
");
scanf("%d",&n);
printf("\n1,1");
for(i=3;i<=n;i++)
{
printf("%d",fun(i));
if(i%10==0)printf("\n");
}
}
fun(intn)
{
intm;
if(n>2)m=fun(n-1)+fun(n-2);
elsem=1;
return(m);
}
运行结果:
请输入n的值:
8
1,1,2,3,5,8,13,21
思考:
如果欲将前n的和也求出,程序应如何改动?
7-21用递归方法解第六章习题18的猴子吃桃子的问题。
解:
#include"stdio.h"
voidmain()
{
inti,m;
intfun(int,int);
m=fun(1,10);
printf("第一天摘的桃子数为%d\n",m);
}
fun(intn,intp)
{
intm;
if(p==1)return(m);
else
{
m=(n+1)*2;
n=m;
p=p-1;
m=fun(n,p);
}
}
运行结果:
第一天摘桃子的数为1534
思考:
与6-18习题的程序比较,此程序有哪些特点?
7-22用递归方法将某十进制整数转换成二进制数。
解:
#include"stdio.h"
fun(intn)
{
inti,k;
while
(1)
{
i=n%2;
k=n/2;
if(k>0)fun(k);
{
printf("%d",i);
break;
}
}
}
voidmain()
{
intm;
printf("请输入十进制数m的值:
");
scanf("%d",&m);
fun(m);
printf("\n");
}
运行结果:
请输入十进制数m的值:
123
1111011
思考:
如果不用递归的方法来解决此问题,将会遇到什么困难?
(各位数的存储如何解决?
)
7-23编写程序,进行下列数制转换,要求采用模块化程序设计。
(1)十进制转二进制
(1)十进制转八进制
(1)十进制转十六进制
(1)二进制转十进制
(1)八进制转十进制
(1)十六进制转十进制
进一步请考虑对实型数据进行转换。
解:
此题有一定的难度,且内容较多,这里只给出第(4)小题针对正整数的两种解法,其余由读者自行设计。
(4)/*解法一:
用位移运算与循环控制实现*/
#include"stdio.h"
voidmain()
{
unsignedintgetval(unsignedint);
unsignedinta;
printf("请输入一个以八进制表示的二进制数:
");
scanf("%o",&a);
printf("转换成十进制为:
%d\n",getval(a));
}
unsignedintgetval(unsignedintvalue)
{
inti,j;
unsignedintz,a,b;
longintq;
z=0;
b=~(~0<<1);
for(i=0;i<=15;i++)
{
q=1;
for(j=0;j<15-i;j++)
q=q*2;//计算相应位的二进制幂次
a=value>>(15-i);
a=a<<5;
a=a>>5;
a=b&a;//取得二进制表示的最高位
printf("%o\n",a);//输出二进制的形式
z=z+a*q;
}
return(z);
}
/*解法二:
用位移运算与递归算法实现*/
#include"stdio.h"
intn=1;
unsignedintz=0,b;
longintq=1;
voidmain()
{
unsignedintgetval(unsignedint);
unsignedinta;
b=~(~0<<1);
printf("请输入一个以八进制表示的二进制数:
");
scanf("%o",&a);
printf("转换成十进制为:
%d\n",getval(a));
}
unsignedintgetval(unsignedinta)
{
unsignedintx;
x=a<<(16-n);
x=x>>15;
x=x&b;//取得二进制表示的最低位
z=z+x*q;
q=2*q;
if(n==15)return(z);
n++;
getval(a);
}
思考:
在此题的各问题解决过程中,你遇到的主要问题是否是如何取得给定数据的