# Q

Students should attempt to write a program that efficiently prints all prime numbers up to a supplied number (primes are numbers that have no other factors other than 1 and themselves). There are many ways to accomplish this task - each of varying efficiency.

By now, students should have come to some sort of 'internal' agreement as to how they plan their programs - tasks will begin to get complex, leaping straight into Pascal is most unwise.

In most computer languages it is possible to define ACTIONS (called sub-programs or procedures), which can be called when needed. These modules can be used as many times as you want in a program - define them once, use them over and over.

Procedures are 'called' into action by mentioning their name - this usually is a statement in itself. It is possible to write modules that can be fed values at runtime (the values you feed are termed parameters) as part of the call. Procedures that do not reequire parameters are more primitive but can be just as useful.

A variation of a procedure is called a Function - these are typically part of a statement (ie. embedded in an expression)

### Parameter-less Processes

```   eg1:  procedure fiddleabout;
:

{\$R *DFM}
var   a,b    :  integer;

Procedure ExchangeThem;
{exchanges two variables' values}
var    t  :  integer;
begin
t := b;
b := a;
a := t
end;

begin
a:= 5;
b:= 30;
ExchangeThem;
showmessage('a = '+inttostr(a) +'   b = ' + inttostr(b));
if a > b
then  ExchangeThem;
showmessage('a = '+inttostr(a) +'   b = ' + inttostr(b));
end;```

In the above example, a and b are GLOBAL variables - they are owned by the main unit (they are declared under the {\$R *.DFM} compiler directive making them visible to all processes in this unit.

Although the sub-program (ExchangeThem) can see and use these global variables, it is generally NOT a good idea to do this due to the many and varied side-effects that can result.

You will notice that ExchangeThem has it's own var section that introdices t.t is a LOCAL variable - known only to ExchangeThem - the main program cannot see nor access it

You will also notice ExchangeThem is called twice in this program.

```   eg2:  procedure initialize;
procedure calcordercost;
:
Procedure Tform1.initialize;
{set up for a new order}
begin
label1.caption :='MUCKDONALDS';
label2.caption :='McChunder Burger';

numburgers := 0;
numfries := 0;
numshakes := 0;
{....etc}

Procedure Tform1.calcordercost;
{works out the cost of an order}
var temp : real;
begin
temp := numburgers*2.50 + numfries*1.25 + numshakes*2.10;
ordertotal.caption := floattostr(temp)
end;
```

Good programs have MODULES that break the task into smaller parts, making each of the parts independent (self contained). This simple action can vastly improve your program, making it easier to read and maintain (debug and add to)

```   eg3:  procedure displayanswer;
:
{\$R *.DFM}
var      j,k : real;

function     OneOnK : real;
begin
OneOnK := 1/k
end;

begin
j := 5;
k := j;
j := j * OneOnK;
showmessage('j = '+ inttostr(j) +' k = '+ inttostr(k))
end;```

This function preys on GLOBAL variables - this is unwise (and generally unheard of). You will notice the function is used in a different way to the procedure. Whereas a procedure call is a statement, a function call must be part of a statement

Good programmers aim to separate the code that tells the machine HOW to perform a task (some action or process) from the actual request to perform the task (ie. the 'site' of the call)

Very Important:

• always ensure that the function/procedure can be executed if called.
• make sure that your functions can return values in each instance that they are called.
• each function has a specific type
General Sub-Programs

## SUB-PROGRAMS WITH PARAMETERS

If you want to supply your procedure with a value to use in it's execution, or you want it to safely use variables owned by the main program, you should use parameters in your procedure definiition.

You either want your procedure to be handed a value to use (pass by value) or you want to hand your procedure a variable to manipulate (pass by reference).

Pass By Value - creating a 'one way link' to reliably hand values to a procedure without it preying on global variables.

```eg1.  Procedure TForm1.CountTo(num : integer);     {formal parameter}
{counts to the number supplied as num}
var   loop : integer;
temp : string
begin
temp := '';
for loop := 1 to num do
temp := temp + inttostr(loop) + ' ';
showmessage(temp)
end; {CountTo}```

could be called in another process as:

`  CountTo(5);`

```eg2.  TForm1.Function Factorial(num : integer) : integer;   {formal parameter}
{returns the factorial, num!, as num*num-i*num-2*...*1}
var   loop : integer;
begin
for loop := 1 to num do
end; {Factorial}```

could be called in another process as:

`  showmessage(inttostr(Factorial(6)+Factorial(3)));`

With Pass By Value, calls to the sub-program hand a value, or values, to be used locally.

```eg3.  Function EuclideanDist(x1,y1,x2,y2:integer) : real;
{calculates the distance between two points using
distance formula, and returns it as a real }

begin
EuclideanDist := sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1))
end; {euclidean distance}```

could be called in another process as:

`  showmessage(floattostr(EuclideanDist(3,8,7,5)));`

which will return and output the distance between the points (3,8) and (7,5).

Pass By Reference - where you provide a safe means of communication back to the body, by temporarily allowing a local variable to share the memory address of a another global variable.

```eg4:  Procedure Factorial(num : integer; var answer : integer);
{evaluates the factorial of num and returns it in answer}
var   loop : integer;
begin
for loop := 1 to num do
end; {Factorial}```

could be called in the main program as:

```    Factorial(thing,result);
showmessage('The factorial of' + inttostr(thing) +' = '+inttostr(result));```

Result and answer, at the time of the call temporarily share the same memory cell - what happens to answer in the procedure, also happens to result. When the procedure terminates, the resting value of answer remains in the memory cell known as result.

```eg5:  Procedure WhatASCII (ch : char ; var x : integer);
{returns to x the ASCII value of ch}
begin
x := ord(ch)
end;```

could be called in the main program as:

`  WhatASCII('Q',num);`

where num and x temporarily share the same memory location, and so after the procedure call has terminated, the result of the procedure is stored in num

Sending a value to a sub-program = Pass by Value, specifying a variable in a call and receiving a value back for it = Pass By Reference

```eg6:  Procedure Exchange(var a,b : integer);
{swaps two supplied variables and returns them swapped}
var t : integer;
begin
t := a; a:= b; b:= t
end;

Procedure Swapem(a,b : integer);
{swaps two supplied variables locally only}
var t : integer;
begin
t := a; a:= b; b:= t
end;

Begin
x := 1; y := 42;
Swapem(x, y); showmessage(inttostr(x)+'  '+inttostr(y));   {no effect}
Exchange(x, y); showmessage(inttostr(x)+'  '+inttostr(y)); {swapped}```

Pass by value can send expressions (ie. any expression that can be evaluated into a single value of the same type as the accepting parameter)

`eg:   WhatAscii(char(ord(x)*42-b), answer);`

Pass by reference can only send variable names (or pointers to memory locations)

### PROCEDURAL PROBLEMS

1. Side Effects
• A procedure inside another procedure may alter values defined in the ancestor.
• This causes problems that are almost impossible to locate
• beware of procedures that re-assign a global variable unexpectedly - good programs will not have such side effects
2. Environmental Dependence
• Most of the procedures encountered so far are ENVIRONMENTALLY DEPENDENT - that is they use global variables in the host program. This renders them NOT PORTABLE to other programs unless the same environmental conditions exist.
• A programmers aim is to build up a 'personal library' of environmentally independent, side-effect free procedures that can be imported into what ever program is currently being written if needed.
3. Identical Identifiers
• Syntactically, local variables (in procedures and functions) are allowed to be named the same as global variables. Sub-program local variables are stored in different places to globals. (control is abandoned by the body and so locals take over anyway)
• BUT readability should prevent us from doing this unless unavoidable.
Parameterised Sub-Programs

## SIMPLE RECURSION

recursion(re-ker-shun) v. - see recursion

```      Procedure TForm1.CountDownFrom (number:integer);
{performs a countdown to blastoff recursively}
begin
if number > 0
then
begin
showmessage(inttostr(number));
CountDownFrom(number-1)
end
else
showmessage('Blastoff')
end;

Procedure TForm1.button1click(sender :TObject);
begin
CountDownFrom(5)
end.```

wind-in going to a new call without completing the previous one
wind-back completing a call then moving back to work on a previously called but as yet un-completed one.

```      Function TForm1.pow(x, y : integer) : integer;
{returns x to the power of y recursively}
begin
if y = 0
then pow := 1
else pow := x * pow(x,y-1)
end;

Procedure TForm1.button1click(sender :TObject);
begin
showmessage(inttostr(pow(2,4)))
end;```

Before you get too excited by recursion, be warned that efficiency and memory may prohibit a recursive solution - the number of calls within calls may cause the program to run out of memory attempting to complete the task, or at least make it so inefficient that you would not use it. There are, however some problems that there is no other solution except for a recursive one (fortunately these are rare).

Recursive Sub-Programs

wonko@wonko.info