Subprogramele in Pascal
In anumite
situatii, este necesar ca o sceventa de instructiuni sa se execute de mai multe
ori in cadrul unui program, eventual cu alte date; sau este nevoie pentru
usurarea algoritmului sa se faca impartirea unei probleme in subprobleme. O
astfel de secventa poate fi cuprinsa in cadrul uni modul de program numit subprogram. La aceste subprograme
referirea se face cu ajutorul unui nume si eventual parametri (adica date de
intrare si iesire pentru subprogramul respectiv).
In Pascal exista doua tipuri de
subprograme:
-
subprograme de tip procedura;
-
subprograme de tip functie.
Tot ca si o
clasificare: subprogramele pot fi predefinte de limbaj (sqrt(), val()) si
definite de programator. Noi ne vom ocupa de a doua categorie.
Indiferent de
tip, subprogramele trebuie declarate si definite in cadrul programului
principal inainte de blocul acestuia.
EX:
Program nume_principal;
USES unituri
CONST
declaratii_constante
TYPE declaratii_tipuri de date
VAR declarartii_variabile
Declaratii de proceduri si functii
BEGIN
{blocul
programului – unde apare apelul la subprogram}
END.
O declaratie de
subprogram se realizeaza in doua parti:
-
un antet de subprogram (care face
legatura intre programul principal si subprogram);
-
blocul subprogramului (care descrie
functionarea subprogramului).
1. Procedurile – se declara
astfel:
PROCEDURE
nume [(lista parametrilor formali)];
[Declaratii;]
Begin
{corpul procedurii}
End;
Unde nume=este
un identificator ce constituie numele simbolic dat de programator procedurii.
Lista parametrilor formali= este optionala (poate fi vida) si
precizeaza datele de care depinde subprogramul si tipul lor si are urmatoarea
forma:
([var] lista_variabile1:tip1;[var] lista_variabile2:tip2;……….);
Utilizarea
parametrilor formali confera subprogramelor capacitatea de a actiona
independent de contextul programului, dar se supun unor reguli:
-
in cadrul subprogramului se
manifesta ca orice variabila declarata la inceputul unui program;
-
pot fi date de intrare (fara var,
referirea la ele se face prin valoare) sau date de iesire (cu var, referirerea
la ele se face prin adresa)
-
nu pot fi declarati din nou in partea de
declaratii a procedurii;
Declaratii=procedura poate avea lista ei de declaratii in general
de variabile. In cazul in care in aceasta parte se declara alte subprograme
atunci avem de-a face cu subprograme imbricate. Toate declaratiile facute in
acest loc sunt locale subprogramului in care sunt declarate (adica lucrurile
definite aici nu au semnificatie decat in cadrul acestui subprogram.
Declaratiile facute in programul
principal se numesc globale si se vad si se pot folosi in tot programul,
inclusiv in interiorul subprogramelor.
Apelul procedurilor
se face in felul urmator:
Nume [(lista parametrilor actuali)];
Unde nume=numele
stabilit de programator procedurii;
Lista
parametrilor actuali=o lista de variabile sau expresii dar care trebuie sa
corespunda ca si numar, ordine, tip cu lista parametrilor formali de la
definirea procedurii.
Apelul unei proceduri are ca efect
intreruperea secventei de instructiuni din partea apelanta (program principal
sau alt subprogram), realizarea corespondentei intre parametrii actuali cu cei
formali, executia subprogramului apelat, dupa care se revine la programul
apelant. Astfel in memorie: se aloca
spatiu pentru p. actuali, variabilele locale, adresa de revenire in programul
apelant, se face transferul parametrilor actuali, se transmite controlul primei
instructiuni din subprogram.
EX: sa se scrie un program care face suma a n matrici
patratice citite de la tastatura.
-
o procedura de
citire,
-
o procedura de
calcul al sumei.
uses
crt;
type
matrice=array[1..10,1..10] of integer;
var
a,s:matrice;
n,i,j,m:integer;
procedure
citire(var a:matrice;n:integer);
var
i,j:integer;
begin
for i:=1 to n do
for j:=1 to n do
begin
write('a[',i,',',j,']=');
readln(a[i,j]);
end;
end;
procedure
suma(x:matrice;n:integer;var s:matrice);
var
i,j:integer;
begin
for i:=1 to n do
for j:=1 to n do
s[i,j]:=s[i,j]+x[i,j];
end;
BEGIN
clrscr;
write('Dati
dimensiunea matricilor ');
readln(n);
write('Dati
numarul de matrici la care se face suma ');
readln(m);
for
i:=1 to m do
begin
writeln('Dati a ', i,' a matrice');
citire(a,n);
suma(a,n,s);
end;
writeln('Matricea
suma este');
for
i:=1 to n do
begin
writeln;
for j:=1 to n do
write(s[i,j],' ');
end;
readln;
END.
2. Functiile – se declara
astfel:
FUNCTION nume [(lista parametrilor formali)]:tip;
[Declaratii;]
Begin
{corpul functii}
nume:=expresie;
End;
Elementele
nume, lista parametrilor formali, declaratii au aceeasi semnificatie ca la
proceduri. Diferenta fata de acestea este ca o functie returneaza o valoare
care are un anumit tip (standard, string sau adresa a unei date) specificat in
linia de antet si obligatoriu in cadrul blocului functiei numele acesteia
trebuie sa primeasca o valoarea unei expresii.
Apelul unei
functii se face prin: nume(lista
parametrilor formali) dar aceasta
forma trebuie sa apara in cadrul unei expresii, a unei atribuiri, sau valoarea
returnata de functie se va tipari.
Ex:
Se da un vector cu numere naturale si se cere sa se numere cate din ele sunt
prime.
Program nrprime;
Uses crt;
Type vector=array[1..10] of word;
Var v:vector;
I,n,nr:integer;
Function prim(a:word):boolean;
Var
Begin
Prim:=true;
For
I:=2 to trunc(sqrt(a)) do
If
a mod I=0 then prim=false;
If
a=2 then prim:=true;
If
a=1 then prim:=false;
End;
BEGIN Clrscr;
Write(‘n=’);readln(n);
Nr:=0;
For
I:=1 to n do
Begin
Readln(v[I]);
If prim(v[I])=true then nr:=nr+1;
End;
Writeln(‘Vectorul are ‘,
nr,’ numere prime’);
Readln;
END.
Mecanismul
de transfer al parametrilor:
Am
specificat ca parametrii pot fi de doua tipuri:
-
parametri de intrare, transmisi
prin valoare, (nu au cuvantul rezervat var in fata) mecansimul de lucru cu
acestia este urmatorul: in momentul
apelarii subprogramului se transmite valoarea acestui parametru care se va
pastra intr-o zona de memorie separata, iar toate modificarile referitoare la
acesta se vor face in acest loc, iar in momentul iesirii din subprogram cand se
lucreaza cu aceasta variabila modificarile nu vor fi vizibile.
EX:
Program xxx;
Var x,y:integer;
Procedure ex(x:integer);
Begin
x:=5;
End;
Begin x:=8;
Ex(x);
Writeln(x); End.
Acest
program va tipari valoarea 8.
-
parametri de iesire, transmisi
prin adresa (care au in fata cuvantul rezervat VAR), mecanismul de lucru este
urmatorul: in momentul apelarii subprogramului acestora nu lise rezerva memorie
ci se va lucra direct in zona de memorie aloca la declararea variabilelor
respective (deci toate modificarile din subprogram vor fi vizibile si in
programul principal.
EX:Program xxx;
Var x,y:integer;
Procedure ex(var x:integer);
Begin
x:=5;
End;
Begin
x:=8;
Ex(x);
Writeln(x);
End.
Acest
program va tipari valoarea 5.
Domeniul
de vizibilitate al variabilelor
Am stabilit ca variabilele se impart in:
variabile locale unui subprogra si variabile globale. Semnificatie acestora se
vede in urmatorul desen:
|
|
Astfel
-
variabilele declarate in PP
vor fi vizibile in S1, S2, S3, S4, S5.
-
variabilele declarate in S1
vor fi vizibile in S1 si in S2, iar in PP, S3, S4, S5 nu;
-
variabilele declarate in S3 vor fi vizibile in
S4 si S5 iar in PP si S1, si S2 nu.
-
Variabilele declarate in S4 vor fi vizibile doar
acolo si nu in S5, S3, S1, S2 si PP
|
|
Variabilel declarate in S3 sunt variabile
locale pentru pentru S3 dar sunt variabile globale pentru S4 si S5. Variabilele
declarate in PP sunt globale deoarece sunt vizibile de toate subprogramele.
Daca exista o variabila declarata si in
S3 si in S4 (ex: var a:integer) atunci in S3 se va folosi variabila
definita acolo iar in S4 variabila a declarata in S4 cea din S3 pierzandu-si semnificatia.
In Pascal se
pot folosi si subprograme declarate in zona de declaratii si definite mai
tarziu folosind cuvantul rezervat FORWARD, acest lucru face posibila utilizarea
unui subprogram inainte de a-l defini.