Sunteți pe pagina 1din 17

7.

Tipuri de date structurate în Pascal: tablou (Array ),


mul•ime (Set ), •ir_caractere (String), înregistrare (Record )

În aceast• lec•ie se prezint• câteva modalit••i de reprezentare a datelor,


utilizând tipuri de date (caracterizate prin mul•imea valorilor sau domeniul tipului
respectiv •i mul•imea opera•iilor caracteristice acelui tip) structurate (date ale
c•ror elemente componente sunt grupate).

7.1. Tipul tablou (Array ).

Structura tablou const• într-o succesiune (•ir) de elemente (aflate într-o


anumit• ordine) având toate acela•i tip (tipul_elementelor). Elementele pot fi
identificate prin indici, ace•tia fiind dintr-un subdomeniu al unui tip ordinal sau
chiar un tip ordinal. Aceasta înseamn• c• în definirea unui tablou va trebui s•
preciz•m atât domeniul_indicilor (tipul de indexare) cât •i tipul_elementelor
componente. Sintaxa specificarii în limbajul Pascal a unei structuri tablou este :

<tablou> ::= Array ‘[‘ <domeniul_indicilor> ‘]’ Of <tipul_elementelor>;

Exemple :
Type Sir_intregi = Array [1..9] Of Integer; { tipul sir de maxim 9 intregi }
Var Matrice : Array [1..25] Of Sir_intregi;{ tipul elementelor poate fi array }

Un element al tabloului se refer• prin scrierea numelui tabloului urmat de


indicele elementului scris între paranteze drepte ( nume_tablou[indice] ).
Elementele unui tablou pot fi la rândul lor tablouri. Astfel, elementele
unui tablou de tipul :
Array [1..6] Of Array [1..7] Of Real ;
sunt vectori având 7 elemente reale. Dac• T este un tablou de acest tip atunci T
are 6 componente, fiecare component• fiind un vector cu 7 elemente. De fapt
este vorba de o matrice cu 6 linii •i 7 coloane.

49
Componenta T[i] a acestui tablou va fi un vector cu 7 elemente reale.
Selectarea elementului cu indicele j al tabloului T[i] poate fi ob•inut• scriind
T[i][j]. Mention•m c• se accept• o prescurtare a declara•iei de mai sus sub forma
:
T : Array [1..10, 1..6] Of Real ;

iar elementele matricei, Tij vor fi referite prin T[ i , j ].

Ca exemplu, am ales un program care tip•re•te calendarul pe anii r•ma•i


din secolul nostru. Pentru aceasta, se va construi pentru fiecare lun• (din anul
pentru care se dore•te calendarul) un tablou cu s•pt•mânile lunii respective (cel
mult 6). O s•pt•mân• con•ine pentru fiecare zi începand de luni pân• duminic•,
ziua din luna corespunz•toare. De exemplu, dac• în anul 1997, 29 decembrie va
fi în a cincea s•pt•mân•, luni, atunci Luna[5,Luni]=29. Pentru zilele care lipsesc
dintr-o lun• se va completa tabloul cu 0. •tiind c• în 1997, 1 ianuarie a fost
miercuri, se poate calcula pentru urm•torii ani, în ce zi va începe anul (pentru care
se dore•te calendarul).

Program Calendar_pe_199_; { Exemplu Array }


Type Zi_Sapt = (Luni,Marti,Mercuri,Joi,Vineri,Sambata,Duminica);
Sir_Zile = Array [Zi_Sapt] Of Byte;
Saptamana = Array [1..6] Of Sir_Zile;
Const Nume_Zi : Array [Zi_Sapt] Of Char = (’L’,’M’,’M’,’J’,’V’,’S’,’D’);
Var Luna : Saptamana;
Anul,a : Word; Zi,Zl,l,s : Byte; z,ziua : Zi_Sapt;
Begin
Write (’ Calendarul pe anul 199’); Readln (Anul);
Anul:=1990+Anul; Zi:=2 { Calc. ziua de inceput a anului (0..6) }
For a:=1998 To Anul Do Begin
Zi:=Succ(Zi);
If (a−1) Mod 4 = 0 Then Zi:=Succ(Zi);
End;
Zi:=Zi Mod 7; { Ziua în care incepe anul }
z:=Luni; While Ord(z)<Zi Do z:=Succ(z); { (Luni..Duminica) }

50
For l:=1 To 12 Do Begin { Calendarul pe luna l }
For s:=1 To 6 Do
For ziua:=Luni To Duminica Do
Luna[s,ziua]:=0;
Case l Of { Nr.zile în luna l }
2 : If Anul Mod 4 = 0 Then Zl:=29
Else Zl:=28;
4,6,9,11 : Zl:=30
Else Zl:=31
End;
s:=1; { saptamana s = 1,... cel mult 6}
For Zi:=1 To Zl Do Begin
Luna[s,z]:=Zi;
If z=Duminica Then Begin z:=Luni; s:=s+1 End
Else z:=Succ(z)
End;
Case l Of
1 : Writeln (' Ianuarie '); 2 : Writeln (' Februarie ');
3 : Writeln (' Martie '); 4 : Writeln (' Aprilie ');
5 : Writeln (' Mai '); 6 : Writeln (' Iunie ');
7 : Writeln (' Iulie '); 8 : Writeln (' August ');
9 : Writeln (' Septembrie'); 10 : Writeln (' Octombrie ');
11 : Writeln (' Noiembrie '); 12 : Writeln (' Decembrie ')
End; Writeln;
For ziua:=Luni To Duminica Do Begin {pentru fiecare zi din saptamana}
Write (' ',Nume_Zi[ziua],' ');
For s:=1 To 6 Do Begin { pentru fiecare saptamana s }
If Luna[s][ziua]>0 Then Write (Luna[s,ziua]:3)
Else Write (' ');
End; Writeln
End; Readln
End;
End.

51
Un exerci•iu pe care îl propunem este urm•torul :

“Fiind dat• o matrice A cu elemente reale, având m linii •i n coloane, se cere s• se


transforme aceast• matrice prin interschimb•ri de linii, astfel încât pe coloana k
(dat•), elementele s• fie în ordine cresc•toare, apoi s• se tip•reasc• matricea în
forma final•.”

Pentru aceasta putem s• declar•m aceast• matrice astfel :

Type Linie = Array [1..10] Of Real;


Matrice = Array [1..10] Of Linie;
Var A : Matrice;
X : Linie;

Interschimbarea liniilor ( i cu i+1, dac• este cazul ) în vederea ordon•rii pe


coloana k va fi :

For i:=1 To m−1 Do


If A[i,k] >A[i+1,k] Then Begin
X:=A[i]; A[i]:=A[i+1]; A[i+1]:=X; o:=False
End;

7.2. Tipul mul•ime (Set ).

Tipul mul•ime se poate utiliza în aplica•iile care folosesc no•iunea de


mul•ime din matematic•.
Acest tip se declar• astfel : Set Of <tipul_elementelor>. Elementele
pot fi numere naturale mai mici decât 256, caractere sau elemente ale unui tip
enumerare, iar cardinalul mul•imilor poate fi maxim 256.

52
Exemplu :

Type Multime_Nr = Set Of 0..255; { sau Multime_nr = Byte }


Multime_Car = Set Of Char;
Multime_LitM = Set Of ‘A’..’Z’;
Zile = (Luni,Marti,Miercuri,Joi,Vineri,Sambata,Duminica);
Var Multime_cif : Set Of ‘0’..’9’;
M_Zile : Set Of Zile;
M_Zile_Lucratoare : Set Of Luni..Vineri;
Vocale, Consoane : Multime_LitM;
Numere : Multime_Nr;

Operatorii utilizati pentru date de acest tip sunt :

a) pentru opera•ii cu mul•imi :


- reuniunea ( ∪ ) se noteaz• cu + (A ∪ B vom scrie A + B ) ,
- intersectia ( ) se noteaz• cu ∗ (A B vom scrie A ∗ B ) ,
- diferenta ( \ ) se noteaz• cu − ( A \ B vom scrie A − B ) ;

b) rela•ionali :
- = pentru egalitatea a doua multimi ( = ), If A=B Then ...
- <> pentru neegalitate ( ≠ ), While A<>B Do ...
- >= pentru incluziunea nestricta “include” ( ⊇ ) , Repeat ... Until A>=B ;
- <= pentru incluziunea nestricta “inclus in” ( ⊆ ) , Inclus := A<=B ;
- In pentru apartenen•• (∈). Case e în A Of ... End;

Observa•ie : e ∉ A se va scrie : Not (e în A).

Constructorii de mul•imi se definesc astfel:


<constructor>::=[<lista_elemente>] ,
unde lista_elemente poate fi o sucesiune de elemente sau subdomenii de forma
elem1..elem2. De exemplu, mul•imea {1,10,100,101,...,199,200} se scrie
[1,10,100..200], iar mul•imea vid• se scrie [ ] .

53
Exemplu :
Vocale := [‘A’,’E’,’I’,’O’,’U’];
Consoane := [‘A’..’Z’] − Vocale;
Readln (N); Numere := [1..N]; { N este o variabil• de tip Integer }

Observa•ie. O variabil• de tip mul•ime nu se poate citi, iar o expresie de tip


mul•ime nu se poate tip•ri (atât citirea cât •i tip•rirea nu se pot realiza decât
decât element cu element). De exemplu, instruc•iunea Write(Consoane) nu este
permis•.
Dac• se dore•te citirea unei mul•imi, atunci aceasta se va citi element cu
element •i se vor ad•uga succesiv la mul•imea respectiv• (care a fost ini•ializat•
cu mul•imea vid•) astfel :
“ M:=[ ]; Repeat Read(e); M:=M+[e] Until Terminat_Citirea; “.
Tip•rirea unei mul•imi se va face verificând fiecare pentru element
posibil dac• apar•ine mul•imii, caz în care se va tip•ri acel element astfel:
“ For e:=Min To Max Do If e în M Then Write(e); “.

Exemplul urm•tor î•i propune rezolvarea urm•toarei probleme :


“ S• se determine numerele prime mai mici sau egale decât un num•r n dat ”.

Pentru c• vom utiliza tipul mul•ime (Set), n va fi cel mult 255.

Vom rezolva aceast• problem• în felul urm•tor :

Ciur={2,...,n}; Prime=∅;
Repet•
elementul minim din Ciur va fi mutat în mul•imea Prime,
iar din Ciur se elimin• to•i multiplii acestuia
Pân•_când Ciur-ul devine vid; { Ciur=∅ }
Rezultate Prime.

54
Program Ciurul_lui_Eratostene; (* Numerele prime < n *)
Var Ciur, Prime, Mp : Set Of 2..255;
p, n : Byte; m : Integer;
Begin
Write (’ Dati n : ’); Readln (n);
Ciur:=[2..n]; Prime:=[ ]; p:=2;
Repeat
If p în Ciur Then Begin
Prime:=Prime+[p]; (* Prime:=Prime U {p} *)
Mp:=[]; m:=p;
Repeat
Mp:=Mp+[m]; m:=m+p
Until m>n;
Ciur :=Ciur − Mp (* Ciur := Ciur \ Mp *)
End; {If}
p:=p+1
Until Ciur = [ ];
Write(' Prime = {'); (* Tipar. mult. Prime *)
For p:=1 To 255 Do
If p în Prime Then Write (p,',');
Write (Chr(8)+'}');
Readln
End.

Un exerci•iu cu mul•imi pe care îl propunem ca tem• este urm•torul :


“Sa se calculeze C.m.m.d.c. (a,b) “ astfel :
- se determin• mul•imile Da •i Db a divizorilor lui a respectiv b,
- se calculeaza mul•imea Dc a divizorilor comuni ( Dc:=Da Db )
- Cmmdc (a,b) = Maxim ( Dc ).

Pot fi a •i b mai mari dacât 255 ? Cum poate fi modificat acest program
pentru a rezolva aceast• problem• ? În mul•imi vom re•ine doar indici din •irul
tuturor divizorilor. În felul acesta mul•imile pot con•ine elemente de orice tip,
dar cardinalul maxim al mul•imilor va fi doar 255.

55
7.3. Tipul •ir_caractere (String).

Tipul String a fost conceput pentru a prelucra •iruri de caractere. Pentru


c• o dat• de tip Array Of Char nu permite opera•ii specifice •irurilor de
caractere (concatenare, citire, tip•rire •i altele), tipul string reu•e•te astfel de
opera•ii.
Acest tip se declar• astfel : String [m] sau simplu String. m
reprezint• num•rul maxim de caractere pe care poate s•-l con•in• o variabil• de
acest tip. Dac• nu se specific• aceast• limit• m (varianta a doua), atunci
lungimea maxim• este 255 (valoarea implicit• pentru m).

Exemplu :
Type Linie = String [80]; { Siruri de maxim 80 de caractere }
SirCar = String; { Siruri de maxim 255 de caractere }
Var Mesaj : String;
Rand : Line;
S : String [20];
X : Array [0..20] Of Char;

Exist• o compatibilitate între variabilele de tip String •i cele de tip Array


Of Char (S •i X, în exemplul de mai sus). Memoria ocupat• în ambele cazuri
fiind de 21 de octeti ( S[0] con•ine num•rul de caractere ale •irului S, care
poate fi cel mult m) iar S[i] reprezint• caracterul i din sirul S ( ca •i X[i] , 1”
i ”m ). Observa•ie : 0 ”Ord(S[0]) ”m, pentru c• S[0] este de tip Char.
Descrierea constantelor de tip String se realizeaz• utilizând caracterul
apostrof (′) astfel : ′ sir_caractere ′ . Dac• dorim ca •irul de caractere descris
s• con•in• acest caracter, atunci caracterul apostrof va fi dublat.

Exemplu :
′Str. Lalelelor, Nr.2′ ,
′ Domnu′′ Trandafir ′ ( reprezint• •irul Domnu′ Trandafir ).

56
Opera•ia de concatenare a dou• •iruri este notat• cu + . De exemplu
′Algoritmica,′ + ′ Programare ′ are valoarea ′Algoritmica, Programare′.
Operatorii rela•ionali permit compararea a dou• •iruri utilizând ordinea
lexicografic• (utilizat• în dic•ionare, c•r•i de telefon, etc.) :
• = •i <> pentru egalitatea respectiv neegalitatea a dou• •iruri ,
• <, >, <=, >= pentru compararea lexicografic•.

Exemple :
‘Alb’ < ‘Albastru’;
‘Ionescu’ < ‘Popescu’ ; ‘0...’ < ‘9...’ < ‘A...’ < ‘Z...’ < ‘a...’ < ‘z...’.

Tipul String are ( în plus fa•• de tipul Array Of Char ) implementate


urm•toarele facilit••i :
a) valorile variabilelor •i expresiilor de tip String pot fi citite respectiv tip•rite,
de exemplu :
Mesaj:=‘Numele autorului’; Write (‘Dati ‘+Mesaj+’ : ‘); Readln (s);

b) se pot utiliza urm•toarele patru func•ii •i patru proceduri specifice tipului


string :
- Length (S) (=Ord(S[0]) ) returneaz• lungimea •irului S (Length(‘mare’)=4),
- Copy (S,p,l) returneaz• sub•irul (lui S) de lungime l începând din pozitia p
( Copy(‘Marinescu’,2,4)=‘arin’ ),
- Concat (S1,S2,...,Sn) (=S1+S2+...+Sn) d• ca rezultat •irul ob•inut prin
concatenarea •irurilor •i , 1”i ”QQ≥ 2 ( Concat(‘Con’,’Cat’)=‘ConCat’),
- Pos (x,S) determin• pozi•ia sub•irului x în •irul S sau 0 dac• •irul S nu
con•ine ca sub•ir pe x ( Pos(‘in’,‘Marinescu’)=4 iar Pos(‘pop’,’Popescu’)=0 ),
- Delete (s,p,l) •terge din •irului s începând din pozi•ia p , l caractere. De
exemplu secventa :
s:=‘Ionescu’; Delete (s,4,4); Write (s); va tipari ‘Ion’;
- Insert (x,S,p) insereaz• •irul x în •irul S la pozi•ia p. De exemplu :
s:=‘Alg.Progr.’; Insert(‘ •i ‘,s,5); Write (s); va tipari ‘Alg. •i Progr.’;

57
- Str (e,S) depune în variabila S, •irul cifrelor corespunz•toare valorii
(numerice) expresiei e , care poate avea ata•at un format (:n:m ca •i Write) .
Exemplu : v:=5/2; Str (v:5:2,S); va depune în S •irul ‘ 2.50’.
- Val (S,v,Cr) examineaz• •irul S. Dac• acesta con•ine caractere ce reprezint•
un numar scris corect atunci se va depune în v valoarea acelui num•r iar în Cr
valoarea 0. Dac• •irul S con•ine caractere nepermise, atunci în v se depune
valoarea 0 iar în variabila Cr (de tip întreg) pozi•ia primului caracter nepermis.
Val (‘1997’,v,Cr); are ca efect : v=1234 •i Cr=0 , iar
Val (‘19d7’,v,Cr); are ca efect : v=0 •i Cr=3 ( pe pozi•ia 3 se afl• ‘d’).

Problema pe care o vom rezolva utilizând tipul string este urm•toarea :


“S• se calculeze valoarea unei expresii aritmetice de forma : n1Œn2[=] unde :
n1,2 sunt dou• numere reale, Œ este un operator aritmetic (+, −, *, ×, / sau : ) iar
semnul egal la sfâr•itul expresiei poate lipsi. Expresia (simpl•, cu un singur
operator •i f•r• paranteze) este dat• sub forma unui •ir de caractere, iar rezultatul
se va afi•a cu dou• zecimale. “
De exemplu pentru ‘123+45’ rezultatul este 168,00 , iar pentru
‘123.3:3=’ rezultatul este 41,10 .
Problema o vom rezolva astfel :
e - reprezint• expresia sub forma unui •ir de caractere, iar r este rezultatul
(valoarea expresiei) dat• tot sub forma unui •ir de caractere în care se va înlocui
marca zecimal• ‘.’ cu ‘,’ . Dac• expresia nu se termina cu caracterul ‘=‘, acesta
va fi adaugat •irului introdus.
Se determin• pozi•ia operatorului (p). Inseamn• c• o=e[p] va fi
caracterul ce va desemna opera•ia ce urmeaz• a fi facut•. n1 este scris cu
caracterele e1...ep-1 , deci poate fi obtinut cu procedura Val, iar apoi se sterg
primele p caractere, ceea ce înseamn• c• în expresia e mai ramane ‘n2=’. În
continuare, se procedeaz• analog, extragând pe n2, din •irul r•mas , mai pu•in
ultimul caracter. Dup• tip•rirea rezultatului (a •irului r ) se va citi alt •ir (alt•

58
expresie) pân• când se va introduce expresia vid• (•irul vid) adic• se tasteaz•
doar Enter în momentul citirii expresiei.
Programul Pascal este urm•torul:

Program Valoarea_Expresiei; (* ’123+22=’ *)


Var e,r : String (* n1 o n2 = ? *)
o : Char; (* o ∈ {+,-,x,:,*,/} *)
n1, n2 : Real;
p , er : Integer;
Begin
Repeat
Write (’ Dati expresia (n1 o n2 =) : ’); Readln (e);
If e>’’ Then Begin
If Pos (’=’,e)=0 Then e:=e+’=’;
Val (e,n1,p); { p:=Poz(o) }
Val (Copy(e,1,p-1),n1,er); {n1:=...}
o:=e[p];
Delete (e,1,p);
Val (Copy(e,1,Length(e)-1),n2,er);
Case o Of
’+’ : Str (n1+n2:8:2,r);
’-’ : Str (n1-n2:8:2,r);
’x’,’*’ : Str (n1*n2:8:2,r);
’:’,’/’ : Str (n1/n2:8:2,r)
Else r:=’ Operator necunoscut.’+o
End;
p:=Pos(’.’,r); If p>0 Then r[p]:=’,’;
Writeln (r)
End
Until e=’’
End.

59
Un alt exerci•iu pe care îl propunem ca tem• este urm•torul:
“S• se calculeze valoarea unui polinom P (dat ca •ir de caractere), într-un punct
x dat.”
Polinomul P(X) = a0Xn + a1Xn-1 + ... + an-1X + an se d• sub forma:
“a0X^n+a1X^n-1+...+an-1X+an”.
De exemplu, polinomul P(X) = 3X5-7X2+12X-9 se poate scrie astfel :
3X^5-7X^2+12X-9 , utilizând caracterul ‘^’ pentru a marca puterea.

Pentru a rezolva aceast• problem•, se poate extrage din •irul dat, pe rând
fiecare monom (acestea fiind separate de caracterul + sau -), iar din fiecare
monom se va extrage coeficientul •i puterea. În acest fel putem memora
polinomul ca un •ir de perechi de forma (coeficient, grad), urmând s• calcul•m
valoarea polinomului ob•inut.

7.4. Tipul înregistrare (Record ).

Tipul Record permite gruparea datelor de tipuri diferite. O astfel de


dat• numtit• înregistrare putem spune c• este alcatuit• din mai multe câmpuri,
nu neap•rat de acela•i tip. Un câmp poate la rândul s•u s• fie alc•tuit din mai
multe subcâmpuri •i a•a mai departe. De exemplu, pentru a memora date
referitoare la studen•ii unei facult••i ca în tabelul urm•tor, avem nevoie de o
structur• în care elementele (Nr. matricol, Nume, Rezultate •i Medie) au tipuri
diferite ( întreg, sir de caractere, 1..10 sau (FB,B,S,NS) sau (Admis,Respins),
real). Sunt •i situa•ii în care nu toate înregistr•rile con•in acelea•i informa•ii,
ceea ce înseamn• c• avem nevoie de o structur• variabil• (diferite câmpuri) în
func•ie de anumite valori ale unor câmpuri fixe. În acest sens putem spune c• o

60
înregistrare are o parte fix• format• din mai multe câmpuri de diverse tipuri,
urmat• eventual de o parte variabil•.
Nr. Numele •i Rezultate (Note •i calificative) Media
matricol prenumele Algebr• Analiz• Geometrie Informatic• Sport general•
12292 Avram Valentin 10 8 9 F.B. Admis 9.00
12295 Barbulescu Ioan 9 7 9 B. Admis 8.33
... ... ... ... ... ... ... ...
18944 Zaharascu Paula 9 10 8 F.B. Respins -

Declararea tipului inregistare const• într-o o parte fix• (în care se declar•
câmpurile împreun• cu tipurile lor) •i eventual o parte variabil• (Case ... , în
care câmpurile difer• în func•ie valoarea unor câmpuri din partea fix•) astfel :
Record
<list•_câmpuri> : <tip_câmp> { ;
<list•_câmpuri> : <tip_câmp> }
[ Case [ <id> : ] <tip_sel> Of
<const> : (<list•_câmpuri> : <tip_câmp> { ;
<list•_câmpuri> : <tip_câmp> } ) { ;
<const> : (<list•_câmpuri> : <tip_câmp> { ;
<list•_câmpuri> : <tip_câmp> } ) } ]
End;

Prin <list•_câmpuri> în•elegem o list• de identificatori de câmpuri, iar


<tip_câmp> este tipul câmpurilor care pot fi chiar Record.
Referirea unui câmp al unei variabile de tip inregistrare se face astfel :
<var_record> . <id_câmp>

De exemplu în programul urm•tor, Un_Student.Media_Gen reprezint•


câmpul Media_Gen al variabilei Un_Student, iar Un_Student.Rezultate.Informatic•
reprezint• calificativul la Informatic• din câmpul Rezultate. Dac• în câmpul
Informatic• a fost depus• valoarea NS sau S, înregistrarea are în partea variabil•

61
notele ob•inute la scris •i practic, iar dac• valoarea depus• a fost B sau FB
atunci în partea variabil• se va re•ine doar nota final• obtinut•.
În cazul în care referim mai multe câmpuri din cadrul unei înregistr•ri se
poate evita precizarea multipl• a acelea•i înregistr•ri prin instruc•iunea With.
Aceasta are urm•toarea sintax• :

With <var_record> { , <id_câmp> } Do <instruc•iune> ,

ceea ce permite omiterea scrierii în <instruc•iune> a selectorilor preciza•i o


singur• dat• (<var_record> ,<id_câmp> ).

De exemplu, în loc de

Writeln (Un_Student.Nume, Un_Student.Media_Gen);

se poate scrie mai simplu :

With Un_Student Do Writeln (Nume, Media_Gen);

În cazul în care un câmp este de tip record, se poate omite •i acest


selector din instruc•iune, dac• acesta a fost precizat ca <id_câmp> în
instruc•iunea With. De exemplu, în loc de

Readln (Un_Student.Rezultate.Algebra, Un_Student.Rezultate.Analiza, ...)

se poate scrie mai simplu :

With Un_Student, Rezultate Do Readln (Algebra, Analiza, ...) .

Un exemplu de program care utilizeaz• structurile men•ionate mai sus


este redat în continuare. Se citesc informa•iile fiec•rui student (mai putin
media, care se calculeaz•, dac• este promovat la toate disciplinele), apoi se
ordoneaz• descresc•tor dup• medii, iar în final se listeaz• studen•ii în ordinea
mediilor.

62
Program Inregistrari;
Type Calificativ = (NS,S,B,FB);
Student = Record
Nr_Matricol : Word;
Nume_Prenume : String[20];
Rezultate : Record
Algebra, Analiza, Geometrie : 1..10;
Informatica : Calificativ;
Sport : (Respins, Admis);
Case Inf : Calificativ Of
Ns : (Scris,Practic : Integer);
S,B,FB : (Nota : Integer)
End;
Media_Gen : Real;
End;
Var Studenti : Array [1..25] Of Student;
Un_Student : Student;
i, n, k : Byte;
Ordonati : (Da, Nu);
Rasp : String[10];
Begin
n:=0; {Citeste datele fiecarui student}
With Un_Student, Rezultate Do Begin
Repeat
Write (’ Nume student : ’); Readln (Nume_Prenume);
If Nume_Prenume<>’’ Then Begin
Write (’ Numar matricol : ’); Readln (Nr_Matricol);
Write (’ Algebra (1..10) : ’); Readln (Algebra);
Write (’ Analiza (1..10) : ’); Readln (Analiza);
Write (’ Geometrie (1..10) : ’); Readln (Geometrie);
Write (’ Informatica (NS..FB) : ’); Readln(Rasp);
Case Rasp[1] Of
’N’ : Informatica:=NS; ’S’ : Informatica:=S;
’B’ : Informatica:=B; ’F’ : Informatica:=FB
End;
If Informatica = Ns Then Begin Write (’ Scris, Practic : ’);
Readln ( Scris, Practic)
End
Else Begin Write (’ Nota : ’);
Readln ( Nota)
End;
Write (’ Sport(Adm,Resp) : ’); Readln(Rasp);
Case Rasp[1] Of

63
’A’ : Sport:=Admis; ’R’ : Sport:=Respins
End;
If (Informatica in [FB,B,S]) And (Sport = Admis) And
(Algebra>4) And (Analiza>4) And (Geometrie>4) Then
Media_Gen:=(Algebra+Analiza+Geometrie+Nota)/4 Else
Media_Gen:=0;
n:=n+1; Studenti[n]:=Un_Student
End {If}
Until Nume_Prenume=’’ End; {With}
k:=0; { Ordoneaza descrescator dupa medii }
Repeat Ordonati:=Da; k:=k+1;
For i:=1 To n-k Do
If Studenti[i].Media_Gen < Studenti[i+1].Media_Gen Then Begin
Un_Student:=Studenti[i]; Studenti[i]:=Studenti[i+1];
Studenti[i+1]:=Un_Student; Ordonati:=Nu End
Until Ordonati=Da; { Tipareste studentii în ordinea rezultata }
For i:=1 To n Do With Studenti[i] , Rezultate Do Begin
Write (Nr_Matricol:7,Nume_Prenume:20,
Algebra:3,Analiza:3,Geometrie:3);
Case Informatica Of
NS : Write (' Nesatisfacator ',Scris:3,Practic:3);
S : Write (' Satisfacator ',Nota:6);
B : Write (' Bine ',Nota:6);
FB : Write (' Foarte Bine ',Nota:6)
End;
Case Sport Of
Admis : Write (' Admis '); Respins : Write (' Respins ')
End;
Writeln (Media_Gen:6:2) End;{With}
Readln
End.

Ca tem• propunem modificarea acestui program astfel încât s• se poat•


ob•ine lista studen•ilor în ordinea descrescatoare a notelor la fiecare disciplin•
far• a interschimba lista studen•ilor introdus• de la tastatur•. Pentru aceasta se
va construi de fiecare dat• un vector de ordine O (oi, i=1,...,n ) unde oi
reprezint• num•rul de ordine al studentului (din lista ini•ial•) care se afla pe
locul i în lista ordonat•. Aceasta înseamn• c• ini•ial •irul O va con•ine valorile
(1,...,n), apoi se va schimba aceast• ordine, dac• este cazul, (se interschimb•

64
doar elementele •irului O, deci oi ↔ oi+1) iar în final se vor tip•ri studen•ii în
ordinea dorit•, adic• se va tip•ri St[oi], i=1,...,n.

65