资源描述
第七课 WHILE循环与REPEAT
看下列程序的功能:
Program Exam12;
Var a: byte;
Begin
While a:<=200 do
BEGIN
Writeln (a);
A:=a+1;
END;
Readln
End.
一、WHILE循环
对于for循环有时也称为计数循环,当循环次数未知,只能根据某一条件来决定是否进行循环时,用while 语句或repeat语句实现循环要更方便。
while语句的形式为:
while <布尔表达式> do <语句>;
其意义为:当布尔表达式的值为true时,执行do后面的语句。
while语句的执行过程为:
①判断布尔表达式的值,如果其值为真,执行步骤2,否则执行步骤4;
②执行循环体语句(do后面的语句);
③返回步骤1;
④结束循环,执行while的下一个语句。
说明:这里while和do为保留字,while语句的特点是先判断,
看下列程序的功能:
Program Exam12;
Var a: byte;
Begin
repeat
Writeln (a);
A:=A+1;
Until a>200
Readln
End.
后执行。 当布尔表达式成立时,重复执行do后面的语句(循环体)。
例1 、求恰好使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。
程序如下:
var
s : real;
n : integer;{n表示项数}
begin
s:=0.0;n:=0;
while s<=10 do{当s的值还未超过10时}
begin
n:=n+1;{项数加1}
s:=s+1/n;{将下一项值累加到s}
end;
writlen('n=',n);{输出结果}
end.
例2、求两个正整数m和n的最大公约数。
分析:求两个正整数的最大公约数采用的辗转相除法求解。以下是辗转的算法:
分别用m,n,r表示被除数、除数、余数。
①求m/n的余数r.
②若r=0,则n为最大公约数.若r≠0,执行第③步.
③将n的值放在m中,将r的值放在n中.
④返回重新执行第①步。
程序如下:
program ex4_4;
var m,n,a,b,r:integer;
begin
write('Input m,n:');
readln(m,n);
a:=m;b:=n;r:=a mod b;
while r<>0 do
begin
a:=b;b:=r;
r:=a mod b;
end;
writeln('The greatest common divide is:',b:8);
end.
二、直到循环(REPEAT-until语句)
用while语句可以实现"当型循环",用repeat-until 语句可以实现"直到型循环"。repeat-until语句的含义是:"重复执行循环,直到指定的条件为真时为止"。
直到循环语句的一般形式:
Repeat
<语句1>;
<语句n>;
until <布尔表达式>;
其中Repeat、until是Pascal保留字,repeat与until之间的所有语句称为循环体。
说明:
①repeat语句的特点是:先执行循环,后判断结束条件,因而至少要执行一次循环体。
②repeat-until是一个整体,它是一个(构造型)语句,不要误认为repeat是一个语句, until是另一个语句。
③repeat语句在布尔表达式的值为真时不再执行循环体,且循环体可以是若干个语句,不需用begin和end把它们包起来, repeat 和until已经起了begin和end的作用。while循环和repeat循环是可以相互转化的。
对于例2中求两个正整数的最大公约数,程序可用repeat-until循环实现如下:
var
m,n,a,b,r : integer;
begin
write('Input m,n=');
readln(m,n);
a:=m;b:=n;
repeat
r:=a mod b;
a:=b;b:=r;
until r=0;
writeln('The greatest common divide is',a);
end.
以上我们已介绍了三种循环语句。一般说来,用for 循环比较简明,只要能用for循环,就尽量作用for循环。只在无法使用for循环时才用while循环和repeat-until循环, 而且 while 循环和repeat-until循环是可以互相替代的。for 循环在大多数场合也能用whiel和repeat-until循环来代替。一般for循环用于有确定次数循环,而while和repeat-until循环用于未确定循环次数的循环。
当一个循环的循环体中又包含循环结构程序时,我们就称之为循环嵌套。
三、循环结构程序设计
例3 求1!+2!+…+10!的值。(自己先思考如何处理)
分析:这个问题是求10自然数的阶乘之和,可以用for 循环来实现。程序结构如下:
for n:=1 to 10 do
begin
①N!的值àt
②累加N!的值t
end
显然,通过10次的循环可求出1!,2!…,10!,并同时累加起来, 可求得S的值。而求T=N!,又可以用一个for循环来实现:
t=1;
for j:=1 to n do
t:=t*j;
因此,整个程序为:
program ex4_5;
var t,s:real;
i,j,n:integer;
begin
S:=0;
for n:=1 to 10 do
begin
t:=1;
for j:=1 to n do
t:=t*j;
S:=S+t;
end;
writeln('s=',s:0:0);
end.
以上的程序是一个二重的for循环嵌套。这是比较好想的方法,但实际上对于求n!,我们可以根据求出的(n-1)!乘上n即可得到,而无需重新从1再累乘到n。
程序可改为:
program ex4_5;
var t,s:real;
i,j,n:integer;
begin
S:=0;t:=1;
for n:=1 to 10 do
begin
t:=t*n;
S:=S+t;
end;
writeln('s=',s:0:0);
end.
显然第二个程序的效率要比第一个高得多。第一程序要进行1+2+…+10=55次循环,而第二程序进行10次循环。如题目中求的是1!+2!+…+1000!,则两个程序的效率区别更明显。
例4 一个炊事员上街采购,用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。
源程序如下:
programr ex4_6;
var i,j,k:integer;
begin
for i:=1 to 5 do
for j:=1 to 8 do
begin
k:=90-i-j;
if 15*i+10*j+5*k=500 then writeln(i:5,j:5,k:5);
end;
end.
例5、求100-200之间的所有素数。()
分析:我们可对100-200之间的每一整数进行判断,判断它是否为素数,是则输出。而对于任意整数i,根据素数定义,我们从2开始,到 ,找i的第一个约数。若找到第一个约数,则i必然不是素数。否则i为素数。
源程序如下:
var
i : integer;
x : integer;
begin
for i:=100 to 200 do
begin
x:=2;
while (x<=trunc(sqrt(i)))and(i mod x<>0)do
begin
x:=x+1;
end;
if x>trunc(sqrt(i)) then write(i:8);
end;
end.
练 习
1、输入一个正整数n,将n分解成质因数幂的乘积形式。
例如:36=22*32
2、输出如下图形。
3、编写一程序,验证角谷猜想。所谓的角谷猜想是:"对于任意大于1的自然数n,若n为奇数,则将n变为3*n+1,否则将n变为n的一半。经过若干次这样的变换,一定会使n变为1。"
4.有一堆100多个的零件,若三个三个数,剩二个;若五个五个数,剩三个;若七个七个数,剩五个。请你编一个程序计算出这堆零件至少是多少个?
展开阅读全文