循环结构程序设计a.docx

上传人:b****6 文档编号:16182732 上传时间:2023-07-11 格式:DOCX 页数:17 大小:31.95KB
下载 相关 举报
循环结构程序设计a.docx_第1页
第1页 / 共17页
循环结构程序设计a.docx_第2页
第2页 / 共17页
循环结构程序设计a.docx_第3页
第3页 / 共17页
循环结构程序设计a.docx_第4页
第4页 / 共17页
循环结构程序设计a.docx_第5页
第5页 / 共17页
循环结构程序设计a.docx_第6页
第6页 / 共17页
循环结构程序设计a.docx_第7页
第7页 / 共17页
循环结构程序设计a.docx_第8页
第8页 / 共17页
循环结构程序设计a.docx_第9页
第9页 / 共17页
循环结构程序设计a.docx_第10页
第10页 / 共17页
循环结构程序设计a.docx_第11页
第11页 / 共17页
循环结构程序设计a.docx_第12页
第12页 / 共17页
循环结构程序设计a.docx_第13页
第13页 / 共17页
循环结构程序设计a.docx_第14页
第14页 / 共17页
循环结构程序设计a.docx_第15页
第15页 / 共17页
循环结构程序设计a.docx_第16页
第16页 / 共17页
循环结构程序设计a.docx_第17页
第17页 / 共17页
亲,该文档总共17页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

循环结构程序设计a.docx

《循环结构程序设计a.docx》由会员分享,可在线阅读,更多相关《循环结构程序设计a.docx(17页珍藏版)》请在冰点文库上搜索。

循环结构程序设计a.docx

循环结构程序设计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循环来求解

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 自然科学 > 物理

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2