Title: Chapter 4 Basic building blocks
1Chapter 4 Basic building blocks
4.1 Procedures, subprograms and functions 4.2
Programs and program units 4.3 External
functions 4.4 Subroutines 4.5 Actual arguments,
dummy arguments and local variables 4.6
Procedures as an aid to program structure 4.7
Modules 4.8 Modules and derived data types 4.9
Modules and explicit procedure interfaces 4.10
Modules as an aid to program design
24.1 Procedures, subprograms and functions
The way we do things in real life at Figure
4.1. It is a sequence of instructions
but not all the instructions are there.
34.1 (2)
A cross-reference to the other recipes, saves
space and keeps the main recipe less cluttered
and thus easier to follow. In program a special
section of program which is referred to
whenever required is known as a
procedure. Procedures fall into two broad
categories, subroutines and functions. Almost
all of the procedures which are part of the
Fortran 90 language are functions and are
referred to as intrinsic functions. There are
also five intrinsic subroutines.
44.1 (3)
The purpose of a function is to take one or more
values (or arguments) and create a single
result. Intrinsic function such as
SIN(x) which calculates the value of sinx
(where x is in radians) LOG(x) which
calculates the value of logex SQRT(x) which
calculates the value of
54.1 (4)
A function reference takes the general form
name(argument) Or, where there are two or
more arguments name(arg1, arg2, ...) A
function is used simply by referring to it in an
expression in place of a variable or constant.
Thus -b SQRT(bb 4.0ac) will first
calculate (bb -4.0ac), then use the function
SQRT and finally add this to b There are 108
intrinsic functions available in Fortran 90, a
full list can be found in Appendix A for
reference.
64.1 (5)
The type of the result will usually be of the
same type as the arguments. REAL x,
y . . y ABS (x) INTEGER x,
y . . y ABS (x) Those functions
which exhibit this quality are referred to as
generic functions, the appropriate one of
which will be selected by the compiler
depending upon the types of the arguments.
74.1 (6)
EXAMPLE 4.1 (1) Problem A farmer has a
triangular field which he wishes to sow with
wheat. Write a program that reads the
lengths of the three sides of the field (in
meters), and the sowing density (in grams per
square meter). Print the number of 10
kilo bags of wheat he must purchase in order to
sow the whole field.
84.1 (7)
- (2) Analysis
- The key to solution of this problem is the
equation - area
- For the area of a triangle whose sides have
lengths a, b and c, - where 2sabc.
- Read lengths of the sides of the field (a, b and
c) - Calculate the area of the field
- Read the sowing density
- Calculate the quantity of wheat seed required
- 5. Calculate the number of 10 kilo bags this
represents
9Example of rounding
- No. of bags (quantity of seed)/10,0000.0001qua
ntity - If this is less than 0.1kilogram 100gr it must
be rounded. - Thus, nbags (No. of 10 kilo bags)
0.0001quantity0.9 (to allow for a partly used
bag). - e.g. 1) nbags 11.5 0.9 12 (we drop 0.4
because nbags is - INTEGER)
- 2) nbags 11.1 0.9 12
- 3) nbags 11.09 0.9 11 (we drop 0.99 because
nbags is - INTEGER)
104.1 (8)
(3) Solution (p86.f) PROGRAM
wheat_sowing IMPLICIT NONE ! A program to
calculate the quantity of the wheat required to
! sow a triangular field ! Variable
declarations REAL a, b, c, s, area,
density, quantity INTEGER num_bags !
Read the lengths of the sides of the field
PRINT , Type the lengths of the three sides of
the field in metres READ ,
a, b, c
114.1 (9)
! Calculate the area of the field s
0.5(abc) area SQRT(s(s-a)(s-b)(s-c)) !
Read sowing density PRINT , What is the sowing
density (gm/sq.m.) ? READ , density !
Calculate quantity of wheat and the number of 10
kg bags quantity densityarea num_bag
0.0001quantity 0.9 ! Round up more than
.1kg ! Print results PRINT , The area of the
field is , area, sq. metres PRINT , and ,
num_bags, 10 kilo bags will be required END
PROGRAM wheat_sowing
124.2 Programs and program units
A procedure may be an intrinsic procedure, or may
be provided by the programmer. In the latter
case it is normally implemented by means of a
Fortran subprogram A main program
unit PROGRAM name . .
Specification statements etc. . .
Executable statements . . END PROGRAM
name
134.2 (2)
we have already used the term main program unit,
and we now introduce the four other types of
program units. They have the same broad
structure, consisting of an initial statement,
any specification statements, any executable
statements and an END statement. These four
program units are two types of external
subprograms, known as function subprograms and
subroutine subprograms, modules and block data
program units.
144.2 (3)
A program will normally consist of a number of
different program units, of which exactly one
must be a main program unit. One program unit
need never be aware of the internal details of
any other program unit. The only link is
through the interface of the subsidiary program
unit.
154.2 (4)
A function subprogram unit FUNCTION name (arg,
...) . . Specification statements
etc. . . Executable statements
. . END FUNCTION name
164.2 (5)
A subroutine subprogram unit SUBROUTINE name
(arg, ...) . . Specification
statements etc. . . Executable
statements . . END SUBROUTINE name
174.2 (6)
A module program unit MODULE name .
. Specification statements etc. . .
Excutable statements . . END MODULE
name
184.2 (7)
A block data program unit BLOCK DATA name
. . Specification statements etc. .
. END BLOCK DATA name This feature opens
up the way for libraries of subprograms.
194.3 External functions
Write our function subprograms, referred to as
external functions the first statement of the
function is a special FUNCTION
statement type FUNCTION name(d1, d2,
...) Where d1, d2, ... are dummy arguments which
represent the actual arguments which will be
used when the function is used (or referenced),
and type is the type of the result of the
function.
204.3 (2)
For example REAL FUNCTION cube_root (x)
IMPLICIT NONE ! Function to calculate
the cubic root of a positive ! real
number ! Dummy argument declaration
REAL, INTENT (IN) x ! Local
variable declaration REAL log_x
! Calculate cube root by using logs
log_x LOG(x) cube_root EXP
(log_x/3.0) END FUNCTION cube_root
214.3 (3)
- There are four very important points to notice
about this function. -
- 1. The variable log_x is not accessible from
outside the function. -
- It is called an internal variable or a local
variable. - The phrase INTENT (IN) after the type, REAL, is
- the second attribute.
-
- It informs the compiler that the dummy argument
x - may not be changed by the function cube_root.
- Dummy arguments to functions should always be
- declared with INTENT (IN).
224.3 (4)
- Cube_root which has the same name as the
function, - is a special variable, known as the result
variable. -
- Every function must contain a variable having
the same name - as the function, and this variable must be
assigned, - a value to return as the value of the function.
- The last statement of the procedure is the END
statement -
- END FUNCTION cube_root
- END FUNCTION
- END
- We would strongly recommend that the first form
always be used, - the END statement causes execution of the
program to return to - the point in the calling procedure.
234.3 (5)
a bcube_root (c) d The function cube_root
must be declared in the calling program unit in
order that the Fortran processor is aware of its
type, any other relevant information. Declare
actual args REAL cube_root ! Not
enough REAL, EXTERNAL cube_root ! Need this
REAL a,b,c,d
Addition of this attribute, EXTERNAL, informs the
compiler that the name is that of a real
function and not of a real variable.
244.3 (6)
The interface of a function consists of the name
and type of the function and the number and
type of its dummy arguments. To write a
function which has no argument , we must still
include the parentheses around the non-existent
argument when declaring the function, and also
when using the function.
254.3 (7)
INTEGER FUNCTION next_int () (p92.f) IMPLICIT
NONE ! This function requests an integer from
the keyboard ! Get number PRINT ,
Please type an integer READ , next_int END
FUNCTION next_int could be used in
264.3 (8)
PROGRAM next_int_test IMPLICIT NONE !
This program displays the product of two numbers
which are ! typed at the keyboard !
External function declaration INTEGER,
EXTERNAL next_int ! Variable declaration
INTEGER product product
next_int()next_int() PRINT ,"The product is
",product END PROGRAM next_int_test
274.3 (9)
Results produced by the program using the
function next_int Please type an
integer 17 Please type an integer 23 Their
product is 391 Functions can be referenced in
another function or subroutine. A function must
not refer to itself, either directly or
indirectly. This is known as recursion and is not
allowed unless we take special action to permit
it.
284.4 Subroutines
A subroutine differs form a function. In how a
subroutine is referenced and how the results, if
any, are returned. A function reference causes
a transfer of control. The execution of the
function utilizes the values provided as
arguments to calculate a single value (the
function value). A function reference,
therefore, is not a complete statement but is
part of an expression var fun (arg1, arg2,
...) PRINT , fun1 (arg1, arg2, ...) var fun2
(a1, fun3 (arg1, arg2, ...), a2, a3, )
294.4 (2)
A subroutine is accessed by means of a CALL
statement, which gives the name of the
subroutine and a list of arguments. CALL name
(arg1, arg2, ...) The CALL statement causes a
transfer of control. Unlike a function, a
subroutine need not return anything to the
calling program unit however, if it does
return any value then they are returned by
means of one or more of its arguments.
304.4 (3)
SUBROUTINE roots (x, square_root, cube_root,
fourth_root, fifth_root) IMPLICIT
NONE ! Subroutine to calculate various
roots of a positive real ! number supplied as
the first argument, and return it in ! the
second to fifth arguments ! Dummy argument
declarations REAL, INTENT (IN) x REAL,
INTENT (OUT) square_root, cube_root,
fourth_root, fifth_root ! Local
variable declaration REAL log_x
314.4 (4)
! Calculate square root using intrinsic
SQRT square_root SQRT (x) ! Calculate other
roots by using logs log_x LOG (x) cube_root
EXP (log_x/3.0) fourth_root EXP
(log_x/4.0) fifth_root EXP (log_x/5.0) END
SUBROUTINE roots
324.4 (5)
The results of executing the subroutine are
assigned to variables which are themselves
dummy arguments. These dummy arguments have been
given an INTENT (OUT) attribute, to indicate
that they are to be used to transfer information
from the subroutine back to the calling program.
334.4 (6)
PROGRAM subroutine_demo IMPLICIT NONE
! A program to demonstrate the use of the
subroutine roots ! Variable declarations
actual args REAL pos_num, root_2, root_3,
root_4, root_5 ! Get positive number from
user PRINT , Please type a positive real
number READ , pos_num ! Obtain
roots CALL roots (pos_num, root_2, root_3,
root_4, root_5)
344.4 (7)
! Display number and its roots PRINT ,
The square root of , pos_num, is , root_2
PRINT , The cube root of , pos_num, is ,
root_3 PRINT , The fourth root of ,
pos_num, is , root_4 PRINT , The fifth
root of , pos_num, is , root_5 END PROGRAM
subroutine_demo
354.4 (8)
If a subroutine has no argument then the CALL
statement takes the form CALL
sub or CALL sub () We recommend the simpler
form without any parentheses. As for function, a
subroutine may call other subroutines or
reference functions, but it must not call
itself, either directly or indirectly, such
recursive calls are only allowed if specific
steps are taken to permit it.
364.5 Actual arguments, dummy arguments and local
variables
The relationship between the actual arguments
in the calling program unit and the dummy
arguments in the subroutine or function is of
vital importance. The order and types of the
actual arguments must correspond exactly with
the order and types of the corresponding dummy
arguments. When the procedure (function or
subroutine) is called from some other program
unit, we can imagine that a message is
pinned up for each dummy argument identifying
the corresponding actual argument.
374.5 (2)
For example, if the only executable statement
in the subroutine sub(x, y, z) was x y
z then the effect of the CALL sub(a, c, d) in
Figure 4.10 would be as if it was replaced in
the calling program unit by the statement a
c d
384.5 (3)
Figure 4.10 A representation of CALL sub (a, c,
d).
394.5 (4)
Figure 4.11 A representation of CALL sub (b, e,
a).
404.5 (5)
Whereas the effect of the CALL sub(b, e, a) in
Figure 4.11 would be as if it was replaced by
the statement b e a The distinction
between dummy arguments used for these
different purposes is achieved by use of the
INTENT attribute. INTENT attribute may only be
used in the declaration of a dummy argument.
414.5 (6)
It can take one of the following three forms
INTENT(IN) this dummy argument is used only to
provide information to the procedure,
the procedure will not be allowed to
alter its value. INTENT(OUT) this dummy
argument will only be used to return
information, it must be given a value.
INTENT(INOUT) this dummy argument may be used for
transmission of information in both
directions.
424.5 (7)
A subroutine's arguments may have all three forms
of INTENT attribute. The dummy arguments in a
function should always be declared with INTENT
(IN). The assignment statement which should
have read arg3 arglarg2
434.5 (8)
An example of confusion about the INTENT of dummy
arguments. PROGRAM intent_demonstration IMPLICIT
NONE INTEGER, PARAMETER a2 INTEGER b3,
c4, d CALL problem_sub (a, b, c) CALL
problem_sub (b, c, d) PRINT , "a ", a," and b
", b END PROGRAM intent_demonstration SUBROUTIN
E problem_sub (argl, arg2, arg3) IMPLICIT
NONE !This subroutine returns the product of its
first two !arguments via the third
argument INTEGER argl, arg2, arg3 argl
arg2arg3 END SUBROUTINE problem_sub
444.5 (9)
If the declarations in the subroutine had
read INTEGER, INTENT(IN) arg1,arg2 INTEGER,
INTENT(OUT) arg3 Then the following assignment
statement would have led to an error during
compilation, if it was the comment that was
wrong, then the declarations should have
been INTEGER, INTENT(OUT) arg1 INTEGER,
INTENT(IN) arg2, arg3 The problem with
character arguments concerns the length of the
arguments, and can be demonstrated by an example.
454.5 (10)
- EXAMPLE 4.2
- Problem
- Write a procedure which will take two
character arguments as - input arguments, containing two names
- (a 'first name' and a 'family name',
respectively), - and which will return a string containing the
two names with exactly one space separating
them. - (2) Analysis
- The first difficulty is that the procedure
cannot know the length that will be declared for.
-
- Fortran provides an assumed-length
character declaration. - Used for declaring a dummy argument
- CHARACTER(LEN) character_dummy_arg
- It assumes its length from the corresponding
actual argument - when the procedure is executed.
464.5 (11)
The second difficulty is removing any redundant
spaces at the TRIM intrinsic function, removes
any trailing blanks ADJUSTL moves its argument
enough spaces to the left to remove any
leading blanks. Function full_name (first_name,
last_name) full_name, first_name and last_name
are all CHARACTER (LEN). Concatenate names,
using ADJUSTL to remove leading blanks from
both names, and TRIM to remove trailing blanks
from first_name.
474.5 (12)
(3) Solution CHARACTER(LEN) FUNCTION full_name
(first_name, last_name) IMPLICIT NONE
! Function to join two names to form a full
name with a ! single space between the first
and last names ! Dummy argument
declarations CHARACTER(LEN), INTENT(IN)
first_name,last_name ! Use ADJUSTL to
remove redundant leading blanks, and ! TRIM to
remove redundant blanks at the end of first_name
full_name TRIM (ADJUSTL(first_name)) // " "
// ADJUSTL(last_name)
END FUNCTION full_name
484.5 (13)
The result variable (full_name) is declared to be
of assumed length. The function name must
appear in a declaration statement in any
program unit that references the function, and
that declaration must specify the length of the
function CRARACTER(LEN30), EXTERNAL
full_name An intrinsic function LEN
(character_string) returns the length of its
argument.
494.5 (14)
CHARACTER (LEN) FUNCTION full_name
(first_name, last_name) IMPLICIT NONE !
Function to join two names to form a full name
with a ! single space between the first and
last names ! Dummy argument declarations
CHARACTER(LEN), INTENT(IN) first_name,
last_name ! Local variables
CHARACTER(LENLEN(first_name)) new_first_name
CHARACTER(LENLEN(last_name)) new_last_name
! Use ADJUSTL to remove redundant leading
blanks new_first_name ADJUSTL(first_name)
new_last_name ADJUSTL(last_name) ! Use TRIM
to remove blanks at the end of new_first_name
full_name TRIM(new_first_name) // " " //
new_last_name END FUNCTION full_name
504.5 (15)
An alternative way would be to move the
declaration of the type of the function to the
body of the function FUNCTION full_name (first
name, last_name) IMPLICIT NONE !Function to join
two names to form a full name with a !single
space between the first and last names !Result
type and dummy argument declarations CHARACTER(LEN
), INTENT(IN) first_name, last-name CHARACTER
(LEN) full_name . .
514.5 (16)
Consider the derived data type complex_number In
the procedure we will declare the dummy arguments
by TYPE (complex_number) argl, arg2,
arg3 Within a procedure, we cannot have a type
definition as an argument. So, how can the
calling program unit know about the definition of
the new derived type complex_number? The
answer requires a new concept in Section 4.8.
524.5 (17)
The locality of variables Each program unit is
only aware of any variables declared within the
program unit itself as its local variables,
together with pseudo-variables known as dummy
arguments. It would be useful for several
procedures to access the same variables. The
importance of local variables combined with
arguments cannot be overemphasized.
534.6 Procedures as an aid to program structure
Modular program development is a key concept of
software engineering. This approach breaks the
problem down into its major sub-problems, or
components. A component may itself be
sub-divided into further components. The
interface between each component and the rest of
the program is well defined. The interface
consists of two parts. The first is the list
of arguments, the second is the specification
of the action of the component.
544.6 (2)
A structure plan gives very great assistance in
modular development as it identifies the major
components of the program. They can be
integrated to form the complete program according
to the top-level structure plan. EXAMPLE
4.3 (1) Problem Write a program which will
read a set of ten experimental results and
calculate their mean and standard deviation. (2)
Analysis 1 Read ten real data items (x1, ,
x10) using the subroutine input 2 Calculate
the mean and standard deviation using the
subroutine statistics 3 Print results
using the subroutine results
554.6 (3)
Subroutines provide two major benefits. The
first is that we can test each of the subroutines
separately. The second benefit is that we can
keep the size of each procedure down to
manageable proportions. A second level of
subsidiary structure plans, such as Subroutine
statistics (x1, , x10, mean, st_dev) REAL
x1, , x10, mean, st_dev 1. Calculate mean and
standard deviation The interface with the
subroutine statistics is fully defined.
564.7 Modules
Functions and subroutines are normally written as
independent program units in the form of
external subprograms. Another form of program
unit is a module. A module starts with an
initial statement MODULE name and ends with
an end statement END MODULE name or END
MODULE END
574.7 (2)
A module exists in order to make some or all of
the entities declared within it accessible to
more than one program unit. One very important
use of modules relates to global accessibility of
variables, constants and derived type
definitions. A module allows a defined set of
variables and/or constants to be made available
to any program units which access them by means
of an appropriate USE statement. The USE
statement takes the form USE name where name
is the name of the module.
584.7 (3)
MODULE global_data IMPLICIT NONE SAVE !
Constant declarations REAL, PARAMETER
pi3.1415926, piby2pi/2.0 ! Variable
declarations REAL global_1, global_2,
global_3, global_4, global_5 END MODULE
global_data SAVE should always be included in
any module which declares any
variables. Entities which are made available in
this way are said to be made available by USE
association.
594.7 (4)
The USE statement comes after the initial
statement (PROGPAM, SUBROUTINE or FUNCTION) but
before any other statements SUBROUTINE
component USE global_data IMPLICIT NONE !Any
additional specification statements . . !Execut
able statements . . END SUBROUTINE component
604.7 (5)
All procedures which use a module that includes a
SAVE statement are sharing the same copy of
any variables, constants, type definitions or
other entities accessed from by USE association.
614.7 (6)
SUBROUTINE sub1 (p111.f) USE global_data IMPLICI
T NONE global_1 pi !both accessed from
module PRINT , global_1 !prints 3.14159
(approximately!) CALL sub2 !global_1 now has
the value 2.5 PRINT , global_1 !prints
2.5 END SUBROUTINE sub2 USE global_data IMPLICI
T NONE global_1 2.5 !variable is
accessed from module END One modules can USE
another module in order to gain access to items
declared within it.
624.7 (7)
MODULE first IMPLICIT NONE SAVE INTEGER
first_int END MODULE first MODULE second USE
first IMPLICIT NONE SAVE INTEGER
second_int END MODULE second
634.7 (8)
SUBROUTINE module_user USE second IMPLICIT
NONE !This subroutine has access to second_int
from the !module second, and first_int from the
module first . . It is not allowed for a
module to USE itself, either directly or
indirectly.
644.8 Modules and derived data types
- It was not possible to use derived type variables
or constants as arguments to a procedure. - Problem
- Write four functions for use in a complex
arithmetic package using the complex_number
derived type - which was created in Example 3.4.
- The functions should each take two complex
arguments and - return as their result the result of
- adding, subtracting, multiplying or dividing
the two numbers.
654.8 (2)
(2) Analysis We calculated three of these
in Example 3.4, and we can easily confirm that
the result of dividing (x1, y1) by (x2, y2) is
((x1x2 y1y2)/(x22 y22), (x2y1 - x1y2)/(x22
y22)). All that is necessary,
therefore, is to define a module containing the
definition of the derived data type and use this
in each of the four functions.
664.8 (3)
(3) Solution (p113.f) MODULE complex_data
IMPLICIT NONE SAVE ! This module
defines a complex data derived data type
TYPE complex_number REAL real_part,
imag_part END TYPE complex_number
END MODULE complex_data
674.8 (4)
FUNCTION c_add(z1,z2) USE complex_data
IMPLICIT NONE ! Declare function type and
dummy arguments TYPE(complex_number) c_add
TYPE(complex_number), INTENT(IN) z1, z2
! Calculate function result c_addreal_part
z1real_part z2real_part c_addimag_part
z1imag_part z2imag_part END FUNCTION c_add
684.8 (5)
FUNCTION c_sub(z1,z2) USE complex_data
IMPLICIT NONE ! Declare function type and
dummy arguments TYPE (complex_number)
c_sub TYPE (complex_number), INTENT(IN)
z1,z2 ! Calculate function result
c_subreal_part z1real_part - z2real_part
c_subimag_part z1imag_part - z2imag_part
END FUNCTION c_sub
694.8 (6)
FUNCTION c_mult(z1,z2) USE complex_data IMPLICIT
NONE ! Declare function type and dummy
arguments TYPE (complex_number)
c_mult TYPE (complex_number), INTENT(IN) z1,
z2 ! Calculate function result
c_multreal_part z1real_partz2real_part -
z1imag_partz2imag_part c_multimag_part
z1real_partz2imag_part
z1imag_partz2real_part END FUNCTION
c_mult
704.8 (7)
FUNCTION c_div(z1,z2) USE complex_data
IMPLICIT NONE ! Declare function type and
dummy arguments TYPE(complex_number) c_div
TYPE(complex_number), INTENT(IN) z1, z2 !
Local variable to save calculating denominator
twice REAL denom ! Calculate function
result denom z2real_part2
z2imag_part2 c_divreal_part
(z1real_partz2real_part
z1imag_partz2imag_part)/denom
c_divimag_part (z2real_partz1imag_part -
z1real_partz2imag_part)/denom END FUNCTION
c_div
714.8 (8)
Any program or procedure that wishes to use these
functions need to use the same module to access
to the complex_number data type PROGRAM
complex_example USE complex_data IMPLICIT
NONE ! Declare external functions
TYPE(complex_number), EXTERNAL c_add, c_sub,
c_mult, c_div ! Declare two complex
variables TYPE(complex_number) z1, z2
724.8 (9)
! Read data PRINT , "Please supply two
complex numbers as two pairs of
numbers" PRINT , "Each pair represents the
real and imaginary parts of a
complex number" READ , z1, z2
! Calculate and print sum, difference, product
and quotient PRINT , "The sum of the two
numbers is ", c_add(z1, z2) PRINT , "The
difference between the two numbers is ",
c_sub(z1, z2) PRINT , "The product
of the two numbers is ", c_mult(z1, z2)
PRINT , "The result of dividing the first
number by the second is ",
c_div(z1, z2) END PROGRAM complex_example
734.9 Modules and explicit procedure interfaces
Traditionally, the calling program unit knew
nothing about the procedure, and vice versa.
The called procedure is said to have an
implicit interface. Some of the most powerful
features of Fortran 90 can only work if they
have a full knowledge of any relevant procedure
interfaces. This requires that the procedures
concerned have an explicit interface. We can
make the interface of a procedure explicit, by
placing the procedure in a module. Interfaces
of all the procedures explicit to each other.
Explicit in the program unit.
744.9 (2)
There is one additional statement required in a
module that contains a procedure. This
statement consists of the single
word CONTAINS Which must be placed before the
first procedure within a module.
754.9 (3)
MODULE my_procedures IMPLICIT NONE CONTAINS
SUBROUTINE problem_sub(arg1,arg2,arg3)
IMPLICIT NONE ! This subroutine
returns the product of its first two !
arguments via the third argument INTEGER
arg1, arg2, arg3 arg3 arg1arg2
END SUBROUTINE problem_sub END MODULE
my_procedures
764.9 (4)
The program that called the subroutine would USE
this module PROGRAM intent_demonstration USE
my_procedures IMPLICIT NONE INTEGER,
PARAMETER a2 INTEGER b3, c4, d
CALL problem_sub(a, b, c) CALL
problem_sub(b, c, d) END PROGRAM
intent_demonstration All procedures are
encapsulated in a module.
774.9 (5)
EXAMPLE 4.5 (1) Problem In Example 3.3 we
created two geometric derived types, point and
line, and wrote a program to determine the line
joining two points. Rewrite this example so
that the types are stored in a module, and
the line is determined by a procedure which
is stored in another module. (We shall add
further types and procedures to these two modules
in later chapters.) (2) Analysis 1 Read
coordinates of two points 2 Call subroutine
(line_two_points) to calculate the line joining
the points 3 Print the equation of the line
784.9 (6)
Subroutine line_two_points(line_1,point_1,point_2)
TYPE(line) line_1 TYPE(point) point_1,
point_2 1 Calculate coefficients of the line
joining the points.
794.9 (7)
(3) Solution MODULE geometric_data IMPLICI
T NONE SAVE ! Type definitions
TYPE point REAL x, y !
Cartesian coordinates of the point END TYPE
point TYPE line REAL a,
b, c ! coefficients of defining equation
END TYPE line END MODULE geometric_data
804.9 (8)
MODULE geometric_procedures USE
geometric_data IMPLICIT NONE CONTAINS
SUBROUTINE line_two_points(line_1, point_1,
point_2) IMPLICIT NONE ! Dummy
arguments TYPE(line), INTENT(OUT)
line_1 TYPE(point), INTENT(IN)
point_1, point_2 ! Calculate
coefficients of equation representing the line
line_1a point_2y - point_1y
line_1b point_1x - point_2x
line_1c point_1ypoint_2x -
point_2y point_1x END SUBROUTINE
line_two_points END MODULE geometric_procedures
814.9 (9)
PROGRAM geometry USE geometric_procedures
IMPLICIT NONE ! A program to test the
subroutine line_two_points ! Variable
declarations TYPE(point) p1, p2
TYPE(line) p1_to_p2 ! Read data
PRINT , "Please type coordinates of first
point" READ , p1 PRINT , "Please type
coordinates of second point" READ , p2
824.9 (10)
! Call procedure to calculate the equation of
the line CALL line_two_points(p1_to_p2, p1,
p2) ! Print result PRINT , "The
equation of the line joining these two points is"
PRINT , "ax by c 0" PRINT ,
"where a ", p1_to_p2a PRINT , "
b ", p1_to_p2b PRINT , " c
", p1_to_p2c END PROGRAM Geometry
834.10 Modules as an aid to program design
Structure plan another important aspect of
programming is the design of the program's data
structure. All procedures that require access to
a particular group can do so by simply using
the appropriate module.
844.10 (2)
Purpose Type Name A Global data types
Date (day, month, year) Int, Int, Int date
Time (hours, mins, secs) Int, Int,
Real time B Global data Date of
experiment date experiment_date Times at
start and end of time start_time
experiment end_time Sample
number INTEGER sample_number Material
type CHARACTER20 material_type
Measurements 1-4 at start REAL start_measuremen
t_1 , etc. Measurements 1-4 at
end REAL end_measurement_1 , etc.
Stats measurements 1-3 REAL stats_measurement_1
, etc. Properties 1-4 REAL proper
ty_l, ... etc.
854.10 (3)
This information could all be encapsulated in a
module, such as MODULE data_design IMPLICIT
NONE ! Declare derived types TYPE date
INTEGER day, month, year END TYPE
date TYPE time INTEGER hours, mins
REAL seconds END TYPE time
864.10 (4)
! Declare global variables TYPE(date)
experiment_date TYPE(time) start_time,
end_time INTEGER sample_number
CHARACTER(LEN20) material_type REAL
start_measurement_1, start_measurement_2,
start_measurement_3,
start_measurement_4,
end_measurement_1, end_measurement_2,
end_measurement_3, end_measurement_4,
stats_measurement_1,
stats_measurement_2,
stats_measurement_3, property_1, property_2,
property_3, property_4 END MODULE
data_design
874.10 (5)
SUBROUTINE output_data USE data_design IMPLICIT
NONE PRINT , "Experiment conducted on ",
experiment_dateday, /,
experiment_datemonth,"/",
experiment_dateyear PRINT , "At start
time (", start_timehours, "",
start_timemins, "", start_timesecs, ")
measurements were" PRINT ,
start_measurement_1 PRINT , start_measurement_2
PRINT , start_measurement_3 PRINT ,
start_measurement_4 .
88Main Program
- PROGRAM experiments
- USE data_design
- IMPLICIT NONE
- CALL input_data
- CALL output_data
- END PROGRAM experiments