第六章 循环结构程序设计.docx
《第六章 循环结构程序设计.docx》由会员分享,可在线阅读,更多相关《第六章 循环结构程序设计.docx(16页珍藏版)》请在冰豆网上搜索。
第六章循环结构程序设计
6-1.比较while语句、do–while语句和for语句的异同。
答:
(1)while语句、do-while语句用于条件循环,for语句用于计数循环。
(2)while语句、for语句是先判断循环条件,后执行循环体,如果循环条件一开始就不成立,则循环体一次也不被执行;而do-while语句是是先执行循环体,后判断循环条件,所以循环体至少被执行一次。
(3)知道循环的次数可选用for语句实现循环,不知道循环的次数可选用while语句或do-while语句实现循环.
(4)一般而言,三种循环语句可等价实现.
6-2仔细阅读下面的程序,指出程序的运行结果.
#include
voidmain()
{inti;
for(i=0;++i;i<5)
{if(i==3)
{printf("%d\n",++i);
break;
}
printf("%d\n",++i);
}
}
答:
2
4
思考:
语句“for(“i=0;++i;i<5”)在编译时为何会给出语法警告错误?
当将其改为“for(i=0;i<5;++i)”时,运行结果又将如何?
6-3仔细阅读下面的语的程序,指出程序的运行结果。
#include"stdio.h"
voidmain()
{inti,a=0;
for(i=1;i<=5;i++)
{do
{i++;
a++;
}while(i<3);
}
i++;
printf("a=%d,i=%d",a,i);
}
答:
a=3,i=7
思考:
在for循环中嵌套着do-while循环,那么do-while循环中对i的修改会对for循环产生影响吗?
6-4编写程序,用1000个单词”computer”填充屏幕,每行60个.
解:
#include
voidmain()
{inti;
for(i=1;i<=1000;i++)
{printf("computer.");
if(i%60==0)printf("\n");
}
}
思考:
在for循环中,”if(i%60==0)printf(“\n”);”语句的作用是什么?
没有此语句将会是什么状况?
6-5输入一行字符(以$结束),统计其中的数字字符、空格字符出现的次数。
解:
#include
voidmain()
{charc;
intd=0,s=0;
printf("请输入字符(当输入时结束):
");
while((c=getchar())!
='$')
{
if(c>='0'&&c<='9')s++;
if(c=='')d++;
}
printf("数字字符出现的次数为%d\n",d);
printf("空格字符出现的次数为%d\n",s);
}
若输入字符:
12345abcd678xyz$
则运行结果为:
数字字符出现的次数为8
空格字符出现的次数为4
思考:
此题中的循环次数是如何控制的?
有何特点?
6-6编写程序,求1000以内的奇数之和及偶数之和。
解:
#include
voidmain()
{longn=0,m=0;
inti;
for(i=1;i<1000;i++)
{if(i%2==0)n=n+i;
elsem=m+i;
}
printf("奇数之和为%ld\n",m);
printf("偶数之和为%ld\n",n);
}
运行结果:
奇数之和为250000
偶数之和为249500
思考:
在此题中为何选用for循环进行控制?
用while循环或do-while循环是否也可以?
6-7计算π,计算公式π/4=1-1/3+1/5-1/7+…直到最后一项的绝对值小于
为止。
解:
#include
#include
voidmain()
{ints=1;
floatn=1.0,t=1,pi=0;
while(t>1e-6)
{pi=pi+t*s;
n=n+2;
s=-s;
t=1/n;
}
pi=pi*4;
printf("pi=%f\n",pi);
}
运行结果:
pi=3.141594
思考:
在此题中为何不选用for循环进行控制,而选用while循环呢?
6-8编写程序,求任意两个整数之间的所有素数。
解:
#include
#include"math.h"
voidmain()
{intn,m,i,j,k,p=0;
printf("请输入两个整数m,n(m");
scanf("%d,%d",&m,&n);
for(i=m;i<=n;i++);
{k=sqrt(n);
for(j=2;j<=k;j++)
if(i%j==0)break;
if(j>=k+1){printf("%d",i);p=p+1;}
if(p%10==0)printf("\n");
}
printf("\n");
}
思考:
此题中若输入的两个整数m,n分别为13,100时,13这个素数是否被输出,为什么?
6-9编写程序,求任意两个整数之间的所有能被3、4、5同时整除的数。
解:
#include
voidmain()
{intn,m,i;
printf("请输入两个整数m,n(m");
scanf("%d,%d",&m,&n);
for(i=m;iif((i%3==0)&&(i%4==0)&&(i%5==0))//或写为if(i%60==0)
printf("%d\n",i);
思考:
如果要分析输出,每行输出5个数,应该怎么修改程序?
6-10编写程序,求1000至9999之间的回文数.回文数是指正读与反读都一样的数,如1221.
解:
#include
voidmain()
{intn,i,j;
for(i=1000;i<=9999;i=i+1000)
{for(j=0;j<=9;j++)
{n=i+j*100+j*10+i/1000;
printf("%d",n);
}
printf("\n");
}
}
运行结果:
1001111112211331144115511661177118811991
2002211222222332244225522662277228822992
3003311332233333344335533663377338833993
4004411442244334444445544664477448844994
5005511552255335544555555665577558855995
6006611662266336644665566666677668866996
7007711772277337744775577667777778877997
8008811882288338844885588668888888888998
9009911992299339944995599669999999999999
思考:
在此题中,内、外循环各起什么作用?
是否可以交换?
如果用if语句设计程序,数据的各位数(个位、十位、百位、千位)应该如何分离?
6-11 编写程序,判断某一个整数是否为完数。
完数是指其因子之和等于自身的整数,如6=1+2+3请进一步考虑,求任意两个整数之间的所有完数。
解:
#include
voidmain()
{intn,i,k=0;
printf("请输入整数:
");
scanf("%d",&n);
for(i=1;i<=n;i++)
if(n%i==0)k=k+i;
if(n==k)printf("%d是完数\n",n);
elseprintf("%d不是完数\n",n);
}
运行结果:
请输入整数:
28
28是完数
思考:
变量k在此题中起什么作用?
初值为何要被赋0?
循环语句for”(i=1;i<=n;i++)”中的判断式”i注:
1000以内的完数有6=1+2+3,28=1+2+4+7+14,496=1+2+4+8+16+31+62+124+248.
6-12编写程序,以上三角形式输出九九乘法表。
解:
#include
voidmain()
{intj,i;
printf("%4c",'*');
for(i=1;i<=9;i++)
{for(j=1;j<=9;j++)
printf("%4d",i*j);
printf("\n");
}
}
运行结果:
*123456789
1123456789
24681012141618
39121518212427
4162024283236
52530354045
636424854
7495663
86472
981
思考:
如果希望输出下三角形式的九九乘法表,程序应如何改动?
*123456789
11
224
3369
4481216
5510152025
661218243036
77142128354249
8816243240485664
991827364554637281
6-13 编写程序,计算1!
+2!
+3!
+…+n!
的值,n从键盘输入。
解:
#include
voidmain()
{longsum=0,t=1;
intn,i;
printf("请输入整数n:
");
scanf("%d",&n);
for(i=1;i<=n;i++)
{
t=t*i;
sum=sum+t;
}
printf("总和=%ld\n",sum);
}
6-14编写程序,求1!
+2!
+…+n!
小于1000的项数n。
解:
#include
voidmain()
{intsum=0,t=1;
intn=0;
do
{n=n+1;
t=t*n;
sum=sum+t;
}while(sum<1000);
printf(“项数为%d\n”,n-1);
}
运行结果:
项数为6
思考:
此题为何要选用do-while循环结构?
最后输出变量的值为何要减1?
另请改为while循环实现。
6-15某门课程有n个同学参加考试,编写程序计算这门课程的最高分、最低分及平均分。
解:
#include
voidmain()
{
floataver,max,min,a;
intn,i;
printf("请输入学生的人数n的值:
");
scanf("%d",&n);
aver=max=0;
min=100;
for(i=0;i{
printf("请输入第%d位同学的成绩:
",i+1);
scanf("%f",&a);
aver+=a;//累加成绩
if(maxif(min>a)min=a;
}
aver/=n;//计算平均成绩
printf("aver=%f,max=%f,min=%f\n",aver,max,min);
}
思考:
变量max为何赋初值为0?
而变量min为何赋初值为100?
6-16编写程序,求分数序列2/1,2/3,3/5,8/5,8/13,…的前二十项及它们之和。
解:
#include
voidmain()
{
inti,t;
floatsum=0,a=2,b=1;
for(i=1;i<=20;i++)
{
sum=sum+a/b;
t=a;
a=a+b;
b=t;
}
printf("sum=%f\n",sum);
}
运行结果:
sum=32.660259
思考:
此题中没有输出各项的值,请问如何实现这一要求?
6-17编写程序,求满足下式的数字A,B,C的值。
ABC
+BCC
 ̄ ̄ ̄ ̄ ̄
234
解:
#include
voidmain()
{
inta,b,c,e,i,j,k,t,bw,jw,jw1,jw2;
printf("请输入计算式的期望结果值(1xxx):
");
scanf("%d",&e);
c=e%10;e/=10;
b=e%10;e/=10;
a=e%10;e/=10;
for(i=0;i<10;i++)
{
t=i+i;
bw=t%10;jw1=t/10;
if(bw==c)
{
for(j=0;j<10;j++)
{
t=j+i+jw1;
bw=t%10;
jw2=t/10;
if(bw==b)
{
for(k=0;k<10;k++)
{
t=k+j+jw2;
bw=t%10;
jw=t/10;
if(bw==a&&e==jw)
printf("所求的A,B,C可以是:
%d,%d,%d\n",k,j,i);
}
}
}
}
}
}
方法二:
#include"stdio.h"
voidmain()
{
inti,j,k,a,b,c;
inte;
printf("请输入计算式的期望结果值(1xxx):
");
scanf("%d",&e);
c=e%10;e=e/10;//各位
b=e%10;e=e/10;//十位
a=e%10;e=e/10;//百位
for(i=0;i<=5;i++)
for(j=0;j<=9;j++)
for(k=0;k<=9;k++)
{
if((i+i)==c&&(j+i)==b&&(k+j)==a)
printf("所求的A,B,C可以是:
%d,%d,%d\n",k,j,i);
}
}
运行结果:
请输入计算式的期望结果值(1xxx):
234
所求的A,B,C可以是:
1,1,2
ABCABC
思考:
如果将计算式+BCC改为+ABC程序应在
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
234234
什么地方进行修改?
(提示:
结果为1,1,7)
6-18猴子吃桃问题.猴子第一天摘下若干个桃子,当即吃了一半,不过瘾,还多吃了一个。
以后每天如此,至第十天,只剩下一个桃子。
编写程序计算第一天猴子摘得桃子个数。
解:
#include
voidmain()
{
intday,n1,n2;
day=9;
n2=1;
while(day>0)
{
n1=(n2+1)*2;/*第一天的桃子数是第二天桃子数加1后的2倍*/
n2=n1;
day--;
}
printf("第一天共摘的桃子数为%d\n",n1);
}
运行结果:
第一天共摘的桃子数为1534
思考:
此题可假设第一天共摘桃子x颗,可否用递归算法求解(只描述计算过程)?
6-19百鸡问题。
百元买百鸡,公鸡8元钱1只,母鸡6元钱1只,鸡仔2元钱4只。
编写程序,计算百元所买的公鸡,母鸡,鸡仔数。
解:
#include
Voidmain()
{
intx,y,z,j;
for(x=0;x<=12;x++)
for(y=0;y<=16;y++)
{
z=100-x-y;
if(8*x+6*y+z/3==100)
printf("%2d:
cock=%-2dhen=%-2dchicken=%-2d\n",++j,x,y,z);
}
}
运行结果:
1:
cock=8hen=11chicken=81
2:
cock=11hen=4chicken=84
思考:
如何理解条件式想x<=12,y<=16与计算式z=100-x-y的含义。
6-20将十元钱对换成一元,五角,一角的硬币,共计40枚,计算有多少种兑换方法。
解:
#include
voidmain()
{
intx,y,z,j=0;/*x表示一元的枚数,y表示五角的/*
/*枚数,z表示一角的枚数*/
for(x=0;x<=10;x++)
for(y=0;y<=20;y++)
{
z=40-x-y;
if(10*x+5*y+z==100)
{
j=j+1;
printf("第%d种兑换方法:
1元%d枚,5角%d枚,1角%d枚\n",j,x,y,z);
}
}
printf("共有%d种兑换方法\n",j);
}
思考:
对于任意数额的钱数,有100元、50元、20元、10元、5元、2元、1元、5角、2角、1角、5分、2分、1分等面额,如何找出张钱最少的组合?
6-21两个乒乓球对进行比赛,各出三人。
甲对为A,B,C三人,乙对为X,Y,Z三人。
有人打听比赛对阵安排,A说他不和X比,C说他不和X,Z比。
编写程序,找出三队赛手名单。
解:
#include
voidmain()
{
chari,j,k;/*i是A的对手;j是B对手;K是C的对手*/
for(i='X';i<='Z';i++)
for(j='X';j<='Z';j++)
if(i!
=j)
for(k='K';k<='Z';k++)
{
if(i!
=k&&j!
=k)
{
if(i!
='X'&&k!
='X'&&k!
='Z')
printf("顺序为:
\nA--%C\tB--%C\n",i,j,k);
}
}
}
运行结果:
顺序为:
A—ZB—XC—Y
思考:
此题为何要用
for(i='X';i<='Z';i++)
for(j='X';j<='Z';j++)
两层的'X'到'Z'的循环?
6-22阶梯问题。
有一阶梯,若每步跨2阶,最后余1阶;若每步跨3阶,最后余2阶;若每步跨5阶,最后余4阶;若每步跨6阶,最后余5阶;若每步跨7阶,刚好到达阶梯顶部。
编写程序,求最后的阶梯数。
解:
#include
voidmain()
{
inti=7;
do
{
if((i%2==1)&&(i%3==2)&&(i%5==4)&&(i%6==5)&&(i%7==0))
break;
i=i+7;
}while
(1);
printf("N=%d\n",i);
}
运行结果:
N=119
思考:
循环结构“do-while
(1);”这种形式具有什么特性?
此题中的“break;”语句起什么作用?
6-23编写程序,用牛顿迭代法求
算法提示:
(1)牛顿迭代公式为
(2)可用两次结果之差的绝对值小于某个很小的数作为循环控制条件,而用此时的结果值作为近似值。
解:
#include
#include
voidmain()
{
floata,x1,x2;
scanf("%f",&a);
x1=a/2;
x2=(x1+a/x1)/2;
do
{
x1=x2;
x2=(x1+a/x1)/2;
}while(fabs(x1-x2)>1e-5);
printf("%5.2f的平方根=%8.5f\n",a,x2);
}
运行结果:
2
2的平方根=1.41421
思考:
迭代算法是一个重要的算法,一般根据起精度要求进行循环控制,此题哪个表达式起精度循环控制作用?
如果出现迭代不收敛的情况,应如何再进行迭代次数的控制?