选择结构

2.3.1 IF构造

a) IF的组成和执行

IF的一般形式可写成:

IF(逻辑表达式) THEN     ← 块IF语句

1                then

ELSE

2                else

END IF

IF语句不是一个单独语句。块IF语句、ELSE语句和ENDIF语句只能用在块IF中而不能单独使用,它们必须和块IF中其它语句联系起来共同起作用。可以说一个块IF是一个语句块(决不能只包括一个语句),用来实现选择结构。但是,块IF可以不包含ELSE语句和else块。then块是当块IF语句中的逻辑表达式为真时执行的语句组。[e_231_01.f90]

IF的执行步骤为:先执行块IF语句,求出逻辑表达式的值,如果此值为“真”,则将流程转到then块。执行then块中各个执行语句。执行完then块后跳过ELSE语句和else块,流程转到END IF语句处。如果逻辑表达式的值为“假”,则流程跳过then块,转到ELSE语句及else块。执行完else块以后流程转到END IF语句。END IF语句是块IF的“出口”,无论执行完then块或else块,流程都转到END IF语句,接着执行ENDIF语句之后的下一语句。END IF语句本身不进行什么操作,它是块IF的结束符号,用它标志块IF的范围(IF语句开始,END IF结束)

一个块IF中可完整地包含另一个(或多个)IF,称为块IF的嵌套。注意嵌套时不能交叉。

b) ELSE IF语句

在块IF中,then块和else块还可以包含另一个块IF,即上面介绍的块IF的嵌套。如果嵌套的层次比较多,而每一个块IF又都要包含块IF语句、ELSE语句、ENDIF语句,程序就会冗长。而且每一层的嵌套都向右缩进,层次多时就会发生困难,无法再向右缩进了。

F77提供ELSE IF语句来处理“否则,如果……”的情况。其一般形式为:

IF(逻辑表达式1) THEN

                         then

ELSE IF(逻辑表达式2) THEN

                         else if

ELSE

                         else

END IF

当处理多分支选择时,用数条ELSE IF语句往往比较方便,在程序中ELSE IF语句不必向右缩进,而连续用多个ELSE IF语句表示各个条件的选择。注意块IF语句必须有一个END IF语句与之对应。而ELSE IF语句不需END IF语句与之对应,它可以有与之配对的ELSE语句。

例:解[e_231_02.f90]

c) IF构造

F90明确提出了块的概念。块是作为单元看待的一个可执行构造的序列,它可用于IF构造、CASE构造和DO构造中,对这三种构造都可命名(即标签)。块的规则为:1)如果一个块中包含一个可执行构造,那么它必须完整地被包含在该块中。2)禁止从块的外部转入块的内部,可以在块的内部进行控制转移,也可以从块内转移到块的外部。3)块是可以嵌套的。

IF构造的一般形式为:

[构造名:] IF(e1) THEN

1

[ELSE IF(e2) THEN [构造名]

2]

[ELSE IF(en) THEN [构造名]

n]

[ELSE [构造名]

n+1]

END IF [构造名]

其中e1,…,en是逻辑表达式,指出各种条件。语句块是一组语句,内容是当e成立(e逻辑表达式值为真)时要执行的算法。IF构造的控制机制为:(1) 检查e1真否。真,执行块1,绕过其它块,直接转出口语句END IF处出口;假,跳过块1,检查e2真否。(2) e2真,执行块2,而后直接转出口;假,跳过块2,检查e3,以此类推;(3) 如果所有ELSE IF语句的e都是假,那么必须执行ELSE语句下的块n1。如果IF构造中没有ELSE语句,就什么也不执行,转出口。由此可见,执行IF构造,自上而下顺次检查每块前面的条件,满足条件的就执行该条件下面的块,执行完该块后立即转向出口。以后即使还有块满足条件(条件可以相交),也不予理睬。因此,一个IF构造中最多只执行一块,也可能一块也不执行。

例:输入实数x,求下面的三角波脉冲函数F(x)的值。[e_231_03.f90]

d) IF构造的缺省形式

IF构造中,then块、else if块、else块都可以缺省。缺省有两种形式,一种是构造中出现该类语句,但后面没有算法语句块;一种是连该类语句一起省略。这两种情况使执行时可能结果不同,应按控制机理仔细分析。

*          只有then

IF(e) THEN

1

END IF

e真,执行块1e假,则不执行任何语句,此时IF构造相当于没有。

*          缺省else if

如果连ELSE IF语句省去:

IF(e) THEN

1

ELSE

2

END IF

e真执行块1,假执行块2

如果保留ELSE IF语句,缺省下面块:

IF(e1) THEN

1

ELSEIF(e2) THEN

ELSE

2

END IF

e1真执行块1e1假、但e2真时不作任何操作,转出口,e1e2都假时,执行语句块2

*          缺省else

IF(e1) THEN

1

ELSEIF(e2) THEN

2

END IF

e1真执行块1e1假、但e2真语句块2e1e2都假时不作任何操作。

*          缺省then

IF THEN语句必须有,但后随的块可以缺省:

IF(e1) THEN

ELSEIF(e2) THEN

2

ELSE

n+1

END IF

e1真时,整个构造等于空设,什么也不执行。只有当e1为假时,才会一块块检查下去。

e) IF构造的嵌套

IF构造的任一语句块中(then块、else if块、else块)都可以嵌入另一个构造,被嵌入的构造可以是另一IF构造,也可以是另一些形态、功能不同的构造,如CASE构造、DO构造,前提是必须把整个构造完整地嵌在IF构造的某一块中,不允许一部分嵌在一个块中,另一部分嵌在另一个块中,即被嵌入的任何构造不可跨越两块。

IF构造嵌套时,为了清晰区分内层与外层构造,一般应对内、外层构造分别取名,并且内层构造要缩进几格(可用[Tab]键统一缩进)。

在某些场合IF构造嵌套是必需的,但嵌套过多,阅读时要一层层地记住前面各层的条件,容易出错,也不易维护,应尽量减少嵌套。办法是把条件分细,列成多句ELSE IF语句。

2.3.2 多重选择和CASE构造

a) 整型

F90增加了CASE构造,提供了从几个可选项中选取一个执行的手段,这是因为在某些多种条件的选择情况下使用IF构造显得比较繁琐,而使用CASE构造可是程序显得直观、简短。CASE构造控制和块IF构造类似,它也是用来编写分叉选择算法,也是根据条件区分作不同的算法,不同的是它只能把某个量分成若干个孤立的离散值,按不同值作不同处理。在处理复杂、多种交叉的条件时不像IF构造方便,但更为简明。其一般形式为:

[构造名:] SELECT CASE(case表达式)

CASE(case选择符) [构造名]

[CASE DEFAULT [构造名]

]

END SELECT [构造名]

其中,case表达式是整型、字符型或逻辑型表达式,不能是实型和复型表达式。SELECT CASE是入口语句,END SELECT是出口语句。case选择符是case值范围表,它有以下四种形式:

(值表)                 表示等于该值,各值之间用逗号分开

(下界:)                表示大于或等于该值

(:上界)                表示小于或等于该值

(下界: 上界)           表示在这两个值之间(包括等于)

上面的四种表示方法可以混用,如CASE(2:5,9)等价于CASE(2,3,4,5,9)

CASE DEFAULT语句是可选的,当case表达式的值在case值范围以外时,执行CASE DEFAULT语句后面的块。CASE构造的执行顺序是:先计算case表达式的值,当它落在值范围内,则执行其后的块。注意,CASE语句是一条单独的语句。

例:错误语句     CASE(0:59)  PRINT*,"不及格"

正确写法     CASE(0:59)PRINT*,"不及格"

例:统计学生考试成绩:100分为满分,85分以上为优,7084为良,6069为及格,59分以下不及格。[e_232_01.f90]

CASE构造的规则是:1) CASE DEFAULT语句最多只能有一句;2) case值必须与表达式的类型相同;3) 给定CASE构造中的case值范围不能有重叠;5) CASE块可以是空的,也可以包含其它块,其嵌套形式与块IF相同。

程序执行时,CASE构造的控制机制是:(1)控制进入CASE构造后,先计算情况表达式的值;(2)如果第一个CASE语句选择符值与情况表达式值相等则执行语句块1,转出口;(3)如第一个选择符值不为情况表达式的值,再查下一个CASE语句的选择符值,满足执行语句块2,转出口,不满足再查下一个CASE语句的选择符值,直至全部情况选择符值都检查完;(4)如果全部情况选择符值都不符情况表达式的值,且又有CASE DEFAULT语句,则执行该语句后的DEFAULT块,否则直接转出口。

例:块IF包含CASE块。(有无错?)

if_construct: if(a.gt.0) then

case_construct_b: select case (b)

case(:0)

……

case(0:)

……

end select case_construct_b

else

case_construct_c: select case (c)

case(:0)

……

case(0:)

……

end select case_construct_c

end if if_construct

b) 字符型

设要编一程序,把学生按专业划分以便检索,专业分为天体物理、应用物理、理论物理三种,把每个专业应修的课程依次编成语句块1、块2、块3,构造名为DEPARTMENT_22_MAJOR,专业变量名为MAJOR,则CASE构造为:

DEPARTMENT_22_MAJOR: SELECT CASE(MAJOR)

CASE(Astronomical Physics)

语句块1

CASE(Applied Physics)

语句块2

CASE(Theoretical Physics)

语句块3

END SELECT DEPARTMENT_22_MAJOR

则当变量MAJOR取值为‘Applied Physics’时,执行语句块2(例如它的功能是打印出学生专业课程成绩),如此等等。

例:字符型选择。[e_232_02.f90]

c) 逻辑型

case表达式为逻辑表达式时,CASE语句中的情况选择符也要取逻辑值:真或假。由于它不可能取多于两个的值,因此在逻辑型的情况选择符内不允许写成一个值域范围(即始值:终值形式)。

设有一个关系表达式X>=3,当成立时打印‘YES’,否则打印印‘NO’。CASE构造为:

SELECT CASE(X>=3)

CASE(.TRUE.)

PRINT *,YES

CASE(.FALSE.)

PRINT *,NO

END SELECT

【作业】

[2.1] IF语句编写下面功能程序:

(1) 读入a,b,若a>b,则置X=1.23,否则置X=32.1,打印X值;

(2) 读入a,b,c,d,若a+b>c+d,则X=1.1,若a+b=c,则X=0.0,若a+b<c+d,则X=-1.1,输出X值;

(3) 读入SS1,如|S-S1|10-7,则置SS1

[2.2] IF构造嵌套方法编程:读入X,分三种情况求得Z值,当X<0时,Z=-100;当X=0时,又分三种情况(y<0,则Z=sinXy=0,则Z=0y>0,则Z=cosX);当X>0时,Z=100,打印Z值。

[2.3] 读入一个整型变量N的值,用CASE构造编程,若N1235,则YXN48,则YX2N67,则YX3,其它情况则Y=0,打印Y值。

[2.4] 设变量color_light是字符型变量,表示灯光色彩,编一CASE构造,当该变量值是红色(RED)则打印STOP字样。当变量值是黄色(YELLOW),打印WAIT字样,当值是绿色(GREEN)打印CROSS字样。