7- Scientiffic Computer Language (Phy 435)
7- Scientiffic Computer Language (Phy 435)
Faculty of Science
Physics Department
Fortran Language
(Programming)
For
B.Sc. Students (Phys 435)
Mansoura University
Faculty of Science
Physics Department
FORTRAN LANGUAGE
(PROGRAMMING)
For
B. Sc. Students
0
CONTENTS
1- INTRODUCTION.....................................................................1
2- DATA TYPES AND OPERATIONS ....................................... 4
3- CONTROL STATEMENTS..................................................... 40
• IF statement..........................................................................40
• S E L E C T CASE statement .............................................49
• DO Loops .........................................................................58
4- FUNCTIONS AND SUBROTINES SUBPROGRAMS.............79
5- ARRAYS.................................................................................... 101
6- OUTPUT DESIGN AND FILE PROCESSING.........................117
i
1. Introduction:
1.1 What is Fortran?
FORTRAN (FORmula TRANslation) was developed in the fifties as a
programming language for scientific and engineering applications. In 1966 the
language was standardized and FORTRAN IV was born. It was updated a number
of times in order to remain competitive with more contemporary programming
languages. FORTRAN 77 was released in 1978, followed by FORTRAN 90 in
1991, updated in 1997 to Fortran 95 and further updated in 2004 to Fortran 2003,
and in 2010 to Fortran 2008 and updated in 2018 to Fortran 2018. FORTRAN
90 we will be using in this course.
High level language instructions are not executable. Instead, a high-level
language source program is read as input by a program called a compiler, which
checks its syntax and, if it is free from errors, compiles an equivalent machine
code object program.
1
FORTR Link
FORTRA AN with Executab
N Compil Librari le File
Program er es
Executable
Source Code Object Code
Code Librari
es
Make
Test &
Change Execute
s Debug
Program Program
in
Sourc
Figure 1: Compiling, linking and running a Fortran program
Portability
PROGRAM program-name
declarations
statements
stop
END PROGRAM program-name
2
syntax to be a valid Fortran program. We start by looking at a simple example
where we calculate the area of a circle:
PROGRAM circle_area
IMPLICIT NONE
! reads a value representing the radius of a circle,
! then calculates and writes out the area of the circle.
REAL :: radius, area
REAL, PARAMETER :: pi=3.141592
READ (*,*) radius
area = pi*radius*radius
WRITE (*,*) area
END PROGRAM circle_area
Comments
Comments may appear anywhere in the program. Well-written comments are
crucial to program readability.
• In-line comments are allowed. These comments begin with an exclamation
point (!) and extend to the end of the line.
• Everything following ! will be ignored.
• The exclamation mark may appear anywhere on a line.
for example:
! This is an example
!
PROGRAM Comment
..........
READ(*,*) Year ! read in the value of Year
..........
Year = Year + 1 ! add 1 to Year
..........
END PROGRAM Comment
3
Continuation Lines
• If a statement is too long to fit on one line, it has to be continued.
• The continuation character is &, which is not part of the statement.
For example:
Blank spaces
Blank spaces are ignored in Fortran. So, if you remove all blanks in a Fortran
program, the program is still syntactically correct but almost unreadable for
humans.
Each program should end with the “END” statement. This signifies the
physical end of the program. The STOP statement signals the logical end of the
program. While the END statement appears at the end of the program, the STOP
statement may appear anywhere in the program, possibly, to stop execution of the
program under certain conditions. The compiler sequentially executes each
statement in the program.
2.1 Constants
A constant is a fixed value of a data type that cannot be changed.
2.1.1 Integer Constants
Integer constants are whole numbers. An integer constant does not have a
decimal point. Examples of integer constants are:
4
32 0 -6201 27 -83 1992
2.1.2 Real Constants
A real constant is a constant number that has a decimal point. Examples of real
constants are 1.23, -0.0007, 3257.263, 5.0, 0.00002, 18., 774.00000, -64.9899 and
94000000000000000.0. The last number in the previous example leads us to the
scientific notation for real numbers. 94000000000000000.0 can be written as 9.4
x 1016 or as 0.94 x 1017. In FORTRAN, this number can be written in two possible
ways: as 94000000000000000.0, or in scientific notation as 9.4E16 or 0.94E+17.
2.1.3 Complex number
a complex number has a real and an imaginary component. Complex numbers in
Fortran as a pair of real numbers (real part first, followed by the imaginary part).
For example, the complex number (3.0, -5.0) is equal to 3.0 – 5.0i
2.1.4 Logical Constants
There are two logical constants; true and false. In FORTRAN, the logical constant
true is written as .TRUE. and the logical constant false is written as .FALSE..
2.2 Variables
A variable is an object of a certain data type that takes a value of that type. A
variable, as the name suggests, can change its value through certain FORTRAN
5
statements such as the assignment statement and the READ statement. We shall
use the term variable to mean variable name. There are some rules for choosing
variable names in FORTRAN. These rules are as follows:
• Variable names may consist of up to 31 characters.
• The first character of a variable name must be a letter.
Valid characters include all letters, digits, and the underscore symbol ( _ ).
• A variable should not contain special characters ($, ;, ,, :, !, ~, ^,(,{, [, ), }, ],
<, >, ?, “, „, \, | , @, %, &, #, +, -,/,*, .., etc.).
• A variable should not contain blanks.
Examples of valid and invalid variable names are given below:
Variable Comment
TRY Valid.
NAME21 Valid.
name_all Valid.
A+B Invalid. Special character '+' can not be used.
5TEST Invalid. Name does not start with a letter.
FIVE7 Valid.
The following subsections present different variable types and how to define
them.
2.2.1 Implicit Declaration
Fortran 90 permits variables to be typed and declared implicitly, that is
without using a variable declaration as given above. An implicit declaration is
performed whenever a name appears which has not been explicitly declared and
the program section does not contain the statement IMPLICIT NONE.
The command IMPLICIT NONE is allowed. This feature cancels the default
naming convention. When invoked, program variables MUST be specified
explicitly.
Declaring the type of a Fortran variable is done with type statements. It has the
following form:
type-specifier :: list
6
where the type-specifier is one of the following and list is a list of variable
names separated with commas:
• INTEGER :: the variables in list can hold integers
• REAL:: the variables in list can hold real numbers
• COMPLEX:: the variables in list can hold complex numbers
• LOGICAL:: the variables in list can hold logical values
(i.e., true or false)
• CHARACTER:: the variables in list can hold character strings
2.2.2 Integer Variables
Integer variables can hold only integer values. There are two ways to define an
integer variable in FORTRAN: explicitly and implicitly. The explicit definition
allows us to define variable types, irrespective of the first letter of the variable
name. In such a case, we must use the INTEGER statement. The general form
of this statement is as follows:
INTEGER :: list of integer variables
where list of integer variables is a list that has the names of variables separated
by commas. The INTEGER statement is a FORTRAN declaration statement.
This statement must be appeared at the beginning of the program before any other
executable statement. In fact, all declaration statements must appear at the
beginning of the program. The following examples demonstrate the use of the
INTEGER statement:
Example Comments
INTEGER :: BOOKS, NUM, X Three integer variables: BOOKS, NUM, X
INTEGER :: Y1, AB3W Two integer variables: Y1, AB3W
INTEGER:: CLASS, ID, TOTAL Three integer variables: CLASS, ID, TOTAL
INTEGER :: SUM One integer variable: SUM
In implicit definition, we choose a variable name that starts with one of the
following letters: I, J, K, L, M, N. Hence, any variable that starts with one of
these letters is considered implicitly as an integer variable unless it is otherwise
7
explicitly stated. Examples of integer variables are:
NUMB, N1, LAB, ISUM, JX, KILO, MEMO.
Implicit definition is assumed when a programmer forgets to use explicit
definition.
We should try our best to declare our variables explicitly. If we forget to use
explicit definition, then FORTRAN compilers assume implicit definition. In
implicit definition, any variable that does not start with one of the letters I, J, K,
L, M, N is considered, implicitly, as a real variable unless the type of the variable
is explicitly stated. Examples of real variables are:
YNUMB, X1, PERC, SUM, RJX, TOTAL, STID, A5, EPSLON, PI.
8
2.2.4 Parameters
The term parameter in Fortran refers to a value which will be constant, for
example the programmer will want the value of pi to be unaltered during a
program. Therefore, pi may be defined as
The word REAL defines the type of pi and the word PARAMETER is an attribute
of the REAL object which is known as pi and has the value 3.141592. Parameters
may also be defined for other data types, for example:
INTEGER, PARAMETER :: maxvalue=1024
INTEGER, PARAMETER :: repeatcount=1000
The objects declared to be parameters may not be altered in the program.
2.2.5 Complex Variables
Fortran allows variables to be declared as complex numbers. Variables such as
this are declared with their first value as the real component and the second
as the imaginary. The following statements show an example of a complex
variable declaration in a portion of a program.
COMPLEX:: the variables in list can hold complex numbers
where list of real variable is a list that has the names of variables separated by
commas. The COMPLEX statement is a FORTRAN declaration statement. It
must be appeared in the beginning of the program before any other executable
statement.
The following program demonstrates complex number arithmetic −
program ComplexArithmatic
implicit none
x = (7, 8);
y = (5, -7)
write(*,*) i * x * y
9
z=x+y
write(*,*) "z = x + y = ", z
z=x-y
write(*,*) "z = x - y = ", z
z=x*y
write(*,*) "z = x * y = ", z
z=x/y
write(*,*) "z = x / y = ", z
When you compile and execute the above program it produces the following result-
(9.00000000, 91.0000000)
z = x + y = (12.0000000, 1.00000000)
z = x - y = (2.00000000, 15.0000000)
z = x * y = (91.0000000, -9.00000000)
z = x / y = (-0.283783793, 1.20270276)
Complex Type
The generic function cmplx() creates a complex number. It produces a result who’s
real and imaginary parts are single precision, irrespective of the type of the input
arguments.
program createComplex
implicit none
integer , parameter :: i = 10
real, parameter :: x= 5.17
print *, cmplx(i, x)
When you compile and execute the above program it produces the following result-
(10.0000000, 5.17000008)
10
where list of logical variables is one or more variables separated by commas.
Examples of LOGICAL statement usage are given below:
Example Comments
LOGICAL:: TEST, FLAG, Q, P Four logical variables: TEST, FLAG, Q, P
LOGICAL:: M5 One logical variable: M5
LOGICAL:: SORTED, LINK Two logical variables: SORTED, LINK
Here, variables letter and digit can only hold no more than one character.
11
• If you want to declare character variables of different length with a single
statement, you can attach a length specification, *i, to the right of a variable.
In this case, the corresponding variable will have the indicated length and all
other variables are not affected.
• CHARACTER(LEN=10) :: City, Nation*20, BOX, bug*1
Here, variables City and BOX can hold a string of no more than 10
characters, Nation can hold a string of no more than 20 characters,
and bug can hold only one character.
• There is one more way of specifying the length of a character variable. If the
length value is replaced with a asterisk *, it means the lengths of the declared
variables are determined elsewhere. In general, this type of declarations is
used in subprogram arguments or in PARAMETER and is refereed to
as assumed length specifier.
• CHARACTER(LEN=*) :: Title, Position
Here, the actual lengths of variables Title and Position are unknown and will
be determined elsewhere.
12
FORTRAN Operation FORTRAN Math Precedency
Operator Example Notation
** Exponentiation X ** Y xy 1
* Multiplication X*Y x y 2
/ Division X/Y xy 2
+ Addition X+Y x+y 3
- Subtraction X-Y x-y 3
13
2.3.2 Integer Operations
Note that the expression I/J * J is not always equivalent to I. For example, if I
and J are integer variables, and the value of I is 17 and the value of J is 6, the
expression becomes 17 / 6 * 6. To evaluate this expression, we consider operator
precedence. Since operators '/' and '*' have the same priority, they are evaluated
from left to right. We start with 17 / 6. The two operands are integers and therefore
'/' here is an integer operator. The result must be an integer, which in this case
evaluates to 2. Now, evaluation proceeds as 2 * 6 which results in 12 and not 17.
14
An operator between an integer operand and a real operand is considered to be a
mixed-mode operator and the operation is considered to be a mixed-mode
operation. Mixed-mode operations produce real results. The following table
shows examples of mixed-mode operations:
Expression Value Comment
50 - 23.0 27.0000000
3.0 ** 2 9.0000000
3 ** 2.0 9.0000000
4** 0.5 2.0000000
5.0 * 7 35.0000000
56.7 / 7 8.1000000
8 / 2.0 4.0000000
8.0 / 3 2.6666667
9 / 10. 0.9000000 Decimal point can be placed without zero.
17 / 6 * 6.0 12.0000000 '/' is an integer operator and '*' is a mixed mode
operator
The number of positions to the right of the decimal point in a real number
depends on the computer used. In the examples above, we have assumed that the
computer allows up to 7 positions.
2.3.5 Examples
Example 1: Evaluate the following arithmetic expression
20 - 14 / 5 * 2 ** 2 ** 3
Solution:
Expression: 20 - 14 / 5 * 2 ** 2 ** 3
Priority is for ** from right to left
Step 1: 2 ** 3 = 8 (integer operation)
Expression: 20 - 14 / 5 * 2 ** 8
Priority is for ** from right to left
Step 2: 2 ** 8 = 256 (integer operation)
Expression: 20 - 14 / 5 * 256
Priority is for / and * from left to right
Step 3: 14 / 5 = 2 (integer operation)
Expression: 20 - 2* 256
Priority is for *
Step 4: 2 * 256 = 512 (integer operation)
Expression: 20 – 512
Priority is for –
Result: -492
15
14.0 / 5 * (2 * (7 - 4) / 4) ** 2
Solution:
Expression: 14.0 / 5 * (2 * (7 - 4) / 4) ** 2
Priority is for expression inside the inner most parenthesis
Step 1: (7 - 4) = 3 (integer operation)
Expression: 14.0 / 5 * (2 * 3 / 4) ** 2
Priority is for expression inside the parenthesis
Step 2 & 3: (2 * 3 / 4) = (6 / 4) = 1 (2 integer operations)
Expression: 14.0 / 5 * 1 ** 2
Priority is for **
Step 4: 1 ** 2 = 1 (integer operation) Expression: 14.0 / 5 * 1
Priority is for / and * from left to right
Step 5: 14.0 / 5 = 2.8000000 (Mixed mode operation)
Expression: 2.8000000 * 1
Priority is for *
Result: 2.8000000
Example 3: Rewrite the following FORTRAN expression as a mathematical
form X+Y/W–Z
Solution:
y
x+ −z
w
16
These are predefined functions that are available from the FORTRAN language.
Certain functions, such as the trigonometric functions, are frequently encountered
in programming. Instead of developing them repeatedly in each program. A list
of commonly used intrinsic functions is given below.
Function Meaning
• Note that all trigonometric functions use radian rather than degree for
measuring angles. For function ATAN(x), x must be in (-PI/2, PI/2).
For ASIN(x) and ACOS(x), x must be in [-1,1].
• Conversion functions:
Function Meaning
INT(x) integer part x
NINT(x) nearest integer to x
FLOOR(x) greatest integer less than or equal to x
FRACTION(x) the fractional part of x
REAL(x) convert x to REAL
17
• Other functions:
Function Meaning
The example below has three initialized variables A, B and C. The result is
computed and saved into uninitialized variable R.
Examples:
1. INT(-3.5) = -3
2. NINT(3.5) = 4
3. NINT(-3.4) = -3
4. FLOOR(3.6) = 3
5. FLOOR(-3.5) = -4
6. FRACTION(12.3)= 0.3
7. REAL(-10) = -10.0
8. MOD(4,3) = 1
18
• The logical operator .AND., requires two expressions or variables and
gives a .TRUE.result only if both expressions are true, otherwise evaluates
to .FALSE.. Consider the following example:
LOGICAL :: test, employed=.true.
INTEGER :: age=50
...
test = employed .AND. (age<45) !test=.false.
There are two sub-expressions here, one .TRUE.the other .FALSE.hence the
result is .FALSE..
• The logical operator .OR. requires two expressions or variables and gives
the value .TRUE. if either one of the expressions is true, and .FALSE.
otherwise. Consider the following example:
LOGICAL :: test
CHARACTER(LEN=10) :: name = `James`
...
test = (name='Dimitris') .OR. (name='James') !test=.true.
19
LOGICAL :: test
...
test = (5*3>12) .EQV. (6*2>8) !test=.true.
test = (5*3<12) .EQV. (6*2<8) !test=.true.
both statements evaluate to .TRUE. because the sub-expressions in each
statement take the same logical values.
• The logical non-equivalence operator .NEQV. is used to evaluate
expressions to .TRUE. only if one of the expressions has a different logical
value to the other(s), otherwise evaluates to .FALSE..
For example:
LOGICAL :: test
...
test = (5*3>12) .NEQV. (6*2>13) !test=.true.
test = (5*3>12) .NEQV. (6*2<13) !test=.false.
the first expression has one true and one false component and therefore evaluates
to .TRUE., the second expression has two true components and therefore
evaluates to .FALSE..
The following table shows the results of the five logical operations .AND., .OR.,
.NOT. , .EQV. and .NEQV on different operand values, assuming P and Q are
logical variables:
P Q P .AND. Q P. OR. Q .NOT. P P. EQV. Q P. NEQV. Q
.FALSE. .FALSE. .FALSE. .FALSE. .TRUE. .TRUE. .FALSE.
.FALSE. .TRUE. .FALSE. .TRUE. .TRUE. .FALSE. .TRUE.
.TRUE. .FALSE. .FALSE. .TRUE. .FALSE. .FALSE. .TRUE.
.TRUE. .TRUE. .TRUE. .TRUE. .FALSE. .TRUE. .FALSE.
• The .NOT. operator has the highest priority of the three logical operators
followed by the .AND. operator and .OR. operator. The .EQV. operator and
.NEQV. has the lowest priority. These operators are shown in the following
table with the sequence in which they are evaluated (precedency):
20
Logical Operator Precedence
.NOT. 1
.AND. 2
.OR. 3
.EQV. 4
.NEQV. 4
21
Operator Operator
Fortan77 Fortan90
.EQ. == : equal to
.NE. /= : not equal to
.GT. > : greater than
.GE. >= : greater than or equal to
.LT. < : less than
.LE. <= : less than or equal to
** right to left
+ - left to right
• This means that a relational operator can be evaluated only if its two operands
have been evaluated. For example,
in a + b /= c*c + d*d
expressions a+b and c*c + d*d are evaluated before the relational
operator /= is evaluated.
22
• If you are not comfortable in writing long relational expressions, use
parenthesis. Thus,
3.0*SQRT(Total)/(Account + Sum) - Sum*Sum >= Total*GNP - b*b
is equivalent to the following:
(3.0*SQRT(Total)/(Account + Sum) - Sum*Sum) >= (Total*GNP - b*b)
• Although a < b < c is legal in mathematics, you cannot write comparisons this
way in Fortran. The meaning of this expression is a < b and b < c. You should
use logical operator to achieve this.
Examples:
i. 3**2 + 4**2 == 5**2 is .TRUE.
ii. If the values of REAL variables a, b and c are 1.0, 2.0 and 4.0, respectively,
then b*b - 4.0*a*c >= 0.0 is equivalent to 2.0*2.0 - 4.0*1.0*4.0 >= 0.0, which
evaluates to -12.0 >= 0.0. Thus, the result is .FALSE.
iii. If REAL variables x and y have values 3.0 and 7.0, and INTEGER
variables p and q have values 6 and 2, what is the result of
x*x - y*y + 2.0*x*y /= p*q + p**3 - q**3?
Solution:
x*x - y*y + 2.0*x*y /= p*q + p**3 - q**3
--> 3.0*3.0 - 7.0*7.0 + 2.0*3.0*7.0 /= 6*2 + 6**3 - 2**3
--> ([3.0*3.0] – (7.0*7.0) + ((2.0*3.0)*7.0)) /= (((6*2) + (6**3)) – (2**3))
--> 2.0 /= 220.0
--> .TRUE.
The next subsection presents the use of relational, logical, and arithmetic
operators in logical expressions.
23
Type Operator Associativity
** right to left
Arithmetic * / left to right
+ - left to right
Relational < <= > >= == /= none
.NOT. right to left
.AND. left to right
Logical
.OR. left to right
.EQV. .NEQV. left to right
24
Example 1: Given that X has a value of 3.0, Y has a value of 5.0, Z has a value
of 10.0, and FLAG is a logical variable with .FALSE. value, evaluate the
following FORTRAN expression:
.NOT. FLAG .AND. X*Y> Z .OR. X+Y > Z
Solution:
Expression: .NOT. FLAG .AND. X*Y >Z .OR. X+Y >Z
Evaluate arithmetic expressions first.
Expression: .NOT. FLAG .AND. 15.0 >10.0 .OR. 8.0>10.0
Evaluate relational expressions next.
Expression: .NOT. FLAG .AND. .TRUE. .OR. .FALSE.
Evaluate logical expressions. Start with .NOT..
Expression: .TRUE. .AND. .TRUE. .OR. .FALSE.
Evaluate logical .AND. next.
Expression: .TRUE. .OR. .FALSE.
Evaluate .OR. next
Result: .TRUE.
Example 2: When is the value of the following expression .TRUE.? Assume K
and L are integers.
K / L * L .EQ. K
Solution: If K is divisible by L, the value of the expression is .TRUE.. Otherwise,
the value will be .FALSE..
Example 3: Given that X has a value of 3.0, Y has a value of 5.0, Z has a value
of 10.0, and FLAG is a logical variable with the value .FALSE., find the value of
each of the following expressions:
.NOT. FLAG .OR. FLAG
X > Y - Z / 2.0
X*Z==. 20.0 .OR. FLAG .AND. .NOT. Z== 5.0
X >Y .AND. X >Z .OR. X < Y .AND. X < Z
Z*10 .NE. Y*30 .AND. X < Y .AND. FLAG
.NOT. FLAG .AND. FLAG
.NOT. .NOT. FLAG
Solution:
25
Expression Value
.NOT. FLAG .OR. FLAG .TRUE.
X >Y - Z / 2.0 .TRUE.
X*Z == 20.0 .OR. FLAG .AND. .NOT. Z == 5.0 .FALSE.
X >Y .AND. X >Z .OR. X < Y .AND. X < Z .TRUE.
Z*10 /= Y*30 .AND. X < Y .AND. FLAG .FALSE.
.NOT. FLAG .AND. FLAG .FALSE.
.NOT. .NOT. FLAG .FALSE.
26
Example 2:
Write a FORTRAN assignment statement to store in X1 the value stored in Y1.
Solution:
X1 = Y1
Example 3: Write a FORTRAN assignment statement to increment X1 by 1.
Solution:
X1 = X1 + 1.0
Example 4: Write a FORTRAN assignment statement to add to X1 the value of
Y1.
Solution:
X1 = X1 + Y1
Example 5: Write a FORTRAN assignment statement to store in X1 the contents
of X1 times the contents of Y1.
Solution:
X1 = X1 * Y1
Example 6: Assume that the coefficients of a quadratic equation are given as A,
B, and C. Write FORTRAN assignment statements to find the two roots, ROOT1
and ROOT2, of the quadratic equation.
Solution:
ROOT1 = SQRT (-B + (B ** 2.0 - 4.0 * A * C) / (2.0 * A)
ROOT2 = SQRT (-B - (B ** 2.0 - 4.0 * A * C) / (2.0 * A)
27
The following points must be noted while using the unformatted READ
statement:
• Each read statement starts reading from a new line.
• If the input data is not enough in the current line, reading continues in the
next line.
• The data values can be separated by blanks or comma.
• The data values must agree in type with the variables.
• Integer values can be read into real variables but real values must not be
read into integer variables.
• Extra data on an input line is ignored.
2.7.1 Examples
Example 1: Assume the following declaration:
INTEGER:: NUM, M1, K, L1, L2, L3, K1, K2
REAL :: TOT, X1, YY, S, ST, A, X, Y, Z
The following table gives examples of READ statements:
Statement Input Line Effect
READ(*,*) NUM,TOT 9 5.08 NUM = 9
TOT = 5.08
READ(*,*) X1, YY 325 27 X1 = 325.0
YY = 27.0
READ(*,*) M1 20.0 ERROR MESSAGE. DATA
TYPE MISMATCH
READ(*,*) K, S 18,0.35E-2 K = 18 S = 0.35E-2
28
The following table gives examples of READ statements:
• The execution of a READ always starts searching for input values with a
new input line.
Example 4:
INTEGER :: I, J, K, L, M, N
READ(*,*) I, J
READ(*,*) K, L, M
READ(*,*) N
If the above READ statements are used to read the following input lines,
100 200
300 400 500
600
then I, J, K, L, M and N will receive 100, 200, 300, 400, 500 and 600,
respectively.
29
• Consequently, if the number of input values is larger than the number of
variables in a READ statement, the extra values will be ignored. Consider the
following:
Example 5:
INTEGER :: I, J, K, L, M, N
READ(*,*) I, J, K
READ(*,*) L, M, N
30
The first READ reads 100 and 200 into P and Q and 300 is lost. The
second READ starts with a new input line, which is the second one. It does not
read in anything. The third READ starts with the third line and reads 700 and
800 into R and S. As a result, the three input values (i.e., 400, 500 and 600) are
all lost. The third value on the third line, 900, is also lost.
31
WRITE(*,*) L / K * K * 1.0 18.0000000
WRITE(*,*) L * 1.0 / K * K 20.0000000 May be 19.9999994
(accuracy)
WRITE(*,*) 5,6+7, L, 2, K+3 5 13 20 2 6 Constants and expressions
WRITE(*,*) 'K= ',K,' L IS ',L K= 3 L IS 20 Characters may be printed
WRITE(*,*) 'THIS TESTS' THIS TESTS
WRITE(*,*) FLAG, .FALSE. T F Logical values either T or F
WRITE(*,*) Prints an empty line
Example 2: In the table below, more examples of the PRINT statement are given
assuming the following initializations:
CHARACTER(10):: LSTNAM
CHARACTER :: CLASS*5, MAJOR*4
LSTNAM = 'AL-FORTRAN'
CLASS = 'BATAL'
MAJOR = 'ANY1'
The following points must be noted while using the WRITE statement:
• Each WRITE statement starts printing on a new line.
• If the spaces in the line are not enough to hold the whole output, printing
continues on the next line.
• A variable that does not have a value will produce question marks if it is
printed.
Example 3: The following example displays the values of four variables on
screen:
INTEGER :: Factor, N
REAL :: Multiple, tolerance
WRITE(*,*) Factor, N, Multiple, tolerance
Example 4: The following example displays the string content of Title,
followed by the result of (Height + Length) * Area.
CHARACTER(LEN=10) :: Title
REAL :: Height, Length, Area
WRITE(*,*) Title, (Height + Length) * Area
There are some useful rules:
32
Each WRITE starts with a new line.
Consequently, the second form in which the WRITE does not have a list of
expressions just displays a blank line.
INTEGER :: Target
REAL :: Angle, Distance
CHARACTER(LEN=*), PARAMETER :: Time = "The time to hit target " &
IS = " is " &
UNIT = " sec."
Target = 10
Angle = 20.0
Distance = 1350.0
WRITE(*,*) 'Angle = ', Angle
WRITE(*,*) 'Distance = ', Distance
WRITE(*,*)
WRITE(*,*) Time, Target, IS, Angle * Distance, UNIT
This example may produce the following result:
Angle = 20.0
Distance = 1350.0
The time to hit target 10 is 27000sec.
The blank line is generated by the third WRITE.
The above example uses assumed length specifier (i.e., LEN=*)
and continuation lines (i.e., symbol &).
If there are too many results that cannot be fit into a single line, the computer will
display remaining results on the second, the third line and so on.
33
Write a program to compute and display the means of three REAL variables
initialized with positive real values.
Solution
! -------------------------------------------------------
! Computes arithmetic, geometric and harmonic means
! -------------------------------------------------------
PROGRAM ComputeMeans
IMPLICIT NONE
ArithMean = (X + Y + Z)/3.0
GeoMean = (X * Y * Z)**(1.0/3.0)
HarmMean = 3.0/(1.0/X + 1.0/Y + 1.0/Z)
Program Output
Data items: 1., 2., 3.
Arithmetic mean = 2.
Geometric mean = 1.81712067
Harmonic Mean = 1.63636363
34
2.10 Exercises
1. Evaluate the following arithmetic expressions:
1. 4 ** 2 / 3
2. ( ( 2 + 6 ) / 2 + 3.0 /6.0 *4 ) * ( 2 / 4 )
3. 10 ** 2 ** 3
4. 10 / 4 /4 + ( 2 - 10 / 2.0 )
35
WRITE(*,*) FIVE
END
iii. INTEGER:: I, J, K, L
READ(*,*)I, J
READ(*,*) K, I
WRITE(*,*) I, J, K, L
END
Assume the input for the program is:
4 5 6
7 8 9
iv. REAL:: X
X = 1.2
X = X + 1.0
X = X + 1.0
X = X + 1.0
WRITE(*,*) X , X, X, X
END
5. What is the value of each of the following expressions? Use the following
values if needed:
REAL:: A, B
INTEGER:: K, J
A = 2.0
K = -2
B = 3.5
J = 1
1. 6*J/K*4
2. 9+K/5*A/2
3. A/(B+K)/J
4. 3 ** J ** A ** 1 + K / J
5. -2 / 4 * 4 ** 2
6. -2 / 4.0 * 2 ** 2 + 2 * 4.0 ** 2
7. 3 ** 2.0 * ( 3.0 - 1 ) + 2.0 * 1 * 3.0
8. 5 ** 3 / 2 ** 5 / 2
9. ( 5 / 2 ) ** 1.0 ** 2
36
2. Q = 1012.0 * P ** 0.5 * (1.0 - P / 100.0 )
3. K = A * B / C - 2
10. Write a FORTRAN program which reads the radius of a sphere and calculates
the surface area and the volume of the sphere. Your program should print the
radius, surface area and the volume:
4
Surface area = 4 r2 & Volume = r3
3
11. Convert the following mathematical expressions / assignments to FORTRAN
expressions / assignments. (Do not use extra parentheses)
𝑦
1. 2𝑥 + 𝐴 = 𝜋𝑟 2
2
𝑎+𝑏
2. √
𝑎−𝑏
3
𝑟3 𝑎𝑐 4
3. −
3 2𝑏
1
4. 1 1 1
+ +
𝑟1 𝑟2 𝑟3
37
𝑥𝑦
5. 𝑎=𝑏+ +2
𝑐+𝑑
6. 2𝑎 + 𝑐 −6
12. The input data to a certain program is more than what is required. The data
is as follows:
4 5 12 10
6 1 8 13 19
3 2 9 0 7 18 20
Write a FORTRAN program to read enough data (i.e. using the minimum
number of variables in the READ statement) to print the following output:
4 5
1 8
9 0
(your program should have READ and PRINT statements only)
38
14. Determine whether the following conditions are TRUE or FALSE. Assume
A = 3.5, B = -4.1, I = -4, J = 9, FLAG = .TRUE. when needed:
1. (3.0/2<1.5).AND.(4/2 >1)
2. .FALSE..AND..TRUE..OR..NOT.(.FALSE..AND..TRUE.)
3. .NOT..FALSE..AND..TRUE.
4. .NOT..FALSE..OR..TRUE..AND.3/2==1.0
5. .NOT.5**2 == 5*2.AND.0> 5.OR.5*2+2> 0
39
3. Control statements
Fortran 90 has three main types of control construct:
• IF statement
• S E L E C T CASE statement
• DO Loops
40
number is odd. Function MOD(x,y) computes the remainder of x divided by y. This
is the the remainder (or modulo) function
INTEGER :: Number
READ(*,*) Number
IF (MOD(Number, 2) == 0) THEN
WRITE(*,*) Number, ' is even'
ELSE
WRITE(*,*) Number, ' is odd'
END IF
READ(*,*) a, b
IF (a <= b) THEN
Smaller = a
ELSE
Smaller = b
END IF
WRITE(*,*) 'The smaller of ', a, ' and ', &
b, ' is ', Smaller
Example 3: Write a FORTRAN program that reads an integer number and finds out
if the number is even or odd. The program should print a proper message.
Solution:
PROGRAM even_odd
IMPLICIT NONE
INTEGER :: K
READ(*,*) K
WRITE (*,*) 'INPUT: ', K
IF(K / 2 * 2 .EQ. K) THEN
41
WRITE (*,*) 'EVEN'
ELSE
WRITE (*,*) 'ODD'
ENDIF
END PROGRAM even_odd
IF (logical-expression) THEN
statements
END IF
42
of x is x if x is non-negative; otherwise, the absolute value is -x. For example, the
absolute value of 5 is 5 and the absolute value of -4 is 4=-(-4). Also note that
the WRITE(*,*) statement has been intentionally broken into two lines with the
continuation line symbol &. The trick is that the value of X is first saved
to Absolute_X whose value is changed later only if the value of X is less than zero.
REAL :: X, Absolute_X
X = .....
Absolute_X = X
IF (X < 0.0) THEN
Absolute_X = -X
END IF
WRITE(*,*) 'The absolute value of ', x, &
' is ', Absolute_X
Example 2: The following program segment reads in two integer values into a
and b and finds the smaller one into Smaller.
INTEGER :: a, b, Smaller
READ(*,*) a, b
Smaller = a
IF (a > b) THEN
Smaller = b
END IF
WRITE (*,*) 'The smaller of ', a, ' and ', &
b, ' is ', Smaller
In many cases, it is required to do something when certain condition is satisfied;
otherwise, do nothing. This is exactly what we need the form of IF-THEN-END
IF. In the following, an INTEGER variable Counter is used for counting
something. When its value is a multiple of 10, a blank line is displayed.
Example 3:
INTEGER :: Counter
Example 4: Write a FORTRAN program that reads a grade. If the grade is not zero,
the program must add 2 points to the grade. Then, the new grade should be printed.
Solution:
PROGRAM grade
43
IMPLICIT NONE
REAL:: GRADE
READ(*,*) GRADE
WRITE (*,*) 'ORIGINAL GRADE IS', GRADE
IF (GRADE >0) THEN
GRADE = GRADE + 2.0
WRITE (*,*) 'SCALED GRADE IS ', GRADE
ENDIF
END PROGRAM grade
IF (logical-expression) one-statement
where one-statement is a executable statement which is not another IF, and logical-
expression is a logical expression. The execution of this logical IF statement goes as
follows:
44
Examples on the Logical IF
• In many cases, it is required to do something when certain condition is satisfied;
otherwise, do nothing. This is exactly what we need the form of IF-THEN-END
IF.
Example 1: In the following, an INTEGER variable Counter is used for counting
something. When its value is a multiple of 10, a blank line is displayed.
INTEGER :: Counter
INTEGER:: ID
REAL:: GPA
CHARACTER(LEN=10):: STATE
READ(*,*) ID, GPA
WRITE(*,*) 'INPUT: ', ID, GPA
IF (GPA >= 3.5) STATE = 'EXCELLENT'
IF (GPA >= 3.0 .AND. GPA<3.5) STATE ='VERY GOOD'
IF (GPA >= 2.5 .AND. GPA < 3.0) STATE = 'GOOD'
IF (GPA>= 2.0 .AND. GPA < 2.5) STATE = 'FAIR'
IF (GPA < 2.0) STATE = 'POOR'
WRITE(*,*) ID,' ', STATE
END PROGRAM student_ID
Example 2: Write a FORTRAN program that reads three integer numbers and
finds and prints the maximum. Use simple IF constructs.
Solution:
45
PROGRAM the_maximum
IMPLICIT NONE
if b*b-4*a*c is non-negative, the roots of the equation can be solved with the
following formulae:
Write a program to read in the coefficients a, b and c, and compute and display the
roots. If the discriminant b*b - 4*a*c is negative, the equation has complex root.
Thus, this program should solve the equation if the discriminant is non-negative and
show a message otherwise.
Solution
! ---------------------------------------------------
! Solve Ax^2 + Bx + C = 0 given B*B-4*A*C >= 0
! Now, we are able to detect complex roots.
! ---------------------------------------------------
PROGRAM QuadraticEquation
IMPLICIT NONE
REAL :: a, b, c
REAL :: d
REAL :: root1, root2
47
READ(*,*) a, b, c
WRITE(*,*) 'a = ', a
WRITE(*,*) 'b = ', b
WRITE(*,*) 'c = ', c
WRITE(*,*)
d = b*b - 4.0*a*c
IF (d >= 0.0) THEN ! is it solvable?
d = SQRT(d)
root1 = (-b + d)/(2.0*a) ! first root
root2 = (-b - d)/(2.0*a) ! second root
WRITE(*,*) 'Roots are ', root1, ' and ', root2
ELSE ! complex roots
WRITE(*,*) 'There is no real roots!'
WRITE(*,*) 'Discriminant = ', d
END IF
a = 1.
b = 5.
c = 2.
48
Examples
• Suppose we need a program segment to read a number x and display its sign. More
precisely, if x is positive, a + is displayed; if x is negative, a - is displayed;
otherwise, a 0 is displayed. With an IF-THEN-ELSE-END IF statement, we have
a two-way decision (i.e., true or false).
IF (x > 0) THEN
WRITE(*,*) '+'
ELSE
IF (x < 0) THEN
WRITE(*,*) '-'
ELSE
WRITE(*,*) '0'
END IF
END IF
• Given a x, we want to display the value of -x if x < 0, the value of x*x if x is in
the range of 0 and 1 inclusive, and the value of 2*x if x is greater than 1.
Converting to using IF, we have the following:
IF (x < 0) THEN
WRITE(*,*) -x
ELSE
IF (x <= 1) THEN
WRITE(*,*) x*x
ELSE
WRITE(*,*) 2*x
END IF
END IF
49
where statements-1, statements-2, statements-3, ..., statements-n and statements-
DEFAULT are sequences of executable statements, including the SELECT
CASE statement itself. The label lists label-list-1, label-list-2, label-list-3, ...,
and label-list-n are called case labels.
A label-list is a list of labels, separated by commas. Each label must be one of the
following forms. In fact, three of these four are identical to an extent specifier for
substrings:
value
value-1 : value-2
value-1 :
: value-2
where value, value-1 and value-2 are constants. The type of these constants must
be identical to that of the selector.
• The first form has only one value
• The second form means all values in the range of value-1 and value-2. In
this form, value-1 must be less than value-2.
• The third form means all values that are greater than or equal to value-1
• The fourth form means all values that are less than or equal to value-2
Example 2:
CHARACTER(LEN=4) :: Title
INTEGER :: DrMD = 0, PhD = 0, MS = 0, BS = 0, Others = 0
51
DrMD = DrMD + 1
CASE ("PhD")
PhD = PhD + 1
CASE ("MS")
MS = MS + 1
CASE ("BS")
BS = BS + 1
CASE DEFAULT
Others = Others + 1
END SELECT
Example 3:
• The following program uses the value of Number to determine the value
of Range.
INTEGER :: Number, Range
52
Programming Example: Computing Letter Grade
At the end of a quarter, the average of three marks must be computed. Then, this
average is rounded and used to determine the corresponding letter grade. The letter
grades are computed as follows:
Range Grade
>= 90 A
< 90 and >= 85 AB
< 85 and >= 80 B
< 80 and >= 75 BC
< 75 and >= 70 C
< 70 and >= 65 CD
< 65 and >= 60 D
< 60 F
Write a program to read three marks, compute its average, round the average and
use it to determine the corresponding letter grade.
Solution
! ----------------------------------------------------------
! This program reads three marks, computes their average
!
! ----------------------------------------------------------
PROGRAM LetterGrade
IMPLICIT NONE
53
CASE (80:84) ! >= 80 and <= 84 ---> B
Grade = 'B '
CASE (85:89) ! >= 84 and <= 89 ---> AB
Grade = 'AB'
CASE DEFAULT ! >= 90 -------------> A
Grade = 'A '
END SELECT
3.3 GOTO
The GOTO statement can be used to transfer control to another statement, it
has the form:
GOTO label
The GOTOstatement simply transfers control to the statement, skipping any
state- ments in between. For example:
...
IF( x<10 ) GOTO 10
...
10 STOP
54
3.4 Exercises
2. REAL:: A,B
INTEGER:: I
READ(*,*) A, I, B
IF (A<3.0) THEN
WRITE(*,*)A+I
IF (B<2.5) THEN
WRITE(*,*)B**I
ENDIF
ELSE
WRITE(*,*) A*B*I
ENDIF
END
Assume the input for the program is:
2.5 2 2.5
3. NTEGER:: A, B, C
READ(*,*) A, B, C
IF (A > B) THEN
IF (B<C) THEN
WRITE(*,*)B
ELSE
WRITE(*,*)C
ENDIF
ELSE
WRITE(*,*)A
ENDIF
WRITE(*,*)A, B, C
END
Assume the input for the program is:
-2 -4 -3
55
4. LOGICAL:: A,B
INTEGER:: K1, K2
K1 = 10
K2 = 12
A = K1<K2
B = .TRUE.
IF (A) B = .FALSE.
WRITE(*,*)A, B
END
56
I. IF (X ------ Y) WRITE(*,*)X
IF (X ------ Y) WRITE(*,*)Y
57
3.5. REPETITION (LOOPS)
While writing a program, it may be necessary to execute a statement or a group of
statements repeatedly. Repetition is supported in FORTRAN through two repetition
constructs. A repetition construct is known as a loop.
DO Count = -1, 5, 2
WRITE(*,*) Count
END DO
Program output
-1
1
3
Some Notes
There are certain things you should know about DO-loops.
DO count = -3, 4, 0
...
END DO
• Do not change the value of the increement. The following is not a good
practice:
INTEGER :: a, b, c
DO a = b, c, 3
READ(*,*) a ! the value of a is changed
a = b-c ! the value of a is changed
END DO
INTEGER :: a, b, c, d, e
DO i = 10, -10
.....
END DO
• While you can use REAL type for control-var, initial-value, final-
value and step-size, it would be better not to use this feature at all since it may
60
be dropped in future Fortran standard. In the DO-loop below, x successively
receives -1.0, -0.75, -0.5, -0.25, 0.0, 0.25, 0.5, 0.75 and 1.0.
REAL :: x
Sum = 0
DO Count = 1, Number
READ(*,*) Input
Sum = Sum + Input
END DO
Sum is initialized to zero. For each iteration, the value of Input, which is read in
with READ, is added to the value of Sum. For example,
if the value of Number is 3, and the three input values are 3, 6, and 8 then the final
value of Sum is 17 = 3+6+8.
Example 2:
Factorial: A simple variation could be used to compute the factorial of a positive
integer. The factorial of an integer N, written as
N! = N*(N-1)*(N-2)*...*3*2*1.
INTEGER :: Factorial, N, I
Factorial = 1
DO I = 1, N
Factorial = factorial * I
END DO
61
Programming Example: Computing Factorial
Write a program that reads in an integer and computes its factorial. This program
should detect if the input is negative and display an error message.
Solution
! ----------------------------------------------------------
! Given a non-negative integer N, this program computes
! the factorial of N. The factorial of N, N!, is defined as
! N! = 1 x 2 x 3 x .... x (N-1) x N
! and 0! = 1.
! ----------------------------------------------------------
PROGRAM Factorial
IMPLICIT NONE
INTEGER :: N, i, Answer
62
This program computes the factorial of
a non-negative integer
What is N in N! -->
5
5! = 120
DO
statements-1
IF (logical-expression) THEN
statements-THEN
EXIT
END IF
statements-2
END DO
Example
• The following code reads in values into variable x until the input value
becomes negative. All input values are added to Sum. Note that the negative
one is not added to Sum, since once the code sees such a negative
value, EXIT is executed.
INTEGER :: x, Sum
Sum = 0
DO
READ(*,*) x
IF (x < 0) EXIT
Sum = Sum + x
END DO
64
Write a program that reads in a REAL value and computes EXP() of that value
using the series until the absolute value of a term is less than a tolerance value, say
0.00001.
Solution
! ---------------------------------------------------------
! This program computes exp(x) for an input
! ---------------------------------------------------------
PROGRAM Exponential
IMPLICIT NONE
READ(*,*) X ! read in x
Count = 1 ! the first term is 1 and counted
Sum = 1.0 ! thus, the sum starts with 1
Term = X ! the second term is x
DO ! for each term
IF (ABS(Term) < Tolerance) EXIT ! if too small, exit
Sum = Sum + Term ! otherwise, add to sum
Count = Count + 1 ! count indicates the next term
Term = Term * (X / Count)! compute the value of next term
END DO
After 35 iterations:
Exp(10.) = 22026.4648
From EXP() = 22026.4648
Abs(Error) = 0.E+0
65
3.5.5 Nested DO Loops
DO loops can be nested, that is you may have a DO loop inside another DO loop.
However, one must start the inner loop after starting the outer loop and end the inner
loop before ending the outer loop. It is allowed to have as many levels of nesting as
one wishes. The constraint here is that inner loops must finish before outer ones and
the indexes of the nested loops must be different.
Note further that an EXIT statement only brings the control out of the inner-
most DO-loop that contains the EXIT statement.
Suppose we have the following nested DO loops:
DO
statements-1
DO
statement-2
END DO
statement-3
END DO
Each iteration of the outer DO starts with statements-1. When the control reaches
the inner DO, statements-2 is executed until some condition of the inner DO brings
the control out of it. Then, statements-3 is executed and this completes one iteration.
Any EXIT in the inner DO brings the control out of the inner DO to the first
statement in statement-3.The following are a few simple examples:
DO i = 1, 9
DO j = 1, 9
WRITE(*,*) i*j
END DO
END DO
66
Example 2:
It is obvious that the inner DO-loop computes the sum of all integers in the range of
1 and i (i.e., Sum is equal to 1+2+3+...+i). Since i runs from 1 to 10, the following
loop computes ten sums: 1, 1+2, 1+2+3, 1+2+3+4, ...., 1+2+3+...+9, and
1+2+3+...+9+10.
INTEGER :: i, j, Sum
DO i = 1, 10
Sum = 0
DO j = 1, i
Sum = Sum + j
END DO
WRITE(*,*) Sum
END DO
Example 3:
Nested DO Loops: Consider the following program.
INTEGER :: M, j
DO M = 1, 2
DO j = 1, 6 , 2
WRITE(*,*) M, J
END DO
END DO
In many cases, it is convenient to combine the features of the block DO and block
IF constructs into one construct featuring the best of both. The DO WHILE statement
is a conditional loop construct that performs this function.
The block DO WHILE construct conditionally executes a block as many times as
necessary, as long as the tested logical expression included in the DO WHILE
statement continues to be satisfied at every iteration of the loop.
67
The DO WHILE statement has the form:
This loop is executed 10 times, with B being decremented by 10. at every iteration
of the loop. The loop finishes when B is less than 5.
This loop continues to execute while B ≥ 0. The loop is set up in such a way that this
condition is always satisfied. The initial value of B is 5., and B continues to increase
with every iteration of the loop. Therefore, there is no way to logically terminate the
loop. This construct will not produce an error upon execution, but will tie up the
processor in an infinite loop.
Just as with DO loops (Section 7.1), it is often necessary to place one or more DO
WHILE loops inside of another DO WHILE loop. This is referred to as "nesting"
68
DO WHILE loops. As stated previously, the nested loop should be completely
contained within the nesting loop.
The following rules apply to nested DO WHILE loops:
• Nested and nesting DO WHILE loops cannot share the same unlabeled END
DO statement.
• Nested and nesting DO WHILE loops can share the same labeled END DO
statement.
• If two or more nested DO WHILE loops share the same labeled END DO
statement, control can be transferred to that statement only from within the
innermost DO WHILE block.
If the condition is .TRUE., the block of statements is executed once. For the next
iteration, since we need to go to the beginning of the IF statement, we require the
GOTO statement. It has the following general form :
GOTO statement number
A GOTO statement transfers control to the statement that has the given statement
69
number. Using the IF and the GOTO statements, the general form of the WHILE
loop is as follows :
n IF (condition) THEN
block of statements
GOTO n
ENDIF
The execution of the loop starts if the condition evaluates to a .TRUE. value. Once
the loop iterations begin, the condition must be ultimately changed to a .FALSE.
value, so that the loop stops after a finite number of iterations. Otherwise, the loop
never stops resulting in what is known as the infinite loop. In the following section,
we elaborate more on the WHILE loop.
Example 1: Computation of the Average: Write a FORTRAN program that reads
the grades of 100 students in a course. The program then computes and prints the
average of the grades.
Solution:
PROGRAM the_Average
IMPLICIT NONE
REAL:: X, AVG, SUM
INTEGER:: K
K = 0
SUM = 0.0
25 IF (K<100) THEN
READ(*,*) X
K = K + 1
SUM = SUM + X
GOTO 25
ENDIF
AVG = SUM / K
WRITE(*,*) AVG
END PROGRAM the_Average
Note that the variable K starts at 0. The value of K is incremented after the reading
of a grade. The IF condition presents the loop from reading any new grades once the
100th grade is read. Reading the 100th grade causes K to be incremented to the value
of 100 as well. Therefore, when the condition is checked in the next iteration, it
becomes .FALSE. and the loop stops.
70
In each iteration, the value of the variable GRADE is added to the variable SUM.
After the loop, the average is computed by dividing the variable SUM by the variable
K.
PROGRAM Alternating
IMPLICIT NONE
INTEGER:: SUM, TERM,NTERM
SUM = 0
TERM = 1
DO NTERM = 1, 100
SUM = SUM + (-1) ** (NTERM + 1) * TERM
TERM = TERM + 2
END DO
WRITE(*,*) SUM
END PROGRAM Alternating
Notice the summation statement inside the loop. The expression (-1) ** (NTERM +
71
1) is positive when NTERM equals 1, that is for the first term. Then, it becomes
negative for the second term since NTERM + 1 is 3 and so on.
Implied loops are only used in READ and PRINT statements. The implied loop is
written in the following manner :
READ(*,*) (list of variables, index = initial, limit, increment)
As in the case of explicit DO loops, the index must be either an integer or real
expression. The variables in the READ statement can be of any type including array
elements. The expressions in the PRINT statement can be of any type as well. All
the rules that apply to DO loop parameters also apply to implied loop parameters.
Usage of implied loops is given in the following examples:
Example 1: Printing values from 100 to 87: The following segment prints the integer
values from 100 down to 87 in a single line.
WRITE(*,*) (K, K = 100 , 87 , -1)
Output:
100 99 98 97 96 95 94 93 92 91 90 89 88 87
Notice that the increment is -1, which means that the value of K decreases from
100 to 87. In each iteration, the value of K is printed. Since K is the index of the
loop, the value printed here is the value of the index, which varies in each iteration.
Consider the following explicit DO loop version of the implied loop:
DO K = 100, 87 , -1
WRITE(*,*) K
END DO
Output:
100
99
98
...
...
...
87
The two loops are equivalent except in terms of the shape of the output. In the
implied loop version, the output will be printed on one line. In the explicit DO loop
72
version, the output will be printed as one value on each line.
3.5.9 The DO-CYCLE Construct
In parallel with the DO-EXIT construct, Fortran has a DO-CYCLE construct as
follows:
DO control-info
statements-1
CYCLE
statements-2
END DO
where control-info is empty if the loop is a DO-END DO; otherwise, control-
info contains all information that a counting DO should have.
When the execution of a DO-loop encounters the CYCLE statement, the DO-loop
starts next iteration immediately.
This is not a recommended feature. So, if it is possible, do not use it.
Example 1:
The following loop only displays 1, 2, 4 and 5. If the value of i is 1, 2, 4 or 5, the
execution of the loop enters the ELSE part and displays the value of i. However,
if i is 3, since i == 3 is .TRUE., the CYCLE statement is executed, which brings
back to the beginning of the DO-loop starting the next iteration (i.e., the iteration
corresponds to i=4).
INTEGER :: i
DO i = 1, 5
IF (i == 3) THEN
CYCLE
ELSE
WRITE(*,*) i
END IF
END DO
Output
1
2
4
5
The following code has a DO-loop for processing the input value stored in Range.
At the beginning of the loop, the value of Range is read in and checked. If the value
is less than 2, the CYCLE statement brings the control back to the beginning of the
73
loop to read a new value for Range. This will continue until a value that is greater
than or equal to 2. Then, the logical expression of the IF-THEN-END
IF is .FALSE. and consequently the execution continues with "... process Range ...".
INTEGER :: Range
DO
WRITE(*,*) 'An integer >= 2 please --> '
READ(*,*) Range
IF (Range < 2) THEN
WRITE(*,*) 'Input not in the required range'
CYCLE
END IF
... process Range ...
END DO
3.6 Exercises
74
1. What will be printed by the following programs?
1. PROGRAM Ex1_1
IMPLICIT NONE
INTEGER:: K, M, N
N = 0
DO K = -5 , 5
N = N + 2
DO M = 3 , 1
N = N + 3
END DO
N = N + 1
END DO
WRITE(*,*) N
END PROGRAM Ex1_1
2. PROGRAM Ex1_2
IMPLICIT NONE
INTEGER:: K, J
K = 2
25 IF ( K.GT.0 ) THEN
DO J = K, 3, 2
WRITE(*,*) K, J
END DO
K = K - 1
GOTO 25
ENDIF
END PROGRAM Ex1_2
3. PROGRAM Ex1_3
IMPLICIT NONE
INTEGER:: J, K
DO K = 1,2
WRITE(*,*) K
DO J = 1,3
WRITE(*,*)K,J
END DO
END DO
END PROGRAM Ex1_3
4. PROGRAM Ex1_4
IMPLICIT NONE
INTEGER:: X, K, M
M = 4
DO K = M ,M+2
X = M + 2
IF ( K<6 )THEN
WRITE(*,*)'HELLO'
ENDIF
END DO
END PROGRAM Ex1_4
2. Find the number of iterations of the WHILE-LOOPS in each of the following
programs:
75
1. PROGRAM number_1
IMPLICIT NONE
INTEGER:: K, M, J
K = 80
M = 5
J = M-M/K*K
10 IF ( J/= 0 ) THEN
WRITE(*,*)J
J = M-M/K*K
M = M + 1
GOTO 10
ENDIF
END PROGRAM number_1
2. PROGRAM number_2
IMPLICIT NONE
REAL:: W
INTEGER:: L
W = 2.0
L = 5 * W
100 IF ( L/W ==((L/4.0)*W) ) THEN
WRITE(*,*)L
L = L + 10
GOTO 100
ENDIF
END PROGRAM number_2
76
II. L = 1
SUM =0
3 IF (L < 15) THEN
J = -L
2 IF (J < 0) THEN
SUM =SUM+J
J = J + 1
GOTO 2
ENDIF
L = L+3
GOTO 3
ENDIF
WRITE(*,*)SUM
6. The following program segments may or may not have errors. Identify the errors
(if any).
1. PROGRAM Ex6_1
IMPLICIT NONE
INTEGER:: K, J
DO K = 1,4
DO J = K-1,K
WRITE(*,*)K
END DO
END DO
END PROGRAM Ex6_1
2. PROGRAM Ex6_2
MPLICIT NONE
INTEGER:: K, J
K = 10
J = 20
1 IF ( J>K ) THEN
77
K = K/2
GOTO 1
ENDIF
END PROGRAM Ex6_2
8. Write a program that reads the values of two integers M and then prints all the
odd numbers between the two integers. (Note: M may be less than or equal to N or
vice-versa).
9. Write a program that prints all the numbers between two integers M and N
which are divisible by an integer K. The program reads the values of M, N and K.
78
4. FUNCTIONS AND SUBROUTINES SUBPROGRAMS
Many problems consist of a number of tasks. One good technique in solving such
problems is to identify the tasks, decompose each task into sub-tasks and solve these
sub-tasks by smaller and simpler solutions.
4.1 Functions subprograms
In addition to intrinsic functions, Fortran allows you to design your own functions.
A Fortran function, or more precisely, a Fortran function subprogram, has the
following syntax:
type FUNCTION function-name (arg1, arg2, ..., argn)
IMPLICIT NONE
[specification part]
[execution part]
[subprogram part]
END FUNCTION function-name
• The first line of a function starts with the keyword FUNCTION. Before
FUNCTION, the type gives the type of the function value
(i.e., INTEGER, REAL, LOGICAL and CHARACTER) and after
FUNCTION is the name you assign to that function.
• Following the function-name, there is a pair of parentheses in which a number
of arguments arg1, arg2, ..., argn are separated with commas. These arguments
are referred to as formal arguments. Formal arguments must be variable names
and cannot be expressions. Here are some examples::
1. The following is a function called Factorial. It takes only one formal
argument n and returns an INTEGER as its function value.
INTEGER FUNCTION Factorial(n)
2. The following is a function called TestSomething. It takes three formal
79
• Between FUNCTION and END FUNCTION, there are the IMPLICIT
NONE, specification part, execution part and subprogram part. These are
exactly identical to that of a PROGRAM.
80
INTEGER FUNCTION Sum(a, b, c)
IMPLICIT NONE
INTEGER, INTENT(IN) :: a, b, c
Sum = a + b + c
END FUNCTION Sum
Example 2:
• The following function has a name Positive with a REAL formal argument. If the
argument is positive, the function returns .TRUE.; otherwise, the function
returns .FALSE.
LOGICAL FUNCTION Positive(a)
IMPLICIT NONE
REAL, INTENT(IN) :: a
The above function can be made much shorter by using LOGICAL assignment.
Example 3:
• The following function GetNumber() does not have any formal arguments and
returns an INTEGER function value. This function has a DO-loop which keeps
asking the user to input a positive number. The input is read into the function name.
If this value is positive, then EXIT and the function returns the value
in GetNumber. Otherwise, the loop goes back and asks the user again for a new
input value.
REAL FUNCTION GetNumber()
IMPLICIT NONE
DO
WRITE(*,*) 'A positive real number --> '
READ(*,*) GetNumber
IF (GetNumber > 0.0) EXIT
WRITE(*,*) 'ERROR. Please try again.'
END DO
WRITE(*,*)
END FUNCTION GetNumber
81
4.1.2 Common Problems
• Forget the type of a FUNCTION.
FUNCTION DoSomething(a, b)
IMPLICIT NONE
INTEGER, INTENT(IN) :: a, b
If there is no type, you will not be able to determine if the returned value is
an INTEGER, a REAL or something else.
• Forget INTENT(IN).
REAL FUNCTION DoSomething(a, b)
IMPLICIT NONE
INTEGER :: a, b
Actually, this is not an error. But, without INTENT(IN), our Fortran compiler will
not be able to check many potential errors for you.
• Change the value of a formal argument declared with INTENT(IN).
REAL FUNCTION DoSomething(a, b)
IMPLICIT NONE
INTEGER, INTENT(IN) :: a, b
IF (a > b) THEN
a = a - b
ELSE
a = a + b
END IF
DoSomthing = SQRT(a*a + b*b)
END FUNCTION DoSomthing
INTEGER, INTENT(IN) :: a, b
INTEGER :: c
c = SQRT(a*a + b*b)
END FUNCTION DoSomthing
82
When the execution of this function reaches END FUNCTION, it returns the value
stored in DoSomething. However, in the above, since there is no value ever stored
in DoSmething, the returned value could be anything (i.e., a garbage value).
• Function name is used in the right-hand side of an expression.
REAL FUNCTION DoSomething(a, b)
IMPLICIT NONE
INTEGER, INTENT(IN) :: a, b
In the above, function name DoSomething appears in the right-hand side of the
second expression. This is a mistake. Only a special type of
functions, RECURSIVE functions, could have their names in the right-hand side
of expressions.
• Only the most recent value stored in the function name will be returned..
REAL FUNCTION DoSomething(a, b)
IMPLICIT NONE
INTEGER, INTENT(IN) :: a, b
In the above, the value of SQRT(a*a-b*b) rather than the value of a*a + b*b is
returned. In fact, this is obvious. Since the name of a function can be considered as
a special variable name, the second assignment overwrites the previous value.
4.1.3 Examples on function subprograms
Example 1: Write a real function VOLUME that computes the volume of a sphere
(4/3 r3) given its radius.
Solution:
REAL FUNCTION VOLUME(RADIUS)
IMPLICIT NONE
REAL, INTENT (IN):: RADIUS
REAL:: PI
PI = 3.14159
VOLUME = 4.0 / 3.0 * PI * RADIUS ** 3
END FUNCTION VOLUME
83
Example 2: Write a logical function ORDER that checks whether three different
integer numbers are ordered in increasing or decreasing order.
Solution:
LOGICAL FUNCTION ORDER(X, Y, Z)
IMPLICIT NONE
INTEGER INTENT (IN):: X, Y, Z
LOGICAL:: INC, DEC
DEC = X >Y .AND. Y >Z
INC = X < Y .AND. Y < Z
ORDER = INC .OR. DEC
END FUNCTION ORDER
Example 3: Write a function subprogram to evaluate the function f(x) defined below.
f(x) = 2x2 + 4x + 2 if x < 5
f(x) = 0 if x = 5
f(x) = 3x + 1 if x > 5
Solution:
REAL FUNCTION F(X)
IMPLICIT NONE
REAL INTENT (IN):: X
IF (X < 5) THEN
F = 2 * X ** 2 + 4 * X + 2
ELSEIF (X == 5) THEN
F = 0
ELSE
F = 3 * X + 1
ENDIF
END FUNCTION F
84
Examples of correct function calls:
Function Call Function Value
ORDER(3, 2, 4) .FALSE.
ORDER(3, 4 * 3, 99) .TRUE.
F(A) 0.0
F(3 + F(2.0)) 64.0
VOLUME(B) 38808.0
F(A + B) 79.0
! FUNCTION SUBPROGRAM
INTEGER FUNCTION SUM(A, B, C)
IMPLICIT NONE
INTEGER INTENT (IN):: A, B, C
SUM = A + B + C
END FUNCTION SUM
The execution starts with the reading of variables X, Y and Z in the main program.
The execution of the expression SUM(X, Y, Z) transfers control to the function
SUM. The value of the actual arguments X, Y and Z is passed to the dummy
arguments A, B and C respectively. In the function SUM, execution begins with the
first executable statement which computes the value of SUM. The return statement
returns control to the main program. The print statement in the main program prints
the value of SUM(X, Y, Z) and the execution ends. Assume that the input to the
above program is as follows:
7 3 9
then the output of the program is
19
Programming Examples:
Example1:
86
We shall use the following function to illustrate the above rules.
Function Small() takes three formal arguments x, y and z and returns the value of
the smallest.
INTEGER :: a, b, c NTEGER FUNCTION Small(x, y, z)
IMPLICIT NONE
a = 10 INTEGER, INTENT(IN) :: x, y, z
b = 5
c = 13 IF (x <= y .AND. x <= z) THEN
WRITE(*,*) Small(a,b,c) Small = x
WRITE(*,*) Small(a+b,b+c,c) ELSE IF (y <= x .AND. y <= z) THEN
WRITE(*,*) Small(1, 5, 3) Small = y
WRITE(*,*) Small((a),(b),(c)) ELSE
Small = z
END IF
END FUNCTION Small
In the first WRITE, x, y and z in function Small() receives 10, 5 and 13,
respectively.
In the second WRITE, x, y and z receive 15, 18 and 13 respectively.
In the third WRITE, x, y and z receive 1, 5 and 3 respectively.
In the fourth WRITE, x, y and z receive 10, 5 and 13, respectively.
Example2:
Computing Cubes
Write a program to compute the cubes of 1, 2, 3, ..., 10 in
both INTEGER and REAL types. It is required to write a function intCube() for
computing the cube of an integer and a function realCube() for computing the
cube of a real.
Solution
PROGRAM Cubes
IMPLICIT NONE
INTEGER, PARAMETER :: Iterations = 10
INTEGER :: i
REAL :: x
DO i = 1, Iterations
x = i
WRITE(*,*) i, x, intCube(i), realCube(x)
END DO
END PROGRAM Cubes
! -----------------------------------------------------
! INTEGER FUNCTION intCube() :
87
! This function returns the cube of the argument.
! -----------------------------------------------------
INTEGER FUNCTION intCube(Number)
IMPLICIT NONE
INTEGER, INTENT(IN) :: Number
intCube = Number*Number*Number
END FUNCTION intCube
! -----------------------------------------------------
! REAL FUNCTION realCube() :
! This function returns the cube of the argument.
! -----------------------------------------------------
REAL FUNCTION realCube(Number)
IMPLICIT NONE
REAL, INTENT(IN) :: Number
realCube = Number*Number*Number
END FUNCTION realCube
89
WRITE(*,*)VALUE , ' F = ' , CTEMP(VALUE), ' C'
ELSE
WRITE(*,*)'INPUT ERROR'
ENDIF
END Temperature
The statement functions FTEMP and CTEMP convert the argument value to
Fahrenheit and centigrade respectively. The statement functions are placed
immediately after the declaration statements. The variables CODE and VALUE are
read. Based on the value of CODE, the appropriate statement function is invoked
and the converted value is printed.
• The first line of a subroutine starts with the keyword SUBROUTINE, followed by
that subroutine's name.
• Following subroutine-name, there is a pair of parentheses in which a number of
arguments arg1, arg2, ..., argn are separated with commas. These arguments are
referred to as formal arguments. Formal arguments must be variable names and
cannot be expressions and constants. Here are examples:
90
1. The following is a subroutine called Factorial. It has two formal
arguments n and Answer.
SUBROUTINE Factorial (n, Answer)
2. The following is a subroutine called TestSomething. It takes four formal
arguments a, b, c, and Error.
SUBROUTINE TestSomething(a, b, c, Error)
• A subroutine must end with END SUBROUTINE, followed by its name.
• Between SUBROUTINE and END SUBROUTINE, there are IMPLICIT
NONE, specification part, execution part and subprogram part. These are
exactly identical to that of a PROGRAM.
• Subroutines can be internal to a program. Subroutine can also be external and in
this case INTERFACE blocks are required.
If a subroutine does not need any formal argument, it can be written as
SUBROUTINE subroutine-name ()
IMPLICIT NONE
[specification part]
[execution part]
[subprogram part]
END SUBROUTINE subroutine-name
91
• Unlike functions, the name of a subroutine is not a special name to which you can
save a result. Subroutine's name is simply a name for identification purpose and you
cannot use it in any statement except the CALL statement.
• A subroutine receives its input values from its formal arguments, does computations,
and saves the results in some of its formal arguments. When the control of execution
reaches END SUBROUTINE, the values stored in some formal arguments are
passed back to their corresponding actual arguments.
• Any statements that can be used in a PROGRAM can also be used in
a SUBROUTINE.
4.2.1 Arguments’INTENT
We have three cases to consider:
• If an argument only receives value from outside of the subroutine, it still has its intent
like INTENT(IN). This is the simplest case.
• An argument does not have to receive anything from outside of the subroutine. It can
be used to pass a computation result back to the outside world. In this case, its intent
becomes INTENT(OUT). In a subroutine, an argument declared
with INTENT(OUT) is supposed to hold a computation result so that its value can
be passed "out".
• Finally, an argument can receive a value, use it for computation, and hold a result so
that it can be passed back to the outside world. In this case, its intent
is INTENT(INOUT).
An argument must be declared
with INTENT(IN), INTENT(OUT) or INTENT(INOUT).
Examples
Here are some examples:
Example 1:
• The following subroutine Means() has six arguments. Arguments a, b and c are
declared with INTENT(IN) and therefore can only take values from outside world
and cannot be changed. Arguments Am, Gm and Hm are declared
with INTENT(OUT), indicating that their values will be computed and passed to
92
the outside world. More precisely, in subroutine Means(), some values must be
stored into these three arguments so that they can be passed out. Note that an
argument declared with INTENT(OUT) does not have to receive any value from
outside of the subroutine.
SUBROUTINE Means(a, b, c, Am, Gm, Hm)
IMPLICIT NONE
REAL, INTENT(IN) :: a, b, c
REAL, INTENT(OUT) :: Am, Gm, Hm
..........
END SUBROUTINE Means
Example 2:
• The following subroutine Swap() has its both arguments declared with
INTENT(INOUT). That means, a and b will receive some values, after some
processing a new set of values will replace the given one so that they can be passed
back.
SUBROUTINE Swap(a, b)
IMPLICIT NONE
INTEGER, INTENT(INOUT) :: a, b
..........
END SUBROUTINE Swap
If the called subroutine has formal arguments, the CALL statement that calls that
subroutine must have actual argument. This is the first form. However, if a
subroutine does not have any argument, it can be called with the second form or the
third form.
93
Examples on Subroutine Subprograms:
Here are some simple examples:
Example 1: Write a subroutine that exchanges the value of its two real arguments.
Solution:
SUBROUTINE EXCHNG(NUM1, NUM2)
IMPLICIT NONE
REAL, INTENT(INOUT) :: NUM1, NUM2
REAL :: TEMP
TEMP = NUM1
NUM1 = NUM2
NUM2 = TEMP
END SUBROUTINE EXCHNG
94
have the values 4, 6, 8 respectively. Also assume that MAX and MIN are integer
variables. After the following CALL statement
CALL MINMAX(A, B, C, MAX, MIN)
is executed, the value of MAX will be 8 (the maximum of variables A, B, C) and
the value of MIN will be 4 (the minimum of variables A, B, C). Note that the names
of the actual arguments may be similar or different from the corresponding
dummy arguments but the type must be the same.
• If the following CALL statement
CALL MINMAX(C+4, -1, A+B, MAX, MIN)
is executed, the value of MAX will be 12 and the value of MIN will be -1, since the
first three actual arguments in the CALL statement are evaluated to 12, -1 and 10
respectively. Note here that the actual arguments can be expressions.
Example 3:
• The following has a subroutine Larger() whose job is returning the larger one of
the first two arguments with the third argument.
The main program calls subroutine Larger() with a CALL statement.
PROGRAM Example1 SUBROUTINE Larger(u, v, w)
IMPLICIT NONE IMPLICIT NONE
INTEGER a, b, c INTEGER, INTENT(IN) :: u, v
......... INTEGER, INTENT(OUT) :: w
CALL Larger(a, b, c) IF (u > v) THEN
......... w = u
END PROGRAM Example1 ELSE
w = v
END IF
END SUBROUTINE Larger
Example 4:
• In the following program, subroutine DoSomething() takes three formal
arguments. If p is greater than 3, then adds 1 to q and puts 1 into r. If p is less
then -3, then 1 is subtracted from q and 2 is stored to r. Otherwise, r receives 3
and the value of q is unchanged.
For the main program, if the value read into a is 7, then the CALL will receive 1
for b and 1 for c. If the value read into a is -4, b and c should receive -1 and 2
from subroutine DoSomething(). If a receives a value of 2, since q is not
changed
95
in DoSomething(), b and c receive 0 (unchanged) and 3, respectively.
Write a program to read three positive numbers and use a single internal subroutine
to compute the arithmetic, geometric and harmonic means.
Solution
! ----------------------------------------------------------
! This program contains one subroutine for computing the
! arithmetic, geometric and harmonic means of three REALs.
! ----------------------------------------------------------
PROGRAM Mean
IMPLICIT NONE
REAL :: u, v, w
REAL :: ArithMean, GeoMean, HarmMean
READ(*,*) u, v, w
! ----------------------------------------------------------
! SUBROUTINE Means():
! This subroutine receives three REAL values and computes
! their arithmetic, geometric, and harmonic means.
! ----------------------------------------------------------
REAL, INTENT(IN) :: a, b, c
REAL, INTENT(OUT) :: Am, Gm, Hm
Am = (a + b + c)/3.0
Gm = (a * b * c)**(1.0/3.0)
Hm = 3.0/(1.0/a + 1.0/b + 1.0/c)
END SUBROUTINE Means
The following is the output from the above program for the input
3.0, 6.0 and 8.0:
Arithmetic Mean = 5.66666651
Geometric Mean = 5.24148321
Harmonic Mean = 4.80000019
97
4.3 Exercises
1. Which of the following statement(s) is (are) FALSE?
1. A subroutine may return one value, many values, or no value.
2. A subroutine cannot call itself in FORTRAN.
3. The statement function is a non-executable statement.
4. A function may return more than one value.
5. A program may contain more than one subprogram.
6. A subroutine cannot call another subroutine.
98
3. PROGRAM EX2_3
IMPLICIT NONE
INTEGER:: K , EVL
K = 1
WRITE(*,*) EVL (K), K
END PROGRAM EX2_3
4. PROGRAM EX2_4
IMPLICIT NONE
INTEGER A, B
REAL FUN
READ(*,*)A, B
A = FUN(A, B)
B = FUN(B, A)
WRITE(*,*) FUN(A, B)
END PROGRAM EX2_4
5. PROGRAM EX2_5
IMPLICIT NONE
INTEGER:: K, L
K = -9
L = 10
WRITE(*,*) MOD(ABS(K),L)
END PROGRAM EX2_5
6. PROGRAM EX2_6
IMPLICIT NONE
REAL :: A, B, DIST, X, Y
DIST(X,Y) = SQRT(X ** 2 + Y ** 2)
READ(*,*)A, B
WRITE(*,*) DIST(A - 3.0, DIST(A, B) - 6.0)
END PROGRAM EX2_6
Assume the input is
99
6.0 8.0
7. PROGRAM EX2_7
IMPLICIT NONE
REAL ::F, G, A, B, X, Y
F(A , B) = A + B
G(X) = X ** 2
READ(*,*)Y
WRITE(*,*) G(Y), G(F(Y, Y + 2))
END PROGRAM EX2_7
Assume the input is
3.0
8. PROGRAM EX2_8
IMPLICIT NONE
LOGICAL :: COMP
REAL :: X, Y, Z, A, B, C
COMP(A, B, C) = A. GE. B .AND. A .GE. C
READ(*,*)X, Y, Z
IF (COMP(X, Y, Z)) WRITE(*,*) X
IF (COMP(Y, X, Z)) WRITE(*,*) Y
IF (COMP(Z, X, Y)) WRITE(*,*) Z
END PROGRAM EX2_8
Assume the input is
35.0 90.0 65.0
3. Write a logical function subprogram FACTOR that takes two arguments and
checks if the first argument is a factor of the second argument. Write a main program
to test the function.
5. Write a function subprogram called AREA to compute the area of a circle. The
argument to the function is the diameter of the circle. Write a main program to test
the function.
6. Write a logical function subprogram that checks whether all its three arguments
are non-zero. Write a main program to test the function.
7. Consider the following statement function IXX (J,K) = J-J/K*K. Which one of the
following intrinsic (built-in) functions is the same as the function IXX ?
i) MOD
ii) MAX
iii) MIN
iv) SQRT
100
5. Arrays
It is fairly common in programs to read a large quantity of input data, process the
data and produce the computations as output. Use array to store Such large amounts
of input data , all of the same type.
A one-dimensional array represents a group of memory locations. Each member
of an array is called an element. An element in an array is accessed by the array name
followed by a subscript (also called an index) enclosed in parentheses.
Arrays can be one- dimensional (like vectors), two-dimensional array (like
matrices). An element in a two-dimensional array is addressed by its row and
column; for example, X(3,2) refers to the element in row 3 and column 2 which has
a value 6 and Fortran allows you to create up to 7-dimensional arrays.
two-dimensional array
• The elements of arrays a and Sum are REALs and the indices are in the range
of -1 and 1.
• The elements of array InputData are INTEGERs and the indices are in the
range of 0 and 100.
LOGICAL, DIMENSION(1:100) :: AnswerSheet
REAL, DIMENSION(10:10) :: Score, Mark
In the above, the range of array AnswerSheet is 1 and 100, while the range of
arrays Score and Mark is -10 and 10.
We can declare arrays of any type. There are two common notations for declaring
array variables: using the dimension attribute or by appending the array dimensions
in parentheses to the variable name.
Example: static array declaration
program arrays
implicit none
! 1D integer array
integer, dimension(10) :: array1
! An equivalent array declaration
integer :: array2(10)
! 2D real array
real, dimension(10, 10) :: array3
102
! Custom lower and upper index bounds
real :: array4(0:9)
real :: array5(-5:5)
end program arrays
The following declarations are equivalent. Both declare an integer array a with 6
elements; an array b with 10 real elements and a logical 2-dimensional array named
yes_no.
INTEGER, DIMENSION(6) :: a
REAL, DIMENSION(0:9) :: b
LOGICAL, DIMENSION(2,2) :: yes_no
INTEGER :: a(6)
REAL :: b(0:9)
LOGICAL :: yes_no(2,2)
Use the dimension attribute form when several arrays of the same bounds and type
need to be declared. Use second form when several arrays of the same type but
different bounds need to be declared. The choice is influenced by the style followed
by the programmer but certain circumstances might dictate the use of one form rather
than another.
A mixture of the two forms in the same program is allowed. Some further examples
are shown below:
INTEGER, DIMENSION(8) :: x,y
REAL:: alpha(1:3), beta(4:9)
REAL, DIMENSION(0:5,12:45,6) :: data
CHARACTER(len=10) :: names(25)
The first example declares two arrays of the same dimension and type, therefore the
dimension attribute form is employed. The second example declares two arrays of
the same type but different dimension hence the array specification form is followed.
For the third and fourth examples any of the two forms could have been used. The
fourth example declares an array which has 25 elements with each element having a
character string of size 10.
Array Elements
An element of an array has a form of the following:
array-name ( integer-expression )
For example, suppose we have the following array declarations:
REAL, DIMENSION(-1:1) :: a, Sum
INTEGER, DIMENSION(0:100) :: Input
103
Consider array a declared above. Its elements are a(-1), a(0) and a(1). The elements
of array Input are Input(0), Input(1), …., Input(100). Moreover, if integer
variables i and j have values 3 and 8, respectively, Input(j-i) is equivalent
to Input(5), Input(i*j) is equivalent to Input(24).
However, Input(3.0) is incorrect, since array index or subscript must be integers.
The value of the integer-expression used as an index or subscript for an array
element must be in the range of the extent used to declare the array.
Examples:
Example 1: Declaration of an integer array LIST consisting of 20 elements.
INTEGER, DIMENSION (20) :: LIST
Example 2: Declaration of a logical array FLAG that consists of 30 elements.
LOGICAL, DIMENSION(30):: FLAG
Example 3 : Declaration of a character array CITIES that consists of 9 elements in
3 rows and 3 columns and each element is of size 15.
CHARACTER(LEN=15) :: CITIES (3,3)
5.2 Implied DO
Implied DO-loops provide a fast way of listing many items. These items, depending
on the place where an implied DO is used, can be variables, expressions, or even
implied DO-loops.
The syntax of an implied DO is the following:
( item-1, item-2, ...., item-n, DO-var = initial, final, step )
Depending on the place where an implied DO is used, the items can be variables,
including array elements, or expressions.
Example
• In the following, the DO variable is i and the items are a(i) and b(i+1).
( a(i), b(i+1), i = 1, 3 )
For i=1, the listed items are a(1) and b(2). For i=2, the listed items are a(2)
and b(3). For i=3, the listed items are a(3) and b(4). In summary, there are six
items listed as i goes from 1 to 3:
104
a(1), b(2), a(2), b(3), a(3), b(4)
READ(*,*) n
DO i = 1, n
READ(*,*) x(i)
END DO
In this case, if the input to n is 5. the READ(*,*) statement in the DO-loop executes
5 times. Therefore, excluding the input for n, five input lines are required.
However, the implied DO can simplify this greatly. Consider the following
example:
INTEGER, DIMENSION(1:10) :: x
INTEGER :: n, i
READ(*,*) n
READ(*,*) (x(i), i=1, n)
105
READ #1 READ #2
======= =======
INTEGER,DIMENSION(1:10) :: x INTEGER,DIMENSION(1:10) :: x
INTEGER :: n, i INTEGER :: n, i
READ(*,*) n READ(*,*) n
DO i = 1, n READ(*,*) (x(i), i=1, n)
READ(*,*) x(i)
END DO
READ #1 can certainly reads in File #1 correctly. The result is
5 10 30 20 40 50
READ #2 can certainly reads in File #2 correctly. Using READ #2 to read File
#1 would get the same result.
It is interesting to remind you that the following READ #3 can successfully read
in File #1 and File #2. Why?
READ #3
=======
INTEGER, DIMENSION(1:10) :: x
INTEGER :: n, i
106
Note again that we require 100 lines of input with one data value per line since the
READ statement is executed 100 times.
Solution 3: (Using an implied Loop)
INTEGER:: A(100), K
READ(*,*)(A(K), K = 1, 100)
Note that we require one line with 100 data values since the READ statement is
executed only once. Even if the input is given in 100 lines with one data value per
line, the implied loop will correctly read the input.
Output
Consider the following example:
INTEGER, DIMENSION(1:10) :: x, y
INTEGER :: n = 5, i
DO i = 1, 5
WRITE(*,*) x(i), y(i)
END DO
The first WRITE(*,*) is executed five times. Each time, it reads in two integers, one
for x(i) and the other for y(i). Thus, the output is on five different lines.
The second WRITE(*,*) is equivalent to
INTEGER, DIMENSION(1:10) :: x, y
INTEGER :: n = 5, i
WRITE(*,*)x(1),y(1),x(2),y(2),x(3)y(3),x(4),y(4),x(5),y(5)
Solution:
PROGRAM OUTPUT_1
IMPLICIT NONE
INTEGER, DIMENSION(4) :: x
INTEGER:: K
READ(*,*)X
! PRINTING THE ENTIRE ARRAY IN ONE LINE
WRITE(*,*) 'PRINTING THE ENTIRE ARRAY'
107
WRITE(*,*) X
! PRINTING ONE ARRAY ELEMENT PER LINE
WRITE(*,*) 'PRINTING ONE ARRAY ELEMENT PER LINE'
DO K = 1, 4
WRITE(*,*) X(K)
END DO
! PRINTING ARRAY ELEMENTS GREATER THAN 0
WRITE(*,*) 'PRINTING ARRAY ELEMENTS GREATER THAN 0'
DO K = 1, 4
IF(X(K) >0) WRITE(*,*) X(K)
END DO
END PROGRAM OUTPUT_1
If the input is given as
7, 0, 2, -4
the output of the program is as follows:
PRINTING THE ENTIRE ARRAY
7 0 2 -4
PRINTING ONE ARRAY ELEMENT PER LINE
7
0
2
-4
PRINTING ARRAY ELEMENTS GREATER THAN
7
2
PROGRAM Counting
IMPLICIT NONE
INTEGER, DIMENSION(50) :: A
INTEGER:: COUNT, N , K
READ(*,*)N, (A(K), K = 1, N)
COUNT = 0
DO K = 1, N
IF (MOD (A(K), 2) .EQ. 1) COUNT = COUNT + 1
END DO
WRITE(*,*) 'COUNT OF ODD ELEMENTS = ', COUNT
END PROGRAM Counting
If the input is:
7, 35, 66, 83, 22, 33, 1, 89
The value of variable N in this example is 7. The next seven input data values are
109
placed in the array. There are 5 odd values among the seven elements of the array.
For the given input, the output is as follows:
COUNT OF ODD ELEMENTS = 5
Example 2: More on Reading Two-Dimensional Arrays: Write a FORTRAN
program that reads a two dimensional array of size 5 x 4 row-wise. Each value is
read from a separate line of input. The program then prints the same array column-
wise such that the elements of the first column are printed on the first line of output
and the elements of the second column are printed on the second line of output and
so on.
Solution :
PROGRAM Reading
IMPLICIT NONE
INTEGER, DIMENSION(5,4) :: TDIM
INTEGER :: ROW , COL
DO ROW = 1, 5
DO COL = 1, 4
READ(*,*)TDIM(ROW , COL)
END DO
END DO
DO COL = 1, 4
WRITE(*,*) (TDIM(ROW , COL), ROW = 1 , 5)
END DO
END PROGRAM Reading
Let us first consider the reading segment. Reading is done using two nested loops.
The outer loop index corresponds to the rows of the two-dimensional array. The
inner one corresponds to the columns. Hence, the array TDIM is read row-wise. Note
that the READ statement is executed 20 times and therefore 20 input lines are
required with one data value per line. In the printing segment, we used an implied
loop inside a DO loop.
5.6 Arrays and Subprograms
Arrays can be passed to a subprogram or can be used locally within a subprogram.
In both the cases, the array must be declared within the subprogram. The following
examples illustrate the use of one-dimensional arrays in a subprogram.
Example 1: Summation of Array Elements: Read 4 data values into an array LIST
(of size 10) and print the sum of all the elements of array LIST using a function SUM.
Solution:
110
PROGRAM Summation
IMPLICIT NONE
INTEGER, DIMENSION(10) :: LIST
INTEGER :: SUM, K
READ(*,*)(LIST(K), K = 1, 4)
WRITE(*,*) SUM(LIST, 4)
END PROGRAM Summation
PROGRAM Reverse
IMPLICIT NONE
112
END DO ! loop back
113
5.7.1 Exercises 0n dimension array
1. What is printed by the following programs?
1. program Exercises5
implicit none
INTEGER:: A(3), J
A(1) = 1
DO J = 2, 3
A(J) = 3 * A(J - 1)
END DO
WRITE(*,*) A
END Exercises5
2. program Exercises5
implicit none
INTEGER:: A(3), K
READ(*,*)A
DO K = 1,3
A(3) = A(3) + A(K)
END DO
WRITE(*,*) A(3)
END Exercises5
Assume the input for the program is:
10,20,30
3. program Exercises5
implicit none
INTEGER:: X(5), Y(5), N, K
READ(*,*)N, (X(K),Y(K),K=1,N)
DO K=X(N),Y(N)
WRITE(*,*) ('X',J=X(K),Y(K))
END DO
END Exercises5
Assume the input for the program is:
4,1,2,3,3,3,4,2,4
2. The following program segments may or may not have errors. For each one of
the segments, identify the errors(if any). Assume the following declarations :
INTEGER:: M(4)
LOGICAL:: L
a. DO K = 2,5,2
READ(*,*)M(K-1)
END DO
Assume the input for the program is:
20,40,50,30,60
b. DO K = 1,4
M(K+1) = -K
END DO
114
3. Consider the following subroutine :
SUBROUTINE CHECK(A,B,C,N)
INTEGER, INTENT(IN) :: A(10), B(5),N
INTEGER, INTENT(OUT) :: C
If the only declaration and assignment statement in the main program are the
following:
INTEGER ::X(5), M(10), A
A = 3
Which of the following CALL statements is correct assuming that X and M have
some value ?
A) CALL CHECK(M,X,C)
B) CALL CHECK(M(10),X(5),C,5)
C) CALL CHECK(M,X,B,A+2)
D) CALL CHECK(M,X,N,A)
E) CALL CHECK
2. program Exercises5
implicit none
REAL:: B(2,3), F
INTEGER:: J, K
F(X, Y) = X + Y * 2
READ(*,*)((B(J,K), K = 1, 2), J = 1, 2)
DO J = 1, 2
B(J,3) = F(B(J,1), B(J,2))
END DO
115
WRITE(*,*) B
END program Exercises5
3. program Exercises5
implicit none
INTEGER:: A(3,3) , J, K
READ(*,*)((A(K,J),K=1,3),J=1,3)
WRITE(*,*) A
WRITE(*,*) ((A(K,J),J=1,2),K=1,3)
WRITE(*,*) A(3,2)
WRITE(*,*) (A(K,2),K=3,1,-2)
END program Exercises5
Assume the input is:
1 2 3
4
5 6 7 8
9
4. program Exercises5
implicit none
INTEGER:: A(2,2) , J, K
READ(*,*)A
DO J = 1,2
WRITE(*,*) (A(J,K), K=1,2)
END DO
END program Exercises5
Assume the input is:
1 2 3 4
II DO J = 1,10
READ(*,*)(Z(K,J),K=1,10)
END DO
III. DO K = 1,10
DO J = 1,10
READ(*,*)Z(J,K)
END DO
END DO
116
6. OUTPUT DESIGN AND FILE PROCESSING
6.1 Output Formatting
The write statement we have been using in the previous chapters is a list-directed
output statement. In list-directed output, the output list determines the precise
appearance of printed output. In other words, we have no control over the format of
the output. To control the manner in which the output is printed or to produce an
output in a more readable form, we use FORMAT statements. The general form of
a formatted WRITE statement is
WRITE(*,K) expression list
Where K : FORMAT statement label , identifies a format to be used by the print
statement. The statement number can be any positive INTEGER constant.
The format statement may be used to read or write data in a form other than the
default format, for example:
READ (*,100) i, j
WRITE (*,100) i, j
READ (*,200) x, y
WRITE (*,200) x, y
.....
100 FORMAT (2I)
200 FORMAT (2F10.6)
117
30 FORMAT( 2F12.6 )
replaced by
READ (*,'(2I)') I, J
WRITE (*,'(2F12.6)') X, Y
Fortran format is to master many format edit descriptors. In the following are the
editor descriptors to be discussed.
Examples
Let us look at the following example. There are three INTEGER variables a ,
b and c with values 123, -123 and 123456, respectively. In the following table,
the WRITE statements are shown in the left and their corresponding output, all
using five positions, are shown in the right.
WRITE(*,``(I5)``) a 1 2 4
WRITE(*,``(I5)``) b - 1 2 4
WRITE(*,``(I5)``) c * * * * *
118
Consider the following example.
INTEGER :: a = 3, b = -5, c = 128
WRITE(*,"(3I4)") a, b, c
The edit descriptor is 3I4 and the format is equivalent to (I4,I4,I4) . Therefore, each
of the three INTEGER variables is printed with I4. Based on the discussion earlier,
the result is the following:
3 - 5 1 2 8
Example 1: What is the minimum I specification needed to print each of the
following integers?
345, 67, -57, 1000, 123456
Solution:
Number I specification
345 I3
67 I2
-57 I3
1000 I4
123456 I6
Example 2: What will be printed by the following program?
INTEGER:: M
M = -356
WRITE(*,10) M
10 FORMAT(' ', I4)
END DO
Solution:
....+....1....+....2
-356
Notice that the carriage control character ' ' did not appear in the output. This
characters indicates that the output line is single spacing.
Example 3: If the FORMAT statement in the previous example is modified as
follows:
FORMAT(' ', I3)
What will be printed?
Solution:
....+....1....+....2....+....3.
***
119
Example 4: Assume K = -244 and M = 12. The following PRINT statements will
produce the shown outputs.
a. WRITE(*,10) K
10 FORMAT(' ', I4)
....+....1....+....2....+....3.
-244
b. WRITE(*,20) K, M
20 FORMAT(' ', I5, I6)
....+....1....+....2....+....3.
-244 12
c. WRITE(*,30) K
WRITE(*,35) M
30 FORMAT(' ', I3)
35 FORMAT(' ', I2)
....+....1....+....2....+....3
***
12
d. WRITE(*,40) K + M
40 FORMAT(' ', I5)
....+....1....+....2....+....3....+....4.
-232
....+....1....+....2....+....3.
1 3 5 135 135 135
Then, all four variables receive the same value, 135.
120
Examples
Suppose we have the following input and the system ignores spaces.
....+....1....+....2....+....3.
12 34 56 78 90
• What are the values in each variable after reading in the above input?
INTEGER :: a, b, c, d
READ(*,"(I1, I2, I3, I4)") a, b, c, d
Variable a receives 12. Variable b receives 34. Variable c receives 5678. Finally,
Variable d receives zero.
6.3 REAL Output: The F Descriptor
The Fw.d descriptor is for REAL output. The general form is:
rFw.d
The meaning of r, w and d are:
• F is for REAL
• w is the width of field, which indicates that a real number should be printed
with w positions.
• d indicates the number of digits after the decimal point. More precisely, of
these w positions, the right-most d positions are for the fraction part of a real
number, and the d+1 position from the right is a decimal point. The remaining w-
(d+1) positions are for the integral part. This is shown in the figure below:
• Note that the integral part contains a sign and as a result w should be greater than
or equal to d+2.
• The fractional part may have more than d digits. In this case, the (d+1)th digit
will be rounded to the dth one. For example, if 1.73 is printed with F3.1, since
121
the second digit of the fractional part is 3, the result is 1.7. However, if 1.76 is
printed with F3.1, the result becomes 1.8 because 6 is rounded.
• The fractional part may have fewer than d digits. In this case, trailing zeros will
be added.
• Note that d can be zero. In this case, no fractional part will be printed. More
precisely, the right-most position is the decimal point.
• r is the repetition indicator, which gives the number of times the edit descriptor
should be repeated. For example, 3F5.3 is equivalent to F5.3, F5.3, F5.3.
Examples
Let us look at the following example. There are two REAL variables a and b with
values 123.345 and -123.345, respectively. In the following table,
the WRITE statements are shown in the left and their corresponding output, all
using five positions, are shown in the right.
REAL:: a =123.345, b = -123.345
WRITE(*,”(F10.0)”) a 1 2 3 .
WRITE(*,”(F10.2)”) a 1 2 3 , 3 5
WRITE(*,”(F10.5)”) a 1 2 3 , 3 5 5 0 0
WRITE(*,”(F10.7)”) a * * * * * * * * * *
WRITE(*,”(F10.4)”) b - 1 2 3 , 3 5 5 0
WRITE(*,”(F10.6)”) b * * * * * * * * * *
1 2 3 4 5 6 7 8 9 10
Consider the following example. The WRITE statement has three REAL variables
and consequently the format must also have three F edit descriptors, one for each
variable.
REAL :: a = 12.34, b = -0.945, c = 100.0
WRITE(*,"(3F6.2)") a, b, c
122
Example 1: What is the minimum F specification needed to print the following real
numbers?:
823.67509, 0.002, .05, -.05, -0.0008
Solution:
Number F specification
823.67509 F9.5
0.002 F5.3
.05 F3.2
-.05 F4.2
98. F3.0
98.0 F4.1
-0.0008 F7.4
Example 2: What will be printed by the following program?
program OUTPUT_F2
implicit none
REAL:: X
X = 31.286
WRITE(*,10) X
10 FORMAT(' ', F6.3)
END OUTPUT_F2
Solution: The printed output on a new page is as follows:
....+....1....+....2....+....3.
31.286
Example 3: If the FORMAT statement in the previous example is modified as
follows:
FORMAT(' ', F8.4)
What will be printed?
Solution:
....+....1....+....2....+....3.
31.2860
Example 4: If the FORMAT statement in the previous example is modified as
follows:
FORMAT(' ', F5.3)
What will be printed?
Solution:
....+....1....+....2....+....3.
*****
123
Example 5: Assume X = -366.126, Y = 6.0 and Z = 20.97. The following PRINT
statements will produce the shown outputs.
a. WRITE(*,10) X
10 FORMAT(' ', F11.5)
....+....1....+....2....+....3.
-366.12600
b. PRINT 20, X
20 FORMAT(' ', F8.3)
....+....1....+....2....+....3.
-366.126
c. WRITE(*,30) Z
WRITE(*,35) Y
30 FORMAT(' ', F4.1)
35 FORMAT(' ', F4.2)
....+....1....+....2....+....3.
21.0
6.00
d. WRITE(*,40) X / Y
40 FORMAT(' ', F7.3)
....+....1....+....2....+....3....+....4.
-61.210
124
The Ew.d descriptor generates real numbers in the following form:
Of these w positions, the last three are for the exponent, including its sign, the
middle d positions are for the number in normalized form. Therefore, excluding the
exponent part, there are w-4 positions for printing the digits of the normalized
number. In fact, you can consider the normalized number is printed with Fw-4.d. The
above figure also includes a 0 and a decimal point. If the number is negative, we
must also include its sign. Hence, 4+3=7 positions are not available for printing the
normalized number and, as a result, when you use the E edit descriptor, w must be
greater than or equal to d+7; otherwise, your number may not be printed properly
and all w positions will be filled with asterisks.
Examples
In the following table, the WRITE statements use different E edit descriptors to
print the value of 3.1415926. The WRITE statements are shown in the left and
their corresponding output, all using 12 positions, are shown.
REAL :: PI=3.1415926
WRITE(*,10) PI
10 FORMAT (E12.5)
Output
0 . 3 1 4 1 6 E + 0 1
1 2 3 4 5 6 7 8 9 10 11 12
The following table shows some examples of real numbers and their presentation in
FORTRAN:
Real Decimal Notation FORTRAN Representation
Number
6.3 x 10-5 0.000063 0.63E-04
4.932 x 107 49320000.0 0.4932E+08
-5.7 x 10-6 -0.0000057 -0.57E-05
5.7 x 10-6 0.0000057 0.57E-05
5.7 x 106 5700000.0 0.57E+07
125
REAL Input: E Descriptors
Suppose we have the following:
REAL :: u
READ(*,"(F10.4)") u
and the input is
....+....1....+....2....+....3.
12345E20
then u takes the first ten positions. The exponent is 20 and 12345 is read in with 4
digits in the fractional part. Therefore, the actual value read in is 1.2345×1020.
Examples
Suppose we have the following input and the system.
....+....1....+....2....+....3.
12 3.4 56E 78. 90
What are the values in each variable after reading in the above input?
REAL :: a, b, c, d
READ(*,"(F3.0, F4.1, F6.2, F7.3)") a, b, c, d
126
• The output of a LOGICAL value is either T for .TRUE. or F for .FALSE. The
single character value is shown in the right-most position and the remaining w-
1 positions are filled with spaces. The is shown in the figure below.
128
Since w is larger than the length of the string, all five characters are printed and
right-justified. The result is shown below:
1 2 3 4 5
o If w is less than the length of the character string, then the string
is truncated and only the left-most w positions are printed in
the w positions. The following example prints the string "12345678" of length
8 (i.e., eight characters) using A6.
WRITE(*,'(A6)') "12345678"
Since w is less than the length of the string, only the first six characters are
printed. The result is shown below:
1 2 3 4 5 6
o If w is equal to the length of the character string, then it is an exact match. All
characters can be printed and all w positions are filled.
o If w is missing, then the value of w is assumed to be the length of the
string. The following example shows two WRITE statements. The first one
uses A to print a, a string of length 5. The second one also uses A to print b, a
string of length 2.
CHARACTER(LEN=5) :: a = "abcde"
CHARACTER(LEN=2) :: b = "MI"
WRITE(*,'(A)') a
WRITE(*,'(A)') b
Since the A edit descriptor will use the length of the string as the value of w, the
above is equivalent to the following:
CHARACTER(LEN=5) :: a = "abcde"
CHARACTER(LEN=2) :: b = "MI"
WRITE(*,'(A5)') a
WRITE(*,'(A2)') b
Therefore, the A edit descriptor is more convenient than Aw.
• r is the repetition indicator, which gives the number of times the edit descriptor
should be repeated. For example, 3A5 is equivalent to A5, A5, A5, and 3A is
equivalent to A, A, A.
129
• Please keep in mind that the length of the string includes trailing spaces. For
example, if we have the following:
CHARACTER(LEN=5) :: a = "123"
CHARACTER :: b = "*"
WRITE(*,"(A,A)") a, b
it is equivalent to
CHARACTER(LEN=5) :: a = "123"
CHARACTER :: b = "*"
WRITE(*,"(A5,A1)") a, b
Example 1:
Let us look at the following example.
CHARACTER(LEN=5) :: a = "12345"
CHARACTER :: b = "*"
In the following table, the WRITE statements are shown at the left and their
corresponding output are shown at the right.
a =”12345” b =”*”
WRITE(*,”(A1, A)”) a, b 1 *
WRITE(*,”(A2, A)”) a, b 1 2 *
WRITE(*,”(A3, A)”) a, b 1 2 3 *
WRITE(*,”(A4, A)”) a, b 1 2 3 4 *
WRITE(*,”(A5, A)”) a, b 1 2 3 4 5 *
WRITE(*,”(A6, A)”) a, b 1 2 3 4 5 *
WRITE(*,”(A7, A)”) a, 1 2 3 4 5 *
WRITE(*,”(A, A)”) a, 1 2 3 4 5 *
1 2 3 4 5 6 7 8
PROGRAM WRITE_L_E2
IMPLICIT NONE
CHARACTER :: TEXT*5 TEXT = 'KFUPM'
130
WRITE (*,”(A, 3X, A3, 3X, A9)”) TEXT, TEXT, TEXT
END PROGRAM WRITE_L_E2
Solution:
....+....1....+....2....+....3....+....4.
KFUPM KFU KFUPM
READ(*,"(4A5)") a, b, c, d
This example has three variables and six edit descriptors in the format. This is a
simple case. Here is the answer:
variables a, b and c are printed with I5, I5 and I5. The three unused I5s are
ignored.
• The number of variables is greater than the number of edit descriptors. This is
shown with the following example:
INTEGER :: a = 1, b = 2, c = 3, d = 5, e = 8
CHARACTER(LEN=20) :: FMT = "(I4, I3)"
WRITE(*,FMT) a, b, c, d, e
This example has five variables; but the format to print them has only two edit
descriptors.
Examples
• The following has an array x with maximum number of elements 100. But, the
actual number of elements in x depends on the input. The WRITE statement
always prints the elements of x five elements per row.
INTEGER, DIMENSION(1:100) :: x
INTEGER :: n
INTEGER :: i
WRITE(*,"(5E17.7)") (x(i), i = 1, n)
The format has five E17.7s. Therefore, after x(1) to x(5) are printed, x(6) to x(10)
are printed on the second line, followed by x(11) to x(15) on the third line and so on
until all n elements of x are printed.
• How about the follow example, which is a slightly modified version of the above.
INTEGER, DIMENSION(1:100) :: x
INTEGER :: n
132
INTEGER :: i
• Note that the program below prints the same output; but it uses a DO-END DO.
Obviously, the version above is shorter.
INTEGER, DIMENSION(1:100) :: x
INTEGER :: n
INTEGER :: i
Programming Example:
Write a program that for each INTEGER in the range of 1 and 5, prints its value,
square, cube and square root.
Solution
PROGRAM Squares_and_Roots
IMPLICIT NONE
INTEGER, PARAMETER :: MAXIMUM = 5
INTEGER :: i
CHARACTER(LEN=30) :: Format
1 2 3 4 5 6 7 8 0 1 2
2x I4 3X F5.2 2X A4
READ(*,FMT) a, b, c
It should generate the following output:
134
prints the following output:
....+....1....+....2....+....3....+....4.
-3.6212.5
The output is not readable because the two printed values are not separated by blanks.
If we modify the format statement using X specification as follows:
FORMAT(' ', F5.2, 3X, F4.1)
the output becomes:
....+....1....+....2....+....3....+....4.
-3.62 12.5
The X specification can be used as a carriage control character. The following pairs
of FORMAT statements print the same output.
10 FORMAT(' ', I2)
is equivalent to
10 FORMAT(1X, I2)
and
20 FORMAT(' ', 2X, F4.1)
is equivalent to
20 FORMAT(3X, F4.1)
The slash edit descriptor / is used to terminate the current input/output line. The
general forms of this descriptor are as follows:
/ and r/
• For Input: The current input line is skipped and the remaining unread content on
the current input line is ignored. The reading process starts at the first position on
the next input line.
• For Output: The current output line is printed and the next output item, including
the printer control character, starts at the first position of a new buffer output line.
• While commas are used for separating two neighboring edit descriptors, they are
not required if one of these two neighboring edit descriptors is a /. For example,
the following
READ(*,"(I3,5X,I5,/,/,T15,F10.0)") ......
135
is equivalent to
READ(*,"(I3,5X,I5//T15,F10.0)") ......
r is equivalent to writing / r times. For example, 4/ is equivalent to ////.
Examples
Consider the following input:
....+....1....+....2....+....3....+....4.
123 456
789 012
345 678
Suppose this input is read by the following READ statement.
INTEGER :: a, b, c
READ(*,"(I5/I5/I5)") a, b, c
The reading starts with the first input line. Thus, a receives a value of 123. Since the
next edit descriptor is a /, the content on the current input line is ignored. As a result,
, the value for b receives 789. After this, we see a second / which causes ignoring
the remaining of the second input line. Therefore, the value for c receives 345.
Consider the following input:
....+....1....+....2....+....3....+....4.
123 456
789 012
345 678
901 234
567 890
135
Suppose this input is read by the following READ statement.
INTEGER :: a, b, c, d
READ(*,"(I5//I5/I5/)") a, b, c
READ(*,"(I5)") d
a is receives 123. b receives 345 from the third input line. After reading b, we have
a / and c will use the fourth input line. Hence, c receives 901. The sixth input line is
read and d receives 135.
The above discussion is illustrated with the figure below.
136
6.7.3 Grouping: r( )
Sometimes we want to repeat several edit descriptors rather than a single one. In
this case, you can group several edit descriptors together using ( ). This grouping
descriptor has the following general forms:
r( ) and ()
The meaning of r( ) and ( ) are:
• For the form of r(....), the edit descriptors within () repeat r times. For example,
(1X, 3(I5, F5.2), A)
is equivalent to the following:
(1X, I5, F5.2, I5, F5.2, I5, F5.2, A)
• Grouping can also be nested. Suppose we have the following
(1X, 3(I5, 2(I4, A3)), A)
Then, we can expand 3(...) into the following:
(1X, I5, 2(I4, A3), I5, 2(I4, A3), I5, 2(I4, A3), A)
After expanding all 2(...)'s, we have the final equivalent format:
(1X, I5, I4, A3, I4, A3, I5, I4, A3, I4, A3, I5, I4, A3, I4, A3, A)
Examples:
The following pairs of FORMAT statements illustrate the use of repetition
constants:
WRITE(*,”(3X, I2, 3X, I2)”)
is equivalent to
WRITE(*,”(2(3X, I2)”)
and
137
WRITE(*,”(F5.1,F5.1,F5.1,5X,I3,5X,I3,5X,I3,5X,I3)”)
is equivalent to
WRITE(*,”(3F5.1,4(5X, I3)”)
138
OPEN(UNIT = 1, FILE = 'POINTS DATA', STATUS = 'OLD')
Example 2: Assume that you want to use file RESULT DATA as an output file. The
following statement will then appear before any write statement to the file:
OPEN(UNIT = 1, FILE = 'RESULT DATA',STATUS = 'UNKNOWN')
139
COUNT = 0
333 READ(12, *, END = 999) NUM
SUM = SUM + NUM
COUNT = COUNT + 1
GOTO 333
999 AVG = SUM / COUNT
WRITE(*,*) AVG
PROGRAM OPEN_FILE
6.8.3 Writing to Files
To write to a file, the file must have been opened using an OPEN statement and the
WRITE statement must be used in the following form:
WRITE(UNIT, *) EXPRESSION LIST
where UNIT is the same value that is used in the OPEN statement. The rules of
writing to a file are exactly the same as those of the print statement. The * in the
WRITE statement indicates that the output is free formatted. If format is needed, the
format statement number is used instead.
Example: Create an output file CUBES DATA that contains the table of the cubes
of integers from 1 to 20 inclusive.
Solution:
PROGRAM OPEN_FILE
IMPLICIT NONE
INTEGER:: NUM
OPEN(UNIT =20, FILE ='CUBES DATA',STATUS = 'UNKNOWN')
DO NUM = 1, 20
WRITE(20, *) NUM, NUM**3
END DO
PROGRAM OPEN_FILE
Format statement could be used with the write statement in the same way it is used
with the print statement. The * in the write statement is replaced with the format
statement number.
140
6.9 Exercises
1. What will be printed by each of the following programs?
1. PROGRAM EX_FILE
IMPLICIT NONE
REAL ::X
X = 123.8367
WRITE(*,”(F7.2, 2X, F6.2, F9.5) “)X, X, X
END PROGRAM EX_FILE
2. PROGRAM EX_FILE
IMPLICIT NONE
INTEGER:: J, K, N
K = 123
J = 456
N = 789
WRITE(*,”(I3) “)K
WRITE(*,”(3X,I3) “)J
WRITE(*,”(6X,I3) “)N
END PROGRAM EX_FILE
4. PROGRAM EX_FILE
IMPLICIT NONE
INTEGER:: ARR(5), K
READ(*,*)( ARR(K), K = 1, 5)
DO K = 1, 5
WRITE(*,”(I4)”)ARR(K)
END DO
END PROGRAM EX_FILE
Assume the input for the above program is:
10 20 30 40 50
Which of the above FORMAT statements can be used in place of the FORMAT
statement in the program to print the output as follows?
....+....1....+....2....+....3....+....4.
469 17.4
142
5. What will be printed by the following programs?
1. IMPLICIT NONE
INTEGER:: M, K
OPEN(UNIT = 10,FILE ='INPUT DATA',STATUS='OLD')
READ(10,*) ( M, K = 1,100)
10 WRITE(*,*) M, K-1
END
2. IMPLICIT NONE
INTEGER:: J, K
OPEN (UNIT = 3, FILE = 'FF1',STATUS = 'OLD')
DO J=1,100
READ ( 3,*,END = 60) K
END DO
WRITE(*,*) 'THE VALUES ARE:'
WRITE(*,*) K,J
END
The contents of the file 'FF1' are:
20 50 67 45 18 -2 -20
88 66 77 105 55 300
143