Lecture 15 - Subroutines


Home


Objectives

Contents


1. Introduction

As programs become larger it become necessary to divide them into sub-tasks. This is necessary to:

So far we have indicated the sub-tasks in a program by separating it into sections, and used blank lines to separate these sections. However with the marks problem, validating the marks required the same code to be inserted in the program at different places (duplicate code). Inputting and validating a mark is an identifiable sub-task that could be written separately. A sub-program (called a subroutine or function in Basic) can be used to perform a sub-task. In this lecture we will look at writing subroutines and using pre-written functions.

2. Example 1 - Display a Rocket

Problem Description

Display a picture of a rocket composed of a triangle on top of two rectangles.

Example Run

Run
  *
 * *
*****
*****
*   *
*   *
*   *
*****
*****
*   *
*   *
*   *
*****
  *
 * *
*****

Outline the Problem

The rocket consists of a triangle, two equal sized rectangles and a triangle that is the same as the first one

Pseudo Code

displayRocket()
    displayTriangle()
    displayRectangle()
    displayRectangle()
    displayTriangle()
STOP
displayTriangle()
    Display "  *"
    Display " * *"
    Display "*****"
EXIT
displayRectangle()
    Display "*****"
    Display "*   *"
    Display "*   *"
    Display "*   *"
    Display "*****"
EXIT

How it Works

displayRocket()
└───┐
    displayTriangle() ────┐
                          displayTriangle()
                              Display "  *"
                              Display " * *"
                              Display "*****"
                          EXIT
    ┌─────────────────────┘
    displayRectangle() ───┐
                          displayRectangle()
                              Display "*****"
                              Display "*   *"
                              Display "*   *"
                              Display "*   *"
                              Display "*****"
                          EXIT
    ┌─────────────────────┘
    displayRectangle() ───┐
                          displayRectangle()
                              Display "*****"
                              Display "*   *"
                              Display "*   *"
                              Display "*   *"
                              Display "*****"
                          EXIT
    ┌─────────────────────┘
    displayTriangle() ────┐
                          displayTriangle()
                              Display "  *"
                              Display " * *"
                              Display "*****"
                          EXIT
┌─────────────────────────┘
STOP

Desk Check

1  displayRocket()
2      displayTriangle()
3      displayRectangle()
4      displayRectangle()
5      displayTriangle()
6  STOP
7  displayTriangle()
8      Display "  *"
9      Display " * *"
10     Display "*****"
11 EXIT
12 displayRectangle()
13     Display "*****"
14     Display "*   *"
15     Display "*   *"
16     Display "*   *"
17     Display "*****"
18 EXIT

Data: none

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Code

' Name: displayRocket
' Purpose: Display a picture of a rocket
' Author: Tim Whitfort

Sub Main()
    displayTriangle
    displayRectangle
    displayRectangle
    displayTriangle
End Sub


' Display a triangle
Sub displayTriangle()
    Debug.Print "  *"
    Debug.Print " * *"
    Debug.Print "*****"
End Sub


' Display a rectangle
Sub displayRectangle()
    Debug.Print "*****"
    Debug.Print "*   *"
    Debug.Print "*   *"
    Debug.Print "*   *"
    Debug.Print "*****"
End Sub

3. Subroutine Syntax

Pseudo Code

Calling a subroutine is executing the subroutine (do the instructions specified in the declaration)
Declaring
a subroutine is stating what it will do if it is called (a set of instructions)

Calling a subroutine

sub-name()

Declaring a subroutine

sub-name()
    statement
    statement
    ...
EXIT

Basic

Calling a subroutine

sub-name

Note: don't put () after the subroutine name when calling it.

Declaring a subroutine

Sub sub-name()
    statement
    statement
    ...
End Sub

In Basic, Main is a special subroutine. When a program is run it automatically runs the subroutine called Main. Main may then call other subroutines.

4. Local and Global Variables

Local Variables

When variables are declared inside a subroutine they can only be used inside that subroutine. Each time the subroutine finishes running the values held in the variables are lost. These are known as local variables. So far we have used local variables. This has worked as we have had only one subroutine, called Main.

Global variables

Variables that are declared outside of subroutines can be used throughout the whole program (module). The values held in the variables are remembered throughout the program run, and are lost when the program ends. Global variables are normally declared near the top of a program after the Option statements. Using global variables is one way to access variables that are used in more than one subroutine (other methods will be looked at in Programming Concepts).

Example Program Format

Option Compare Database
Option Explicit
' Declare global variables
Dim global-variable1 As datatype
Sub Main()
    ' Declare variables local to Main 
    Dim local-variable1 As datatype
    ' Code for Main
    OtherSub
End Sub

Sub OtherSub
    ' Declare variables local to OtherSub
    Dim local-variable2 As datatype
    ' Code for OtherSub
End Sub

5. Example 2 - Membership Problem Revisited

Problem Description

The club membership fee problem again with validation of input, and subroutines.

Defining Diagram

Inputs Processing Output
membershipType Input and validate the membershipType
Determine the membershipFee
Display membershipFee
Total the membershipFees
Display totalFees
membershipFee
totalFees

Outline the Solution

A WHILE loop is required for the main loop, with a sentinel value of "X" for the membershipType
A WHILE loop is required to validate the membershipType
Nested IFs are required to determine the membershipFee from the membershipType smallest.

Pseudo Code (without subroutines)

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Pseudo Code (WITH subroutines)

1  calcMembership()
2      totalFees = 0
3      inputMembershipType()
4      WHILE membershipType <> "X" DO
5          calcMembershipFee()
6          totalFees = totalFees + membershipFee
7          Display membershipFee
8          inputMembershipType()
9      ENDWHILE
10     Display totalFees
11 STOP
12 inputMembershipType()
13     Input membershipType
14     WHILE membershipType <> "F" AND membershipType <> "J" AND
            membershipType <> "L" AND membershipType <> "X" DO
15         Display "Error: membership type must be F, J, L or X"
16         Input membershipType
17     ENDWHILE
18 EXIT

19 calcMembershipFee()
20     IF membershipType = "F" THEN
21         membershipFee = 160
22     ELSE
23         IF membershipType = "J" THEN
24             membershipFee = 80
25         ELSE
26             membershipFee = 10
27         ENDIF
28     ENDIF
29 EXIT

Discussion

The program main (or mainline) is now simplified, showing the main things the program does rather than showing a lot of detail. If details of the subroutines are required, then the programmer can look at the appropriate subroutine. Each subroutine is a simple, easy to check and performs one sub-task. The names of the subroutines should accurately describe what the subroutine does.

inputMembershipType() - this is an identifiable sub-task that asks the user to input the membershipType and validates it. This occurs twice, allows the same code to be-used, rather than duplicated.
calcMembershipFee() - is an identifiable sub-task to calculate a membership fee based on the membershipType.

Data Dictionary

Name Data Type Description
membershipFee Double The membership fee for a club member in $
membershipType String The type of membership in the club. F=Full, J=Junior, L=Life.
totalFees Double The total fees for all members input in $

Desk Check

Inputs: membershipType = J; Correct results: membershipFee = 80
Inputs: membershipType = X; Correct results: totalFees = 80

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Code

' Name: calcMembership
' Purpose: Calculate and total the membership fees for club members
' Author: Tim Whitfort

Option Compare Database
Option Explicit

' Global variable declarations. These variables can be used throughout the program
Dim membershipFee As Double
Dim membershipType As String
Dim totalFees As Double

' The main subroutine. This is to be executed first
Sub Main()
    ' Local variable declaration. This variable can be used in this subroutine
    Dim totalFees As Double

    totalFees = 0

    ' Call the inputMembershipType subroutine
    inputMembershipType

    While membershipType <> "X"
        ' Call the calcMembershipFee subroutine
        calcMembershipFee
        ' Total the fees so far
        totalFees = totalFees + membershipFee
        ' Display the membership fee for the member
        Debug.Print "Membership fee = "; membershipFee
        ' Call the inputMembershipType subroutine
        inputMembershipType
    Wend

    ' Display the total fees for members input
    Debug.Print "Total fees = "; totalFees
End Sub

' Input and validate a membership type
Sub inputMembershipType()
    membershipType = InputBox("Membership type (F=Full, J=Junior, L=Life, X=eXit) ?")
    While membershipType <> "F" And membershipType <> "J" And _
          membershipType <> "L" And membershipType <> "X"
        Debug.Print "Error: membership type must be F, J, L or X"
        membershipType = InputBox("Membership type (F=Full, J=Junior, L=Life, X=eXit) ?")
    Wend
End Sub

' Determine the membership fee based on the membership type
Sub calcMembershipFee()
    If membershipType = "F" Then
        membershipFee = 160
    Else
        If membershipType = "J" Then
            membershipFee = 80
        Else
            membershipFee = 10
        End If
    End If
End Sub

Key Points

Further Reading


Written by Tim Whitfort.