Sunteți pe pagina 1din 13

91

12. Tipuri abstracte de dat n Pascal (Unit ).


12.1. Tip abstract de dat.
Prin tip dc datc sc n clcgc o mul imc dc valori, D, care formeaz
domeniul tipului, mpreun cu o mul imc dc opcratori pc accst domcniu. n cazul
cnd elementele domeniului sunt valori compuse din mai multe componente
atomicc, tipul dc datc ob inut sc numctc tip dc datc structurat, sau structur de
date.
Un programator poate s-i dcIincasc propriile tipuri de date de care are
nevoie n programul su. Opcra iilc cxistcntc n accstc noi tipuri dc datc sunt n
primul rnd cele existente asupra componentelor. n structura definit de
programator, ca entitate de sine stttoare exist ns doar operatorul de atribuire.
Adcsca programatorul arc ncvoic dc opcra ii propriu-zisc.
Tipul abstract de date (prescurtat TAD) este un astfel de tip, definit de
om n urma unui proces de abstractizare. El este precizat prin:
- domeniul TAD;
- opcratorii dcIini i n accst domcniu.
Nu intereseaz cum se reprezint clcmcntclc domcniului n calculator i nici cum
se execut opcratorii asupra diIcri ilor opcranzi posibili.
Pentru a specifica un TAD este necesar s precizm cele dou elemente
alc tipului: domcniul i opcra iilc.
Domcniul cstc prccizat ca o mul imc matcmatic, D.
Pentru a spcciIica o opcra ic o este necesar s dcIinim matcmatic opcra ia
o. n gcncral, sprc dcoscbirc dc opcra ia matcmatic, n programarc opcra ia o nu
cstc o aplica ic total; ea are sens numai pentru anumite elemente din D. Valorile
pcntru carc opcra ia o are sens satisfac un predicat numit prccondi ic pcntru
92
opcra ia o. Rezultatul efecturii opcra ici o depinde de operanzi, este legat de
accti opcranzi, lcgtur precizat cu ajutorul unci postcondi ii, dat printr-un
predicat .
Exemplul 3.1.1. S specificm un TAD "numUUD LRQDO".
Domeniul acestui TAD const din mul imca numcrclor ra ionalc, notat
prin Q:
Q = {(m,n) mZ, nN
+
, m,n prime ntre ele}.
n aceast mul imc vom spcciIica urmtoarclc opcra ii:
Opcra ia "Adun(q1,q2,q)": { q := q1 + q2 }
Prccondi ia: q1, q2 Q ;
Postcondi ia: q q1 q2 .
Opcra ia "Scad(q1,q2,q)": { q := q1 - q2 }
Prccondi ia: q1, q2 Q ;
Postcondi ia: q q1 - q2 .
Opcra ia "Inmult(q1,q2,q)": { q := q1 * q2 }
Prccondi ia: q1, q2 Q ;
Postcondi ia: q q1*q2.
Opcra ia "Divid(q1,q2,q)": { q := q1 : q2 }
Prccondi ia: q1, q2 Q i q20;
Postcondi ia: q q1/q2.
93
Opcra ia "Atribc(sus,jos,q)"; { q:= sus/jos}
Prccondi ia: sus Z, jos N i jos0;
Postcondi ia: q sus/jos.
Opcra ia "Citcstc(q)"; {q:= numr ra ional citit}
Prccondi ia: dc la tastatur se introduce un numr ra ional ca pcrcchc
(numrtor, numitor).
Postcondi ia: q numrul ra ional citit.
Opcra ia "Tiparcstc(q)"; Sc aIicaz numrul q}
Prccondi ia: q Q
Postcondi ia: sc aIicaz pe ecran numrul q
Rcla ia "Estczcro(q)"; { Este q egal cu zero ?}
Prccondi ia: q Q
Postcondi ia: Dac q=0 atunci Estezero=TRUE
altfel Estezero=FALSE
sfdac.
Rcla ia "Egal(q1,q2)"; { Este q1 egal cu q2 ?}
Prccondi ia: q1, q2 Q
Postcondi ia: Dac q1=q2 atunci Egal=TRUE
altfel Egal=FALSE
sfdac.
Rcla ia "Maimarc(q1,q2)"; { Este q1 mai mare dect q2 ?}
Prccondi ia: q1, q2 Q
Postcondi ia: Dac q1>q2 atunci Maimare=TRUE
altfel Maimare=FALSE
sfdac.
94
Func ia "Intrcg(q)"; { Partea ntreag a lui q}
Prccondi ia: q Q
Postcondi ia: Intrcg partca ntrcag a lui q.
Un tip abstract de date trebuie s con in suIicicntc opcra ii pcntru a Ii util.
El trebuie s permit crearea oricrei valori din domeniul tipului. Trebuie s
cxistc suIicicntc opcra ii dc tcstarc pcntru a putca Ii vcriIicatc toatc prccondi iilc
opcra iilor. Trcbuic conccputc suIicicntc opcra ii pcntru ca programatorul s aib
acces la oricare din componentele din care e compus acest tip abstract de date.
Dcci tipurilc dc opcra ii pc carc lc con inc un TAD sunt:
- opcra ii dc intrarc-icirc;
- opcra ii dc construirc dc valori din domcniul tipului;
- opcra ii dc convcrsic (a unor valori din altc tipuri dc datc) n valori dc accst
tip;
- opcra ii dc tcstarc a unor condi ii;
- opcra ii dc sclcctarc a unor componcntc din carc c construit accst tip dc datc.
n cazul TAD "numr ra ional" dcIinit mai sus, opcra iilc dc intrarc-icirc
sunt "Citeste" i "Tipareste", opcra ia "Atribc" cstc constructor, opcra ia "Intreg"
este o conversie, "Estezero", "Egal" i "Maimare" sunt opcra ii dc tcstarc, iar
"Adun", "Scad", "Inmult" i "Divid" sunt opcra iilc aritmcticc cunoscutc.
Printrc avantajclc Iolosirii tipurilor abstractc dc datc mcn ionm
specificarea exact, indcpcndcn a implcmcntrii, ascundcrca inIorma ici,
simplitatc i intcgritatc. Prin abstractizarc nc putcm conccntra asupra
propriet ilor cscn ialc i nu asupra rcprczcntrii i implcmcntrii; accentul cade
asupra specificrii tipului abstract de date. Utilizatorul se va folosi doar de
aceast spcciIicarc, cl nu vcdc rcprczcntarca i nici modul dc implcmcntarc a
opcra iilor. Tipurilc abstractc dc datc constituic unul din mijloacclc carc pcrmit o
abordare sistematic i prin a cror utilizare se ajunge la realizarea unor module
95
corcctc i rcIolosibilc. Mai mult, accstc modulc sc pot organiza n bibliotcci utilc,
ducnd la crctcrca productivit ii n programarc.
12.2. Uniti de program n Pascal.
Prin unitate de program (Unit) Pascal nelegem o grupare de declaraii
(constante, tipuri, variabile i subprograme) i eventual o seciune de iniializare.
Un unit este compus dintr-o parte de interfa (Interface) i una de
implementare (Implementation). Interfaa const din acele elemente ale unitii
care sunt disponibile n exterior. Partea de implementare nu este accesibil n
afara unitii i ea const din constante, tipuri de date, variabile, funcii, proceduri
i instructiuni (toate acestea fiind locale) care sunt referite n funciile i
procedurile descrise n interfa. Ea este invizibil din alte uniti de program.
Forma general a unei uniti este urmtoarea :
Unit <Nume_Unitate>;
Interface
<List _declara ii_globale>
Implementation
<List _declara ii_locale>
[ Begin {opional}
<Secven _de_ini ializare> ]
End.
n lista de declaraii care urmeaz dup Interface, se definesc constante,
tipuri de dat, variabile, funcii i proceduri, accesibile altor uniti care folosesc
aceast unitate de program. n aceste unitti, elementele declarate n seciunea
Interface devin globale, putnd fi folosite ca orice variabile globale dintr-un
program Pascal, spre deosebire de elementele declarate n seciunea
Implementation. Acestea din urma ramn locale i nu sunt accesibile n afara
96
unitii n care sunt declarate. Secven a de ini ializare conine instruciuni care
vor fi executate implicit naintea programului principal n scopul unor iniializri.
Un program sau o unitate de program care dorete s foloseasc un Unit
trebuie s precizeze acest lucru printr-o declaraie Uses
<List _unit i_utilizate>.
Pe lng unitile de program pe care i le scrie utilizatorul, acesta mai
poate folosi cteva uniti standard oferite de mediul Turbo Pascal. Menionm
urmtoarele uniti:
System - conine proceduri i funcii de baz, predefinite, din Turbo Pascal;
Crt - conine constante, funcii, proceduri, etc. de lucru cu ecranul i
tastatura;
Graph - conine constante, variabile, tipuri de dat, funcii i proceduri
grafice;
Dos - conine subprograme de lucru cu fiiere.
System este inclus automat n orice program, fr a mai fi necesar clauza
Uses.
Primul exemplu prezentat n continuare apeleaz Unitul Rational pentru
calculul unei expresii. Aici se poate vedea ct de simpl este realizarea unui
astfel de program avnd la dispoziie acest tip. n acest exemplul s-a reuit ca
operaiile de intrare-ieire s fie cele obinuite ( Read / Write ).
Program Numere__Rationale; { x+y y+z z+x }
Uses Rational; { E = ----- * ----- * ----- }
Var x,y,z : Rationale; { x-y y-z z-x }
Begin { x,y,z e Q (de forma p/q, q<>0) }
Write ( x : ); Readln (x);
Write ( y : ); Readln (y);
Write ( z : ); Readln (z);
Writeln ( E = , ProdQ( ProdQ ( ImpcQ(AdunQ(x,y),ScadQ(x,y) ),
ImpcQ(AdunQ(y,z),ScadQ(y,z)) ),
ImpcQ (AdunQ(z,x),ScadQ(z,x))));
Readln
97
End.
Implementarea acestui tip este descris n continuare. Se poate observa
c s-a reuit ca operaiile de intrare - ieire s fie cele standard i de asemenea
operaiile aritmetice s fie funcii (nu proceduri) reprezentnd datele prin siruri
de caractere (String). Tipul Q, care este de fapt perechea (numrtor, numitor)
este ascuns utilizatorului, iar conversiile necesare de asemenea (TransfQ/R).
Operaiile fiind cele elementare, binecunoscute din matematic, considerm c
unitatea de program care urmeaz se poate nelege uor, fr alte explicaii.
Unit Rational;
Interface
Type Rationale = String [20];
Func ion AdunQ ( a,b : Rationale) : Rationale;
Func ion ScadQ ( a,b : Rationale) : Rationale;
Func ion ProdQ ( a,b : Rationale) : Rationale;
Func ion ImpcQ ( a,b : Rationale) : Rationale;
Func ion InversQ ( a : Rationale) : Rationale;
Implementation
Type Q = Record
Numarator,
Numitor : Integer
End;
Func ion Cmmdc (a,b:Integer) : Integer; { Alg. Euclid recursiv }
Begin
If b=0 Then Cmmdc := a
Else Cmmdc := Cmmdc (b, a Mod b)
End;
Func ion Cmmmc (a,b:Integer) : Integer;
Begin
98
Cmmmc := a*b Div Cmmdc (a,b)
End;
Procedure Simplific ( Var x : Q);
Var p:Integer;
Begin
With x Do Begin
p:=Cmmdc(Numarator,Numitor);
If p>1 Then Begin
Numarator:=Numarator Div p;
Numitor :=Numitor Div p
End;
If Numitor<0 Then Begin
Numarator:= - Numarator;
Numitor := - Numitor
End
End
End;
Procedure TransfQ ( s:Rationale; Var x : Q ); { String Q }
Var p,q:Integer;
Begin
With x Do Begin { s de forma numarator/numitor , de ex. 3/2 }
Val (s,Numarator,p); { p = poz. car / }
Val (Copy(s,1,p-1),Numarator,q);
Val (Copy(s,p+1,Length(s)-p),Numitor,q);
If Numitor=0 Then Begin
Write ('<',s,'>',' Numitor=0'); Readln
End;
Simplific (x)
End
End;
Func ion TransfR ( x : Q ) : Rationale; { Q String }
Var m, n : String;
Begin
99
With x Do Begin Str (Numarator, m); Str (Numitor, n) End;
TransfR:=m+/+n
End;
Procedure TipQ ( x : Q ); { Tipareste (q) }
Begin
With x Do Write (Numarator,/,Numitor);
End;
Func ion AdunQ ( a,b : Rationale) : Rationale; { a+b }
Var x,y, z : Q;
Begin TransfQ(a,x); TransfQ(b,y); {z:=x+y}
With z Do Begin
Numitor := Cmmmc (x.Numitor,y.Numitor);
Numarator := x.Numarator * (Numitor Div x.Numitor)+
y.Numarator * (Numitor Div y.Numitor)
End;
Simplific(z); AdunQ:=TransfR(z)
End;
Func ion ScadQ ( a,b : Rationale ) : Rationale; { a-b }
Var y:Q;
Begin
TransfQ(b,y);
With y Do Numarator := -Numarator; { a+(-b)}
b:=TransfR(y);
ScadQ:=AdunQ (a,b)
End;
Func ion ProdQ ( a,b : Rationale) : Rationale; { a*b }
Var x,y, z:Q;
Begin
TransfQ(a,x); TransfQ(b,y); { z:= x*y }
With z Do Begin
Numarator := x.Numarator * y.Numarator;
Numitor := x.Numitor * y.Numitor
100
End;
Simplific (z);
ProdQ:=TransfR(z)
End;
Func ion InversabQ ( a : Rationale ) : Boolean; {Numarator <> 0}
Var x:Q;
Begin
TransfQ(a,x);
InversabQ:=x.Numarator<>0;
End;
Func ion InversQ ( a : Rationale ) : Rationale; { m/n n/m }
Var x : Q; n : Integer;
Begin
TransfQ (a,x);
With x Do Begin
If InversabQ(a) Then Begin
n := Numarator;
Numarator:= Numitor;
Numitor := n
End;
End;
InversQ:=TransfR(x)
End;
Func ion ImpcQ ( a,b : Rationale) : Rationale; { a / b = a * 1/b}
Begin
If InversabQ (b)
Then ImpcQ:=ProdQ (a,InversQ(b))
Else Write ( Operatie ilegala (:0) )
End;
{ Nu are secventa de initializare }
End.
101
Al doilea exemplu prezntat n cele ce urmeaz se refer la TAD num r
natural n precizie mrit. Avnd aceast aritmetic la dispoziie se poate uor
extinde pentru numere ntregi prin adugarea semnului (+ sau ), iar apoi
operaiile se reduc la operaii cu numere naturale (lund n considerare i
semnul numerelor pentru care se efectueaz operaia).
Programul Pascal care utilizeaz numere naturale n precizie marit,
calculeaza C.m.m.d.c. (a,b) , apelnd operaia de comparare (<) i diferena a
dou numere:
Program Cmmdc_Natural_Marit;
Uses Prec_Mar;
Var a, b : Natural;
Begin
Write ( Dati a : ); Readln (a);
Write ( Dati b : ); Readln (b); { Date a,b }
While a<>b Do { Cat_Timp a <> b Executa }
If MaiMic (a,b) Then b:=Dif(b,a) { Daca a<b Atunci b:=b-a }
Else a:=Dif(a,b); { Altfel a:=a-b }
Write ( Cmmdc = ,a); { Sf_Cat_Timp; }
Readln { Rezultate a }
End.
Unit-ul apelat de acest program este descris n continuare. Acesta
implementeaz operaii corespunztoare pentru : + , , < , >. Citire, Tip rire,
Egalitate i Neegalitate nu au fost implementate pentru c se pot utiliza cele
standard (Read, Write, = i <>).
102
Unit Prec_Mar; { Numar Natural Precizie Marit }
Interface
Const Dm = 10;
Type Natural = String[Dm];
Func ion Suma (a,b:Natural) : Natural;
Func ion Dif (a,b:Natural) : Natural;
Func ion MaiMic (a,b:Natural) : Boolean;
Func ion MaiMare (a,b:Natural) : Boolean;
Implementation
Func ion Tr (a,b:Char; Var t:Byte; Var c:Char):Byte; { a+b+t c i Tr }
Const C0=Ord(0); Var s : Byte;
Begin Tr:=0;
s:= Ord(a)+Ord(b)-2*C0+t;
If s>9 Then Begin Tr:=1; s:=s-10 End;
c:= Chr(s+C0);
End;
Func ion Adun (a,b:Natural; t:Byte) : Natural; { a+b }
Var n : Byte; Uc : Char; { Uc = Ultima Cifra }
Begin
n:=Length(a); { numarul de cifre }
If a= Then If t=0 Then Adun:=
Else Adun:=1
Else Adun:=Adun(Copy(a,1,n-1),Copy(b,1,n-1),Tr(a[n],b[n],t,Uc))+Uc
End;
Func ion Suma; { Suma a doua numere naturale a,b }
Begin
If a[0]<b[0] Then Suma:=Suma(b,a) Else
If a[0]>b[0] Then Suma:=Suma(a,0+b) Else Suma:=Adun(a,b,0)
End;
Func ion Trs(a,b:Char; Var t:Byte; Var c:Char):Byte; {Tr. la scadere}
Const C0=Ord(0); Var s : Integer;
103
Begin Trs:=0;
s:= Ord(a)-Ord(b)-t;
If s<0 Then Begin Trs:=1; s:=s+10 End;
c:= Chr(s+C0);
End;
Func ion Scad (a,b:Natural; t:Byte) : Natural; { Scade : a-b-t }
Var n : Byte; Uc : Char;
Begin
n:=Length(a);
If a= Then Scad:=
Else Scad:=Scad(Copy(a,1,n-1),Copy(b,1,n-1),Trs(a[n],b[n],t,Uc))+Uc
End;
Func ion Dif;
Var d:Natural;
Begin
If MaiMic(a,b) Then Begin Dif:=0; Write (a,-,b, < 0 ); Readln End
Else If a[0]>b[0] Then Dif:=Dif (a,0+b)
Else Begin
d:=Scad(a,b,0); { d:=a-b-0}
While (Length(d)>1) And (d[1]=0) Do Delete(d,1,1); { Sterge 0 }
Dif:=d End
End;
Func ion MaiMic;
Begin MaiMic:=(a[0]<b[0]) Or ((a[0]=b[0]) And (a<b)) End;
Func ion MaiMare;
Begin MaiMare:=MaiMic(b,a) End;
End.
Propunem ca teme implementri pentru TAD Num r_Intreg, Complex i
Polinom.