Fortran Guide
Fortran Guide
Programming
using
Fortran 95
Ed Jorgensen
August, 2015
Version 2.1.25
Cover Diagram
The cover image is the plotted output from the chaos game program from chapter 11.
The image was plotted with GNUplot.
Copyright
Ed Jorgensen, 2013, 2014, 2015
Attribution. You must attribute the work to Introduction to Programming using Fortran
95 (but not in any way that suggests that the authors endorse you or your use of the
work).
Share Alike. If you alter, transform, or build upon this work, you may distribute the
resulting work only under the same, similar or a compatible license.
For any reuse or distribution, you must make clear to others the license terms of this work. The
best way to do this is with a link to
http://creativecommons.org/licenses/by-sa/3.0/
Any of the above conditions can be waived if you get permission from the copyright holder.
Nothing in this license impairs or restricts the author's moral rights.
ii
Table of Contents
1 Introduction........................................................................................................................................
1.1 Why Learn Programming.............................................................................................................
1.2 Fortran..........................................................................................................................................
1.3 Complete Fortran 95 Documentation...........................................................................................
1.4 What Is A Program.......................................................................................................................
1.5 Operating System.........................................................................................................................
1
1
1
1
2
2
2 Computer Organization.....................................................................................................................
2.1 Architecture Overview.................................................................................................................
2.2 Compiler.......................................................................................................................................
2.3 Information Representation..........................................................................................................
2.3.1 Decimal Numbers.................................................................................................................
2.3.2 Binary Numbers....................................................................................................................
2.3.3 Character Representation......................................................................................................
2.4 Exercises.......................................................................................................................................
2.4.1 Quiz Questions......................................................................................................................
3
3
4
4
4
5
5
5
5
3 Getting Started................................................................................................................................... 7
3.1 Required Skills............................................................................................................................. 7
3.2 Program Formats.......................................................................................................................... 7
3.2.1 Program Statement................................................................................................................ 7
3.2.2 Comments............................................................................................................................. 8
3.2.3 Simple Output....................................................................................................................... 8
3.2.4 Example First Program...................................................................................................... 8
3.3 Text Editor.................................................................................................................................... 8
3.4 Compiling..................................................................................................................................... 9
3.4.1 Advanced Compiler Options................................................................................................. 9
3.5 Executing...................................................................................................................................... 9
3.6 Exercises..................................................................................................................................... 10
3.6.1 Quiz Questions.................................................................................................................... 10
3.6.2 Suggested Projects.............................................................................................................. 11
4 Fortran 95 Basic Elements...........................................................................................................
4.1 Variables.....................................................................................................................................
4.1.1 Variable Names...................................................................................................................
4.1.2 Keywords............................................................................................................................
4.2 Data Types..................................................................................................................................
4.2.1 Integer.................................................................................................................................
4.2.2 Real.....................................................................................................................................
4.2.3 Complex..............................................................................................................................
4.2.4 Character.............................................................................................................................
4.2.5 Logical................................................................................................................................
iii
13
13
13
14
14
14
15
15
15
15
15
16
16
16
16
17
17
17
17
18
18
18
19
19
19
20
5 Expressions.......................................................................................................................................
5.1 Literals........................................................................................................................................
5.1.1 Integer Literals....................................................................................................................
5.1.2 Real Literals........................................................................................................................
5.1.2.1 E-Notation...................................................................................................................
5.1.3 Complex Literals................................................................................................................
5.1.4 Character Literals................................................................................................................
5.1.5 Logical Constants...............................................................................................................
5.2 Arithmetic Operations................................................................................................................
5.2.1 Assignment.........................................................................................................................
5.2.2 Addition..............................................................................................................................
5.2.3 Subtraction..........................................................................................................................
5.2.4 Multiplication.....................................................................................................................
5.2.5 Division..............................................................................................................................
5.2.6 Exponentiation....................................................................................................................
5.3 Order of Operations....................................................................................................................
5.4 Intrinsic Functions......................................................................................................................
5.4.1 Mathematical Intrinsic Functions.......................................................................................
5.4.2 Conversion Functions.........................................................................................................
5.4.3 Summary.............................................................................................................................
5.5 Mixed Mode...............................................................................................................................
5.6 Examples....................................................................................................................................
5.7 Exercises.....................................................................................................................................
5.7.1 Quiz Questions....................................................................................................................
5.7.2 Suggested Projects..............................................................................................................
21
21
21
21
21
22
22
23
23
23
23
24
24
24
25
25
26
26
26
27
27
28
28
28
29
31
31
32
32
iv
6.3 Example......................................................................................................................................
6.4 Exercises.....................................................................................................................................
6.4.1 Quiz Questions....................................................................................................................
6.4.2 Suggested Projects..............................................................................................................
33
34
34
34
7 Program Development.....................................................................................................................
7.1 Understand the Problem.............................................................................................................
7.2 Create the Algorithm..................................................................................................................
7.3 Implement the Program..............................................................................................................
7.4 Test/Debug the Program.............................................................................................................
7.4.1 Error Terminology..............................................................................................................
7.4.1.1 Compiler Error............................................................................................................
7.4.1.2 Run-time Error............................................................................................................
7.4.1.3 Logic Error..................................................................................................................
7.5 Exercises.....................................................................................................................................
7.5.1 Quiz Questions....................................................................................................................
7.5.2 Suggested Projects..............................................................................................................
37
37
38
38
39
39
39
40
41
41
41
42
8 Selection Statements........................................................................................................................
8.1 Conditional Expressions.............................................................................................................
8.2 Logical Operators.......................................................................................................................
8.3 IF Statements..............................................................................................................................
8.3.1 IF THEN Statement............................................................................................................
8.3.1.1 IF THEN Statement, Simple Form.............................................................................
8.3.2 IF THEN ELSE Statement..................................................................................................
8.3.3 IF THEN ELSE IF Statement.............................................................................................
8.4 Example One..............................................................................................................................
8.4.1 Understand the Problem.....................................................................................................
8.4.2 Create the Algorithm...........................................................................................................
8.4.3 Implement the Program......................................................................................................
8.4.4 Test/Debug the Program.....................................................................................................
8.5 SELECT CASE Statement.........................................................................................................
8.6 Example Two..............................................................................................................................
8.6.1 Understand the Problem.....................................................................................................
8.6.2 Create the Algorithm...........................................................................................................
8.6.3 Implement the Program......................................................................................................
8.6.4 Test/Debug the Program.....................................................................................................
8.7 Exercises.....................................................................................................................................
8.7.1 Quiz Questions....................................................................................................................
8.7.2 Suggested Projects..............................................................................................................
43
43
44
44
45
45
45
46
47
47
48
49
50
51
53
53
53
54
54
55
55
56
9 Looping.............................................................................................................................................
9.1 Counter Controlled Looping......................................................................................................
9.2 EXIT and CYCLE Statements....................................................................................................
9.3 Counter Controlled Example......................................................................................................
9.3.1 Understand the Problem.....................................................................................................
9.3.2 Create the Algorithm...........................................................................................................
59
59
61
61
62
62
62
63
63
65
65
65
66
67
67
67
69
10 Formatted Input/Output...............................................................................................................
10.1 Format......................................................................................................................................
10.2 Format Specifiers.....................................................................................................................
10.3 Integer Format Specifier...........................................................................................................
10.4 Real Format Specifier...............................................................................................................
10.5 Logical Format Specifier..........................................................................................................
10.6 Character Format Specifier......................................................................................................
10.7 Advance Clause........................................................................................................................
10.8 Example....................................................................................................................................
10.8.1 Understand the Problem...................................................................................................
10.8.2 Create the Algorithm.........................................................................................................
10.8.3 Implement the Program....................................................................................................
10.8.4 Test/Debug the Program...................................................................................................
10.9 Exercises...................................................................................................................................
10.9.1 Quiz Questions..................................................................................................................
10.9.2 Suggested Projects............................................................................................................
71
71
71
72
73
73
74
75
75
76
76
76
78
79
79
79
81
81
82
82
82
83
83
83
84
84
85
85
85
86
87
87
87
88
vi
12 File Operations...............................................................................................................................
12.1 File Open..................................................................................................................................
12.2 File Write..................................................................................................................................
12.3 File Read...................................................................................................................................
12.4 Rewind......................................................................................................................................
12.5 Backspace.................................................................................................................................
12.6 Close File..................................................................................................................................
12.7 Example....................................................................................................................................
12.7.1 Understand the Problem...................................................................................................
12.7.2 Create the Algorithm.........................................................................................................
12.7.3 Implement the Program....................................................................................................
12.7.4 Test/Debug the Program...................................................................................................
12.8 Exercises...................................................................................................................................
12.8.1 Quiz Questions..................................................................................................................
12.8.2 Suggested Projects............................................................................................................
89
89
90
90
91
91
92
92
92
92
93
94
94
95
95
111
111
112
112
112
113
114
114
115
116
117
121
121
121
122
122
122
122
122
122
123
123
124
124
124
125
126
127
128
129
130
130
130
132
135
135
136
136
137
137
138
138
141
141
142
142
143
144
146
147
147
147
viii
17 Modules.........................................................................................................................................
17.1 Module Declaration................................................................................................................
17.2 Use Statement.........................................................................................................................
17.3 Updated Compilation Commands..........................................................................................
17.4 Module Example Program......................................................................................................
17.4.1 Understand the Problem.................................................................................................
17.4.2 Create the Algorithm.......................................................................................................
17.4.3 Implement the Program..................................................................................................
17.4.3.1 Main Program.........................................................................................................
17.4.3.2 Module Routines.....................................................................................................
17.4.4 Compile the Program......................................................................................................
17.4.5 Test/Debug the Program.................................................................................................
17.5 Exercises.................................................................................................................................
17.5.1 Quiz Questions................................................................................................................
17.5.2 Suggested Projects..........................................................................................................
149
149
150
150
151
151
152
152
152
153
154
154
155
155
155
18 Recursion......................................................................................................................................
18.1 Recursive Subroutines............................................................................................................
18.2 Recursive Print Binary Example............................................................................................
18.2.1 Understand the Problem.................................................................................................
18.2.2 Create the Algorithm.......................................................................................................
18.2.3 Implement the Program..................................................................................................
18.2.4 Test/Debug the Program.................................................................................................
18.3 Recursive Functions...............................................................................................................
18.4 Recursive Factorial Example..................................................................................................
18.4.1 Understand the Problem.................................................................................................
18.4.2 Create the Algorithm.......................................................................................................
18.4.3 Implement the Program..................................................................................................
18.4.4 Test/Debug the Program.................................................................................................
18.5 Recursive Factorial Function Call Tree..................................................................................
18.6 Exercises.................................................................................................................................
18.6.1 Quiz Questions................................................................................................................
18.6.2 Suggested Projects..........................................................................................................
157
157
158
158
158
159
160
160
160
161
161
161
162
163
164
164
164
167
167
169
170
170
171
20 System Services............................................................................................................................
20.1 Date and Time........................................................................................................................
20.1.1 Date and Time Options...................................................................................................
20.1.2 Date and Time Example Program...................................................................................
20.2 Command Line Arguments.....................................................................................................
20.2.1 Argument Count..............................................................................................................
173
173
173
174
176
177
ix
177
178
181
181
181
185
185
185
186
186
186
186
186
187
187
188
188
189
189
189
190
191
193
193
193
194
194
195
195
196
197
197
197
198
198
198
198
199
200
200
201
201
201
202
202
203
203
203
204
205
206
206
207
208
208
209
210
210
212
212
Illustration Index
Illustration 1: Computer Architecture........................................................................................................3
Illustration 2: Fortran 95 Compile Process................................................................................................4
Illustration 3: Factorial Recursion Tree.................................................................................................163
xi
xii
Introduction
Computers are everywhere in our daily lives. Between the desktop, laptop, phone, bank, and vehicle, it
is difficult to completely get away from computers. It only makes sense to learn a little about how a
computer really works.
This text provides an introduction to programming and problem solving using the Fortran 95
programming language. This introduction is geared for non-computer science majors. The primary
focus is on an introduction to problem solving and algorithm development. As such, many details of
the Fortran 95 language are omitted.
1.2 Fortran
Fortran is a programming language often used by the scientific community. Its name is a contraction of
FORmula TRANslation. FORTRAN is one of the earliest programming languages and was designed
specifically for solving scientific and engineering computational problems.
This text utilizes the Fortran 90/95 standard. Older versions of Fortran, like Fortran 77, are not
referenced. The older Fortran versions have less features and require additional, often burdensome,
formatting requirements.
If this location changes, a web search will be able to find the new location.
Chapter 1 Introduction
Computer Organization
Before writing programs, it is useful to understand some basics about how a computer is organized.
This section provides a brief, high-level overview of the basic components of a computer and how they
interact.
CPU
Random Access
Memory (RAM)
BUS
(Interconnection)
Screen / Keyboard /
Mouse
Primary Storage
(i.e., SSD, Disk Drive
or Other Storage
Media)
2.2 Compiler
Programs can be written in the Fortran programming language. However, the CPU does not read
Fortran directly. Instead, the Fortran program that we create will be converted into binary (1's and 0's)
by the compiler. These 1's and 0's are typically referred to as machine language. The CPU will read
the instructions and information, represented in binary as machine language, and perform the
commands from the program.
Fortran 95
Program
Compiler
Executable
File
2.3.1
Decimal Numbers
Before discussing binary numbers, a brief review of the decimal system is presented. The number
"1234" as,
Which means,
Thousands
Hundreds
Tens
Ones
103
102
101
100
1000
100
10
2.3.2
Binary Numbers
A bit is the basic unit of information in computing and digital communications. A bit can have only
one of two values, 0 or 1. The term bit is a contraction of binary digit.
The binary system, as well as its math, operates in base 2, using two symbols, 0 and 1.
27
26
25
24
23
22
21
20
128
64
32
16
In base 2, we put the digits 0 or 1 in columns 20, 21, 23, and so on. For example,
3
11012 = 12 12 02 12 = 841
Which in decimal is 1310.
A set of 8 bits is a referred to as a byte. Computer data is typically allocated in bytes or sets of bytes.
2.3.3
Character Representation
Characters are represented using the American Standard Code for Information Interchange (ASCII).
Refer to Appendix A.
2.4 Exercises
Below are some quiz questions based on this chapter.
2.4.1
Quiz Questions
Getting Started
This section provides a brief overview of how to get started. This includes the general process for
creating a very simple program, compiling, and executing the program. Some detailed steps regarding
working with files, obtaining the compiler, and compiling a program are included in Appendix B,
Windows Start-up Instructions.
If you are unsure about any of these requirements you will need to learn them before continuing.
Fortunately, they are not difficult. Additionally, there are numerous tutorials available on the Web.
The following sections assume that the Fortran 95 compiler is installed and available. For additional
information regarding obtaining and installing the compiler, refer to Appendix B. The Fortran 95
compiler is available for download at no cost.
3.2.1
Program Statement
A Fortran 95 program is started with a program statement, 'program<name>', and ended with an end
program statement, 'endprogram<name>'. Refer to the example first program to see an example of
these statements. The program name for <name> is chosen by the program author and would typically
reflect something related to what the program does.
The name used may not be used again for other program elements (such as variables described in the
next chapter). The program name must start with a letter, followed by letters, numbers, or an
underscore (_) and may not be longer than 32 characters. Capital letters are treated the same way as
lower-case letters. Refer to the sample program in the following sections for an example.
3.2.2
Comments
Comments are information for the programmer and are not read by the computer. For example,
comments typically include information about the program. For programming assignments, the
comments should include the programmer name, assignment number, and a brief description of the
program. In Fortran, the exclamation mark (!) denotes a comment. Any characters after the
exclamation mark (!) are ignored by the compiler and thus are comments as shown in the example.
3.2.3
Simple Output
A program can display a simple message to the screen by using the write statement. For example:
write(*,*)"HelloWorld"
Will display the message HelloWorld to the screen. Additional information regarding the write
statement and outputting information is provided in later chapters.
3.2.4
In this example, the program is named 'first'. This file is typically referred to as the source file.
3.4 Compiling
Once the program is typed into a file, the file must be compiled. Compiling will convert the human
readable Fortran program, or source file, into a computer readable version (in binary).
In order to compile, the command prompt (Windows) or terminal interface (Unix, MAC) is required.
This interface will allow commands to be typed directly into the computer (instead of using a mouse).
Once started, it is typically necessary to change directories (from the default location) to the location of
where the hw.f95 source file was located (form the previous steps). Changing directories is typically
done with a cd <directoryName> command. For example, cdfortran (which is the name of the
directory used in this example). The prompt typically changes to include the current directory location.
In the example below, the commands typed by the user are displayed in bold. The regular (non-bolded)
text refers to prompts or other information displayed by the computer (which will not need to be typed).
To compile the example program, the following command would be entered:
C:\fortran>gfortranohwhw.f95
This command will tell the 'gfortran' compiler to read the file hw.f95 and, if there are no errors,
create an executable file. On Windows based machines the executable file is named hw.exe. And on
Unix or Mac based machines, the executable is named hw (no extension). If there is an error, the
compiler will generate an error message, sometimes cryptic, and provide a line number. Such errors
are usually the result of mistyping one of the instructions. Any errors must be resolve before
continuing.
3.4.1
In addition, to the basic compilation sometimes additional instructions, or options, may be required.
For example, when using arrays (chapter 9), an option for bounds checking is typically desired.
For example, to compile with bounds checking, the following command might be entered:
C:\fortran>gfortranfcheck=boundsohwhw.f95
This command will tell the 'gfortran' compiler to include bounds checking. More information
regarding arrays and bounds checking is addressed in chapters 13 and 14.
3.5 Executing
To execute or run a program on a Windows based machine, type the name of the executable file. For
example, to execute or run the hw.exe program:
C:\fortran>hw
HelloWorld.
C:\fortran>
Which will execute the example program and display the Hello World. message to the screen.
It is not necessary to type the extension (i.e., .exe) portion of the file name. It should be noted that
the space prior to the H is not produced by the program, but is how the system displays output.
To execute or run a program on a Unix or MAC based machine, type ./ and the name of the
executable file. For example, to execute or run the hw program:
c:\fortran>./hw
HelloWorld.
c:\fortran>
The output ('Hello World.' as displayed on the screen) will be the same for Windows, Unix, or MAC
based machines.
3.6 Exercises
Below are some quiz questions and project suggestions based on this chapter.
3.6.1
Quiz Questions
10
3.6.2
Suggested Projects
11
12
Before beginning to writing programs, it is necessary to know some of the basic elements of the
Fortran language. This section describes some of the basic elements of Fortran. Additional
information will be added in later sections.
4.1 Variables
The basic concept in a program is the concept of a variable. Variables in a program are like variables in
an algebraic expression. They are used to hold values and then write mathematical expressions using
them. Fortran allows us to have variables of different types.
A variable can hold one value at a time. If another value is placed in the variable, the previous value is
over-written and lost.
Variable Name
42
Variables must be declared at the start of the program before they are used.
4.1.1
Variable Names
Each variable must be named. The variable name is how variables, which are memory locations, are
referred to by the program. A variable name must start with a letter, followed by letters, numbers, or an
underscore (_) and may not be longer than 32 characters. Capital letters are treated the same way as
lower-case letters, (i.e., AAA is the same variable as aaa).
Note that the space (between next and month) or the special character, @, is not allowed. Additionally,
each variable must have a type associated as explained in the following sections.
13
4.1.2
Keywords
Such keywords are reserved in that they can not be used for anything else such as variable names. That
is, a variable name of program or write is not allowed.
As additional Fortran 95 statements and language constructs are explained, more keywords will be
identified. In general, words used for Fortran language statements, attributes, and constructs will likely
be keywords. A complete list of keywords or reserved words is located in Appendix F.
Description
integer
real
complex
character
logical
It is also possible to have derived types and pointers. Both of these can be useful for more advanced
programs and are described in later chapters.
4.2.1
Integer
An integer1 is a whole number (not a fraction) that can be positive, negative, or zero. Examples include
the numbers 10, 0, -25, and 5,148. Integers are the numbers people are most familiar with, and they
serve a crucial role in mathematics and computers. All integers are whole numbers, so operations like
one divided by two (1/2) is 0 since the result must be a whole number. For integer division, no
rounding will occur as the fractional part is truncated.
1 For more information regarding integers, refer to: http://en.wikipedia.org/wiki/Integer
14
4.2.2
Real
A real number2 includes the fractional part, even if the fractional part is 0. Real numbers, also referred
to as floating point numbers, include both rational numbers and irrational numbers. Examples of
irrational numbers or numbers with repeating decimals include , 2 and e. Additional examples
include 1.5, 5.0, and 3.14159. Fortran 95 will accept 5. as 5.0. All examples in this text will include
the .0 to ensure clarity.
4.2.3
Complex
A complex number3, in mathematics, is a number comprising a real number and an imaginary number. It
can be written in the form of a + bi, where a and b are real numbers, and the i is the standard imaginary
unit with the property that i2 = 1.0. The complex numbers contain the ordinary real numbers, but
extend them by adding in extra numbers like an extra dimension. This data type is not used
extensively, but can be useful when needed.
4.2.4
Character
A character4 is a symbol like a letter, numerical digit, or punctuation. A string5 is a sequence or set of
characters. Characters and strings are typically enclosed in quotes. For example, the upper case letter
Z is a character and Hello World is a string. The characters are represented in a standardized
format referred to as ASCII.
4.2.5
Logical
A logical6 is only allowed to have two values, true or false. A logical can also be referred to as a
boolean. In Fortran, the true and false values are formally expressed as .true. or .false. which are also
called logical constants. The leading and trailing . (period) are required for the true and false constants.
4.2.6
Unless a variable was explicitly typed, older versions of Fortran implicitly assumed a type for a
variable depending on the first letter of its name. Thus, if not explicitly declared, a variable whose
name started with one of the letters I through O was assumed to be an integer; otherwise it was
assumed to be real. To allow older code to run, Fortran 95 permits implicit typing. However, this is
poor practice, can be confusing, and often leads to errors. So, we will include the IMPLICIT NONE
statement at the start of all programs. This turns off implicit typing and the compiler will identify and
flag any variable not defined. This help make some errors, such as mis-spelling a variable name,
significantly easier to locate.
2
3
4
5
6
15
4.3 Declarations
Fortran variables must be declared before executable statements. This section provides an introduction
to how variables are declared.
4.3.1
Declaring Variables
Declaring variables formally defines the data type of each variable and sets aside a memory location.
This is performed by a type declaration statement in the form of:
<type>::<listofvariablenames>
The type must be one of the predefined data types (integer, real, complex, character, logical). Outlined
in the previous section. Declarations are placed in the beginning of the program (after the program
statement).
For example, to define an integer variable today,
integer::today
4.3.2
Variable Ranges
The computer has a predefined amount of space that can be used for each variable. This directly
impacts the size, or range, of the number that can be represented.
For example, an integer value can range between 2,147,483,648 and +2,147,483,647. Fortunately, this is
large enough for most purposes.
The range for real values is more complex. The range is approximately 1.710308 which supports about
15 digits of precision.
4.3.3
Type Checking
The variable type declaration is enforced by the compiler. For example, if a variable is declared as an
integer, only an integer value (a whole number) is allowed to be assigned to that variable. Attempting
to assign a value of 1.75 to an integer variable could cause problems related to loss of precision. This
restriction is related to the fact that the internal representations for various types are very different and
not directly compatible. The compiler can sometimes recognize a type mismatch and implicitly
(automatically) perform a conversion. If this is done automatically, it is not always clear and could
lead to errors. As such, it is generally considered poor programming practice.
16
4.3.4
Initialization
It is possible to declare a variable and set its initial value at the same time. This initialization is not
required, but can sometime be convenient.
For example, to define an integer variable todaysdate and set it to the 15th of the month:
integer::todaysdate=15
Spaces or no spaces are allowed between the variable name. The variable declaration may or may not
include an equal signs (for initialization). Comma's are used to separate multiple variable declarations
on the same line. Variables initialized at declaration can be changed later in the program as needed.
4.3.5
Constants
A constant is a variable that can not be changed during program execution. For example, a program
might declare a variable for and set it to 3.14159. It is unlikely that a program would need to change
the value for . The parameter qualifier will declare the variable as a constant, set the initial value, and
not allow that initial value to be altered during the program execution.
For example, the declarations:
real,parameter::pi=3.14159
integer,parameter::width=1280
will set the variable pi to 3.14159 and width to 1280 and ensure that they can not be changed while the
program is executing.
4.4 Comments
Comments are information for the programmer ignored by the compiler. In general, comments
typically include information about the program. For example, a comment might include the last
modification date, programmer name, and details about the update. For programming assignments, the
comments might include the programmer name, assignment number, and a description of the program.
&
4.5.1
Example
The following trivial program illustrates the program formatting requirements and variable
declarations.
!ExampleProgram
programexample1
implicitnone
integer::radius,diameter
integer::height=100,width=150
real::area,perimeter
real::length=123.5,distance=413.761
real,parameter::pi=3.14159
character(11)::msg="HelloWorld"
write(*,*)"Greeting:",msg
endprogramexample1
In this example, a series of variables are defined (as examples) with most not used. The program will
display Greeting:HelloWorld when executed. The following chapters will address how to use
the variables to perform calculations and display results. Additional information regarding character
variables is provided in chapter 11.
4.6.1
Integers
As previously noted, the range of an integer value can range between 2,147,483,648 and
+2,147,483,647. In the unlikely event that a larger range is required, a special declaration can be used
to extend the range. The kind specifier is used with the integer declaration.
18
The extended range of integer variables declared with the kind=8 is 9,223,372,036,854,775,808 to
9,223,372,036,854,775,807.
4.6.2
Real
As previously noted, the range is approximately 1.710308 which supports about 15 digits of
precision. If more precision is required, the kind specifier can be used.
For example, to declare a variable rnum with an extended range, the integer declaration would be as
follows:
real(kind=16)::rnum
The extended precision of real variables declared with the kind=16 is approximately 1.710308
which supports about 31 digits of precision.
4.7 Exercises
Below are some quiz questions and project suggestions based on this chapter.
4.7.1
Quiz Questions
____________
____________
____________
____________
____________
4) Write the statements required to declare value as an integer and count as a real.
5) Write the statements required to declare rate as an real initialized to 7.5.
6) Write the statements required to declare e as an real constant initialized to 2.71828183.
19
4.7.2
Suggested Projects
20
Expressions
This section describes how to form basic Fortran 95 expressions and perform arithmetic operations
(i.e., add, subtract, multiple, divide, etc.). Expressions are formed using literals (actual values),
variables, and operators (i.e., +, -, *, /, etc.). The previous chapter provides an explanation of what
variable is and a summary of the five Fortran data types.
5.1 Literals
The simplest expression is a direct value, referred to as a literal. Since literals are actual values, not
variables, they can not be changed. There are various types of literal constants described in the
following sections, correspond to the data types.
5.1.1
Integer Literals
5.1.2
Real Literals
The real number should include the decimal point (i.e., the .). A real number includes the fractional
part, even if the fraction is 0. Fortran will accept a number with the . and no further digits. For example,
5. is the same as 5.0. All examples in this text will include the .0 to ensure clarity.
5.1.2.1
E-Notation
For larger real numbers, e-notation may be useful. The e-notation means that you should multiply the
constant by 10 raised to the power following the "E". This is sometimes referred to as scientific
notation.
21
Chapter 5 Expressions
The following are some real constants using e-notation:
2.75E6
3.3333E1
5.1.3
Complex Literals
A complex constant is designated by a pair of constants (integer or real), separated by a comma and
enclosed in parentheses. Examples are:
(3.2,4.1)
(1.0,9.9E1)
The first number denotes the real part and the second the imaginary part. Although a complex number
always consists of two elements, it is considered a single value.
5.1.4
Character Literals
A character constant is either a single character or a set of characters, called a string. A character is a
single character enclosed in quotes. A string consists of an arbitrary sequence of characters also
enclosed in quotes. Some examples include:
"X"
"HelloWorld"
"Goodbyecruelworld!"
"Haveaniceday"
Character and string constants (enclosed with quotes) are case sensitive. So, character X (uppercase) is not the same as x (lower-case).
A problem arises if you want to have a quote in the string itself. A double quote will be interpreted as a
single within a string. The two quotes must be together (no spaces between). For example, the string:
"Hesaid""wow""whenheheard"
Would be displayed as
"Hesaid"wow"whenheheard"
The double-quote is sometimes referred to as an escape character. Strings and characters must be
associated with the character data type.
22
Chapter 5 Expressions
5.1.5
Logical Constants
The fifth type is the logical constant. These can only have one of two values:
.true.
.false.
5.2.1
Assignment
In programming, assignment is the term for setting a variable equal to some value. Assignment is
performed with an equal (=) sign. The general form is:
variable=expression
The expression may be a literal, variable, an arithmetic formula, or combination of each. Only one
assignment to a single variable can be made per line.
For example, to declare the variable answer1 as a real value,
real::answer1
The value for answer1 can be changed as often as needed. However, it can only hold one value at a
time.
5.2.2
Addition
The Fortran addition operation is specified with a plus sign (+). For example, to declare the variables,
mysum, number1, number2, and number3,
integer::mysum,number1=4,number2=5,number3=3
which will set the variable mysum to 9 in this example. The data types of the variables, integer in this
example, should be the same. Multiple variables can be added on one line. The line can also include
literal values. For example,
mysum=number1+number2+number3+2
which will set the variable mysum variable to 14. Additionally, it will over-write the previous value of
9.
23
Chapter 5 Expressions
5.2.3
Subtraction
The Fortran subtraction operation is specified with a minus sign (-). For example, to declare the
variables, ans, value1, value2, and value3,
real::ans,value1=4.5,value2=2.5,value3=1.0
which will set the variable ans to 2.0. The data types of the variables, real in this example, should be
the same. Multiple variables can be subtracted on one line. The line can also include literal values.
For example,
ans=value1value2value3
which will set the variable ans to 1.0. Additionally, it will over-write the previous value of 2.0.
5.2.4
Multiplication
The Fortran multiplication operation is specified with an asterisk (*). For example, to declare the
variables, ans, value1, value2, and value3,
real::ans,value1=4.5,value2=2.0,value3=1.5
which will set the variable ans to 9.0. The data types of the variables, real in this example, should be
the same. Multiple variables can be multiplied on one line. The line can also include literal values.
For example,
ans=value1*value2*2.0*value3
which will set the variable ans to 27.0. Additionally, it will over-write the previous value of 9.0.
5.2.5
Division
The Fortran division operation is specified with a slash symbol (/). For example, to declare the
variables, ans, value1, value2, and value3,
real::ans,value1=10.0,value2=2.5,value3=2.0
which will set the variable ans to 4.0. The data types of the variables, real in this example, should be
the same. Multiple variables can be divided on one line.
24
Chapter 5 Expressions
For example,
ans=value1/value2/value3
which will set the variable ans to 2.0. Additionally, it will over-write the previous value of 4.0.
5.2.6
Exponentiation
Exponentiation means raise to the power of. For example, 2 to the power of 3, or 23 is (2 * 2 * 2)
which is 8. The Fortran exponentiation operation is specified with a double asterisks (**).
For example, to declare the variables, ans and value1,
real::ans,value1=2.0
which will set the variable ans to 8.0. When using exponentiation, pay close attention to the data types.
For example, raising an integer variable to the power 0.5 would produce a truncated integer result.
Operator
Operation
1st
unary -
2nd
**
exponentiation
3rd
4th
For operations of the same precedence level, the expression is evaluated left to right. Parentheses may
be used to change the order of evaluation as necessary. For example, declaring the variables ans1,
ans2, num1, num2, and num3.
integer::ans1,ans2,num1=20,num2=50,num3=10
25
Chapter 5 Expressions
5.4.1
The intrinsic or built-in functions include the standard mathematical functions such as sine, cosine,
tangent, and square root.
For example, the cosine of is -1.0. Declaring and initializing the variables x and pi as follows,
real::z
real,parameter::pi=3.14159
and then performing the calculation of the cosine the variable pi as follows,
z=cos(pi)
5.4.2
Conversion Functions
Other intrinsic functions include functions to change the type of variables or values. The basic
conversion functions are as follows:
Function
Explanation
real(<integer argument>)
int(<real argument>)
nint(<real argument>)
Chapter 5 Expressions
5.4.3
Summary
Description
COS(W)
INT(A)
MOD(R1,R2)
NINT(X)
REAL(A)
SIN(W)
SQRT(W)
TAN(X)
Any integers values are converted to real only when mixed-mode is encountered on the same operation
type. Conversion may also occur on assignment.
Unexpected conversions can cause problems when calculating values. In order to avoid such problems,
it is strongly recommended to not use mixed-mode. There are a series of rules associated with mixed
mode operations. In some circumstances, these rules can be confusing. For simplicity, those rules are
not covered in this text.
If it is necessary to perform calculations with different data types, such as integers and reals, the
intrinsic or built-in conversion functions should be used to ensure correct and predictable results. This
also allows the programming greater control of when types are converted. In very complex
calculations, this would help ensure clarity and address precision issues. Further recommendations to
address highly precise calculations are not addressed in this text.
27
Chapter 5 Expressions
5.6 Examples
Below is an example program that calculates velocity based on acceleration and time. The program
declares the appropriate variables and calculate the velocity.
programfindvelocity
!Programtocalculatethevelocityfromthe
!accelerationandtime
!Declarevariables
implicitnone
real::velocity,acceleration=128.0
real::time=8.0
!Displayinitialheader
write(*,*)"VelocityCalculationProgram"
write(*,*)
!Calculatethevelocity
velocity=acceleration*time
write(*,*)"Velocity=",velocity
endprogramfindvelocity
Additional information regarding how to perform input and output in the next chapter. The comments
are not required, but help make the program easier to read and understand.
5.7 Exercises
Below are some quiz questions and project suggestion based on this chapter.
5.7.1
Quiz Questions
28
Chapter 5 Expressions
7) Write the single Fortran statement for each of the following formulas. You may assume all
variables are already declared as real values. Additionally, you may assume the variable PI is
set as a parameter and initialized to 3.14159.
x1 =
( 6 ) ( 3 a + 3 b + c ) c
x2 =
2a
cos ( b) sin( b)
c
b + ( b 24 a c)
x3 =
2a
5.7.2
Suggested Projects
29
Chapter 5 Expressions
30
Simple, unstructured, input and output can be performed with the write and read statements as
explained in the following sections. In a later chapter, a more structured approach will be presented in
later sections.
Which will send the message, referred to as a string, Hello World to the screen. The first * means
the default output device, which is the screen or monitor. The second * refers to the 'free format'.
Thus, the (*,*) means to send it to the screen in 'free format'.
The free format allows the Fortran compiler to determine the appropriate format for the information
being displayed. This is easy, especially when first getting started, but does not allow the program
much control over how the output will be formatted or displayed on the screen.
Additionally, the value held by declared variables can be displayed. For example, to declare the
variables num1, num2, and num3.
integer::num1=20,num2=50,num3=10
The free format allows the Fortran compiler to determine the appropriate output format for the
information being displayed.
A write statement with no strings or variables,
write(*,*)
The information inside the quotes is displayed as is, including capitalization and any spelling errors.
When the quotes are not used, it is interpreted as a variable. If the variable is not declared, a compiler
error will be generated. The value assigned to each variable will be displayed. A value must have be
assigned to the variable prior to attempting to display.
31
6.1.1
Output Print
In addition to the write statement, a print statement can be used. The print statement will send output
only to the screen. Thus, it is a more restrictive form of the write statement.
As with the write statement, multiple variables and strings can be displayed with one print statement.
For example, using the previous declarations,
print*,"Number1=",num1,"Number2=",num2
The information inside the quotes is displayed as is, including capitalization and any spelling errors.
When the quotes are not used, it is interpreted as a variable. If the variable is not declared, an error will
be generated. If the variable is defined, the value assigned to that variable will be displayed.
In general, all examples will use the write statement.
Which will read a number from the user entered on the keyboard into the variable ans1. The (*,*)
means to send it to read the information in 'free format'. The free format allows the Fortran compiler to
determine the appropriate format for the information being read.
Multiple variables can be read with one read statement. For example, using the previous declarations,
read(*,*)ans1,ans2
will read two values from the user into the variables ans1 and ans2.
Since the read is using free format, two numbers will be required. The numbers can be entered on the
same line with one more more spaces between them or on separate lines. The read will wait until two
numbers are entered.
When reading information from the user, it is usually necessary to provide a prompt in order to ensure
that the user understands that input is being requested by the program. A suitable write statement with
an appropriate string, followed by a read statement will ensure that the user is notified that input is
being requested.
For example, to read a date, a program might request month, date, and year as three separate variables.
Given the following declarations,
integer::month,date,year
the program might prompt for and read the data in the following manner,
write(*,*)"Enterdate(month,date,andyear)"
read(*,*)month,date,year
32
The type of number requested here is an integer, so integers should be entered. Providing a real
number or character (e.g., letter) would generate an error. Later chapters will address how to deal with
such errors.
6.3 Example
Below is an example program that calculates the area of a circle. The program will declare the
appropriate variables, read the radius, calculate the circle area, and display the result.
Programcircle
!Programtocalculatetheareaofacircle
!Declarevariables
implicitnone
real::radius,area
real,parameter::pi=3.14159
!Displayinitialheaderandblankline
write(*,*)"CircleAreaCalculationProgram"
write(*,*)
!Promptforandreadtheradius
write(*,*)"EnterCircleRadius"
read(*,*)radius
!Calculatethecirclearea
area=pi*radius**2
!Displayresult
write(*,*)"CircleArea:",area
endprogramcircle
33
6.4 Exercises
Below are some quiz questions and project suggestions based on this chapter.
6.4.1
Quiz Questions
6.4.2
Suggested Projects
a2+ b2
perimeter = a + b+ c
b
Test the program on several sets of input.
34
a2
p
4
c2
35
p
4
36
Program Development
Writing or developing programs is easier when following a clear methodology. The main steps in the
methodology are:
To help demonstrate this process in detail, these steps will be applied to a simple problem to calculate
and display the period of a pendulum.
As additional examples are presented in later chapters, they will be explained and presented using this
methodology.
Period = 2
(
L
g
1+
( ))
sin 2
4
2
Where:
g
=
=
=
=
980 cm/sec2
3.14159
Pendulum length (cm)
Angle of displacement (degree)
Both g (gravity) and should be declared as a constants. The formula is a simplified version of the
more general case. As such, for very large, very small, or zero angle values the formula will not
provide accurate results. For this example, that is acceptable.
As shown, the pendulum is attached to a fixed point, and set into motion by displacing the pendulum
by an angle, , as shown in the diagram. The program must define the constants for g and , declare
the variables, display appropriate prompts, read the values for L and , then calculate and display the
original input and the period of the pendulum with the given length and angle of displacement.
37
While this is a fairly straightforward algorithm, more complex problems would require more extensive
algorithms. Examples in later chapters will include more complex programs. For convenience, the
steps are written a program comments. This will allow the addition of the code to the basic algorithm.
38
The indentation is not required, but helps make the program easier to read. Note that the 2, 1, and
4 in the algorithm are entered as 2.0, 1.0, and 4.0 to ensure consistent data typing (i.e., all reals). If
the 1 over 4 is entered as 1/4 instead of 1.0/4.0, it be incorrect since 1/4 would provide a result of
0 (since this would be integer division).
As before, input typed by the user is shown in bold. For this program, the results can be verified with a
calculator. A series of different values should be used for testing. If the program does not work, the
program comments provide a checklist of steps and can be used to help debug the program.
7.4.1
Error Terminology
In case the program does not work, it helps to understand some basic terminology about where or what
the error might be.
7.4.1.1
Compiler Error
Compiler errors are generated when the program is compiled. This means that the compiler does not
understand the instructions. The compiler will provide a list of errors and the line number the of each
39
The first digit, 13 in this example, represents the line number where the error occurred. Using a text
editor that displays line numbers, the statement that caused the error can be quickly found and
corrected.
If the declaration for the variable length is omitted, the error would appear as follows:
c:\mydir>gfortranoperiodperiod.f95
period.f95:17.18:
read(*,*)length,angle
1
Error:Symbol'length'at(1)hasnoIMPLICITtype
In this case, the error is shown on line 18 (first digit after the :). However, the actual error is that the
variable length is not declared. Each error should be reviewed and evaluated.
7.4.1.2
Run-time Error
A run-time error is something that causes the program to crash. For example, if the number is
requested from the user and a letter is entered, that can cause occur.
For example, the period program expects two real numbers to be entered. If the user enters letters, x
and y, in this example, an error will be generated during the execution of the program as follows:
c:\mydir>period
PendulumPeriodCalculationProgram
EnterLengthandAnglevalues:
xy
Atline17offileperiod.f95(unit=5,file='stdin')
Fortranruntimeerror:Badrealnumberinitem1oflistinput
The program was expecting numeric values and letters were provided. Since letters are not meaningful
40
7.4.1.3
Logic Error
A logic error is when the program executes, but does not produce the correct result. For example,
coding a provided formula incorrectly or attempting to computer the average of a series of numbers
before calculating the sum.
For example, the correct formula for the period of a pendulum is as follows:
pperiod=2.0*pi*sqrt(length/gravity)*
&
(1.0+1.0/4.0*sin(angle/2.0)**2)
The 1 over 4 is entered as 1/4 which are interpreted as integers. As integers, 1/4 results in 0. The
compiler will accept this, perform the calculations, and provide an incorrect result.
The program would compile and execute as follows.
c:\mydir>period
PendulumPeriodCalculationProgram
EnterLengthandAnglevalues:
120.015.0
Theperiodis:2.198655
However, an incorrect answer would be generated as shown. This is why testing the program is
required. Logic errors can be the most difficult to find.
One of the best ways to handle logic errors is to avoid them by careful developing the algorithm and
writing the code.
If the program has a logic error, one way to find the error is to display intermediate values. Further
information will be provided in later chapters regarding advice on finding logic errors.
7.5 Exercises
Below are some quiz questions and project suggestions based on this chapter.
7.5.1
Quiz Questions
41
7.5.2
Suggested Projects
circumference = 2
CircleArea
Which will result in a true or false result based on the value of the variable gameLives.
Explanation
.and.
.or.
.not.
Logical operators are used to combine conditional expressions as needed to form a more complex
conditional expression. For example, given the declaration of,
integer::gameLives,extraLives
it might be useful to know if the current value of gameLives and extraLives are both 0 which would
indicate the game is over. In this case, the relational operator would be AND with the complete
conditional expression,
((gameLives==0).and.(extraLives==0))
which will result in a true or false result. Since the AND logical operation is used, the final result will
be true only if both conditional expressions are true.
Another way of check the status to determine if the game should continue might be,
((gameLives>0).or.(extraLives>0))
which still results in a true or false result. However, since the OR logical operation is used, the final
result will be true if either conditional expressions is true.
The relational operators (e.g., <, <=, >, >=, ==, /=) have higher precedence than logical operators
(AND, OR, NOT). This means each of the smaller conditional expressions will be completed before
the local operation is applied.
A conditional expression can be a combination of multiple conditional expressions combined with
logical operators.
8.3 IF Statements
IF statements are used to perform different computations or actions based on the result of a conditional
expression (which evaluates to true or false). There are a series of different forms of the basic IF
statement. Each of the forms is explained in the following sections.
44
8.3.1
IF THEN Statement
The IF statement, using the conditional expression, is how programs make decisions. The general
format for an IF statement is as follows:
if(<conditionalexpression>)then
<fortranstatement(s)>
endif
Where the <fortran statements> may include one or more valid Fortran statements.
For example, given the declaration of,
integer::gameLives
based on the current value of gamelives is, a reasonable IF statement might be;
if(gameLives==0)then
write(*,*)"GameOver."
write(*,*)"Pleasetryagain."
endif
which will display the message Game Over. and Please try again. on the next line if the value of
gameLives is equal to 0.
8.3.1.1
In this form, only a single statement is executed if the conditional expression evaluates to true. The
previous example might be written as;
if(gameLives==0)write(*,*)"GameOver."
In this form, no then or end if are required. However, only one statement can be executed.
8.3.2
The IF THEN ELSE statement expands the basic IF statement to also allow a series of statements to be
performed if the conditional expression evaluates to false.
The general format for an IF THEN ELSE statement is as follows:
if(<conditionalexpression>)then
<fortranstatement(s)>
else
<fortranstatement(s)>
endif
Where the <fortran statements> may include one or more valid Fortran statements.
45
based on the current value of gameLives is, a reasonable IF THEN ELSE statement might be:
if(gameLives>0)then
write(*,*)"StillAlive,KeepGoing!"
else
write(*,*)"ExtraLifeGranted."
gamesLives=1
endif
Which will display the message Still Alive, Keep Going! if the value of gameLives is greater than 0
and display the message Extra Life Granted. if the value of gameLives is less than or equal to 0.
8.3.3
The IF THEN ELSE IF statement expands the basic IF statement to also allow a series of IF statements
to be performed in a series.
The general format for an IF THEN ELSE IF statement is as follows:
if(<conditionalexpression>)then
<fortranstatement(s)>
elseif(<conditionalexpression>)then
<fortranstatement(s)>
else
<fortranstatement(s)>
endif
Where the <fortran statements> may include one or more valid Fortran statements.
For example, given the declaration of,
integer::gameLives
based on the current value of gameLives is, a reasonable IF THEN ELSE IF statement might be:
if(gameLives>0)then
write(*,*)"StillAlive,KeepGoing!"
elseif(gameLives<0)then
write(*,*)"Sorry,gameover."
else
write(*,*)"ExtraLifeGranted."
gamesLives=1
endif
Which will display the message Still Alive, Keep Going! if the value of gameLives is greater than 0,
display the message Sorry, game over. if the value of game lives is < 0, and display the message
Extra Life Granted. if the value of gameLives is equal to 0.
46
To help demonstrate this process in detail, these steps will be applied to a familiar problem as an
example. The example problem is to calculate the solution of a quadratic equation in the form:
a x2 + b x + c = 0
Each of the steps, as applied to this problem will be reviewed.
8.4.1
x =
In the quadratic equation, the term b2 4 a c is the discriminant of the equation. There are three
possible results for the discriminant as described below:
If b24 a c 0 then there are two distinct real roots to the quadratic equation. These two
solutions represent the two possible answers. If the equation solution is graphed, the curve
representing the solution will cross the x-axis (i.e., representing x=0) in two locations.
If b24 a c = 0 then there is a single, repeated root to the equation. If the equation solution
is graphed, the curve representing the solution will cross the x-axis in one location.
If b24 a c 0 then there are two complex roots to the equation. If the equation solution is
graphed, the curve representing the solution will not cross the x-axis and this no real number
solution. However, mathematically the square root of a negative value will provide a complex
result. A complex number includes a real component and an imaginary component.
A correct solution must address each of these possibilities. For this problem, it is appropriate to use
real values.
47
Zero Discriminant
Negative Discriminant
Example:
3x 29x3
Example:
2x 24x2
Example:
3x 23x3
One x-intercept
No x-intercept
Root 1 = -0.382
Root 2 = -2.618
Root 1 = -1.0
The examples provided above are included in the example solution in the following sections.
8.4.2
The algorithm is the name for the ordered sequence of steps involved in solving the problem. The
variables must be defined and an initial header displayed. For this problem, the a, b, and c values will
need to be read from the user. Formalizing this, the following steps can be developed.
!declarevariables
!
reals>a,b,c,discriminant,root1,root2
!displayinitialheader
!readthea,b,andcvalues
48
8.4.3
49
!ifdiscriminantis<0,
!
calculateanddisplaycomplexroot1androot2
if(discriminant<0)then
root1=b/(2.0*a)
root2=sqrt(abs(discriminant))/(2.0*a)
write(*,*)"Thisequationhasacomplexroot:"
write(*,*)"root1=",root1,"+i",root2
write(*,*)"root2=",root1,"i",root2
endif
endprogramquadratic
The indentation is not required, but does help make the program easier to read.
8.4.4
Once the program is written, testing should be performed to ensure that the program works. The
testing will be based on the specific parameters of the program. In this example, each of the three
possible values for the discriminant should be tested.
C:\mydir>quad
QuadraticEquationSolverProgram
EnterA,B,andCvalues
242
Thisequationhasoneroot:
root=1.0000000
C:\mydir>quad
QuadraticEquationSolverProgram
EnterA,B,andCvalues
393
Thisequationhasacomplexroot:
root1=0.38196602
root2=2.6180339
C:\mydir>quad
QuadraticEquationSolverProgram
EnterA,B,andCvalues
333
Thisequationhasacomplexroot:
root1=0.50000000+i0.86602539
root2=0.50000000i0.86602539
C:\mydir>
50
where value, value-1 and value-2 are constants or literals. The type of these constants must be identical
to that of the selector.
The second form means all values in the range of value-1 and value-2 (inclusive). In this form,
value-1 must be less than value-2
The third form means all values that are greater than or equal to value-1
The fourth form means all values that are less than or equal to value-2
In order, each selector expression is evaluated. If the variable value is the selector or in the selector
range, then the sequence of statements in <fortran statement(s)> are executed.
If the result is not in any one of the selectors, there are two possibilities:
51
if the CASE DEFAULT is not there, the statement following END SELECT is executed
The constants listed in selectors must be unique. The CASE DEFAULT is optional. But with a CASE
DEFAULT, you are guaranteed that whatever the selector value, one of the labels will be used. The
place for CASE DEFAULT can be anywhere within a SELECT CASE statement; however, putting it at
the end would be more natural.
For example, given the declarations,
integer::hours24,hours12
logical::isAM
might be useful to convert 24-hour time into 12-hour time. In this example, a logical variable isAM is
used to indicate AM (true) or PM (false).
Additionally, the selectors can be combined and separated by commas. For example, given the
declarations,
integer::monthnumber,daysinmonth
52
casedefault
write(*,*)"Error,monthnumbernotvalid."
endselect
might be useful to determine the number of days in a given month. The leap-year calculation is not
complete, but is adequate if the range of the year is sufficiently limited.
8.6.1
For this example, the program will assign grades using the following grade scale:
A
A>=90
80 - 89
70 - 79
60 - 69
<=59
The program will read three test scores, compute the average, and display the appropriate grade based
on the average.
8.6.2
The algorithm is the name for the ordered sequence of steps involved in solving the problem.
For this problem, the variables will be declared and an initial header displayed. Then, the test1, test2,
and test2 values will need to be read from the user.
!declarevariables
!
reals>test1,test2,test3
!
integer>testave
!displayinitialheader
!readthetest1,test2,andtest3values
Next, the average can be calculated. The average will be converted to the nearest integer and, based on
that, the appropriate grade can be determined and displayed. Formalizing this, the following steps can
be developed.
!calculatethetestaveandconverttointeger
!determinegrade
!A>=90
!B80to89
!C70to79
!D60to69
!F<=59
53
8.6.3
The indentation is not required, but does help make the program easier to read.
8.6.4
Once the program is written, testing should be performed to ensure that the program works. The
testing will be based on the specific parameters of the program.
54
The program should be tested with a series of data items to ensure appropriate grade assignment for
each grade. Test values for each grade should be entered for the testing.
8.7 Exercises
Below are some quiz questions and project suggestions based on this chapter.
8.7.1
Quiz Questions
______________
(b1.or.b3)
______________
(b1.and.b2)
______________
((b1.or.b2).and.b3)
______________
(b1.or.(b2.and.b3))
______________
(.not.(i<j))
______________
(j<i)
______________
4) Write the Fortran IF THEN statements to display the message "Game Over" if the integer
variable lives is to 0. You may assume the variable lives is already declared as an integer
and initialized.
55
7) Write the statements require to compute the following formula using real variables f, x, and y.
Use a single IF THEN ELSE IF statement. You may assume the values for f, x, and y have
already been declared as real values and initialized.
f ( x)= x y
x y
8.7.2
if x0.0
if x> 0.0
Suggested Projects
A-
B+
B-
C+
C-
94
93-90
89-87
86-84
83-80
79-77
76-74
73-70
69-60
59
Compile, and execute the program. Test the program on a series of input values that will check
each grade.
56
( 59 ) ( fahrenheit 32 )
The fahrenheit value must be between -50 and 150 (inclusive). If the fahrenheit value is out of
range, the program should display an error message, "Temperature out of range", and terminate.
The calculations must be performed as real. Include program statements, appropriate
declarations, prompts, read statements, calculations, and write statements. Test the program on
a series of input values.
6) Write a Fortran to program that reads an item cost (real numbers) and amount tendered (real
number) and compute the correct change. The correct change should be returned as the number
of twenties, tens, fives, ones, quarters, dimes, nickels, and pennies. The main program should
ensure that the amount paid exceeds the item cost and, if not, display an appropriate error
message. Test the program multiple times using a series of input values.
7) Write a Fortran to program that reads a number from the user that represents a television
channel and then uses a CASE construct to determine the call letters for that station.
Channel
Call Letters
Affiliation
KVBC
NBC
KVVU
FOX
KLAS
CBS
10
KLVX
Public
13
KTNV
ABC
57
58
Looping
where the count variable must be an integer variable, start, stop, and step are integer variables or
integer expressions. The step value is optional. If it is omitted, the default value is 1. If used, the step
value cannot be zero. The <fortran statement(s)> is a sequence of statements and is referred to as the
body of the do-loop. You can use any executable statement within a do-loop, including IF-THENELSE-END IF and even another do-loop. Before the do-loop starts, the values of start, stop, and step
are computed exactly once. More precisely, during the course of executing the do-loop, these values
will not be re-computed.
The count variable receives the value of start variable or expression. If the value of control-var is less
than or equal to the value of stop-value, the <fortran statement(s)> part is executed. Then, the value of
step (1 if omitted) is added to the value of control-var. At the end, the loop goes back to the top and
compares the values of control-var and stop-value.
If the value of control-var is greater than the value of final-value, the do-loop completes and the
statement following end do is executed.
For example, with the declarations,
integer::counter,init=1,final=10,sum=0
will add the numbers between 1 and 10 which will result in 55. Since the step was not specified, it is
defaulted 1.
59
Chapter 9 Looping
Another example, with the declarations,
integer::counter,init=1,final=10,step=2
The use of the function real() converts the sum and count variables from integers to real values as
required for the average calculation. Without this conversion, sum/count division would be interpreted
as dividing an integer by an integer, yielding an integer result.
A final example of a counter controlled loop is to compute the factorial of a positive integer. The
factorial of an integer n, written as n!, is defined to be the product of 1, 2, 3, ..., n-1, and n. More
precisely, n! = 1 * 2 * 3 * ... * n.
integer::factorial,n,i
factorial=1
doi=1,n
factorial=factorial*i
enddo
the above do-loop iterates n times. The first iteration multiplies factorial with 1, the second iteration
60
Chapter 9 Looping
multiplies factorial with 2, the third time with 3, ..., the ith time with i and so on. Thus, the values that
are multiplied with the initial value of factorial are 1, 2, 3, ..., n. At the end of the do-loop, the value of
factorial is 1 * 2 * 3 * ... * n which is n!.
will display the numbers from 1 to 4 skipping the remaining iterations. Since the variable i is checked
before the write statement, the value is not displayed with i is 5 and the loop is exited without
completing the remaining iterations. While it is possible to have multiple exit statements, typically one
one is used. However, multiple exit statements may be required for more complex problems.
The cycle statement will skip the remaining portion of the do-loop and start back at the top. The cycle
statement can be used in a counter controlled loop or a conditionally controlled loop. If the cycle
statement is used within a counter controlled loop, the next index counter is updated to the next
iteration, which could terminate the loop.
For example, given the following declarations,
integer::i
61
Chapter 9 Looping
9.3.1
In order to find the difference between the sum of the squares and the square of the sum of the first N
natural numbers, we will need to find both the sum of the squares and the square of the sum. For
example, the sum of the squares of the first ten natural numbers is,
12 2 2 102 = 385
The square of the sum of the first ten natural numbers is,
1 2 102 = 552 = 3025
Hence the difference between the sum of the squares of the first ten natural numbers and the square of
the sum is 3025 - 385 = 2640.
The program will display the N value, the sum of the squares, the square of the sum, and the difference
for each number from 2 to a given N value. The program should prompt for and read the N value. The
program will display appropriate headers.
9.3.2
For this problem, first we will need to read the N value. Then, we will loop from 1 to the N value and
find both the sum of the squares and the square of the sum.
!declarevariables
!
integer>i,n,SumOfSqrs,SqrOfSums
!displayinitialheader
!promptforandreadthenvalue
!loopfrom1ton
!
computesumofsquares
!
computesums
!squarethesums
!computedifferencebetweensumofsquaresandsquareofsums
!displayresults
9.3.3
62
Chapter 9 Looping
!displayinitialheader
write(*,*)"ExampleProgram"
write(*,*)"Differencebetweensumofsquares"
write(*,*)"andsquareofsums"
write(*,*)
!promptforandreadthenvalue
write(*,*)"EnterNvalue:"
read(*,*)n
!loopfrom1ton
doi=1,n
!computesumofsquares
SumOfSqrs=SumOfSqrs+i**2
!computesquareofsums
SqrOfSums=SqrOfSums+i
enddo
!squarethesums
SqrOfSums=SqrOfSums**2
!computedifferencebetweensumofsquaresandsquareofsums
difference=SqrOfSumsSumOfSqrs
!displayresults
write(*,*)"Difference:",difference
endprogramdifference
The spacing and indentation is not required, but helps to make the program more easily readable.
9.3.4
For this problem, the testing would be to ensure that the results match the expected value. Some
expected results can be determined with a calculator or a spreadsheet. If the program does not provided
the correct result, one or both of the intermediate results, SumOfSqrs or SqrOfSums, may be incorrect.
These values can be displayed with a temporary write statement to determine which might not be
correct. If the problem is still not found, the intermediate values calculated during the loop can also be
displayed with a write statement. The output can be reviewed to determine what the program is doing
(and what may be wrong).
63
Chapter 9 Looping
One form of the conditional loop is:
dowhile(conditionalexpression)
<fortranstatement(s)>
enddo
In this form, the conditional expression is re-checked at the top of the loop on each iteration.
A more general format of the conditional loop is:
do
<fortranstatement(s)>
enddo
As is, this loop will continue forever. Probably not so good. A selection statement, such as an IF
statement, and an exit statement would be used to provide an means to terminate the looping.
For example,
do
<fortranstatement(s)>
if(conditionalexpression)exit
<fortranstatement(s)>
enddo
Would stop looping only when the conditional expression evaluates to true. The exit statement can
used used in multiple times in different locations as needed. An IF statement, in any form, can be used
for either the exit or cycle statements.
For example, a conditional loop could be used to request input from the user and keep re-prompting
until the input is correct.
integer::month
do
write(*,*)"Entermonth(112):"
read(*,*)month
if(month>=1.and.month<=12)exit
write(*,*)"Error,monthmustbebetween1and12."
write(*,*)"Pleasereenter."
enddo
This will keep re-prompting an unlimited number of times until the correct input (a number between 1
and 12) is entered.
64
Chapter 9 Looping
Since a counter controlled DO loop requires an integer loop counter, another use of conditional loops
would be to simulate a real counter. For example, to display the values from 1.5 to 4.5 stepping by
0.25, the following conditional loop could be used.
real::value=1.5
dowhile(value<=4.5)
write(*,*)"Value=",value
value=value+0.25
enddo
9.5.1
For this limited example, we will request a date where the year is between 1970 and 2020. The month
must be between 1 and 12. The date will depend on the month since some months have 30 or 31 days.
February has either 28 days or 29 days if it is a leap year. Due to the limited allowable range of the
year, the determination of a leap year can be performed by checking if the year is evenly divisible by 4
(which implies a leap year).
9.5.2
For this problem, we will need to read the three values (month, date, and year). Then, we will check
the values to ensure that date is valid. Then, we will check the month first and then the year since it
will be used to check the date.
The months January, March, May, July, August, October, and December have 31 days. The months
April, June, September, and November have 30 days. February has 28 days unless the year is evenly
divisible by 4, in which case February has 29 days.
!declarevariables;integer>month,date,year
!displayinitialheader
!loop
!
requestmonth,date,andyear
!
readmonth,date,andyear
!
checkmonth(112)
!
checkyear(19702020)
!
checkdate
!
1,3,5,7,8,10,1231days
!
4,6,9,1130days
!
2ifmoduloofyear/4is029days
65
Chapter 9 Looping
!
2ifmoduloofyear/4isnot028days
!
ifinvalid,displayerrorandlooptotryagain
!
endloop
!displayresults
9.5.3
66
Chapter 9 Looping
selectcase(month)
case(1,3,5,7,8,10,12)
datemax=31
case(2)
if(mod(year,4)==0)then
datemax=29
else
datemax=28
endif
case(4,6,9,11)
datemax=30
endselect
!ifinvalid,displayerrorandlooptotryagain
if(date<1.or.date>datemax)then
write(*,*)"Error,invaliddate."
cycle
endif
exit
!
endloop
enddo
!displayresults
write(*,*)"ValidDateis:",month,date,year
endprogramdatecheck
The spacing and indentation is not required, but helps to make the program more easily readable.
9.5.4
For this problem, the testing would be to ensure that the results match the expected value. This will
require entering a series of different dates and verifying that the displayed output is correct for the
given input data.
9.6 Exercises
Below are some quiz questions and project suggestions based on this chapter.
9.6.1
Quiz Questions
Chapter 9 Looping
7) What is the output of the following Fortran statements. Assume i and j are declared as integer.
write(*,*)"start"
doi=1,3
doj=1,2
write(*,*)i,"*",j,"=",(i*j)
enddo
enddo
write(*,*)"end"
8) Are the following Fortran statements valid or invalid? If valid, what will happen?
doi=3,2
write(*,*)i
enddo
9) Are the following Fortran statements valid or invalid? If valid, what will happen?
doi=3,3
if(i==3)then
write(*,*)i
enddo
endif
68
Chapter 9 Looping
9.6.2
Suggested Projects
Impact
Origin
Time
The range (distance between the initial origin and final impact) is determined by the formula:
2 v 20
range =
cos sin
g
where v0 is the initial velocity of the ball, is the angle of the throw, and g is the acceleration
due to the earth's gravity. The value for gravity should be defined as a constant and set to -9.81
meters per second.
Note, the intrinsic trigonometric functions work in radians, so the angle in degrees will need to
be converted to radians for the calculations. To convert degrees to radians:
radians = degrees
( 180 )
69
Chapter 9 Looping
70
10
Formatted Input/Output
Fortran uses a FORMAT statement to allow control of how data is displayed or read. This is useful
when very specific input or output is required. For example, displaying money figures typically require
exactly two decimal places. There are format specifiers for each data type; integer, real, character,
logical, and complex.
10.1
Format
The format specifiers, separated by commas, are contained in a pair of parenthesis as a string literal.
There are multiple possible ways to define a format. However, we will focus on the easiest, most direct
method. The format specifier will replace the second * in the read or write statements. For example:
read(*,'(<formatspecifiers>)')<variables>
write(*,'(<formatspecifiers>)')<variables/expressions>
The following sections explain the options for the format specifiers.
10.2
Format Specifiers
The format specifiers tell the system exactly how the input or output should be handled. Each value
being read or written requires some amount of space. For example, an integer of four digits requires at
least four spaces or positions to print. Therefore, the number of positions to be used is a key part of the
specifier.
The following convention of symbols:
w
m
d
n
r
Specifier
Integers
rIw or rIw.m
Real
rFw.d
Logicals
rLw
Characters
rA or rAw
nX
Tn
Vertical Spacing
In addition, each specifier or group of specifiers can be repeated by preceding it with a repeat count.
Format specifiers for complex numbers will be addressed in later chapters.
10.3
The integer format specifier rIw or rIw.m is used tell the system exactly how many positions should be
used to either read or write an integer variable. The w is the width or how many total places are used.
If the number is negative, the sign uses a place. The m is optional and can be used to set a minimum
number of digits to display, which will display leading zero's if needed in order to display the minimum
number of digits. The r is the number of times the format specifier should be repeated.
A format of '(i6)' would look like:
x
x
w
the following write statement can be used to display the value in variable num1 with no leading or
trailing spaces.
write(*,'(i2)')num1
Which will display 42123 with no spaces between the two different values. However,
write(*,'(i2,i4)')num1,num2
will display 42123 with one space between the values. Further,
write(*,'(i5,i5,i5)')num1,num2,num3
will display 421234567 where each variable uses 5 spaces. And, finally,
write(*,'(i6.4)')num1
72
10.4
The real format specifier rFw.d is used tell the system exactly how many positions should be used to
either read or write an real variable. The w is the width or how many total places are used, including
the decimal point. If the number is negative, the sign uses a place. The d is how digits are displayed
after the decimal point, which does not count the decimal point. The r is the number of times the
format specifier should be repeated.
A format of '(f6.2)' would look like:
x
the following write statement can be used to display the value in variable var1 with no leading or
trailing spaces.
write(*,'(f3.1)')var1
Which will display 4.5 with no leading spaces. Multiple variables can be displayed. For example,
to display the values in variables var1 and var2.
write(*,'(f5.2,f8.3)')var1,var2
Which will display 4.5012.000. Another example with three variables, var1, var2, and var3, is
as follows:
w=qF eF
write(*,'(f10.4,f10.4,f10.4)')var1,var2,var3
10.7
Advance Clause
The advance clause instructs the computer whether or not to advance the cursor to the next line. The
possible values are yes and no. If the advance clause is not included, the default value is yes.
This clause is useful when prompting for user input to allow the input to be entered on the same line as
the prompt. When using the advance clause is used, the free format (*) is not allowed. A format must
be included.
For example, the period program from the previous chapter included the statements:
!promptforandreadthenvalue
write(*,'(a)')"Entercounttosum:"
read(*,*)n
Which, when executed, the input is entered on the line following the prompt.
c:\mydir>sums
ExampleProgram
Differencebetweensumofsquares
andsquareofsums
Entercounttosum:
3
Difference:2640
Which allows the input to be entered on the same line as the prompt.
10.8
Example
This example will read a date from the user (month, day, and year, on the same line), determine the day
of week (for that month/day/year). Then, the program will display the original input date (numeric
form) and the formatted date. The original input date will be displayed include leading 0's (i.e.,
01/01/2010).
75
10.8.1
For this problem, we will read the three numbers for the date from the user. The verification of the date
information is left as an exercise.
To calculate the day on which a particular date falls, the following algorithm may be used (the divisions
are integer divisions):
a=(14month)/12
y=yeara
m=month+12*a2
daynum=[date+y+y/4y/100+y/400+(31*m/12)]mod7
The value of daynum is 0 for a Sunday, 1 for a Monday, 2 for a Tuesday, etc.
10.8.2
For this problem, first we will need to read the date. The verification of the date entered and error
checking is left as an exercise. Then, the original input date can be displayed, in numeric form,
formatted appropriately. For a date, this would mean two digits for the month, a /, two digits for the
day, a /, and four digits for the year. When the day is only one digit, for example 5, it is customary to
display a 05 so the program will ensure this occurs.
!declarevariables
!
integer>month,day,year
!displayinitialheader
!promptformonth,day,andyear
!readmonth,day,andyear
!displayformattednumericmonth/day/year
Then the program can calculate the day of the week (based on the formula) and convert the resulting
number (0-6) into a date string and display the result.
!calculatedayofweek
!convertdayofweek(06)tostring
!convertmonth(112)tostring
!displayformattedstringforday,month,andyear
10.8.3
76
77
&
&
endprogramdateFormatter
The spacing and indentation is not required, but helps to make the program more easily readable. The
trim() intrinsic function removes any trailing spaces from the input string. Additional information
regarding handling character data types in provided in the following section.
10.8.4
For this problem, the testing would be to ensure that the output formatting is correct. Since there is no
error checking on the input, only correct dates should be entered. Test the program on a series of
different input values and verify that the output is correct for those input values.
78
10.9
Exercises
Below are some quiz questions and project suggestions based on this chapter.
10.9.1
Quiz Questions
4) What is the write statement and format specifier to output the integer variable num1 which
contains an value between 0 and 999 (right justified, no leading zero's, no additional spaces).
5) What is the write statement and format specifier to output the real value of pi which has been
initialized to 3.14159 (right justified, no additional spaces)?
6) What is the single write statement and format specifier to output "Programming" and "Is Fun!"
on two different lines?
7) What is the single write statement and format specifier to output "Enter Number:" and leave the
cursor on the current line?
10.9.2
Suggested Projects
79
Note, the irate in the formula must be converted to a monthly rate (divided by 12) and then
divided by 100 (to convert from percentage). During the time period (term), some of each
monthly payment will be used to pay the interest and some will be used to reduce the
outstanding balance. The monthly interest amount can be calculated by monthly interest rate
times outstanding balance. The amounts must be lined up with only two digits for cents. The
payment number must three digits (including leading zero's if necessary). Test the program on a
series of different input values and verify that the output is correct for those input values.
4) Write a Fortran program that calculates and displays compounded interest. The program should
read the initial principal amount, interest rate percentage, and the term (number of years). The
program should display a summary of the input and the yearly compounded interest. Refer to
the example output for formatting.
The formula for compounding interest is:
value = principal( 1+ interest ) year
Note, the interest rate percentage read from the user must be converted to a number (i.e.,
divided by 100). The output must be formatted in a manner similar to the example output. This
includes ensuring that the dollar amounts are displayed with the appropriate two decimal points.
Test the program on a series of different input values and verify that the output is correct for
those input values.
80
11
Fortran was originally developed for scientific and engineering application requiring significant
mathematical calculations. However, the Fortran 95 language includes extensive character and string
handling capabilities.
11.1
A character is a single character or symbol, typically enclosed in quotes. For example, letters (A-Z
and a - z), punctuation (!, ,, ?, etc.) , symbols, (@, #, >, etc.), and digits 1, 2 are
characters.
Some examples include:
"X"
"z"
"5"
Character and string constants are case sensitive. So, character X (upper-case) is not the same as x
(lower-case). When a digit is enclosed in quotes, it is treated as a character and consequently
arithmetic operations (addition, subtraction, etc.) are not allowed.
A string is a series of characters. A string consists of an arbitrary sequence of characters also enclosed
in quotes. Some examples include:
"HelloWorld."
"456"
"123"
"456?"
"Goodbyecruelworld!!"
"Haveaniceday?"
Since digits enclosed in quotes are not numeric values, the strings 1 2 3 and 456? are allowed.
A problem arises if you want to have a quote in the string itself. A double quote will be interpreted as a
single within a string. The two quotes must be together (no spaces between). For example, the string:
"Hesaid""wow""whenheheard"
Would be displayed as
"Hesaid"wow"whenheheard"
The double-quote is sometimes referred to as an escape character. Strings and characters must be
associated with the character data type.
81
11.2
A character variable is a variable that can contain a set of 1 or more characters. Character variables
must have a defined length. All declarations are placed in the beginning of the program (after the
program statement). Declaring character variables formally defines the type and sets aside memory.
This is performed with a type declaration statement in the form of:
<type>::<listofvariablenames>
For character variables, the type is character. For example, to define a character variable to hold the
day of week (i.e., Wednesday), the following declaration,
character(len=9)::dayofweek
Would define the variable, dayofweek, with a maximum length of 9 possible characters.
Additional examples include:
character(len=3)::symbol1,symbol2
character::symbol3
character(1)::symbol5,symbol5
character(30)::symbol6,symbol7
The declarations can be entered in any order, however they must be at the beginning of the program.
The len= is optional and can be omitted. When the length is omitted entirely, the default length is set
to 1. This, character, character(len=1), and character(1) are all the same.
When multiple variables are included in a single declaration, they must all be the same length. If
different lengths are required, separate declaration lines are required.
11.3
It is possible to declare a character variable and to set it is initial value at the same time. This
initialization is not required, but can sometime be convenient. For example, to define a character
variable, dayofweek, and set it to the day of week:
character(len=9)::dayofweek="Wednesday"
Spaces or no spaces between the variables, equal signs, semicolons, and commas are allowed.
Variables initialized at declaration can be changed during program execution as needed.
11.4
Character Constants
It is possible to declare a character variable, set it is initial value, and ensure that the value can not be
changed. For example, to define a character constant, language,
character(len=7),parameter::language="English"
82
This instructs the Fortran compiler to count the characters and set the appropriate length.
11.5
Character Assignment
Assignment is term for setting a character variable equal to some value (character or string).
Assignment is performed with a equal (=) sign. For example, given the declaration,
character(9)::thismonth
When character variables are assigned they are filled from the left and automatically padded with
blanks if necessary. For example, if the variable thismonth is reset
thismonth="May"
11.6
Character Operators
The only character operator is // (concatenation) which simply concatenates two strings together. For
example,
"Universityof"//"NevadaLasVegas"
Characters variables and literals may be used with concatenation. For example, given the following
declaration,
character(len=6)::str1="ABCDEF",str2="123456"
character(len=12)::str3
11.7
Character Substrings
A substring is a subset of a string. A substring can be selected based on the characters position or count
within the start with the first character corresponding to 1 and the second character corresponding to 2
as so forth for as many characters are in the entire string. The substring is specified with a start and
stop position in the form of (start:stop). The stop must be greater than or equal to the stop position.
83
11.8
Character Comparisons
The standard relational operators (==, >, >=, etc.) have some limitations when character data is
used. Simple comparisons, such as,
"A"<"D"
"ABC"=="ABC"
11.9
There are a number of character oriented intrinsic operations. Some of the basic character oriented
functions include:
Function
Description
ACHAR(I)
IACHAR(C)
LEN(STR)
84
TRIM(STR)
11.10
Example
This example will scan a string and convert all lower-case letter to upper-case.
11.10.1
For this problem, the string will be read from the user with a maximum of 80 characters. Any lower
case letters encountered will be converted to upper-case. All other characters (digits, symbols, etc.)
will be left alone. To determine if a characters is lower-case, we can see if it is between a and z.
The final string will be displayed back to the screen. Based on the ASCII table in Appendix A, there is
a specific, fixed difference between each upper and lower-case letter. Thus, in order to convert a lowercase character to upper-case, that difference can be subtracted. However, in order to perform the
subtraction, each character needs to be converted into an integer (based on its value in the ASCII table).
The IACHAR() intrinsic function performs this conversion. After the conversion (subtraction), the
integer must be converted back into its corresponding character, which can be accomplished with the
ACHAR() intrinsic function. These functions work on a single character/integer, so each character will
need to be addressed individually.
11.10.2
For this problem, first we will need to prompt for and read the input string. Then any trailing blanks
will be removed and the final length can be determined. Based on that length, each character will be
accessed and converted if needed.
!declarevariables
!
integer>string1,string2,I,strlen
!displayinitialheader
!promptforstring
!readstring
!trimanytrailingblanks
!determinelengthofstring
!loop
!
accesseachcharacter
!
ifchecklowercase("a""z")>converttouppercase
!displayfinalstring
85
11.10.3
accesseachcharacter
ifchecklowercase>converttouppercase
if(string1(i:i)>="a".and.string1(i:i)<="z")then
string1(i:i)=achar(iachar(string1(i:i))32)
endif
enddo
!
!displayfinalstring
write(*,'(/,a)')""
write(*,'(a,/,2x,a,/)')"FinalString:",string1
endprogramcaseConverter
The spacing and indentation is not required, but helps to make the program more easily readable.
86
11.10.4
For this problem, the testing would ensure that the output string is correct for the given input.
For example, the following output,
c:\mydir>case
CaseConversionExample
EnterString(80charmax):HelloWorld!?
FinalString:
HELLOWORLD!?
Each lower-case letter was converted to upper-case while the upper-case, space, and punctuation were
unchanged. The program should be executed with a series of test inputs to verify the correct output.
11.11
Exercises
Below are some quiz questions and project suggestions based on this chapter.
11.11.1
Quiz Questions
87
11.11.2
Suggested Projects
88
12
File Operations
File operations allow Fortran programs to read from files and/or write to files. The basic read and write
statements for file operations are the same as previously used with some additional information or
clauses.
12.1
File Open
A file must be opened before information can be written or read from a file. In order to open a file, the
operating system needs some information about the file in order to correctly identify the file and
establish the access parameters (i.e., read, write, etc.). The open statement clauses is how is
information is provided.
The file open statement is as follows:
open(unit=<unitnumber>,file=<filename>,
&
status=<filestatus>,action=<fileaction>,
&
position=<fileposition>,iostat=<statusvariable>)
Explanation
unit
file
status
action
position
12.2
File Write
The file must be opened for write or readwrite access before any information can be written to the
file. The general form of the write statement is as follows:
write(unit=<unitnumber>,fmt=<formatstatement>,
advance="no",iostat=<variable>)
<variables/expressions>
&
&
The write is the same as the simple write, however the unit number must be the number assigned
during the open operation. Normally, the next write will be on the next line. The advance=no is
optional. If it is included, the next write will be on the same line where the previous line stopped.
For example to open a file named temp.txt and place the string Fortran Example and the numbers 42,
and 3.14159 on separate lines, the following declarations:
integer::myanswer=42,myopenstatus,mywritestatus
real,parameter::pi=3.14159
character(15)::mymessage="FortranExample"
character(8)::myfilename="temp.txt"
action="write", position="rewind",
iostat=myopenstatus)
if(myopenstatus>0)stop"Cannotopenfile."
write(10,'(a/,i5/,f7.5)',iostat=mywritestatus)
mymessage,myanswer,pi
&
&
&
12.3
File Read
The file must be opened for read or readwrite access before any information can be read from the
file.
The general form of the write statement is as follows:
read(unit=<unitnumber>,fmt=<formatstatement>,
iostat=<variable>)<variables>
90
&
The read is the same as the simple read, however the unit number must be the number assigned during
the open operation. If the status variable is set to less than 0, that is an indication that the end of the file
has been reached.
For example, if the file numbers.dat exists and has two numbers (on separate lines), the following
declarations,
integer::num1,num2,myopenstatus,myreadstatus
character(11)::myfilename="numbers.txt"
&
&
read(12,'(i5)',iostat=myreadstatus)num1
read(12,'(i5)',iostat=myreadstatus)num2
12.4
Rewind
An open file can be reset back to the beginning. This might be useful if the file needs to be read twice.
The rewind statement will reset the file read pointer and subsequent reads will start back at the
beginning. The general form of a rewind statement is:
rewind(<unitnumber>)
Where the unit number was assigned during the initial open. The file must be open for the rewind to
work correctly.
12.5
Backspace
When reading from a file, each successive read will return the next line from the file. The computer
keeps track of which lines have been read and will automatically return the next line. It is possible to
read a line and then backspace and re-read the line again with the backspace statement.
The general form of a backspace statement is:
backspace(<unitnumber>)
Where the unit number was assigned during the initial open. The file must be open for the backspace
to work. This is not used very often.
91
12.6
Close File
An open file should be closed when it is no longer needed. The general form of a close statement is:
close(<unitnumber>)
Where the unit number was assigned during the initial open.
For the previous examples,
close(10)
close(12)
12.7
Example
In this example we will write a Fortran program to read an input file and write a line number and the
original line to an output file.
12.7.1
For this problem, we will read get the file names from the user and open the files. Then we will read a
line from the input file, and write the line number and line to the output file. When done, we will close
the file.
12.7.2
For this problem, first we will need to prompt for and read the file names from the user and ensure that
they open correctly. If the file can not be opened, an error message will be displayed and the file names
will be re-read.
!declarevariables
!
integer>i,rdopst,wropst
!
character>line
!displayinitialheader
!loop
!
promptforinputfilename
!
readinputfilename
!
openinputfile(readaccess)
!
ifopenunsuccessful,displayerrormessage
!
otherwise,endloop
!loop
!
promptforoutputfilename
!
readoutputfilename
!
openoutputfile(writeaccess)
!
ifopenunsuccessful,displayerrormessage
!
otherwise,endloop
Once the file is open, a line will be read from the input file, and the line number and the line will be
written to the output file. For this example, we will assume that a line will have 132 or less characters.
92
12.7.3
&
&
write(*,'(a/,a)')"Unabletoopeninputfile.", &
"Pleasereenter"
enddo
!
!promptforoutputfilename
do
write(*,'(a)',advance="no")"OutputFileName:"
93
!readoutputfilename
read(*,*)wrfile
!openoutputfile(readaccess)
!ifopenunsuccessful,displayerrormessage
!
otherwise,endloop
open(14,file=wrfile,status="replace",
action="write",position="rewind",
iostat=wropst)
if(wropst==0)exit
&
&
write(*,'(a,a/,a)')"Unabletoopen",
&
"outputfile.","Pleasereenter"
enddo
!
i=1
do
!readlinefrominputfile
read(12,'(a)',iostat=rdst)line
!ifendoffile,exitloop
if(rdst>0)stop"readerror"
if(rdst<0)exit
!writelinenumberandlinetooutputfile
write(14,'(i10,2x,a)')i,line
i=i+1
enddo
!closefiles
close(12)
close(14)
endprogramlinenumbers
The spacing and indentation is not required, but helps to make the program more easily readable.
12.7.4
For this problem, the testing would involve executing the program with various input files and
verifying that the line numbers are correctly added.
12.8
Exercises
Below are some quiz questions and project suggestions based on this chapter.
94
12.8.1
Quiz Questions
What is the read statement required to get data1, data2, and data3 into the integer variables
num1, num2, and num3 respectively.
12.8.2
Suggested Projects
95
(
(
(
))
step
offsetposition sin (radius + radius )
(
radius ) )
step
radius 2
The step should start at 0.0 and stop at 360.0, stepping by 0.1. All writes should use a formatted
output (not the '*'). Then the program should close the output file, inform the user the plotting
is completed. Test the program on a number of different input values.
3) Write a Fortran program that plays the Chaos Game. To play the Chaos Game, plot 3 points A,
B, C and an arbitrary initial point X1. Then, generate a random number between 1 and 3
representing A, B, or C. If A comes up, plot the midpoint of the line joining X1 to A. If B
comes up, plot the midpoint of the line joining X1 to B; the case with C is similar. Call this
new point X2. Roll the die again. Plot the midpoint of the line joining X2 to either A, B or C
depending on the outcome of the die toss. Call this new point X3. Repeat this process N times.
Test the program on a number of different input values.
Refer to Appendix C for more information regarding generating random numbers.
Note, the correct output of this program is shown on the cover page.
96
reserving the name nums2, but not reserving any space for values.
13.1.3.1
To allocate the space for the array, the allocate statement must be used. Before an array can be allocated, it
must be declared as allocatable. The general form of the allocate statement is:
allocate(<arrayname>,stat=<statusvariable>)
The status variable must be an integer variable and will be used by the system to place a status code
indicating the status (success or failure) of the operation. If the status variable is set to 0, the allocation
was successful. If the status variable is set to >0, an error occurred and the allocation was not
unsuccessful.
For example, given the declarations,
integer,dimension(:),allocatable::nums2
integer::allst
the following allocate statement allocates space for 1000 numbers in array nums2,
allocate(nums2(1000),stat=allst)
The size, 1000 in this example, can be a variable, but it must be an integer. The status variable allst
will be set to 0 if the allocation is successful. However, if the status variable allst is set to a value >0,
an error occurred and the allocation was not successful.
13.2
To access elements in an array, the array name and an index must be specified. The index must be an
integer or integer expression and enclosed in parentheses. The general format is,
arrayname(<integerexpression>)
would declare an array with ten elements. To place a value 121.3 in the first array element,
times(1)=121.3
The index in these examples is a literal. However, the index can be an integer variable or integer
expression.
99
would declare an array with ten elements. To place a value 98.6 in the fifth array element,
temps(i)=98.6
To access the fifth element, subtract 3.0 and place the result in the sixth element,
temps(i+1)=temps(i)3.0
To set all elements of the temps array to 0.0, a loop could be used as follows:
doi=1,10
temps(i)=0.0
enddo
13.2.1
Array Bounds
When an array is declared for a specific size, only that many elements can be used. For example, if an
array is declared with 10 elements, only 10 elements are available. Given the following declaration,
real,dimension(10)::expArr
would declare an array with ten elements. To place a value 42.5 in the first array element and 73.5 in
the last array element.
expArr(1)=42.5
expArr(10)=73.5
However, if an array element is accessed that outside the declared bounds, it is an error. For example,
expArr(11)=99.5
would be an error. These kinds of errors would be difficult to find. However, if the bounds checking is
turned on (as noted in chapter 3), when the program is executed the error will be noted.
To compile with bounds checking turned on, the following compile command should be used:
C:\fortran>gfortranfcheck=boundsohwhw.f95
This command will tell the 'gfortran' compiler to include bounds checking.
In general, using the bounds checking can slow a program down. However, this is not a significant
issue when learning to write programs.
100
13.3
Implied Do-Loop
An implied do-loop is a special form of a loop that can be performed on one line. This can be useful
for accessing elements in an array. For example, assuming i is declared as an integer, the following
code,
doi=1,5
write(*,*)nums(i)
enddo
Both forms of the loop will display the same results. If necessary, a step can be used. If the step is
omitted, as in the example, the step is defaulted to 1.
13.4
Initializing Arrays
An array can be initialized when it is declared. Each element in the array can be initialized to a single
value or each element to a different value. The following declaration,
real,dimension(10)::numbers=1.0
will initialize each of the 5 elements in the array numbers to 1.0, 2.0, 3.0, 4.0, and 5.0 respectively.
The implied do-loop may also be used. For example, in the following declaration,
integer,dimension(5)::numbers=(/(i,i=1,5)/)
will initialize each of the 5 elements in the array numbers to 1, 2, 3, 4, and 5 respectively.
13.5
Example
In this example we will write a Fortran program to read a series of numbers from a file and compute
some statistical information including minimum, maximum, sum, average, and standard deviation9.
101
standard deviation =
( average list ( i) )2
i =1
13.5.1
The program will display an initial header and get the file name. Specifically, we will need to prompt
for the file name, read the file name, and verify that the file is available by attempting to open the file.
Then, the program will read the numbers from the file and store them in an array. For this problem,
there will be no more than 5000 numbers in the file. After the numbers are in the array, the minimum,
maximum, and sum will be found. Next, the average can be computed. Finally, the standard deviation
can be calculated in steps, the first of which is computing the inner loop. The numbers should be
displayed, ten per line, followed by the results.
13.5.2
After the header is displayed, the program should prompt for the file name, read the file name, and
verify that the file is available by attempting to open the file. If the file can not be opened, the program
will display an error message and re-prompt. If the user does not enter correct information after three
tries, the program should terminate with an appropriate error message. That is, three errors are
acceptable, but if a fourth error is made, the program will terminate.
!declarevariables
!
integer>i,ncount,errs,opstat,rdstat
!
real>min,max,sum,stdsum
!
real>arrayfor
!
character>filename(20)
!displayinitialheader
!loop
!
promptforfilename
!
readfilename
!
attempttoopenfile
!
iffileopensuccessful,exitloop
!
displayerrormessage
!
counterror
!
if>3errors,terminateprogram
!endloop
Then, the program will loop to read the numbers from the file and store them in an array. The program
will check for any read errors (status variable > 0) and for the end of file (status variable < 0).
102
Next, another loop will be used to find the minimum, maximum, and sum of the numbers. To find the
minimum and maximum values, we will assume that the first element in the array is the minimum and
maximum. Then, the program will check each number in the array. If the number from the array is less
than the current minimum value, the current minimum value will be updated to the new value. Same
for the maximum, if the number from the array is more than the current maximum value, the current
maximum value will be updated to the new value.
!initializemin,max,andsum
!loop
!
checkfornewmin
!
checkfornewmax
!
updatesum
!endloop
Once the sum is available, the average can be computed. Finally, a loop will be used to calculate the
summation for the standard deviation.
!calculateaverage
!initializestdsum
!loop
!
calculateaveragearrayitem
!
updatestdsum
!endloop
Once the summation is completed, the standard deviation can be computed and the final results
displayed. As per the example specifications, the numbers should be displayed 10 per line.
One way to handle this is to display numbers on the same line (with the advance=no clause) and
every 10th line display a new line.
!calculatestandarddeviation
!looptodisplaynumbers,10perline
!displayresults
!endprogram
103
13.5.3
&
&
!iffileopensuccessful,exitloop
if(opstat==0)exit
!displayerrormessage
write(*,'(a)')"Error,cannotopenfile."
write(*,'(a)')"Pleasereenter."
!counterror
errs=errs+1
!if>3errors,terminateprogram
if(errs>3)then
write(*,'(a)')"Sorryyourhavingproblems."
write(*,'(a)')"Programterminated."
stop
endif
!endloop
enddo
104
!loop
do
!readfile
read(42,*,iostat=rdstat)num
!iferroronread,terminateprogram
if(rdstat>0)stop"Erroronread."
!ifendoffile,exitloop
if(rdstat<0)exit
!incrementnumbercounter
ncount=ncount+1
!placenumberinarray
numbers(ncount)=num
!endloop
enddo
!initializemin,max,andsum
min=numbers(1)
max=numbers(1)
sum=0.0
!loop
doi=1,ncount
!checkfornewminandnewmax
if(numbers(i)<min)min=numbers(i)
if(numbers(i)>max)max=numbers(i)
!updatesum
sum=sum+numbers(i)
!endloop
enddo
!calculateaverage
average=sum/real(ncount)
!initializestdsum
stdsum=0.0
!loop
doi=1,ncount
!calculate(averagearrayitem)^2andupdatesum
stdsum=stdsum+(averagenumbers(i))**2
105
!endloop
enddo
!calculatestandarddeviation
std=sqrt(stdsum/real(ncount))
!displayresults
write(*,'(a)')""
write(*,'(a)')"Results:"
doi=1,ncount
write(*,'(f8.2,2x)',advance="no")numbers(i)
if(mod(i,10)==0)write(*,*)
enddo
write(*,'(a,f8.2)')"Minimum=",min
write(*,'(a,f8.2)')"Maximum=",max
write(*,'(a,f8.2)')"Sum=",sum
write(*,'(a,f8.2)')"Average=",average
write(*,'(a,f8.2)')"StandardDeviation=",std
endprogramstandardDeviation
The spacing and indentation is not required, but helps to make the program more easily readable.
13.5.4
For this problem, the testing would involve executing the program using a file with a set of numbers
where the correct results are either known ahead of time or can be calculated by hand in order to verify
that the results are accurate.
13.6
Arrays of Strings
An array may also contain characters or strings. The declaration and and access of array elements is
the same. However, the string size must be included in the declaration and can not be easily changed
once define.
For example, to declare an array to hold 100 titles where each title is a maximum of 40 characters,
character(40),dimension(100)::titles
Setting an element is the same. For example, to set the first element of the array to the title of this text,
titles(1)="IntroductiontoProgrammingusingFortran95"
Character arrays may be statically or dynamically declared as noted in the previous sections.
106
13.7
Exercises
Below are some quiz questions and project suggestions based on this chapter.
13.7.1
Quiz Questions
a)
b)
c)
d)
107
13.7.2
Suggested Projects
norm =
2
1
Refer to Appendix C for more information regarding generating random numbers. Test the
program on a series of different input values.
108
You will need to convert the above pseudo-code algorithm into Fortran code. Test the program
on a series of different input values.
109
110
14
Multidimensional Arrays
index
<value>
<value>
<value>
<value>
...
...
...
...
<value>
<value>
<value>
<value>
The specific syntax requires an index or subscript to specify which element of the array to access. The
indexing for a two dimension array is:
Array Name
index
arr(1,1)
arr(1,2)
arr(2,1)
arr(2,2)
arr(3,1)
arr(3,2)
...
...
...
...
arr(n,1)
arr(n,2)
By default, the first element is at index=1, the next at index=2, and so forth. This default (where the
first number is at index 1) can be changed if needed.
14.1
Array Declaration
Multidimensional array declaration is very similar to single-dimension array declaration. Arrays must be
declared before use. The type of the array is defined followed by the size or dimension, which in this case
requires a size for each dimension. As before, there are two ways to declare an array: static and dynamic.
111
14.1.1
Static Declaration
A static declaration means that the size or dimension of the array must be defined initially (before the
program is compiled). The size definition can not be altered. The general form of an array declaration is,
type,dimension(extent,extent)::name1,name2,...,nameN
where type is the data type (integer, real, etc.) of the array. The dimension specifies the size, and name1,
name2, ... , nameN are names of one or more arrays being declared.
For example, to declare a two-dimensional array 100 by 100,
integer,dimension(100,100)::nums1
will create an array, nums1, with space for a total of 10,000 integer values.
In this example the extent for each dimension is 100 which means that each of the two dimension's
indexes will range form 1 to 100. Each or both extent's can be changed by specifying the extents as:
(smallerinteger:largerinteger,smallerinteger:largerinteger)
When only one number is specified, the smaller-integer is assumed to be 1. When both numbers,
smaller and larger index, are specified the dimension of the array will range between the smallerinteger and the larger-integer. For example, a declaration of:
integer,dimension(0:9,0:9)::ranges
will create an array, ranges, with both indexes between 0 and 9 (inclusive). Using index values not
within the specified range will result in an error.
14.1.2
Dynamic Declaration
The same as single dimension, a dynamic declaration means that the dimension of the array can be set when
the program is executed. Once set, the dimensions can not be altered. When using a dynamic declaration,
the array type and name must be defined, which specifies only the name and type of the array, but does not
reserve any space for the array. Then, during program execution, the array can be allocated which will
create the space for the array. Only after the array has been allocated can it be used.
For example, to declare an array,
integer,dimension(:,:),allocatable::nums2
reserving the name nums2, but not reserving any space for values.
14.1.3
To allocate the space for the array, the allocate statement must be used. Before an array can be allocated, it
must be declared as allocatable.
The general form of the allocate statement is:
allocate(<arrayname>,<dimension>,stat=<statusvariable>)
The status variable must be an integer variable and will be used by the system to place a status code
112
the following allocate statement allocates space for 10,000 numbers in array nums2,
allocate(nums2(100,100),stat=allstat)
The size, 100 by 100 in this example, can be a parameter or variable, but it must be an integer. The
variable allstat will be set to 0 if the allocation is successful and >0 if the allocation failed.
14.2
To access elements in an array, the array name and the an index must be specified. The index must include
an integer or integer expression for each dimension enclosed in parentheses. The general format is,
arrayname(<integerexpression>,<integerexpression>)
would declare an array, table1, with a total of 50 elements. To place a value 121.3 in the first row and first
column,
table1(1,1)=121.3
The index in these examples is a literal. However, the index can be an integer variable or integer
expression. For example, given the following declarations,
real,dimension(10,10)::tmptable
integer::i=2,j=3
To access the same element, subtract 3.0 and place the result back into the same location,
tmptable(i,j+1)=tmptable(i,j+1)3.0
113
14.3
Example
In this example we will write a Fortran program that will request a count, generate count (x,y) random
points, and perform a Monte Carlo estimation based on those points. All x and y values are between
0 and 1. The main routine will get the count and the use a subroutine to generate the random (x,y)
points and a function, to perform the Monte Carlo estimation. For this example, the count should be
between 100 and 1,000,000.
14.3.1
Based on the problem definition, we will use a main routine that will get and check the count value. If
the count is not between 100 and 1,000,000, the routine will re-prompt until the correct input is
provided. Once a valid count value is obtained,
then the main will allocate the array and call the
two subroutines. The first subroutine will
generate the random (x,y) points and store them
in an array. The second subroutine will perform
the Monte Carlo estimation.
Monte Carlo methods are a class of
computational algorithms that rely on repeated
random sampling to compute their results.
Suppose a square is centered on the origin of a
Cartesian plane, and the square has sides of
length 2. If we inscribe a circle in the square, it
will have a diameter of length 2 and a radius of
length 1. If we plot points within the upper right quadrant, the ratio between the points that land within
the inscribed circle and the total points will be an estimation of .
est = 4
inside circle
( samples
)
total samples
As more samples are taken, the estimated value of should approach the actual value of . The
Pythagorean theorem can be used to determine the distance of the point from the origin. If this distance
114
14.3.2
The main routine will display an initial header, get and check the count value, and allocate the array.
The program will need to ensure that the array is correctly allocated before proceeding. Then program
can generate the (x,y) points. Based on the problem definition, each point should be between 0.0 and
1.0 which is provided by default by the Fortran random number generator. Next, the program can
perform the Monte Carlo pi estimation. This will require the already populated (x,y) points array and
the count of points. Each point will be examined to determine the number of points that lie within the
inscribed circle. The Pythagorean theorem allows us to determine the distance of the point from the
origin (0.0,0.0). Thus, for each point, we will calculate the ( x 2+ y 2) and if the distance is less than
the circle radius of 1.0, it will be counted as inside the circle.
Then, the estimated value of can be calculated based on the formula:
est = 4
inside circle
( samples
)
total samples
When completed, the program will display the final results. The basic algorithm is as follows:
!declarevariables
!displayinitialheader
!promptforandobtaincountvalue
!
loop
!
promptforcountvalue
!
readcountvalue
!
ifcountiscorrect, exit loop
!
displayerrormessage
!
endloop
!allocatetwodimensionarray
!generatepoints
!
loopcounttimes
!
generatexandyvalues
!
place(x,y)valuesinarrayatappropriateindex
!
endloop
!setcountofsamplesinsidecircle=0
!
loopcounttimes
!
if[sqrt(x(i)**2+y(i)**2)<1.0]
!
incrementcountofsamplesinsidecircle
!
endloop
!displayresults
14.3.3
&
!readcountvalue
read(*,*)count
! if count is correct, exit loop
if(count>=100andcount<=1000000)exit
!displayerrormessage
write(*,'(a,a,/a)')"Error,countmustbe",
"between100and1,000,000.",
"Pleasereenter."
enddo
!allocatetwodimensionarray
allocate(points(count,2),stat=alstat)
if(alstat<>0)then
write(*,'(a,/a)')"Error,unabletoallocate"
"memory.","Programterminated."
stop
endif
!generate_points
callrandom_seed()
!loopcounttimes
doi=1,cnt
!generatexandyvalues
callrandom_number(x)
116
&
&
&
The spacing and indentation is not required, but helps to make the program more easily readable.
14.3.4
For this problem, the testing would involve executing the program using a series of different count
values and ensure that the estimate is reasonable and improves with higher count values.
117
14.4
Exercises
Below are some quiz questions and project suggestions based on this chapter.
14.4.1
Quiz Questions
(row, column)
(column, row)
(row, row)
(column, column)
user-selectable
a)
b)
c)
d)
e)
14.4.2
Suggested Projects
118
After placing an integer, k, move up one row and one column to the right to place the
next integer, k+1, unless the following occurs:
If a move takes you above the top row in the jth column, move to the bottom of the jth
column and place the integer there.
If a move takes you outside to the right of the square in the ith row, place the integer
in the ith row at the left side.
If a move takes you to an already filled square or if you move out of the square at
the upper right hand corner, place k+1 immediately below k.
Test the program and compare the results to the Wikipedia example.
119
120
15
Subprograms
Until now, all of the programs have essentially been single, fairly small programs. However, as we
scale up into larger programs, this methodology will become more difficult. When developing larger
programs, it becomes necessary to break the larger program up into multiple, smaller more manageable
pieces. Then, during program development, it is possible to focus on each subsection or piece
individually and then combine the results into a final complete program. And, for very large projects,
multiple people may work on different parts of the program simultaneously.
Some of the key advantages of developing a program using functions and/or subroutines include:
Reuse of subprograms
Isolation of subprograms
Fortran subprograms are the mechanism to break a large program into multiple smaller parts. This
allows for a more comprehensive program design.
15.1
Subprogram Types
There are two types of Fortran subprograms: functions, and subroutines, each of which is explained in
the following sections.
15.2
Program Layout
The functions and subroutines can be defined as either internal or external. Internal functions and
subroutines are defined within the program statement (i.e., before the end program <name>
statement). The basic layout for both internal and external subprograms is as follows:
program<name>
<declarations>
<programstatements>
contains
<internalfunctionsorsubroutines>
endprogram<name>
<externalfunctionsorsubroutines>
Chapter 15 Subprograms
15.2.1
Internal Routines
Internal routines require the keyword contains to separate them from the program code. Primarily,
internal routines will be used in this text for simplicity. There is no limit to the number of internal
routines. However, if too many routines are included the file will become large and such large files can
be difficult to work with.
15.2.2
External Routines
External functions are defined outside the program statement (i.e., after the end program <name>
statement) or in another file. For larger programs external routines would be used extensively.
However, additional set-up statements, including an external declaration and an interface block, are
required. The definition and use of external routines is not addressed in this chapter.
15.3
Arguments
When writing and using Fortran subprograms, it is typically necessary to provide information to and/or
obtain results from the functions or subroutines. This information, in the form of variables, is referred
to as an argument or arguments. The argument or arguments in the calling routine are referred to as
actual arguments and the argument or arguments in the function or subroutine are referred to as formal
arguments. The formal arguments take on the values that are passed from the calling routine.
The only way to transfer values in to or out of a subroutine is through the arguments. A function
typically passes values in through the arguments with a single return value (via the function name). All
other variables are independent and isolated.
15.3.1
Argument Intent
Subprograms often return values by altering or updating the some of the arguments. When passing a
variable, the information (value or values) can be passed into the function or subroutine. This is
referred to as intent(in). If the variable is to be set by the function or subroutine, that is referred to as
intent(out). If the variable contains a value or multiple values (i.e., an array) that are to be passed
into the function or subroutine and altered in some way by the function or subroutine and returned back
to the calling routine, that is referred to as intent(inout).
15.4
Variable Scope
The variable scope refers to where a given variable can be accessed. Scope rules tell us if an entity
(i.e., variable, parameter, and/or function) is visible or accessible at certain places. Places where an
entity can be accessed or visible is referred as the scope of that entity. The variables defined in a
subprogram are generally not visible to the calling routine. Thus a variable x in the calling routine is
different than a variable x in the subprogram.
15.5
Before a function or subroutine can be used, it must be defined or written. Once defined, the function
or subroutine can be used or called. A function or subroutine is called by using its name as we have
done with the intrinsic functions. When a program uses a subroutine it is called with a call statement.
122
Chapter 15 Subprograms
When a program uses a function, it used used by name and returns a result which must be assigned
somewhere appropriate (e.g., like a variable).
15.5.1
Argument Passing
When using functions or subroutines, information (values, variables, etc.) is typically passed to or from
the routines. Argument association is a way of passing values from actual arguments to formal
arguments. If an actual argument is an expression, it is evaluated and passed to the corresponding
formal argument. If an actual argument is a variable or constant, its value is passed to the
corresponding formal argument. There must be a one-to-one correspondence between the actual
argument (calling routine) and the formal argument (function/subroutine).
The arguments in the call are matched up to the arguments in the function/subroutine by position. Each
of the arguments is matched by its corresponding position. The names of the variables do not need to
match, however the data types must match. For example, given the following subroutine call and
subroutine,
Calling Routine
...
callexample(x,y,z)
...
Subroutine
...
subroutineexample(a,b,c)
...
15.6
Functions
A function is a special type of Fortran subprogram that is expected to return a single result or answer.
A function will typically accept some kind of input information and based on that information, return a
result. The two types of Fortran functions are described in the following sections.
123
Chapter 15 Subprograms
15.6.1
Intrinsic Functions
As described previously, an intrinsic function is a built-in function that is already available. Some of
the intrinsic functions already described include sin(), cos(), tan(), real(), int(), and nint(). A more
comprehensive list is contained in Appendix D.
15.6.2
User-Defined Functions
A user-defined function are functions that a written by the user for specific or specialized requirement.
The general form of a user-defined function is a follows:
<type>function<name>(<arguments>)
<declarations>
<bodyoffunction>
<name>=expression
return
endfunction<name>
The <type> is one of the Fortran data types; real, integer, logical, character, or complex. It is possible
to place the type declaration on a separate line from the function statement.
The information, in the form of arguments, is passed from the calling routine to the function. Each of
the passed arguments must be declared and the declaration must include the type and the intent. The
arguments in the calling routine and the function must match and are matched up by position.
An example function to convert a Fahrenheit temperature to Celsius temperature would be as follows:
realfunctionfahr_to_celsius(ftemp)
real,intent(in)::ftemp
fahr_to_celsius=(ftemp32.0)/1.8
return
endfunctionfahr_to_celsius
Which, given a Fahrenheit temperature, will return the Celsius temperature. The single input argument,
ftemp, is declared to be a real value and intent(in), which means that the value is expected to be
coming into the function and can not be changed. The final value is returned to the calling routine by
assigning a value to the function name, fahr_to_celsius, in this example.
15.6.2.1
Side Effects
A side-effect is when a function changes one or more of its input arguments. Since the arguments can
be declared as intent(out) or intent(inout), the function could change the arguments. In general,
this is consider poor practice and should be avoided. None of the examples in this text will include or
utilize side-effects.
124
Chapter 15 Subprograms
15.7
Subroutines
A subroutine is a Fortran subprogram that can accept some kind of input information and based on that
information, return a result or series of results.
The general form of a subroutine is a follows:
subroutine<name>(<arguments>)
<declarations>
<bodyofsubroutine>
return
endsubroutine<name>
The information, in the form of arguments, is passed from the calling routine to the subroutine. Each
of the passed arguments must be declared and the declaration must include the type and the intent. The
arguments in the calling routine and the subroutine must match and are matched up by position.
For example, given the following simple program to find the sum and average of three numbers.
programsubExample
implicitnone
real::x1=4.0,y1=5.0,z1=6.0,sum1,ave1
real::x2=4.0,y2=5.0,z2=6.0,sum2,ave2
callsumAve(x1,y1,z1,sum1,ave1)
write(*,'(a,f5.1,3x,a,f5.1)')"Sum=",sum1,
"Average=",ave1
callsumAve(x2,y2,z2,sum2,ave2)
write(*,'(a,f5.1,3x,a,f5.1)')"Sum=",sum2,
"Average=",ave2
contains
&
&
subroutinesumAve(a,b,c,sm,av)
real,intent(in)::a,b,c
real,intent(out)::sm,av
sm=a+b+c
av=sm/3.0
return
endsubroutinesumAve
endprogramsubExample
The arguments in the first call (x1, y1, z1, sum1, and ave1) are matched up to the arguments in the
subroutine (a, b, c, sm, and av) by position. That is, the x1 from the call is matched with the a in the
subroutine. The arguments in the second call (x2, y2, z2, sum2, and ave2) are again matched up to the
125
Chapter 15 Subprograms
arguments in the subroutine (a, b, c, sm, and av) by position. While the names of the variables do not
need to match, the data types must match. Variables declared in a function or subroutine are not the
same as variables in the calling routine. This is true, even if they are the same name!
15.8
Example
In this example we will write a Fortran program to simulate the dice game of Twenty-Six11 which is
single player betting game with 10 dice. The main program will determine how many games to play,
track the count of games won and lost, and display some win/loss statistics. A subroutine will be used
to play the Twenty-Six game. The subroutine will be called as many times as requested.
The subroutine, twenty_six(), will play the game dice game Twenty-Six. To play the game, the player
rolls the dice (1 to 6) and this initial roll is used as the point number. Then the player throws the ten
dice 13 times. The score is the number of times that the point number is thrown. A random number
between 1 and 6 will be used for each dice roll.
The routine will determine the payout based on the point count using the following table:
Point Count
Payout
10 or less
10
13
26
27
28
29
30
10
Other
The subroutine should display the dice (all 10 dice for each of 13 rolls), point count, game result,
payout. For example, if the point was 6, the subroutine might display the following:
Point:6
Roll:1Dice:4653311332
Roll:2Dice:1633414426
Roll:3Dice:3264532154
Roll:4Dice:5641466244
Roll:5Dice:4664536155
Roll:6Dice:3145653334
Roll:7Dice:6656155655
Roll:8Dice:4134144625
Roll:9Dice:4421143154
Roll:10Dice:5612411211
Roll:11Dice:2324133651
Roll:12Dice:1165451665
Roll:13Dice:6445335335
11 For more information, see: http://www.dice-play.com/Games/TwentySix.htm
126
Chapter 15 Subprograms
PointCount:22
GameResult:LOSSPayout=0
For this example, the main will track the games won and lost.
15.8.1
The program will display an initial header and get the number of games to play. Specifically, we will
need to prompt for the count of games and verify that the count is between 2 and 1,000,000 (arbitrarily
chosen). Then, the program will call the twenty_six() subroutine count times. After each game, the
main will update the count of games won. The main will also track the payout and bank value status,
which is initialized to 100 (chosen arbitrarily) and updated after each game is played.
An example main is provided as follows:
programdiceGame
!
!FortranprogramtosimulateadicegameofTwentySix
!
Themainprogram:
!
displaysappropriateheaders
!
obtainsandchecksnumberofgamestoplay
!
loopstoplay'count'numberofgamestimes
implicitnone
integer,parameter::initial_bank=100
integer::num_games,games_won=0,games_lost=0
integer::i,payout,bank
integer,dimension(13,10)::dice
real::win_pct
write(*,'(/a/a/)')
&
"",
&
"DiceGame""TwentySix""Simulator."
do
write(*,'(2x,a)',advance="no")
&
"Enternumbergamestosimulate:"
read(*,*)num_games
if(num_games>=1.and.num_games<=1000000)exit
write(*,'(2x,a)')"Error,numberof",
&
"gamesmustbebetween1and1000000."
write(*,'(2x,a)')"Pleasereenter."
enddo
bank=initial_bank
callrandom_seed()
doi=1,num_games
bank=bank1
127
Chapter 15 Subprograms
calltwentySix(payout)
if(payout>0)then
games_won=games_won+1
else
games_lost=games_lost+1
endif
bank=bank+payout
enddo
win_pct=(real(games_won)/real(num_games))*100.00
write(*,'(/a,/a/,3(2x,a,i9/),2(2x,a,i8/),2x,a,f4.1,a)')&
""&
"GamesStatistics:",
&
"GameCount:",num_games,
&
"GamesWon:",games_won,
&
"GamesLost:",games_lost,
&
"InitialBank:",initial_bank,
&
"FinalBank:",bank,
&
"WinPercentage:",win_pct,"%"
contains
!*********************************************************
!
subroutine(s)goeshere...
!*********************************************************
endprogramdiceGame
Refer to Appendix C for additional information regarding the random number generation and
initialization of the built-in random number generator.
15.8.2
Since the main is provided, the algorithm will focus on the twenty-six game. Since the built-in random
number generator provides random numbers between 0.0 and 1.0, they will need to be scaled and
converted to an integer between 1 and 6 (for a dice). The initial point value must first be established
followed by a loop to throw the ten dice 13 times in accordance with the game rules. The results will
be stored in a two-dimensional array. While not strictly required, it does provide an additional example
of how to use a two-dimensional array. Finally, the payout will be determined based on the game rules.
!Randomlyselectanumberfrom1to6asthe"point"number
!Throwtendice13times
!
resultsgointodice(13,10)array
!Scoreisthenumberoftimesthatthepointnumber
!
isthrown
!determinepayout
128
Chapter 15 Subprograms
For convenience, the steps are written a program comments.
15.8.3
determinepoint
callrandom_number(x)
point=int(x*6.0)+1
rolldice
pnt_cnt=0
doi=1,13
doj=1,10
callrandom_number(x)
dice(i,j)=int(x*6.0)+1
if(dice(i,j)==point)pnt_cnt=pnt_cnt+1
enddo
enddo
!determinepayout
selectcase(pnt_cnt)
case(6,10)
payout=10
case(13,27)
payout=5
case(26)
payout=4
case(28)
payout=6
case(29)
129
Chapter 15 Subprograms
payout=8
case(30)
payout=10
casedefault
payout=0
endselect
write(*,'(/,5x,a,/,5x,a,i2,/,5x,a,i2)')
"",
"Point:",point
doi=1,13
write(*,'(8x,a,i2,2x,a,10(2x,i1),/)',
advance="no")"Roll:",i,"Dice:",
(dice(i,j),j=1,10)
enddo
&
&
&
&
write(*,'(/,5x,a,i2)')"PointCount:",pnt_cnt
if(payout>0)then
write(*,'(5x,a,i2)')
"GameResult:WINPayout=",payout
else
write(*,'(5x,a,i2)')
"GameResult:LOSSPayout=",payout
endif
&
&
write(*,'(5x,a,i6)')"Bank:",bank
return
endsubroutinetwentySix
The spacing and indentation is not required, but helps to make the program more easily readable.
15.8.4
For this problem, the testing would involve executing the program using a file with a set of numbers
where the correct results are either known ahead of time or can be calculated by hand in order to verify
that the results are accurate.
15.9
Exercises
Below are some quiz questions and project suggestions based on this chapter.
15.9.1
Quiz Questions
Chapter 15 Subprograms
131
Chapter 15 Subprograms
15.9.2
Suggested Projects
g =
xn
= 1+ x+ x 2 + x3 + + x( n1 )
n= 0
The arguments for the call, in order, are as follows; n (integer value). The function should
return an integer result (of the formula based on the n value). The main should call the function
with several different values.
3) Write a main program and a real function, harmonicMean(), to compute the harmonic mean of
a series of real numbers. The real numbers are pass to the function in an array along with the
count.
harmonic mean =
1 1
1
+ + ...+
x1 x 2
xN
The arguments for the call, in order, are as follows; array of numbers (with count real values),
count (integer). The function should return an real result (of the formula). The main should call
the function with several different values.
132
Chapter 15 Subprograms
4) Write a main program and a subroutine, CircleStats(), that, given an array containing a series of
circle diameter's (real values), will compute the area of each circle in a series of circles and
store them into a different array (real values). The subroutine should also compute the real
average of the circle areas. The arguments for the call, in order, are as follows; circle diameter's
array (count real values), circle areas array (count real values), count (integer), areas average
(real). The main program should declare the array and initialize the array with a series of values
for circle areas. The program results should be verified with a calculator.
5) Write a main program and a subroutine, ReadCoord(), to read an (x, y, z) coordinate from the
user. The subroutine must prompt for and read (x, y, z) and ensure that the x, y, and z values are
between 0 and 100 (inclusive). The values may be prompted for and read together, but prompt
should leave the cursor on the same line. The subroutine should re-prompt for all three if the
input data is not correct. If the user provides valid data, the (x, y, z) values should be returned
with a logical for valid data set to true. If the user does not provide valid data entry after three
tries, the subroutine should display an error message and a set the logical for valid data to false.
The arguments for the call, in order, are as follows; x value (integer), y value (integer), z value
(integer), and valid data flag (logical value). The main program should call the subroutine three
times and display the results for each call.
6) Write a main program and a subroutine, Stats(), that, given an array containing a series of
numbers (real values), will find and display the following real values; minimum, median,
maximum, sum, and average. The display must use a formatted write(). The real values will
not exceed 100.0 and should display three digits decimal values (i.e., nnn.xxx). The arguments
for the call, in order, are as follows; array of numbers (count real values), count (integer). The
main program should populate the array with random numbers and call the subroutine.
133
Chapter 15 Subprograms
134
16
A derived data type is a user-defined combination of the intrinsic data types. The derived data types
are a convenient way to combine or group variables about a particular item.
For example, a 'student' might include a name, identification number, final score, and grade. Each of
these pieces of information can be represented with individual variables (as outlined in previous
section) as follows:
character(50)::name
integer::id
real::score
character(2)::grade
However, for multiple students, multiple sets of variables would be required. This can become
cumbersome and confusing.
By using a derived data type, these separate pieces of information can be more easily grouped together.
The details on defining, declaring and using derived data types are provided in the following sections.
16.1
Definition
Before a derived data type can be used, it must be defined. The definition will establish which pieces
of information will be grouped together. Each piece of information included in the definition is
referred to as a component.
typetype_name
<componentdefinitions>
endtypetype_name
For example, to declare the student type described previously, the following declaration would be
appropriate:
typestudent
character(50)::name
integer::id
real::score
character(2)::grade
endtypestudent
The indentation is not required, but does make the definition easier to read. The fields (name, id, score,
grade) are called components. These components together make up the information for a 'student'.
The type definition is required only once at the beginning of the program. Once defined, the type
definition can not be changed. More specifically, additional components can not be added unless the
definition is updated and program is recompiled.
135
name
id
score
grade
Once defined, the template can be used to declare variables. Each variable declared with this definition
will be created based on the definition which includes these four components.
16.2
Declaration
Once a derived data type is defined, variables using that definition can be declared. The general format
for a declaration is as follows:
type(<type_name>)::<variable_name(s)>
For example, to declare two students, the following declaration could be used:
type(student)::student1,student2
This declaration will declare two variables, student1 and student2, each with the set of components
defined in the type definition. The definition can be thought of as the cookie cutter and the declaration
is the cookie. Only after a variable has been declared, can values be set for that variable.
16.3
Accessing Components
Once some variables using the derived data type have been declared, the individual components can be
accessed. First the variable name is specified, followed by a % (percent sign), and then the
component name. The general format is:
<variable_name>%<component_name>
For example, to set all components for the student student1, the following
student1%name="Joseph"
student1%id=1234
student1%score=99.99
student1%grade="A"
Each component for student1 is set individually. Not every component must be set. Of course, as with
other variables, any component that has not been set can not be used.
136
name
Joseph
id
1234
score
99.99
grade
It is possible to assign all components to another variable of the same derived data type. For example,
to set student2 to be the same as student1, an assignment is used as follows:
student2=student1
This will copy all components from the variable student1 into the variable student2 (since both
student1 and student2 are of the same derived data type).
16.4
Example One
In this example, we will write a simple program to read two times from the user, time one and time
two, and calculate the sum of the two times. For this example, the time will consist of hour, minutes,
seconds in 24-hour format. For this exercise, the hours may exceed 23 when the times are summed.
The program should declare the appropriate variables using a derived data type, use a subroutine to
read a time (which should be called twice), and another subroutine to calculate the sum of the times.
The subroutine to read the times must perform appropriate error checking. The main should display
both the times and the final time sum.
16.4.1
The main is expected to define the appropriate derived data type for time, declare some variables of
that type and call the subroutines. The first subroutine will read a time from the user which will consist
of hour, minutes, and seconds in 24-hour format. This subroutine will be called twice. The second
subroutine will add the times together and provide a result.
The first subroutine to read a time from the user is expected to perform error checking on the data
entered by the user. Specifically, this requires that hours range from 0 to 23, minutes range from 0 to
59, and seconds range from 0 to 59. Values outside these ranges, 60 seconds for example, are not valid.
For this simple example, we will re-prompt for incorrect data entry (until correct data is provided).
The second subroutine will add the two times and must ensure that the correct ranges for seconds and
minutes are maintained. When adding the two times, it is possible to add the seconds, minutes, and
hours. However, if the sum of the two seconds values exceeds 60, the seconds must be adjusted and
the minutes must be updated accordingly (add one extra minute). This applies to the minutes as well.
However, when added in this exercise, the final time sum hours may exceed 23 hours.
For example, given time one as 14 hours, 47 minutes and 22 seconds (i.e., 14:47:22) and time two as 18
hours, 22 minutes, and 50 seconds, (i.e., 18:22:50), the total time would be 33 hours, 10 minutes and 12
seconds (i.e., 33:10:12).
137
16.4.2
For this example there are three parts; the main, the read time subroutine, and the time summation
subroutine. The basic steps for the main include:
!definederiveddatatypefortime
!
mustincludehours,minutes,seconds
!declarevariables,includingtime1,time2,andtimesum
!displayinitialheader
!callsubroutinetoreadtime1
!callsubroutinetoreadtime2
!callsubroutinetoaddtimes
!displayresults
16.4.3
138
do
promptfortime
write(*,'(a)',advance="no")
"Entertime(hhmmss):"
readtime(hours,minutes,seconds)
read(*,*)timeval%hours,timeval%minutes,
timeval%seconds
checktimeentered
if(timeval%hours>=0.and.
timeval%hours<=23.and.
timeval%minutes>=0.and.
139
&
&
&
&
&
displayerrormessage
write(*,'(a,/,a)')
"Error,invalidtimeentered.",
"Pleasereentertime."
&
&
&
&
enddo
return
endsubroutinereadtime
!*******************************************************
!Subroutinetoaddtwotimes.
!
Ensuressecondsandminutesarewithinrange(059)
!
Hoursmayexceed23
!subroutineheaderandappropriatedeclarations
subroutineaddtimes(tm1,tm2,tmsum)
type(time),intent(in)::tm1,tm2
type(time),intent(out)::tmsum
!addtheseconds,minutes,hours
tmsum%seconds=tm1%seconds+tm2%seconds
tmsum%minutes=tm1%minutes+tm2%minutes
tmsum%hours=tm1%hours+tm2%hours
!ifseconds>59,subtract60fromsecondsandadd1tominutes
if(tmsum%seconds>59)then
tmsum%seconds=tmsum%seconds60
tmsum%minutes=tmsum%minutes+1
endif
!ifminutes>59,subtract60fromminutesandadd1tohours
if(tmsum%minutes>59)then
tmsum%minutes=tmsum%minutes60
tmsum%hours=tmsum%hours+1
endif
return
endsubroutineaddtimes
endprogramtimeSummation
If the program does not work at first, the comments can aid in determining the problem.
140
16.4.4
For this problem, the testing would involve executing the and entering a series of various time values to
ensure that the results are correct. If the program does not work initially, the functionality of each
subroutine should be checked. The times read from the user can be displayed to the screen to ensure
they are correct. Once the times are correct, the add times subroutine can be checked. Each of the time
sums can be displayed to help determine where the error might be.
16.5
In addition to declaring single variables based on the derived data type definition, it is possible to
declare an array based the derived data type definition. For example, to declare an array named class to
hold 30 elements of type student, the following declaration can used used.
type(student),dimension(30)::class
Each element of the array class will be of the type student and include each of the defined components
(name, id, score, grade in this example). For an array of type(student), the layout would be as follows:
class(1)
name
id
score
grade
class(2)
name
id
score
grade
class(3)
name
id
score
grade
...
...
To access elements in the array, an index must be used. After the index, the desired component would
be specified. For example, to set values for the third student, the following statements could be used.
class(3)%name="Fred"
class(3)%id=4321
class(3)%score=75.75
class(3)%grade="C"
141
This code fragment will copy all components from the fifth array element (of type type student) into a
temporary variable (also of type student). Then, the eleventh array element can be copied into the fifth
array element (thus overwriting all previous values). And, finally, the eleventh array element can be set
of the original values from the fifth array element which are held in the temporary variable.
16.6
Example Two
In this example, we will write a simple program to perform some processing for students. The student
information will be stored in an array of derived data types. There will be no more than 50 students per
class. The main will call a subroutine to read student information (name and score) and another
subroutine to set the student grades. Finally, the main will call a function to calculate the class average.
The main will display the average. Routines for displaying the students are left as an exercise.
16.6.1
The main is expected to define the appropriate derived data type for student, declare some variables of
that type and call the subroutines. The first subroutine will read student information including a name
(up to 60 characters) and score from the user. Names and scores should continue to be read until a
blank name is entered. The score value must be between 0.0 and 100.0 (inclusive). For this simple
example, we will re-prompt for incorrect data entry (until correct data is provided). The routine must
return the count of students entered. The second subroutine set the grades based on the following
standard scale.
A
A>=90
80 - 89
70 - 79
60 - 69
<=59
When determining the final grade, the program should round up when appropriate. The main will call
a function to calculate and return the average of the scores. Additionally, the main will display the final
average.
142
16.6.2
For this example main part for the main include declaration, display header, call read time subroutine,
and the call the time summation subroutine. The basic steps for the main include:
!definederiveddatatypeforstudent
!
mustincludename,id,grade
!declarevariables
!
includesarrayforupto50students
!displayinitialheader
!callsubroutinetoreadstudentinformation
!callsubroutinetosetgrades
!usefunctiontocalculateaverageofscores
!displayaverage
The basic steps for the read student information subroutine include:
!subroutineheaderandappropriatedeclarations
!loop
!
promptforstudentname
!
readname
!
ifnameisempty,exitloop
!
loop
!
promptforstudentscore
!
readscore
!
checkscoreentered
!
if[scoreisbetween0.0and100.0,inclusive]exit
!
displayerrormessage
!
endloop
!
updatecountofstudents
!
placevaluesinstudentarray
!endloop
When determining the final grade, the nearest integer intrinsic function, nint(), can be used to perform
the appropriate rounding.
The basic steps for the calculate average score function include:
!functionheaderandappropriatedeclarations
!loop
!
sumscores
!endloop
!calculateandreturnaverage
143
16.6.3
144
do
promptforstudentnameandreadname
write(*,'(a)',advance="no")"EnterStudentName:"
read(*,'(a60)')tempname
ifnameisempty,exitloop
if(len_trim(tempname)==0)exit
do
promptforstudentscoreandreadscore
write(*,'(a)',advance="no")
"EnterStudentScore:"
read(*,*)tempscore
&
checkscoreentered
if(tempscore>=0.0.and.
tempscore<=100.0)exit
&
displayerrormessage
write(*,'(a,/,a)')
"Error,invalidscore.",
"Pleasereentertime."
&
&
enddo
!
updatecountofstudentsandplaceinstudentarray
count=count+1
class(count)%name=tempname
class(count)%score=tempscore
enddo
return
endsubroutinereadStudents
!*******************************************************
!Subroutinetosetstudentgrades.
!
90A;8089B;7079C;6069D;59F
subroutinesetStudentGrades(class,count)
type(student),dimension(50),intent(inout)::class
integer,intent(in)::count
integer::i
!
checkeachscore/seteachgrade
doi=1,count
selectcase(nint(class(i)%score))
case(90:)
145
sumscores
doi=1,count
sum=sum+class(i)%score
enddo
!calculateandreturnaverage
classaverage=sum/real(count)
return
endfunctionclassAverage
endprogramclassScores
If the program does not work at first, the comments can aid in determining the problem.
16.6.4
For this problem, the testing would involve executing the program and entering a series of student data
values to ensure that the results are correct. If the program does not provide the correct results, each of
the subroutines and the function results should be verified individually. Each can be checked by
displaying the intermediate results to the screen. In this manner, the subroutine or function that is not
working correctly can be quickly identified. Once identified, some additional write statements inside
the subprogram can be used to help identify the specific problem. The testing and debugging process is
left to the reader as an exercise.
146
16.7
Exercises
Below are some quiz questions and project suggestions based on this chapter.
16.7.1
Quiz Questions
16.7.2
Suggested Projects
Subroutine readPlanets() to prompt for file name of planets file, open the file (including
error checking), and read file into an array. Three errors are allowed, but if a fourth
error is made, the routine should terminate the program.
147
Option (3) Planets with Shortest and Longest Days (based on day length)
Subroutine printPlanetsSummary() to display the planet name, distance from sun, and
planet size.
The output should be formatted as appropriate. Test on several sets of input values and verify
that the output is correct for the given input values.
3) Modify the planet program (from previous question) to sort the planets based on the radius. Test
on several sets of input values and verify that the output is correct for the given input values.
4) Type in the time class scores program, compile and execute the program. Test on several sets of
input values.
5) Modify the class scores program to assign grades based on the following scale:
F
C-
C+
B-
B+
A-
0-59
60-70
70-72
73-76
77-79
80-82
83-86
87-89
90-92
A+
93-96 97-100
Test on several sets of input values and verify that the output is correct for the given input.
6) Modify the class scores program to read the name and score file a file. Should include
prompting for a file, opening the file, and reading the file contents into the class array. In order
to complete this exercise, create a file containing some random names and scores. Test on
several sets of input values.
148
17
Modules
For larger programs, using a single source file for the entire program becomes more difficult.
Fortunately, large programs can be split into multiple source files, each file can contain a subset of
subroutines and/or functions. There must be a main or primary source file that includes the main
program. The secondary file or files is referred to as a module or modules. Additionally, the modules
can then be more easily used in other, different programs ensuring that the code can be easily re-used.
This saves time and money by not re-writing routines. This section provided a description of the
formatting requirements and an example of how to set-up the modules.
17.1
Module Declaration
The secondary source file or module must be formatted in a specific manner as follows:
module<name>
<declarations>
contains
<subroutineand/orfunctiondefinitions>
endmodule<name>
For example, to declare a module named stats that includes some a function to find the average of the
numbers in an array, the following module declaration might be used.
modulestats
!note,noglobalvariablesusedinthismodule
contains
!*************************************************************
!Simplefunctiontofindaverageoflenvaluesinanarray.
realfunctionaverage(array,len)
real,intent(in),dimension(1000)::array
integer,intent(in)::len
integer::i
real::sum=0.0
doi=1,len
sum=sum+array(i)
enddo
average=sum/real(len)
endfunctionaverage
endmodulestats
149
Chapter 17 Modules
This example assumes the real array contains len number of values up to a maximum of 1000 values.
17.2
Use Statement
Once the module is defined, the routines from the module can be included by using the use statement.
The use statement or statements must be at the beginning of the applicable source file. For example,
below is a simple main that uses the previous stats module.
programaverage
usestats
implicitnone
real,dimension(1000)::arr
integer::i,count
real::ave
!
!Initializearraywithsomevalues.
count=0
doi=1,20
arr(i)=real(i)+10.0
count=count+1
enddo
!
!Callfunctiontofindaverageanddisplayresult.
ave=arraverage(arr,count)
write(*,'(/,a,f10.2,/)')"Average=",ave
endprogramaverage
The use statement is included before the variable declarations. Any number of use statements for
defined modules may be included.
17.3
For a large program that is split between multiple source files, the compilation process must be
updated. The compilation process refers to the steps required to compile the program into a final
executable file. Each module unit must be compiled independently. This allows the programmer to
focus on one module, set of routines, at a time. Further, for very large projects, multiple programmers
can work on separate modules simultaneously.
150
Chapter 17 Modules
The initial step is to compile each module. Assuming the module from the earlier section is named
stats.f95, the command to compile a module is:
gfortrancstats.f95
which will read the source file (stats.f95) and create two new files; an object file stats.o and a
module file stats.mod. The name of the object file is based on the name of the source file. The
name of the module file is based on the module name. While they are the same name in this example,
that is not a requirement.
The compile command is required for each module.
Once all the modules are compiled and the .o and .mod files are available, the main file can be
compiled. This step reads the .o and .mod files for each module and builds the final executable file.
For example, the command to compile the main file for the previous array average example is:
gfortranomainmain.f95stats.o
For multiple modules, each of the .o files would be listed. In this example, the stats.mod file is read
by the gfortran compiler. While not explicitly listed, the .mod files are required and used at this
step.
17.4
The following is an example program to compute the surface area and volume of a sphere. This is a
fairly straightforward problem focusing more on the creation and use of a module for some routines.
17.4.1
This problem will be divided into two parts, the main program source file and a secondary source file
containing the subroutines and functions. While this problem is not large enough to require splitting
into multiple files, it is split to provide an example of how to use modules.
The formulas for the surface area and volume of a sphere are as follows:
surfaceArea = 4.0 radius2
volume =
4.0
radius 3
3.0
151
Chapter 17 Modules
17.4.2
Based on the problem definition, the steps for the main are:
!displayheaderandreadradius
!callfunctionsforspherevolumeandsurfacearea
!callroutinetodisplayformattedresults
The module will contain the functions and subroutine. The first function will compute the sphere
volume. The single step is:
!computethevolumeofaspherewithgivenradius.
!
spherevolume=[(4.0*pi)/3.0]*radius^3
The second function will compute the sphere surface area. The single step is:
!computethevolumeofaspherewithgivenradius
!
spherevolume=4.0*pi*radius^2
17.4.3
The program is presented in two parts corresponding to the main program and the secondary module
routines. While this example is not really long or complex enough to require multiple files, the
program is split in order to provide an example using a separate module file.
17.4.3.1
Main Program
152
Chapter 17 Modules
spSurfaceArea=sphereSurfaceArea(radius)
!
!Callroutinetodisplayformattedresults.
calldisplayResults(radius,spVolume,spSurfaceArea)
endprogramsphere
The name of module, sphereRoutines in this example, must be the name of the secondary source
file.
17.4.3.2
Module Routines
Based on the algorithms for the two functions and subroutine, the below module program could be
developed. In this example, the declaration for is defined as a global variable. This shares the
variable between all the subroutines and functions in the module. Use of global variables is typically
limited. This provided an example of an appropriate use of a global variable.
!Examplesecondarysourcefile.
modulesphereRoutines
implicitnone
!neededineverymodule
!Globaldeclarations,ifany,gohere.
real,parameter::pi=3.14159
!********************************************************
!Subroutinesandfunctionsareincludedafter
!the'contains'.
contains
!********************************************************
!Computethevolumeofaspherewithgivenradius.
!
spherevolume=[(4.0*pi)/3.0]*radius^3
realfunctionsphereVolume(radius)
real,intent(in)::radius
sphereVolume=((4.0*pi)/3.0)*radius**3
return
endfunctionsphereVolume
!********************************************************
!Computethevolumeofaspherewithgivenradius.
!
spherevolume=4.0*pi*radius^2
153
Chapter 17 Modules
realfunctionsphereSurfaceArea(radius)
real,intent(in)::radius
sphereSurfaceArea=4.0*pi*radius**2
return
endfunctionsphereSurfaceArea
!********************************************************
!Simpleroutinetodisplayresults.
subroutinedisplayResults(rad,vol,area)
real,intent(in)::rad,vol,area
write(*,'(/,a)')""
write(*,'(a)')"Results:"
write(*,'(3x,a,f10.2)')"SphereRadius=",rad
write(*,'(3x,a,f10.2)')"SphereVolume=",vol
write(*,'(3x,a,f10.2,/)')
&
"SphereSurfaceArea=",area
return
endsubroutinedisplayResults
!********************************************************
endmodulesphereRoutines
In a more complex program multiple module files might be used. The grouping should be based on the
logical relationship of the routines. A more complicated program would require a more comprehensive
design effort.
17.4.4
The commands to compile the module file and then the main file are as follows:
gfortrancsphereroutines.f95
gfortranomodmainmodmain.f95sphereroutine.o
The first will create files sphereroutines.o and sphereroutines.mod. The second will read the
files modmain.f95 and sphereroutines.o then create the executable modmain.exe file.
17.4.5
For this problem, the testing would involve executing the and entering a series of radius values and
ensure that the results are correct. If the program does not provide the correct results, each of the
functions and the subroutines could be verified individually. Each can be checked by displaying the
154
Chapter 17 Modules
intermediate results to the screen. In this manner, the subroutine or function that is not working
correctly can be quickly identified. Once identified, some additional write statements inside the
subprogram can be used to help identify the specific problem.
17.5
Exercises
Below are some quiz questions and project suggestions based on this chapter.
17.5.1
Quiz Questions
17.5.2
Suggested Projects
155
Chapter 17 Modules
156
18
Recursion
The Google search result for recursion, shows Recursion, did you mean recursion?
Recursion is a powerful general-purpose programming technique and is used for some important
applications including search and sorting methods. Recursion is the idea that a function may call itself
(which is the basis for the joke).
Recursion can be very confusing in its simplicity and power. The examples in this section will not be
enough in themselves for the reader to obtain recursive enlightenment. The goal of this section is to
provide an introduction to the concept on recursion. The simple examples here, which are used
introduce recursion, are meant to help demonstrate the form and structure for recursion. More complex
examples (than will be discussed here) should be studied and implemented in order to ensure a
complete appreciation for the power of recursion.
The calling process previously described supports recursion without any changes.
A recursive routine must have a recursive definition that includes:
1. base case, or cases, that provide a simple result (that defines when the recursion should stop).
2. rule, or set of rules, that reduce toward the base case.
This recursive definition is referred to as a recursive relation.
18.1
Recursive Subroutines
A recursive subroutine declaration must be preceded by the keyword recursive. For example:
recursivesubroutine<name>(<arguments>)
<declarations>
<bodyofsubroutine>
return
endsubroutine<name>
Based on this declaration the subroutine can call itself. The routine must ensure that it eventually stops
calling itself. Arguments are passed in the standard way.
The calling routine does not need any special declarations in order to call a recursive routine.
157
Chapter 18 Recursion
18.2
This section provides an example recursive subroutine to accept a decimal number and print that
number in binary (i.e., using 1's and 0').
It is assumed the reader has a basic understanding of binary12 representation. This information is
summarized in the chapter on Computer Organization. Additionally, there are many references
available on the Internet.
18.2.1
For this example, the problem is divided into two parts, the main program and the recursive subroutine.
The main program will handle the prompting and reading of the decimal number including error
checking and re-prompting as needed. The recursive subroutine will display the binary value. Since
the error checking is already performed, the recursive subroutine will assume valid input. For more
complex examples, the routine may need to perform basic error checking.
18.2.2
One basic algorithm to convert a decimal number into a binary number, is successive integer division
by 2. For example, given the number 13, 13 divided by 2 is 6 with a remainder of 1. Next, the 6 is
divided by 2 giving 3 with a remainder of 0. Again, the 3 is divided by 2 providing a 1 with a
remainder of 1. The final 1 is divided by 2 resulting in a 0 with a remainder of 1. With a final result of
0, the algorithm is completed. The process is shown as follows:
13
= 6
2
remainder 1
6
= 3
2
remainder 0
3
= 1
2
remainder 1
1
= 0
2
remainder 1
The remainders, always 0 or 1, represent the binary value. However, the resulting remainders are
generated in backwards order. As such, the resulting remainders 1, 0, 1, and 1 in this example must be
reversed for a final value of 11012 (as noted in chapter 2).
This process can be converted into a recursive relation as follows:
printBinary (n) =
if n1
if n> 1
n
printBinary ( n/ 2)
output mod(num , 2)
158
Chapter 18 Recursion
This definition assumes that the value of n is positive. The recursive relation can be used by directly
converting the algorithm into code.
18.2.3
Based on the recursive definition, a simple recursive subroutine can be created. In order to demonstrate
the recursive subroutine, a main program is provided that will read a decimal value from user and
ensure it is between 0 and 1,000,000, and then call the recursive routine.
!Simplerecursiveprogramtoprintadecimalnumberinbinary
programbinary
implicitnone
integer::decimalNumber
write(*,'(a/)')"DecimaltoBinaryConversionExample"
do
write(*,'(a)',advance="no")
"EnterDecimalNumber(01,000,000):"
read(*,*)decimalNumber
if(decimalNumber>=0.and.
decimalNumber<=1000000)exit
&
&
write(*,'(a)')"Error,decimalvalueoutofrange."
write(*,'(a)')"Pleasereenter."
enddo
write(*,'(/a,i7,a)',advance="no")
&
"Thedecimalvalueof",decimalNumber,"is"
callprintBinary(decimalNumber)
write(*,'(/)')
contains
!************************************************************
!Printbinarysubroutine.
recursivesubroutineprintBinary(num)
integer,intent(in)::num
if(num>1)callprintBinary(num/2)
write(*,'(i1)',advance="no")mod(num,2)
return
endsubroutineprintBinary
159
Chapter 18 Recursion
!************************************************************
endprogrambinary
The spacing and indentation is not required, but helps to make the program more easily readable. The
main program ensures that the recursive routine is not called in invalid values (i.e., values 0).
18.2.4
For this problem, the testing would involve executing the program and entering a series of decimal
values and ensure that the results are correct. The Windows calculator provides simple convert-tobinary function that can be used for verification.
If the program does not provide the correct results, the input to the recursive subroutine should be
verified (via write statements). Next, some additional write statements in the recursive subroutine can
be added to provide insight into what is being done for each call.
18.3
Recursive Functions
A recursive function declaration must be preceded by the keyword recursive. In addition, the keyword
result must be explicitly added to the function declaration. The result keyword is used to specify a
single variable for the return value. Similar to a standard function, the result variable must be set to a
return value to the calling routine.
The function type specifies the type of the result variable. For example:
<type>recursivefunction<name>(<arg's>)result(<variable>)
<declarations>
<bodyoffunction>
<variable>=expression
return
endfunction<name>
18.4
This section provides an example recursive function to computer the mathematical factorial13 function.
It is assumed the reader is familiar with the factorial function.
160
Chapter 18 Recursion
18.4.1
n! =
k
k= 1
18.4.2
1
n factorial( n1)
if n=0
if n 1
18.4.3
Based on the recursive definition, a simple recursive function can be created. In order to demonstrate
the recursive function, a main program is provided that will read the decimal value from user and
ensure it is between 1 and 15, and then call the recursive routine.
The recursive function declaration uses an input argument, n, and a result argument, ans, in this
example. The input argument must be declared as intent(in) in the standard manner. However, the
result argument is an out by definition and will assume the type of the function itself, integer in this
example.
For the recursive factorial function, the basic algorithm is provided as part of the recursive definition.
The example main will read the n value from the user, call the factorial function, and display the
results.
!Simplerecursivefunctionexample.
programrecursionExample
implicitnone
161
Chapter 18 Recursion
integer::num,numFact
write(*,'(a/)')"RecursionExample"
do
write(*,'(a)',advance="no")"EnterN(115):"
read(*,*)num
if(num>=1.and.num<=15)exit
write(*,'(a)')"Error,Noutofrange."
write(*,'(a)')"Pleasereenter."
enddo
numFact=fact(num)
write(*,'(a,i2,a,i10,/)')"Factorialof",num,&
"is",numFact
contains
!*************************************************************
!Factorialfunction
integerrecursivefunctionfact(n)result(ans)
implicitnone
integer,intent(in)::n
if(n==1)then
ans=1
else
ans=n*fact(n1)
endif
return
endfunctionfact
!*************************************************************
endprogramrecursionExample
The spacing and indentation is not required, but helps to make the program more easily readable. The
main program ensures that the recursive routine is not called in invalid values (i.e., values 0).
18.4.4
For this problem, the testing would involve executing the program, entering a number, and ensuring
that the result is correct. The Windows calculator includes a factorial function which can be used to
verify the result.
If the program does not provide the correct result, the input to the recursive function should be verified
(via write statements). Next, some additional write statements in the recursive function can be added to
provide insight into what is being done for each call.
162
Chapter 18 Recursion
18.5
In order to better understand recursion, a recursion tree can help show how the recursive calls interact.
main:
f = fact(5)
Step 1
Step 10
fact:
5 * fact(4)
Step 2
Step 9
fact:
4 * fact(3)
Step 3
Step 8
fact:
3 * fact(2)
Step 4
Step 7
fact:
2 * fact(1)
Step 5
Step 6
fact:
return 1
When the initial call to factorial function occurs from main, the main will start into the fact() function
(shown as step 1). Since the argument of 5 is not a base case, the fact() function must call fact() again
with the argument of n-1 or 4 in this example (step 2). And, again, since 4 is not the base case, the
fact() function must call fact() again with the argument of n-1 or 3 in this example (step 3).
This process continues until the argument passed into the fact() function meets the base case which is
when the arguments is equal to 1 (shown as step 5). When this occurs, only then is a return value
provided to the previous call (step 6). This return argument is then used to calculate the previous
multiplication which is 2 times 1 which will return a value to the previous call (as shown in step 7).
This process will continue (steps 8, 9, and 10) until the main has a final answer.
Since the code being executed is the same, each instance of the fact() function is different from any
other instance only in the arguments and any local values (none in this example).
163
Chapter 18 Recursion
It should also be noted that the height of the recursion tree is directly associated with the amount of
memory used by the recursive function. For problems where the recursion tree is very large, this can
have a negative impact on overall performance of a recursive routine.
18.6
Exercises
Below are some quiz questions and project suggestions based on this chapter.
18.6.1
Quiz Questions
18.6.2
Suggested Projects
fib(n) =
1
1
fib( n1)+ fib(n2)
if n=0
if n=1
if n 2
Create a main program to read the n value from the user and ensure it is between 1 and 40.
Develop recursive function, fib, to recursively compute the Fibonnaci number based on the
provided definition. Note, the recursive Fibonnaci function requires two recursive calls for the
non-base case step.
164
Chapter 18 Recursion
4) Develop a recursive subroutine to recursively print a star tree. Based on an initial value, n, the
star tree should be displayed. For example, for an n value of 5, the program should output
something similar to the following:
RecursiveSubroutineProgram
EnterNumberofStars:5
StarTree:
*****
****
***
**
*
Create a main program to read the n value from the user and ensure it is between 1 and 50.
Develop recursive subroutine, printStars(), to recursively print the start tree as shown. The
subroutine should print one line per call. For successive recursive calls, the n value passed as
an argument should be decremented. The based case would be one (1) star.
5) Write a program using a recursive function to determine the number of possible paths through a
two-dimensional grid. The only allowed moves are one step to the right or one step down. For
example, given a grid as follows:
0
0
start
1
2
3
end
Moving from the starting location, (0,0) in this example, going to the end location, (3,2) in this
example, can be performed in 10 different ways. Two, of the ten, different ways are shown in
the example above. The function must be recursive.
Create a main program to read the initial grid coordinates and ensure that they are valid
(positive values) and that the end coordinates are greater than the start coordinates. Create a
recursive function, countPaths(), to determine the number of possible paths through a twodimensional grid. The function will accept a start coordinate (row,col) and a final end
coordinate (row,col).
165
Chapter 18 Recursion
6) The Tower of Hanoi is a mathematical puzzle that consists of three pegs, and a number of disks
of different sizes which can slide onto any peg. The puzzle starts with the disks neatly stacked
in order of size on one peg, the smallest at the top, thus making a conical shape.
The objective of the puzzle is to move the entire stack
to another peg, obeying the following rules:
hanoi ( n , from , to , by ) =
if n=1
if n> 1
Create a main program to read and validate the number of disks, n, from the user and ensure it
is between 1 and 10. Develop recursive function, hanoi, to recursively compute a solution to
the Tower of Hanoi problem.
166
19
Characters string values, such as 123 can not be used to perform numeric operations such as addition
or multiplication. As such, for more complex programs, there is sometimes the need to convert
between a character string representing a numeric value and an actual real or integer number.
These conversions can be performed using what is referred to as an internal read or an internal write.
Basically, the read or write functions and associated format statements can be used to perform basic
conversions. Instead of reading from an open file, the read and write operations can read and write
directly from and to variables. The specified format provides guidance for the conversion result.
Based on the input, a conversion may not be possible. For example, the character string 3.14 can be
converted into the real value of 3.14. However, the character string 3.1z4 could not be converted
since the 'z' is not a legal numeric value.
If a conversion is not possible, an error would be generated. If not handled, such an error would crash
the program. In order to address and handle any potential errors, the iostat parameter for the read/write
operation is used as previously described in the file operations chapter.
19.1
A character string can be converted into an integer or real value using an internal read operation. The
string is provided as the input instead of a file unit number. The numeric variable is provided as the
location for the result of the read operation. The format will provide guidance for the conversion.
The following is a simple example that will declare two strings and convert the first into an integer
value and the second into a real value. Additionally, a third string conversion is perform on a invalid
numeric string (to better show the error handling).
!Exampleprogramtouseaninternalreadfor
!character/numericconversion.
programcvtExample1
implicitnone
integer::cvtErr
character(4)::iString="1234"
character(7)::rString="3.14159"
character(7)::badString="3.14z59"
integer::iNum1,iNum2
real::pi,tau
write(*,'(a,/)')"ExampleConversionProgram."
167
The specific formats used on the read operations in the example are wider or larger than the expected
number (which is allowed). Should a smaller format be used, it would either truncate the value or
possibly generate a conversion error. To ensure appropriate conversion, the final values should be
verified against the expected result.
168
The multiplication by 2 for each of the numeric values was performed only as an example since
multiplication can only be performed on numeric data types (i.e., integer, real, or complex).
19.2
An integer or real value can be converted into a character string using a write operation. The string is
provided as the output variable instead of a file unit number. The numeric variable is provided as the
input for the write operation.
The following is a simple example that will convert an integer into a string and a real into a string.
Some numeric operations are performed on the numeric values and then the resulting strings are
concatenated with another string. Concatenation can only be performed on character data types.
!Exampleprogramtouseaninternalwritefor
!character/numericconversion.
programcvtExample2
implicitnone
integer::cvtErr
character(50)::str1,str2,msg1,msg2
integer::iNum=2468
real::pi=3.14,tau
write(*,'(a,/)')"ExampleConversionProgram."
!
!Convertintegervaluetoastring.
iNum=iNum/100
write(str1,'(i3)',iostat=cvtErr)iNum
if(cvtErr==0)then
msg1="Myageis"//str1
write(*,'(a,a)')
&
"Message1=",msg1
else
169
Once the numeric values are converted into strings, the character functions and character operations
can be used as needed.
19.3
Exercises
Below are some quiz questions and project suggestions based on this chapter.
19.3.1
Quiz Questions
170
19.3.2
Suggested Projects
171
172
20
System Services
The term system services generally refers to asking the operating system for information.
The read, write, and file operations (open, read, write, close) are common system services and have
already been addressed in a previous chapter.
Other system services include obtaining the date and/or time from the operating system and obtaining
the command line arguments (if any). The term command line arguments is used to refer to
information entered on the command line after the program name. This allows the user to provide
some information to the program before it starts (or as the program is started), which might save time
as compared to prompting for and interactively reading the information at run-time.
While there are many system services, only these basic ones are presented for reference. These system
services may be useful when working on more complex problems. Additionally, the calls and usage for
other system services is very similar to how these are performed.
20.1
The date and time functions are combined into a single system service call. The date and time values
can be obtained as character strings, as integers, or both simultaneously. The options for date and time
as explained in the next section followed by an example.
It must be noted that if the operating system has an incorrect date or time, the values returned to the
program will also be incorrect.
20.1.1
The date and/or time values are are obtained from the operating system using the get_date_time()
system service call. The argument or arguments for the system service call must specify at least one of
the following options:
date = <character(8)>
time = <character(10)>
zone = <character(5)>
values = <integer values array>
As noted, each option must provide a location of where to place the results of the specified size and
date type. The options are comma separated, similar to the read and write calls noted in a previous
chapter. At least one argument must be included in the call.
The zone, or time zone, option will provide the time difference between local time and Coordinated
Universal Time (UTC14). The character string will provide a result in hours:minutes format and the integer
values will be in minutes only. However, the minutes can be easily converted to hours.
14 For more information regarding coordinated universal time, refer to:
http://en.wikipedia.org/wiki/Coordinated_Universal_Time
173
Data Type
Description
date
character(8)
time
character(10)
zone
character(5)
values
integer array, 8
elements
values(1) year
values(2) month (1-12)
values(3) date (1-31)
values(4) month (1-12)
values(5) hour (0-23)
values(6) time zone difference
(minutes)
values(7) seconds (0-59)
values(8) milleseconds (0-999)
Each argument is optional, but at least one argument must be included. Multiple arguments are
allowed.
20.1.2
The following as an example program that obtains the date and time information from the operating
system in various formats. The final results are shown for reference.
!Exampleprogramtoobtainthedateandtimefromthesystem.
programtimeDateExample
!
!Declarations.
implicitnone
174
&
!
!Getdate,time,andzonefromsystemascharacters.
!Displaytoscreenforreference.
calldate_and_time(date=today)
write(*,'(/a,a)')"Todayis:",today
calldate_and_time(time=now,zone=myzone)
write(*,'(a,a)')"Timeis:",now
write(*,'(a,a/)')"TimeZoneis:",myzone
!
!Getalldatevaluesfromthesystemasintegers.
!Displaytoscreenforreference.
calldate_and_time(values=valuesArr)
write(*,'(a)')"ValuesArray:"
write(*,'(a,i4)')"Date,Year:",valuesArr(1)
write(*,'(a,i2)')"Date,Month:",valuesArr(2)
write(*,'(a,i2)')"Date,Day:",valuesArr(3)
write(*,'(a,i2)')"Time,Hour:",valuesArr(5)
write(*,'(a,i2)')"Time,Minutes:",valuesArr(6)
write(*,'(a,i2)')"Time,Seconds:",valuesArr(7)
write(*,'(a,i3)')"Time,Millseconds:",valuesArr(8)
write(*,'(/,a,i8)')
"TimedifferencewithUTCinminutes:",
valuesArr(4)
&
&
write(*,'(a,i2,a1,i2.2,/)')
&
"TimedifferencewithUTCinhours:",
&
valuesArr(4)/60,":",mod(valuesArr(4),60)
endprogramtimeDateExample
175
The UTC for Las Vegas, Nevada is indeed, -8 hours as shown. The results for the UTC will be based
on the actual geographic location of where the system executing the program is located.
20.2
The usage of command line arguments, information entered on the command line after the program
name, can be very useful in specific circumstances. By allowing the user to provide some information
on the command line, it saves the effort of entering the information interactively after the program
starts. The term command line arguments is sometimes referred to as command line options.
For example, when starting a Fortran program for a simple game, the persons name could be provided
on the command line. If the name is provided, the program could use that name. Otherwise, the
program could use a generic name such as 'player'. The command line might appears as follows:
c:\fortran>tictactoeed
Where tictactoe is the name if the program and 'ed' is the single command line argument.
Multiple command line arguments can be provided, but must be separated with a space or multiple
spaces. There is no predefined required format. The formatting or ordering requirements are up to the
program.
The gfortran compiler requires command line arguments for the various options include the input file
name (i.e., tictactoe.f95) and the output file name (i.e., -o tictactoe) specification. For example,
c:\fortran>gfortrantictactoe.f95otictactoe
176
20.2.1
Argument Count
There are generally two steps to obtaining the command line arguments. The first step is getting the
argument count or the number of arguments entered on the command line. The previous tic-tac-toe
example has one argument (i.e., 'ed'). The previous gfortran example had three (i.e., 'tictactoe.f95', '-o',
and 'tictactoe').
The argument count is obtained using the command_argument_count() system service as follows:
integer::myCount
myCount=command_argument_count()
Which will return the count in the variable myCount (as shown above). The count will be zero if no
arguments are entered.
20.2.2
Get Arguments
Once the argument count is available, the actual arguments can be obtained. The arguments are always
returned as character values. If the argument is meant to be used as a real or integer value, it must be
converted. The Character String / Numeric Conversions chapter provides a description of how this can
be accomplished.
When obtaining the command line arguments, the get_command_argument() system service is
used. An argument is returned into a specified character variable. The character variable should be
large enough (i.e., able to hold enough characters) to store the expected argument. The actual length of
the returned argument can optionally be provided. Additionally, if the character variable is too small,
the returned result will be truncated and the status set accordingly to indicate an error.
The options and associated values returned are described in the following table.
Option
Data Type
Description
length
integer
177
character(*)
length
integer
status
integer
The first two arguments are required and the final two arguments are optional.
20.2.3
This simple example obtains the command line argument count and displays the arguments to the
screen for reference. In this example, the program will expect a real value as the first argument and an
integer value as the second argument (if a second argument is provided). Any additional arguments,
while not used, are still displayed the screen along with the argument count value.
For this example, since the number of arguments is unknown ahead of time, an array to hold the
arguments is allocated at run-time. While this is not necessary, it does help provide a more complete
example. Such a process would only be appropriate if a varying number of command line arguments is
desired.
!Exampleprogramtodemonstratehowtoobtainthe
!commandlineargumentsfromthesystem.
programargsExample
implicitnone
integer::argCount,allocStatus,rdErr,i,iNum
real::rNum
character(len=80),dimension(:),allocatable::args
!
!Getcommandlineargumentcountfromsystem.
argCount=command_argument_count()
if(argCount==0)then
write(*,'(a)')"Nocommandlineargumentsprovided."
stop
endif
178
&
!
!Geteachargument,oneatatime,fromsystem.
doi=1,argCount
callget_command_argument(number=i,value=args(i))
enddo
!
!Displayargumentstoscreen.
if(argCount==0)then
write(*,'(a)')"Nocommandlineargumentsprovided."
else
if(argCount==1)then
write(*,'(a,i1,a)')"Therewas",
&
argCount,"commandlineargument."
else
write(*,'(a,i2,a)')"Therewere",
&
argCount,"commandlinearguments."
endif
write(*,'(/,a)')"Theargumentswere:"
doi=1,argCount
write(*,'(a,a)')"",trim(args(i))
enddo
write(*,*)
endif
!
!Convertastringtoanumericvalueusinganinternalread.
if(argCount>=1)then
read(args(1),'(f12.5)',iostat=rdErr)rNum
if(rdErr==0)then
write(*,'(a,f12.5)')
&
"Argument1RealNumber=",rNum
else
179
An example of the output for this program with valid command line arguments provided is shown
below. The executable name of the example program is 'args'.
c:\fortran>args3.1423helloworld
Therewere4commandlinearguments.
Theargumentswere:
3.14
23
hello
world
Argument1RealNumber=3.14000
Argument2IntegerNumber=23
c:\fortran>
Another example of the output for this program with invalid command line arguments provided is
shown as follows:
c:\fortran>args3.1423helloworld
Therewere4commandlinearguments.
Theargumentswere:
hello
3.14
23
world
Error,invalidrealvalue.
180
Note, the order for the valid and invalid arguments was chosen arbitrarily.
20.3
Exercises
Below are some quiz questions and project suggestions based on this chapter.
20.3.1
Quiz Questions
20.3.2
Suggested Projects
181
14 month
12
y = year a
m = month + 12 a 2
daynum =
date + y +
y
y
y
m
+
+ 31
4
100 400
12
) ] mod 7
Where the month, date, and year variables are the integer date values (12, 2, and 2013 in the
previous example). The final value of daynum is 0 for a Sunday, 1 for a Monday, 2 for a
Tuesday, and so forth with the maximum value of 6 for Saturday.
5) Update the program from the previous question to write the formatted date to a file. The file
name should be created based on the current date in the following format
file<MMDDYY>.txt For example, for a date of 12/02/2013, the file should be named
file120213.txt and contain the character string Monday, December 2, 2013.
6) Write a program to obtain the current date and attempt to open a file based on the date in the
following format, file<MMDDYY>.txt. For example, for a date of 12/02/2013, the file
should be named file120213.txt. If the file exists, the contents should be displayed to the
screen. If the file does not exist, an appropriate error message should be displayed.
182
21
This table lists the American Standard Code for Information Interchange (ASCII) characters or symbols
and their decimal numbers.
Char.
Dec.
Char.
Dec.
Char.
Dec.
32
64
96
33
65
97
"
34
66
98
35
67
99
36
68
100
37
69
101
&
38
70
102
'
39
71
103
40
72
104
41
73
105
42
74
106
43
75
107
44
76
108
45
77
109
46
78
110
47
79
111
48
80
112
49
81
113
50
82
114
51
83
115
52
84
116
53
85
117
54
86
118
55
87
119
56
88
120
57
89
121
58
90
122
59
91
123
<
60
92
124
61
93
125
>
62
94
126
63
95
183
127
184
22
The following provides some specific instructions for getting started. These instructions are
specifically geared for using a Windows based PCs. This includes all versions of Windows from
Windows XP, Windows Vista, Windows 7, and Windows 8.
The basic process is very similar to MAC and Linux (which is not covered here).
22.1
Working Files
Before working with Fortran program files, you should decide where you will be working (C\: drive,
USB drive, network drive, etc.) and create a working directory where your files will be placed. In
general, it will be easier if your Fortran files are not mixed with other, unrelated files. This directory
should be someplace you can easily get to it. That might be on your home workstation/laptop, on a
network drive, or on a USB drive.
22.2
First, you will need to download and install the GNU Fortran compiler. The main web page for the
GNU Fortran compiler is:
http://gcc.gnu.org/fortran/
This page provides general information regarding the Fortran compiler development effort, project
objectives, and current status.
More specific information, and the Windows compiler binaries, can be found on the gFortran Wiki
page, which is located at:
http://gcc.gnu.org/wiki/GFortran
This page contains links to the Gfortran binaries. On this page, click on the link labeled:
Binaries for Windows, Linux, and MacOS
Which will display the page for the GNUBinaries for various platforms, including Windows, MacOS,
and Linux. Click on the Windows link, which will show the various Windows options. For standard
Windows (XP/Vista/7/8), the heading MinGW build (native Windows build), includes a link for the
latest installer. Click on the link and download the Windows installation program. You will need to
access this file to perform the actual installation. There is no need to install the MinGW build.
This version will work on all supported Windows versions including Windows Vista, Windows XP,
Windows 7 and Windows 8.
After downloading, install the compiler. The installation can be accomplished by double-clicking on
the downloaded file. As with all Windows installs, it will require System Administrator privileges.
185
22.3
Command Prompt
In order to compile and work with programs under Windows, we will need to provide typed commands
to the computer. This is done from within the Command Prompt utility.
22.3.1
Windows XP/Vista/7
In For Windows 7, the Command Prompt is usually under Programs Accessories Command
Prompt.
22.3.2
Windows 8
For Windows 8, the Command Prompt can be found by using Search and is listed under the
Windows System heading.
22.3.3
The open Command Prompt window for any Windows version will look similar to the following:
Once the Command Prompt is open, the device and directory for the working files can be set.
22.3.4
In order to compile and work with programs under Windows, a working directory should be
established. This is where the program files will be stored. First, establish the device of the working
directory. If the files are on C:\ (the main hard drive), the device is already set. If the working
directory is located on a network drive, alternate drive, or USB drive, the device will need to be set.
Using the My Computer, determine the device or drive letter where you directory is located. Type
that letter at the prompt in the Command Prompt window. For example, if your device is K, you would
type k:.
At the K:\> you will need to change directory into the directory where your files are (if you created
one). The cd <dir_name> command can be used. For example, if the directory is named cs117, the
command would be cd cs117.
186
At this point, typing dir (for directory) will provide a list of files in the directory. While the format
will appear different, the files are the same as shown in the My Computer listing.
22.4
To ensure the compiler is installed correctly, open the Command Prompt, and type gfortran at the
prompt.
K:\cs117>gfortran
gfortran:fatalerror:noinputfiles
compilationterminated.
The no input files message means that the installation was completed correctly. It is not necessary to
set the device or directory in order to perform this verification.
However, if the following message is displayed,
K:\cs117>gfortran
'gfortran'isnotrecognizedasaninternalorexternalcommand,
operableprogramorbatchfile.
means that the Fortran compiler is not installed. The installation issue must be addressed before
continuing. Once the installation is completed successfully, the compilation steps detailed in Chapter 3
can be completed.
22.5
Compilation
Once the Fortran compiler is installed, programs can be compiled. Open the Command Prompt, and
set the device and directory as appropriate.
At this point the program can be compiled, using gfortran. The optional -o qualifier is used to set
the name of the output file. To execute, you can type the name of the executable (that was specified
with the -o).
To compile the example program, the following command would be entered:
K:\cs117>gfortranohwhw.f95
This command will tell the 'gfortran' compiler to read the file hw.f95 and, if there are no errors,
create an executable file named hw.exe. If there is an error, the compiler will generate an error
message, sometimes cryptic, and provide a line number. Such errors are usually the result of mistyping
one of the instructions. Any errors must be resolve before continuing.
187
22.6
Executing
To execute or run a program, type the name of the executable file. For example, to execute or run the
hw.exe program:
K:\cs117>hw
HelloWorld
K:\cs117>
Which will execute the example program and display the Hello World message to the screen.
22.7
Example
It is not necessary to type the extension (i.e., .exe) portion of the file name.
188
23
Generating random numbers is a common requirement for many problems. The following provides a
summary of utilizing the built-in Fortran random number generator routines.
23.1
Initialization
The first step in generating random numbers is to initialize the Fortran random number generator,
random_seed(). The most basic initialization is performed as follows:
callrandom_seed()
This will initialize the random number generator with a default seed. As such, each execution will regenerate the same series of random numbers for each execution. While this may not appear very
random, since successive executions generate the same series of random numbers, the testing is more
repeatable.
23.2
To request a random number, a real variable must be declared and then passed to the following call to
the built-in random_number() routine. For example:
callrandom_number(x)
The random number between 0.0 and 1.0 such that 0.0 random number < 1.0.
In order to obtain a larger number, it can be multiplied by an appropriate scale. For example, to
simulating the roll of a dice, a random integer number between 1 and 6 would be required. The
following code would obtain the random number and then scale it and convert to integer as required.
callrandom_number(x)
die=int(x*6.0)+1
Since the 0.0 is a possible value and 1.0 is not ( 0.0 random number < 1.0) 1 is added to ensure that 0
can not be assigned to the variable die. Further, since .999 is the largest possible value (since 1.0 is
not), and .999 * 6 will generate 6 (5.9 truncated to 5 with 1 added).
189
23.3
Example
A simple example program to generate 100 random integer numbers, each between 1 and 100, is as
follows:
programrand
implicitnone
integer,parameter::rcount=100
integer::i
integer,dimension(rcount)::nums
real::x
callrandom_seed()
doi=1,rcount
callrandom_number(x)
nums(i)=int(x*100.0)+1
enddo
write(*,'(a)')"RandomNumbers:"
doi=1,rcount
write(*,'(i3,2x)',advance="no")nums(i)
if(mod(i,10)==0)write(*,*)
enddo
endprogramrand
The call to random_seed() must be performed before the call to random_number(). Additionally, the
call to random_seed() can only be performed once.
The output of this example program is shown below:
RandomNumbers:
1005797753749813535
2214913945672666533
86412197606846341176
617290661662981002656
66569891667341931568
77341262839574503843
5610010075961074769571
8256749601459528931
676751278115538280
6378961232605122211
190
23.4
Example
In order to generate different random number for successive executions, the seed must be initialized
with a different set of seed values each time.
The following example simulates the roll of two dice, which requires two random integer numbers,
each between 1 and 6.
programdiceRoll
implicitnone
integer::m,die1,die2,pair
real::x
integer::i,n,clock
integer,dimension(:),allocatable::seed
character(10)::nickname
callrandom_seed(size=n)
allocate(seed(n))
callsystem_clock(count=clock)
seed=clock+37*(/(i1,i=1,n)/)
callrandom_seed(put=seed)
deallocate(seed)
callrandom_number(x)
die1=int(x*6.0)+1
callrandom_number(x)
die2=int(x*6.0)+1
write(*,'(2(a,1x,i1/),a,1x,i2)')"Dice1:",die1,
"Dice2:",die2,"DiceSum",(die1+die2)
&
endprogramdiceRoll
Will generate different values each execution. For example, three executions of the example program
are shown below:
C:\fortran>dice
Dice1:5
Dice2:4
DiceSum9
C:\fortran>dice
Dice1:2
Dice2:4
DiceSum6
191
C:\fortran>dice
Dice1:1
Dice2:6
DiceSum7
C:\fortran>
192
24
The following is a partial listing of the Fortran 95 intrinsic functions. Only the most common intrinsic
functions are included in this section. A complete list can be found on-line at the GNU Fortran
documentation web page.
24.1
Conversion Functions
The following table provides a list of intrinsic functions that can be used for conversion between
different data types.
24.2
Function
Description
INT(A)
NINT(X)
REAL(A)
Integer Functions
The following table provides a list of intrinsic functions that can be used for integers.
Function
Description
ABS(A)
MOD(R1,R2)
193
24.3
Real Functions
The following table provides a list of intrinsic functions that can be used for reals.
24.4
Function
Description
ABS(A)
ACOS(W)
ASIN(W)
ATAN(X)
COS(W)
LOG(W)
MOD(R1,R2)
SIN(W)
SQRT(W)
TAN(X)
Character Functions
The following table provides a list of intrinsic functions that can be used for characters/strings.
Function
Description
ACHAR(I)
IACHAR(C)
LEN(STR)
LEN_TRIM(STR)
LGE(STR1,STR2)
LGT(STR1,STR2)
LLE(STR1,STR2)
LLT(STR1,STR2)
TRIM(STR)
194
24.5
Complex Functions
The following table provides a list of intrinsic functions that can be used for complex numbers.
24.6
Function
Description
AIMAG(Z)
CMPLX(X,Y)
REAL(A)
Array Functions
The following table provides a list of intrinsic functions that can be used for arrays.
Function
Description
MAXLOC(A1)
MAXVAL(A1)
MINLOC(A1)
MINVAL(A1)
SUM(A1)
195
24.7
The following table provides a list of intrinsic functions that obtain information from the system.
Function
Description
CPU_TIME(TIME)
DATE_AND_TIME
(DATE,
TIME,ZONE,VALUES)
196
25
The Fortran language does not have any built-in graphics capabilities. To support some basic data
visualization a plotting application, GNUplot, can be used. GNUplot is a free, open source plotting
program that can plot data files and display user-defined functions.
This appendix provides a very brief summary of some of the basic GNUplot functions as applied to
plotting data from simple programs in this text. An general example program to plot a simple function
is provided for reference.
25.1
Obtaining GNUplot
To ensure that GNUplot is installed correctly, for Windows machine, you can enter command prompt
and type,
wgnuplot
which will start GNUplot by opening a new window. To exit, type exit at the prompt.
Complete documentation, tutorials, and examples are available at that site. Additionally, there are
many other web site dedicated to GNUplot.
25.2
Since our specific use of GNUplot will involve plotting a data file created with a Fortran program, it
will be necessary to provide some information and directions for GNUplot in the file. That information
is provided in a header (first few lines) and a footer (last few lines). As such, the program must first
write the header, write the data, typically in the form of data points to be plotted, and write a final
footer. The header and footer may be very different based on what is being plotted.
197
25.2.1
Header
The header will provides some guidelines on how the output should look, including title (if any), axises
(if any), lables (if any), and plotting color(s). Additionally, comments can be included with a #
character. Comments are useful to provide information about the contents of the plot file or nature of
the data being plotted. A typical header might be as follows:
#ExamplePlotFile
settitle"CS117PlotFunction"
plot""notitlewithdotslinewidth2linecolor2
25.2.2
Footer
The footer is used to formally tell GNUplot there are no more points. Additionally, the pause
directive can be used to ensure that any plots displayed from the command line are left on the screen.
A typical footer might be as follows:
end
pause1
25.3
Plotting Files
In order to display a plot file on a Windows machine, at the command prompt, type,
wgnuplotfile.plt
which will start GNUplot and instruct GNUplot to read the file file.plt. The file name can be
anything and the file extension is not required to be .plt.
If the header or footer commands are incorrect or the data points are invalid, nothing will be displayed.
To investigate, the file can be opened with a text editor.
25.4
Example
( x)
( 1cos
)
3.0
The program, data file, and final output are presented for reference.
198
25.4.1
Plot Program
The following is an example program that generates points, opens a plot file, write the header, data
points, and footer.
programplotExample
implicitnone
real,dimension(200)::x,y
integer::i,opnstat
!Generatexandypoints
doi=1,200
x(i)=i*0.05
y(i)=sin(x(i))*(1cos(x(i)/3.0))
enddo
!Outputdatatoafile
open(12,file="data.plt",status="replace",
action="write",position="rewind",
&
iostat=opnstat)
if(opnstat>0)stop"erroropeningplotfile."
&
!Writeheader
write(12,'(a)')"#ExamplePlotFile"
write(12,'(a)')"settitle""ExamplePlotFunction"""
write(12,'(a,a)')"plot""""notitlewithdots",
"linewidth2linecolor2"
!Writepointstofile.
doi=1,100
write(12,*)x(i),y(i)
enddo
!Writefooterandclosefile
write(12,'(a)')"end"
write(12,'(a)')"pause1"
close(12)
endprogramplotExample
The data file name can be changed or read from the user.
199
25.4.2
Plot File
The output file can be edited with a standard text editor. This will allow checking the data file for
possible errors if it does not display correctly.
25.4.3
Plot Output
On Windows machines, the plot can be printed by right clicking on the blue bar (on top). This will
display a menu, with Print as one of the options.
200
26
This appendix provides answers for the quiz questions in each chapter.
26.1
26.2
26.3
201
26.4
26.5
4) An integer variable can be converted to a real with the real conversion function. For example,
intVar=int(realVar)
Note, in this example precision may be lost since the fractional part is truncated (not rounded).
5) The two logical constants are .true. and .false. which must include the leading and trailing
periods.
6) Some intrinsic functions are real(), int(), nint(), cos(), sin(), mod(), tan(), and sqrt(). There
are more as listed in Appendix D.
7) The statements are as follows:
x1=(pi/6.0)*(3.0*a**2+3.0*b**2+c**2)
x2=(2.0*a/c)*cos(b)*sin(b)
x3=b+sqrt(b**24.0*a*c)/(2.0*a)
202
26.6
26.7
26.8
203
26.9
204
8) The statements are valid, however since the initial value of i is greater than the stop value, no
statements in the loop will be executed.
9) The statements are valid, however since the initial value of i is greater than the stop value, no
statements in the loop will be executed.
10) There is no specified limit.
11) When nesting IF statements, the nested IF statement must be completely nested within the loop.
26.10
205
26.11
2) The results are .false., .true., .false., .false., .false., .false., .true. where the leading and trailing
periods are required.
3) The value for astr1 = abc, the value for astr2 = 456, the value for astr3 = 12345678910,
and the value for astr4 = DEF123bc.
4) The integer value can be obtained by using the IACHAR() function.
5) The character can be obtained from the integer value by using the ACHAR() function.
26.12
206
26.13
99
99
207
26.14
2.0
3.0
4.0
3.0
4.0
5.0
4.0
5.0
6.0
5.0
6.0
7.0
6.0
7.0
8.0
c) 3.0.
d) 4.0
e) 7.0
4) An unsuccessful allocation can be detected by checking the status variable for a value > 0.
26.15
208
26.16
209
26.17
26.18
210
main:
fib(4)
step 16
step 1
fib:
fib(3) +
fib(2)
step 2
fib:
fib(2) +
fib(1)
step 9
step 12
step 8
step 3
fib:
fib(1) +
fib(0)
step 5
step 10
fib:
return 1
step 4
fib:
fib(1) +
fib(0)
step 14
step 11
step 13
fib:
return 1
fib:
return 0
step 7
step 6
fib:
return 1
step 15
step 7
fib:
return 0
211
26.19
4) The statement to convert the integer variable iNum=234 into a character string sNum is as
follows:
write(sNum,'()',iostat=cvtErr)iNum
26.20
7) If there are no arguments entered on the command line, the get_command_argument() system
service call will return a 0.
8) The statement is as follows:
callget_command_argument(number=3,value=arg3,
length=arg3length,status=arg3stat)
212
&
27
In programming, a keyword is a word or identifier that has a special Fortran 95 meaning. Keywords are
reserved in that they can not be used for anything else such variable names.
statement implies a keyword that starts a statement, usually one line unless there is a
continuation "&"
For reference, below is a partial list of keywords or reserved words. For a complete list of keywords,
refer to the on-line GNU Fortran 95 documentation.
Keyword
Type
Meaning
allocatable
attribute
allocate
statement
assignment
attribute
backspace
statement
call
statement
call a subroutine
case
statement
character
statement
close
statement
close a file
complex
statement
contains
statement
cycle
statement
deallocate
statement
default
statement
do
construct
start a do loop
else
construct
else if
construct
elsewhere
construct
end do
construct
ends do loop
end function
construct
ends function
213
construct
ends if
end interface
construct
ends interface
end module
construct
ends module
end program
construct
ends program
end select
construct
end subroutine
construct
ends subroutine
end type
construct
ends type
end where
construct
ends where
endfile
statement
exit
statement
format
statement
defines a format
function
construct
if
statement and
construct
if(...) statement
implicit
statement
in
a keyword for
intent
inout
a keyword for
intent
integer
statement
intent
attribute
interface
construct
intrinsic
statement
inquire
statement
kind
attribute
len
attribute
logical
statement
module
construct
namelist
statement
nullify
statement
nullify a pointer
only
attribute
open
statement
operator
attribute
optional
attribute
out
a keyword for
intent
214
statement
pointer
attribute
private
statement and
attribute
in a module
program
construct
public
statement and
attribute
read
statement
performs input
real
statement
recursive
attribute
result
attribute
return
statement
rewind
statement
select case
construct
stop
statement
subroutine
construct
target
attribute
then
construct
part of if construct
type
construct
use
statement
brings in a module
where
construct
conditional assignment
while
construct
write
statement
performs output
215
216
Index
ABS(A).........................................................193p.
Accessing Array Elements.........................99, 113
Accessing Components...................................136
ACHAR(I).................................................84, 194
ACOS(W)........................................................194
Actual arguments.............................................122
Addition.............................................................23
Advance clause..................................................75
AIMAG(Z)......................................................195
Allocate.............................................................99
American Standard Code for Information
Interchange..........................................................5
Argument count...............................................177
Argument Intent..............................................122
Argument Passing............................................123
Arguments.......................................................122
Array Declaration......................................97, 111
ASCII..................................................................5
ASIN(W).........................................................194
Assignment........................................................23
ATAN(X).........................................................194
Base 10................................................................4
Base 2..................................................................5
Binary digit..........................................................5
Binary Numbers..................................................5
Bit........................................................................5
Boolean..............................................................15
Byte.....................................................................5
Call statement..................................................122
CASE statement................................................51
Central Processing Unit.......................................3
Chaos Game......................................................96
Character...........................................................15
Character constant.............................................22
Character Literals..............................................22
Character Representation....................................5
Character String / Numeric Conversions.........167
CMPLX(X,Y)..................................................195
Command line arguments........................173, 176
Chapter Index
Equal to.............................................................43
Error Terminology.............................................39
Escape character..........................................22, 81
Exit statement....................................................61
Exponentiation...................................................25
External...........................................................121
External declaration.........................................122
External Routines............................................122
Factorial function............................................160
File Open...........................................................89
Formal arguments............................................122
FORMAT statement..........................................71
Functions.........................................................123
Get_command_argument()..............................177
GET_COMMAND_ARGUMNENT(NUMBER,
VALUE, LENGTH, STATUS)........................196
Get_date_time()...............................................173
GNUplot..........................................................197
Greater than.......................................................43
Greater than or equal.........................................43
Helper function................................................161
IACHAR(C)..............................................84, 194
IF statement.......................................................45
IF THEN ELSE IF statement............................46
IF THEN ELSE statement.................................45
IMPLICIT NONE..............................................15
Implicit typing...................................................15
Implied do-loop...............................................101
Index..................................................................97
INT(A).............................................................193
Integer................................................................14
Integer constants................................................21
Integer Literals..................................................21
Intent(in)..........................................................122
Intent(inout).....................................................122
Intent(out)........................................................122
Interface block.................................................122
Internal.............................................................121
Internal read.....................................................167
Internal Routines.............................................122
Internal write...................................................167
Intrinsic Functions.....................................26, 124
Iostat................................................................167
Irrational numbers.............................................15
Keyword....................................................14, 213
Kind................................................................18p.
Kind specifier.................................................18p.
LEN_TRIM(STR).....................................85, 194
LEN(STR).................................................84, 194
Less than............................................................43
Less than or equal..............................................43
LGE(STR1,STR2)...........................................194
LGT(STR1,STR2)...........................................194
Literals...............................................................21
LLE(STR1,STR2)...........................................194
LLT(STR1,STR2)............................................194
LOG(W)..........................................................194
Logic Error........................................................41
Logical...............................................................15
Logical constant................................................23
Logical Constants..............................................23
Logical Operators..............................................44
Loop..................................................................59
Machine language................................................4
Magic Square...................................................119
MAXLOC(A1)................................................195
MAXVAL(A1)................................................195
MINLOC(A1)..................................................195
MINVAL(A1)..................................................195
MOD(R1,R2)................................................193p.
Module file......................................................151
Modules...........................................................149
Monte Carlo.....................................................114
Multidimensional Arrays.................................111
Multiplication....................................................24
NINT(X)..........................................................193
Not equal to.......................................................43
Object file........................................................151
Operands............................................................43
Operating System................................................2
Order of Operations...........................................25
Parameter...........................................................17
Pi estimation....................................................115
Primary Storage...................................................3
Print Binary.....................................................158
Program Layout...............................................121
Program Statement..............................................7
Pythagorean theorem.......................................114
Quadratic equation............................................47
Random Access Memory.....................................3
Random_number()...........................................189
Random_seed()................................................189
Rational numbers...............................................15
Read statement..................................................32
218
Chapter Index
Real constants....................................................21
Real Literals......................................................21
Real number2....................................................15
REAL(A).........................................................195
Recursion.........................................................157
Recursive Factorial..........................................160
Recursive relation............................................157
Recursive subroutine.......................................157
Relational Operation..........................................43
Relational Operator...........................................43
Relational Operator (alternate)..........................43
Result variable.................................................160
Run-time Error..................................................40
Secondary source file......................................149
SELECT CASE Statement................................51
Selector lists......................................................51
Side Effects......................................................124
Side-effect.......................................................124
SIN(W)............................................................194
Single Dimension Arrays...................................97
Solid State Drive.................................................3
Source file............................................................8
SQRT(W).........................................................194
Static Array Declaration....................................98
Static Declaration......................................97, 112
String.................................................................31
String5...............................................................15
Subprogram Types...........................................121
Subprograms....................................................121
Subroutines......................................................125
Subscript............................................................97
Subtraction........................................................24
SUM(A1).........................................................195
System Services...............................................173
TAN(X)...........................................................194
Time.................................................................173
TRIM(STR)...............................................85, 194
Type Checking...................................................16
Type declaration................................................16
Unit number.......................................................89
Use Statement..................................................150
User-Defined Functions..................................124
Using Functions and Subroutines....................122
Values array.....................................................173
Variable Ranges.................................................16
Variable Scope.................................................122
Whole number...................................................14
Write statement..................................................31
Zone.................................................................173
.and....................................................................44
.eq......................................................................43
.ge......................................................................43
.gt.......................................................................43
.le.......................................................................43
.lt........................................................................43
.ne......................................................................43
.not.....................................................................44
.or.......................................................................44
/=........................................................................43
<.........................................................................43
<=......................................................................43
==......................................................................43
>.........................................................................43
>=......................................................................43
219