 |
» |
|
|
 |
A
control construct consists of a statement block whose execution
logic is defined by one of the following control statements: A
statement block is a sequence of statements delimited by a control
statements and its corresponding terminal statement. A statement
block consists of zero or more statements and can include nested
control constructs. However, any nested construct must have its
beginning and end within the same statement block. Although
the Standard forbids transferring control into
a statement block except by means of its control statement, HP Fortran
90 allows it. The Standard does permit the transferring control
out of a statement block. For example,
the following IF
construct contains a GO TO
statement that legally transfers control to a label that is defined
outside the IF
construct: IF (var > 1) THEN var1 = 1 ELSE GO TO 2 END IF ... 2 var1 = var2 |
The next logical IF
statement is nonstandard (but permitted by HP Fortran 90) because
it would transfer control into the DO
construct: IF (.NOT.done) GO TO 4 ! nonstandard! ... DO i = 1, 100 sum = b + c 4 b = b + 1 END DO |
The following sections describe the operations performed by
the three control constructs. CASE construct |  |
The
CASE construct
selects (at most) one out of a number of statement blocks for execution. Syntax[construct-name :] SELECT CASE ( case-expr ) [CASE ( case-selector ) [ construct-name ] statement-block ] ... [CASE DEFAULT [construct-name] statement-block ] END SELECT [ construct-name] Notes on syntax case-selector
is one of the following: For additional information about case-selector,
see the description of the CASE
statement in Chapter 10. case-selectors must be
mutually exclusive and must agree in type with case-expr. case-expr must evaluate
to a scalar value and must be an integer, logical, or character
type. If construct-name is
given in the SELECT CASE
statement, the same name may appear after any CASE
statement within the construct, and must appear in the END CASE
statement. The construct name cannot be used as a name for any other
entity within the program unit. CASE
constructs can be nested. Construct names can then be useful in
avoiding confusion. Although the Standard forbids
branching to any statement in a CASE
construct other than the initial SELECT CASE
statement from outside the construct, HP Fortran 90 allows it. The
Standard allows branching to the END SELECT
statement from within the construct.
Execution logicThe execution sequence of the CASE
construct is as follows: case-expr is evaluated. The resulting value is compared to each case-selector. If a match is found, the corresponding statement-block
executes. If no match is found but a CASE DEFAULT
statement is present, its statement-block
executes. If no match is found and there is no CASE
DEFAULT statement,
execution of the CASE
construct terminates without any block executing. The normal flow of execution resumes with the first
executable statement following the END SELECT
statement, unless a statement in statement-block
transfers control.
ExampleThe following CASE
construct prints an error message according to the value of ios_err: INTEGER :: ios_err... SELECT CASE (ios_err) CASE (:900) PRINT *, "Unknown error" CASE (913) PRINT *, "Out of free space" CASE (963:971) PRINT *, "Format error" CASE (1100:) PRINT *, "ISAM error" CASE DEFAULT PRINT *, "Miscellaneous Error" END SELECT |
DO construct |  |
The
DO construct
repeatedly executes a statement block. The syntax of the DO
statement provides two ways to specify the number of times the statement
block executes: By specifying a loop count. By testing a logical expression as a condition for
executing each iteration.
You can also omit all control logic from the DO
statement, in effect creating an infinite loop. The following sections
describe the three variations of the DO
construct. You can use the CYCLE
and EXIT statements
to alter the execution logic of the DO
construct. For information about these statements, see “Flow control statements”. Counter-controlled DO loopA
counter-controlled DO
loop uses an index variable to determine the number of times the
loop executes. Syntax[ construct-name : ] DO index = init, limit [ , step ] statement-block END DO [ construct-name ] HP
Fortran 90 also supports the older, FORTRAN 77-style syntax of the
DO loop: DO label index = init, limit [ , step ] statement-sequence label terminal-statement A third form, combining elements of the other two, is also
supported: [construct-name :] DO label index = init, limit [, step] For a full description of the DO
loop syntax—including a list of legal terminal-statements—see
the DO statement
in Chapter 10. Execution logicThe following execution steps apply to all three syntactic
forms, except as noted: The loop becomes active, and index
is set to init. The iteration count is determined by the following
expression: MAX( INT ( limit - init + step ) / step, 0 ) step is optional, with the default
value of 1. It may not be 0. Note that the iteration count is 0 if either of the following
conditions is true: step (if
present) is a positive number and init
is greater than limit. step is a negative number
and init is less than limit.
If the iteration count is 0, the construct becomes
inactive and the normal flow of execution resumes with the first
executable statement following the END DO
or terminal statement. statement-block executes.
(In the case of the old-style syntactic form, both statement-sequence
and terminal-statement execute.) The iteration count is decremented by 1, and index
is incremented by step, or by 1 if step
is not specified. Go to Step 3.
 |  |  |  |  | NOTE: To ensure compatibility with older
versions of Fortran, you can use the +onetrip
compile-line option to ensure that, when a counter-controlled DO
loop is encountered during program execution, the body of the loop
executes at least once. For more information about this option,
see Chapter 13. |  |  |  |  |
ExampleThis example uses nested DO
loops to sort an array into ascending order: INTEGER :: scores(100) DO i = 1, 99 DO j = i+1, 100 IF (scores(i) > scores(j)) THEN temp = scores(i) scores(i) = scores(j) scores(j) = temp END IF END DO END DO |
The following example
uses the older syntactic form. Note that, unlike the newer form,
old-style nested DO
loops can share the same terminal statement: DO 10 i = 1, 99 DO 10 j = i+1, 100 if (scores(i) <= scores(j)) GO TO 10 temp = scores(i) scores(i) = scores(j) scores(j) = temp 10 CONTINUE |
A
conditional DO
loop uses the WHILE
syntax to test a logical expression as a condition for executing
the next iteration. Syntax[ construct-name :] DO WHILE ( logical-expression ) statement-block END DO [ construct-name ] Fortran 90 also supports the older syntax of the DO WHILE
loop: DO label WHILE ( logical-expression ) statement-sequence label terminal-statement Execution logicThe loop becomes active. The logical-expression
is evaluated. If the result of the evaluation is false, the loop
becomes inactive, and the normal flow of execution resumes with
the first executable statement following the END DO
statement, or in the old DO-loop
syntax, the terminal statement. statement-block executes.
(In the case of the old-style syntactic form, both statement-sequence
and terminal-statement execute.) Go to Step 2.
Example! Compute the number of years it takes to ! double the value of an investment earning ! 4% interest per annum REAL :: money, invest, interest INTEGER :: years money = 1000 invest = money interest = .04 years = 0 DO WHILE (money < 2*invest) ! doubled our money? years = years + 1 money = money + (interest * money) END DO PRINT *, "Years =", years |
The
DO statement
for the infinite DO
loop contains no loop control logic. It executes a statement block
for an indefinite number of iterations, until it is terminated explicitly
by a statement within the block; for example, a RETURN
or EXIT statement. Syntax[ construct-name :] DO statement-block END DO [ construct-name ] Execution logicThe execution sequence of an infinite DO
loop is as follows: The loop becomes active. statement-block executes. Go to Step 2.
Example! Compute the average of input values; ! press 0 to exit INTEGER :: i, sum, n sum = 0 n = 0 average: DO PRINT *, 'Enter a new number or 0 to quit' READ *, i IF (i == 0) EXIT sum = sum + i n = n + 1 END DO average PRINT *, 'The average is ', sum/n |
IF construct |  |
The
IF construct
selects between alternate paths of execution. The executing path
is determined by testing logical expressions. At most, one statement
block within the IF
construct executes. Syntax[construct-name :] IF (logical-expression1) THEN statement-block1 [ELSE IF (logical-expression2) THEN [construct-name] statement-block2 ] ... [ELSE [construct-name] statement-block3] END IF [construct-name] Execution logiclogical-expression1 is evaluated.
If it is true, statement-block1 executes. If logical-expression1
evaluates to false and ELSE IF
statements are present, the logical-expression
for each ELSE IF
statement is evaluated. The first expression to evaluate to true
causes the associated statement-block
to execute. If all expressions evaluate to false and the ELSE
statement is present, its statement-block
executes. If the ELSE
statement is not present, no statement block within the construct
executes. The normal flow of execution resumes with the first
executable statement following the END IF
statement.
Example! Compare two integer values IF ( num1 < num2 ) THEN PRINT *, "num1 is smaller than num2." ELSE IF ( num1 > num2 ) THEN PRINT *, "num1 is greater than num2." ELSE PRINT *, "The numbers are equal" END IF |
|