Content of the lesson:
A procedure is a separated part of a program which should deal with a problem (see the term procedural programming). Procedures are used often in these cases:
The syntax consists of the header (keyword procedure, name of the procedure and also parameters which are not required). Then you can declare variables for your procedure and finally you can write commands between keywords begin and end.
procedure name (procedure parameters);
//parameters are optional
var variables //variables are optional
begin
commands
end;
Consider the program from the previous lesson which loaded any number of values into a 2D array and then wrote the array to screen.
Program NaplneniAVypisPole;
const n = 5000;
type pole = array[1..5000]of integer;
var p:pole;
i, pocet:integer;
begin
writeln('Enter the number of values to be inserted (1-',n,')');
readln(pocet);
while ((pocet<1) or (pocet>n)) do
begin
writeln('Enter the number again:');
readln(pocet);
end;
for i:=1 to pocet do
begin
readln(p[i]);
end;
for i:=1 to pocet do
begin
writeln(p[i]);
end;
readln;
end.
This program can be divided into the following sequence of steps:
The program is relatively short but if you see it the first time you will need some time to orientate into it and to understand its principles and functionality. This could be a problem in case that more programmers work together on a project. They should write the source code to be understandable to any colleague. We are going to divide our program:
Dividing it into steps means creating a transcription of every part into a procedure:
procedure zadanipoctucisel;
begin
writeln('Enter the number of values to be inserted (1-',n,')');
readln(pocet);
while ((pocet<1) or (pocet>n)) do
begin
writeln('Enter the number again:');
readln(pocet);
end;
end;
procedure vlozenicisel;
begin
for i:=1 to pocet do
begin
readln(p[i]);
end;
end;
procedure vypiscisel;
begin
for i:=1 to pocet do
begin
writeln(p[i]);
end;
readln;
end;
You got three simple procedures (programs) after dividing our source code and you can re-write your program by assembling these parts together. Move the procedures above the keyword begin in the main program and write only the name of the procedure instead of commands in the main part. Inserting the name of each procedure inside the main part will insert its commands to the main part (to the place where you inserted the name).
Program NaplneniAVypisPole;
const n = 5000;
type pole = array[1..5000]of integer;
var p:pole;
i, pocet:integer;
procedure zadanipoctucisel;
begin
writeln('Enter the number of values to be inserted (1-',n,')');
readln(pocet);
while ((pocet<1) or (pocet>n)) do
begin
writeln('Enter the number again:');
readln(pocet);
end;
end;
procedure vlozenicisel;
begin
for i:=1 to pocet do
begin
readln(p[i]);
end;
end;
procedure vypiscisel;
begin
for i:=1 to pocet do
begin
writeln(p[i]);
end;
readln;
end;
begin
zadanipoctucisel;
vlozenicisel;
vypiscisel;
end.
You can see that the program contains a standard header with defined variables, then the declaration of each procedure and finally the main part which runs the procedures as needed. The main part can of course contain any other commands between the calls to procedures.
To summarize our job, we have created a program with only 3 commands in the main part: zadanipoctucisel, vlozenicisel, vypiscisel. It is absolutely clear what is done and in case of any modification you only have to modify one procedure, not the whole program. You saw one of three situations when you should use procedures for your own good: if you want to make your program well-arranged you should divide the source code to procedures (parts).
Take a look at the illustration of the second possible usage of procedures (if a complex command or set of commands is repeated inside a program). Consider writing a simple program to compute the sum of two numbers (you can use procedures of course to compute complex mathematical formulas but a simple example is enough).
Program Soucet_cisel;
var a,b:integer;
begin
writeln('Enter number a:');
readln(a);
writeln('Enter number b:');
readln(b);
writeln('The sum of numbers ',a,' and ',b,' is ',a+b,'.');
readln;
end.
Try to explain this program in your words and divide it into steps as we did with the previous one.
The program can be logically divided into these sequences of steps (variant A):
or the variant B:
You can see the further process using both variants (they are compared).
procedure zadanicisel;
begin
writeln('Enter number a:');
readln(a);
writeln('Enter number b:');
readln(b);
end;
procedure vypocetsouctucisel;
begin
writeln('The sum of numbers ',a,' and ',b,' is ',a+b,'.');
end;
procedure zadanicislaa;
begin
writeln('Enter number a:');
readln(a);
end;
procedure zadanicislab;
begin
writeln('Enter number b:');
readln(b);
end;
procedure vypocetsouctucisel;
begin
writeln('The sum of numbers ',a,' and ',b,' is ',a+b,'.');
end;
Which variant is better and why?
Whether you have chosen the variant A or the variant B, a part of the code is repeated. This is not suitable because in case you want to change anything, you have to change it twice (or even more times - it depends on the final appearance of your source code). You can make a mistake when trying to change something and forget to do some changes (these mistakes are the worst ones because it is difficult to find them). If you, for example, want to change the text "Enter number b:" to "Enter required number:", you have to make two changes in both variants - you solve the same problem at two (or even more) places.
Try to adjust the previous program (any variant) to let it load two different couples of numbers (for example couples a,b and c,d). Then the program computes the sums of both couples (sum of a+b and c+d).
The final program can look like the following one:
Program Soucet_cisel;
var a,b,c,d:integer;
procedure zadanicisel;
begin
writeln('Enter number a:');
readln(a);
writeln('Enter number b:');
readln(b);
writeln('Enter number c:');
readln(c);
writeln('Enter number d:');
readln(d);
end;
procedure vypocetsouctucisel;
begin
writeln('The sum of numbers ',a,' a ',b,' is ',a+b,'.');
writeln('The sum of numbers ',c,' a ',d,' is ',c+d,'.');
end;
begin
zadanicisel;
vypocetsouctucisel;
end.
Program Soucet_cisel;
var a,b,c,d:integer;
procedure zadaniciselab;
begin
writeln('Enter number a:');
readln(a);
writeln('Enter number b:');
readln(b);
end;
procedure zadaniciselcd;
begin
writeln('Enter number c:');
readln(c);
writeln('Enter number d:');
readln(d);
end;
procedure vypocetsouctucisel;
begin
writeln('The sum of numbers ',a,' a ',b,' is ',a+b,'.');
writeln('The sum of numbers ',c,' a ',d,' is ',c+d,'.');
end;
begin
zadaniciselab;
zadaniciselcd;
vypocetsouctucisel;
end.
Take a look at the both variants:
In the variant A you can see that we use the same command for inserting number 4 times in the procedure zadanicisel (we ignore the names of variables a, b, c, d which is generally acceptable) and also we use the same command twice in the procedure vypocetsouctucisel (using only different couples of variables).
In the variant B you can see a similar problem only divided to two generally identical procedures zadaniciselab and zadaniciselcd.
The program is well-arranged after adding procedures but there are many duplicated commands. Imagine a program to compute a sum of every possible couple from 4 variables (ab, cd, ca, bd... - 8 possible couples). We can also use 10 variables like number1,...,number10 or any other procedure using more variables (for example 100 variables). The program would be extremely long because of all possible combinations and it would become complicated and you probably would not be able to realize it (imagine a program computing sums of every couples for an array of 15000 items). You can solve all these problems using so called parameters.
A parameter is a variable which is sent inside a procedure and this procedure can use it. Take a look at the following example:
Program Soucet_cisel;
var a,b,c,d:integer;
procedure zadanicisla(var cislo:integer);
begin
writeln('Enter number:');
readln(cislo);
end;
procedure vypocetsouctudvoucisel(var cislo1,cislo2:integer);
begin
writeln('The sum of numbers is ',(cislo1+cislo2),'.');
end;
begin
zadanicisla(a);
zadanicisla(b);
vypocetsouctucisel(a,b);
end.
You can see that there are additional brackets in the head of the procedure zadanicisla with the parameter cislo (declared variable cislo). This tells the procedure to expect an integer parameter when being called. If you want to use such a procedure, you have to write its full name inside the program and put a variable inside brackets to define the parameter. Using the notation of zadanicisla(a); you order your program to launch the procedure zadanicisla using the a variable. All actions done to the variable cislo are in fact done to the variable a. The variable a is in fact inserted inside the variable cislo inside the procedure zadanicisla. You will get a small program (procedure) which can load an integer variable into any variable which is set as the parameter (its name has to be written into brackets in the main program).
You can easily understand that using the notation zadanicisla(c) the variable c is loaded in the following program. Using the same way you can compute and write the sum using the notation vypocetsouctucisel(a,c). Thanks to procedures you can do this operation using variables of any types.
Program Soucet_cisel;
var a,b,c,d:integer;
procedure zadanicisla(var cislo:integer);
begin
writeln('Enter number:');
readln(cislo);
end;
procedure vypocetsouctudvoucisel(var cislo1,cislo2:integer);
begin
writeln('The sum of the numbers is ',(cislo1+cislo2),'.');
end;
begin
zadanicisla(a);
zadanicisla(b);
vypocetsouctucisel(a,b);
zadanicisla(c);
vypocetsouctucisel(a,c);
vypocetsouctucisel(c,b);
end.
Try to re-write the gomoku program from the previous lesson using procedures (you should divide your program to parts - ignore parameters).
Write a program which loads 5 numbers into p1 and p2 array. Then it writes both arrays to screen, sorts the p1 array and then writes both arrays to screen again.