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

FORTRAN LESSON

Lesson Topics
Editing Fortran Assignment
Compiling Parameter
Running a Program Comments
Program Print *
Variables Read *
Declarations End
Types Operations
Implicit Quantifier Intrinsic Functions
View Demos Download Demos
#1 #1
Main Fortran Page

Introduction

Fortran is one of the oldest programming languages devised, but it is also still one of the
most popular, especially among engineers and applied scientists. It was developed in the
1950's at IBM. Part of the reason for Fortran's durability is that it is particularly well-
suited for mathematical programming; moreover, there are millions of useful programs
written in Fortran, created at considerable time and expense, and understandably people
are reluctant to trash these old programs and switch to a new programming language.

The name Fortran originally referred to "Formula Translation", but it has long since taken
on its own meaning. There are several versions of Fortran around, among them Fortran
77, Fortran 90, and Fortran 95. (The number denotes the year of introduction.) Fortran 77
is probably still the most used, and it is the version installed on UHUNIX and in the UH
math lab. Even though this semester we have thus far studied Basic, at the same time we
have studied Fortran, because commands and procedures are very similar in the two
languages. Moving from QuickBasic to Fortran is more a matter of change of
terminology than anything else.

Editing Fortran
Unlike in Basic, a Fortran program is not typed in a "Fortran window". Instead, a
program is typed and saved with an editor (i.e., a word processor), and the program is
then turned into an executable file by a Fortran compiler. To begin the process of creating
a Fortran program in the math lab, you must open an editor. It is preferable to use a
simple editor - such as Notepad or the DOS editor - because fancy word processors might
add extraneous formatting notation that will hang up Fortran.

A most peculiar feature of Fortran 77 is its line structure, which is a carryover from the
old days when programs were typed on punch cards. A punch card had 80 columns, and
so does a line of Fortran code. A "c" in column 1 indicates a comment (similar to REM in
Basic). Columns 2-5 (usually left blank) are reserved for line numbers. Column 6 is used
only to indicate a continuation of a line too long to fit on the card. Columns 7-72 contain
the instructions of the program. Columns 73-80 were originally used for numbering the
punch cards, but are rarely used nowadays - leave them blank and the compiler will
ignore them.

Fortran is case insensitive - that is, it does not distinguish between capital and small
letters. Thus x and X refer to the same variable. Many programmers for simplicity use all
small letters, but you may do as you like. Also, after column six Fortran does not
recognize spaces (except for spaces inside quotations as in print statements). In general,
spaces are mostly for the purpose of making code more readable by humans. When you
type a Fortran program with an editor, make certain the editor indents more than six
spaces; then if you begin every line with an indent you do not have to worry about
counting six spaces at the beginnings of lines.

Let us go through the steps of editing, compiling, and running a short program. First open
Notepad under Windows, or type "edit" (and return) under a DOS prompt to open the
DOS editor. (When you double-click the Fortran icon on a math lab computer, you get a
DOS prompt.) Beginning each line with an indent (except for the fourth line, where the
"c" must be placed in the first column), type the program exhibited below; the program
computes the area of a circle of radius r, as input by the user. The resulting file that you
save is called the source file for the program.

program circlearea
real r, area, pi
parameter (pi = 3.14159)
c This program computes the area of a circle.
print *, "What is the radius?"
read *, r
area = pi * r ** 2
print *, "The area is", area
print *, "Bye!"
end
The first statement above gives the program name, the second declares that "r", "area",
and "pi" will be single precision real quantities, and the third announces that pi has the
value 3.14159. The fourth statement, beginning with "c" in column 1, is a comment
describing what the program does; such comments are for the benefit of the programmer
and are ignored by Fortran. The fifth statement prompts the user for the radius of the
circle, and the sixth accepts this input. The seventh statement computes the area and the
eighth informs the user of this area. Finally, the last two statements bid goodbye and
terminate the program.

The name for a source file in Fortran must end with the extension ".f" before the compiler
recognizes it. After you have typed the above program, save the file as area.f. (If you type
the file in Notepad, include the whole name in quotes when you save it, as otherwise the
extension .txt will be added to the name.) The file will be saved to your h directory in the
math lab. Under a DOS prompt you can view the files in this directory by typing dir and
enter; under Windows you can double-click "My Computer" and then the icon for the h
drive.

Compiling

After you have created and saved a source file, you next must compile this file. Open a
Fortran window and enter g77 name.f, where in place of name you insert the name of
your source file. (If the source file resides in a directory different from that of the Fortran
program, you will have to include also the directory path of the file.) To compile the file
of our example above, in the math computer lab you just enter g77 area.f.

If your program has mistakes (which usually happens on the first attempt at compiling),
instead of a compiled file you will get Fortran error messages pointing out problems.
Some of these messages can be hard to decipher, but after reading hundreds of them you
will get better at it. If your program has no mistakes Fortran will simply return a DOS
prompt - that is good news because it means Fortran has successfully created a compiled
file. By default this new file is given the name a.exe. (You can give the compiled file a
name of your own choosing by typing g77 area.f -o name.exe to compile the program -
but usually there is no reason not to accept the default name.) Your compiled file, also
located in the h directory, is now executable - that means the program is ready to run.

Running a Program

If your compiled file has the default name a.exe, you simply type a and return to run it (or
name and return if you gave the file another name). After you run the program and see
how it works, you can return to your editor and revise it as you wish. It is perhaps better
to keep two windows open - both the Fortran window and the editing window - so that
you can quickly switch from one to the other with a mouse-click. After revising a
program, you must save and compile it again before changes take effect.
If you do enough Fortran programming, sooner or later you will err and create and run a
program that never stops. In such a situation, type "Control-C" to interrupt the execution
of the program.

Now that we have discussed the basic nuts and bolts of creating and running a Fortran
program, we discuss some terminology and commands. You will probably find that most
of these remind you of similar things in Basic.

Program

Every Fortran program must begin with a program line, giving the name of the program.
Here are examples:
program quadratic
program mortgage
program primes .

Variables, Declarations, Types

After the program name come the declaration statements, stating the types of the
variables used in the program. A variable name consists of characters chosen from the
letters a-z and the digits 0-9; the first character of the name must be a letter. You are not
allowed to use your program name as a variable, nor are you allowed to use words
reserved for the Fortran language, such as "program", "real", "end", etc.

The variable types in Fortran are

1) integer (in the range from about - 2 billion to + 2 billion)

2) real (single precision real variable)

3) double precision (double precision real variable)

4) character (string variable)

5) complex (complex variable)

6) logical (logical variable)

As illustration, the declaration statements


real r, area
integer M, N
double precision a, b

declare that r and area are single precision real variables, that M and N are integers, and
that a and b are double precision real variables.
If you do not declare the type of a variable, Fortran will by default make it an integer if it
starts with one of the letters i through n, and will make it a single precision real variable
otherwise. However, it is normal (and good) programming practice to declare the type of
every variable, as otherwise mistakes are easily made.

The implicit quantifier before a type declaration makes all variables starting with the
listed letters of the specified type. For example, the declarations

implicit integer (i-m)


implicit real (r-t)

make variables starting with i, j, k, l, m integers, and those starting with r, s, t real.
However, the implicit quantifier is probably best avoided, as programmers with short
memories will make mistakes.

A declaration statement is nonexecutable - that is, it provides information but does not
instruct Fortran to carry out any action. Declarations must appear before any executable
statement (a statement that does tell Fortran to take some action).

Assignment

The equals sign "=" assigns the variable on the left side the value of the number or
expression on the right side (exactly as in Basic).

Parameter

The parameter statement works like CONST in Basic - it specifies a value for a constant.
The syntax is
parameter (name = constant expression)

where name is replaced by the name of the constant, and constant expression by an
expression involving only constants. Thus

parameter (pi = 3.14159)

specifies a value for the constant pi, while the succeeding statement

parameter (a = 2* pi, b = pi/2)

fixes values of new constants a and b in terms of the old constant pi. Remember that once
a constant is defined you are not allowed to change its value later.

All parameter statements must appear before the first executable statement.

Comments
A comment is similar to an REM statement in Basic. You can indicate a comment by
placing a "c" in column 1 and then the comment in columns 7-72. Alternatively, you can
use an exclamation point "!" to indicate a comment; it may occur anywhere in the line
(except columns 2-6). Everything on a line after an exclamation point becomes a
comment.

Print *

The command "print *" is analogous to PRINT in Basic; it instructs Fortran to print items
to the screen. Examples are
print *, x
print *, "The solution is ", x
print *, 'The radius is', r, 'and the area is', area

Note that a comma follows "print *", and that commas (instead of semicolons as in Basic)
appear between successive items to be printed. Observe also that either double or single
quotes may enclose strings. The command "print *" on a line by itself (without a comma)
serves as a line feed.

Read *

The command "read *" is analogous to INPUT in Basic. Examples are


read *, radius
read *, A, B, C .

In the first example the program pauses to allow the user to enter the radius. In the second
example the user types the values of A, B, and C, separated by returns; alternatively, the
user can type A, B, and C separated only by commas, and then one final return.

End

The end statement marks the end of the main Fortran program or of a subprogram. (It
cannot be used in the middle of the program, as in Basic.)

Operations of Arithmetic

Here are the common arithmetical operations in Fortran:


Addition x+y
Subtraction x-y
Multiplication x*y
Division x/y
Exponentiation x ** y

Fortran performs exponentiations first, then multiplications and divisions, and lastly
additions and subtractions. (When in doubt, use parentheses!)

Be careful with division. If m and n are integers, then m/n is truncated to its integer part.
Thus 3/4 is evaluated as 0, and 25/6 as 4. When working with constants rather than
variables you can avoid this problem by using periods after integers. For example 3./4. is
evaluated in the standard way as .75, as Fortran treats 3. and 4. as real variables rather
than as integers.

Intrinsic Functions

Many standard mathematical functions are built into Fortran - these are called intrinsic
functions. Below is a table of some of the functions most commonly used in
mathematical programming. All trig functions work in radians. (Note that arguments of
functions must be enclosed in parentheses.)
Function Description
abs(x) absolute value of x
acos(x) arccosine of x
asin(x) arcsine of x
atan(x) arctangent of x
cos(x) cosine of x
cosh(x) hyperbolic cosine of x
dble(x) converts x to double precision type
exp(x) exponential function of x (base e)
log(x) natural logarithm of x (base e)
mod(n,m) remainder when n is divided by m
real(x) converts x to real (single precision) type
sign(x,y) changes the sign of x to that of y
sin(x) sine of x
sinh(x) hyperbolic sine of x
sqrt(x) square root of x
tan(x) tangent of x
tanh(x) hyperbolic tangent of x

FORTRAN LESSON 2
Lesson Topics
Logical Expressions Go To
If ... Then ... Else Character Variables
Stop Do Loops
Labels
View Demos Download Demos
# 1 # 2 # 3 # 4 # 5 # 6 # 7 # 8 # 9 # 10 # 1 # 2 # 3 # 4 # 5 # 6 # 7 # 8 # 9 # 10
Main Fortran Page

We look at more of the commonly used features and commands of Fortran.

Logical Expressions

A logical expression is a relation between variables or expressions that can have a value
of TRUE or FALSE. Such expressions are used in "if … then" constructions and in loops,
when testing whether to execute certain steps of a program. Relations and connectives
appearing in logical expressions are listed in the following table; you will see how some
of these are used in later examples.
Relation/Connective Meaning
.lt. less than
.gt. greater than
.le. less than or equal to
.ge. greater than or equal to
.eq. equals
.ne. not equal to
.and. and
.or. or
.not. not
.xor. "exclusive" or (i.e., only one is true)
.eqv. equivalent (i.e., same truth values)
.neqv. not equivalent

If ... Then ... Else Constructions

"If … Then … Else" constructions in Fortran are pretty much like those in Basic, with but
a few minor modifications. First, instead of using in the tests symbols like "=", "<", ">=",
etc., as in Basic, you must use the abbreviations in the preceding table. Also, tests must
be enclosed in parentheses, and "else if" may be two words. Here are several examples:
1) if (x .gt. 0) print *, "x is positive"

2) if (x .ge. y .and. x .ge. z) go to 40

3) if (x .ge. 0) then
y = sqrt(x)
print *, y, " squared = ", x
end if

4) if (x .ge. 0) then
y = sqrt(x)
print *, y, " squared = ", x
else
print *, "x has no square root"
end if

5) if (x .gt. 0) then
print *, "x is positive"
y = sqrt(x)
else if (x .lt. 0) then
print *, "x is negative"
go to 60
else if (x .eq. 0) then
print *, "x is zero"
y=0
end if
Observe that, as in examples 1) and 2), the one-line "if" statement does not use "then".
Moreover, "else" appears on a line by itself, while "else if" shares the line with the test
condition and "then".

Stop

A stop statement stops the execution of a program. For instance, the sequence of
statements below terminates the program whenever n is less than zero:
if (n .lt. 0) then
print *, "Error - your age cannot be negative!"
stop
end if .

Do not confuse stop and end. Use end only as the very last statement in the program, and
use stop only to terminate the program before this last statement. Violating these rules
will fatally confuse the compiler - it regards an end statement as the program's physical
end.

Labels and Go To

Labels and the "go to" statement work as in Basic, except that a label must be a number,
and it must be typed in columns 2-5. Here is an example of a go to command directing
the action to a labeled statement:
if (x .lt. 0) go to 10
print *, "The square root of x is ", sqrt(x)
stop
10 print *, "x is negative and has no square root"

Character Variables

A character variable is analogous to a string variable in Basic. A character variable must


be declared at the beginning of the program, and attached to it in the declaration must be
a number following an asterisk "*"; this number indicates the maximum number of
symbols in the string. For example, the declaration statement
character name*20, ans*1

indicates that "name" is a character variable holding no more than 20 symbols, while
"ans" is a character variable holding only one symbol.

A string in Fortran may be enclosed in either double quotes, as in "hello", or in single


quotes, as in 'goodbye'.
Do Loops

"For … Next" loops in Basic become "Do Loops" in Fortran. Such a loop begins with a
do statement, and ends with either end do, or a labeled continue statement. Here are two
loops that add the squares of the integers from 1 to 10:
sum = 0 | sum = 0
do i = 1, 10 | do 5 i = 1, 10
sum = sum + i ** 2 | sum = sum + i ** 2
end do | 5 continue
print *, "The sum is", sum | print *, "The sum is", sum

The end do and continue statements serve only to identify the end of the loop. The limits
of the loop may be variables as well as numbers (e.g.: do i = m, n). As in Basic you may
indicate a step size, which can be positive or negative. For example, the statement

do i = 1, 9, 2

specifies that the loop variable i run over the odd numbers 1, 3, 5, 7, 9.

Loops can be nested, and nested loops can end on the same continue statement (but not
on the same end do statement). Here are two instances of nested loops assigning the
entries of a 10 x 10 matrix:

do i = 1, 10 | do 5 i = 1, 10
do j = 1, 10 | do 5 j = 1, 10
a(i,j) = i + j | a(i,j) = i + j
end do | 5 continue
end do |

FORTRAN LESSON 3
Lesson Topics
Integers Exponentials
Real(x) Rational Exponents
Single Precision Roots
Double Precision Write
Base 2 Conversion Errors Format
Mixed Type Arithmetic Format Code Letters
View Demos Download Demos
#1#2#3#4#5#6#7#8#9 #1#2#3#4#5#6#7#8#9
Main Fortran Page

In Fortran Lesson 1 we briefly looked at the types of variables in Fortran. To avoid


mistakes in Fortran arithmetic you must pay close attention to rules regarding working
with numbers of the various types. Whereas Basic is more lenient, allowing some
flexibility in mixing variables and numbers of different types, Fortran is less forgiving
and will make you pay for oversights. In this lesson we look more closely at some of the
rules and conventions that must be observed.

Integers

An integer in Fortran is a whole number; it cannot contain commas or a decimal point.


Examples of numbers considered integers by Fortran are
12 , -1311 , 0 , +43 , 123456789 .

For positive integers the plus sign is optional, but negative integers must be preceded by a
minus sign. Examples of numbers not considered integers by Fortran are

22,547 , 3. , 4.0 , -43.57 .

Because of the decimal points, Fortran will regard 3. and 4.0 as real numbers.

An integer N in GNU Fortran must lie within the range

- 2,147,483,648 ≤ N ≤ 2,147,483,647 .

One idiosyncrasy of Fortran is that when it performs arithmetic on integers, it insists on


giving an answer that is likewise an integer. If the answer is not really an integer, Fortran
makes it one by discarding the decimal point and all digits thereafter. For example,
Fortran will assert that

11/8 = 1 , 15/4 = 3 , -4/3 = -1 , -50/6 = -8 , 2/3 = 0 .

If you want Fortran to give you the correct value of 11/8, you tell it to compute 11./8., so
that it interprets the numbers as real numbers and produces the correct value 1.375.
Integer arithmetic in Fortran can lead to other weird surprises - for instance, the
distributive law of division is invalid, as demonstrated by the example
(2 + 3)/4 = 5/4 = 1 but (2/4) + (3/4) = 0 + 0 = 0 .

Most of the built-in functions in Fortran apply to real numbers, and attempts to apply
them to integers result in compiler error messages. The compiler will protest if you ask
Fortran to compute sqrt(5), but it has no problem with sqrt(5.). Likewise, if you declare N
to be an integer variable and ask Fortran to compute sqrt(N) or cos(N) or log(N), your
program will not compile since these functions cannot act on integers. One way around
this problem is to use the intermediate function

real(x) ,

which converts x to a real number (if it is not already one). Then, for example,

real(5) = 5. , sqrt(real(5)) = sqrt(5.) = 2.23606801 .

The compiler will have no objection if N is an integer variable and you ask Fortran to
compute a composition like sqrt(real(N)) or cos(real(N)).

If you declare that A is an integer and later make the assignment A = 3.45, Fortran will
not complain but it will truncate 3.45 and assign A the value A = 3. Likewise, if you insert
the statement A = sqrt (5.), Fortran will truncate sqrt (5.) = 2.23606801 and deduce that A
= 2. But errors such as these are easily avoided if you are careful to make correct type
declaration statements for all variables at the beginning of your program.

Single Precision Real Numbers

A real number, or more precisely a single precision real number, is written with a
decimal point by Fortran, even when it is a whole number. The sequence of statements
real x
integer y
x=3
y=3
print *, "x = ", x, " but y = ", y, " - weird!"

produces the output

x = 3. but y = 3 - weird!

GNU Fortran uses up to 9 digits, not counting the decimal point, to represent real
numbers. It will report that

sqrt (3.) = 1.73205078 , sqrt (1100.) = 33.1662483 , sqrt (2.25) = 1.5 .

Fortran can use also scientific notation to represent real numbers. The sequence "En"
attached to the end of a number, where n is an integer, means that the number is to be
multiplied by 10n. Here are various ways of writing the number 12.345:
1.2345E1 , .12345E2 , .012345E3 , 12.345E0 , 12345E-3 .

In working in single precision it is futile to assign more than 9 or 10 nonzero digits to


represent a number, as Fortran will change all further digits to 0. (The 10th digit can
affect how Fortran does the truncation.) The assignments

x = 123456789876543. , x = 123456789800000. , x = 1234567898E5

produce the same result if x already has been declared a single precision real number.
Note that commas are not used in representing numbers; as helpful as they might be to
humans, computers find them unnecessary.

Double Precision Real Numbers

A double precision real number in GNU Fortran can be represented by up to 17 digits


before truncation occurs. Double precision numbers are written in scientific notation but
with D usurping the role of E. Some various ways of writing the number 12.345 as a
double precision real number are
1.2345D1 , .12345D2 , .012345D3 , 12.345D0 , 12345D-3 .

When assigning a value to a double precision variable you should use this D-scientific
notation, as otherwise the value will be read only in single precision. For example, if A is
double precision and you want to assign A the value 3.2, you should write

A = 3.2D0

instead of just A = 3.2. (See Base 2 Conversion Errors below for more explanation.)

When a number is input from the keyboard in response to a "read *" command, the user
need not worry about types or input format. Suppose for example that x is single or
double precision, and the user is to enter a value for x in response to the command "read
*, x". If the user enters simply "3" (integer format), GNU Fortran will change 3 to the
proper format (to 3. if x is single precision and to 3D0 if x is double precision) before
assigning it to x. Likewise, if x is double precision and the user enters 3.1 (single
precision format), Fortran converts 3.1 to 3.1D0 before assigning it to x. (However, with
an ordinary assignment statement "x = 3.1" from within the program, the number is not
changed to double precision format before being assigned to x.)

A number x can be converted to double precision by the function

dble(x) .

Base 2 Conversion Errors


Whereas humans, having 10 fingers, do arithmetic in base 10, computers have no fingers
but do arithmetic with on-off switches and therefore use base 2. As we know, some
numbers have infinite decimal representations in base 10, such as
1/3 = .33333 … , 2/7 = .285714285714 … .

There is no way to represent such numbers in base 10 with a finite number of digits
without making a round-off error. Computers have the same problem working in base 2.
In general, the only numbers representable with a finite number of digits in base 2 can be
written in the form m/n, where m and n are integers and n is an integral power of 2.
Examples are

6 (= 6/20) , 5/2 , 3/8 , 29/16 , 537/256 , -3/1024 .

When we ask computers to do arithmetic for us, there is an inevitable source of error. We
give the computer the numbers in base 10, and the computer must change them all over to
base 2. For most numbers there is a round-off error, as the computer can work with only a
finite number of digits at a time, and most numbers do not have a finite representation in
base 2. If the computer is working in single precision Fortran, it works in about 9 digits
(base 10), and so the round-off error will occur in about the 8th or 9th base 10 digit. In
double precision this error appears much later, in about the 16th or 17th base 10 digit. If
the arithmetic the computer performs is very complicated, these round-off errors can
accumulate on top of each other until the total error in the end result is much larger. After
the computer has done its job in base 2, it converts all numbers back to base 10 and
reports its results.

Even if the computer does no arithmetic at all, but just prints out the numbers, the base 2
conversion error still appears. Here is a program illustrating the phenomenon:

program demo
real x
double precision y, z
x = 1.1
y = 1.1
z = 1.1D0
print *, "x =", x, " , y =", y, " , z =", z
end

The somewhat surprising output when this program is run in GNU Fortran is

x = 1.10000002 , y = 1.10000002 , z = 1.1 .

The variable x is single precision, and base 2 conversion round-off error shows up in the
9th digit. Although y is double precision, it has the same round-off error as x because the
value 1.1 is assigned to y only in single precision mode. (What happens is Fortran
converts 1.1 to base 2 before changing it to double precision and assigning it to y.) Since
z is double precision, and it is assigned the value 1.1 in double precision mode, round-off
error occurs much later, far beyond the nine digits in which the results are printed. Thus
the value of z prints exactly as it is received. Using write and format statements (see
below), it is possible to print z using 17 digits; if you do so, you will find that Fortran
reports z = 1.1000000000000001, where the final erroneous 1 appears as the 17th digit.

Base 2 round-off error occurs in the preceding example because 1.1 = 11/10, and 10 is not
a power of 2. If you modify the program by replacing 1.1 with 1.125 = 9/8, there will be
no round-off error because 8 = 23 is a power of 2 - so the values of x, y, and z will print
exactly as assigned. (Try it!!)

Mixed Type Arithmetic

In general, arithmetic in Fortran that mixes numbers of different types should be avoided,
as the rules are quickly forgotten and mistakes are easily made. If Fortran is asked in
some arithmetic operation to combine an integer number with a real one, usually it will
wait until it is forced to combine the two and then convert the integer to real mode. Here
are some calculations illustrating the process followed by Fortran, and showing why you
should stay away from this nonsense:
5. * (3 / 4) = 5. * 0 = 5. * 0. = 0.
(5. * 3) / 4 = (5. * 3.) / 4 = 15. / 4 = 15. / 4. = 3.75
5. + 3 / 4 = 5. + 0 = 5. + 0. = 5.
5 + 3. / 4 = 5 + 3. / 4. = 5 + .75 = 5. + .75 = 5.75

If x and y are declared as double precision variables, and you want to multiply x by a
number, say 2.1 for example, to get y, you should write

y = 2.1D0 * x .

Writing just y = 2.1 * x will retain single precision when 2.1 is converted to base 2,
thereby introducing a larger base 2 round-off error and defeating your efforts at double
precision. Similar remarks apply to other arithmetic operations. Errors of this nature are
easily made when working in double precision. The best way to avoid them is to follow
religiously this general rule:

Do not mix numbers of different types in Fortran arithmetic!!

Exponentials and Roots

Already we point out an exception to the above rule - it is OK to use integers as


exponents of real numbers. That is because, when serving as an exponent, an integer acts
more as a "counter of multiplications" rather than as an active participant in the
arithmetic. For instance, when Fortran does the calculation 1.25, it performs the
multiplications
1.2 * 1.2 * 1.2 *1.2 * 1.2 ,
and the integer 5 never enters into the calculations! Thus, although it may appear so at
first glance, the computation of 1.25 does not really mix an integer with a real number in
any arithmetic operation. The same can be said of negative integers as exponents. The
calculation of 1.2-5 involves multiplying five factors of 1.2, and then taking the reciprocal
of the result - so the number -5 is not involved in the actual arithmetic.

Rational exponents must be handled carefully. A common mistake of novice Fortran


programmers is to write something like 5 ** (2/3) and expect Fortran to compute the
value of 52/3. But Fortran will view 2 and 3 as integers and compute 2/3 = 0, and conclude
that 5 ** (2/3) = 5 ** 0 = 1. The correct expression for computing 52/3 is

5. ** (2./3.) ,

wherein all numbers are viewed as real numbers.

Roots of numbers are computed in the same manner. To compute the seventh root of 3
you would use the expression

3. ** (1./7.) .

If N is an integer variable and you wish to compute the N-th root of the real variable x, do
not write x ** (1/N), as Fortran will interpret 1/N as 0 when N > 1. Instead write x **
(1./real (N)), so that 1 and N are first converted to real variables.

Write and Format Statements

Just as in Basic we use TAB and PRINT USING commands to more precisely control
program output, in Fortran we can use write commands with format statements. While
these can get complicated, the most commonly used options are pretty easy to use. A
typical write statement is
write (*,20) x, y, z .

The "*" in the parentheses instructs Fortran to write to the screen, while "20" refers to the
label of the format statement for this write command. The x, y, and z are the variables to
be printed. A format statement for this write command might be

20 format (3f10.4) .

Inside the parentheses, the "3" indicates that 3 entities will be printed, the "f" denotes that
these will be floating point real numbers (not exponential notation), the "10" stipulates
that 10 places will be used for printing (counting the sign, decimal point, and the digits),
and ".4" mandates 4 digits after the decimal point. Some printouts formatted this way are

12345.6789 , -1234.5678 , 10002.3400 .


The letter "f" in this context is a format code letter; here are some of the more commonly
used format code letters, with their implications:

f real number, floating point format


e single precision real number, exponential notation
d double precision real number, exponential notation
i integer
a text string (character)
x space
/ vertical space (line feed)
t tab indicator

Strings (in quotes) may be placed in format statements, separated by commas. Here are
examples of write statements with corresponding format statements; at the right of each is
a description of the corresponding output:

integer n printed using 4 places,


then 4 spaces, then real numbers
write (*,10) n, x, y
x and y printed with 2 spaces
10 format (i4,4x,f10.4,2x,f10.4)
between, each using 10 places
and 4 decimal places
string in quotes is printed, then the
write (*,20) area
real number area is printed, using
20 format ("The area is ",f8.5)
8 places with 5 decimal places
write (*,30) "The area is ", area
same output as immediately above
30 format (a,f8.5)
3 double precision numbers x, y, z
write (*,40) x, y, z
printed, each reserving 20 spaces,
40 format (3d20.14)
with 14 decimal places
student, a text string up to 20
write (*,50) student, score characters, is printed, then 4
50 format (a20,4x,i3) spaces, then score, an integer
using a maximum of 3 places
tabs to column 10, prints real
write (*,60) r, A
number r, goes to next line, tabs to
60 format (t10,f4.2,/,t10,f6.2)
column 10, prints real number A
You can use loops with format statements to print arrays; here are examples:

an array a of real numbers,


do i = 1, 10
indexed from 1 to 10, is printed;
write (*,70) a(i)
each entry occupies 5 places with
end do
2 decimal places, and is printed
70 format (f5.2)
on a separate line
write (*,80) (a(i), i = 1, 10)
same output as immediately above
80 format (f5.2)
write (*,90) (a(i), i = 1, 10) same output as above, except that all
90 format (10f5.2) entries are printed on the same line
do i = 1, 5 prints a 5 x 6 two-dimensional array
write (*,7) (m(i,j), j = 1, 6) m of integers, with each integer entry
7 format (6i3) m(i,j) occupying 3 places. Each row
end do of the matrix appears on its own line.
Here are other useful things to know about formatting:

1. If you do not specify a format, GNU Fortran will print real numbers using about 9
digits, even if you do calculations in double precision. If you want to print in
double precision you must use write and format statements. When double
precision is used the maximum number of digits possible is 17. A format specifier
something like format (fm.n), where m is at least 20, is required to take full
advantage of double precision.
2. If a value is too large to be printed in the specified format, Fortran will just print a
string of asterisks (eg: ********** ). If you get such an output, you have to fix
your format statement.
3. Real numbers are rounded off (not truncated) to fit the specified formatting.
4. If your formatting specifies more positions than the number requires, blanks are
inserted to the left of the number.
5. Format statements may appear anywhere in a program after the variable
declarations and before the end statement.
6. Unless your format statement is very simple, the chances are that your output
won't look like you want on the first try - just fiddle with the formatting until you
get it right.

Following are examples of stored values, formatting specifications for printing the
values, and resulting output. (The "^" symbol indicates a blank).
Stored Value Format Specifier Output
1.234567 f8.2 ^^^^1.23
0.00001 f5.3 0.000
-12345 i5 *****
-12345 i6 -12345
12345 i6 ^12345
0.00001234 e10.3 ^0.123E-04
0.0001234 e12.4 ^^0.1234E-03
1234567.89 e9.2 ^0.12E+07
aloha a8 ^^^aloha
1.23456789123D0 d17.10 ^0.1234567891E+01

FORTRAN LESSON 4
Lesson Topics
Statement Functions Do While Loops
Continuation Lines Sign Function
View Demos Download Demos
#1#2#3#4#5#6 #1#2#3#4#5#6
Main Fortran Page

Statement Functions

A statement function in Fortran is like a single line function definition in Basic. These are
useful in defining functions that can be expressed with a single formula. A statement
function should appear before any executable statement in the program, but after any type
declaration statements. The format is simple - just type
f(x,y,z,…) = formula .

You may replace f with any name you like for your function, and x, y, z, … with your
own variable names. Instead of formula type the formula for your function.

Examples :
area(r) = pi * r * r
vol(r,h) = pi * r * r * h
f(x,y,z) = sqrt(x / y) * cos(z)

You should declare a type for the function in a declaration statement. Here is a program
using a statement function, named "area", to compute areas of circles; the program
computes in double precision the area of an annulus of inner radius a and outer radius b:

program annulus
double precision r, area, pi, a, b
parameter (pi = 3.1415926535897932D0)
area(r) = pi * r * r
print *, "Enter the inner and outer radii of the annulus: "
read *, a, b
write (*,10) "The area of the annulus is ", area(b) - area(a)
10 format (a,f25.15)
end

In the type declaration statement just include the name of the function - do not include the
parentheses or the function variables.

Observe that variables plugged into the function need not be the same variables used in
defining the function.

It is possible to use a previous statement function in the definition of another. In the


above program, for example, we have already defined the function area(r), so we could
define further a second function "annarea", giving the area of the annulus as

annarea(a,b) = area(b) - area(a) .

But this second function definition must appear later in the program than the first one.

Continuation Lines

Sometimes a Fortran statement will not all fit into columns 7-72. In such a case you may
continue the statement onto the next line by placing a character in column 6 of that next
line. Although any character is allowed, most programmers use "+", "&", or a digit (using
2 for the first continuation line, 3 for another if necessary, and so on).

Example :

det = a(1,1) * a(2,2) * a(3,3) + a(1,2) * a(2,3) * a(3,1)


& + a(2,1) * a(3,2) * a(1,3) - a(3,1) * a(2,2) * a(1,3)
& - a(2,1) * a(1,2) * a(3,3) - a(1,1) * a(3,2) * a(2,3)
Do While Loops

A do while loop in Fortran is similar to the same loop in Basic. However, in Fortran the
test must be enclosed in parentheses, and the end of the loop is identified with either end
do or a labeled continue statement. As in "if … then" constructions, in loop tests one uses
letter abbreviations for relations such as "≤", ">", "=", etc. Here are two loops adding the
squares of the integers from 1 to 10; they differ only in the way the loops are terminated:
N=1 | N=1
S=0 | S=0
do while (N .le. 10) | do 5 while (N .le. 10)
S = S + N ** 2 | S = S + N ** 2
N=N+1 | N=N+1
end do | 5 continue

Sign Function

The function sign in Fortran is called the sign transfer function. It is a function of two
variables, and its definition involves two cases:
CASE 1: If y ≥ 0 then
sign(x,y) = abs(x) ,
CASE 2: If y < 0 then
sign(x,y) = - abs(x) .

The practical effect is that sign(x,y) has the same absolute value as x, but it has the same
sign as y; thus the sign of y is transferred to x. (The case y = 0 is a little special - it gives
sign(x,y) always a plus sign.)

Examples :

sign(2,3) = 2 , sign(2, -3) = - 2 , sign(-2,3) = 2 , sign(-2, -3) = - 2 .

The variables x and y in sign(x,y) may be integers or real numbers, and either single or
double precision. (And x and y may even be of different types.)

If we substitute x = 1 in the sign transfer function, we get the sign of y; that is,

CASE 1: If y ≥ 0 then
sign(1,y) = 1 ,
CASE 2: If y < 0 then
sign(1,y) = - 1 .

Thus, sign(1,y) in Fortran is essentially the same as the function SGN(y) in Basic (except
when y = 0, when the Fortran value is + 1 but the Basic value is 0).
FORTRAN LESSON 5
Lesson Topics
Arrays Factorials
Dimension Statement Arrays in Function Subprograms
Function Subprograms Return in Function Subprograms
View Demos Download Demos
#1#2#3 #1#2#3
Main Fortran Page

Arrays

There are only a few minor differences in the way Fortran and Basic treat arrays. Array
declarations in Fortran go at the beginning of the program, before any executable
statement. Arrays can be declared with either a dimension statement or a type declaration.
The latter way is preferred, because it is best anyway to declare the type of the array.
Here are examples of arrays introduced by type declarations:
one-dimensional arrays a and b of
real a(10), b(5) real variables, indexed from 1 to 10
and from 1 to 5, respectively
one-dimensional array n of integers,
integer n(3:8), m indexed from 3 to 8, and an integer
variable m
two-dimensional array c of double
precision real numbers, the first
double precision c(4,5)
index running from 1 to 4, and the
second from 1 to 5
one-dimensional array student of
character student(30)*20 strings, indexed from 1 to 30, each
string up to 20 symbols long
real num(0:5,1:10,-3:3) three-dimensional array num of single
precision real numbers, the first index
running from 0 to 5, the second from
1 to 10, and the third from -3 to 3

In Fortran the default lower limit of the range of a subscript is 1, rather than 0 as in Basic.
A colon separates the lower and upper limits whenever both are specified.

Because arrays are declared at the beginning of the program, they must be given a fixed
size - i.e., the limits must be constants rather than variables. (In this respect Fortran is less
flexible than Basic, in that Basic allows the dimension of an array to be a variable whose
value can be input by the user, thereby ensuring that exactly the right amount of storage
space is reserved.) You don't have to use the full size of the array specified in the
declaration statements; that is, you may reserve space for more entries in the array than
you will need.

If you use a dimension statement to declare an array, you should precede it with a type
declaration. Here is one way to introduce a real array weights, indexed from 1 to 7:

real weights
dimension weights(7)

But the same can be accomplished more briefly with the single statement

real weights(7) .

Although the upper and lower limits of an array cannot be variables, they can be
constants declared in parameter statements. The sequence of statements

integer max
parameter (max = 100)
character names(max)*30
real scores(max)

instructs Fortran to set aside storage space for a list of at most 100 names, each a string of
length no longer than 30 symbols, as well as a list of at most 100 scores, each a real
number.

As in Basic, in Fortran you may input and print arrays with do loops. But you can
sometimes more efficiently do the same with single statements. For instance, the above
array weights can be input with only the statement

read *, weights .

This read statement pauses the program to allow the user to enter all seven entries of the
array. The user can either enter the seven weights one-by-one separated by returns, or
alternatively, can enter all seven weights separated only by commas, and then a single
return. If you want to input say only the first five weights, you can do so with the
statement

read *, (weights(i), i=1,5) .

Analogously, the single print statement

print *, weights

prints the seven entries of weights to the screen, while the statement

print *, (weights(i), i=p,q)

prints only the weights indexed from p to q.

There are various formatting tricks useful in printing two-dimensional arrays. Here is one
example demonstrating how to print a matrix A having 5 rows and 6 columns of real
numbers, with each row of the matrix printed on its own line :

do i = 1, 5
write (*,10) (A(i,j), j = 1, 6)
end do
10 format (6f7.3)

More precise formatting can be accomplished with double loops and tab indicators.

Function Subprograms

Function subprograms in Fortran define functions too complicated to describe in one line.
Here is a function subprogram defining the factorial function, fact(n) = n! :
function fact(n)
integer fact, n, p
p=1
do i = 1, n
p=p*i
end do
fact = p
end

The first line of the function subprogram specifies the name of the function, and lists in
parentheses the variables upon which the function depends. The subprogram has its own
type statements, declaring the type of the function itself, as well as the types of the
variables involved in computing the function. Somewhere in the subprogram there must
be a line giving the value of the function. (Above it is the line "fact = p".) The
subprogram concludes with an end statement. In Fortran, function subprograms do not
have to be declared as they do in Basic. The entire function subprogram appears in the
source file after the final end statement of the main program.

The above factorial subprogram, with variables of integer type, works only for
nonnegative integers no larger than 12, as 13! = 6,227,020,800 exceeds the Fortran upper
limit of 2,147,483,647 for integers. To handle larger integers, the types can be changed to
real or double precision. In GNU Fortran, single precision real type handles factorials of
integers as large as 34, and double precision as large as 170.

The main program (or in fact any subprogram) utilizing a function subprogram should
likewise specify the type of the function. Here is a simple main program using the above
factorial function "fact":

program demofactorial
integer fact, n
print *, "What is n?"
read *, n
print *, "The value of", n, " factorial is", fact(n)
end

Because n is declared an integer in the function subprogram defining fact(n), it must also
be an integer in the main program when fact(n) is evaluated; if it is of a different type the
compiler displays a type mismatch error message.

A function subprogram may depend on several variables, and it may use an already
defined statement function or a function defined by another function subprogram.
Following is a function subprogram utilizing the above factorial function subprogram; it
computes the Poisson probability function, defined as

P(n,t) = tn e- t / n! ,

where n is a nonnegative integer and t any positive number:

function poisson(n,t)
real poisson, t
integer n, fact
poisson = (t ** n) * exp(-t) / fact(n)
end

Note that, as this subprogram references the function "fact", it must declare its type. Both
this subprogram and the factorial subprogram will appear in the source file following the
end statement for the main program. (The order in which the subprograms are typed
makes no difference - just as long as they both follow the main program.)
Again, in referencing function subprograms one must respect types; for example, if the
main program is to compute poisson(m,s) for some variables m and s, then, in order to
conform to the type declarations in the function poisson, m must first be declared an
integer and s of real type. Oversights will lead to compiler type-mismatch messages.

Arrays in Function Subprograms

An array can be listed as a variable of a function defined by a function subprogram - but


you just write the array name, with no parentheses after the name as in Basic. The type
and dimension of the array must be specified in the function subprogram.

Following is a program called "mean" that computes the mean, or average, of a list
containing up to 100 numbers. The main program prompts for the list of numbers, and
then references a function subprogram named "avg" that computes the average.

program mean
real numbers(100), avg
integer m
print *, "How many numbers are on your list?"
print *, "(no more than 100, please)"
read *, m
do i =1, m
print *, "Enter your next number:"
read *, numbers(i)
end do
print *, "The average is", avg(m,numbers)
end

function avg(n,list)
real avg, list(100), sum
integer n
sum = 0
do i = 1, n
sum = sum + list(i)
end do
avg = sum/n
end

Note that both the main program and the subprogram declare the type of the function
"avg". The main program calls the function subprogram with the arguments "m" and
"numbers", and these are substituted into the function subprogram for the variables "n"
and "list". The main program specifies the dimension of the array "numbers", while the
subprogram specifies the dimension of the array "list". The subprogram does its
calculations and returns the value of "avg" to the main program. For this procedure to
work, the types of the variables "m" and "n" must agree, as well as the types of
"numbers" and "list".

Return (in Function Subprograms)

A return statement in a function subprogram acts like a stop statement in the main
program; the subprogram is terminated and Fortran returns to where it left off in the main
program. Here is a function subprogram defined on integers n; the value of the function
"demo" is 0 if n ≤ 0, and if n > 0 it is the sum of the squares of the integers from 1 to n:
function demo(n)
integer demo, n
demo = 0
if (n .le. 0) return
do i =1, n
demo = demo + i * i
end do
end

FORTRAN LESSON 6
Lesson Topics
Initializing Variables Call Statement
Mod Return in Subroutines
Subroutines Variable Substitution
View Demos Download Demos
#1#2#3#4 #1#2#3#4
Main Fortran Page

Initializing Variables

Recall that in Basic the default value of a numeric variable is always zero - that is, if you
introduce a numeric variable but do not specify its value, Basic automatically gives it the
value zero. In GNU Fortran the situation is more confused. A real variable with no value
specified will be given a value - but usually a very small value that is not precisely zero,
and sometimes a value that is not even close to zero. An integer is given the default value
1. This strange behavior is hardly ever a problem, as usually when the variable is
eventually used in the program it is given an appropriate value by some assignment
statement. But trouble might arise if a forgetful programmer proceeds on the assumption
that the default value is zero, or perhaps neglects to include an assignment statement. If
you are worried about the problem, you can assign values to all your variables at the
beginning of your program - a procedure called "initializing variables". The easiest way
to do this is with ordinary assignment statements, such as "x = 0", or "y = 2.61", etc. (For
programs with a large number of variables a more efficient method is to use DATA
statements; we will discuss these later.)

Mod

In Fortran the expression mod(n,m) gives the remainder when n is divided by m; it is


meant to be applied mainly to integers. Examples are
mod(8,3) = 2 , mod(27,4) = 3 , mod(11,2) = 1 , mod(20,5) = 0 .

Subroutines

A subroutine in Fortran works like a subprogram in Basic, except that you do not declare
a subroutine. Subroutines are typed in the source file after the main program. A
subroutine must have a name, followed by a list of variables in parentheses. A variable
may be of any type, including a character variable, and can be an array. A subroutine
begins with variable declaration statements, just as the main program.

The main program uses a call statement to call the subroutine. The call statement has also
a list of variables, which are substituted for the subroutine variables. The subroutine
executes, modifying some or all of its variables, which are then substituted back for the
original call variables in the main program. The variables in the call statement must
match the variables in the subroutine according to number, type, and dimension.
(Oversights lead to type-mismatch error messages by the compiler.)

Here is a simple program named average that prompts the user for two real numbers,
calls a subroutine named avg to average the numbers, and then prints the average.

program average
real x, y, z
print *, "What are the two numbers you want to average?"
read *, x, y
call avg(x,y,z)
print *, "The average is", z
end

subroutine avg(a,b,c)
real a, b, c
c = (a + b)/2.
end

When the subroutine is called it substitutes x for a, y for b, and z for c. (Although the user
does not input z, GNU Fortran will have given it some default value.) After the
subroutine does its calculations, the new values of a, b, c are substituted back into the
main program for x, y, z. (In this particular subroutine only c changes, so x and y retain
their original values.) After the subroutine completes its run, action is returned to the
statement in the main program immediately following the call statement.

Just remember that, except for the first statement naming the subroutine and listing the
variables, a subroutine has the same general structure as a main program. It begins with
type and dimension statements, has a main body carrying out the action, and concludes
with an end statement.

The advantage of using subroutines is that the main program can be kept relatively simple
and easy to follow, while nitty-gritty calculations and complex procedures are shuffled
off to various subroutines, each performing a specific task. A well-written subroutine can
be saved in a subroutine "library", to be inserted into other main programs as the need
arises.

A subroutine can call another subroutine, and it can also access a function subprogram.

A subroutine need not depend on any variables - in which case no parentheses follow the
subroutine name. Here is a simple subroutine involving no variables:

subroutine bluesky
print *, "The sky is blue."
end

The call statement for this subroutine,

call bluesky ,

likewise lists no variables.

The following subroutine computes the product of a 2 x 2 matrix A with a 2 x 1 vector x,


according to the formula

It accepts as variables a 2 x 2 array A and one-dimensional arrays x and y, each indexed


from 1 to 2. The array y represents the product y = Ax.
subroutine prod(A,x,y)
real A(2,2), x(2), y(2)
y(1) = A(1,1) * x(1) + A(1,2) * x(2)
y(2) = A(2,1) * x(1) + A(2,2) * x(2)
end

A call statement for this subroutine might be something like

call prod(B,u,v) ,

where B and u are arrays known to the main program and the product v is to be computed
by the subroutine. Of course the main program will have appropriately dimensioned these
arrays. After the subroutine completes its task and returns control to the main program,
the array v will represent the product Bu.

Return (in Subroutines)

A return statement in a subroutine instructs Fortran to terminate the subroutine and return
to the main program at the point where it departed. Thus it works like a stop statement in
the main program, halting the program prematurely before the final end statement. A
subroutine may have several returns, but only one end statement.

Here is a subroutine, using a return statement, that decides whether a positive integer n is
a prime number:

subroutine check(n,result)
integer n, i, root
character result*9
if (n .eq. 1) then
result = "not prime"
return
end if
root = sqrt(real(n))
do i = 2, root
if (mod(n,i) .eq. 0) then
result = "not prime"
return
end if
end do
result = "prime"
end

The subroutine begins by checking whether n = 1, and if true it sets result = "not prime"
and returns to the main program. If n > 1 the DO LOOP looks at integers from 2 up to the
square root of n, checking whether each is a divisor of n. If and when it finds such a
divisor, it sets result = "not prime" and returns to the main program. But if no divisor of n
is found, the subroutine completes the entire loop and sets result = "prime". After the
subroutine ends, the main program need only look at the value of result to find out
whether n is prime or not prime.

Variable Substitution in Subprograms

We look in more detail at how variables are substituted for one another in the calling and
execution of a subroutine or function subprogram. Let us suppose for example that a
certain subroutine named "demo" depends on three variables, say a, b, and c, so that the
first line of the subroutine is
subroutine demo(a,b,c) .

Let us assume also that the main program's call statement for this subroutine is

call demo(x,y,z) ,

where x, y, and z are variables from the main program. The types and dimensions of x, y,
and z will have been declared in the main program, and these must match the types and
dimensions of a, b, and c, respectively, as declared in the subroutine.

The values of x, y, and z will have been stored by Fortran in certain memory locations,
designated in the diagram below as triangles:

x→Δ
y→Δ
z →Δ

When the subroutine "demo" is called, Fortran assigns the variable a the same memory
location as x, b the same location as y, and c the same as z:

x →Δ← a
y →Δ← b
z →Δ← c

(This explains why the types and dimensions must match!) Now, as the subroutine
"demo" runs, the variables a, b and c might change to new values. But since x, y, and z
share memory locations with a, b, and c, the values of x, y, and z of course will have to
change simultaneously along with a, b, and c. When the subroutine terminates and returns
control to the main program, a, b, and c then are no longer active variables, but x, y, and z
retain the final values of a, b, and c at the conclusion of the subroutine.

There is a way to fool Fortran into not changing the value of a calling variable when the
subroutine runs. In the above example, suppose we change the call statement to
call demo(x,(y),z) .

When the variable y is enclosed in parentheses, Fortran treats (y) as a new expression and
assigns it a different memory location than that of y, but with the same value as y. The
last diagram changes to

x →Δ← a
y→Δ
(y) → Δ ← b
z →Δ← c

Now, as b changes values during the execution of the subroutine, y is unaffected, so that
at the conclusion of the subroutine y has its original value.

The above analysis applies to function subprograms as well as to subroutines. Changes in


the function variables during execution of a function subprogram induce corresponding
changes in the variables used to call the function subprogram.

FORTRAN LESSON 7
Lesson Topics
Open Write (to Files)
Close Read (from Files)
View Demos Download Demos
#1#2#3 #1#2#3
Main Fortran Page

Sometimes it is convenient in a Fortran program to use files for accessing or storing data -
especially when large amounts of data are involved. Too much keyboard input during the
run of a program leads to mistakes and tedium, while too much screen output has similar
consequences. Putting data into files - both for input and output - is a more leisurely and
less error-prone approach.

Open
The open command is used to open files - that is, it makes files available so that Fortran
can read or write to them. The simplest form of the command is
open (unit = number, file = "name") .

In place of number you insert a positive integer (but not 6) to be used to refer to the file,
and instead of name you insert the name of the file. Here are examples of open
commands:

open (unit = 2, file = "scores")


open (unit = 7, file = "a:scores.txt")
open (unit = 5, file = "h:\\results\\primes")
open (unit = 24, file = "c:\\fortran\\data\\divisors.dat") .

Fortran uses the unit number to access the file with later read and write statements.
Several files can be open at once, but each must have a different number. There is one
thing to remember about numbering a file - you cannot use the number 6, as GNU
Fortran reserves that number to refer to the screen.

Note that quotes enclose the filename. Also, in specifying a directory path for a file, you
must use double backslashes instead of single ones. Do not put a space on either side of
the colon after the drive letter. If you do not specify a drive or directory path for a file, or
if you specify the same drive upon which GNU Fortran is installed but without a path,
GNU Fortran will by default assume the file is located on the same drive and in the same
directory from where Fortran is running.

If the named file does not already exist, Fortran will create it; if it does exist, Fortran will
replace it. (So don't mistakenly give the file the same name as another important file!)

Close

The close command is used to close one or more files - examples are
close (5) , close (1, 3, 8) .

The first of these commands closes the file numbered 5, while the second closes the three
files numbered 1, 3, and 8. It is not necessary to close files; all files will automatically be
closed when an end or stop statement is executed. However, in programs handling large
amounts of data it can be prudent to close files before the end of the program in order to
avoid possible memory problems and to increase efficiency.

Write (to Files)

The write command is used to write data to a file. For example, the command
write (7,*)

works like a print * command, except that data is written to the file numbered 7 instead
of to the screen. The two statements
print *, "The solutions to the equation are : ", x1, x2
write (7,*) "The solutions to the equation are : ", x1, x2

produce exactly the same output, except that the first writes to the screen and the second
to file number 7. The command "write (7,*)" on a line by itself serves as a line feed,
skipping a line in the file numbered 7 before the next writing to that file.

You can also use write statements in conjunction with format statements to write to a file;
this gives you better control of formatting. In the following, the first number in "write
(7,5)" refers to the file number and the second to the label of the format statement:

write (7,5) "The solutions are ", x1, " and ", x2
5 format (a,f16.10,a,f16.10)

The "write (7,5)" command works exactly like the similar command "write (*,5)", except
that in the former output is directed to file number 7, and in the latter to the screen.

Each execution of a write command writes to a single line in a file. The next write
command will write to a new line.

Here is a program that finds and prints to a file the divisors of an integer n :

program divisors
c This program finds the divisors of an integer input by the user.
c The divisors are printed to a file.
integer n, k, d(10)
open (unit = 1, file = "divisors")
print *, "Enter a positive integer :"
read *, n
write (1,*) "Here are the divisors of ", n, " :"
k=0
do i = 1, n
if (mod(n,i) .eq. 0) then
k=k+1
d(k) = i
end if
if (k .eq. 10) then
write (1,5) (d(j), j = 1, 10)
k=0
end if
end do
write (1,5) (d(j), j = 1, k)
5 format (10i7)
close (1)
print *, "The divisors are listed in the file 'divisors'. Bye."
end

Note that the program counts the divisors, storing them in an array d, until 10 are
accumulated; then it prints these 10 on a single line, reserving 7 places for each divisor. It
then begins a new count and repeats the procedure until all divisors are found. The last
write statement prints whatever divisors are left over after the last full line of 10. The
close statement, included here for demonstration only, is unnecessary, as the program is
all but finished at that point and the end statement will automatically close the file
anyway.

Read (from Files)

The read statement is used to read data from a file. Generally data is read from a file in
the standard way, line-by-line and from left to right. But you must remember that each
read statement begins reading a new line, whether or not the preceding read statement
used all the data in the preceding line.

Suppose for example that a file is numbered 7, and that the first two lines of the file
contain the data (separated by commas)

1.23 , 4.56 , 7.89


11, 13 , "Sally"

If the first two read statements in the program are

read (7,*) x, y, z
read (7,*) m, n, first ,

then the program assigns x = 1.23, y = 4.56, z = 7.89, m = 11, n = 13, first = "Sally". The
variables will have to be declared in the program to correspond with the data assigned
them by the read statements. For instance, in the above situation x, y, and z will have
been declared real variables, m and n integers, and "first" a character variable. Failure to
match variable types with data types will most likely lead to error messages.

It is possible that a program does not know beforehand the length of a file. If data is
being read from a loop, there is a way to exit the loop when all data in the file has been
read, thereby avoiding a program hang-up. One simply modifies the read statement to
something like

read (7,*,end=10) .

This command instructs Fortran to read the next line in the file numbered 7, but to jump
to the statement labelled 10 in the program in the event that the last line in that file has
already been read.
You can also use format specifiers in read statements, but this can be somewhat tedious
and we will not go into the details. As but one example, suppose you want to make the
assignments

n = 77 , x = 123.45 , y = 67.8 ,

where n is an integer and x and y are real variables. Then you may use the read and
format statements

read (7,5) n, x, y
5 format (i2,f5.2,f3.1) ,

and in file number 7 place the corresponding line of data

7712345678 .

Fortran will read and separate the data, insert appropriate decimal points, and assign it to
the variables. But as you can see the method is confusing and perhaps not worth the
effort.

MORE FORTRAN INFO


Topics
Intrinsic Functions (More) Data
Save Arithmetic If
Common (Blank) Computed Go To
Common (Named)
Main Fortran Page

Following is further Fortran information not covered in the lessons.

More Intrinsic Functions

This table lists additional functions intrinsic to Fortran, not already listed in Lesson 1.
Function Description
truncates the decimal part of x
aint(x)
(without changing the type of x)
rounds x to the nearest integer
anint(x)
(without changing the type of x)
converts x to integer type, giving it
int(x) the value of the integer closest to x
but no larger than x in absolute value
log10(x) common logarithm of x (base 10)
max(x1,x2,...,xn) maximum of x1, x2, ..., xn
min(x1,x2,...,xn) minimum of x1, x2, ..., xn
converts x to integer type,
nint(x)
rounding x to the nearest integer

Save

This command, used in a subprogram, preserves the values of local variables (i.e.,
variables used in the subprogram but not listed in the title statement) from one call of the
subprogram to the next. For instance, the statement
save m, z

in a subroutine ensures that in calls after the first run the subroutine remembers the final
values of m and z from the previous run. A save statement by itself,

save ,

preserves the values of all local variables in the subprogram. You cannot save a listed
variable of the subprogram - the compiler will give an error message. (EG: If a
subroutine's first line is "subroutine area(r)", then you cannot save r.)

Common (Blank)

Ordinarily the only information shared between the main program and subprograms are
the values of variables appearing in variable lists. The common statement can be used to
share additional information.

The simplest form of the common statement is the blank common statement. Let us
suppose for illustration that the main program has real variables x and y as well as an
integer variable n which are to be shared with one or more subroutines. Then at the
beginning of the main program, before any executable statements, you first declare the
types of x, y, and n and next insert the "blank common" statement
common x, y, n .

This instructs Fortran to preserve three "common" memory locations for x, y, and n,
designated as triangles below:

x→Δ
y→Δ
n→Δ

These memory locations are then accessible by all subroutines of the program containing
a similar common statement (but with possibly different variables). For example, suppose
a subroutine declares real variables u and v and an integer variable m. If the subroutine
contains also the common statement

common u, v, m ,

then u, v, and m will share memory locations with x, y, and n, respectively :

x →Δ← u
y →Δ← v
n →Δ← m

When the values of u, v, and m change in the subroutine, then the values of x, y, and n in
the main program change accordingly; and vice-versa - changes in x, y, or n in the main
program produce changes in u, v, and m in the subroutine. Obviously, because of the
sharing of memory locations, the types of x, y, and n must match those of u, v, and m,
respectively (and also dimensions must match in the case of arrays.)

It is possible for a third or even more subroutines to share the same three memory
locations. If a third subroutine has real variables a and b and an integer variable k, as well
as the statement

common a, b, k ,

then x, u, a share one memory location, y, v, b another, and n, m, k a third. A change in


one of these variables in the main program or a subroutine produces the same change in
whatever variables share the same memory location.

A common statement cannot list variables that are listed also in the title statement of the
subprogram in which the common statement appears. (EG: If a subroutine's first line is
"subroutine area(r)", then you cannot list r in the subroutine's common statement.)

Common (Named)
In programs with more than one subroutine it is sometimes desirable to share different
sets of variables among different sets of program units. In such situations the named
common statement is useful. The general form of this statement is
common / name1 / list1 / name2 / list2 / name3 / list3 / … / nameN / listN .

The "names" are names for the different sets of variables, and the "lists" contain the
names of variables in these sets.

Suppose, for example, that the main program uses variables A, B, C, D, E, F, G, while
subroutine "demo1" uses variables A, B, C, D, and subroutine "demo2" uses variables C,
D, E, F, G. If we want all program units using the same variable to share the value of that
variable, then in the main program we insert the named common statement

common / first / A, B / second / C, D / third / E, F G ,

in subroutine "demo 1" we insert

common / first / A, B / second / C, D ,

and in "demo 2" we insert

common / second / C, D / third / E, F, G .

Then the variable set "first" consists of A and B, and is shared by the main program and
demo1. Variable set "second" consists of C and D and is shared by all three units.
Variable set "third" consists of E, F, and G and is shared by the main program and
"demo2". It is not necessary that different units use the same variable names for shared
data. For example, subroutine "demo2" could name its five variables V, W, X, Y, Z; then
its common statement would change to

common / second / V, W / third / X, Y, Z ,

and consequently V and C would share a memory location, as would W and D, X and E,
Y and F, and Z and G.

Data

A data statement is used to initialize (i.e., assign initial values to) variables before the
program begins. All data statements must appear after parameter and type declarations; it
is common practice to include them immediately following these statements.

The general form of a data statement is

data list1 / data1 / list2 / data2 / list3 / data 3 / ... / listN / dataN / .
Each list is a list of variables separated by commas, and each data is a list of values of the
variables in the preceding list. Following is a table of examples with the corresponding
resulting assignments:

data x, y, z / 2.1, 3.3, -4.4 / x = 2.1, y = 3.3, z = - 4.4


data k, m, n, p / 3 * 0, 1 / k = m = n = 0, p = 1
data first, last / "Jane", "Smith" / first = "Jane", last = "Smith"
data A / 5.2 / B, C / 2.8, 3.9 / A = 5.2, B = 2.8, C = 3.9
data x, y / 2*1. / m,n / 2*0 / pi / 3.14 / x = y = 1., m = n = 0, pi = 3.14

Note that in a data list the notation "n * x" means that the value x is to be assigned to n
successive variables in the preceding variable list.

Data statements were necessary in earlier versions of Fortran, when the compiler did not
automatically initialize variables; in more modern versions of Fortran they can usually be
omitted without repercussions.

Arithmetic If

The arithmetic if statement has the form


if (expression) k, m, n ,

where expression is some numeric expression that Fortran can evaluate, and k, m, n are
integers representing labels of executable statements. If expression is negative, zero, or
positive, then the program jumps to the statement labeled k, m, or n, respectively. As
illustration, a program solving a quadratic equation

ax2 + bx + c = 0

might have the arithmetic if statement

if (b * b - 4 * a * c) 10, 20, 30 .

Then if the discriminant b2 - 4ac is negative, the program jumps to the statement labeled
10, if it is zero the jump is to label 20, and if positive to label 30.

Computed Go To

The computed go to statement has the form


go to (n1 , n2 , ..., nm) integer expression ,
where n1, n2, ..., nm are integers representing labels of executable statements, and integer
expression is some integer - valued expression that Fortran can evaluate. If the value of
this expression is 1, the program jumps to the statement labeled n1, if the value is 2 the
program jumps to the statement labeled n2, etc. For example, suppose a program contains
the sequence

print *, "Enter the number of the task you want to perform:"


read *, n
go to (10,12,14,16,18,20) n

If the user enters 1, the program jumps to the statement labeled 10, if the user enters 2 it
jumps to statement 12, if the user enters 3 it jumps to 14, etc. If the user errs and enters an
integer different from 1, 2, 3, 4, 5, 6, Fortran defaults to the first statement listed, in this
case statement 10.

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