CHAPTER 8
SUBSCRIPTED VARIABLES
In Chapter 5 we learned how to assign values to variables,
but we could assign only one value per variable.
A variable which can take only one value is referred to as an
unsubscripted or scalar variable. So far, we have worked
only with scalar variables.
Often there is a need to assign more than one value per
variable, i.e., to connect a group or "array" of values with
one variable name. A variable which can take an array of
values is referred to as a subscripted variable. Arrays can
be of one dimension (a vector), two dimensions (a matrix),
or multidimensional (a multidimensional matrix, limited to
a maximum of seven dimensions).
In Chapter 3 we learned how to use declaration state
ments to specify variable types (integer, real, complex, and
so on). In this chapter we learn how to use the DIMENSION
statement to specify the name and size of subscripted variables. The size of a subscripted variable refers
to the number of values it can store for later reference.
When the program includes many subscripted variaables and corresponding DIMENSION statements, the
PARAMETER statement may be used to list a common
variable size as a program parameter (see Section 8.2).
Input/output of subscripted variables is accomplished
with the implied DO list, which combines the features of
a DO loop and a READ/WRITE. When program units include subscripted variables, array specification is accomplished with DIMENSION statements (Section 8.1), their
input/output with implied DO lists (Section 8.4), and their
manipulation with one or more single or nested DO loops
(Section 7.1).
8.1 ARRAY SPECIFICATION
The specification block is a block of nonexecutable state
ments which is placed immediately after the PROGRAM
statement and before all executable statements in a program unit (see Table 1.1).
The specification block contains the usual declaration
statements (INTEGER, REAL, COMPLEX, DOUBLE
PRECISION, LOGICAL, and CHARACTER) and all
other specification statements, including IMPLICIT (Section 11.6), PARAMETER and DIMENSION. INTEGER
and REAL arrays may be declared implicitly or explicitly
(see Chapter 3). As before, DOUBLE PRECISION,
LOGICAL, and CHARACTER arrays may only be declared explicitly.
Specification of Integer or Real Arrays
that Are Declared Implicitly
The DIMENSION statement is used to specify arrays
of integer or real type that are declared implicitly. The
DIMENSION statement defines:
- The array's name.
- Its number of dimensions, and
- The number of elements in each one of its dimensions,
and by extension, the total number of elements (values)
it can hold.
The following examples illustrate the DIMENSION
statement:
DIMENSION ITEM(10),A(3,5)
DIMENSION VELOCITY(10,20,5)
In the first example, ITEM(10) defines
In the same example, A(3,5) defines
- a real subscripted variable or array named A,
- the dimension of the array: two dimensions, since two
numbers are listed within the parentheses, separated by
a comma, and
- the number of elements or values that the array can hold
(3 rows × 5 columns, making a total of 15 values).
|___ |___ |___ |___ |___
|___ |___ |___ |___ |___
|___ |___ |___ |___ |___
In the second example, VELOCITY(10,20,5)
defines
- a real subscripted variable or array named VELOCITY,
- the dimension of the array: three dimensions, since
three numbers are listed within the parentheses, separated by commas, and
- the number of elements or values that the array can hold
(10 rows × 20 columns × 5 layers, making a total of
1000 values).
A program unit may have as many DIMENSION statements as is necessary to properly specify all subscripted
variables. However, several arrays may be listed in one
DIMENSION statement. Thus, within one program unit,
subcripted variables may be specified either (1) in one
long DIMENSION statement, using column 6 for continuation, or (2) in several short DIMENSION statements,
avoiding the use of column 6. The decision of whether to
have one long or several short DIMENSION statements is
one of individual preference.
Specification of Integer or Real Arrays
that are Declared Explicitly
The specification of arrays of integer or real type that are
declared explicitly is accomplished in either of the following ways:
- Using a declaration statement (INTEGER or REAL) to
declare the variable type, and a DIMENSION statement
to size the subscripted variable, or
- Using a declaration statement (INTEGER or REAL) to
declare and size the subscripted variable, therefore
eliminating the need for a DIMENSION statement.
The first case is illustrated below.
INTEGER TEST
REAL LENGTH
DIMENSION TEST(10),LENGTH(10,3)
In these statements, TEST and LENGTH are explicitly
declared as integer and real variables, respectively, and
they are specified as one- and two-dimensional arrays, respectively, by the DIMENSION statement.
The second case is the following:
INTEGER TEST(10)
REAL LENGTH(10,3)
In these statements, TEST and LENGTH are explicitly
declared as integer and real variables, and specified in the
declaration statement as one- and two-dimensional arrays,
respectively. Both of these cases are equivalent.
Note that a subscripted variable may be specified only
once in a program unit. Therefore, the following set of
statements will cause an error during compilation, because
the size of the array TEST has been defined twice.
INTEGER TEST(10)
REAL LENGTH
DIMENSION TEST(10),LENGTH(10,3)
Arrays of Logical and Character Type
The specification of arrays of logical or character type is
accomplished with the LOGICAL or CHARACTER state
ments, respectively, as illustrated by the following examples:
LOGICAL SWITCH(10)
CHARACTER*15 NAME(12),SSNO(12)*11
In these examples:
- SWITCH is the name of a one-dimensional logical array
which can store up to 10 values (either .TRUE. or
.FALSE.);
- NAME is the name of a one-dimensional character array
of 15-character maximum length, which can store up to
12 values; and
- SSNO is the name of a one-dimensional character array
of 11-character maximum length, which can store up to
12 values.
Lower and Upper Bounds of Arrays
Arrays have lower and upper bounds. The lower bound of
a one-dimensional array is the subscript number of its first
(base) element; the upper bound is the subscript of its last
element.
The array bounds are specified in the DIMENSION or
declaration (INTEGER or REAL) statements.
For example, in
DIMENSION A(1:10)
the lower bound is 1 and the upper bound is 10. This array
can hold up to 10 elements or values, subscripted from 1 to
10.
As another example, in
DIMENSION A(0:20)
the lower bound is 0 and the upper bound is 20. This array
can hold up to 21 elements, subcripted from 0 to 20. If the lower bound is equal to 1, it can be omitted. For
instance, in
DIMENSION A(30)
the lower bound is 1 and the upper bound is 30. This array
can hold up to 30 elements, subscripted from 1 to 30.
As another example, in
DIMENSION A(-10:10),B(-5:25)
the lower bound of array A is -10, and the upper bound is
+10. This array can hold up to 21 values, subcripted from
-10 to +10, including 0. Likewise, array B can hold up to
31 values, subscripted from -5 to +25, including 0.
Another example is:
DIMENSION C(0:10,0:5)
Array C is a two-dimensional array. It can hold 11
rows, subscripted from 0 to 10, and 6 columns, subscripted
from 0 to 5, for a total of 11 × 6 = 66 values.
8.2 PARAMETER STATEMENT
The PARAMETER statement is a nonexecutable statement
placed within the specification block, i.e., on top of the
program unit (see Table 1.1). It is an important statement
because it is used to permanently associate a variable
name (to be taken as a program parameter) with a constant
or with a constant arising from the execution of a constant
expression. The PARAMETER statement takes the form:
PARAMETER (p1=c1, p2=c2, p3=c3,...)
where p1, p2, and p3 are parameters, and c1, c2, and c3
are constants or constant expressions. The parentheses en
closing the parameter list are required in standard Fortran;
however, they may be optional in some extensions.
An example of a PARAMETER statement is:
PARAMETER (PI=3.1416)
Adhere to the following guidelines:
- The data type of a parameter is determined either by an
explicit type declaration (using INTEGER or REAL
statements) or by following the rules for implicit type
declaration (i.e., variables starting with I, J, K, L, M,
and N are integers; otherwise, they are real).
- A parameter may be defined only by a PARAMETER
statement, and only once in a program unit. It cannot be
redefined, i.e., assigned a new value, elsewhere in the
program unit.
- Once defined in a PARAMETER statement, a parameter
can be referenced anywhere in a program unit, except in
FORMAT statements. However, some Fortran exten
sions allow the use of parameters in FORMAT state
ments.
- A parameter may be used as a length specifier in a
CHARACTER statement, but only provided it is en
closed in parentheses. For example, in:
CHARACTER*(NC) ALPHA
the character variable ALPHA has a maximum length of
NC characters. The value of NC should be defined in
the specification block, prior to the appearance of this
statement (see next Section).
8.3 SEQUENCE OF STATEMENTS
IN SPECIFICATION BLOCK
The required sequence of statements in the specification
block is that which assures that all variable types are declared and all parameters are defined prior to their usage
within the block. If this does not occur, errors will result
during compilation or execution. For example:
LOGICAL FLAG
PARAMETER (FLAG=.TRUE.)
PARAMETER (NC=10)
CHARACTER*(NC) ALPHA10
PARAMETER (ALPHA10='ABCDEFGHIJ')
PARAMETER (EX=2.71828,PI=3.1416)
PARAMETER (PIO2=PI/2)
As shown above:
- The declaration of variable FLAG as logical type precedes the definition of FLAG as a logical parameter.
- The parameter NC is defined prior to its usage as a
length specifier in the CHARACTER statement that follows.
- The declaration of variable ALPHA10 as character type
precedes the definition of ALPHA10 as a character parameter.
- The parameter PI is properly defined prior to its usage
in the constant expression of the PARAMETER statement that follows.
Alternatively, the specification block shown above can
be written as follows:
LOGICAL FLAG
CHARACTER*(*) ALPHA10
PARAMETER (FLAG=.TRUE.)
PARAMETER (ALPHA10='ABCDEFGHIJ')
PARAMETER (EX=2.71828,PI=3.1416)
PARAMETER (PIO2=PI/2)
In this example, the asterisk * has been used as a free
length specifier in place of the parameter NC in the
CHARACTER statement. This eliminates the need for
prior definition of the parameter NC.
Sizing DIMENSION Statements with Parameters
The PARAMETER statement can be used to conveniently
size one or more DIMENSION statements. This is particularly useful when many arrays have the same size, as shown in the set of statements that follow:
PARAMETER (NR=10,NC=20,NL=5)
DIMENSION A(NR),B(NR),C(NR),D(NR)
DIMENSION XX(NR,NC),YY(NR,NC)
DIMENSION ZZ(NR,NC,NL)
In this example, a change in parameter will cause an
automatic and corresponding adjustment in one or more
DIMENSION statements. The defining PARAMETER
statement must precede the DIMENSION statement that
references the parameter.
8.4 INPUT/OUTPUT OF ARRAYS
Often, arrays are read from an input file or written to an
output file. This input/output is usually performed with an
implied DO list.
An implied DO list is a combination of a DO loop and
a READ or WRITE in one statement. Using implied DO
lists, array input/output can be accomplished by either
- Using one or more implied DO lists, or
- Combining an implied DO list with an explicit DO loop.
The choice between these is one of individual preference.
Rules governing the interaction between: (1) implied
DO lists, (2) combined implied DO list and explicit DO
loop, and (3) formatted and unformatted input/output are
discussed below.
Implied DO Lists in READ/WRITE Statements
The following examples illustrate the usage of the implied
DO list.
Example 1
READ(5,10) (A(J),J=1,10)
WRITE(6,20) (B(J),C(J),J=1,20)
READ(5,30) ((D(J,K),E(J,K),J=1,10),K=1,5)
WRITE(6,40)(((F(J,K,L),J=1,8),K=1,5),L=1,3)
The J in A(J),J=1,10 is the control variable of the
DO loop (see Section 7.1). Likewise, the K and L are
control variables of nested DO loops.
Note the required syntax of implied DO lists:
- The implied DO lists are enclosed within parentheses,
and follow the respective READ or WRITE statement.
- One-dimensional arrays are enclosed within one set of
parentheses; two-dimensional arrays within two sets;
and so on.
- The commas between and immediately following the
variable lists are required.
In this example, the first statement reads 10 values of
one-dimensional array A. The second statement writes 20
pairs of values of one-dimensional arrays B and C. The
third statement reads 10 × 5 = 50 pairs of values of two-
dimensional arrays D and E. The fourth statement writes
8 × 5 × 3 = 120 values of three-dimensional array F.
The format statements have not been included.
Example 2
WRITE(6,100) (B(J),C(J),J=2,20,2)
READ(5,200) ((D(J,1),E(J,1),J=1,10)
WRITE(6,300) ((F(J,K,1),J=1,8),K=1,5)
The first statement writes 10 even values of one-
dimensional arrays B and C. The second statement reads
10 pairs of values of two-dimensional arrays D and E (a
total of 20 values) and assigns them to the first column of
the respective arrays. The third statement writes 8 × 5 =
40 values of three-dimensional array F and assigns them to
the first layer (the third dimension) of the array. Again, the
format statements have not been included.
Example 3
DIMENSION A(8)
READ(5,400) (A(J),J=1,5)
400 FORMAT(5F10.2)
The array A has 8 elements; the first 5 elements are being read,
five to a record, following format 400.
Example 4
In the special case when all the elements of the array
are being read (or written in the case of output), the implied DO list of Example 3 can be simplified as follows:
DIMENSION A(8)
READ(5,500) A
500 FORMAT(8F10.2)
Example 5
DIMENSION B(10,20)
READ(5,600) ((B(J,K),J=1,10),K=1,20)
600 FORMAT(10F8.2)
In this example, the two-dimensional array B contains
10 × 20 = 200 elements, all of which are being read.
Input/output of two-dimensional arrays can be accom
plished in either: (1) column order, or (2) row order. In
Example 5, matrix B is being read in column order, i.e.,
first, column K = 1 is read, with J varying from 1 to 10;
then, column K = 2 is read, with J varying from 1 to 10;
and so on, until the last column (K = 20) is read.
Example 6
DIMENSION B(10,20)
READ(5,600) ((B(J,K),K=1,20),J=1,10)
600 FORMAT(10F8.2)
This is the same as Example 5, but with matrix B being
read in row order, i.e., first, row J= 1 is read, with K vary
ing from 1 to 20; then, row J= 2 is read, with K varying
from 1 to 20; and so on, until the last row (J= 10) is read.
Example 7
DIMENSION B(10,20)
READ(5,600) B
600 FORMAT(10F8.2)
This example should be compared with Examples 5
and 6 above. The implied DO list has been shortened to
contain only the name of the array (B). In this case, the
processor expects to read the entire array (10 rows by 20
columns, i.e., 200 values), and the data must be arranged
by the programmer and read in column order.
Combined Implied DO Lists with Explicit DO Loops
Implied DO lists of arrays of two or more dimensions can
be written by combining an implied DO list with one or
more explicit DO loops.
For instance, compare the implied DO list
READ(5,100) ((D(J,K),E(J,K),J=1,5),K=1,15)
100 FORMAT(10F8.2)
with the combined implied DO list and explicit DO loop:
DO K= 1,15
READ(5,100) (D(J,K),E(J,K),J=1,5)
END DO
100 FORMAT(10F8.2)
The two forms accomplish the same task of reading 15
records, each containing 5 pairs (10 values).
As another example, compare the implied DO list
WRITE(6,200)(((F(J,K,L),J=1,8),K=1,5),L=1,3)
with the combined implied DO list and explicit DO loop:
DO L= 1,3
WRITE(6,200) ((F(J,K,L),J=1,8),K=1,5)
END DO
or, alternatively, with the combined implied DO list and
two explicit DO loops:
DO L= 1,3
DO K= 1,5
WRITE(6,200) (F(J,K,L),J=1,8)
END DO
END DO
The three forms may accomplish the task, depending
on the nature of the list-to-format interaction (see following section).
8.5 LIST-TO-FORMAT INTERACTION
The implied DO lists interact with formatted or unformatted input/output. There are four areas of interaction:
- Implied DO lists with FORMAT statements.
- Implied DO lists with unformatted READ and WRITE.
- Combined implied DO lists and explicit DO loops with
FORMAT statements.
- Combined implied DO lists and explicit DO loops with
unformatted READ and WRITE.
Interaction of Implied DO Lists with FORMAT
Statements
The interaction of implied DO lists with FORMAT statements follows rules similar to those applicable to input/output of variable lists (Section 6.3). The implied DO
list retains control, and it executes the transfer of a number
of data items equal to the number of subscripted variables
on the list, multiplied by the number of values to read or
write per variable. For example,
READ(5,100) (A(J),B(J),J=1,10)
will read two variables (A and B), 10 values per variable,
for a total of 20 values transferred.
WRITE(6,200) ((C(J,1),D(J,1),J=1,15)
will write two variables (C and D), 15 values per variable,
for a total of 30 values transferred.
READ(5,300) ((F(J,K,1),J=1,5),K=1,8)
will read one variable (F), in 5 rows, 8 columns, and 1
layer, for a total of 40 values transferred.
In each of the above examples, the implied DO list interacts with its format as one READ/WRITE statement.
Therefore, the format is referenced only once to transfer
the entire DO list.
Note the following:
If the field descriptor list is longer than the implied DO
list, the latter takes precedence: the processor uses,
from left to right, only as many fields as needed to accomplish the transfer of all items listed on the implied
DO list.
If the field descriptor list is shorter than the implied DO
list, the processor treats the format specification as typical, and repeats it as many times as needed to accomplish
the transfer of all items on the implied DO list.
During repeated execution of the field descriptor list,
the processor ignores any remaining unused fields.
Example 1
READ(5,100) (A(J),J=1,10)
100 FORMAT(10F8.2)
The implied DO list has 10 values of array A, and it is
connected to format 100, whose field descriptor specifies
10 real fields of 8 characters each. The number of values
in the implied DO list (10) exactly matches the number of
fields specified in the format (10). Ten real values of array
A will be read under the specified format.
Example 2
READ(5,200) (B(J),J=1,5)
200 FORMAT(8F10.2)
The implied DO list has 5 values of array B, and it is
connected to format 200, whose field descriptor specifies 8
real fields of 10 characters each. The field descriptor list is
longer than the implied DO list. Therefore, 5 real values of
array B will be read under the specified format. The remaining unused three fields (8 - 5 = 3) will be ignored.
Example 3
READ(5,300) (C(J),J=1,20)
300 FORMAT(10F8.2)
The implied DO list has 20 values of array C, and it is
connected to format 300, whose field descriptor specifies
10 real fields of 8 characters each. The field descriptor is
shorter than the implied DO list; therefore, the format is
interpreted as typical. Twenty real values of array C will
be read under the specified format, ten in each of two data
records.
Example 4
WRITE(6,400) (D(K),E(K),K=1,120)
400 FORMAT(1X,12F10.0)
The implied DO list has two variables (arrays D and
E), and 120 values per variable, for a total of 240 paired
values. It is connected to format 400, whose field descrip
tor specifies 12 real fields of 10 characters each. The field
descriptor list is shorter than the implied DO list; there
fore, the format is interpreted as typical. One-hundred-
and-twenty pairs of real values of arrays D and E will be
written under the specified format, six pairs per record, for
a total of twenty records.
Example 5
WRITE(6,500)((F(J,K,1),J=1,8),K=1,4)
500 FORMAT(1X,8E15.6)
The implied DO list has one three-dimensional variable
F, with 8 rows, 4 columns, and only 1 layer, for a total of
32 values. It is connected to format 500, whose field descriptor specifies 8 real E fields of 15 characters each. The
field descriptor is shorter than the implied DO list; therefore, the format is interpreted as typical. Thirty-two values of real three-dimensional array F will be written under
the specified format, eight values per record, for a total of
four records. The first record contains all J values for K=
1; the second all J values for K= 2; and so on.
Example 6
WRITE(6,500)((F(J,K,1),J=1,4),K=1,8)
500 FORMAT(1X,8E15.6)
This example is similar to Example 5. The field descriptor list is shorter than the implied DO list; therefore,
the format is interpreted as typical. Thirty-two values of
real three-dimensional array F will be written, 8 values per
record, for a total of 4 records. However, unlike Example
5, the first record contains all J values for K= 1, followed
by all J values for K= 2; the second record contains all J
values for K= 3, followed by all J values for K= 4; and so
on.
Example 7
WRITE(6,510)((F(J,K,1),J=1,4),K=1,8)
510 FORMAT(1X,E15.6)
This example is similar to Examples 5 and 6, except
that the format specification contains only one field descriptor (E15.6). The field descriptor list is shorter than the
implied DO list; therefore, the format is interpreted as
typical. Thirty-two values of real three-dimensional array
F will be written, one per record, for a total of thirty-two
records. The first record contains the value for J= 1 and
K= 1; the second for J= 2 and K= 1; the third for J= 3 and
K=1; and so on.
Interaction of Implied DO Lists with Unformatted
READ and WRITE
The interaction of implied DO lists with unformatted
READ and WRITE follows rules similar to those applicable to input/output of variable lists (Section 6.3). Control
remains with the implied DO list, which executes the
transfer of a number of data items equal to the number of
subscripted variables on the list, multiplied by the number
of values to read or write per variable.
For example,
READ(5,*) (A(J),B(J),J=1,15)
will read two variables (A and B), 15 values per variable,
for a total of 15 pairs = 30 values transferred, in free format (see Section 2.5 for unformatted input/output rules).
The processor will read as many records as needed to accomplish the transfer of 30 values. At least one record
will be read. In this case, it is likely that several records
will be read.
Likewise, the following example
WRITE(6,*) ((C(J,K),J=1,4),K=1,8)
will write a two-dimensional matrix (C), of 4 rows by 8
columns, for a total of 32 values transferred, in free format. The processor will write as many records as needed
to accomplish the transfer of 32 values. Assuming that the
processor writes five values per record under free format,
this example will write seven records, the first six with
five values each, and the last one with the two remaining
values.
Writing arrays in free format may change the character
of the array (visually confuse rows and columns) and,
therefore, is not recommended. Arrays, particularly two-
and three-dimensional arrays, should always be written
following a format.
Interaction of Combined Implied DO Lists and
Explicit DO Loops with FORMAT Statements
The interaction of combined implied DO lists and explicit
DO loops with FORMAT statements follows rules similar
to those applicable to that of implied DO lists with FORMAT statements. Control remains with the implied DO
list, which executes the transfer of a number of data items
equal to the number of subscripted variables on the list,
multiplied by the number of values to read or write per
variable.
There is, however, one important difference. Unlike the
implied DO list, which interacts with the FORMAT as one
statement, the combined implied DO list and explicit DO
loops interact with the FORMAT as two or more state
ments. This is because the FORMAT is referenced as
many times as required by the explicit DO loops.
Example 1
DO K= 1,4
READ(5,100) (A(J,K),J=1,8)
END DO
100 FORMAT(8F10.2)
The combined implied DO list and explicit DO loop
has one two-dimensional variable (A), of 8 rows by 4 columns, for a total of 8 × 4 = 32 values. The implied DO list
is connected to format 100, whose field descriptor specifies 8 real fields of 10 characters each. Notice that the
number of values in the implied DO list (8) matches exactly the number of fields specified in the format (8).
Eight real values of array A will be read with the implied DO loop under the specified format. The format will
be referenced four times by the explicit DO loop, transfer
ring 4 data records, 8 values per record, for a total of 4 X 8
= 32 values. The first record contains all eight J values for
K= 1; the second all eight J values for K= 2; and so on.
Example 2
DO K= 1,4
READ(5,200) (A(J,K),J=1,6)
END DO
200 FORMAT(8F10.2)
This is similar to Example 1, but the two-dimensional
variable A has 6 rows by 4 columns, for a total of 6 × 4 =
24 values. The implied DO list is connected to format
200, whose field descriptor specifies 8 real fields of 10
characters each. The number of values specified in the
format (8) is longer than the number of values in the implied DO list (6), which takes precedence.
Six real values of array A will be read in the first record under the specified format; the remaining two fields
will be ignored. The format will be referenced four times
by the explicit DO loop, transferring 4 data records, 6 values per record, for a total of 4 × 6 = 24 values. The first
record contains all six J values for K= 1; the second all six
J values for K= 2; and so on.
Example 3
DO K= 1,4
READ(5,300) (A(J,K),J=1,8)
END DO
300 FORMAT(4F10.2)
This is similar to Example 1, but uses a slightly different format. The implied DO list is connected to format
300, whose field descriptor specifies 4 real fields of 10
characters each. The number of values specified in the
format (4) is shorter than the number of values in the implied DO list (8); therefore, the format is interpreted as
typical.
Four real values of array A will be read with the implied DO loop in the first record, and the remaining four in
the second record. The format will be referenced four
times by the explicit DO loop, transferring 8 data records,
4 values per record, for a total of 8 × 4 = 32 values. The
first and second records contains all eight J values for K=
1; the third and fourth all eight J values for K= 2; and so
on.
Example 4
DO L= 1,2
DO K= 1,4
WRITE(6,400) (B(J,K,L),J=1,6)
END DO
END DO
400 FORMAT(1X,8F10.3)
The combined implied DO list and two nested explicit
DO loops have one three-dimensional variable (B), of 6
rows, 4 columns, and 2 layers, for a total of 6 × 4 × 2 = 48
values. The implied DO list is connected to format 400,
whose field descriptor specifies 8 real fields of 10 characters each. The number of values specified in the format
(8) is longer than the number of values in the implied DO
list (6), which takes precedence.
Six real values of array B will be written in the first record under the specified format; the remaining two fields
will be ignored. The format will be referenced 2 × 4 = 8
times by the nested DO loops, transferring 8 data records,
6 values per data record, for a total of 8 × 6 = 48 values.
The first record contains all six J values for K =1 and L =
1; the second all six J values for K= 2 and L= 1; and so on.
Example 5
DO L= 1,2
WRITE(6,500) ((B(J,K,L),J=1,6),K=1,4)
END DO
500 FORMAT(1X,8F10.3)
This is similar to Example 4, but uses only one explicit
DO loop instead of two. The implied DO list is connected
to format 500, whose field descriptor specifies 8 real fields
of 10 characters each. The number of values specified in
the format (8) is shorter than the number of values in the
implied DO list (6 × 4 = 24); therefore, the format is interpreted as typical.
The implied DO list will write twenty-four real values
of array B, eight values per record, making a total of three
records. The format will be referenced twice by the explicit DO loop, each time transferring 3 data records and 8
values per record, for a total of 2 × 3 × 8 = 48 values.
The first record contains all six J values for K = 1 and L =
1, and the first two J values for K = 2 and L = 1; the second record contains the remaining four values for K = 2
and L = 1, and the first four values for K = 3 and L = 1,
and so on.
This type of list-to-format interaction will change the
character of the array (visually confuse rows, columns, and
layers), and therefore, is not recommended. A better way
of writing array B is shown in the following example.
Example 6
DO L= 1,2
WRITE(6,600) ((B(J,K,L),J=1,6),K=1,4)
END DO
600 FORMAT(1X,6F10.3)
This differs from Example 5 in that it uses a slightly
different format. The implied DO list is connected to format 600, whose field descriptor specifies 6 real fields of
10 characters each. The number of values specified in the
format (6) is shorter than the number of values in the implied DO list (6 x 4 = 24); therefore, the format is interpreted as typical.
The implied DO list will write twenty-four real values
of array B, six values per record, for a total of four records. The format will be referenced twice by the explicit
DO loop, each time transferring 4 data records and 6 values per record, making a total of 2 × 4 × 6 = 48 values.
The first record contains all six J values for K= 1 and L=
1; the second contains all six J values for K= 2 and L= 1;
and so on. Unlike Example 5, this type of list-to-format
interaction does not alter the visual character of the array.
Interaction of Combined Implied DO Lists and Explicit
DO Loops with Unformatted READ and WRITE
The interaction of combined implied DO lists and explicit
DO loops with unformatted READ and WRITE follows
rules similar to those applicable to implied DO lists. As
before, control remains with the implied DO list, which
executes the transfer of a number of data items equal to the
number of subscripted variables on the list, multiplied by
the number of values to read or write per variable.
However, unlike the implied DO list, which interacts
with the free format as one statement, the combined implied DO list and explicit DO loops interact with the free
format as two or more statements.
Example 1
DO K= 1,4
READ(5,*) (A(J,K),J=1,8)
END DO
The combined implied DO list and explicit DO loop
has one two-dimensional variable, of 8 rows by 4 columns,
for a total of 8 × 4 = 32 values. Eight real values of array
A will be read by the implied DO loop in free format. The
free format will be referenced 4 times by the explicit DO
loop, transferring a total of 8 × 4 = 32 values. At least 4
records will be read. As many as 32 records could be
read (in case that there is only one value per record).
Example 2
DO 20 L= 1,2
DO 20 K= 1,4
WRITE(6,*) (B(J,K,L),J= 1,6)
END DO
END DO
The combined implied DO list and two nested explicit
DO loops have one three-dimensional variable (B), of 6
rows, 4 columns, and 2 layers, for a total of 6 × 4 × 2 = 48
values. Six real values of array B will be written by the
implied DO loop in free format. The free format will be
referenced 2 × 4 = 8 times by the nested DO loops, transferring at least 8 records, with up to 6 values per record,
for a total of 8 × 6 = 48 values. Each record is written into
at least one line. Remember that writing arrays in free format is not recommended because it may alter their appearance in an unpredictable manner.
Things to keep in mind with regard to
list-to-format interaction:
To avoid errors in input/output of arrays, try
to match the number of values in an implied
DO list with the field descriptor list specified
in the format.
For arrays of two or more dimensions,
you may find it easier to use a combined
implied DO list and explicit DO loop.
Always write arrays using a format.
|
8.6 IMPLIED DO LISTS IN DATA STATEMENTS
Often it is necessary to use DATA statements to provide
initial values of one or more arrays. For this purpose, the
implied DO list is included in a DATA statement, as illustrated by the following examples:
Example 1
DIMENSION A(10)
DATA (A(J),J= 1,5) /1.,4.,-3.,10.,25./
This example considers an array A of 10 elements.
The first 5 elements of the array are initialized in a DATA
statement using an implied DO list.
Example 2
DIMENSION A(5)
DATA (A(J),J= 1,5) /1.,4.,-3.,10.,25./
The array A has 5 elements. The entire array is initialized in a DATA statement using an implied DO list.
Example 3
DIMENSION A(5)
DATA A /1.,4.,-3.,10.,25./
This is similar to Example 2. Since the entire array is
being initialized, the reference to the implied DO list in the
DATA statement may be omitted.
Example 4
DIMENSION B(4,6)
DATA
*((B(J,K),K=1,3),J=1,2) /3.,4.,7.,2.,9.,-0.5/
The two-dimensional array B has 4 rows by 6 columns,
for a total of 4 × 6 = 24 values. Six (2 × 3 = 6) values of
the array are being initialized. Note that the array is being
initialized in row order, i.e., first, all K values of row J= 1,
second, all K values of row J= 2. The matrix B is stored as
follows:
column 1
column 2
column 3
row 1
3.
4.
7.
row 2
2.
9.
-0.5
|
Example 5
DIMENSION B(2,3)
DATA
*((B(J,K),K=1,3),J=1,2)/3.,4.,7.,2.,9.,-0.5/
This is similar to Example 4, with the difference that
the entire array is being initialized. As with Example 4,
the array is being initialized in row order, i.e., first, all K
values of row J= 1, second, all K values of row J= 2.
Example 6
DIMENSION B(2,3)
DATA
*(B(J,K),J=1,2),K=1,3)/3.,4.,7.,2.,9.,-0.5/
This is similar to Example 5, with the difference that
the array is being initialized in column order, i.e., first, all
J values of column K= 1; second, all J values of column
K= 2; third, all J values of column K= 3. The matrix B is
stored as follows:
column 1 column 2 column 3
row 1 3.
7.
9.
row 2 4.
2.
-0.5
|
Example 7
DIMENSION B(2,3)
DATA B /3.,4.,7.,2.,9.,-0.5/
This is the same as Example 6. The array has 6 values
(2 × 3), and the DATA statement lists 6 values, i.e., the
entire array is being initialized. In this case, the reference
to the implied DO list in the DATA statement may be
omitted.
If a DATA statement contains an array, and the implied
DO list is missing, the array is assumed to be in column
order, and is stored as such.
Example 8
DIMENSION C(5,12)
DATA C /60*1./
The entire array C, consisting of 5 × 12 = 60 values,
has been initialized with an implied DO list in a DATA
statement. A repeat counter 60, placed within the delimiting slashes and preceding the asterisk, is used to express
that all elements are being initialized with the value 1. As
with Example 7, the reference to the implied DO list has
been omitted.
Example 9
DIMENSION C(5,12)
DATA C /28*1.,32*0./
This is similar to Example 8. The array C consists of
5 × 12= 60 values. The entire array is being initialized
with an implied DO list. The reference to the implied DO
list has been omitted. A repeat counter is used to express
that the first 28 elements are being initialized with the
value 1., and the remaining 32 with the value 0.
The array C is stored in column order as shown below.
column no. 1 2 3 4 5 6 7 8 9 10 11 12
row 1 1. 1. 1. 1. 1. 1. 0. 0. 0. 0. 0. 0.
row 2 1. 1. 1. 1. 1. 1. 0. 0. 0. 0. 0. 0.
row 3 1. 1. 1. 1. 1. 1. 0. 0. 0. 0. 0. 0.
row 4 1. 1. 1. 1. 1. 0. 0. 0. 0. 0. 0. 0.
row 5 1. 1. 1. 1. 1. 0. 0. 0. 0. 0. 0. 0.
|
8.7 SORTING OF ARRAYS: THE BUBBLE SORT
When working with arrays, you may need to sort the entries to arrange them in a specific order. For instance, consider the following one-dimensional array A:
12. 45. 23. 87. 51. 20. 11.
To arrange it in ascending order, i.e., to produce
11. 12. 20. 23. 45. 51. 87.
a sorting procedure must be implemented. The bubble sort is a commonly used sorting procedure.
In a bubble sort, the values of two variables (addresses)
A(J) and A(J+1) are to be interchanged. First, a temporary
variable TEMP is created by assigning the value of A(J) to
TEMP. Second, the value of A(J+1) is assigned to A(J).
Third, the value of TEMP, i.e., the value of A(J), is assigned to A(J+1). This procedure effectively switches the
values of A(J) and A(J+1).
The following program implements a bubble sort for
the previous example.
Example Program: Bubble Sort
C234567890
PROGRAM BUBBLE_SORT
PARAMETER (N=7)
DIMENSION A(N)
OPEN(5,FILE='SORT.DAT',STATUS='UNKNOWN')
OPEN(6,FILE='SORT.OUT',STATUS='UNKNOWN')
READ(5,*) (A(J),J=1,N)
DO 20 K= 1,N-1
DO 10 J= 1,N-K
IF(A(J).GT.A(J+1)) THEN
TEMP= A(J)
A(J)= A(J+1)
A(J+1)= TEMP
ENDIF
10 END DO
20 END DO
WRITE(6,*) (A(J),J=1,N)
END
|
In this example program, each execution of the outer
loop positions the largest value to the right of the array.
Complete execution of the program sorts the array in ascending order.
8.8 EXAMPLE PROGRAM
Matrix Multiplication
This program reads an array A of 2 rows by 3 columns,
and an array B of 3 rows by 2 columns, and multiplies the
arrays to obtain C, of 2 rows by 2 columns. [Note that in
order to multiply A × B, the number of columns of A
(three rows) has to be equal to the number of rows of B
(three columns)]. Array C has the same number of rows as
A (two rows) and the same number of columns as B (two
columns).
Note the features of this program:
- PARAMETER and DIMENSION statements are used to
size the arrays A, B, and C.
- The outer two DO loops, with index J varying from 1 to
2, and index K varying from 1 to 2, generate an array C
of 2 rows by 2 columns.
- The inner loop, with index L varying from 1 to 3, gener
ates the four elements of array C.
- Each element of array C is equal to the sum of the prod
ucts of A(J,L) times B(L,K), where L varies from 1 to 3,
with 3 being the number of columns of A and the number of rows of B.
Example Program: Matrix Multiplication
C234567890
PROGRAM MATRIX_MULT
PARAMETER (MZ=2,NZ=3)
DIMENSION A(MZ,NZ),B(NZ,MZ),C(MZ,MZ)
DATA C/4*0./
READ(5,100)((A(J,K),K=1,NZ),J=1,MZ)
READ(5,110)((B(J,K),K=1,MZ),J=1,NZ)
DO 10 J= 1,MZ
DO 10 K= 1,MZ
DO 10 L= 1,NZ
C(J,K)= C(J,K) + A(J,L)*B(L,K)
10 END DO
WRITE(6,200) ((C(J,K),K=1,MZ),J=1,MZ)
100 FORMAT(3F5.0)
110 FORMAT(2F5.0)
200 FORMAT(1X,2F5.0)
END
|
The input arrays are:
A= 1. 2. 3. B= 7. 1.
4. 5. 6.
8. 2.
9. 3.
The output array is:
C= 50. 14.
122. 32.
For instance, the first row and column of the output
array C is: 1 × 7 + 2 × 8 + 3 × 9 = 7 + 16 + 27 = 50.
8.9 SUMMARY
This chapter describes subscripted variables, which can
take an array of values.
The name and size of a subscripted variable (the number of values it can take) is specified in a DIMENSION statement.
The specification of subscripted variables is made in the
specification block, a block of nonexecutable statements
which is placed immediately after the PROGRAM statement and before all executable statements.
Subscripted variables (arrays) can be of integer, real,
logical, or character type.
The PARAMETER statement specifies program parameters, which unlike variables, cannot be redefined
elsewhere in the program unit.
The PARAMETER statement helps in conveniently
setting up the specification block, particularly when
declaring many subscripted variables.
The implied DO list combines the features of DO and
READ/WRITE statements into one.
Implied DO lists can be combined with explicit DO
loops to accomplish the transfer of data in many ways,
both formatted and unformatted
The list-to-format interaction has the following rules:
If the format is longer than the list, the latter takes
precedence.
If the format is shorter than the list, the format is re
garded as typical, and repeated as many times as
needed to accomplish the transfer of the entire list.
Implied DO lists can also be used in conjunction with
DATA statements.
The bubble sort is a procedure to interchange the values
of subscripted variables.
CHAPTER 8--PROBLEMS
1. Solve Problem 4.5 (water utility billing) using formatted input/output,
subscripted variables, and two indexed DO loops, one to calculate the
values and another to print them.
2. Solve Problem 4.10 (electric utility billing) using formatted input/output, subscripted variables, and two indexed DO loops, one to cal
culate the values and another to print them.
3. Solve Problem 6.3 (natural log table) using subscripted variables. Use a
two-dimensional array, nested DO loops, and combined explicit DO
loops and implied DO lists.
4. Solve Problem 6.7 (table of hyperbolic sines) using using subscripted
variables. Use a two-dimensional array, nested DO loops, and combined explicit DO loops and implied DO lists.
5. Solve Problem 6.11 (radian-to-degree conversion table) using subscripted variables. Use two indexed DO loops, one to calculate the values and another to print them.
6. Solve Problem 7.12 (annuity table) using a one-dimensional array for
the annuity factor A/P.
7. Solve Problem 7.12 (annuity table) using a two-dimensional array for
the annuity factor A/P. Calculate and print the array in two separate DO
loops.
8. Solve Problem 7.19 using subscripted variables. Include the calculation
of the median, the value which divides the distribution into two equal
parts (half of the values are lower than the median).
9. Write a program to read a two-dimensional array of M rows by N columns, and to search for and report the entry having the minimum absolute value. Test your program with the following array:
11. 34. 67. -12. 23. 76. 12.
-10.5 43. 78. 112. -13. -12. 56.5
-120. 56. 23. 78. 90. 111. 90.1
10. Write a program to read a two-dimensional array of M rows by N columns, to sum all rows and all columns, and to report the row or column
with the minimum sum. As an example, the output should read:
ROW 3 HAS THE MINIMUM SUM, EQUAL TO 34.5. Test
your program with the input array of Problem 8.9.
11. Write a program to read from an input file a two-dimensional array of M
rows by N columns, to sort all rows in descending order, and print the
sorted array to an output file. Test your program with the input array of
Problem 8.9.
12. Write a program to read from an input file a two-dimensional array of M
rows by N columns, to sort all columns in ascending order, and print the
sorted array to an output file. Test your program with the input array of
Problem 8.9.
13. Write a program to read a square matrix of size N, and to calculate and
report the average of the entries in the outside rows and columns, and
the average of the inside entries. Test your program with the following
matrix:
10. 12. 13. 12. 15. 18.
11. 23. 21. 17. 13. 10.
12. 21. 10. 16. 12. 14.
12. 13. 14. 16. 12. 20.
10. 12. 14. 21. 22. 21.
15. 12. 13. 23. 21. 20.
14. Write a program to read a square matrix A of size N (for N even), and to
partition the matrix into four square submatrices each of size N/2. If N
is not even, print an appropriate message and stop execution. Calculate
and report a square matrix B, of size 2, with each entry being the average of all entries in each of the four square submatrices. Test your program with the input array of Problem 8.13.
10. 12. 13. 12. 15. 18.
11. 23. 21. 17. 13. 10.
12. 21. 10. 16. 12. 14.
12. 13. 14. 16. 12. 20.
10. 12. 14. 21. 22. 21.
15. 12. 13. 23. 21. 20.
15. Solve Problem 7.17 (numeral design) using subscripted variables.
16. Write a program to print the following numeric pattern:
0123456789
1012345678
2101234567
3210123456
4321012345
5432101234
6543210123
7654321012
8765432101
9876543210
Use subscripted variables, and a combined implied DO list and explicit
DO loop.
17. Write a program to calculate the parameters a, b, and c of the nonlinear
equation z= axbyc, given three data arrays x, y, and z, of n elements each.
Taking u= log x, v= log y, and w= log z, use the following regression
equations (Σ is the summation from 1 to n):
b= (AC - BE)/(A2 - DE)
c= (B - bD)/A
a= log-1 [(Σw - b Σu - c Σv)/n]
in which:
A= n Σuv - Σu Σv
B= n Σwu - Σw Σu
C= n Σwv - Σw Σv
D= n Σ(u2)- (Σu)2
E= n Σ(v2)- (Σv)2
Test your program with the following data:
Z
X
Y
__________________________________________________________
89.
3245.
0.008
75.
2567.
0.011
57.
2783. 0.009
34.
1234. 0.015
101. 5345. 0.006
121. 5329. 0.007
68. 3002. 0.008
79. 2976. 0.010
25. 1034. 0.018
59. 2984. 0.010
96. 3892. 0.007
12. 534. 0.020
__________________________________________________________
|
18. Eight persons take a TRUE or FALSE test containing ten questions.
Write a program to calculate the number of correct answers for each
person. Test your program with the following data:
KEY T T F F T F T F F F
JONES T T T F F F T F T F
LONG F F F F F T T F T F
MARTIN F F F F T T F F T T
PETERS F F F F T F T F T F
DALEY F F F F T F T F T F
PEREZ T T T F F F T F F T
FONG F F F F T T F T F T
JACKSON T T F F F T T T F T
Your output should read, for example:
JONES NO. OF CORRECT ANSWERS: 7
|