资源描述
第三章 流程控制与逻辑运算
3.1 if语句
前面所介绍的程序,它们的执行流程,都是经过直线,一行接着一行来执行,这样的东西是很难做出一个具备复杂功能的程序。功能较强的程序,都免不了会出现一些“流程判断”的命令。也就是能够在程序执行当中自动选择转向、跳过某些程序块来执行程序代码,这也正是if这个关键字的功能。
3.1.1 if的基本用法
If的使用方法很直观,最基本的使用方法是由一个程序模块所构成。当if中所赋值的逻辑判断式成立时,这个程序模块中的程序代码才会执行。
if(逻辑判断式)then
……
…… ←逻辑成立时,才会执行这里的程序代码
……
end if
下面用if来写一个警告车速过快的程序。假设现在正在高速公路上,如果车速超过100公里,就输出警告标志。
1. program ex0301
2. implicit none
3. real::speed
4. write(*,*)"speed:" ! 信息提示
5. read(*,*) speed !读入车速
6. if (speed>100.0) then
7. ! speed>100 时才会执行下面这一行程序
8. write(*,*)"Slow down."
9. end if
10. stop
11. end
程序执行后会要求输入现在车速,如果车速太快会输出“Slow down.”,没有超速的话就不会出现任何警告。
If命令还可以搭配上else,用来赋值当判断不成立时,会去执行某一段程序代码。
if(逻辑判断式)then
……
…… ←——逻辑成立时,执行这一段代码
……
else
……
…… ←———逻辑不成立时,则执行这一段代码
……
end if
看下面例子: 计算并输出下列分段函数值,其中从键盘输入。
PROGRAM EX0302
IMPLICIT NONE
REAL::X,Y
READ(*,*) X
IF (X<0.0) THEN
Y=X**3+2*X**2-4*X+7
ELSE
Y=3*X**2-6*X+10
END IF
WRITE(*,*) 'Y=',Y
END
由此可以看出,一般的块IF结构由块IF语句、THEN块、ELSE语句、ELSE块、END IF语句组成。
块IF结构的执行过程如下:
(1)首先执行块IF语句,计算其中的逻辑表达式值;
(2)如果逻辑表达式值为真,则执行THEN块中的各可执行语句,否则执行ELSE块中的各可执行语句;
(3)无论是执行完THEN块还是完ELSE块,最后都要转到END IF语句,从而结束该块IF结构的执行。
由此可以看出,块IF结构的执行总是从块IF语句开始,以END IF语句结束,而ELSE语句的作用是将THEN块和ELSE块隔开。特别要提醒大家注意的是,THEN块与ELSE块不能都执行,只能根据块IF语句中的逻辑表达式值来确定是执行哪一块。
下面对块IF语句作一些说明:
(1)块IF语句是块IF结构的第一个语句,其中的逻辑表达式必须用一对圆括号括起来;
(2)THEN块可以由若干个可执行语句组成,但一行上只能写一个语句,语句太长时可以使用继续行;
(3)ELSE语句必须单独占一行;
(4)ELSE块也是由若干个可执行语句组成,但一行上只能写一个语句,语句太长时可以使用继续行;
(5)END IF语句是块IF结构的最后一个语句,必须单独占一行,它表示块IF结构的结束;
(6)在一个块IF结构中,块IF语句与END IF语句是必须的,而THEN块、ELSE语句、ELSE块可以根据实际情况省略。
3.1.2 多重判断if-else if
If可以配合else if来做多重判断,多重判断可以一次列出多个条件及多个程序模块,但其中最多只有一个条件成立,也就是最多只有其中一个程序模块会被执行。
IF (条件1) THEN
块1 ←——条件1成立时,执行这个模块程序
ELSE IF (条件2) THEN
块2 ←——条件2成立时,执行这个模块程序
ELSE IF (条件3) THEN
块3 ←——条件3成立时,执行这个模块程序
ELSE IF (条件n) THEN
块n ←——条件n成立时,执行这个模块程序
ELSE
块n+1 ←——每个条件都不成立时,才执行这个模块程序
END IF
下面用一个例子来说明ELSE IF语句的使用。
例如:计算并输出下列分段函数值,其中从键盘输入。
PROGRAM EX0303
IMPLICIT NONE
REAL::X,Y
READ(*,*) X
IF (X>=50.0) THEN
Y=0.0
ELSE IF (X>=40.0) THEN
Y=50-X
ELSE IF (X>=20.0) THEN
Y=30.0-0.5*X
ELSE IF (X>=0.0) THEN
Y=20
ELSE IF (X>=-10.0) THEN
Y=2.0*X+20
ELSE
Y=0.0
END IF
WRITE (*,*) 'Y=',Y
END
在上述程序中,由于第一个ELSE IF语句中的条件“X>=40.0”是在块IF语句中的“X>=50.0”为假的前提下进行处理的,因此,实际上意味着条件为“X>=40.0.AND.X<50.0”。同样的道理,第二个ELSE IF语句中的条件“X>=20.0”,实际上意味着条件为“X>=20.0.AND.X<40.0”。后面两个ELSE IF语句的情况以此类推。
在用ELSE IF语句实现多路分支选择结构时,要注意以下几个问题:
(1)ELSE IF语句相当于将ELSE语句与下一行的块IF语句连接成一个语句。
(2)在用块IF结构实现多路分支时,每一个块IF语句必须有一个END IF语句与之相对应。但ELSE IF语句不需要END IF语句与之相对应。
(3)在一个块IF结构中,可以有多个ELSE IF语句,但只能有一个ELSE语句,且该ELSE语句与块IF结构中的最后一个ELSE IF语句相配对;在一个块IF结构中,也可以只有ELSE IF语句,而没有ELSE语句,此时ELSE块为一个空块。
(4)特别要强调的是,在利用块IF结构的嵌套或者利用ELSE IF语句处理多路分支选择的时候,块IF语句或ELSE IF语句中的条件必须写对,否则会出现逻辑错误,程序运行后将得到错误的结果。
3.1.3 嵌套if语句
介绍完多重判断if-else if后,现在来介绍多层if的使用。
块IF结构嵌套的一般形式为:
IF (C1) THEN
IF (C11) THEN
ELSE
END IF
ELSE
IF (C12) THEN
ELSE
END IF
END IF
其中,C1,C11,C12均为逻辑表达式,并且在所有省略的地方都还可以是块IF结构。
例如:从键盘读入一个成绩,如果在85~100分之间,则输出“Very good”;在70~84分之间,则输出“Good”;在60~69分之间,则输出“Pass”;在60分以下,则输出“No pass”。
PROGRAM EX0304
IMPLICIT NONE
REAL::GRADE
READ(*,*) GRADE
IF (GRADE>=85.0) THEN
WRITE(*,*) 'Very good!'
ELSE
IF (GRADE>=70.0) THEN
WRITE(*,*) 'Good!'
ELSE
IF (GRADE>=60.0) THEN
WRITE(*,*) 'Pass!'
ELSE
WRITE(*,*) 'No pass!'
END IF
END IF
END IF
END
3.1.4 逻辑运算
if命令需要搭配逻辑表达式才能使用。一个逻辑表达式,可以不只是单纯的两个数字之间互相比较大小,它还可以是由两个,甚至多个小逻辑表达式组合成的。
Fortran90的逻辑运算符号共有以下几种:
==
判断是否“相等”
/=
判断是否“不相等”
>
判断是否“大于”
>=
判断是否“大于或等于”
<
判断是否“小于”
<=
判断是否“小于或等于”
逻辑表达式除了可以单纯地对两个数字来比较大小之外,还可以对两个逻辑表达式间的关系来运算,看下面的例子:
IF (A>=80.AND.A<90) then
“.AND.”是并且的意思,所以上一行程序代码的逻辑判断式就是在说“如果A>=80并且A<90的话,就……”。下面就是所有使用在相互关系之间的集合运算符号:
.AND.
交集,如果两边的表达式都成立,整个表达式就成立
.OR.
并集,两边的表达式只要有一个成立,整个表达式就成立
.NOT.
逻辑反向,如果后面的表达式不成立,整个表达式就成立
.EQV.
两边表达式的逻辑运算结果相同时,整个表达式就成立
.NEQV.
两边表达式的逻辑运算结果不同时,整个表达式就成立
3.2 循环语句
循环可以用来自动重复执行某一段程序代码,善用循环可以让让程序代码变得很精简。循环有两种执行格式,第一种格式会固定重复程序代码n次。另一种格式则是不固定重复几次,一直执行到出现跳出循环的命令为止。
3.2.1 DO循环语句
先来看一段实例程序,
例如:我们想对一个好朋友连说10次happy birthday,用前面学过的方法要连续用10个write命令来显示10行happy birthday。使用循环语句就不用这么麻烦。
Program ex0305
implicit none
integer::counter
integer,parameter::lines=10
!counter<=lines之前会一直重复循环
!每执行一次循环counter会累加1
do counter=1,lines,1
write(*,*)"happy birthday",counter
end do
stop
end
程序执行后显示10行happy birthday,每一行最后还会计算行数用的数字:
happy birthday 1
happy birthday 2
happy birthday 3
happy birthday 4
happy birthday 5
happy birthday 6
happy birthday 7
happy birthday 8
happy birthday 9
happy birthday 10
这个程序会重复执行程序中(第7行至第9行)的程序代码10次。下面是do语句的详细语法:
DO V=e1,e2,e3
其中,V称为循环控制变量,并且它只能是简单变量(整型或实型),而不能是表达式。e1,e2,e3分别为循环控制变量的初值、终值和增量(步长),它们都可以是表达式。当e3为1时,e3可以省略。
DO循环结构的执行过程如下图所示:
计算e1,e2,e3的值
V= e1
计算循环次数CONT=INT((e2-e1+ e3)/ e3)
当CONT>0
循环体语句
V=V+e3
CONT=CONT+1
由上图中可以看出,DO循环的执行过程如下:
首先分别计算表达式e1,e2,e3的值,并将它们转换成与循环控制变量V的类型一致;然后将初值e1赋给循环控制变量V,并计算需要循环的次数CONT=INT((e2-e1+ e3)/ e3);最后根据循环次数执行循环体中的各语句,并且每执行完一次循环体,就将循环控制变量V增值一次,循环次数减少一次。
下面再举一个例子来说明DO循环结构。
例如:用DO循环语句的功能是计算并输出(阶乘)值,其中从键盘输入。
PROGRAM EX0306
IMPLICIT NONE
INTEGER::N,K
REAL::S
READ(*,*)N
S=1.0
DO K=1,N
S=S*K
END DO
WRITE(*,*)N,'!=',S
END
在DO语句中,由于步长为1,因此其步长就省略了。
3.2.2 DO WHILE循环
循环并不一定要由循环控制变量的增、减来决定是否该结束循环,它可改由一个逻辑运算来决定,这就是do while的功能。的do while语句的详细语法为:
do while(逻辑运算)←-----逻辑运算成立时,会一直重复执行循环
……
……
end do
例如:用do while 语句计算2+4+6+8+10
Program ex0307
implicit none
integer,parameter::limit=10 !循环控制变量的上限
integer::counter ! 循环控制变量
integer::ans=0 !拿来累加使用
counter=2 !设置循环控制变量的初值
do while(counter<=limit)
ans=ans+counter
counter=counter+2 !循环控制变量累加
end do
write (*,*)ans
stop
end
执行后结果会显示30
3.2.3 循环的流程控制
(1)cycle命令
Cycle命令可以略过循环程序模块中,在cycle命令后面的所有程序代码,直接跳回循环的开头来进行下一次循环,来看下面的例子。
例如:假设某百货公司共有9层楼,但电梯在4层不停,试写一个程序来仿真百货公司中电梯从一楼爬升到9楼时的等号显示情况。
program ex0308
implicit none
integer:: dest=9
integer:: floor
do floor=1,dest
if(floor==4) cycle
write(*,*) floor
end do
stop
end
执行结果如下:
1
2
3
5(没有出现4,直接跳到5)
6
7
8
9
在程序中,如果需要略过目前的循环程序模块,直接进行下一个循环时,就可以使用cycle命令。
(2)exit命令
Exit的功能是可以直接“跳出”一个正在运行的循环,不论是do循环还是do while循环都可以使用。看下面的例子。
例如:某女士把她的体重视为秘密,下面这个程序可以让大家来猜她的体重。
1. program ex0309
2. implicit none
3. real, parameter:: weight=45.0 !答案
4. real, parameter:: error=0.0001 !误差
5. real:: guess !猜测值
6.
7. do while(.true.)
8. write(*,*) "weight"
9. read(*,*) guess
10. if (abs(guess-weight)<error) exit
11. end do
12.
13. write(*,*)"You are right!"
14. stop
15. end
程序执行后会不断要求用户猜一个数字,一直到猜到答案才会停止。
程序中的第7行第一次出现这个用法:
7. do while(.true.)
循环的逻辑表达式直接放入一个.true.值,这是允许的做法,代表这个循环继续执行的条件永远成立,不需要判断。如果不在循环中加入跳出循环(exit命令)的描述,会造成循环一直执行下去,程序无法终止,所以在第10行加入了exit命令。
第10行表示当猜测值(guess)和答案(weight)之差的绝对值小于误差(error)时,执行命令(exit)跳出循环。
展开阅读全文