Procedures – Chapter 4

Procedures provide a means of encapsulating chunks of code. We have already seen two kinds of procedures, event procedures and built-in functions. In this section we will look at general procedures.

Procedures have two primary purposes:

1. To allow frequently used operations (sequences of statements) to be used without requiring multiple copies of the code. This simplifies the actual writing of the code and, more importantly, simplifies maintenance of the code.

2. To provide a mechanism for abstraction. Abstraction can be defined as focusing only on the aspects of something that are relevant to the problem at hand.

Consider the Sqr() built in function:

1. This is a frequently used operation, we do not want to have to rewrite (or even copy) the code to do it every time we want a square root.

2. We are not interested in the details of how the square root is calculated. We just want to know that when we specify Sqr(n), we get the square root of n.

Abstraction is a key concept in programming languages. Traditionally we think of data abstraction and procedural abstraction. Data abstraction is the process of focusing on the relevant elements of the data items that we deal with. Procedural abstraction is the process of focusing on the relevant parts of the operations that are performed. For example, the statements in a programming language like VB are abstractions of the underlying operations actually performed by the computer. Data and procedural abstraction come together in Abstract Data Types and object oriented programming.

Procedural abstraction is the basis of top down structured program design. Essentially, we subdivide the problem into smaller sub-problems to be solved. We then analyze and subdivide the sub-problems into even smaller problems. We continue this process until the sub-problems are small enough to solve easily.

Procedures are one of the methods used to implement structured designs. They allow the code from the sub-programs to be encapsulated.

This has several benefits including:

1. Abstraction. Details of the implementation not relevant at a particular level are hidden, making the code at that level easier to understand.

2. Smaller sections of code are easier to understand, so they are easier to write, verify and maintain.

3. They can be developed independently by different programmers.

4. They can be reused in the same program and in other programs.

Sub-Programs (Section 4.1)

We will look at two kinds of general procedures; sub-programs and functions. Note that most programming languages use the term sub-program to refer the general case and procedures to refer to sub-programs that do not evaluate to some value (ie are not functions), Visual Basic does the opposite.

Functions we have encountered when we looked at built-in functions. They are procedures that evaluate to some value. They can be used in expressions just like constants or variables. Sub-programs do not evaluate to values.

Sub-programs are named sequences of statements that can be called using a Call statement from another sequence of statements.

Consider the following example:

Private Sub cmdAdd_Click()

Dim num1 As Single, num2 As Single

' Display the sum of two numbers

picResult.Cls

picResult.Print "This program displays a sentence"

picResult.Print "identifying two numbers and their sum"

picResult.Print

Let num1 = 2

Let num2 = 3

picResult.Print "The sum of"; num1; "and"; num2; "is"; num1 + num2

End Sub

This event procedure has two main components

1. display a message explaining its purpose

2. display two numbers and their sum in a particular format

We can implement these functions as two sub-routines. First we will look at a sub-routine to display a message explaining the purpose.

We simply take the two lines of code that display the strings and put them into a sub-program called ExplainPurpose.

Private Sub ExplainPurpose()

' Explain the task performed by the program

picResult.Print "This program displays a sentence"

picResult.Print "identifying two numbers and their sum"

End Sub

There are two ways to create a sub-program. The easiest is to just type:

Private Sub subName()

anywhere outside of other the procedures (ie not between Private Sub and End Sub). An End Sub is automatically generated. Alternately, you can select Add Procedure from the Tools menu and fill in the appropriate boxes.

In either case, you then enter the statements between the Private Sub line and the End Sub.

The sub-routine will be put in the General code section. To edit the sub-routine, select General in the code box and then select the sub-program by name from the procedure box.

The rules for naming the sub-routine are the same as for naming variables. In the text they capitalize the first letter to distinguish sub-programs from variables.

The sub-program is invoked (or called) from the cmdAdd_Click event procedure using the Call statement:

Private Sub cmdAdd_Click()

Dim num1 As Single, num2 As Single

' Display the sum of two numbers

picResult.Cls

Call ExplainPurpose

picResult.Print

Let num1 = 2

Let num2 = 3

picResult.Print "The sum of"; num1; "and"; num2; "is"; num1 + num2

End Sub

The ExplainPurpose sub-program is quite simple, it simply executes a couple of statements and does not require information from the calling procedure and does not produce information required by the calling procedure.

In general, we may want to supply information to a procedure and get information out of a procedure. One method of doing this is parameter passing.

The second function of the cmdAdd_Click event procedure is to add and display the two numbers. We will also write a sub-program to handle this task, but we want to make the sub-program general, so we can use it to add any two numbers. We do this by specifying what numbers we want to add in a particular case as arguments to the sub-program call.

Private Sub cmdAdd_Click()

' Display the sum of two numbers

picResult.Cls

Call ExplainPurpose

picResult.Print

Call AddAndDisplay(2, 3)

End Sub

The sub-program must be written to accept the arguments. This is done by specifying parameters in the declaration. The parameters specify the order and type of values that will be passed to the sub-program.

Private Sub AddAndDisplay(num1 As Single, num2 As Single)

' Display the numbers and their sum

picResult.Print "The sum of"; num1; "and"; num2; "is"; num1 + num2

End Sub

The argument 2 corresponds to the parameter num1 and the argument 3 corresponds to the parameter num2, the types must match. The arguments can be constants, variables or expressions (anything that evaluates to the correct type).

If we look at the event procedure we see that it has become quite simple, making it easy to understand what happens when the command button is clicked. The event handling is no longer obscured by implementation details. In addition, the sub-programs that implement the details are small and self-contained, making them easy to write and maintain. These attributes are the basis of modular, top-down design.

The sub-programs also allow the procedures to be reused, either in the same program or in another program. For example to add more than one pair of numbers we can modify the event procedure to call the AddAndDisplay sub-program more than once.

4.2 Subroutines Part 2

Passing values back from subroutines

We have seen how to get values into subroutines, now we need to get values out. Consider the event procedure:

Private Sub cmdDisplay_Click()

Dim amt As Single

Let amt = 2

picResults.Print amt;

Call Triple(amt)

picResults.Print amt

End Sub

We want the sub-program Triple to triple the value of amt. (Note that we would probably use a function to do this in practice.)

Private Sub Triple(num As Single)

Let num = 3 * num

End Sub

Changing the value of the parameter num in the sub-program will change the value of the variable argument in the calling procedure. What the calling procedure passes to the sub-program is the actual memory location of the argument variable, so when the value is changed in the sub-program the value of the argument variable also changes. This is known as passing by reference. Parameters can also be passed by value. In this case the argument’s value is copied to the parameter variable, so changes in the procedure do not change the argument.

In the following example the parameters are used to get values from the first sub-program, to supply and get values from the second, and to supply values to the third.

Private Sub cmdCompute_Click()

Dim x As Single, y As Single, s As Single

Call GetNumbers(x, y)

Call CalculateSum(x, y, s)

Call DisplayResult(x, y, s)

End Sub

Private Sub GetNumbers(in1 As Single, in2 As Single)

Let in1 = Val(txtFirstNum.Text)

Let in2 = Val(txtSecondNum.Text)

End Sub

Private Sub CalculateSum(num1 As Single, num2 As Single, sum As Single)

Let sum = num1 + num2

End Sub

Private Sub DisplayResult(num1 As Single, num2 As Single, sum As Single)

picResult.Cls

picResult.Print num1; “+”; num2; “=”; sum

End Sub

Note that the arguments do not have to have the same name as the parameters. Also note the input, process, output structure.

Local Variables

Local variables are variables declared inside the procedure.

When the same variable name is declared in two different procedures, the variables have separate identities and are treated as two different variables. A value assigned to a variable in one procedure will not affect the value of a variable of the same name in another procedure.

Form Level Variables

Variables declared outside any procedure (in the General area) are form level variables.

Form level variables can be accessed inside any procedures in the form and keep the value assigned in one procedure can be accessed in another.

Since the values can be accessed across procedures, why not use these to pass values into and out of procedures?

In some cases we do. For example event procedures, where the interface is predetermined.

In general, use of form level variables makes the flow of data through the code hard to follow. It is also difficult to ensure that some other procedure does not change the value of the variable unexpectedly. (This is particularly a problem in event oriented programming, where the order in which the events are handled is determined by VB.)

The Form_Load event is automatically activated when the program is run (actually when the form is loaded, which, in a single form program, is the approximately the same thing). This is useful for initializing form level variables and other initialization tasks.