Remember that before reaching this step you have produced a written description of the of the problem. This design document lists:
I usually do this at a keyboard so that I can easily copy this information into program comments.
Refering to your design document, you must decide what information will be required by each unit of the program, and how it will be shared between the program units to accomplish the overall goal of the program. The first thing you should learn about communication between program units is that simply giving a variable in one unit the same name as a variable in another program unit will not result in communication of the value of that variable between units. Both Intel and MicroSoft may have employees named John Smith, but they are probably not the same person with the same knowledge. A variable named "a" in SUBROUTINE "input" will not refer to the same location in the computer memory as a variable with the same name in SUBROUTINE "add", unless you take special action in your program to insure that these separate program units recognize "a" as the same location in memory.
The simplest way to share information in Fortran 90 is through the MODULE program unit. The first statement in this unit begins with word "module" and is followed by an arbitrary, but unique name for the MODULE (you can define and use as many MODULEs as you want). The MODULE must end with and END (or END MODULE) statement. In between you include type statements for all variables that you want to share. The program units that need these shared variables access them with the USE statement. Simply include a line immediately after the start of your program unit (after the PROGRAM, SUBROUTINE, MODULE, FUNCTION or BLOCKDATA statement) statement beginning with "use" and followed by the name of the module that you want to use. If you inadvertently do something like place the IMPLICIT NONE statement before the USE statements, the program won't compile.
Using the above program unit, the program to read two numbers, add them, and print the result could be written as below.
module global implicit none real a,b,s c a - one of the numbers to be added c b - the other number to be added c s - the sum of a and b end module global c program add2 c implicit none c c use subroutine input to get the values for a and b c call input c c find the sum of and b c call add c c use the subroutine output to send the results to the screen c call output stop end c subroutine add use global implicit none c c Add two numbers and store the sum in "s" c s = a + b return end c subroutine input use global implicit none print *, ' This program adds 2 real numbers' print *, ' Type them in now separated by a comma or space' c c Now read the numbers that are typed by the user c this Fortran read will wait until the numbers are typed c read *, a,b return end c subroutine output use global implicit none c c Print out the results with a description c print *, ' The sum of ', a,' and ' , b print *, ' is ' , s return end
Note that one program unit immediately follows the END statement of a previous unit. Also note that the SUBROUTINEs are not necessarily entered in the same order that they are called. Order of program units in your program file is not particularly important to the compiler. However, when using a single file for your program, one good practice is to start with your MODULEs, follow with the main program, and then provide other program units (SUBROUTINEs and FUNCTIONs) in the alphabetical order of their names. Later, we will learn that you don't have to limit yourself to a single disk file for your program. It is very common to put each program unit in its own file, and to let the compiler combine the contents of all files into a single executable program.
This business of using program units really isn't very complicated. I recommend that once you decide how your are going to split up the tasks and shared data in your program, you start by simply typing a framework of your program consisting of the program unit statements (MODULE, PROGRAM, SUBROUTINE, ...) and associated END statements. Then fill in the statements that assign data types and do the work.
As an example of this approach consider an exercise specified to add 3 numbers. Your program must ask the user for 3 numbers, read them as REAL numbers, add them together, and print out the result. For practice with modules you are to communicate the 3 input numbers to the addition subprogram with one MODULE, and the result to the output subprogram with a second MODULE.
I would first develop the framework for the program with the following coding.
module invalues end module module result end module program add3 end subroutine add end subroutine input end subroutine output end
Next I would add IMPLICIT NONE statements to program units containing executable statements. I could also add them to the MODULEs, but they don't have any advantage in this instance. At the same time I check to see which program units need access to which shared variables. I add type statements for these variables in the MODULEs and add the appropriate USE statements to the program units using these modules. I don't use any modules in the main program, because it doesn't directly use any of the variables. I use "invalues" in the subroutine "output", because it will also reflect the input values. I could have passed this over if "input" had taken care of this print to the screen. All of this can be done fairly quickly with the help of text editor copy and past commands (in vi "yy" and "p").
module invalues real a,b,c end module module result real s end module program add3 implicit none end subroutine add use invalues use result implicit none end subroutine input use invalues implicit none end subroutine output use invalues use result implicit none end
Now it's time to do the real work. I fill in the executable statements in my main program and each SUBROUTINE.
module invalues real a,b,c end module module result real s end module program add3 implicit none call input call add call output stop end subroutine add use invalues use result implicit none s = a + b + c return end subroutine input use invalues implicit none print *, ' This program adds 3 real numbers' print *, ' Type them in now separated by a comma or space' read *, a,b,c return end subroutine output use invalues use result implicit none print *, ' The sum of ', a, ', ',b , ' and ' , c print *, ' is ' , s return end
Finally I add comments (generally with cut and paste from my design document), so that I can figure out what I was trying to do when I try to modify the program in six months, or at the very least add comments so that I can pass the programming course. The comments provide definitions of all significant variables, list the purpose of the program and all subprograms, identify the programmer and modification history, and describe key blocks of code.
module invalues real a,b,c c a - one of the numbers to be added c b - the second number to be added c c - the third number to be added end module c module result real s c s - the result of the calculation end module c program add3 c c Program to add 3 numbers c John Mahaffy 11/2/96 c implicit none c c use subroutine input to get the values for a, b, and c c call input c c find the sum of and b c call add c c use the subroutine output to send the results to the screen c call output stop end c subroutine add c c Perform addition of 3 numbers c John Mahaffy 11/2/96 c use invalues use result implicit none c c Add three numbers and store the sum in "s" c s = a + b + c return end c subroutine input c c Obtain user input c John Mahaffy 11/2/96 c use invalues implicit none c c Prompt for and read three numbers for addition c this Fortran read will wait until the numbers are typed c print *, ' This program adds 3 real numbers' print *, ' Type them in now separated by a comma or space' read *, a,b,c return end c subroutine output use invalues use result implicit none c c Print out the results with a description c John Mahaffy 11/2/96 c print *, ' The sum of ', a, ', ',b , ' and ' , c print *, ' is ' , s return end
In a program of normal complexity, the solution procedure is often complex enough to justify splitting it into several subprograms corresponding to the stages of the solution. Frequently this results in a multi-layered program with one or more solution subprograms references other subprograms to handle low level steps of the solution. When the program is a complex application, the input and output steps are also broken into multiple subprograms. For these large programs this division facilitates a project employing multiple programmers.
Authored by John Mahaffy and Jason Wehr Maintained by John Mahaffy : jhm@cac.psu.edu