Earlier in this module it was stated that the primary philosophy of structured programming is to partition a large program into a number of smaller programs. Let's now look at a simple example of how this is done. Consider the GoForARide program from the previous lesson.
GoForARide
Put on cycling clothes
For 2 hours
Ride for 15 minutes
Drink from water bottle
Remove cycling clothes
Take a shower
The statement:
Drink from water bottle
seems pretty simple, but for the sake of discussion let us suppose that it involves the following.
If the water bottle is empty
Find a source of water
Open the water bottle
Fill it with water
Close the water bottle
Drink some water
Thus our GoForARide program really should be:
GoForARide2
Put on cycling clothes
For 2 hours
Ride for 15 minutes
If the water bottle is empty
Find a source of water
Open the water bottle
Fill it with water
Close the water bottle
Drink some water
Remove cycling clothes
Take a shower
This is starting to get a little complicated, so in order to simplify the program we might create a subprogram called DrinkFromWaterBottle that looks like:
DrinkFromWaterBottle
If the water bottle is empty
Find a source of water
Open the water bottle
Fill it with water
Close the water bottle
Drink some water
And then call this subprogram from our GoForARide program as in the following (roll your cursor over the highlighted line of code to see a graphic representation of this subprogram being executed):
Put on cycling clothes
For 2 hours
Ride for 15 minutes
Subprogram Execution
Subprogram Execution
As the name subprogram suggests, a subroutine behaves in much the same way as a computer program that is used as one component in a larger program or another subprogram. A subroutine is often coded so that it can be called several times from several places during execution of the main program, including from other subroutines, and then return to the next instruction after the initial call once the subroutine's task is completed.
How Subroutines are used in Fortran
In Fortran 2023, a subroutine does not encompass the full functionality of both procedures and functions.
✅ Procedures in Fortran
Subroutines
Functions
✅ Subroutines vs. Functions
Aspect
Subroutine
Function
Return value
No return value; uses arguments to return data
Returns a value via the function name
Usage in expressions
Cannot be used directly in expressions
Can be used in expressions
Call syntax
CALL mySub(args)
result = myFunc(args)
Side effects
Typically used for actions (I/O, modifying arguments)
Typically used for computing and returning values
In Fortran 2023:
A subroutine does not encompass the full functionality of a function.
Both are procedures, but each has distinct syntax and usage patterns.
In Fortran 2023, this distinction still holds and has not been merged.
Here is a Fortran 2023 program that performs Gaussian Elimination on a 3×3 matrix to reduce it to row echelon form:
✅ Features:
Written in Fortran 2023 syntax
Modular: separates the elimination logic into a subroutine
Uses real64 from iso_fortran_env for numerical precision
🔢 Program: Gaussian Elimination for 3×3 Matrix
program gaussian_elimination
use, intrinsic :: iso_fortran_env, only: real64
implicit none
real(real64) :: A(3,4) ! Augmented matrix [A|b], 3x3 matrix with RHS
integer :: i, j
! Sample 3x3 augmented matrix [A|b]
A = reshape([ &
2.0_real64, 1.0_real64, -1.0_real64, 8.0_real64, &
-3.0_real64, -1.0_real64, 2.0_real64, -11.0_real64, &
-2.0_real64, 1.0_real64, 2.0_real64, -3.0_real64 &
], shape(A))
print *, "Original matrix [A|b]:"
call print_matrix(A)
call gaussian_elim(A)
print *, "Row echelon form [A|b]:"
call print_matrix(A)
contains
subroutine gaussian_elim(A)
real(real64), intent(inout) :: A(3,4)
integer :: i, j, k
real(real64) :: factor
do i = 1, 2
! Partial pivoting (optional for stability)
do k = i + 1, 3
if (abs(A(k,i)) > abs(A(i,i))) then
call swap_rows(A, i, k)
end if
end do
! Eliminate below pivot
do j = i + 1, 3
factor = A(j,i) / A(i,i)
A(j,i:4) = A(j,i:4) - factor * A(i,i:4)
end do
end do
end subroutine gaussian_elim
subroutine swap_rows(A, row1, row2)
real(real64), intent(inout) :: A(3,4)
integer, intent(in) :: row1, row2
real(real64) :: temp_row(4)
temp_row = A(row1,:)
A(row1,:) = A(row2,:)
A(row2,:) = temp_row
end subroutine swap_rows
subroutine print_matrix(A)
real(real64), intent(in) :: A(3,4)
integer :: i
do i = 1, 3
print '(4F10.4)', A(i,:)
end do
end subroutine print_matrix
end program gaussian_elimination
Making the task of drinking from the water bottle a subprogram has noticeably simplified the GoForARide program, but there is an additional benefit in that the DrinkFromWaterBottle subprogram can be used in other programs as well. Imagine how this subprogram might be used in programs such as DoYardWork or GoForAHike. The next lesson concludes our look at the fundamental concepts of structured programming.
Structured Programming Terms
Unstructured programming: Tends to produce programs that are difficult to understand and expensive to maintain
Structured programming: A form of programming that breaks complex tasks into smaller, simpler tasks
Pseudocode: Outlines the logic of a program in structured English
Subprogram: A program within a program
Sequence: Performing tasks in a particular order
Decision: Conditionally performing a task
Repetition: Repeatedly performing a task
Structured programming is a programming paradigm aimed on improving the clarity, quality, and development time of a computer program by making extensive use of subroutines, block structures and repetition constructs. This is in contrast to using simple tests and jumps such as the goto statement which could lead to "spaghetti code" which is both difficult to follow and to maintain as was shown by Edsger Dijkstra .
Control Structures and Structured Program Theorem:
Following the structured program theorem, programs are seen as composed of control structures:
Sequence: ordered statements or subroutines executed in sequence.
Selection: one or a number of statements is executed depending on the state of the program. This is usually expressed with keywords such as if-then-else.
Iteration: a statement or block is executed until the program reaches a certain state, or operations have been applied to every element of a collection. This is usually expressed with keywords such as while, repeat, for or do..until.
Often it is recommended that each loop should only have one entry point and only one exit point.
Recursion: A statement is executed by repeatedly calling itself until termination conditions are met.
While similar in practice to iterative loops, recursive loops may not be more computationally efficient because the parameters rest on the local call stack.
Struktogram showing directional flow within a program
Struktogram showing conditional statement to determine which branch will be executed
[1]Subprogram: A program within a program. Also called a function, method, procedure, or subroutine.