Teaching Programming III

Copyright © by Mark Baker 1996

Return to Contents


Procedures and Functions

This section is crucial - students must become confident at writing procedures and functions if they are to become successful programmers. Calling a procedure seems to come naturally enough, but correct parameter passing and the distinction between a procedure and a function can cause lingering problems. Do not allow students to race through this phase as a shaky understanding of some of the finer points will lead to problems later.

One of the chief arts of a successful programmer is the ability to break a complex task into a series of procedures and functions. Modular programs offer many advantages. They are much more readable and much easier to debug, since problems can be more readily traced to a particular module, which can then be examined in depth. Modules can often be transferred to libraries and reused in other programs and once they have been written and debugged, they will not need debugging in the future. So as you build up your libraries, you should find that the amount of debugging you have to do, when you write new programs, decreases. Modular design also allows teams of programmers to work in parallel, as each one can take a different module to work on. Individual modules can be redesigned/upgraded, without the need to alter other parts of the program, provided that the module interface (the parameter list) remains unchanged.

Pascal allows you to write two types of module, a procedure and a function. They are similar, but there are important differences and it is important that you clearly understand them. A function is used when you want to return a single data item, such as a number, a string or a boolean value. A procedure is used when you do not want to return any values, or when you want to return more than one value, or when you want to return one or more data structures, such as an array or a record.

.
.
a:= MyAge;
b:= YourAge;
AveAge:= Average(a,b);                     {Average is a function, with 2 parameters, a and b}
ResetScreen;                               {This procedure has no parameters}
WriteTitles;                               {ResetScreen and WriteTitles are both procedures}
DrawGraph(ExamResultsArray, ValidError);   {DrawGraph is also a procedure}
.
.
Note that procedures and functions are called in different ways. A procedure is called by writing its name and any required parameters. A function always returns a value and that value normally has to be assigned somewhere. Functions can appear as part of various programming statements, replacing variables or constants:
writeln('The average age is: ', Average(a,b));


if > 50 then write ('Student has passed!')
  else if Average(mark1, mark2) = 50 then write ('Borderline student')
    else write ('Student has failed');


repeat
  
until (Average(score1, score2)>10) or (quit=true);

Parameters

The parameter list is the list of variables that are sent to a procedure or function when it is called. The parameters form the interface between the procedure or function and the module that calls it. A parameter may be used to send data into a module, to return data from it, or to do both. A parameter may be a simple, atomic data type, such as an integer or a character, or it may be a complex data structure, such as an array or a record.

AveScore:= Average(mark1,mark2)        {The parameters here are mark1 and mark2}
DrawGraph(ExamResultsArray,ValidError);{The parameters here are ExamResultsArray and ValidError}
Parameter passing can cause many problems, the worst of which is when the student gives up trying to use parameters and resorts to using global variables instead. This should be looked for and discouraged at all costs. Using global variables makes a program much harder to read and bugs are harder to find. Procedures/functions are no longer "independent" plug-in modules, but are tied to a particular program and cannot be transferred to a library unit. This can cause major problems in bigger programs. With Turbo Pascal, if the code generated by your main program reaches 64k in size, then the only way to continue programming is to transfer code into one or more units, each of which has a 64k limit.

The simplest of procedures may not have any parameters. For example, you may write a procedure to reset the screen at the end of your programs. This might involve resetting the background colour to black and the text colour to grey and clearing the screen. Such a procedure would not need any parameters:

{----------------------------------------------}
procedure ResetScreen;

  begin
  textbackground(0);
  textcolor(7);
  clrscr;
  end;
{----------------------------------------------}
However, most procedures and functions need parameters, either to pass data into them, to return data from them, or both.

Passing parameters by value

This is the simplest way of passing parameters. It allows values (numbers, characters, strings, etc.) to be passed into a procedure or function. Suppose you wanted to write a function that would return the largest of two integers. Clearly, you would have to pass the two integer values into the function:

{----------------------------------------------}
function Max(a,b: integer): integer;

var largest: integer;

  begin
  if a>b then largest:= a
    else largest:= b;
  Max:= largest;
  end;
{----------------------------------------------}
When this function is called, you have to pass it two integer values, which are copied into the local variables a and b, before the function starts to execute:
oldest:= Max(age1,age2);   {The value in age1 is copied into a and age2 is copied into b}

Passing parameters by reference

When a parameter is passed to a procedure by reference then any changes that are made to that parameter in the procedure are also made to the original parameter. For example, you may write an adapted form of the Max function, that only allows positive integers.
{----------------------------------------------}
procedure Max(a,b: integer; var largest: integer; var error: boolean);
  begin
  if (a<=0) or (b<=0) then error:= true
    else
      begin
      error:= false;
      if a>b then largest:= a
        else largest:= b;
      end;
  end;
{----------------------------------------------}
In the above example, a and b are being used to pass the two integer values into the procedure. largest and error are used to pass the results of the procedure back out. a and b are being passed by value and largest and error are being passed by reference. The var that appears in front of largest and error tells the compiler that these parameters are being passed by reference.

When a parameter is passed by reference, instead of copying a value into the local procedure or function variable, the memory reference saying where that parameter is stored in memory is passed in instead. The local variable then uses the same memory location, so that in effect any changes made inside the procedure or function are also made to the original parameter. Hence the term "pass by reference".

Creating a Library

Writing algorithms consists of two main processes. First of all the programmer must divide the task up into a series of smaller and smaller sub-tasks. Then when the sub-tasks are sufficiently small, the programmer must decide what instructions to use to achieve the desired effect. It is now time to create some library procedures. Each one is a small sub-task, the problem is to work out how to code them.

Getting students to create their own library, fairly early on in the course, emphasises the importance of modularity in programming and allows the students to start building up a resource of reusable code. Also, it is a vehicle for concentrating on "microprogramming", each procedure completes a single, clearly defined task. Most can be programmed in a few lines. It is the quality of thought that is important, with no need to produce a large program, with a complex interface. A simple test program that can call the library, is all that is needed as a framework. This exercise is designed to reinforce the fundamentals of programming and some students will need quite a lot of support during this exercise.

Students will need introducing to various string handling techniques, procedures and functions that will be needed for this exercise. I usually build up to this exercise by going through some algorithms in class and getting the students to work out what they do.

The Library Specification

Write a simple test program that calls a procedure called StarGow and try to write a procedure that meets the specification given below. When you have written and debugged this procedure, go on to each of the others in turn. When you have successfully written all of the modules outlined, you will then put them into a library (Turbo Pascal calls them a UNIT). The procedures and functions in this library can then be incorporated into any of your programs, by adding the library name to your USES list.

Procedure StarGow
Go to a given position, clear to the end of the line, write a *, followed by a given string, followed by another *.

Procedure StarLine
Go to a given Y coordinate and write a line of *'s across the screen.

Function StopsToSpaces
Take a string and replace any full stops with spaces.

Function StripLeadSpaces
Take a string and remove any leading spaces (spaces at the front of the string).

Function AllCaps
Take a string and convert all the letters to upper case (capitals).

Function StripSandS
Take a string and strip out any spaces and full stops.

Procedure MoveChar
Take a given character and make it appear to move across the screen.

Procedure MoveStr
Take a string and make it appear to move across the screen, stopping at a given position.

I take care to emphasise proper layout and indenting of programs. If students can be encouraged to indent properly from the beginning, it makes their work much more readable and debugging easier.

Creating a Turbo Pascal Unit (a library of functions and procedures)

To create the library, you must transfer the functions and procedures into a unit file, as outlined below.
unit MyUnit;   {The file should be saved with the file name MyUnit.pas, to match this line}

interface

uses crt,...etc;

procedure StarGow(x,y: integer; s: string);
procedure StarLine(y: integer);
function  StopsToSpaces(s: string): string;
*	
*	
*	etc.

implementation

{--------------------------------------------------------------------------------------}
procedure StarGow(x,y: integer; s: string);
  begin
  gotoxy(x,y);
  clreol;
  gotoxy(x,y);
  write('*',s,'*');
  end; 
{---------------------------------------------------------------------------------------}
procedure StarLine(y: integer);
*	
*	
*	
*  ...etc.	
  end;  {End of last procedure or function}
{---------------------------------------------------------------------------------------}

end.   {End of unit}

To use the unit you have created you will need to do the following:

  1. Compile the unit file to disc. This creates the .TPU machine code version of your library.
  2. Include the library name in the uses statement (uses MyUnit, ...,etc.) of any program that needs to access your library.

Return to Contents

Teaching Programming I
Teaching Programming II
Teaching Programming IV


Author: Mark Baker, e-mail mbaker@rmplc.co.uk
Last revision: 1st January 1997