Вы находитесь на странице: 1из 28

Fortran 77.

txt K Vijay Anand

PROGRAMMING IN FORTRAN77

Table of Contents

0. Introduction
1. Fortran Statements
2. Data Types, Constants and Variables
Types
Constants
Variables
Implicit typing
3. Operators
Assignment
Arithmetic
Type conversion
Relational
Logical
Character
4. Task Repetition Using DO Loops
The DO statement
The DO WHILE statement
5. Conditional Constructs
The simple IF statement
The block IF statement
6. Arrays
Multi-dimensional arrays
7. Input/Output
Terminal I/O
List-directed output
List-directed input
Formatted output
Formatted input
File I/O
List-directed output
List-directed input
Formatted output
Formatted input
8. The Use of Format
9. Subprograms
Intrinsic functions
Function subprograms
Subroutines
10. Common
Named common blocks
Blank common
0. INTRODUCTION

You should already have met some of the features of the Fortran77 programming language in the
Introductory Course. IF YOU HAVE NOT COMPLETED THE PROGRAMMING TUTORIAL IN THE INTRODUCTORY
COURSE, YOU ARE STRONGLY ADVISED NOT TO PROCEED WITH THIS TUTORIAL, BUT TO GO BACK AND DO IT!

The Fortran language is still evolving; Fortran77 is an internationally agreed standard to


which nearly all current compilers conform, but there is now a revised standard, Fortran90,
which has been agreed but which has not yet been widely implemented. However, many compilers,
-1-
Fortran 77.txt K Vijay Anand

including that available on this machine, already incorporate some of the new features of the
Fortran90 standard as extensions to Fortran77. We will introduce some of these new features in
this tutorial but will always point out that they are not part of the Fortran77 standard, but
are extensions thereof by labelling them F90. However, YOU ARE STRONGLY ENCOURAGED TO USE THE
F90 FEATURES.

We will begin by reminding you of the structure of the projectile program that featured in the
Introductory Course but we will now try to be a little more systematic in our description! Get
hold of a copy of the program by going to the WORKER window, clicking the mouse and typing

cp /usr/local/text/cplabwork/examples/fortprogs/proj1.f proj1.f
or
cp $TFILES/cplabwork/examples/fortprogs/proj1.f proj1.f
Then invoke the emacs editor on your copy of the file by typing

ue proj1.f
Click here if you wish to return to the Table of Contents.

1. FORTRAN PROGRAM STATEMENTS

Fortran77 programs are typed in lines of up to 72 characters, with the first six columns of
each line reserved for special purposes. As a result, Fortran77 statements ALWAYS BEGIN AT, OR
AFTER, COLUMN 7.
One of the special purposes for which the first six columns may be used is shown in the
projectile program: if the first column contains a 'c' or a '*' then the whole line is treated
as a COMMENT and is ignored when the program is compiled into executable code.

A second special use of the first six columns is to specify a CONTINUATION LINE. If column 6 of
a line contains any character other than a space or a zero then the line is treated as a
continuation of the previous line. In this case columns 1-5 of the continuation line MUST BE
BLANK, and column 7 is treated as if it came immediately after column 72 of the previous line!

The third special use of the first six columns (actually, the first five columns) is for
identifying a statement by means of a STATEMENT LABEL, which is an integer, written in columns
1-5. The number chosen can be any integer in the range 1-99999 as long as it is unique to the
statement being labelled. We will encounter uses of statement labels later in the tutorial; for
now, note that they are not generally required and their use is DISCOURAGED.

!!!!!!!!!!!!!!!!!!!!!!!!!!!! F90 FEATURE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!


The strict Fortran77 standard requires the use of upper-case letters only in program
statements, except in comment statements or when writing strings of text to be used in printed
output. Fortran90 allows the use of lower-case as well as upper-case letters. Note, however,
that upper- and lower-case are EQUIVALENT; they are distinguished only when they form part of
character sequences, NOT when used in names of variables or constants.

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Click here if you wish to return to the Table of Contents.

2. DATA TYPES, CONSTANTS AND VARIABLES

TYPES

The data items which appear in a Fortran77 program have a type associated with them. The
allowed types are:
-2-
Fortran 77.txt K Vijay Anand

real
exponent and significant fraction stored separately - known as floating point storage
integer
stored as integer
character
used to store text, or character strings
logical
only two possible values denoted .TRUE. and .FALSE.
double precision
like 'real' but uses twice the number of bits
complex
equivalent to a pair of 'reals'
CONSTANTS

Real constants are numbers containing a decimal point and (optionally) preceded by a sign e.g.

4.7 -0.01 +3.14159 17. -.1


The exponent form represents real constants by a (signed) number (the mantissa), with or
without a decimal point, followed by the letter e (or E) and a second number (the exponent), so
the previous examples could be written:

47E-1 -1E-2 3.14159E0 0.17E2 -1E-1


Integer constants are numbers which do not contain any decimal point and which may, optionally,
be preceded by a sign e.g.

4 -1 +275
Integers up to a certain size (dependent upon the particular computer) are stored with complete
precision.

Character constants are sequences of characters, known as strings, enclosed in single quotes,
or apostrophes, e.g.

'Computational Physics' 'a4' 'aaaa'


The apostrophes do not form part of the string and are not stored in memory, unless repeated
e.g. 'I don''t' is a string containing a single apostrophe.

VARIABLES

Fortran variables have names which denote storage locations in memory. The strict Fortran77
rules for names are that they

must start with a letter of the alphabet


must contain only UPPER CASE letters or digits (known as alphanumeric characters)
must be at most 6 characters long
Particular implementations of Fortran may relax these rules e.g. in our example proj1.f, there
is a variable called theta_rad which is clearly longer than 6 characters and includes the
underscore character, but if you wish your code to be portable between different machines you
should stick to the standard!

Variable names can be declared before the first executable statement of a program, e.g.

real x, height, range


integer month, minute
-3-
Fortran 77.txt K Vijay Anand

character*9 name, class, degree


logical test
double precision xplot, yplot
NOTE that in declaring a character variable, the length of the character string is specified by
appending * followed by the number of characters in the string to the type. In the above
example, name, class and degree are all declared to be character strings of length 9.

IMPLICIT TYPING

Fortran77 has some potentially dangerous rules about variable types. If a variable name is used
without declaration, IT IS ASSUMED TO BE REAL if its name starts with a letter in the range a-h
or o-z, whereas IT IS ASSUMED TO BE INTEGER if it starts in the range i-n.

Some programmers adopt the practice of always declaring all the variables used in a program,
regardless of whether or not they conform to the implicit typing. Going back to proj1.f we see
that x, y, u, vx, vy, g, dt, theta, theta_rad, and pi are all declared to be of type real,
whereas nstep and max_steps are declared to be of type integer. In this case, the declarations
conform to the implicit typing rules.

!!!!!!!!!!!!!!!!!!!!!!!!!!!! F90 FEATURE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!


The statement

implicit none
at the start of a program overrides the implicit typing of Fortran77, requiring that all
variables then be declared explicitly. Its use is widely regarded as good programming practice
and you are STRONGLY ENCOURAGED TO USE IT.

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Click here if you wish to return to the Table of Contents.

3. OPERATORS

ASSIGNMENT OPERATOR

Remember that the assignment operator, =, has a different meaning to the usual arithmetic
'equals'. Thus

x = x+vx*dt
means 'evaluate the expression on the right hand side using the current values of the variables
x, vx and dt, and then use it to overwrite the current value of x i.e. store the value of the
expression in the memory location labelled by x'.

ARITHMETIC OPERATORS

The arithmetic operators are

+ - / * **
representing, respectively, addition, subtraction, division, multiplication and exponentiation.
The first four appear explicitly in our example program, proj1.f.
It is important to be aware that there is an order of precedence for these operators which may
matter when evaluating complicated expressions. The priority rule is: ** has highest priority
followed by / and * followed by + and -

Within any one priority level, evaluation is carried out from left to right. For example in the
-4-
Fortran 77.txt K Vijay Anand

expression

3.0+4.0**2.0-8.0/4.0+2.0
exponentiation is performed first, causing the expression to reduce to
3.0+16.0-8.0/4.0+2.0
followed by any multiplication or division, leading to
3.0+16.0-2.0+2.0
which finally reduces to 19.0.
There is one important exception to the left -> right evaluation rule: multiple exponentiation.
Thus for example

a**b**c
is evaluated from right to left!
Ambiguities can always be resolved by the use of parentheses. Thus for example, in the expression

x+vx*dt
the multiplication of vx and dt is performed first, followed by the addition of the result to
x. Had we wished first to add x to vx and then multiply by dt we could have written
(x+vx)*dt
In general, ANY EXPRESSION ENCLOSED IN PARENTHESES IS EVALUATED FIRST.
-------------------------------------------------------------------

Exercise: what are the values of the following Fortran expressions?

5.+2.*3. (5.+2.)*3. 2.*3.**3. (2.*3.)**3. 2.**3.**2.

-------------------------------------------------------------------
In the evaluation of an arithmetic expression of the form
operand operator operand
in Fortran77, one of the rules is that both operands must be of the same type (other than in
expressions involving exponentiation of the form x**2). If one is an integer and the other is a
real (a MIXED-MODE expression), then the integer will be converted to real before the operation
is performed. The result is of the same type as the operands. MIXED-MODE assignment is also
possible but should be used with care.
Examples:

9*tempc/5
Here tempc is real by default, so 9 is converted to 9.0 and the multiplication is performed
according to the rules of precedence discussed above. The result is of type real and thus the
denominator is first converted to 5.0 before the division is carried out, the final result
being of type real.
a = 7*8
Both operands on the r.h.s. are of type integer, so the result of the multiply is 56, of type
integer. This is then assigned to a, which is by default of type real, so a takes the value 56.0
j = 6.0*7.0/9.0
Here the r.h.s. is a real expression which evaluates to 4.666... The value assigned to the
integer j is then 4, the fractional part being discarded (this is known as truncation).
*******************************
* Warning on integer division *
*******************************
Any fractional part remaining on integer division is also discarded, which can catch out the
unwary programmer! For example,
i = 7
j = 2
-5-
Fortran 77.txt K Vijay Anand

k = i/j
gives k = 3.
Similarly

i = 7
j = 2
a = i/j
gives a = 3.0, from the rules for mixed-mode assignment.
TYPE CONVERSION OPERATORS

Type conversion is possible using type conversion operators; thus applied to the previous example

i = 7
j = 2
a = real(i)/real(j)
gives a = 3.5, which is probably what you intended!
It is also possible to convert from type real to type integer; int(a) yields an integer result,
the integer part of a.

RELATIONAL OPERATORS

In proj1.f you see an example of a comparator, or relational operator, which is used in the line

do while(y.ge.0.0)
to test whether or not y is greater than or equal to zero. The expression y.ge.0.0 is called a
relational expression because it expresses a relation between two values. There are six
relational operators in Fortran which may be used to construct relational expressions of type
'logical' which are either true or false - that is, they correspond in value to one of the two
logical (or Boolean) constants .TRUE. or .FALSE.
The complete set of relational operators is as follows:

a.lt.b
evaluates to .TRUE. if a is less than b, otherwise .FALSE.
a.le.b
evaluates to .TRUE. if a is less than or equal to b, otherwise .FALSE.
a.gt.b
evaluates to .TRUE. if a is greater than b, otherwise .FALSE.
a.ge.b
evaluates to .TRUE. if a is greater than or equal to b, otherwise .FALSE.
a.eq.b
evaluates to .TRUE. if a is equal to b, otherwise .FALSE.
a.ne.b
evaluates to .TRUE. if a is not equal to b, otherwise .FALSE.
******************************
* Warning on comparing reals *
******************************
It can be dangerous to use the relational operators .ne. and .eq. for comparing reals because
of rounding errors. For example, in finite precision, 1./3. has the value 0.3333333, say, so
that 3.0*(1.0/3.0) has the value 0.9999999 NOT 1.0, so that the comparison
3.0*(1.0/3.0).eq.1.0
evaluates to .FALSE. instead of .TRUE.
LOGICAL OPERATORS

Relational operators are used to create a logical expression, which takes the value .TRUE. or
-6-
Fortran 77.txt K Vijay Anand

.FALSE.; logical expressions can be combined using logical operators to perform more
sophisticated logical tests. The logical operators are

.AND. .OR. .EQV. .NEQV. .NOT.


and their use is illustrated by the following table, where L1 and L2 are logical expressions;

L1 L2 L1.OR.L2 L1.AND.L2 L1.EQV.L2 L1.NEQV.L2


--------------------------------------------------------------------------
.TRUE. .TRUE. .TRUE. .TRUE. .TRUE. .FALSE.
.TRUE. .FALSE. .TRUE. .FALSE. .FALSE. .TRUE.
.FALSE. .TRUE. .TRUE. .FALSE. .FALSE. .TRUE.
.FALSE. .FALSE. .FALSE. .FALSE. .TRUE. .FALSE.
--------------------------------------------------------------------------
Thus .OR. gives a result that is only true if either of its operands is true, whereas .AND.
gives the result true only if both operands are true.
.EQV. gives a true result only if both L1 and L2 are logically the same value, whilst .NEQV.
gives a true result if L1 and L2 have opposite values. They may be used to simplify more
complex logical expressions; e.g. the following two expressions have the same value:

(a.lt.b.AND.x.lt.y).OR.(a.ge.b.AND.x.ge.y) a.lt.b.EQV.x.lt.y
The remaining operator, .NOT., takes only a single operand, whose value it inverts. For
example, the following two expressions are equivalent:
.NOT.(a.lt.b.EQV.x.lt.y) a.lt.b.NEQV.x.lt.y
Priority rules for logical operators apply just as they did for arithmetic operators:
Operator Priority
----------------------------------
.NOT. 1 (high)
.AND. 2
.OR. 3
.EQV./.NEQV. 4 (low)
----------------------------------
As before, parentheses may be used to make the order of evaluation clear.

CHARACTER OPERATOR

There is only one character operator, the concatenation operator //, which can be used to
combine two strings to form a third string. For example:

'Wed'//'nesday' is equivalent to the string 'Wednesday'


INITIAL VALUES

Often we need to assign an initial value to some or all of the variables in a program.
Fortran77 allows us to do this by means of the data statement, which takes the form:

data 'namelist1'/'clist1','namelist2'/'clist2',........
or
data 'namelist1'/'clist1'/'namelist2'/'clist2'.........
where 'namelist*' is a list of variables names and 'clist*' is a list of constant values, with
the same number of items as the corresponding 'namelist'. The effect is to give each variable
in 'namelist' the initial value specified by the corresponding item in 'clist'. The normal
rules of arithmetic apply and the constant will be type-converted if necessary to match the
type of the variable. Note: the quotation marks are not part of the sytax.
Example:

-7-
Fortran 77.txt K Vijay Anand

data a,b,n/1.0,2.0,3/,code/8667.0/
gives the real variables a and b initial values of 1.0 and 2.0, the integer variable n an
initial value of 3, and the real variable code an initial value of 8667.0.
Several items can be given the same initial value by preceding the constant by a repetition
count e.g.

data i,j,k,l,m,n/6*0/
A data statement must appear AFTER any specification statements. It is usual, but not necessary
to put data statements at the beginning of the executable part of the program.
*****************************
* Warning on initial values *
*****************************
Many computer systems initialise all variables to a pre-defined value, usually 0, but IT IS
NEVER SAFE to assume that this is the case.
NAMING CONSTANTS

Although the data statement can be used to give a value to a variable that is never changed e.g.

data pi/3.14159/
there is a preferred way of naming constants, which is to use the parameter statement. It takes
the form
parameter ('name1'='const1', 'name2'='const2',......)
with obvious meaning. Thus we could write
parameter (pi=3.14159)
Then on every occasion that pi is referred to in the program, the value 3.14159 will be used.
Constant expressions can also be used e.g.

parameter (third=1.0/3.0, pi3by4=3.0*pi/4.0)


Where an expression is used there are some restrictions:
only the operators + , - , / and * may be used, except that ** may be used as long as the
exponent is an integer; parentheses may be used as normal;
if a named (or symbolic) constant appears in a constant expression it must have been defined by
an earlier 'parameter' statement, or in an earlier part of the current statement.
Click here if you wish to return to the Table of Contents.

4. TASK REPETITION USING DO LOOPS

THE DO LOOP

The repetition of a number of statements a predetermined number of times is so important that


Fortran contains a special construct that allows this to be done. In general, a "do loop" may
contain any Fortran statements, including another do statement, known as a "nested do loop".

!!!!!!!!!!!!!!!!!! F90 FEATURE: the 'end do' statement !!!!!!!!!!!!!!!!!!!!!!!!


Fortran90 denotes the terminating statement of a "do loop" by means of the end do statement.

The syntax is:

do index=int1,int2[,int3]
'statements'
end do
where:

index is NORMALLY an integer variable, but MAY BE OF TYPE REAL; the use of real "do loop"
-8-
Fortran 77.txt K Vijay Anand

indices is DISCOURAGED
int* are variables or expressions, converted if necessary to the SAME TYPE as index. index
starts at int1, and is incremented by int3 at the end of the loop. int2 is usually the final
value of index, although this is not always so.
Note: The notation [,int3] simply means that int3 is optional; it is assumed to be 1 if
omitted. The square brackets are not part of the syntax!

The number of times that the body of the "do loop", denoted by 'statements', is executed (known
as the "trip count") is calculated from the formula:

MAX(0, INT((int2-int1+int3)/int3))
where INT denotes the integer part of the ensuing expression. This number is calculated BEFORE
the loop starts. If zero, it means that the body of the "do loop" is NOT executed.
Examples:

do i=0,100,5
has a trip count of 21 whereas
do i=0,100,9
has a trip count of 12
Example: a very simple program to compute the squares of the integers from 1 to 10, and print
them out.

program squares
c
c a program to calculate the squares of the first ten integers
c
implicit none
integer int,intsq
do int = 1,10
intsq=int*int
write(*,*) 'The square of ',int,' = ',intsq
end do
stop
end

RESTRICTIONS

the "do" variable, index, must NOT be altered within the "do loop", although its value may be
used in an expression
the "do" variable is updated at the end of each pass through the loop, but before a decision is
made about another pass - this may have implications if you wish to use the value of index
later in your program
it is not permissible to jump into the body of a "do loop" although jumps out are allowed
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
The Fortran77 syntax involves the use of a labelled statement to denote the end of the loop and
is:
do m, index=int1,int2[,int3]
'statements'
m continue
where:

m is a statement label (an integer in the range 1-99999)


index is normally an integer variable, but MAY BE OF TYPE REAL
-9-
Fortran 77.txt K Vijay Anand

int* are variables or expressions, converted if necessary to the SAME TYPE as index
Note: the comma after m in the do statement is optional - you may encounter both forms.

THE DO WHILE LOOP

!!!!!!!!!!!!!!!!!!!! F90 FEATURE: the 'do while' construct !!!!!!!!!!!!!!!!!!!


There is an example of a "do while loop" in proj1.f. This construct permits the repeated
execution of one or more Fortran statements conditional upon the status of a logical
expression, rather than for a fixed number of repetitions. The syntax is:

do while ('logical expression')


'statements'
end do
which loops through 'statements' for as long as 'logical expression'evaluates to .TRUE.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
------------------------------------------------------------------------------
Exercise: Go to the WORKER WINDOW and use the editor to write a program
to print out the factorial of n (an integer) from n=1 to 20. NOTE: the
filename that you use for storing your program must have the default
extension .f otherwise it will not be recognised by the compiler, so use
something like
ue fact.f

Your program should not use more than one "do loop". Try compiling and
running your program. What goes wrong if you use integer variables in
your program ??

Remember, the command which invokes the compiler is

f77 'filename'

which produces an executable file called a.out

or f77 -o 'file2' 'file1'

if you want the executable to be called 'file2'. (Do not type the quote
marks!). To run your program, simply type the name of the executable file.

*** CHECKPOINT 1 ***

------------------------------------------------------------------------------
Click here if you wish to return to the Table of Contents.

5. CONDITIONAL CONSTRUCTS

SIMPLE IF

There are two forms of the IF construct. The simple form (which is, strictly speaking, a
hangover from earlier versions of Fortran) is:

if ('logical expression') 'statement'


Here 'statement' is any executable statement and is only implemented if 'logical expression'
has the value .TRUE.
Example:
-10-
Fortran 77.txt K Vijay Anand

if (volts.gt.threshold) signal=gain*input
BLOCK IF

There is also a block IF construct:

if ('logical expression 1') then


'statements1'
else if ('logical expression 2') then
'statements2'
else if ('logical expression 3') then
'statements3'
else
'statements4'
end if
Here 'statements*' are blocks of one or more lines of Fortran. Only one block gets executed in
a particular run; e.g. 'logical expression 2' is only tested if 'logical expression 1' has the
value .FALSE. and so on.
Any number, including zero, of else if blocks can be used and the final "catch-all" else block
can be omitted. Thus the simplest form is

if ('logical expression 1') then


'statements1'
end if
which is equivalent to the simple form described above in the case where 'statements1' consists
of just a single statement.
Example: a program to compute the number of points with positive integer coordinates inside the
ellipse x**2/16 + y**2/25 = 1

program ellipse
c
c declarations
c
implicit none
integer npts,ix,iy
c
c initialise counter
c
npts = 0

c
c loop over x direction
c
do ix = 1,4
c
c loop over y direction
c
do iy = 1,5

c
c test to see if point lies within ellipse
c
if(real(ix*ix)/16.0 + real(iy*iy)/25.0.lt.1.0) then
-11-
Fortran 77.txt K Vijay Anand

npts = npts +1
end if
end do
end do
write(*,*) 'Number of points: ',npts
stop
end

Note the use of the "program statement"; not essential, but good programming practice. The name
of the program may be freely chosen, within the Fortran naming conventions.

Note that indentation has been used to clarify the loop structure, although not necessary ; the
contents of each "do loop" are indented by two spaces with respect to the do and end do
statements, as are the contents of the if block.

-----------------------------------------------------------------------------
Exercise: go to the WORKER window and get a copy of the ellipse program by
typing

cp /usr/local/text/cplabwork/examples/fortprogs/ellipse.f ellipse.f

Try compiling and running this program. Remember, the command which invokes
the compiler is

f77 'filename'

which produces an executable file called a.out

or f77 -o 'file2' 'file1'

if you want the executable to be called 'file2'. (Do not type the quote
marks!). To run your program, simply type the name of the executable file.
------------------------------------------------------------------------------
Example: a program to read positive integers and compute their average; negative integers are
ignored whilst zero terminates the program.

program average

c summary: program to read positive integers and find their average,


c ignoring negative integers and terminating on zero

c variable definitions:

c numint number of integers read in so far


c intsum running total of integer values
c int current integer
c n for do loop control

c
c declarations
c
implicit none
integer numint,intsum,int,n
-12-
Fortran 77.txt K Vijay Anand

c
c initialise counter and total
c
numint = 0
intsum = 0
n = 1

do while (n.eq.1)
c
c input integer from keyboard
c
write(*,*) 'Input integer '
read(*,*) int
c
c test for negative or zero values
c
if(int.gt.0) then
numint = numint + 1
intsum = intsum + int
else if(int.eq.0) then
write(*,*) 'Number of positive integers: ',numint,
& ' Average: ',real(intsum)/real(numint)
stop
end if
end do
end

Note the continuation line, denoted by '&' in column 6.

Note the difference between the stop statement, which signifies the logical end of the program
and terminates execution, and the end statement, which denotes the physical end of the program.
Any program that you write must have an end statement as its final statement, or it will not
compile. It should also have a stop statement, although it may well compile and run without one.

-------------------------------------------------
Exercise: Get a copy of the average program:

cp /usr/local/text/cplabwork/examples/fortprogs/aver.f aver.f

and try it out.


------------------------------------------------------
Click here if you wish to return to the Table of Contents.

6. ARRAYS

It is often desirable to refer to a group of related items of the same type by giving them the
same group name, and identifying the individual items by their positions within the set. Arrays
are used for this purpose in Fortran.

Each item within an array is referred to as an array element and is identified by an integer
index or subscript which follows the array name in parentheses. An array is always declared in
an extended type declaration statement, which also declares the range of possible subscripts,
and hence the size of the array. For example

-13-
Fortran 77.txt K Vijay Anand

integer n(100)
reserves 100 integer locations in memory called n(1), n(2), n(3),.....n(100). In statements
which reference an array element, the index or subscript may be any integer expression e.g.
n(3*j+2).
Array elements may be used anywhere that a variable name can be used, but are especially useful
in conjunction with a "do loop", whose index can be used as an array subscript, enabling each
pass through the loop to use a different array element.

Example: here are the bare bones of a program to find the largest element of an array of ten
integers. You are invited to complete it:

program largest
c
c variables:
c
c ivec array to hold numbers
c large largest array element
c j labels largest array element
c i do loop index

c
c declarations
c
implicit none
integer ivec(10),large,i,j
c
c input the array elements
c
write(*,*) 'Enter 10 integers, one per line:'
read(*,*) (ivec(i), i = 1,10)
c
c start by assuming first element to be largest....
c
large = ivec(1)
j = 1
do i = 2, 10
c
c now write the rest of this loop yourself........
c
end do
write(*,*) 'Element ',j,' is largest and has value ',large
stop
end

Note: in this example the use of a so-called "implied do loop" in the read statement which
inputs the ten elements of the array ivec in sequence.

----------------------------------------------------------------------
Exercise: get the skeleton program

cp /usr/local/text/cplabwork/examples/fortprogs/largest.f largest.f

and try to complete it; check your program by compiling and running it.
-14-
Fortran 77.txt K Vijay Anand

*** CHECKPOINT 2 ***

-----------------------------------------------------------------------
By default, array subscripts in Fortran start at 1, but this can be overridden; for example

real v(-4:3)
declares a real array with 8 elements v(-4), v(-3),.....v(3) The first example could equally
well have been written
integer n(1:100)
MULTI-DIMENSIONAL ARRAYS

There are many instances where it is useful to be able to declare an array with more than one
subscript; for example, to store the values of the electrostatic potential at points in the x-y
plane. Fortran77 allows us to have up to seven subscripts for a single array. The number of
subscripts is referred to as the DIMENSION of the array.

Examples:

real potl(100,100)
integer pressure(20,40,30)
The first of these could equally well be written
real potl(1:100,1:100)
or
real potl(1:100,100)
or
real potl(100,1:100)
An element of a multi-dimensional array must always be referred to with the correct number of
subscripts and can, of course, be used in exactly the same way as a variable or an element of a
one-dimensional array.

Arrays may have characters rather than numbers as elements, for example, we might want to
process a set of names of students by tutorial group and serial number within the group:

program namelist

c
c variable definitions:
c
c igroup labels a group
c ident labels an individual
c name stores names in required order
c next next name in sequence
c
c one '*' terminates a group
c two '**' terminates the whole data set

c
c declarations
c
implicit none
character*15 name(30,10), next
integer igroup,ident

-15-
Fortran 77.txt K Vijay Anand

igroup = 1
10 ident = 1
20 read(5,*) next
if(next.eq.'*') then
igroup = igroup +1
go to 10
else if(next.ne.'**') then
name(ident,igroup) = next
ident = ident + 1
go to 20
end if

c now process the data in the array name............

Note the use of the go to statement together with statement labels, to transfer program control
conditionally. The use of the go to is STRONGLY DISCOURAGED as it makes program logic difficult
to follow and can lead to poorly structured code.

---------------------------------------------------------------------------
Exercise: can you devise a way of aavoiding the use of "go to" statements and
statement labels in the previous example, using the F90 constructs that you
have already met?
---------------------------------------------------------------------------
We can use an implied do loop to input to or output from a part, or the whole of a
multi-dimensional array e.g.

read(5,*) ((potl(i,j),i=2,25),j=10,50)
****************************
* Warning on storage order *
****************************
The elements of a one-dimensional array occupy consecutive storage locations in memory but it
is not immediately obvious what happens with higher- dimensional arrays. In fact in Fortran,
multi-dimensional arrays are stored in such a way that the first subscript changes most rapidly
e.g. the elements of

integer mat(3,3)
are stored with mat(1,1), mat(2,1), mat(3,1), mat(1,2),...... in consecutive locations in
memory. This is important to know if you wish to optimise the speed of execution of a program
that manipulates arrays. Thus in the example above on the use of implied do loops to read into
a two-dimensional array it would be less efficient to write
read(5,*) ((potl(i,j),j=10,50),i=2,25)
because the innermost loop is accessing elements which do not correspond to consecutive
locations in memory.
Click here if you wish to return to the Table of Contents.

7. INPUT/OUTPUT

TERMINAL I/O

The simplest form of input and output, which utilises only the keyboard and screen of your
terminal, is known as list-directed. You have already met examples in the program proj1.f. In
fact that program did not make use of the very simplest forms which we now describe.

LIST-DIRECTED OUTPUT
-16-
Fortran 77.txt K Vijay Anand

uses
print*, 'expression list'
or
write(*,*) 'expression list'
or
write(6,*) 'expression list'
In the third form, 6 denotes the default output device, the terminal screen, for historical
reasons. It is better and safer to use the second form in which * denotes the default device.
The values of any literals, variables, constants or expressions in 'expression list' will be
printed in the order in which they are listed. The form of numeric output is pre-determined by
the compiler.

Examples:

print*, 'Distance versus velocity'


print*, 'Slope = ', slope
write(*,*) 'Specify launch speed u (m/sec) :'
LIST-DIRECTED INPUT

uses
read*, 'variable list'
or
read(*,*) 'variable list'
or
read(5,*) 'variable list'
Here 5 denotes the default input device, the terminal keyboard, again for historical reasons.
The second form is preferred.
Values are stored in the order in which the variables are listed. Data values must be separated
by commas or blanks. As many lines as are needed will be read. Each read* statement will begin
searching for values with a new line.

Examples:

read*, time
read*, (x(j), j=1,100)
read(*,*) theta
-----------------------------------------------------------------------------
Exercise: Write a program to read in a and b, the sides of a rectangle,
and print out the perimeter and area.

*** CHECKPOINT 3 ***

-----------------------------------------------------------------------------
We may wish to exercise more control over the appearance of our output than is afforded by the
list-directed forms just described. Fortran makes provision for the use of 'format descriptors'
to achieve user control over both input and output.

FORMATTED OUTPUT

to the default output device uses


print k, 'expression list'
or
write(*,k) 'expression list'
-17-
Fortran 77.txt K Vijay Anand

or
write(6,k) 'expression list'
The values of any variables or expressions in 'expression list' will be printed in the order in
which they are listed according to the specifications in a format statement with label k. We
will discuss format in Section 8.

Examples:

print 100, alpha, beta


print 50
write(*,99) x, (a(i), i=1,6)
This last example again illustrates use of the implied do loop to print out elements of an array.
FORMATTED INPUT

from the default input device uses


read k, 'expression list'
or
read(*,k) 'expression list'
or
read(5,k) 'expression list'
The values of any variables or expressions in expression list will be input in the order in
which they are listed according to the specifications in a format statement with label k. We
will discuss format in Section 8.
Examples:

read 200, alpha, beta


read(*,99) x, (a(i), i=1,6)
FILE I/O

We may wish more generally to read from, or write to files rather than the standard input and
output devices keyboard and screen. You may already have tried doing this in the Introductory
Course Programming Exercises. The way in which this is done in Fortran77 is by means of the
open statement, whose form is

open('olist')
where 'olist' is a list of open specifiers chosen from the following set:
unit=u, file=fn, status=st, access=acc, form=fm, err=s, iostat=ios
The first of these, unit, MUST BE PRESENT, the others are all optional. The unit specifier
takes the same form as in the read and write statements discussed above, and provided it is
first in the list, the string unit= may be omitted, with only an integer value, u, specifying
the unit number.
We shall not consider the full generality of the open statement here but restrict consideration
to the following form:

open(unit=integer expression, file='filename', status='literal')


designates the file named 'filename' for all input or output statements that refer to the unit
number specified by the value of integer expression.
If the string 'literal' is 'old', the file must be an existing one; if 'literal' is 'new', the
file must NOT be an existing one. If a file whose status is 'new' is successfully opened, its
status is thereby changed to 'old' and any subsequent attempts to open the file as 'new' will
fail.

'literal' may also be 'unknown', which is equivalent to omitting the status specifier and is
-18-
Fortran 77.txt K Vijay Anand

implementation-dependent, or 'scratch' for a temporary file which is deleted when execution


finishes.

Examples:

open(8, file='projdata')
open(unit=15, file='data/run.1', status='old')
open(unit=10, file='latest', status='new')
Each open statement should be matched by a corresponding close statement, once the unit in
question is no longer needed by the program:

Examples:

close(8)
close(unit=15)
close(unit=10)
LIST-DIRECTED INPUT

then uses
read(unit number,*,end=n) 'variable list'
to read from the data file referenced by unit number, which must correspond to a unit number
assigned to a file by a previous open statement, except for the case where unit number is 5,
which is by default the terminal keyboard. * denotes list-directed input. end=n is optional and
will cause control to pass to statement n if the read statement is executed after the last line
of data has been read.
Examples:

read(15,*,end=200) x, y, z
read(11,*) i, j, k, l
FORMATTED INPUT

uses
read(unit number, k, end=n) 'variable list'
to read using the format statement labelled k. end=n is optional, as before.
Example:

read(15,99,end=200) u, v, w
LIST-DIRECTED OUTPUT

uses
write(unit number, *) 'variable list'
to write data to a file specified by unit number , which must have been assigned in an open
statement, except when unit number is 6 which is by default the terminal screen.
Example:

write(13,*) a, b, c
FORMATTED OUTPUT

uses
write(unit number, k) 'variable list'
to write data to a file specified by unit number , which must have been assigned in an open
statement, using the format statement labelled k.
Example:

-19-
Fortran 77.txt K Vijay Anand

write(8,100) a, (r(k), k=1,20)


Click here if you wish to return to the Table of Contents.

8. FORMAT

{{{OPTIONAL

This section should probably be regarded as optional if you are doing this tutorial for the
first time. If you find it hard going, skip to section 9. The most readable way to specify the
format in which data is to be input or output is by means of the "format" statement, referred
to in the previous section. The general form of the format statement is:

k format('format descriptor')
where 'format descriptor' is a character expression and k is a statement label. Format
statements can appear anywhere in a program; a popular choice is to gather them all together
just before the end statement.
Format is just about the hardest thing to get right in a Fortran program, so let us start with
a simple example!

print 100, max, res


100 format(1x,i5,f9.3)
The format descriptor consists of a list of format codes, with the following meanings:
nx denotes n spaces; here n is 1
iw is INTEGER format, printed in a field of width w characters; w is 5;
fw.d is REAL format, printed in a field of width w (including the decimal point), with d digits
after the decimal point; here w is 9 and d is 3.
Thus if, for example, max = 12345 and res = 12345.678 we would get the following output:

1234512345.678
which is not very readable!
On the other hand, if say max = 1 and res = 2.0 we would get

1 2.000
Your program may crash if you try to print too large a number for the field width; thus max =
876543 is too big for the format code i5.
OUTPUT FORMAT CODES

Here is a table describing the effects of various format codes for output:

code meaning
--------------------------------------------------------------------------
iw output an integer in the next w character positions
fw.d output a real in the next w positions with d decimal places
ew.d output a real in the next w characters using a scientific
notation with d decimal places in the mantissa and four
characters (including e and a possible sign) in the exponent
dw.d as ew.d but for double precision numbers
gw.d same as fw.d if there is room, otherwise ew.d
nx ignore the next n character positions i.e. output n blanks
an output character expression in a field of width w, truncating
or padding with spaces as necessary; for truncation n leftmost
characters are output; padding is on left
a output character expression in a field of its own width
-20-
Fortran 77.txt K Vijay Anand

tc output next item starting in character position c


tln output next item starting n character positions before (tl) or
trn after (tr) the current position
'abcd..' output the string of characters 'abcd..' starting at the next
character position
---------------------------------------------------------------------------

You can use a repetition count for multiple instances of the same format code or codes in a
format statement e.g.

10 format(1x,3i5,2(4x,a4))
is equivalent to
10 format(1x,i5,i5,i5,4x,a4,4x,a4)
Separators in the list of format codes can be of two kinds:

the comma, the simple separator we have used in all examples so far
the slash, /, the multi-record separator, which produces a new line
Example:

print 100, max, res


100 format(1x,i5/f9.3)
with max = 12345 and res = 12345.678 as in the first example, would produce
12345
12345.678
What happens if there is a mis-match between the number of items in the output list and the
number of format codes?
a) excess codes are ignored, for example,

print 100, jj
100 format('a=',i3,' b=',i3)
if jj = 123 would produce
a=123 b=
b) if there are too few codes, a new line is taken, and the codes are repeated from the left
parenthesis corresponding to the LAST BUT ONE right hand parenthesis! For example,

print 100, (a(i), i=1,80)


100 format(' Results:'/(1x,10f7.3))
gives a header line followed by 8 lines of 10 items. However,
print 100, (a(i), i=1,80)
100 format(' Results:'/1x,10f7.3)
would give 8 pairs of lines, each with Results: on the first line and 10 items on the next.
CARRIAGE CONTROL OR FORMAT EFFECTORS

If the output from a Fortran program goes to a lineprinter, or to a file which then gets
printed on a lineprinter, then the first character in each line is not printed, but is used for
"carriage control" or as a "format effector".

The allowed format effectors are as follows:

character effect
--------------------------------------------------------------------
space no extra action i.e. single spacing
0 skip an extra line i.e. double spacing
1 new page
-21-
Fortran 77.txt K Vijay Anand

+ overprint the last line (not always implemented)


--------------------------------------------------------------------
As an example

100 format('1Results:'/(1x,10f7.3))
starts printing on a new page.
INPUT FORMAT CODES

Most of the output format codes described above are available as input format codes but are not
widely used, as free-format (denoted by *) deals with most situations:

code meaning
---------------------------------------------------------------------------
iw read the next w characters as an integer
fw.d read the next w characters as a real with d decimal places
if no decimal point is present; otherwise ignore d
ew.d same as fw.d on input
dw.d same as fw.d on input
gw.d same as fw.d on input
nx ignore the next n characters
an read next n characters as characters; if n is less than length
of input list item pad with blanks; in n is greater than
length, store rightmost characters of input string in item
a read sufficient characters to fill input list item
tc next character to be read is at position c
tln next character to be read is n characters before (tl) or
trn after (tr) the current position
---------------------------------------------------------------------------

The treatment of reals by fw.d (or ew.d) perhaps needs an example to clarify;

read 100, a,b,c,d


100 format(f3.1,f2.2,f3.2,f1.0)
then the result for two different examples is as follows:
data a b c d
-------------------------------------------------
123456789 12.3 .45 6.78 9.
.23.56.8 0.23 0.5 6.8
-------------------------------------------------
}}}

Click here if you wish to return to the Table of Contents.

9. SUBPROGRAMS

Subprograms, or procedures, are the basic building blocks of good Fortran programs (in the
jargon, WELL-STRUCTURED PROGRAMS). There are two types of procedure or subprogram: subroutines
and functions. A complete Fortran program consists of a main program and any number of
subprogram program units.

INTRINSIC FUNCTIONS

Fortran contains a library of intrinsic functions providing the commonly used mathematical
functions such as the trigonometric functions, which you have already met in the example
-22-
Fortran 77.txt K Vijay Anand

program proj1.f. You can also write your own functions to supplement or replace those provided
as part of the language. The key feature of a function subprogram is that it returns a result
through its name, whereas subroutine subprograms do not. Generally a function takes one or more
arguments and returns a result.

Here is an example of an intrinsic function, the square root, being used to calculate the area
of a triangle of sides a,b,c from the formula

area = square root{s(s-a)(s-b)(s-c)}


where 2s is the sum of the lengths of the sides:

program triangle

c variable definitions:

c a,b,c sides of triangle


c s (a+b+c)/2
c area area of triangle

c
c declarations
c
implicit none
real a,b,c,s,area
c
c read the lengths of the sides of the triangle
c
write(*,*) 'Input sides a,b,c :'
read(*,*) a,b,c

c
c compute area using intrinsic function sqrt
c
s = 0.5*(a + b + c)
area = sqrt(s*(s-a)*(s-b)*(s-c))
write(*,100) area
100 format(1x,'Area of triangle is: ',f10.4)
stop
end

-----------------------------------------------------------------------------
Exercise: try modifying the triangle program to check that the input
values of a,b and c do indeed correspond to a valid triangle, that is,
they are all non-negative and the sum of any two is greater than the
third. As usual you can get a copy by means of the command

cp /usr/local/text/cplabwork/examples/fortprogs/triangle.f triangle.f

*** CHECKPOINT 4 ***

-----------------------------------------------------------------------------
FUNCTION SUBPROGRAMS

-23-
Fortran 77.txt K Vijay Anand

Function subprograms are also known as external functions to distinguish them from intrinsic
functions. Here is a simple example, a function to calculate the average of five numbers:

program mean

c use a function subprogram to calculate the mean of a set of five numbers


c
c declarations
c
implicit none
real a1,a2,a3,a4,a5,av,avrage
c
c input five real numbers
c
write(*,*) 'Input five real numbers :'
read(*,*) a1,a2,a3,a4,a5
c
c instance of function
c
av = avrage(a1,a2,a3,a4,a5)
write(*,100) av
100 format(' Average of five numbers is :',1x,f10.4)
stop
end

c end of main program

c definition of function subprogram

real function avrage(x1,x2,x3,x4,x5)

c this function returns the average of its five arguments


c
c declarations
c
implicit none
real x1,x2,x3,x4,x5,sum

sum = x1 + x2 + x3 + x4 + x5
avrage = sum/5.0
return
end

Notes:

the first statement is a special function statement which takes the general form :
'type' function 'name'('d1,'d2',.....)
where 'type' is optional; if omitted the type is determined by the usual Fortran rules for
'name'. 'd1','d2' etc are dummy arguments that represent the actual arguments that will be used
when the function is used (in the jargon, referenced).
the penultimate statement, return, is analogous to the stop statement in the previous examples,
except that it does not terminate program execution but simply that of the function subprogram,
returning to the place in the main program from where the function was referenced.
-24-
Fortran 77.txt K Vijay Anand

one further observation; it is possible to write a function that has no arguments; nevertheless
in referencing that function by name in the main program, the parentheses must be included,
even though the argument list is empty e.g.
result = fun()
SUBROUTINE SUBPROGRAMS

A subroutine subprogram has the same overall structure as a function subprogram except that the
first statement is a subroutine statement rather than a function statement. The chief
difference lies in how they are referenced and how their results are returned.

As we have just seen, a function is referenced by writing its name, followed by any arguments
enclosed in parentheses. Control is then transferred from the current statement to the
statements contained within the function. The execution of the function uses the actual values
provided for its arguments, substituting them for the dummy arguments in the function
definition, and calculates a value, the function value, which is then available as the value of
the function reference in the main program.

A subroutine, on the other hand, is accessed by means of a call statement, which gives the name
of the subroutine and a list of arguments which are used to transfer information between the
main program and the subroutine:

call 'name'('arg1,'arg2',..............)
The call statement transfers control to the subprogram, whose statements are executed until a
return statement is encountered, when control returns to the statement immediately following
the subroutine call.
As a simple example, let us rework the previous example to use a subroutine instead of a
function subprogram:

program mean

c use a subroutine subprogram to calculate the mean of a set


c of five numbers
c
c declarations
c
implicit none
real a1,a2,a3,a4,a5,av
c
c input five real numbers
c
write(*,*) 'Input five real numbers :'
read(*,*) a1,a2,a3,a4,a5
c
c subroutine call
c
call avrage(a1,a2,a3,a4,a5,av)
write(*,100) av
100 format(' Average of five numbers is :',1x,f10.4)
stop
end
c
c end of main program
c
c definition of subroutine subprogram
-25-
Fortran 77.txt K Vijay Anand

c
subroutine avrage(x1,x2,x3,x4,x5,xbar)

c this subroutine returns the average of its first five arguments


c in the sixth argument
c
c declarations
c
implicit none
real x1,x2,x3,x4,x5,sum,xbar
sum = x1 + x2 + x3 + x4 + x5
xbar = sum/5.0
return
end

Notes:

the name of the subroutine (avrage in this example) is simply an identifier; it does not have a
type and cannot appear in a type specification statement.
the actual arguments, a1, a2, a3, a4, a5, av replace the dummy arguments x1, x2, x3, x4, x5,
xbar which appear in the subroutine definition. They must match in number, type and order.
some of the arguments are input parameters to the subroutine whilst others are output parameters
the variables x1, x2, x3, x4, x5, xbar are LOCAL to the subprogram. Thus when writing a
subprogram or a main program we need not be concerned that names used in one program unit might
clash with those in another program unit. This is one reason why it then becomes possible to
write libraries of useful subprograms, functions and subroutines, which can subsequently be
used in other programs of yours or other people's.
Note that it is possible to have array names as subroutine arguments; the array or arrays must
be declared within the body of the subroutine as well as in the calling routine. However,
unlike in a main program, where the dimensions of an array must be declared of fixed size, an
array declaration within a subroutine may specify the name of a variable in the declaration.

For example, here is a fragment of a program which calls a subroutine to take a vector of
'number' data events (up to a maximum of 150) and return a character array of size 70 x
'number' which can then be printed to give a crude histogram

program analys

implicit none
integer number
real events(150),xmin,xmax
character*1 matrix(70,150)
:
:
call hist(xmin, xmax, events, matrix, number)
:
:
stop
end

subroutine hist(xlow, xhigh, dvec, harray, n)

implicit none
-26-
Fortran 77.txt K Vijay Anand

integer n
real dvec(n),xlow,xhigh
character*1 harray(70,n)
:
:
return
end

Click here if you wish to return to the Table of Contents.

10. COMMON

{{{OPTIONAL

Subprograms are useful in structuring large programs into subtasks, but communication between
the different program modules via parameter lists is not always appropriate. There may be a
body of variables which have to be accessed by many of the subtasks but don't really 'belong'
to any of them. Fortran allows us to declare a "common" block of variables for this purpose.

NAMED COMMON BLOCKS

A named block of storage is defined by the statement:

common/'name'/'n1','n2',....
where 'name' is the global name of the "common" block and 'n1', 'n2',... is a list of local
variable names, array names or array declarators. For example,
integer age(50),num
real mark(50,6),av,avrage
common/exam/num,mark,av(50),age,avrage
defines a "common" block called exam which consists of 402 numeric storage items. The first of
these is an integer, num, the next 300 a two-dimensional array mark, the next 50 a real array
av, the next 50 an integer array age and the last a real variable avrage.
*********************************
* Warning on common block names *
*********************************

Because the name of a "common" block is global, it must be different from the names of any
other "common" blocks or program units.
Notes:

If a "common" block contains any character variables or character arrays then it cannot contain
any variables or arrays of any other type.
The common statement is a specification statement and must therefore precede any data
statements or executable statements. Although not mandatory, it is a good idea to place any
type or array declarations of items that appear in the common statement immediately before it,
as in the example above.
Because only the name of a "common" block is global, different program units may refer to the
individual items within the "common" block in different ways. For example, the block exam in
the above example might be defined in another program unit as
common/exam/n,total(50,6),av(50),nyrs(50),avyrs
or even as
common/exam/n,score(50,7),nage(50),avrage
where the two real arrays have been declared as a single real array. Because of the rule about
storage order in Fortran77, those elements of score with second subscript 7 occupy the last 50
-27-
Fortran 77.txt K Vijay Anand

storage locations and thus correspond exactly to the array av in the first specification.
BLANK COMMON

As well as blocks of storage of fixed size with global names, Fortran77 allows us to have a
single further block of storage that is available to any program unit and that has neither a
name or a fixed size. This is known as "blank common" and is declared thus:

common 'n1','n2',.....
where 'n1', 'n2',... is a list of local variable names, array names or array declarators. For
example,
common x,y,a(-10:10)
Notes:

Unlike named "common" blocks, the size of blank "common" need not be the same in different
program units.
Blank "common" is usually more appropriate where several variables and/or arrays are to be made
available to all (or nearly all) program units.
}}}

-28-

Вам также может понравиться