第4章 选择结构
在第三章介绍了最简单的FORTRAN程序,在程序中语句执行的顺序是按照语句书写的顺序决定的,写在前面的语句就先执行,写在后面的语句就后执行,这种执行语句的过程叫顺序执行。导致顺序执行的语句结构叫顺序结构。只包含顺序结构的程序像流水账一样,只能解决简单的、顺序性的问题。有些问题仅用顺序结构是不能解决的,例如,计算税款问题。
【例4.1】 当月收入超过800元时,超过部分按5%纳税,要求写程序完成输入月收入INCOME,计算应交税款TAX。
分析:根据题意,得到税款计算公式:
INCOME?800?0 TAX??INCOME?800INCOME?800?根据上述计算公式画出计算税款的流程图如图4.1:
开始 输入 INCOME 和TAX=0 INCOME>800 Y N TAX=(INCOME-800)*0.05 输出 TAX 结束
图4.1 计算税款的算法流程图
从流程图中可以看见,问题求解的过程不再是顺序性的了,需要对输入的月收入INCOME进行判断再决定计算其应该交纳的税款,即问题求解需要根据输入数据进行选择、判断,出现了选择(分支)结构,为了描述选择结构,FORTRAN语言也提供了对应的能描述选择结构的语句。
4.1 逻辑IF语句
逻辑IF语句格式:
IF (逻辑表达式) 语句
逻辑IF语句功能:求出逻辑表达式的值,如果为“真”,则执行<语句>后再执行后续语句,否则直接执行后续语句。其功能也可以用图4.2所示的流程图描述。
逻辑IF语句说明:
(1)逻辑IF语句描述了最简单的选择结构,只提供<逻辑表达式>为真时的操作,并且只能有一个动作,<逻辑表达式>为假时未提供操作。
65
(2)逻辑IF语句又称“行IF语句”。
逻辑表达式 Y 语句 N
图4.2 逻辑IF结构示意图
利用逻辑IF语句可以将图4.1翻译成程序: REAL INCOME,TAX
READ *,INCOME TAX=0
IF(INCOME.GT.800)TAX=(INCOME-800)*0.05 PRINT *,‘月收入=’,INCOME,‘应交税款为=’,TAX END
由于只有月收入超过了800元才会有税款的计算问题,程序中用逻辑IF语句对应地描述了此分支关系,为了保证低于800元时TAX也有相应的值,所以在判断月收入情况之前TAX被初始化为0。
如果〈逻辑表达式〉为真时要做的操作有两个以上,则可以利用下面介绍的“块IF结构”进行描述。
4.2 块IF结构
块IF结构是由多条语句组合而成的可以描述复杂选择结构的语句组,可以有下面几种格式。
4.2.1 单分支的块IF结构
格式:
IF (逻辑表达式) THEN 语句块 ENDIF
功能:计算逻辑表达式的值,如果为“真”则执行语句块操作,否则执行ENDIF的后续语句。其功能也可以用如图4.3所示的流程图表示。
逻辑表达式 Y 语句块 N
图4.3 单分支块IF结构示意图
说明:
(1)IF-THEN语句称为块IF语句,它和ENDIF语句是块IF结构中必不可少的入口和出口语句,
66
且必须配对使用。
(2)<语句块>可以是一条或多条语句。
对图4.1描述的计算税款问题,也可以用块IF结构写出程序如下:
REAL INCOME,TAX READ*,INCOME TAX=0.0
IF(INCOME.GT.800) THEN TAX=(INCOME-800)*0.05
ENDIF
PRINT*,‘月收入=’,INCOME,‘应交税款为=’,TAX
END
(3)单分支的块IF结构和逻辑IF语句的逻辑功能是相同的,但在块IF结构中,当逻辑表达式为真时可以完成多个操作(语句块),而在逻辑IF语句中,当逻辑表达式为真时只能完成一个操作(语句),并且两者的书写格式也不相同。
【例4.2】 输入A,B,C三个数代表三角形的三边,判断这三个数是否能够组成三角形,若能则用海伦公式计算其面积,否则结束。
海伦公式:面积=S(S?A)(S?B)(S?C),其中S=
A?B?C 2分析:从数学知识知道,任何三个数据可以做三角形三边的充分必要条件是“任何两边之和大于第三边”。根据题意画出求解此问题的流程图如图4.4所示。
开始 输入 A,B,C 能组成三角形 Y 计算并输出三角形面积 N 结束
图4.4 例4.2算法流程图
对于图4.4描述的流程就不能用逻辑IF语句书写程序,因为当逻辑表达式为“真”时,需要完成的工作不是一条语句可以做到的,只能用块IF结构写出对应程序如下: READ*,A,B,C IF((A+B).GT.C.AND.(A+C).GT.B.AND.(B+C).GT.A)THEN
P=(A+B+C)/2
S=SQRT(P*(P-A)*(P-B)*(P-C)) 语句块 PRINT*,‘S=’,S
ENDIF END
67
4.2.2 双分支的块IF
格式:
IF (逻辑表达式)THEN 语句块1
ELSE
语句块2 ENDIF
功能:计算逻辑表达式的值,当逻辑表达式的值为“真”时执行<语句块1>的操作,否则执行<语句块2>的操作。其功能可以用流程图描述为图4.5。
逻辑表达式 Y 语句块1 N 语句块2
图4.5 双分支块IF结构示意图
说明:
(1)IF-THEN-ELSE-ENDIF结构描述了逻辑表达式为“真”和为“假”时都要做相应操作的双分支结构。两个分支中必须选择一个并且只能选择一个,然后直接到块IF结构的出口语句ENDIF。
(2)ELSE语句只能使用在IF-THEN和ENDIF语句之间,分隔<语句块1>和<语句块2>。如果没有<语句块2>,ELSE可以要也可以不要(此时块IF结构已经变成单分支形式)。
(3)<语句块1>和<语句块2>都可以是一条语句或多条语句。
如果将计算税款问题的流程图修改如图4.6所示,可以写出对应的程序如下:
开始 输入 INCOME INCOME>800 Y N TAX=(INCOME-800)*0.05 TAX=0 输出 TAX 结束
图4.6 用双分之块IF结构描述税款问题
REAL INCOME,TAX
68
READ*,INCOME
IF(INCOME.GT.800) THEN
TAX=(INCOME-800)*0.05
ELSE
TAX=0.0
ENDIF PRINT*,‘月收入=’,INCOME,‘应交税款为=’,TAX END
计算税款这样的问题面临的选择结构比较简单,只有两个分支,对于多分支的选择结构可以使用下面形式的块IF结构。
4.2.3 块IF的嵌套
在块IF结构的<语句块>中可以包含任何合法的语句,当然也可以是一个块IF结构,这种情况称为块IF结构的嵌套。
【例4.3】 判断肥胖问题。输入某人的身高(H,cm)和体重(W0,kg),按照下列方法判断其体重情况。
(1)标准体重=(身高-110)公斤 (2)体重超过标准体重5公斤则过胖 (3)体重低于标准体重5公斤则过瘦
根据判断条件,画出流程图如图4.7所示,使用两分支的块IF结构写出程序如下:
开始 输入 H,W0 计算标准体重W1 |W0-W1|<5 Y N N W0>W1 Y 提示 “标准” 提示 “过胖” 提示 “过瘦” 结束
图4.7 例4.3算法流程图
REAL H,W0 READ *,H,W0 W1=H-110
IF(ABS(W0—W1).LE.5)THEN
69
PRINT *,'标准!' ELSE
PRINT *,'过胖!' ELSE
PRINT *,'过瘦!' ENDIF ENDIF END
IF(W0.GT.W1) THEN
在程序最外层的块IF结构中,ELSE后的语句块又是一个两分支的块IF结构。注意各自都有自己的ENDIF出口语句。
书写语句时为了区分嵌套的层次关系,最好将每一个内嵌的块IF结构向右缩进几格,同一层的块IF语句、ELSE语句和ENDIF语句对齐。
使用块IF嵌套结构时,一定要注意IF-THEN和ENDIF语句的配对关系,如果嵌套层数多了就容易漏掉ENDIF语句。其实,FORTRAN语言对ELSE语句后再嵌套块IF结构的形式提供了简化的语句,专门用于表示“否则,如果…”这种情况。
4.2.4 多分支的块IF
格式:
IF (逻辑表达式1)THEN 语句块1
ELSE IF(逻辑表达式2) THEN 语句块2
ELSE IF(逻辑表达式3) THEN 语句块3 ??
ELSE IF(逻辑表达式n)THEN 语句块n ELSE
语句块n+1 ENDIF
功能:计算逻辑表达式1,如果结果为“真”则执行<语句块1>,然后直接到ENDIF出口语句;否则计算逻辑表达式2,如果为“真”则执行<语句块2>,然后直接到ENDIF出口语句….,否则计算逻辑表达式n,如果为“真”则执行<语句块n>,然后直接到ENDIF出口语句,否则执行<语句块n+1>,经ENDIF出口语句。其功能也可以用流程图表示为图4.8。
说明:
(1)ELSEL IF语句相当于把ELSE和其下一行的IF-THEN语句连接成为一个语句。在块IF结构中可以有一个或多个ELSE IF-THEN语句,当然也可以一个也没有。
(2)ELSE IF-THEN语句独立使用,不需要ENDIF配对。但只能在IF-THEN语句和ENDIF语句构成的中间出现。
(3)ELSE语句只能有一个,也可以不要(要看块IF结构中是否需要)。
(4)当选择了某个分支以后,应该直接到ENDIF出口语句,不再进行其它的判断选择,所以,如果要处理多分支选择结构时,用ELSE IF-THEN语句往往很方便 。
70
条件1 Y N N N 条件2 Y 条件n Y 语句块2 语句块2 语句块2 语句块2 图4.8 多分支块IF结构示意图
需要再次重申的是:块IF结构是一个由IF-THEN、ELSE IF-THEN、ELSE和ENDIF几种语句组成的描述分支情况的语句结构,其中IF-THEN是入口语句,ENDIF是出口语句,绝对不能省略。ELSE IF-THEN、ELSE语句则要根据问题描述的需要可以取舍。
利用ELSE IF-THEN语句组成块IF结构,可以更简洁地写出例4.3描述的体重问题程序。
REAL H,W0 READ *,H,W0 W1=H-110
IF(ABS(W0-W1).LE.5)THEN PRINT *,'标准!' ELSEIF(W0.GT.W1) THEN PRINT *,'过胖!' ELSE
PRINT *,'过瘦!' ENDIF END
由于利用了 ELSE IF-THEN 语句,将前面书写的嵌套分支结构程序变成了无嵌套的、三分支的分支结构程序。
【例4.4】 计算利率问题。已知银行存款利率如下(在定期存款期内不计复利)。
活期 0.81 1年定期 3.81 2年定期 4.5 3年定期 5.22 5年定期 5.76
今有现金P,欲存5年,有以下几种方案:
(1)存5年活期; (2)存5次1年期;
(3)存2次2年期,1次1年期; (4)存1次3年期,1次2年期; (5)存1次5年期。 输入方案号C(C的值取1~5),计算出到5年后应得到的本利和。
这是一个较复杂的多分支选择结构问题,根据问题给出的方案可以画出计算本利和的流程图如图4.9所示。在流程图中需要连续判断C的各种取值情况,当然可以用嵌套的块IF结构写出程序,但使用ELSE IF-THEN语句更方便。
71
开始 输入 P,C N C=1 N Y C=2 Y C=3 N Y C=4 N Y 计算方案1利息 计算方案2利息 计算方案3利息 计算方案4利息 计算方案1利息 输出 本金,利润 结束 图4.9 例4.4算法流程图
INTEGER C REAL P,Q READ *,P,C IF(C.EQ.1) THEN
Q=P*0.0297*5 ELSE
IF(C.EQ.2) THEN
Q=P*0.0918*5 ELSE
IF(C.EQ.3) THEN
Q=P*0.099*2+P*0.0918 ELSE
IF(C.EQ.4) THEN
Q=P*0.108+P*0.099 ELSE
Q=P*0.1206 ENDIF ENDIF ENDIF ENDIF PQ=P+Q PRINT*,PQ END
72
程序中有三处ELSE后紧接IF-THEN语句的情况,所以用ELSE IF-THEN替代,程序变成一个没有嵌套的形式:
INTEGER C REAL P,Q READ *,P,C IF(C.EQ.1) THEN
Q=P*0.0297*5 ELSE IF(C.EQ.2)THEN
Q=P*0.0918*5 ELSE IF(C.EQ.3) THEN
Q=P*0.099*2+P*0.0918 ELSE IF(C.EQ.4)THEN
Q=P*0.108+P*0.099 ELSE
Q=P*0.1206 ENDIF PQ=P+Q PRINT *,PQ END
4.3 选择结构程序设计
【例4.5】 判断闰年问题如下: 输入一个年份(例如2000年),要求判断它是否闰年。
判断闰年的方法是:能被4整除但不能被100整除的是闰年;能被4整除又能被400整除的是闰年;其它为非闰年。
要根据输入的年份数确定该年是否闰年,需要用判断闰年的方法进行判定、分析,画出其判断的思路如图4.10所示。
开始 输入年数 满足闰年条件 Y 输出 “是闰年” N 输出 “不是闰年” 结束
图4.10 例4.5算法流程图
由于分支部分是一个双分支关系,只能使用“块IF结构”。将流程图翻译得到程序如下:
73
READ*,YEAR
IF(MOD(YEAR,4).EQ.O.AND.(MOD(YEAR,100)
& .NE.0.OR.MOD(YEAR,400).EQ.0))THEN
PRINT*,‘是闰年’ ELSE
PRINT*,‘不是闰年’ ENDIF END
【例4.6】 求以下分段函数的函数值。
?3x?ln|x|?y??x3?1?(x?0)(0?x?10) (x?10)分析:分段函数中,不同的自变量取值导致函数计算的形式不同,因此对于任何一个x值都应该考察它位于哪个区域,然后再决定相应的函数计算形式。
开始 输入 x x < 0 Y N N x≤10 Y y=3x-ln|x| y=x3 y=1 输出 y 结束
图4.11 例4.6算法流程图
画出流程图如图4.11所示,流程图是一个多分支关系,只能使用“块IF结构”将其翻译得到程序如下:
REAL X,Y READ *,X
IF(X.LT.0)THEN
Y=3*X+LOG(ABS(X)) ELSE IF(X.LE.10)THEN Y=X*X*X ELSE Y=1
74
ENDIF
PRINT *,X,Y END
在流程图中使用的逻辑表达式并不是公式给出的形式,为什么可以这样改变呢?请注意各条件的顺序及含义,例如,ELSE IF-THEN语句中的条件“X.LE.10”并没有写成“X.GE.0.AND.X.LE.10”形式,因为它是在上一个条件“X.LT.0”为“假”的前提下才进行处理的,也即“X.GE.0”成立的情况下,所以,这里书写的“X.LE.10”也就等于“X.GE.0.AND.X.LE.10”的意义。类似的用法今后还会遇到,希望大家能够举一反三,灵活应用。
【例4.7】 有四个圆,圆心分别为(2,2),(-2,2),(2,-2),(-2,-2),圆半径为1(见图4.12)。键盘输入一对坐标点(X,Y),判断该点是否落在某个圆上或圆内,如果是在某个圆上或圆内,相应的H值为10,否则相应的H值为0(该问题也可以描述为:有四个圆塔,高为10米,其他为平地,高为0)。写程序求任意点允许的高度。
y 2 1 -2 -1 -1 -2 1 2 x
图4.12 四个圆的位置示意图
分析:根据问题要求,首先写出这四个圆的方程,依次是:(X+2)2+(Y-2)2=1,(X-2)2+(Y-2)2=1,(X+2)2+(Y+2)2=1,(X-2)2+(Y+2)2=1,要判断某点(X0,Y0)是开始 22
否落在某个圆上或圆内,就要看(X0+2)+(Y0-2)≤1或(X0-2)2+(Y0-2)2≤1或(X0+2)2+(Y0+2)2≤1或(X0-2)2+(Y0+2)2≤1
输入 X,Y 是否为真,再确定该点的高度。算法流程图如图4.13所示。
用“块IF结构”写出程序如下:
N REAL X0,Y0 X,Y在某个圆中 LOGICAL P1,P2,P3,P4
Y READ *,X0,Y0
P1=(X0+2)**2+(Y0-2)**2.LE.1 H = 10 H = 0P2=(X0-2)**2+(Y0-2)**2.LE.1 P3=(X0+2)**2+(Y0+2)**2.LE.1 P4=(X0-2)**2+(Y0+2)**2.LE.1 输入 H IF(P1.OR.P2.OR.P3.OR.P4)THEN H=10
结束 ELSE H=0
图4.13 例4.7算法流程图
75
ENDIF PRINT *,‘(‘,X0,Y0,‘)处的高度应该是:’,H,‘米’ END
由于判断条件较长,书写不方便,所以用四个逻辑变量依次表示条件。其实这个程序也可以用单分支的结构书写出来,读者可以自己试一试画出单分支的流程图再写出程序。
分支结构的构成应该说是自然形成的,问题的判断关系是在问题中确定了的,设计者只是把问题的关系用流程图表示出来,然后再用FORTRAN语言提供的对应语句翻译成程序。
76
习 题 4
. 1 项选择题
(1)下面正确的逻辑IF语句是( )。
A)IF(NX.EQ.NY)THEN GOTO 10 B)IF A.LT.B. PRINT*
C)IF(ABS(X).LE.1E-5) X=5 D)IF(S.AND.(S.LE.2.0))S=2*3 (2)下面正确的语句形式是( )。
A)IF(X.LT.0.0.GT.5.0)X=.TRUE. B)IF(.NOT.(X.LT.1.0))Y=.FALSE. C)IF(X.EQV.Y) A=.T. D)IF(X.LT.1.0)THEN Y=.FALSE. (3)下面程序段中有错误的语句是( )。 A) IF A.GT.B THEN B) A=B C) ELSE
B=A D) END IF
(4)下面程序中有错误的语句是( )。
LOGICAL L
,B/-1.0,1.0/
A) L=A.GT.B B) IF(L)THEN C) X=2A+B LX=0
ELSE X=0 D) X=B
END IF
PRINT*,X,LX END
(5)设I=1,则运行结果为2的程序段是( )。 A) IF(I.LE.2)J=1 B) IF(I.GE.1)J=2 IF(I.GT.1)J=2 IF(I.GE.2)J=3 PRINT*,J J=1
PRINT*,J
C) J=1 D) IF(I.LE.1)J=1 (I.GE.1)J=2 IF(I.LT.2)J=2 (I.GE.2)J=3 IF(I.LT.3)J=3 ,J PRINT*,J
(6)若运行程序时,从键盘输入2.0,则下面程序的运行结果为( )。 ,X
(X.LT.0.0)THEN (X.LT.10.0)THEN 77
4 DATA A IF IF PRINT* READ* IF Y=0.0
ELSEIF Y=1.0/X ELSE
Y=10.0
ENDIF PRINT*,Y END
A)0.000000 B)0.250000 C)0.500000 D)1.000000
(7)执行两次以下程序,若运行时输入的数据分别为2.5和-1.0,则两次的运行结果分别为( )。 LOGICAL L
L=.TRUE. READ*,X
IF(X.LT.0.0)THEN L=.FALSE. ELSE
PRINT*,X ENDIF
IF(.NOT.L)PRINT*,-X END
A)2.5和1.0 B)-2.5和1.0 C)2.5和-1.0 D)-2.5和-1.0 4.2 分析程序
(1)写出程序的执行结果。 M=105 K=0
IF(MOD(M,7).EQ.0.AND.MOD(M,11).EQ.0)K=1
IF(M/8.GT.13)K=2 IF(M.NE.0)K=3 PRINT*,K END
(2)写出程序的执行结果。
I=2 J=-1 K=2
IF(I.LT.5)THEN IF(J.LT.0)THEN K=0 ELSE K=K+1 ENDIF ENDIF PRINT*,K END
4.3 程序填空
(1)程序的功能是判断键盘输入的整数是否为方程X4-3X2-8X-30=0的根,填空完善程序。 INTEGER D,X READ*,X
D=X**4-3*X*X-8*X-30
IF PRINT*,X END
(2)下面程序的功能是求方程X2+BX+C=0实根,填空完善程序。
78
READ*,B,C D=B**2-4*C
IF THEN
IF THEN
X1=B/2.0+SQRT(D)/2.0 X2=-B/2.0-SQRT(D)/2.0 ELSE
X1=-B/2.0 X2=X2
PRINT*,X1,X2 ELSE
PRINT*,‘ERROR!’ ENDIF END (3)下面程序的功能是判断一个整数是否能被3或7整除,若能被整除则输出“YES”,否则输出“NO”,填空完善程序。
READ*,M
IF THEN PRINT*,‘YES’ ELSE
PRINT*,‘NO’ END
4.4 将流程图翻译成FORTRAN语言的程序。
开始 输入 X N X > 0 Y Y=X Y=-X 输入 Y 结束
4.5 程序设计
(1)键盘输入两个整数,判断第一个数是否能被第二个数整除,若能整除则输出“YES”,否则输出“NO”。先画出流程图,再写出程序。
79
(2)从键盘输入三个数,将数值为中的数输出。先画出流程图,再写出程序。 (3)计算分段函数:
?10?f??1??10?x2?y2?1x2?y2?1 x2?y2?1(4)输入一个学生的三门课考试成绩,计算他的平均成绩,并根据平均成绩输出对应的等级。90分以上为‘A’,75分以上为‘B’,60分以上为‘C’,60分以下为‘D’。
(5)有一地区的建筑规划是从市中心向外逐渐增加建筑高度。见图4.16。如果以市中心为坐标原点,则规定:
1区:|X| 与 |Y| 均小于10公里范围内,建筑高度H不超过20米。 2区:|X| 与 |Y| 在20公里以下的,建筑高度H不超过30米。 3区:|X| 与 |Y| 在30公里以下的,建筑高度H不超过50米。 4区:|X| 与 |Y| 超过30公里的,建筑高度H不超过100米。 输入一个(X,Y)值,求出在该处盖房可以达到多少米高。
80
实验四 分支结构程序设计
一、实验要求:
1. 理解分支结构的意义。
2.掌握分支结构的构成及分支语句的功能 3.能书写分支结构程序。 二、实验步骤
1. 打开 Microsoft Developer Studio,建立项目,编辑输入下面程序并运行。如果运行程序后分别输入-100和50,写出输出结果。
program main read*,j IF(J.LT.0)THEN K=0 ELSE K=100 ENDIF PRINT*,K END
问题1:程序运行结果分别是: 问题2:画出程序对应的流程图。
2.将下面的流程图翻译成程序并调试运行,说说程序的功能。 程序代码:
81
3.程序的功能是求方程X2+BX+C=0的实根,填空完善程序并调试 PROGRAM MAIN READ*,B,C D=B**2-4*C IF THEN
IF THEN X1=B/2.0+SQRT(D)/2.0 X2=-B/2.0-SQRT(D)/2.0 ELSE
X1=-B/2.0 X2=X1
PRINT*,X1,X2 ELSE
PRINT*,‘ERROR!’
82
ENDIF END
4.程序功能是计算分段函数,已知程序有错,请调试。
x2?1 (X≤0)
Y=?
x2?x?1 (X>0) PROGRAM MAIN
READ*, X
IF (X.GT.0) Y=X*X-X+1 Y=X*X+1 PRINT Y END
5.从键盘输入三个数,将最大数输出。先画出流程图,再写出程序并调试。
三、总结:
83
百度搜索“70edu”或“70教育网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,70教育网,提供经典综合文库fortran语言教程第4章在线全文阅读。
相关推荐: