第6章 循环结构程序设计Word文档下载推荐.docx
- 文档编号:878680
- 上传时间:2023-04-29
- 格式:DOCX
- 页数:27
- 大小:124.90KB
第6章 循环结构程序设计Word文档下载推荐.docx
《第6章 循环结构程序设计Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《第6章 循环结构程序设计Word文档下载推荐.docx(27页珍藏版)》请在冰点文库上搜索。
intn=0;
while(n++<
=2);
printf(“%d”,n);
4
【讨论】n=3时,while条件为假,结束循环,但比较后n自加了一,所以n=4。
【例三】
inti=0;
while
(1)
{
printf(“*”);
i++;
if(i<
3)break;
}
printf(“\n”);
*
【讨论】若将if(i<
3)改为if(i>
3),结果:
****
【例四】编程实例研究:
求解全班平均成绩
问题描述:
某个班中有n个学生,已知他们参加某次考试的成绩(0至100之间的整数),编程求全班学生在这次考试中的平均成绩。
思路:
使用用自顶向下、逐步求精的技术,先用伪码表示问题的顶层:
Determinetheclassaverageforthequiz(求解全班平均成绩)
顶层只有一句(描述程序的整个功能,但未给出足够的细节)。
第一步求精——
initializevariables(初始化变量)
input,sum,countthequizgrades(输入各人成绩,求其总和,计数键入次数)
calculateandprinttheclassaverage(计算并输出全班的平均成绩)
这里只用到顺序结构,即所列出的步骤是按顺序一个接一个执行的。
说明:
如果用total表示总成绩,用counter表示键入成绩的次数,则使用前这两个变量应先初始化(设置为0)。
第二步求精:
①伪码语句initializevariables
可作如下求精:
initializetotaltozero
initializecountertozero
讨论:
为什么只对这两个变量进行初始化?
②伪码语句input,sum,countthequizgrades
inputthefirstgrade
whiletheuserhasnotasyetenteredthesentinel
addthisgradeintotherunningtotal
addonetothegradecounter
inputthenextgrade(possiblythesentinel)
因为本例不知道要输入多少个成绩,所以程序必须能够处理任意个数的成绩。
程序如何判断何时终止输入成绩呢?
方法之一是使用一个专门的值来指示数据输入的结束。
这个值称为“标志值”(sentinetvalue)。
由于考试成绩是非负的整数值,本例中将取-1为标记值。
③伪码语句calculateandprinttheclassaverage
ifthecounterisnotequaltozero
settheaveragetothetotaldividedbythecounter
printtheaverage
else
print“Nogradeswereentered”
被0除是一种致命的错误,如果不能明确检测并在程序中作适当的处理,将会导致程序执行失败(“崩溃”)。
当伪码算法详细到能够把伪码转换为C程序时,即可着手编写程序了。
参考程序如下:
/*用标记控制的循环求全班平均成绩的程序*/
#include<
stdio.h>
main()
{
floataverage;
/*变量声明*/
intcounter,grade,total;
/*初始化阶段*/
total=0;
counter=0;
/*处理阶段*/
printf(“请输入成绩(用-1结束输入):
”);
scanf(“%d”,&
grade);
while(grade!
=-1){
total=total+grade;
counter=counter+1;
printf(“(“请输入成绩(用-1结束输入):
/*终止阶段*/
if(counter!
=0){
average=(float)total/counter;
printf(“全班平均值是%.2f”,average);
else
printf(“还没有输入成绩!
\n”);
return0;
/*表明程序成功地结束*/
6.4do…while语句循环结构P108
一般形式do{循环语句(组)}while(条件表达式);
用于构成直到型循环:
先执行后判断/条件为真继续循环,直到条件为假时结束循环。
don++;
while(n<
5);
5
【讨论】如果将最后两句合成:
doprintf(“%d”,n++);
结果:
01234
【例二】求∑i=1+2+3+4…+99+100(i=0~100)
inti=1,sum=0;
do
{sum=sum+i;
}while(i<
=100);
printf(“Sum=%d\n”,sum);
【例三】从键盘输入一个整数,分析以下程序运行结果。
若X为整数,则X%10可得X的个位数X/10可得X的个位数移去后形成的新数
如:
125%10=5→125/10=12→12%10=2→12/10=1→1%10=0→1/10=0(结束)
intnum,c;
printf(“请输入一个整数:
“);
scanf(“%d”,&
num);
c=num%10;
/*取得num的个位数*/
printf(“%d”,c);
/*输出num的个位数*/
}while((num/=10)>
0);
/*直到num/10为0*/
输入12456,输出65421(将各位数字反序显示出来)
【讨论】如果while(num/=10>
0),结果如何?
陷入无限循环(输出无数个6)。
原因:
num/=10>
0中赋值号优先级最低,而num/(10>
0)的结果除num=0(输出0)外均真。
6.5for语句循环结构P110
一般形式for(表达式1;
条件表达式;
表达式3)
{循环语句(组);
表达式1:
整个循环中只执行1次,常用来对循环变量设置初值
条件表达式(表达式2):
其值为真(非0)时继续执行循环语句(组),否则结束循环
表达式3:
常用于循环变量值的更新(循环体的一部分每次循环语句组执行完后执行一次)
以下程序中执行几次循环?
{inti;
for(i=2;
i==0;
)
printf(“%d”,i++);
0次
【讨论】若i==2,结果为2,循环执行一次。
i为其他值时,同i==0。
{inti,sum=0;
for(i=1;
i<
=100;
i++)sum=sum+i;
printf(“Sum=%d\n”,sum);
for(a=1,i=-1;
-1<
=i<
1;
i++)
{a++;
printf(“%d”,a);
printf(“%d”,i);
-1
【讨论】-1<
1为假(从左到右,-1<
=i的值为1)
【例四】
for(i=0;
3;
printf(“*”);
***3
【例五】
{inta,i;
for(i=0;
printf(“a=”),scanf(“%d”,&
a);
i++)printf(“H”);
a=1
Ha=2
Ha=6
Ha=…(不管a为何整型数值,包括0,循环均不停止,但a为实型数值或字符等时,循环终止)
scanf()函数的返回值见P386。
正确输入时,返回数据个数,错误输入时返回0。
如c=scanf(“%d,%d,%d”,&
a,&
b,&
c);
如果a、b、c输入正确,c=3,否则c=0。
【讨论】如果
a),a=a;
则当a为0或-0时,循环结束(表达式2为逗号表达式,其值为最后赋值表达式的值。
【例七】下列程序段的for循环语句
inti,x;
for(i=0,x=0;
=9&
&
x!
=876;
i++)scanf(“%d”,x);
A)最多执行10次B)最多执行9次C)是无限循环D)循环体一次也不执行
【例八】以下程序的输出结果是:
inty=10;
while(y--);
printf("
y=%d\n"
y);
A)y=0B)y=1C)y=随机值D)y=-1
6.8break语句和continue语句P114
break在switch中退出switch结构/在循环中结束循环
a=10y=0
1212
14+216+12=28
14+216+28=44
14+216+44=60
inta,y;
a=10,y=0;
do{a+=2;
y+=a;
if(y>
50)break;
}while(a=14);
/*每次循环到此a值都为14*/
printf(“a=%d,y=%d\n”,a,y);
a=16,y=60
②continue循环“短路”(跳过循环体后面的语句,开始下一循环)。
在for循环中,遇到continue语句后,首先计算for语句中表达式3的值,然后再执行条件测试(表达式2),最后根据测试结果决定是否继续循环。
ix
11→6
26→3
33→8
48→5
55→10
6
【例二】求以下程序段执行后x和i的值。
inti,x;
for(i=1,x=1;
=50;
if(x>
=10)break;
if(x%2==1)
{x+=5;
continue;
x-=3;
x的值为10,i的值为6。
{inti=1;
while(i<
=15)
i++i%3输出i
1→222
2→30
3→41
4→525
5→60
……
if(++i%3!
=2)continue;
elseprintf(“%d”,i);
2581114(除3余数为2者输出,其余跳过)。
③goto跳转——只能从循环内向外跳转
inti,k=0;
;
{
k++;
while(k<
i*i)
if(k%3==0)
gotoloop;
/*类似break,但可跳到循环体外任何处*/
loop:
printf(“%d,%d”,i,k);
2,3
6.9程序举例
1、枚举法(穷举法)
“笨人之法”——把所有可能的情况一一测试,筛选出符合条件的各种结果进行输出。
【例一】百元买百鸡:
用一百元钱买一百只鸡。
已知公鸡5元/只,母鸡3元/只,小鸡1元/3只。
分析:
这是个不定方程——三元一次方程组问题(三个变量,两个方程)
x+y+z=100
5x+3y+z/3=100
设公鸡为x只,母鸡为y只,小鸡为z只。
用枚举法分析后可得出流程图如下:
intx,y,z;
for(x=0;
x<
x++)
for(y=0;
y<
y++)
for(z=0;
z<
z++)
{if(x+y+z==100&
5*x+3*y+z/3.0==100)
printf(“x=%d,y=%d,z=%d\n”,x,y,z);
x=0,y=25,z=75
x=4,y=18,z=78
x=8,y=11,z=81
x=12,y=4,z=84
【讨论】此为“最笨”之法——要进行101×
101×
101=次(100多百次)运算。
改进:
①令z=100-x-y只进行101×
101=10201次运算(前者的1%)
②取x<
=19,y<
=33只进行20×
34=680次运算(①的6.7%)
要点:
确定独立变量个数及取值范围——每个独立变量用一层循环实现“穷举”(遍历);
确定符合题意的条件表达式——条件成立的方案,输出结果。
【例二】雨水淋湿了算术书的一道题,8个数字只能看清3个,第一个数字虽然看不清,但可看出不是1。
编程求其余数字是什么?
[□*(□3+□)]2=8□□9
设分别用A、B、C、D、E五个变量表示自左到右五个未知的数字。
其中A的取值范围为2~9,其余取值范围为0~9。
条件表达式即为给定算式。
main(){
intA,B,C,D,E;
for(A=2;
A<
=9;
A++)
for(B=0;
B<
B++)
for(C=0;
C<
C++)
for(D=0;
D<
D++)
for(E=0;
E<
E++)
if(A*(B*10+3+C)*A*(B*10+3+C)==8009+D*100+E*10)
printf(“%d%d%d%d%d\n”,A,B,C,D,E);
32864
【例三】求100~200之间不能被3整除也不能被7整除的数。
求某区间内符合某一要求的数,可用一个变量“穷举”。
所以可用一个独立变量x,取值范围100~200。
for(x=100;
=200;
if(x%3!
=0&
x%7!
=0)printf(“x=%d\n”,x);
如果是求指定条件的奇数呢?
x=101;
x=x+2(x++,x++)
如果是求指定条件的偶数呢?
x=100;
【例四】张三、李四、王五三个棋迷,定期去文化宫下棋。
张三每五天来一次,李四每六天来一次,王五每九天来一次。
问每过多少天他们才能一起在文化宫下棋?
此问题实际上是求最小公倍数的数学问题。
设结果为x,其取值范围为0→∞。
因上限为无限大,计数值不能预先确定,故用while循环结构更合适。
intx=1;
while
(1)
{if(x%5==0&
x%6==0&
x%9==0)
{printf(“x=%d\n”,x);
break;
x++;
x=90
2、归纳法(递推法)
“智人之法”——通过分析归纳,找出从变量旧值出发求新值的规律。
求∑i=1+2+3+4…+99+100(i=0~100)。
{inti,s=0;
for(i=1;
s=s+i;
printf(“Sum=%d\n”,s);
求1-1/2+1/3-1/4+1/5-…+1/99-1/100。
inti;
floats=0;
if(i%2)s=s+1.0/i;
elses=s-1.0/i;
Sum=%f\n"
s);
法二:
法三:
math.h>
main()
main(){inti,k=1;
{inti;
floats=0;
i++){s=s+k/i;
s=s+pow(-1,i+1)/i;
k=-k;
printf(“Sum=%f\n”,s);
}}
0.
【讨论】第二个程序运算结果为1(错误),为什么?
如何纠正?
【例三】求n!
(n由键盘输入)
{inti,s,n;
printf(“请输入N=”);
scanf(“%d”,&
n);
s=1;
for(i=1;
i<
=n;
s=s*i;
printf(“%d!
=%d\n”,n,s);
【讨论】为什么取初值s=1?
运行时会发现:
当n较大(≥8)时,这个程序的结果是错误的。
为什么?
求∑n!
法1:
用双重循环实现求和(外循环作累加,内循环求阶乘)
inti,j,n;
floats,s1;
printf("
请输入n="
);
scanf("
%d"
&
s=0;
s1=1;
for(j=1;
j<
=i;
j++)
s1=s1*j;
s=s+s1;
Sum=%.0f\n"
s);
通过单循环实现。
inti,n;
s=0,s1=1;
s1=s1*i;
输入N=5,Sum=153
输入N=20,Sum=2.56133e+18(用printf(“Sum=%e\n”,s)输出)
【例五】P116例6.7
兔子繁殖问题(斐波那契数列问题)。
著名意大利数学家斐波那契(Fibonacci)1202年提出一个有趣的问题。
某人想知道一年内一对兔子可以生几对兔子。
他筑了一道围墙,把一对大兔关在其中。
已知每对大兔每个月可以生一对小兔,而每对小兔出生后第三个月即可成为“大兔”再生小兔。
问一对小兔一年能繁殖几对小兔?
▲表示大兔,△表示小兔
开始
▲▲
新增对数
1月
▲▲△△
1
2月
▲▲△△△△
3月
▲▲▲▲△△△△△△
2
4月
▲▲▲▲▲▲△△△△△△△△△△
3
5月
▲▲▲▲▲▲▲▲▲▲△△△△△△△△△△△△△△△△
▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲△△△△△△…△△
8
由分析可以推出,每月新增兔子数Fn={1,1,2,3,5,8,13,21,34,…}(斐波那契数列)
月份n兔子数Fn
初值
1F1=11(i=1)
2F2=11(i=2)
3F3=2=F1+F2可归纳出Fi=
4F4=3=F2+F3
5F5=5=F3+F4Fi-1+Fi-2(递推公式)
…
nFn=Fn-1+Fn-2
intf1=1,f2=1,f=2,i,s=2,n;
Inputn="
);
scanf("
for(i=3;
{s=s+f;
f1=f2;
f2=f;
f=f1+f2;
F1=1,F2=1,S=2
输入n值
i=3~n
S=S+F
F1=F2
F2=F
F=F1+F2
输出S
376
【例六】
编程显示以下图形(共N行,N由键盘输入)。
*
***
*****
*******
*********
此类题目分析的要点是:
通过分析,找出每行空格、*与行号i、列号j及总行数N的关系。
其循环结构可以用下图表示:
(设N=5)
第1行4个空格=5-11个“*”=2×
行号-1
第2行3个空格=5-23个“*”=2×
第3行2个空格=5-35个“*”=2×
第4行1个空格=5-47个“*”=2×
第5行0个空格=5-59个“*
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 第6章 循环结构程序设计 循环 结构 程序设计
![提示](https://static.bingdoc.com/images/bang_tan.gif)