Sunteți pe pagina 1din 182

Algritmi i Structuri de Date

Note de curs























1
1. ALGORITMI I MODURI DE REPREZENTARE

Prelucrarea datelor cu ajutorul calculatorului se realizeaz prin execuia
unor operaii simple (aritmetice, logice, pe iruri de caractere etc.). nlnuirea
acestora poate conduce la prelucrri deosebit de complexe. Aceast nlnuire
nu este fcut la ntmplare, ci n conformitate cu reguli definite riguros, adic
n conformitate cu algoritmul de prelucrare sau de rezolvare a problemei.
Nu exist o definiie unanim acceptat a noiunii de algoritm. n mod
intuitiv, un algoritm este o mulime de operaii cunoscute (aritmetice, logice
etc.), care executate ntr-o ordine bine stabilit, pornind de la o mulime de
valori (numit intrarea algoritmului) care fac parte dintr-o mulime de astfel de
mulimi (numit domeniul de definiie al algoritmului), produc n timp finit un o
alt mulime de valori numit ieirea algoritmului.
Pentru a analiza proprietile algoritmilor vom prezenta doi algoritmi
cunoscui:
- determinarea celui mai mare divizor comun a dou numere naturale nenule
(algoritmul lui Euclid);
- rezolvarea aproximativ a ecuaiilor algebrice i transcendente prin metoda
njumtirii intervalului.

Algoritmul lui Euclid
A determina cel mai mare divizor comun a dou numere naturale nenule,
notate m i n, nseamn a gsi cel mai mare numr natural care divide numerele
date. Algoritmul lui Euclid de determinare a cmmdc const n urmtoarea
secven de operaii:
(E1) mparte m la n i fie restul r
(E2) Dac r=0 treci la (E6)
(E3) Noteaz cu m valoarea lui n (sau atribuie lui m valoarea n)
(E4) Noteaz cu n valoarea lui r (sau atribuie lui n valoarea r)
(E5) Treci la (E1)
(E6) Cel mai mare divizor comun este n (afieaz cmmdc este n)
(E8) Stop

Rezolvarea ecuaiilor algebrice i transcendente prin metoda njumtirii
intervalului

Fie R b] [a, : f o funcie real de o variabil real, continu pe [a,b], cu
f(a)*f(b)<0 i care are pe intervalul [a,b] exact o rdcin. Ne propunem s
determinm rdcina ecuaiei cu o precizie dat e. Rezolvarea ecuaiei se
realizeaz conform urmtoarelor reguli

2

(I1) Fie c mijlocul intervalului [a,b], adic
2
b) + (a
:= c ;

(I2) Dac f(c)=0 treci la (I10)
(I3) Dac |a-b| e treci la (I9)
(I4) Dac f(a)*f(c) < 0, treci la (I7)
(I5) Atribuie lui a valoarea lui c
(I6) Treci la (I1)
(I7) Atribuie lui b valoarea lui c
(I8) Treci la (I1)
(I9) Atribuie lui c valoarea lui b
(I10) Afieaz Radacina ecuatiei este, c
(I11) Stop

Proprietile algoritmilor
Analiznd cei doi algoritmi constatm c:
- algoritmii rezolv problemele unei clase de probleme: algoritmul lui
Euclid este aplicabil oricrei perechi de numere naturale nenule, iar
algoritmul de rezolvare a ecuaiilor algebrice i transcendente prin
njumtirea intervalului este aplicabil oricrei funcii f care satisface
condiiile problemei i orice eroare de aproximare e. Prin urmare, ei au
caracter general. Din acest motiv, algoritmii debuteaz cu precizarea
datelor iniiale (sau citirea datelor iniiale);
- secvenele de operaii descrise mai sus se ncheie dup un numr finit de
operaii. Prima se ncheie pentru c irul resturilor formeaz un ir de
numere naturale strict descresctor (restul fiind mai mic dect
mpritorul). A doua secven se termin dup un numr finit de operaii,
fiindc lungimile intervalelor [a,b] formeaz un ir strict descresctor de
numere pozitive convergent la zero (la a n-a aplicare a operaiei de
njumtire, lungimea intervalului este
2
| a - b |
n
), deci pentru un n
suficient de mare lungimea sa va fi mai mic dect e. Pentru acest n, orice
punct din intervalul [a,b] poate fi considerat rdcin a ecuaiei.
- Prin urmare algoritmii au un caracter finit ;
- operaiile care alctuiesc algoritmii se execut riguros i fr ambiguiti.
Prin urmare, pornind de la aceleai date de intrare se obin aceleai date
de ieire, deci algoritmii au un caracter de unicitate.


3
- n practic se doresc algoritmi buni, dar noiunea de algoritm bun este
definit vag. Uneori se doresc algoritmi care s conduc la programe de
dimensiuni reduse, alteori la programe simple i elegante, alteori la
programe care furnizeze soluia n timp ct mai scurt, alteori la algoritmi
care snt adaptabili mai multor tipuri de calculatoare etc.
Numim pas al unui algoritm o succesiune de operaii de acelai tip. Vom
conveni c, un pas nu poate conine dou sau mai multe operaii de decizie sau
de trimitere. n cele dou exemple, operaiile identificate prin (E1)-(E7) i (I1)-
(I11) snt exemple de pai. Operaiile identificate prin (E3) i (E4) pot fi reunite
ntr-un singur pas.

- Pentru reprezentarea algoritmilor se pot utiliza mai multe procedee:
- n cuvinte (ca mai sus);
- cu ajutorul schemelor logice;
- cu ajutorul limbajelor specializate (pseudocoduri);
- direct ntr-un limbaj de programare.

LIMBAJUL PSEUDOCOD

Reprezentarea alogritmilor cu ajutorul limbajelor specializate se impune
cel puin din urmtoarele motive:
- descrierea algoritmilor n cuvinte este nepotrivit datorit ambiguitii
limbajului natural (un cuvnt putnd avea mai multe sensuri);
- dificulti legate de reprezentarea grafic prin scheme logice (algoritmi
relativ simpli se reprezint prin scheme mari);
- lipsesc comentariile explicative privind semnificaia diferitelor variabile,
secvene de instruciuni etc.;
- citirea unei scheme logice este greoaie;
- majoritatea limbajelor de programare dispun de instruciuni puternice
care in locul mai multor operaii elementare descrise n mai muli pai ai
algoritmului (vezi instruciunea for, Do .. Until etc.).

Un identificator este o secven de unul sau mai multe caractere, litere i
cifre, primul caractere fiind obligatoriu liter. Literele mici snt echivalente cu
literele mari.

Identificatorii se mpart n dou grupe mari:
- cuvinte cheie (cuvinte rezervate care reprezint nume de instruciuni sau
ale unor pri din instruciuni; de exemplu If, then, else) ;

4
- definii de utilizator (proiectant) pentru a desemna nume de variabil,
procedur sau funcie.

Vom prezenta n continuare un pseudocod care utilizeaz cuvinte cheie n
limba englez, chiar dac efortul necesar nsuirii lui este n faza iniial mai
mare.
Adoptm urmtoarele convenii de scriere:
- cuvintele cheie vor fi scrise cu litere italice (inclinate);
- un element cuprins ntre [] este opional (sintaxa nu impune prezena sa);
- o mulime de elemente dispuse unul sub altul i incluse ntre {} indic o
alegere: din acea mulime se va alege un singur element.

- Instruciunile se mpart n:
- comentarii explicative;
- instruciuni de descriere sau de declarare a variabilelor;
- instruciuni executabile.
Comentariile snt texte n care se explic rolul diferitelor secvene de
program, semnificaia unor elemente, metoda utilizat, numele proiectantului
(programatorului), data i autorul unor modificri aduse algoritmului etc. Se pot
ntlni oriunde n text, dar nu pot mpri n dou sau mai multe pri un
identificator sau o constant. Ele ncep cu /* i se ncheie cu */.
Exemplu:
/* rezolvarea ecuatiilor algebrice si transcendente prin metoda
injumatatirii intervalului */
Succesiunea int/*20.03.1998*/eger m; este incorect.
Orice instruciune de declarare sau executabil se ncheie cu ; (caracterul
punct i virgul). Sintaxa limbajului este liber: o instruciune se poate ntinde
pe mai multe rnduri, iar un rnd poate conine mai multe instruciuni.

Variabila este o mrime (dat) care i poate modifica valoarea n timpul
execuiei programului. Are asociat un nume prin intermediul cruia se fac
referiri la valoarea ei. Dup coninutul pe care l pot avea, variabilele snt de tip
numeric (care la rndul lor se mpart n variabile de tip ntreg i de tip real), de
tip logic i caracter.

Constantele snt mrimi care nu i modific i nici nu-i pot modifica
valoarea n timpul prelucrrilor. Ele se recunosc dup forma lor: o constant de
tip ntreg se reprezint printr-un numr cu sau fr semn (de exemplu -1, 2), o
constant real printr-un numr real cu sau fr semn (virgula zecimal este
caracterul punct), constantele logice snt true i false, iar un caracter sau un ir

5
; ariabile lista_de_v
char
bool
real
integer


de caractere se reprezint ntre apostrofuri sau ntre ghilimele. Dac irul este
delimitat prin apostrof i conine caracterul apostrof, acesta se va dubla, de
exemplu intr o zi de sarbatoare . Dac irul este delimitat prin ghilimele i
conine caracterul ghilimele acestea se vor dubla (de exemplu ;,. <> ).
Cu datele de tip numeric se pot efectua urmtoarele operaii:
+ i - operatori unari de precizare a semnului
+ adunare - scdere
* nmulire / mprire
^ ridicare la putere.
Dac mrimile a i b snt de tip ntreg, rezultatul mpririi a/b este de tip
ntreg (este ctul mpririi ntregi).
Notm cu [] funcia parte ntreag, cu sqrt funcia radical, cu sin, cos etc.
funciile trigonometrice cunoscute.
- Datele de tip logic pot fi operanzi ai urmtoarelor operaii logice:
- negaia (NOT);
- conjucia logic sau AND ( I logic);
- disjuncia (OR, SAU LOGIC).

Datele de tip ir de caractere pot fi operanzi ai operaiilor de concatenare
(notat +). Dac a are valoarea Astazi este , iar b valoarea Joi , expresia
a+b are valoarea Astazi este Joi .

Expresiile de tip numeric i cele de tip ir de caractere pot interveni n
expresii de relaie. Se pot folosi urmtorii operatori de relaie:
- < (mai mic);
- > (mai mare);
- # (diferit);
- = (egalitate);
- <= (mai mic sau egal);
- >= (mai mare sau egal).
Acetia au semnificaiile cunoscute. Dou iruri de caractere se compar
caracter cu caracter. Dac c i c snt dou caractere, c<c dac n tabelul de
codificare ASCII c este n faa lui c (cu alte cuvinte codul ASCII zecimal al lui
c este mai mic dect codul ASCII zecimal al lui c ).
Prioritile i regulile de asociere snt cele cunoscute de la matematic.

Instruciunile de declarare precizeaz tipul i modul de organizare a
variabilelor. Ele au sintaxa


6
expresie; = :
_tablou element_de
variabila
)
`




Folosim cuvntul cheie integer pentru a declara variabile care au valori
numere ntregi, real pentru a declara variabile care au valori numere reale, bool
pentru a declara variabile de tip logic sau boolean (care au valoarea true -
adevrat sau false - fals), respectiv char pentru a declara variabile care au ca
valoare un caracter. Elementele listei de variabile se separ prin virgul.
Exemple
Instruciunile
integer m,n;
real x;
declar variabilele m i n de tip ntreg, iar variabila x de tip real.

Pentru a declara tablouri (matrici) cu una sau mai multe dimensiuni
folosim instruciunea array care are sintaxa
array list_de_tablouri;
Elementele listei de tablouri se separ prin virgul. Numele tabloului este urmat
de o list de expresii de tip ntreg care definesc valorile indicilor maximali pe
fiecare dimensiune. Lista de indici este cuprins ntre paranteze rotunde.
Prin array a(100); variabila a se declar vector de 100 de elemente.
Toate elementele unui vector au acelai tip (integer, real, bool sau char), iar
indicii ncep s varieze de la 1. n locul a dou instruciuni de declarare (de tip
i organizare n tablou) putem folosi o singur instruciune. De exemplu, n
locul instruciunilor
integer a;
array a(100);
putem folosi instruciunea
integer a(100);
n expresii, un element de tablou este identificat prin numele tabloului i
valorile indicilor si. De exemplu, a(i) este elementul cu indicele i al vectorului
a, iar m(i,j) este elementul situat n linia i i coloana j a matricii m.

Instruciuni executabile
- instruciunea de atribuire are forma





7
Execuia ei presupune evaluarea expresiei din mebrul drept, conversia
acesteia la tipul variabilei sau al elementului de tablou i atribuirea
acestuia ca valoare nou variabilei sau elementului de tablou.
De exemplu, instruciunea a:=1; atribuie variabilei a valoarea 1,
iar n instruciunea delta:=b^2_4*a*c; variabilei delta i se asociaz
valoarea b*b-4*a*c.

- instruciunea de citire (de introducere a datelor de la tastatur) are sintaxa
read lista_de_variabile_sau_elemente_de_tablou;
De exemplu, instruciunea
read m,n,a(i);
citete valorile variabilelor m i n i a elementului cu indicele i al
vectorului a.
- instruciunea de scriere (afiare pe monitor) are sintaxa
Write lista_de_expresii;
De exemplu, instruciunea
write Cel mai mare divizor comun este ,n;
afieaz textul Cel mai mare divizor comun este i valoarea pe care o are
variabila n.

Definiie. Numim secven de instruciuni o succesiune de instruciuni
executabile complete.

- instruciunea de ramificare IF THEN ELSE are dou forme:
if P then
Secven_de_instruciuni_1
endif;
sau
if P then
Secven_de_instruciuni_1
else
Secven_de_instruciuni_2
endif;
n prima form, se evalueaz expresia logic P. Dac este adevrat, se
execut secvena secven_de_instruciuni_1. Dup execuia acesteia sau
dac P este fals se trece la instruciunea urmtoare. n forma a doua, se
evalueaz expresia logic P: dac este adevrat se execut
secvent_de_instruciuni_1, altfel (dac este fals) se execut
secvent_de_instruciuni_2. Se trece la instruciune urmtoare.
Exemplu

8
if delta<0 then
Write Ecuatia are radacini complexe;
else
Write Ecuatia are radacini reale ';
endif;
sau
if x>maxim then
Maxim:=x;
endif;

- instruciunea repetitiv sau bucla While are sintaxa:
While p:
secvent_de_instructiuni
repeat;
Efectul su este:
1. Se evalueaz expresia logic p;
2. Dac este fals se trece la instruciunea urmtoare (de dup
repeat)
3. Se execut secven_de_instruciuni;
4. Se reia de la 1.
Sau, altfel spus, att timp ct p este adevrat se execut
secven_de_instruciuni. Dac p este iniial fals, secvena nu se execut
nici o dat.
Exemplu:
S se calculeze suma elementelor unui vector x cu n elemente.
i:=1; s:=0;

s:=s+x(i);
i:=i+1;
repeat;

- instruciunea repetitiv DO .. UNTIL are sintaxa
do
Secven_de_instruciuni
until p;
Este echivalent cu urmtoarea secven:
secven_de_instruciuni
while p
Secven_de_instruciuni;
repeat;

9
n care p este negata expresiei logice p.

Exemplu. Afiai textul Nr de elemente i citii valoarea variabilei n pn
cnd aceasta devine strict pozitiv i mai mic sau egal cu 100.

Do
write Nr de elemente;
read n;
<=100;


- ciclul cu un contor sau instruciunea FOR are sintaxa
for v:=E1,E2 [ ,E3]:
secven_de_instruciuni
repeat;
V este o variabil numeric numit contor, iar E1, E2 i E3 expresii
numerice numite valoare iniial, valoare final, respectiv pas. Dac E3
lipsete, se consider egal cu 1.

Instruciunea for este echivalent cu urmtoarele instruciuni:

v:=E1; v2:=E2; v3:=E3;
while(v - v2)*v3 0:
secven_de_instruciuni
v:=v+v3;
repeat;

Exemplu.
S se determine cel mai mic element al unui vector cu n elemente
de tip ntreg.

Integer minim,n, i;
/* citeste numarul de elemente (un numar intreg si pozitiv) */
do
write Dimensiunea vectorului =;
read n;
until n 0;
/* declara vectorul si citeste elementele sale */
integer v(n);
for i:=1,n:

10
write v(,i,)=;
read v(i);
repeat;
/* determina minimul */
minim:=v(1);
for i:=2,n:
if minim<v(i) then
Minim:=v(i);
endif;
repeat;
/* afiseaza rezultatul */
write Cel mai mic element al vectorului este , minim;

- instruciunea exit are ca efect abandonarea celei mai interioare bucle
while, for, do ..until care o conine (indiferent dac este sau nu ndeplinit
condiia de continuare a buclei). Are sintaxa
exit;

Exemplu.
Un ir de n numere ntregi are elementele dispuse n ordine
cresctoare. Verificai dac o valoare x face parte din ir.

/* presupunem c toate datele snt citite */
for i:=1,n:
if x=v(i) then
Exit;
endif;
repeat;

write Face parte din sir;
else
write Nu face parte din sir ;
endif;

- instruciunea cycle provoac trecerea la sfritul celei mai interioare bucle
while, for, do ...until care o conine. Bucla este reluat dac snt
ndeplinite condiiile de reluare.
Sintaxa instruciunii este
cycle ;
Exemplu.

11
Determinai media aritmetic a elementelor nenule ale unui vector
cu n elemente de tip ntreg.

/* presupunem ca datele sint citite */
suma:=0; /* suma elementelor nenule */
nr:=0; /* numarul elementelor nenule */
for i:=1,n:
if v(i)=0 then
Cycle;
endif;
suma:=suma+v(i);
nr:=nr+1;
repeat;
if nr=0 then
write Vectorul nu contine elemente nenule ;
else
write Media aritmetica a elementelor nenule este , suma/nr;


- instruciunea stop - marcheaz sfritul execuiei programului. Sintaxa ei
este
stop;

12

PROGRAME, PROCEDURI I FUNCII

Un program corespunde unui algoritm. Este alctuit din una sau mai
multe proceduri (deci procedura ar corespunde unui subalgoritm). O procedur
ncepe cu o instruciune de declarare de procedur (excepie face, eventual,
prima procedur) care are forma:

procedure nume_procedura[(Lista_de_parametri_formali)};

Se continu cu instruciunile de declarare a parametrilor p1,p2 etc., cu
declararea variabilelor locale i cu instruciunile executabile.
Se ncheie cu instruciunea end care marcheaz sfritul fizic al
procedurii.
Numele procedurii este un identificator (care nu poate fi un cuvnt cheie
sau numele unei variabile).
Execuia unui program ncepe cu execuia primei instruciuni executabile
a primei proceduri. O procedur poate apela o alt procedur. Dac procedura p
are declaraia
procedure proc(p
1
,p
2
,...p
n
);
apelul su se realizeaz printr-o instruciune de forma
call proc(a
1
,a
2
,...,a
n
);
Parametrii p
1
,p
2
,...,p
n
se numesc parametri formali, iar a
1
,a
2
,... ,a
n
se
numesc parametri actuali sau parametri efectivi sau parametri reali.
Corespondena dintre parametrii formali i actuali se realizeaz prin poziie
(valoarea lui a
1
este atribuit ca valoare iniial lui p
1
etc.).
Revenirea n procedura apelant are loc la ntlnirea (n procedura
apelat) a instruciunii return.

Exemplu
Elaborai un algoritm pentru determinarea celui mai mare divizor comun
a n numere naturale nenule.

procedure cmdc;
integer n,i;
do
write Numar de elemente;
read n;
until n 0;
integer a(n);

13
)]; ri_f ormali de_paramet ie[(lista_ nume_f unct f unction
char
bool
real
integer


for i:=1,n:
do
Write a(,i,)=;
Read a(i);
until a(i) 0;
repeat;
integer c,c1; /* cel mai mare divizor comun */
c:=a(1);
for i:=2,n:
call Euclid(c,a(i),c1);
c:=c1;
repeat;
write Cmmdc este ,c;
stop;
end;

procedure Euclid(m,n,r); /*declararea procedurii */
integer m,n, /* cele dou numere */
r; /* in final va contine cel mai mare divizor comun */
do
r:=m-n*[m/n];
m:=n;
n:=r;
until r=0;
r:=n;
return;
end; /*Euclid */



Ca i procedurile, funciile snt alctuite dintr-o instruciune de declarare
a funciei, de forma:





din declaraii ale parametrilor formali i a variabilelor locale, din instruciuni
executabile, i o instruciune de atribuire prin care numele funciei primete ca

14
valoare rezultatul ntors de funcie. Instruciunea end indic sfritul fizic al
funciei (dup end funcia nu mai are instruciuni).
Apelul funciei const n utilizarea n expresii a numelui funciei urmat
(cnd este cazul) de lista parametrilor actuali cuprins ntre paranteze rotunde.
Ca i n cazul procedurilor, corespondena dintre parametrii formali i cei
actuali se realizeaz prin poziie.

Iat cum ar arta algoritmul precedent, cu subalgoritmul Euclid implementat ca
funcie:

procedure ccmdc;
integer n,i;
do write Numar de elemente; read n; until n 0;
integer a(n);
for i:=1,n:
do
Write a(,i,)=;
Read a(i);
until a(i) 0;
repeat;
integer c; /* cel mai mare divizor comun */
c:=a(1);
for i:=2,n:
c:=Euclid(c,a(i));
repeat;
write Cmmdc este ,c;
stop;
end;

integer function Euclid(m,n); /*declararea procedurii */
integer m,n; /* cele dou numere */
integer r; /* restul impartirii */
do r:=m-n*[m/n]; m:=n; n:=r; until r=0;
Euclid:=n;
end; /*Euclid */


n cazul unor probleme de matematic (i nu numai) anumite elemente
(mrimi) se calculeaz utiliznd o relaie de recuren. De exemplu, funcia
factorial se definete dup cum urmeaz

15

1 > n , 1)! - (n * n
1 = n 1,
0 = n 1,
= n!



Limbajul pseudocod permite scrierea de funcii recursive.Condiia
impus este ca s fie ndeplinit o condiie de consisten: o valoare a funciei
trebuie s fie o valoare dat sau o valoare calculabil pe baza valorilor date. n
cazul nostru, valorile date pentru factorial snt valorile pentru n=0 i n=1.
Celelalte valori ale funciei se pot calcula innd seama de aceste valori i
formula de recuren.

Funcia factorial se poate defini recursiv astfel:

integer function factorial (n);
integer n;
if n<2 then
factorial:=1;
else
factorial:=n*factorial(n-1);
endif;
end; /* factorial */

Funcia Euclid se poate rescrie recursiv astfel

integer function Euclid(m,n);
integer m,n;
if n=0 then
Euclid:=m;
else
Euclid:=Euclid(n,m-n*[m/n]);
endif;
end; /* Euclid */

Pentru determinarea rdcinii ecuaiilor algebrice i transcendente prin
metoda njumtirii intervalului se poate folosi urmatorul algoritm
real function Biparti(f,a,b,e);
real a,b,e,c;
c:=(a+b)/2;
if |b-a|<e or f(c)=0 then
Biparti:=c;

16
else
if f(c)*f(a)<0 then
Biparti:=Biparti(f,a,c,e);
else
Biparti:=Biparti(f,c,b,e);
endif;
endif;
end ; /* Biparti */




17

LIMBAJE DE PROGRAMARE

Utilizatorul i calculatorul comunic prin intermediul comenzilor
sistemului de operare pe care le introduce, n general, de la perifericul standard
de intrare (tastatura) i prin intermediul unor secvene de instruciuni reunite sub
form de programe. n ultimul caz, utilizatorul specialist (programatorul)
folosete un limbaj intermediar ntre limbajul natural i limbajul calculatorului:
limbajul de programare.
Dei evoluia limbajelor de programare este strns legat de evoluia
sistemelor de calcul, se constat o tendin de apropiere a limbajului de
programare de limbajul natural.
Primele calculatoare au fost programate n limbajul calculatorului (cod
main). Sarcina utilizatorului n aceast etap a fost deosebit de grea:
X programele erau secvene de numere binare (programatorul aciona
butoane sau comutatoare cu dou stri);
X programele aveau dimensiuni mici, prelucrrile erau foarte simple i
puternic dependente de tipul de calculator utilizat ;
X programatorul trebuia s cunoasc semnificaia tuturor regitrilor
calculatorului.

Odat cu evoluia calculatoarelor i creterea nevoii de prelucrri
complexe, la nceputul anilor 50, se trece la programarea simbolic.
Limbajele de programare simbolice i uureaz munca programatorului sub
dou aspecte:
X instruciunile snt scrise ntr-o form intermediar ntre limbajul
calculatorului i limbajul natural ;
X programatorul nu este obligat s cunoasc n amnunt semnificaiile
diferiilor regitri ai calculatorului, el putndu-se concentra asupra
algoritmului de prelucrare.

n anul 1950, un grup de cercettori ai firmei IBM condui de John W.
Backus proiecteaz limbajul de programare FORTRAN (FORmula
TRANslation) destinat calculelor numerice de natur tehnico-tiinific.
Implementat pe diferite tipuri de calculatoare, el sufer mai multe transformri
concretizate n versiuni diferite ale limbajului: FORTRAN IV, FORTRAN 77,
FORTRAN 80 etc.

Zece ani mai trziu, un grup de cercettori coordonat de Peter Naur
definesc limbajul ALGOL - 60 (ALGOritmic Language). Acesta se remarc

18
prin precizia definiiilor i prin completa formalizare a sintaxei (regulilor de
scriere). Dei a avut o utilizare relativ restrns, limbajul devine un model
pentru proiectanii de limbaje de programare.

n 1970, Nicolaus Wirth definete limbajul PASCAL. Continuator al
ALGOL-ului, el se remarc prin simplitate i claritate. De-a lungul vremii,
diferitele variante ale limbajului pornesc de la limbajul standard PASCAL
definit de Wirth n 1974. Datorit calitilor sale, este foarte rspndit n mediile
de nvmnt.

COBOL - Common Business Oriented Language - fost definit n 1968,
apoi redefinit n 1974 de ctre ANSI (American National Standards Institute).
Este destinat prelucrrilor cu caracter economic care vehiculeaz volume mari
de date organizate n fiiere de organizare secvenial, secvenial indexat i
selectiv. Deoarece este capabil s efectueze calcule exacte cu numere mari, se
preteaz la proiectarea aplicaiilor de gestiune economic. Implementarea unei
instruciuni de sortare cu posibiliti de prelucrare iniial (nainte de sortare) i
final (dup sortare), prezena generatorului de rapoarte fac ca la nivelul anilor
1989, 60-70% din codul aplicaiilor noi s se scrie n COBOL. Faptul c datele
snt descrise ntr-o seciune separat, la fel de important ca partea de
prelucrare, au o influen pozitiv asupra altor limbaje de programare.

Limbajul C este un limbaj de programare general care face economie n
scrierea expresiilor, se caracterizeaz printr-un control modern al fluxului de
prelucrare i o mare varietate de operatori. Nu este un limbaj de programare de
nivel foarte nalt i nu este specializat pe anumite tipuri de aplicaii. El a fost
proiectat i implementat de ctre Denis Ritchie pe un calculator DEC PDP 11
nzestrat cu un sistem de operare UNIX. Operaiile de intrare/ieire (puternic
dependente de echipament) nu snt implementate sub form de instruciuni, ci
sub form de funcii de bibliotec, astfel c programele scrise n C au nalt grad
de portabilitate. La ora actual aproape pe toate tipurile de calculator exist
implementat o variant de C. Cea mai mare parte a componentelor sistemelor
de operare snt scrise n C, ceea ce l face foarte apropiat de sistemul de operare,
dar i fa de sistemul de calcul.

LIMBAJUL PASCAL

VOCABULARUL

n scrierea programelor PASCAL se utilizeaz :

19
- caractere alfabetice: literele mari i mici ale alfabetului englez i liniua de
subliniere;
- caractere numerice: cifrele sistemului de numeraie zecimal;
- caractere punctuaie i speciale:
= - \ _ & spaiu (blanc)

Numim identificator o succesiune de litere i cifre care ncepe cu o liter
i identific o instruciune, o parte a sa, un tip de dat, o variabil, un nume de
program, o constant, o procedur sau funcie. Lungimea acestuia depinde de
implementarea limbajului. O parte a acestora snt predefinii (snt identificatori
standard), iar o alta snt definii de ctre programator. O parte a
identificatorilor standard pot fi redefinii (de exemplu readln). Cuvintele cheie
snt identificatori care nu pot fi redefinii. Cuvintele cheie (BORLAND Pascal
versiunea 7) snt:

And
Asm
Array
Begin
Case
Const
Constructor
Destructor
Div
Do
Downto
Else
End
Exports
File
For
Function
GoTo
If
Implementation
In
Inherited
Inline
Interface
Label
Library
Mod
Nil
Not
Object
Of
Or
Packed
Procedure
Program
Record
Repeat
Set
Shl
Shr
String
Then
To
Type
Unit
Until
Uses
Var
While
With
Xor.





PROGRAME PASCAL


ntr-o prim aproximare, un program PASCAL este alctuit dintr-un antet
(n care se precizeaz numele programului i unitilor - unit-urilor folosite) i
un bloc alctuit din instruciuni de declarare (a variabilelor, constantelor,
funciilor etc.) i instruciuni executabile.

20
Comentariile explicative pot s apar oriunde n textul programului cu
condiia s nu despart un identificator sau o constant. Ele ncep cu (* i se
ncheie cu *), sau ncep cu { i se ncheie cu }. ntre caracterele delimitatoare se
poate insera orice text.

Exemplu de program Pascal
(* antetul *)
program afiseaza; {numele programului este afiseaza }
uses crt; { se folosete unitatea Crt }

(*declarari de variabile *)
const n=10; {n este constanta 10 }
var x: real; {variabila x este de tip Real }
i: integer; {variabila i este de tip I nteger }
a: array [1..n] of real; {a este un vector cu n componente de tip
Real }

(*instructiuni executabile *)
begin
for i:=1 to n do {citeste elementele vectorului }
Begin
{afiseaza numele elementului care se citeste }
Write( a( ,i, )= );
Readln(a[i]) {citeste valoarea elementului }
End;
write( Valoare cautata ); { citeste valoarea variabilei x }
readln(x);

for i:=1 to n do { compara valoarea lui x cu a elementelor
vectorului }
I f a[i]=x then break; { daca este egala cu una, incheie
cautarea }
if i>n then {Daca i>n, valaarea x nu este luata de elem lui
a}
Writeln( Nu este printre elementele date );
else
Writeln( Este printre elementele date );

(* sfirsit program *)
end.

21



CONSTANTE I VARIABILE

Reamintim c o constant este o dat care nu-i poate schimba valoarea n
timpul execuiei programului. Ele se pot reprezenta explicit sau li se poate
asocia un nume (constante simbolice). Aceast asociere se face n partea
declarativ a programului folosind o construcie de tipul:
const nume_constant_1=valoare-1;
[nume_constant_2=valoare_1;]...

Valoare_1, valoare_2 etc. pot fi constante n accepiune uzual sau pot fi
expresii constante (care pot fi evaluate n momentul compilrii textului
programului).

Constantele pot fi de tip
ntreg
zecimal - valoarea lor este un numr ntreg cu sau fr semn
cuprins n intervalul -2147483648 .. 2147483647. De exemplu, -1
750 300 snt constante de tip ntreg;

hexazecimal - valoarea lor se exprim printr-un ir cifre ale
sistemului de numeraie hexazecimal precedat de caracterul $) i
este cuprins ntre $00000000 i $FFFFFFFF. De exemplu, $12
$400 snt constante de tip ntreg n reprezentare hexazecimal;

real se exprim printr-un numr real cu sau fr semn) de forma
[semn][cifre].[cifre]
[semn][cifre].[cifre]E[semn]cifre
Prima form este numit form normal, iar a doua form
exponenial sau tiinific. n aceste scrieri, semn este semnul
numrului real (+ sau -), cifre o succesiune de cifre zecimale,
caracterul . (punct) este virgula zecimal. Succesiunile de cifre din
faa virgulei i de dup virgul pot lipsi, dar nu simultan. Valoarea
constantelor exponeniale se poate obine nmulind numrul real
situat n faa lui E cu 10 ridicat la puterea dat de numrul ntreg ce
este scris dup E.
Exemple 10. .5 -10.7 6. E2 Valoarea ultimei constante este
600. (6. nmulit cu 10 la puterea a doua).

22

boolean (logic) se reprezint prin valorile true (pentru adevrat) i false
(pentru fals).

ir de caractere care ncep i se ncheie cu . Dac irul conine un
caractert apostrof, acesta se dubleaz. Pentru a reprezenta
constante de tip caracter corespunztoare unor caractere speciale i
de control se folosesc expresii de tipul #cod sau ^c , unde cod este
codul ASCII zecimal al caracterului ce trebuie reprezentat, iar c
caracterul ce se tasteaz simultan cu CTRL pentru a obine
caracterul dorit. De exemplu #10 sau ^J pentru caracterul LF, #12
sau ^L pentru FF etc.
Exemple:
const n=10;
k=2*n;
j=1.5;
esc=$1b;
constat= O linie #13#10'Continuarea ei pe linia urmatoare ;
da=true;

Exist i constante predefinite MaxInt=32767 (care este cea mai mare
valoare ntreag cu semn), MaxLongInt= 2147483647 pentru cea mai mare
valoare reprezentabil ca LongInt etc.


Variabilele snt mrimi ale cror valoare se poate modifica n timpul
execuiei programului. Ele au asociat un nume (care este un identificator) prin
intermediul cruia le putem referi. Valorile pe care le poate lua o variabil i
operaiile permise asupra lor depind de tipul variabilei care nu poate fi modificat
i care se declar prin construcii de forma:

nume_de_variabila_11[,nume_de_variabila_12 ]... :
tip_de_data_1;
[nume_de_variabila_21[,nume_de_variabila_22] ... :
tip_de_data_2;]...


DATE DE TIP NUMERIC


23
Variabilele i constantele cu tip numeric de baz snt Integer i Real i
corespund reprezentrilor interne n virgul fix , respectiv virgul flotant (sau
mobil). Alturi de acestea se pot folosi i urmtoarele tipuri: Byte, Shortint,
Word, Longint, Comp (care se reprezint n virgul fix) i Single, Double i
Extended (care se reprezint n virgul flotant).

Lungimile zonei de memorie necesare i valorile maxime i e pe care le
pot lua datele variaz n funcie de tipul lor i depind de funcie de tipul lor i
depind de calculatorul folosit. n cazul calculatoarelor personale compatibile
IBM PC (Borland PASCAL 7) acestea snt:


Tipul datei

Numr
de
octei

Valoare

Valoare maxim

BYTE

1

0

255

SHORTINT

1

-128

127

WORD

2

0

65535

INTEGER

2

-32768

32767

LONGINT

4

-2147483648

2147483647

COMP

8

-9.2 E 18

9.2E18



Tipul de dat

Numr
octei

Numr de
cifre
semnificati
ve

Valoare
absolut

Valoare
absolut
maxim

SINGLE

4

7 .. 8

1.5 E -45

3.4 E 38

REAL

6

11 .. 12

2.9 E -39

1.7 E 38

DOUBLE

8

15 .. 16

5.0 E -324

1.7 E 308

EXTENDED

10

19 .. 20

3.4 E -4932

1.1 E 4932



24
Datele ntregi reprezentate n Comp i cele de tip Real, cu excepia tipului
Real, necesit prezena coprocesorului matematic sau emularea acestuia cu
directivele {$E+,$N+}

Datele de acelai tip sau compatibil (de exemplu, integer cu comp,
integer cu real etc.) se pot compara folosind operatorii de relaie = (egal) <
(mai mic) >(mai mare) <= (mai mic sau egal) >=(mai mare sau egal)
<> (diferit). n expresii logice (care pot conine operatori aritmetici, operatori de
relaie etc.), operatorii de relaie au cea mai mic prioritate.

Indicm, n ordinea crescnd a prioritii, operaiile care pot fi efectuate
asupra datelor de tip ntreg i semnificaia lor:
+ - (adunare, scdere);
* / (nmulire ntreag i mprire cu rezultat real);
DIV (mprire ntreag - ctul mpririi ntregi);
MOD (restul mpririi ntregi).

Asupra datelor de tip ntreg se pot executa urmtoarele operaii logice:
op
1
SHL op
2
- deplaseaz valoarea lui op
1
spre stnga cu op
2
bii;
biii eliberai se pun pe zero;
op
1
SHR op
2
- deplaseaz valoarea lui op
1
spre dreapta cu op
2
bii;
op
1
OR op
2
- sau logic bit cu bit asupra reprezentrilor lui op
1
i
op
2;

op
1
AND op
2
- i logic bit cu bit;
op
1
XOR op
2
- sau exclusiv bit cu bit asupra reprezentrilor
lui op
1
i op
2
;
NOT op
1
- negaie logic pe bii.

Exemplu
Dac op
1
are valoarea 9 i op
2
valoarea 3 ele se reprezint n memorie pe
2 octei astfel
op
1
0000 0000 0000 1001
2

op
2
0000 0000 0000 0011
2


Avem op
1
SHR op
2
= 0000 0000 0000 0001
2
=1
10
,
op
1
SHL op
2
= 0000 0000 0001 1000
2
= 24
10

op
1
OR op
2
= 0000 0000 0000 1011
2
= 11
10

op
1
AND op
2
= 0000 0000 0000 0001
2
= 1
10

op
1
XOR op
2
= 0000 0000 0000 1010
2
= 10
10

NOT op
1
= 1111 1111 1111 0110
2
= -10
10


25

Tabelele pentru operatorii OR AND XOR i Not pentru operanzii binari
p1 i p
2
snt



p
1


p
2


1


p
1
OR p
2


p
1
AND p
2


p
1
XOR p
2


0

0

1

0

0

0

0

1

1

1

0

1

1

0

0

1

0

1

1

1

0

1

1

0


Asupra mrimilor reprezentate n virgul flotant se pot executa urmtoarele
operaii aritmetice:
+ - (adunare, scdere sau schimbare de semn);
* / (nmulire i mprire).

Expresiile aritmetice snt alctuite din constante, variabile, valori de
funcii sau constante, variabile i valori de funcii reunite cu ajutorul
operatorilor.
Pentru a se impune o anumit ordine de efectuare a operaiilor se folosesc
parantezele rotunde. n lipsa parantezelor sau n interiorul lor, ordinea
descrescnd a prioritii operaiilor este
- NOT (operatorii unari de schimbare a semnului i negaie pe bit);
* / DIV MOD SHR SHL AND ;
+ - OR XOR.
Dac operatorii au aceeai prioritate, evaluarea rezultatului se face de la stnga
la dreapta.

DATE DE TIP CHAR

O dat de tip CHAR are ca valoare codul unui caracter (liter mare, mic,
cifr, caractere speciale) i ocup n memorie un octet. Pentru a reprezenta o
constant de tip CHAR, caracterul respectiv se include ntre dou caractere
apostrof.



26
DATE DE TIP BOOLEAN

O dat de tip BOOLEAN poate avea, la un moment dat, una din valorile
TRUE (pentru adevrat) i FALSE (pentru fals). Identificatorul de tip cu care
se declar tipul lor este BOOLEAN. Modul de reprezentare intern ale valorilor
true i false depinde de implementare. Datele de tip BOOLEAN pot fi
operanzi ai urmtoarelor operaii logice:
- negaia - operatorul NOT;
- conjucia - operator AND
- disjuncia - operator OR
- sau exclusiv - operator XOR (sau <>).
- echivalena - operator =
- implicaia - operator <=
- implicaia invers - operator >=

OBSERVAIE.
Pentru compatibilitate cu WINDOWS se pot folosi i urmtoarele tipuri
logice:
WORDBOOL (se reprezint pe 2 octei), LONGBOOL (pe 32 bii) i
BYTEBOOL (pe 1 octet).

TIPUL ENUMERARE

n numeroase situaii intervin date care au un caracter nenumeric, cum ar
fi culoarea unui obiect, calitatea sau ocupaia unei persoane etc.
Se pune probema de a asocia acestor variabile un tip de date care s fie
utilizat n prelucrri. O soluia ar consta n codificarea acestora (de pild
culoarea A s nsemne alb, N negru, R rou etc.). O alta, oferit de limbajul
PASCAL, const n enumerarea constantelor care aparin tipului respectiv. De
exemplu
culori=(alb,galben, oranj,bej,auriu,albastru,verde,rosu,negru);
sex=(femeiesc,barbatesc)
Datele de tip enumerare nu pot fi citite sau scrise sau utilizate pentru a
defini alte tipuri, dar ele pot fi utilizate n comparaii, atribuiri etc. Ele se
utilizeaz n cadrul programelor pentru a mri gradul de lizibilitate.


TIPURI ORDINALE DE DATE



27
Tipurile ordinale se caracterizeaz prin faptul c mulimea valorilor
posibile este finit i ordonat. Astfel, dintre tipurile de date enumerate mai sus,
urmtoarele snt tipuri ordinale:
- ntreg cu excepia lui COMP;
- CHAR;
- BOOLEAN;
- enumerare;
- subdomeniu.

Orice dat de tip ordinal poate fi argument al unei dintre urmtoarele funcii
ORD (ordinal sau valoarea datei sau rangul datei - primul element are
ordinalul 0 );
PREC (predecesor- este nedefinit pentru primul element);
SUCC (succesor - este nedefinit pentru ultimul).
Dac ch este o dat de tipul CHAR, Ord(ch) este egal cu codul ASCII
zecimal al caracterului ch. De exemplu Ord( A )=45, Ord( a )=97, Prec( B
)= A , Succ( A )= B .
Pentru constantele logice True i False avem Ord(True)=1, Ord(False)=0,
Succ(False)=True i Prec(True)=False.
Pentru data de tip enumerare culori=(rosu, galben, albastru), avem
Ord(rosu)=0, Ord(galben)=1, Ord(Albastru)=2, Succ(rosu)=galben,
Succ(galben)=albastru, Prec(albastru) = galben etc.
Pentru orice dat x de tip ordinal pentru care au sens Ord(x), Succ(x) i
Prec(x) au loc relaiile Ord(Prec(x))=Ord(x)-1 i Ord(Succ(x))=Ord(x)+1.

OBSERVAIE
Funcia Chr, care are argument de tip ntreg, furnizeaz caracterul care
are ordinalul egal cu argumentul. Prin urmare, Chr(65) este caracterul A,
Chr(48) caracterul 0, Chr(12)=FF (FormFeed), Chr(10)=LF (Line Feed) etc.




TIPUL SUBDOMENIU


Snt numeroase situaiile n care domeniile datelor care se vehiculeaz n
interiorul programelor snt subdomenii ale unor date de tip ordinal. De
exemplu, notele care le obin studenii snt numere ntregi cuprinse ntre 1 i 10,
o cifr a sistemului de numeraie zecimal este cuprins ntre 0 i 9 etc. Un tip

28
subdomeniu se definete prin intermediul a dou constante de acelai tip ordinal.
Acestea satisfac condiia c prima este mai mic sau egal cu a doua. Sintaxa de
definire este c1..c2. Dac ord(c2)<ord(c1), atunci c1..c2 desemneaz mulimea
vid.
Exemplu:
type nota=1..10;
culori=(alb,galben, oranj,bej,auriu,albastru,verde,rosu,negru);
culoare_deschisa=alb..auriu;
culoare_inchisa=albastru..negru;



INSTRUCIUNI EXECUTABILE PASCAL

Un program PASCAL poate conine instruciuni de declarare, instrucini
executabile i comentarii.
Comentariile se folosesc pentru a explica semnificaia diferitelor
variabile, rolul unor secvene de program, autorul, data scrierii programului etc.
Snt alctuite din iruri de caractere care ncep cu { i se ncheie cu }, sau ncep
cu (* i se ncheie cu *). Un comentariu se poate ntinde pe mai multe linii de
program.
Sintaxa limbajului este liber n sensul c o instruciune se poate ntinde
pe mai multe linii de program i o linie de program poate conine mai multe
instruciuni. Instruciunile se separ unele de altele (cnd este cazul) prin
caracterul ; (punct i virgul).
Instruciunile executabile (cu excepia instruciunii de atribuire) ncep cu
un cuvnt cheie.
O instruciune executabil este una dintre urmtoarele:
- instruciunea de atribuire (:=);
- instruciunea compus sau blocul (Begin..End);
- alternativa multipl (Case..Of..Else..End);
- ciclul cu contor (For..To/Downto..Do);
- instruciunea de salt (GoTo);
- alternativa simpl (If..Then..Else);
- inserarea de instruciuni n limbaj de asamblare (inline(...));
- apelul de procedur;
- bucla cu test final (Repeat..Until..);
- bucla cu test iniial (While.. do);
- intruciunea nul;

29
- instruciunea de calificare (With ... do ).

Mai multe instruciuni executabile se pot grupa ntr-un bloc pentru a fi
tratate din punct de vedere sintactic ca o instruciune. n acest scop se utilizeaz
cuvntul cheie BEGIN n faa primei intruciuni i cuvntul cheie END dup
ultima instruciune.
Cnd, ntre instruciunile executabile, se ntlnesc dou caractere punct
virgul consecutive sau cnd caracterul punct i virgul este situat n faa
cuvntului cheie END (de ncheiere a blocului), se consider c ntre acestea se
afl instruciune: instruciunea vid. Efectul su din punctul de vedere al
execuiei este nul. Totui ea este util n situaia n care sintaxa cere prezena
unei instruciuni, dar efectul su trebuie s fie nul. Instruciunea vid nu poate fi
utilizat n fat cuvntului cheie ELSE asociat alternativei If.

Prezentm n continuare instruciunile executabile ale limbajul
PASCAL. Cuvintele cheie care identific instruciunea sau o parte a acesteia vor
fi scrise cu litere mari.

Instruciunea apel procedur se reduce la numele procedurii care poate fi urmat
de o list de parametri actuali inclus ntre (). n general, declararea procedurii
trebuie s precead utilizarea ei. Procedurile pot fi definite de ctre programator
sau pot face parte din bibliotecile PASCAL. Prezentm n continuare dou
funcii de bibliotec.
Procedura WRI TE scrie n fiierul standard de ieire (de regul pe
monitor) valorile unor expresii. Apelul ei este de forma:
WRITE(Lista_de_expresii)
Elementele listei de expresii se separ prin virgul. Nu pot fi date de tip
enumerare. Pentru a trece la rnd nou (la nregistrare nou) vom tipri caracterul
#10 (LF), iar pentru a trece la nceput de rnd caracterul #13 (CR).
Prin urmare, instruciunea WRITE( Viata e frumoasa #13#10'Noi sa fim
sanatosi ) va scrie pe rndul curent textul Viata e frumoasa, iar de la nceputul
rndului urmtor Noi sa fim sanatosi. Apelul WRITE( A( ,i, )= ) va afia
textul A(, apoi valoarea variabilei i, apoi textul )=.
Vom folosi procedura WRITELN pentru a obine efectul procedurii
WRITE urmat de o trecere la rndul urmtor. Apelul acestei proceduri este
similar cu al procedurii WRITE.

Procedura READ se folosete pentru a citi date n memoria intern din
fiierul standard de intrare (de regul, tastatura). Ea se apeleaz astfel
READ(Lista_de_elemente)

30
n care list_de_elemente este alctuit din variabile (cu tipul diferit de
enumerare) sau elemente de tablou separate prin virgul. Valorile introduse
trebuie s fac parte din domeniul de valori al tipului variabilelor. n lista de
intrare, valorile se separ una de alta printr-un caracter alb (spaiu, Tab etc.). Fie
apelul READ(a,b,c). Dac A este de tip INTEGER, B i C de tip REAL,
introducnd valorile 10 5. 20.4 dup execuia instruciunii apel de procedur, A
va avea valoarea 10, B valoarea 5. , iar C valoarea 20.4.
Dac tipul elementului ce se citete i tipul datei introduse nu snt
compatibile (de exemplu, trebuie citit valoarea pentru o variabil de tip ntreg,
iar valoare introdus este 14.34), execuia instruciunii se ncheie cu eroare.
Vom folosi procedura READLN pentru a obine efectul procedurii READ
i o trecere la linie nou (sau o nou nregistrare).
Instruciunea de atribuire are urmtoarea sintax

nume_variabil :=expresie

Se execut urmtoarele prelucrri:
- se evalueaz mai nti expresia din membrul drept;
- rezultatul se convertete la tipul variabilei;
- valoarea rezultat este atribuit ca nou valoare variabilei.

Tipul variabilei trebuie s coincid sau s fie compatibil cu tipul
expresiei.Pentru tipurile de dat definite anterior snt valabile regulile de
compatibilitate:
- o expresie de tip ntreg se poate atribui fr restricii unei varibile de tip real
;
- o expresie de tip ntreg se poate atribui, n anumite limite, unei variabile de
tip ntreg;
- alte reguli se vor da ulterior.

OBSERVAII
- Nu se poate atribui o expresie de tip real unei variabile de tip ntreg. Pentru
aceasta se utilizeaz funcii Round (de rotunjire la ntreg) i Trunc (de
trunchiere la ntreg).

- Atribuirile de forma
variabila:=variabila +expresie
sau
variabila:=variabila-expresie

31
cnd expresie este de tipul LongInt, se pot nlocui cu instruciunile apel de
procedur
I NC(variabila[,expresie])
respectiv
DEC(variabila[,expresie])

Valoarea implicit (prin lips) pentru expresie este 1.

Deci inc(n,3) este echivalent cu n:=n+3, iar dec(n,4) cu n:=n-4

- Pentru a realiza conversii de tip explicite se folosesc expresii de forma
nume_tip(expresie).

INSTRUCIUNEA IF

Se folosete cnd trebuie efectuate prelucrri condiionate de faptul c o
expresie logic este adevrat sau fals. Este omoloaga instruciunii cu acelai
nume din limbajul pseudocod.
Are dou forme

I F expresie_logica THEN
instruciune1

i

I F expresie_logica THEN
instruciune1
ELSE
instructiune2

Prima form a instruciunii este tratat astfel:
- Se evalueaz expresie_logica ;
- Dac este adevrat se execut instruciune1;
- Se trece la instruciunea urmtoare.

A dou form a instruciunii este tratat astfel:

- Se evalueaz expresie_logic;
- Dac este adevrat se execut instruciune1, n caz contrar se execut
instruciune2;

32
- Se trece la instruciunea urmtoare.

OBSERVAII
- instructiune1 i instruciune2 pot fi instruciuni compuse ;
- snt permise instruciuni if imbricate (incluse una n alta). n acest caz
cuvntul cheie else se asociaz ultimului if nceput.

EXEMPLE
1.
if d=2 then
inc(d)
else
inc(d,2)

2.
If a=2 then
c:=b
else (* urmeaz o instruciune vida *)
;


INSTRUCIUNEA CASE

Cnd execuia programului continu cu o instruciune sau alta dintr-o
mulime de instruciuni posibile, n funcie de valorile unei expresii numite
selector, programatorul poate folosi mai instruciuni if sau poate folosi
instruciunea case.

Sintaxa acesteia este

CASE expresie OF
lista_de_valori_1:
instructiune_1;
lista_de_valori_2:
instruciune_2;
.................................
lista-de_valori_n:
instruciune_n [;
ELSE
instructiune_m]

33
END;

lista_de_valori_1, lista_de valori_2 etc. snt liste de elemente separate prin
virgul. Elementele pot fi constante sau subdomenii. Listele de valori se numesc
etichete.
Execuia instruciunii are loc dup urmtorul algoritm:
- Se evalueaz expresie (selectorul) ;
- Se compar cu etichetele n ordinea n care acestea snt scrise ;
- Daca valoarea expresiei este egal cu a unei constante din lista
corespunztoare etichetei se execut instruciunea asociat etichetei. n caz
contrar, dac else este prezent, se execut instruciune_m.
- se trece la instruciunea care urmeaz dup end.

OBSERVAIE
Instructiunea care precede Else este urmat de caracterul ; dar
instruciunea ce precede end nu este urmat de caracterul ;

EXEMPLU. Gsii numrul trimestrului n funcie de lun. Dac luna este
incorect, atribuii trimestrului valoarea 0.

case luna of
1..3: trimestrul:=1;
4..6: trimestrul:=2;
7..9: trimestrul:=3;
10..12: trimestrul:=4;
else
trimestrul:=0 (* luna incorecta *)
end;


INSTRUCIUNEA FOR

Este corespondenta PASCAL a instruciunii For din limbajul pseudocod,
obinut pentru valoarea pasului 1, respectiv -1.
Instruciunea FOR are dou forme

FOR contor:=valoare_iniial TO valoare_final DO instruciune;

FOR contor:=valoare_iniial DOWNTO valoare_final DO
instructiune;

34

Contor este o variabil de tip ordinal, iar valoare_iniial i valoare_final
expresii care au au acelai tip ordinal (nu pot fi date de tip Real).

Execuia acesteia presupune execuia urmtorilor pai:
1. se evalueaz valoare_iniial i valoare_final;
2. se atribuie variabile contor valoare_iniial;
3. se compar contor cu valoare final;
4. dac este mai mic sau egal cu aceasta(n prima form ) sau mai mare
sau egal cu aceasta n cea de-a doua, se execut instruciune. Altfel se
trece la instruciunea ce urmeaz dup for
5. se mrete cu 1 (n cazul primei variante) sau se micoreaz cu 1 (n cazul
variantei a doua) valoarea variabilei contor. Se trece la punctul 3.




INSTRUCIUNEA WHILE

Are sintaxa

WHI LE expresie_logica DO instructiune;

Are urmtorul efect:
- se evalueaz expresie_logic;
- dac este adevrat se execut instruciune i se reia de la reevalularea
condiiei, iar
dac este fals se continu cu tratarea instruciunii urmtoare.



INSTRUCIUNEA REPEAT

Are forma

REPEAT
secventa_de_instruciuni
UNTIL expresie logic;

este echivalent din punctul de vedere al tratrii cu

35

secventa_de_instructiuni
WHILE expresie_logica DO secvent_de_instruciuni;

EXEMPLU
Verificai dac numrul natural n, mai mare dect 1, introdus de la
tastatur este prim.

Uses crt;
var n, (* numarul natural *)
d: INTEGER; (* un posibil divizor *)
Begin
repeat
write( dati numarul natural );
read(n)
until n>1;
d:=2;
while (d<n) and (n mod d <>0) do (* parantezele sint necesare! *)
Inc(d,1+ord(d<>2));
if d<n then
write( Numarul este compus )
Else
write( Numarul este prim )
end.

OBSERVAIE
Sub influena limbajul C, au fost implementate procedurile:

break - care termin necondiionat cea mai interioar instruciune de
ciclare (while, repeat
i for).

continue - cea mai interioar instruciune de ciclare (while, repeat i for)
se reia cu pasul urmtor.


PROCEDURI I FUNCII PASCAL




36
Un subprogram este o alctuit dintr-o mulime de instruciuni care
execut o aciune specific, eventual, n funcie de valorile unor parametri.
Gruparea instruciunilor n subprograme se face din dou motive:
- aceeai secven de instruciuni trebuie executat n mai multe locuri ale
programului, eventual cu date diferite;
- pentru a putea descompune o problem complex n subprobleme care s
poat fi stpnite mai uor.
Ele pot fi apelate din programul principal sau din alt subprogram. Cnd se
apeleaz un subprogram, execuia programului se continu cu prima
instruciune executabil a acestuia, iar la revenirea n apelant se continu cu
instruciunea urmtoare instruciunii de apel a subprogramului. Un subprogram
poate fi apelat de un alt subprogram, ba mai mult, un subprogram se poate apela
pe sine nsui (deci subprogramul poate fi recursiv).
Subprogramele pot primi la intrare valori de care depinde rezultatul
execuiei lor. Anumite valori de intrare (anumii parametri actuali) ai
procedurilor sau funciilor pot fi modificate n interiorul subprogramului.
Subprogramele Pascal snt de dou tipuri: proceduri i funcii. Funciile
snt subprograme care ntorc o valoare, adic la sfritul execuiei lor i transmit
apelantului o valoare care este folosit n expresii. Spre deosebire de funcii,
procedurile nu ntorc nici o valoare. Folosind opiunea de compilare {$X+},
valoarea furnizat de o funcie poate fi ignorat: nu sntem interesai de valoarea
ntoars de funcie, ci de aciunea ei.
Subprogramele Pascal se definesc n ntregime n partea introductiv a
unui program, nainte de corpul propriu-zis al programului.

O procedur este alctuit din urmtoarele prti:
- un antet n care se specific numele procedurii i, cnd este cazul, lista
parametrilor formali (care corespund valorilor de intrare):
procedure nume_de_procedur;
sau
procedure nume_de_procedur ( lista_de_parametri );
n prima form, procedura nu are parametri de intrare sau parametri
fomali.
Parametrii formali corespund valorilor care se transmit procedurii:
parametrilor reali, efectivi sau actuali. Corespondena dintre parametrii
formali i parametrii actuali se face prin poziie. Lista de parametri
formali este alctuit din subliste de forma [var] p1[,p2]...; n care p1, p2
etc. snt numele parametrilor formali. Dac sublista nu ncepe cu var,
parametrii (numii parametri de tip valoare) pot fi modificai n
procedur, dar parametrii reali rmn nemodificai dup revenire din

37
procedur. n caz contrar,se numesc parametri de tip referin, iar valorile
primite n cadrul procedurii vor fi valorile parametrilor reali dup
revenire n apelant;
- declaraii locale procedurii (variabile, constante etc.;
- instruciuni care definesc corpul procedurii cuprinse ntre cuvintele Begin i
End.

O funcie este o parte de program n care se calculeaz i care ntoarce o
valoare. O funcie este alctuit din:
- un antet de forma:
function nume_de_funcie : tipul_functiei;
sau
function nume_de_functie (lista_de_parametri) : tipul funciei;
Antetul de funcie specific numele funciei, parametrii formali (dac
exist) i tipul funciei. Lista de parametri are structura prezentat la
proceduri. Tipul funciei sau tipul valorii ntoarse poate fi ordinal, real, ir
i pointer. Valoarea furnizat de funcie poate fi folosit n expresii
PASCAL;
- declaraii locale ;
- corpul funciei. El trebuie s conin cel puin o instruciune de atribuire prin
care identificatorul funciei primete valoarea pe care funcia o ntoarce
apelantului;
- o declaraie de funcie poate conine directive forward, external, far sau
inline.

Exemple
1. Calculai i afiati n!.
Vom prezenta trei versiuni ale aceluiai program. Vom considera c n=10
(modificai blocul de execuie ca programul s fie independent de valoarea lui
n).
1a) { Calculati n! }
uses crt;
function fact(n:word):word;
var f:word;
begin
f:=1;
while (n>1) do begin
f:=f*n;
dec(n)
end;

38
fact:=f;
end;

begin
writeln('10!=',fact(10));
end.

1b) { Calculati n! }
uses crt;
procedure fact(n:word;var f:word);
begin
f:=1;
while (n>1) do begin
f:=f*n;
dec(n)
end;
end;

var factorial: Integer;

begin
fact(10,factorial);
writeln('10!=',factorial);
end.

1c) {Calculati lui n! prin recursivitate}
uses crt;
function fact(n:word):word;
begin
if (n=0) then
fact:=1
else
fact:=n*fact(n-1);
end;

begin
writeln('10!=',fact(10));
end.


39
Un alt caz de recursivitate este acela n care n definiiile a dou
subprograme acestea se apeleaz reciproc, deci avem de-a face cu o
recursivitate indirect. Vom arta cum se procedeaz n asemenea situaii n
cazul urmtoarei probleme: Fie x0 i y0 dou numere reale pozitive. Definim
irurile x
n
i y
n
astfel: pentru n=0, avem x
0
= x0 i y
0
=y0, iar pentru n>0a vem
x
n
=(x
n-1
+y
n-1
)/2 i y
n
=(x
n-1
+y
n-1
)
1/2
. Calculai , pentru un n dat, x
n
i y
n
.
Vom scrie doar funciile prin care se calculeaz cele dou valori.

Function y( x0,y0:Real;
n:Integer):Real; forward;{indicm tipul funciei y i c ea va fi
definit ulterior}
Function x( x0,y0:Real;n:
Integer):Real;
begin
if n=0 then
x:=x0
else
x:=(x(n-1)+y(n-1))/2;
end;

Function y;
begin
if n=0 then
y:=y0
else
y:=sqrt(x(n-1)+y(n-1));
end;


TIPURI DE DATE DEFINITE DE UTILIZATOR

Limbajul Pascal permite definirea unor tipuri de date noi pornind de la
cele de baz. Acestea pot reprezenta restricii sau extensii ale tipurilor de date
predefinite. Aceste tipuri de date pot fi identificate printr-un nume sau pot fi
anonime. In primul caz, fiecare identificator se definete n partea declarativ a
blocului (de regul, ntre declaraiile de constante i cele de variabile), n care se
utilizeaz.
Sintaxa lor este

type Identificator_de_tip= definiie_de_tip;

40
identificator_de_tip=definitie_de_tip;

Complexitatea unei instruciuni de declarare a tipului variaz n funcie de
problema concret care trebuie rezolvat.

Exemplu:
type logic=boolean;

n continuare tipul de dat definit poate fi utilizat pentru a declara
variabile, constante i funcii.
De exemplu
var da,nu:logic;

n cazul tipurilor anonime, declaraiile se fac direct n cadrul
instruciunilor de definire/declarare a variabilelor.



Declararea tablourilor

Un tablou este un ir de elemente de acelai tip, fiecare element fiind
identificat printr-un indice, valorile acestuia formnd un subdomeniu al unui tip
ordinal. Pentru a declara tablouri, trebuie precizate: numele tabloului, tipul
elementelor sale i subdomeniul indicilor.Prin urmare, un tablou se declar prin
construcii de forma

identificator: ARRAY [domeniu_indice_1{,domeniu_indice_2}...] OF tip;

n care {} indic prezena unui element opional, iar tip un tip de date
PASCAL.
Prin a: array [1..25] of integer , se declar a tablou (vector) cu elemente de tip
INTEGER, cu domeniul valorilor indicilor 1..25, deci a are 25 de elemente.
Prin declaraia b: array [ A .. Z ] of REAL; b se declar vector cu
elemente de tip real ale crui elemente snt indexate prin caractere cuprinse ntre
A i Z (prin urmare numrul elementelor sale este ord( Z )-ord( A )+1).
Un element al tabloului se poate referi prin numele tabloului urmat de o
list de expresii de indici care d rangul elementului pe fiecare dimensiune.
Singura operaie predefinit asupra datelor de tip tablou este atribuirea,
care are ca efect copierea valorilor elementelor tabloului din membrul drept al

41
instruciunii n elementele tabloului din membrul stng. Cele dou tablouri
trebuie s aib acelai tip.
Elementele unui tablou pot fi la rndul lor elemente de tablou, deci snt
posibile declaraii de forma
a array [1..15] of array [1..10] of real.
n aceast situaie a[i] este un vector de 10 elemente de tip real. Un element de
rang j al acestuia se refer prin a[i][j].

EXEMPLE
Fie (A, ) o mulime finit total ordonat n raport cu relaia adic:
- relaia este reflexiv: x A avem x x;
- relaia este tranzitiv: x,y,z A din x y i y z rezult x z;
- relaia este antisimetric: din x y i y x rezult x=y;
-

Fie A={a
1
,a
2
,a
3
,..a
n
}. A sorta mulimea A nseamn:
- a dispune elementele sale n ordinea
a
...
a a a
i i i i n 3 2 1
s s s s , unde { } { }
a
,...,
a
,
a
=
a
,...,
a
,
a
,
a n 2 1
i i i i n 3 2 1

sau
- a determina un vector O=(o
1
,o
2
,...,o
n
), componenta o
i
indicnd poziia
elementului a
i
n mulimea sortat (ca la primul punct).

Exemplul 1. Se d un ir (vector) de numere ntregi. S se scrie un program
Pascal de sortare cresctoare a acestuia.

Vom prezenta n continuare mai multe programe PASCAL
corespunztoare unor algoritmi cunoscui. Pentru simplificarea expunerii vom
presupune c elementele mulimii A snt de tip ntreg, c numrul elementelor
sale nu depete 100, iar relaia de ordine este relaia obinuit.

1a) Sortare prin metoda bulelor sau prin interschimbare
Ideea acestui algoritm este urmtoarea:
- parcurgem mulimea (care poate fi echivalat cu un vector) de nceput la
sfrit comparnd doi vecini: a
i
cu a
i+1
. Dac a
i+1

i
, schimbm valorile lor
ntre ele ;
- dac am efectuat schimbri de poziie (de valori) relum procedeul ;
- Numele metodei deriv din faptul c, aa cum o bul de aer dintr-un lichid se
ridic la suprafa, tot aa la fiecare pas, valorile elementelor mai mari i
ocup poziii pe care nu le mai prsesc.

42
Programul Pascal este
uses crt;
var n, (* numarul de elemente *)
i, (* contor *)
aux: INTEGER; (* variabil de lucru *)
a: Array [1..10] of INTEGER;
sortat:Boolean;
begin

(* citim numarul de elemente ce trebuie sortate *)

repeat
write ( Numar de elemente de sortat );
read(n)
until (n>0) and (n<=100);

(* citeste elementele *)
for i:=1 to n do begin
write( a( ,i, )= );
read(a[i])
end;
(* sortarea elementelor *)
repeat
sortat:=true;
for i:=1 to n-1 do
if a[i+1]<= a[i] then begin
Aux:=A[i];
A[i]:=A[i+1];
A[i+1]:=Aux;
sortat:=false
end;
until sortat;

(* afiseaza rezultatul *)
clrscr; (*sterge ecranul*)
for i:=1 to n do
write(a[i], );
readln; (*asteapta Enter *)
end.


43

1b) Sortare prin selecie direct

Metoda se bazeaz pe observaia c primul loc n vectorul sortat st cel
mai mic element al mulimii, locul al doilea este ocupat de elementul care
urmeaz imediat dup acesta (ul multimii iniiale mai puin cel deja completat)
etc.

Programul Pascal este

uses crt;
var n, (* numarul de elemente *)
i,j, (* variabile contor *)
,indice_: INTEGER; (* variabile de lucru *)
a: Array [1..10] of INTEGER;
begin

(* citim numarul de elemente ce trebuie sortate *)

repeat
write ( Numar de elemente de sortat );
read(n)
until (n>0) and (n<=100);

(* citeste elementele *)
for i:=1 to n do begin
write( a( ,i, )= );
read(a[i])
end;

(* sortarea elementelor *)

for i:=1 to n do (*completam toate pozitiile ale multimii sortate *)
Begin
(* pe pozitia i trebuie sa stea cel mai mic element dintre a[i],a[i+1],...,
a[n] *)
:=a[i];
indice_:=i;
for j:=i+1 to n do
if a[j]< then begin

44
:=a[j];
Indice_:=j
end;
a[indice_]:=a[i];
a[i]:=
End;

(* afiseaza rezultatul *)
clrscr; (*sterge ecranul*)
for i:=1 to n do
write(a[i], );
readln; (*asteapta Enter *)
end.

1c) Sortare prin numrare
Cu aceast metod mulimea iniial se sorteaz n conformitate cu
definiia a doua a sortrii (se gsesc poziiile elementelor n mulimea sortat).
Ideea este urmtoarea: se ia elementul de indice i i se numr cte
elemente snt mai mici dect el. n vectorul sortat, el va ocupa urmtoarea
poziie.

uses crt;
type vector=array [1..10] of integer; (* definim tipul de data vector *)
var n, (* numarul de elemente *)
i,j:Integer; (* variabile contor *)
a, (* vectorul de sortat *)
o: vector; (*pozitiile in vectorul sortat *)
begin

(* citim numarul de elemente ce trebuie sortate *)

repeat
write ( Numar de elemente de sortat );
read(n)
until (n>0) and (n<=100);

(* citeste elementele ce trebuie sortate si initializeaza vectorul cu ordinea
elementelor *)
for i:=1 to n do begin
o[i]:=1; (* cel mai mic element ocup prima poziie *)

45
write( a( ,i, )= );
read(a[i])
end;

for i:=1 to n do (* elementele a[i] si a[j] se vor compara o singura
data ! *)
for j:=i+1 to n do
if a[i]<=a[j] then
Inc(o[j])
else
Inc(o[i]);

(* afiseaza rezultatul *)
clrscr; (*sterge ecranul*)
for i:=1 to n do
writeln (a[i], ocupa pozitia ,o[i]);
readln; (*asteapta Enter *)
end.


MODIFICAI programul de mai sus ca el s afieze elementele n ordine
cresctoare.


1d) Sortare prin inserie direct
Ideea acestei metode este urmtoarea: se pornete de la o list format din
primul element al mulimii. Se insereaz al doilea element al mulimii n list
astfel nct noua list s aib elementele dispuse n ordine cresctoare.La pasul j
avem lista ordonat a
1
a
2
a
3
... a
j-1
. Trebuie inserat elementul a
j
n list.
Pentru aceasta procedm astfel: l comparm pe a
j
cu elementele listei ncepnd
cu a
j-1
, a
j-2
s.a.m.d. Toate elementele mai mari dect el se deplaseaz cu o poziie
mai la dreapta. Elementul a
j
va fi inserat n capul listei (cnd lista nu are
elemente mai mici dect el) sau dup primul (nsensul de parcurgere a
vectorului) element a
i
care satisface relaia a
i
a
j
.

uses crt;
var n, (* numar de elemente *)
i,
j, (* contoare *)
aux, (* variabila de lucru *)

46
poz:integer; (*pozitia dupa care se va insera a[j] *)
a: array [1..100] of integer;
begin

(* citeste si valideaza numarul de elemente care alcatuiesc multimea (???!) *)
repeat
write('Numar de elemente = ');
readln(n)
until (n>0) and (n<=100);

(* citeste elementele *)

for i:=1 to n do begin
write('a(',i,')=');
read(a[i])
end;

(* completeaza pe rind elementele in lista partiala sortata *)
for j:=2 to n do begin
aux:=a[j]; (* pastreaza valoarea lui a[j] care se poate
modifica *)
i:=j-1;
while (i>0) and (aux<=a[i]) do begin
(* elementele mai mari ca a[j] se decaleaza spre dreapta cu o
pozitie *)
a[i+1]:=a[i];
dec(i)
end;
a[i+1]:=aux; (* pune a[j] pe locul sau *)
end;
(* afiseza rezultatul *)
clrscr;
for i:=1 to n do write (a[i],' ');
readkey; (* asteapta Enter *)
end.

2. Problema cutrii
Fie A o mulime finit de date i x o dat de acelai tip cu elementele
mulimii. Se cere s se verifice dac x A.

47
Prezentm n continuare mai multe soluii ale acestei probleme,
presupunnd c mulimea are n elemente care snt citite n memoria intern i
au tipul Integer.


2a) Cutare secvenial
Se compara x cu elementele mulimii pn cnd am gsit unul cu care este
egal sau am efectuat toate comparaiile posibile
(* s-a omis partea de declaraii i citiri de date *)

(* compara x cu elementele multimii. Daca s-a intilnit un element a[i] cu a[i]=x
ebandoneaza comparatiile *)
for i:=1 to n do
if x=a[i] then break;
if i<=n then
write( Elementul , x, este egal cu elementul de pe pozitia ,i)
else
write( Elementul ,x, nu face parte din multime );


Presupunem c mulimea A este sortat cresctor
Algoritmul de mai sus se poate mbunti n sensul c operaiile de
comparare se pot ncheia cnd s-a ntlnit primul element mai mare ca x sau cnd
s-a comparat cu toate. n acest caz avem

for i:=1 to n do
if x<=a[i] then break;
if (i<=n) and (x=a[i]) then
write( Elementul , x, este egal cu elementul de pe pozitia ,i)
else
write( Elementul ,x, nu face parte din multime );

2b). Cutare binar (sau prin metoda dihotomiei)

Ideea metodei este asemntoare cu cea de rezolvare a ecuaiilor
algebrice i tran-scendente prin metoda njumtirii intervalului.

program cautare;
var n, (* numar de elemente *)
x, (* valoarea ce se cauta *)

48
i,is,id,im:integer; (* indici *)
gasit:boolean;
a:array [1..10] of integer;
begin
for i:=1 to 10 do a[i]:=2*i+5;
write('introduceti valoarea de cautat ');
readln(x);
is:=1;id:=10; gasit:=false;
while((is<=id) and not gasit) do
begin
im:=(is+id) div 2;
if x<a[im] then
id:=im-1
else
if x>a[im] then
is:=im+1
else
gasit:=true;
end;
if gasit then writeln('Este pe pozitia ',im)
else writeln('Nu este');
end.



Se citesc de la tastatur valori ntregi. Fie n un numr natural dat. Reinei
din valorile date cele mai mici n dispuse n ordine cresctoare.
Rezolvm problema astfel:
- fie k variabila n care memorm numrul valorilor re
- valoarea iniial a variabile k este 0 (n-am reinut nici un element);
- citim o valoare x de la tastatur ;
- ncercm s o inserm n lista celor deja reinute astfel:
- parcurgem lista celor reinute ncepnd cu ultimul element al acesteia punnd
fiecare element mai mare dect x pe poziia urmtoare (cnd k=n, ultimul se
pierde);
- dac toate elementele snt mai mari dect x, acesta se va insera pe prima
poziie, altfel dup elementul care este mai mic dect x (dac nu exist un
astfel de element i k=n, valoarea x nu este inserat n list)
Presupunem c numrul n este mai mic sau egal cu 100.


49
Un posibil program PASCAL este urmtorul

uses crt;
var x, (* valori citite *)
n, (*numar de elemente ce trebuie retinute *)
j, (* contor *)
k: Integer; (* numar de elemente retinute *)
a: Array [1..100] of Integer; (* va contine elementele retinute *)

Begin
(* citim numarul de elemente ce trebuie pastrate *)
Repeat
Write( Cite elemente se retin (pastreaza) = );
Readln(n);
until (n>0) and (n<=100);

K:=0; (* n-am retinut inca nici un element *)
writeln( Incheiati cu CTRL - Z Enter );

while true do begin
write( x = );
read(x);
if eof then (* functia de biblioteca Eof intoarce true daca s-a tastat
CTRL-Z *)
break;
j:=k;
while (j>0) and (x<a[j]) do begin
a[j+ord(j<n)]:=b[j];
dec(j);
end;
inc (k,ord(k<n));
if j<n then
a[j+1]:=x
end;
writeln( Valorile retinute sint );
for j:=1 to k do
write(a[j], );
readln;
end


50
OBSERVAII
1. Dac numrul de elemente introduse coincide cu numrul de elemente ce
se pstreaz, valorile introduse se sorteaz cresctor ;
2. Ord(k<n) este 0 daca relaia k<n este false i 1 dac este true;
3. Afiarea elementelor se oprete la k i nu la n, fiindc s-ar putea ca
numrul de elemente introduse s fie mai mic dect n.

Tipul String


Tip de date String a fost introdus pentru a prelucra iruri de caractere. Se
declar prin
String[N]
sau
String
unde N 255 este numrul maxim de caractere al irului de caractere. Numrul
maxim implicit este 255.
S considerm urmtoarele declaraii
Type Sir=string[120];
var S: string;
P: Sir;
V: array [0..120] of Char;
n memorie, un ir de caractere ocup o zon de N+1 octei, n exemplul
nostru variabila S ocup 121 de octei, iar P 256 de octei. Caracterul i al irului
S poate fi referit prin expresia S[i], deci la fel cum ne referim la elementele unui
vector ( n particular, de caractere). Spre deosebire de vectori, prima poziie,
S[0], conine lungimea actual a irului (de aici limitarea la 255 a lungimii
irurilor de caractere), dar reprezentat sub form de tip Char. Prin urmare,
lungimea irului este Ord(S[0]).
Dac vectorul V l putem utiliza doar operaii de atribuire, irurile S i P
pot fi folosite n operaii de atribuire i n urmtoarele operaii cu iruri:
- concatenarea - notat + Dac S are valoarea Astazi este , unde prin am
notat caracterul spaiu, iar P miercuri atunci, S+P este irul de caractere
Astazi este miercuri
De notat c rezultatul nu poate depi 255 de caractere.
- comparri n sensul = < > <= >= i <>. Compararea se face caracter cu
caracter innd seama de poziia fiecrui caracter n tabelul de codificare
ASCII (prin urmare a > A , A > 3' etc.). Aceast comparare este
numit comparare lexicografic.


51
irurile de caractere pot fi argumente actuale ale funciilor Read, Write
etc. Prin urmare, un ir nu trebuie citit caracter cu caracter ca n cazul vectorilor
i nici nu trebuie scris caracter cu caracter.
Snt disponibile urmtoarele proceduri i funcii pe iruri:
- Length - ntoarce lungimea unui ir ;
- Copy - ntoarce un subir al unui ir;
- Concat - concateneaz dou sau mai multe iruri;
- Pos - ntoarce poziia unui subir ntr-un ir;
- Delete - elimin un subir dintr-un ir;
- Insert - insereaz un subir ntr-un ir;
- Str - convertete o expresie numeric n forma extern;
- Val - convertete un subir ntr-o valoare numeric.

Toate vor fi tratate n capitolul relativ la unitile de program Pascal.

Exemplu.
S se transforme n litere mici literele mari ale unui ir de caractere.

function Litere_mari(S: string): string;
var
I: Integer;
begin
for I := 1 to Length(S) do
if (S[I] >= 'a') and (S[I] <= 'z') then
Dec(S[I], 32);
Litere_mari := S;
end;



Date de tip ZString

Un ZString este un tablou de caractere care are primul indice 0, iar
ultimul un ntreg pozitiv nenul N. Ele se declar prin
array[0..N] of Char
Valoarea maxim a lui N este 65535. Lungimea acestuia poate fi mai
mic dect N+1. n acest caz, irul se ncheie cu caracterul NULL (de aceea ele
mai poart numele de iruri care se termin cu null).
Exist funcii de conversie din string n Zstring i invers.
.

52
Tipul mulime

Mulimea este o colecie de date de acelai tip care poate fi de un baz
nestructurat exceptnd tipul REAL.
Tipul mulime se declar prin
Set of <tip>
Elementele pot fi numere naturale mai mici ca 256, elemente ale unui tip
enumerare sau caractere. Numrul de elemente care formeaz mulimea se
limiteaz la 256. Prin urmare, tipul de baz al unei mulimi de elemente de tip
ntreg nu poate fi INTEGER, ci o parte a sa.
O mulime poate fi construit din elementele sale folosind constructorul
de mulimi [] care conine n interior enumerri. De exemplu:
[] nseamn mulimea vid;
[1] nseamn mulimea format din elementul 1;
[1,2,3] este muliema format din elementele 1,2 i 3;
[ A .. Z ] este mulimea caracterelor alfabetice cuprinse ntre A i Z;
[ Z .. A ] este mulimea vid.

Exemple
type examen=(algebra, analiza,programare,bazamate);
examene=set of examen;
var promovate,
nepromovate,
aminate: examene;

O mulime al crui tip de baz are n elemente se reprezint n memorie
printr-un ir de n bii. Bitul I este 1 dac elementul cu ordinalul I face parte din
mulime.

Operaii cu mulimi:
reuniunea +
intersecia *
diferena -
Dou mulimi se pot compara n sensul =, <> (diferit), <= i >=
(incluziune).In fine, folsind operatorul IN se poate testa dac un element
aparine unei mulimi.
n limbajul PASCAL exist dou proceduri de includere i eliminare a
unui element dintr-o mulime. Acestea snt
Include(var S: set of T; element:T);
Exclude(var S: set of T; element:T);

53
Ele pot fi nlocuite cu instruciunile de atribuire S:=S+[T], respectiv S:=S-[T]

EXEMPLU

program Eratostene;
(*
Determinarea tuturor numerelor prime mai mici decit 255 folosind ciurul lui
Eratostene
*)
uses crt;
const n=255;

type multime= set of 2..n ;

var ciur,
prime : multime;
multiplu,
urmator :integer;

begin
ciur:=[2..n];
prime:=[];
urmator:=2;
clrscr;
repeat
while not (urmator in ciur) do (* cauta urmatorul numar prezent in
ciur *)
urmator:=succ(urmator);
exclude(ciur,urmator); (* exclude-l din ciur *)
include(prime,urmator); (* adauga-l la prime *)
multiplu:=urmator; (* elimina-i multiplii din ciur *)
while multiplu<=n do
begin
exclude(ciur,multiplu);
inc(multiplu,urmator);
end;
urmator:=succ(urmator); (*determina urmatorul element *)
until (ciur=[]) or (urmator>n);

for urmator:=2 to n do (* afiseaza numerele prime *)

54
if urmator in prime then
write(urmator:4);
write(^m^j'Tastati Enter');
readln;
end.

Tipul record (nregistrare)

Numeroase obiecte din lumea real se caracterizeaz printr-o mulime de
proprieti sau atribute. Atributele servesc la descrierea unei clase generale de
obiecte de acelai tip care formeaz tipul obiectului. Un obiect particular al
acestui tip se obine asociind valori fiecrui atribut. De exemplu, un student al
Facultii de tiinte se poate caracteriza prin: nume, nr_matricol, secia, grupa,
adresa etc, un abonat al ROMTELECOM prin nume, adresa i numar_telefon.
n informatic, definirea unui tip structurat const n enumerarea numelui
fiecrui atribut care caracterizeaz tipul de date i tipul de dat corespunztor
fiecrui atribut. Un astfel de tip de date se va numi tip record sau nregistrare.
.Declaraia sa respect urmtoarele reguli
TipDeI nregistrare=record
cimp1[,cimp2].. : TipDeData;
[cimp1[,cimp2].. : TipDeData;]...
End;

Exemple

type
Point = record
X, Y: Real;
end;
Vector = array[0..1] of Point;
Month = (Jan, Feb, Mar, Apr, May, Jun, Jly, Aug, Sep, Oct, Nov, Dec);
Date = record
D: 1..31;
M: Month;
Y: 1900..1999;
end;

Exemplul 2.

type student=record

55
numele: string[30];
sex: boolean;
data_nasterii: record
zi: 1..31;
luna: 1..12;
an:1900..1982;
end;
nr_grupa:integer;
note: array[1..10] of 1..10;
end;

Se poate defini o variabil de acest tip

var grupa:array [1..35] of student;
un_student: student;

Asupra datelor de tip record se pot efectua numai operaii de atribuire, n
timp ce asupra unui cmp se pot efectua toate operaiile permise la acel tip de
date.
Pentru a face referiri la un cmp al unei nregistrri se folosete selectorul
. (punct). Ne vom referi la cmpul numele al variabilei un_student prin
un_student.numele, iar la cmpul numele celui de-al 10-lea student al tabloului
grupa prin grupa[10].numele.

OBSERVAIE
Structura de date nregistrare modeleaz produsul cartezian din
matematic. O nregistrare const dintr-un numr fix de elemente componente,
fiecare avnd un anumit tip.
Pentru a simplifica scrierea programelor, cnd ntr-o secvena de
instruciuni ne referim n mod repetat la membrii aceleiai structuri, putem
folosi intructiunea WITH care are urmtoarea sintax
WITH nregistrare DO instruciune;

De exemplu secvena

with grupa[i] do begin
numele:= ;
sex:=false;
nr_grupa:=0;
end;

56

ine locul urmtoarelor instruciuni:

grupa[i].numele:= ;
grupa[i].sex=false;
grupa[i].nr_grupa:=0;


Inregistrri cu variante

Snt situaii cnd structura unei nregistrri variaz n funcie de valoarea
pe care o ia un anumit cmp al su numit discriminator. n mod obligatoriu,
partea variabil se descrie la sfritul structurii, astfel
CASE [discriminator:] tip_discriminator OF
valoare_discriminator:(definiii_de_cmpuri);
valoare_discriminator:(definiii_de_cmpuri);

Exemplul 1

uses crt;
type sex=(barbatesc,femeiesc);
alfa=string[30];
personal=record
nume:alfa;
adresa:alfa;
case sexul:sex of
Barbatesc: (greutate: integer; barba:char);
Femeiesc: (inaltime: 145..200;nume_fata: alfa);
end;
var persoana:personal;
C_sex:char;
begin
with persoana do begin
writeln('persoana'); readln(nume);
writeln('adresa'); readln(adresa);
writeln('sexul'); readln(C_sex);
case C_sex of
'm': begin
sexul:=barbatesc;
writeln('gr'); readln(greutate);

57
writeln('barba');readln(barba);
end;
'f': begin
Sexul:=femeiesc;
write('inaltime');readln(inaltime);
write('nume fata'); readln(nume_fata);
end;
end;
end;
end.

Exemplul 2.

Type denumire=array [1..30] of char;
forma=(fara, { fara studii}
Medie, { cu liceu }
Sup); { cu facultate }
persoana=record
Nume,prenume: array [1..20] of char;
Data_nasterii: record
zi: 1..31;
Luna: 1..12;
An: 1940..1975;
End;
Studii: forma;
case forma of
fara:(); { nu avem atribute}
medie:(liceu: record
Den:denumire;
Media_bac:real;
End);
sup:(s: record
Liceu:denumire;
Media_bac:real;
fac:denumire;
mediaf:real
end);
end; { persoana}

Date de tip referin cu tip

58

O variabil de tip referin are ca valoare adresa unei zone de memorie.
Aceasta poate fi, de exemplu, adresa la care se memoreaz valoarea unei
variabile scalare (deci adresa variabilei). Se declar prin construcii de forma:

nume_variabil:^tip_de_dat
De exemplu

p:^integer; { variabila p este o referin de tip integer }
type ptr=^persoana; { ptr este tipul de date referin la date de tip
persoana}
persoana=record
nume:string[30];
vrsta:integer;
end;
var student:ptr; { student este o referin la date de tip persoana }

n primul caz, data referit de p are tipul integer, iar n al doilea, data
referit de student este de tipul persoana.
Unei variabile referin cu tip i se poate atribui o valoare prin operaii de
atribuire, folosind operatorul de adres @ sau funciile New i GetMem (prin
care poate rezerva zon de memorie pentru date dinamice).
Valoarea predefinit de tip referin Nil corespunde referinei ctre nici
un obiect/dat.
n expresii, valoarea datei spre care puncteaz o referin p este indicat
prin construcia p^. Aciunea prin care se identific o dat prin intermediul unei
variabile de tip referin poart numele de defereniere a variabilei.
O referin cu tip poate interveni n operaii de adresare (cu @) sau de
comparare n sensul <> sau =).

Tipul pointer sau referin fr tip

Definirea i utilizarea acestui tip de dat snt asemntoare cu cele de la
tipul referin cu tip. Deosebirile constau n:
- data referit nu are precizat tipul (este nedefinit);
- nu se poate utiliza funcia New pentru a li se atribui valoare.

De exemplu
type adresa=Pointer;
var a:adresa;

59

CONSTANTE CU TIP

O categorie special de constante este cea a constantelor cu tip.
Declararea lor se face n partea declarativ a blocului prin expresii de forma:

const nume_de_constanta_1 : tip_de_data_1=valoare_1;
[nume_de_constanta_2 : tip_de_data_2=valoare_2;]...

Constantele cu tip snt similare variabilelor iniializate (variabile ale cror
valori snt definite cnd se intr in blocul n care se definesc).Expresiile prin
care se declar conin att tipul, ct i valoarea constantei.
Constantele cu tip se utilizeaz ca variabilele de acelai tip i pot s apar
n membrul stng al unei instruciuni de atribuire.
Ele snt iniializate o singur dat: la nceputul programului. Pentru orice
punct de intrare ntr-o procedur sau funcie, constantele cu tip declarate local
nu snt reiniializate.

Exemple de constante simple cu tip:
const
Min : Integer = 0;
Max : Integer = 9999;
Send : Char = #3;


X Constante cu tipul string
Declaraia unei constante cu tipul string specific lungimea maxim a
irului i valoarea sa iniial.
Exemple
const LinieNoua: string[2] = #13#10;
Da: string[2] = 'Da';


X Constante cu tipul Set
Declararea unei constante cu tipul set specific valoarea mulimii folosind
expresii constante.
Exemple:
type Cifre = set of 0..9; Litere = set of 'A'..'Z';
const
CifrePare: Cifre = [0, 2, 4, 6, 8];

60
Vocale: Litere = ['A', 'E', 'I', 'O', 'U'];
CifreHexa: set of '0'..'z' = ['0'..'9', 'A'..'F', 'a'...f'];


- Constante cu tipul Array
Declaraia unei constante cu tipul array specific valorile componentelor
sale. Fiecare element al tabloului poate fi de orice tip diferit de file.
Exemple:
type Stare = (Activa, Pasiva, Asteptare); StareM = array[Stare] of
string[9];
const
StareStr: StareM = ('Activa', 'Pasiva', 'Asteptare');

{ Componentele acestei constante snt: StareStr[Activa] = 'Activa',
StareStr[Pasiva] = 'Pasiva', StareStr[Asteptare] = 'Asteptare' }


- Constante cu tipul array of Char
Tablourile de caractere pot fi specificate ca vectori ale cror elemente snt
caractere sau ca iruri. n acest sens, declaraia

const Cifre: array[0..9] of Char = ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9');

este echivalent cu declaraia

const Cifre: array[0..9] of Char = '0123456789';


- Constante cu tipul ZString
Un ZString este un tablou de caractere care are primul indice 0, iar
ultimul un ntreg pozitiv nenul. De exemplu, array[0..X] of Char. Cnd este
permis sintaxa extins (directiva de compilare {$X+} ),un Zir poate fi
iniializat cu un ir care este mai scurt dect lungimea declarat a tabloului.

const Nume_De_Fiier = array[0..79] of Char = 'PERSONAL.DAT';

Dac irul de inializare este mai scurt dect dimensiunea tabloului,
caracterele rmase (n dreapta) snt puse pe NULL (00), deci tabloul va conine
efectiv un ir care se ncheie cu caracterul NULL.


61
- Constante cu tipul tablou multidimensional
n cazul tablourilor multidimensionale, constantele pentru fiecare
dimensiune snt incluse ntre paranteze. Constantele cele mai interioare
corespund dimensiunilor celor mai din dreapta. De exemplu, n cazul
declaraiilor
type Cub = array[0..1, 0..1, 0..1] of Integer;
const Tab: Cub = (((0, 1), (2, 3)), ((4, 5), (6, 7)));
avem
Tab[0, 0, 0] = 0 Tab[0, 0, 1] = 1
Tab[0, 1, 0] = 2 Tab[0, 1, 1] = 3
Tab[1, 0, 0] = 4 Tab[1, 0, 1] = 5
Tab[1, 1, 0] = 6 Tab[1, 1, 1] = 7

- Constante cu tipul nregistrare

Declaraia unei constante de tip nregistrare specific identificatorul i
valoarea fiecrui cmp (membru) al nregistrrii.
Nu este aplicabil nregistrrilor care conin cmpurile unor fiiere cu tip.
Dac o nregistrare conine o variant se vor specifica numai cmpurile variantei
selectate.

Exemplu
type Punct = record
X, Y: Real;
end;
Vector = array[0..1] of Punct;
Luna = (Ian, Feb, Mar, Apr, Mai, Iun, Jul, Aug, Sep, Oct, Nov, Dec);
Data = record
D: 1..31;
M: Luna;
Y: 1900..1999;
end;
const Origine: Punct = (X: 0.0; Y: 0.0);
Linie: Vector = ((X: -3.1; Y: 1.5), (X: 5.8; Y: 3.0));
Odata: Data = (D: 2; M: Dec; Y: 1960);


- Constante cu tipul pointer
Declaraia unei constante cu tipul pointer utilizeaz expresii de adres
constante pentru a specifica valoarea pointerului. Dac este permis utilizarea

62
sintaxei extinse (directiva {$X}), o constant cu tipul PChar poate fi iniializat
cu un ir de constante.

Exemple:
type Directie = (Stinga, Dreapta, Sus, Jos);
StringPtr = ^String;
NodPtr = ^Nod;
Nod = record
Urmator: NodePtr;
Simbol: StringPtr;
Valoare: Directie;
end;
const
S1: string[3] = 'JOS'; S2: string[3] = 'SUS';
S3: string[7] = 'DREAPTA'; S4: string[6] = 'STINGA';
N1: Nod = (Urmator: nil; Simbol: @S1; Valoare:Jos);
N2: Nod = (Urmator: @N1; Simbol: @S2; Valoare: Sus);


EXEMPLUL 1.
{
Calculeaza valoarea bitului de paritate al unui caracter ASCII si
seteaza-l
astfel incit:
- numarul total de biti 1 sa fie impar (ODD);
- numarul total de biti 1 sa fie par (EVEN);
- bitul sa fie 1 (MARK);
- bitul sa fie 0 (SPACE).
}
uses crt;

type paritate =(EVEN,ODD,MARK,SPACE);

{
Intoarce un sir de caractere alcatuit din valorile bitilor argumentului
}

function binary(n: byte):string;
var i:integer;
s:string;

63
begin
s:='';
for i:=7 downto 0 do
s:=s+chr ((n shr i) and 1 + $30);
binary:=s;
end;

{
intoarce cifra hexazecimala corespunzatoare valorii argumentului
}
function cifra(n:byte):char;
begin
if n<10 then
cifra:=chr(n+$30) { valorile sub 10 se transforma in caracterele '0' etc.}
else
cifra:=chr(n+$37); { valorile peste 9 in literele 'A'..'F'}
end;

{ intoarce valoarea hexazecimala a unui octet}

function hexa(c:byte):string;
begin
hexa:=cifra(c div 16) + cifra(c mod 16);
end;

{ In cazul paritatii EVEN numarul total de biti de 1 trebuie sa fie par,
deci valoarea bitului de paritate este rezultatul intersectiei exclusive a valorilor
bitilor b0-b6 ai caracterului.
In cazul paritatii ODD numarul total de biti de 1 trebuie sa fie impar,
deci valoarea bitului de paritate este complementara intersectiei exclusive a
valorilor
bitilor b0-b6 ai caracterului.
}

function pune( c: byte; fel:paritate) :INTEGER;

var c1: byte; { bitul de paritate setat}

i:integer;
begin

64

c:=c and $7f; { ELIMINA BITUL DE PARITATE }

if fel=MARK then
pune:=c or $80
else
if fel=SPACE then
pune:=c and $7f
else
begin
c1:=ord(fel);
for i:=0 to 6 do
c1:=c1 xor (( c shr i) and 1);
pune:=c or (c1 shl 7);
end;
end;


var c:byte;
begin
clrscr;

while true do begin
write('Tastati un caracter (Incheiati cu <CTRL-BREAK>) ');
c:=byte(readkey);
writeln(#10#13'Caracterul ',chr(c), '(cod ASCII hexazecimal ',hexa(c),
') are valoarea hexazecimala cu paritate: ',
#10#13,' ODD ',hexa(pune(c,ODD)),' ',binary(pune(c,ODD)),
#10#13,' EVEN ',hexa(pune(c,EVEN)),' ',binary(pune(c,EVEN)),
#10#13,' MARK ',hexa(pune(c,MARK)),' ',binary(pune(c,MARK)),
#10#13+' SPACE ',hexa(pune(c,SPACE)),'
',binary(pune(c,SPACE)));
end;
end.



EXEMPLUL 2.
(* Alcatuieste toate numerele binare de cel mult n cifre *)


65
program contor;
uses crt;

var n:integer; (* numar de cifre *)
a: array [1..10] of byte; (* cifrele numarului *)

(*in aceasta functie se alcatuieste un numar pornind de la precedentul *)

function alcatuieste:boolean;
var i:integer;
begin
alcatuieste:=true;
for i:=n downto 1 do
if a[i]=0 then
begin
a[i]:=1;
alcatuieste:=false;
exit;
end
else
a[i]:=0;
end;
var i:integer;
begin
repeat
write('n=');
readln(n);
until n in [1..10];
for i:=1 to n do a[i]:=0;
repeat
writeln;
i:=1;
while(i<n) and (a[i]=0) do
begin
inc(i);
write('..');
end;
for i:=i to n do write(a[i]:2);
until alcatuieste;
readln;end.

66

UNITI DE PROGRAM PASCAL

O unitate de program Pascal este o colecie de elemente (constante, tipuri
i variabile) , funcii i proceduri i o seciune de iniializare organizate ntr-un
bloc compilabil separat.
O unitate de program are dou pri: interfaa i implementarea. Interfaa
este alctuit din elementele accesibile din exterior. Partea de implementare este
alctuit din constante, variabile, funcii i proceduri, toate inaccesibile din
exterior i funcii i proceduri descrise n interfa. Forma general a unei uniti
de program este

UNIT nume;

INTERFACE
{ declaraii }

IMPLEMENTATION
{lista de declaraii locale}

[BEGIN
{secven de iniializare}
] end.

Secvena de iniializare poate lipsi i conine instruciuni ce trebuie
executate naintea nceperii execuiei programului principal (pentru iniializarea
unor elemente).
Un program sau unitate de program care dorete s utilizeze unitatea U
trebuie s declare acest lucru explicit sub forma uses U;

Exist uniti de Program standard (oferite de mediul TURBO PASCAL)
cum snt system (singura care nu trebuie declarat), crt, dos, etc.

Prezentm n continuare o unitate de program PASCAL care definete
tipul virtual de dat numr raional.

unit ura;
interface
type rational=record
numarator:integer;

67
numitor:integer;
end;

procedure aduna(a,b:rational;var suma:rational);
procedure scade(a,b:rational;var diferenta: rational);
procedure inmulteste(a,b:rational; var produs:rational);
procedure imparte(a,b:rational; var cit:rational);
procedure citeste(var r:rational);
procedure tipareste(r:rational);
function p_intreaga(r:rational):integer;
function mai_mare(a,b:rational):boolean;
function estezero(r:rational):boolean;
implementation

function cmmdc(m,n:integer):integer;
begin
if n=0 then
cmmdc:=m
else
cmmdc:=cmmdc(n, m mod n);
end;

function cmmmc(m,n:integer): integer;
begin
cmmmc:=m*n div cmmdc(m,n);
end;

procedure simplifica(var r:rational);
var c:integer;
begin
c:=cmmdc(r.numarator,r.numitor);
if c*r.numitor<0 then
c:=-c;
r.numarator:=r.numarator div c;
r.numitor:=r.Numitor div c;
end;
function estezero;
begin
estezero:=r.numarator=0;
end;

68

procedure aduna;
begin
suma.numarator:=a.numarator*b.numitor+b.numarator*a.numitor;
suma.numitor:=a.numitor*b.numitor;
simplifica(suma);
end;

procedure scade;
begin
diferenta.numarator:=a.numarator*b.numitor-b.numarator*a.numitor;
diferenta.numitor:=a.numitor*b.numitor;
simplifica(diferenta);
end;

procedure inmulteste;
begin
produs.numarator:=a.numarator*b.numarator;
produs.numitor:=a.numitor*b.numitor;
simplifica(produs);
end;
procedure imparte;
begin
cit.numarator:=a.numarator*b.numitor;
cit.numitor:=a.numitor*b.numarator;
simplifica(cit);
end;

procedure citeste;
begin
write('Numaratorul = '); read(r.numarator);
write('Numitorul = '); read(r.numitor);
end;

procedure tipareste;
begin
write(r.numarator); write('/'); write(r.numitor);
end;

function p_intreaga;

69
begin
p_intreaga:=r.numarator div r.numitor;
end;

function mai_mare;
begin

mai_mare:=(a.numarator*b.numitor-a.numitor*b.numarator)/(a.numitor*b.nu
mitor)>=0;
end;
end.

n exemplul de mai jos, unitatea de program Pascal Ura este folosit
pentru rezolvarea sistemelor de ecuaii liniare cu coeficieni raionali.

program sistem;
uses ura,crt;
const n=3;
type vector=array [1..n] of rational;
matrice=array [1..n] of vector;
var a: matrice;
b: vector;
cod,i,k:integer;

{ citeste matricea extinsa asociata sistemului }

procedure citim(var a:matrice;var b:vector);
var i,j:integer;
begin
clrscr;
for i:=1 to n do { coeficientii se dau pe linie }
begin
for j:=1 to n do
begin
write('a(',i,',',j,') '); citeste(a[i,j]);
end;
write('b(',i,')'); citeste(b[i]); { citeste termenul liber }
end;
end;


70
procedure Gauss( n: integer;
var a:matrice;
var b:vector;
var cod:integer);
var i,j: integer;
var r:rational;

(* schimba intre ele liniile i si j *)

procedure schimba(i,j:integer);
var k: integer;
aux:rational;
begin { se putea porni cu indicele de la i,fiindca pina acolo toate elem sunt
zero}
for k:=1 to n do begin
aux:=a[i,k];
a[i,k]:=a[j,k];
a[j,k]:=aux;
end;
aux:=b[i]; b[i]:=b[j]; b[j]:=aux; { schimba si termenul liber }
end;

(* imparte ecuatia i cu r *)

procedure impart(i:integer;r:rational);
var k: integer;
begin
for k:=1 to n do
imparte(a[i,k],r,a[i,k]);
imparte(b[i],r,b[i]);
end;

procedure elimina(i,j:integer; r:rational); { elimina x[i] din ecuatia j }
var k:integer;
r1: rational;
begin
for k:=i to n do
begin
inmulteste(r,a[i,k],r1);
scade(a[j,k],r1,a[j,k]);

71
end;
inmulteste(r,b[i],r1);
scade(b[j],r1,b[j]);
end;

{ cauta un coeficient nenul pe linia i }

procedure cauta(var i,j:integer; var c:integer);
begin
if estezero(a[i,j]) then c:=0 else c:=1;
j:=i+1;
while (j<=n) and (c=0) do
if estezero(a[i,j]) then
j:=j+1
else
c:=1;
end;
(*inceputul metodei Gauss *)
begin
i:=1; cod:=1;
while(cod=1) and (i<n) do
begin
cauta(i,j,cod);
if cod=1 then begin
schimba(i,j);
r:=a[i,j];
impart(i,r);
for j:=i+1 to n do
begin
r:=a[i,j];
elimina(i,j,r);
end
end
else
cod:=0;
end;
end; {Gauss}

procedure rezolva( n:integer;
a:matrice;

72
var b:vector;
var ind: integer);
var r,r1:rational;
i,k: integer;
begin
r1:=b[n]; ind:=1;
if estezero(a[n,n]) then ind:=0 else imparte(r1,a[n,n],b[n]);
i:=n-1;
while(ind=1) and (i>=1) do
begin
r1:=b[i];
for k:=i+1 to n do
begin
r:=a[i,k];
inmulteste(r,b[k],r);
scade(r1,r,r1)
end;
if estezero(a[i,i]) then ind:=0 else imparte(r1,a[i,i],b[i]);
i:=i-1;
end;
end;

begin
citim(a,b);
gauss(n,a,b,cod);
rezolva(n,a,b,cod);
if cod=0 then writeln('Sistemul nu este Cramer')
else begin
writeln(#13#10'Solutia sistemului este ');
for i:=1 to n do begin
write('x(',i,')='); tipareste(b[i]); writeln;
end;
End;
end.

Tipul de dat file

A fost introdus pentru a face legtura cu perifericele unui calculator. El
respect structura fiierelor de pe discul magnetic ntr-o form proprie.

73
Un fiier este alctuit dintr-o list liniar de nregistrri (componente sau
articole), fiecare avnd sau nu un tip. Tipul componentelor trecuie s difere de
tipul file.
Dac fiierul nu are tip, se consider alctuit din nregistrri de lungime
fix. Lungimea nregistrrilor se declar la deschiderea sa. Accesul la articolele
fierelor fr tip poate fi secvenial i direct (prin intermediul numrului de
articol - primul articol avnd numrul 0).
Fiierele predefinite de tip text conin caractere care snt organizate n
linii sau rnduri care snt delimitate ntre ele prin caracterele CR LF. Sfritul de
fiier este marcat prin caracterul CTRL Z (codul hexazecimal 1A). Accesul este
numai secvenial.
Prezentm mai jos cteva instruciuni de declarare de fiiere:
type
Persoana = record
Nume: string[15];
Prenume : string[25];
Adresa : string[35];
end;
Var Fisier_persoane : file of Persoana;
Fiser_de_Numere : file of Integer;
FisierDeManevra : file;
Scrisoare : Text;

Prezentm n continuare proceduri i funcii relative la tratarea fiierelor.
Acestea fac parte din unitatea de program Pascal System.

Assign
- asociaz numele unui fiier extern cu o variabil PASCAL de tip fiier;
- are declaraia
procedure Assign(var f ;Sir:String);
unde f este o variabil fiier de orice tip, iar Sir expresie de tip ir de
caractere (sau o expresie de tip Pchar n cazul sintaxei extinse). Toate
operaiile asupra lui f vor aciona asupra fiierului extern identificat prin
Sir. Sir este de forma [Drive:][Cale]Nume[.Ext] , unde Drive reprezint
numele simbolic al unitii de disc pe care se afl fiierul, Cale calea de
cutare, Nume i Ext numele i extensia numelui fiierului. Elementele
cuprinse ntre [] snt opionale. Snt valabile regulile din MS DOS privind
identificarea fiierelor. Lungimea irului de caractere Sir trebuie s fie
cuprins intre 0 i 79. n cazul n care irul are lungimea 0, variabila fiier
f este asociat fiierului standard de intrare (dac fiierul se deschide cu

74
Reset) sau fiierului standard de ieire (dac fiierul se deschide cu
procedura Rewrite);
- asocierea dintre f i fiierul Sir rmne valabil pn cnd variabila fiier f
este utilizat ntr-un alt apel al funciei Assign;
- nu poate fi utilizat pentru un fiier deschis.
Exemplu
var F1: Text;
F2: file of Integer;
Assign(F1, '');{ f1 este asociat fisierului standard de intrare sau iesire }
Assign(F2, date );


IOResult
- ntoarce modul de ncheiere a ultimei operaii de deschidere de fiier, citire
sau scriere i pune pe 0 indicatorul intern de eroare;
- are declaraia
function IOResult: Integer;
- ntoarce 0 n cazul n care operaiile s-au ncheiat normal;
- pentru a se putea verifica modul de terminare a operaiilor de mai sus, textul
surs trebuie s conin directiva de compilare {$I-}. La ntlnirea unei erori,
toate operaiile care urmeaz pn la apelul funciei IOResult snt ignorate.

Reset
- deschide un fiier existent;
- are declaraia
procedure Reset(var F : File[; Lungime: Word ] );
unde F este un fiier de orice tip care a fost asociat cu un fiier extern,
Lungime specific dimensiunea articolului n cazul fiierelor fr
tip.Valoarea sa implicit este 128;
- dac fiierul extern asociat variabilei F nu exist, procedura Reset se ncheie
anormal. Dac la apelul procedurii F este deschis, el este nchis, apoi
redeschis;
- poziia curent n fiier (locul din care se va citi sau se va scrie) este
nceputul fiierului. Funcia Eof care are ca parametru fiierul F va avea
valoare True numai dac fiierul este vid.
- dac F este de tipul text, asupra lui F se pot efectua numai operaii de citire;
- dac directiva de compilare {$I-} este prezent, funcia IOResult ntoarce
valoarea 0, iar n caz contrar codul de eroare.
Exemplu.

75
Funcia de mai jos ntoarce valoarea True, dac fiierul identificat prin
parametrul FileName exist

function Exista(FileName: String): Boolean;
var F: file;
begin
{$I-}
Assign(F, FileName);
{ deschide si inchide fisierul }
Reset(F); Close(F);
{$I+}
Exista := (IOResult = 0) and (FileName <> '');
end;
Rewrite
- creaz i deschide un fiier nou;
- are declaraia
procedure Rewrite(var F: File [; Lungime: Word ] );
n care F este o variabil file de orice tip asociat cu Assign unui fiier
extern. Parametrul Lungime poate fi specificat n cazul fiierelor fr tip.
Valoare implicit (prin lips) este 128;
- dac fiierul este deschis, el se nchide. Dac fiierul exist, el este ters i se
creaz altul nou;
- poziia curent n fiier este nceputul fiierului;
- n cazul fiierelor de tip text, singura operaie permis este scrierea;
- dup apelul funciei Rewrite, Eof(F) are valoarea True. n prezena directivei
de compilare {$I-}, funcia IOResult ntoarce valoarea 0 n cazul n care
deschiderea a reuit, altfel aceasta ntoarce un cod de eroare.
Exemplu
var F: Text;
{...}
Assign(F, 'scris');
Rewrite(F);
{...}

Append
- deschide un fiier text pentru scriere n continuare (la sfritul su);
- are declaraia
procedure Append(var f: Text);
unde f este o variabil file de tip text care a fcut obiectul unei asocieri cu
un fiier extern (procedura Assign). Acesta din urm trebuie s existe.

76
Poziia curent n fiier este sfritul su sau, dac n ultimii 128 de octei
ai fiierului este prezent caracterul CTRL Z, poziia acestuia;
- dac fiierul este deschis, el este nchis, apoi redeschis;
- singura operaie permis este cea de scriere;
funcia IOResult ntoarce 0 sau codul de eroare, dac este prezent directiva de
compilare {$I-}.

Exemplu
var F: Text;
begin
Assign(F, 'TEST.TXT');
Rewrite(F); { Creaza un fisier }
Writeln(F, 'text initial');
Close(F); { inchide fisierul }
Append(F); {deschide fisierul pentru scriere in continuare }
Writeln(F, 'Text adaugat');
Close(F); { inchide fisierul }
end.


Close
- nchide un fiier deschis cu Reset, Rewrite sau Append;
- are declaraia
procedure Close(var F);
- dac fiierul F este deschis pentru scriere fiierul extern asociat lui F este
completat cu ultimele date care nu au fost scrise;
- folosii IOResult pentru a verifica modul n care s-a terminat operaia de
nchidere.

Flush
- transfer coninutul zonei tampon pe disc sau golete zona tampon;
- are declaraia
flush(Var F: Text);

- pentru a accelera transferul de date dintre memoria intern i suportul
magnetic (discul), pentru citire i scriere se utilizeaz o zon de memorie
suplimentar (diferit de aceea n care citim componente ale fiierului)
numit zon tampon sau buffer. Citirea i scrierea efectiv au loc la prima
citire, n momentul n care zona tampon este goal (n cazul citirilor) sau
plin (n cazul scrierilor), cnd fiierul este nchis, la terminarea normal a

77
programului sau cnd se cere n mod expres acest lucru.

Truncate
- trunchiaz un fiier ncepnd cu poziia curent;
- are declaraia
procedure Truncate(var F);

unde fiierul f este un fiier deschis i de orice tip diferit de text. Toate
nregistrrile fiierului ncepnd cu poziia curent snt terse, iar poziia
curent n fiier este sfritul fiierului;
- folosii IOResult pentru a verifica modul de ncheiere a operaiei de
trunchiere.

Uses crt, dos;
var
f: file of Integer;
i,j: Integer;
begin
Assign(f,'date');
Rewrite(f);
for i := 1 to 6 do Write(f,i);
Writeln('Continutul fisierului inainte de trunchiere:');
Reset(f);
while not Eof(f) do
begin
Read(f,i);
Writeln(i);
end;
Reset(f);
for i := 1 to 3 do
Read(f,j); { Citeste primele 3 articole}
Truncate(f); { Trunchiaza fisierul }
Writeln;
Writeln('Continutul fisierului dupa trunchiere:');
Reset(f);
while not Eof(f) do
begin
Read(f,i);
Writeln(i);
end;

78
Close(f);
Erase(f); { sterge fisierul }
end.


Seek
- mut poziia curent a unui fiier la o component specificat;
- are declaraia
procedure Seek(var F; N: Longint);
unde F este o variabil de tip file (diferit de text) deschis , iar N o
expresie de tipul LongInt;
- dup apelul procedurii, poziia curent devine cea a componentei a N-a,
prima component avnd numrul 0;
- apelul seek(f,sizeof(f)) mut poziia curent la sfritul fiierului;
- folosii funcia IOResult pentru a vedea dac operaia de poziionare s-a
ncheiat corect sau nu.
FilePos
- ntoarce poziia curent a unui fiier;
- are declaraia
function FilePos(var F): Longint;
n care F este o variabil fiier diferit de tipul text, asociat unui fiier
deschis;
- poziia curent corespunztoare nceputului de fiier este 0, iar poziia
curent corespunztoare sfritului de fiier este este FileSize(F).

Erase
- terge un fiier extern ;
- are declaraia
procedure Erase(var F);
n care F este o variabil de tip file asociat unui fiier extern cu Assign;
- fiierul nu trebuie s fie deschis !
- folosii Ioresult pentru a verifica modul de ncheiere a operaiei de tergere.
Rename
- schimb numele unui fiier extern ;
- are declaraia
procedure Rename(var F; Nume_nou);
n care F este o variabil fiier de orice tip, iar Nume_nou este o expresie
de tip ir sau un pointer de tipul Char dac este permis sintaxa extins;
- fiierul extern va primi numele Nume_nou;

79
- IOResult ntoarce 0 n cazul n care operaia de schimbare a numelui a reuit
i #0 n caz contrar.

FileSize
- ntoarce dimensiunea curent a fiierului n numr de componente;
- are declaraia
function FileSize(var F): Longint;
- fiierul trebuie s fie deschis i nu trebuie s aib tipul text. Dac fiierul este
fr tip, mrimea unei componente se precizeaz la deschidere (Reset sau
Rewrite);
- Mrimea n octei a fiierului este FileSize(F)*sizeof(tip_component);
- dac fiierul este vid, dimensiunea sa este 0.

Read

- pentru fiiere de tip text:
- citete din fiierul text valorile unor variabile de tip numeric, caracter sau ir.
n cazul variabilelor numerice citirea ncepe cu primul caracter diferit de
spaiu, Tab, LF/CR i se ncheie la ntlnirea unui caracter spaiu, Tab,
CR/LF sau CTRL Z, valoarea irului de caractere citit fiind convertit la
tipul variabilei. n cazul variabilelor Char se citete un caracter, iar pentru un
ir de caractere se citete pn la sfrit de linie (CR/LF) sau pn la CTRL Z
(n cazul n care lungimea irului citit este mai mare dect a variabilei ir are
loc o trunchiere a valorii citite). n nici o situaie nu se trece la linia
urmtoare;
- are declaraia
Procedure Read([Var F:Text;]var v1[,v2]...);

- dac F lipsete, citirea are loc din fiierul standard de intrare, iar datele citite
snt afiate n ecou pe monitor (sau fiierul standard de ieire). Citirea este
efectiv dup acionarea tastei Enter;
- dup primul Read care conine variabile ir, orice citire ulterioar va
ntoarce un ir de lungime 0. Pentru a citi valori string succesive se va utiliza
procedura Readln;
- pentru fiiere cu tip:
- se citesc din fiier valorile unor variabile care au tipul identic cu tipul
fiierului;
- are declaraia
procedure Read(F , var V1 [, V2,...,Vn ] );

80
Readln
- execut operaiile de la Read i trece la urmtoarea linie a fiierului;
- are declaraia
procedure Readln([ var F: Text; ] V1 [, V2, ...,Vn ]);

Write
- n cazul fiierelor cu tip scrie o variabil ntr-o component a fiierului, iar n
cazul fiierelor text scrie una sau mai multe valori n fiier;
- are declaraia
pentru fiiere cu tip
procedure Write(F, V1 [, V2,...,Vn ] );
pentru fiiere text
procedure Write( [ var F: Text; ] P1 [,P2,...,Pn ] );

- parametrii P pot conine specificaii de lungime i precizie (numr de
zecimale). Fiecare expresie P poate fi de tipul Char, Integer, Real, String sau
Boolean.

Writeln
- execut procedura Write dup care scrie CR/LF
- are declaraia
procedure Writeln([ var F: Text; ] P1 [, P2, ...,Pn ] );
- este utilizabil n cazul fiierelor de tip text .

SeekEof
- ntoarce valoarea true dac fiierul cu tipul text nu conine (ncepnd cu
poziia curent) dect caractere albe ;
- are declaraia
function SeekEof [ (var F: Text) ]: Boolean;

SeekEoln
- ntoarce valoarea true dac, ncepnd cu poziia curent i pn la sfritul
liniei curente din fiierul text, snt numai caractere albe;
- are declaraia
function SeekEoln [ (var F: Text) ]: Boolean;

var
f : Text;
j : Integer;

81
begin
Assign(f,'TEST.TXT');
Rewrite(f);
{ Creaza un fisier cu 8 numere si spatiu la finele fiecarei linii }
Writeln(f,'1 2 3 4 ');
Writeln(f,'5 6 7 8 ');
Reset(f);
{
Citeste numerele. SeekEoln intoarce TRUE daca nu mai sint numere in
linia curenta, iar SeekEof intoarce TRUE daca nu mai exista caractere diferite
de caractere albe
}
while not SeekEof(f) do
begin
if SeekEoln(f) then
Readln; { Treci la o alta linie }
Read(f,j);
Writeln(j);
end;
end.

Eoln
- ntoarce valoarea true dac pointerul de fiier asociat unui fiier text
puncteaz pe sfrit de linie (caracterele CR/LF) sau pe CTRL Z;
- are declaraia
function Eoln [(var F: Text) ]: Boolean;

Eof
- ntoarce valoarea true dac poziia curent corespunde ultimului octet al unui
fiier fr tip, CTRL Z pentru fiiere text sau corespunde unei poziii situate
dup ultima nregistrare a unui fiier cu tip;
- are declaraia
function Eof(var F): Boolean;

Exemplu
Afieaz coninutul fiierului \autoexec.bat
var
F: Text;
Ch: Char;
begin

82
Assign(F, \autoexec.bat );
Reset(F);
while not Eof(F) do
begin
Read(F, Ch);
Write(Ch); { Afiseaza textul }
end;
end.

OPERAII CU FI IERE FR TIP

BlockRead
- citete una sau mai multe nregistrri;
- are declaraia
procedure BlockRead(var F: File; var Buf; Nr: Word [; var Rezt:
Word]);
unde
F - este o variabil de tip fiier fr tip care corespunde unui fiier
deschis;
Buf - variabil de orice tip;
Nr - este o expresie de tip Word;
Rez este o variabil de tip Word;

- BlockRead citete cel mult Nr nregistrri din fiierul F n memorie, ncepnd
de la primul octet al lui Buf. Numr de nregistrri citite complet (mai mic
sau egal ca Nr) este ntors n parametrul opional Rez. Dac acesta nu este
specificat i numrul de nregistrri citite difer de Nr, operaia de citire se
ncheie cu eroare de. Blocul transferat n memorie ocup cel mult
Nr*lungime_nreg unde lungime_nreg a fost specificat la deschiderea
fiierului (valoarea sa implicit este 128). Mrimea blocului transferat nu
poate depsi 65535 (64K)Dup citire, poziia n fiier este deplasat cu Rez
articole (componente)spre sfritul fiierului;
- n prezena directivei {$I-}, funcia IOResult ntoarce o valoare nenul n
cazul unei erori.

BlockWrite
- scrie una sau mai multe nregistrri ntr-un fiier fr tip;
- are declaraia
procedure BlockWrite(var f: File; var Buf; Nr: Word [; var Rez:
Word]);

83

unde
F - este o variabil de tip fiier fr tip corespunztoare unui fiier
deschis;
Buf - variabil de orice;
Nr - este o expresie de tip Word;
Rez este o variabil de tip Word;
- procedura scrie cel mult Nr nregistrri nfiierul F de la adresa Buf.
Numrul de nregistrri scrise efectiv este ntors n parametrul opional Rez.
Dac acest parametru opional nu este folosit i Rez<Nr, apelul se ncheie cu
eroare;
- lungimea blocului transferat nu poate depi 64 K;
- Poziia n fiier este mutat cu Rez ntregistrri spre sfritul fiierului;
- dac este prezent directiva {I-}, funcia IOResult ntoarce o valoare nenul
n cazul unei erori.

Funcia ParamStr, ca de altfel toate funciile i procedurile prezentate la
acest tip de date, fac parte din unitatea de program PASCAL System. Iat care
este modelul de apel i valoarea ntoars.

ParamStr - ntoarce un parametru al linie de comand
- delaraia sa este
function ParamStr(Nr:word): String;

- ntoarce parametru cu numrul Nr de pe linia de comand sau irul vid dac
Nr este mai mare dect ParamCount (numarul total).. ParamStr(0) ntoarce
calea i numele programului care se execut.

Exemplu
Copiai un fiier. Numele fiierului surs i numele fiierului destinaie se
vor de pe linia de comand corespunztoare punerii n execuie a programului
executabil.

var
De_unde, Unde: file;
NumCit, NumScris: Word;
Buf: array[1..2048] of Char;
begin
Assign(De_unde, ParamStr(1)); { Open input file }
Reset(De_unde, 1); { Record size = 1 }

84
Assign(Unde, ParamStr(2)); { Open output file }
Rewrite(Unde, 1); { Record size = 1 }
Writeln('Se copiaza ', FileSize(De unde), ' octeti...');
repeat
BlockRead(de_unde, Buf, SizeOf(Buf), NumCit);
BlockWrite(Unde, Buf, NumCit, NumScris);
until (NumCit = 0) or (NumScris <> NumCit);
Close(De_unde);
Close(Unde);
end.



85
Unitatea de program Pascal System

Vom prezenta procedurile i funciile acestei uniti de program Pascal
innd seama de categoria lor.

Funcii matematice

Abs
- ntoarce valoarea absolut a argumentului;
- are declaraia
function Abs(x): (acelai tip cu argumentul x);

ArcTan
- ntoarce arctangenta argumentului;
- are declaraia
function ArcTan(X:Real): Real;
- dei Pascal nu are funcie tangent, ea se poate calcula innd seama de
relaia:
tg(x)=sin(x)/cos(x);

Cos
- ntoarce cosinusul argumentului;
- are declaraia
function Cos(x:Real): real;
- argumentul x se exprim n radiani;

sin
- ntoarce sinusul argumentului care este un unghi exprimat n radiani;
- declaraia ca la funcia cos;

Exp
- intoarce e
x
;
- are declaraia
function exp(x:real):Real;
Int
- ntoarce partea ntreag a argumentului;
- are declaraia
function Int(x:Real): Real;


86

Frac
- ntoarce partea fracionar a argumentului;
- are declaraia
function Fract(X:Real):Real;
- partea fracionar a valorii x este x-Int(x);

Ln
- ntoarce logaritmul natural al argumentului;
- are declaraia
function Ln(X:Real): Real;

Pi
- ntoarce valoarea numrului iraional ;
- are declaraia
function Pi: Real;

Sqr
- ntoarce ptratul argumentului;
- are declaraia
function Sqr(X): (acelai tip cu x);

Sqrt
- ntoarce radicalul argumentului;
- are declaraia
function Sqrt(X:Real): Real;

inc
- incrementeaz (mrete) valoarea unei variabile cu un numr ;
- are declaraia
procedure Inc(Var x[;N: Longint]);
- variabila poate fi de tip scalar sau pointer de tip Pchar. n lips, valoarea lui
N este 1.

Dec
- decrementeaz (micoreaz) valoarea unei variabile cu un numr ;
- are declaraia
procedure Dec(Var x[;N: LongInt]);
- snt valabile observaiile de la procedura Inc ;

87

Proceduri i funcii de gestionare dinamic a memoriei (de alocare dinamic de
memorie)
New
- creaz o variabil dinamic i seteaz o variabil de tip referin pe adresa
zonei alocate;
- are declaraia
procedure New(Var P:pointer);

Dispose
- elibereaz o variabil dinamic;
- are declaraia
procedure Dispose(Var P:Pointer);

FreeMem
- elibereaz o variabil dinamic de mrime dat;
- are declaraia
procedure FreeMem(Var P: Pointer; mrime:Word);
GetMem
- creaz o variabil dinamic de mrime specificat i scrie adresa blocului n
variabila de tip Pointer;
- are declaraia
procedure Getmem(var P:pointer; mrime: Word);
- mrimea zonei de memorie rezervat se exprim n numr de octei

MaxAvail
- ntoarce mrimea n octei al celui mai mare bloc de memorie continu i
liber din zona de manevr (Heap);
- are declaraia
function MaxAvail: LongInt;
MemAvail
- ntoarce dimensiunea n octei a memoriei Heap disponibile
- declaraie ca la MaxAvail;

Control de procese

Exit
- abandoneaz blocul curent. Dac acesta este blocul principal, ncheie
execuia programului;

88
- are declaraia
procedure Exit;

Halt
- ncheie execuia programului i pred controlului sistemului de operare;
- are declaraia
procedure Halt(Cod_retur:Word);

Proceduri i funcii de citire/scriere
- se vor vedea i funciile de la tipul de date File

Funcii i proceduri diverse
Assigned
- testeaz dac un pointer sau o variabil au valoarea Nil;
- are declaraia
function Assigned(var P):Boolean;
- ntoarce valoarea True dac P<>Nil;

ChDir
- schimb directorul curent;
- are declaraia
procedure ChDir(S: String);
- S este un ir sau un pointer Pchar care conine numele directorului;
- dac este prezent directiva {$I+} IOResult furnizeaz codul de eroare sau 0
n caz de reuit;
GetDir
- ntoarce directorul curent pentru un disc specificat;
- are declaraia
procedure GetDir(Disc:Byte; Var Director:String);
- Disc =0 pentru discul de lucru, 1 pentru A, 2 pentru B, 3 pentru C etc.
Numele directorului curent va fi depus n variabila String S;

MkDir
- creaz un director;
- are declaraia
procedure MkDir(S:String);
- S este un ir care conine numele directorului , poate conine i numele
simbolic al discului;
RmDir

89
- terge un director vid;
- are declaraia
Procedure RmDir(S:string);
- S conine numele directorului (ca la MS DOS);

Exclude
- elimin dintr-o mulime un element;
- are declaraia
procedure Exclude(var S: Set Of T; Element : T);
- elementele mulimii snt de tipul T;

Include
- adaug un element la o multime ;
- are declaraia
procedure nclude(var S: Set Of T; Element : T);
- elementele mulimii snt de tipul T;

FillChar
- iniializeaz o zon de memorie cu o valoare specificat (cuprins ntre
0..255) ;
- are declaraia
procedure FillChar(Var X; Lungime: Word; Valoare);
- n urma execuiei procedurii Lungime octei a zonei de memorie X vor fi
pui pe Valoare;

Hi
- ntoarce octetul mai semnificativ a unei date de tipul Integer sau Word;
- are declaraia
function Hi(X): Byte;

Lo
- ntoarce octetul mai puin semnificativ a unei date de tipul Integer sau Word;
- are declaraia
function Lo(X): Byte;

Swap
- schimb ntre ei octeii semnificativ i nesemnificativ al unui element de tip
Integer sau Word. Dac valoarea iniial a unui element X este
256*Hi(X0+Lo(x), dup execuia funciei va avea valoarea 256*Lo(X)+

90
Hi(X);
- are declaraia
function Swap(X): (Tipul lui X);

Move
- copiaz un numr de octei dintr-o zon de memorie n alta;
- are declaraia
procedure Move(Var Suirsa, Destinaie; Lungime: Word);

ParamCount
- ntoarce numrul de elemente ale liniei de comand utilizat la punerea n
execuie a programului;
- are declaraia
function ParamCount: Word ;

ParamStr
- ntoarce valoarea parametrului cu numrul de ordine precizat (parametrul cu
numrul 0 corespunde specificatorului complet asociat programului
executabil);
- are declaraia
function ParamStr(Numr : Word) :String;

Random
- genereaz un numr aleator situat n intervalul [0, valoare) ;
- are declaraia
function Random(Valoare: Word): Real;
- dac Valoare lipsete se consider 1.

Randomize
- inializeaz variabila RandSeed declarat n unitatea Pascal System pe baza
ceasului sistem
- are declaraia
procedure Randomize;

SizeOf
- ntoarce mrimea zonei de memoriei necesar pentru memorarea unui
element (variabil, tip de dat etc.);
- are declaraia
function SizeOf(X) : Word;

91

UpCase
- convertete o liter mic n liter mare;
- are declaraia
function UpCase(Char: caracter): Char;
- ntoarce valoarea convertit;

Length
- determin lungimea unui ir de caractere;
- are declaraia
function Length(S: String): Integer;
- lungimea irului poate fi obinut i cu ajutorul expresiei Ord(S[0])

Concat
- concateneaz dou sau mai multe iruri de caractere ( a concatena irul X cu
irul Y nseamn a aduga la sfritul irului X caracterele din irul Y);
- are declaraia
function Concat(S1,S2[,S3]...:String): String;
- ntoarce rezultatul operaiei;

Copy
- extrage un subir dintr-un ir;
- are declaraia
function Copy(S: String; De_Unde, Lungime: Word): String;
- este ntors subirul de caractere format din Lungime caractere din sirul S
ncepnd cu caracterul de pe poziia De_Unde;

Delete
- terge dintr-un ir un subir;
- are declaraia
procedure Delete(Var S: String; De_unde,Lungime: Word);

Insert
- insereaz un subir ntr-un ir;
- are declaraia
procedure Insert(SubSir:string; Var Sir: string; De_unde:
Integer);

Pos

92
- ntoarce 0 sau locul din care ncepe prima apariie a unui subir ntr-un ir
- are declaraia
function Pos(SubSir,Sir:String):Byte;

Str
- convertete o expresie de tip numeric n ir de caractere;
- are declaraia
procedure Str(Expresie[:Numar_de_caractere{:Din_care_zecimale]];
Var S: String);

Val
- convertete un ir de caractere sau o parte a sa ntr-o valoare numeric pe
care o atribuie unei variabile;
- are declaraia
procedure Val(S: String; Var V; Var
Numar_de_caractere_convertite);
- pentru ca programul s nu se ncheie cu o eroare folosii directiva de
compilare {$R+}.

Unitatea de program PASCAL CRT

Imaginile afiate pe ecran snt de dou tipuri: text i grafice. Adaptoarele
video au dou moduri de lucru: un mod text i un mod grafic. n modul text, se
pot afia numai texte, pe cnd n modul grafic se pot afia texte i grafice. n
modul text cea mai mic unitate afiabil este caracterul. Ecranul este mprit
n linii (dispuse pe vertical), iar liniile n coloane. Poziia unui caracter pe
ecran este dat de numrul liniei i coloanei.
Procedurile i funciile din unitatea Pascal Crt gestioneaz activitatea
ecranului n modul text i a difuzorului extern.
n untitatea Crt snt definite urmtoarele constante
- moduri text:
BW40=0 - adaptor color B/W (alb/negru) 25 de linii a 40 de
coloane;
CO40= 1 - adaptor color 25 de linii a 40 de coloane;
BW80=2 - adaptor color B/W 25 de linii a 80 coloane;
CO80 = 3 - adaptor color 25 linii a 80 de coloane;
MONO = 7 Adaptor monocrom B/W 25 linii a 80 coloane;
- culori pentru fond i pentru text:

Culoare

Nume constant

valoare

93

Culoare

Nume constant

valoare

Negru

Black

0


Albastru

Blue

1

Verde

gree

2

Cian

Cyan

3

Rou

Red

4

Magenta

Magenta

5

Brun

Brown

6

Gri deschis

LightGray

7

Gri nchis

DarkGray

8

Albastru deschis

LightBlue

9

verde deschis

LightGreen

10

Cian deschis

LightCyan

11

Rou deschis

LightRed

1

Magenta decshis

LightMagenta

12

galben

Yellow

14

Alb

White

15

Pentru fond se pot folosi culorile 0 - 7, iar pentru text 0-15. Pentru a scrie
un text clipitor, adugai la numrul culorii textului constanta Blink (128).

n unitatea de program Pascal Crt snt definite urmtoarele variabile:
- CheckBreak - variabil boolean. Dac are valoarea true, programul
executabil poate fi ntrerupt cu Ctrl-Break sau CTRl-C. Valoarea implicit
este True ;
- CheckEof - variabil boolean. Dac are valoarea True, combinaia de taste
Ctrl-Z este interpretat ca sfritul fiierului asociat lui Crt. Valoarea
implicit este False ;
- DirectVideo - variabil boolean. Dac are valoare true, scrierile au loc

94
direct n memoria ecran, altfel se fac prin intermediul Bios-ului;
- LastMode - variabil de tip Word care conine modul text anterior modului
grafic. Variabila este modificat la fiecare apel al procedurii TextMode;
- TextAttr - variabil de tip Byte care conine:
- biii 0-3 culoarea textului;
- biii 4-6 culoarea fondului;
- bitul 7 - cod pentru Blink;
- WindMin - variabil de tip Word care conine coordonatele punctului
(stnga, sus) al ferestrei (x- nr coloanei este n octetul superior, iar Y-
numrul liniei n octetul inferior);
- Windmax - variabil de tip Word ce conine coordonatele punctului
(dreapta, jos) al ferestrei;

Funcii i proceduri din unitatea Crt
AssignCrt
- perifericului Crt i se asociaz un fiier text pentru o gestionare mai rapid a
ecranului;
- are declaraia
procedure AssginCrt(Var F: Text);

window
- definete o fereastr text pe ecran;
- are declaraia
Procedure Window(stntga, sus, dreapta,jos: Byte);
- colul stnga sus al ecranului are coordonatele (1,1). Dimensiunea minim a
ferestrei este 1 coloan dintr-o linie. Fereastra implicit corespunde
ntregului ecran, deci apelului window(1,1, 80,25) n cazul modurilor text cu
25 de linii. Toate coordonatele (exceptndu-le pe cele din apelul window)
snt relative la fereastr. Punctul (stnga,sus) al ferestrei are coordonatele
(1,1).
ClrEol
- terge toate caracterele ncepnd de la poziia curent i pn la sfritul liniei,
fr a modifica poziia curent;
DelLine
- terge linia curent (n care se afl cursorul) ;
- are declaraia
Procedure DelLine;
- liniile urmtoare snt mutate mai sus cu o linie, iar la baza ecranului este
adugat o linie nou;

95

InsLine
- insereaz o linie goal pe poziia cursorului;
- are declaraia
Procedure InsLine;
- Liniile care o urmeaz se deplaseaz n jos cu o poziie, iar ultima linie se
pierde;
WhereX
- ntoarce coordonata x (numrul coloanei) punctului curent;
- are declaraia
Function WhereX : Byte;
- Valoarea sa este dat de expresia Cursor.X+1;
WhereY
- ntoarce coordonata y (numrul liniei) punctului curent;
- are declaraia
Function WhereY : Byte;
- Valoarea sa este dat de expresia Cursor.Y+1;
GoToXY
- mut cursorul n punctul de coordonate specificat ;
- are declaraia
Procedure GoToXY(nr_coloana,nr_linie: Byte);
TextMode
- stbilete modul text;
- are declaraia
Procedure TextMode(Mod: Word);
- fereastra curent se extinde pe tot ecranul, modul video curent devine
LastMode, iar atributul textului pe Normal.
TextBackGround
- stabilete culoarea fondului;
- are declaraia
Procedure Textbackground(Culoare: Byte);
- culoarea fondului este cuprins ntre 0 i 7 (vezi tabelul de mai sus);
TextColor
- stabilete culoarea conturului caracterelor (peniei)
- are declaraia
Procedure TextColor(culoare: Byte);
- culoarea peniei este cupris ntre 0 i 15. Pentru a obine efectul de clipire se
va aduna culoarea cu constanta Blink;
LowVideo

96
- stabilete modul de scriere la o intensitate mic (reseteaz bitul 3 al
variabilei TextAttr);
- are declaraia
Procedure LowVideo;
NormVideo
- restabilete modul de scriere la parametrii iniiali (cu care a nceput
programul);
- are declaraia
Procedure NormVideo;
HighVideo
- stabilete modul de scriere la o intensitate mare (seteaz bitul 3 al variabilei
TextAttr);
- are declaraia
Procedure HighVideo;
Readkey
- citete un caracter
- are declaraia
Function ReadKey: Char;
- dac n zona tampon asociat tastaturii exist caractere, funcia ntoarce
primul caracter. n caz contrar, se ateapt pn cnd se tasteaz un caracter.
Citirea este fr ecou (caracterul tastat nu este afiat n ecou pe monitor).
KeyPressed
- ntoarce valoarea True dac n zona tampon asociat tastaturii exist
caractere;
- are declaraia
Function KeyPressed : Boolean;
Sound
- activeaz difuzorul intern;
- are declaraia
Procedure Sound(Frecventa: Word);
- frecvena sunetului este dat prin argument (440 corespunde notei Do).
Sunetul se emite pn la un alt apel Sound sau la un apel NoSound;
NoSound
- oprete difuzorul;
- are declaraia
Procedure NoSound;

Exemplu
S se afieze calendarul pe o lun a unui an.

97

program calendar;
{ Calendar pe o luna a unui an }
uses crt;
type vector_n=array [1..12] of integer;
vector_s=array [1..12] of string;
{ numar de zile scures de la inceputul unui an pina la inceputul lunii ianuarie,
februarie etc. }
const zile: vector_n=(0,31,59,90,120,151,181,212,243,273,304,334);
{ numar de zile din lunile unui an comun }
zile_luna: vector_n=(31,28,31,30,31,30,31,31,30,31,30,31);
{ nume de luni }
nume_luni:
vector_s=('Ianuarie','Februarie','Martie','Aprilie','Mai','Iunie',

'Iulie','August','Septembrie','Octombrie','Noiembrie','Decembrie');

procedure calend(luna,an:integer);
var z,
i: integer;

begin
if (luna>2) and ((an mod 400=0) Or ((an mod 4=0) and (an mod
100<>0))) then
z:=zile[luna]+1
else
z:=zile[luna];
dec(an);
z:=(z + an + 1 + an div 4 - an div 100 + an div 400) mod 7;
clrscr;
gotoxy(1,2);
write('Calendarul lunii ',nume_luni[luna],' ',an+1);
textcolor(WHITE);
write(#13#10' D L M M J V S'#13#10);
for i:=1 to z do
write(' ');
i:=z;
for z:=1 to zile_luna[luna] do
begin
inc(i);

98
write(z:3);
if i mod 7 =0 then
writeln
else
write(' ');
end;
end;

var luna,
anul:integer;
begin
clrscr;
window(1,1,lo(windmax),hi(windmax));
textbackground(LIGHTCYAN);
textcolor(RED);

repeat
gotoxy(5,2);
write('Calendar pe luna ');
read(luna);
until luna in [1..12];

repeat
gotoxy(25,2);
write(' anul ');
read(anul);
until anul >0;

calend(luna,anul);
readkey;
end.


Proceduri i funcii din unitatea de program Dos

n unitatea de program Pascal DOS se definesc urmtoarele tipuri de date:

DateTime = record Year, Month, Day, Hour, Min, Sec: Word end;
- se utilizeaz n apelul de proceduri PackTime i UnpackTime;


99
SearchRec= record
Fill: Array [1..21] of Byte;
Attr: Byte;
Time,Size: LongInt;
name: string[21];
end;
- este utilizat de procedurile FindFirst i Findnext;

ComStr = string[127];
- se foloeste pentru liniile de comand ale programelor executabile (Exec);

PathStr = string [79];
DirStr= string[67];
NameStr = String[8];
ExtStr = String[4];
- se folosesc pentru precizarea cii de cutare, numelor de fiiere, extensiilor
de nume;
Variabil DosError declarat n unitatea DOS este de tip Integer. Dintre
valorile pe care le poate lua i semnificaia acestora amintim:
2 - fiier inexistent;
3 - cale inexistent;
5 - acces interzis;
8 - memorie insuficient;
18 - nu mai snt fiiere.

Proceduri i funcii

GetDate
- citete data calendaristic;
- are declaraia
procedure GetDate(var An, Luna, Zi, ZI_din_saptamina: Word);
- anul furnizat este cuprins ntre 1980 i 2099, luna ntre 1 i 12, ziua ntre 1 i
31, iar ziua din sptmn ntre 0 i 6 (0 corespunde zilei duminic);

GetFTime
- ntoarce data i ora ultimei modificri relative la un fiier ;
- are declaraia
procedure GetFTime(var F; var Data: Longint);

- F este o variabil fiier cu sau fr tip sau un fiier de tip text care a fost

100
asignat i deschis;
- Data furnizat poate fi despachetat cu UnpackTime.

GetTime
- citete ora curent
- are declaraia
procedure GetTime(var Ore, Minute, Secunde, Sutimi: Word);


PackTime
- convertete data i ora ntr-o forma utilizabil de SetFTime.;
- are declaraia
procedure PackTime(var T: data_i_ora; var Timp:
Longint);

SetDate
- seteaz data n sistemul de operare ;
- are declaraia
procedure SetDate(An, Luna, Zi: Word);

SetFTime
- seteaz data i ora ultimei actulizri a unui fiier;
- are declaraia
procedure SetFTime(var F; Data_ora: Longint);
- fiierul F trebuie s fie deschis

SetTime
- seteaz ora curent;
- are declaraia
procedure SetTime(Ora, Minutul, Secunda, Sutimea_de_secunda:
Word);

UnpackTime
- convertete data i ora mpachetate ntr-o structura LongInt ntr-o structur
despachetat;
- are declaraia
- procedure UnpackTime(Data_ora: Longint; var DaTa: TDateTime);

DiskFree

101
- ntoarce spaiul disponibil pe o unitate de disc;
- are declaraia
function DiskFree(Drive: Byte): Longint;
- Drive este numrul corespunztor unitiide disc: 0- pentru discul de
lucru (implicit), 1 pentru A, 2 pentru B, 3 pentru C etc.
- dac numrul unitii este invalid, ntoarce valoarea -1.

DiskSize
- ntoarce capacitatea unui disc ;
- are declaraia
function DiskSize(Drive: Byte): Longint;
- drive ia valorile indicate la funcia DiskFree;

GetVerify
- ntoarce starea comutatorului MS DOS Verify;
- are declaraia
procedure GetVerify(var Verify: Boolean);
- Dac comutatorul Verify este off, variabila boolean Verify este false. n
acest caz operaiile de scriere pe disc nu snt verificate;

SetVerify
- seteaz starea comutatorului Verify;
- are declaraia
procedure SetVerify(Verify: Boolean);
- dac parametrul verify este false, starea comutatorului Verify este setat
la On;

Fsearch
- caut un fiier n directorul curent i ntr-o list de directoare;
- are declaraia
function FSearch(Path: PathStr; DirList: string): PathStr;
- directoarele listei de directoare DirList se separ prin caracterul ; (punct
i virgul);

Fsplit
- descompune un specificator de fiier n componentele sale (unitatea de
disc i calea, numele i extensia numelui);
- are declaraia

102
procedure FSplit(Specificator: PathStr; var Director: DirStr; var
Nume: NameStr; var Ext: ExtStr);
- tipurile ir PathStr, DirStr, NameStr i ExtStr snt definite n unitatea de
program Pascal dos;

FindFirst
- caut n directorul specificat n primul argument prima intrare n director
cu atributele specificate;
- are declaraia
procedure FindFirst(Path: PChar; Attr: Word; var F:
TSearchRec);
- atributele posibile pentru un fiier snt: ReadOnly = $01 Hidden=$02
SySfile=$03 Directory=$10 Archive=$20 AnyFile=$3F i VolumeId=$08
- parametrul Path este un specificator de fiier n accepiunea Dos (poate
conine unitatea logic de disc, calea, numele i extensia numelui fiierului)
- dac exist un astfel de fiier carcteristicile sale (atribute, data i ora ultimei
modificri, numele i extensia de nume exact) snt memorate n parametrul
F;
Exemplu
Prin apelul findfirst( \*.bat ,AnyFile,fis); se caut n rdcina
discului implicit fiiere cu extensia numelui bat
- dac nu exist fiiere de tipul celor cutate, variabila DosError ia o valoare
nenul ;

FindNext
- continu cutarea iniiat cu FindFirst;
- are declaraia
procedure FindNext(var F: TSearchRec);
- dac nu mai exist fiiere, variabila DosError ia valoarea 18;

Exec
- lanseaz n lucru un program executabil;
- are declaraia
procedure Exec(Program, Parametri: string);
- specificatorul de fiier corespunztor programului executabil se indic prin
parametrul Program, iar parametrii specifici programului prin Parametri;
- orice eroare n execuia procedurii Exec este evideniat n DosError;

GetCBreak

103
- ntoarce starea comutatorului Dos Break;
- are declaraia
procedure GetCBreak(var Break: Boolean);
- dac starea comutatorului Break este On (la fiecare apel al unor funcii
sistem se va verifica dac s-a tastat sau nu CTRL BREAK), variabila Break
(din apel) va primi valoarea True;

SetCBreak
- seteaz starea comutatorului Break ;
- are declaraia
procedure SetCBreak(Break: Boolean);
- dac parametrul Break are valoarea True, comutatorul Break va fi setat pe
On . Dac are valoarea false, comutatorul Break va fi pus pe Off (se verific
dac s-a tastat CTRL C numai la execuia unor operaii de citire/scriere pe
periferice standard -consol, imprimant i porturile de comunicaie).

Proceduri i funcii din unitatea Graph

n general, un monitor poate funciona n dou moduri: text i grafic.
n modul grafic, ecranul este privit ca o matrice de puncte (numite pixeli)
caracterizate prin culoare. Numrul de puncte pe orizontal i vertical i
numrul de culori pe care acestea le pot avea simultan definesc rezoluia
imaginii. De exemplu, n cazul adaptorului grafic VGA, ecranul poate fi
mprit n 640 x 200, 640 x 350 sau 640 x 480 pixeli. Colul din stnga sus are
coordonatele (n ultimul caz) (0,0), cel din dreapta sus (639,0), cel din stnga jos
(0,479), iar cel din dreapta jos (639,479).
Dac gestiunea imaginii este asigurat, din punctul de vedere al hardului,
de ctre adaptorul grafic, gestionarea acestuia din punct de vedere soft este
asigurat printr-un program (driver) de grafic. n Pascal, aceste drivere se afl
pe suport sub form de fiiere care au extensia numelor BGI (Borland Graphics
Interface). Unitatea Pascal n care snt definite constantele, variabilele i
procedurile grafice este Graph. Vom prezenta n continuare cteva dintre
acestea.

InitGraph
- iniializeaz modul grafic;
- are declaraia
Inigraph(Var Driver_grafic,Mod_grafic:Integer;
Cale_fisiere_BGI);
- driverele grafice posibile snt: Detect = 0 (cu autodetecie i alegerea

104
modului grafic cel mai performant), CGA=1, MCGA=2, EGA=2,EGA64=3,
EGAMono=5, IBM8514=6, HecMono=7, ATT400=9, VGA=9, PC3270=10,
CurrentDriver=-128;
- modurile grafice snt constante definite n unitatea graph. Iat modurile
grafice posibile n cazul driverului de grafic VGA:
VGALo =0, 640x200 pixel;i,16 culori, fiier grafic EGAVGA.BGI;
VGAMed=1, 640x350 pixeli, 16 culori, fiier grafic
EGAVGA.BGI;
VGAHI=2, 640x480 pixeli, 16 culori, fiier grafic EGAVGA.BGI.
- erorile de iniializare sau cu care se ncheie procedurile i funciile grafice
snt furnizate de funcia GraphResult. Operaia se ncheie normal, cnd codul
de eroare este 0 (constanta GrOk);

CloseGraph
- ncheie lucrul n modul grafic, modul curent devenind modul text;
- are declaraia
procedure CloseGraph;

GraphResult
- ntoarce codul de eroare asociat ultimei operaii grafice i pune codul de
eroare pe 0;
- are declaraia
function GraphResult:Integer;
SetViewPort
- precizeaz fereastra fizic (un domeniu dreptunghiular de pixeli) n care se
deseneaz;
- are declaraia
procedure SetViewPort(stnga,sus, dreapta,jos: Integer;
Decupare:Boolean);
- fereastra este determinat de dreptunghiul care are vrfurile opuse de
coordonate (stnga,sus) i (dreapta, jos) i are laturile orizontale i verticale;
- dac variabila boolean Decupare are valoarea True, dintr-o figur care nu
ncape n fereastr se decupeaz doar por
Cnd are valoare False, va fi afiat toat figura (chiar dac nu ncape n
fereastr);
- dup declararea ferestrei fizice, toate coordonatele vor fi relative la fereastr.
SetActivePage
- stabilete numrul paginii n care se deseneaz. Un ecran grafic poate avea
asociate una sau mai multe pagini grafice (de exemplu, VGALo 4, VGAMed

105
2, iar VGAHi 1). Pagina activ poate fi invizibil. Numrul primei pagini
este 0;
- are declaraia
Procedure SetActivePage(Nr_Pagina:Word);
SetVisulalPage
- afieaz o pagin grafic;
- are declaraia
Procedure SetVisualPage(Nr_Pagin:Word);
GetX
- ntoarce abscisa corespunztoare punctului grafic curent (a cursorului grafic)
;
- are declaraia
Function GetX: Integer;
GetY
- ntoarce ordonata corespunztoare punctului grafic curent (a cursorului
grafic) ;
- are declaraia
Function GetY: Integer;

MoveTo
- modific poziia punctului grafic curent (fr desenare) ;
- are declaraia
Procedure MoveTo(X,Y: Integer);

- coordonatele X i Y snt relative la fereastr;
MoveRel
- modific poziia punctului grafic curent (fr desenare) ;
- are declaraia
Procedure MoveRel(Depl_Pe_X,depl_Pe_Y: Integer);

- Depl_Pe_X i Depl_Pe_Y definesc coordonatele noului punct grafic curent
n coordonate relative fa de poziia actual a cursorului grafic;

SetColor
- stabilete culoarea peniei (culoarea cu care se deseneaz);
- are declaraia
Procedure SetColor(Culoare: Word);
- valorile posibile pentru culoare snt cuprinse n domeniul 0..15 i snt
prezentate la unitatea Pascal Crt;

106
GetColor
- ntoarce culoarea peniei;
- are declaraia
Function GetColor: Word;
SetBkColor
- stabilete culoarea fondului;
- are declaraia
Procedure SetBkColor(Culoare: Word);
- valorile posibile pentru culoare snt cuprinse n domeniul 0..15 i snt
prezentate la unitatea Pascal Crt;
GetBkColor
- ntoarce culoare actual a fondului;
- are declaraia
Function GetBkColor: Word;

PutPixel
- aprinde un punct de o anumit culoare;
- are declaraia
Procedure PutPixel(X,Y: Integer; Culoare:Word);
- pixelul are coordonatele relative X,Y, iar culoarea Culoare;
GetPixel
- ntoarce numrul culorii unui pixel;
- are declaraia
Function GetPixel(X,Y: Integer): Word;
ClearDevice
- terge imaginea afiat pe ecran;
- are declaraia
Procedure ClearDevice;
- terge ecranul (toi pixelii vor avea culoarea fondului), iar punctul grafic
curent devine punctul (0,0) al ecranului;
ClearViewPort
- terge fereastra grafic curent. Punctul grafic curent devine punctul (0,0) al
ferestrei;
- are declaraia
Procedure ClearViewPort;
GetMaxX
- ntoarce valoarea maxim abscisei vizibile pe ecran;
- are declaraia
Function GetMaxX: Integer;

107
GetMaxY
- ntoarce valoarea maxim ordonatei vizibile pe ecran;
- are declaraia
Function GetMaxY: Integer;
SetActivePage
- stabilete numrul paginii grafice active (n care se deseneaz). Adaptoarele
grafice Hercules, EGA i VGA au mai multe pagini de memorie utilizate n
operaii grafice. Prima pagin are numrul 0;
- are declaraia
Procedure SetActivePage(Nr_pagina: Word);
SetVisualPage
- afieaz pagina grafic indicat prin numrul su;
- are declaraia
Procedure SetVisualPage(Nr_pagin: Word);
Line
- deseneaz un segment de dreapt;
- are declaraia
Procedure Line(x_i,y_i,x_f,y_f: Integer);
- segmentul de dreapt este definit prin extremitile sale (x_i,y_i) i (x_f,y_f);
- extremitatea final a segmentului devine punct grafic curent;
LineTo
- deseneaz un segment de dreapt;
- are declaraia
Procedure LineTo(x_f,y_f: Integer);
- segmentul de dreapt este definit de punctul grafic curent i (x_f,y_f);
- extremitatea final a segmentului devine punct grafic curent;
LineRel
- deseneaz un segment de dreapt;
- are declaraia
Procedure Linerel(Depl_x,Depl_y: Integer);
- dac (x_c,y_c) snt coordonatele punctul grafic curent, atunci segmentul de
dreapt este determinat de punctele (x_c,y_c) i (x_c+Depl_x,y_c+Depl_y).
- extremitatea final a segmentului devine punct grafic curent ;
Circle
- deseneaz un cerc;
- are declaraia
Procedure Circle(X_Centru,Y_Centru: Integer; Raza: Word);
Arc
- deseneaz un arc de cerc;

108
- are declaraia
Procedure Arc(X_Centru,Y_Centru: Integer; Unghi_i,Unghi_f,
Raza: Word);
- Unghi_i i Unghi_f snt unghiurile de poziie ale primului i ultimului punct
al arcului de cerc exprimate n grade;
Ellipse
- deseneaz un arc eliptic;
- are declaraia
Procedure Ellipse(X_Centru,Y_Centru: Integer;
Unghi_i,Unghi_f: Word; Semiaxa_x,Semiaxa_y:
Word);
- Unghi_i i Unghi_f snt unghiurile de poziie ale primului i ultimului punct
al arcului de eliptic exprimate n grade;
Rectangle
- deseneaz un dreptunghi definit dou vrfuri diagonal opuse;
- are declaraia
Procedure Rectangle(X1,Y1,x2,y2: Integer);
DrawPoly
- deseneaz o linie poligonal (dac primul i ultimul punct au aceleai
coordonate se deseneaz un poligon);
- are declaraia
procedure DrawPoly(Numar_de_virfuri: Word; Var Virfuri);
- Vrfuri este o alctuit din perechi de forma (x,y), adic este un vector de
elemente de tipul
PointType= record { X,Y: Integer) end;
SetFillStyle
- selecteaz modelul i culoarea haurii;
- are declaraia
Procedure SetFillStyle(Model_hasura,Culoare: Word);
- dintre modelele de haur amintim:
EmptyFill - haurare cu culoarea de fond;
SollidFill - haurare cu culoarea peniei (figur plin );
LineFill - linii orizontale;
LtSlashFill - haurare cu / (slash);
SlashFill - haurare cu / (model mai gros);
HatchFill - ptrele;
XHatchFill -romburi
InterleaveFill - punctat (puncte dese);
WideDotFill - punctat (puncte rare);

109
Bar
- deseneaz un dreptunghi haurat;
- are declaraia
Procedure Bar(x1,y1,x2,y2);
FillEllipse
- deseneaz o elips haurat;
- are declaraia
o Procedure FillEllipse(X_centru,Y_centru: Integer; Semiaxa_x,
Semiaxa_y: Word);
FillPoly
- deseneaz un poligon haurat;
- declaraia este asemntoare cu a procedurii Poly;
Sector
- deseneaz un sector eliptic haurat;
- declaraia este asemntoare cu a procedurii Ellipse;
TextHeight
- ntoarce nlimea textului n numr de pixeli;
- are declaraia
function Textheight: Word;

TextWidth
- ntoarce limea textului n numr de pixeli;
- are declaraia
function TexWidth: Word;
SetTextStyle
- definete tipul, direcia i dimensiunea caracterelor;
- are declaraia
Procedure SetTextStyle(Font,Directie:Word; Dimensiune: Word);
- tipurile de fonturi (caractere) snt: defaultFont, TriplexFont,
SmallFont,SanSerifFont, GothicFont;
- direcie text: HorDir - text orizontal i VertDir - text vertical;
- dimensiune font - UserCharSize dimensiune utilizator
SetTextJustify
- stabilete alinierea textului fat de cursorul grafic
- are declaraia
Procedure SetTextJustify(Oriz,vert: Word);
- Oriz poate fi :
LeftText - la stnga; Centertext - poziie central; RightText -
aliniere la dreapta

110
- Vert poate fi :
BottomtText - jos; Centertext - poziie central; TopText - sus;

OutText
- scrie un text ncepnd cu punctul grafic curent;
- are declaraia
OutText(Text: String);
OutTextxy
- scrie un text ncepnd cu punctul de coordonate indicate;
- are declaraia
OutTextxy(X,Y: Integer;Text: String);
ImageSize
- ntoarce numrul de octei necesari pentru a memora imaginea cuprins n
dreptunghiul definit prin vrfurile diagonal opuse (stinga,sus) i (dreapta,jos);
- are declaraia
Function ImageSize(Stnga,Sus,Dreapta,Jos): Word;

GetImage
- copiaz imaginea cuprins n dreptunghiul definit prin vrfurile diagonal
opuse (stinga,sus) i (dreapta,jos) n memorie ;
- are declaraia
Procedure getImage(stinga,sus,dreapta,jos:Integer; Var
Adresa_zona_memorie);
PutImage
- afieaz pe ecran imaginea salvat cu GetImage, n dreptunghiul care are
coordonatele vrfului stnga-sus precizate;
- are declaraia
Procedure PutImage(Stinga,Sus: Integer; Var
Adresa_zona_memorie; Op:Word);
- parametrul Op indic modul de afiare i poate avea una din valorile
0 - CopyPut = afiare direct (fr modificare);
1 - XorPut = afiare cu XOR (cu imaginea curent);
2 - OrPut = afiare cu Or;
3 - AndPut = afiare cu And;
4 - NotPut = afiare invers.


Proceduri i funcii din unitatea de program String


111
Procedurile i funciile din aceast unitate Pascal ofer posibilitatea
tratrii elementelor cu tipul Zstring. Reamintim c pentru a putea lucra cu date
de tip Zstring, trebuie s fie permis sintaxa extins (directiva {$X}).
StrLen
- ntoarce numrul de caractere al unui ir (lungimea irului);
- are declaraia
Function Strlen(Sir: Pchar): Word;
- n calculul lungimii irului nu se ine seama de caracterul NULL (acesta nu
este numrat).

StrEnd
- ntoarce un pointer la sfritul unui ZString;
- are declaraia
Function StrEnd(Sir: Pchar): Pchar;
- ntoarce adresa caracterului Null (de ncheiere a irului);


StrNew
- creaz copia unui ir n zona de memorie de manevr (heap);
- are declaraia
Function StrNew(Sir: PChar): Pchar;
- rezerv strlen(sir)+1 octei din zona Heap i copiaz n ea irul Sir;
- ntoarce adresa memoriei alocate sau Nil (cnd nu exist spaiu).

StrDispose
- elibereaz zona de memorie rezervat n heap pentru un ZString;
- are declaraia
Procedure StrDispose(Sir: Pchar);
- zona pentru irul Sir a fost alocat prin intermediul funciei StrNew;
StrPas
- convertete Zstring ntr-un ir memorat n stil PASCAL (primul octet al
irului conine lungimea sa);
- are declaraia
Function StrPas(sir:PChar): String;
- ntoarce rezultatul conversiei;

StrComp
- compar dou iruri;
- are declaraia

112
Function StrComp(Sir1,Sir2:Pchar): Integer;
- ntoarce valoarea 0 dac irurile snt egale, o valoare negativ dac primul ir
este mai mic dect al doilea i o valoare pozitiv dac primul ir este mai
mare dect al doilea.Compararea caracterelor din cele dou iruri se face pe
baza poziiei lor n tabelul de codificare ASCII (ordine lexicografic).
StrIComp
- compar dou iruri fr a ine seama de felul literelor (literele mici snt
echivalente cu cele mari);
- are declaraia
Function StrIComp(Sir1,Sir2:Pchar): Integer;
- ntoarce valoarea 0 dac irurile snt egale, o valoare negativ dac primul ir
este mai mic dect al doilea i o valoare pozitiv dac primul ir este mai
mare dect al doilea.Compararea caracterelor din cele dou iruri se face pe
baza poziiei lor n tabelul de codificare ASCII (ordine lexicografic).
StrLComp
- compar un numr de caractere din dou iruri ;
- are declaraia
Function StrLComp(Sir1,Sir2:Pchar;Nr_de_caractere:Word):
Integer;
- ntoarce aceeai valoare ca funcia StrComp
StrECopy
- copiaz un ir n altul ;
- are declaraia
Function StrECopy(destinatie,Sursa:PChar):PChar;
- nu se face nici un control n ceea ce privete lungimea destinaiei (pentru ca
operaia s fie ncheiat corect trebuie ca zona destinaie s aib cel puin
StrLen(Sursa) octei;
- ntoarce adresa sfritului rezultatului;
StrLCopy
- copiaz un numr de octei dintr-un ir n altul ;
- are declaraia
Function
StrLCopy(destinatie,Sursa:PChar;Lungime:Word):PChar;
- nu se face nici un control n ceea ce privete lungimea destinaiei (pentru ca
operaia s fie ncheiat corect trebuie ca zona destinaie s aib cel puin
StrLen(Sursa) octei;
- ntoarce adresa rezultatului;
StrPCopy
- copiaz un ir memorat n stil PASCAL (lungimea acestuia se memoreaz n

113
fa) ntr-un ZString;
- are declaraia
Procedure StrPCopy(Destinatie: Pchar; Sursa: String): Pchar;
- nu se efectueaz nici un control de lungime (destinaia trebuie s fie
sufiecient de mare)
- ntoarce adresa destinaiei;

StrLower
- convertete literele mari ale unui ZString n litere mici;
- are declaraia
function StrLower(Sir: Pchar): Pchar;
- ntoarce adresa Sir;

StrUpper
- convertete literele mici ale unui ZString n litere mari;
- are declaraia
function StrLower(Sir: Pchar): Pchar;
- ntoarce adresa Sir;

StrCat
- concateneaz dou Zstring-uri;
- are declaraia
function Strcat(Destinatie,Sursa: Pchar): Pchar;
- ntoarce adresa irului rezultat ;

StrLCat
- adaug un numr de caractere ale unui ir la sfritul unui Zstring;
- are declaraia
function StrLcat(Destinatie,Sursa: Pchar;
Nr_de_caractere:Word): Pchar;
- ntoarce adresa irului rezultat ;

StrMove
- copiaz caractere dintr-un ir n altul;
- are declaraia
function StrMove(Destinatie,Sursa:PChar; Lungime:Word):
Pchar;
- numrul de caractere copiate este dat de parametrul Lungime;
- sursa i destinaia pot avea o poriune comun ;

114
- ntoarce adresa destinaiei.
StrPos
- caut prima apariie a unui ir n altul;
- are declaraia
function StrPos(Sir,Subsir: Pchar): Pchar;
- ntoarce adresa subirului Subsir n sir sau pointerul Nil
StrScan
- caut prima apariie a unui caracter ntr-un ZString;
- are declaraia
function StrPos(Sir: Pchar; C: Char): Pchar;
- ntoarce adresa primului caracter c din Sir sau pointerul Nil

StrRScan
- caut ultima apariie a unui caracter ntr-un Zstring;
- are declaraia
function StrRScan(Sir: Pchar; C: Char): Pchar;
- ntoarce adresa ultimei apariii n Sir a caracterului c sau pointerul Nil



Grafice de funcii reale de o variabil real

Fie f o funcie real definit n intervalul [a,b] , mrginit. Prin
urmare, exist un interval [c,d] cu proprietatea c f(x) [c,d] pentru orice x
din [a,b]. S se reprezinte graficulu acestei funcii.


Fie [u1,u2]x[v1,v2] zona dreptunghiular de pe ecran care conine
graficul funciei. Dac P(x,y) este un un punct al dreptunghiului [a,b]x[c,d],
imaginea sa Q(u,v) trebuie s aparin lui [u1,u2]x[v1,v2], prin urmare vom
avea
de unde, avnd n vedere c pe ecran coordonatele snt numere ntregi i
pozitive, vom avea

v1 - v2
v1 - v
=
d - c
d - y
u1 - u2
u1 - u
=
a - b
a - x



115
Mrimile c i d pot fi, n particular, maximul i minimul funciei F pe [a,b].
in programul Pascal de mai jos, punctul (u1,v1) este notat (stnga,sus),
punctul de coordonate (u2,v2) este notat (dreapta,jos).

{$F+} { pentru a putea folosi functii si proceduri ca argumente de functii }

USES graph,crt;
TYPE functie= function(x:real):real;
tip=(puncte,linii,scara,bare);

procedure grafic(f:functie; { functia }
x1,x2,x3:real; { primul punct, al doilea, ultimul }
stinga,sus,dreapta,jos:integer; { dreptunghiul in care se va reprezenta }
culoare,fond:integer;{ culoare penita }
forma:tip); { forma graficului }
var x,y, { abscisa si ordonata reala }
pas, { pasul cu care se vor calcula ordonatele punctelor graficului }
, { valoarea a a functiei }
maxim, { valoarea maxima a functiei }
rx,ry: real; { variabile de lucru - contin valori de reducere la scara }
xc,yc,xp,yp:integer; { punctul grafic curent si punctul grafic precedent }
init:boolean; { are valoare true la primul punct }
BEGIN
pas:=(x2-x1); { determina pasul, ul si maximul functiei }
x:=x2; :=f(x1) ; maxim:=f(x1);
repeat
y:=F(x);
if y< then :=y
else if y>maxim then
maxim:=y;
x:=x+pas;
until x>x3;

rx:=(dreapta-stinga)/(x3-x1);
ry:=(sus-jos)/(maxim-);

-
-
v1) +
d - c
v1) - (v2 d) - (y
Round( = v
u1) +
a - b
u1) - (u2 a) - (x
Round( = u


116
init:=true;
yp:=detect;
{ initializare mod grafic }
initgraph(yp,xp,'\bp\bgi');
x:=x1;

{ traseaza graficul }
repeat
xc:=trunc(dreapta+rx*(x-x3)+0.5); { calculeaza coordonatele si le
rotunjeste }
yc:=trunc(sus+ry*(f(x)-maxim)+0.5);
if init then begin
{cleardevice; { sterge ecranul }
setcolor(GREEN); { deseneaza dreptunghiul cu culoarea verde }
rectangle(stinga,sus,dreapta,jos);
setcolor(culoare); { seteaza culoarea penitei }
setbkcolor(fond);
setfillstyle(InterleaveFill,BLUE);
if forma=puncte then
putpixel(xc,yc,culoare);
init:=false;
end
else
case forma of
puncte:
putpixel(xc,yc,culoare);
linii:
lineto(xc,yc);
scara:
linerel(xc-xp,0);
bare:
bar(xp,yp,xc-3,jos);
end;
moveto(xc,yc);
x:=x+pas;
xp:=xc; yp:=yc;
until x>x3;
end;

{ functii ce se reprezinta grafic }

117

function PATRAT(t:real):real;
begin
PATRAT:=t*t;
end;

function SINUS(x:real):real;
begin
sinus:=sin(x);
end;



Trasri de suprafee

Fie f o funcie real definit pe dreptunghiul [a,b]x[c,d]. Pentru a
reprezenta suprafaa definit de f vom proiecta fiecare punct P(x,y,z) pe planul
XoYdup urmtoarea regul:
- punctul P(0,0,1) va fi proiectat pe XoY n punctul Q care satisface relaiile
OQ=r (o mrime fixat), iar o = QoX _ ;
- orice alt punct R(x,y,z) se va proiecta ntr-un punct S(x ,y ,0) cu
proprietatea c PQ RS. Din considerente geometrice x =x+r*z*cos(),
iar y =y+r*z*sin();
- pentru orice x fixat, trasm graficul proieciei punctelor P(x,y,f(x,y)) cu y
variabil n [c,d];
- pentru orice y fixat, trasm graficul proieciei punctelor P(x,y,f(x,y)) cu x
variabil n [a,b].


{$F+} { pentru a putea folosi functii si proceduri ca argumente de functii }

USES graph,crt;

TYPE fct2=function(x,y:real):real;

var x0,y0:real;

procedure suprafata(f:fct2; { functia }
a,b,c,d, { domeniul de definitie [a,b]x[c,d] }
alfa,r:real; { elemente ce definesc poiectia paralela }

118
stinga,sus,dreapta,jos:integer; { dreptunghiul in care se va reprezenta }
n:integer; { numar de subintervale }
culoare:integer);{ culoare penita }
var x,y,z, { abscisa, ordonata reala si cota }
pasx, { pasii pe ox si oy }
pasy,
xp,yp, { coordonatele proiectiei }
x, { extremele pentru xp si yp }
xmaxim,
y,
ymaxim,
rx,ry: real; { coeficienti de reducere la scara }
i,j, { contoare }
xc,yc:integer; { punctul grafic curent }
init:boolean; { are valoare true la primul punct }
BEGIN
pasx:=(b-a)/n; { determina pasii, ul si maximul coordonatelor }
pasy:=(d-c)/n;
x:=a+r*cos(alfa)*f(a,c) ; xmaxim:=x;
y:=c+r*sin(alfa)*f(a,c) ; ymaxim:=y;
for i:=0 to n do begin
x:=a+i*pasx;
for j:=0 to n do begin
y:=c+j*pasy;
z:=f(x,y);
xp:=x+r*cos(alfa)*z;
yp:=y+r*sin(alfa)*z;
if yp<y then y:=yp
else if yp>ymaxim then
ymaxim:=yp;
if xp<x then x:=xp
else if xp>xmaxim then
xmaxim:=xp;
end;
end;

{ calculeaza factorii de scara }
rx:=(dreapta-stinga)/(xmaxim-x);
ry:=(sus-jos)/(ymaxim-y);


119
{ traseaza graficele cu elemente x[i] fixate }
for i:=0 to n do begin
init:=true;
x:=a+i*pasx;
for j:=0 to n do begin
y:=c+j*pasy;
z:=f(x,y);
xp:=x+r*cos(alfa)*z;
yp:=y+r*sin(alfa)*z;
xc:=trunc(dreapta+rx*(xp-xmaxim)); { calculeaza coordonatele si le
rotunjeste }
yc:=trunc(sus+ry*(yp-ymaxim));
if init then
init:=false
else
lineto(xc,yc);
moveto(xc,yc);
end;
end;
readkey;

{ traseaza grafice cu y[j] fixat }

setcolor(culoare);
for j:=0 to n do begin
init:=true;
y:=a+j*pasy;
for i:=0 to n do begin
x:=c+i*pasx;
z:=f(x,y);
xp:=x+r*cos(alfa)*z;
yp:=y+r*sin(alfa)*z;
xc:=trunc(dreapta+rx*(xp-xmaxim));
yc:=trunc(sus+ry*(yp-ymaxim));
if init then begin
init:=false
end
else
lineto(xc,yc);
moveto(xc,yc);

120
end;
end;

end;

function f(x,y:real):real;
begin
f:=sin(x*x+y*y);
end;

function g(x,y:real):real;
begin
g:=sin(x*y);
end;
var gdriver,gmode:integer;
alfa,r:real;
BEGIN
gdriver:=detect;
initgraph(gdriver,gmode,'\bp\bgi');
alfa:=pi/4; r:=1;
suprafata(f,-pi,pi,-pi,pi,alfa,r,100,50,getmaxx-100,getmaxy-50,50,cyan);
readkey;
cleardevice;
suprafata(g,-pi,pi,-pi,pi,alfa,r,100,50,getmaxx-100,getmaxy-50,50,cyan);
readkey;
END.

{ procedura principala }

var t:real;
BEGIN
t:=arctan(1)*4;
grafic(sinus,0,0.1,2*t,0,0,300,300,CYAN,BLACK,puncte);
readkey;

grafic(sinus,0,0.1,2*t,0,0,300,300,CYAN,BLACK,scara);
readkey;

grafic(sinus,0,0.1,2*t,0,0,300,300,CYAN,BLACK,linii);
readkey;

121

grafic(patrat,0,5,100,0,0,300,300,CYAN,BLACK,puncte);
readkey;

grafic(patrat,0,5,100,0,0,300,300,CYAN,BLACK,scara);
readkey;

grafic(patrat,0,5,100,0,0,300,300,CYAN,BLACK,linii);
readkey;

grafic(patrat,0,5,100,0,0,300,300,CYAN,BLACK,bare);
readkey;
END.




Liste simplu nlnuite


O list este o mulime (o colecie) de elemente de acelai tip. O list
poate fi vid. De exemplu, lista candidailor nscrii la concursul de admitere la
facultate, lista candidailor admii, lista studenilor bursieri, lista studenilor
promovai etc. Asupra unei liste se pot efectua urmtoarele operaii:
- activarea sau crearea listei (lista nu conine nici un element);
- adugarea unui element ntr-o list. Adugarea se poate face n orice poziie
(la nceput, la sfrit etc.);
- eliminarea (tergerea) unui element din list;
- descompunerea unei liste n dou sau mai multe liste (partiionarea listei) n
funcie de anumite criterii;
- sortarea elementelor listei dup diferite criterii;
- cutarea unui element ntr-o list.

Alocarea memoriei pentru elementele unei liste se poate realiza
- static (la creare sau iniializare se rezerv memorie pentru un numr maxim
de elemente);
- dinamic (fiecrui element i se rezerv zon cnd se adaug n list; memoria
va fi eliberat cnd elementul se va terge).
n ultimul caz, pe lng valoarea fiecrui element, va trebui memorat o adres
de nlnuire (adresa zonei de memorie rezervat pentru urmtorul element al

122
listei). Prin urmare, o list poate fi conceput ca o mulime de noduri care
conine o parte de date i adresa urmtorului element.
Prezentm n continuare un program Pascal n care se creaz o list
simplu nlnuit cu studenii unei grupe care conine elemente de forma numele
(numele i prenumele) i media anual (nota) i liseaz elementele listei n
ordinea descresctoare a mediei.


{ Crearea unei liste simplu inlantuita}
program lista_inlantuita;
uses crt;
type Legatura=^lista;
gata=(da,nu);
lista= record
numele: string [30];
nota:integer;
adresa_u:legatura;
end;
var
adresa_e, { adresa elementului curent }
adresa_p, { adresa precedentului }
adresa_n, { adresa elementului urmator }
adresa_listei: Legatura;
incep: boolean;

{Scrie un text ca un nume propriu}
function StrProper(s:string):string;

var i,l:integer;

begin
i:=1; l:=length(s);
while i<=l do
begin
while (i<=l) and (s[i] in [' ',#9,'.',',',';']) {spatiu,TAB etc.}
do inc(i);
if s[i] in ['a'..'z'] then {este litera mica }
s[i]:=chr(ord(s[i])-32);
inc(i);
while (i<=l) and (s[i] in ['a'..'z','A'..'Z','0'..'9'])

123
do inc(i);
end;
strProper:=s;
end;

{Adauga unui element in lista}
procedure adauga_in_lista( n:string; { numele }
v:integer); { nota }
begin
new(adresa_e); { aloca spatiu in heap}
if incep then
begin
adresa_listei:=adresa_e; { la inceput memoreaza adresa listei }
incep:=false; { se vor memora alte elemente }
end
else
adresa_p^.adresa_u:=adresa_e; { memoreaza adresa in precedentul
element }
with adresa_e^ do
begin
adresa_u:=nil; { poate este ultimul }
numele:=n; { memoreaza numele }
nota:=v { ... si nota }
end;
adresa_p:=adresa_e; { retine adresa elementului curent }
end;

{ Listarea listei }
procedure listeaza_lista;
begin
adresa_e:=adresa_listei;
repeat
writeln('Numele ',adresa_e^.numele, ' nota ',adresa_e^.nota);
adresa_e:=adresa_e^.adresa_u
until adresa_e=nil;
write('Tastati Enter');
readln;
end;

{ sortarea listei in ordine descretoare a notei - mediei }

124
procedure sorteaza_lista;
var sortat:gata;
begin
repeat
sortat:=da;
adresa_p:=nil;
adresa_e:=adresa_listei;
adresa_n:=adresa_e^.adresa_u;
while adresa_n<>nil do
begin
if adresa_e^.nota < adresa_n^.nota then
begin
if adresa_p= nil then
adresa_listei:=adresa_n
else
adresa_p^.adresa_u:=adresa_n;
adresa_e^.adresa_u:=adresa_e;
adresa_n^.adresa_u:=adresa_n;
sortat:=nu;
end;
if adresa_p=nil then
adresa_p:=adresa_listei { nu are precedent }
else
adresa_p:=adresa_p^.adresa_u;
adresa_e:=adresa_e^.adresa_u; { treci la urmatoarea
pereche }
adresa_n:=adresa_n^.adresa_u;
if adresa_n<>nil then adresa_n:=adresa_n^.adresa_u;
end
until sortat=da
end;

{ procedura principala }
var valoare: integer;
nume: string[30];
begin
incep:=true; { initializari }
clrscr;
repeat
write('Numele (incheiati cu Enter) '); { citeste numele }

125
readln(nume);
if length(nume)=0 then break;
repeat
write('Nota='); { si nota }
readln(valoare);
until (valoare>=0) and (valoare<=10);
if valoare <>0 then { daca valoare admisa }
adauga_in_lista(strproper(nume),valoare); { memoreaza elementul}
until valoare=0; { pina cind nota = 0 }
if not incep then
begin
sorteaza_lista;
listeaza_lista;
end;
end.

Liste dublu nlnuite
Listele de tipul celei prezentate n exemplul precedent poate fi parcurse
ntr-un singur sens: de la nceput la sfrit (se ncepe cu primul, se continu cu al
doilea, apoi al treilea etc.). Vom prezenta n continuare, o list care poate fi
parcurs n ambele sensuri. Operaiile pe list vor face obiectul unitii de
program PASCAL Listed. Toate funciile i procedurile acestei uniti snt
polimorfice (independente de tipul elementelor listei).


unit listed;
interface

type PElement=^Element;
Element= record
adresa_date:pointer; {adresa partii ce contine datele }
adresa_u:Pelement; { adresa elementului urmator }
end;

{declarari de proceduri si functii }
procedure init_lista(var l:Pelement); { initializare lista }
procedure adauga(var s, { adauga un element }
precedent:Pelement;
date:pointer);
procedure citeste_date(s:Pelement;var date:pointer); { preia partea de date }

126
function treci_la_altul(var c:Pelement):boolean; { treci la urmatorul element
al listei }
function lista_vida(s:PElement): boolean; { test daca lista e vida }
procedure sterge_element(var s,prec:PElement); { sterge elementul curent }

{ partea de implementare a operatiilor }
implementation

{ initializare lista}
procedure init_lista(var l:Pelement);
begin
l:=nil;
end;

{ adaugare element }
procedure adauga(var s,
precedent:Pelement;
date:pointer);
var c:Pelement;
begin
new(c);
if s=nil then s:=c else precedent^.adresa_u:=c;
with c^ do begin
adresa_u:=nil;
adresa_date:=date;
end;
precedent:=c;
end;

{ citeste partea de date }
procedure citeste_date(s:Pelement;var date:pointer);
begin
date:=s^.adresa_date;
end;

{ treci la urmatorul element din lista }
function treci_la_altul(var c:Pelement):boolean;
begin
c:=c^.adresa_u;
treci_la_altul:=(c=nil);

127
end;

{ sterge elementul curent }
procedure sterge_element(var s,prec:PElement);
var p:PElement;
begin
if s=prec then begin
s:=s^.adresa_u;
dispose(prec);
end
else
begin
p:=prec^.adresa_u;
prec^.adresa_u:=p^.adresa_u;
end;
end;

{ test daca lista este vida }
function lista_vida(s:PElement): boolean;
begin
lista_vida:=(s=nil);
end;

end.

Programul de mai jos utilizeaz elementele unitii Listed

program studenti;
uses listed,
crt;

type student=record (* date relative la un student *)
nume:string[30];
nota: integer;
end;
Tadr=^student; (* este un pointer la un articol de tip student *)

var stud, (* adresa listei de studenti *)
prec:Pelement; (* precedentul student *)


128
x:pointer; (* este un pointer al carui tip se va preciza *)

adresa_s:^student;

begin
init_lista(stud); (* initializarea listei de studenti *)
while true do begin (* introdu in lista pina cind numele este spatiu *)
new(adresa_s); (* rezerva spatiu pentru un student *)
with adresa_s^ do begin
write('Numele '); readln(nume); (* citeste numele *)
if length(nume)=0 then begin
dispose(adresa_s); (* elibereza zona alocata *)
break; (* incheie bucla *)
end;
write('nota= '); readln(nota); (* citeste nota *)
end;
adauga(stud,prec,adresa_s); (* adauga-l in lista *)
end;

(* listeaza studentii *)
prec:=stud; (* incepe cu primul *)
repeat
citeste_date(prec,x); (* citeste datele *)
writeln(Tadr(x)^.nume,' are nota ',Tadr(x)^.nota); (* afiseaza-le *)
until treci_la_altul(prec); (* treci la altul *)
readln; (* asteapta un caracter *)
prec:=stud;
(* listeaza studentii *)
sterge_element(stud,prec);
prec:=stud; (* incepe cu primul *)
repeat
citeste_date(prec,x); (* citeste datele *)
writeln(Tadr(x)^.nume,' are nota ',Tadr(x)^.nota); (* afiseaza-le *)
until treci_la_altul(prec); (* treci la altul *)
readln; (* asteapta un caracter *)
end.




129
2. Structuri de date
Date i structuri de date
Tipuri de date
Sistemele de prelucrare automat a datelor prelucreaz date, n concordan cu
cerinele informaionale, pentru a se obine informaii. ntr-un program se
utilizeaz:
- date de intrare, cunoscute n problema pe care programul o rezolv;
- date de ieire, reprezentate de rezultatele ce se cer n problem.
Datele de intrare sunt valori ce se atribuie variabilelor de intrare iar datele de ieire
sunt valori pe care le iau variabilele de ieire. Ele trebuie s aparin domeniului
acestor variabile.
Dup complexitatea lor, datele pot fi:
- date atomice (simple), a cror valoare nu se poate descompune;
- date structurate (grupate), formate din n valori.
Structura definete modul de dispunere a elementelor unei date i relaiile ce se
pot stabili ntre aceste elemente. Elementele constitutive se numesc cmpuri i ele
pot fi date simple sau, la rndul lor, grupate.
Un tip de date se identific prin:
- domeniu - o mulime de valori posibile pentru acele date (realizri ale
tipului);
- comportament - o mulime de operaii, funcii i relaii ce opereaz cu
valorile tipului.
De foarte multe ori se pune problema prelucrrii unui volum mare de date de
acelai tip. Prelucrrile pot fi att individuale ct i globale. n prelucrrile globale
datele sunt parcurse secvenial, dar n prelucrrile individuale se pune problema
accesului punctual la date, pe baza unui element de identificare.
Elementele unui tip de date se mpart n:

130
- partea de identificare (cheia), care trebuie s fie unic pentru o anumit
realizare a tipului;
- partea de atribute (de informaie).
Tipuri de legturi
n funcie de legturile ce se pot stabili ntre elementele componente ale unui tip se
deosebesc patru tipuri fundamentale de structuri:
- mulime;
- liniar;
- arborescent;
- graf (reea).
Tipul de legturi specifice pentru fiecare tip de structur este dat n tab. 2.1, iar
reprezentarea grafic a acestora este dat n fig. 2.1.

Tip structur Tip legtur ntre elemente
mulime nici una
liniar unu - la - unu
arbore unu - la - mai multe
graf mai multe - la - mai multe

Tab. 2.1 Tipul de legturi specifice structurilor de date



131






mulime liniar arbore graf


Fig. 2.1 Tipuri fundamentale de structuri de date

Structuri fizice de date
Memoria intern a sistemelor de calcul, n care datele se stocheaz n timpul
execuiei programelor, are o organizare liniar. Indiferent de tipul structurilor
logice de date, se pune aadar problema liniarizrii lor. Liniarizarea se realizeaz n
mod diferit, astfel nct operaiile elementare asupra structurilor de date s se
execute n timp optim. Din acest punct de vedere, structurile fizice de date pot fi:
- statice - ocup n memorie o zon de dimensiune constant, iar
elementele componente i pstreaz locul n tot timpul execuiei
programului;
- semistatice - ocup n memorie o zon de dimensiune constant, dar
elementele componente i modific locul n timpul execuiei
programului;
- dinamice - memoria ocupat nu are o dimensiune constant, ea alocndu-
se pe msura nevoii de prelucrare, n timpul execuiei programului.
Unele structuri logice de date pot fi implementate sub oricare din cele trei forme,
altele nu.
Structuri statice
Pentru structurile statice de date alocarea memoriei este static att la nivelul
ntregii structuri ct i la nivelul elementelor componente. Locul structurilor i a
fiecrei componente, n memoria intern, este fix, structurile statice fiind structuri
de date inerte. Ele exist pe toat durata execuiei programului sub aceeai form,
fr s evolueze.
Articolul este format dintr-un numr fix de componente de tipuri diferite, care
formeaz n ansamblu o structur logic. Componentele articolului se numesc

132
cmpuri. Structura articolului este neomogen, datorit cmpurilor de tip diferit.
Structura unui articol este reprezentat grafic n fig. 2.2.


cmp 1 cmp 2 cmp i cmp n

a
1
l
1
a
2
l
2
a
i
l
i
a
n
l
n


Fig. 2.2 Structura unui articol


Cmpurile pot avea lungimi diferite, iar adresa cmpului i (a
i
) se poate obine pe
baza adresei primului cmp (a
1
) i a lungimii primelor i-1cmpuri (l
1
l
i-1
):

a
i
= a
1
+l
1
+ l
2
++ l
i-1
(2.1)

Tabloul este o aplicaie prin care unui k-uplu de indici (i
1
, i
2
i
k
) i se asociaz un
element m
i1, i2,,ik
. n general tabloul este o structur omogen, toate elementele
tabloului fiind de acelai tip. Pentru k = 1 tabloul este unidimensional (vector), iar
pentru k = 2 tabloul este bidimensional (matrice). Elementele unui tablou ocup, n
memoria intern, locaii succesive.
Dac tabloul este omogen, adresa relativ a unui element fa de adresa de nceput
a tabloului este uor de calculat. Pentru un vector, dac toate elementele au
lungimea l i adresa primului element al tabloului este a
1
, adresa elementului i (a
i
)
va fi:

a
i
= a
1
+l*(i-1) (2.2)

Mulimea este o colecie finit de elemente (m
1
, m
2
, , m
n
) care poate fi asimilat
cu un vector. Structura de submulime poate fi definit cu ajutorul unui vector
asociat, de aceeai dimensiune. Elementul i al vectorului asociat va avea valoarea 1
dac elementul m
i
al mulimii de baz aparine submulimii definit pe baza
vectorului asociat i va avea valoarea 0 n caz contrar. Orice operaii cu
submulimile unei mulimi pot fi implementate ca operaii logice asupra vectorilor
asociai acelor submulimi.
Structuri semistatice
Pentru structurile semistatice de date alocarea memoriei este static la nivelul
ntregii structuri i dinamic la nivelul elementelor componente. Structurile
semistatice utilizeaz o zon fix de memorie, alocat n mod static, dar n cadrul
acesteia se aloc dinamic locaii corespunztoare elementelor structurii. Spaiul

133
alocat structurilor statice este rezervat lor pe toat durata execuiei programului, dar
structura se modific prin adugarea i eliminarea de elemente.
Elementele structurii pot fi eliminate, atunci cnd nu mai sunt necesare, iar locaiile
eliberate pot fi reutilizate pentru alte elemente. Procedura de adugare a unui nou
element va trebui s verifice dac structura semistatic nu este deja plin (spaiul
alocat a fost utilizat n ntregime), iar procedura de eliminare a unui element va
trebui s verifice dac structura nu este deja vid.
Stiva este o structur semistatic pentru care spaiul de memorie alocat este
cuprins ntre baza B i vrful V, unde B < V. Adugarea unui element n stiv
se face prin ocuparea primei locaii libere, de la baz spre vrf. tergerea unui
element din stiv se face prin eliberarea primei locaii ocupate, de la vrf spre
baz. Dup modul n care elementele ntr n i ies din stiv, aceasta se mai
numete i list LIFO (Last In - First Out, ultimul intrat - primul ieit).
Stiva are asociat un indicator inds. Dac stiva este vid, atunci inds = B, iar dac
stiva este plin, atunci inds = V. Procedura de adugare a unui nou element n stiv
trebuie s verifice dac stiva nu este plin, iar n urma operaiei de adugare
indicatorul stivei va crete cu o unitate. Procedura de eliminare a unui element din
stiv va trebui s verifice dac stiva nu este vid, iar n urma eliminrii indicatorul
stivei va descrete cu o unitate.
Coada este o structur semistatic asemntoare cu stiva, dar al crei mecanism de
actualizare este diferit. Adugarea unui element n coad se face prin ocuparea
primei locaii libere de la vrf spre baz. tergerea unui element din coad se face
prin eliberarea primei locaii ocupate, de la baz spre vrf. Dup modul n care
elementele ntr n i ies din coad, aceasta se mai numete i list FIFO (First I n -
First Out, primul intrat - primul ieit
O coad are doi indicatori relativi, care arat locul n care se adaug un element
nou (inda) i respectiv locul din care se elimin un element (inde). Adresa la care
se adaug noul element va fi B+inda, iar adresa de la care se extrage un element va
fi B+inde. Coada este vid dac inda = inde (iniial inda = inde = 0) i este plin
dac inde = (inda+1)(mod n), unde n = V-B. Procedura de adugare a unui nou
element n coad trebuie s verifice dac aceasta nu este plin, iar n urma operaiei
de adugare indicatorul inda va crete cu o unitate (mod n). Procedura de eliminare
a unui element din coad va trebui s verifice dac aceasta nu este vid, iar n urma
eliminrii indicatorul inde va crete cu o unitate (mod n).
Structuri dinamice
Pentru structurile dinamice de date alocarea memoriei este dinamic att la nivelul
ntregii structuri ct i la nivelul elementelor componente. n cazul n care numrul
elementelor componente ale unei anumite structuri de date nu este cunoscut,
alocarea unui spaiu fix de memorie pentru stocarea acelei structuri este ineficient.

134
Spaiul alocat poate fi fie insuficient, fie prea mare. Spaiul de memorie trebuie s
fie alocat dinamic, pe msura apariiei elementelor structurii.
Alocarea dinamic a memoriei presupune nlnuirea elementelor structurii.
Fiecare element va conine:
- informaie de legtur (referin) - LEG
i
;
- informaie util - INF
i
.
Informaia de legtur este o informaie suplimentar pe baza creia sunt legate
ntre ele elementele structurii.
Lista liniar este o structur dinamic n care elementele componente sunt situate
pe un singur nivel. Pentru reprezentarea intern a unei liste sunt necesare:
- adresa primului element al listei, numit cap de list (CAP);
- modul de nlnuire al elementelor listei;
- indicarea ultimului element din list (LEG
n
= nil).


CAP

INF
1
LEG
1
INF
2
LEG
2
INF
n
LEG
n
=nil


Fig. 2.3. Structura unei liste


n lista liniar simplu nlnuit informaia de legtur conine doar adresa
elementului urmtor din list. n lista liniar dublu nlnuit informaia de
legtur conine att adresa elementului urmtor ct i adresa elementului
precedent din list. n lista circular informaia de legtur a ultimului element din
list conine adresa primului element al listei.
Structura arborescent este o structur dinamic n care elementele componente
sunt grupate pe mai multe niveluri ierarhice. Elementele componente formeaz
nodurile (vrfurile) arborelui. Orice arbore are un nod special, numit rdcin.
Nodul rdcin formeaz nivelul 1 al unui arbore, fiind singurul nod nesubordonat
nici unui alt nod. Toate celelalte noduri ale arborelui sunt subordonate unele altora,
fiecare nod fiind subordonat direct unui singur nod. Nodurile subordonate rdcinii
formeaz nivelul 2 al arborelui, nodurile subordonate acestora formeaz nivelul 3,
.a.m.d. Fiecare set disjunct de noduri, altele dect rdcina, formeaz la rndul su
un arbore (subarbore).
Un nod terminal (frunz) este un nod care nu are nici un alt nod subordonat. Un
nod este printe (tat) pentru nodurile subordonate direct lui, iar acestea sunt fii

135
ale nodului crora le sunt subordonate. Nodurile subordonate direct aceluiai nod
sunt frai.
Arborii care nu au noduri ierarhizate pe mai multe niveluri sunt arbori neorientai.
Un arbore este binar dac se compune din rdcin i din doi subarbori, numii
subarborele stng i subarborele drept. Un arbore ale crui noduri au cel mult doi
descendeni este binar dac se tie ntotdeauna care sunt fiul stng i fiul drept al
fiecrui nod.
Elementele unui arbore sunt nodurile i legturile dintre ele. Ierarhizarea nodurilor
se exprim, de regul, prin referine descendente (printe - fiu), dar se poate
exprima i prin referine ascendente (fiu - printe) sau orizontale (frate - frate).
Dac numrul maxim de referine ale unui nod este n, elementul corespunztor
nodului poate fi reprezentat ca n fig. 2.7. Absena unei legturi se semnaleaz
printr-o valoare special nil.


LEG
1
LEG
2
LEG
n
Informaie util

Fig. 2.4. Reprezentarea unui nod cu n referine


Reeaua (graful) este o structur dinamic n care elementele componente nu sunt
grupate pe niveluri ierarhice, putnd exista legturi ntre oricare dintre noduri.
Fiecare nod poate avea un numr oarecare de referine i poate fi referit, la rndul
su, de un numr oarecare de alte noduri. Dac numrul maxim de referine ale
unui nod este n, reprezentarea acestuia se poate face ca n fig. 2.7.
Implementarea tipurilor abstracte de date
Prima etap n implementarea unui TAD este alegerea limbajului de programare.
Aceasta se va baza pe cunoaterea tipurilor de date i a facilitilor de
implementare pe care le ofer limbajul respectiv. n continuare este dat o
clasificare general a tipurilor de date pe care le posed limbajele de programare de
nivel nalt. n fiecare caz sunt date exemple specifice limbajului Pascal.
Dup componena elementelor, tipurile de date se mpart n:
- simple (atomice) - integer, real, char, enumerare, subdomeniu, pointer;
- structurate - omogene (tablou - array, mulime set) sau heterogene
(articol - record).
Dup relaiile ntre elementele domeniului, se disting:
- tipuri de date ordinale (au operatori relaionali - integer, real, char,
enumerare, subdomeniu);

136
- tipuri liniare (au operatori de preceden - integer, char, enumerare,
subdomeniu);
- tipuri amorfe (au doar operatori de atribuire i egalitate - real, set, array,
record, pointer).
Dup specificarea n limbajul de programare, tipurile de date sunt:
- predefinite - integer, real, char;
- definite de utilizator (pe baza tipurilor existente, prelund de la acestea
reprezentarea, dar nu i operaiile existente) - enumerare, subdomeniu.
Dup gradul de abstractizare, tipurile de date sunt:
- clasice;
- abstracte (ncapsuleaz date i operaii i permit motenirea acestora) -
object.
Limbajele noi de programare includ mecanisme proprii abstractizrii datelor,
programrii modulare i obiectuale. Limbajele clasice apar n versiuni noi, care
extind limbajul standard. Versiunile limbajului Turbo Pascal includ mecanisme de
modularizare (unit-uri, ncepnd cu versiunea 4.0) i de programare obiectual
(ncepnd cu versiunea 5.5). Mecanismele de programarea obiectual sunt
inexistente n limbajul C dar sunt prezente n limbajul C++.
Implementare unui TAD se va face pe baza tipurilor de date predefinite i a
mecanismelor de tipizare i abstractizare ale limbajului de programare ales.
Specificarea TAD-ului trebuie respectat ntocmai la implementare. Pentru acelai
TAD pot fi imaginate implementri diferite. Alegerea algoritmilor utilizai la
implementare se va face dup criterii de eficien specifice domeniului de utilizare.
Cele mai des utilizate criterii sunt cele privitoare la memoria necesar reprezentrii
i la timpul de execuie a operaiilor.
O problem deosebit de important o reprezint regsirea unei instane a unui tip de
date, pe suportul de memorie. Regsirea poate fi:
- poziional;
- legat.
Regsirea poziional presupune determinarea adresei fizice a elementului cutat,
prin calcul. Ea se bazeaz pe o relaie de ordine stabilit pe mulimea elementelor,
relaie definit de poziia pe care elementul o ocup n memorie. Se presupune c
se cunoate lungimea de reprezentare a unui element i numrul de ordine al
elementului cutat. Regsirea este rapid, dar actualizarea elementelor (eliminare,
adugare) este laborioas, necesitnd recopierea unor elemente.
Regsirea legat impune ca fiecare element s conin ca informaie suplimentar
adresa urmtorului element. Actualizarea elementelor necesit doar modificarea
informaiilor de legtur.
n continuare este dat o posibil implementare, n limbajul Pascal, a tipului de date
Natural, conform specificaiei informale prezentate anterior.

137


unit UNatural;

interface

{Tipul Natural se reprezinta ca subdomeniu al tipului predefinit LongInt}
type Natural = 0 .. MaxLongint;
function Zero: Natural;
function EZero(x: Natural): Boolean;
function Succesor(x: Natural): Natural;
function Predecesor(x: Natural): Natural;
function MaiMicSauEgal(x, y: Natural): Boolean;
function Egal(x, y: Natural): Boolean;
function Aduna(x, y: Natural): Natural;
function Scade(x, y: Natural): Natural;
function I nmulteste(x, y: Natural): Natural;
function Imparte(x, y: Natural): Natural;

implementation

procedure Eroare(Sir: String);
begin
WriteLn(EROARE!!! , Sir);
ReadLn;
Halt;
end;

function Zero: Natural;
begin
Zero := 0
end;

function EZero(x: Natural): Boolean;
begin
EZero := (x = Zero)
end;

function Succesor(x: Natural): Natural;
begin
if x < MaxLongInt then Succesor := x + 1
else Eroare(Numar prea mare!)
end;

138

function Predecesor(x: Natural): Natural;
begin
if not EZero(x) then Predecesor:= x - 1
else Eroare(Nu are predecesor!)
end;

function MaiMicSauEgal(x, y: Natural): Boolean;
begin
MaiMicSauEgal := (x <= y)
end;

function Egal(x, y: Natural): Boolean;
begin
Egal := (MaiMicSauEgal(x,y) and MaiMicSauEgal(y,x))
end;

function Aduna(x, y: Natural): Natural;
begin
if Int(x) + Int(y) <= Int(MaxLongInt) then Aduna := (x + y)
else Eroare(Rezultat prea mare!)
end;

function Scade(x, y: Natural): Natural;
begin
if y <= x then Scade := x-y
else Eroare(X<Y!)
end;

function I nmulteste(x, y: Natural): Natural;
begin
if Int(x) * Int(y) <= Int(MaxLongInt) then Inmulteste := x * y
else Eroare(Rezultat prea mare)
end;

function Imparte(x, y: Natural): Natural;
begin
if not EZero(y) then Imparte := x div y
else Eroare(Impartire la zero!)
end;

end.


139

Un program pentru testarea unit-ului UNatural ar putea fi cel de mai jos.


Program Test_unit_UNatural;
uses UNatural, Crt;

var
Operatie: Integer;
x,y: Natural;

begin
clrscr;
Write('x, y: '); Readln(x,y);
Writeln('1 Aduna, 2 Scade, 3 Inmulteste, 4 Imparte');
Write('Operatie: '); Readln(Operatie);
case Operatie of
1: Writeln(Aduna(x,y));
2: Writeln(Scade(x,y));
3: Writeln(Inmulteste(x,y));
4: Writeln(Imparte(x,y));
end;
readln;
end.
Tipuri colecie
Datele compuse de tip colecie conin un numr finit de elemente. Dac pentru
tipul elementelor ce formeaz colecia este definit un operator de ordonare (o
relaie de ordine), colecia este ordonat. n caz contrar colecia este neordonat.
Coleciile pot admite sau nu elemente multiple.
Dup tipul elementelor componente, coleciile pot fi:
- omogene (tablou de reali, string, stive de elemente ntregi etc.);
- heterogene (list liniar de primitive grafice etc.).
Coleciile pot fi:
- de mrime fix (tablou, string etc.);
- de mrime variabil (list liniar sau arbore generate dinamic etc.).
Funciile primitive ale tipurilor colecie pot fi:
- de tip constructori;
- de adugare a unui element la colecie;

140
- de eliminare a unui element din colecie;
- de selecie a unui element al coleciei;
- de testare a coleciei vide.
Funciile derivate ale tipurilor colecie reprezint operaii de:
- cutare;
- sortare;
- interclasare;
- traversare.
Liste liniare
Lista este una din structurile fundamentale de date, reprezentnd un mod uzual de a
pstra o colecie de elemente, n orice domeniu: lista studenilor unei faculti, lista
medicamentelor existente ntr-o farmacie, lista abonailor unei centrale telefonice,
lista materialelor existente ntr-o magazie etc. Astfel de liste sunt actualizate
continuu, prin adugarea de noi elemente, eliminarea unor elemente sau
modificarea unor elemente existente n list. Listele sunt aadar dinamice prin
natura lor. n memorie listele pot fi reprezentate prin structuri statice (tablouri) sau
prin structuri dinamice (liste nlnuite).
Lista este o structur de date omogen, format din elemente ale listei. Elementele
pot fi de acelai tip atomic, caz n care lista este liniar simpl, sau pot fi la rndul
lor liste, caz n care lista este neliniar. Proprietile unei liste sunt independente
de proprietile tipului elementelor listei.
O list este fie vid fie este alctuit dintr-un element de list numit cap i o list
numit coad (restul listei). Lista cu un singur element are lista coad vid. Lista
poate fi definit recursiv astfel:


list tip_el_list: list_vid / tip_el_list cap list tip_el_list coad


O caracteristic esenial a unei liste este faptul c ntre elementele ei exist
legturi. Orice element al listei conine, pe lng informaia util, i o informaie
de legtur. Prin legarea elementelor listei, exist un unic element al listei numit
primul (capul listei) i un unic element numit ultimul, a crui informaie de
legtur indic o valoare special (nil), care nu reprezint adresa nici unui element
din list. Fiecare element al listei, cu excepia primului, are un predecesor unic.
Fiecare element al listei, cu excepia ultimului, are un succesor unic. Pentru ca
toate elementele listei s aib predecesor i succesor, n list se pot introduce dou

141
elemente false, numite santinele, plasate la nceputul listei (naintea primului
element al listei) i la sfritul listei (dup ultimul element din list).
Toate operaiile de prelucrare a listei opereaz cu poziia curent n list, definit
ca poziia elementului accesibil la momentul dat. Operaiile se efectueaz asupra
elementului curent. Elementul curent este singurul vizibil la un moment dat.
Toate elementele pot deveni, pe rnd, vizibile prin modificarea poziiei curente n
list.


CAP

INF
1
LEG
1
INF
2
LEG
2
INF
n
LEG
n
=nil


Fig. 2.5. Lista simplu nlnuit


Dac informaia de legtur a fiecrui element al listei conine doar adresa
succesorului su, lista este simplu nlnuit (fig. 2.13). Listele liniare simplu
nlnuite pot fi parcurse doar ntr-un singur sens, de la primul spre ultimul
element.
Operaiile care presupun referirea la predecesorul elementului curent, cum sunt
inserarea unui element naintea elementului curent sau tergerea elementului
curent, sunt dificil de realizat pentru listele simplu nlnuite. Dac informaia de
legtur a fiecrui element al listei conine att adresa succesorului ct i a
predecesorului su, lista este dublu nlnuit (fig. 2.14). Listele liniare dublu
nlnuite pot fi parcurse n ambele sensuri, att de la primul spre ultimul element,
ct i de la ultimul spre primul element.



Pred
1
=nil INF
1
Succ
1
Pred
2
INF
2
Succ
2
Pred
n
INF
n
Succ
n
=nil


Fig. 2.6. Lista dublu nlnuit


Dac ultimul element este legat cu primul element, lista capt o structur
circular. n acest caz santinelele nu mai sunt necesare, primul element fiind
succesorul ultimului, iar ultimul element fiind predecesorul primului.
Structura unei liste poate fi modificat prin:

142
- iniializarea unei liste ca o list vid;
- adugare de noi elemente la sfritul listei;
- inserare de noi elemente pe orice poziie n list;
- tergere de elemente de pe orice poziie a listei;
- modificarea unor elemente din list.
Operaii care nu modific structura listei dar dau informaii despre ea
(caracterizeaz lista) sunt:
- determinarea lungimii listei (numrul de elemente din list);
- localizarea poziiei elementului care satisface un criteriu dat.
Operaii mai complexe asupra listelor sunt:
- partiionarea unei liste n dou sau mai multe subliste;
- combinarea a dou sau mai multe liste ntr-una singur, prin
concatenare (simpl alipire) sau interclasare (ordinea elementelor n
noua list e stabilit conform unui criteriu dat);
- selecia elementelor dintr-o list, care ndeplinesc un criteriu dat;
- ordonarea (ascendent sau descendent) a unei liste, dup o cheie.
i. Implementarea dinamic a tipului abstract de
date Lista
O implementare a TAD Lista, pe baza unei liste simplu nlnuit este data mai
jos, prin unit-ul ULista. Alocarea memoriei se face dinamic. Elementele listei pot fi
de orice tip. Acest lucru este posibil prin utilizarea n nodurile listei a pointerilor
generici ctre elemente. Lista este format din noduri, care pstreaz referine la
elementele propriu-zise. Operaiile asupra elementelor listei sunt, de fapt, operaii
asupra nodurilor listei. Aadar elementele listei sunt noduri, a cror informaiei
util reprezint referine ctre elementele propriu-zise.
Lista este o structur cu doi indicatori (fig. 2.15):
- Cap - indic primul nod al listei;
- Curent - indic poziia curent n list.
Lista e declarat ca un articol cu dou cmpuri, Cap i Curent, iar nodul este un
articol ale crui cmpuri sunt:
- Element - pointer la elementul propriu-zis;
- Urmatorul - pointer la nodul urmtor al listei.



143


Cap Curent

e
1
e
2


e
i-1
e
i
e
i+1


e
n
nil

Fig. 2.7 List simplu nlnuit cu doi indicatori (Cap, Curent)


{
Implementare TAD Lista prin lista simplu inlantuita.
Indicatori Cap (primul nod al listei) si Curent (nodul curent).
Alocare dinamica.
Informatia din noduri reprezinta pointeri la informatia utila.
Listele pot avea orice tip de elemente.
}
unit ULista;

I nterface

type

{tip Nod lista}
PNod = ^Nod;
Nod = record
Element: pointer;
Urmatorul: PNod
end;

{tip lista}
Lista = record
Cap, Curent: PNod
end;

{initializare lista}
procedure Creaza(var L: Lista);
{test lista vida}
function EVida(L: Lista): Boolean;
{test pozitionare pe primul nod}
function EPrimul(L: Lista): Boolean;
{test pozitionare pe ultimul nod}

144
function EUltimul(L: Lista): Boolean;
{pozitionare pe primul nod}
function PePrimul(var L: Lista): Boolean;
{pozitionare pe ultimul nod}
function PeUltimul(var L: Lista): Boolean;
{pozitionare pe nodul urmator}
function PeSucc(var L: Lista): Boolean;
{pozitionare pe nodul precedent}
function PePrec(var L: Lista): Boolean;
{inserare dupa nodul curent}
procedure I nsereaza(var L: Lista; e: pointer);
{adaugare la sfarsitul listei}
procedure Adauga(var L: Lista; e: pointer);
{stergere nodul curent}
procedure Sterge(var L: Lista);
{actualizare nod}
procedure Actualizeaza(var L: Lista; e: pointer);
{extragere nod}
procedure Extrage(var L: Lista; var e: pointer);
{lungime lista}
function Lungime(var L: Lista): Integer;

Implementation

procedure Creaza(var L: Lista);
begin
L.Cap := nil;
end;

function EVida(L: Lista): Boolean;
begin
EVida := (L.Cap = nil)
end;

function EPrimul(L: Lista): Boolean;
begin
if not EVida(L) then EPrimul := (L.Curent = L.Cap)
else EPrimul:=False;
end;

function EUltimul(L: Lista): Boolean;
begin
if not EVida(L) then EUltimul := (L.Curent^.Urmatorul = nil)

145
else EUltimul := False;
end;

function PePrimul(var L: Lista): Boolean;
begin
if not EVida(L) then
begin
L.Curent := L.Cap;
PePrimul := True;
end
else PePrimul := False;
end;

function PeUltimul(var L: Lista): Boolean;
begin
if not EVida(L) then
begin
repeat
until not PeSucc(L);
PeUltimul := True;
end
else PeUltimul := False;
end;

function PeSucc(var L: Lista): Boolean;
begin
if EVida(L) then PeSucc := False
else
begin
PeSucc := True;
if not Eultimul(L) then L.Curent := L.Curent^.Urmatorul
else PeSucc := False
end;
end;

function PePrec(var L: Lista): Boolean;
var p: PNod;
begin
if (not EVida(L)) and (L.Curent <> L.Cap) then
begin
p := L.Curent;
if PePrimul(L) then
repeat

146
until (p = L.Curent^.Urmatorul) or (not PeSucc(L))
else PePrec := False;
end
else PePrec := False;
end;

procedure I nsereaza(var L: Lista; e: pointer);
var p: PNod;
begin
New(p);
p^.Element := e;
if EVida(L) then begin
p^.Urmatorul := L.Cap;
L.Cap := p;
L.Curent := p
end
else begin
p^.Urmatorul := L.Curent^.Urmatorul;
L.Curent^.Urmatorul := p;
L.Curent := p
end
end;

procedure Adauga(var L: Lista; e: pointer);
var p: PNod;
begin
if EVida(L) then Insereaza(L, e)
else
begin
repeat
until not PeSucc(L);
New(p);
p^.Element := e;
p^.Urmatorul := L.Curent^.Urmatorul;
L.Curent^.Urmatorul := p;
L.Curent := p
end;
end;

procedure Sterge(var L: Lista);
var p: PNod;
begin
if not EVida(L) then

147
begin
p := L.Curent;
if PePrec(L) then L.Curent^.Urmatorul := p^.Urmatorul;
else L.Cap := L.Cap^.Urmatorul;
if p^.Urmatorul <> nil then L.Curent := p^.Urmatorul;
{OPTIONAL - eliminarea elementului din memorie}
Dispose(p^.Element);
{eliminarea nodului din lista}
Dispose(p);
end;
end;

procedure Actualizeaza(var L: Lista; e: pointer);
begin
if not EVida(L) then
begin
{OPTIONAL - eliminarea vechiului element din memorie}
Dispose(L.Curent^.Element);
L.Curent^.Element := e
end;
end;

procedure Extrage(var L: Lista; var e: pointer);
begin
if not EVida(L) then e := L.Curent^.Element
end;

function Lungime(var L: Lista): Integer;
var i: Integer;
begin
i := 0;
if (not EVida(L)) and PePrimul(L) then
repeat
i := i+1;
until not PeSucc(L);
Lungime := i;
end;

end.


Procedura Sterge realizeaz att eliminarea nodului curent din list ct i
eliminarea elementului propriu-zis din memorie. Dup efectuarea operaiei nodul

148
succesor al nodului eliminat devine nod curent. Procedura Actualizeaza elimin i
ea vechiul element din memorie. Implementarea celor dou operaii poate fi
modificat, astfel nct elementele s fie eliminate ca noduri din list dar pstrate n
memorie. Aceast abordare este mai logic pentru c, aa cum s-a mai precizat,
lista este format din noduri asupra crora acioneaz operaiile. Crearea i
eliminarea din memorie a elementelor propriu-zise pot fi lsate pe seama
aplicaiei. nainte de alocarea memoriei pentru noduri (respectiv elemente) noi
trebuie s se verifice dac exist memorie disponibil. n Turbo Pascal acest lucru
se poate face cu ajutorul funciei MaxAvail.
Condiia Cap = nil este suficient pentru ca lista s fie vid. Din acest motiv nu
este necesar ca procedura Creaza s iniializeze i indicatorul Curent = nil.
Operaiile Adaug, terge, PeUltimul, PePred i Lungime sunt de complexitate
O(l), dac l este lungimea listei. Toate celelalte operaii sunt de complexitate O(1).
Complexitatea operaiei terge se reduce la O(1) dac implementarea se realizeaz
pe baza unei liste simplu nlnuite cu trei indicatori: Cap, Curent i Precedent (fig.
2.16).

Precedent
Cap Curent

e
1
e
2


e
i-1
e
i
e
i+1


e
n
nil

Fig. 2.8 List simplu nlnuit cu trei indicatori (Cap, Curent, Precedent)

Prin utilizarea unei liste circulare simplu nlnuite cu doi indicatori, Coad i
Curent (fig. 2.17), complexitatea operaiei Adaug se reduce la O(1), dar
complexitatea operaiei terge rmne O(l). n acest caz indicatorul Cap devine
inutil, primul nod al listei fiind indicat de legtura ultimului nod. Complexitatea
operaiei PeUltimul se reduce i ea la O(1).





Curent Coad

e
1
e
2


e
i-1
e
i
e
i+1


e
n



Fig. 2.9 List circular simplu nlnuit cu doi indicatori (Coad, Curent)

149

Dac se utilizeaz o list circular simplu nlnuit cu trei indicatori, Coad,
Curent i Precedent (fig. 2.18), complexitatea operaiilor Adaug i terge se
reduce la O(1), dar complexitatea operaiei PeUltimul rmne O(l).

Precedent
Curent Coad

e
1
e
2


e
i-1
e
i
e
i+1


e
n



Fig. 2.10 List circular simplu nlnuit cu trei indicatori (Coad, Curent,
Precedent)

n toate cele patru cazuri de liste simplu nlnuite prezentate, structura unui nod
este aceeai (Element, Urmatorul). Structura listei difer de la caz la caz, n funcie
de indicatorii utilizai.
Listele dublu nlnuite pot fi parcurse n ambele sensuri. n cazul listelor dublu
nlnuite structura unui nod trebuie s fie:
- Element - pointer la elementul propriu-zis;
- Urmatorul - pointer la nodul urmtor al listei;
- Precedentul - pointer la nodul precedent al listei.
Structura unei liste dublu nlnuite este tot de tip articol cu dou componente
(Cap, Curent), ca i n cazul listei simplu nlnuite. Indicatorul Precedent devine
inutil, fiecare nod al listei avnd o legtur la nodul precedent (fig 2.19). Prin
utilizarea unei astfel de liste complexitatea operaiilor terge i PePrec se reduce la
O(1).



Cap Curent

nil e
1
e
2


e
i-1
e
i
e
i+1


e
n
nil

Fig. 2.11 List dublu nlnuit cu doi indicatori (Cap, Curent)

n cazul unei liste circulare dublu nlnuite (fig. 2.20) complexitatea tuturor
operaiilor (mai puin Lungime) devine O(1).

150

Curent Coad

e
1
e
2


e
i-1
e
i
e
i+1


e
n



Fig. 2.12 List circular dublu nlnuit cu doi indicatori (Coad, Curent)

Complexitatea operaiilor Adaug i PeUltimul poate fi redus la O(1) n toate
cazurile, prin introducerea n structura listei a indicatorului Coad. Complexitatea
operaiei Lungime poate fi redus la O(1) n toate cazurile, prin introducerea n
structura listei a indicatorului Lungime. n mod evident, aceti indicatori trebuie s
fie actualizai, cnd este cazul, de ctre operaiile asupra listei.
Un program pentru testarea unit-ului ULista poate fi cel prezentat n continuare.
Elementele listei vor fi numere ntregi. Programul poate fi uor adaptat pentru
lucrul cu liste ale cror elemente au un alt tip. Pentru aceasta se vor schimba
declaraia tipului PElement i, corespunztor, procedurile de I/O.


{Testare unit ULista}

Program Operatii_cu_liste;

uses ULista, Crt;

type
{tipul elementelor listei}
PElement = ^Integer;

var
optiune: Integer;
L: Lista;
e: pointer;
element: PElement;

{cauta in lista elementul dat}
function Cauta (L:lista; e:pointer):Boolean;
var elem: pointer;
begin
Cauta := False;
if not EVida(L) then

151
begin
PePrimul(L);
repeat
Extrage(L, elem);
if PElement(e)^=PElement(elem)^ then Cauta := true;
until not PeSucc(L)
end;
end;

{afiseaza elementele listei}
procedure Afiseaza (L:lista);
var e: pointer;
begin
if not EVida(L) then
begin
PePrimul(L);
repeat
Extrage(L, e);
writeln(PElement(e)^);
until not PeSucc(L)
end;
end;

begin
clrscr;
Creaza(L);
repeat
Writeln('1 - Testeaza lista vida');
Writeln('2 - Test pozitionare pe primul element');
Writeln('3 - Test pozitionare pe ultimul element');
Writeln('4 - Adauga la sfarsitul listei');
Writeln('5 - Insereaza dupa elementul curent');
Writeln('6 - Cauta elementul in lista');
Writeln('7 - Pozitionare pe primul element');
Writeln('8 - Pozitionare pe elementul urmator');
Writeln('9 - Pozitionare pe elementul precedent');
Writeln('10 - Pozitionare pe ultimul element');
Writeln('11 - Extrage valoarea elementului curent');
Writeln('12 - Actualizeaza elementul curent');
Writeln('13 - Sterge elementul curent');
Writeln('14 - Afiseaza lista');
Writeln('15 - Da lungimea listei');
Writeln('16 - Termina executia programului');

152
Read(optiune);
if optiune in [4, 5, 6, 12] then
begin
new(element);
Readln(element^);
e := element;
end;
case optiune of
1: if EVida(L) then Writeln('Lista e vida!') else Writeln('Lista nu e
vida!');
2: if EPrimul(L) then Writeln('E primul!') else Writeln('Nu e primul!');
3: if EUltimul(L) then Writeln('E ultimul!') else Writeln('Nu e ultimul!');
4: Adauga(L, e);
5: Insereaza(L, e);
6: if Cauta(L, e) then Writeln('Elementul ', PElement(e)^, ' se afla in
lista')
else Writeln('Elementul ', PElement(e)^, ' nu se afla in lista');
7: if not PePrimul(L) then Writeln('Eroare!!! Lista e vida!');
8: if not PeSucc(L) then Writeln('Eroare!!! Nu are succesor!');
9: if not PePrec(L) then Writeln('Eroare!!! Nu are predecesor!');
10: if not PeUltimul(L) then Writeln('Eroare!!! Lista e vida!');
11: if EVida(L) then Writeln('Eroare!!! Lista e vida!')
else begin
Extrage(L, e);
Writeln(PElement(e)^)
end;
12: if EVida(L) then Writeln('Eroare!!! Lista e vida!') else
Actualizeaza(L, e);
13: if EVida(L) then Writeln('Eroare!!! Lista e vida!') else Sterge(L);
14: if EVida(L) then Writeln('Lista e vida!') else Afiseaza(L);
15: Writeln(Lungime(L));
end;
until optiune = 16;
end.


Implementarea static a tipului abstract de date
Lista
ntre elementele unei liste liniare cu n elemente, x
1
, x
2
, ... , x
n
i submulimea
numerelor naturale {1, 2, , n} se poate stabili o coresponden biunivoc.

153
Primului element al listei (x
1
) i se asociaz numrul natural 1, celui de-al doilea
element (x
2
) i se asociaz numrul natural 2, iar ultimului element (x
n
) i se asociaz
numrul natural n. Numrul natural asociat unui element al listei definete poziia
elementului n list.
Ordinea elementelor listei este dat de poziiile acestora n list. Orice element al
listei, cu excepia primului, are un predecesor. Orice element al listei, cu excepia
ultimului, are un succesor. Legturile ntre elemente nu mai trebuie s fie precizate
explicit, ele fiind implicite, prin poziia elementelor n list. Elementul x
i
va avea
ca predecesor pe x
i-1
i ca succesor pe x
i+1
. O astfel de list este aadar similar
listei dublu nlnuite.
Consideraiile de mai sus conduc la ideea de implementare a listelor prin tablouri.
Poziia unui element n list va fi determinat de poziia sa n tablou. Primul
element al tabloului va reprezenta primul element al listei, iar elementul de pe
ultima poziie ocupat a tabloului va reprezenta ultimul element al listei. Ca i n
cazul implementrii dinamice, elementele tabloului pot fi referine la elementele
propriu-zise ale listei (similare nodurilor de la implementarea dinamic). Acest
lucru va asigura faptul c pot fi gestionate liste cu elemente de orice tip. Alocarea
memoriei pentru elementelor propriu-zise se face dinamic.
Dezavantajul implementrii unei liste printr-o structur static (tablou) l constituie
faptul c alocarea spaiului de memorie pentru list se face de la nceput i nu mai
poate fi modificat pe parcurs. Numrul maxim de elemente din list este egal cu
dimensiunea tabloului.
O list implementat static va avea doi indicatori:
- Curent - indic poziia curent n list;
- Ultim - indic ultima poziie ocupat n list.
Aceti doi indicatori vor fi de tip ntreg i vor reprezenta indici n tabloul prin care
lista este implementat (fig. 2.21).




Curent Ultim

e
1
e
2
e
i-1
e
i
e
i+1
e
n


Ultimul element al tabloului

Fig. 2.13 Implementare static a TAD Lista

Toate operaiile vor avea complexitate O(1), mai puin terge i Insereaz, care vor
avea complexitate O(l). n ambele cazuri referinele spre toate elementele ce succed

154
elementul curent vor trebui deplasate n tablou. n cazul operaiei terge deplasarea
se va face spre stnga, pentru a se ocupa poziia corespunztoare elementului
eliminat din list (fig. 2.22).







e
1
e
2
e
i-1
e
i
e
i+1
e
n



Fig. 2.14 tergere n list implementat static


n cazul operaiei Insereaz deplasarea referinelor spre elementele de dup
elementul curent se va face spre dreapta, pentru a se elibera o poziie
corespunztoare noului element (fig. 2.23).


e
nou



e
1
e
2
e
i-1
e
i
e
i+1
e
n


Fig. 2.15 Inserare n list implementat static

Liste ordonate
Un caz particular l constituie listele ordonate, n care elementele ocup n list o
ordine stabilit dup o cheie de ordonare. Toate operaiile efectuate asupra listei
trebuie s pstreze lista ordonat.
Operaiile afectate de obligativitatea ordonrii listei sunt Adaug, Insereaz i
Actualizeaz. Operaia Adaug nu are sens n cazul listelor ordonate, pentru c ea
poate afecta ordinea elementelor n list.
Operaia Insereaz nu va mai introduce noul element dup elementul curent, ci pe
o poziie n concordan cu valoarea elementului nou introdus. Problema poate fi
rezolvat dac operaia este precedat de o repoziionare n list, astfel nct ultimul
element care respect relaia de ordine fa de elementul ce va fi inserat n list,

155
conform criteriului de ordonare, s devin noul element curent. Operaia Insereaz
poate fi apoi efectuat, pentru c ea va introduce n list noul element pe o poziie
care nu va afecta ordonarea. Dac primul element al listei nu respect relaia de
ordine fa de elementul nou, inserarea trebuie s se fac n capul listei.
Operaia Actualizeaz nu se va mai limita la modificarea valorii elementului curent
din list ci l va repoziiona n concordan cu noua sa valoare, conform criteriului
de ordonare. Operaia Actualizeaz va implica, de fapt, o operaie de tergere a
elementului curent i una de inserare a noului element. Operaia tergere nu
afecteaz ordinea elementelor.
Stive i cozi
Aa cum am vzut pn acum, n cazul listelor este important poziia unui element
n list i nu momentul n care elementul a fost introdus n list. Locul elementului
n list este ales de utilizator sau este impus de informaia util a elementului, n
cazul listelor ordonate. Un singur element este accesibil la un moment dat, dar toate
elementele pot fi fcute pe rnd accesibile, prin modificarea poziiei curente n
list.
Exist multe cazuri n care pentru o colecie de elemente este esenial momentul de
timp n care fiecare element a fost introdus n colecie. Criteriul de alegere a
elementului curent, care va fi supus urmtoarei prelucrri, este dat de ordinea
introducerii elementelor n colecie.
S presupunem c n buctria unui restaurant farfuriile splate se aeaz pe un
raft, una peste alta. Se obine o stiv de farfurii, iar n momentul servirii clienilor
farfuria aezat n vrful stivei va fi utilizat prima. Ea fiind ultima aezat n stiv,
se poate spune c accesul la elementele stivei se face dup principiul ultimul
intrat, primul ieit (LIFO - Last In First Out). Un principiu identic se poate aplica
n cazul angajailor unei firme, dac singurul criteriu de evaluare al acestora este
vechimea lor n firm. Primul angajat ce va fi avut n vedere la o eventual
concediere va fi angajatul cel mai nou, cu cea mai mic vechime n firm.
S analizm acum cazul clienilor unui magazin. n mod normal, acetia vor fi
servii n ordinea intrrii lor n magazin. Ei formeaz o coad la care i ateapt
rndul pentru a fi servii. Spre deosebire de stiv, accesul la elementele cozii se
face dup principiul primul intrat, primul ieit (FIFO - First In First Out).
Acelai principiu este evident n cazul vagoanelor unui tren, la trecerea acestuia
printr-un tunel, se aplic mainilor dintr-o intersecie etc.
Att stivele ct i cozile sunt colecii ordonate de elemente, dar relaia de ordine
ntre elemente nu are legtur cu informaia util coninut n elemente, ci depinde
exclusiv de momentele integrrii elementelor n colecie. Proprietile coleciilor de
tip stiv i coad sunt independente de tipul elementelor din colecie. Att n cazul
stivelor ct i n cazul cozilor, un singur element este vizibil la un moment dat i
va putea fi extras din colecie n vederea prelucrrii. n cazul stivei elementul

156
accesibil va fi cel plasat n vrful stivei, elementul cel mai nou din colecie. n
cazul cozii elementul accesibil va fi cel plasat n capul cozii, elementul cel mai
vechi din colecie. Se observ c structurile de date de tip stiv i coad trebuie s
aib un mecanism care s memoreze ordinea n care elementele sunt introduse n
structur. Aceast ordine nu mai poate fi modificat.
Stivele i cozile pot fi considerate cazuri particulare de liste. Ele sunt liste
specializate n privina accesului la elemente. Dac n cazul listelor orice element
poate deveni accesibil, prin modificarea poziiei curente, n cazul stivelor i cozilor
se impun restricii suplimentare. Poziia curent n list nu poate fi modificat
arbitrar i un singur element poate fi accesibil la un moment dat, conform
mecanismului de stiv, respectiv coad.
Dac o list implementeaz o structur de tip stiv, introducerea i extragerea
elementelor se va face la acelai capt al listei (fig. 2.24), n faa celorlalte
elemente din stiv.

Introducere/Extragere

e
1
e
2


e
i-1
e
i
e
i+1


e
n

nil

Fig. 2.16 List ce implementeaz o structur de tip stiv

n cazul n care lista implementeaz o structur de tip coad, introducerea i
extragerea elementelor din list se va face la capete diferite (fig. 2.25). Fiecare nou
element este introdus n spatele celorlalte elemente din coad, iar elementul care
se gsete n fa va fi primul extras.




Extragere Introducere

e
1
e
2


e
i-1
e
i
e
i+1


e
n

nil nil

Fig. 2.17 List ce implementeaz o structur de tip coad

Operaiile de baz n cazul stivelor i cozilor sunt:
- introducerea unui element n colecie;

157
- extragerea unui element din colecie.
Dac n cazul listelor extragerea i eliminarea unui element din colecie sunt
operaii distincte, n cazul stivelor i cozilor extragerea elementului accesibil la un
moment dat presupune, n mod normal, i eliminarea sa din colecie. Urmtorul
element va deveni element curent.
Alte operaii ce se pot defini pentru colecii de tip stiv sau coad sunt:
- iniializarea coleciei;
- testarea coleciei vide;
- extragerea elementului curent fr eliminarea lui din colecie.
Ca i coleciile de tip list, coleciile de tip stiv i coad pot fi implementate static
sau dinamic.
O generalizare a coleciilor de tip stiv i coad o reprezint colecia de tip coad
generalizat (sau stiv generalizat). O astfel de structur trebuie s permit
introducerea i extragerea de elemente de la oricare din cele dou capete.
Tipul de date Stiva
Stivele sunt colecii din care elementele pot fi eliminate doar n ordinea invers
introducerii lor. Stiva este o structur dinamic pentru c dimensiunea ei variaz
prin introducerea i eliminarea de elemente.
Stivele nu sunt adecvate prelucrrilor ce necesit traversarea coleciilor. Ele sunt
mult utilizate ca suport pentru funciile recursive, apelul imbricat al funciilor i
evaluarea expresiilor aritmetice n form postfixat.

Operaia de introducere a unui element n stiv se numete, de obicei, PUSH iar
operaia de extragere a unui element din stiv se numete, de obicei, POP.
Mecanismul de apel recursiv fiind des utilizat, n limbajele de asamblare aceste
operaii sunt implementate ca instruciuni cu acelai nume.
Unit-ul UStiva implementeaz TAD-ul Stiva static, printr-un tablou de pointeri.
Toate operaiile au fost implementate ca funcii ce returneaz o valoare boolean:
True, dac operaia s-a efectuat corect, i False, dac operaia nu a putut fi
executat.
Stiva este declarat ca o structur format din (fig. 2.26):
- Elemente - tablou de pointeri la elementele stivei;
- Varf - poziia pe care se va aduga urmtorul element.
Numrul maxim de elemente din stiv este MAX, dei numrul total de componente
al tabloului Elemente este MAX+1 (de la 0 la MAX). n implementarea realizat
prin unit-ul UStiva stiva este considerat plin atunci cnd Varf = MAX.



158

Varf

x x x x x x x

0 1 2 MAX

Fig. 2.18 Implementarea static a unei stive


{
Implementare statica (tablou de pointeri) a TAD-ului Stiva.
Indicator Varf (pozitia pe care se va adauga urmatorul element).
Stiva poate avea orice tip de elemente.
}
Unit UStiva;

I nterface

const MAX = 5;

type

{tip indice tablou}
tip_indice = 0..MAX;

{tip stiva}
PStiva = ^Stiva;
Stiva = record
Varf: Integer;
Elemente: Array[tip_indice] of pointer;
end;

{initializare stiva}
function CreazaStiva(var S: Stiva): Boolean;
{test stiva vida}
function EStivaVida(S: Stiva): Boolean;
{adaugarea unui element}
function I ntroduceI nStiva(var S: Stiva; E: Pointer): Boolean;
{extragerea unui element}
function ExtrageDinStiva(var S: Stiva; var E: Pointer): Boolean;
{returneaza pointer spre elementul accesibil, fara eliminarea lui}

159
function ValoareVarfStiva(S: Stiva; var E: Pointer): Boolean;

Implementation

function CreazaStiva(var S: Stiva): Boolean;
begin
S.Varf := 0;
CreazaStiva := True;
end;

function EStivaVida(S: Stiva): Boolean;
begin
EStivaVida := (S.Varf = 0);
end;

function I ntroduceI nStiva(var S: Stiva; E: Pointer): Boolean;
begin
with S do
begin
If Varf=MAX then IntroduceInStiva := False
else
begin
Elemente[Varf] := E;
Varf := Varf+1;
IntroduceInStiva := True;
end;
end;
end;

function ExtrageDinStiva(var S: Stiva; var E: Pointer): Boolean;
begin
with S do
begin
If EStivaVida(S) then ExtrageDinStiva := False
else
begin
E := Elemente[Varf-1];
Varf := Varf-1;
ExtrageDinStiva := True;
end;
end;
end;


160
function ValoareVarfStiva(S: Stiva; var E: Pointer): Boolean;
begin
with S do
begin
If EStivaVida(S) then ValoareVarfStiva := False
else
begin
E := Elemente[Varf-1];
ValoareVarfStiva := True;
end;
end;
end;

end.


Programul Turbo Pascal Test_stiva este un program de testare a unit-ului UStiva.


{Testare unit UStiva}

program Test_stiva;
uses UStiva, Crt;

type
{tipul elementelor listei}
PElement = ^Integer;

var
optiune: Integer;
S: Stiva;
E: pointer;
element: PElement;
i: Integer;

begin
clrscr;
CreazaStiva(S);
repeat
Writeln('1 - Testeaza stiva vida');
Writeln('2 - Da lungimea stivei');
Writeln('3 - Adauga');
Writeln('4 - Extrage');

161
Writeln('5 - Afiseaza elementul curent');
Writeln('6 - Afiseaza stiva');
Writeln('7 - Afiseaza pozitia varfului');
Writeln('8 - Termina executia programului');
Read(optiune);
if optiune in [3] then
begin
new(element);
Readln(element^);
E := element;
end;
case optiune of
1: if EStivaVida(S) then Writeln('Stiva e vida!') else Writeln('Stiva nu e
vida!');
2: writeln('Stiva are ', S.Varf, ' elemente.');
3: If IntroduceInStiva(S, E) then writeln('OK!') else writeln('Imposibil!');
4: if not ExtrageDinStiva(S, E) then writeln('Imposibil!')
else writeln(PElement(E)^);
5: if not ValoareVarfStiva(S, E) then writeln('Imposibil!')
else writeln(PElement(E)^);
6: for i:=0 to S.Varf-1 do
begin
E := S.Elemente[i];
writeln(PElement(E)^);
end;
7: writeln('Varful este pe pozitia ', S.Varf);
end;
until optiune = 8;
end.


Tipul de date Coada
Cozile sunt colecii din care elementele pot fi eliminate doar n ordinea introducerii
lor. Ca i stiva, coada este o structur dinamic, pentru c dimensiunea ei variaz
prin introducerea i eliminarea de elemente. Tot ca i stivele, cozile nu sunt
adecvate prelucrrilor ce necesit traversarea coleciilor.

Unit-ul UCoada implementeaz TAD-ul Coada static, printr-un tablou de
pointeri. Toate operaiile au fost implementate ca funcii ce returneaz o valoare

162
boolean: True, dac operaia s-a efectuat corect, i False, dac operaia nu a putut
fi executat.
Coada este declarat ca o structur format din (fig. 2.27):
- Elemente - tablou de pointeri la elementele cozii;
- Prim - poziia elementului vizibil, care va fi primul extras din coad;
- Ultim - poziia pe care se va aduga urmtorul element;
- Lungime - numrul elementelor din coad.
Indicatorul Ultim nu indic poziia ultimului element introdus n coad, ci poziia
pe care va fi introdus urmtorul element.





Prim Ultim

x x x x x

0 1 2 MAX

Fig. 2.19 Implementarea static a unei cozi

Numrul maxim de elemente din coad este MAX. Datorit mecanismului cozii,
prin adugarea elementelor la un capt si extragerea lor de la un alt capt, coada se
deplaseaz spre captul la care se face adugarea. Poziiile rmase libere la
captul de unde se extrag elemente nu mai pot fi utilizate. Pentru a preveni acest
lucru, ar fi necesar ca la fiecare extragere a unui element toate celelalte elemente
din coad s se deplaseze cu cte o poziie, astfel nct poziia rmas liber s fie
ocupat (fig. 2.28).



x x x x x

0 1 2 MAX

Fig. 2.20 Deplasarea elementelor unei cozi

O soluie mai elegant o reprezint transformarea tabloului n care se pstreaz
pointerii ntr-un tablou circular. Dup ocuparea tuturor poziiilor din tablou la

163
captul la care se face adugare, urmtoarea poziie disponibil devine prima
poziie de la captul opus al tabloului (fig. 2.29). Acest lucru se poate realiza dac
indicatorii Prim i Ultim ai cozii sunt actualizai modulo numrul de elemente al
vectorului ce conine elementele cozii.
La introducerea n coad a unui nou element se va face actualizarea:

Ultim := (Ultim+1) mod MAX; (2.1)

La extragerea unui element din coad se va face actualizarea:

Prim := (Prim+1) mod MAX; (2.2)



x x x x x x

0 1 2 MAX

Fig. 2.21 Implementarea unei cozi prin tablou circular

Dei numrul total de componente al tabloului Elemente este MAX+1, care ocup
poziiile 0 .. MAX, n implementarea realizat prin unit-ul UCoada numrul maxim
de elemente al cozii este MAX. Coada este considerat plin atunci cnd Lungime =
MAX.


{
Implementare statica (prin tablou de pointeri) a structurii Coada.
Indicatori Prim (pozitia elementului accesibil) si
Ultim (pozitia pe care se va adauga urmatorul element).
Coada poate avea orice tip de elemente.
}

Unit UCoada;

I nterface

const MAX = 10;

type

{tip indice tablou}

164
tip_indice = 0..MAX;

{tip coada}
PCoada = ^Coada;
Coada = record
Prim, Ultim, Lungime: Integer;
Elemente: Array[tip_indice] of pointer;
end;

{initializare coada}
function CreazaCoada(var C: Coada): Boolean;
{test coada vida}
function ECoadaVida(C: Coada): Boolean;
{adaugarea unui element in coada}
function I ntroduceI nCoada(var C: Coada; E: Pointer): Boolean;
{extragerea unui element din coada}
function ExtrageDinCoada(var C: Coada; var E: Pointer): Boolean;
{returneaza pointer spre elementului accesibil, fara eliminarea lui din
coada}
function ValoareVarfCoada(C: Coada; var E: Pointer): Boolean;

Implementation

function CreazaCoada(var C: Coada): Boolean;
begin
with C do
begin
Prim := 0;
Ultim := 0;
Lungime := 0;
CreazaCoada := True;
end;
end;

function ECoadaVida(C: Coada): Boolean;
begin
ECoadaVida := (C.Lungime=0);
end;

function I ntroduceI nCoada(var C: Coada; E: Pointer): Boolean;
begin
with C do
begin

165
If Lungime=MAX then IntroduceInCoada := False
else
begin
Elemente[Ultim] := E;
Ultim := (Ultim+1) mod MAX;
Lungime := Lungime+1;
IntroduceInCoada := True;
end;
end;
end;

function ExtrageDinCoada(var C: Coada; var E: Pointer): Boolean;
begin
with C do
begin
If ECoadaVida(C) then ExtrageDinCoada := False
else
begin
E := Elemente[Prim];
Prim := (Prim+1) mod MAX;
Lungime := Lungime-1;
ExtrageDinCoada := True;
end;
end;
end;

function ValoareVarfCoada(C: Coada; var E: Pointer): Boolean;
begin
with C do
begin
If ECoadaVida(C) then ValoareVarfCoada := False
else
begin
E := Elemente[Prim];
ValoareVarfCoada := True;
end;
end;
end;

end.



166
Programul Turbo Pascal Test_coada este un program ce poate fi utilizat pentru
testarea unit-ului UCoada.


{Testare unit UCoada}

program Test_coada;
uses UCoada, Crt;

type
{tipul elementelor listei}
PElement = ^Integer;

var
optiune: Integer;
C: Coada;
E: pointer;
element: PElement;
i: Integer;

begin
clrscr;
CreazaCoada(C);
repeat
Writeln('1 - Testeaza coada vida');
Writeln('2 - Da lungimea cozii');
Writeln('3 - Adauga');
Writeln('4 - Extrage');
Writeln('5 - Afiseaza elementul curent');
Writeln('6 - Afiseaza coada');
Writeln('7 - Afiseaza pozitiile curente');
Writeln('8 - Termina executia programului');
Read(optiune);
if optiune in [3] then
begin
new(element);
Readln(element^);
E := element;
end;
case optiune of
1: if ECoadaVida(C) then Writeln('Coada e vida!') else Writeln('Coada
nu e vida!');
2: writeln('Coada are ', C.Lungime, ' elemente');

167
3: If IntroduceInCoada(C, E) then writeln('OK!') else
writeln('Imposibil!');
4: if not ExtrageDinCoada(C, E) then writeln('Imposibil!')
else writeln(PElement(E)^);
5: if not ValoareVarfCoada(C, E) then writeln('Imposibil!')
else writeln(PElement(E)^);
6: for i:=0 to MAX do
begin
E := C.Elemente[i];
writeln(PElement(E)^);
end;
7: writeln('Prim: ', C.Prim, ' Ultim: ', C.Ultim);
end;
until optiune = 8;
end.


Arbori
n multe cazuri coleciile ntre elementele crora se stabilesc legturi liniare (unu-
la-unu) nu sunt adecvate pentru modelarea problemelor ce trebuie rezolvate cu
calculatorul. Obiectele poate fi descompuse n altele mai simple, procesul de
descompunere putndu-se realiza pe un numr finit de niveluri ierarhice. Orice
obiect este definit printr-un set de atribute i prin mulimea obiectelor componente.
Acest mod de descriere este recursiv, pentru c obiectele componente pot fi, la
rndul lor, descompuse. Se obine astfel o colecie de elemente organizate ierarhic,
arborescent, elemente ntre care se stabilesc legturi de tipul unu-la-mai-multe.
Organizarea ierarhic intervine n toate domeniile: organigrama unei societi
comerciale, structura directoarelor pe discul unui calculator, organizarea hardware-
ului unui calculator, nomenclatorul meseriilor recunoscute n Romnia, organizarea
unei universiti pe faculti, secii, ani de studiu etc.
Elementele unei structuri de tip arbore se numesc noduri sau vrfuri. Orice nod,
cu excepia rdcinii, are un nod predecesor unic (printe) cruia i este
subordonat. Orice nod poate avea mai multe noduri succesoare (fii) care i sunt
subordonate. Toate nodurile subordonate direct aceluiai nod sunt frai. Arborele
este format din mulimea nodurilor i legturile dintre acestea. Un nod al arborelui
poate fi (fig. 2.30):
- rdcin - nodul de pe primul nivel al arborelui, care nu are printe;
- nod intern - are att printe ct i fii;

168
- nod terminal (frunz) - nu are noduri subordonate.






Rdcin a

b c noduri
interne
d e f g


h i j k l m



frunze

Fig. 2.22 Structur arborescent

Rdcina unui arbore este situat pe nivelul 1. Dac un nod este situat pe nivelul i
al arborelui, descendenii si direci sunt situai pe nivelul i+1. Accesul de la
rdcina arborelui la un nod situat pe nivelul i necesit parcurgerea a i-1 arce i a i-
2 noduri intermediare. Lungimea cii (drumului) unui nod este dat de numrul
de ramificri de la rdcin pn la acel nod. Lungimea cii unui nod situat pe
nivelul i va fi i. Lungimea cilor interne ale unui arbore este dat de suma
lungimii cilor tuturor nodurilor interne ale arborelui. Lungimea cilor externe ale
unui arbore este dat de suma lungimii cilor tuturor nodurilor terminale ale
arborelui. nlimea (adncimea) unui arbore este dat de nivelul maxim al
nodurilor sale.
Ordinul sau gradul unui nod este dat de numrul descendenilor direci ai acelui
nod. Gradul maxim al unui arbore este dat de maximul gradelor nodurilor sale.
Nodurile terminale au gradul 0. O list reprezint, de fapt, un arbore degenerat, n
care toate nodurile au ordinul 1, cu excepia nodului terminal, care are gradul 0.
Un arbore este fie vid, fie format dintr-un nod rdcin care are ataai un numr
finit de arbori, numii subarbori ai arborelui iniial. Orice nod intern este rdcina
unui subarbore. Doi subarbori ai aceluiai arbore pot fi fie disjunci (nu au noduri
comune), fie unul este subarbore al celuilalt.

169
Gradul nodurilor unui arbore multici (arbore generalizat) nu este limitat. Un
arbore generalizat este compus dintr-un nod rdcin i un numr oarecare de
subarbori generalizai.
Numrul maxim posibil de noduri pe care le poate conine un arbore de grad d i
nlime h este:

( )

=
=
1
0
h-
i
i
d d,h N
(2.3)


n tabelul 2.1 sunt specificate nivelele i gradele nodurilor arborelui din fig. 2.30,
precum i nlimile fiecruia din subarborii si.
Dac un arbore are gradul maxim 2 i se pot ntotdeauna identifica subarborele
stng i drept al fiecrui nod, arborele este binar. Aadar un arbore binar este fie
vid, fie compus dintr-un nod rdcin i doi subarbori binari, stng i drept.
Pentru un arbore binar de nlime h numrul de noduri poate fi cuprins ntre:

( )
1
2 2
h-
,h N h s s
(2.4)

Numrul minim de noduri se obine pentru arborii degenerai de tip list, care au
cte un singur subarbore, stng sau drept.
nlimea unui arbore binar cu N noduri poate varia ntre:

N h N s s
2
log
(2.5)





Nod Nivel Grad nlime subarbore
a 1 2 4
b 2 3 3
c 2 1 3
d 3 3 2
e 3 1 2

170
Nod Nivel Grad nlime subarbore
f 3 0 1
g 3 2 2
h 4 0 1
i 4 0 1
j 4 0 1
k 4 0 1
l 4 0 1
m 4 0 1

Tab. 2.2 Caracteristicile arborelui din fig. 2.22


Orice arbore multici poate fi transformat n arbore binar echivalent, dac orice nod
este considerat direct legat la cel mult dou noduri: primul fiu (la stnga) i
urmtorul frate (la dreapta). Arborele din fig. 2.30 poate fi transformat n arborele
binar echivalent din fig. 2.31.
Un arbore este echilibrat dac diferena dintre nlimile subarborilor si este cel
mult 1. Arborii binari echilibrai se mai numesc i arbori AVL (Adelson-Velsky i
Landis). Arborii ordonai sunt arbori pentru care ramificrile n fiecare nod sunt
ordonate, dup valorile unei chei, reprezentat de un cmp din informaia util a
nodurilor.


a

b

d c

h e g

i k f l


171
j m


Fig. 2.23 Arborele binar echivalent arborelui din fig. 2.22

Traversarea arborilor
Traversarea unui arbore presupune vizitarea (inspectarea) tuturor nodurilor sale, o
singur dat, ntr-o anumit ordine, cu scopul efecturii unor operaii asupra
informaiei utile din noduri. Ordinea vizitrii, pentru un nod oarecare, stabilete
succesiunea n care vor fi parcurse acel nod i nodurile subarborilor pentru care
nodul este rdcin. Ordinea de parcurgere a nodurilor este, de obicei, impus de
specificul aplicaiei (prelucrarea realizat asupra informaiei utile din noduri).
n toate cazurile, ordinea relativ de prelucrare a nodurilor terminale este, prin
convenie, de la stnga la dreapta. Exist dou moduri de parcurgere a nodurilor
unui arbore:
- n lime (lrgime) - vizitarea nodurilor se face pe nivele ierarhice;
- n adncime - ordinea de vizitare a nodurilor reflect relaiile de
subordonare ntre acestea.
n cazul arborelui din fig. 2.30, traversarea n lime presupune vizitarea nodurilor
n ordinea a, b, c, d, e, f, g, h, i, j, k, l, m. Pentru implementarea traversrii n lime
se poate utiliza o structur de tip coad, iniializat cu nodul rdcin. Ct timp
coada nu devine vid, se repet urmtoarele operaii:
- se extrage i se prelucreaz nodul curent din coad;
- fii si sunt adugai n coad.
Utiliznd operaiile tipului abstract de date Coada, algoritmul de traversare a unui
arbore n lime poate fi descris astfel:

ALGORITMUL TraversarenLime ESTE:
CreazCoad(C);
IntroducenCoad(C, Rdcina);
CTTIMP not ECoadaVid(C) EXECUT
ExtrageDinCoad(C, Nod);
Prelucreaz(Nod);
CTTIMP (Nod are fii) EXECUT
IntroducenCoad(C, Fiu);
SFCTTIMP
SFCTTIMP
SFALGORITM

172

n cazul traversrii n adncime sunt posibile dou alternative, n funcie de
ordinea de prelucrare a nodului rdcin i a subarborilor:
- n preordine - nodul rdcin este prelucrat naintea subarborilor;
- n postordine - nodul rdcin este prelucrat dup prelucrarea
subarborilor.
n cazul arborelui din fig. 2.30, la traversarea n preordine nodurile vor fi vizitate n
ordinea a, b, d, h, i, j, e, k, f, c, g, l, m. La traversarea n postordine ordinea de
vizitarea a nodurilor va fi h, i, j, d, k, e, f, b, l, m, g, c, a. Se poate observa c la
traversarea n preordine ierarhia este parcurs descendent, iar la traversarea n
postordine ierarhia este parcurs ascendent.
n cazul arborilor binari traversarea n adncime se poate face n trei moduri:
- n preordine - rdcin, subarbore stng, subarbore drept (RSD);
- n inordine - subarbore stng, rdcin, subarbore drept (SRD);
- n postordine - subarbore stng, subarbore drept, rdcin (SDR).
n cazul arborilor generalizai traversarea n inordine nu poate fi definit, pentru c
momentul prelucrrii rdcinii este incert.
Algoritmii de traversare n adncime a unui arbore binar pot fi definii recursiv:

SUBALGORITMUL Traversare nPreordine (Arbore) ESTE:
* Prelucrare Rdcin.
CHEAM TraversarenPreordine(SubarboreStng);
CHEAM TraversarenPreordine(SubarboreDrept);
SFSUBALGORITM

SUBALGORITMUL Traversare nI nordine (Arbore) ESTE:
CHEAM TraversarenInordine(SubarboreStng);
* Prelucrare Rdcin.
CHEAM TraversarenInordine(SubarboreDrept);
SFSUBALGORITM

SUBALGORITMUL Traversare nPostordine (Arbore) ESTE:
CHEAM TraversarenPostordine(SubarboreStng);
CHEAM TraversarenPostordine(SubarboreDrept);
* Prelucrare Rdcin.
SFSUBALGORITM


173
Tipul de date ArboreBinar
n continuare este prezentat o structur de tip arbore binar. Operaiile
fundamentale specificate sunt operaii ce modific arborele, operaii ce furnizeaz
informaii despre arbore, i operaii de parcurgere a arborelui.
Operaiile ce modific arborele sunt:
- IniializeazArbore - construiete arborele vid;
- CreazArbore - construiete un arbore pe baza elementelor caracteristice
date (informaie util rdcin, subarbore stng, subarbore drept);
- ModificInfRdcin, ModificStng, ModificDrept - modific
elementele caracteristice ale arborelui (respectiv informaia util din
rdcin, subarborele stng, subarborele drept);
- DistrugeRdcin - elimin din memorie rdcina arborelui.
S-au specificat urmtoarele operaii ce furnizeaz informaii despre arbore:
- EArboreVid - testeaz dac arborele este vid;
- DInfRdcin, DStng, DDrept - furnizeaz adresele elementelor
arborelui (informaie util rdcin, subarbore stng, subarbore drept),
preluate din rdcina arborelui;
- nlime - d nlimea arborelui;
- NumrNoduri - d numrul de noduri ale arborelui.
S-au specificat cele trei operaii posibile la parcurgerea arborelui n adncime:
- nPreordine - traversare n preordine;
- nInordine - traversare n inordine;
- nPostordine - traversare n postordine.




Adugarea sau eliminarea de noduri se poate realiza utilizndu-se operaiile
specificate.
Unit-ul UArbBin implementeaz structura ArboreBinar. Prelucrarea ce se aplic
informaiei din noduri este generic, specificat prin variabila Prel, de tip
procedure. Ea este precizat la nivelul aplicaiei.


{
Implementare a TAD-ului ArboreBinar.
Arborele poate avea orice tip de elemente.

174
}

Unit UArbBin;

I nterface

type
{tip arbore}
arbore = ^nod;
nod = record
Element: pointer;
Stang, Drept: arbore;
end;
{tip prelucrare}
Prelucrare = procedure(p: pointer);

{Construieste arborele vid}
function I nitializeazaArbore(var R: arbore): Boolean;
{Construieste un arbore}
function CreazaArbore(E: pointer; S, D: pointer; var R: arbore): Boolean;
{testeaza arborele vid}
function EArboreVid(R: arbore): Boolean;
{da adresa informatiei utile din radacina}
function DaI nfRadacina(R: arbore; var E: pointer): Boolean;
{da adresa arborelui stang}
function DaStang(R: arbore; var S: arbore): Boolean;
{da adresa arborelui drept}
function DaDrept(R: arbore; var D: arbore): Boolean;
{modifica informatia utila din radacina}
function ModificaI nfRadacina(R: arbore; E: pointer): Boolean;
{modifica arborele stang}
function ModificaStang(R: arbore; S: arbore): Boolean;
{modifica arborele drept}
function ModificaDrept(R: arbore; D: arbore): Boolean;
{elimina radacina}
function DistrugeRadacina(var R, S, D: arbore; var E: pointer): Boolean;
{da inaltimea arborelui}
function I naltime(A: arbore): integer;
{da numarul nodurilor}
function NumarNoduri(A: arbore): integer;
{parcurge in preordine}
procedure I nPreordine(A: arbore; Prel: Prelucrare);
{parcurge in inordine}

175
procedure I nI nordine(A: arbore; Prel: Prelucrare);
{parcurge in postordine}
procedure I nPostordine(A: arbore; Prel: Prelucrare);

Implementation

function I nitializeazaArbore(var R: arbore): Boolean;
begin
R := nil;
InitializeazaArbore := True;
end;

function CreazaArbore(E: pointer; S, D: pointer; var R: arbore): Boolean;
begin
if MaxAvail < SizeOf(nod) then
CreazaArbore := False
else
begin
new(R);
with R^ do
begin
Element := E;
Stang := S;
Drept := D;
end;
CreazaArbore := True;
end;
end;

function EArboreVid(R: arbore): Boolean;
begin
EArboreVid := (R=nil);
end;

function DaI nfRadacina(R: arbore; var E: pointer): Boolean;
begin
if R<>nil then E := R^.Element
else E := nil;
DaInfRadacina := (E<>nil);
end;

function DaStang(R: arbore; var S: arbore): Boolean;
begin

176
if R<>nil then S := R^.Stang
else S := nil;
DaStang := (S<>nil);
end;

function DaDrept(R: arbore; var D: arbore): Boolean;
begin
if R<>nil then D := R^.Drept
else D := nil;
DaDrept := (D<>nil);
end;

function ModificaI nfRadacina(R: arbore; E: pointer): Boolean;
begin
if R<>nil then R^.Element := E;
ModificaInfRadacina := (R<>nil);
end;

function ModificaStang(R: arbore; S: arbore): Boolean;
begin
if R<>nil then R^.Stang := S;
ModificaStang := (R<>nil);
end;

function ModificaDrept(R: arbore; D: arbore): Boolean;
begin
if R<>nil then R^.Drept := D;
ModificaDrept := (R<>nil);
end;

function DistrugeRadacina(var R, S, D: arbore; var E: pointer): Boolean;
begin
if R=nil then DistrugeRadacina := False
else
begin
with R^ do
begin
S := Stang;
D := Drept;
E := Element;
end;
dispose(R);
DistrugeRadacina := True;

177
end;
end;

function I naltime(A: arbore): integer;
var
IStang, IDrept :Integer;
begin
if EArboreVid(A) then Inaltime := 0
else
begin
IStang := Inaltime(A^.Stang);
IDrept := Inaltime(A^.Drept);
if IStang>IDrept then
Inaltime := IStang+1
else
Inaltime := IDrept+1
end;
end;

function NumarNoduri(A: arbore): integer;
begin
if EArboreVid(A) then NumarNoduri := 0
else
NumarNoduri := 1+NumarNoduri(A^.Stang)+NumarNoduri(A^.Drept);
end;

procedure I nPreordine(A: arbore; Prel: Prelucrare);
var
E: pointer;
arb: arbore;
begin
if DaInfRadacina(A,E) then Prel(E);
if DaStang(A, arb) then InPreordine(arb, Prel);
if DaDrept(A, arb) then InPreordine(arb, Prel);
end;

procedure I nI nordine(A: arbore; Prel: Prelucrare);
var
E: pointer;
arb: arbore;
begin
if DaStang(A, arb) then InInordine(arb, Prel);
if DaInfRadacina(A,E) then Prel(E);

178
if DaDrept(A, arb) then InInordine(arb, Prel);
end;

procedure I nPostordine(A: arbore; Prel: Prelucrare);
var
E: pointer;
arb: arbore;
begin
if DaStang(A, arb) then InPostordine(arb, Prel);
if DaDrept(A, arb) then InPostordine(arb, Prel);
if DaInfRadacina(A,E) then Prel(E);
end;

end.


Un exemplu de utilizare a unit-ului UArbBin l constituie programul ArbBin.
Programul construiete un arbore binar total echilibrat de nlime 3. Informaia
util din noduri reprezint pointeri la ntregi. n fiecare nod se reine numrul de
ordine al nodului. Dup construirea arborelui, se afieaz nlimea sa i numrul
de noduri pe care le conine. Arborele este apoi traversat n trei moduri (preordine,
inordine, postordine), prelucrarea ce se efectueaz n fiecare caz fiind afiarea
informaiei utile din nodurile parcurse (procedura Tiparire).
Utilizarea directivei de compilare {$F+} este obligatorie atunci cnd se utilizeaz
variabile de tip procedure sau function. Compilatorul este astfel forat s utilizeze
modelul de apel FAR.


{Testare unit UArbBin}

program ArbBin;
{compilatorul foloseste modelul de apel FAR}
{$F+}

uses UArbBin, Crt;

type
PElement = ^Integer;

var
Element: PElement;
arb, nou, radacina: arbore;


179
procedure Tiparire(E: pointer);
begin
write(PElement(E)^:4);
end;

begin
clrscr;
InitializeazaArbore(Radacina);

{construire arbore}
New(Element);
Element^ := 1;
CreazaArbore(Element, nil, nil, Radacina);

New(Element);
Element^ := 2;
CreazaArbore(Element, nil, nil, nou);
ModificaStang(Radacina, nou);

New(Element);
Element^ := 3;
CreazaArbore(Element, nil, nil, nou);
ModificaDrept(Radacina, nou);

New(Element);
Element^ := 4;
CreazaArbore(Element, nil, nil, nou);
DaStang(Radacina, arb);
ModificaStang(arb, nou);

New(Element);
Element^ := 5;
CreazaArbore(Element, nil, nil, nou);
DaStang(Radacina, arb);
ModificaDrept(arb, nou);

New(Element);
Element^ := 6;
CreazaArbore(Element, nil, nil, nou);
DaDrept(Radacina, arb);
ModificaStang(arb, nou);

New(Element);

180
Element^ := 7;
CreazaArbore(Element, nil, nil, nou);
DaDrept(Radacina, arb);
ModificaDrept(arb, nou);

{informatii despre arbore}
Writeln('Inaltime: ', Inaltime(Radacina));
Writeln('NumarNoduri: ', NumarNoduri(Radacina));
{parcurgeri arbore}
Writeln('Preordine');
InPreordine(Radacina, Tiparire);
Writeln;
Writeln('Inordine');
InInordine(Radacina, Tiparire);
Writeln;
Writeln('Postordine');
InPostordine(Radacina, Tiparire);
readln;

end.















181

S-ar putea să vă placă și