Com221 Fortran Lang
Com221 Fortran Lang
Com221 Fortran Lang
Fortran – Overview
FORTRAN (FORmula TRANslation) is a third-generation ( 3GL ) programming language that
was designed for use by engineers, mathematicians, and other users and creators of scientific
algorithms. It has a very succinct and spartan syntax. Today, the C language has largely
displaced FORTRAN.
History
One of the oldest programming languages, the FORTRAN was developed by a team of
programmers at IBM led by John Backus, and was first published in 1957. The name FORTRAN
is an acronym for FORmula TRANslation, because it was designed to allow easy translation of
math formulas into code.
Often referred to as a scientific language, FORTRAN was the first high-level language, using the
first compiler ever developed. Prior to the development of FORTRAN computer programmers
were required to program in machine/assembly code, which was an extremely difficult and time
consuming task, not to mention the dreadful chore of debugging the code. The objective during
it's design was to create a programming language that would be: simple to learn, suitable for a
wide variety of applications, machine independent, and would allow complex mathematical
expressions to be stated similarly to regular algebraic notation.
The American Standards Association (now known as the American National Standards
Association) had released its first Standard for a Programming Language in 1966. This first
standardized version has come to be known as FORTRAN '66 (aka.. FORTRAN IV).
Despite this standardization, a few years later, various new dialects began to surface again,
requiring the Standards Association review the language again. This version is known as
FORTRAN '77. This version was released in 1978 (it was called '77 because the Association
began it's review in 1977), with several new features. Some of the more notable properties
were; new error handling methods, and mechanisms for managing large-scale programs. The
latest version; Fortran '90 (released in 1990, using the new capitalization scheme) added even
more new features, such as support for: recursion, pointers, and for programmer-defined data
types.
Some of the more significant features of the language are as listed below:
Simple to learn - when FORTRAN was design one of the objectives was to write a
language that was easy to learn and understand.
Machine Independent - allows for easy transportation of a program from one machine
to another.
More natural ways to express mathematical functions - FORTRAN permits even
severely complex mathematical functions to be expressed similarly to regular algebraic
notation.
Problem orientated language
Remains close to and exploits the available hardware
FORTRAN[221] |2
Areas of Application
FORTRAN is useful for a wide variety of applications, some of the more outstanding ones are as
follows:
Number crunching - due to the more natural (like it's true algebraic form) way of
expressing complex mathematical functions and it's quick execution time, FORTRAN is
easy and efficient at processing mathematical equations.
Scientific, mathematical, statistical, and engineering type procedures - due to it's
rapid number-crunching ability FORTRAN is a good choice for these type of applications.
Each program contains one main program and may or may not contain other program units.
The syntax of the main program is as follows:
program program_name
implicit none
! type declaration statements
! executable statements
end program program_name
Program addNumbers .
! This simple program adds two numbers
implicit none
! Type declarations
real :: a, b, result
! Executable statements
a = 12.0
b = 15.0
result = a + b
print *, 'The total is’ ,result
FORTRAN[221] |3
When you compile and execute the above program, it produces the following result:
All Fortran programs start with the keyword program and end with the keyword end
program, followed by the name of the program.
The implicit none statement allows the compiler to check that all your variable types
are declared properly. You must always use implicit none at the start of every program.
Comments in Fortran are started with the exclamation mark (!), as all characters after
this (except in a character string) are ignored by the compiler.
Fortran allows both uppercase and lowercase letters. Fortran is case-insensitive, except
for string literals.
Basics
The basic character set of Fortran contains:
Identifier
An identifier is a name used to identify a variable, procedure, or any other user-defined item. A
name in Fortran must follow the following rules:
It must be composed of alphanumeric characters (all the letters of the alphabet, and the
digits 0 to 9) and underscores (_).
Keywords
FORTRAN[221] |4
Keywords are special words, reserved for the language. These reserved words cannot be used
as identifiers or names.
end interface end module end program end select end subroutine
Where While
Integer type
Real type
Complex type
Logical type
Character type
Integer Type
The integer types can hold only integer values. The following example extracts the largest value
that can be held in a usual four byte integer:
program testingInt
implicit none
integer :: largeval
print *, huge(largeval)
end program testingInt
When you compile and execute the above program it produces the following result:
2147483647
Note that the huge() function gives the largest number that can be held by the specific integer
data type. You can also specify the number of bytes using the kind specifier. The following
example demonstrates this:
program testingInt
implicit none
!two byte integer
integer(kind=2) :: shortval
!four byte integer
integer(kind=4) :: longval
!eight byte integer
integer(kind=8) :: verylongval
!sixteen byte integer
integer(kind=16) :: veryverylongval
!default integer
integer :: defval
print *, huge(shortval)
print *, huge(longval)
print *, huge(verylongval)
print *, huge(veryverylongval)
print *, huge(defval)
end program testingInt
When you compile and execute the above program, it produces the following result:
32767
2147483647
9223372036854775807
170141183460469231731687303715884105727
2147483647
Real Type
It stores the floating point numbers, such as 2.0, 3.1415, -100.876, etc.
Traditionally there are two different real types, the default real type and double
precision type. However, Fortran 90/95 provides more control over the precision of real and
integer data types through the kind specifier, which we will study in the chapter on Numbers.
program division
implicit none
! Define real variables
real :: p, q, realRes
! Define integer variables
integer :: i, j, intRes
! Assigning values
p = 2.0
q = 3.0
i = 2
j = 3
! floating point division
realRes = p/q
intRes = i/j
print *, realRes
print *, intRes
end program division
When you compile and execute the above program it produces the following result:
0.666666687
0
Complex Type
This is used for storing complex numbers. A complex number has two parts, the real part and
the imaginary part. Two consecutive numeric storage units store these two parts.
For example, the complex number (3.0, -5.0) is equal to 3.0 – 5.0i
Logical Type
There are only two logical values: .true. and .false.
Character Type
The character type stores characters and strings. The length of the string can be specified by
len specifier. If no length is specified, it is 1.
Variable names starting with i, j, k, l, m, or n, are considered to be for integer variable and
others are real variables. However, you must declare all the variables as it is good programming
practice. For that you start your program with the statement:
implicit none
This statement turns off implicit typing.
FORTRAN[221] |7
Fortran – Variables
A variable is nothing but a name given to a storage area that our programs can manipulate.
Each variable should have a specific type, which determines the size and layout of the variable's
memory; the range of values that can be stored within that memory; and the set of operations
that can be applied to the variable.
The name of a variable can be composed of letters, digits, and the underscore character. A name
in Fortran must follow the following rules:
Variable Declaration
Variables are declared at the beginning of a program (or subprogram) in a type declaration
statement.
type-specifier :: variable_name
For example,
integer :: total
real :: average
complex :: cx
logical :: done
character(len=80) :: message ! a string of 80 characters
Later you can assign values to these variables, like,
total = 20000
average = 1666.67
done = .true.
message = “A big Hello from Softecks”
cx = (3.0, 5.0) ! cx = 3.0 + 5.0i
You can also use the intrinsic function cmplx, to assign values to a complex variable:
cx = cmplx (1.0/2.0, -7.0) ! cx = 0.5 – 7.0i
FORTRAN[221] |8
cx = cmplx (x, y) ! cx = x + yi
Example
The following example demonstrates variable declaration, assignment and display on screen:
program variableTesting
implicit none
! declaring variables
integer :: total
real :: average
complex :: cx
logical :: done
character(len=80) :: message ! a string of 80 characters
!assigning values
total = 20000
average = 1666.67
done = .true.
message = "A big Hello from Softecks"
cx = (3.0, 5.0) ! cx = 3.0 + 5.0i
Print *, total
Print *, average
Print *, cx
Print *, done
Print *, message
end program variableTesting
When the above code is compiled and executed, it produces the following result:
20000
1666.67004
(3.00000000, 5.00000000 )
T
A big Hello from Softecks
Fortran – Constants
The constants refer to the fixed values that the program cannot alter during its execution. These
fixed values are also called literals.
Constants can be of any of the basic data types like an integer constant, a floating constant, a
character constant, a complex constant, or a string literal. There are only two logical
constants : .true. and .false.
The constants are treated just like regular variables, except that their values cannot be
modified after their definition.
Literal constants
Named constants
A literal constant have a value, but no name.
FORTRAN[221] |9
Type Example
Named constants should be declared at the beginning of a program or procedure, just like a
variable type declaration, indicating its name and type. Named constants are declared with the
parameter attribute. For example,
Example
The following program calculates the displacement due to vertical motion under gravity.
program gravitationalDisp
implicit none
! gravitational acceleration
! variable declaration
real :: s ! displacement
real :: t ! time
! assigning values
F O R T R A N [ 2 2 1 ] | 10
t = 5.0
u = 50
! displacement
s = u * t - g * (t**2) / 2
! output
When the above code is compiled and executed, it produces the following result:
Time = 5.00000000
Displacement = 127.374992
Fortran – Operators
An operator is a symbol that tells the compiler to perform specific mathematical or logical
manipulations. Fortran provides the following types of operators:
Arithmetic Operators
Relational Operators
Logical Operators
Let us look at all these types of operators one by one.
Arithmetic Operators
Following table shows all the arithmetic operators supported by Fortran. Assume
variable A holds 5 and variable B holds 3 then:
** Exponentiation Operator, raises one operand to the power A ** B will give 125
of the other.
Relational Operators
Following table shows all the relational operators supported by Fortran. Assume
variable A holds 10 and variable B holds 20, then:
> .gt. Checks if the value of left operand is greater than (A > B) is
the value of right operand, if yes then condition not true.
becomes true.
< .lt. Checks if the value of left operand is less than the (A < B) is
value of right operand, if yes then condition true.
becomes true.
>= .ge. Checks if the value of left operand is greater than or (A >= B) is
equal to the value of right operand, if yes then not true.
condition becomes true.
<= .le. Checks if the value of left operand is less than or (A <= B) is
equal to the value of right operand, if yes then true.
condition becomes true.
the multiplication operator has higher precedence than the addition operator.
For example, x = 7 + 3 * 2; here, x is assigned 13, not 20 because operator * has higher
precedence than +, so it first gets multiplied with 3*2 and then adds into 7.
Here, operators with the highest precedence appear at the top of the table, those with the
lowest appear at the bottom. Within an expression, higher precedence operators will be
evaluated first.
Fortran – Decisions
Decision making structures require that the programmer specify one or more conditions to be
evaluated or tested by the program, along with a statement or statements to be executed, if the
condition is determined to be true, and optionally, other statements to be executed if the
condition is determined to be false.
F O R T R A N [ 2 2 1 ] | 13
Following is the general form of a typical decision making structure found in most of the
programming languages:
Statement Description
If… then...else construct An if… then statement can be followed by an optional else
statement, which executes when the logical expression is
false.
select case construct A select case statement allows a variable to be tested for
equality against a list of values.
nested select case construct You can use one select case statement inside
another select case statement(s).
The optional else is placed at the end and it is executed when none of the above conditions hold
true.
[name:]
! block 1
! block 2
! block 3
else
! block 4
end if [name]
Example
program ifElseIfElseProg
implicit none
integer :: a = 100
if( a == 10 ) then
else
end if
F O R T R A N [ 2 2 1 ] | 15
When the above code is compiled and executed, it produces the following result:
Fortran – Loops
There may be a situation, when you need to execute a block of code several number of times. In
general, statements are executed sequentially : The first statement in a function is executed
first, followed by the second, and so on.
Programming languages provide various control structures that allow for more complicated
execution paths.
A loop statement allows us to execute a statement or group of statements multiple times and
following is the general form of a loop statement in most of the programming languages:
Fortran provides the following types of loop constructs to handle looping requirements
do while loop Repeats a statement or group of statements while a given condition is true. It
tests the condition before executing the loop body.
nested loops You can use one or more loop construct inside any other loop construct.
exit If the exit statement is executed, the loop is exited, and the execution
F O R T R A N [ 2 2 1 ] | 16
stop If you wish execution of your program to stop, you can insert a stop
statement
Fortran – Numbers
Integer type
Real type
Complex type
Integer Type
The integer types can hold only integer values. The following example extracts the largest value
that could be hold in a usual four byte integer:
program testingInt
implicit none
integer :: largeval
print *, huge(largeval)
When you compile and execute the above program it produces the following result:
2147483647
Please note that the huge() function gives the largest number that can be held by the specific
integer data type. You can also specify the number of bytes using the kind specifier. The
following example demonstrates this:
program testingInt
implicit none
integer(kind=2) :: shortval
integer(kind=4) :: longval
F O R T R A N [ 2 2 1 ] | 17
integer(kind=8) :: verylongval
integer(kind=16) :: veryverylongval
!default integer
integer :: defval
print *, huge(shortval)
print *, huge(longval)
print *, huge(verylongval)
print *, huge(veryverylongval)
print *, huge(defval)
When you compile and execute the above program it produces the following result:
32767
2147483647
9223372036854775807
170141183460469231731687303715884105727
2147483647
Real Type
It stores the floating point numbers, such as 2.0, 3.1415, -100.876, etc.
Traditionally there were two different real types : the default real type and double
precision type.
However, Fortran 90/95 provides more control over the precision of real and integer data
types through the kind specifier, which we will study shortly.
program division
implicit none
real :: p, q, realRes
integer :: i, j, intRes
! Assigning values
F O R T R A N [ 2 2 1 ] | 18
p = 2.0
q = 3.0
i=2
j=3
realRes = p/q
intRes = i/j
print *, realRes
print *, intRes
When you compile and execute the above program it produces the following result:
0.666666687
Complex Type
This is used for storing complex numbers. A complex number has two parts : the real part and
the imaginary part. Two consecutive numeric storage units store these two parts.
For example, the complex number (3.0, -5.0) is equal to 3.0 – 5.0i
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 :: i = 10
real :: x = 5.17
print *, cmplx(i, x)
When you compile and execute the above program it produces the following result:
(10.0000000, 5.17000008)
program ComplexArithmatic
implicit none
complex :: x, y, z
x = (7, 8);
y = (5, -7)
write(*,*) i * x * y
z=x+y
z=x-y
z=x*y
z=x/y
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)
The following table displays the number of bits and range for integers:
64 9,223,372,036,854,774,807 (2**63)–1
32 2,147,483,647 (2**31)–1
The following table displays the number of bits, smallest and largest value, and the precision
for real numbers.
program rangePrecision
implicit none
real:: x, y, z
x = 1.5e+40
y = 3.73e+40
z=x*y
print *, z
When you compile and execute the above program it produces the following result:
x = 1.5e+40
main.f95:5.12:
y = 3.73e+40
program rangePrecision
implicit none
real:: x, y, z
x = 1.5e+20
y = 3.73e+20
z=x*y
print *, z
z = x/y
print *, z
When you compile and execute the above program it produces the following result:
Infinity
0.402144760
program rangePrecision
implicit none
real:: x, y, z
x = 1.5e-30
y = 3.73e-60
z=x*y
print *, z
z = x/y
print *, z
When you compile and execute the above program it produces the following result:
y = 3.73e-60
$demo
0.00000000E+00
Infinity
The intrinsic function kind() allows you to query the details of the hardware’s data
representations before running a program.
program kindCheck
implicit none
integer :: i
real :: r
F O R T R A N [ 2 2 1 ] | 22
complex :: cp
When you compile and execute the above program it produces the following result:
Integer 4
Real 4
Complex 4
program checkKind
implicit none
integer :: i
real :: r
character*1 :: c
logical :: lg
complex :: cp
When you compile and execute the above program it produces the following result:
Integer 4
Real 4
Complex 4
Character 1
Logical 4
Fortran – Characters
F O R T R A N [ 2 2 1 ] | 23
The Fortran language can treat characters as single character or contiguous strings.
Characters could be any symbol taken from the basic character set, i.e., from the letters, the
decimal digits, the underscore, and 21 special characters.
The intrinsic data type character stores characters and strings. The length of the string can be
specified by len specifier. If no length is specified, it is 1. You can refer individual characters
within a string referring by position; the left most character is at position 1.
Character Declaration
Declaring a character type data is same as other variables:
type-specifier :: variable_name
For example,
reply = ‘N’
sex = ‘F’
The following example demonstrates declaration and use of character data type:
program hello
implicit none
character(len=6) :: title
character(len=25)::greetings
surname = 'Atkinson'
print *, greetings
When you compile and execute the above program it produces the following result:
Concatenation of Characters
F O R T R A N [ 2 2 1 ] | 24
program hello
implicit none
character(len=6) :: title
character(len=40):: name
character(len=25)::greetings
surname = 'Atkinson'
name = title//firstname//surname
print *, greetings
When you compile and execute the above program it produces the following result:
Function Description
scan(string, chars) It searches the "string" from left to right (unless back=.true.) for the
first occurrence of any character contained in "chars". It returns an
integer giving the position of that character, or zero if none of the
characters in "chars" have been found.
verify(string, chars) It scans the "string" from left to right (unless back=.true.) for the first
occurrence of any character not contained in "chars". It returns an
integer giving the position of that character, or zero if only the
characters in "chars" have been found
repeat(string,ncopy) It returns a string with length equal to "ncopy" times the length of
"string", and containing "ncopy" concatenated copies of "string"
Example 1
program testingChars
implicit none
integer :: i
text = 'The intrinsic data type character stores characters and strings.'
i=index(text,'character')
if (i /= 0) then
end if
When you compile and execute the above program it produces the following result:
F O R T R A N [ 2 2 1 ] | 26
in text : The intrinsic data type character stores characters and strings.
Example 2
program hello
implicit none
character(len=6) :: title
character(len=25)::greetings
title = 'Mr.'
firstname = 'Rowan'
surname = 'Atkinson'
When you compile and execute the above program it produces the following result:
Example 3
program testingChars
implicit none
character:: ch
integer:: i
do i=65, 90
ch = achar(i)
end do
When you compile and execute the above program it produces the following result:
65 A
66 B
F O R T R A N [ 2 2 1 ] | 27
67 C
68 D
69 E
70 F
71 G
72 H
73 I
74 J
75 K
76 L
77 M
78 N
79 O
80 P
81 Q
82 R
83 S
84 T
85 U
86 V
87 W
88 X
89 Y
90 Z
Function Description
lle(char, char) Compares whether the first character is lexically less than or equal to the
second
lge(char, char) Compares whether the first character is lexically greater than or equal to
the second
F O R T R A N [ 2 2 1 ] | 28
lgt(char, char) Compares whether the first character is lexically greater than the second
llt(char, char) Compares whether the first character is lexically less than the second
Example 4
program testingChars
implicit none
character:: a, b, c
a = 'A'
b = 'a'
c = 'B'
if(lgt(a,b)) then
else
end if
if(lgt(a,c)) then
else
end if
if(llt(a,b)) then
end if
if(llt(a,c)) then
end if
When you compile and execute the above program it produces the following result:
Fortran – Strings
The Fortran language can treat characters as single character or contiguous strings.
A character string may be only one character in length, or it could even be of zero length. In
Fortran, character constants are given between a pair of double or single quotes.
The intrinsic data type character stores characters and strings. The length of the string can be
specified by len specifier. If no length is specified, it is 1. You can refer individual characters
within a string referring by position; the left most character is at position 1.
String Declaration
Declaring a string is same as other variables:
type-specifier :: variable_name
For example,
The following example demonstrates declaration and use of character data type:
program hello
implicit none
character(len=6) :: title
character(len=25)::greetings
title = 'Mr.'
firstname = 'Rowan'
surname = 'Atkinson'
print *, greetings
F O R T R A N [ 2 2 1 ] | 30
When you compile and execute the above program it produces the following result:
String Concatenation
The concatenation operator //, concatenates strings.
program hello
implicit none
character(len=6) :: title
character(len=40):: name
character(len=25)::greetings
title = 'Mr.'
firstname = 'Rowan'
surname = 'Atkinson'
name = title//firstname//surname
print *, greetings
When you compile and execute the above program it produces the following result:
Extracting Substrings
In Fortran, you can extract a substring from a string by indexing the string, giving the start and
the end index of the substring in a pair of brackets. This is called extent specifier.
The following example shows how to extract the substring ‘world’ from the string ‘hello
world’:
program subString
character(len=11)::hello
print*, hello(7:11)
When you compile and execute the above program it produces the following result:
World
Example
The following example uses the date_and_time function to give the date and time string. We
use extent specifiers to extract the year, date, month, hour, minutes and second information
separately.
program datetime
implicit none
year = dateinfo(1:4)
month = dateinfo(5:6)
day = dateinfo(7:8)
! and s = second
hour = timeinfo(1:2)
minute = timeinfo(3:4)
second = timeinfo(5:10)
When you compile and execute the above program, it gives the detailed date and time
information:
Year: 2014
Month: 08
Day: 03
Hour: 07
Minute: 58
Second: 35.466
Trimming Strings
The trim function takes a string, and returns the input string after removing all trailing blanks.
Example
program trimString
implicit none
When you compile and execute the above program it produces the following result:
The function adjustr takes a string and returns it by removing the trailing blanks and
appending them as leading blanks.
Example
program hello
implicit none
character(len=6) :: title
character(len=40):: name
character(len=25):: greetings
firstname = 'Rowan'
surname = 'Atkinson'
name = adjustl(title)//adjustl(firstname)//adjustl(surname)
print *, greetings
name = adjustr(title)//adjustr(firstname)//adjustr(surname)
print *, greetings
name = trim(title)//trim(firstname)//trim(surname)
print *, greetings
When you compile and execute the above program it produces the following result:
Here is Mr.RowanAtkinson
Example
program hello
implicit none
character(len=30) :: myString
character(len=10) :: testString
testString = 'test'
else
end if
When you compile and execute the above program it produces the following result:
Fortran – Arrays
Arrays can store a fixed-size sequential collection of elements of the same type. An array is used
to store a collection of data, but it is often more useful to think of an array as a collection of
variables of the same type.
F O R T R A N [ 2 2 1 ] | 35
All arrays consist of contiguous memory locations. The lowest address corresponds to the first
element and the highest address to the last element.
Arrays can be one- dimensional (like vectors), two-dimensional (like matrices) and Fortran
allows you to create up to 7-dimensional arrays.
Declaring Arrays
Arrays are declared with the dimension attribute.
For example, to declare a one-dimensional array named number, of real numbers containing 5
elements, you write,
The individual elements of arrays are referenced by specifying their subscripts. The first
element of an array has a subscript of one. The array numbers contains five real variables –
numbers(1), numbers(2), numbers(3), numbers(4), and numbers(5).
You can also declare an array with some explicit lower bound, for example:
Assigning Values
You can either assign values to individual members, like,
numbers(1) = 2.0
do i=1,5
numbers(i) = i * 2.0
end do
One dimensional array elements can be directly assigned values using a short hand symbol,
called array constructor, like,
please note that there are no spaces allowed between the brackets ‘( ‘and the back slash
‘/’
Example
F O R T R A N [ 2 2 1 ] | 36
program arrayProg
do i=1,5
numbers(i) = i * 2.0
end do
do i = 1, 5
Print *, numbers(i)
end do
do i=1,3
do j = 1, 3
matrix(i, j) = i+j
end do
end do
do i=1,3
do j = 1, 3
Print *, matrix(i,j)
end do
end do
do i = 1, 5
Print *, numbers(i)
end do
When the above code is compiled and executed, it produces the following result:
F O R T R A N [ 2 2 1 ] | 37
2.00000000
4.00000000
6.00000000
8.00000000
10.0000000
1.50000000
3.20000005
4.50000000
0.899999976
7.19999981
Term Meaning
Rank It is the number of dimensions an array has. For example, for the array named
matrix, rank is 2, and for the array named numbers, rank is 1.
Exten It is the number of elements along a dimension. For example, the array numbers has
t extent 5 and the array named matrix has extent 3 in both dimensions.
Shape The shape of an array is a one-dimensional integer array, containing the number of
elements (the extent) in each dimension. For example, for the array matrix, shape is
(3, 3) and the array numbers it is (5).
Size It is the number of elements an array contains. For the array matrix, it is 9, and for
F O R T R A N [ 2 2 1 ] | 38
program arrayToProcedure
implicit none
integer :: i
call printArray(myArray)
implicit none
! local variables
integer :: i
do i = 1, 5
a(i) = i
end do
subroutine printArray(a)
integer::i
do i = 1, 5
Print *, a(i)
end do
When the above code is compiled and executed, it produces the following result:
2
F O R T R A N [ 2 2 1 ] | 39
In the above example, the subroutine fillArray and printArray can only be called with arrays
with dimension 5. However, to write subroutines that can be used for arrays of any size, you
can rewrite it using the following technique:
program arrayToProcedure
implicit none
integer :: i
interface
integer :: i
integer, dimension(:) :: a
integer :: i
end interface
call printArray(myArray)
implicit none
! local variables
integer :: i, arraySize
arraySize = size(a)
do i = 1, arraySize
a(i) = i
F O R T R A N [ 2 2 1 ] | 40
end do
subroutine printArray(a)
implicit none
integer,dimension (:) :: a
integer::i, arraySize
arraySize = size(a)
do i = 1, arraySize
Print *, a(i)
end do
Please note that the program is using the size function to get the size of the array.
When the above code is compiled and executed, it produces the following result:
10
Array Sections
So far we have referred to the whole array, Fortran provides an easy way to refer several
elements, or a section of an array, using a single statement.
To access an array section, you need to provide the lower and the upper bound of the section,
as well as a stride (increment), for all the dimensions. This notation is called a subscript
triplet:
When no lower and upper bounds are mentioned, it defaults to the extents you declared, and
stride value defaults to 1.
F O R T R A N [ 2 2 1 ] | 41
program arraySubsection
real, dimension(10) :: a, b
b(2:10:2) = 3.9
b(1:9:2) = 2.5
!display
asize = size(a)
bsize = size(b)
do i = 1, asize
Print *, a(i)
end do
do i = 1, bsize
Print *, b(i)
end do
When the above code is compiled and executed, it produces the following result:
5.00000000
5.00000000
5.00000000
5.00000000
5.00000000
5.00000000
5.00000000
0.00000000E+00
0.00000000E+00
0.00000000E+00
2.50000000
3.90000010
2.50000000
F O R T R A N [ 2 2 1 ] | 42
3.90000010
2.50000000
3.90000010
2.50000000
3.90000010
2.50000000
3.90000010
Reduction
Inquiry
Construction
Reshape
Manipulation
Location
We have so far seen that we can read data from keyboard using the read * statement, and
display output to the screen using the print* statement, respectively. This form of input-output
is free format I/O, and it is called list-directed input-output.
However the formatted I/O gives you more flexibility over data transfer.
Where,
Format specification defines the way in which formatted data is displayed. It consists of a
string, containing a list of edit descriptors in parentheses.
An edit descriptor specifies the exact format, for example, width, digits after decimal point
etc., in which characters and numbers are displayed.
For example:
Print "(f6.3)", pi
I This is used for integer output. This takes the form print "(3i5)", i, j, k
‘rIw.m’ where the meanings of r, w and m are
given in the table below. Integer values are right
justified in their fields. If the field width is not
large enough to accommodate an integer then the
field is filled with asterisks.
F This is used for real number output. This takes the print "(f12.3)",pi
form ‘rFw.d’ where the meanings of r, w and d are
given in the table below. Real values are right
justified in their fields. If the field width is not
large enough to accommodate the real number
then the field is filled with asterisks.
the zero, four for the mantissa and two for the
exponent itself. In general, w ≥ d + 7.
A This is used for character output. This takes the print "(a10)", str
form ‘rAw’ where the meanings of r and w are
given in the table below. Character types are right
justified in their fields. If the field width is not
large enough to accommodate the character string
then the field is filled with the first ‘w’ characters
of the string.
X This is used for space output. This takes the form print "(5x, a10)", str
‘nX’ where ‘n’ is the number of desired spaces.
/ Slash descriptor – used to insert blank lines. This print "(/,5x, a10)", str
takes the form ‘/’ and forces the next data output
to be on a new line.
Symbol Description
c Column number
d Number of digits to right of the decimal place for real input or output
w Field width – the number of characters to use for the input or output
Example 1
program printPi
pi = 3.141592653589793238
Print "(f6.3)", pi
Print "(f10.7)", pi
Print "(f20.15)", pi
When the above code is compiled and executed, it produces the following result:
3.142
3.1415927
3.141592741012573
0.3142E-01
Example 2
program printName
implicit none
read *,first_name
print "(1x,a)",first_name
When the above code is compiled and executed, it produces the following result: (assume the
user enters the name Zara)
Up to 20 characters, please
Zara
Example 3
program formattedPrint
F O R T R A N [ 2 2 1 ] | 46
implicit none
print "(i6)", k
print "(i6.3)", k
print "(3i10)", n, k, i
print "(i10,i3,i5)", n, k, i
print "(a15)",str
print "(f12.3)", d
print "(e12.4)", c
When the above code is compiled and executed, it produces the following result:
45
045
300789 45 2
300789 45 2
Tutorials Point
123.457
0.1279E-08
n = 300789 d = *******
program productDetails
implicit none
integer :: id
real :: weight
name = 'Ardupilot'
F O R T R A N [ 2 2 1 ] | 47
id = 1
weight = 0.08
print 100
When the above code is compiled and executed, it produces the following result:
Ardupilot 1 0.08
Fortran allows you to read data from, and write data into files.
In the last chapter, you have seen how to read data from, and write data to the terminal. In this
chapter you will study file input and output functionalities provided by Fortran.
You can read and write to one or more files. The OPEN, WRITE, READ and CLOSE statements
allow you to achieve this.
open (list-of-specifiers)
Specifier Description
[UNIT=] u The unit number u could be any number in the range 9-99 and it indicates
the file, you may choose any number but every open file in the program
must have a unique number
F O R T R A N [ 2 2 1 ] | 48
IOSTAT= ios It is the I/O status identifier and should be an integer variable. If the open
statement is successful then the ios value returned is zero else a non-zero
value.
ERR = err It is a label to which the control jumps in case of any error.
STATUS = sta It shows the prior status of the file. A character string and can have one of
the three values NEW, OLD or SCRATCH. A scratch file is created and
deleted when closed or the program ends.
ACCESS = acc It is the file access mode. Can have either of the two values, SEQUENTIAL
or DIRECT. The default is SEQUENTIAL.
FORM= frm It gives the formatting status of the file. Can have either of the two values
FORMATTED or UNFORMATTED. The default is UNFORMATTED
After the file has been opened, it is accessed by read and write statements. Once done, it should
be closed using the close statement.
close ([UNIT=]u[,IOSTAT=ios,ERR=err,STATUS=sta])
Example
This example demonstrates opening a new file for writing some data into the file.
program outputdata
implicit none
real, dimension(100) :: x, y
real, dimension(100) :: p, q
integer :: i
! data
do i=1,100
x(i) = i * 0.1
F O R T R A N [ 2 2 1 ] | 49
end do
do i=1,100
end do
close(1)
When the above code is compiled and executed, it creates the file data1.dat and writes the x and
y array values into it. And then closes the file.
The read and write statements respectively are used for reading from and writing into a file
respectively.
Most of the specifiers have already been discussed in the above table.
The END=s specifier is a statement label where the program jumps, when it reaches end-of-file.
Example
In this program we read from the file, we created in the last example, data1.dat, and display it
on screen.
program outputdata
implicit none
real, dimension(100) :: x, y
real, dimension(100) :: p, q
integer :: i
! data
do i=1,100
x(i) = i * 0.1
end do
do i=1,100
end do
close(1)
do i=1,100
end do
close(2)
do i=1,100
end do
When the above code is compiled and executed, it produces the following result:
0.100000001 5.54589933E-05
0.200000003 4.41325130E-04
0.300000012 1.47636665E-03
0.400000006 3.45637114E-03
0.500000000 6.64328877E-03
0.600000024 1.12552457E-02
0.699999988 1.74576249E-02
0.800000012 2.53552198E-02
0.900000036 3.49861123E-02
1.00000000 4.63171229E-02
1.10000002 5.92407547E-02
1.20000005 7.35742599E-02
1.30000007 8.90605897E-02
F O R T R A N [ 2 2 1 ] | 51
1.39999998 0.105371222
1.50000000 0.122110792
1.60000002 0.138823599
1.70000005 0.155002072
1.80000007 0.170096487
1.89999998 0.183526158
2.00000000 0.194692180
2.10000014 0.202990443
2.20000005 0.207826138
2.29999995 0.208628103
2.40000010 0.204863414
2.50000000 0.196052119
2.60000014 0.181780845
2.70000005 0.161716297
2.79999995 0.135617107
2.90000010 0.103344671
3.00000000 6.48725405E-02
3.10000014 2.02930309E-02
3.20000005 -3.01767997E-02
3.29999995 -8.61928314E-02
3.40000010 -0.147283033
3.50000000 -0.212848678
3.60000014 -0.282169819
3.70000005 -0.354410470
3.79999995 -0.428629100
3.90000010 -0.503789663
4.00000000 -0.578774154
4.09999990 -0.652400017
4.20000029 -0.723436713
4.30000019 -0.790623367
4.40000010 -0.852691114
4.50000000 -0.908382416
4.59999990 -0.956472993
F O R T R A N [ 2 2 1 ] | 52
4.70000029 -0.995793998
4.80000019 -1.02525222
4.90000010 -1.04385209
5.00000000 -1.05071592
5.09999990 -1.04510069
5.20000029 -1.02641726
5.30000019 -0.994243503
5.40000010 -0.948338211
5.50000000 -0.888650239
5.59999990 -0.815326691
5.70000029 -0.728716135
5.80000019 -0.629372001
5.90000010 -0.518047631
6.00000000 -0.395693362
6.09999990 -0.263447165
6.20000029 -0.122622721
6.30000019 2.53026206E-02
6.40000010 0.178709000
6.50000000 0.335851669
6.59999990 0.494883657
6.70000029 0.653881252
6.80000019 0.810866773
6.90000010 0.963840425
7.00000000 1.11080539
7.09999990 1.24979746
7.20000029 1.37891412
7.30000019 1.49633956
7.40000010 1.60037732
7.50000000 1.68947268
7.59999990 1.76223695
7.70000029 1.81747139
7.80000019 1.85418403
7.90000010 1.87160957
F O R T R A N [ 2 2 1 ] | 53
8.00000000 1.86922085
8.10000038 1.84674001
8.19999981 1.80414569
8.30000019 1.74167395
8.40000057 1.65982044
8.50000000 1.55933595
8.60000038 1.44121361
8.69999981 1.30668485
8.80000019 1.15719533
8.90000057 0.994394958
9.00000000 0.820112705
9.10000038 0.636327863
9.19999981 0.445154816
9.30000019 0.248800844
9.40000057 4.95488606E-02
9.50000000 -0.150278628
9.60000038 -0.348357052
9.69999981 -0.542378068
9.80000019 -0.730095863
9.90000057 -0.909344316
10.0000000 -1.07807255
Fortran – Procedures
A procedure is a group of statements that perform a well-defined task and can be invoked
from your program. Information (or data) is passed to the calling program, to the procedure as
arguments.
Functions
Subroutines
Function
A function is a procedure that returns a single quantity. A function should not modify its
arguments.
F O R T R A N [ 2 2 1 ] | 54
The returned quantity is known as function value, and it is denoted by the function name.
Syntax:
[executable statements]
The following example demonstrates a function named area_of_circle. It calculates the area of a
circle with radius r.
program calling_func
real :: a
a = area_of_circle(2.0)
Print *, a
implicit none
! function result
real :: area_of_circle
! dummy arguments
real :: r
! local variables
real :: pi
pi = 4 * atan (1.0)
area_of_circle = pi * r**2
When you compile and execute the above program, it produces the following result:
12.5663710
You must specify implicit none in both the main program as well as the procedure.
If you want the returned value to be stored in some other name than the function name, you
can use the result option.
[executable statements]
Subroutine
A subroutine does not return a value, however it can modify its arguments.
Syntax
[executable statements]
Calling a Subroutine
The following example demonstrates the definition and use of a subroutine swap, that changes
the values of its arguments.
program calling_func
implicit none
real :: a, b
a = 2.0
b = 3.0
call swap(a, b)
subroutine swap(x, y)
implicit none
real :: x, y, temp
temp = x
x=y
y = temp
When you compile and execute the above program, it produces the following result:
a = 2.00000000
b = 3.00000000
a = 3.00000000
b = 2.00000000
program calling_func
implicit none
real :: x, y, z, disc
F O R T R A N [ 2 2 1 ] | 57
x= 1.0
y = 5.0
z = 2.0
Print *, disc
implicit none
! dummy arguments
d = b*b - 4.0*a*c
When you compile and execute the above program, it produces the following result:
17.0000000
Recursive Procedures
Recursion occurs when a programming languages allows you to call a function inside the same
function. It is called recursive call of the function.
When a procedure calls itself, directly or indirectly, is called a recursive procedure. You should
declare this type of procedures by preceding the word recursive before its declaration.
Following is an example, which calculates factorial for a given number using a recursive
procedure:
program calling_func
implicit none
integer :: i, f
i = 15
f = myfactorial(15)
Print *, f
implicit none
! function result
integer :: fac
! dummy arguments
case (0:1)
fac = 1
case default
end select
Internal Procedures
When a procedure is contained within a program, it is called the internal procedure of the
program. The syntax for containing an internal procedure is as follows:
program program_name
implicit none
! executable statements
...
contains
! internal procedures
...
program mainprog
implicit none
F O R T R A N [ 2 2 1 ] | 59
real :: a, b
a = 2.0
b = 3.0
call swap(a, b)
contains
subroutine swap(x, y)
real :: x, y, temp
temp = x
x=y
y = temp
When you compile and execute the above program, it produces the following result:
a = 2.00000000
b = 3.00000000
a = 3.00000000
b = 2.00000000
program output
implicit none
F O R T R A N [ 2 2 1 ] | 60
real,dimension(3) :: a,b,c
character :: answer*1
!initialise arrays
a = 1.5
b = 2.5
c = 3.5
write(*,1) 'a',a
read *, answer
write(*,1) 'b',b
read *, answer
write(*,1) 'c',c
read *, answer
write(*,1) 'a*b*c',a * b * c
1 format(a,3f8.3)
The program sets up some arrays and then outputs them. At three stages in the program
(bolded), it asks whether it should continue; it stops if the answer is not 'y'. Notice that the
three bolded parts of the code are identical.
Simple enough – but look at the amount of code! Most of it is the same – wouldn't it be nice to
re-use the code and cut down on the typing? The answer is to use subroutines.
program output1
implicit none
real,dimension(3) :: a,b,c
!initialise arrays
a = 1.5
b = 2.5
F O R T R A N [ 2 2 1 ] | 61
c = 3.5
write(*,1) 'a',a
call prompt()
write(*,1) 'b',b
call prompt()
write(*,1) 'c',c
call prompt()
write(*,1) 'a*b*c',a * b * c
1 format(a,3f8.3)
!++++++++++++++++++++++++++++++++++++++++++++++
subroutine prompt()
implicit none
character answer*1
read *, answer
call prompt()
subroutine prompt()
then executes each line of the code it finds in the subroutine until it reaches the line
and then returns to the main program and carries on where it left off.
The program is much easier to understand now. All the code for prompting is in one place. If we
ever need to change the code which prompts the user to continue, we will only ever need to
change it once. This makes the program more maintainable.