The final construct for directing the flow of control in a program is the subprogram. Subprograms are a way of grouping statements that provide a single logical operation. Actually, subprograms come in two varieties: procedures and functions.

Procedures

Procedures are like small versions of a program that perform a single logical task. A useful example of a procedure is the swap operation. Suppose we had a program that sorted an array of letters. A common operation for such a program is to swap the letters stored in two of the array cells so that they are put in alphabetical order. To put the entire array in sorted order, our sort program will need to make many swaps. In the example to the right, we can see that at least three more swaps will be needed to sort the array. In order to actually perform a swap, we will need to include the following three operations in our program.

temp := variable1
variable1 := variable2
variable2 := temp

Rather than writing the three statements for the swap operation every time, we can use a subprogram to group them together into a logical unit. Then whenever we need to swap the values of two variables, we can call the same swap procedure to do the work. The diagram below shows how the flow of control might look in our sorting program:

Notice how the flow of control changes when the Sort program calls Swap. At the start of the call, the flow of control is transferred to the procedure and once the procedure completes, the flow of control transfers back to the calling program. Also notice that the call to Swap includes some data that is not displayed in the diagram. These data are called parameters and they are represented by three dots in parentheses. In the next lesson, we will take a close look at parameters and how they are transferred to subprograms.

Functions

Functions are specialized subprograms that produce a single output as the result of their execution. You are probably already familiar with many functions from your study of mathematics. Operations like sine, cosine, exponential, square root, and logarithm are all functions that require a number as input and produce a number as output. The diagram below shows the square root function as a black box that takes 16 as an input parameter and returns 4 as the output:

Advantages of Subprograms

Two important advantages of using subprograms are reuse and abstraction. In our Sort program we saw how subprograms allow us to reuse the same code. Although the Sort program does many swaps, we only have to write the Swap procedure one time. Each call to Swap uses the same code that we wrote for the procedure. Because we are reusing this code, our Sort program is shorter and easier to read.

Using subprograms also allows us to incorporate abstraction into our programs. Abstraction is a way of simplifying the details of a program. When we think of a program abstractly, we only consider its functionality rather than the details of how it is implemented. One way to think about subprograms abstractly is to imagine them as black boxes that take a certain input, do some operations on it, and return some output. The animation below shows a function called Power represented as a black box. Click the button "Call Power" to execute the subprogram.

Now let's watch the animation again, but instead of seeing the abstract view, we will peek inside the black box to see what is happening. Following a program's execution in this way is called a program trace. Click the button "Trace Power" to trace the execution of the function.

These two animations should give you a good idea of how subprograms allow us to think abstractly. Abstraction is a very important tool for writing programs, especially when the programs are large and complex. Without some way of decomposing a program into logical units like subprograms, we would be overwhelmed with details! Just imagine how much trouble it would be to write a large mathematical program without having functions like Power. Every time we wanted to find the power of a number, we would have to rewrite the same code! Now you can see how beneficial subprograms are as tools for abstraction and reuse.