Statements |
4 |
![]() |
This chapter describes the statements recognized by Sun FORTRAN 77. The nonstandard
statements are indicated with a small black diamond ( ). The
syntax and a description of each statement is given, along with possible restrictions and
examples. A table of sample statements appears in Appendix B.
The ACCEPT statement reads from standard
input.
ACCEPT f [, iolist ] | |
ACCEPT grname | |
f | Format identifier |
iolist | List of variables, substrings, arrays, and records |
grname | Name of the namelist group |
ACCEPT
f [,iolist] is equivalent to READ f [,iolist] and is for compatibility with older versions of FORTRAN. An example of list-directed input:REAL VECTOR(10) ACCEPT *, NODE, VECTOR |
The ASSIGN statement assigns a statement label to a variable.
ASSIGN s TO i | |
s | Statement label |
i | Integer variable |
The label s is the label of an executable statement or a FORMAT statement.
The statement label must be the label of a statement that is defined in the same program unit as the ASSIGN statement. The integer variable i, once assigned a statement label, can be reassigned the same statement label, a different label, or an integer. Once a variable is defined as a statement label, you can reference in:Define a variable with a statement label before you reference it as a label.
i must be INTEGER*4 or INTEGER*8, not INTEGER*2. While i is defined with a statement label value, do no arithmetic with i.Example 1: Assign the statement number of an executable statement:
ASSIGN 9 TO K GO TO K ... 9 WRITE (*,*) 'Assigned ', K, ' to K' |
In the above example, the output shows the address, not 9.
Example 2: Assign the statement number of a format statement:
INTEGER PHORMAT 2 FORMAT ( A80 ) ASSIGN 2 TO PHORMAT ... WRITE ( *, PHORMAT ) 'Assigned a FORMAT statement no.' |
The assignment statement assigns a value to a variable, substring, array element, record, or record field.
v = e | |
e | Expression giving the value to be assigned |
v | Variable, substring, array element, record, or record field |
The value can be a constant or the result of an expression. The kinds of assignment statements: are arithmetic, logical, character, and record assignments.
v is of numeric type and is the name of a variable, array element, or record field.
e is an arithmetic expression, a character constant, or a logical expression. Assigning logicals to numerics is nonstandard, and may not be portable; the resultant data type is, of course, the data type of v.
Note - Compiling with any of the options
-i2
,-dbl
,-r8
, or-xtypemap
can alter the default data size of variables and expressions. This is discussed in Chapter 2. See also the Sun Fortran User's Guide for a description of these options.
Example: An assignment statement:
REAL A, B DOUBLE PRECISION V V = A * B |
The above code is compiled exactly as if it were the following:
REAL A, B DOUBLE PRECISION V V = DBLE( A * B ) |
v is the name of a variable, array element, or record field of type logical.
e is a logical expression, or an integer between -128 and 127, or a single character constant. Execution of a logical assignment statement causes evaluation of the logical expression e and assignment of the resulting value to v. If e is a logical expression (rather than an integer between -128 and 127, or a single character constant), then e must have a value of either true or false. Logical expressions of any size can be assigned to logical variables of any size. The section on the LOGICAL statement provides more details on the size of logical variables.The constant can be a Hollerith constant or a string of characters delimited by apostrophes (') or quotes ("). The character string cannot include the control characters Control-A, Control-B, or Control-C; that is, you cannot hold down the Control key and press the A, B, or C keys. If you need those control characters, use the char() function.
If you use quotes to delimit a character constant, then you cannot compile with the -xl option, because, in that case, a quote introduces an octal constant. The characters are transferred to the variables without any conversion of data, and may not be portable. Character expressions which include the // operator can be assigned only to items of type CHARACTER. Here, the v is the name of a variable, substring, array element, or record field of type CHARACTER; e is a character expression. Execution of a character assignment statement causes evaluation of the character expression and assignment of the resulting value to v. If the length of e is more than that of v, characters on the right are truncated. If the length of e is less than that of v, blank characters are padded on the right.v and e are each a record or record field.
The sections on the RECORD and STRUCTURE statements have more details on the structure of records.
Example 1: Arithmetic assignment:
Example 2: Logical assignment:
LOGICAL B1*1, B2*1 LOGICAL L3, L4 L4 = .TRUE. B1 = L4 B2 = B1 |
Example 3: Hollerith assignment:
CHARACTER S*4 INTEGER I2*2, I4*4 REAL R S = 4Hwxyz I2 = 2Hyz I4 = 4Hwxyz R = 4Hwxyz |
Example 4: Character assignment:
CHARACTER BELL*1, C2*2, C3*3, C5*5, C6*6 REAL Z C2 = 'z' C3 = 'uvwxyz' C5 = 'vwxyz' C5(1:2) = 'AB' C6 = C5 // C2 BELL = CHAR(7) ! Control Character (^G) |
C2 C3 C5 C6 |
gets 'z gets 'uvw' gets 'ABxyz' gets 'ABxyzz' an extra z left over from C5 |
BELL |
gets 07 hex Control-G, a bell |
Example 5: Record assignment and record field assignment:
The AUTOMATIC statement makes each recursive
invocation of the subprogram have its own copy of the specified items. It also makes the
specified items become undefined outside the subprogram when the subprogram exits through
a RETURN statement.
AUTOMATIC vlist | |
vlist | List of variables and arrays |
For automatic variables, there is one copy for each invocation of the procedure. To
avoid local variables becoming undefined between invocations, f77 classifies
every variable as either static or automatic with all local variables being
static by default. For other than the default, you can declare variables as static or
automatic in a STATIC , AUTOMATIC
, or IMPLICIT statement. See also the discussion of
the -stackvar option in the Fortran User's Guide.
INTEGER FUNCTION NFCTRL( I ) IMPLICIT AUTOMATIC (A-Z) ... RETURN END |
Automatic variables and arrays cannot appear in DATA or SAVE statements.
Arguments and function values cannot appear in DATA, RECORD, STATIC, or SAVE statements because f77 always makes them automatic.Example: Some other uses of AUTOMATIC:
AUTOMATIC A, B, C REAL P, D, Q AUTOMATIC P, D, Q IMPLICIT AUTOMATIC (X-Z) |
Example: Structures are unpredictable if AUTOMATIC:
An AUTOMATIC statement and a type statement cannot be combined to make an AUTOMATIC
type statement. For example, AUTOMATIC REAL X
does not
declare the variable X to be both AUTOMATIC and REAL; it
declares the variable REALX to be AUTOMATIC.
The BACKSPACE statement positions the specified file to just before the preceding record.
BACKSPACE
in a terminal file has no effect. u must be connected for sequential access. Execution of a BACKSPACE statement on a direct-access file is not defined in the FORTRAN Standard, and is unpredictable. We do not recommend using a BACKSPACE statement on a direct-access file or an append access file. Execution of the BACKSPACE statement modifies the file position, as follows:Prior to Execution |
After Execution |
Beginning of the file | Remains unchanged |
Beyond the endfile record | Before the endfile record |
Beginning of the previous record | Start of the same record |
Example 1: Simple backspace:
BACKSPACE 2 LUNIT = 2 BACKSPACE LUNIT |
Example 2: Backspace with error trap:
INTEGER CODE BACKSPACE ( 2, IOSTAT=CODE, ERR=9 ) ... 9 WRITE (*,*) 'Error during BACKSPACE' STOP |
The BLOCK DATA statement identifies a subprogram that initializes variables and arrays in labeled common blocks.
BLOCK DATA [ name ] | |
name | Symbolic name of the block data subprogram in which the BLOCK DATA statement appears. This parameter is optional. It is a global name. |
A block data subprogram can contain as many labeled common blocks and data initializations as desired.
The BLOCK DATA statement must be the first statement in a block data subprogram. The only other statements that can appear in a block data subprogram are:Only an entity defined in a labeled common block can be initially defined in a block data subprogram.
If an entity in a labeled common block is initially defined, all entities having storage units in the common block storage sequence must be specified, even if they are not all initially defined.Only one unnamed block data subprogram can appear in the executable program.
The same labeled common block cannot be specified in more than one block data subprogram in the same executable program. The optional parameter name must not be the same as the name of an external procedure, main program, common block, or other block data subprogram in the same executable program. The name must not be the same as any local name in the subprogram.BLOCK DATA INIT COMMON /RANGE/ X0, X1 DATA X0, X1 / 2.0, 6.0 / END |
The BYTE statement specifies the type to be
1-byte integer. It optionally specifies array dimensions and initializes with values.
BYTE v [/c/] ... | |
v | Name of a symbolic constant, variable, array, array declarator, function, or dummy function |
c | List of constants for the immediately preceding name |
This is a synonym for LOGICAL*1. A BYTE type item can hold the logical values .TRUE., .FALSE., one character, or an integer between -128 and 127.
BYTE BIT3 / 8 /, C1 / 'W' /, & COUNTER /0/, M /127/, SWITCH / .FALSE. / |
The CALL statement branches to the specified subroutine, executes the subroutine, and returns to the calling program after finishing the subroutine.
CALL sub [ ( [ ar [, ar ] ... ] ) ] | |
sub | Name of the subroutine to be called |
ar | Actual argument to be passed to the subroutine |
Arguments are separated by commas.
The FORTRAN Standard requires that actual arguments in a CALL statement must agree in order, number, and type with the corresponding formal arguments of the referenced subroutine. The compiler checks this only when the -XlistE option is on. Recursion is allowed. A subprogram can call itself directly, or indirectly by calling another subprogram that in turns calls this subroutine. Such recursion is nonstandard.The simplest expressions, and most frequently used, include such constructs as:
If a subroutine has no arguments, then a CALL statement that references that subroutine must not have any actual arguments. A pair of empty matching parentheses can follow the subroutine name.
Execution of the CALL statement proceeds as follows:
Note - A
CALL
to a subprogram defined as aFUNCTION
rather than as aSUBROUTINE
will cause unexpected results and is not recommended. The compiler does not detect such inappropriateCALL
s and no warning is issued.
Example 1: Character string:
CHARACTER *25 TEXT TEXT = 'Some kind of text string' CALL OOPS ( TEXT ) END SUBROUTINE OOPS ( S ) CHARACTER S*(*) WRITE (*,*) S END |
Example 3: Another form of alternate return; the & is
nonstandard:
CALL RANK ( N, &8, &9 ) |
Example 4: Array, array element, and variable:
REAL M(100,100), Q(2,2), Y CALL SBRX ( M, Q(1,2), Y ) ... END SUBROUTINE SBRX ( A, D, E ) REAL A(100,100), D, E ... RETURN END |
Example 5: A structured record and field; the record is nonstandard:
The CHARACTER statement specifies the type of a symbolic constant, variable, array, function, or dummy function to be character.
Optionally, it initializes any of the items with values and specifies array dimensions.Each character occupies 8 bits of storage, aligned on a character boundary. Character arrays and common blocks containing character variables are packed in an array of character variables. The first character of one element follows the last character of the preceding element, without holes.
The length, len must be greater than 0. If len is omitted, it is assumed equal to 1. For local and common character variables, symbolic constants, dummy arguments, or function names, len can be an integer constant, or a parenthesized integer constant expression. For dummy arguments or function names, len can have another form: a parenthesized asterisk, that is, CHARACTER*(*), which denotes that the function name length is defined in referencing the program unit, and the dummy argument has the length of the actual argument. For symbolic constants, len can also be a parenthesized asterisk, which indicates that the name is defined as having the length of the constant. This is shown in Example 5 in the next section. The list c of constants can be used only for a variable, array, or array declarator. There can be only one constant for the immediately preceding variable, and one constant for each element of the immediately preceding array.Example 1: Character strings and arrays of character strings:
CHARACTER*17 A, B(3,4), V(9) CHARACTER*(6+3) C |
The above code is exactly equivalent to the following:
CHARACTER A*17, B(3,4)*17, V(9)*17 CHARACTER C*(6+3) |
Both of the above two examples are equivalent to the nonstandard
variation:
CHARACTER A*17, B*17(3,4), V*17(9) ! nonstandard |
Example 2: No null character-string variables:
CHARACTER S*1 S = '' |
Example 3: Dummy argument character string with constant length:
SUBROUTINE SWAN( A ) CHARACTER A*32 |
Example 4: Dummy argument character string with length the same as
corresponding actual argument:
SUBROUTINE SWAN( A ) CHARACTER A*(*) ... |
Example 5: Symbolic constant with parenthesized asterisk:
CHARACTER *(*) INODE PARAMETER ( INODE = 'Warning: INODE corrupted!' ) |
Example 6: The LEN intrinsic function:
CHARACTER A*17 A = "xyz" PRINT *, LEN( A ) END |
The above program displays 17, not 3.
The CLOSE statement disconnects a file from a unit.
The options can be specified in any order.
The DISP= and DISPOSE= options are allowable alternates for STATUS=, with a warning, if the -ansi flag is set. Execution of CLOSE proceeds as follows:All open files are closed with default sta at normal program termination. Regardless of the specified sta, scratch files, when closed, are always deleted.
Execution of a CLOSE statement specifying a unit that does not exist, or a unit that has no file connected to it, has no effect. Execution of a CLOSE statement specifying a unit zero (standard error) is not allowed, but you can reopen it to some other file. The unit or file disconnected by the execution of a CLOSE statement can be connected again to the same, or a different, file or unit.
Note - For tape I/O, use the TOPEN() routines.
Example 1: Close and keep:
CLOSE ( 2, STATUS='KEEP') |
CLOSE ( 2, STATUS='DELETE', IOSTAT=I ) |
Example 3: Close and keep a scratch file even though the status is
SCRATCH:
OPEN ( 2, STATUS='SCRATCH') ... CLOSE ( 2, STATUS='KEEP', IOSTAT=I ) |
The COMMON statement defines a block of main memory storage so that different program units can share the same data without using arguments.
COMMON [/[ cb ]/] nlist [[,]/[ cb ] / nlist ] ... | |
cb | Common block name |
nlist | List of variable names, array names, and array declarators |
If the common block name is omitted, then blank common block is assumed.
Any common block name including blank common can appear more than once in COMMON statements in the same program unit. The list nlist following each successive appearance of the same common block name is treated as a continuation of the list for that common block name. The size of a common block is the sum of the sizes of all the entities in the common block, plus space for alignment. Within a program, all common blocks in different program units that have the same name must be of the same size. However, blank common blocks within a program are not required to be of the same size.Formal argument names and function names cannot appear in a COMMON statement.
An EQUIVALENCE statement must not cause the storage sequences of two different common blocks in the same program unit to be associated. See Example 2. An EQUIVALENCE statement must not cause a common block to be extended on the left-hand side. See Example 4.Example 1:
DIMENSION V(100) COMMON V, M COMMON / LIMITS / I, J ... |
Unlabeled common and labeled common:
Example 2: You cannot associate storage of two different common
blocks in the same program unit:
COMMON /X/ A COMMON /Y/ B EQUIVALENCE ( A, B) ! |
Example 3: An EQUIVALENCE statement can extend a common block on the
right-hand side:
DIMENSION A(5) COMMON /X/ B EQUIVALENCE ( B, A) |
COMMON /X/ A REAL B(2) EQUIVALENCE ( A, B(2)) ! |
The COMPLEX statement specifies the type of a symbolic constant, variable, array, function, or dummy function to be complex, optionally specifies array dimensions and size, and initializes with values.
The declarations can be: COMPLEX, COMPLEX*8, COMPLEX*16, or COMPLEX*32.
Specifying the size is nonstandard.
For a declaration such as COMPLEX W, the variable W is usually two REAL*4 elements contiguous in memory, interpreted as a complex number.
If you do not specify the size, a default size is used. The default size for a declaration such as COMPLEX W can be altered by compiling with any of the options-dbl
, -r8
, or -xtypemap
.
See the discussion in Chapter 2 for details.
For a declaration such as COMPLEX*8 W, the variable W is always two REAL*4 elements contiguous in memory, interpreted as a complex number.
For a declaration such as COMPLEX*16 W, W is always two REAL*8 elements contiguous in memory, interpreted as a double-width complex number.
(SPARC, PowerPC only)
For a declaration such as COMPLEX*32 W, the variable W is always two REAL*16 elements contiguous in memory, interpreted as a quadruple-width complex number.There is a double-complex version of each complex built-in function. Generally, the specific function names begin with Z or CD instead of C, except for the two functions DIMAG and DREAL, which return a real value.
There are specific complex functions for quad precision (SPARC, PowerPC only). In general, where there is a specific REAL a corresponding COMPLEX with a C prefix, and a corresponding COMPLEX DOUBLE with a CD prefix, there is also a quad-precision COMPLEX function with a CQ prefix. Examples are: SIN(), CSIN(), CDSIN(), CQSIN().Example 1: Complex variables. These statements are equivalent.
COMPLEX U, V or, COMPLEX*8 U, V or, COMPLEX U*8, V*8 |
Example 2: Initialize complex variables:
COMPLEX U / (1, 9.0) /, V / (4.0, 5 ) / |
A complex constant is a pair of numbers, either integers or reals.
Example 3: Double complex, with initialization:
COMPLEX U*16 / (1.0D0, 9 ) /, V*16 / (4.0, 5.0D0) / COMPLEX*16 X / (1.0D0, 9.0) /, Y / (4.0D0, 5 ) / |
Example 4: Quadruple complex, with initialization (SPARC,
PowerPC only):
COMPLEX U*32 / (1.0Q0, 9 ) /, V*32 / (4.0, 5.0Q0) / COMPLEX*32 X / (1.0Q0, 9.0) /, Y / (4.0Q0, 5 ) / |
Example 5: Complex arrays, all of which are nonstandard (SPARC,
PowerPC only):
COMPLEX R*16(5), S(5)*16 COMPLEX U*32(5), V(5)*32 COMPLEX X*8(5), Y(5)*8 |
The CONTINUE statement is a "do-nothing" statement.
[ label ] CONTINUE | |
label | Executable statement number |
The CONTINUE statement is often used as a place to hang a statement label, usually it is the end of a DO loop.
The CONTINUE statement is used primarily as a convenient point for placing a statement label, particularly as the terminal statement in a DO loop. Execution of a CONTINUE statement has no effect. If the CONTINUE statement is used as the terminal statement of a DO loop, the next statement executed depends on the DO loop exit condition.DIMENSION U(100) S = 0.0 DO 1 J = 1, 100 S = S + U(J) IF ( S .GE. 1000000 ) GO TO 2 1 CONTINUE STOP 2 CONTINUE ... |
The DATA statement initializes variables, substrings, arrays, and array elements.
All initially defined items are defined with the specified values when an executable program begins running.
r*c is equivalent to r successive occurrences of the constant c. A DATA statement is a nonexecutable statement, and must appear after all specification statements, but it can be interspersed with statement functions and executable statements, although this is non-standard
Note - With the
-stackvar
compiler option, if a variable appears on aDATA
statement after an executable reference to that variable. See the Sun Fortran User's Guide.
Taking into account the repeat factor, the number of constants in clist must be equal to the number of items in the nlist. The appearance of an array in nlist is equivalent to specifying a list of all elements in that array. Array elements can be indexed by constant subscripts only.
Automatic variables or arrays cannot appear on aDATA
statement.
Normal type conversion takes place for each noncharacter member of
the clist.
If the length of a character item in nlist is greater than the length of the corresponding constant in clist, it is padded with blank characters on the right.
If the length of a character item in nlist is less than that of the corresponding constant in clist, the additional rightmost characters are ignored. If the constant in clist is of integer type and the item of nlist is of character type, they must conform to the following rules:If the constant of clist is a character constant or a Hollerith constant, and the item of nlist is of type INTEGER, then the number of characters that can be assigned is 2 or 4 for INTEGER*2 and INTEGER*4 respectively. If the character constant or the Hollerith constant has fewer characters than the capacity of the item, the constant is extended on the right with spaces. If the character or the Hollerith constant contains more characters than can be stored, the constant is truncated on the right.
An nlist can specify an implied DO list for initialization of array elements.
The form of an implied DO list is:Variables can also be initialized in type statements. This is an extension of the
FORTRAN Standard. Examples are given under each of the individual type statements and
under the general type statement.
Example 1: Character, integer, and real scalars. Real arrays:
CHARACTER TTL*16 REAL VEC(5), PAIR(2) DATA TTL / 'Arbitrary Titles' /, & M / 9 /, N / 0 /, & PAIR(1) / 9.0 /, & VEC / 3*9.0, 0.1, 0.9 / ... |
Example 2: Arrays--implied DO:
REAL R(3,2), S(4,4) DATA ( S(I,I), I=1,4) / 4*1.0 /, & (( R(I,J), J=1,3), I=1,2) / 6*1.0 / ... |
Example 3: Mixing an integer and a character:
CHARACTER CR*1 INTEGER I*2, N*4 DATA I / '00' /, N / 4Hs12t /, CR / 13 / ... |
ENCODE
writes to a character variable, array, or array element.The entities in the I/O list can be: variables, substrings, arrays, array elements, record fields. A simple unsubscripted array name specifies all of the elements of the array in memory storage order, with the leftmost subscript increasing more rapidly.
Execution proceeds as follows:A program using DECODE/ENCODE:
CHARACTER S*6 / '987654' /, T*6 INTEGER V(3)*4 DECODE( 6, '(3I2)', S ) V WRITE( *, '(3I3)') V ENCODE( 6, '(3I2)', T ) V(3), V(2), V(1) PRINT *, T END |
The above program has this output:
98 76 54 547698 |
The DECODE reads the characters of S as 3 integers, and stores them into V(1), V(2), and V(3).
The DIMENSION statement specifies the number of dimensions for an array, including the number of elements in each dimension.
Optionally, the DIMENSION statement initializes items with values.DIMENSION a ( d ) [,a ( d )] ... | |
a | Name of an array |
d | Specifies the dimensions of the array. It is a list of 1 to 7 declarators separated by commas. |
This section contains descriptions for the dimension declarator and the arrays.
The lower and upper limits of each dimension are designated by a dimension declarator.
The form of a dimension declarator is:
[ dd1 :] dd2 |
If the dimension declarator is an arithmetic expression that contains formal arguments or variables defined in the COMMON statement, then the array is called an adjustable array. In such cases, the dimension is equal to the initial value of the argument upon entry into the subprogram.
The array is called an assumed-size array when the dimension declarator contains an asterisk. In such cases, the upper bound of that dimension is not stipulated. An asterisk can only appear for formal arrays and as the upper bound of the last dimension in an array declarator.
Example 1: Arrays in a main program:
DIMENSION M(4,4), V(1000) ... END |
Example 2: An adjustable array in a subroutine:
SUBROUTINE INV( M, N ) DIMENSION M( N, N ) ... END |
Example 3: Lower and upper bounds:
DIMENSION HELIO (-3:3, 4, 3:9) ... END |
Example 4: Dummy array with lower and upper bounds:
SUBROUTINE ENHANCE( A, NLO, NHI ) DIMENSION A(NLO : NHI) ... END |
PARAMETER ( LO = 1, HI = 9.3 ) DIMENSION A(HI, HI*3 + LO ) ... END |
In the above example, A is an array of dimension 9×28.
Example 6: Adjustable array with noninteger bounds:
SUBROUTINE ENHANCE( A, X, Y ) DIMENSION A(X : Y) ... END |
Example 7: Assumed-size arrays:
SUBROUTINE RUN(A,B,N) DIMENSION A(*), B(N,*) ... |
The DO statement repeatedly executes a set of statements.
DO s [,] loop-control or DO loop-control |
The DO statement contains the following constructs.
A labeled DO loop consists of the following:
The statement identified by s is called the terminal statement. It must follow the DO statement in the sequence of statements within the same program unit as the DO statement.
The terminal statement should not be one of the following statements:ELSE IF
If the terminal statement is a logical IF statement, it can contain any executable statement, except:
ELSE IF
The range of a DO loop consists of all of the executable statements that appear following the DO statement, up to and including the terminal statement.
If a DO statement appears within the range of another DO loop, its range must be entirely contained within the range of the outer DO loop. More than one labeled DO loop can have the same terminal statement. If a DO statement appears within an IF, ELSE IF, or ELSE block, the range of the associated DO loop must be contained entirely within that block. If a block IF statement appears within the range of a DO loop, the corresponding END IF statement must also appear within the range of that DO loop.A block DO loop consists of:
This loop is nonstandard.
Execution proceeds as follows:After the terminal statement of a DO loop is executed, the following steps are performed:
The DO variable must not be modified in any way within the range of the DO loop.
Control must not jump into the range of a DO loop from outside its range.In some cases, the DO variable can overflow as a result of an increment that is performed prior to testing it against the final value. When this happens, your program has an error, and neither the compiler nor the runtime system detects it. In this situation, though the DO variable wraps around, the loop can terminate properly.
If there is a jump into the range of a DO loop from outside its range, a warning is issued, but execution continues anyway. When the jump is from outside to the terminal statement that is CONTINUE, and this statement is the terminal statement of several nested DO loops, then the most inner DO loop is always executed.Example 1: Nested DO loops:
Example 2: The program DoNest2.f (DO variable
always defined):
INTEGER COUNT, OUTER COUNT = 0 DO OUTER = 1, 5 NOUT = OUTER DO INNER = 1, 3 NIN = INNER COUNT = COUNT+1 END DO END DO WRITE(*,*) OUTER, NOUT, INNER, NIN, COUNT END |
6 5 4 3 15 |
The DO WHILE statement repeatedly
executes a set of statements while the specified condition is true.
DO [ s [,]] WHILE (e) | |
s | Label of an executable statement |
e | Logical expression |
Execution proceeds as follows:
If s is specified, the statement identified by it is called the terminal statement, and it must follow the DO WHILE statement. The terminal statement must not be one of the following statements:
If the terminal statement is a logical IF statement, it can contain any executable statement, except:
DO WHILE
If s is not specified, the DO WHILE loop must end with an END DO statement.
The range of a DO WHILE loop consists of all the executable statements that appear following the DO WHILE statement, up to and including the terminal statement.
If a DO WHILE statement appears within the range of another DO WHILE loop, its range must be entirely contained within the range of the outer DO WHILE loop. More than one DO WHILE loop can have the same terminal statement. If a DO WHILE statement appears within an IF, ELSE IF, or ELSE block, the range of the associated DO WHILE loop must be entirely within that block. If a block IF statement appears within the range of a DO WHILE loop, the corresponding END IF statement must also appear within the range of that DO WHILE loop.After the terminal statement of a DO WHILE loop is executed, control is transferred back to the corresponding DO WHILE statement.
Jumping into the range of a DO WHILE loop from outside its range can produce unpredictable results.
The variables used in the e can be modified in any way within the range of the DO WHILE loop.
Example 1: A DO WHILE without a statement number:
INTEGER A(4,4), C, R ... C = 4 R = 1 DO WHILE ( C .GT. R ) A(C,R) = 1 C = C - 1 END DO |
Example 2: A DO WHILE with a
statement number:
INTEGER A(4,4), C, R ... DO 10 WHILE ( C .NE. R ) A(C,R) = A(C,R) + 1 C = C+1 10 CONTINUE |
The DOUBLE COMPLEX statement
specifies the type to be double complex. It optionally specifies array dimensions and
size, and initializes with values.
DOUBLE COMPLEX v [/c/] [, v [/c/] ... | |
v | Name of a symbolic constant, variable, array, array declarator, function, or dummy function |
c | List of constants for the immediately preceding name |
The declaration can be: DOUBLE COMPLEX or COMPLEX*16.
For a declaration such as DOUBLE COMPLEX Z, the variable Z is two REAL*8 elements contiguous in memory, interpreted as one double-width complex number.
If you do not specify the size, a default size is used. The default size, for a declaration such asDOUBLE
COMPLEX Z, can be altered by compiling with any of the options -dbl
, -r8
,
or -xtypemap
. See the discussion in Chapter 2 for details.
For a declaration such as COMPLEX*16 Z, the variable Z is always two REAL*8 elements contiguous in memory, interpreted as one double-width complex number.
There is a double-complex version of each complex built-in function. Generally, the specific function names begin with Z or CD instead of C, except for the two functions, DIMAG and DREAL, which return a real value. Examples are: SIN(), CSIN(), CDSIN().
Example: Double-complex scalars and arrays:DOUBLE COMPLEX U, V DOUBLE COMPLEX W(3,6) COMPLEX*16 X, Y(5,5) COMPLEX U*16(5), V(5)*16 |
The DOUBLE PRECISION statement specifies the type to be double precision, and optionally specifies array dimensions and initializes with values.
DOUBLE PRECISION v [/c/] [, v [/c/] ... | |
v | Name of a symbolic constant, variable, array, array declarator, function, or dummy function |
c | List of constants for the immediately preceding name |
The declaration can be: DOUBLE PRECISION or REAL*8.
For a declaration such as DOUBLE PRECISION X, the variable X is a REAL*8 element in memory, interpreted as one double-width real number.
If you do not specify the size, a default size is used. The default size, for a declaration such as DOUBLE PRECISION X, can be altered by compiling with any of the options-dbl
, -r8
, or -xtypemap
. See the
discussion in Chapter 2 for details.
For a declaration such as REAL*8 X, the variable X is always an element of type REAL*8 in memory, interpreted as a double-width real number.
For example:
DOUBLE PRECISION R, S(3,6) REAL*8 T(-1:0,5) |
The ELSE statement indicates the beginning of an ELSE block.
IF ( e ) THEN
... ELSE ... END IF |
|
e | Logical expression |
Execution of an ELSE statement has no effect on the program.
An ELSE block consists of all the executable statements following the ELSE statements, up to but not including the next END IF statement at the same IF level as the ELSE statement. See Section , "IF (Block)," for more details.You cannot jump into an ELSE block from outside the ELSE block.
The statement label, if any, of an ELSE statement cannot be referenced by any statement. A matching END IF statement of the same IF level as the ELSE must appear before any ELSE IF or ELSE statement at the same IF level.Example 1: ELSE:
CHARACTER S ... IF ( S .GE. '0' .AND. S .LE. '9' ) THEN CALL PUSH ELSE CALL TOLOWER END IF ... |
Example 2: An invalid ELSE IF where an END
IF is expected:
IF ( K .GT. 5 ) THEN N = 1 ELSE N = 0 ELSE IF ( K .EQ. 5 ) THEN ... |
The ELSE IF provides a multiple alternative decision structure.
IF ( e1 ) THEN
ELSE IF ( e2 ) THEN END IF... |
|
e1 and e2 | Logical expressions |
You can make a series of independent tests, and each test can have its own sequence of statements.
An ELSE IF block consists of all the executable statements following the ELSE IF statement up to, but not including, the next ELSE IF, ELSE, or END IF statement at the same IF level as the ELSE IF statement. An ELSE IF block can be empty. Execution of the ELSE IF (e) proceeds as follows, depending on the value of the logical expression, e:You cannot jump into an ELSE IF block from outside the ELSE IF block.
The statement label, if any, of an ELSE IF statement cannot be referenced by any statement. A matching END IF statement of the same IF level as the ELSE IF must appear before any ELSE IF or ELSE statement at the same IF level.Example: ELSE IF:
READ (*,*) N IF ( N .LT. 0 ) THEN WRITE(*,*) 'N<0' ELSE IF ( N .EQ. 0) THEN WRITE(*,*) 'N=0' ELSE WRITE(*,*) 'N>0' END IF |
The ENCODE statement writes data from a list
to memory.
ENCODE
is provided for compatibility with older versions of FORTRAN. Similar functionality can be accomplished using internal files with a formatted sequential WRITE statement. ENCODE is not in the FORTRAN Standard. Data are edited according to the format identifier.CHARACTER S*6, T*6 INTEGER V(3)*4 DATA S / '987654' / DECODE( 6, 1, S ) V 1 FORMAT( 3 I2 ) ENCODE( 6, 1, T ) V(3), V(2), V(1) |
See Section , "DECODE/ENCODE," for more details and a full example.
The END statement indicates the end of a program unit.
END |
The END statement:
In a main program, an END statement terminates the execution of the program. In a
function or subroutine, it has the effect of a RETURN.
Example: END:
PROGRAM MAIN WRITE( *, * ) 'Very little' END |
The END DO statement terminates a DO loop.
END DO |
The END DO statement is the delimiting statement of a Block DO statement. If the statement label is not specified in a DO statement, the corresponding terminating statement must be an END DO statement. You can branch to an END DO statement only from within the range of the DO loop that it terminates.
Example 1: A DO loop with a statement number:
DO 10 N = 1, 100 ... 10 END DO |
Example 2: A DO loop without statement number:
DO N = 1, 100 ... END DO |
The END FILE statement writes an end-of-file record as the next record of the file connected to the specified unit.
If you are using the ENDFILE statement and other standard FORTRAN I/O for tapes, we recommend that you use the TOPEN() routines instead, because they are more reliable.
Two endfile records signify the end-of-tape mark. When writing to a tape file, ENDFILE writes two endfile records, then the tape backspaces over the second one. If the file is closed at this point, both end-of-file and end-of-tape are marked. If more records are written at this point, either by continued write statements or by another program if you are using no-rewind magnetic tape, the first tape mark stands (endfile record), and is followed by another data file, then by more tape marks, and so on.u must be connected for sequential access. Execution of an END FILE statement on a direct-access file is not defined in the FORTRAN Standard, and is unpredictable. Do not use an END FILE statement on a direct-access file.
Example 1: Constants:
END FILE 2 END FILE ( 2 ) END FILE ( UNIT=2 ) |
LOGUNIT = 2 END FILE LOGUNIT END FILE ( LOGUNIT ) END FILE ( UNIT=LOGUNIT ) |
NOUT = 2 END FILE ( UNIT=NOUT, IOSTAT=KODE, ERR=9) ... 9 WRITE(*,*) 'Error at END FILE, on unit', NOUT STOP |
The END IF statement ends the block IF that the IF began.
END IF |
For each block IF statement there must be a corresponding END IF statement in the same program unit. An END IF statement matches if it is at the same IF level as the block IF statement.
Example 1: IF/END IF:
IF ( N .GT. 0 )THEN N = N+1 END IF |
IF ( N .EQ. 0 ) THEN N = N+1 ELSE N = N-1 END IF |
The END MAP statement
terminates the MAP declaration.
END MAP |
See
Section , "UNION and MAP."The MAP statement must be within a UNION statement.
... MAP CHARACTER *16 MAJOR END MAP ... |
The END STRUCTURE statement terminates the STRUCTURE
statement.
END STRUCTURE |
See
Section , "STRUCTURE."STRUCTURE /PROD/ INTEGER*4 ID CHARACTER*16 NAME CHARACTER*8 MODEL REAL*4 COST REAL*4 PRICE END STRUCTURE |
The END UNION statement
terminates the UNION statement.
END UNION |
See
Section , "UNION and MAP."UNION MAP CHARACTER*16 END MAP MAP INTEGER*2 CREDITS CHARACTER *8 GRAD_DATE END MAP END UNION |
The ENTRY statement defines an alternate entry point within a subprogram.
Note these nuances for the ENTRY statement:
An ENTRY name used in a subroutine subprogram is treated like a subroutine and can be referenced with a CALL statement. Similarly, the ENTRY name used in a function subprogram is treated like a function and can be referenced as a function reference.
An entry name can be specified in an EXTERNAL statement and used as an actual argument. It cannot be used as a dummy argument. Execution of an ENTRY subprogram (subroutine or function) begins with the first executable statement after the ENTRY statement. The ENTRY statement is a nonexecutable statement. The entry name cannot be used in the executable statements that physically precede the appearance of the entry name in an ENTRY statement.The formal arguments of an ENTRY statement need not be the same in order, number, type, and name as those for FUNCTION, SUBROUTINE, and other ENTRY statements in the same subprogram. Each reference to a function, subroutine, or entry must use an actual argument list that agrees in order, number, type, and name with the dummy argument list in the corresponding FUNCTION, SUBROUTINE, or ENTRY statement.
Alternate return arguments in ENTRY statements can be specified by placing asterisks in the dummy argument list. Ampersands are valid alternates.An ENTRY statement cannot be used within a block IF construct or a DO loop.
If an ENTRY statement appears in a character function subprogram, it must be defined as type CHARACTER with the same length as that of a function subprogram.Example 1: Multiple entry points in a subroutine:
SUBROUTINE FIN( A, B, C ) INTEGER A, B CHARACTER C*4 ... RETURN ENTRY HLEP( A, B, C ) ... RETURN ENTRY MOOZ ... RETURN END |
Example 2: In the calling routine, you can call the above subroutine
and entries as follows:
INTEGER A, B CHARACTER C*4 ... CALL FIN( A, B, C ) ... CALL MOOZ ... CALL HLEP( A, B, C ) ... |
Example 3: Multiple entry points in a function:
REAL FUNCTION F2 ( X ) F2 = 2.0 * X RETURN ENTRY F3 ( X ) F3 = 3.0 * X RETURN ENTRY FHALF ( X ) FHALF = X / 2.0 RETURN END |
The EQUIVALENCE statement specifies that two or more variables or arrays in a program unit share the same memory.
EQUIVALENCE ( nlist ) [, ( nlist ) ] ... | |
nlist | List of variable names, array element names, array names, and character substring names separated by commas |
An EQUIVALENCE statement stipulates that the storage sequence of the entities whose names appear in the list nlist must have the same first memory location.
An EQUIVALENCE statement can cause association of entities other than specified in the nlist. An array name, if present, refers to the first element of the array. If an array element name appears in an EQUIVALENCE statement, the number of subscripts can be less than or equal to the number of dimensions specified in the array declarator for the array name.In nlist, dummy arguments and functions are not permitted.
Subscripts of array elements must be integer constants greater than the lower bound and less than or equal to the upper bound. EQUIVALENCE can associate automatic variables only with other automatic variables or undefined storage classes. These classes must be ones which are not in any of the COMMON, STATIC, SAVE, DATA, or dummy arguments. An EQUIVALENCE statement can associate an element of type character with a noncharacter element.DIMENSION A (2) EQUIVALENCE (A(1),B), (A(2),B) |
REAL A (2) DOUBLE PRECISION D (2) EQUIVALENCE (A(1), D(1)), (A(2), D(2)) |
CHARACTER A*4, B*4, C(2)*3 EQUIVALENCE (A,C(1)),(B,C(2)) |
The association of A, B, and C can be graphically illustrated as
follows:
|
01 |
02 |
03 |
04 |
05 |
06 |
07 |
A |
A(1) |
A(2) |
A(3) |
A(4) |
|||
B |
B(1) |
B(2) |
B(3) |
B(4) |
|||
C |
C(1) |
C(2) |
The EXTERNAL statement specifies procedures or dummy procedures as external, and allows their symbolic names to be used as actual arguments.
EXTERNAL proc [, proc ] ... | |
proc | Name of external procedure, dummy procedure, or block data routine. |
If an external procedure or a dummy procedure is an actual argument, it must be in an EXTERNAL statement in the same program unit.
If an intrinsic function name appears in an EXTERNAL statement, that name refers to some external subroutine or function. The corresponding intrinsic function is not available in the program unit.A subroutine or function name can appear in only one of the EXTERNAL statements of a program unit.
A statement function name must not appear in an EXTERNAL statement.Example 1: Use your own version of TAN:
EXTERNAL TAN T = TAN( 45.0 ) ... END FUNCTION TAN( X ) ... RETURN END |
Example 2: Pass a user-defined function name as an argument:
REAL AREA, LOW, HIGH EXTERNAL FCN ... CALL RUNGE ( FCN, LOW, HIGH, AREA ) ... END FUNCTION FCN( X ) ... RETURN END SUBROUTINE RUNGE ( F, X0, X1, A ) ... RETURN END |
The FORMAT statement specifies the layout of the input or output records.
label FORMAT ( f ) | |
label | Statement number |
f | Format specification list |
[ r ] d | |
[ r ] ( f ) | |
r | A repeat factor |
d | An edit descriptor (repeatable or nonrepeatable). If r is present, then d must be repeatable. |
The repeatable edit descriptors are:
I Iw Iw.m O Ow Ow.m Z Zw Zw.m |
F Fw Fw.m A Aw L Lw |
E Ew Ew.m Ew.m.e Ew.mEe |
D Dw Dw.m Dw.m.e Dw.mEe |
G Gw Gw.m Gw.m.e Gw.mEe |
See the section,
"Formatted I/O," in Chapter , "Input and Output," for full details of these edit descriptors.'a1a2 ... an' | [k]R | k defaults to 10 |
"a1a2 ... an" | [k]P | k defaults to 0 |
nHa1a2 ... an | S | |
$ | SU | |
/ | SP | |
: | SS | |
B | Tn | |
BN | nT | |
BZ | TL[n] | n defaults to 1 |
TR[n] | n defaults to 1 | |
[n]X | n defaults to 1 |
In general, any integer constant in a format can be replaced by an arbitrary expression
enclosed in angle brackets:
1 FORMAT( ... < e > ... ) |
The n in an nH... edit descriptor cannot be a variable format expression.
The FORMAT statement includes the explicit editing directives to produce or use the layout of the record. It is used with formatted input/output statements and ENCODE/DECODE statements.
r must be a nonzero, unsigned, integer constant.
The descriptors I, O, Z, F, E, D, G, L, and A indicate the manner of editing and are repeatable.
w and e are nonzero, unsigned integer constants. d and m are unsigned integer constants.The descriptors are the following:
("), ($), ('), (/), (:), B, BN, BZ, H, P, R, Q, S, SU, SP, SS, T, TL, TR, X These descriptors indicate the manner of editing and are not repeatable:Items in the format specification list are separated by commas. A comma can be omitted before or after the slash and colon edit descriptors, between a P edit descriptor, and the immediately following F, E, D, or G edit descriptors.
In some sense, the comma can be omitted anywhere the meaning is clear without it, but, other than those cases listed above, this is nonstandard. uThe FORMAT statement label cannot be used in a GO TO, IF-arithmetic, DO, or alternate return.
For constant formats, invalid format strings cause warnings or error messages at compile time.
For formats in variables, invalid format strings cause warnings or error messages at runtime. For variable format expressions, of the form <e>, invalid format strings cause warnings or error messages at compile time or runtime. See Chapter 5, "Input and Output," for more details and more examples.Example 1: Some A, I, and F formats:
READ( 2, 1 ) PART, ID, HEIGHT, WEIGHT 1 FORMAT( A8, 2X, I4, F8.2, F8.2 ) WRITE( 9, 2 ) PART, ID, HEIGHT, WEIGHT 2 FORMAT( 'Part:', A8, ' Id:', I4, ' Height:', F8.2, & ' Weight:', F8.2 ) |
Example 2: Variable format expressions:
DO 100 N = 1, 50 ... 1 FORMAT( 2X, F<N+1>.2 ) |
The FUNCTION statement identifies a program unit as a function subprogram.
[ type ] FUNCTION fun ( [ ar [, ar ] ... ] ) |
(COMPLEX*32
and REAL*16
are SPARC,
PowerPC only.)
An alternate nonstandard syntax for length specifier is as follows:
[ type ] FUNCTION name [* m]([ ar [,ar] ...]) | |
m | Unsigned, nonzero integer constant specifying length of the data type. |
Note the type, value, and formal arguments for a FUNCTION statement.
The function statement involves type, name, and formal arguments.
If type is not present in the FUNCTION statement, then the type of the function is determined by default and by any subsequent IMPLICIT or type statement. If type is present, then the function name cannot appear in other type statements.
Note - Compiling with any of the options
-dbl
,-r8
,-i2
, or-xtypemap
can alter the default data size assumed in the call to or definition of functions unless the data type size is explicitly declared. See Chapter 2 and the Fortran User Guide for details on these options.
The symbolic name of the function must appear as a variable name in the subprogram. The value of this variable, at the time of execution of the RETURN or END statement in the function subprogram, is the value of the function.
The list of arguments defines the number of formal arguments. The type of these formal arguments is defined by some combination of default, type statements, IMPLICIT statements, and DIMENSION statements.
The number of formal arguments must be the same as the number of actual arguments at the invocation of this function subprogram. A function can assign values to formal arguments. These values are returned to the calling program when the RETURN or END statements are executed in the function subprogram.Alternate return specifiers are not allowed in FUNCTION statements.
f77 provides recursive calls. A function or subroutine is called recursively if it calls itself directly. If it calls another function or subroutine, which in turn calls this function or subroutine before returning, then it is also called recursively.Example 1: Character function:
CHARACTER*5 FUNCTION BOOL(ARG) BOOL = 'TRUE' IF (ARG .LE. 0) BOOL = 'FALSE' RETURN END |
FUNCTION SQR (A) SQR = A*A RETURN END |
Example 3: Size of function, alternate syntax:
INTEGER FUNCTION FCN*2 ( A, B, C ) |
The above nonstandard form is treated as:
INTEGER*2 FUNCTION FCN ( A, B, C ) |
The assigned GO TO statement branches to a statement label identified by the assigned label value of a variable.
GO TO i [ [,] ( s [, s ] ... ) ] | |
i | Integer variable name |
s | Statement label of an executable statement |
Execution proceeds as follows:
i must be assigned by an ASSIGN statement in the same program unit as the GO TO statement.
i must be INTEGER*4 or INTEGER*8, not INTEGER*2. s must be in the same program unit as the GO TO statement. The same statement label can appear more than once in a GO TO statement. The statement control jumps to must be executable, not DATA, ENTRY, FORMAT, or INCLUDE. Control cannot jump into a DO, IF, ELSE IF, or ELSE block from outside the block.Example: Assigned GO TO:
ASSIGN 10 TO N ... GO TO N ( 10, 20, 30, 40 ) ... 10 CONTINUE ... 40 STOP |
The computed GO TO statement selects one statement label from a list, depending on the value of an integer or real expression, and transfers control to the selected one.
GO TO ( s [, s ] ... ) [,] e | |
s | Statement label of an executable statement |
e | Expression of type integer or real |
Execution proceeds as follows:
s
must be in the same program unit as the GO TO statement. The same statement label can appear more than once in a GO TO statement. The statement control jumps to must be executable, not DATA, ENTRY, FORMAT, or INCLUDE. Control cannot jump into a DO, IF, ELSE IF, or ELSE block from outside the block.Example: Computed GO TO
... GO TO ( 10, 20, 30, 40 ), N ... 10 CONTINUE ... 20 CONTINUE ... 40 CONTINUE |
:
The unconditional GO TO statement transfers control to a specified statement.
GO TO s | |
s | Statement label of an executable statement |
Execution of the GO TO statement transfers control to the statement labeled s.
s
must be in the same program unit as the GO TO statement. The statement control jumps to must be executable, not a DATA, ENTRY, FORMAT, or INCLUDE statement. Control cannot jump into a DO, IF, ELSE IF, or ELSE block from outside the block.A = 100.0 B = 0.01 GO TO 90 ... 90 CONTINUE |
The arithmetic IF statement branches to one of three specified statements, depending on the value of an arithmetic expression.
IF ( e ) s1, s2, s3 | |
e |
Arithmetic expression: integer, real, double precision, or quadruple precision |
s1, s2, s3 |
Labels of executable statements |
The IF statement transfers control to the first, second, or third label if the value of the arithmetic expression is less than zero, equal to zero, or greater than zero, respectively.
The restrictions are:N = 0 IF ( N ) 10, 20, 30 |
Since the value of N is zero, control is transferred to statement label 20.
The block IF statement executes one of two or more sequences of statements, depending on the value of a logical expression.
IF ( e ) THEN | |
... | |
END IF | |
e | A logical expression |
The block IF statement evaluates a logical expression and, if the logical expression is true, it executes a set of statements called the IF block. If the logical expression is false, control transfers to the next ELSE, ELSE IF, or END IF statement at the same IF-level.
The IF level of a statement S is the value n1-n2, where n1 is the number of block IF statements from the beginning of the program unit up to the end, including S; n2 is the number of END IF statements in the program unit up to, but not including, S.
Example: In the following program, the IF-level of statement 9 is 2-1, or, 1:IF ( X .LT. 0.0 ) THEN MIN = NODE END IF ... 9 IF ( Y .LT. 0.0 ) THEN MIN = NODE - 1 END IF |
An IF block consists of all the executable statements following the block IF statement,
up to, but not including, the next ELSE, ELSE IF, or END IF statement that has
the same if level as the block IF statement. An IF block can be empty. In the following
example, the two assignment statements form an IF block:
IF ( X .LT. Y ) THEN M = 0 N = N+1 END IF |
Execution proceeds as follows:
Control cannot jump into an IF block from outside the IF block.
Example 1: IF-THEN-ELSE:
IF ( L ) THEN N=N+1 CALL CALC ELSE K=K+1 CALL DISP END IF |
Example 2: IF-THEN-ELSE-IF with ELSE-IF:
IF ( C .EQ. 'a' ) THEN NA=NA+1 CALL APPEND ELSE IF ( C .EQ. 'b' ) THEN NB=NB+1 CALL BEFORE ELSE IF ( C .EQ. 'c' ) THEN NC=NC+1 CALL CENTER END IF |
Example 3: Nested IF-THEN-ELSE:
IF ( PRESSURE .GT 1000.0 ) THEN IF ( N .LT. 0.0 ) THEN X = 0.0 Y = 0.0 ELSE Z = 0.0 END IF ELSE IF ( TEMPERATURE .GT. 547.0 ) THEN Z = 1.0 ELSE X = 1.0 Y = 1.0 END IF |
The logical IF statement executes one single statement, or does not execute it, depending on the value of a logical expression.
IF ( e ) st | |
e | Logical expression |
st | Executable statement |
The logical IF statement evaluates a logical expression and executes the specified statement if the value of the logical expression is true. The specified statement is not executed if the value of the logical expression is false, and execution continues as though a CONTINUE statement had been executed.
st can be any executable statement, except a DO block, IF, ELSE IF, ELSE, END IF, END, or another logical IF statement.IF ( VALUE .LE. ATAD ) CALL PUNT ! Note that there is no THEN. IF ( TALLY .GE. 1000 ) RETURN |
The IMPLICIT statement confirms or changes the default type of names.
IMPLICIT type ( a [, a ] ... ) [, type ( a [, a ] ... ) ] |
or: |
IMPLICIT NONE |
or: |
IMPLICIT UNDEFINED(A-Z) u |
type is one of the following permitted types:
The different uses for implicit typing and no implicit typing are described here.
The IMPLICIT statement can also indicate that no implicit typing rules apply in a program unit.
An IMPLICIT statement specifies a type and size for all user-defined names that begin with any letter, either a single letter or in a range of letters, appearing in the specification. An IMPLICIT statement does not change the type of the intrinsic functions. An IMPLICIT statement applies only to the program unit that contains it. A program unit can contain more than one IMPLICIT statement. IMPLICIT types for particular user names are overridden by a type statement.
Note - Compiling with any of the options
-dbl
,-i2
, -r8
, or-xtypemap
can alter the assumed size of names typed with anIMPLICIT
statement that does not specify a size:IMPLICIT REAL (A-Z)
. See Chapter 2 and the Fortran User's Guide for details.
The second form of IMPLICIT specifies that no implicit typing should be done for user-defined names, and all user-defined names shall have their types declared explicitly.
If either IMPLICIT NONE or IMPLICIT UNDEFINED (A-Z) is specified, there cannot be any other IMPLICIT statement in the program unit.IMPLICIT statements must precede all other specification statements.
The same letter can appear more than once as a single letter, or in a range of letters in all IMPLICIT statements of a program unit.Example 1: IMPLICIT: everything is integer:
IMPLICIT INTEGER (A-Z) X = 3 K = 1 STRING = 0 |
Example 2: Complex if it starts with U, V, or W; character if it starts
with C or S:
IMPLICIT COMPLEX (U,V,W), CHARACTER*4 (C,S) U1 = ( 1.0, 3.0) STRING = 'abcd' I = 0 X = 0.0 |
Example 3: All items must be declared:
IMPLICIT NONE CHARACTER STR*8 INTEGER N REAL Y N = 100 Y = 1.0E5 STR = 'Length' |
Example 4: A letter used twice:
IMPLICIT INTEGER (A-Z) IMPLICIT REAL (A-C) C = 1.5E8 D = 9 |
In the above example, D through Z implies INTEGER, and A through C implies REAL.
The INCLUDE statement inserts a file into the
source program.
INCLUDE 'file' | |
or: | |
INCLUDE "file" | |
file | Name of the file to be inserted |
The contents of the named file replace the INCLUDE statement.
If the name referred to by the INCLUDE statement begins with the character /, then it is taken by f77 to mean the absolute path name of the INCLUDE file. Otherwise, f77 looks for the file in the following directories, in this order:
The release number, SC4.2, varies with the release of the set of compilers.
These INCLUDE statements can be nested ten deep.The paths and order searched for the INCLUDE statement are not the same as those searched for the preprocessor #include directive, described under -I in the Fortran User's Guide. Files included by the preprocessor #include directive can contain #defines and the like; files included with the compiler INCLUDE statement must contain only FORTRAN statements.
f77
interprets VMS logical file names on the INCLUDE statement if:-vax=
spec compiler options are set. "lname1=path1; lname2=path2; ... " |
Example 1: INCLUDE, simple case:
INCLUDE 'stuff' |
The above line is replaced by the contents of the file stuff.
Example 2: INCLUDE, search paths:
INCLUDE 'ver1/const.h' |
In this example, f77 seeks const.h in these directories, in the order shown.
For a standard install, f77 searches these directories:For a non-standard install to a directory /mydir, it searches these directories:
The INQUIRE statement returns information about a unit or file.
An inquire by unit has the general form:
INQUIRE( [ UNIT=] u, slist ) |
An inquire by file has the general form:
INQUIRE( FILE=fn, slist ) | |
fn | Name of the file being queried |
u | Unit of the file being queried |
slist | Specifier list |
The INQUIRE slist can include one or more of the following, in any order:
You can determine such things about a file as whether it exists, is opened, or is connected for sequential I/O. That is, files have such attributes as name, existence (or nonexistence), and the ability to be connected in certain ways (FORMATTED, UNFORMATTED, SEQUENTIAL, or DIRECT).
Inquire either by unit or by file, but not by both in the same statement. In this system environment, the only way to discover what permissions you have for a file is to use the ACCESS(3F) function. The INQUIRE statement does not determine permissions. The specifiers for INQUIRE are:Example: An OPEN statement in which declarations are omitted:
OPEN( 1, FILE='/dev/console' ) |
The following table summarizes the INQUIRE options:
Example 1: Inquire by unit:
LOGICAL OK INQUIRE( UNIT=3, OPENED=OK ) IF ( OK ) CALL GETSTD ( 3, STDS ) |
LOGICAL THERE INQUIRE( FILE='.profile', EXIST=THERE ) IF ( THERE ) CALL GETPROFILE( FC, PROFILE ) |
Example 3: More than one answer, omitting the UNIT=
:
CHARACTER FN*32 LOGICAL HASNAME, OK INQUIRE ( 3, OPENED=OK, NAMED=HASNAME, NAME=FN ) IF ( OK .AND. HASNAME ) PRINT *, 'Filename="', FN, '"' |
The INTEGER statement specifies the type to be integer for a symbolic constant, variable, array, function, or dummy function.
Optionally, it specifies array dimensions and size and initializes with values.The declarations can be: INTEGER
, INTEGER*2
, INTEGER*4
,
INTEGER*8
.
INTEGER
For a declaration such as INTEGER H
, the variable H
is
usually one INTEGER*4
element in memory, interpreted as a single integer
number. Specifying the size is nonstandard.
-dbl
, -i2
, -r8
, or -xtypemap
.
See the discussion in Chapter 2 for details.
INTEGER*2
For a declaration such as INTEGER*2 H
, the variable H
is
always an INTEGER*2
element in memory, interpreted as a single integer
number.
INTEGER*4
For a declaration such as INTEGER*4 H
, the variable H
is
always an INTEGER*4
element in memory, interpreted as a single integer
number.
INTEGER*8
For a declaration such as INTEGER*8 H
, the variable H
is
always an INTEGER*8
element in memory, interpreted as a single integer
number.
Do not use INTEGER*8 variables or 8-byte constants or expressions when indexing arrays, otherwise, only 4 low-order bytes are taken into account. This action can cause unpredictable results in your program if the index value exceeds the range for 4-byte integers.
Example 1: Each of these integer declarations are equivalent:
INTEGER U, V(9) or INTEGER*4 U, V(9) or INTEGER U*4, V(9)*4 |
INTEGER U / 1 /, V / 4 /, W*2 / 1 /, X*2 / 4 / |
The INTRINSIC statement lists intrinsic functions that can be passed as actual arguments.
INTRINSIC fun [, fun ] ... | |
fun | Function name |
If the name of an intrinsic function is used as an actual argument, it must appear in an INTRINSIC statement in the same program unit.
Example: Intrinsic functions passed as actual arguments:INTRINSIC SIN, COS X = CALC ( SIN, COS ) |
A symbolic name must not appear in both an EXTERNAL and an INTRINSIC statement in the same program unit.
The actual argument must be a specific name. Most generic names are also specific, but a few are not: IMAG, LOG, and LOG10. A symbolic name can appear more than once in an INTRINSIC statement.In the FORTRAN Standard, a symbolic name can appear only once in an INTRINSIC statement.The LOGICAL statement specifies the type to be logical for a symbolic constant, variable, array, function, or dummy function.
Optionally, it specifies array dimensions and initializes with values.The declarations can be: LOGICAL
, LOGICAL*1,
LOGICAL*2
,
LOGICAL*4,
LOGICAL*8
.
LOGICAL
For a declaration such as LOGICAL H
, the variable H
is
usually one INTEGER*4
element in memory, interpreted as a single logical
value. Specifying the size is nonstandard.
-dbl
, -i2
,-r8
, or -xtypemap
.
See the discussion in Chapter 2 for details.
LOGICAL*1
For a declaration such as LOGICAL*1 H
, the variable H
is
always an BYTE
element in memory, interpreted as a single logical value.
LOGICAL*2
For a declaration such as LOGICAL*2 H
, the variable H
is
always an INTEGER*2
element in memory, interpreted as a single logical value.
LOGICAL*4
For a declaration such as LOGICAL*4 H
, the variable H
is
always an INTEGER*4
element in memory, interpreted as a single logical value.
LOGICAL*8
For a declaration such as LOGICAL*8 H
, the variable H
is
always an INTEGER*8
element in memory, interpreted as a single logical value.
Example 1: Each of these declarations are equivalent:
LOGICAL U, V(9) or LOGICAL*4 U, V(9) or LOGICAL U*4, V(9)*4 |
LOGICAL U /.false./, V /0/, W*4 /.true./, X*4 /'z'/ |
The MAP declaration defines alternate groups
of fields in a union.
MAP field-declaration ... [field-declaration] END MAP |
Each field declaration can be one of the following:
Example: MAP:
STRUCTURE /STUDENT/ CHARACTER*32 NAME INTEGER*2 CLASS UNION MAP CHARACTER*16 MAJOR END MAP MAP INTEGER*2 CREDITS CHARACTER*8 GRAD_DATE END MAP END UNION END STRUCTURE |
The NAMELIST statement defines a list of
variables or array names, and associates it with a unique group name.
NAMELIST / grname / namelist [[,] / grname / namelist ] ... | |
grname | Symbolic name of the group |
namelist | List of variables and arrays |
The NAMELIST statement contains a group name and other items.
The group name is used in the namelist-directed I/O statement to identify the list of variables or arrays that are to be read or written. This name is used by namelist-directed I/O statements instead of an input/output list. The group name must be unique, and identifies a list whose items can be read or written.
A group of variables can be defined through several NAMELIST statements with the same group name. Together, these definitions are taken as defining one NAMELIST group.The namelist items can be of any data type. The items in the namelist can be variables or arrays, and can appear in more than one namelist. Only the items specified in the namelist can be read or written in namelist-directed I/O, but it is not necessary to specify data in the input record for every item of the namelist.
The order of the items in the namelist controls the order in which the values are written in namelist-directed output. The items in the input record can be in any order.Input data can assign values to the elements of arrays or to substrings of strings that appear in a namelist.
The following constructs cannot appear in a NAMELIST statement:See
Chapter 5, "Input and Output," for more details on namelist.Example: The NAMELIST statement:
CHARACTER*16 SAMPLE LOGICAL*4 NEW REAL*4 DELTA NAMELIST /CASE/ SAMPLE, NEW, DELTA |
In this example, the group CASE has three variables: SAMPLE, NEW, and DELTA.
The OPEN statement connects an existing external file to a unit, or creates a file and connects it to a unit, or changes some specifiers of the connection.
Note - For tape I/O, use the TOPEN() routines.
OPEN( KEYWORD1=value1, KEYWORD2=value2, ... ) | |
KEYWORDn | A valid keyword specifier, as listed below |
The OPEN statement determines the type of file named, whether the connection specified
is legal for the file type (for instance, DIRECT access is illegal for tape and
tty devices), and allocates buffers for the connection if the file is on tape
or if the subparameter FILEOPT='BUFFER=n' is specified. Existing files are never truncated
on opening. The options can be specified in any order.
Details of the OPEN keyword specifier are listed in the
following table.
Here are six examples.
Example 1: Open a file and connect it to unit 8--either of the following forms of the OPEN statement opens the file, projectA/data.test, and connects it to FORTRAN unit 8:OPEN( UNIT=8, FILE='projectA/data.test' ) OPEN( 8, FILE='projectA/data.test' ) |
Example 2: Explicitly specify properties:
OPEN( UNIT=8, FILE='projectA/data.test', & ACCESS='SEQUENTIAL', FORM='FORMATTED' ) |
Example 3: Either of these opens file, fort.8, and connects it to unit
8:
OPEN( UNIT=8 ) OPEN( 8 ) |
Example 4: Allowing for open errors:
OPEN( UNIT=8, FILE='projectA/data.test', ERR=99 ) |
The above statement branches to 99 if an error occurs during OPEN.
Example 5: Allowing for variable-length records;
OPEN( 1, ACCESS='DIRECT', recl=1 ) |
For more information on variable-length records, see "Direct Access I/O" on page 265.
OPEN( 1, STATUS='SCRATCH' ) |
The OPTIONS statement overrides compiler
command-line options.
OPTIONS /qualifier [/qualifier ...] |
The following table shows the OPTIONS statement qualifiers:
The OPTIONS statement must be the first statement in a program unit; it must be before the BLOCK DATA, FUNCTION, PROGRAM, and SUBROUTINE statements.
Options set by the OPTIONS statement override those of the command line. Options set by the OPTIONS statement endure for that program unit only. A qualifier can be abbreviated to four or more characters. Uppercase or lowercase is not significant.For the following source, integer variables declared with no explicit size occupy 4
bytes rather than 2, with or without the -i2 option on the command line. This
rule does not change the size of integer constants, only variables.
OPTIONS /I4 PROGRAM FFT ... END |
The PARAMETER statement assigns a symbolic name to a constant.
PARAMETER ( p=e [, p=e ] ... ) | |
p | Symbolic name |
e | Constant expression |
An alternate syntax is allowed, if the -xl flag is set:
PARAMETER p=e [, p=e ] ... |
e can be of any type and the type of symbolic name and the corresponding expression must match.
A symbolic name can be used to represent the real part, imaginary part, or both parts of a complex constant. A constant expression is made up of explicit constants and parameters and the FORTRAN operators. See Constant Expressions on page 77.No structured records or record fields are allowed in a constant expression.
Exponentiation to a floating-point power is not allowed, and a warning is issued.
A symbolic constant must not be defined more than once in a program unit.
If a symbolic name appears in a PARAMETER statement, then it cannot represent anything else in that program unit. A symbolic name cannot be used in a constant format specification, but it can be used in a variable format specification. If you pass a parameter as an argument, and the subprogram tries to change it, you may get a runtime error.Example 1: Some real, character, and logical parameters:
CHARACTER HEADING*10 LOGICAL T PARAMETER ( EPSILON=1.0E-6, PI=3.141593, & HEADING='IO Error #', & T=.TRUE. ) ... |
Example 2: Let the compiler count the characters:
CHARACTER HEADING*(*) PARAMETER ( HEADING='I/O Error Number' ) ... |
Example 3: The alternate syntax, if the -xl compilation flag
is specified:
PARAMETER FLAG1 = .TRUE. |
The above statement is treated as:
LOGICAL FLAG1 PARAMETER (FLAG1 = .TRUE.) |
Example: An ambiguous statement:
PARAMETER S = .TRUE. |
With -xl, the above statement is a PARAMETER
statement about the variable S.
PARAMETER S = .TRUE. |
It is not an assignment statement about the variable PARAMETERS.
PARAMETERS = .TRUE. |
The PAUSE statement suspends execution, and waits for you to type: go.
PAUSE [str ] | |
str | String of not more than 5 digits or a character constant |
The PAUSE statement suspends program execution temporarily, and waits for acknowledgment. On acknowledgment, execution continues.
If the argument string is present, it is displayed on the screen (written to stdout), followed by the following message:PAUSE. To resume execution, type: go Any other input will terminate the program. |
After you type: go, execution continues as if a CONTINUE
statement is executed. See this example:
If stdin is not a tty I/O device, PAUSE
displays a message like this:
PAUSE: To resume execution, type: kill -15 pid |
Example: stdin not a tty I/O device:
demo% a.out < mydatafile PAUSE: To resume execution, type: kill -15 20537 demo% |
demo% kill -15 20537 |
The POINTER statement establishes pairs of
variables and pointers.
POINTER ( p1, v1 ) [, ( p2, v2 ) ... ] | |
v1, v2 | Pointer-based variables |
p1, p2 | Corresponding pointers |
Each pointer contains the address of its paired variable.
A pointer-based variable is a variable paired with a pointer in a POINTER statement. A pointer-based variable is usually called just a based variable. The pointer is the integer variable that contains the address.Normal use of pointer-based variables involves the following steps. The first two steps can be in either order.
No storage for the variable is allocated when a pointer-based variable is defined, so you must provide an address of a variable of the appropriate type and size, and assign the address to a pointer, usually with the normal assignment statement or data statement.
There are three procedures used to manage memory with pointers:The subroutine FREE() deallocates a region of memory previously allocated by MALLOC(). The argument given to FREE() must be a pointer previously returned by MALLOC(), but not already given to FREE(). The memory is returned to the memory manager, making it unavailable to the programmer.
The function MALLOC() allocates an area of memory and returns the address of the start of that area. The argument to the function is an integer specifying the amount of memory to be allocated, in bytes. If successful, it returns a pointer to the first item of the region; otherwise, it returns an integer 0. The region of memory is not initialized in any way--do not assume it is initiallized to zero.
Pointers have the side effect of reducing the assumptions that the global optimizer can make.
Compare:Therefore, the optimizer must assume that a variable passed as an argument in a subroutine or function call can be changed by any other call. Such an unrestricted use of pointers would degrade optimization for the vast majority of programs that do not use pointers.
The pointers are of type integer and are automatically typed that way by the compiler. You must not type them yourself.
A pointer-based variable cannot itself be a pointer. The pointer-based variables can be of any type, including structures. No storage is allocated when such a pointer-based variable is defined, even if there is a size specification in the type statement. You cannot use a pointer-based variable as a dummy argument or in COMMON, EQUIVALENCE, DATA, or NAMELIST statements. The dimension expressions for pointer-based variables must be constant expressions in main programs. In subroutines and functions, the same rules apply for pointer-based array variables as for dummy arguments--the expression can contain dummy arguments and variables in common. Any variables in the expressions must be defined with an integer value at the time the subroutine or function is called. This implementation of POINTER follows more along the line of Cray, not Fortran 90, although it does not follow Cray exactly. The address cannot exceed the range of INTEGER*4. If the address expression is not in the range (-2147483648, 2147483647), then the results are unpredictable. If you use an optimization level greater than -O2, you must write your programs with the following restrictions on the use of pointers:Example: One kind of code that could cause problems if you optimize at a level greater
than -O2:
COMMON A, B, C POINTER ( P, V ) P = LOC(A) + 4 ! ... |
Example 1: A simple POINTER statement:
POINTER ( P, V ) |
Here, V is a pointer-based variable, and P is its associated pointer.
Example 2: Using the LOC() function to get an address:
* ptr1.f: Assign an address via LOC() POINTER ( P, V ) CHARACTER A*12, V*12 DATA A / 'ABCDEFGHIJKL' / P = LOC( A ) PRINT *, V(5:5) END |
Example 3: Memory allocation for pointers, by MALLOC
POINTER ( P1, X ), ( P2, Y ), ( P3, Z ) ... P1 = MALLOC ( 36 ) ... CALL FREE ( P1 ) ... |
:
Example 4: Get the area of memory and its address
POINTER ( P, V ) CHARACTER V*12, Z*1 P = MALLOC( 12 ) ... END |
:
Example 5: Dynamic allocation of arrays:
Example 6: One way to use pointers to make a linked list in f77:
demo% f77 -silent Linked.f "Linked.f", line 6: Warning: local variable "b" never used "Linked.f", line 31: Warning: local variable "b" never used demo% a.out 1 aaa 2 bbb 3 ccc 4 ddd demo% |
The PRINT statement writes from a list to stdout.
PRINT f [, iolist ] | |
PRINT grname | |
f | Format identifier |
iolist | List of variables, substrings, arrays, records, ... |
grname | Name of the namelist group |
The PRINT statement accepts the following arguments.
f
is a format identifier and can be:iolist can be empty or can contain output items or implied DO lists. The output items must be one of the following:
A simple unsubscripted array name specifies all of the elements of the array in memory storage order, with the leftmost subscript increasing more rapidly.
The second form of the PRINT statement is used to print the items of the specified namelist group. Here, grname is the name of a group previously defined by a NAMELIST statement.
Execution proceeds as follows:Output from an exception handler is unpredictable. If you make your own exception handler, do not do any FORTRAN output from it. If you must do some, then call abort right after the output. Doing so reduces the relative risk of a program freeze. FORTRAN I/O from an exception handler amounts to recursive I/O. See the next point.
Recursive I/O does not work reliably. If you list a function in an I/O list, and if that function does I/O, then during runtime, the execution may freeze, or some other unpredictable problem may occur. This risk exists independent of parallelization. Example: Recursive I/O fails intermittently:PRINT *, x, f(x) ! Not allowed, f() does I/O. END FUNCTION F(X) PRINT *, X RETURN END |
Example 1: Formatted scalars:
CHARACTER TEXT*16 PRINT 1, NODE, TEXT 1 FORMAT ( I2, A16 ) |
Example 2: List-directed array:
PRINT *, I, J, ( VECTOR(I), I = 1, 5 ) |
INTEGER VECTOR(10) PRINT '( 12 I2 )', I, J, VECTOR |
CHARACTER LABEL*16 REAL QUANTITY INTEGER NODE NAMELIST /SUMMARY/ LABEL, QUANTITY, NODE PRINT SUMMARY |
The PROGRAM statement identifies the program unit as a main program.
PROGRAM pgm | |
pgm | Symbolic name of the main program |
For the loader, the main program is always named MAIN. The PROGRAM statement serves only the person who reads the program.
The PROGRAM statement can appear only as the first statement of the main program.
The name of the program cannot be:The name of the program can be the same as a local name in the main program. The FORTRAN Standard does not allow this practice.
Example: A PROGRAM statement:
PROGRAM US_ECONOMY NVARS = 2 NEQS = 2 ... |
The READ statement reads data from a file or the keyboard to items in the list.
Note - For tape, it is more reliable to use the TOPEN() routines.
READ( [ UNIT=] u [, [ FMT=] f ] [, IOSTAT= ios ] [, REC= rn ] [, END= s ] [, ERR= s ] ) iolist |
READ f [, iolist ] |
READ([UNIT=] u, [NML=] grname [,IOSTAT=ios ] [,END=s ] [,ERR=s ] ) |
READ grname |
An alternate to the UNIT=u, REC=rn
form is as follows:
READ( u 'rn ... ) iolist |
The options can be specified in any order.
The READ statement accepts the following arguments.
u
is either an external unit identifier or an internal file identifier. An external unit identifier must be one of these:If the optional characters UNIT= are omitted from the unit specifier, then u must be the first item in the list of specifiers.
f
is a format identifier and can be:If the optional characters, FMT=, are omitted from the format specifier, then f must appear as the second argument for a formatted read; otherwise, it must not appear at all.
Unformatted data transfer from internal files and terminal files is not allowed, hence, f must be present for such files. List-directed data transfer from direct-access and internal files is allowed; hence, f can be an asterisk for such files.ios
must be an integer variable or an integer array element.rn
must be a positive integer expression, and can be used for direct-access files only. rn can be specified for internal files.s
must be the label of an executable statement in the same program unit in which the READ statement occurs. The END=s and REC=rn specifiers can be present in the same READ statement.s
must be the label of an executable statement in the same program unit in which the READ statement occurs.iolist
can be empty or can contain input items or implied DO lists. The input items can be any of the following:A simple unsubscripted array name specifies all of the elements of the array in memory storage order, with the leftmost subscript increasing more rapidly.
The third and fourth forms of the READ statement are used to read the items of the specified namelist group, and grname is the name of the group of variables previously defined in a NAMELIST statement.
Execution proceeds as follows:
There are two forms of READ:
READ f [, iolist ] |
READ ( [ NML= ] grname ) |
Execution has the following differences:
If u specifies an external unit that is not connected to a file, an implicit
OPEN operation is performed equivalent to opening the file with the options in the
following example:
OPEN( u, FILE='FORT.u', STATUS='OLD', | |
& |
ACCESS='SEQUENTIAL', FORM=fmt ) |
Example 1: Formatted read, trap I/O errors, EOF, and I/O status:
READ( 1, 2, ERR=8, END=9, IOSTAT=N ) X, Y ... 8 WRITE( *, * ) 'I/O error # ', N, ', on 1' STOP 9 WRITE( *, * ) 'EoF on 1' RETURN END |
Example 2: Direct, unformatted read, trap I/O errors, and I/O status:
READ( 1, REC=3, IOSTAT=N, ERR=8 ) V ... 4 CONTINUE RETURN 8 WRITE( *, * ) 'I/O error # ', N, ', on 1' END |
Example 3: List-directed read from keyboard:
READ( *, * ) A, V or READ *, A, V |
Example 4: Formatted read from an internal file:
CHARACTER CA*16 / 'abcdefghijklmnop' /, L*8, R*8 READ( CA, 1 ) L, R 1 FORMAT( 2 A8 ) |
Example 5: Read an entire array:
DIMENSION V(5) READ( 3, '(5F4.1)') V |
Example 6: Namelist-directed read:
CHARACTER SAMPLE*16 LOGICAL NEW*4 REAL DELTA*4 NAMELIST /G/ SAMPLE, NEW, DELTA ... READ( 1, G ) or READ( UNIT=1, NML=G ) or READ( 1, NML=G ) |
The REAL statement specifies the type of a symbolic constant, variable, array, function, or dummy function to be real, and optionally specifies array dimensions and size, and initializes with values.
Following are descriptions for REAL, REAL*4, REAL*8, and REAL*16.
For a declaration such as REAL W, the variable W is usually a REAL*4 element in memory,
interpreted as a real number. Specifying the size is nonstandard.
-dbl
, -r8
, or -xtypemap
.
See the discussion in Chapter 2 for details.
For a declaration such as REAL*4 W, the variable W is always a REAL*4 element in memory, interpreted as a single-width real number.
For a declaration such as REAL*8 W, the variable W is always a REAL*8 element in memory, interpreted as a double-width real number.
(SPARC, PowerPC only)
For a declaration such as REAL*16 W, the variable W is always an element of type REAL*16 in memory, interpreted as a quadruple-width real.Example 1: Simple real variables--these declarations are equivalent:
REAL U, V(9) or REAL*4 U, V(9) or REAL U*4, V(9)*4 |
Example 2: Initialize variables (REAL*16 is SPARC, PowerPC
only):
REAL U/ 1.0 /, V/ 4.3 /, D*8/ 1.0 /, Q*16/ 4.5 / |
Example 3: Specify dimensions for some real arrays:
REAL A(10,100), V(10) REAL X*4(10), Y(10)*4 |
Example 4: Initialize some arrays:
REAL A(10,100) / 1000 * 0.0 /, B(2,2) / 1.0, 2.0, 3.0, 4.0 / |
Example 5: Double and quadruple precision (REAL*16 is SPARC,
PowerPC only):
REAL*8 R REAL*16 Q DOUBLE PRECISION D |
In the above example, D and R are both double precision; Q is quadruple precision.
The RECORD statement defines variables to have
a specified structure, or arrays to be arrays of variables with such structures.
RECORD /struct-name/ record-list [,/struct-name/ record-list]... | |
struct-name | Name of a previously declared structure |
record-list | List of variables, arrays, or array declarators |
A structure is a template for a record. The name of the structure is included in the STRUCTURE statement, and once a structure is thus defined and named, it can be used in a RECORD statement.
The record is a generalization of the variable or array: where a variable or array has a type, the record has a structure. Where all the elements of an array must be of the same type, the fields of a record can be of different types. The RECORD line is part of an inherently multiline group of statements, and neither the RECORD line nor the END RECORD line has any indication of continuation. Do not put a nonblank in column six, nor an & in column one.Example 1: Declare some items to be records of a specified structure:
STRUCTURE /PRODUCT/ INTEGER*4 ID CHARACTER*16 NAME CHARACTER*8 MODEL REAL*4 COST REAL*4 PRICE END STRUCTURE RECORD /PRODUCT/ CURRENT, PRIOR, NEXT, LINE(10) ... |
Example 2: Define some fields of records, then use them:
The above program produces the following output:
82 CacheBoard 1000.00 96K |
A RETURN statement returns control to the calling program unit.
RETURN [ e ] | |
e | Expression of type INTEGER or REAL |
Execution of a RETURN statement terminates the reference of a function or subroutine.
Execution of an END statement in a function or a subroutine is equivalent to the execution of a RETURN statement.Example 1: Standard return:
CHARACTER*25 TEXT TEXT = "Some kind of minor catastrophe" ... CALL OOPS ( TEXT ) STOP END SUBROUTINE OOPS ( S ) CHARACTER S* 32 WRITE (*,*) S RETURN END |
REWIND
positions the file associated with the specified unit to its initial point. If you use this statement for tapes, we recommend the TOPEN() routines instead, because they are more reliable.The options can be specified in any order.
Rewinding a unit not associated with any file has no effect. Likewise, REWIND in a terminal file has no effect either. Using a REWIND statement on a direct-access file is not defined in the FORTRAN Standard, and is unpredictable.Example 1: Simple form of unit specifier:
ENDFILE 3 REWIND 3 READ (3,'(I2)') I REWIND 3 READ (3,'(I2)')I |
Example 2: REWIND with the UNIT=u form of
unit specifier and error trap:
INTEGER CODE ... REWIND (UNIT = 3) REWIND (UNIT = 3, IOSTAT = CODE, ERR = 100) ... 100 WRITE (*,*) 'error in rewinding' STOP |
The SAVE statement preserves items in a subprogram after the RETURN or END statements are executed, preventing them from becoming undefined.
SAVE [ v [, v ] ... ] | |
v | Name of an array, variable, or common block (enclosed in slashes), occurring in a subprogram |
SAVE
variables are placed in an internal static area. All common blocks are
already preserved because they have been allocated to a static area. Therefore, common
block names specified in SAVE statements are allowed but ignored.
A SAVE statement is optional in the main program and has
no effect.
A SAVE with no list preserves all local variables and
arrays in the routine.
Local variables and arrays are already static by default,
predisposing the need for SAVE. However, using SAVE can ensure portability, especially
with routines that leave a subprogram by some way other than a RETURN.
The following constructs must not appear in a SAVE statement:
Example: A SAVE statement:
SUBROUTINE FFA(N) DIMENSION A(1000,1000), V(1000) SAVE A ... RETURN END |
A statement function statement is a function-like declaration, made in a single statement.
fun ( [ d [, d ] ... ] ) = e | |
fun | Name of statement function being defined |
d | Statement function dummy argument |
e | Expression. e can be any of the types arithmetic, logical, or character. |
If a statement function is referenced, the defined calculations are inserted.
Example: The following statement is a statement function:ROOT( A, B, C ) = (-B + SQRT(B**2-4.0*A*C))/(2.0*A) |
Execution proceeds as follows:
The resulting value is thus available to the expression that referenced the function.
Note these restrictions:
Example 1: Arithmetic statement function:
PARAMETER ( PI=3.14159 ) REAL RADIUS, VOLUME SPHERE ( R ) = 4.0 * PI * (R**3) / 3.0 READ *, RADIUS VOLUME = SPHERE( RADIUS ) ... |
Example 2: Logical statement function:
LOGICAL OKFILE INTEGER STATUS OKFILE ( I ) = I .LT. 1 READ( *, *, IOSTAT=STATUS ) X, Y IF ( OK FILE(STATUS) ) CALL CALC ( X, Y, A ) ... |
Example 3: Character statement function:
CHARACTER FIRST*1, STR*16, S*1 FIRST(S) = S(1:1) READ( *, * ) STR IF ( FIRST(STR) .LT. " " ) CALL CONTROL ( S, A ) ... |
The STATIC statement ensures that the
specified items are stored in static memory.
STATIC list | |
list | List of variables and arrays |
All local variables and arrays are classifed static by default: there is exactly one copy of each datum, and its value is retained between calls. You can also explicitly define variables as static or automatic in a STATIC or AUTOMATIC statement, or in any type statement or IMPLICIT statement.
However, you can still use STATIC to ensure portability, especially with routines that leave a subprogram by some way other than a RETURN. Also note that:STATIC REAL X
does not declare the
variable X to be both STATIC and REAL; it declares the variable REALX to be STATIC. STATIC A, B, C REAL P, D, Q STATIC P, D, Q IMPLICIT STATIC (X-Z) |
The STOP statement terminates execution of the program.
STOP [ [ str ] | |
str | String of no more that 5 digits or a character constant |
The argument str is displayed when the program stops.
If str is not specified, no message is displayed.Example 1: Integer:
stop 9 |
STOP: 9 |
stop 'error' |
STOP: error |
The STRUCTURE statement organizes data into
structures.
Each field declaration can be one of the following:
A STRUCTURE statement defines a form for a record by specifying the name, type, size, and order of the fields that constitute the record. Optionally, it can specify the initial values.
A structure is a template for a record. The name of the structure is included in the STRUCTURE statement, and once a structure is thus defined and named, it can be used in a RECORD statement. The record is a generalization of the variable or array--where a variable or array has a type, the record has a structure. Where all the elements of an array must be of the same type, the fields of a record can be of different types.The name is enclosed in slashes and is optional in nested structures only.
If slashes are present, a name must be present. You can specify the field-list within nested structures only. There must be at least one field-declaration. Each structure-name must be unique among structures, although you can use structure names for fields in other structures or as variable names. The only statements allowed between the STRUCTURE statement and the END STRUCTURE statement are field-declaration statements and PARAMETER statements. A PARAMETER statement inside a structure declaration block is equivalent to one outside.Fields that are type declarations use the identical syntax of normal
FORTRAN type statements, and all f77 types are allowed, subject to the
following rules and restrictions:
In a structure declaration, the offset of field n is the offset of the preceding field, plus the length of the preceding field, possibly corrected for any adjustments made to maintain alignment.
You can initialize a field that is a variable, array, substring, substructure, or union.Example 1: A structure of five fields:
STRUCTURE /PRODUCT/ INTEGER*4 ID / 99 / CHARACTER*16 NAME CHARACTER*8 MODEL / 'Z' / REAL*4 COST REAL*4 PRICE END STRUCTURE RECORD /PRODUCT/ CURRENT, PRIOR, NEXT, LINE(10) |
Example 2: A structure of two fields:
STRUCTURE /VARLENSTR/ INTEGER*4 NBYTES CHARACTER A*25 END STRUCTURE RECORD /VARLENSTR/ VLS VLS.NBYTES = 0 |
The SUBROUTINE statement identifies a named program unit as a subroutine, and specifies arguments for it.
SUBROUTINE sub [ ( [ fd [, fd ] ... ])] | |
sub | Name of subroutine subprogram |
d | Variable name, array name, record name, or dummy procedure name, an asterisk, or an ampersand |
A subroutine subprogram must have a SUBROUTINE statement as the first statement. A subroutine can have any other statements, except a BLOCK DATA, FUNCTION, PROGRAM, or another SUBROUTINE statement.
sub is the name of a subroutine and is a global name, and must not be the same as any other global name such as a common block name or a function name. Nor can it be the same as any local name in the same subroutine. d is the dummy argument, and multiple dummy arguments are separated by commas. d can be one of the following:The dummy arguments are local to the subroutine and must not appear in any of the following statements, except as a common block name:
The actual arguments in the CALL statement that references a subroutine must agree with the corresponding formal arguments in the SUBROUTINE statement, in order, number, and type. An asterisk (or an ampersand) in the formal argument list denotes an alternate return label. A RETURN statement in this procedure can specify the ordinal number of the alternate return to be taken.
Example 1: A variable and array as parameters:
SUBROUTINE SHR ( A, B ) CHARACTER A*8 REAL B(10,10) ... RETURN END |
Example 2: Standard alternate returns:
The TYPE statement writes to stdout.
TYPE f [, iolist ] | |
or: | |
TYPE grname | |
f | Format identifier |
iolist | List of output variables |
grname | Name of the namelist group |
The TYPE statement is provided for compatibility and is equivalent to:
Example: Formatted and namelist output:
INTEGER V(5) REAL X(9), Y NAMELIST /GNAM/ X, Y .... TYPE 1, V 1 FORMAT( 5 I3 ) .... TYPE GNAM .... |
The type statement specifies the data type of items in the list, optionally specifies array dimensions, and initializes with values.
type can be preceded by either AUTOMATIC or STATIC.
type can be one of the following type specifiers:
n, as in CHARACTER*n, must be greater than
0. COMPLEX*32
and REAL*16
are SPARC and PowerPC only.
A type statement can be used to:
A type statement can assign initial values to variables, arrays, or record fields by
specifying a list of constants (clist) as in a DATA statement.
type VariableName / constant / ... |
or: |
type ArrayName / constant, ... / |
or: |
type ArrayName / r*constant / |
where r is a repeat factor. |
Example: Various type statements:
CHARACTER LABEL*12 / 'Standard' / COMPLEX STRESSPT / ( 0.0, 1.0 ) / INTEGER COUNT / 99 /, Z / 1 / REAL PRICE / 0.0 /, COST / 0.0 / REAL LIST(8) / 0.0, 6*1.0, 0.0 / |
When you initialize a data type, remember the following restrictions:
INTEGER Z / 4 / POINTER ( x, Z ) |
Note - Compiling with any of the options
-dbl,
-r8,
-i2
, or-xtypemap
can alter the default size of names typed without an explicit size. See the discussion in Chapter 2.
A symbolic name can appear only once in type statements in a program unit.
A type statement must precede all executable statements.Example: The type statement:
INTEGER*2 I, J/0/ REAL*4 PI/3.141592654/,ARRAY(10)/5*0.0,5*1.0/ CHARACTER*10 NAME CHARACTER*10 TITLE/'Heading'/ |
The UNION statement defines groups of fields that share
memory at runtime.
UNION map-declaration map-declaration [map-declaration] ... END UNION |
The syntax of a UNION declaration is as follows:
The syntax of a MAP declaration is:
MAP field-declaration [field-declaration] ... [field-declaration] END MAP |
A MAP statement defines alternate groups of fields in a union. During execution, one map at a time is associated with a shared storage location. When you reference a field in a map, the fields in any previous map become undefined, and are succeeded by the fields in the map of the newly referenced field. Also:
The UNION line is part of an inherently multiline group of statements, and neither the UNION line nor the END UNION line has any special indication of continuation. You do not put a nonblank in column six, nor an & in column one.
Each field-declaration in a map declaration can be one of the following:Declare the structure /STUDENT/ to contain either NAME, CLASS, and MAJOR, or NAME,
CLASS, CREDITS, and GRAD_DATE:
STRUCTURE /STUDENT/ CHARACTER*32 NAME INTEGER*2 CLASS UNION MAP CHARACTER*16 MAJOR END MAP MAP INTEGER*2 CREDITS CHARACTER*8 GRAD_DATE END MAP END UNION END STRUCTURE RECORD /STUDENT/ PERSON |
In the above example, the variable PERSON has the structure /STUDENT/, so:
The VIRTUAL statement is treated the same as
the DIMENSION statement.
VIRTUAL a ( d ) [, a ( d ) ] ... | |
a | Name of an array |
a(d) | Specifies the dimension of the array. It is a list of 1 to 7 declarators separated by commas |
The VIRTUAL statement has the same form and effect as the DIMENSION statement. It is included for compatibility with older versions of FORTRAN.
VIRTUAL M(4,4), V(1000) ... END |
The VOLATILE statement prevents optimization
on the specified items.
VOLATILE nlist | |
nlist | List of variables, arrays, or common blocks |
The VOLATILE statement prevents optimization on the items in the list. Programs relying on it are usually nonportable.
Example: VOLATILE:
PROGRAM FFT INTEGER NODE*2, NSTEPS*2 REAL DELTA, MAT(10,10), V(1000), X, Z COMMON /INI/ NODE, DELTA, V ... VOLATILE V, Z, MAT, /INI/ ... EQUIVALENCE ( X, V ) ... |
The WRITE statement writes data from the list to a file.
Note - For tape I/O, use the
TOPEN()
routines.
The options can be specified in any order.
An alternate for the REC=rn form is allowed, as
follows:
WRITE( u ' rn ... ) iolist
![]() |
See Example 3, later on in this section.
u is either an external unit identifier or an internal file identifier.
An external unit identifier must be one of the following:If the optional characters UNIT= are omitted from the unit specifier, then u must be the first item in the list of specifiers.
f
is a format identifier and can be:If the optional characters, FMT=, are omitted from the format specifier, then f must appear as the second argument for a formatted write; otherwise, it must not appear at all.
f must not be an asterisk for direct access. f can be an asterisk for internal files.ios
must be an integer variable, integer array element, or integer record field.rn
must be a positive integer expression. This argument can appear only for direct-access files. rn can be specified for internal files.s
must be the label of an executable statement in the same program unit in which this WRITE statement occurs.iolist
can be empty, or it can contain output items or implied DO lists. The output items must be one of the following:A simple unsubscripted array name specifies all of the elements of the array in memory storage order, with the leftmost subscript increasing more rapidly.
If the output item is a character expression that employs the concatenation operator, the length specifiers of its operands can be an asterisk (*). This rule is nonstandard.The second form of WRITE is used to output the items of the specified namelist group. Here, grname is the name of the list previously defined in a NAMELIST statement.
Execution proceeds as follows:
Note these restrictions:
WRITE(*,*) x, f(x) ! Not allowed, f() does I/O. END FUNCTION F(X) WRITE(*,*) X RETURN END |
If u specifies an external unit that is not connected to a file, an implicit OPEN
operation is performed that is equivalent to opening the file with the following options:
OPEN( u, FILE='FORT.u', STATUS='UNKNOWN', & ACCESS='SEQUENTIAL', FORM=fmt ) |
The value of fmt is 'FORMATTED' if the write is formatted, and 'UNFORMATTED' otherwise.
The record number for direct-access files starts from one onwards.
Namelist-directed output is permitted on sequential access files only.
Example 1: Formatted write with trap I/O errors and I/O status:
WRITE( 1, 2, ERR=8, IOSTAT=N ) X, Y RETURN ... 8 WRITE( *, * ) 'I/O error # ', N, ', on 1' STOP END |
Example 2: Direct, unformatted write, trap I/O errors, and I/O status:
... WRITE( 1, REC=3, IOSTAT=N, ERR=8 ) V ... 4 CONTINUE RETURN 8 WRITE( *, * ) 'I/O error # ', N, ', on 1' END |
Example 3: Direct, alternate syntax (equivalent to above example):
... WRITE( 1 ' 3, IOSTAT=N, ERR=8 ) V ... 4 CONTINUE RETURN 8 WRITE( *, * ) 'I/O error # ', N, ', on 1' END |
Example 4: List-directed write to screen:
WRITE( *, * ) A, V or PRINT *, A, V |
Example 5: Formatted write to an internal file:
CHARACTER CA*16, L*8 /'abcdefgh'/, R*8 /'ijklmnop'/ WRITE( CA, 1 ) L, R 1 FORMAT( 2 A8 ) |
Example 6: Write an entire array:
DIMENSION V(5) WRITE( 3, '(5F4.1)') V |
Example 7: Namelist-directed write:.
CHARACTER SAMPLE*16 LOGICAL NEW*4 REAL DELTA*4 NAMELIST /G/ SAMPLE, NEW, DELTA ... WRITE( 1, G ) or WRITE( UNIT=1, NML=G ) or WRITE( 1, NML=G ) |