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.
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 END IF
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
END IF
statement.
Y = 0.0 Z = -1.0 IF (X .NE. 0.0) THEN Y = 1.0/X Z = X**2 END IF 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**2
. 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 END IF
statement.
IF (logical-expression) THEN statement-block1 ELSE statement-block2 END IF
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.
Suppose CREDIT
and DEBIT
have been declared to be
INTEGER
variables and TRNSCT
(short for
'transaction') has been declared to be a REAL
variable.
IF (TRNSCT .GE. 0.0) THEN CREDIT = CREDIT + 1 ELSE DEBIT = DEBIT + 1 END IF
Assuming that these variables have been given values earlier in the program,
this IF
statement tests to see if TRNSCT
is
non-negative. If it is, the logical expression evaluates to
.TRUE.
and the variable CREDIT
is incremented by 1.
Otherwise, the variable DEBIT
is incremented by 1. 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
statements following.
Note how this structure differs from the previous one. In the
IF-THEN-END IF
, it is possible for no action to take place.
However, with an IF-THEN-ELSE-END IF
structure, one of the
blocks must be executed.
IF (logical-expression1) THEN statement-block1 ELSE IF (logical-expression2) THEN statement-block2 ELSE IF (logical-expression3) THEN statement-block3 … ELSE statement-blockn END IF
This is the most general case, allowing for multiple decisions with an
optional default. Any number of ELSE IF-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.
The Gregorian reform of the Julian calendar during the sixteenth century gave us the rule we use today to determine leap years. Years evenly divisible by 4 are leap years but the only centurial years (years ending with 00) that are leap years are those evenly divisible by 400.
IF (MOD(YEAR,400) .EQ. 0) THEN WRITE(*,*)YEAR,' is a leap year' ELSE IF (MOD(YEAR,100) .EQ. 0) THEN WRITE(*,*)YEAR,' is NOT a leap year' ELSE IF (MOD(YEAR,4) .EQ. 0) THEN WRITE(*,*)YEAR,' is a leap year' ELSE WRITE(*,*)YEAR,' is NOT a leap year' END IF
This block IF
statement is one way of testing to see if an
INTEGER
variable called YEAR
is a leap year or not.
(Note that this is a very inefficient algorithm for calculating leap years!)
The MOD
function returns the value argument1
modulo argument2. The first logical expression,
(MOD(YEAR,400) .EQ. 0
returns .TRUE.
if
the year is evenly divisible by 400. If it is, then the year followed by
the message is a leap year
is written to the
standard output device. If not, the second logical expression is
evaluated. This one tests to see if YEAR
is evenly divisible
by 100
. This takes care of the other three centurial year
cases. The third logical expression looks for years that are evenly
divisible by 4. If none of the logical expressions evaluate to
.TRUE.
, then the ELSE
block is executed, leaving
us with no leap year.
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
GO TO
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
END IF
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 ELSE IF
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' ELSE IF (DISC .LT. 0.0) THEN WRITE(*,*)'The roots are complex conjugates' ELSE WRITE(*,*)'The roots are real and identical' END IF ELSE WRITE(*,*)'The equation is linear, not quadratic' END IF
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 is strongly
discouraged.
It is equivalent to this block IF
statement:
IF (arithmetic-expression .LT. 0) THEN GO TO label-1 ELSE IF (arithmetic-expression .EQ. 0) THEN GO TO label0 ELSE GO TO label1 END IF