Previous | Contents | Index |
This chapter describes:
A program normally executes statements in the order in which they are written. Executable control constructs and statements modify this normal execution by transferring control to another statement in the program, or by selecting blocks (groups) of constructs and statements for execution or repetition.
In Fortran 95/90, control constructs (CASE, DO, and IF) can be named. The name must be a unique identifier in the scoping unit, and must appear on the initial line and terminal line of the construct. On the initial line, the name is separated from the statement keyword by a colon (:).
A block can contain any executable Fortran statement except an END statement. You can transfer control out of a block, but you cannot transfer control into another block.
DO loops cannot partially overlap blocks. The DO statement and its
terminal statement must appear together in a statement block.
7.2 Branch Statements
Branching affects the normal execution sequence by transferring control to a labeled statement in the same scoping unit. The transfer statement is called the branch statement, while the statement to which the transfer is made is called the branch target statement.
Any executable statement can be a branch target statement, except for the following:
Certain restrictions apply to the following statements:
Statement | Restriction |
---|---|
DO terminal statement | The branch must be taken from within its nonblock DO construct. 1 |
END DO | The branch must be taken from within its block DO construct. |
END IF | The branch should be taken from within its IF construct. 2 |
END SELECT | The branch must be taken from within its CASE construct. |
The following branch statements are described in this section:
The unconditional GO TO statement transfers control to the same branch target statement every time it executes. It takes the following form:
|
label
Is the label of a valid branch target statement in the same scoping unit as the GO TO statement.
The unconditional GO TO statement transfers control to the branch target statement identified by the specified label.
The following are examples of GO TO statements:
GO TO 7734 GO TO 99999 |
The computed GO TO statement transfers control to one of a set of labeled branch target statements based on the value of an expression. It is an obsolescent feature in Fortran 95.
The computed GO TO statement takes the following form:
|
label-list
Is a list of labels (separated by commas) of valid branch target statements in the same scoping unit as the computed GO TO statement. (Also called the transfer list.) The same label can appear more than once in this list.expr
Is a scalar numeric expression in the range 1 to n, where n is the number of statement labels in label-list. If necessary, it is converted to integer data type.
When the computed GO TO statement is executed, the expression is evaluated first. The value of the expression represents the ordinal position of a label in the associated list of labels. Control is transferred to the statement identified by the label. For example, if the list contains (30,20,30,40) and the value of the expression is 2, control is transferred to the statement identified with label 20.
If the value of the expression is less than 1 or greater than the number of labels in the list, control is transferred to the next executable statement or construct following the computed GO TO statement.
The following example shows valid computed GO TO statements:
GO TO (12,24,36), INDEX GO TO (320,330,340,350,360), SITU(J,K) + 1 |
The ASSIGN statement assigns a label to an integer variable. Subsequently, this variable can be used as a branch target statement by an assigned GO TO statement or as a format specifier in a formatted input/output statement.
The ASSIGN and assigned GO TO statements have been deleted in Fortran 95; they were obsolescent features in Fortran 90. HP Fortran fully supports features deleted in Fortran 95.
On obsolescent features in Fortran 95 and Fortran 90, as well as
features deleted in Fortran 95, see Appendix A.
The ASSIGN statement assigns a statement label value to an integer
variable. It takes the following form:
When an ASSIGN statement is executed, the statement label is assigned
to the integer variable. The variable is then undefined as an integer
variable and can only be used as a label (unless it is later redefined
with an integer value).
The ASSIGN statement must be executed before the statements in which
the assigned variable is used.
The following example shows ASSIGN statements:
Note that NSTART and KSTOP are integer variables implicitly, but ERROR
must be previously declared as an integer variable.
The following statement associates the variable NUMBER with the
statement label 100:
If an arithmetic operation is subsequently performed on variable NUMBER
(such as follows), the run-time behavior is unpredictable:
To return NUMBER to the status of an integer variable, you can use the
following statement:
This statement dissociates NUMBER from statement 100 and assigns it an
integer value of 10. Once NUMBER is returned to its integer variable
status, it can no longer be used in an assigned GO TO statement.
The assigned GO TO statement transfers control to the statement whose
label was most recently assigned to a variable. The assigned GO TO
statement takes the following form:
The variable must have a statement label value assigned to it by an
ASSIGN statement (not an arithmetic assignment statement) before the GO
TO statement is executed.
If a list of labels appears, the statement label assigned to the
variable must be one of the labels in the list.
Both the assigned GO TO statement and its associated ASSIGN statement
must be in the same scoping unit.
The following example is equivalent to
GO TO 200
:
The following example is equivalent to
GO TO 450
:
The following example shows an invalid use of an assigned variable:
In this case, variable J is not the variable assigned to, so it cannot
be used in the assigned GO TO statement.
7.2.3.1 ASSIGN Statement
label
Is the label of a branch target or FORMAT statement in the same scoping
unit as the ASSIGN statement.
var
Is a scalar integer variable.
INTEGER ERROR
...
ASSIGN 10 TO NSTART
ASSIGN 99999 TO KSTOP
ASSIGN 250 TO ERROR
ASSIGN 100 TO NUMBER
NUMBER = NUMBER + 1
NUMBER = 10
7.2.3.2 Assigned GO TO Statement
var
Is a scalar integer variable.
label-list
Is a list of labels (separated by commas) of valid branch target
statements in the same scoping unit as the assigned GO TO statement.
The same label can appear more than once in this list.
ASSIGN 200 TO IGO
GO TO IGO
ASSIGN 450 TO IBEG
GO TO IBEG, (300,450,1000,25)
ASSIGN 10 TO I
J = I
GO TO J
7.2.4 Arithmetic IF Statement
The arithmetic IF statement conditionally transfers control to one of three statements, based on the value of an arithmetic expression. It is an obsolescent feature in Fortran 95 and Fortran 90.
The arithmetic IF statement takes the following form:
|
expr
Is a scalar numeric expression of type integer or real (enclosed in parentheses).label1, label2, label3
Are the labels of valid branch target statements that are in the same scoping unit as the arithmetic IF statement.
All three labels are required, but they do not need to refer to three different statements. The same label can appear more than once in the same arithmetic IF statement.
During execution, the expression is evaluated first. Depending on the value of the expression, control is then transferred as follows:
If the Value of expr is: | Control Transfers To: |
---|---|
Less than 0 | Statement label1 |
Equal to 0 | Statement label2 |
Greater than 0 | Statement label3 |
The following example transfers control to statement 50 if the real variable THETA is less than or equal to the real variable CHI. Control passes to statement 100 only if THETA is greater than CHI.
IF (THETA-CHI) 50,50,100 |
The following example transfers control to statement 40 if the value of the integer variable NUMBER is even. It transfers control to statement 20 if the value is odd.
IF (NUMBER / 2*2 - NUMBER) 20,40,20 |
On obsolescent features in Fortran 95 and Fortran 90, see Appendix A.
7.3 CALL Statement
The CALL statement transfers control to a subroutine subprogram. It takes the following form:
|
sub
Is the name of the subroutine subprogram or other external procedure, or a dummy argument associated with a subroutine subprogram or other external procedure.a-arg
Is an actual argument optionally preceded by [keyword=], where keyword is the name of a dummy argument in the explicit interface for the subroutine. The keyword is assigned a value when the procedure is invoked.Each actual argument must be a variable, an expression, the name of a procedure, or an alternate return specifier. (It must not be the name of an internal procedure, statement function, or the generic name of a procedure.)
An alternate return specifier is an asterisk (*), or ampersand (&) followed by the label of an executable branch target statement in the same scoping unit as the CALL statement. (An alternate return is an obsolescent feature in Fortran 95 and Fortran 90.)
When the CALL statement is executed, any expressions in the actual argument list are evaluated, then control is passed to the first executable statement or construct in the subroutine. When the subroutine finishes executing, control returns to the next executable statement following the CALL statement, or to a statement identified by an alternate return label (if any).
If an argument list appears, each actual argument is associated with the corresponding dummy argument by its position in the argument list or by the name of its keyword. The arguments must agree in type and kind parameters.
If positional arguments and argument keywords are specified, the argument keywords must appear last in the actual argument list.
If a dummy argument is optional, the actual argument can be omitted.
An actual argument associated with a dummy procedure must be the
specific name of a procedure, or be another dummy procedure. Certain
specific intrinsic function names must not be used as actual arguments
(see Table 9-1).
You can use a CALL statement to invoke a function as long as the
function is not one of the following types:
The following example shows valid CALL statements:
CALL CURVE(BASE,3.14159+X,Y,LIMIT,R(LT+2)) CALL PNTOUT(A,N,'ABCD') CALL EXIT CALL MULT(A,B,*10,*20,C) ! The asterisks and ampersands denote CALL SUBA(X,&30,&50,Y) ! alternate returns |
The following example shows a subroutine with argument keywords:
PROGRAM KEYWORD_EXAMPLE INTERFACE SUBROUTINE TEST_C(I, L, J, KYWD2, D, F, KYWD1) INTEGER I, L(20), J, KYWD1 REAL, OPTIONAL :: D, F COMPLEX KYWD2 ... END SUBROUTINE TEST_C END INTERFACE INTEGER I, J, K INTEGER L(20) COMPLEX Z1 CALL TEST_C(I, L, J, KYWD1 = K, KYWD2 = Z1) ... |
The first three actual arguments are associated with their corresponding dummy arguments by position. The argument keywords are associated by keyword name, so they can appear in any order.
Note that the interface to subroutine TEST has two optional arguments that have been omitted in the CALL statement.
The following is another example of a subroutine call with argument keywords:
CALL TEST(X, Y, N, EQUALITIES = Q, XSTART = X0) |
The first three arguments are associated by position.
The CASE construct conditionally executes one block of constructs or statements depending on the value of a scalar expression in a SELECT CASE statement.
The CASE construct takes the following form:
|
name
Is the name of the CASE construct.expr
Is a scalar expression of type integer, logical, or character (enclosed in parentheses). Evaluation of this expression results in a value called the case index.case-value
Is one or more scalar integer, logical, or character initialization expressions enclosed in parentheses. Each case-value must be of the same type and kind parameter as expr. If the type is character, case-value and expr can be of different lengths, but their kind parameter must be the same.Integer and character expressions can be expressed as a range of case values, taking one of the following forms:
- low:high
- low:
- :high
Case values must not overlap.
block
Is a sequence of zero or more statements or constructs.
If a construct name is specified in a SELECT CASE statement, the same name must appear in the corresponding END SELECT statement. The same construct name can optionally appear in any CASE statement in the construct. The same construct name must not be used for different named constructs in the same scoping unit.
The case expression (expr) is evaluated first. The resulting case index is compared to the case values to find a matching value (there can only be one). When a match occurs, the block following the matching case value is executed and the construct terminates.
The following rules determine whether a match occurs:
Data Type | A Match Occurs If: |
---|---|
Logical | case-index .EQV. case-value |
Integer or Character | case-index == case-value |
Range | A Match Occurs If: |
---|---|
low: | case-index >= low |
:high | case-index <= high |
low:high | low <= case-index <= high |
The following are all valid case values:
CASE (1, 4, 7, 11:14, 22) ! Individual values as specified: ! 1, 4, 7, 11, 12, 13, 14, 22 CASE (:-1) ! All values less than zero CASE (0) ! Only zero CASE (1:) ! All values above zero |
If no match occurs but a CASE DEFAULT statement is present, the block following that statement is executed and the construct terminates.
If no match occurs and no CASE DEFAULT statement is present, no block is executed, the construct terminates, and control passes to the next executable statement or construct following the END SELECT statement.
Figure 7-1 shows the flow of control in a CASE construct.
Figure 7-1 Flow of Control in CASE Constructs
You cannot use branching statements to transfer control to a CASE statement. However, branching to a SELECT CASE statement is allowed. Branching to the END SELECT statement is allowed only from within the CASE construct.
The following are examples of CASE constructs:
INTEGER FUNCTION STATUS_CODE (I) INTEGER I CHECK_STATUS: SELECT CASE (I) CASE (:-1) STATUS_CODE = -1 CASE (0) STATUS_CODE = 0 CASE (1:) STATUS_CODE = 1 END SELECT CHECK_STATUS END FUNCTION STATUS_CODE SELECT CASE (J) CASE (1, 3:7, 9) ! Values: 1, 3, 4, 5, 6, 7, 9 CALL SUB_A CASE DEFAULT CALL SUB_B END SELECT |
The following three examples are equivalent:
1. SELECT CASE (ITEST .EQ. 1) CASE (.TRUE.) CALL SUB1 () CASE (.FALSE.) CALL SUB2 () END SELECT 2. SELECT CASE (ITEST) CASE DEFAULT CALL SUB2 () CASE (1) CALL SUB1 () END SELECT 3. IF (ITEST .EQ. 1) THEN CALL SUB1 () ELSE CALL SUB2 () END IF |
Previous | Next | Contents | Index |