- 第一章 Fortran 语言程序设计初步
- 第二章 改变程序流程
- 第三章 循环结构
- 第四章 数据结构
- 第五章 数组
- 第六章 过程和模块
- 第七章 输入输出和文件
3.1.2 有循环变量的 DO 构造
a) DO 语句和循环次数
DO 构造可分为不带循环变量与带循环变量两种形式。
当需要执行的循环次数为已知时,用 DO 语句实现循环比较方便。它的一般形式为:
DO [[标号][,]] 循环变量=初值式,终值式[,增量式]
例:循环读入学生的学号和成绩 30 次并打印。
DO 10, N=1,30,1
READ *,NUM,GRADE
10 PRINT *,NUM,GRADE
上面是一个循环,第一行 DO 语句称为循环语句,DO 后面的数 10 是一个标号,表示循环的范围到标号为 10 的语句为止,也就是反复执行 READ 语句和 PRINT 语句。DO 语句中的 N 是“循环变量”,用它来控制循环次数,“N=1,30,1”的意思是:N 的初值为 1,终值为 30,每执行一次循环 N 的值增加 1。当 N 再变化到 31 时,由于它已超过了指定的终值 30,不再执行循环。
下面的 DO 语句是合法的:
DO 10,I=1,10,2
DO 20 N=1,5
DO 100,X=1.2,2.4,0.2
DO T=2.5*2,5O./3.,0.3
DO M=1.5,12.5,15
DO 语句的一些特点是:
在上述 DO 语句的一般形式中,当循环变量的增量(步长值) 为 1 时增量式可不写。
循环变量初值、终值和步长可以分别是常数、变量或表达式。如果是变量则它应预先被赋值。如果是表达式,则先计算出表达式的值。循环次数可以从循环初值、终值和步长计算出来:次数=INT((终值-初值+增量)/增量)。如果计算出的循环次数<0 时,则按 0 处理,即一次也不执行循环。
例:对于 D0 I=1,10,2 其循环次数=INT((10-1+2)/2)=5 次。I 按序分别取值为:1,3,5,7,9。对于 D0 I=10,1,2 则循环次数=0 次。I 不可取值,程序运行到这里时将跳过此循环。
循环变量的初值、终值和步长可以为正或负。初值、终值可以为零。但步长不应为 0,否则循环变量的值永远不会超过终值,从而陷入死循环。
例:对于 D0 I=-1,-3,-1 其循环次数=INT((-3+1-1)/(-1))=3 次。I 按序分别取值为:-1,-2,-3。
如果循环变量的类型和初值、终值和步长的类型不一致,则按赋值的规则处理,即需先将初值、终值和步长的类型转化成循环变量的类型,然后进行处理。为避免错误,应尽量使循环变量类型与初值、终值和步长的类型一致。
例:对于 D0 I=1.5,3.6,1.2 不要根据 INT((3.6-1.5+1.2)/1.2)=2 而认为循环次数为 2,而应当先将实型量转化为整型量,即变成相当的循环语句 DO I=1,3,1 其循环次数为 3 次而不是 2 次。
例:对于 D0 X=1.5,3.6,1.2 由于循环变量不是整型的而是实型的,它的循环次数为 2 次。X 取值分别是 1.5,2.7。
由于实型数在运算和存储时有一些误差,因而循环次数的理论值与实际值之间会有一些差别。这种情况在程序设计中常有发生,而且比较隐蔽不易发现。所以应该避免使用实型的循环变量,用整型循环变量计算出的循环次数是绝对准确的。
例:对于 D0 X=0.0,50.0,0.1 理论循环次数=INT(50.1/0.1)=501,但实际上在许多计算机上它只执行 500 次循环。原因是实数在内存中的误差使得增量值不是准确的 0.1,由于循环的误差积累,到执行完 500 次循环后 X 的值可能已超过 50.O,因而停止执行循环。改用整型循环变量时,则循环改写为:D0 I=0,500; X=I/10。
b) DO 循环执行步骤
循环执行过程按序为以下几个步骤:
(1).计算初值式、终值式、增量式的值,并将它们转换成循环变量的类型。
(2).将初值赋予循环变量。
(3).计算应循环的次数。
(4).检查循环次数,若≤0 则跳过循环体,执行循环终端语句下面的一个执行语句。如果>0,则执行循环体。
(5).执行终端语句时,循环变量增值。
(6).循环次数减 1。
(7).返回(4),重复执行(4)、(5)、(6)、(7)。
c) 循环终端语句
上面介绍的循环中,循环终端语句为一般的执行语句。F90 规定:循环终端语句可以是除了 GOTO、块 IF、CASE、CYCLE、DO、ELSE、ELSE IF、END IF、END、END SELECT、EXIT、SELECT CASE、STOP 和 RETURN 语句以外的任一可执行语句,如打印语句、赋值语句、输入语句、逻辑 IF 语句等都可以作为终端语句。特殊的循环终端语句是:END DO(常用于无语句标号时) 和 CONTINUE(常用于有语句标号时)。END DO 语句使老的 CONTINUE 语句显得没有什么用处了,虽然 F90 的向下兼容性使 CONTINUE 语句仍然可用,但新编写的程序应该尽量使用以 END DO 结束的块 DO 构造。
例:用展开式求指数函数的数值。 [e_312_01.f90]
a) 停止语句
CONTINUE 语句本身不进行任何机器操作,只是将流程转到逻辑上的下一个语句,因此,CONTINUE 语句又称为“空语句”,即进行“空操作”。与 CONTINUE 语句(继续功能) 相对应的停止功能语句是 STOP 和 PAUSE 语句。
PAUSE 语句(在 F90 中不推荐使用,在 F95 中被废除) 暂时中止程序的运行,将系统挂起,使程序操作员可以执行其它操作系统命令。它的一般形式是:PAUSE [暂停值],暂停值为字符串常量或 5 位数以下的整型数,当程序运行至断点处将输出暂停值。如无暂停值的话,系统将输出默认的信息,WinNT/9x 系统上输出“回车才能继续”的信息。
例:PAUSE 701
PAUSE 'ERROR DETECTED'
在这些例子中,它的用处是在程序中加入断点把程序分段,以便于一段一段地调试程序。Visual Fortran 的 Debug 功能可代替这种程序调试方法,但它也可以用于一些输出情形。 [e_312_02.f90]
STOP 语句是停止运行,一个程序单位中可以有多个 STOP 语句,执行到任一个 STOP 语句处时,程序即完全中止运行。在子程序中如果有 STOP 语句,也是使整个程序停止运行而不是使控制返回主程序。STOP 语句的一般形式为: STOP [停止值],与 PAUSE 语句类似,程序停止运行时将输出停止值。在 F66 中,END 不作为执行语句而只作为程序单位的结束标志,需要在 END 之前用 STOP 语句使程序结束运行。有些人在写 F77 程序时仍保留此习惯,在 END 语句之前又写了一个 STOP 语句。
b) DO 循环嵌套
在一个 DO 循环中又完整地包含另一个 DO 循环,称为 DO 循环的嵌套。嵌套层数可以不限,各层的循环变量不允许同名。注意内循环应当完整地嵌套在外循环之内,即内循环是外循环体中的一部分,内外循环不能交叉。即:
do i=1,1O
do j=1,20
………
end do
end do
程序的执行过程是外循环执行一次,内循环执行一遍。 [e_312_03.f90]
例:有 10 个实数,将它们按大小排列。 [e_312_04.f90]
c) DO 循环规则
循环变量可以在循环体中被引用,但不应当再被赋值。
例:下面写法是不正确的,循环变量 N 不能在循环体内被重新赋值。
do n=1,1O
………
n=2*n
end do
循环的次数是根据循环变量的初值、终值和步长值计算出来的,在执行循环体期间是确定不变的。
可以用转移语句从循环体内转到循环体外,也可以在循环体内转移,但不允许从循环外转到循环内。(块规则)
例:下面写法是合法的(尽管不符合结构化原则)。
do n=1,1O
………
if(n*x.gt.1.) go to 10
end do
10 ………
例:下面写法是非法的。
if(x.gt.1.) go to 10
do n=1,1O
………
10 ………
end do
多个 DO 循环可以共享一条循环终端语句,但循环体必须完全包含在外围 DO 循环体内。
如果 DO 循环出现在 if,else if 或 else 块内,则 DO 循环范围必须完全包含在该块中。
如果 IF 语句和 SELECT CASE 语句出现在 DO 循环范围内,则相应的 END IF 语句和 END SELECT 语句也必须出现在这个 DO 循环体内。
d) 隐 DO 循环
隐 DO 循环实际上是带控制循环变量的 DO 循环,但简化成只有 DO 循环的第一句,且把关键字 DO 隐去,成为 I=m1,m2,m3形式。它不是独立语句,只是用作为读写语句的输入输出表中一个组成部分,用来控制重复读写的次数。例如:
READ *,(VALUE(I),I=1,20)
表示读入 VALUE(1),VALUE(2),…,VALUE(20) 的值。
WRITE(*,*)(A,B,N=1,5)
表示在当前设备用默认格式重复输出 A、B 的值 5 次。
隐 DO 循环只能作为输入输出表的一部分出现,不能用于其它场合。此时输入输出表的一般形式为:(I/O 列表,循环变量名=初值,终值,增值)。也即把输入输出表与循环控制部分一起用括号括起,中间用逗号分开,称为隐 DO 表,写在读写语句后面作为读写对象。
隐 DO 表可以嵌套,如:
PRINT *, ((A(I,J),I=1,3),J=1,3)
先把内层(A(I,J),I=1,3) 隐 DO 表作为输出表,再与隐 DO 控制 J=1,3 合成外层隐 DO 表。其控制机制与嵌套 DO 循环一致,先内层循环完,外层循环变量加一步长,再循环完内层。其打印值的次序如下:
A(1,1),A(2,1),A(3,1),A(1,2),A(2,2),…,A(3,3)
即先输出第 1 列,再输出第 2 列、第 3 列。如果把 J 作为内层,I 作为外层循环变量,则输出是按行的:
PRINT *,((A(I,J),J=1,3),I=1,3)
则打印输出值的次序为:
A(1,1),A(1,2),A(1,3),A(2,1),A(2,2),…,A(3,3)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论