Sunteți pe pagina 1din 106

dr. Tudor Blnescu, erban Gavril, conf. dr. Horia Georgescu, dr. Marian Gheorghe, Liviu Sofoea, prof.

dr. Ion "Vduva

IPffiOGlMMAMEA N LMBAHELIE PASCAL TURBO PASCAL


volumul I Limbajul Pascal. Concepte fundamentale

(Q )
EDITURA TEHNICA Bucureti, 1992

Copyright 1992, Editura Tehnic Toate drepturile asupra acestei ediii snt* rezervate editurii

Adresa : Editura Tehnic Pia{a Presei Libere, 1 33 Bucureti, Romnia cod 79738

Redactor: Ing. Silvia Cndea ( .pena : grafician Dumilrescu : Ing. Simona Silvia Cundea

B024779

Tehnoredactor

Coli de tipar: 17; Bun de tipar: 24.1.92 C.Z.: 681.3.06 ISBN: 973-31-0430-2; ISBN: 973-31-0431-0

Comanda nr. 49 Tiraj exemplare

20

000

Tiparul: IMPRIMERIA ARDEALUL" CLUJ UnivarsiUUH Stat A l C B d.-> R u o i: o "

iJiblioieca tiinifica Fond didactic

Limbajul Pascal

- Concepte fundamentale

Un limbaj de programare este un sistem de notaii pentru reprezentarea algoritmilor. Exprimai n aceast form, algoritmii pot fi executai de ctre calculatorul electronic sau comunicai altor programatori. Primele limbaje de programare au fost limbajele main, care foloseau o notaie foarte deprtat de cea uzual sau matematic. Odat cu dezvoltarea activitii de programare a aprut necesitatea de a transcrie un proces de calcul ntr-un limbaj ct mai apropiat de modul n care a fost elaborat algoritmul ce-l descrie, sau apropiat de limbajul natural. Astfel au aprut limbajele de nivel nalt (FORTRAN, COBOL, ALGOL, PL/I, BASIC, APL, Pascal, C, Aia etc). Dac limbajele FORTRAN i COBOL snt cele mai folosite n problemele de calcule tiinifice i n cele comerciale, limbajul Pascal a devenit n ultimul timp "lingua franca" a comunitii informatice din mediul universitar, integrnd cu mult succes un numr mic de faciliti ntr-un corpus puternic i eficient. Acest limbaj a fost definit n 1971 de profesorul Niklaus Wirth de la Universitatea Tehnic din Zurich [Wi71a, Wi72J. Numele limbajului este cel al matematicianului i umanistului francez Blaise Pascal (1623 - 1662), care a conceput la vrsta de numai 18 ani prima main simpl de calculat. Cteva din caracteristicile ce au impus limbajul snt: simplitatea i claritatea acestuia, obinute printr-o riguroas selecie a conceptelor de programare; posibilitatea de a atinge o anumit disciplin a programrii ce conduce la programe robuste i eficiente, prin obligativitatea impus declarrii obiectelor utilizate (tipuri, constante, variabile) precum i prin facilitile oferite de instruciuni ce permit un bun stil de programare (instruciuni compuse - begln . . . end, instruciuni condiionale - l f . . . then. . .else, caso, instruciuni iterative - while, repeat. . .vntll, fox). La noi n ar, importante investigaii privind implementarea sau/i utilizarea limbajului Pascal au fost efectuate de colective din nvmntul superior (Institutul Politehnic din Timioara [Ci82, Ci85], Institutul Politehnic din Bucureti [Io83, Se84], Universitatea din Iai [Ru87J). Prezentarea limbajului Pascal din lucrarea de fa urmrete att nucleul su, aa cum rezult din monografiile lui Jensen i Wirth [JeWi74, JeV/i85], ct i extensiile din varianta Oregon [Pa81]. Un compilator pentru acest limbaj este disponibil pe minicalculatoarele din familia Independent - Coral. n textul lucrrii marcm extensiile limbajului prin scrierea cu italice a prii care semnaleaz acest fapt. Lucrarea se adreseaz cititorilor care snt oarecum familiarizai cu proble

matica programrii calculatoarelor i cu noiunile de baz ale informaticii teoretice. Ea poate servi ca suport de curs studenilor facultilor de matematic i tn aceeai msur poate fi parcurs cu folos i de absolvenii acestor faculti i ai seciilor de specialitate din institutele tehnice t economice. In abordarea anumitor concepte ale limbajului Pascal am ncercat s introducem un instrument matematic care s confere mai mult exactitate i claritate prezentrii Astfel, tipurile de date au fast n general definite utiUzSnd instrumente din teoria structurilor algebrice [AUr78], sintaxa limbajului este exprimat fie n notaia BNF, fie prin diagrame sintactice, iar anumite elemente de semantic jac apel la modele ale semanticii axiomatice de tip Hoare [HoW73]. Lucrarea este structurat astfel: o introducere, 7 capitole i 4 anexe. Primele noiuni despre programarea n limbajul Pascal snt expuse n introducere. Capitolul 1 prezint elementele lexicale i sintactice ale limbajului n capitolul 2 snt abordate tipurile de date simple, structurau! i tipul pointer, variabilele, constantele, etichetele i expresiile. Instruciunile limbajului snt prezentate n capitolul 3. in capitolul 4 snt prezentate conceptele de procedur, funcie i program care permit descrierea modular-structurat a proceselor de calcul de mare complexitate. Printre aplicaiile mai importante prezentate aici amintim: construcia tabelelor de analiz sintactic n cazul gramaticilor de preceden simpl; folosirea recursiei n cadrul unor algoritmi cu reluare ('backtracking algorithms") i pentru analiza sintactic recursiv descendent Capitolul 5 conine o prezentare formalizat a semanticii, utiUznd modele axiomatice. Mecanismele dezvoltate aici snt aplicate la proiectarea programelor prin metoda rafinrii succesive i verificarea corectitudinii tn capitolul 6 snt prezentate facilitile de depanare simbolic ale compilatorului Pascal-Oregon, utile i pentru nvarea interactiv a limbajului Capitolul 7 ofer cteva informatii referitoare la punerea n lucru a compilatorului Pascal sub sistemul de operare RSX. Anexele i 2 conin lexicul i respectiv sintaxa limbajului Pascal n notaia BNF; anexa 3 conine diagramele de sintax O list a constantelor, tipurilor i variabilelor predefinite, precum i o scurt prezentare a procedurilor i funciilor predefinite se afl n anexa 4. _, , Adresm cele mai sincere mulumiri colegei Silvia Pepelea care, cu rbdare, pricepere i contiinciozitate, ne-a asistat n redactarea acestui text Autorii

Limbajul Pascal

- Concepte fundamentale

INTRODUCERE.................................................................................................

1. VOCABULARUL I SINTAXA LIMBAJULUI ....................................................... 5 1.1. Mulimea de caractere............................................................................. 5 - 1.2. Vocabularul limbajului.................................................................. 6 1.3.Sintaxa limbajului......................................................................... 8 1.3.1................................................................Form alismul BNF............................................................................ 8 1.3.2................................................................Diagr ame sintactice ...................................................................... 10 1.4. Exerciii........................................................................................ 11 2. TIPURI DE DATE, VARIABILE, CONSTANTE, ETICHETE, EXPRESII ---------------- 13 2.1. Tipuri de date simple.................................................................... 14 2.1.1................................................................Tipur i de date predcfmitc............................................................... 14 2.1.2................................................................Tipur i de date enumerare............................................................... 19 2.1.3................................................................Tipul de date subdomeniu............................................................... 20 2.2. Tipuri de date structurate............................................................. 21 2.2.1................................................................Tipul de date array (tablou)............................................................ 21 2.2.2................................................................Tipul de date record (nregistrate)................................................... 26 2.2.3................................................................Tipul de date set (mulime)............................................................. 30 2.2.4................................................................Tipul de date file (fiier).................................................................. 32 2.2.4.1...................................................................................Fiiere secveniale 33 2.2.4.1.1. Operaii de intrare/ieire ............... 33 2.2.4.12........................................Fiier e text .................................................................38 2.2.4.13. Fii erele standard input i output . . . . 44 2.2.4.2. Asocierea fiierelor Pascal cu fiiere externe . . . 44 2.2.4.3.Fiiere cu acces direct.................................... 46 2.3.............................................................................Tipul de date pointer (referin)................................................................... 47 2.4.............................................................................Tipur i de date recursive............................................................................... 49

2.5.......................Expresii..........................................................'. 2.6.............................................................................Exer
ciii ......................................................................................................................54 3. NSTOUCRJNI............................................................................................... 57 3.1. Instruciuni simple....................................................................... 57 3.1.1................................................................Instr uciunea dc atribuire.............................................................. 57 3.1.2................................................................mstr uciunea apel de procedur.................................................... 59 3.1.3................................................................Instr uciunea de transfer necondiionat ........................................ 59 3.1.4................................................................Instr uciunea de efect nul.............................................................. 62 ,3.2. Instruciuni structurate................................................................. 62 ($t)

Limbajul Pascal

- Concepte fundamentale

3.2.1................................................................Instr
uciunea compus.................................................................. 62 3.2.2................................................................Instr uciuni iterative...................................................................... 63 3.2.2.1....................................................Instr uciunea while .......................................................... 63 3.2.2.2....................................................Instr uciunea repeat.......................................................... 66 3.2.2.3....................................................Instr uciunea for ............................................................... 68 3.2.3....................................................................................................Instruciuni condiionale .......................................................................... 71 3.2.3.1....................................................Instr uciunea if.................................................................. 71 3.2.3.2....................................................Instr uciunea case ............................................................ 73 3.2.4....................................................................................................Instruciunea with 74 3.3.............................................................................Exe mple................................................................................................... 76 3.4.............................................................................Exer ciii .....................................................................................................................80 4. PROCEDURL FUNCII, PROGRAME, MODULE ............................................. nisme de abstractizare n Pascal......................................................... ii

4.1.............................................................................Meca 4.2.............................................................................Func
.....................................................................................................................84
ararea funciilor......................................................................

84 84

4.2.1................................................................Decl 4.2.2................................................................Apel
ul funciilor............................................................................. 84 85

4.2.3................................................................Exe

mple ....................................................................................................86 4.3. Proceduri...................................................................................... 90 4.3.1................................................................Decl ararea procedurilor................................................................. 90 4.3.2...............................................................Apelul procedurilor..........................................................................i 90 4.3.3................................................................Exe mple ...................................................................................................91 4.4. Programe...................................................................................... 92 4.4.1................................................................For me sintactice; exemple . .'...................................................... 92 4.4.2................................................................Stru ctura static a programelor.................................................... 93 4.4.3................................................................Dom enii de vizibilitate a declaraiilor............................................. 94 4.4.3.1....................................................Dom enii de vizibilitate ale declaraiilor de identificatori ..................................................................................95

4.4.3.2.Domenii de vizibilitate pentru alte declaraii . . . . 4.4.3.3....................................................Cont


ext asociat unei uniti de program............................ 99 4.5.Comunicarea ntre uniti de program ...................................... 100 4.5.1...............................................................Comu nicarea prin identificatori globali ......................................... 100 4.5.2...............................................................Comu nicarea prin parametri.......................................................... 101 4.5.2.1..................................................Para metri valoare........................................................... 101 4.5.2.2..................................................Para metri variabil.......................................................... 102 4.5.2.3..................................................Para metri formali funcie / procedur............................. 103 4.5.2.4..................................................Tablo uri ca parametri....................................................... 106 4.5.2.5..................................................Struct ura dinamic a programelor .................................... 107 4.5.3. Efecte secundare la execuia funciilor i procedurilor . . . . 108 4.5.3.1. Atribuiri asupra variabilelor globale.............. 109 4.5.3.2. Atribuiri asupra parametrilor formali varia bil.............................................................. 109 4.5.3.3. 98

...............................................................................
Parametri actuali cu acelai nume pentru parametri formali variabil distinci..................... 110 4.5.4. Recursie .................................................................... 111 4.5.4.1..................................................Recur sia indirect ............................................................ 111 4.5.4.2..................................................Recur sia direct ............................................................. 112 4.5.4.3. Recursia i metoda relurii ("backtracking") . . . 125 4.5.4.4..................................................Aplica ie: analiza sintactic recursiv descendent 131 4.5.4.5. Aplicaie: calculul relaiilor de preceden .......................................................... 139 4.6. Module....................................................................................... 150 4.6.1.Definirea si utilizarea modulelor in Pascal Oregon....... 150 4.6.1.1..................................................Compi larea separat.......................................................... 151 4.6.1.2..................................................Modul e externe................................................................. 151 4.6.1.3..................................................Modul principal................................................................... 153 4.6.2.Comunicarea ntre module.......................................... 154 4.6.2.1............................................Comunicar ea prin variabile globale .................................. 154

10

Limbajul Pascal

- Concepte fundamentale

4.6.2.2..................................................Comu
nicarea prin apel de funcii / proceduri externe

................................................................................154
4.7. Exerciii...................................................................................... 5. REPREZENTAREA FORMALIZAT A SEMANTICII.......................................... ucere................................................................................................ 155 158 158 159 162

5.1...........................................................................Introd 5.2...........................................................................Siste
me axiomatice de tip Hoare.............................................................. a instruciunii de efect nul....................................................

5.2.1..............................................................Axiom 5.2.2..............................................................Axiom

a instruciunii de atribuire ................................................... 162 5.2.3..........................................Regula consecinelor . ...................................................................163 5.2.4...............................................................Regul a instruciunii compuse........................................................ 163 5.2.5...............................................................Regul a instruciunii if..................................................................... 164 5.2.6...............................................................Regul a instruciunii while.............................................................. 165 5.2.7...............................................................Regul a instruciunii repeat............................................................ 171 5.2.8...............................................................Proble ma terminrii programelor ................................................... 174 5.2.9...............................................................Regul a instruciunii for ............................................................... 176 5.2.10.............................................................Regul a funciilor............................................................................ 177 5.2.11.............................................................Regul a apelului dc procedur ....................................................... 178 5.3...........................................................................Metod a de programare top-down................................................................ 180 5.4...........................................................................Exerci ii ...................................................................................................................192 6. DEPANATORUL SIMBOLIC........................................................................... 196 196

6.1...........................................................................Consi
deraii generale................................................................................

6.2...........................................................................Come

nzile de baz ale depanatorului........................................................ 197 6.3. Comenzi de depanare .................................................. 198 6.3.1. Comenzi relative la crearea/distrugerea punctelor de ntrerupere (breakpoints).................................... 198 6.3.1.1. Comenzi relative la crearea/distrugerea punctelor de ntrerupere ce controleaz execuia unui program................................................. 198 6.3.1.2. Comenzi relative la crearea/distrugerea punctelor de ntrerupere pentru variabile.................. 199 6.3.2...............................................................Come nzi ce controleaz execuia programului..................................... 200

6.3.3...............................................................Come
nzi pentru trasarea execuiei..................................................... 201 6.3.4...............................................................Come nzi relative la date................................................................... 201 6.3.5...............................................................Come nzi informative........................................................................ 202 6.3.6.................................Macrocomenzi.................., 203 6.3.7...............................................................Come nzi referitoare la stiva programului............................................. 204 6.4. Lista comenzilor ............................................................................ 206 7. UTILIZAREA COMPILATORULUI PASCAL-OREGON----------------------_ .. .------------- 201 7.1...........................................................................Puner ea n lucru a compilatorului Pascal-Oregon.............................................. 207 7.2...........................................................................Opiun i de compilare..................................................................................... 208 7.3...........................................................................Exem ple ...................................................................................................................209 7.4. Directive comentariu.................................................................... 211 7.5. Directiva % include ....................................................................... 212 Anexa 1. VOCABULARUL LIMBAJULUI PASCAL........................................,............. 219 Anexa 2. SINTAXA LIMBAJULUI PASCAL N NOTAIA BNF........................................ 221 Anexa 3. DIAGRAMELE SINTACTICE PENTRU LIMBAJUL PASCAL.............................. 226 Anexa 4. CONSTANTE, TIPURI, VARIABILE, FUNCTH, PROCEDURI

4.1...........................................................................Const
ante................................................................................................... 233 4.2...........................................................................Tipuri ...................................................................................................................233 4.3...........................................................................Variab ile ...................................................................................................................233 4.4...........................................................................Funcii ...................................................................................................................233 4.5...........................................................................Proce duri ...................................................................................................................235 4.6...........................................................................Lista simbolurilor echivalente........................................................................ 236 RSPUNSURI LA EXERCIII................................................................................. 237 BIBLIOGRAFIE.................................................................................................. 255

PREDEFINITE .................................................................................... 233

12

Limbajul Pascal

- Concepte fundamentale

INTRODUCERE

Acest capitol prezint cteva exemple de programe n limbajul Pascal, precum i unele caracteristici ale limbajului, avnd drept scop formarea unei viziuni de ansamblu asupra acestuia nainte de a-i cunoate detaliile. n ncheiere snt descrise pe scurt comenzile necesare executrii unui program scris n limbajul Pascal-Oregon sub sistemul de operare RSX-11M. Acest limbaj a fost proiectat i implementat de ctre firma Oregon Software. Menionm c la citirea i scrierea datelor n exemplele din acest capitol se utilizeaz doar mediile standard de intrare / ieire, in implementarea Pascal-

Ore-gon acestea fiind terminalul utilizatorului.

Primul exemplu este un program numit Mesaj care scrie un ir de caractere. Pe unele linii ale programului apare un comentariu, delimitat prin acoladele { i }. program Mesaj; (programul numit Mesaj} begin {inceputul secvenei de instruciuni} writeln( ' Primul program in limbajul Pascal') {instruciunea writeln ...scrie irul de caractere "Primul . . . " si apoi trece la linia urmtoare a ecranului terminalului} end. {sfirsitul programului} Urmtorul program numit suma, citete dou numere ntregi, calculeaz suma acestora i scrie rezultatul. program Suma; var x , y, z : integer; begin {citete o valoare in x } {citete o valoare in y si trece la linia urmtoare a ecranului} z := x + y ; {instruciune de atribuire; z primete valoarea x + y } writeln(z) {este scris z } read(x); readln(y);

{declara variabilele intregi x, y , z }

Din exemplele anterioare se poate desprinde urmtoarea structur a unui program n limbajul Pascal: program NUME; . { d e c l a r a i i de v a r i a b i l e } begin . { i n s t r u c i u n i ce p o t } } antet de p r o g r a m ~| \ partea declarativ J 1 |

. end.

{utiliza aceste variabile}

\ instruciunea | compus J

Prin urmare, un program este alctuit n general dintr-un antet de program, o parte declarativ n care snt descrise toate entitile folosite i o instruciune compus. Instruciunea compus poate conine la rndul ei, alte instruciuni (condiionale, iterative, etc.). Spre exemplu, pentru a calcula valoarea absolut a unui numr real x se folosete instruciunea condiional if, dup cum urmeaz: program Valabs; var x : r e a l ; begin readln(x); if x < o then x : = - x ;

{se declara variabila reala x}

{se citete x} {daca x < 0 } {atunci i se atribuie lui x valoarea -x, altfel x.ramine neschimbat} writelnCabs( x ) , x) {sint scrise mesajul "abs(x)=" s i valoarea.x } end.

Dintre instruciunile iterative ale limbajului Pascal vom alege spre exemplificare instruciunea for care este folosit n programul urmtor pentru a calcula suma a n elemente aflate ntr-un vector: program Suma_n_elem; const n - 10; { s e introduce constanta 10, c u numele n } var i : integer; v : array [ l . . n ] of r e a l ; { s e d e c l a r a un v e c t o r v c u n componente numere r e a l e } suma : r e a l ; procedura Adun ( x : x e a l ; var y : r e a l ) ; {Procedura Aduna c a l c u l e a z x + y s i intoaxce r e z u l t a t u l in y; detalii despre proceduri in capitolul 4 i begin y:= y + x end; {Aduna} begin { p r o g r a m p r i n c i p a l } for i : = l to n do { p e n t r u i de la 1 la n j r e a d l n ( v [ i ) ; c i t e t e v a l o a r e a v [ i ] , c i t e una de p e o linie} suma : - 0; for i : = 1 to n do {pentru v a l o r i l e succesive ale lui i} Adun( v [ i ] , s um a ) ; { a d u n a la suma a l i - l e a element a l l u i v ) w r i t e l n ( ' s u m a ' , suma) end.

{se

n programul care urmeaz, ilustrm utilizarea instruciunii iterative while pentru a calcula numerele Fibonacci mai mici dect 100.

14

Limbajul Pascal

- Concepte fundamentale

program F i b o n a c c i ; var J , K : i n t e g e r ; begin J : = 0; K : = 1; ->r-': while K < 100 do begin { c i t t i m p u l t i m u l numr Fibonacci obinut este mai m i c dect 100} writeln(K); {scrie valoarea numrului Fibonacci} K ; = K + J; { K v f i u r m t o r u l n u m r Fibonacci} J := K - J { J este valoarea a n t e r i o a r a a lui K} end { w h i l e } end. Presupunem c textul unui program Pascal se afl ntr-un fiier creat cu ajutorul unui editor de texte (EDT, EDI, etc). Pentru ca programul s devin executabil, acest text este" prelucrat succesiv de compilator i de editorul de taskuri. Spre exemplu, dac programul Fibonacci se afl ntr-un fiier numit 7IBO. PAS, atunci compilarea sa se face n urma lansrii comenzii PAS FIBO Rezultatul compilrii este depus n fiierul FIBO . OBJ , care va fi prelucrat de editorul de task-uri. Acesta se activeaz prin comanda F T B PROG /FP /CP " FIBO, LB[1,1]PASLIB /LB Programul n format executabil este obinut n fiierul PROG. TSK i poate fi lansat n lucru prin comanda: HUN PROG Alte detalii n legtur cu compilarea programelor pot fi gsite n capitolul 7. Pentru programatorii familiarizai cu alte limbaje de programare, menionm cteva din caracteristicile limbajului Pascal: 1. Declararea variabilelor este obligatorie. 2. Anumite cuvinte cheie (de exemplu hegin, end) snt rezervate, neputnd fi utilizate ca identificatori. * 3. Tipurile de date disponibile n Pascal snt: simple (tipuri de date ntregi, reale, logice, caractere, enumerare, subdomeniu), structurate (tipuri de date tablou, nregistrare, mulime, fiier), pointer. Limbajul permite definirea de ctre utilizator a unor tipuri noi. 4.Tablourile pot avea dimensiuni i limite arbitrare, dar constante, ale indicilor. 5.Instruciunile pot fi etichetate. Etichetele snt ntregi fr semn i trebuie s fie declarate. 6. Procedurile i funciile pot fi apelate recursiv. 7. Toate obiectele (constante, tipuri, variabile, etichete, proceduri, funcii) trebuie s fie declarate nainte de utilizare, cu urmtoarele dou excepii:

- identificatorul de tip din definiia unui tip de date pointer (vezi 2.3); - identificatorii de proceduri i funcii pentru care exist o directiv forward (vezi 4.6.4.1).

Vocabularul oricrui limbaj de programare conine cele mai simple elemente cu semnificaie lingvistic, iar sintaxa limbajului definete modul n care se combin elementele vocabularului pentru a obine fraze corecte (instruciuni, secvene de instruciuni, declarri de tipuri, variabile, constante, etichete, funcii, proceduri etc).

1.1. Mulimea de caractere


Elementele vocabularului snt alctuite din caractere. Orice caracter este reprezentat n calculator, n mod urne, printr-un numr natural cuprins ntre 0 i

023456,70 |nulsohstxetx eotenqack bel1 Ibshtlfvtff crsosi 2 | dle deldc2dc3 dc4naksynetb 3 | can emsubescfsgs us4 !- -..5 |l6 j7 |'8' 9 ' 1 m 1I m * t ' <'* ST '' >'' ?'8 |'''A''B''C''D': 'E'' F'' G' 9 1' H' 10 |'p''Q' 'r.''s''t* -'u''v'.11 |i ' X ' 'Y' [''V* * 1 12 |I I I 'a' .',b' ,c'd''ef %''g' 13,. j\ -K' i''X'k' 1''m''h''o' 141 'p'15del

Se face distincie ntre caracterele neimprimabile (caracterul del i cele de pe primele patru linii, care au codul cuprins

16

Limbajul Pascal

- Concepte fundamentale

127, numit cod ASCII. Astfel, codul unui caracter de pe linia 1 i coloana c dm
tabela de mai jos este 8 1+c. Spre exemplu, codul caracterului 2 este 50. Mulimea de caractere a limbajului Paseal-Oregon conine urmtoarele elemente: ale acestei mulimi: literele alfabetului latin (mari sau mici), cifrele arabe, caracterul * ' (spaiu), '+*, *-', '>', etc.

1.2. Vocabularul limbajului


Cele mai simple elemente, alctuite din caractere i care au semnificaie lingvistic snt unitile lexicale. Acestea fonneaz vocabularul limbajului. Distingem urmtoarele uniti lexicale: - simboluri speciale; - identificatori; - numere; - iruri de caractere; - etichete; - comentarii; - directive. Simbolurile speciale snt:

+ *
{ }

<

>
*
@

> <> >= case else goto

J <=

:=
t

.0)

i cuvintele cheie: and div file in of procedure then while array do for labei or program to with begin downto function mod origin record type end if

const

nil otherwise repeat until

not packed set var

(2)

Cuvintele cheie snt rezervate, adic snt utilizate n programe doar cu semnificaia dat explicit prin definiia limbajului. Celelalte simboluri speciale snt folosite ca operatori i delimitatori. Identificatorii snt nume asociate constantelor, variabilelor, tipurilor de date, procedurilor i funciilor. Primul caracter al numelui este o liter sau '$* iar celelalte snt litere, cifre, '$', sau *_' Exemple: x i , Suma____x_y, $PRET____NOU. Numerele pot fi de tipul integer sau de tipul real. Numerele de tipul integer desemneaz numere ntregi i snt scrise n reprezentare zecimal, precedate sau nu de semnele *+* sau Spre exemplu, valoarea ntreag 23 poate fi reprezentat prin numerele +23, 23, 023 etc. n

Pascal Oregon numerele de tipul integer pot fi reprezentate i n baza 8, irul de cifre octale fiind urmat n acest caz de litera B (sau b). Spre exemplu +27 B , 27 b i 027 B snt reprezentri ale valorii 23.
Numerele de tipul real desemneaz numere raionale cu numr finit de zecimale. n mod uzual ele snt reprezentate prin numere fracionare (n baza 10) cu partea""fracionar separat de partea ntreag prin punct,,Spre exemplu prin

3.1415 este reprezentat aproximarea prin lips a numrului %. Punctai zecimal trebuie s fie precedat i urmat de cel puin o cifr zecimal. Astfel, 1. sau .1 snt reprezentri eronate pentru 1.0 i respectiv 0.1. n scrierea numerelor de tipul real se poate utiliza i un factor de scal. Acesta este un numr de tipul integer, precedat de litera E (sau e). El apare dup un numr de tipul integer sau un numr fracionar i are urmtorul efect: valoarea numrului de tipul real este valoarea numrului ntreg sau a celui fracionar, nmulit cu 10 la puterea dat de factorul de scal. Spre exemplu 31415 E -4, 314.15 E -2, 0.31415 E 1, 0.31415 E +leta., reprezint aceeai aproximare a numrului 7 C . Numerele de tipul real pot fi precedate de semnele + sau -. irurile de caractere snt iruri de caractere imprimabile, delimitate de apostrof. n irul de caractere, apostroful apare dublat. Exemple: ' i r de c a r a c t e r e IMPRIMABILE ' ' APOSTROFUL ESTE ' ' ' Etichetele snt iruri de cifre zecimale. Exemple: 1, 01,20, 0. De notat c 1 i 01 reprezint aceeai etichet. Comentariile snt iruri de caractere precedate de { i urmate de }. Directivele snt cuvintele rezervate forward, externai, nonpascal (vezi capitolul 4) i %include (vezi capitolul 7). In scrierea oricrei uniti lexicale ce nu este literal alfanumeric nu se face distincie ntre litere mari i litere mici. Astfel, identificatorul SUMA este identic cu Suma, dar literalele alfanumerice 'SUMA' i 'Suma' snt distincte. De asemenea orice unitate lexical (cu excepia comentariilor) se scrie pe o singur linie. ' ;-, Exemplu: Urmtorul mod de scriere a identificatorului SUMA: su MA . nu este permis. La scrierea consecutiv a identificatorilor, a cuvintelor cheie, a literalelor numerice fr semn i a celor alfanumerice, nceputul unei uniti lexicale ar putea fi luat n unele cazuri drept o continuare a celei precedente. n aceast situaie, ntre ele se insereaz spaii (caracterul ' ') caractere de tabulare (ht din tabela ASCII) sau de salt la rnd nou (f f i cr n aceeai tabel). Trebuie observat c simbolurile speciale compuse de forma o, < = etc., identificatorii i literalele numerice snt uniti lexicale ale programului; deci nu se pot introduce spaii ntre caracterele componente. Exemplu: nu se poate scrie < > , < = , su MA , I 23 pentru o, <=, SUMA i 123 .
Uiii '.

.'

ii

13.

Sintaxa limbajului

Prin sintaxa unui limbaj de programare se nelege, n general, un ansamblu de reguli de agregare a unitilor lexicale pentru a forma structuri mai complexe (instruciuni, declaraii, programe, etc). Spre exemplu, n introducere a fost prezentat forma general a unui program Pascal: un antet, urmat de o parte declarativ i de o instruciune compus. Pentru descrierea n detaliu a acestor componente snt necesare desigur alte reguli. Prezentarea n limbaj natural a acestor reguli poate conduce la neclariti sau la specificri incomplete. Ne-am putea ntreba spre exemplu dac prezena antetului unui program este

18

Limbajul Pascal

- Concepte fundamentale

obligatorie etc. De asemenea, prin aceast prezentare nu este posibil o verificare complet a corectitudinii unui program. n 1959 este prezentat de ctre J. Backus o descriere a sintaxei limbajului Aigol60 printr-un ansamblu de reguli formale [Back59]. Notaia utilizat a devenit cunoscut sub numele de notaie BNF (Backus-Naur-Form) i are aceeai putere generativ [GR62] cu gramaticile independente de context introduse de N. Chomsky [Ch59]. Au fost dezvoltate i alte variante echivalente de specificare a sintaxei, precum formalismul de descriere a sintaxei limbajelor Cobol i PL/I [Sam78] i diagramele sintactice pentru definirea sintaxei limbajului Pascal [Wi72] i FORTRAN [ANSI78J.

1.3.1. Formalismul BNF


Deoarece majoritatea limbajelor de programare nu snt independente de context [F166], prin notaia BNF se obine o descriere incomplet, referitoare doar la aspectele de sintax ale limbajului. Cu toate acestea, datorit simplitii sale, formalismul a cptat o larg popularitate, rspunznd att dezideratelor impuse de fazele de proiectare i implementare a unui limbaj de programare, ct i cerinelor utilizatorilor. Varianta de formalism BNF utilizat n aceast prezentare folosete urmtoarele opt metasimboluri: < > | { 1 [ ]

pentru a defini uhitile sintactice ale limbajului Pascal. O unitate sintactic este o mulime de fraze alctuite din elemente ale vocabularului. Metasimbolurile < i > snt utilizate pentru delimitarea numelui unei uniti sintactice. u >;.Exemplu. Unitatea sintactic <program> are numele program i este mulimea tuturor programelor Pascal; <expresie> este mulimea tuturor expresiilor ce apar n programele Pascal. Pe mulimea unitilor sintactice este definit o operaie de concatenare prin <uxv> - {xy | x din <u>, y din <v>i unde xy este o fraz obinut prin adugarea frazei y la sfritul frazei x. Aceast operaie este asociativ i are elementul neutru <empty> (unitatea sintactic ce nu conine nici o fraz). Exemplu: dac + aparine lui <semn> i (a b) aparine lui <termen> atunci + (a * b) este n <semn><termen>. Metasimbolul ::= apare dup o unitate sintactic i are sensul "unitatea sintactic este definit prin". Exemplu. Definiiile urmtoare: <termen> : : - < f a c t o r > < r e s t termen> <rest termen)::^ <operator multiplicativ> <factor><rest termen> <rest termen>: : - <empty> T "

au semnificaia: un termen este o succesiune de unul sau mai muli factori, desprii printr-un operator multiplicativ. Metasimbolul | este utilizat pentru a delimita ntre ele mai multe variante de definire a unei uniti sintactice. Unitatea sintactic definit este obinut prin reuniunea variantelor. Exemplu. Unitatea sintactic <rest termen}.- <mai poate fi definit si prin 'i i ' . <rest termen)::<empty> | <operator multiplicativ) <factox> <rest.termen) iar definiia
:

< o p e r a t o r m u l t i p l i c a t i v ) ::- * | / | div | mod | and precizeaz care snt cei cinci operatori multiplicativi. ; ,, Metasimbolurile { i } denot repetarea posibil (de zero sau mai multe ori) a simbolurilor pe care le delimiteaz. n general, <u) :.:= { <v) ) se folosete ca prescurtare pentru definiia recuri v .-v<u> ::= <u)<v> | <empty) v-. Exemplu. Definiia unitii sintactice < termen > din exemplele anterioare mai poate fi scris sub forma <termen>::=<factor> <operator multiplicativ) <factor> Exemplu: Definiia Cidentificator> : : = <litera> { <litera> | <cifra> ] _ }

are semnificaia: un identificator ncepe cu o liter; dup aceast liter poate urma o secven finit de litere,cifre sau caractere *_*. Astfel, A, a l , A 1 B , Al_b snt conforme cu aceast definiie, dar 2 A nu. Metasimbolurile [ i 3 denot prezena opional a simbolurilor pe care le limiteaz. Spre exemplu, definiia < unu > [ + | --] l definete unitatea sintactic ce conine elementele +1, - l i 1. O definiie n notaia BNF poate fi privit ca o expresie n care snt evaluai, n aceast ordine de prioritate, operatorii concatenare, | i : : = , cu convenia uzual n ceea ce privete parantezele (, } i [ , ] . Sintaxa limbajului Pascal, n notaie BNF, este dat n anexa 2. Frazele unitii sintactice <program> se numesc programe Pascal corecte sintactic. Exemplu. Urmtoarele fraze p r o g r a m A (I ) ; b e g i n e n d . program A (I, O); begin begin end end. snt programe Pascal corecte sintactic. Simbolurile { , } , [ i ] utilizate n notaia BNF snt n acelai timp i elemente ale vocabularului limbajului Pascal. Pentru a evita confuziile, n anexa 2 aceste simboluri, ca elemente ale vocabularului, snt redate prin simbolurile echivalente ( * , * ) , ( . i respectiv . ) . n programele Pascal pot fi utilizate ambele variante.

20

Limbajul Pascal

- Concepte fundamentale

n notaia BNF se poate specifica i vocabularul unui limbaj de programare dac prin <u> desemnm unitatea lexical u. Vocabularul limbajului Pascal este descris in notaie BNF n anexa 1.

1.3.2. Diagrame sintactice

Prin diagrame sintactice se realizeaz o reprezentare mai intuitiv a sintaxei unui limbaj independent de context dect cea dat de notaia BNF. Au fost utilizate pentru prima dat pentru definirea sintaxei limbajului Pascal [Wi73J. Notaia prin diagrame poate fi derivat din notaia BNF n modul urmtor. 1.4. Exerciii O definiie de forma <u> : <u> -------> x_l --------> . . . ---------> x _ n -----> iar o definiie de forma <u> :: - x_l | x_2 . . . | x_n prin diagrama x_l ... 11

x_n se reprezint prin diagrama

<u> ------> x_l---------------,------> I-------> X 2 --------1

-------> x_n --------1 Definiia <u> : : = x { yx { se reprezint prin <u> I --- - -> * ------1 --------> 1-------- y <-----J < U ^ : : = [ X ] prin <U> -------1- - -> X ----1-----> L ______________I
F
1

iar

Exemplu. Unitatea sintactica <r.ertnen> poate fi definit prin diagrama <termen> ------1----------------> < f a c t o r > -------------------------1-----> l ----- < o p e r a t o r m u l t i p l i c a t i v > <----------1 iar <identif icator> prin <xdentificator> ----------------------------> < l i t e r a > ---------1--------: -----------i < l i t e r a > <------j < c i f r a > < <-------U Sintaxa limbajului Pascal este definit cu ajutorul diagramelor sintactice n anexa 3.

I A . Exerciii
1. Limbajul Pascal are cuvinte rezervate. Dar FORTRAN? Dai exemple de limbaje care au cuvinte rezervate.

2. Care dintre urmtorii identificatori snt coreci: Pascal, PASCAL ,


p_l. Identificator_f oar te_lung_dar__, $ 1 , $_ 1, P_-

$ PASCAL ,

PI ,

1P,

3. Limbajul Ada [Ada83] definete instruciunea if astfel:


<if_stmt> ::= i f < c o n d i t i o n > then < s o q _ o f _ s t m t s > < i f _ a l t e r . n a t i v e > endif <if_atternative> ::- (<elsif_alternative>} [else < s e q _ o f _ s t m t s > J < e l s i f _ a l t e r n a t i v e > : : e l s i f < c o n d i t i o n > then < s e q _ o f _ s t m t s > Rescriei aceast notaie BNF prin diagrame sintactice echivalente. 4. Fie urmtoarele diagrame sintactice:
A B

- - - -,--------------,-- - -> I---B

,-------> <'

C "------,-- - ->

'------- c <-------1

Scriei n notaia BNF definiiile acestor diagrame. 5. Fie diagramele urmtoare: " A -i i' -4i
I ----- B

'

-------------,-----------------------------------------------i--------------->

---------> C ------> D

<--- -

Snt acestea echivalente cu


A

>

---- C < D <-l 6. Care dintre exemplele urmtoare snt programe Pascal corecte sintactic (vezi anexele 1 i 2) ? a) program E X E M P L U ;

b)

const type const var begin


X Y

- 1; T = 0 .. 2; C A; X, Y : T;

c)

:- A + 1; : = A *

end. d) Programul obinut prin concatenarea exemplelor a, b i c.

TIPURI DE DATE, VARIABILE, CONSTANTE, ETICHETE, EXPRESII

22

Limbajul Pascal

- Concepte fundamentale

Un program n limbajul Pascal conine o descriere a aciunilor ce trebuie s fie executate de calculator i o descriere a datelor ce snt manevrate de aceste aciuni. Aciunile snt descrise prin instruciuni, iar datele prin declaraii (sau definiii). Prin tip de date se nelege o mulime de valori. Pe tipurile de date ale unui program se definesc o serie de operaii, rezultatul fiind o algebr multisortat [ADJ77] avnd ca domenii aceste tipuriijSe disting trei categorii de tipuri de date: sjmple (elementare), compuse (structurate) i de referin (pointer). n general, tipurile de date snt definite explicit prin declaraiile type iar operaiile asociate prin declaraiile f unction sau procedura i snt specifice programului n care ajpar.: Exist ns tipuri de date elementare de interes mai general, numite tipuri predefinite a cror definiie se consider cunoscut i nu cade n sarcina programatorului. O serie de operaii relative la aceste tipuri snt de asemenea predefiit. .Valorile unui tip de date snt referite prin variabile sau constante. Anumite constante snt predefinite (vezi anexa 4). O declaraie de tip este de forma type
I

- T;

unde I este un identificator numit numele tipului, iar T specificaia sa (vezi anexa 3, diagrama 3.7). Declaraia variabilelor este precedat de cuvntul cheie var, a constantelor de cuvntul cheie const, iar a etichetelor, de ciivntul cheie labei (vezi anexa 3, diagramele 3,8, 3.6, 3.5). Numele I poate fi folosit pentm referirea la tipul T in declaraiile ulterioare de variabile sau pentru definirea altor tipuri. Exista ns tipuri de date anonime, definite implicit prin declaraii de variabile de forma var v_l, . . . , v_n : T ; Exemplu. Prin labei 1 , 1 0 ; type bin = 0. . 1; var bit. : bin; c i f r a : 0 . . 9 ; const z e r o - 0 ; var i : integer; s-au definit: etichetele 1 i i o , tipul b i n cu elementele 0 i i, variabila b i t de tipul bi n, variabila cifr de tipul anonim o. variabila i de tipul predefina integer precum i constanta zero avnd valoarea 0.

2.1. Tipuri de date simple


Tipurile simple snt de trei categorii: predefinite, subdomeniu. Tipurile simple se mai numesc i tipuri scalare. enumerare i

2.1.1. Tipuri de date predefinite


Exist cinci tipuri de date predefinite: integer, real, boolean, char i text. - Tipul integer este o mulime de numere ntregi cuprinse ntre cel mai mic i cel mat mare numr ntreg ce se pot reprezenta pe un calculator gazd al limbajului. Valoarea maxim admis poate fi referit prin constanta predefinit

ataxint, iar valoarea minim este - m a x i n t . In implementarea Pascal Oregon, maxint este 32767, iar valoarea minim este -maxint -1. Elementele de acest tip se reprezint n programele Pascal prin literale numerice de forma i, unde i este numr ntreg n reprezentare zecimal (eventual precedat de semnul + sau -) sau de forma i 13, unde i este numr ntreg n baza 8 (reprezentare octal, eventual cu semn). Spre exemplu, elementul -15 al tipului integer poate fi reprezentat prin literalele -15 sau - l7B.

Reprezentarea intern (fornui de memorare) a elementelor de acest tip se face n cod complementar pe cuvinte de 2 bytes [PDP76J. Fie
x reprezentarea n baza 2 a unui numr ntreg. Reprezentarea n cod complementar a lui x este f x rc(x) - j l _ 2 " - | x | dac x < 0 i 2 " - | x | 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 f x dac 0 < x < 2i,-l H L 2 l t e + x dac 2" < x < o d a c 0 < x < 0 111 3 11 11.1 i i i m

De exemplu -9 se reprezint prin 2l6-9, adic 177767 (n octal), iar 9 prin 000011 (n octal). Rezult c cel mai mare numr reprezentabil n cod complementar este 2lM, adic 32767 (maxint); cel mai mic numr este -21S, adic -32768. Tipul real este mulimea de numere reale { x f x - 0 , x 0Xi. . . x - b* i x . s n t c i f r e n b a z a b i l,SeSl,J unde baza b a sistemului de numeraie, limitele lt i 1 ale exponentului e i numrul n + l de cifre ale prii fracionare snt dependente de implementare iar x0*o pentru x*o. n cazul de fal, b = 2 , -128 e < 127, iar n - 2 3 (sau, opional, n = 5 5 - vezi cap. 7, opiunea / DOUBLE ). Elementele tipului real se reprezint n programe prin literale numerice de formele i. f, i. f Es sau iEs, eventual precedate de semnul + sau -, unde i i f snt numere zecimale ntregi fr semn reprezentnd partea ntreag i respectiv partea fracionar a literalului numeric. Dac este specificat i factorul de scal s (zecimal ntreg, eventual cu semn), atunci literalul reprezint valoarea real i, f io" sau i r io?. Spre exemplu, elementul -0,25 al tipului real poate apare n programe Pascal n una din formele -0.25, -25E-2, -25.0E-2 etc. Se observ c n programele Pascal elementele tipului real se presupun a fi scrise n baza 10.

Reprezentarea (memorarea) acestora n calculator se face n virgul mobil pe 2 cuvinte (32 bii - simpl precizie) sau pe 4 cuvinte (64 bii - dubl precizie). Poziia binar 15 (prima din sting, n notaia uzual) a primului cuvnt este a semnului, n poziiile 7-14 ale primului cuvnt se memoreaz caracteristica (exponentul mrit cu 128), iar n rest se memoreaz mantisa (partea fracionar fr prima poziie dup virgul; numrul real fiind normalizat, aceast poziie este 1, cu excepia numrului real 0). De exemplu +1.0 se scrie 0,1-2' (adic xc=l, b=2 i e-l);
caracteristica este c = l?B+e ~ 27+.l = o o o o o o i . Deci primul cuvnt al

24

Limbajul Pascal

- Concepte fundamentale

reprezentrii n calculator este o 10000001 o o o o o o o , iar al doilea cuvnt este o o o o o o o o o o o o o o o o (n baza 2). Reprezentarea octal este 4 0200, respectiv o. n mod analog, -5.0 se va reprezenta prin numerele octale 14 0 6 4 0 i o. Cel mai mare numr real reprezentabil n simpl precizie este 0 , l l l l . l l l l l l J . l l l l l l l l l - l l . i l . ' 2.A-,*l- 2'27*1038. Cel mai mic numr real pozitiv reprezentabil este 123 0,1-2'127=2 ip3% . Numerele reale de fonna o, l x t . . . x2, mpart intervalul n 223 subintervale de lungime (l-^)'2"23=224. n consecin, eroarea maxim de aproximare a unui numr real printr-un numr real reprezentabil este zS-2"2* < IO"7. De aici rezult o precizie de 7 cifre zecimale semnificative pentru numerele reale reprezentate n precizie simpl. --. Tipul boolean conine dou elemente referite prin constantele predefinite false i true. Operaiile predefinite ale acestui tip (and, or i not) definesc o structur de algebr booleana. Tipul char este o mulime finit i ordonat de caractere ce conine, printre altele, litere, cifre i caracterul spaiu. n cazul de fa, toate caracterele ASCII (vezi paragraful 1.1) aparin tipului c h a r . n programe, un element al acestui tip se desemneaz prin includerea caracterului ntre dou semne ' (apostrof). Spre exemplu, ' A ' , ' 0 ' , ' + ' , ' ' desemneaz litera A, cifra o, caracterul + i caracterul spaiu. Caracterul ' se reprezint prin

Reprezentarea intern a unui element de acest tip se face pe I byte i are ca valoare codul ASCII al caracterului respectiv (paragraful LI). Primul
caracter al tabelei are numrul de ordine 0.
. c.

-Tipul text va fi prezentat n paragraful 2.2.4.1.2. Exist de asemenea o serie de operaii predefinite n care snt implicate tipurile de date descrise anterior. Ele snt desemnate prin operatori i funcii predefinite. Astfel, operatorii binari (adunare), - (scdere), * (nmulire) i / (mprire) pot avea operanzi de tipul integer sau r e a l . n cazul operatorului / rezultatul este totdeauna de tipul r e a l . Pentru +, - i * rezultatul este de tipul integer dac ambii operanzi snt din integer i este de tipul real dac cel puin unul din operanzi este de tipul r e a l . Pentru mprirea prin trunchiere a valorilor din tipul integer se utilizeaz operatorul dlv. Astfel, a div b - n dac: 1) 2' 0- i n < n +1 sau 2) < 0 i n- l < g Sn. Deci -13 div 2 este -6. Fie a , b z , b*o. Se noteaz prin q ctul i prin r restul mpririi ntregi a lui a la b (a - b * q + r , 0< = r < abs ( b ) ); He rem - a - ( a div b ) * b. Dac a o sau b divide pe a, atunci q - a div b i r - rem. n caz contrar, q = a div b - s i g n (b) i r = rem + abs ( b ) . Pentru calculul expresiei r e m se poate utiliza operatorul nod. n limbajul standard [JeWi85], a mod b m r e m dac ai.0 sau b divide pe a i a mod b = rem + b n caz contrar. n implementarea Pascal-Oregon, a mod b - rem n ambele cazuri n consecin, n implementarea Pascal-Oregon q i r se calculeaz prin

instruciunile urmtoare:
q : - a div b ; r : = a mod b; it ( a < 0) and ( r O 0) than begin

r : = r + abs( y ) ; ii b < 0 then q : = q + 1 else q : = q - 1 end n limbajul standard, q i r se calculeaz prin: q : = a div b ; r : a mod b ; if. ( a < 0) and ( r O 0) then if b > 0 then q q-1 else begin q : - q + l ; r : - r - 2 * b end Exemplu: begin 3); w r i t e l n C 8 div 3 = , 8 div 3); writelnC-8 div 3 = , - 8 div 8 div (-3)); writelnC 8 div -3' (-3)); writelnC-8 div - 3 - ' - 8 div 8 mod 3): writelnC 8 mod 3-' w r i t e l n ( ' - 8 mod 3 = ' , - 8 nod 3}.;:*. w r i t e l n C 8 mod - 3 - ' , 8 nod ( - 3 ) ) ; w r i t e l n C - 8 mod - 3 - ' , - 8 nod ( - 3 ) ) ; end. '4 - - ' :' -ii .; * . TOt ;>' V - -" ilustreaz aplicarea operatorilor div i mod. Operatorii relaionali uzuali , o (diferit de), <, < (mai mic sau egal), >, > conduc la rezultate de tip boolean. Ambii operanzi trebuie s fie de acelai tip (integer, r e a l , char sau boolean). Ca excepie, se admite in locul unui operand de tipul r e a l un operand de tipul integer. Pe tipurile integer i real relaia de ordine <* este cea uzual; elementele tipului char snt ordonate prin valorile asociate n codul ASCII, iar f a l s e < tiue. . Operatorii not, and i or se aplic asupra operanzilor de tip boolean, cu semnificaia logic uzual. n plus, operanzii pot fi i de tip integer; rezultatul este

tot de tip integer i se obine prin aplicarea operatorilor respectivi asupra reprezentrii binare a operanzilor bit cu bit. Spre exemplu, not a este - 2, 6 ox 3 este
7, 6 and 3 este 2. Alte operaii snt implementate prin funcii pnedefinite. Spre exemplu, abs ( x ) este valoarea absolut a lui x, iar sqr ( x ) este ptratul lui x. Tipul rezultatelor este acelai cu tipul argumentului x, care poate fi integer sau real. Urmtoarele funcii: s i n , c o s , a r c t a n , exp (exponeniala de baz e), In, s q x t (rdcina ptrata) admit argumente de tipul Integer sau r e a l , dar rezultatul este totdeauna de tipul real. Predicatul odd (x.;, cu argument de tip integer ia valoarea t r u e dac x este impar i f a l s e n caz contrar. Trunchierea i rotunjirea numerelor reale se realizeaz prin funciile trunc i respectiv round. Astfel, t r u n c ( x ) -n dac x este de tipul real, n numr ntreg i nix<n+l n cazul cnd x kosaun- l < x S n n cazul cnd x < 0. De asemenea, round ( x ) este t r u n c ( x +0.5) pentru x^o i trunc ( x - o. 5) pentru x <0. Pentru tipurile integer, char i boolean exist funciile succ (succesor) i pred (predecesor), cu semnificaia uzual. Funcia bijectiv ord, cu argument de tip char ia valori de tip integer cuprinse ntre 0 i 127 i realizeaz codificarea caracterelor. Spre exemplu, ord('0' ) = 4 8 , ord( ' 1' ) - 4 9 etc., o r d ( ' A ' ) = 6 5 , o r d ( ' B ' ) - 6 6 etc.. Inversa acestei funcii este c h r . De fapt, relaia de ordine o pe mulimea char este definit astfel: a <- b dac i numai dac ord ( a ) < - o r d ( b ) . De asemenea, pred ( c ) -chr ( o r d ( c ) -1) i s u c c ( c ) =chr ( o r d ( c ) + l ) . Toate aceste operaii snt prezentate sintetic n anexa 4.

26

Limbajul Pascal

- Concepte fundamentale

Trebuie remarcat c tipurile de date snt mulimi finite, prin urmare cea mai mare parte a operaiilor discutate anterior snt doar parial definite; spre exemplu, succ (maxint) , maxint+1, pred ( - maxint -1) etc, nu au sens. n general operaiile nu snt definite pentru acele argumente care provoac depirea limitelor impuse de tipurile de date. Executarea programelor n aceste situaii conduce la obinerea unor rezultate incorecte. Evitarea acestor cazuri este n sarcina programatorului, deoarece numai o parte a lor este sesizat i semnalat de calculator. Tipurile de date i operaiile predefinite prezint o seric de abateri de la proprietile matematice cunoscute. Astfel, tipul integer nu este considerat o submulime a tipului rea 1, datorit modurilor diferite de reprezentare n calculator. Acest fapt este reflectat n programe prin forma diferit a literalelor cate desemneaz elementele celor dou tipuri (spre exemplu, numrul real 1 se reprezint prin 1.0). Pentru a corecta aceast anomalie, operaiile asociate tipului real snt extinse astfel nct admit i operanzi de tip integer; n acest caz, calculatorul realizeaz o conversie de la reprezentarea integer la cea de tip real. Spre exemplu, operaia 1/2 este precedat de conversia lui 1 n 1.0 i a lui 2 n 2.0. Aceast conversie nu cade n sarcina programatorului. De asemenea, multe proprieti familiare ale operaiilor nu se mai pstreaz. Astfel, adunarea ntregilor nu este totdeauna asociativ; spre exemplu, maxint+(maxintmaxint) d rezultatul maxint, dar (maxint maxint) - maxint conduce la depirea limitelor tipului integer. Totui, cu excepia cazului n care apare depirea limitelor, axiomele aritmeticii numerelor ntregi se consider a fi satisfcute pentru tipul integer, cu operaiile predefinite ataate. Deoarece depirea este semnalat de calculator, se poate presupune c un program care s-a terminat fat aceast eroare a executat operaiile asupra tipului integer respectnd proprietile matematice uzuale. Situaia este mai complicat n cazul tipului real, deoarece astfel de abateri pot apare n absena fenomenului de depire a limitelor. Pentru ilustrare, s considerm ca reprezentare a tipului real mulimea {x | x-i o, XgXiXgX, io*}. Fie elementele x-o,9554IO0, y = 0,3000* 10 i z - -0,2555*10 de acest tip. Dac se evalueaz n aceast reprezentare expresia x (y + z) se obine rezultatul corect 0.9999. ntr-adevr, s = y+ + z = 0,0445 i se reprezint prin 0,4450*IO" 1, iar x + s - 0.9999 i se reprezint prin o,9 9 9 9 io0. Pentru expresia (x + y)+z, suma s=x+y-i,2554 i se reprezint prin 0,9995*10. Aceasta este o aproximare a rezultatului corect Estimarea erorilor de calcul n cazul tipului real cade n responsabilitatea programatorului. Urmtorul exemplu ilustreaz utilizarea variabilelor de tipurile prezentate mai sus, precum i a operatorilor i funciilor predefinite asociate. Exemplu: var a : integer; " b ! real; c : char; d : boolean; bagin c := 'X';

nd.

b- 1.5; .-a- a + trunc(-b) round(b);a- a nod a div a: ord('X'); bsucc(a) + b /b pred(succ(a));cchr(ord(c)); d- (b <write(a, b, c, d) b) andtrue;

2.1.2. Tipuri de date enumerare


Un tip enumerare este o mulime ordonat de valori specificate prin identificatori. Aceast specificare are forma (identificator_l,...,identificator_n) i induce o relaie de ordine astfel c identificator_i < identificator_jj pentru i < j. Spre exemplu, tipul predefinit boolean poate fi specificat i ca tip enumerare prin typ boolean ( f a l s e , t r u e ) ; Elementele unui tip de date enumerare E sint identificatori ce constituie mulimea valorilor hii E. De exemplu, dac se definete tipul type EN - (unu, doi, trei); atunci elementele acestui tip sint u n u , doi i trei. Operaiile aplicabile elementelor de tip enumerare sint cele relaionale specificate n paragraful anterior (<, < = etc). De asemenea, se pot aplica funciile predefinite succ, pred i ord (astfel, ord (identif icator_l) - 0). Identificatorii ce apar n definiia unui tip de date enumerare urmeaz regulile obinuite de valabilitate (vezi paragraful 4.5.4). Exemplu: type luni - ( i a n , luni; b : boolean; begin w r i t e l n (ord( i a n ) ) ; L : - feb; X pred(L); Y succ(X); b X < Y; w r i t e l n ( b , f e b < o c t , i a n = dec) end. Observaie. Variabilele de tip enumerare nu pot apare in instruciunile de intrare - ieire; ele pot ti utilizate, spre exemplu, pentru indexarea tablourilor.

feb, m a r , a p r , m a i , iun, i u l , aug, sep, o c t , nov, d e c ) ; var L , X , Y , z :

2.1.3. Tipul de date subdomeniu

28

Limbajul Pascal

- Concepte fundamentale

Un tip subdomeniu este o parte a unui tip deja definit. Tipul subdomeniu se poate introduce pentru orice tip scalar n afar de r e a l . Specificarea acestui tip se tace prin: <constanta>..<constanta> unde prin cele dou constante se definete un interval^ ce conine valorile subdomeniului. Un subdomeniu se poate indica i ca un tip anonim asociat unor variabile n declaraii de tipul: var v__l, . . . , v_n : c_l. .c_2 Operatorii i funciile prdfini te care se pot aplica operanzilor de tip subdomeniu snt cele asociate tipului n care acesta este inclus. n cazul

implementrii de fa se poate defini un tip ntreg fr senin care nu este un subdomeniu al tipului prdfinit integer. Acest tip are ca mulime de valori numerele ntregi x, cu proprietatea o. <= x < = 6 5 5 3 5 , iar operaiile cu care este nzestrat snt cele ale tipului i n t e g e r .
Exemplu. ,type T = "IO..10; natural = 0..65535;
m f

,:. _

b : natural;

^ ;:,

c, a :
begin

a .. a ;
+ 1;

a : 0 ; a : = succ( p r e d ( a ) ) ; b 65535; b := pred(b) c := 'a'; d = 'd'; writeln(a,b,c,d); c : = chr( s u c c ( o r d ( c ) ) ) ; d chr(pred( o r d ( d ) ) ) ; wiiteln(cd)

Observaie. Toate tipurile de date simple snt mulimi finite i ordonate de valori. Tipurile de date simple diferite de r e a l se mai numesc i tipuri ordinale. O caracteristic a acestor tipuri este prezena operaiilor predecesor (pred) i succesor (succ). Pentru tipurile ordinale diferite de integer i care nu snt subdomenii ale acestuia se poate aplica funcia bijectiv o r d care asociaz valorilor tipului numerele naturale 0,1 etc. Relaia de ordine este cea indus de funcia ord i este notat prin <.

2.2. Tipuri de date structurate


Tipurile de date structurate snt agregri ale unor tipuri de date deja definite (simple sau structurare). Tipurile de date structurate care se pot defini n limbajul Pascal snt urmtoarele: azzay, record, set i file. r&'* . - v-JidssKv ei -. ' .-ii-.- ;. ' 'ijtariti* *>f5>ifsc-..-; jmm Jv fi 9io : *j* .a s, ,.>a

2.2.1. Tipul de date array (tablou)


Re T un tip de date oarecare i I un tip scalar diferit de integer i r e a l . T se numete tip de baz iar I mulime de indici. . Prin tip de date azzay cu indici din I i elemente din t se nelege mulimea de funcii A = { x | x :; I > T ), care se noteaz ( I --> T ) .

Elementele tipului azzay se numesc tablouri. Un tip azzay poate fi specificat prin azzay ti] of T sau packed azzay [I ] of T Tipurile I i T pot fi predefinite, anonime sau definiia lor trebuie s precead, n textul programului, definiia tipului azzay. Dac x este numele unei variabile sau constante de tip azzay, atunci elementul x ( i ) se noteaz n programe prin x [ i ] . Atributul packed indic n general cerina de optimizare a spaiului de memorare pentru elementele tipului azzay. Un caz special l reprezint tipurile de date string (ir de caractere), declarate prin packed azzay [ I ] of char eo
M

Elementele de tipul string, avnd acelai numr de componente pot s apar n instruciuni de atribuire i de asemenea pot fi asociate cu operatori relaionali ( = , O , < , > , < = , >= ).
za?

Elementele acestui tip pot s apar ca argumente n procedurile standard xead i write. Exemplu. Prin programul var a , b : packed arxay [ 1 . . 7 ] of c h a r ; begin a :- ' l o n e s c u ' ; b 'Popescu'; if a < b then w r i t e l n ( b ) else w r i t e l n ('eroare') nd. se realizeaz atribuirea irurilor de caractere ' lonescu' , ' popescu' variabilelor a i respectiv b, iar n urma executrii instruciunii if se tiprete irul de caractere ' Popescu'. Trebuie menionat c dac a i b ar fi fost declarate tar atributul packed atunci expresia a < b i instruciunea w r i t e l n ( b ) nu ar mai fi avut sens, necesitind substituirea referirilor la variabilele a, b cu referiri la componente ale acestora. Optimizarea spaiului de memorie ocupat de elemente de tipul packed azray poate provoca accesul ineficient la componentele acestora. Din acest motiv, se recomand efectuarea unei operaii de despachetare a acestor elemente prin invocarea procedurii predefinite unpack, nainte de prelucrarea elementelor lor. Dup aceast prelucrare, spaiul de memorie ocupat de elementele respective poate fi din nou optimizat prin operaia de mpachetare apelnd procedura predefinit pack. Re i.
. . . .

A : array ( m . . n ] of T ; B : packed axzay [ u . . v ] of T ; in-m >= v - u . Dacm <= i <= n, atunci prin operaia de mpachetare pack (A, i , B) tabloul B ia valorile B t j ] - A [ j - u + i ] pentru u <- j <= v, iar prin operaia de despachetare unpack( B , A , i ) tabloul A ia valorile A [ j ] - B [ j + u - i ] , pentru i < = j <= i+vru.

Elementele tipului array pot apare n programe sub form de constante structurate (vezi anexa 3, diagrama 3.9). Spre exemplu, dac A desemneaz un

30

Limbajul Pascal

- Concepte fundamentale

tip array definit prin type A = axzay [ 1 . . 5 ] of integer, atunci A ( 1 , o, 2, -1, 3) este un element al acestui tip.
Exemplu. Fie programul type A 2E-1); cb - B ( l . l , 2 . 1 , 0 . 1 , 3 . 1 , 2 E - 1 ) ; Var : A; y i begin writeln(ca[l], cb[l]); X ;= ca; y := cb; fox i : = 1 to 5 do writeln(x[i], y[i-2]) end. Snt definite aici dou tipuri azxay (a si B) ale cror elemente reprezint vectori, avnd cte 5 componente numere reale. n timp ce componentele variabilei x i ale constantei ca snt referite n program prin x [l ] , . . . , x [ 5 ] i respectiv ca [1], ca 12] etc., cele ale lui y i c b snt referite prin y [ - 1 ] , t . . , y [ 3 ] , respectiv c b [ -1], cb [ol, etc. Constantele ca i cb, dei conin aceleai componente, snt totui de tipuri diferite. Exemplu. type T - ( r o u , verde, a l b a s t r u ) ; vax e : axxaytT] of integer; begin e [ r o s u ] : = 1; e [ s u c c ( r o u ) 3 '" succ ( e [ r o u ] ) ; e[albastru] := 3; writeln(e[verde]) [valoarea 2} end. Exemplu. Fie programul vax a , b : paeked axzay [ i . .1] of c h a r ; d : paeked azzay VI -- 2 ] of char ; c : c h a r ; begin b [ l ] : = ' a' ; [ ' a ' e s t e constanta d e t i p c h a r } d := ' a b ' ; { ' a b ' e s t e c o n s t a n t a de t i p s t r i n g } w r i t e l n ( b , d ) [ i r u r i de c a r a c t e r e i n w r i t e } end. Trebuie subliniat c tipul char nu este identic cu tipul paeked axxay [ 1 . . 1 ] of char. Astfel, instruciunea b 1 = ' a' este incorect, deoarece b este variabil de tipul ir de caractere, dar ' a' este constant de tipul char. Din acelai motiv i instruciunea b : - c este incorect. n exemplele de mai sus, tipul de baz a fost de fiecare dat un tip prdfinit (deci simplu). Considerm acum un exemplu n care tipul de baz este el nsui un tip structurat. type N - axxay [ 1 . . 3 ] of r e a l ; type M = axxay [1. . 2 ] of N; const C - M ( N (1.1, : B; : 1. . 5 ; x - arxay [ 1 . . 5 ] of r e a l ; B - axzay [ - 1 . . 3 ] of r e a l ; corist ca - A (1.1, 2 . 1, 0 . 1, 3 . 1,

1. 2 , 1. 3 ), N ( 2 .1, 2 . 2 , 2 . 3 ) ) ;

Elementele tipului M au cte 2 componente reprezenund la rndul lor vectori cu 3 componente. Fie o declaraie de forma type T = array[ i ] of array[J] of B; Elementele tipului T snt funcii avnd domeniul I i codomeniul ( J ------>B). Tipul T este deci mulimea de funcii ( i -------------> ( j -------> B ) ) . ntre mmimileT i u * ( I x J----------------> B) exist o coresponden bijectiv, deoarece unei funcii f e T i se poate asocia o funcie g e u, definit prin g ( i , j ) - f ( i ) ( j ) . n astfel de situaii se poate folosi declaraia n form prescurtat: type U = array [ I , J ] of B; Trebuie subliniat c tipurile T i u snt considerate totui distincte. Componentele unei variabile sau constante x de tipul T sau u pot ns s apar n programe n oricare din formele x [ i ] [ j] sau x [ i , j ] . Forma prescurtat a declaraiei de tip array se aplic i n cazul general. Astfel, o declaraie de forma &
:-{

i- ; array [T_0] of array[T_l, se poate scrie ca T _ k ] of T

. .

array [T_0, . . . , T_k] of T Deci x [ i _ o , i_i, . . . , i_k] are sensul x [i_p] [i_i, , i_k]. Exemplu. type B = array [1. . 3 ] of r e a l ;

T = array [1. . 2 ] of B; .H. U - "y 11. . 2 , 1. . 3 ] of r e a l ; const CT -= T ( B (1.1, 1. 2 , 1. 3 ) , B ( 2 .1, 2 . 2 , 2 . 3 ) ) ; CU 4 U ( ( l . l , 1. 2, 1. 3 ) , (2.1, 2 . 2, 2 . 3 ) ) ; var VB : B ; VT s T; VU : ti; begin VT : = CT; VU : = CU; w r i t e l n ( V T [ l ] [ 2 ] , VT[1, 2 ] > ;

32

Limbajul Pascal

- Concepte fundamentale

{ s e s c r i e de doua o r i valoarea
U((10.1,10.2,10.3),

w r i t e l n (VU[l,2}) end. Constantele CT i cu au proprietatea CT [ i ] [ j ] = C T [ i , j ] - CU[ i , j ] = CU[ i ] [ j ] pentru orice l <- i <= 2 s i 1 <= j <- 3. Ele snt totui de tipuri diferite; astfel, variabila VT de tipul T nu poate lua niciodat valoarea c u (de tipul u) dar poate lua valoarea CT. Exemplu. Mulimea matricilor ptrate de ordinul 2 cu elemente numere reale poate fi definit prin >
>r >

1.2} VU : = (20.1,20.2,20.3));

typa LINIE - azzay (1..2J of r e a l ; ' M2RA array [1. ,2] of L I N I E ; sau prin "' s:S.l.Si f^iftH^. . hx&. S^;^r.a.-., v. WI type M2RB = azzay [1..2] of azzay [1..2] of r e a l ; sau prescurtat prin type M2RC

-'rVfcfc

= azzay [1..2,
1 2

1..2] of r e a l ;

Deci matricea j

| poate fi descris in programe Pascal prin M2RA

(1.0,

3 4 2.0), LINIE(3.0, 4.0)), prin

( L I N I E d .0,

2.0), LINIE(3.0, 4.0)), prin M2RB ((1.0,2.0), (3.0, 4.0)), SOU prin M2RC ((1.0, 2.0), (3.0, 4.0)).
Exemplu. type M2RC - azzay [1..2,1..2] of r e a l ; const M
M2RC((1.0,

2.0),

{prima

(3.0, l i n i e : 1 , 2}

4.0));

{ a doua i i n i e : 3 , 4 } var 1: integer; begin foz 1:=1 to 2 do w r i t e l n (M[ l , l ] ) { s e s c r i u elementele de pe d i a g o n a l a p r i n c i p a l a } end. Exemplu. Acest program ilustreaz utilizarea irurilor de caractere: vaz s i r : packed azzay [1..4] of c h a r ; c o p i e : azzay [1..4] of c h a r ; i: integer; begin sir 'MASA'; unpack( s i r , c o p i e , 1); { s i r e s t e despachetat i n copie} copie[1] ' . - C i pack(copie, 1, sir); { i n s i r este impachetat c o p i e } writeln(sir) {scrie irul 'CASA'} end.

2.2.2. Tipul de date record (nregistrare)


Re tipurile de date Tx , . . . , Tm i identificatorii distinci s x , . . . , sm prin care snt notate proieciile canonice ale produsului cartezian 1\ x . . . x Tm. Spre exemplu, dac m = 2 i ( x , y ) Tx x T2, atunci s x ( x , y ) - x i s 3 ( x , y ) - y. Se numete tip de date record produsul cartezian Tt x. . . x Tn mpreun cu cele m operaii de selectare a componentelor, definite de proieciile canonice s x , . . . , s. Elementele unui astfel de tip se numesc articole. Forma sintactic a unei definiii de tip record este prezentat n anexa 3, diagramele 3.12-3.15. Elementele s j ( x ) apar n programe notate prin x . s . Exist posibilitatea de a omite n aceast notaie partea x . , prin utilizarea unei instruciuni with (vezi 3.2.4). Dac unul din tipurile T4 este de asemenea record i are proieciile ri, compunerea celor dou proiecii se noteaz prin sx. z
y

Exemplu. Mulimea numerelor complexe poate fi reprezentat n programe Pascal ca un tip de date record. Astfel, prin programul
*

type C - record r e , im : r e a l end; var x : C ; begin x.re:=l.0; x.im:=2.0 end. se definete tipul record cu numele c, avnd ca proiecii funciile r e i im. Tipurile si T, snt ambele r e a l . Partea real i partea imaginara a variabilei x apar n program n notaia x . r e i respectiv x.im. Exemplu. Fie programul type d a t a - record luna : ( i a n , f e b , m a r, a p r , m a i , i u n , i u l , a u g , s e p , o c t , n o i , d e c ) ; ziua ; 1 . . 3 1 ; a n u l : integer end; persoana = record nume: packed array [1..10] of c h a r ; d a t a n : data ____________________________22. Tipuri de date structurate_______________________27

34

Limbajul Pascal

- Concepte fundamentale

nd; var data_cr : d a t a ; p : persoana; begin data_cr.l u n a i a n ; data_cr.ziua:-24; data_cr. a n u l :-1859; p.nuine:-'IONESCU p.da ta_n.luna: = f e b ; p.data_n.ziua:=2; p.da ta_n.anu1: = 1947 nd. n acest program este introdus tipul record cu numele d a t a i cu proieciile luna, z i u a i anul. Tipul T x este un tip enumerare, T2 un tip subdomeniu, iar T, un tip predefinit Variabila data_cr are componentele data_cr. l u n a , d a t a _ c r . z i u a idata_cr.anul. Exemplu. Poziia unui punct material n spaiul cu trei dimensiuni poate fi descris n funcie de timp, prin elemente ale unui tip de date racord, n programul: fcype POZIIA = racord x, y, z : real; timp : 0 . . 3 6 0 0

and; var punct, origine : POZIIA; begin origine: = P O Z I T I A ( 0. 0 , 0 . 0 , 0 . 0 , 0 ) ; p u n c t . x : = 1 . 0 ; punct.y : = 1 . 0 ; punct.z: = 1 . 0 ; pune t.timp: - 19 89 and. Componentele variabilei punct se obin prin proieciile x , y , z i timp i snt urmtoarele: punct. x, punct.y, punct. z, i punet. timp.

Elementele unui tip de date record snt reprezentate n programe conform cu anexa 3, diagramele 3.9, 3.10. Astfel c ( 0 . o , 1 . 0 ) i C(1.0 , 2 . 0 ) snt articole ale tipului c reprezentind numerele complexe i i respectiv 1 + 2 i , data (aug, 2 , 1 9 8 8 ) este articol al tipului d a t a iar persoana (' POPESCU ' , d a t a ( i u l , l , 1 9 5 0 ) ) aparine tipului persoana.
Deci tipurile de date racord descriu elemente ale produsului cartezian T x x . . . x T f f Produsele carteziene T pot fi descrise i prin tipuri de date axray. Totui, tipul array nu este caz particular de tip record, pentru ^ = T , l < = i <= m, deoarece operaia de selectare a componentelor n cazul tipului de date array este mai general decit n cazul tipului racord ntr-adevr, indicele unui tip axxay poate fi orice tip scalar (diferit de i n t e g e r i r e a l ) n timp ce proieciile canonice ale unui tip record snt desemnate prin identificatori. Mai mult, un indice poate fi o expresie ce se evalueaz n timpul execuiei programului dar identificatorii ce indic proieciile canonice snt stabilii la momentul scrierii programului. Cazul particular de tip record obinut prin T4 = T, i < = i < = m poate fi definit ca un tip array, n care indicele este un tip enumerare. Astfel type RT = zacord x, y , z : T end; poate fi definit prin type AT = array [(x, y , z)] of T;

Bineneles, operaiile de selectare a componentelor se noteaz n mod diferit (v.x pentru v de tipul RT i v[x] pentru v de tipul AT). De asemenea, indicele unui element de tip AT se poate exprima prin expresii de genul pr ed ( y ) , s u c c ( p r e d ( y ) ), eto. Exist i o form mai general de tipuri record prin care se definesc reuniuni disjuncte de tipuri de date. Acestea se numesc tipuri de date record cu variante. Elementele unui astfel de tip snt articole ce conin o component prin care se identific tipul din care face parte articolul. Aceast component apare explicit n definiia tipului record cu variante dup cuvntul cheie case i se numete identificator de variant. Forma complet a unei definiii de tip record cu variante este dat n anexa 3, diagramele 3.12-3.15. Ca i n cazul tipului record fr variante, numele proieciilor canonice ale aceluiai tip trebuie s fie distincte ntre ele. Exemplu. Prin definiiile: type varianta - (a, b); T - 1 . . 2 ; U - 2 . . 3 ; reuniune_di s j record case v : v a r i a n t a of a : (X : T; y : U) ; b : (Z : U; W : T) and; se introduce tipul reuniune_dis j . Elementele acestui tip se reprezint n Pascal prin: r e u n i u n e _ d i s j (a, 1 , 2 ) reuniune_disj(b, 2 , 1 ) reuniune_disj(a, 1, 3 ) i reuniune_disj(b, 2 , 2 ) reuniune_disj (a, 2, 2) ieuniune_disj (a, 2, 3) reuniune_disj( b , 3 , 1 ) reuniune_disj( b , 3 , 2 ) .

Aceasta corespunde reuniunii disjuncte T x U U U x T. Se oberv c elementul ( 2 , 2 ), comun celor dou produse carteziene, apare dublat Operaiile de selectare a componentelor snt desemnate de identificatorii distinci ntre ei v, x, y, z i w. Exemplu. S presupunem c se dorete prelucrarea unor progresii geometrice i aritmetice. Identificm o progresie aritmetic prin elementul ( t , r ) e x e a l x r e a l reprezentind primul termen i raia. n mod analog, o progresie geometric se reprezint prin ( u , q ) r e a l x r e a l . Rezult c o progresie (aritmetic sau geometric) este un element al reuniunii disjuncte r e a l x real U r e a l x r e a l . n limbaj Pascal, urmtorul program ilustreaz prelucrarea progresiilor: type progresie = record case modul : ( a r , ge) of ar : (t, r : real); ge : (u, q ; real) end; var x : p r o g r e s i e ; begin X : = p r o g r e s i e ( a r , 1 . 0, 2 . 0 ) ; I p r o g r e s i e a r i t m e t i c a } w r i t e l n C termenul t _ 1 0 - ' , x . t + 9 * x . r ) ; x : = p r o g r e s i e ( g e , 1 . 0 , 2 . 0 ) ; { p r o g r e s i e g e o m e t r i c a } w r i t e l n ( ' termenul u_3 = ' , x.u*sqr(x.q)) end. Elementele acestui tip snt articole de forma p r o g r e s i e ( a r , t , r ) pentru progresiile aritmetice i de forma p r o g r e s i e ( g e , u , q ) pentru cele geometrice. Natura variabilei x se determin dup valoarea x.modul. Dac aceasta este a r , atunci primul termen este x. t, iar raia este x. r . Analog pentru cele geometrice.

36

Limbajul Pascal

- Concepte fundamentale

Exemplu. Presupunem c se dorete prelucrarea unor informaii referitoare la starea civil a unor persoane. Aceste informaii conin numele persoanei, sexul, starea civil (cstorit, cstorit i divorat, vduv, necstorit) i, dup caz, data cstoriei sau date cstoriei i a divorului. Urmtoarele definiii introduc tipurile de date necesare unei astfel de prelucrri. type d a t a = record luna : ( i a n , f e b , m a r , a p r , m a i , i u n , i u l , a u g , sep, o c t , n o i , d e c ) ; z i u a : 1 . .31; anul t integer end; type nume_persoana = racord primul, ultimul: packed . .10] of c h a r end; type persoana = record nume : nume__persoana; sex : (femeie, b r b a t ) ; o case s t a t u t : ( c s t o r i t , n e c s t o r i t , d i v o r a t , vduv) of cstorit, vduv : (data_casatoriei: d a t a ) ; divorat : (data_cas, data_divort:data); n e c s t o r i t : ( ) end;

Urmtoarele articole: persoana(nume_persoana('Popescu ', 'Ion ' ), b r b a t , c s t o r i t , d a t a ( i a n , 2, 1940)), persoana ( n u m e _ p e r s o a n a ( ' I o n e s c u ', 'Mria ' ), f e m e i e , divorat, data(mar, 2, 1950), data(oct, 10, 1960)), persoana"( mime_persoana( ' P o p a 'Ion '), brbat, n e c s t o r i t ) , aparin tipului record cu variante persoana. Asupra acestui tip de date se pot aplica urmtoarele operaii de selectare: nume, nume.primul, nume.u l t i m u l , s t a t u t , d a t a _ c a s a t o r i e i . l u n a , data_cas. luna etc.

2.2.3. Tipul de date set (mulime)


Unul din conceptele noi impuse de limbajul Pascal l reprezint tipul de date ale crui elemente snt mulimi asupra crora se pot aplica operaiile uzuale. Fie un tip scalar diferit de r e a l j e numete tip eet cu tipul de baza , mulimea ( T ) , format din toate submulimile lui . Definiia unui tip eet se face printr-o declaraie set of T sau packed aet of T unde prin este desemnat tipul de baz. Spre exemplu, mulimea P ( { 1 , declaraia: type S_l_50 = eet of 1 . . 5 0 ;

2,

5 0 } ), este definit prin

Construcia urmi element de tip eet se face n conformitate cu definiiile: < s e t > : : = [<lista_eleniente>] | [ ] <lista_elemente> : : = <element> 1 , <element> } <element> : : - <expresie> 1 <expresie> . . <expresie> unde < e x p r e s i e > desemneaz o expresie (vezi 2.5) a crei valoare aparine tipului de baz. Spre exemplu, pentru a desemna mulimea vid se folosete notaia (], iar pentru a specifica mulimea { 1 , 2 , 3 , 4 , 5 } putem folosi una din variantele: [ 1 , 2 , 3, 4 , 5 ] sau 5] sau [1, 2 . . 3 , 4 , 5 ] ete. Operaiile care se pot face cu variabile sau elemente de tip set snt: reuniunea (+), intersecia (*), diferena (-), rezultatul fiind de tipul set, i egalitatea (-), inegalitatea (<>), incluziunea (<", >-), rezultatul fiind de tipul boolean. Operaia de apartenen a unui element la o mulime se specific prin cuvntul cheie in, iar rezultatul este de tipul boolean. De exemplu, dac a , b , c smi variabile de tipul S _ l _ 5 0 , a fiind mulimea vid, b mulimea [ i , 2 , . . . , 4 0 } ic = [ 3 0 , 3 1 , . . . , 5 0 } atunci expresia 3 0 in b are valoarea t i u e , reuniunea lui a cu b este desemnat prin a b, iar incluziunea mulimii [ i , 2 , . . , 3 0 } in b prin [ 1 . . 3 0 ] < = b. Observaie. Numrul de elemente ai multimii tipului de baz este limitat n

implementarea de fa la 256 (dac tipul de baz este o parte a mulimii numerelor ntregi, atunci acesta trebuie s fie inclus n l o , 1 , . . . . , 2 5 5 } ) .
Exemplu. Prin execuia programului var A , B , C : aat of 0 . . 5 ; [A , B , C - m u l i m i cu elemente numere n a t u r a l e i n t r e 0 s i 5 } begin A := [1.-3, 5]; [A conine 1,2,3,5} B := [5, 2..3, 1]; [B conine 1 , 2, 3 , 5 } C := []; [C - m u l i m e a vida} w r i t e l n ( A - B , A - B - C , A+B = A ) ; w r i t e l n ( A + [ 4 ] = [ 1 . . 5 ] , 3 in A , 1 in [ 1 ] ) ; writeln(C <= A, [1,2] >= [1], [1,2] O [1]) and. va fi scris de nou ori constanta true. Exemplu. n programul urmtor, mulimile conin valori ale unui tip enumerare. type s t a r e - ( i n i i a l a , o a r e c a r e , f i n a l a ) ; s: s t a r e ; . .var

m : set of s t a r e ; begln s : - i n i i a l a ; m: = [s]; w r i t e l n ( i n i i a l a in m ) ; { s c r i e t r u e } m : = m + [ f i n a l a ] ; writeln ( f i n a l a in n i ) ; { s c r i e t r u e ] n i : = m - [ i n i i a l a ] ; w r i t e l n ( i n i t i a l a in m ) { s c r i e f a l s e } end. n paragraful 3.2.2.1 poate fi gsit un alt exemplu de utilizate a tipului de date set.

38

Limbajul Pascal

- Concepte fundamentale

2.2.4. Tipul de date file (fiier)


Fie T un tip de date i EOF un element special care nu aparine lui T . Mulimea FT = T* {EOF } se numete tip file (fiier) cu componente de tipul T . Elementele acestei mulimi snt iruri finite i ordonate de elemente din T ,,urmate de EOF ; un astfel de ir se numete fiier. Tipul T se numete tip de baz. Componentele fiierului se numesc nregistrri sau articole. Exemplu. Dac T este tipul i n t e g e r , arunci urmtoarele iruri: <0, -l, EOF > <1, EOF > <EOF>

'. ~ . ;
....

snt fiiere cu componente de tipul integer. n limbajul Pascal, un tip fiier se definete prin: < t i p _ f i s i e r > ::= file of < t i p > | packed file of < t i p > unde < t i p > este tipul de baz. Atributul packed indic o compactificare a reprezentrii componentelor fiierului n memorie. Cele mai uzuale operaii asupra unui fiier snt extragerea ("citirea") i introducerea ("scrierea") unei componente noi. Aceste operaii se realizeaz prin procedurile predefinite g e t sau r e a d i respectiv p u t sau w r i t e . nainte de efectuarea operaiilor de scriere sau de citire este necesar o aciune de validare a lor, numit deschidere a fiierului, realizat prin procedurile predefinite r e s e t i rewrite. Dup tipul operaiilor permise asupra componentelor, fiierele se clasific n: fiiere de intrare (este permis numai citirea); fiiere de ieire (este permis numai scrierea); i fiiere de actualizare (snt permise scrierea i citirea). Operaiile permise snt fixate la deschiderea fiierului. Dup medul de acces la componente, fiierele se clasific n: fiiere cu acces secvenial sau secveniale (accesul la componenta n este permis numai dup ce s-a citit/scris componenta n-i) i fiiere cu acces aleator sau direct (orice component se poate referi direct prin numrul ei de ordine n fiier). n lipsa altor specificri, fiierele declarate n programele Pascal snt secveniale i de intrare sau de ieire. Orice declarare de variabil f de tip fiier cu tipul de baz T conduce la declararea implicit a unei alte variabile cu numele f * de tipul T, pe care o vom numi variabil asociat fiierului i care se poate utiliza n programul Pascal, f * se poate considera ca o "fereastr" prin care se extrage / introduce o component din / n fiierul f. Aceasta este singura component accesibil la un moment dat i se numete component curent. Exemplu. Prin definiiile type candidat = record nume : packed array [1..30] of char; media: real end; t_fc = file of candidat; var fc : t_fc; se introduc tipul fiier t_f c cu componente de tipul candidat, variabila fiier f c de tipul t_f c i variabila f c * de tipul candidat.

Observaie. n apelurile de procedur, parametrii actuali de tip f i l e snt comunicai prin referin (vezi 4.6.2.2). Prin urmare, n declaraiile de procedur parametrii formali de tip file vor fi declarai ca variabili prin specificaia var.

2.2.4.1. Fiiere secveniale 2.2.4.1.1. Operaii de intrare/ieire Fie definiiile Pascal: type FT=file of T; var f :FT; . ; f,",:,, '.,,15* i'icy: prin care au fost introduse tipul fiier FT cu tipul de baz T, variabila f de tip FT i variabila f * de tipul T. Pentru a explica mecanismul operaiilor asupra tipului FT, introducem notaiile ce urmeaz. Fie <c 1( c 2 ,.. .c ,EOF> valoarea lui f, unde n e N i Cj e T pentru i = i , . . . ,n snt componentele fiierului f). Cnd n=o valoarea l u i f este <EOF> . Un fiier se consider totdeauna a fi secionat n dou pri (partea sting i partea dreapt), notate prin f , respectiv f d , astfel nct f = f fd. Definiiile lui f i fd se vor preciza la descrierea operaiilor asupra fiierelor. Este posibil ca partea sting f s nu conin,niciun.element; aceast situaie se va nota prin f 3=e (e este elementul neutru la operaia de concatenare). Partea dreapta.f d conine totdeauna cel puin elementul EOF. . Exemplu. Dac variabila f este declarat prin var f : file of i n t e g e r ; i are valoarea < o, -1, EOF>, este posibil ca f s aib valoarea o i n acest caz f d este < o , - l , EOF>. De asemenea, putem avea f = < o > i f d = < - i ,EOF>, sau f 8 = < o , - i > i f D=<EOF>. Definim funciile pariale p r i m u 1 : FT>T i r e s t : FT ^>FT, unde FT este mulimea fiierelor cu componente de tipul T prin: p r i m u l ( < c 1 , c 2 , . . .c,EOF>) - c l ( daca n>l r e s t (<<=!,c 2 , . . . c N,EOF>) < c 2 , . . c N,EOF> , dacan> l .

Se observ c aceste funcii nu snt definite n cazul n= o . s Observaie. Valoarea variabilei f * asociate variabilei f de tipul fila este definit n felul urmtor: dac f = f 3 f d i f d nu este <EOF>, atunci f " = p r i m u l ( f d ) ; n cazul f d = <EOF> valoarea lui f - este nedefinit. Deci pentru f d * <EOF> , p r i m u l ( f d ) este componenta curent a fiierului. Exemplu. n cazul cnd f = < o , i ,EOF> i f s = < 0 > , f d = < - l , EOF>avemf* = p r i m u l ( < - l , EOF>) = - l ; de asemenea, r e s t ( < - 1 , EOF>) = <EOF>. Dac f s = < 0 , - l > i f d = <EOF> atunci f * este nedefinit Descriem n continuare procedurile i funciile predefinite care realizeaz operaiile asupra tipului FT. reset este procedura de deschidere a fiierelor pentru citire. Dac f este un fiier, arunci dup apelul de procedur r e s e t ( f ) , avem f B=o, f d = f . Vom nota acest fapt prin reset( f ) { f 8=e, f d = f } .

40

Limbajul Pascal

- Concepte fundamentale

n consecin, componenta curent este f * = p r i m u l ( f ). Exemplu. Dac valoarea lui f este < o , - l ,EOF> atunci dup r e s e t ( f ) avem f =e, f d = < 0 , -1,EOF>; prin urmare f - = o. Notm acest fapt prin {f=<0,1,E0F>] reset(f) { f s=e, f d = < 0 , - l ,EOF>} {f'=0} Observaie. Dac fiierul nu conine nici o component din T ( f - < EOF >, adic fiierul este vid) atunci, dup execuia lui r e s e t ( f ) , f " este nedefinit. eof este o funcie booleana care semnaleaz prin valoarea t r u e sfritul de fiier. Are ca argument variabila f de tip fiier. ntotdeauna are loc relaia: eof(f) ~ f =< EOF >.
D

Se observ c dac f=< EOF > (fiierul este vid), dup deschiderea fiierului f prinreset( f ) avem e o f ( f ) = t r u e . g e t este procedura de citire a unei componente din fiier. Apelul de procedur g e t ( f ) este permis numai dac eof ( f ) = f a l s e . Dac f = x , f d = y , atunci dup execuia instruciunii g e t ( f ) avem: f = x p r i m u l ( y ) , f d - r e s t ( y ) . n consecin, f " = p r i m u l ( r e s t ( y ) ). Vom nota acest fapt prin: {not eof(f), f=x,fd=y} get(f> tfa=x primul (y), fd=rest(y)} lfA=primul (fd) =primul(rest (y)}} Se observ c dac y = < c , EOF > (adic f * are ca valoare ultima component a fiierului f ) atunci dup instruciunea g e t ( f ), f * este nedefinit i eof ( f ) are valoarea true. Exemplu. var f; file of integer; begin {f=<0,-l,EOF>} reset(f); f f = e , f d ~ < 0 , -l, EOF >} {f=0} {not eof(f)} get(f); {f=<0>, fd=<l , EOF >} { f - 1 1 { n o t eof( f ) } g e t ( f ) ; {fs=<0,-l>, fd-<EOF>} (f* nedefinit} { e o f ( f ) ; d e c i g e t ( f ) nu m a i e s t e p e r m i s } Prelucrarea n succesiune a tuturor componentelor unui fiier f se poate realiza prin urmtoarea secven de program: . . . var f : file of T ;

r e s e t ( f ) ; { f " e s t e p r i m a componenta f l a l u i f } while not eof( f ) do begin. . . . { p r e l u c r a r e a componentei c u r e n t e f * } g e t ( f ) ; { t r e c e r e a l a componenta u r m t o a r e , d a c a e x i s t a } end

..."

Exemplu. Programul urmtor calculeaz media aritmetic a cmpurilor media din componentele fiierului f c: type c a n d i d a t - record n u m e : packed array [ 1 . . 3 0 ] of c h a r ; m e d i a : r e a l end; var f c : file of c a n d i d a t ; s : r e a l ; n: mteger ; begin s:= 0; n:= 0; reset(fc); while not e o f ( f c ) do begin n : = n + 1; s:= s + fc".media; get(fc) end; if n < > 0 then w r i t e ( ' m e d i a g e n e r a l a e s t e = ' , s / n ) end. Observaie. Citirea unei componente care precede componenta curent este posibil numai relund citirea fiierului de la nceput prin apelul r e s e t ( f ) . rewrite este procedura de deschidere a fiierelor pentru scriere. Dup apelul de procedur r e w r i t e ( f ) , f=e i f d = < E O F > (deci eof ( f ) = t r u e i f = < E 0 F > , adic fiierul este considerat vid). Notaie: r e w r i t e ( f ) { f .-a, fd=<E0F>} {eof(f)} put este procedura de scriere a unei noi componente n fiier. Apelul de procedur p u t ( f ) este permis numai dac f d = <EOF>. Dac f 8 = x i f * = c , atunci dup execuia instruciunii p u t ( f ) avem f = x c , f d = < E O F > , iar f * este nedefinit. Notaie: {fe=x, fd-<EOF>, f=c) put(f) {f,=xc, fd-<EOF>, f* nedefinit) Exemplu, var f : file of i n t e g e r ; begin r e w r i t e ( f ) ; { f =e, f d - < E O F > ) f*:=0; put(f); {f8 = < 0 > , fd-<EOF>l { f nedefinit; astfel f*i-f*-l este incorect} f-:--l; put(f);

42

Limbajul Pascal

- Concepte fundamentale

{fa = < 0 , - 1 > , fd=<EOF>} ?f= < 0 , 1,E0F>} end.

sfritul fiierului ca ultim component. 3.O component deja scris nu se poate modifica dect prin rescrierea ntregului fiier, validat prin r e w r i t e . Schema de utilizare a acestor proceduri pentru crearea unui fiier este urmtoarea: var f : file of T ; . . . begin rewrite(f); repeat {atribuie valoare lui f * } put(f) until u l t i m a component a f o s t a d u g a t ' end.

1.Dup apelul de procedur p u t (f), f * rmne nedefinit. 2.Prin execuia instruciunii p u t (f), valoarea lui f * se adaug l a

Observaii.

43

2. Tipuri de date, variabile, constante, etichete, expresii

xead i. x i ta smt proceduri de citite, respectiv serios, a valorilor unor variabile, respectiv expresii de tipul T n fiier. Ele admit un numr variabil de argumente al. . . . , am de tipul T. Apelul read(f, a l , . . . , am ) este echivalent cu secvena: al:-f\- get (f) ; . . . , -am: =f\- get(f) Apelul write(f, a l , . . . , am) este echivalent cu secvena: f * : = a l ; put( f ) ; . . . ; f * : -am; put(f)

alome este o procedur prin care se interzice accesul la componentele unui fiier f ptn la un nou reset sau rewrite (se spune c "nchide" fiierul). Aceast
procedur nu exist n limbajul Pascal standard. De notat c fiierele snt automat nchise la terminarea execuiei programului sau cnd apar ca argumente ntr-un nou reset sau rewrite. Utilizarea procedurilor de intrare/ieire este ilustrat n exemplul 1 din paragraful 3.3. Sintetic, operaiile de creare i citire a unui fiier secvenial snt prezentate n schema urmtoare:
-> (f) rewrite revrite(f) <-

<get(f) I

h-<-> >1 . _____f _____1 --------1


put(f) 1
*/------- i reset(f)

i>

2.2.4.1.2. Fiiere text In Pascal, tipul text este predefinit ca un caz particular de tip fila. Prin declaraia var f : text; se introduce fiierul f de tip text i variabila asociat f * de tip char. Vom numi text valoarea (coninutul) unui fiier de tip text. Conceptual, textele snt divizate m linii; modul efectiv de delimitare a liniilor nu este relevant pentru utilizator i

44

2. Tipuri de date, variabile, constante, etichete, expresii

depinde de implementare. Pentru discuia care urmeaz, considerm tipul c h a r c extins cu un caracter numit "sfrit de linie" i notat eol ( e o l C ).FieC' = c U { e o l } . Atonei tipul text este mulimea C * { E O F } , ale crei elemente snt iruri de caractere (inclusiv e o l ) terminate prin EOF. O linie este un ir < c l , . . . c , e o l > cu n > - o i c 4 e C. Linia care conine componenta curent se numete linie curent. Cititorul poate tace analogie cu textul unei cri, n care trecerea la nudul urmtor este marcat prin eol. Evident, operaiile de intrare/ieire descrise n paragraful precedent rmn valabile pentru fiiere text Observaie. Dac p r i m u l ( f d ) - e o l atunci valoarea lui f * este spaiu. Deci la citirea sfritului de linie (caracterul e o l ) acesta este transformat n spaiu. Exemplu. Prin execuia programului var f : t e x t ; c: char; begin reset(f); while not eof( } do begin read(f, c); {adic c:=f*; get(f);} write(c) end; writeC .') and. cu fiierul f avnd coninutul < a , b , e o l , c , e o l , E O F > se afieaz rezultatul: ab c Cele dou spaii corespund caracterelor eol din fiierul f. n plus, utilizatorul dispune de operatorii predefinii e o l n , writeln i readln pentru manipularea liniilor de text. Reamintim c un tip de date este alctuit dintr-un domeniu (mulime de valori) i o mulime de operaii. Prin urmare, alte tipuri declarate, prin fila of char nu snt identice cu tipul t e x t , deoarece au domenii diferite (C'* { E O F } pentru text i c* { E O F } pentru fila of char) i operaii diferite ( r e a d l n , w r i t e l n i eoln pot fi aplicate numai fiierelor text). Spre exemplu, programul jjj . var i : fila of c h a r ; begin reset(f); readln(f) este incorect eoln este o funcie booleana care semnaleaz prin valoarea t r u e sfritul de linie. Are ca argument o variabil de tipul t e x t . ntotdeauna are loc relaia: e o l n ( f ) * ( p r i m u l ( f d ) = e o l ) sau e o f ( f ) writeln este o procedur prin a crei execuie se marcheaz sfritul liniei curente a fiierului text. Apelul de procedur wi i t e In f) este permis numai dac f d= < E O F >. Dac f B-x, atunci dup execuia instruciunii w r i t e l n ( f ) avem f - x eol. Observaii.

1.

n implementarea descris, la crearea unui nou fiier text, lungimea maxim a unei linii este de 132 caractere (n <= 132); ea poate fi modificat prin specificarea comutatorului " /VAR:n" n apelul r e w r i t e (vezi 2.2,4.2).

45

2. Tipuri de date, variabile, constante, etichete, expresii

2. Spre deosebire de fiierele declarate fila of c h a r , scrierea ntr-un fiier t e x t f trebuie s se ncheie printr-o instruciune w r i t e l n ( f ) ; n caz contrar, ultima linie de text nu este totdeauna scris n fiier din motive dependente de implementare.
xeadln este o procedur prin care la citire se avanseaz la nceputul liniei urmtoare celei curente. Apelul de procedur r e a d l n ( f ) este echivalent cu secvena: while not e o l n ( f ) get(f) do g e t ( f ) ;

Astfel, f * primete ca valoare primul caracter din linia urmtoare celei curente. Dac linia urmtoare este vid (const doar din eol), atunci f * primete valoarea spaiu i e o l n ( f ) ia valoarea true. paga este o procedur cu urmtorul efect: textul scris n fiierul f dup apelul page (f) va apare pe o nou pagin atunci cnd coninutul fiierului f este imprimat De fapt, apelul p a g e ( f ) are ca efect inserarea n text a caracterului ff ("form feed"),

interpretat de imprimante drept comand de salt la pagin nou.


Utilizarea fiierelor t e x t este ilustrat n exemplul 2 din paragraful 3.3. Exploatarea caracter cu caracter a fiierelor text este greoaie atunci cnd secvene de caractere din text trebuie interpretate ca formnd date de tip i n t e g e r , r ea 1, boolean, ir de caractere; conversia ntre formatul extern i reprezentarea intern a acestor tipuri ar cdea n sarcina programatorului (vezi exerciiul 11 din capitolul 3). n consecin, procedurile predefin te r e a d , r e a d l n , w r i t e , w r i t e l n snt extinse ntr-un mod nestandard, admind un numr variabil de argumente de tipurile char, integer, r e a l , ir de caractere ("packed array of char"). Mai precis, fie f un fiier text i a, a l , . . . , am variabile de tipurile menionate mai sus. Apelul xaad (f, a) are urmtorul efect: - dac este de tip integer sau r e a l , atunci este citit ntregul ir de caractere care reprezint valoarea ntreag sau real i convertit la reprezentarea intern respectiv. n text, datele numerice trebuie separate prin spatii sau eol. Spatiile sau eol dinaintea unei valori numerice snt ignorate. irul de caractere care reprezint valoarea numeric se conformeaz sintaxei constantelor numerice de tipul respectiv. Exemplu. Fie programul: var i : i n t e g e r ; begin while not eof do begin read(i); write(i) and cod.

IM

-,*

.ti

prin care snt citite i scrise numere ntregi pe fiierele text input i o u t p u t (vezi paragraful 2.2.4.1.3). Trebuie observat c la introducerea datelor, ultima cifr a ultimului numr va fi urmat imediat de sfritul de fiier (caracterul CTRL/Z); n caz contrar, dup ultimul numr citit, condiia eof este fals; prin urmare, se execut nc o dat instruciunea r e a d ( i ) . Deoarece n acest moment nu mai exist numere ntregi n fiierul input, va fi semnalat eroare. - dac a este un ir de caractere, atunci se citesc attea caractere cte

snt necesare pentru completarea irului. Dac nainte de executarea instruciunii r e a d ( f , a ) condiia eoIn ( f ) este true, atunci irul a este umplut cu spaii; de

46

2. Tipuri de date, variabile, constante, etichete, expresii

asemenea, dac n timpul citirii e o l n ( f ) devine true, atunci restul irului este completat cu spaii; n ambele cazuri caracterul curent rmne eol.
Exemplu. Dac executm programul var f : t e x t ; a : packed array [ 1 . . 3 ] of c h a r ; C ! char; begin reset(f); r e a d ( f , a ) ; { c a r a c t e r u l curent e s t e e o l } w r i t e l n ( a , eoln(f)); r e a d ( f , a ) ; { c a r a c t e r u l curent nu s - a m o d i f i c a t deoarece a e s t e s i r } writeln(a, eoln(f)); r e a d ( f , c ) ; { c a r a c t e r u l curent s - a m o d i f i c a t deoarece c e s t e c h a r } wziteln(c, eoln(f)); read(f, c); writeln(c, eoln(f)) cu fiierul f avind urmtorul coninut <l,2,eol,3,4,eol,EOF> atunci rezultatele afiate snt: 12 TRUE TRUE FALSE 3 FALSE Apelul xead(f,
. .

al,..., an) este echivalent cu secvena:

r e a d ( f , a l ) ; . . . ; r e a d ( f , am) Apelul xeadln( f , al,..., am) este echivalent cu secvena: r e a d ( f , a l , . . . , a m ) ; r e a d l n ( f ) Fie f un fiier text i a , a l , . . . , am argumente de una din formele: e e:ix

undea este o expresie de tip char, integer, real, boolean sau packed azray of char (ir de caractere), a crei valoare trebuie scris n fiierul f n format extern; i j i i2 snt expresii de tipul integer, numite specificatori de format i, specific prin valoarea sa absolut numrul minim de caractere ce vor fi folosite la scrierea valorii lui a n fiierul f; dac Snt necesare mai puin de I i j | caractere, atunci forma extern a valorii lui a este completat cu spaii la sting pn la | it | caractere. Dac o valoare numeric necesit mai mult de J it | caractere, se scriu attea caractere cte snt necesare (valoarea numeric nu este trunchiat). irurile de caractere i valorile booleene snt trunchiate la primele | i11 caractere. Valoarea implicit a lui it este dependent

de implementare i de tipul expresiei :

47

2. Tipuri de date, variabile, constante, etichete, expresii

Tipul lui.a integer real char packed array of char boolean

ii implicit 7 13

1 i

1 | lungimea i r u l u i

2.2. Tipuri structurate

dc

date

43

O valoare ij. negativ are sens numai n cazul cnd e este de tip integer, packed azzay of char sau char: ntregii snt scrii n baza 8, tar scrierea irurilor de caractere (caracterelor) este suprimat
i, are sens numai n cazul cnd expresia a este de tip real i specific prin valoarea sa absolut numrul de cifre care urmeaz punctului zecimal n scrierea valorii lui a n virgul fix. n lipsa lui i2, valoarea lui a se scrie In virgul mobil (cu factor de scal). Exponentul este format din litera ' E ', semnul ' ' sau ' - ' i dou cifre zecimale. Dac i2 are valoare negativ, atunci valoarea expresiei a este scris n virgul mobil. Apelul write(f ,a) are urmtorul efect: valoarea expresiei a din argumentul a este scris in fiierul f de tip text, convertit la formatul extern conform specificatorilor de format ilf i2. Apelul wzite (v, al,..., a) este echivalent cu secvena: write(f, a l ) ; . . . ; w r i t e ( f , a m ) . Apelul zitain(f, al,..., an) este echivalent cu secvena: w z i t e ( f , a l , . . . , am); wiiteln(f) . Exemplu. Programul var i : integex; r : real; s i packad array [ 1 . .1 0 ] of char; b s boolean; begin i:- 323; r : 3 . 1 4 1 5 9 2 6 ; { r primete valoarea 3 . 1 4 1 5 9 3 } s : = 'specificat'; b : = true; writelnCi-', i , ' ; ' , i : 4 , ' ; ' , i : 2 , ' ; ' , l : - 4 ) ; writelnCr-', r , r:10, ';', 1:4, ';', r:4:6, '.ii*. writeln('r=', r: 1 0 : 3 , ' ; ' , r : 1 0 : 8 , ' ; ' , r : 1 0 : - 5 ) ; writelnCs-', S , ' ; ' , . s : 1 2 , ' ; ' , 3 : 8 ) ; writeln('b=', b, ' ; ' , b : 3 , ' ; ' , b : 7 ) and. afieaz rezultatele: i323; 323;323; 503 r- 3 .1 4 1 5 9 3 E + 0 0 ; 3 .1 4 1 5 9 3 E + 0 0 ; 3 . 1 4 1 5 9 3 E + 0 0 , - 3 . 1 4 1 5 9 3 ; 1= 3.142;3.14159300;3.14159E+00 s =specificat; specificat;specific '< b- TRUE;TRU; TRUE 2.24.U. Fiierele standard input i output

48

2. Tipuri de date, variabile, constante, etichete, expresii

Exist dou fiiere text cu numele input i o u t p u t , predeclarate astfel: var i n p u t , o u t p u t : t e x t ; i asociate implicit cu mediile standard de intrare i respectiv ieire ale sistemului de calcul. n implementarea descris, ambele stnt asociate cu terminalul utilizatorului (TI:). Dat fiind utilizarea lor frecvent, numele lor snt luate ca valori prin lips ale numelui de fiier text n operaiile de intrare/ieire. Prin urmare, apelurile urmtoare snt respectiv echivalente: read(al, . .., a) readln ( a i y . . . , a ) readln write (ai, aj writeln (alf . .., a) writeln ; cu cu cu cu cu cu read (input, a x , ..., am) readln( i n p u t , a1#. . . , ' a j readln( i n p u t ) write(output, alf a) writeln (output, aw . . ., am) writeln(output).

n cazul folosirii acestor fiiere, standardul prevede specificarea lor n lista de parametri din antetul de program. n implementarea descris, acest lucru nu este necesar. Fiierele standard input i o u t p u t snt deschise automat la nceputul execuiei programului. Apelul reset ( i n p u t ) este echivalent cu r e a d l n , iar r ewr i te (ou t p u t ) termin linia de text curent. Apelurile r e s e t ( o u tpu t) i r e w r i t e ( i n p u t ) snt incorecte.

1. La deschiderea pentru citire a unui fiier text asociat cu un terminal interactiv (de exemplu input asociat cu i i : ) , variabila asociat (n exemplu i n p u t * ) primete valoarea spaiu, iar funcia e o l n primete valoarea f a l s e , fr s se transmit efectiv vreun caracter.

Observaii.

2. Conform standardului Pascal, variabilele input i output trebuie considerate variabile globale dac apar ca argumente n antetul de program. n implementarea descris, antetul de program este ignorat i variabilele input, output snt predeclarate ca variabile globale. Deci la nivelul global, programatorul nu poate declara o variabil sau o procedur cu numele input sau output.
2.2.4.2. Asocierea fiierelor Pascal cu fiiere externe Fiierele existente independent de programul Pascal se numesc fiiere externe. Acestea snt recunoscute i gestionate de sistemul de operare. Exist posibilitatea de asociere a fiierelor Pascal cu fiiere externe. Standardul Pascal prevede ca aceast asociere s se realizeze prin specificarea fiierelor externe ca argumente n antetul de program. n implementarea descris, antetul de program fiind ignorat. _______ 2.2. Tipri de date structurate 45

asocierea fiierelor externe se realizeaz prin extensii ale procedurilor z e s e t i


r e w r i t e . Restul paragrafului descrie aceste extensii, in apelurile: reset(f, n, c, i) rewrite(f, n, c, i) argumentele f , n, c , i au urmtoarea semnificaie: f este o variabil de tip file. n (opional) este o variabil sau constant de tip ir de caractere (packed zzay of char) i conine numele fiierului extern asociat cu fiierul Pascal f. Prin lips, fiierul

49

2. Tipuri de date, variabile, constante, etichete, expresii

extern are numele i extensia vide; el este ters din catalogul curent la terminarea execuiei programului. c (opional) este o variabil sau constant de tip ir de caractere i conine alte cmpuri ale specificaiei de fiier extern neincluse n n. Att n n ct i n c se pot specifica opiuni de intrare / ieire relative la fiierul etern asociat O list complet a opiunilor de intrare / ieire apare n [Pa81]. Aici le descriem pe cele mai des utilizate: / SEEK : permite apelul procedurii seek (vezi 22.4.3) n programul Pascal pentru exploatarea unui fiier n acces direct /WR: permite operaii de citire i scriere ntr-un fiier secvenial, indiferent de modul de deschidere. Opiunea /WR poate fi utilizat la adugarea unei componente noi la sfiritul unui fiier extern deja existent la nceputul execuiei programului. /si m: n specific numrul de blocuri de 512 bytes ce se vor aloca fiierului creat prin r e w r i t e . /VARm: fiierul va avea nregistrri de lungime variabil, cu lungimea maxim n. i (opional) este o variabil de tip integer, n care procedurile reset, r ewr i te ntorc dimensiunea fiierului n blocuri de 512 bytes, sau valoarea -l n cazul unei erori la deschiderea fiierului. Exemple: 1. Prin instruciunea rewrite( f i s , ' F i s . D A T ' ) se deschide pentru scriere fiierul Pascal f i s asociat cu fiierul extern Fis .DAT din catalogul curent 2. Prin instruciunea r e w r i t e ( f ,'FILEl/SEEK',*.DAT/SI: 2 ' ) se deschide fiierul cu acces direct f asociat cu fiierul extern FILEI . DAT, cruia i se aloc 2 blocuri. 3. Prin instruciunea r e w r i t e ( f , , '/SEEK') se deschide fiierul cu acces direct f. 4. Prin instruciunea r e w r i t e (output,' L P O : ' ) se asociaz fiierul standard output cu imprimanta LPO: a sistemului de calcul. Observaii. 1. La deschiderea prin reset a unui fiier asociat cu un fiier extern pe disc fr specificarea versiunii, sistemul de operare alege dintre toate fiierele cu numele specificat n x e s e t existente n catalog pe cel cu versiunea maxim. 2. La deschiderea prin xewr i t e a unui fiier asociat cu un fiier extern pe disc tar specificarea versiunii, sistemul de operare creeaz un fiier cu versiunea cu 1 mai mare dect versiunea maxim a fiierelor cu acelai nume existente n catalog n acel moment: dac un astfel de fiier nu exist, numrul de versiune este 1.

50

2. Tipuri de date, variabile, constante, etichete, expresii

2.2.4.3. Fiiere cu acces direct

Acest paragraf se refer n ntregime la implementarea Pascal Oregon.


Prin declarare, fiierele cu acces direct nu se deosebesc de cele secveniale. Diferenierea ntre cele dou categorii de fiiere se realizeaz la deschiderea fiierului. Pentru fiierele cu acces direct este obligatorie specificarea opiunii ' / S E E K ' n apelul procedurilor r e s e t i r e w r i t e (vezi 2.2.4.2). Indiferent de modul de deschidere, un fiier cu acces direct este fiier de actualizare. Fiierele cu acces direct se pot asocia cu fiiere externe numai pe disc. Componentele unui fiier cu acces direct se consider numerotate ncepnd cu 1. Operaiile, de intrare / ieire pentru fiiere cu acces direct se execut prin apelul procedurilor;i funciilor standard prezentate n 2.2.4.1.1. Accesul direct la componentele fiierului f se realizeaz schimbnd componenta curent prin apelul procedurii nestandard seek. Mai precis, fie f=<c1#.. . f n , EOF> un fiier i i o variabil sau constant de tip integer cu valori n domeniul 1. . n. Dup apelul seek ( f , i ) , componenta cu numrul de ordine i a fiierului f devine component curent i valoarea ei se regsete n variabila f *. Dac f=<EOF> (fiier vid) sau dac valoarea lui i iese din domeniul 1. . n atunci funcia eof ( f ) primete valoarea true. n consecin, se pot scrie secvene de program pentru: 1. Scrierea secvenial ntr-un fiier cu acces direct, ncepnd cu componenta i: var f: file of T ; rewrite(f,,'/SEEK'); seek(f,i); while . . . { e x i s t a d a t e de s c r i s } do begin . . . . { c a l c u l e a z a } f * : - a ; p u t ( f ) { s a u w r i t e ( f , a ) } ead ... 2. Citirea secvenial dintr-un fiier cu acces direct, ncepnd cu componenta i. reset( 1 , , ' I SEEK') ; seek(f,i); while not eof( f ) do begin a:=f*; get(f) ; {sau read(f.a);} ... {prelucreaz a } nd . . . 3. Actualizarea componentei i: reset( f ' / S E E K ' ) ;
ii: i

seek(f,i); a:-f; ...{modifica a} seek(f,i); f.*:-a; put(f);


Jii ... : :i

Exemplul 3 din paragraful 3.3 ilustreaz modul de utilizare a fiierelor cu acces direct.
:

51

2. Tipuri de date, variabile, constante, etichete, expresii

23. Tipul de date pointer (referin)


Mecanismul de declarare a variabilelor prin definiii var desemneaz variabilele prin identificatorii asociai. Numrul de variabile i identificatorii lor snt reflectai de textul programului. Ele pot fi utilizate cu destinaia de variabile pe toat durata execuiei blocului n care au fost definite (vezi pentru detalii 4.3.3). Exist situaii n care numrul necesar de variabile de un anumit tip nu este acelai pe toat, durata execuiei unui bloc. S presupunem c se dorete prelucrarea unui vector cu n componente de tipul integer. Dac n este cunoscut n momentul scrierii programului (sau cel puin valoarea sa maxim N) atunci se utilizeaz o declaraie de forma vax v : azray [ 1 . . N ] of integer; unde N este o constant (literal sau identificator de constant). Pe toat durata execuiei este rezervat un spaiu de memorare necesar pentru toate cele N componente ale lui v. Ar fi mai avantajos, din punctul de vedere al ocuprii spaiului de memorie, un mecanism de definire a numrului de componente in momentul execuiei. Spre exemplu, dac de fiecare dat cnd se genereaz o nou component a vectorului exist posibilitatea de a crea o nou variabil de tipul integer n care s fie reinut valoarea noii componente, atunci spaiul de memorie alocat este cel strict necesar. Sntem prin urmare n prezena unui fenomen de generare dinamic de variabile de un anumit tip. Fie T un tip de date. Ptintr-o definiie de forma type PT

- "T;

se introduce un nou tip PT care este o mulime de variabile de tipul T. PT se numete tip de date pointer. O variabil de tipul PT declarat prin: var p : PT; ia ca valori variabile de tipul T. Variabila de tipul T desemnat de p la un anumit moment al execuiei se noteaz cup*. Atribuirea unei variabile de tipul T lui p se face prin procedura predefinit nev. Variabila p * obinut prin instruciunea new ( p ) este distinct de toate variabilele de tip T create anterior. Executarea repetat a instruciunii new ( p ) conduce la crearea unui ir vL, . . . . . . . . v de variabile de tipul T. Numai ultima variabil creat, v, este referit prin p *. Procesul dinamic de creare de variabile de un anumit tip T presupune i existena unui mecanism de distrugere a lor i de eliberare a spaiului de memorie ocupat Acest lucru se realizeaz prin utilizarea procedurii predefinite dispoae. ' Dup executarea unei instruciuni dispose ( p ) , variabila p * devine nedefinit De asemenea, p nu este definit atunci cnd nu s-a executat nici o instruciune new ( p ) . Dac dorim ca p s nu indice nici o variabil, atunci i asignni valoarea constantei predefinite nil. Dac y este o variabil de tipul T, p poate lua ca valoare aceast variabil printr-o instruciune de atribuire p: ref (v ) . Exemplu: var p : * integer; x, y: integer; begin p : = nil; { p * nu e x i s t a i n a c e s t moment, dar p a r e valoarea nil!

52

2. Tipuri de date, variabile, constante, etichete, expresii

new(p); {a fost creata o variabila p* de tip intreg} p * := 0 ; writeln(p*); { scrie numrul 0 } x :~ 1; y :- 2 ; p : - ref( x ) ; writeln(p'); { scrie numrul 1 } p := e f ( y ) ; writeln(p*); { scrie numrul 2 } dispose( p ) ; { p * nu mai exista in acest moment iar valoarea lui p este nedefinita} end. Alte aplicaii ale tipului de date pointer sint prezentate n legtur cu tipurile de date recursive n paragraful urmtor.

2A.

Tipuri de date recursive

Tipurile de date pointer ofer posibilitatea de a reprezenta n programe Pi.si.iil date a cror definiie este recuri v. O bun ilustrare se obine n cazul reprezentrii grturilor orientate. S considerm mai nri gtafuri de forma unor liste 1-------> 5 -------> 7 cu nodurile marcate prin cifre zecimale, definite astfel n notaie BNF: <lista> : ; = <element> <lista> | e <element> :0 1 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 Caracterul recursiv al definiiei este dat de prima regul. Precizm c e este elementul neutru pentru operaia de concatenare. Deoarece o list diferit de este dement al produsului cartezian <element> x <lista>, este sugerat folosirea tipului de date record. Aceasta ar conduce la utilizarea numelui de tip lista pentru propria sa definiie, ceea ce este interzis n limbajul Pascal. Este posibil ns depirea acestei interdicii prin intermediul tipului de date pointer. O list este identificat prin primul ei element i prin sublista ce urmeaz acestui element n limbajul Pascal aceasta revine la definiia type legtura - * lista; type lista = record element : 0 . . 9 ; sublista : legtura nd; Se observ c n definiia tipului l i s t a se folosete tipul pointer l e g t u r a , definit la rindul su pe baza tipului l i s t a . Aceast circularitate este consecina recurivitii definiiei listei. Mai mult, utilizarea tipului l i s t a precede definiia lui (aceasta este o excepie, n general utilizarea unei entiti se poate face dup ce aceasta a fost definit). O list va fi reprezentat n programe Pascal printr-o variabil de tipul pointer declarat prin vai 1 : legtura;

53

2. Tipuri de date, variabile, constante, etichete, expresii

Efectul execuiei instruciunii n e w ( l ) este crearea unei variabile 1 * de tipul l i s t a . Dac 1 - nil, atunci se consider c lista 1 A este vid (adic a). Exemplu. Lista l -----------> 5 -------> 7 descris prin arborele <lista> <element>
I

<lista>
/ \

1 <element> < l i s t a >


I / \

<element> < l i s t a > 7 a

poate fi obinut prin urmtorul program: type legtura - " l i s t a ; l i s t a = record element : 0. . 9 ; s u b l i s t a : legtura and; var.p, g , r t legtura; begin new (p); q : = p; q * . element: = 1; r:= q; new(q); r*.sublista:- q; q*.element:= 5; r:= q; new(q); r A . s u b l i s t a : = q ; q * . e l e m e n t : - 7 ; q * . s u b l i s t a : = nil; and. Prezentm un alt caz, cel al arborilor binari de forma 2 1

/ \

/ \

definii prin <arbore> i : = (<nod> , <arbore>, < a r b o r e > ) | <nod> | a <nod> ::= 0 | l | 2 | 3 | 4 | 5 | 6 r 7 | 8 | 9 .
ies--, -

Deoarece un arbore este fie n form complex, adic un nod urmat de un (sub)arbore sting i altul drept, fie n form simpl, adic un nod, el este un element al reuniunii disjuncte de tipuri <nod> x <axbore> x <arbore> U <nod>. De asemenea, el poate fi vid, adic a. Aceasta sugereaz utilizarea tipurilor record cu variante. n limbajul Pascal acest arbore poate fi obinut prin programul: type legtura - *arbore; type a r b o r e - record case f e l : (complex, simplu) of complex : (nod : 0..9;

54

2. Tipuri de date, variabile, constante, etichete, expresii

a_sting, a_drept : l e g t u r a ) ; simplu : (nod_terminal : 0 . . 9 ) end and; var p , q, s t , d r : legtura; begin new ( p ) ; q : - p; q * . f e l : - complex; q * . n o d : = 2 ; new( s t ) ; new( d r ) ; q*.a_sting:- s t ; q*.a_drept:- dr; q:= st; q ' . f e l : - s i m p l u ; q * .nod_terminai: = 1; q : = d r ; q * . f e l : complex; q * . n o d : = 3 ; new(s t ) ; new(dr) ; q * . a _ s t i n g : st; q*.a_drept:= dr; qs= st; q * . f e l : - s i m p l u ; q A .nod_terminai: - 7 ; q t - d r ; q * . f e l : = complex; q ' . n o d : - 4 ; n e w ( s t ) ; dr: nil; q * . a _ s t i n g : - s t ; q * . a _ d r e p t : = d r ; q : St; q * . f e l : - s i m p l u ; q * . n o d _ t e r m i n a i : - 5; ud. Alte ilustrri ale tipurilor de date recursive se gsesc n exemplul 4 din paragraful 3.3 i n exemplele 5, 6, 7 din paragraful 4.5.4.

2.5. Expresii
n timpul execuiei unui program pe calculator, instruciunile sale prelucreaz elemente ale tipurilor de date predefinite (integer, r e a l , etc), sau ale celor definite de programator (array, racord etc.). Aceste elemente snt referite prin intermediul variabilelor i constantelor i asupra lor snt aplicate anumite operaii. Variabilele snt identificatori ce apar ntr-o declaraie var sau snt referite prin intermediul unei alte variabile de tipul pointer (vezi paragraful 2.3 pentru detalii). Constantele snt numere, iruri de caractere (vezi 1.2), constante structurate (vezi anexa 3, diagrama 3.9), constante predefmite ( m a x i n t , nil, t r u e , f a l s e ) sau identificatori declarai prin const. Numele operaiilor, paritatea i sensul lor pot fi de asemenea predefinite ca n cazul , -, div, mod pentru tipul integer etc, sau definite de programator, ca n cazul numelor proieciilor canonice ale tipurilor record i ale operaiilor introduse prin funcii i proceduri (vezi capitolul 4). Se poate deci considera c execuia unui program se desfoar n cadrul unui model logic de signatur dat, al crui domeniu D este format de tipurile de date. Signatura acestui model cuprinde mulimea simbolurilor operaiilor predefinite (+, - , succ etc) sau definite de programator (proiecii canonice, identificatori de funcii i proceduri etc.), mulimea simbolurUor predicat predefinite ( < , > , >-, in etc.) sau definite de programator i mulimea simbolurilor constant (numere, iruri de caractere, identificatori de constante predefmite precum m a x i n t , nil, false, t r u e i identificatori definii prin const). Interpretarea acestor simboluri este fie predefinit, fie stabilit de programator. Se pune deci n mod natural problema modului n care aceste elemente pot fi agregate n limbajul Pascal pentru a obine expresii. Sintaxa acestor expresii este descris n anexa 3, diagramele 3.24-3.25. Se poate observa c cele mai simple expresii snt constantele fr semn i variabilele. Astfel, numrul l. 2E -10, caracterul ' A ' , constantele predefinite m a x i n t , nil, t r u e , f a l s e , constantele structurate M2RA (LINIE (I.O, 2.0), LINIE (3.0, 4. o) ) , variabilele x, Y, v * snt expresii n

55

2. Tipuri de date, variabile, constante, etichete, expresii

limbajul Pascal. Expresiile de la urmtorul nivel de complexitate se numesc factori (anexa 3, diagrama 3.28) i se obin prin aplicarea opional a simbolurilor funcie, a simbolului predicat no t i a parantezelor (, ) sau [, 1. Astfel X, s i n (XI), a r c t a n ( V ) , zound(2.8), not f a l s e, (2), [ a , b , c ] (desemneaz mulimea cu elementele a, b i c), [ 1 . . 5 ] (desemneaz intervalul de numere ntregi n, 1 <- n <= 5) snt factori. Prin aplicarea opional a operatorilor multiplicativi *, /, div, mod i and asupra factorilor se obin termeni (anexa 3, diagrama 3.26). Astfel x, a * b, a * b mod 10, not x and y and z snt termeni. Din termeni se obin expresiile simple (anexa 3, diagrama 3.27) prin aplicarea opional a operatorilor aditivi , - i or sau prin aplicarea semnelor + i -. Spre exemplu, x + (-1 ) , a * b, -a * b, a * b + b mod 10, not x and y and z or not false snt expresii simple. Cele mai complexe expresii Pascal se obin prin aplicarea simbolurilor predicat <, >, <-, >, -, <>, in. Astfel, x, x < y, x + y in z , (i < j) = (j < k), x in [2, 3 , 6] snt expresii Pascal corecte sintactic. Expresiile prezente n textul unui program Pascal snt evaluate n cursul execuiei programului pe calculator. Rezultatul depinde de valorile variabilelor la momentul cnd se face evaluarea (valorile constantelor nu se modific n cursul execuiei). Spre exemplu, expresia x < o este evaluat la valoarea false dac valoarea lui x este l; este posibil ns ca la o evaluare ulterioar s aib valoarea true dac ntre timp valoarea variabilei x s-a schimbat Operaiile predefinite snt clasificate n patru categorii, dup prioritatea pe care o au n cursul evalurii expresiilor. Cea mai mare prioritate o are operaia not. Urmeaz apoi n ordine descresend a prioritilor operaiile multiplicative, operaiile aditive i operaiile relaionale: prioritate (cea mai mare) operaia

1 2
3

(cea mai mica)

<

not * / div mod and + - or <= >

>

in

Prioritatea operatorilor este reflectat n regulile 2.25-2.29 din anexa 2. Spre exemplu, conform notaiei BNF, expresia a+b*c este descris prin arborele de derivare urmtor: <expresie> I <expresie_simpl> I \ <operator_aditiv> <termen> I / 1 \ + <factor> <operator_multiplicativ> <factor> I I I <variabil> * <variabil>

/ <termen> I <factor> I <variabil>

Din plasarea celor doi operatori n acest arbore (+ mai aproape de rdcin dect *) rezult c operaia * se execut naintea operaiei +. Secvenele de operaii care au aceeai prioritate snt evaluate de la sting la dreapta. Expresiile dintre parantezele (, ) sau [, ] snt evaluate independent de operaiile care le preced sau care le urmeaz. Se observ c operaiile not, and i or au aceeai ordine a prioritilor ca n algebra booleana;

56

2. Tipuri de date, variabile, constante, etichete, expresii

Trebuie remarcat c operaiile relaionale <, <-, etc. snt definite i pentru operanzi de tipul predefinit boolean, deoarece false < true. Prin urmare, operaia < - are sensul de implicaie logic, iar = are sensul de echivalen logic. Aceast ncrcare cu sensuri suplimentare a operatorilor relaionali are ca efect o scriere mai complicat a expresiilor logice n limbajul Pascal dect n matematic sau n alte limbaje de programare (spre exemplu, n AlgoloO exist simbolurile predicat implicaie logic i echivalen logic). Astfel, n cazul declaraiei var x , y, z : r e a l ; expresia (x <- y ) and ( y <" z ) <= ( x <- z ) este evaluat totdeauna a valoarea true i exprim proprietatea de tranzitivitate a relaiei <-. Omiterea parantezelor conduce la expresia x <= y and y <= z <= x <- z care este incorect semantic, deoarece se evalueaz mai nti operaia y and y care nu are sens pe tipul r e a l . Mai mult, dac x , y i z Snt de tipul integer, ultima expresie este corect semantic dar evaluarea ei se face ncepnd cu operaia and (vezi paragraful 2.1.1).

2.6. Exerciii
1. a) S se reprezinte n cod complementar pe 2 bytes numerele ntregi - 2, -l, 0, 1, 2. b) S se reprezinte n virgul mobil (ampl precizie i dubl precizie) urmtoarele numere reale: + 3 . 0 , - 3 . 0.

2. Dac un numr pozitiv x se reprezint n virgul mobil prin x o . i x x . . . x n * 2" (vezi paragraful 2.1.1 tipul r e a l ) , atunci s se reprezinte numrul ntreg i o ... 01 (scris n baza 2, avnd n zerouri). 2.6. Exerciii 3. Snt corecte urmtoarele definiii? a) type culoare ( a l b , r o u, verde, g a l b e n ) ; alta_culoare = ( p o r t o c a l i u , g a l b e n ) ; b) JSypa z i l e = ( l u n i , m a r i , m i e r c u r i , j o i ) ; p r i m e l e _ 3 _ z i l e = luni. . m i e r c u r i ; Fie declaraiile: type T = i n t e g e r ; var A , B : integer; C : integer; D : T; E : T;

55

4.

57

2. Tipuri de date, variabile, constante, etichete, expresii

Dac x i Y aparin mulimii { A , B , c , D , E } , care dintre atribuirile "X : - Y" este acceptat de compilatorul utilizat? 5. Fie declaraiile type R - record I , J : integer end; A - array [ 1 . . 2 ] of integer; var R; AR : A;

RE :

Care dintre urmtoarele atribuiri este corecta? RE.I - AR [1] ; = RE.J; AR[2] = AR; RE 6. Fie declaraiile type numr - ( u n u , d o i ) ; complex = record r e , im : r e a l end; v a r i a n t a = record A : integer; case alege : numr of unu : ( B , C : c o m p l e x ) ; doi : (D : c o m p l e x ) end; Care dintre urmtoarele constante structurate snt conforme cu definiiile de mai sus: a) v a r i a n t a (1,unu,complex(1.1 , 0.IEI),complex(- l . 0 , 0 . 5 ) ) ;

b)complex ( - 1 . 0 , 2.3E5); c) v a r i a n t a (2, d o i , (1.1, 1 . 1 ) )


7. a) Declarai variabilele A, B, c de tip set avnd tipul de baz mulimea { 1 , 2,..., 1 0 } . b)Atribuii tui A mulimea {1 , 2, 3, 4 } , lui B mulimea {3, 4 , 5, 6} , iar lui c mulimea A U B. c) Care este valoarea expresiei 4 in A * B ? Re declaraiile type p i = " i n t e g e r ; var i : integer; vp : p i ;

8.

a) vp este referin la o variabil de tip integer egal cu 1; b)i este egal cu 1; c) vp este referin la i .
9. S se evalueze urmtoarele expresii Pascal: a) l and 2 < 5; b) 1 * 2 < 5 c) (l <= 2) and (2 < = D

S se arate cum se pot realiza urmtoarele aciuni:

58

2. Tipuri de date, variabile, constante, etichete, expresii

d) 1 <= 2 and 2 <= e) x < = 0 - ( - x > = 0 )


10. Exprimai numere reale. n limbajul

Pascal

expresia

algebric

xy,

unde

snt

Sintaxa instruciunilor limbajului Pascal este descris n anexa 2, definiiile 2.22 2.23 i n anexa 3, diagramele 3.22 - 3.23. O instruciune este alctuit dintr-o etichet opional prin intermediul creia poate fi referit din alte instruciuni, urmat de instruciunea propriu-zis, prin care este descris aciunea realizat n momentul execuiei sale. Se face distincie ntre instruciunile simple (instruciunea de atribuire, apelul de procedur, instruciunea de transfer necondiionat i instruciunea de efect nul) i instruciunile structurate (instruciunea compus, instruciunile iterative, instruciunile condiionale i instruciunea with).

3.1. Instruciuni simple


O instruciune se numete simpl dac nu conine alte instruciuni.

3.1.1. Instruciunea de atribuire


Aceast instruciune are forma v. s - E unde v este o variabil (vezi diagrama 3.24 din anexa 3), iar E este o expresie (anexa 2, definiia 2.23.b). Prin execuia instruciunii de atribuire, expresia E este evaluat i rezultatul se atribuie variabilei v. Variabila i rezultatul evalurii trebuie s fie de tipuri identice, sau tipul uneia s fie un subdomeniu al celeilalte, sau ambele s fie subdomenii ale aceluiai tip iar rezultatul n subdomeniul variabilei. Se admite ca excepie cazul cnd variabila este de tipul r e a l iar rezultatul de tipul i n t e g e r sau un subdomeniu al acestuia. Spre exemplu, s considerm declaraiile urmtoare:

ip

type T12 = 1. . 2; T13 = 1 . . 3 ; ABC = ( a , b , c ) ; complex = record r e , im . : r e a l and; t a b - azray [ABC] of complex; conat i - complex( 0 . 0 , 1 . 0 ) ; c_tab - tab(complex( 0 . 0 , 0. 0 ) ,

'

60

3. Instruciuni

complex( 1 . 0 , 1. 0 ) , complex( 0 . 1 , 1. 0 ) ) ; var k : integer; v l 2 : l f . 2; v l 3 : 1 . . 3 ; VS6 : 5 . . 6 ; al2 : T12; a l 3 : T13; v_logic : boolean; r : real; v_tab : tab; z : complex; n acest caz instruciunile k : = v l 2 ; vl3 := al2; al2 := vl2 snt corecte; instruciunea v l 3 : = k este corect numai pentru l < - k < = 3; instruciunea vi2 v l 3 este corect dac l < vl3 <= 2; instruciunile v 5 6 v l 2 ; vl2 := v56; i := z snt incorecte; instruciunea a l 3 : - loophole ( T 1 3 , a ) este incorect, deoarece rezultatul evalurii este 0 i deci nu este din T13 (detalii privind funcia loophole snt in anexa 4); instruciunea a 13 : = loophole (T13, b ) este corect i hii a 13 i se atribuie valoarea 1; instruciunile v_logic : = ( a l 2 < = v l 2 ) = ( a l 2 < v l 2 ) or ( a l 2 = v l 2 ) ; v_logic : = a - p r e d ( b ) ; v_logic : = b = s u c c ( a ) ; v_ l o g i c : = a - p r e d ( c ) snt toate corecte; primele trei atribuie variabilei v_ l o g i c valoarea t r u e iar ultima valoarea f a l s e ; instruciunea r : = s i n ( r ) + c o s ( k ) este corect; instruciunea k : = r este incorect, dar instruciunile r :k : = k round( r ) ; trunc(r) snt corecte; instruciunile z .re 0; z. im i; z i; v tab c tab snt corecte.

3.1.2. Instruciunea apel de procedur

3.1. Instruciuni simple

61

Instruciunea apel de procedur se insereaz n program n locul n care se dorete executarea instruciunilor specificate de o declaraie de procedur asupra entitilor particulare "transmise" ei din locul de apel (vezi capitolul 4). Sintactic, apelul de procedur (vezi regulile 2.23c-f, anexa 1) poate fi reprezentat prin metaforma P(1) unde p reprezint numele procedurii, iar 1 lista de parametri actuali. Parametrii actuali din 1 trebuie s corespund ca numr, ordine i tip cu parametrii formali specificai n antetul declaraiei de procedur. Ei pot fi expresii, funcii, proceduri. Numai parametrii actuali care corespund parametrilor formali variabili (declarai prin var) pot fi modificai. Ei snt variabile a cror locaie este folosit pentru recuperarea n program a rezultatelor din procedur Exemplu. O procedur cu antetul procedura p(x, y. intecter; var z , t : r e a l ) se poate apela prin p ( 3 , 2 * ( a + b - c ) , u, v) sau p ( a , b , u, v) sau p ( 3 , 5 , u, v) unde a , b , c desemneaz variabile ntregi, evaluarea expresiei 2 * ( a + b - c ) produce o valoare ntreag, iar variabilele u i v snt declarate n program ca reale.

3.13. Instruciunea de transfer necondiionat


Instruciunile unui program snt executate secvenial, aa cum apar scrise n textul programului. Instruciunea de transfer necondiionat ofer posibilitatea de a ntrerupe aceast secven i a relua execuia dintr-un alt Ioc al textului (vezi anexa 2, definiia 2.23.p). Aceast instruciune are forma: goto e unde e este o etichet declarat prin labei. Declararea prin labei a etichetei e este obligatorie. Domeniul de valabilitate al unei astfel de declaraii este precizat n 4.4.3.2. Execuia instruciunii goto e are ca efect transferul controlului la instruciunea prefixat de e (exist o singur instruciune de acest fel). Instruciunea goto e i instruciunea marcat cu e trebuie s ndeplineasc una din condiiile urmtoare: 1) instruciunea prefixat cu e conine instruciunea goto e; 2) instruciunea prefixat cu e face parte dintr-o secven de instruciuni s, iar instruciunea goto e este una, sau este coninut n una dintre instruciunile lui s (secvene de instruciuni apar doar n instruciunea compus begin... and sau n instruciunea zepeat. . , until);

62

3. Instruciuni

3) instruciunea

prefixat cu e face parte din secvena de instruciuni din instruciunea compus begin. . . and a unui bloc B, iar instruciunea goto e apare ntr-o funcie/procedur definit n partea de declaraii a blocului B (prin bloc se nelege un program / funcie / procedur). Exemplu. Programul urmtor execut parcurgerea n inordine a unui arbore binar reprezentat prin tablourile s t , dr, info [LiGe86]. Stilul de programare folosit n exemplu trebuie descurajat, deteriornd claritatea programului. Singura instruciune goto folosit justificat n programul de mai jos este goto 1001.

labei 1 0 0 1 , 1 0 0 2 , 1 0 0 3 ; conat nmax-9; type tip=integer; index=0. . n m a x ; f i i =array [ l . . n m a x ] of index; i n f o r m =array [ l . . n m a x ] of t i p ; var s t . d r : f i i ; i n f o : i n f o r m ; r a d : index; procedura inordine( p : i n d e x ) ; labei 1 , 2 , 3 ; const s m a x - 5 ; var s t i v a : array [ L . s m a x ] of index; k: 0..smax; begin k:=0; i f p = 0 then goto 3 ; { c o n d i i a 2 } l : i f s t [ p ] O 0 then begin if k=smax then goto 1001; { c o n d i i a 3 } k:=k+l; stiva[k] :=p; ps= st[p]; goto 1; {condiia 1 } end; 2 : w r i t e l n ( i n f o [ p ] ) ; if d r [ p ] - 0 then begin i f k - 0 then goto 3 ; { c o n d i i a 2 } p : = s t i v a [ k ] ; k : = k - l ; goto 2 ; {condiia 2 } end; p : = d r [p] ; goto 1 ; { c o n d i i a 2 ] 3:end;
"

begin goto 1 0 0 2 ; { c o n d i i a 2 } 1 0 0 1 : w r i t e l n ( ' D e p a s i r e s t i v a ; program intrerupt*); goto 1 0 0 3 ; {condiia 2} 1002: {iniializare arbore} s t : - f i i ( 2 , 3 , 0 , 5 , 0 , 7, 8 , 0 , 0 ) ; d r : - f i i ( 6 , 4 , 0, 0 , 0 , 0 , 9 , 0 , 0 ) ; i n f o : - i n f o r m ( 7 , 3 , 1 , 6 , 5 , 1 1 , 9, 8 , 1 0 ) ; rad:-l; {vizitare in inordine} inordine(rad); {terminare program} 1003:end.

3.1. Instruciuni simple

63

E x e m p l u . Secvenele de program urmtoare snt incorecte:

a) goto 1 ; ...begin 1: a : = b ; . . . e n d b) i f a = b then begin x : = a ; goto 2 end else 2 : c) procedure p; Instruciunea de efect nul

y:-b

procedure q ; label 1; begin l : a : - b end; begin goto 1 end

Executarea acestei instruciuni nu are efect asupra variabilelor programului (starea acestuia rmne neschimbat). Prezena sa n programele Pascal este stabilit prin parantezele de opiune [ i ] ale definiiei 2.23.a din anexa 2 i de arcul nemarcat al diagramei 3.23 din anexa 3. n textul programului, instruciunea de efect nul nu este reprezentat prin nimic dar, deoarece instruciunile snt desprite ntre ele prin delimitatorul " ; , prezena sa este marcat de apariia acestui delimitator. Astfel, n textul 10:; i : = i + 1 ; ; ; goto 10

exist 5 instruciuni, dintre care 3 de efect nul. Dei efectul su la execuie este nul, inserarea sau eliminarea unei astfel de instruciuni dintr-un text de program poate s-i altereze semnificaia (vezi 3.2.3, observaia 1).

3.2. Instruciuni structurate


O instruciune structurat este compus la rndul ei din instruciuni care se execut fie n secven (instruciunea compus), fie condiional (instruciunile condiionale), fie repetate de un anumit numr de ori (instruciunile iterative). 3.2.1. Instruciunea

compus

Instruciunea compus are forma (vezi anexa 2, definiiile 2.23.g): begin I t ; I2. . . ; In end i specific un grup de instruciuni, l x , l 2 . . . ; in, care snt executate n ordinea n care snt scrise. Chiar partea de instruciuni a unui program reprezint o instruciune compus (vezi paragraful 4.) Exemplu. Programul: type c o m p l e x = r e c o r d r e , im : integer end; vector = array . . 5 ] of integer; var : complex;

64

3. Instruciuni

a , b : vector; begin : = complex( 1 , 2 ) ; { c : = l +2il a : = v e c t o r (1, 2, 3 , 4 , 5 ) ; b : = ( e r e , c . i m , 1, 0 , 2) end.

'

conine o singur instruciune compus prin care se iniializeaz variabilele a, b i c. Aceast instruciune este util pentru a plasa n locurile din program n care nu este permis dect o singur instruciune aciuni mai complexe (vezi instruciunile while, for n paragraful 3.2.2, instruciunile condiionale if i caae n paragraful 3.2.3 i instruciunea with n paragraful 3.2.4).

3.2.2. Instruciuni iterative


Instruciunile iterative snt folosite pentru a exprima execuia de zero sau mai multe ori a unui grup de instruciuni. n limbajul Pascal o instruciune iterativ este definit de: <instructiune_iterativa> <instructiunea_while> <instructiunea_repeat> < ins t r u c t i u n e a _ f o r >

| |

Instruciunea for este indicat n situaiile n care numrul de execuii repetate este cunoscut. n caz contrar se pot folosi instruciunile iterative while sau zepeat.

3.2.2.1. Instruciunea while Instruciunea while are forma (vezi anexa 2, definiia 2.23.4): while B do I n mod normal, instruciunea i se execut ct tinip expresia booleana B ce controleaz repetiia este adevrat. Execuia se poate ns ncheia i printr-un transfer necondiionat. Dac expresia B are de la nceput valoarea f a l s e, atunci instruciunea I nu este executat. Astfel, execuia instruciunii while t r u e do x : = 1 conduce la executarea de un numr infinit de ori a instruciunii x: = 1. Pe de alt parte, instruciunea whi.le f a l s e do I este echivalent cu instruciunea de efect nul, deoarece I nu va fi executat deloc. Se recomand utilizarea sa n situaiile cnd numrul de execuii repetate ale instruciunii i este dificil de evaluat

3.1. Instruciuni simple

65

Exemplu. Re seria definit prin sumele pariale s0 = t 0 , Si = s'ili + t1( pentru i > 0 unde t4 - - (x2't11)/(kJ ( k i - i )J, i > 0 kj - ki.x + 2, k0 - 1.

i>0

Este cunoscut c l i m sn - s i n ( x ) . Urmtorul program calculeaz prima sum parial s cu proprietatea 11| e p s i l o n - | s |, unde e p s i l o n > o. var s, t : real; k : integer; x , x 2 , e p s i l o n : r e a l ; begin t : = x; k := 1; s := t; epsilon 0 . 0 0 0 1 ; x2 : = sqr ( x ) ; falle a b s ( t ) > e p s i l o n * abs(s) do begin k := k + 2; . t := -t * x2 / (k * (k-D); s s+t end end.

Dup execuia programului, valoarea variabilei s este o aproximaie a lui s i n ( x ) . Se observ c valoarea x2 se calculeaz nainte de instruciunea wfaile, deoarece variabila x nu se schimb n cursul execuiei acestei instruciuni. Exemplu. Re irul v1# i o , definit prin relaiile de recuren v0 = a V = f t v j .i); i 12:1

i p o proprietate satsfcut de cel puin un termen al irului. Urmtoarele instruciuni determin primul termen vk din ir ce satisface proprietatea P: v:= a; ^rtiile not P ( v ) do v : = f ( v ) { v a r e v a l o a r e a l u i v_k} Exemplu. Programul urmtor calculeaz frecvena literelor ntr-un text var ch: char; frecventa: array [ ' A ' . . ' Z ' ] of i n t e g e r ; l i t e r a _ m a r e : set of ' A ' . . ' Z ' ; l i t e r a _ m i c a : s e t of ' a' . . ' z ' ; begin litera_mare := ['A'..'Z']; Iitexa_mica := ['a'..'z']; f o r c h : = ' A ' to ' Z ' do f r e c v e n t a [ c h ] : - 0 ; while not eof do begin while not e o i n do begin read(ch) ;

66

3. Instruciuni

if ch in l i t e r a _ m i c a + l i t e r a _ m a r e then { l i t e r e l e mici s i n t c o n v e r t i t e i n l i t e r e m a r i } begin i f ch in l i t e r a _ m i c a then c h : = c h r ( o r d ( c h ) - ( o r d ( ' a ' ) - o r d ( ' A ' ) ) ) ; ' frecventa[ c h ] : = f r e c v e n t a [ c h ] + 1 end end; readln end; f o r ch : = ' A ' to ' Z ' do w r i t e l n C Frecventa l u i ch, ' e s t e - ' , f r e c v e n t a [ c h ] ) end. Exemplu. Programul urmtor calculeaz cu aproximaie valoarea c o s ( x )

[W721:

{ c a l c u l e a z cos( x ) = l - x 2/2! + x 4 / 4 ! - . . . } program c o s ; const e p s = l e -6; var x,sx,s,t : real; i,k i integer; begin w r i t e l n C F u r n i z a i v a l o a r e a l u i x ' ) ; r e a d ( x ) ; t : - l ; k :=0; s : = l ; s x : = s q r ( x ) ; while a b s { t ) > eps * a b s ( s ) do begin k : = k +2; t : - - t * s x / ( k * ( k - 1 ) ) ; s:=s+t end; writeln('cos C , x , ' ) = ' , s ) end. O alt ilustrare a utilizrii instruciunii while apare n exemplul 1 din paragraful 3.3, la prelucrarea informaiilor dintr-un fiier.

3.2.2.2. Instruciunea repeat Instruciunea repeat are forma (vezi anexa 2, definiia 2.23.1): zepeat I j . . . In until B Instruciunile aflate intre repeat i until snt executate pn cnd expresia booleana B care controleaz repetiia devine adevrat. Execuia se poate ns ncheia i printr-un transfer necondiionat Aceast instruciune este echivalent cu secvena de instruciuni Ii. . ; IB while not B do begin I j . . . ;

; In and

Se observ c instruciunile I a ,. .., I se execut cel puin o dat. Se recomanda utilizarea sa n locul instruciunii while atunci cnd evaluarea expresiei care controleaz repetiia se face dup executarea instruciunii I . Exemplu. Prin programul urmtor se citete de la fiierul standard de intrare un ir de numere ntregi cu proprietatea c toate numerele, cu excepia ultimului, snt nenule. Aceste numere se transfer ntr-un fiier cu tipul de baza integer i se calculeaz apoi suma tuturor componentelor fiierului. var v: file of integer; a: integer; suma: integer; <.

3.1. Instruciuni simple

67

begin rewrite( v ) ; repeat read( a ) ; write(v,a) until a- 0 ; reset( v ) ; suma:= 0; while not eof(v) do begin suma : = suma + y " ; get(v) end; writeln('Suma=', suma) end. Exemplu. Programul urmtor citete doi vectori cu componente ntregi i scrie pe ecran TRUE sau FALSE dup cum vectorii snt identici.sau nu: const n='i; type vector = airay | L . . n ] of integer; var a , b : vector; i: integer;
begin

for i : - J to n do read(a[ i ] ) ; for i : = l to n do read ( b |'i ] ) ; repeat i : = L * i until ( i = n ) or ( a i i ] o b i i ) ; write(a[i]=bfil) ;


end.

Exemplu. Programul urmtor calculeaz cel m a i mare divizor comun al dou numere ntregi pe baza algoritmului l u i Euclid. var a , b, c : t : char; begin repeat write( ' Furnizai numerele a s: b : ' ) ; readlti(a, b) ; a : = abs(a); b : - a b s ( b ) ; while (a O 0 ) and (b < > o) do begin C b; b : - a mod b; a : -- c end; wr i te( ' cmmdc f ' , a + b, Continuai? Rspundei d sau n ' ) ; readln(t) until t -- 'n' end. integer;

68

3. Instruciuni

Exemplu. Programul urmtor ordoneaz cresctor o list de n>i numere ntregi, prin metoda inversrii elementelor adiacente. const nmax-100; var lista :array [L.nmax] of integer; n, {lungimea efectiva a listei ( i : O . . nmax; loCj nv : 1. .nmax; l l o c u L ultimei inversiuni I I. . : integer; begin writeCdati lungimea l i s t e i ' ) ; read In( n ) ; writeCdati ' , n , ' elemente a l e listei' ) ; f o r i I to n do read ( l i s t a [ i ] ) ; r e p e a t 1ocinv:-l; f o r i : ^1 to n-.l do i f lista M l > l i s t a li+.l ] then b e g i n {se face inversiune} t: --lista 1 i] ; lista { i ] lista [ i i 1 } ; lista l i " l ] t; lOCinV : i end; ! l i s t a |locinv . . n } este ordonata cresctor 1 u n t i l locinv-1 ; wr j te In ( 'lista ordonata cresctor este:').,; for to n do writeln( l i s t a |i|) end.

3.2.2.3. Instruciunea for Instruciunea f o r a r e formele (vezi anexa 2, definiiile 2.23.m , 2.23.n) for v sau f o r v : - i downto f do l. V a r i a b i l a v este de t i p scalar ordinal (deci nu real) iar i i f snt expresii de tipuri compatibile cu tipul l u i v. n mod normal, instniciunea specific executarea repetat a grupului de instruciuni
V

:-

to [ do I

X;

T
_

pentru toate valorile x d i n intervalul cuprins ntre i i t , luate n ordine cresctoare pentni prima form i n ordine descresctoare pentm a doua. Execuia poare fi ns ncheiat i printr-un transfer necondiionat. Valoarea final a variabilei v se consider a f i nedefinit dup terminarea normal a instruciuni' f o r . Prin urmare, cu excepia faptului c variabila Y este nedefinit dup terminarea normal, instmciunea

3.1. Instruciuni simple

69

f o r v := i to f do l este echivalent cu v : - i ; while v <' f do b e g i n I ; v : = s.ucc(v) end i a r i n s t r u c i u n e a f o r v : - i downto f do T cu v := i; while v > = f do begin I ; v : = pied(v) end . .

Aceast instruciune este util pentru programarea formulelor de recuren de forma ac. = a , a n ., - f(an), n> -0 .

Astfel, n urma execuiei unei secvene de instruciuni de forma urmtoare v : - a ; f o r i : ^ 1 to n do v valoarea lui v este a r . P r i n urmare, n cazul a 0 - 1, a ,a* (nKI.) ' : = f (v)

programul urmtor v a r i, v : integer; begin v 1 ; for i : 1 to V do -v : = v *. i.. end.

calculeaz valoarea v = /!. r v: Pentru a prelucra pe rnd toate valorile tipului dat de definiia
- -

t y p e EH -

(A_l,

A_7.,

A_~\, A_4) ;

n ordine descresctoare, utiliznd o procedur P i o variabil v de tipul EH, putem folosi instruciunea iterativ f o r astfel: for v :- A 4 downto A i do P ( v ) n acest c a z , .secvena de instniciuni executat va f i : P(A_4) ; P( A_ i ) ; P( h_ Z ) ; P(A_l) .

E x e m p l u . Programul urmtor calculeaz produsul a dou matrici. { i tunul t i . re m a t r i c i !

70

3. Instruciuni

const m var i S : A B :

= 1; p = 3; - 2 ; n 1. .m; Integer; J . .p! J . .n] l.-.n] si B} mat rit j : n; 1 . : k

: array [.):. .m. : array [ .1 . . p, C : array [1 . . m , begin (ini t i a i i /.are A writeIn < ' scrieti for i: l to m do

begin for k : - 1 to p do begin r e a d ( s ) ; w r i t o ( s ) ; A | i , k } : - S end; wr i. teln end; {a fost citit A} writeln; for k : -1 to p do begin for j : --1 to n do begin read(s); write(s); B[k,;j| := end; v. writeln end; { a tost, citit Bl writeln; ise calculeaza C = A * B) wri teln('A * B - ' ) ; for i : - 1 to m do begin for j : = . l to n do begin s := o; for k : - 1 to p do s s * A]i,k] * B[k,j1; Cfi.jJ s; write(s) end; writeln end; w r i teln

3.2.3. Instruciuni condiionale


O instruciune condiional selecteaz o singur instruciune d i n t r e a l t e r n a t i v e l e sale, pe care apoi o execut. Instruciunile c o n d i i o n a l e snt i f i case.

3.2.3.1. Instruciunea if Instruciunea i f are forma (vezi anexa 2, definiia 2.23.h): i f B then I sau

3.1. Instruciuni simple

71

if 15 then I else J E x e c u i a instruciunii i f ncepe p r i n evaluarea condi;iei B. Dac r e z u l t a t u l e v a l u r i i este t r u c , atunci se execut instruciunea 1 . Dac r e z u l t a t u l e v a l u r i i este f a l s e , atunci n primul caz se execut instniciunea de efect n u l , i a r n a l doilea caz se execut instruciunea J. Observaii Dac n instruciunea i f 6 then s , introducem nainte de s instruciunea de efect nul (if B then; S) atunci a n u m a i intr n componena i n s t r u c i u n i i c o n d i i o n a l e , d e c i este e x e c u t a t i n d i f e r e n t de v a l o a r e a l u i n. 2. Amintim c limbajul Pascal nu consider simbolul ; ca facnd parte d i n instruciune ci l folosete ca delimitator. Prin urmare, dac ntr-o instniciune i f B then I else J introducem dup I simbolul ; obinem un program incorect sintactic (n acest c a z secvena else. . . este interpretat ca f i i n d i n s t n i c i u nea ce urmeaz celei condiionale). 3.Ambiguitatea sintactic a construciei

1.

i f B_l then i f B_2 then else ] _ 2

I_l

(else face parte din primul i f sau din cel de-al doilea?) este rezolvat p r i n interpretarea construciei c a fiind echivalent cu i f 13__3 then begin i f B_2 then I _ l else I._2 end

> kM

Ilustrm utilizarea instruciunii condiionale if i a instruciunii iterative while prin exemplul urmtor care convertete un numr in baza 10 n scrierea cu cifre romane. Daca x este o variabil ntreag ce conine numrul ce trebuie convertit, atunci urmtoarea instruciune compus realizeaz conversia dorit: var x : 0 . . m a x i n t ; begin readln(x); write(x, ' = ' ) ; while x > = 1 0 0 0 do begin w r i t e C M ' ) ; x : x - 1 0 0 0 end; if x > = 9 0 0 then begin w r i t e ( ' C M ' ) ; x : = x - 9 0 0 end else if x > = 5 0 0 then begin w r i t e ( ' D ' ) ; x : = x - 5 0 0 end else if x > = 4 0 0 then begin w r i t e ( ' C D ' ) ; x : = x - 4 0 0 end; while x>=100 do begin w r i t e ( ' C ' ) ; x : = x - 1 0 0 end; if x > = 9 0 then begin w r i t e C X C ) ; x : = x - 9 0 end else if x > = 5 0 then begin w r i t e ( ' L ' ) ; x : - x - 5 0 end else if x > = 4 0 then begin w r i t e { ' X L ' ) ; x : = x - 4 0 end; while x > - l 0 do begin w r i t e ( ' X ' ) ; x : = x-10 end; if x = 9 then begin w r i t e ( ' I X ' ' ) ; x : = x - 9 end else if x > = 5 then begin w r i t e ( ' V ' ) ; x : = x - 5 end else if x - 4 then begin w r i t e C i v ) ; x : = x - 4 end; while x > - l do begin w r i t e C I ' ) ; x : = x - l end; w r i t e l n

72

3. Instruciuni

end. O utilizare abuziv a instruciunii if este urmtoarea if a - b then found : = t r u e else found : = f a l s e unde found este o variabil booleana Evident, acelai efect se obine prin execuia instruciunii found a=b

Exemplu. Prin programul urmtor se calculeaz xy, unde y este numr natural nenul. var e , y : 0 . . 1 0 0 ; u , x , z : r e a l ; begin readln(x); readln(y); z := 1 ; u x; e != y; while e > 0 do begin while not o d d ( e ) do begin e : - e div 2 ; u :- sqr ( u ) ; end;

law

e :- e, - 1; z := z * u and; w r i t e l n { x , ' l a puterea ' , y , i z - x ** y }

z)

end. Observm c o variant mai simpl dar mai puin eficient se poate obine omind instruciunea while interioar, rezultatul z este astfel obinut prin y multiplicri ale lui x. Alte ilustrri ale utilizrii instruciunii if pot fi gsite n exemplul 2 din paragraful 3.3.

3.23.2. Instruciunea case Instruciunea case (vezi anexa 2, definiiile 2.23.i, 2.23.J) const dintr-o expresie numit selector i o list de instruciuni, fiecare precedat de o constant de acelai tip cu selectorul sau de cuvtntul cheie othexwise. Instruciunea casa se execut astfel: se evalueaz expresia ce definete selectorul i apoi se execut fie instruciunea precedat de constanta egal cu valoarea selectorului, fie instruciunea precedat de othexwise

dac valoarea selectorului nu coincide cu nici una din constantele ce eticheteaz instruciunile componente. n acest ultim caz, absena specificaiei othexwise
conduce la erori. Exemplu. Programul urmtor simuleaz un calculator cu operaiile elementare +, -, *, div i mod pentru numere ntregi. program c a l c u l a t o r ; var a , b : i n t e g e r ; codoper: c h a r ; begin

3.1. Instruciuni simple

73

w r i t e ( ' c o d o p e r a i e : ' ) ; r e a d l n (codoper) while codoper <> '.' do begin write('operanzi: ' ) ; readln(a, b); write('rezultat: ' ) ; case codoper of b, a+b) a-b) a*b) writeln( a, div ' , b , b , ' = ' , a div b , mod ', b , writeln( ' - ' , a b , mod b ) ; otherwise a, writeln('cod operaie writeln( n e c u n o s c u t ' ) and; write('cod operaie:'); readln(codoper) an d end. O alt ilustrate a utilizrii instruciunii case poate fi gsit n exemplul 3, paragraful 3.3. Observaii 1.Constantele ce prefixeaz componentele unei instruciuni casa nu snt etichete n sensul din paragraful 1.2 i nu pot prin urmare s fie referite printr-o instruciune goto i nici nu pot s apar ntr-o declaraie labei. 2.Ordinea acestor constante este arbitrar, dar fiecare nu poate apare dect o singur dat ca prefix de componente. 3.Dintr-o instruciune component nu se poate face transfer la o alt component.

3.2.4. Instruciunea with


n paragraful 2.2.2-, unde a fost introdus tipul de date record, s-a menionat c dac x este o variabil de tip record, avnd pe s_i drept component, atunci referirea la s_i se face prin x. s_i. Dac s_i este la rndul ei de tipul record, atunci referirea la componenta sa s_ i _ j se face prin x. s_i. s_i_ j . Acest mod de referire a componentelor unei date structurate este n anumite situaii greoi. Pentru a nltura acest neajuns a fost ncorporat n limbaj instruciunea witb care definete domeniul de valabilitate pentru identificatorii proieciilor canonice ale unor variabile de tip record. n acest fel, o proiecie canonic poate fi referit i prin numele ei s_i, fr a fi necesar calificarea prin numele articolului care o conine. Forma general a instruciunii with este: witb. <variabila_record> { , < v a r i a b i l a _ r e c o r d > } do < i n s t r u c t i u n e > Spre exemplu, n prezena declaraiilor: type complex = record x , y : r e a l and; numr - record case t i p : ( i n t , r e , corn) of

74

3. Instruciuni

i n t : (x_int : i n t e g e r ) ; re : (x_re : real); corn : (x_com : complex) and; var n : n u m r ;

putem face iniializrile: n . t i p .:- int; n.x_int : - 1; n.tip re; n.x_re : = 1 .1 ; n.tip corn; n.x_com.x : 0 . 0 ; n.x_com.y 1 .0 ;

sau putem folosi instruciunea with echivalent: with n , x_com do begin tip int; x_int 1; t i p : = r e ; x_re 1.1; tip corn; X : - 0 . 0 ; y : - 1 .0 rad { w i t h } Exemplele 1 i 3 din paragraful 3.3 snt alte ilustrri ale mstruciunii with. Observata 1. Este interzis afectarea elementelor din lista de variabile prin instruciunile asociate lui with. Dac de exemplu a este o variabil de tipul array avnd tipul de baz un tip record, atunci with a [ i ] do i : - i + 1 nu este permis. 2. Dac declaraia var a : axray [ 1 . . 2 ] of integez; a : 1 . .2 ; nu este permis, datorit unei definiii ambigue pentru a, declaraia var a : integer; b : racord a : r e a l ; b : boolean and; este permis, variabila a este de tip inegez i b. a este de tip r e a l . n plus, ntr-o instruciune with b do S identificatorii a i b, dac snt referii n S, au semnificaia b . a i respectiv b.b.

3.1. Instruciuni simple

75

33. Exemple
Exemplul 1. Programul urmtor creeaz un fiier cu componente de tipul record per soana; cmpurile acestor componente se obin prin citire din fiierul input (de la terminal). Fiierul este apoi citit i snt numrate nregistrrile cu cmpul anul-194 9. type persoana - record nume, prenume : packed azzay [ 1 . . 2 0 ] of c h a r ; z i u a : l . . 3 1 ; luna : 1. .12; anul : integer and; var individ : p e r s o a n a ; f : fila of p e r s o a n a ; n integer; begin \ rewrite(f) ; vith individ do begin while not eof { e x i s t a inca d a t e } do begin w r i t e ( ' nume: ' ) ; readln( n u m e ) ; w r i t e ( ' prenume: ' ) ; r e a d l n ( p r e n u m e ) ; writelnCdata naterii') w r i t e C z i u a : ' ) ; readln ( z i u a ) ; w r i t e ( ' l u n a : ' ) ; readln( l u n a ) ; w r i t e ( ' a n u l : ' ) ; readln( a n u l ) ; f * : - individ; p u t ( f ) { s a u w r i t e ( f , i n d i v i d ) } and; m r e s e t ( f ) ; n : = 0 ; while not e o f ( f ) do begin i n d i v i d : - f " ; g e t ( f ) ; { s a u r e a d ( f , i n d i v i d ) ; } if anul=1949 then n : = n + 1 end; w r i t e l n ( ' s i n t ' , n, ' persoane cu anul 1 9 4 9 ' ) and end. .; . Exemplul 2. Considerm un fiier text de intrare, f a ; coninutul acestuia este copiat n fiierul text f b, pstrndu-se structura de linii a lui f a, dar nlocuind orice grup de dou caractere ' a ' consecutive printr-un caracter ' b ' : var f a , f b : t e x t ; c : c h a r ; begin reset(fa); rewrite(fb);

33.

Exemple while not eof(fa) do begin if e o l n ( f a ) then begin readln(fa); writeln(fb) end Is* begin

77

76

3. Instruciuni

read( f a , c ) ; if c < > ' a' then w r i t e ( f b , c ) else if eof( f a ) then w r i t e ( f b , c ) else if e o l n ( f a ) then begin write(fb, c ) ; readln(fa) ; writeln(fb) end IB* begin read( f a, c ) ; if c - ' a' then w r i t e ( f b , ' b' ) else begin write(fb, ' a ' ) ; write(fb, c) end end end end end.
*-

E x e m p l u l 3. Considerm tipul de date persoana din exemplul 1 completat cu cmpurile cod i c o p i i . Se creeaz un fiier n acces direct cu componente de tip persoana; cod va fi chiar numrul de ordine al componentei. Programul permite urmtoarele tipuri de operaii asupra fiierului: * a': adugarea unei componente la fiier (cmpurile componentei se citesc de la terminal); 'u': actualizarea cmpului copii al unei componente din fiier, identificat prin cod; ' 1': listarea componentelor fiierului cu numere de ordine ntr-un interval; ' a': terminarea programului. type persoana = zacozd cod : integer; nume, prenume : packed array [1..10] o char; ziua : 1 . . 3 1 ; luna : 1..12; anul : integer; copii : integer end; vax individ : p e r s o a n a ; f : fila of persoana; n , ncod,pcod,ucod,i : integer; codoper : char; begin r e w r i t e ( f , , ' / s e e k ' ) ; with i n d i v i d do begin

3.1. Instruciuni simple

77

w r i t e ( ' c o d operaie ( e , a ) : ' ) ; readln( c o d o p e r ) ; while codoper< > ' e ' do begin caaa codoper of ' a ' : { a d a u g a } begin w r i t e ( ' c o d : ' ) ; r e a d l n ( c o d ) ; w r i t e ( ' nume: ' ) ; readln(nume); w r i t e ( * prenume: ' ) ; readln( p r e n u m e ) ; w r i t e l n C d a t a n a t e r i i ' ) ; w r i t e ( ' z i u a : ' ) ; readln( z i u a ) ; writeCluna:'); readln(luna); write('anul: ' ) ; r e a d l n ( a n u l ) ; w r i t e ( ' copii: ' ) ; readln( c o p i i ) ; s e e k ( f . c o d ) ; w r i t e ( f , individ) end; ' u ' : ( a c t u a l i z e a z ) begin w r i t e ( ' c o d : ' ) ; readln(ncod); w r i t e C n u m a r copii de a d u g a t : ' ) ; readln(n) ; seek(f,n c o d ) ; read(f, i n d i v i d ) ; copii: = c o p i i + n ; seek( f , n c o d ) ; w r i t e ( f , individ) end; ' 1 ' : { l i s t e a z } begin w r i t e ( ' de la: ' ) ; readln(pcod); w r i t e C p i n a l a : ' ) ; readln(ucod) ; seek( f , p c o d ) ; fox i:=pcod to ucod do begin r e a d ( f , i n d i v i d ) ; w r i t e l n ( c o d , nume, prenume, z i u a , luna, anul, copii) end 3.3. 79 Exemple ud; otherwise end; w r i t e ( ' c o d o p e r a i e ( e , l , a , u ) : ' ) ; l e a d l n ( c o d o p e r ) end end end. Exemplul 4. (Problema lui Josephus [Kn74], p.178). Se consider n obiecte, aezate pe un cerc i numerotate n ordinea aezrii 1, 2 , . . . , " n . Parcurgnd cercul n sensul dat de numerotarea obiectelor, ncepnd cu obiectul m, se elimin pe rnd toate obiectele din k n k. Programul urmtor determin numerele de ordine ale obiectelor eliminate pentru n , m , k dai, folosind o list circular creat dinamic. type l e g t u r a - "nod; nod = record numr: integer; urmtorul: legtura end; var p , q , r : l e g t u r a ; n , m, k : integer; i, j: integer; begin w r i t e C n u m a r de o b i e c t e : ' ) ; r e a d l n ( n ) ; w r i t e C c u c e obiect s e incepe e l i m i n a r e a : ' ) ; readln ( m ) ;

78

3. Instruciuni

write('din cite in cite:'); readln(k); {construiete lista c i r c u l a r a } n e w ( p ) ; q : = p ; q * . numr: = 1 ; for i : - 2 to n do begin r:= q; new(q); r*.urmtorul:- q; q*.numr:= i end; q*.urmtorul:- p; { i n a c e s t moment p i n d i c a p r i m u l nod din l i s t a s i q u l t i m u l ; s e determina p r i m u l nod de e l i m i n a t ; p va indica nodul de e l i m i n a t s i q nodul precedent d i n l i s t a } for i : = 1 to m - 1 do begin q : = p ; p': = p * . urma t o r u l
and;

{incepe eliminarea} w r i t e l n ( ' ordinea de e l i m i n a r e e s t e : ' ) for i : = 1 to n -1 do


begin

w r i t e l n ( p * . n u m r ) ; { e l i m i n a nodul din l i s t a } q * . u r m t o r u l : = p*.urmtorul;; dispose(p); {determina u r m t o r u l nod de e l i m i n a t } p:- q; fox j : = 1 to k do begin q:= p; p:= p * . urmtorul and and; writeln(p*.numr) ; dispose(p)
and.

3.4. Exerciii
1. Fie programul Pascal: var txue : boolean; i : integer; begin true : = f a l s e ; i : = 0; while not t r u e do begin t r u e : = not t r u e ; i : = i + 1
end and.

Care este valoarea lui i dup execuia sa?

3.1. Instruciuni simple

79

2. S se scrie un program Pascal n care s fie utilizat instruciunea iterativ for (cazul to), pentru a calcula numrul armonic de ordin 100, h_lO0. Reamintim c h_n = 1 + 1/2 + . . . i /n [Kn74]. 3 Aceeai problem ca mai sus n care se substituie to cu downto.

4. Fie suma s _ i o o = l/l - 1/2 + 1/3 - . . . -1/100. Scriei cte un program Pascal care s calculeze s _ i o o a) evalund de la sting la dreapta 3.4. Exerciii b) evalund de ia dreapta la sting. Este corect urmtorul program Pascal? label 1; A var ( a l b , n e g r u ) ; *,' i _ s i r : packed array [ 1 . . 5 ] of c h a r ; begin i r e a d l n ( i _ s i r ) ; if i _ s i r - ' a l b ' then i : = a l b else if i _ s i r = ' n e g r u ' than i : = negru ti'-'' else w r i t e l n ( ' r e z u l t a t u l i m p r e v i z i b i l ' ) ; casa i of a l b : begin if t r u e than goto 1 ; 1 : i := succ(i) and; n e g r u : i : = p r e d ( i ) ; end; casa i of alb: writelnCalb'); negru: writeln('negru') end end.

81

5.

6.

Fie programul Pascal: labei l , 2 , 101, 102; var i : integet; begin i : - 1 ; casa i of 1 : 101 : goto 1 0 2 ; 2 : 102 : goto 101; and and. Este corect? De ce? 7. Fie declaraiile var a : i n t e g e r ; b : record a , b : integer end; a) Suit corecte instruciunile b.a := a ; b.b : = b.a b) Dac se execut instruciunile a : = 0 ; with b do

80

3. Instruciuni

a := 1; ce valoare are a ? 8. Fi T un tip de date pe care s-a definit o relaie de ordine total <,. Se numete sortare (n ordine cresctoare) a fiierelor din T* o aplicaie S : T* ------------------------------------------------------------------------------------------------------------>T*, definit astfel: oricare ar fi u = f l i 4 . f n e T , s ( u ) - f p l . . . f p n , unde (p_l, . . . ,p_n) este o permutare a lui ( i , . . . , n ) , astfel nct f p t f p j pentru 1 i <, j <, n. Practic, se poate construi fiierul sortat s ( u ) , eventual n aceeai arie de memorie ca u, sau numai permutarea (p_i, . . . , p_n). Fie mei un natural fixat, i un tip de date cu ordinea total i T - i". Pe T definim ordinea lexicografic astfel: kt. . . k lt.. .1 * k j - 1 pentru 1 i m sau exist p , l i p i m , astfel nct lq = l t pentru l 5 i S p - l i kp < lp. S se scrie un program de sortare n ordine lexicografic a unui fiier cu componente de tipul T, pentru I - integer. 9. Re definiiile Pascal: type candidat = zecozd

nume: packad axray [ 1 . . 3 0 ] of c h a r ; media : real ' and; var f: file of candidat; S se scrie un program de sortare a fiierului f : a) dup cmpul nume, n ordine lexicografic; b) dup cmpul media, n ordine descresctoare; c) dup cmpul media n ordine descresctoare, iar n cadrul aceleiai valori a cmpului m e d i a , dup cmpul nume n ordine lexicografic.

10.

Fie T un tip de date pe care s-a definit o relaie de ordine total <, i F = im s, unde s este aplicaia de sortare din exerciiul 8 (F este mulimea fiierelor sortate din T*). Se numete interclasare o aplicaie I : F x F r^-> F definit prin i ( u , v ) - s ( u v ) . Scriei un program de interclasare a dou fiiere cu componente de tip integer.

11.

Fie un fiier text f i al crui coninut este descris prin diagramele sintactice urmtoare: <continut> -------------,----------------------------------------------. -'i , - > EOF ---------> | ----- < c o n s t a n t a _ i n t r e a g a > <------1 |----------------- gp < -----------------------_ j l-------------------- eol <---------------------J <constanta_intreaga> --------1----------------1---------------1-----> < c i f r a > ---------1-------> unde sp este caracterul spaiu, eol este caracterul sfrit de linie, EOF este sfrirul de fiier, iar < c i f x a > este o cifr zecimal S se scrie un program care s transfere constantele ntregi mai mari ca -100 din fiierul f i ntr-un fiier text f o. Compararea va fi fcut n binar, iar conversiile vor ii efectuate prin program. Fiierul f o va pstra structura de linii a fiierului f i .

3.1. Instruciuni simple

81

12. Scriei un program care s adauge componente la sfrirul unui fiier extern deja existent, utilizind a) un fiier Pascal secvenial;

b)un fiier cu acces direct


13. Fie programul: var l i n i e : packed axxay [ 1 . . 7 2 ] of c h a r ; contor: integer; begin c o n t o r : - 0 ; bila not eoln do begin c o n t o r : - contor + 1 ; read( l i n i e [ c o n t o r ] ) and; readln; writeln(contor) and. Care este valoarea variabilei contor afiat pe terminal ca urmare a execuiei acestui program cu datele de intrare urmtoare: a) o linie vid, constnd din RETURN; b)spaiu urmat de RETURN; c) sfrit de fiier (CTRL/Z)? (n legtur cu observaia 1 de la paragraful 2.2.4.1.3). 14. S se scrie un program pentru rezolvarea problema lui Josephus (vezi exemplul 4 din paragraful 3.3), folosind o list circular cu legturi duble, definit prin: type l e g t u r a - * n o d ; nod- record inapoi: l e g t u r a ; { s p r e nodul precedent] numr: integer; n a i n t e : l e g t u r a { s p r e nodul u r m t o r ] and;

4.1. Mecanisme de abstractizare n Pascal


...........
Capitolele precedente au introdus conceptele de baz ale programrii (tip de date, expresie, instruciune) i realizarea lor n Pascal. Ele permit exprimarea riguroas a descrierilor i prelucrrilor de date sub form de programe. Introducem acum conceptele de funcie i procedur, care generalizeaz pe cele de expresie i instruciune. O funcie / procedur se definete printr-o declaraie care asociaz un nume cu o instruciune compus precedat, eventual, de o secven declarativ. Numele funciei / procedurii poate fi urmat de o list de parametri formali. Funcia / procedura este referit prin simpla inserare a numelui ei n locurile dorite din program avnd ca efect producerea n acele locuri a valorii / rezultatelor determinate de execuia instruciunii compuse. O astfel de referire se numete apel de funcie / procedur. Un numr de funcii uzuale (sin. I n , s q r t , axctan,...) i de prelucrri standard ( w r i t e l n , read,.. .)snt disponibile utilizatorului ca funcii, respectiv proceduri predefinite (vezi anexa 4). . Conceperea programelor n termeni de funcii / proceduri permite un nivel superior de abstractizare fa de expresii / instruciuni, furniznd astfel un mijloc de control al complexitii programelor. Acestea pot fi descompuse convenabil n subprograme mai simple, rafinate succesiv ca funcii / proceduri programate independent [Wi72]. Exprimarea unui algoritm ca program Pascal nu este unic. Conceperea structurii programelor, fol osirea de funcii sau proceduri, stabilirea parametrilor snt, n bun msur, la alegerea programatorului, cum se va vedea n exemplele din paragrafele urmtoare.

4.2. Funcii
Conceptul de funcie corespunde celui uzual matematic i extinde pe cel de expresie Pascal.

4.2.1. Declararea funciilor


Definirea unei funcii n Pascal se face n conformitate cu urmtoarele diagrame de sintax:
<functie> i> <antet_functie> > ; ,--------> <corp> - - - - -,- -,> ; - - -> ! I> <diiectiv> ' | > function -> <identificator> -> , -> <corp> 1

4.2. Funcii

83

<ancet_functie> i-------- ; <--------1 > function <identificator> T ( L <param foimal> J ) -,


I_____

<corp>

- -> . .-: .

: > <identificator tip> > <U4 sXv S?JJ JS-'JS Sj?. ; JSAS :. >

________________:-------------:____________________l

--------------> <declaratii> > <instructiune_compusa>

n general textul Pascal al unei declaraii de funcie are forma: function f ( x , ; . . . ; x_) : t; begin f : = e; end ; {f}

Primul rnd ilustreaz antetul funciei cu: f: identificator reprezentnd numele funciei; ( x i ( - . . . ; x n ) : list (opional) de parametri formali reprezentnd argumentele funciei; - t: identificator reprezentnd tipul rezultatului; acesta trebuie s fie un tip simplu (scalar) sau pointer. Antetul este urmat de corpul funciei, format din: - dx: declaraii locale ale funciei (opionale) grupate n seciuni (eventual vide) scrise n ordinea

labei const type var function / piocedure

Aceste cerine snt mai puin stricte n Pascal Oregon vezi 4.6.1. -begin . . . f : = e ; . . . e n d ; : instruciune compus specificnd prelucrrile de date ce se produc prin execuia funciei; numele f al funciei (fr parametri) apare cel puin o dat n partea sting a unei instruciuni de atribuire care se execut: f: '- e. Rezultatul ntors de funcie, de tipul t, este ultima valoare atribuit lui f.

4.2.2. Apelul funciilor

. - fi

Utilizarea unei funcii se specific printr-un apel de forma: f(a1( . .. ,a) - f: numele funciei; - ( a t , . . . , a n ) : lista (opional) de parametri actuali reprezentnd expresii ale cror valori sau adrese snt furnizate funciei. Apelul de funcie este un operand ntr-o expresie; el se insereaz n locul n care este dorit valoarea produs de funcie. Cnd expresia este evaluat, funcia este activat, iar valoarea operandului devine valoarea ntoars de funcie.

4.2.3. Exemple
Vom scrie pentru nceput un program extrem de simplu, pentru calculul ariei unui triunghi ABC cunoscnd lungimile laturilor:

84

4. Proceduri, funcii, programe, module

program P I ; var a , b , c , p , s : r e a l ; bag in

- 3 -

; = 5;
6;

ab cPs writeln (s) and; { P l }

= ( a + b + c ) / 2; = sqrt (p * (p - a) * (p - b) * (p - c) ) ;

Acest calcul poate fi realizat i prin urmtoarea funcie: function a r i a : r e a l ; var p : r e a l ; begin p (a + b + c) / 2; aria s q r t ( p * ( p - a ) * ( p - b ) * ( p - c ) ) end; Declaraia acestei funcii conine antetul function a r i a ! r e a l ; n care specificaia real stabilete tipul valorii calculate. Restul textului reprezint corpul fimeiei, format dintr-o declaraie i o instruciune compus. Numele funciei apare n instruciunea compus n partea sting a unei instruciuni de atribuire. Asupra utilizrii variabilei p facem urmtoarea observaie. Dac s-ar rescrie cele dou instruciuni, nlocuind variabila p prin a r i a , cele dou instruciuni ar deveni: aria:= (a+b+c)/2; aria:=sqrt(aria*(aria-a)*(aria-b)*(aria-c)). Apariia variabilei a r i a n membrul drept este incorect, aceasta implicnd apelul (recursiv) la funcia a r i a . Programul PI poate fi rescris acum n forma P 2. program P 2; var a , b , c , s : r e a l ; function a r i a : r e a l ; var p : r e a l ; begin p : = ( a + b + c ) / 2; aria := sqrt(p * (p-a) * (p-b) {aria} begin a := 3 ; b ! 5 ; c :- 6 ; s : = a r i a ; w r i t e l n ( s ) end. { P 21

{arial

* ( p - c ) ) end;

Printre declaraiile programului P 2 apare i cea care definete funcia a r i a . Variabilele reale a, b , c , s ale programului snt cunoscute i n corpul funciei; ele snt variabile globale relativ la funcia a r i a . Variabila p este ajuttoare pentru funcie, ea servind doar la calculul unei valori intermediare fr interes pentru restul programului. Declaraia ei . . . var p : r e a l ; a fost deplasat n corpul funciei; p devine astfel o variabil local funciei i nu este accesibil n afara corpului funciei. Ea va fi creat (prin alocare de spaiu

4.2. Funcii

85

pentru valorile sale) la fiecare activare a funciei i desfiinat (prin dealocarea spaiului ei) la completarea execuiei funciei i revenirea n program. Se previne astfel i un efect secundar (vezi 4.5.3) nedorit c e s-ar fi produs dac p ar fi rmas global: valoarea atribuf ei prin instruciunea p : = ( a + b * c )/2 ar fi devenit, inutil, cunoscut n tot programul. Apariia numelui funciei n expresia din partea dreapt a instruciunii s := aria determin activarea funciei cu efecte echivalente instruciunii compuse: begin p := ( 3 + 5 + 6 ) / 2 ; aria := sqrt(p * (p - 3 ) * (p - 5 ) * (p - 6 ) ) end; Valoarea astfel obinut va fi inserat n locul numelui funciei i atribuit lui s. Comunicarea ntre program i funcie nu este specificat explicit; ea se face prin variabilele globale a, b, c, care snt cunoscute i n corpul funciei. Limbajul permite o form sintactic n care elementele de comunicare snt desemnate explicit prin declararea lor n antet ca parametri formali ai funciei, de exemplu: function aria { a , b, c : real) : real; Prin specificarea ca parametri formali, a, b, c desemneaz i ei variabile locale funciei. Apelurile de funcie vor conine acum parametrii actuali care corespund celor formali n numr i tip, de exemplu: aria( 3 , 5 , 6 ) aria( 6 , 4 , 9 ) . Programul P 3 include aceste modificri. program P 3; var a , b , c , s : real; function aria(a, b, c : real) : real; var p : real; begin p :- (a * b + c) / 2 ; aria : = sqrt(p * (p - a ) * (p - b) * (p - c ) ) end; {aria begin a : = 3 ; b : = 5 ; c : = 6 ; s : = aria (a, b, c) end. { P 3} Identificatorii a, b, c apar acum n dou declaraii: n program i n antetul funciei. n antetul funciei ei snt declarai drept parametri formali. Aceste declaraii snt valabile doar n corpul funciei; variabilele numite de ei nu exist n afara acesteia. Aceste variabile snt deci diferite de cele desemnate cu acelai nume n program prin declaraia var a , b, c , s : real; Variabilele a , b , c astfel declarate nu snt cunoscute n corpul funciei. Doar s este cunoscut n tot textul programului P 3, deci i n corpul funciei

86

4. Proceduri, funcii, programe, module

aria. Spre deosebire de a, b i c, s nu a fost redefinit n corpul acesteia. El rmne o variabil global pentru funcie. Aceste observaii sugereaz c alegerea numelor parametrilor formali este la latitudinea programatorului, fr grij pentru coliziune de notaii, fapt care uureaz mult programarea. Devine astfel posibil realizarea de subprograme scrise ca funcii Pascai de ctre persoane diferite. Pentru a asigura comunicarea ntre aceste subprograme este suficient s se convin asupra aritii lor, adic asupra numrului de parametri formali i asupra tipului lor, nu i asupra numelor lor, care pot s coincid sau nu n declaraii diferite de funcii. Funcia a r i a putea fi declarat folosind de exemplu parametrii formali x, y , z astfel: f u n c t i o n a r i a ( x , y , z : r e a l ) : r e a l ; var p : r e a l ; begin p := (x + y + z) / 2 ; aria := sqrt(p * (p - x) * (p - y) {aria}

* (p - z)) end;

i invocat prin a r i a ( a , b , c ) sau prin a r i a ( 3 , 5 , 6 ) , e t c . Prin aceast ultim chemare, valorile specificate de parametrii actuali 3, 5, 6 snt transmise drept valori ale parametrilor formali a, b, c cu efectele specificate mai sus. Exemplu. Funcia compl din programul urmtor calculeaz complementara unei mulimi x relativ la o alt mulime e. Tipul rezultatului este pointer, deoarece utilizarea unui tip structurat este interzis n aceast situaie. type m u l t i m e = s e t of 0 . . 2 5 5 ; p m = " m u l i m e ; function compl( e , x : m u l i m e ) : pm; var p: pm; begin new(p); pA:= e - x; compl:p; end; var a , b, e : m u l i m e ; begin a:-[0,5,7,3,9]; ' b:=[2,7,8,12,34,3] ; e:[0. .255] ; { V e r i f i c a r e a r e g u l i l o r l u i De M o r g a n } w r i t e l n ( compl( e , a + b ) A = compl( e , a ) * * compl( e , w r i t e l n ( compl ( e , a * b ) * = compl ( e , a ) * + compl ( e , b ) *') ; end.

b)A);

43. Proceduri
Conceptul de procedur extinde pe cel de instruciune. Formele sintactice ale declaraiei i apelului snt similare celor pentru funcii.

4.3.1. Declararea procedurilor


Definirea unei proceduri Pascal se face n conformitate cu urmtoarele diagrame de sintax: <procedura> i-------> <antet_piocedura> ; |--> <corp> ----1- -,> ; - - ->

4.2. Funcii

87

l> <directiva> 1 | > procedure > <identificator> > ; > <corp> 1

<antet^procedura> i-----------; <---------^ ------> procedure<identificatoi> I ( l <param_formal > )-,> Forma general a textului unei declaraii de procedur este: procedura p (x1(\. . . ; x) ;
Di;

begin end; {p}

- p: numele procedurii; - (x1(- . . ; x ) : list (opional) de parametri formali, n

n antetul procedurii apar:

corpul procedurii snt incluse: - D x : declaraii locale procedurii (opionale) grupate dup aceleai reguli ca n cazul funciilor; - begin.. .end; : instruciune compus; ea nu conine vreo atribuire asupra numelui procedurii. Procedura poate s ntoarc mai multe rezultate dar nu prin numele ei, ci prin variabile desemnate special (cu prefixul var) n lista de parametri; tipurile rezultatelor se specific n lista de parametri ca tipuri ale acestor variabile.

4.3.2. Apelul procedurilor


-

Activarea unei proceduri se specific printr-un apel de forma: p(alf . . . ,an) cu - p: numele procedurii; - ( a , . . . , a ) : lista (opional) de parametri actuali. Spre deosebire de funcie, apelul de procedur este o instruciune; aceasta se insereaz n program n locul n care snt dorite efectele produse de execuia procedurii pentru eventualii parametri actuali a l t . . . , an.

4.3.3. Exemple
Textul de program din 4.2.3 pentru calculul ariei unui triunghi poate fi rescris ca o procedur Pascal astfel: pxoceduxe a r i a ( a , b , c : r e a l ; var s : r e a l ) ; var p : r e a l ; begin p := (a + b + c) / 2 ; s : = s q r t ( p * ( p - a ) * ( p - b ) * ( p - c ) ) end; {aria} . Anteml procedurii

88

4. Proceduri, funcii, programe, module

procedure a r i a ( a , b , c : r e a l ; var s : r e a l ) ; conine numele ei i declaraiile parametrilor formali a , b , c i s. Restul textului este corpul procedurii; el conine o declaraie i o instruciune compus. Observm c, spre deosebire de funcii, n antet nu mai apare o specificaie a tipului rezultatului; de asemenea, numele procedurii nu apare n partea sting a unei instruciuni de atribuire din corpul ei. Notm n sfrit forma special n care este declarat parametrul formal s n antet: var s : r e a l ; Acesta este acum parametru variabil i va fi folosit pentru ntoarcerea unui rezultat din procedur; a , b , c snt parametri valoare i servesc, ca i la funcii, pentru acceptarea de valori transmise procedurii. Programul are acum forma: program P4; var s i : r e a l ; procedure a r i a ( a , b , c : r e a l ; var s : r e a l ) ; var p : r e a l ; begin p (a + b + c) / 2; s : = s q r t ( p * ( p - a ) * ( p - b ) * ( p - c ) ) end; {aria} begin aria( 3 , 4 , 6 , si); writeln ( s i ) end; {P4} Execuia instruciunii a r i a ( 3 , 4 , 6 , si) determin transmiterea valorilor primilor trei parametri actuali drept valori ale parametrilor'formali a , b, c i a locaiei parametrului actual si drept locaia parametrului formal s. Observm c sl este o variabil. Ea corespunde parametrului formal s, declarat cu vax. Invocarea procedurii determin efecte echivalente urmtoarei instruciuni compuse: begin p : = (3 + 4 + 6 ) / 2 ; sl : = sqrt(p * (p - 3 ) * end; (p - 4 ) * (p - 6 ) )

4.4. Programe 4.4.1. Forme sintactice; exemple


Sintactic, forma general a unui program amintete pe cea pentru funcii i proceduri: program P(x1( . . . ,xn) ; D; begin . end. {Pl unde P este numele programului. Ca i la funcii / proceduri declaraiile D snt grupate n seciuni (eventual vide) labei, const, type, var, funct-ion / procedure, scrise n aceast ordine; similar se definesc antetul i corpul programului. n implementarea Oregon regulile pentru declaraiile

din lista D snt mai puin stricte (vezi 4.6.1.2). De asemenea, antetul programului este opional.

4.2. Funcii

89

Parametrii formali specificai n lista (xv, . . . ,x) denot entiti (de regul fiiere) de comunicare a programului cu mediul su. Aceste entiti (n afara fiierelor standard input i output) trebuie declarate n program. Specificarea identificatorilor input sau output ca parametri formali ai programului are ca efect declararea implicit a acestora ca fiiere text i executarea implicit a apelurilor de procedur reset (input), respectiv rewri te (output) la nceputul fiecrei activri a programului (vezi 2.2.4.1.2). Corpul programului este urmat de ' . ' i nu de ' ; " ca n cazul funciilor i procedurilor. Exemple: program copie ( f , g ) ; var f , g : f i l e of real; begin reset(f); rewrite(g); while not e o f ( f ) do 4.4. Programe begin g " : = f * ; put(g); get(f) end {copie}

93

ond.

Parametrii formali f i g din antet snt declarai n corpul programului drept fiiere de numere reale. Instruciunea compus care urmeaz descrie partea de aciune a programului: copierea fiierului f n fiierul g. Programul c o p i e t e x t care urmeaz folosete parametrii formali i n p u t i o u t p u t predefinii ca fiiere standard de intrare / ieire. Ei nu vor fi declarai n program. Partea de instruciuni determin la execuie copierea, linie cu linie, a fiierului de intrare n fiierul de ieire, pstrnd structura liniilor. program c o p i e t e x t ( i n p u t , o u t p u t ) ; var c h : c h a r ; begin while not eof do begin while not e o l n do begin read(ch); write(ch) end; writeln; ieadln end end. { c o p i e t e x t }

4.4.2. Structura static a programelor


Funciile / procedurile snt declarate n programe i pot s conin, la rndul lor, declaraii ale altor funcii / proceduri la orice nivel. Relaia de incluziune a declaraiilor de funcii, proceduri i program definete structura static a programului. Ei i se poate ataa o reprezentare arborescent n care: - programului / funciilor / procedurilor le corespund noduri marcate cu numele lor P, 0 , R , . . . ; - dac P conine declaraia lui Q, reprezentm structura static a lui P prin arborele

90

4. Proceduri, funcii, programe, module

- dac P conine declaraiile lui Q i R, n aceast ordine, reprezentm structura static a lui p prin arborele P Exemplu. Fie programul: program P; procedura Q; begin end; { Q } procedure R; function S ; begin end; begin end; end. {P
{R

...

{S}

} begin

Reprezentm structura static a lui P prin arborele:


P

/
Q R

\
s
I

4.4.3. Domenii de vizibilitate a declaraiilor


ntr-un program care nu conine declaraii de funcii / proceduri, pentru orice identificator x al su exist o singur declaraie dx. Orice referire rx a lui x n program are n vedere obiectul definit de aceast declaraie. Declaraia i referirile au loc n acelai program. Am vzut cum declaraii de funcii / proceduri n alte funcii / proceduri conduc la structuri de programe cu mai multe nivele. Aceasta, mpreun cu libertatea de alegere a numelor n program, fac posibil s existe, pentru acelai identificator x, mai multe declaraii diferite n uniti de program diferite. Fiecare astfel de declaraie definete un alt obiect Aceiai identificator poate deci desemna (numi) obiecte diferite n diferite pri ale programului. De asemenea, n program pot s apar mai multe referiri r x ale identificatorului x. Fiecare astfel de referire are n vedere obiectai x definit de o anumit declaraie d x . 4.43.1. Domenii de vizibilitate ale declaraiilor de identificatori Definiia 1. Fie P un program / procedur / funcie, x un identificator i d x o declaraie a lui x n P. Se numete domeniu de vizibilitate al lui d x textul de program n care pot apare referiri r x la identificatorul x ce desemneaz obiectul definit prin declaraia d x . Domeniul de vizibilitate al lui d^ ncepe imediat dup terminarea declaraiei i se sfrete odat cu p. Trebuie precizat c declaraia unei funcii / proceduri se consider terminat la sfritul antetului; acest fapt face posibil apelul recursiv: n corpul funciei / procedurii, aceasta poate fi referit, fiind vizibil. Exemplu: n programul urmtor, ncepuml domeniilor de vizibilitate este marcat prin comentarii, program P ; const n = 3 ; {de aici n devine v i z i b i l i type natural = 0..maxint; {de aici natural devine vizibil} function f ( x : natural {de aici x devine vizibil} ) : natural; {de aici f devine vizibila} begin

4.2. Funcii

91

if x end; begin end.

0 then f : = 1

{deci f poate f i referit} else f : = x * f ( x - l )

Exemplu. Urmtoarea declaraie a tipului arbore este eronat: type arbore - record info: char; sting: " arbore; {eroare, referin nainte ca arbore s devin vizibil} dreapta:* arbore; end; {numai de aici arbore devine vizibil} Domeniul de vizibilitate al unei declaraii d x nu este neaprat o poriune continu din textul programului. Apariia ntr-un subprogram Q, din domeniul de vizibilitate al declaraiei d,, a unei alte declaraii d'x (ce implic acelai identificator x) provoac acoperirea domeniului de vizibilitate al declaraiei prin domeniul de vizibilitate al declaraiei d'x. Acoperirea se produce de la nceputul declaraiei d x , n timp ce noul domeniu de vizibilitate ncepe de la terminarea declaraiei d;. Exemplu. Re programul urmtor: program P ; const c = 1; { a i c i ncepe domeniul de v i z i b i l i t a t e a l l u i d c } procedure q ; const { a i c i ncepe acoperirea l u i dc p r i n d j } c= . c + l ; { e x p r e s i e i n c o r e c t a } { a i c i ncepe domeniul de v i z i b i l i t a t e a l u i d'c} begin end { q } ; b e g i n . . . end. E x p r e s i a c + l este incorect: referirea Ia c se face dup acoperirea declaraiei din programul principal i nainte de a deveni vizibil declaraia din procedura q. E x e m p l u . n programul program P ; type t = 0 . . 1 0 ; procedure q ; var t : t ; { e r o a r e } begin end; end. declaraia din procedura q este eronat. Intenia a fost de a se declara o variabil iocal t, de tipul global t (definit n programul principal). Referirea ia identificatorul t de dup ' : ' nu este ns n nici un domeniu de vizibilitate; cel din programul principal a fost acoperit (la nceputul declaraiei var t: t;), iar cel din procedura q ncepe de abia la sfritul acestei declaraii. Deci n Pascal domeniul de vizibilitate ai unei declaraii se deterrnin static; el depinde doar de poziia declaraiei n textul programului i se poate stabili la compilare ca i n Algol, PL/1 i alte limbaje cu structur d e bloc; conceptul de bloc din

92

4. Proceduri, funcii, programe, module

aceste limbaje (instruciune compus cu declaraii locale ei) difer ns de cel din Pascal (funcie / procedur cu eventuale declaraii locale i o instruciune compus). n alte limbaje de programare (Lisp, Snobol, APL,...) domeniile de vizibilitate se stabilesc dinamic (la execuie). Exemplu. n programul program P ; type i =
integer;

procedure Q; var

{1}

{2} {2.1}

x: i; i : real;

begin end;

{3} begin
end

{4}. mo

domeniul de vizibilitate al declaraiei i - integer este textul cuprins intre punctele marcate {1} i {4} mai puin textul cuprins ntre punctele {2} i {3}. Domeniul de vizibilitate al declaraiei i : real este cuprins ntre punctele {2.1} i {3}. . Exemplu. Stabilirea domeniului de vizibilitate este important pentru corectitudinea apelurilor de funcii / proceduri. n programul program p; procedura q; procedura r; procedura u; begin { u } u ; r ; q ; and; { u } begin { r } U ; r ; q ; end; { r } proceduie s; procedura t ; begin t ; s ; q ; r ; end; { t } begin { s } s ; q ; r ; t ; and; { s } begin { q } and; begin end. {p} {p} cu arborele de structur static P
''> rot

q;r;s; {q}

!
r i l

XQ s

snt peimise numai apelurile specificate n program. O consecin a regulii de stabilire a domeniului de vizibilitate este faptul c orice referire r, n P trebuie precedat de o declaraie d, n P sau ntr-un program / funcie / procedur care include P. Singura excepie o constituie referirea tipului d baz T din

4.2. Funcii

93

definiia unui tip pointer, care poate precede declaraia lui T; totui, declaraia lui T trebuie s apar n aceeai parte de declaraii de tip cu tipul pointer. Exemplu. Declaraiile urmtoare: type ptr = * nod; nod = xecoxd Sting: ptr; informaie: real; drept: ptr; end;
tf

snt corecte, dei declaraia tipului nod apare dup referirea sa n declaraia tipului pointer ptr. 4.43.2. Domenii de vizibilitate pentru alte declaraii Ca i identificatorii, etichetele pot fi definite i referite n program. Domeniul de vizibilitate al unei definiii de etichet se stabilete similar cu cel al declaraiilor identificatorilor. Specificaia unui identificator constant drept component a unui tip enumerare are acelai domeniu de vizibilitate cu declaraia acestui tip. Domeniul de vizibilitate pentru o specificaie de identificator selector de cmp (proiecie canonic) ntr-o nregistrare este textul definiiei tipului nregistrare n care apare. Acest domeniu poate fi extins la textul eventualei instruciuni with n care se specific numele nregistrrii. Un astfel de identificator poate fi referit i n afara domeniului de vizibilitate, dar nu direct ci calificat de numele nregistrrii. O astfel de referire poate fi fcut n tot domeniul de vizibilitate al declaraiei nregistrrii. Exemplu: n programul program p ; typo rec = record x : real; y : record x : integer; t : integer;

(1} {2} {2.1}

end; { 3 } end; {4} var x : boolean; {5} v : rec; begin x : = true; v . x : = 1.2; v.y.x:=1 2 ; with v do {6} begin x:= 12.5; y.t:= 7; end; {7} end. {8}

- declaraia

x: real are ca domeniu de vizibilitate textul cuprins ntre punctele { l } { 4 } cu excepia celui dintre { 2 } - { 3 } ; el este extins cu textul { 6 } - { 7 } prin instruciunea with; - declaraia x: integer are domeniul de vizibilitate {2.1}- { 3 } ; - declaraia x: boolean are domeniul de vizibilitate {5} - {8} cu excepia celui dintre {6} - {7}.

94

4. Proceduri, funcii, programe, module

- n

afara domeniilor de vizibilitate (extinse), selectorii de cmpuri x snt referii prin calificare complet cu numele megtetrrilor: v. x, v. y. x.

ik3
4.43.3. Context asociat unei uniti de program Prin unitate de program nelegem un program, o funcie sau o procedur. Fie P o unitate de program i x un identificator declarat n P (n lista llf. . ., x n ) a parametrilor formali sau n declaraiile D); x desemneaz un obiect focal lui P. Dac acest obiect este vizibil ntr-o funcie / procedur o declarat n ?, atunci el este global relativ la Q, fiind "motenit" din P. Definiia 2. Numim context asociat unei uniti de program mulimea obiectelor vizibile n ea (locale sau globale). Conceptual, este util s considerm ca predefinit o unitate de program fictiv n care este inclus (declarat) orice program. Entitile locale acestui-program fictiv snt constantele, tipurile, variabilele, procedurile i funciile predefinite (vezi anexa 4). Acestea devin astfel globale relativ la orice unitate de program i extind 2stfel contextul asociat acesteia. n lipsa unei precizri contrarii, o referire l contextul asociat are n vedere aceast extensie, numit i context (spaiu) de execuie. Unei declaraii i corespunde pe lng domeniul de vizibilitate i un domeniu de timp. Definiia 3. Se numete durat de via ("extern") a unei declaraii timpul ct exist la execuie obiectul definit prin declaraie. n Pascal, durata de via a unui obiect declarat ntr-o unitate de program P este timpul ct dureaz execuia lui P. Durata de via a unei variabile dinamice (vezi 2.7) este cuprins ntre momentul crerii sale (prin apelul procedurii naw) i momentul dealocrii spaiului s u (prin apelul procedurii dispose) sau, n lipsa unei dealocri explicite, pn la sfritul execuiei programului.

4.5. Comunicarea ntre uniti de program


A m vzut cum limbajul Pascal permite definirea de funcii i proceduri pentru a descrie pri autonome de program care asociaz un nume cu declaraii de obiecte locale i cu o instruciune compus. Definiia unei funcii / proceduri se face n partea de declaraii a unei uniti de program. Referirea ei se poate face prin apeluri n instruciuni ale unitilor de program din domeniul de vizibilitate al definiiei. Fiecare apel solicit executarea aciunilor din instmciunea compus a funciei / procedurii asupra "datelor" particulare locului de chemare. Prezentm n continuare mijloacele prin care aceste date snt comunicate funciei / procedurii, iar rezultatele produse snt ntoarse n locul de apel. n Pascal comunicarea se poate face prin entiti globale i prin parametri.

4.5.1. Comunicarea prin identificatori globali


Un identificator global relativ la o procedur este declarat n afara ei ntrun program / funcie / procedur ce o cuprinde, fr a fi redeclarat n ea. El este cunoscut deci n procedur cu semnificaia dobndit n afara ei, constituind astfel un mijloc de comunicare de la locul de apel la procedura apelat.

4.2. Funcii

95

Comunicarea r sens invers este de asemenea asigurat: efectele asupra unui obiect global referit n procedur devin cunoscute n afara acesteia (n tot domeniul de vizibilitate al declaraiei asociat referirii). Procedeul se mai numete i comunicare prin parametri implicii i a fost ilustrat prin exemplele de la nceputul capitolului.

4.5.2. Comunicarea prin parametri


Limbajul permite i specificarea explicit a interfeei ntre funcie / procedur i programul / subprogramul care o apeleaz. O list de identificatori locali ai funciei / procedurii specificai n antetul acesteia drept parametri formali este pus n coresponden biunivoc cu o list de parametri actuali specificat n apel. Corespondena se realizeaz ntre parametrii din aceeai poziie n cele dou liste, cei actuali avnd tipuri identice cu cei formali corespunztori. . La execuia apelului valorile parametrilor actuali snt substituite parametrilor formali astfel c aciunile instruciunilor funciei / procedurii au loc asupra acestor valori, cu efecte la locul de chemare. Exist patru feluri de parametri formali: - parametri valoare - parametri variabil - parametri funcie - parametri procedur. Parametrii valoare snt cei obinuii n Pascal. Ei nu snt semnalai deci n vreun mod special. Ceilali parametri snt semnalai n antet prin prefixele var, function i respectiv pzoceduze.

4.5.2.1. Parametri valoare Parametrii valoare reprezint mijlocul comun n Pascal pentru comunicarea datelor de la locul de apel spre funcia / procedur apelat. Un astfel de parametru se declar n antetul funciei / procedurii prin numele su urmat de specificaia de tip. De exemplu: pzoceduze q ( n : integer; x, y : real); Parametrul actual corespunztor este o expresie a crei valoare are tipul celui formal (prin excepie, unui parametru formal de tip real poate s-i corespund i o expresie care se evalueaz l o valoare de tip integer). Exemplu. Apelurile urmtoare snt corecte: , q(3, 1.3, q(i, j, k) ; q(7, j, 8 +

7.) ;
{

:
i, j, k : real}

7 div 3) ;

Substituia implicat de parametrii valoare are loc conceptual astfel: la apelul funciei / procedurii se aloc spaiu pentru parametrul formal, se evalueaz expresia parametrului actual i valoarea rezultat se depune n acest spaiu drept valoare curent a parametrului formal. Acesta capt de acum statut de variabil local. El poate fi referit n funcie / procedur, valoarea sa poate fi modificat aici, fr vreun efect n afara ei. Valoarea dobndit astfel de parametrul formal se pierde la revenirea n program. Observaii:

96

4. Proceduri, funcii, programe, module

1. Aceast substituie a parametrilor formali valoare este cunoscut sub numele de transmitere (referire, apel, chemare ...) prin valoare. Ea este folosit i de alte limbaje de programare (ALGOL60, SIMULA, Ada...) [WaGo84]. 2. Dac parametrii actuali sint de tipuri structurate i de dimensiuni mari, un spaiu de memorie de aceeai mrime este irosit pentru parametrii formali, iar copierea valorilor celor actuali n acest spaiu consum timp. Transferul prin parametrii variabili est preferabil n astfel de cazuri, cu deosebire dac nu se fac atribuiri asupra parametrilw formali (vezi 4.5.2.2 i 4.5.3). 3. Fiierele sau Variabilele structurate cu componente fiiere nu pot fi parametri actuali valoare.
4.5.2.2. Parametri variabil Parametrii variabil reprezint mijlocul principal de recuperare a rezultatelor din procedura apelat. Parametrul formal se declar n antet sub forma vai n : t;

unde n este numele iar t tipul su. Exemplu: Antetul procedure s (x : real; var y , z : integer); conine parametrii variabil y i z. Ei se recunosc ca atare prin prefixul var. Parametrul x nu ar vreun prefix, el fiind deci un parametru valoare. Parametrul actual corespunztor unui parametru formal variabil este un identificator de variabil (simpl, component a unui tablou, a unei nregistrri sau a unei combinaii a acestora, dar nu o component a unei structuri de date mpachetate). Substituia implicat de parametrii variabil const n asocierea locaiei parametrului actual cu parametrul formal corespunztor, astfel nct, pe durata apelului, orice referire la parametrul formal este de fapt o referire la parametrul actual corespunztor. Astfel, o atribuire asupra parametrului formal devine cunoscut n afara procedurii prin schimbarea valorii parametrului actual. Observaii: 1. Acest mod de substituie este cunoscut i sub numele de transmitere (referire, apel, chemare...) prin referin (adres ...). El este folosit i n alte limbaje (FORTRAN, Ada...). Snt, de asemenea, implementate i alte mecanisme de substituie: apel prin nume (ALGOL60), prin rezultat (Ada), prin valoare rezultat (FORTRAN, Ada) etc. [WaGo84]. 2. Parametrilor formali variabil li se vor asocia parametri actuali distinci. Parametrii actuali sinonimi produc efecte neateptate n program (vezi 4.5.3). 3. Dei destinai recuperrii de rezultate din procedur, parametrii variabil snt folosii ocazional i pentru comunicarea spre procedur. Este cazul parametrilor actuali de tipuri structurate (azzay, record sau combinaii ale lor) care, transmise prin valoare, ar implica risip de spaiu (alocat parametrilor formali) i de timp (pentru copierea n acest spaiu a valorilor parametrilor actuali). 4. Toate calculele de adrese se fac la intrarea n procedur (de exemplu evaluarea indicilor componentelor de tablouri). Exemplu: Programul urmtor ilustreaz comunicarea prin variabile globale, parametri valoare i prin parametri variabil. program P;

4.2. Funcii

97

var x, y , z : integer; procedure Q (y : integer; var z begin x : = x + 1; y : = y + writeln ( x , y , z ) end; { Q } begin x : = 0 ; y : 0; z : - 0 ; writeln ( x , y , z ) ; 0(x, y); writejn (x, y , z) ; end. {P}

: integer);
z : = z + 1; 11,1,1} {0,0,0} {1,0,1}

1;

Relativ la procedura 0, identificatorul x este global, y este parametru valoare, iar z parametru variabil. n program x , y , z primesc valorile o care snt scrise: 0, 0 , 0 . Prin execuia apelului Q (x, y), variabilele desemnate prin identificatorii x (global), y (din procedur i din program) i z (din procedur) primesc valorile l care snt scrise: l , l , l. La revenirea n program variabila cu numele x (global) pstreaz valoarea l dobndit n procedur; variabila y din procedur dispare, valoarea sa nefiind pstrat n vreun fel, deci y din program continu s aib valoarea o pe care o dobndise aici; z din program dispare dar valoarea 1 atribuit lui n procedur se recupereaz ca valoare a lui z din program. Valorile lui x , y, z din program snt scrise: 1, o, l. Valoarea lui y difer de cele ale lui x i z, dei de flecare dat s-au specificat transformri similare asupra identificatorilor x, y, z. Chiar valorile variabilelor x i z, dei egale, snt dobndite pe ci diferite. 4.5.2.3. Parametri formali funcie / procedur O funcie / procedur poate fi desemnat drept parametru formal al altei funcii / proceduri prin specificarea ei n lista L din antetul acesteia. O specificaie de funcie / procedura ca parametru formal are forma antetului acelei funcii / proceduri incluznd parametrii si formali i tipurile lor, iar pentru funcii i tipul rezultatului. De exemplu function f( x , y : integei) : r e a l ; i procedure p ( z : r e a l ) ; apar ca parametri formali in antetul procedurii cp procedura q (function f ( x, y : integex) : r e a l ; procedura p ( z r e a l ) ; vax n : real); Un apel al lui q ar putea fi q(u, r, a) unde parametrul actual u este numele unei funcii function u ( m , n : integer) : r e a l ; begin . . . and; { u } iar parametrul actual r este numele unei proceduri r cu antetul procedura r ( b : r e a l ) ; Observaie. Funciile / procedurile predefinite nu pot fi transmise ca parametri actuali funcie / procedur. De exemplu apelul procedurii p n forma p ( s i n ) nu este corect, deoarece sin este o funcie predefinit. Inconvenientul poate f i ns depit definind o funcie sini function s i n l ( x : real) : r e a l ; begin sini ! = Sin( x ) and; { s i n i }

98

4. Proceduri, funcii, programe, module

care poate ti folosit n apelul p( s i n i ) cu efectul dorit Exemplu. Programul Ecdif conine declaraia specific funcia f drept unul din parametrii si formali: procedura Runge(function f( x , xO, y0, h n var vx, vy

procedurii

Runge

care .

y : real) : real; : real; -tt- integer; : vector);

De asemenea, n partea de declaraii a corpului programului snt definite dou funcii g l i g2:
'"

function g l ( x , y : real) : r e a l ; function g2( x , y : r e a l ) : r e a l ; Procedura Runge este apelat de dou ori n partea de instruciuni a corpului programului. Primul apel specific, printre altele, pe g i drept parametru actual corespunzind parametrului actual de tip funcie f: Runge(gl, 0 , 1, 5 . 7 , h, vl, v 2 ) ; Similar pentru cel de-al doilea apel i funcia g2. Urmeaz enunul problemei, algoritmul folosit i programul Pascal autodocumentat prin comentarii. Problema: Integrarea ecuaiilor difereniale de forma y' - f(x, y) n condiiile iniiale y (x,,) ye. Algoritmul: folosete metoda Runge-Kutta de ordinul patru cu pas constant h; pentru i - 0 , 1 , . . . , n - l : Xi.i - x + h i yi.i ' Y i * 1/6- (ki + 2 - k j + 2-k, + k4) + O ( h ) unde kx - h - f (Xj , yt) ka - h ( X i 1/2h, y j + 1/2-k,,) k, - h ' t (Xj + 1/2h , yt + 1/2-k2) k - h - f (Xi + h, yt + kj) Cte n valori pentru x i y smt acumulate n vectorii vx i vy pentru a fi ntoarse n punctul de apel.
t

progxan Ecdif; { n piogram se declar procedura Runge i f u n c i i l e g l i g2; se apeleaz Runge de dou o r i pentru integrarea ecuaiilor difereniale y ' = g l ( x , y ) , respectiv y' - g2(x, y).1
. -

cont h - 0.001; n - 10; e - 2.71828; typa vector - axray [ l . . n ] of r e a l ; var 3 : xnteger; v l , v2 : vector; procedura Runge (function f( x , y : r e a l ) : r e a l ; x O , y O , h s r e a l ; n : integer; var vx, v y : v e c t o r ) ; {Procedura pentru integrarea ecuaiilor d i f e r e n i a l e de forma y ' = f ( x, y ) in condiiile iniiale y ( x 0 ) y 0 prin metoda Runge-Kutta de ordinul 4 cu pas constant h i n i t e r a i i ) var x, y , k l , k 2 , k 3 , k 4 : real; i : integer; bagin x x O ; y : - y O { i n i i a l i z r i ] for i : = 1 to n do { n i t e r a i i } bagin kl h * f ( x, y); k2 h * f(x + h/2, y + kl/2); k3 h * f ( x + h/2, y + k2/2); k4 : h * f ( x + h, y + k 3 ) ;

4.2. Funcii

99

y :- y + f(kl + 2 * k2, 2*k3+k4)/6; x x + h; {se modific x} vx[i] := x; {se rein x i y) vy[i] := y

end;{for}end; {Runge} '. .. rfunctiongl(x, y: real): real;begingi : -2 * x* sin(x)end; {gi}function g2(x, y :real) :real;beging2 - 1 + (xy) / (x +ln(y))end;{g2}beginRunge(gi, o,1.57, h.n, vl, v2);lapel al lui Runge pentru integrarea ecuaiei y'- gl(x, y) in condiiile iniiale y(0) - 1.57 } writeln (' x y(x) pentru y''gl(x,y)'); for j := 1 to n do writeln (vl[j], v2[j]); writeln; Runge (g2, e., e + 1, 1E-2, n, vl, v2); {apel al lui Runge pentru integrarea ecuaiei y'=g2(x, y) in condiiile iniiale y'te) = e + 1 } write (' x y(x) pentru y''g2(x,y)'); fox j 1 to n do writeln (vl[j], v2[j]) and. {Ecdif}

4.5^.4. T a b l o u r i ca parametri

Definiia iniial a limbajului nu permite folosirea nemijlocit a tablourilor cu dimensiuni variabile drept parametri formali n funcii i proceduri, fcnd necesar modificarea i recompilarea acestora pentru apeluri cu alte dimensiuni ale parametrilor actuali tablouri. Un remediu const n declararea tablourilor cu dimensiuni specificate prin identificatori de constante care snt definite (i modificate) anticipat. Exemplu. (Vezi 4.52.3, programul Ecdif) .

I secvena de program c on n s t n

10; t y vector - a x[l..n] o real; p e x a y f p r oRunge u (... v vx,, vy : vector; c e d re a r

...)

tablourile vx i vy de tip vector snt folosite ca parametri formali ai procedurii Runge. Valoarea 10 este asociat cu n dar ea poate fi modificat (la 100 de exemplu) prin simpla redefinire a constantei (const n - 100), fr vreo modificare n textul procedurii. Acelai efect s-ar obine definind tipul n forma type vector - axray [1..10] of r e a l i redefinindu-1 cu type vector = axzay [1..100] of r e a l . Prima variant este desigur preferabil. Un apel al procedurii ar putea avea

100

4. Proceduri, funcii, programe, module

forma Runge { . . . v i , v2, . . . ) unde tipul tablourilor vl i v2 este definit anticipat prin var vl, v2 : vector; Ultimul standard al limbajului ofer ca soluie alternativ (nepreluat n Pascal Oregon) folosirea drept parametri formali valoare sau variabil a schemelor de tablouri, adic a specificaiilor de tablouri cu dimensiuni parametrizate definite prin diagramele de sintax: <schema de tablou> ||packad mxxmy [<dimensiuni>]of-^rrj><id_de_tip>^> | 1- - - -> azzay------[{<dimensiuni>]]of|' I ;<- - - - -H I
I-----------!--------------i----------------------------------.------------------ - - -'

<dimensiuni> ----.> identificator>..> identifica tor> : > <id_de_tip> > 4.5.2.5. Structura dinamic a programelor n 4.4.2. am mtrodus structura static a programelor. Ea are n vedere textul surs* al programului, punnd n eviden unitile de program componente i este unic pentru un program dat. Toate consderaiile care au urmat au avut n vedere aceast structur static i este remarcabil c principalele informaii necesare la compilare (domeniile de vizibilitate a declaraiilor, legarea identificatorilor la declaraii^..) snt obinute prin explorarea acestei structuri. Folosirea funciilor /procedurilor face util luarea n considerare i a structurii dinamice (la execuie) a programelor. Structura dinamic este unic pentru o activare a programului (a prii sale de instruciuni) n condiii iniiale date, dar poate s difere la schimbarea condiiilor iniiale. Ea are n vedere succesiunea activrilor unitilor de program (funcii / proceduri) componente (a prii lor de instruciuni) i poate fi reprezentai folosind graful apelurilor (pentru exemple vezi 4.5.4.2) sau modelul conturului al mi Dijksrra [WaGo84]. Fiecare activare a unei funcii / proceduri produce ipostaze proprii ale contextului asociat (vezi 4.4.3) obinute prin: a) crearea de copii proprii ale entitilor locale (etichete, variabile, funcii, proceduri); b) crearea de variabile proprii pentru identificatorii folosii ca parametri formali valoare; c) stabilirea de legturi (referine) de la identificatorii folosii ca parametri formali variabil / funcie / procedur la parametrii actuali corespunztori. Copii multiple de entiti cu declaraii identice pot s existe n acelai timp, n contexte proprii ale activrilor recursive (vezi 4.5.4). Dac Q este declarat n p, atunci contextul propriu unei activri a lui Q este scufundat n contextul asociat (declaraiei) lui p, nu n contextul propriu activrii unitii de program care a provocat activarea lui Q. O referire r x a identificatorului x ntr-o activare a unitii de program P are n vedere obiectul specificat prin declaraia d x vizibil n acel loc; el se determin la compilare explornd structura static a programului. Specificarea atributelor acestui obiect este ns, de regul, incomplet la momentul compilrii. Astfel, pentru o variabil definit prin cvadruplul '

<nume, tip,

locaie, valoare>

4.2. Funcii

101

doar numele i tipul snt specificate n declaraia corespunztoare din textul programului; locaia i valoarea vor f i determinate la execuie, folosind structura dinamic a programului corespunztoare acelei execuii. ;:. Regulile de completare a informaiei de legare a identificatorilor l a entitile ce le corespund se numesc reguli de activare i, pentru Pascal, ele snt urmtoarele: - dac identificatorul este local, el corespunde ipostazei coninute n contextul propriu al activrii; - dac identificatorul este parametru formal valoare, el se refer la variabila creat pentru acesta, n contextul propriu al activrii; - dac identificatorul este un parametru formal variabil / funcie / procedur, el se refer la entitatea la care conduce legtura (referina) stabilit n contextul propriu al activrii. Observaie. Dac identificatorul numete o entitate extern, legarea lui la acea entitate se completeaz la momentul editrii task-ului (vezi 4.7 i 7).

4.5.3. Efecte procedurilor

secundare

Ia

execuia

funciilor

Singurul mod n care execuia unei funcii trebuie s influeneze mediul (contextul) din care este apelat este prin valoarea pe care o ntoarce, atribuit numelui ei, n locul de apel. Orice alt schimbare n acest; mediu produs de execuia ei este un efect secundar care poate influena n mod neateptat execuia programului. Prezentm n continuare practici defectuoase de programare care produc funcii cu efecte secundare la execuie. 4.5.3.1. Atribuiri asupra variabilelor globale ;:vrt-:.{.

Valorile dobndite de variabilele globale n corpul f u n c i e i devin cunoscute n afara ei (n unitile de program din domeniile de valabilitate ale acestor variabile). Execuia unei astfel de funcii va influena mediul de chemare nu doar prin valoarea ntoars, ci i prin alterarea valorilor variabilelor globale. Exemplu. program p; var a , b : integer; var x : real; . function f(c : real) : real; begin a : - 7 ; b : - 3; f : a + h .. . '. . end; { f } ,-, . begin a : - X ; b : - 2; X : = f '<5)/10| . , writeln (a,b,x) end. ].

. tr.i -.

-jft<a

n programul p variabilele a i b - s n t globale relativ l a funcia f. F u n c i a este invocat n program n expresia f (5) /1 ; la execuie ea ntoarce 0 valoarea 15 atribuit numelui ei f. Pe lng aceasta ns, atribuirile fcute asupra variabilelor globale a i b produc, c a efect secundar, alterarea valorilor acestor variabile n tot programul.

4.5.3.2. Atribuiri asupra parametrilor formali variabil

102

4. Proceduri, funcii, programe, module

Valorile dobndite n program de parametrii formali variabil devin cunoscute n locul de chemare c a valori a l e variabilelor globale folosite drept parametri a c t u a l i n apel. Execuia unei funcii c u parametri formali variabil produce deci i efectul secundar de alterare a valorilor acestor variabile globale. Folosirea v a r i a b i l e l o r globale ca parametri actuali corespunztori parametrilor formali variabil este deci descurajat n c a z u l funciilor. Comunicarea standard a funciilor cu mediul de chemare const deci n : transmiterea de valori spre funcie prin parametri v a l o a r e i ntoarcerea u n u i ( s i n g u r ) rezultat din funcie prin numele ei. Folosirea variabilelor globale c a mijloc suplimentar de comunicare este permis. Variabilele globale pot fi deci folosite n f u n c i i , dar se recomand ca valorile lor s nu f i e schimbate d e acestea. Observaii:

1.

Spre deosebire de funcie, o procedur poate s ntoarc mai mult dect o valoare n mediul de chemare. Procedura nu conine vreo atribuire asupra numelui ei, deci nici o valoare nu este ntoars din procedur prin acest nume. Mijlocul standard de ntoarcere de valori din procedur este prin parametri formali variabil: valorile dobndite de acetia n procedur devin cunoscute n afara ei ca valori ale parametrilor actuali corespunztori.

2.

Atribuirile n procedur asupra variabilelor globale produc efecte secundare similare celor discutate pentru astfel de atribuiri la funcii. Ele nu snt recomandate nici n acest caz. Astfel de atribuiri introduc abateri de l a procedeul standard de comunicare dinspre procedur prin care variabilele participante snt desemnate explicit ca parametri formali variabil (n declaraie) i parametri actuali (n apel). Efectele lor se propag l a distan (n domenii de vizibilitate a l e variabilelor globale) i pot interfera cu cele similare produse l a execuia altor proceduri din acelai program, fcnd riscant utilizarea acestor variabile.

4.53.3. Parametri actuali c u acelai nume pentru parametri formali variabil distinci Folosirea de parametri actuali cu acelai nume nu este recomandat dac ei corespund la parametri formali variabil. Se evit astfel o surs de efecte secundare subtile. Parametrii actuali cu acelai nume ar desemna cte o singur variabil, care la execuia apelului ar fi cunoscut sub mai multe nume (ale parametrilor formali corespunztori celor actuali cu acelai nume). O atribuire asupra unuia din aceti parametri formali ar avea ca efect secundar i alterarea valorilor celorlali. Exemplu. Programul urmtor ilustreaz efectele secundare produse de folosirea de parametri actuali cu acelai nume pentru parametri formali variabil. program P ; var a : real; procedure p l 2 (var x , y : r e a l ) ; begin x := 1; y 2 and;f p l 2 l procedure p21 (var x, y : r e a l ) ; begin r. ; y := 2 ; X := 1 end;{p21} begin pl2( a , a ) ; w r i t e l n ('a- ', a ) ; p21( a , a ) ; writeln ( ' a = ' , a ) end. {P}

4.2. Funcii

103

Procedurile pl2 ip21 difer doar prin s i m p l a permutare a instruciunilor de atribuire x : = l i y : - 2. Dup apelul lui pl2 se scrie a - 2. Dup apelul l u i p?l se scrie a = l. n s i t u a i i normale (chemri de fonna'pl2 ( a , b ) , p21 ( a , b ) aceast permutare nu ar f i produs vreun efect pentru c x i y ar fi referit variabile diferite (a, respectiv b). M u l t e implementri, inclusiv cea pentru Pascal Oregon, nu semnaleaz astfel de defecte n programe nici l a compilare, nici l a execuie. Cele de mai sus sugereaz c pentru o procedur c u antetul p r o c e d u r a p (var x , v :

r e a l ) nu este indicat un apel de forma p ( a [ i ] , a ! i I > unde a | i ] este o component de tablou. Chiar un apel de forma pta[ell, aIe2]) unde e l i e2 snt expresii, este susceptibil de a produce efecte secundare dac el i e2 conduc la aceeai valoare. :; -l X: ' :.
. .
:

4.5.4. Recursie
Recursia indirect

4.5.4.1.

ntr-o structur de program reprezentat prin arborele P Q R . I

? poate s apeleze pe Q, dar Q n u poate s apeleze pe k pentru c R nu este nc declarat. Limbajul prevede t o t u i o facilitate prin c a r e aceast referire d e v i n e posibil. Pentru aceasta: 1. R va f i preanunat n P naintea l u i Q p r i n antetul su complet, urmat de d i r e c t i v a f o r w a x d ("nainte"). 2. n declaraia propriu-zis a l u i R care urmeaz dup Q, se folosete un antet redus n care se specific doar numele l u i K , tar parametri i tipuri. Programul p va avea, de exemplu, forma: program
P

; i n t e q e r ) ; f o rw a r d ;

procedure R ( x : r e a l ; vai y : procedure Q ( x : r e a l ) ; var a: i n t e g e r ; b e g i n ( 2 .1 , a ) ; and; Q? procedure R ; begin end; { R } begin

104

4. Proceduri, funcii, programe, module

end. { P $ Reprezentm noua structur a programului prin arborele


P

forward Q

\ R

Desigur, referirea lui R n Q era posibil i fr folosirea directivei f o rw a r d , prin simpla inversare a ordinei declaraiilor Iui Q i R n P. Ar rezulta programul P / \ R Q Dac ns att 0 apeleaz pe R ct i R apeleaz pe 0, o astfel de inversare nu rezolv problema, fiind necesar folosirea directivei forward. Ea face deci posibil acest fel de referire mutual a dou funcii / proceduri care se numete recursie indirect. Cazul mai general de recursie indirect al unui lan finit nchis de n > 2 chemri de funcii / proceduri se specific similar.

4.5.4.2. Recursia direct Discutm acum cazul recursiei directe n care o funcie / procedur se apeleaz nemijlocit pe ea nsi. Conceptual, un astfel de apel nu difer de apelul ntre funcii / proceduri distincte i se implementeaz n translatoare, de regul, prin mijloace similare. Pentru programator recursia este nc o posibilitate, foarte elegant, de exprimare a controlului asupra succesiunii prelucrrilor repetitive i ea permite scrierea natural a programelor care folosesc algoritmi i structuri de date prin esen recursive. Ea este de aceeai natur cu iteraia care se exprim cu ajutorul instruciunilor de control (n Pascal: while, r e p e a t , f o r , vezi 3.2). n cazul iteraiei repetiia este exprimat i controlat explicit folosind variabile sau predicate desemnate special acestui scop. In cazul recursiei, repetiia este implicit. Ea este provocat de execuia unei funcii / proceduri care conine un apel al ei nsi n partea sa de instruciuni: cnd execuia ajunge la acel apel, o nou execuie este declanat .a.m.d.. Desigur, o condiie de oprire a a c e s t u i proces (potenial infinit repetitiv) trebuie prevzut i programat. Ilustrm prin cteva exemple simple mecanismul recursiei i meritele relative ale recursiei i iteraiei. De fiecare dat presupunem definit tipul type natural = 0..maxint; Exemplul 1. Funcia factorial f : N ----> N, f (n) = f 1 \ X n - f (n-1) dac n -

dac n > = 1

poate fi exprimat n Pascal, urmnd direct definiia, n forma function f ( n : natural) : natural; begin i f n = 0 then f : = 1 else f 2 = n * f(n-1) end; { f } Efectul unui apel de forma f (1 o) este declanarea unui lan de apeluri ale lui f pentru parametrii actuali 9 , 8 , 7 , 2, l, 0: f'(10)

4.2. Funcii

105

10 f ( 9 ) i i 2 f (1) l 1 f(0) .. 1

Apelul f (o) determin evaluarea direct a funciei oprind astfel procesul repetitiv; urmeaz revenirile din apeluri i evaluarea lui f pentru l , 2 , 9, 10, ultima valoare fiind ntoars la locul primului apel f (l o). Se observ c apelul recursiv al lui f este ultima aciune care se execut la activarea funciei factorial. Acesta este un exemplu de recursie l a sfrit ("tail - end recursion") care, n general, poate f i uor nlocuit prin iteraie [Kru84] i implementat eficient. Funcia factorial poate fi rescris iterativ folosind dou variabile auxiliare i i p pentru controlul procesului repetitivi respectiv pentru acumularea rezultatelor intermediare: function f(n:natural): natural; var i, p: natural; begin p i - i; for i: 2 to n do p:- p*i; f:= p i ffl end; {f} Exemplul 2. Funcia

fib:N --->, fib(n)

0
o

dac

fib(n-i) + fib(n-2) 2

dac n - 1 dac n >-

are ca valori numerele lui Fibonacci. Forma ei Pascal derivat nemijlocit din definiie nu ilustreaz cazul recursiei la sfrit: function fib(n: natural): natural; begin if n - 0 then fib:= 0 elae if n = 1 then fib:= 1 elae fib:- fib(n-l) + fib(n-2) end; {fib} Fiecare apel al funciei pentru n > - 2 genereaz dou apeluri .a.m.d., de exemplu:

fib(4) fib(3) / \ fib(2) fib(l)


I
/ \

fib(l) 1
I

fib(O)

fib(2) / \ fib(l) 1
I

fib(O)
I

Introducnd variabile suplimentare, se poate obine o variant eficient cu recursie la sfrit (vezi exerciiul 1). O form nerecursiv care evit calculul repetat al valorilor funciei pentru aceeai valoare a argumentului se obine folosind trei variabile auxiliare i, a, b (pentru controlul iteraiei, pentru valoarea curent

106

4. Proceduri, funcii, programe, module

a funciei i pentru pstrarea unei valori precedente):


. . .. .. . <

function fib(n:natural): natural; -var i,a,b: natural; begin if n-0 then fib:= o elae if n-1 then fib:- 1 else begin a:= 0; b:= 1; for i:= 2 to n do bogin and; ond ond; Exemplul 3. Funcia lui Ackermann [Bro77] (exemplu celebru de funcie recursiv care nu este primitiv recursiv), redefinit de R. Peter m forma n + l dac m = o a(m-i, 1 ) dac n - 0 = L a(m-.l, a(m, n-l)) dac m>0 i n>0
''

b:= a+b; a:= b-a

fib:- b

a:NxN ---> N, a(m,n)

poate f i exprimat cu uurin ca o funcie Pascal recursiv: function a(m,n: natural): natural; begin if m - 0 then a:= n+1 elae if n - 0 then a:= a(n-l, elsa a:= a(m-l, a(m, n-D) end; {a}

1)

Funcia ia valori foarte mari chiar pentru valori mici ale parametrilor, de exemplu a (4,2) i o20000. AmM programat, execuia ei necesit timp de calcul mare (datorit numrului mare de apeluri recursive) i un spaiu de memorie prohibitiv (datorit "adineimii" rscursiei), astfel c a devenit un test al calitii implementrii recursiei ,n> limbaje de programare [Wic82]; graful apelurilor ei pentru m=2, n=l este sugestiv n acest sens: