循环结构程序设计a.docx
- 文档编号:28600501
- 上传时间:2023-07-19
- 格式:DOCX
- 页数:17
- 大小:31.95KB
循环结构程序设计a.docx
《循环结构程序设计a.docx》由会员分享,可在线阅读,更多相关《循环结构程序设计a.docx(17页珍藏版)》请在冰豆网上搜索。
循环结构程序设计a
循环结构程序设计
hb007发表于2006-3-2320:
31:
01
在Pascal语言中,循环结构程序通常由三种的循环语句来实现。
它们分别为FOR循环、当循环和直到循环。
通常将一组重复执行的语句称为循环体,而控制重复执行或终止执行由重复终止条件决定。
因此,重复语句是由循环体及重复终止条件两部分组成。
一、for语句(计数循环)
for语句用来描述已知重复次数的循环结构。
for语句有两种形式:
(1)for控制变量:
=初值 to 终值 do
语句; (递增循环)
(2)for控制变量:
=初值 downto 终值 do
语句; (递减循环)
第一种形式的for语句是递增循环。
首先将初值赋给控制变量,接着判断控制变量的值是否小于或等于终值,若是,则执行循环体,在执行了循环体之后,自动将控制变量的值赋为它的后继值,并重新判断是否小于或等于终值。
当控制变量的值大于终值时,退出for循环,执行for语句之后的语句。
第二种形式的for语句是递减循环。
首先将初值赋给控制变量,接着判断控制变量的值是否大于或等于终值,若是,则执行循环体,在执行了循环体之后,自动将控制变量的值赋为它的前趋值,并重新判断是否大于或等于终值。
当控制变量的值小于终值时,退出for循环,执行for语句之后的语句。
说明:
①循环控制变量必须是顺序类型。
例如,可以是整型、字符型等,但不能为实型。
②循环控制变量的值递增或递减的规律是:
选用to则为递增;选用downto则递减。
③所谓循环控制变量的值“超过”终值,对递增型循环,“超过”指大于,对递减型循环,“超过”指小于。
④循环体可以是一个基本语句,也可以是一个复合语句。
fori:
=1to10do
begin
k:
=k+1;
write(k)
end;
关于分号的用法,Pascal语言要求在语句之间要用分号隔开,其他地方不用。
在上面的这个复合语句中,两个语句间用分号隔开,而第二个语句和end之间不用分号,因为“end”不是语句。
在Pascal7.0中,由于容错性的提高,end前用分号也不算错。
但读者还是应该养成规范编程的好习惯。
⑤循环控制变量的初值和终值一经确定,循环次数就确定了。
但是在循环体内对循环变量的值进行修改,常常会使得循环提前结束或进入死循环。
建议不要在循环体中随意修改控制变量的值。
⑥for语句中的初值、终值都可以是顺序类型的常量、变量、表达式。
FOR循环的几点注意内容:
(1)循环控制变量必须是顺序类型的变量。
所谓顺序类型的变量,就是指整型,字符型,枚举型,子界型,不允许是实型。
(2)不允许在循环体内再对循环控制变量赋值。
如:
a:
=10;b:
=50;
fork:
=atobdo
begin
k:
=k+1;{这一句是错误的!
!
!
!
!
!
!
!
}
writeln(k);
end;
(3)当循环初值或循环终值中包含变量时,允许在循环体内改变这些变量的值,但并不改变原定的循环次数。
如:
a:
=1;b:
=10;
fori:
=atobdo
begin
a:
=5;b:
=4;
end;
在上面例子中,a,b的值在循环的内部发生了变化,但并不影响循环的次数,依然是10次。
(4)多重循环:
循环体由PASCAL语句构成,当然也可以包含FOR语句,这就构成了循环的嵌套,形成多重循环。
初学者应当特别注意,内层的循环变量不能和外层的循环变量相同。
也就是说,嵌套的各层循环应当使用不同的变量作为循环变量。
【例1】计算1+2+3+…+99+100的和。
programex701;
vari,sum:
integer;
begin
sum:
=0;
fori:
=1to100do
sum:
=sum+i;
writeln('toltal:
',sum);
readln
end.
【例2】根据公式π2/6=1+1/22+1/32+…+1/n2,计算圆周率的Pai值。
programex702;
vari,n:
integer;
Pai,s,x:
real;
begin
write('inputn(integer)>100:
');
readln(n);
n:
=0;
fori:
=1tondo
begin
x:
=i; {转换为实型数}
s:
=s+1/(x*x)
end;
Pai:
=sqrt(6*s);
writeln('Pai=',Pai:
8:
6);
readln
end.
平方根函数Sqrt(x):
函数值为x的平方根。
【例3】求1*2*3*……(n-2)*(n-1)*n的值,n为用户输入。
即求n!
。
n的阶乘公式:
n!
=1*2*3*……(n-2)*(n-1)*n,且规定0!
=1,负数无意义。
programex703;
{$N+,E+}
varm:
extended;{为扩展实型,1.9×10-4951~1.1×104932,10,19~20}
i,n:
integer;
begin
write('Inputn,calculatn!
(nisinteger):
');
readln(n);
ifn<0then
writeln('Inputn<0,error!
')
else
begin
m:
=1;
fori:
=ndownto1do
m:
=m*i;
writeln(n:
5,'!
=',m);
end;
readln
end.
上例用到了“递推”算法。
所谓递推是指在一个数的序列值中,下一项的值是在前一项的值的基础上推算出来的,即下一项对前一项有某种依赖关系。
例如,为求5!
,应先知道4!
的值,然后再乘以5;为求6!
,必先求出5!
。
也就是说,从1!
可以推出2!
,从2!
可以推出3!
,从3!
可以推出4!
,以此类推。
求n!
的递推公式为:
a0=1 (n=0)
an=n×an-1 (n>0)
a0=1是“初始条件”或“边界条件”。
只要找出递推关系,就可以由循环来处理,一项一项地推算出以后各项。
在程序中用同一个变量m来存放每一次推出来的值。
每一次循环都执行同一个语句,给同一个变量赋以新的值。
这种方法称为“迭代”。
程序中的m称为迭代变量,它的值是在不断变化的。
“递推”可以用“迭代”来处理,例如本例。
由前一个m推出后一个m是递推,用同一个变量存放推出的结果,就是“迭代”。
但是并非所有的递推算法都用迭代来处理。
例如,由a推出b,由b推出c,这是递推,但不存在迭代关系。
用计算机解题时,往往把递推问题表现为迭代形式,用循环来处理比较方便。
例如本例的“m=m*i”,每次循环都执行同一个语句,很方便地实现了递推要求。
迭代法是计算机解题中使用十分广泛的一种算法,可以说数值计算算法的一个基本特点就是“迭代”。
通过多次迭代,递推出所需的近似值。
因此,应熟悉怎样将一个递推问题写成一个迭代形式,由于计算机运算速度快,执行循环能充分发挥计算机的特长,使程序的复杂性大大降低。
【例4】已知一对兔子,每有可以生一对小兔,而小兔过一个月后也可生一对小免。
即兔子的对数是:
第一个月1对,第二个月2对,第三个月3对,第四个月5对,…,假设兔子的生育期是12个月,并且不死,问一年后,这对兔子有多少对活着的后代?
【分析】根据题目给出的条件,得到算法:
设当前月兔子有x对,它的前一个月有lastx对,前二个月有prevx对,明显存在一个递推关系,即x=lastx+prevx。
programex704;
constn=12;
vari,lastx,prevx,x:
integer;
begin
prevx:
=1;
lastx:
=2;
fori:
=3tondo
begin
x:
=lastx+prevx;
prevx:
=lastx;
lastx:
=x;
end;
writeln('total:
',x);
readln
end.
【例5】求两个正整数m和n的最大公约数。
【分析】求两个正整数的最大公约数采用的辗转相除法求解。
以下是辗转的算法:
分别用m,n,r表示被除数、除数、余数。
①求m/n的余数r。
②若r=0,则n为最大公约数。
若r≠0,执行第③步。
③将n的值放在m中,将r的值放在n中。
④返回重新执行第①步。
程序中用到一个标准过程:
halt,其功能是退出现行程序体。
如果在程序体中执行halt,将引起程序结束。
与它功能相同的标准过程是exit,在TurboPascal的编辑环境IDE中将光标移到halt(或exit)第一个字符上,按帮助热键Ctrl+F1即可得到它的全部解释与举例。
programEx705;
varm,n,a,b,r:
integer;
begin
write('Inputm,n:
');
readln(m,n);
a:
=m;b:
=n;r:
=amodb;
whiler<>0do
begin
a:
=b;b:
=r;
r:
=amodb;
end;
writeln('Thegreatestcommondivideis:
',b:
8);
end.
另一种方法:
programex705;
vara,b,i,t:
integer;
begin
write('Inputa,b(integer+):
');
readln(a,b);
write('(',a,',',b',')=');
ifa begin t: =a; a: =b; b: =t; end; fori: =bdownto1do if(amodi=0)and(bmodi=0)then begin writeln(i);readln; halt; end; end. 练习: 1、指出下列程序段的不妥之处: ①fori: =1to15.5do write(i); ②fork: ='d'downto'h'do x: =x+k; ③fori: =1to10do fori: =atocdo write(i); 2、下面程序的运行结果是: fori: =1to6do begin forj: =6-idownto1do write('*': 2); writeln end; 3、下面程序的运行结果是: fori: =1to100do ifimod11=0then write(i: 10); 二、while语句(当型循环) 当循环次数未知,只能根据某一条件来决定是否进行循环时,用while语句或repeat语句实现循环要更方便。 while语句的形式为: while布尔表达式do 语句; 其意义为: 当布尔表达式的值为true时,执行do后面的语句。 while语句的执行过程为: ①判断布尔表达式的值,如果其值为真,执行步骤②,否则执行步骤④; ②执行循环体语句(do后面的语句); ③返回步骤①; ④结束循环,执行while的下一个语句。 说明: 这里while和do为保留字,while语句的特点是先判断,后执行。 当布尔表达式成立时,重复执行do后面的语句(循环体)。 while语句用于“当满足某一条件时进行循环”的情况,也就是说while循环是是属于当型循环。 为了能使while重复能终止,循环体中一定要有影响布尔表达式的操作,否则该循就是一个死循环。 保留关键字DO后面的“语句”只能是一条语句,称为“循环体”;如果循环体中需要包含多个语句则应该采用复合语句。 【例6】计算从0到某个数之间所有奇数的和。 programEx706; varodds,limit,sum: integer; begin readln(limit); sum: =0; odds: =1; whileodds<=limitdo begin sum: =sum+odds; odds: =odds+2 end; writeln(sum: 10) end. 【例7】利用格里高公式求π: π/4=1-1/3+1/5-1/7+…,直到最后一项的值小于10-6为止。 【分析】解本题的关键就是求右边数值序列的和,序列有明显的特点,分母是从1开始的奇数,加减号轮流出现。 因此,我们可以用n=n+2表示序列数值的变化,用f=-f来设置它们各项的符号位。 programex707; varf: integer; n,t,pai: real; begin pai: =0; t: =1; n: =1; f: =1; whileabs(t)>=1e-6do begin pai: =pai+t; n: =n+2; f: =-f; t: =f/n; end; pai: =pai*4; writeln('pai=',pai: 10: 8); readln end. 【例8】求恰好使s=1+1/2+1/3+…+1/n的值大于10时n的值。 【分析】“恰好使s的值大于10”意思是当表达式s的前n-1项的和小于或等于10,而加上了第n项后s的值大于10。 从数学角度,我们很难计算这个n的值。 故从第一项开始,当s的值小于或等于10时,就继续将下一项值累加起来。 当s的值超过10时,最后一项的项数即为要求的n。 程序如下: programex708; vars: real; n: integer; {n表示项数} begin s: =0.0; n: =0; whiles<=10do {当s的值还未超过10时} begin n: =n+1; {项数加1} s: =s+1/n; {将下一项值累加到s} end; writeln('n=',n); {输出结果} end. 练习: 1、指出下列程序段的不妥之处: whilea=bdo begin i: =i+1; writeln(i) end; 2、下面程序段的运行结果是: i: =10;k: =0; while(i>=10)and(i<=30)do begin k: =k+i; i: =i+2 end; writeln('k=',k) 三、repeat-until语句(直到循环) repeat语句用于“重复执行循环体,一直到指定的条件为真时为止”。 语法格式为: repeat 语句1; …… 语句n; until 布尔表达式; 其中Repeat、until是Pascal保留字,repeat与until之间的所有语句称为循环体。 说明: ①repeat语句的特点是: 先执行循环,后判断结束条件,因而至少要执行一次循环体。 ②repeat-until是一个整体,它是一个(构造型)语句,不要误认为repeat是一个语句,until是另一个语句。 ③repeat语句在布尔表达式的值为真时不再执行循环体,且循环体可以是若干个语句,不需用begin和end把它们包起来,repeat和until已经起了begin和end的作用。 while循环和repeat循环是可以相互转化的。 当描述由计算操作后的情况确定重复是否继续进行的计算时,通常用repeat语句描述。 【例9】以下循环求sum=1+2+3+......+n的和。 programEx709; varn,q,sum: integer; begin write('n='); readln(q); sum: =0; n: =1; repeat sum: =sum+n; n: =n+1; untiln>q; writeln('sum=',sum); readln end. 以上我们已介绍了三种循环语句。 一般说来,用for循环比较简明,只要能用for循环,就尽量用for循环。 只在无法使用for循环时才用while循环和repeat-until循环,而且while循环和repeat-until循环是可以互相替代的。 for循环在大多数场合也能用whiel和repeat-until循环来代替。 一般for循环用于有确定次数循环,而while和repeat-until循环用于未确定循环次数的循环。 练习: 1、指出下列程序段的不妥之处: repeat begin read(n); i: =i+1; writeln(i) end untili=100; 2、下面程序的运行结果是: read(n);{n为整形变量} k: =n; repeat k: =k-1 untilnmodk=0; write(k); 四、goto语句和标号 goto语句是一种无条件转向语句,它可以控制直接从程序的一条语句转向另一条语句。 goto语句的语法形式为: goto 标号; 例如: 10read(a); ifa<10then i: =i+1; goto10; 说明: 1、如果程序中使用标号,就必须在程序的标号说明部分加以说明。 标号说明通常放在程序说明部分第一个出现,说明的格式如下: Label标号1,标号2,……; 2、标号只起到一个表明位置的作用,它并不改变原语句的功能; 3、标号是无符号整数,其范围是1~9999之间,但TurboPascal为实现较好的程序可读性,规定不但允许用数字作标号,而且还允许用标识符如error,quit,answer等作语句标号; 4、标号并不代表实际的行数,标号之间也可不按大小顺序; 5、goto语句只能从一个语句结构中转出来,不允许从外部转进去; 6、goto语句的运用往往会使程序的执行路线变得非常复杂。 因此,在程序设计时应尽量避免使用goto语句(在Pascal程序中,goto语句完全可由其他语句代替)。 【例10】编写计算y=ln(x),输入一个实数x,若x>0,则输出计算结果,若x<=0,则显示无解标志“cannotsolve”。 Programex710; Labela10; Varx,y: real; Begin Write('inputrealdata: '); Readln(x); Ifx<=0Then begin writeln('cannotsolve'); gotoa10; end; Y: =ln(x); Writeln('y=',y: 6: 2);{输出指定宽度的结果} A10: {标号后为空语句,表示空操作} End. 练习: 1、下面程序段的运行结果是: i: =1; 1: ifi<=10then begin total: =total+i; i: =i+1; goto1 end; write('total=',total); 五、循环结构程序设计 【例11】求1! +2! +…+10! 的值。 【分析】这个问题是求10自然数的阶乘之和,可以用for循环来实现。 programex711; vart,s: real; i,j,n: integer; begin S: =0; forn: =1to10do begin t: =1; forj: =1tondo t: =t*j; S: =S+t; end; writeln('s=',s: 0: 0); end. 以上的程序是一个二重的for循环嵌套。 这是比较好想的方法,但实际上对于求n! ,我们可以根据求出的(n-1)! 乘上n即可得到,而无需重新从1再累乘到n。 程序可改为: programex711; vart,s: real; i,j,n: integer; begin S: =0;t: =1; forn: =1to10do begin t: =t*n; S: =S+t; end; writeln('s=',s: 0: 0); end. 显然第二个程序的效率要比第一个高得多。 第一程序要进行1+2+…+10=55次循环,而第二程序进行10次循环。 如题目中求的是1! +2! +…+1000! ,则两个程序的效率区别更明显。 【例12】一个炊事员上街采购,用500元钱买了90只鸡,其中母鸡一只15元,公鸡一只10元,小鸡一只5元,正好把钱买完。 问母鸡、公鸡、小鸡各买多少只? 【分析】设母鸡I只,公鸡J只,则小鸡为90-I-J只,则15*I+10*J+(90-I-J)*5=500,显然一个方程求两个未知数是不能直接求解。 必须组合出所有可能的I,j值,看是否满足条件。 这里I的值可以是0到33,J的值可以0到50。 源程序如下: programex712; vari,j,k: integer; begin fori: =1to33do forj: =1to50do begin k: =90-i-j; if15*i+10*j+5*k=500then writeln(i: 5,j: 5,k: 5); end; readln end. 【例13】求100~999中的水仙花数。 (水仙花数是指一个三位数,其各个数之立方和等于该数。 如三位数ABC,ABC=A3+B3+C3,则称ABC为水仙花数。 ) 【分析】根据题意,采用三重循环来求解。 由于循环次数一定,用for循环最为简单。 programex711; vara,b,c: intger; begin fora: =1to9do forb: =0to9do forc: =0to9do ifa*a*a+b*b*b+c*c*c=a*100+b*10+cthen write(a*100+b*10+c: 6); readln end. 只采用一个for循环来求解
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 循环 结构 程序设计