Control structures alter the normal sequential flow of a statement execution.
IF statements allow a program to follow different paths
depending on predefined criteria.
IF (logical-expression) statement
Any executable statement may appear in the statement except
DO, IF, any part of a block IF
statement or END.
If the logical-expression evaluates to .TRUE., then
the statement is executed and control passes on to the next
executable statement in the program. However, if the
logical-expression evaluates to .FALSE., then the
statement is ignored and as before, control passes on to the next
executable statement in the program.
Consider this program fragment:
... Y = 0.0 IF (X .NE. 0.0) Y = 1.0/X WRITE(*,*)X,Y ...
The variable Y is assigned the value 0.0. Then
a logical IF statement is encountered. If X
is nonzero (supposedly X has been assigned a value somewhere
earlier in the program), then Y is assigned the value of
1.0/X and both values are written out to the default output
device. However, if X is zero, then the logical
expression X .NE. 0.0 is false. In this instance,
the statement Y = 1.0/X is skipped and control
passes immediately to the WRITE statement following.
The block IF statement is a more general version of the
simple logical IF and can take several forms, depending
on the complexity of the decisions and/or branching.
IF (logical-expression) THEN statement1 statement2 ... statementn ENDIF
This is the simplest form of the block IF. Instead of
a single executable statement, the word THEN follows the
logical-expression. Then one or more executable statements
are listed in the order they should be executed (this is the
"statement block" which gives the block IF its
name) and the block IF statement concludes with an
ENDIF statement.
Consider this program fragment:
... Y = 0.0 Z = -1.0 IF (X .NE. 0.0) THEN Y = 1.0/X Z = X + Y ENDIF WRITE(*,*)X,Y,Z ...
Here the variable Y is assigned the value 0.0 and
the variable Z is assigned the value -1.0.
Then a block IF statement is encountered. If X
is nonzero then Y is assigned the value of 1.0/X and
Z is assigned the value X + Y. Then all
three values are written out to the default output device. However, if
X is zero, then the logical expression
X .NE. 0.0 is false. In this instance, the statements
inside the block are skipped and control passes immediately to the
WRITE statement following the ENDIF statement.
IF (logical-expression) THEN statement-block1 ELSE statement-block2 ENDIF
This slightly more complicated case allows for one statement block to be
executed if the logical-expression evaluates to .TRUE.
and an alternative statement block to be executed if the
logical-expression is .FALSE.
Consider this program fragment:
... IF (X .NE. 0.0) THEN Y = 1.0/X Z = X + Y ELSE Y = 0.0 Z = -1.0 ENDIF WRITE(*,*)X,Y,Z ...
If X is nonzero then Y is assigned the value of
1.0/X and Z is assigned the value
X + Y. However, if X is zero, then the
logical expression X .NE. 0.0 is false. In this
instance, the second block of statements is executed. In particular,
the variable Y is assigned the value 0.0 and
the variable Z is assigned the value -1.0.
After one of the blocks has been executed, all three values are written out
to the default output device.
Only one of the blocks is executed, depending on the value of the
logical-expression. Once one of the blocks has been executed,
control transfers to the end of the block IF and the
WRITE statement following.
Note how this structure differs from the previous one. In the
IF-THEN-ENDIF, it is possible for no action to take place.
However, with an IF-THEN-ELSE-ENDIF structure, one of the
blocks must be executed.
IF (logical-expression1) THEN statement-block1 ELSEIF (logical-expression2) THEN statement-block2 ELSEIF (logical-expression3) THEN statement-block3 ... ELSE statement-blockn ENDIF
This is the most general case, allowing for multiple decisions with an
optional default. Any number of ELSEIF-THEN blocks may be
used and the final ELSE block is optional. If it exists, then
it will be executed if none of the preceding logical expressions evaluate to
.TRUE. However, if there is no ELSE block, then
it is entirely possible that none of the blocks in the
block IF statement will be executed. Note that if an
ELSE block is to be included in a block IF
statement, it must be the final block.
Consider this program fragment:
... IF (X .GT. 0.0) THEN Y = 1.0/X Z = X + Y ELSEIF (X .LT. 0.0) THEN X = -X Y = 1.0/X Z = X - Y ELSE Y = 0.0 Z = -1.0 ENDIF WRITE(*,*)X,Y,Z ...
If X is positive then Y is assigned the value of
1.0/X and Z is assigned the value
X + Y. If X is negative then
X is turned into a positive number, Y is assigned
the value of 1.0/X and Z is assigned the value
X - Y. However, if X is neither
positive nor negative (that is to say, zero), then the final
ELSE block is executed. In particular,
the variable Y is assigned the value 0.0 and
the variable Z is assigned the value -1.0.
After one of the three blocks has been executed, all three values are written
out to the default output device.
Any executable statement may appear in the statement block except
END. In particular, another complete block IF
or a complete DO loop may appear within the statement block.
Control may pass out of the block (for instance, with a
GOTO statement) but it is illegal to transfer into the
middle of a block. After a block of statements has been executed, control
is passed to the next executable statement following the ENDIF
statement (unless, of course, control was passed out of the block in some
manner).
If a block IF statement contains many branches, then the
order in which the ELSEIF blocks occur may affect efficiency.
Place the blocks which are most likely to be executed near the top of the
block IF. Remember: the optional ELSE block
must always occur last.
In each of the examples, the statement blocks are indented slightly from the left. This is not a requirement but makes the structure of the program much more immediately obvious, particularly when there is deep nesting of control structures.
Nesting refers to the inclusion of a complete control structure
within another control structure. For instance, it is possible to place
a block IF statement within another
block IF. The two block IF statements
do not overlap; rather, one contains the other.
Consider this program fragment where the variables A,
B and C have already been assigned values.
...
IF (A .NE. 0.0) THEN
DISC = B**2 - 4.0*A*C
IF (DISC .GT. 0.0) THEN
WRITE(*,*)'The roots are real and distinct'
ELSEIF (DISC .EQ. 0.0) THEN
WRITE(*,*)'The roots are real and identical'
ELSE
WRITE(*,*)'The roots are complex conjugates'
ENDIF
ELSE
WRITE(*,*)'The equation is linear, not quadratic'
ENDIF
...
If A is non-zero, then the first statement block is
executed. The value for the variable DISC is calculated and
then another complete block IF statement is encountered.
The string
The roots are real and distinct is
written out if DISC is positive. If DISC is
exactly zero, then
The roots are real and identical is
written out. However, if DISC is neither positive nor zero
(that is, if DISC is negative), then
The roots are complex conjugates is
written out. This inner or nested block IF statement
then concludes within in the first statement block of the outer
block IF.
If, however, A is zero, then the second statement block is
executed; namely, the string
The equation is linear, not quadratic
is written out. The outer block IF statement then
concludes.
The careful use of indentation makes nested constructs easier to see although it has no effect on the running of the program.
It is also possible to nest different types of control structures. For
instance, you can nest a DO loop within a statement block
of a block IF statement. Conversely, a
DO loop can contain a block IF. The
only consideration is that one structure must be fully contained within the
other. Overlap is not allowed.
IF (arithmetic-expression) label-1, label0, label1
This form of IF statement is obscure and its use in modern
programs is strongly discouraged. It is equivalent to this
block IF statement:
IF (arithmetic-expression .LT. 0) THEN GOTO label-1 ELSE IF (arithmetic-expression .EQ. 0) THEN GOTO label0 ELSE GOTO label1 ENDIF