C语言程序设计第3版何钦铭 颜 晖 第10章函数与程序结构.docx
《C语言程序设计第3版何钦铭 颜 晖 第10章函数与程序结构.docx》由会员分享,可在线阅读,更多相关《C语言程序设计第3版何钦铭 颜 晖 第10章函数与程序结构.docx(15页珍藏版)》请在冰豆网上搜索。
C语言程序设计第3版何钦铭颜晖第10章函数与程序结构
第10章函数与程序结构
【练习10-1】使用递归函数计算1到n之和:
若要用递归函数计算sum=1+2+3+…+n(n为正整数),请写出该递归函数的递归式子及递归出口。
试编写相应程序。
解答:
递归式子:
sum(i)=sum(i-1)+i;
递归出口:
sum(i)=0;
【练习10-2】请完成下列宏定义:
①MIN(a,b)求a,b的最小值
②ISLOWER(c)判断c是否为小写字母
③ISLEAP(y)判断y是否为闰年
④CIRFER(r)计算半径为r的圆周长
解答:
1MIN(a,b):
求a,b的最小值。
#defineMIN(a,b)(a
a:
b
2ISLOWER(c):
判断c是否为小写字母。
#defineISLOWER(c)(c>='a'&&c<='z')
3ISLEAP(y):
判断y是否为闰年。
#defineISLEAP(y)(y%4==0&&y%100!
=0)||y%400==0)
4CIRFER(r):
计算半径为r的圆周长。
#definePI3.14159
#defineCIRFER(r)2*PI*(r)
【练习10-3】分别用函数和带参宏实现从3个数中找出最大数,请比较两者在形式上和使用上的区别。
解答:
(1)函数实现
intmax(intx,inty,intz)
{
intt;
if(x>=y)
if(x>=z)t=x;
elset=z;
else
if(y>=z)t=y;
elset=z;
returnt;
}
(2)宏实现
#defineMAX(x,y,z)x>=y?
(x>=z?
x:
z):
(y>=z?
y:
z)两者在定义形式上完全不同。
使用上函数是在执行时,从主调函数转到函数max(),然后再返回到主调函数,函数体始终存在;而宏是在编译预处理时,用条件表达式去替换
MAX(intx,inty,intz),等程序执行时,执行的是条件表达式,而不再存在MAX(intx,inty,intz)的式子。
习题10
一、选择题
1.要调用数学函数时,在#include命令行中应包含C。
A.”stdio.h”B.”string.h”C.”math.h”D.”ctype.h”
2.对于以下递归函数f,调用f(4),其返回值为A。
intf(intn)
{if(n)returnf(n-1)+n;
elsereturnn;
}
A.10B.4C.0D.以上均不是
3.执行下列程序:
#defineMA(x,y)(x*y)
i=5;
i=MA(i,i+1)–7;
后变量i的值应为B。
A.30B.19C.23D.1
4.宏定义“#defineDIV(a,b)a/b”,经DIV(x+5,y-5)引用,替换展开后是A。
A.x+5/y-5B.(x+5/y–5)
C.(x+5)/(y-5)D.(x+5)/(y-5);
5.定义带参数的宏“#defineJH(a,b,t)t=a;a=b;b=t”,对两个参数a、b的值进行交换,下
列表述中哪个是正确的C。
A.不定义参数a和b将导致编译错误B.不定义参数a、b、t将导致编译错误
C.不定义参数t将导致运行错误D.不需要定义参数a、b、t类型
6.执行下面程序,正确的输出是A。
intx=5,y=7;
voidswap()
{intz;
z=x;x=y;y=z;
}
intmain(void)
{
intx=3,y=8;
swap();
printf("%d,%d\n",x,y);
return0;
}
A.3,8B.8,3C.5,7D.7,5
7.下面说法中正确的是A。
A.若全局变量仅在单个C文件中访问,则可以将这个变量修改为静态全局变量,以降低模块间的耦合度
B.若全局变量仅由单个函数访问,则可以将这个变量改为该函数的静态局部变量,以降低模块间的耦合度
C.设计和使用访问动态全局变量、静态全局变量、静态局部变量的函数时,需要考虑变量生命周期问题
D.静态全局变量使用过多,可那会导致动态存储区(堆栈)溢出
2、填空题
1.C语言的编译预处理功能主要包括_条件编译_、_宏定义_和_文件包含_。
2.执行完下列语句段后,i的值为5。
inti;
intf(intx)
{
return((x>0)?
f(x-1)+f(x-2):
1);
}
i=f(3);
3.下列程序段A与B功能等价,请填写程序段B中相应语句。
程序段A:
intf(intn)
{if(n<=1)
returnn;
else
returnf(n-1)+f(n-2);
}
程序B:
intf(intn)
{_intt,t0,t1;_
t0=0;t1=1;t=n;
while(_n>1_){
t=_t0+t1_;
t0=t1;
t1=t;
n--;
}
return_t;_
}
5.下面程序用于计算f(k,n)=1k+2k+…+nk,其中power(m,n)求mn。
请填写程序中相应语句。
#include
intpower(intm,intn)
{inti;
intp=1;
for(i=1;i<=n;i++)
p=p*m;
returnp;
}
intf(intk,intn){
inti;
ints=0;
for(i=1;i<=n;i++)
s=s+power(i,k);
returns;
}
intmain(void)
{intk,n;
scanf(“%d%d”,&k,&n);
printf(“f(%d,%d)=%ld”,k,n,f(k,n));
return0;
}
5.下列递归程序的输出结果为g=4,g=3,k=6。
#include
intfib(intg)
{switch(g){
case0:
return0;
case1:
case2:
return2;
}
printf("g=%d,",g);
returnfib(g-1)+fib(g-2);
}
intmain(void)
{
intk;
k=fib(4);
printf("k=%ld\n",k);
return0;
}
6.下列语句的运算结果为_7,-13____。
#defineF(x)x-2
#defineD(x)x*F(x)
printf("%d,%d",D(3),D(D(3)));
三、程序设计题
1.判断满足条件的三位数:
编写一个函数,利用参数传入一个3位数n,找出101~n间所有满足下列两个条件的数:
它是完全平方数,又有两位数字相同,如144、676等,函数返回找出这样的数据的个数。
试编写相应程序。
解答:
#include
#include
intfun(intn);
intmain(void)
{
intn;
printf("Inputn:
");
scanf("%d",&n);
printf("total=%d\n",fun(n));
return0;
}
intfun(intn)
{
inti,d=0;
for(i=101;i<=n;i++)
if(((int)sqrt(i)*(int)sqrt(i))==i){
if(i/100==(i/10)%10||i/100==i%10||(i/10)%10==i%10)
d++;
}
returnd;
}
2.递归求阶乘和:
输入一个整数n(n>0且n<=10),求1!
+2!
+3!
+……n!
。
定义并调用函数fact(n)计算n!
,函数类型是double。
试编写相应程序。
解答:
#include
doublefact(intn);
intmain(void)
{
intn;
printf("Inputn:
");
scanf("%d",&n);
printf("1~%d的阶乘和:
%.0lf",n,fact(n));
return0;
}
doublefact(intn)
{
inti;
doubleresult=1;
if(n==1)
result=1;
else{
for(i=1;i<=n;i++)
result=result*i;
result=result+fact(n-1);
}
returnresult;
}
3.递归实现计算xⁿ:
输入实数x和正整数n,用递归函数计算xⁿ的值。
试编写相应程序。
解答:
#include
doublepower(doublex,intn);
intmain(void)
{
doublex;
intn;
printf("Inputx:
");
scanf("%lf",&x);
printf("Inputn:
");
scanf("%d",&n);
printf("%lf的%d次方=%lf",x,n,power(x,n));
return0;
}
doublepower(doublex,intn)
{
doubleresult;
if(n==1)
result=x;
else
result=x*power(x,(n-1));
returnresult;
}
4.递归求式子和:
输入实数x和正整数n,用递归的方法对下列计算式子编写一个函数。
f(x,n)=x-x²+x³-x4+…+(-1)n-1xⁿ(n>0)
试编写相应程序。
解答:
#include
#include
doublef(doublex,intn);
intmain(void)
{
intn;
doublex;
printf("Inputx:
");
scanf("%lf",&x);
printf("Inputn:
");
scanf("%d",&n);
printf("f(%lf,%d)=%lf\n",x,n,f(x,n));
return0;
}
doublef(doublex,intn)
{
if(n==1)
returnx;
else
returnpow(-1,n-1)*pow(x,n)+f(x,n-1);
}
5.递归计算函数ack(m,n):
输入m和n。
编写递归函数计算Ackermenn函数的值:
n+1m=0
ack(m,n)=ack(m-1,1)n=0&&m>0
ack(m-1,ack(m,n-1))m>0&&n>0
试编写相应程序。
解答:
#include
intAck(intm,intn);
intmain(void)
{
intm,n;
intresult;
scanf("%d%d",&m,&n);
result=Ack(m,n);
printf("Ackerman(%d,%d)=%d\n",m,n,result);
return0;
}
intAck(intm,intn)
{
if(m==0)returnn+1;
elseif(n==0&&m>0)
returnAck(m-1,1);
elseif(m>0&&n>0)
returnAck(m-1,Ack(m,n-1));
}
6.递归实现求Fabonacci数列:
用递归方法编写求斐波那契数列的函数,函数类型为整型,并写出相应主函数。
斐波那契数列的定义如下。
试编写相应程序。
f(n)=f(n-2)+f(n-1)(n>1)其中f(0)=0,f
(1)=1。
解答:
#include
longfib(intn);
intmain(void)
{
intn;
printf("Entern:
");
scanf("%d",&n);
printf("fib(%d)=%ld\n",n,fib(n));
return0;
}
longfib(intn)
{
longres;
if(n==0)res=0;
elseif(n==1)
res=1;
else
res=fib(n-2)+fib(n-1);
returnres;
}
7.递归实现十进制转换二进制:
输入一个正整数n,将其转换为二进制输出。
要求定义并调用函数dectobini(n),它的功能是输出n的二进制。
试编写相应程序。
解答:
#include
intdectobini(intn);
intmain(void)
{
intn;
printf("Inputn(十进制整数):
");
scanf("%d",&n);
printf("输出二进制:
%d",dectobini(n));
return0;
}
intdectobini(intn)
{
intresult;
if(n==0)
result=0;
else
result=dectobini(n/2)*10+n%2;
returnresult;
}
8.递归实现顺序输出整数:
输入一个正整数n,编写递归函数实现对其进行按位顺序输出的递归函数。
试编写相应程序。
解答:
#include
intinorder(intn);
intmain(void)
{
intn;
printf("Inputn:
");
scanf("%d",&n);
printf("按位顺序输出:
%d\n",inorder(n));
return0;
}
intinorder(intn)
{
if(n<10)returnn;
else
return(inorder(n/10)*10+n%10);
}
9.输入n(n<10)个整数,统计其中素数的个数。
要求程序有两个文件组成,一个文件中编写main函数,另一个文件中编写素数判断的函数。
使用文件包含的方式实现。
试编写相应程序。
解答:
10.三角形面积为:
area=
s=(a+b+c)/2
其中a、b、c分别是三角形的3条边。
请分别定义计算s和area的宏。
再使用函数实现,比较两者在形式上和使用上的区别。
解答:
(1)使用宏实现
#include
#include
#defineS(a,b,c)((a)+(b)+(c))/2
#defineAREA(s,a,b,c)sqrt((s)*((s)-(a))*((s)-(b))*((s)-(c)))
intmain(void)
{
doublea,b,c,s;
printf("inputa,b,c:
");
scanf("%lf%lf%lf",&a,&b,&c);
s=S(a,b,c);
printf("s=%lf,area=%lf\n",s,AREA(s,a,b,c));
return0;
}
(2)使用函数实现
#include
#include
doublef1(doublea,doubleb,doublec)
{
return(a+b+c)/2;
}
doublef2(doubles,doublea,doubleb,doublec)
{
returnsqrt(s*(s-a)*(s-b)*(s-c));
}
intmain(void)
{
doublea,b,c,s;
printf("inputa,b,c:
");
scanf("%lf%lf%lf",&a,&b,&c);
s=f1(a,b,c);
printf("s=%lf,area=%lf\n",s,f2(s,a,b,c));
return0;
}