Chapter 16
Essentials of Essentials of Fortran-90/95/2003
Miscellaneous Structures and Features

Math 60 -- D. C. Smolarski, S.J.
Santa Clara University, Department of Mathematics and Computer Science

[Return to Math 60 Homepage | Return to Brief Contents Page]
[Return to Full Contents Page]

Contents


16.1 Select

Fortran-90/95/2003 has introduced a structure similar to the switch statement of C/C++ or the case statement of Pascal. This statement is referred to as the SELECT CASE structure. The Fortran-90/95/2003 SELECT CASE-structure selects one of several distinct alternatives (as in Pascal) based on the value of the structure variable or expression, which can be of type integer, character, or logical. (Thus, there is no need for anything like the C/C++ break statement.) All the statements within the selected option are executed, and afterwards the structure is exited with all other alternatives being skipped.

The structure begins with the keywords SELECT CASE followed by an identifier within parentheses which is a scalar of type integer, character, or logical. Each possible option is begin by a line beginning with the keyword CASE and normally followed by a constant or set of constants or range of constants within parentheses. The final option may be begin with CASE DEFAULT which can provide for the situation when the variable's value does not match any of the previous options listed and some action (such as a warning message) may be desired.

The following example demonstrates chosing among four different subroutines based on the value of variable IVAR. Note the use of parentheses to enclose the variable IVAR and the numbers after the keyword CASE. Note also the use of separate lines to indicate the sections!

     SELECT CASE (IVAR)
        CASE (1,5)
	     CALL SUB1
        CASE (2:4)
	     CALL SUB2
        CASE (6)
	     CALL SUB3
        CASE DEFAULT
	     CALL SUB4
     END SELECT
The second option shows how to specify a range of values that IVAR may take on (by separating the first and final values by a colon). Several individual values can be specified by listing the values within the parentheses, separated by commas, as demonstrated in the first option.

16.2 Example

Because of the lack of program flow structures in older versions of Fortran, and the undisciplined use of GO TO statements (cf. section 18.2), often code written in an older style was difficult, if not impossible, to read, and thus also to debug. The following example shows equivalent sections of code written in an older style (which still is legal Fortran code) and re-written using a SELECT statement and IF statements.

An Unstructured Segment of Fortran (Old FORTRAN 66 Style)

        IF(K.EQ.1) GO TO 212
	IF(K.EQ.2) GO TO 18
	GO TO 106
  212	X(1) = 5.
        Y(K) = K+2.5
   32	IF(K*J.LE.4) GO TO 184
   30	L4 = K*J-K+1
        Y(L4) = 1.0
        X(L4) = Y(L4)
  210	IF(K-J.GE.7) GO TO 265
        GO TO 184
   18	X(K) = 6.
        Y(K) = K-1.5
	GO TO 32
  106   IF(K.NE.3) GO TO 10
        Y(K) = 0.0
        X(K) = Y(K)
	GO TO 23
  265	IF(K.GE.J+7) GO TO 10
        X(K-J+1) = 0.0
	Y(K-J+1) = 1.0
	GO TO 10
  184	IF(K*J.LE.4) GO TO 23
  180	L = K*J-2*K
        Y(L) = 0.0
	X(L) = Y(L)
   23	IF(K-J.GE.7) X(K-J+1) = 1.0
        IF(K*J.LE.4) GO TO 30
	GO TO 265
   10	IF(K-J.GE.7) Y(K-J+1) = 0.0

An Equivalent Segment of Fortran That is Structured (New Fortran-90/95 Style)

        SELECT CASE (K)
	   CASE(1)
	      X(1) = 5.0
	      Y(K) = K+2.5
	   CASE(2)
	      X(K) = 6.
	      Y(K) = K-1.5
	   CASE(3)
	      X(K) = 0.0
	      Y(K) = 0.0
	END SELECT
	IF(K*J <= 4) THEN
	      L4 = K*J-K+1
	      X(L4) = 1.0
	      Y(L4) = 1.0
	   ELSE
	      L = K*J-2*K
	      X(L) = 0.0
	      Y(L) = 0.0
	END IF
	IF(K-J >= 7) THEN
	      X(K-J+1) = 1.0
	      Y(K-J+1) = 0.0
	   ELSE
	      X(K-J+1) = 0.0
	      Y(K-J+1) = 1.0
	END IF

16.3 Interfaces and Operator Definition

It is sometimes desirable to define a new (binary) operator or to give an established operator a new meaning when it is used for different data types. Intrinsic to Fortran-90/95/2003 is the capability for the standard arithmetic operators of +, -, *, and / to be used with integer, real, or complex operands. It might, on occasion, be desirable to give those symbols a new meaning with a newly defined data type or to create a new operator with a new data type. This is possible in Fortran-90/95 using an "operator" interface (cf. section 9.6).

Note that an "operator" is usually a symbol placed between two "operands," e.g., the symbol + is placed between a and b to indicate addition. One could also define a function of two variables to perform the same mathematical function, e.g., f(a,b) = a+b. Therefore, writing f(a,b) or writing a+b in an expression would produce the same result (with this definition of f(a,b)). However, using a symbol between two operands might be more appropriate in some situations. The meaning of the symbol is usually expressed in its definition via a function of two variables.

As an operator symbol, one may use either an established symbol or a character string surrounded by periods, such as .OP1. The symbol or character string to be defined and used as an operator is enclosed in parentheses after the word OPERATOR which follows the keyword INTERFACE, as follows:

        INTERFACE OPERATOR (+)
or
        INTERFACE OPERATOR (.SUM.)
After the interface header statement, the interface includes a reference to a function with two arguments whose arguments are considered to be the operands for the new operator and whose return value is the value of the expression involving the new operator. The arguments must explicitly be given the INTENT of IN (cf. section 12.1).

One may incorporate a new operator either via external function code with explicit interfaces in the calling segment or via modules (see the discussion in section 12.3 concerning generic subprograms). Since a module provides more portable code, an example using the module is provided here although explicit interfaces with external code is also permitted.

To overload the operator + to correspond to the existing logical operator .OR. we can write a module as follows:

        MODULE LOG_PLUS
	  INTERFACE OPERATOR (+)
             MODULE PROCEDURE LOG_PLUS_LOG
	  END INTERFACE
        CONTAINS
          LOGICAL FUNCTION LOG_PLUS_LOG(A,B)
	  LOGICAL, INTENT(IN) :: A,B
	  LOG_PLUS_LOG = A .OR. B
	  END FUNCTION
        END MODULE
Note the use of the keywords MODULE PROCEDURE in the interface.

In a program segment which made use of this module, one could write a statement

        C = A + B
and if A and B were logical variables, the + would act as if it were .OR. The interface links the operator + with the local module function LOG_PLUS_LOG so that the expression A+B receives the value obtained by invoking LOG_PLUS_LOG(A,B). The only difference is whether one wishes to use A and B as arguments to a function or as operands surrounding a binary operator.

If one defined a new operator using a character string, for example, .SUM., it would be used in the same way as a symbolic operator when desired. As an example,

        C = A .SUM. B

16.4 Interfaces and Assignment Definition

It is also possible to give a new meaning to the usual assignment symbol, =, when one wishes to use it with a newly defined data type.

The method to do this parallels the method to define new operators as shown in the previous section, with these differences:

The following example shows how to use a module to overload the assignment symbol to convert a logical value to an integer value (it should be noted that this conversion is automatically done by Fortran-90/95/2003 but is given for the sake of example):
        MODULE LOG_ASSIGN
	  INTERFACE ASSIGNMENT (=)
             MODULE PROCEDURE INT_FROM_LOG
	  END INTERFACE
        CONTAINS
          SUBROUTINE INT_FROM_LOG(A,B)
	  INTEGER, INTENT(OUT) :: A
	  LOGICAL, INTENT(IN) :: B
	  IF (B) THEN
	     A = 1
	  ELSE
             A = 0
	  ENDIF
	  END SUBROUTINE
        END MODULE
In a program segment which made use of this module, one could write a statement
        B = .FALSE.
        I = B
where I is of type INTEGER and B of type LOGICAL. This code results in I receiving the value of 0.


This page is maintained by Dennis C. Smolarski, S.J. dsmolarski@math.scu.edu
© Copyright 1999-2005 Dennis C. Smolarski, SJ, All rights reserved.
Last changed: 28 June 2005.