next up previous contents
Next: Common Blocks Up: Professional Programmer's Guide to Previous: Input/Output Facilities

DATA Statement

The DATA statement is used to specify initial values for variables and array elements. The DATA statement is non-executable, but in a main program unit it has the same effect as a set of assignment statements at the very beginning of the program. Thus in a main program a DATA statement like this:

 
       DATA LINES/625/, FREQ/50.0/, NAME/'PAL'/

could replace several assignment statements:

 
       LINES = 625 
       FREQ  = 50.0 
       NAME  = 'PAL'

This is more convenient, especially when initialising arrays, and efficient, since the work is done when the program is loaded.

In a procedure, however, these two methods are not equivalent, especially in the case of items which are modified as the procedure executes. A DATA statement only sets the values once at the start of execution, whereas assignment statements will do so every time the procedure is called.

It is important to distinguish between the DATA and PARAMETER statements. The DATA statement merely specifies an initial value for a variable (or array) which may be altered during the course of execution. The PARAMETER statement specifies values for constants which cannot be changed without recompiling the program. If, however, you need an array of constants, for which there is no direct support in Fortran, you should use an ordinary array with a DATA statement to initialise its elements (and take care not to corrupt the contents afterwards).

Defined and Undefined Values

The value of each variable and array element is undefined at the start of execution unless it has been initialised with a DATA statement. An undefined value may only be used in executable statements in ways which cause it to become defined. An item can become defined by its use in any of the following ways:

An undefined variable must not be used in any other way. Errors caused by the inadvertent use of undefined values are easy to make and sometimes have very obscure effects. It is important, therefore, to identify every item which needs to be initialised and provide a suitable set of DATA statements.

Modern operating systems often clear the area of memory into which they load a program to prevent unauthorized access to the data used in the preceding job. A few operating systems preset their memory to a bit-pattern which corresponds to an illegal numerical value: this is a very helpful diagnostic facility since whenever an undefined variable is used in an expression it generates an error at run time. Other systems merely set their memory to zero: this makes it more difficult to track down the use of indefined variables and they may only come to light when a program is transported to another system. To rely on undefined variables and arrays having an initial value of zero is to leave the program completely at the mercy of changes to the operating system.

Initialising Variables

The simplest form of the DATA statement consists of a list of the variable names each followed by a constant enclosed in a pair of slashes:

 
       DOUBLE PRECISION EPOCH 
       LOGICAL OPENED 
       CHARACTER INFILE*20 
       DATA EPOCH/1950.0D0/, OPENED/.TRUE./, INFILE/'B:OBS.DAT'/

Note that DATA statements must follow all specification statements. An alternative form is to give a complete list of names can be given first and followed by a separate list of constants:

 
      DATA EPOCH, OPENED, INFILE / 1950.0D0, .TRUE., 'B:OBS.DAT'/

When there are many items to be initialised it is a matter of taste whether to use several DATA statements or to use one with many continuation lines. It is, of course, illegal to have the same name appearing twice.

Character variables can be initialised in sections using the substring notation if this is more convenient:

 
\begin{verbatim} 
      CHARACTER*52 LETTER 
      DATA LETTER(1:26)/'ABCDEFGHIJKLMNOPQRSTUVWXYZ'/, 
     $     LETTER(27:) /'abcdefghijklmnopqrstuvwxyz'/

If the length of the character constant differs from that of the variable then the string is truncated or padded with blanks as in an assignment statement. The type conversion rules of assignment statements also apply to arithmetic items in DATA statements.

Initialising Arrays

There are several ways of using DATA statements to initialise arrays, all of them simpler and more efficient than the equivalent set of DO-loops. Perhaps the most common requirement is to initialise all the elements of an array: in this case the array name can appear without subscripts. If several of the elements are to have the same initial value a repeat count can be precede any constant:

 
       REAL FLUX(1000) 
       DATA FLUX / 512*0.0, 488*-1.0 /

The total number of constants must equal the number of array elements. The constants correspond to the elements in the array in the normal storage sequence, that is with the first subscript varying most rapidly.

Named constants are permitted, but not constant expressions. The repeat count may be a literal or named integer constant. To initialise a multi-dimensional array with parameterised array bounds it is necessary to define another integer constant to hold the total number of elements:

 
       PARAMETER (NX = 800, NY = 360, NTOTAL = NX * NY) 
       DOUBLE PRECISION SCREEN(NX,NY), ZERO 
       PARAMETER (ZERO = 0.0D0) 
       DATA SCREEN / NTOTAL * ZERO /

If only a few array elements are to be initialised they can be listed individually:

 
       REAL SPARSE(50,50) 
       DATA SPARSE(1,1), SPARSE(50,50) / 1.0, 99.99999 /

The third, and most complicated, option is to use an implied-DO loop. This operates in much the same way as an implied-DO in an I/O statement:

 
       INTEGER ODD(10) 
       DATA (ODD(I),I=1,10,2)/ 5 * 43/ 
       DATA (ODD(I),I=2,10,2)/ 5 * 0 /

This example has initialised all the odd numbered elements to one value and all the even numbered elements to another. Note that the loop control variable (I in this example) has a scope which does not extend outside the section of the DATA statement in which it is used. Any integer variable may be used as a loop control index in a DATA statement without effects elsewhere; the value of I itself is not defined by these statements.

When initialising part of a multi-dimensional array it may occasionally be useful to nest DO-loops like this:

 
       DOUBLE PRECISION FIELD(5,5) 
       DATA ((FIELD(I,J),I=1,J), J=1,5) / 15 * -1.0D0 /

This specifies initial values only for the upper triangle of the square array FIELD.

DATA Statements in Procedures

In procedures, DATA statements perform a role for which assignment statements are no substitute. It is quite often necessary to arrange for some action to be carried out at the start of the first call but not subsequently, such as opening a file or initialising a variable or array which accumulates information during subsequent calls.

If information is preserved in a local variable or array from one invocation to another a SAVE statement (described in section 9.11) is also needed. Indeed, in general any object initialised in a DATA statement in a procedure also needs to be named in a SAVE statement unless its value is never altered.

In the next example the procedure opens a data file on its first call, using a logical variable OPENED to remember the state of the file.

 
       SUBROUTINE LOOKUP(INDEX, RECORD)  
       INTEGER INDEX 
       REAL  RECORD 
       LOGICAL OPENED  
       SAVE OPENED 
       DATA OPENED / .FALSE. /  
*On first call OPENED is false so open the file. 
       IF(.NOT. OPENED) THEN 
            OPEN(UNIT=57, FILE='HIDDEN.DAT', STATUS='OLD', 
     $            ACCESS='DIRECT', RECL=100) 
            OPENED = .TRUE. 
       END IF 
       READ(UNIT=57, REC=INDEX) RECORD 
       END

Here, for simplicity, the I/O unit number is a literal constant. The procedure would be more modular if the unit number were also an argument of the procedure or if it contained some code, using the INQUIRE statement, to determine for itself a suitable unused unit number.

There is, of course, no corresponding way to determine which is the last call to the procedure so that the file can be closed, but this is not strictly necessary as the Fortran system closes all files automatically when the program exits.

Note that DATA statements cannot be used to initialise variables or arrays which are dummy arguments of a procedure, nor the variable which has the same name as the function.

General Rules

The general form of the DATA statement is:
DATA nlist / clist /, nlist / clist /, ...
Where nlist is a list of variable names, array names, substring names, and implied-DO lists, and clist is a list of items which may be literal or named constants or either of these preceded by a repeat-count and an asterisk. The repeat-count can also be an unsigned integer constant or named constant.

The comma which precedes each list of names except the first is optional. An implied-DO list has the general form:
( dlist, intvar = start, limit, step )
Where em dlist is a list of implied-DO lists and array elements; intvar is an integer variable called the loop-control variable; start, limit, and step are integer expressions in which all the operands must be integer constants or loop-control variables of outer implied-DO lists.

DATA statements cannot be used to initialise items in the blank common block; items in named common blocks can only be initialised within a BLOCK DATA program unit (see section 12.4).

The DATA statements in each program unit must follow all specification statements but they can be interspersed with executable statements and statement function statements. It is, however, best to follow the usual practice of putting all DATA statements before any of the executable statements.


next up previous contents
Next: Common Blocks Up: Professional Programmer's Guide to Previous: Input/Output Facilities

Clive Page
Tue Feb 27 11:14:41 GMT 2001