Sunteți pe pagina 1din 225

Programarea calculatoarelor [i limbaje de

programare orientate obiect

Programarea calculatoarelor [i limbaje de programare 1 Dan Popa, 2007


Programarea calculatoarelor [i limbaje de programare 2 Dan Popa, 2007
Dan V. Popa

Programarea calculatoarelor [i
limbaje de programare orientate obiect

popavdan @ yahoo.com
versiunea revizuit\ `ntre 3 [i 25 februarie 2007

Programarea calculatoarelor [i limbaje de programare 3 Dan Popa, 2007


Programarea calculatoarelor [i limbaje de programare 4 Dan Popa, 2007
Se dedic\ tuturor celor care au `ncercat ([i n-au reu[it)
s\ `nve]e conceptele program\rii orientate obiect.

Programarea calculatoarelor [i limbaje de programare 5 Dan Popa, 2007


Programarea calculatoarelor [i limbaje de programare 6 Dan Popa, 2007
Programarea calculatoarelor [i limbaje de programare 7 Dan Popa, 2007
Cuprinsul

CAP. 1 CAP.3

De ce un curs despre programarea Elemente de ingineria programării

(şi utilizarea) calculatoarelor ? 17 (metoda SA/SD) 44

Bibliografie 19 Tehnici de appel 45

Modul de examinare 21 Analiza,Modelarea,Implementarea 46

Cum veţi lucra practic (I) 24 Testarea modulelelor de cod 47

Descărcarea şi instalarea Pow 24 Lucrare practică 47

Pornirea mediului de programare 26 Analizā şi analist 48

Deschiderea unei ferestre pe ecran în care Modelul static 49

veţi scrie noul program 27 Modelul dinamic 49

Despre meniul Compile 28 Automatul finit determinist (AFD) 50

Despre meniul Run 29 Modelul funcţional 50

Compilare, linkeditarea, diferenţa dintre ele Dezavantajele 51

29 Schema unei aplicaţii cu baze de date 53

C A P. 2 Ghid pentru studierea unui limbaj de

Arhitectura calculatoarelor compatibile IBM programare imperativ 54

PC 30 Exemple de limbaje obiectuale 53

Servere de reţea 35

Piramida funcţiilor 36 CAP. 4

Programarea imperativă 38 Instrumente practice pentru programatori

Programarea structurată 39 Mediile de programare 58

Programarea funcţională 40 Compilatorul 58

Programarea logică 41 Analizorul lexical 60

Programarea orientată obiect 42 Analizorul sintactic 64

Obiecte, clasă 42 Analizorul semantic 66

Programarea calculatoarelor [i limbaje de programare 8 Dan Popa, 2007


Generatorul de cod 67 MODULE Calif 100

Optimizatorul de cod 69 Matricele bi, tri, .. n, dimensionale 105

Alte componente ale unui mediu de O instrucţiune secretă:

programare 70 Bucla LOOP .. END 106

Despre secţiunea TYPE 107

C A P. 5

Instrumente teoretice pentru programatori CAP.8

72 De la record-uri şi proceduri la obiecte 108

Problema opririi 74 Şi totuşi cum gîndim o problemă în mod

Abordarea practicā a unui limbaj nou 76 “bazat pe obiecte” ? 117

Formalizarea unor noţiuni fundamentale. Clasă 117

Despre vocabular, declaraţii şi proceduri Metode 117

predefinite 78 Proceduri legate la tip 117

Declaraţii şi domeniile de vizibilitate 81 Pointerul this 118

Reguli de valabilitate (vizibilitate) a Obiectele au un ciclu de viaţă 120

identificatorilor 82 Constructor /Destructor 120

Identificatori predeclaraţi 83 Un exemplu comentat: palatul califului

... bazat pe obiecte 121

CAP.6 Utilizarea cîmpurilor procedurale 126

Definiţie : Programarea structurată 84

Instrucţiuni structurate 85 CAP.9

Programarea structurată 86 Liste de RECORD-uri, Liste de obiecte 132

Structura alternativă sau pe scurt IF 87 Pointeri şi variabile dinamice 134

Structura alternativă generalizată CASE 88 Povestea piciorului 140

Bucla cu număr cunoscut de iteraţii, FOR Exemplul «serpa.prj» 145

91 Constructori, destructori (II) 157

Bucla cu test final, REPEAT ... UNTIL. 93

Bucla cu test iniţial sau bucla WHILE. 95 CAP 10

Cum putem simula pe FOR şi REPEAT 96 Tipuri şi tipizare; De la tipuri simple la tipuri

de obiecte polimorfe 159

Tipurile simple 160

CAP 7 Povestea clientului de la CEC 167

De la structuri de date la Programarea Un exemplu comentat : cec.mod 171

Orientată Obiect 97 Tip static, tip dinamic 172

Vectori şi înregistrări, abordarea clasică WITH.. DO.. ELSE .. END 177

neobiectuală 98

Un exemplu de utilizare a datelor compuse, CAP 11

dar fără obiecte 100 Tipul BOOLEAN, expresii logice. Evaluarea

Programarea calculatoarelor [i limbaje de programare 9 Dan Popa, 2007


lor interactivă 180 Anexa A: Mici programe în diverse limbaje

George Boole 180 de programare. 212

Operatorii de comparaţie 184 Anexa B: Mic program în C++ cu obiecte

Lazzy Evaluation 186 cărora li se cer servicii. 213

Avantaje 187 Anexa C: Editarea codului şi compilarea

Dezavantaje 187 unei aplicaţii cu Dev -C++ şi MingW C++

Evaluarea (interpretarea) expresiilor logice Compiler: 214

189 Anexa D: Editorul de proiect al mediului Dev

C++ şi gestionarea claselor şi funcţiilor din

CAP 1 2 proiect. 215

Fractali; Elemente de grafică folosind Anexa E: Operaţii cu obiecte realizate cu

modulul ColorPlane 201 ajutorul operatorilor. 216

Dimensiune 202 Anexa F: Dacă doriţi să folosiţi Pow cu Java

Feriga matematică 206 218

Exemplul Fract.mod 207 Anexa G: Configurarea IDE-ului Dev C++ 219

Anexa H: Jocul cu palatul califului, o

variantă C++ 220

Bibliografie 222

Programarea calculatoarelor [i limbaje de programare 10 Dan Popa, 2007


Cuv=nt introductiv la edi]ia a doua

Acest volum `[i propune s\ fie o punte, o leg\tur\, `ntre cursurile introductive de
programare structurat\ sau de structuri de date [i cele de ingineria program\rii.
Conceput ini]ial ca un manual de programare `n Oberon, unul din limbajele `n care
paradigma program\rii orientate obiect se prezint\ extrem de accesibil\ doritorului s-o
cunoasc\, cursul a evoluat `n anii urm\tori public\rii sale de c\tre Editura EduSoft c\tre
un curs care abordeaz\ holistic limbajele de programare imperative [i obiectuale.
Mul]umesc pe aceast\ cale editorului pentru acceptul de a l\sa acest curs sub licen]a
liber\ OpenDoc [i de a permite republicarea lui electronic\.

Actualmente cursul `nglobeaz\ referin]e la mai multe limbaje (C, C++, Oberon, Pascal
[i ocazional unele limbaje func]ionale ca Lisp [i Haskell) [i exemple privind conceptele
program\rii structurate [i program\rii orientate obiect, concepte prezentate `ntr-un ghid
universal de studiere a limbajelor imperative [i obiectuale, inclus [i el `n volum (la
pagina 54).
Totul este ilustrat cu multe exemple, cod surs\ [i capturi de imagini care fac u[oar\ `n
]elegerea chiar [i `n lipsa unui computer de[i recomand cititorilor s\ foloseasc\ unul
pentru a rezolva temele propuse. Mediile de programare necesare, at=t Pow c=t [i mai
noul Dev C++ se pot desc\rca de pe Internet.

Dup\ citirea acestui curs ve]i putea aborda fie c\r]i de proiectare profesional\ a
software-ului sau de ingineria program\rii fie c\r]i profesionale de proiectare a jocurilor
(de ce nu!), fie manualele unor medii de programare (IDE-uri) puternice [i ale
limbajelor lor asociate deoarece cursul v\ ofer\ cuno[tin]ele care lipsesc `ntre nivelul
[colar ori liceal [i cel profesional.

Mediul de programare cu care am `nceput este Pow (c\uta]i cuvintele cheie: Pow,
Oberon, Download cu un motor de c\utare). Pow este un IDE simplu care poate fi
folosit cu C++, Oberon sau Java. Este ideal pentru a face tranzi]ia de la vechile medii

Programarea calculatoarelor [i limbaje de programare 11 Dan Popa, 2007


Borland la noile instrumente de lucru. Ulterior, folosind `n laborator mediul Dev C++
[i compilatorul MingW C++ am `nceput s\ le recomand pe acestea deoarece Dev
C++-ul se aseam\n\ mult mai bine cu alte medii de lucru profesionale [i are un
gestionar de proiecte mult mai performant, bun de folosit la gestionarea unor proiecte
de mari dimensiuni.
Dan Popa
Bac\u, 3-25 februarie 2007

Programarea calculatoarelor [i limbaje de programare 12 Dan Popa, 2007


Cuv=ntul introductiv al primei edi]ii

Acum doi ani c=nd, proasp\t revenit din mediul industrial `n cel universitar, aveam `n
fa]\ sarcina de a face un curs despre programarea [i utilizarea calculatoarelor la o sec
]ie tehnic\ a universit\]ii Bac\u aveam `n fa]\ o multipl\ provocare. Era nevoie de un
limbaj [i de un mediu de programare care s\ `ndeplineasc\ o sumedenie de criterii.
Iat\ criteriile care m-au f\cut s\ aleg ca `nlocuitor al Turbo Pascalului un alt dialect
inventat de acela[i celebru N.Wirth (autorul Pascal-ului), limbaj cunoscut sub numele
de Oberon. A[tept\rile mele [i ale studen]ilor mei la adresa unui limbaj didactic [i
profesional totodat\ erau:

– Limbajul s\ fie modern, de preferat dintre apari]iile ultimului deceniu, deoarece


cuno[team deja opiniile elevilor de liceu despre “vechitura de Pascal for DOS” de
care se s\turaser\ [i cuno[team perfect motiva]ia unora dintre ei de a-l studia `n
continuare.
– Limbajul s\ fie simplu, deoarece aveam studen]i `n anul I, veni]i de la liceul forestier
dintr-o localitate din apropiere.
– Limbajul s\ fie didactic, `n sensul posibilit\]ii de a se preda cu el, c=t mai multe
concepte importante din teoria program\rii, `n pu]inele ore disponibile de-al lungul
unui semestru. Practica `mi ar\tase c\ `n cursul un set de lec]ii de Turbo Pascal de
un semestru, una pe s\pt\m=n\, adesea unele no]iuni ca matrice
multidimensionale, structuri de date compuse (cum ar fi matricele de record-uri),
record-uri cu variante, fi[iere, obiecte [i programare orientat\ pe obiecte, unit-uri [i
interfe]e (sau numai unele dintre ele) ajung ori s\ nu mai fie predate ori s\ nu mai fie
`nv\]ate de cursan]i. Finalitatea este `n ambele cazuri aceea[i.
– Limbajul s\ fie expresiv, `n sensul cuvintelor folosite. Cei care iubesc austeritatea
din C cunosc [i reversul, textul este obscur unui novice care nu g\se[te `ntr-o
structur\ “if” nici m\car cuv=ntul “then” sau `ntr-o func]ie cuv=ntul “function”, ca `n
Pascal.
– La urm\ dar mai `nt=i de toate, limbajul s\ fie actual [i suficient pentru a `nv\]a

Programarea calculatoarelor [i limbaje de programare 13 Dan Popa, 2007


paradigma OOP (object oriented programming -programarea orientat\ obiect) `n
sensul c\, f\r\ a con]ine o mul]ime de elemente `n plus necesare doar practicienilor,
(cum sunt func]iile friend sau template-urile de clase din C^^), s\ permit\ predarea
OOP urm\rind o serie de concepte care `ncepe cu cele clasice: tipuri, variabile [i
opera]ii, structurile program\rii structurate, structuri de date compuse, proceduri [i
func]ii [i continu\ cu obiecte, ierarhii de clase, mo[tenire [i polimorfism.
– Limbajul s\ fie un punct de plecare pentru `nv\]area altor limbaje deoarece nu [tiu
exact ce va oferi studen]ilor din anul I de azi (care peste 4-5 ani vor fi `n c\utare de
“job-uri”) o pia]\ a muncii `n continu\ schimbare . Pentru aceasta trebui ca el s\ fie
m\car “case sensitive”, modular, obiectual [i suficient de asem\n\tor limbajelor
cerute `n zilele noastre: C^^, Java, etc.
Lucr\rile de laborator aduceau [i ele seria lor de cerin]e:

– Mediul de programare s\ ruleze pe ma[ini Windows cu orice configura]ie, de 16


sau 32 de bi]i, de la 386, 486 cu Windows 3.1 la noile procesoare Pentium I-II-III,
(sau AMD-uri: Athlon, Duron etc) cu Windows 95, 98, NT 4, ba chiar [i mai
moderne (ME, XP). Laboratorul A39 `n care se desf\[urau orele cuprindea mai ales
386 [i 486-uri l=ng\ care se ad\ugaser\ ni[te computere Pentium I. Iar computerele
de acas\ ale studen]ilor mei erau [i ele uimitor de variate. De asemenea
posibilitatea de utilizare a mediului de programare [i pe PC-urile cu Linux (de
exemplu pe Red Hat Linux 6.0, 6,1, 6.2 cu emulatorul Wine) aduce un plus de
atractivitate unei op]iuni deoarece permitea realizarea unui laborator [colar far\
licen]e Microsoft.
– Mediul de programare s\ semene cu vechile produse Borland pentru Dos, (Turbo
Pascal, C, Turbo Prolog, Borland C) u[ur=nd at=t lucrul veteranilor cu el c=t [i
adaptarea celor care `nva]\ teoria program\rii din acest curs, pe alte platforme [i
medii de programare.
– S\ fie o aplica]ie Windows (excludeam orice produs pentru DOS) [i s\ aib\ un
design asem\n\tor cu al procesoarelor de texte moderne. Astfel, elemente de
bazele biroticii nu mai trebuie predate separat sau la un alt curs iar cursan]ii nu vor

Programarea calculatoarelor [i limbaje de programare 14 Dan Popa, 2007


mai ridica din umeri privind (de exemplu), butonul cu desenul dischetei de pe bara
cu butoane a unui procesor de texte Abi Word, MS Word sau Open Office. ~n plus
studen]ii vor putea s\-[i scrie referatele cu Abi Word sau Open Office ori cu alte
produse libere, f\r\ s\ aib\ nevoie de o instruire suplimentar\.
– S\ poat\ fi distribuit f\r\ probleme logistice sau legale studen]ilor, pentru lucru la
domiciliu. Deci pe de o parte s\ fie disponibil `n dou\ variante pe CD respectiv pe
una - dou\ (maxim 4 dischete) apoi s\ aib\ o licen]\ c=t mai apropiat\ produselor
Free Software ori care m\car s\ permit\ distribuirea liber\ de c\tre ter]i. (Un produs
elaborat `n mediul universitar are de obicei asemenea condi]ii de distribuire.) ~n plus,
s\ dispun\ de o versiune (fie ea [i pe 16 bi]i) care s\ poat\ fi folosit\ oriunde `n orice
condi]ii, inclusiv `n medii productive, ceea ce ar fi un punct `n plus `n favoarea
alegerii.
– Eventual, mediul de programare s\ poat\ fi folosit [i cu alte limbaje ca C^^, Java.

Spre marea mea bucurie un asemenea limbaj [i un asemenea mediu de programare


exist\. ~ndepline[te TOATE criteriile de mai sus. Este mediul de programare Pow
(Programmers Open Workbench) livrat `mpreun\ cu compilatorul de Oberon-2 realizat
de Robinson Associates [i oferit de Universitatea din Linz. Pute]i desc\rca o copie de
pe site-ul web al Universit\]ii din Linz. ~n continuarea acestei c\r]i vom vorbi despre el
[i chiar dac\ vom numi uneori limbajul, pe scurt, “Oberon” este vorba de fapt despre
Oberon-2 [i despre mediul de programare mai sus citat.

Cartea se adreseaz\ `n primul r=nd cursan]ilor anului `nt=i de la Univ. Bac\u, care au
nevoie de manuale (inexistente `n limba rom=n\) sau de note de curs. Cartea
poate ]ine locul notelor de curs pentru primele 8-9-10 cursuri predate, dar nu din
tot semestrul. Participarea la cursurile 10 - 14 devine astfel obligatorie.

Cartea se adreseaz\ `n al doilea r=nd cunosc\torilor limbajului Pascal sau profesorilor


de informatic\ dornici s\ studieze un limbaj simplu [i elegant, dincolo de Pascal :

Programarea calculatoarelor [i limbaje de programare 15 Dan Popa, 2007


Oberon. Mesajele lor, printre care cel dint=i, venit de la doamna profesor Romana
S\l\jan din Arad m-au `ndemnat s\ dau la tipar acest prim volum.
Conceput\ s\ deschid\ por]ile spre alte lumi ale cunoa[terii, cartea anun]\
necunosc\torilor [i existen]a unor domenii de “computer science” de care liceenii n-au
avut habar: teoria calculabilit\]ii, ingineria program\rii, teoria model\rii, teoria
automatelor, teoria compilatoarelor [i limbajelor formale, programarea func]ional\,
programarea logic\.

Nu `n ultimul r=nd, cartea `ncearc\ s\ spulbere c=teva mituri [i false concep]ii despre
programarea calculatoarelor. Ve]i afla din ea ce `i trebuie unui adev\rat programator,
dincolo de cunoa[terea unui limbaj de programare, ve]i afla c\ unele propriet\]i ale
programelor nu pot fi depistate de alte programe ([i volumul include o demonstra]ie
simpl\ legat\ de problema opririi), ve]i `n]elege din acest motiv c\ [i antiviru[ii vor fi
`ntotdeauna ineficien]i. Acest lucru este din nefericire demonstrat [i de laboratoarele
universit\]ii `n care am depistat pesonal de doi-trei ani de zile viru[i pe care nu-i
recunoa[te nici m\car RAV-ul achizi]ionat cu c=tva timp `n urm\ dar cu mare tam-tam
de c\tre Microsoft. O frumoas\ dar trist\ confirmare practic\ a teoriei !

Exist\ `n acest volum chiar [i c=teva vorbe despre Linux, o platform\ software care mi-
a fost de mare ajutor, at=t la scrierea de mici compilatoare cu Bison [i Flex (c=t [i la
corectura final\ a volumului, realizat\ pe Mandrake Linux 10 [i PCLinuxOS 9 folosind
Open Office 1.1. Extrem de u[or de utilizat acest Open Office 1.1 pentru Linux care,
permite s\ expor]i documentele `n format PDF la o simpl\ ap\sare pe un buton !

Dan Popa,
Bac\u, august 2005

Programarea calculatoarelor [i limbaje de programare 16 Dan Popa, 2007


1
Cap

De ce un curs despre programarea


(şi utilizarea) calculatoarelor ?
Motive de a audia un curs de programarea şi utilizarea calculatoarelor şi alte lucruri despre calculatoare,
societate şi viitor.

Tr\im `ntr-o lume din ce `n ce mai gr\bit\, mai complex\, mai interesat\ de aspectele
economice. Aceasta deoarece aspectele economice `nseamn\ bun\stare [i oportunit\]i,
combinate cu responsabilitate [i obliga]ii. Este o lume care se mi[c\ din ce `n ce mai
repede, am trecut practic nu `n secolul ci `n mileniul vitezei. Peste tot se cere productivitate
din ce `n ce mai mare a muncii, r\spuns din ce `n ce mai rapid (practic oricine va trebui s\
poat\ servi un client p=n\ a doua zi cel mult), se cere o calificare din ce `n ce mai `nalt\, o
bun\ cunoa[tere de noi tehnologii (fie c\ e vorba de proiectarea fie c\ e vorba de utilizarea
sau `ntre]inerea lor). Vechile obiceiuri [i deprinderi nu ne mai sunt `ntotdeauna de ajutor. Se
`ntrevede o schimbare. Munca `ns\[i se mut\ lent de la sediile marilor corpora]iii spre
birouri, sec]ii [i ateliere descentralizate sau chiar spre domiciliile angaja]ilor. (Personal,
lucrez deja la domiciliu.) Specificul felurilor de munc\ se mut\ de la prelucrarea materiilor
prime [i materialelor la prelucrarea informa]iei. Deja munca uman\, grea sau u[oar\, dar
adesea lent\ [i costisitoare a `nceput s\ fie `nlocuit\ de robo]i [i automate, fie c\ e vorba de
asamblarea [i vopsirea automobilelor, de lipirea circuitelor electronice pe pl\ci, de socotelile
lunare ale contabililor sau de banala v=nzare a cafelei la col] de strad\.

Iar toate aceste aspecte ale realit\]ilor lumii de m=ine reclam\ apari]ia unor noi categorii de

Programarea calculatoarelor [i limbaje de programare 17 Dan Popa, 2007


personal. E vorba de ingineri sau referen]i cu studii superioare, (deoarece produc]ia va fi
practic l\sat\ sub conducerea [i pe seama lor) dar av=nd [i capacitatea de a lua decizii nu
numai pe criterii tehnice ci [i economice (deci pe baz\ de informa]ie). Punerea `n practic\ a
deciziilor cere mai `nt=i o evaluare, o simulare pe calculator, un calcul cu foaia de calcul, o
rulare de program care estimeaz\ rezultate sau anticipeaz\ costuri, o programare a unei
ma[ini cu comand\ program, o c\utare `ntr-o baz\ de date cu legisla]ie etc. Toate acestea
presupun cunoa[terea utiliz\rii sau program\rii calculatoarelor.

Programarea calculatoarelor este util\ [i dac\ nu suntem programatori? Da, pentru


reducerea costurilor activit\]iii dumneavoastr\. Lipsa unor cuno[tin]e de programarea
calculatoarelor ne face s\ avem o viziune gre[it\ asupra posibilit\]ilor calculatorului. Unii mai
a[teapt\ [i ast\zi de exemplu antivirusul ideal pentru platformele Windows, de[i teoria
calculabilit\]ii (domeniu al informaticii care se ocup\ cu stabilirea limitelor calculului
automat) a demonstrat de mult c\ a afla de c\tre un program c\ ALT program este virus
constituie ceea ce se nume[te problem\ nedecidabil\ algoritmic. Un asemenea algoritm,
program, antivirus general nu exist\. Iar viru[i nedetectabili vor exista `ntotdeauna. (Acesta
este [i motivul pentru care eu personal prefer sistemele Unix). De asemenea, un ofertant de
servicii [i produse informatice poate profita de acest gen de necunoa[tere pentru a v\ oferi o
solu]ie (uneori par]ial\, proast\ a unei probleme nedecidabile) la un pre] exagerat. Cunoa
[terea limitelor puterii calculatoarelor de a rezolva probleme v\ poate ajuta s\ afla]i c=nd
ave]i sau c=nd nu ave]i nevoie de un computer. Aceste limite nu depind de viteza
procesoarelor sau computerelor ci sunt de alt\ natur\ - matematic\. Orice calculator a]i
cump\ra, oric=t de puternic, problema va r\m=ne nerezolvat\. Un alt exemplu `n acest sens
este chiar nevoia scrierii unui program care rezolv\ o problem\ dat\. Nici un computer nu
poate scrie, `n general, singur, programul, [tiind doar formularea (enun]ul) problemei.
Scrierea de programme nu este algoritmizabil\ `n general, ci doar pentru anumite clase cu
totul particulare de probleme. Chestiunea aceasta are implica]ii economice [i sociale:
meseria de programator va fi `ntotdeauna foarte c\utat\! Dac\ munca strungarului,
vopsitorului, sudorului, brutarului pot fi `nlocuite cu munc\ robotizat\ sau automatizat\
complet, munca programatorului nu poate fi `nlocuit\! Ceea ce face din programarea
calculatoarelor, o meserie de viitor, mai bine pl\tit\ ca altele. ~ntotdeauna. De re]inut!

Totu[i, ce va include cursul de programarea [i utilizarea calculatoarelor ? F\r\ a fi o

Programarea calculatoarelor [i limbaje de programare 18 Dan Popa, 2007


enumerare exhaustiv\, vor exista `n curs urm\toarele teme.
- Arhitectura calculatoarelor compatibile IBM PC [i evolu]ia lor, cu consecin]e asupra
situa]iei pie]ei de azi [i achizi]iilor de calculatoare. Structura unui calculator, din
punct de vedere hard [i soft. Calculatorul v\zut ca o piramid\ de niveluri func]ionale.
- Paradigme ale program\rii.
- Elemente de ingineria program\rii, Paradigma client / server, Modelele unei aplica]ii
(Static, dinamic, func]ional).
- Instrumente teoretice [i practice pentru programatori. Structura unui compilator. Alte
domenii ale informaticii, legate de programarea calculatoarelor.
- ~nv\]area unui limbaj de programare imperativ, structurat. Mic ghid `n 16 puncte [i
alte no]iuni importante. Programarea structurat\, `n diverse limbaje. Un r\spuns la
`ntrebarea: Unde mai avem nevoie de programarea structurat\ ?
- Limbajul Oberon, (partea I). Men]ionez c\ anumite sec]ii ale universit\]ii au solicitat
alt limbaj pentru exemple practice de laborator.
- Structura unui compilator
- Limbajul Oberon (partea a II-a), sau alt limbaj solicitat, inclusiv no]iuni despre
modelarea obiectual\
- Structurarea datelor
- Programarea orientat\ obiect
- Tipuri [i tipizare
- Proceduri [i func]ii, utilizarea lor `n modelul obiectual. Exemple. Execu]ia
procedurilor. Proceduri legate la tip, c=mpuri procedurale (sau pointeri la func]ii),
recursivitate, structuri de date recursive.
- Tipizare dinamic\, ierarhii de clase, mo[tenire, polimorfism
- Alte elemente dependente de limbajul ales: Modulul Color Plane, pentru grafic\ color
`n Oberon, Fractali sau alte facilit\]i `n limbajele C, C++

Bibliografie
La elaborarea acestui curs s-au utilizat materiale `n format electronic, c\r]i [i articole. Cele
mai importante dintre ele sunt indicate `n continuare.
Materiale `n format electronic:

Programarea calculatoarelor [i limbaje de programare 19 Dan Popa, 2007


1. POW – Programmers Open Workbench, Red Chili Oberon 2 Compiler, mediu de
programare disponibil gratuit de pe pagina web a Universit\]ii Johannes Keppler din
Linz, `mpreun\ cu compilatorul realizat de Robinson Associates. Versiunea pe 32 de
biti se poate desc\rca de la adresa http://www.fim.uni-
linz.ac.at/pow/download.htm [i ocup\ 4 dischete. Desc\rca]i [i compilatorul C++.
2. POW – versiunea pe 16 biti care se poate g\si pe SimtelNet. Ocup\ dou\ dischete.
Ambele versiuni au o documenta]ie electronic\ `n meniul Help. Versiunea pe 16 biti
este util\ pentru cei care mai utilizeaz\ computere vechi, 486, Pentium I. Limbajul
este practic acela[i.
3. Alte materiale `n format electronic privind limbajul Oberon, de pe Internet.
O serie de volume tip\rite, au fost consultate `n procesul elabor\rii acestui curs. Lista nu
este exhaustiv\ iar o serie de no]iuni fundamentale pot fi reg\site `n diferite alte c\r]i de
programarea calculatoarelor.
1. Winn L. Rosch: Hardware Bible, Sams Corp. 1997 (`n edi]ie rom=neasc\ la editura
Teora).
2. Eugenia Kalisz, Irina Athanasiu, Valentin Cristea, Ini]iere `n Turbo Pascal, Teora,
1995, 1998 etc.
3. P.D. Terry, Compilers and Compilers Generators – an introduction with C^^,
International Thomson, 1996
4. Gabriel Ciobanu, Semantica Limbajelor de Programare , Editura Universit\]ii Ia[i,
1996
5. Cristian Calude, Complexitatea Calcului, Aspecte calitative, Editura {tiin]ific\ [i
Enciclopedic\, 1982
6. Donald E. Knuth, Arta Program\rii Calculatoarelor, Vol1 – Algoritmi
fundamentali, Teora 1999 (Titlul original: The Art Of Computer Programming, Vol 1,
Addison Wesley Longman, 1997).
7. Luca Dan {erb\na]i, Limbaje de Programare [i Compilatoare, Editura Academiei
RSR, 1987
C\r]ile cu no]iuni despre tehnici de `nv\]are au fost consultate doar ca auxiliare(B.V.)
O serie de c\r]i le pot `nlocui pe unele dintre cele de mai sus. Orice manual bun de
limbaj Pascal sau C poate ajuta la `n]elegerea program\rii structurate (inclusiv a

Programarea calculatoarelor [i limbaje de programare 20 Dan Popa, 2007


aceleia din Oberon), dar va trebui s\ `nv\]a]i separat conceptul, ideea, [i apoi s\
c\uta]i `n documenta]ia electronic\ - Help-ul mediului de programare POW - sintaxa
exact\ din Oberon. Oberon este practic un succesor al limbajului Pascal, mai simplu,
mai clar [i mai apropiat de limbajele moderne: C^^, Java etc.
Orice manual al unui limbaj obiectual (de exemplu, C^^, Java sau Visual Fox) v\
permite s\ `n]elege]i paradigma program\rii obiectuale. Utilizarea asupra obiectelor
din Oberon r\m=ne `ns\ una dintre cele mai accesibile, poate chiar cea mai
accesibil\, fiind mai pu]in sofisticat\ dec=t cea a altor limbaje.

Modul de examinare
Cursul este prev\zut cu un colocviu `n sesiunea de la sf=r[itul semestrului, iar la sec]iile
care urmeaz\ partea a doua a acestui curs `n semestrul al doilea se va da un colocviu `n
sesiunea din finalul semestrului respectiv. Pentru a putea participa la colocvii sunt necesare:
- Participarea la cursuri sau ob]inerea suportului de curs. Formal prezen]a la curs
nu este obligatorie, dar `n lipsa unui curs publicat [i a unor manuale de Oberon `n
limba Rom=n\ va trebui s\ procura]i cursurile, fie particip=nd direct la ele, fie
copiindu-le. Dac\ unul din cursuri nu apare la bibliotec\ [i a]i lipsit va trebui s\-l
copia]i de la colegii care au fost prezen]i `n sal\ sau s\ utiliza]i cursul tip\rit, dac\ e.
Aten]ie: `n cazul `n care opta]i pentru neparticipare la orele de curs sarcina de a
studia teoria program\rii calculatoarelor [i de a avea competen]e similare sau mai
bune ca ale colegilor dumneavoastr\ care au fost prezen]i v\ revine numai
dumneavoastr\. Limbajele moderne, cum este C++ sunt dificil de `nv\]at numai din
manualele tehnice, f\r\ explica]iile unui profesor. Riscul de a nu termina anul
universitar din cauza cursului de programare devine `n acest caz un risc major.
- Participarea la lucr\rile de laborator. Spre deosebire de prezen]a la curs, prezen]a la
laborator este obligatorie. Absen]a de la 3 lucr\ri de laborator (adic\ peste 20%
din total) de-a lungul unui semestru poate atrage dup\ sine neprimirea la
examene sau colocvii. Studentul respectiv mai are doar [ansa de a fi restan]ier.
Uneori pute]i recupera laboratorul, `n accea[i s\pt\m=n\, cu alt\ grup\ sau cu alt\
semigrup\ care are ore cu acela[i cadru didactic. Asisten]ii no[tri vor comunica mai
exact aceste aspecte la ora de laborator.

Programarea calculatoarelor [i limbaje de programare 21 Dan Popa, 2007


- Studierea exemplelor de laborator [i `n]elegerea acestora. Pute]i primi `ntreb\ri care
verific\ gradul dumneavoastr\ de `n]elegere a no]iunilor exemplificate `n cadrul
laboratoarelor. Chiar dac\ unele exemple au fost date doar ca exemple de utilizare a
mediului de programare [i par simple lec]ii de dactilografie, odat\ cu explicarea la
curs sau laborator a no]iunilor implicate ele devin materie de examen de studiat.
Ave]i obliga]ia de a relua `nainte de examen toate exemplele [i a le studia `n lumina
tuturor explica]iilor oferite de-a lungul semestrului.
- Trebuie s\ dovedi]i `n diverse forme participarea la orele de laborator. Formele sunt:
Prin simpl\ prezen]\, prin prezentarea caietului, a dosarului respectiv a dischetei cu
referate [i lucr\ri de laborator. Simpla prezen]\ nu este suficient\.
Alte informa]ii despre examinare [i preg\tirea ei:
- La colocviu ve]i primi cel pu]in un subiect de teorie din curs [i o problem\, uneori
asem\n\toare dar nu identic\ cu lucr\rile de laborator efectuate. Va trebui s\
discuta]i cu examinatorul, expun=nd subiectul teoretic [i solu]iile problemei sau
problemelor. Accesul la calculator va fi dup\ caz, subiect [i problem\, obligatoriu,
permis op]ional, recomandat, nerecomandat sau chiar interzis. Restan]ele [i
reexamin\rile pot fi sub diverse forme incluz=nd aici brainstorming-ul pe o tem\ dat\
sau teste cu multe `ntreb\ri punctuale, la alegerea examinatorului.
- Temele [i lucr\rile de laborator care presupun s\ realiza]i o solu]ie nu vor fi copiate.
Sunte]i obliga]i s\ oferi]i]i solu]ii proprii [i s\ indica]i sursele din care a]i preluat micile
citate. Preluarea de citate mari, paragrafe `ntregi, capitole, programe este interzis\,
fiind sanc]ionat\, inclusiv conform legii. Postarea programelor pe Internet e interzis\.
- Este permis [i chiar recomandat s\ va consulta]i cu al]i colegi, inclusiv din ani mai
mari asupra felului cum pute]i aborda o sarcin\ sau o problem\. Este interzis s\
primi]i sau s\ oferi]i solu]ii complete. Materialele realizate `n cadrul preg\tirii
dumneavoastr\ la orele de laborator sau ca urmare a orelor de laborator, sunt
proprietate intelectual\ a Universit\]ii Bac\u, cu excep]ia cazurilor prev\zute de lege
[i de eventualele licen]ele tip GNU GPL ale produselor software. Nu le pute]i distribui
gratuit, vinde sau valorifica direct `n scop comercial sau privat. Este permis\
folosirea lor `n scop educa]ional exact la anul [i la sec]ia pentru care sunt destinate.
Aceast\ permisiune de folosire [i multiplicare este valabil\ [i pentru prezentul curs,
care poate fi folosit `n scop educa]ional de studen]ii anului I Inginerie [i ai anului I

Programarea calculatoarelor [i limbaje de programare 22 Dan Popa, 2007


Informatic\, ace[tia av=nd [i dreptul s\ posede [i s\ utilizeze o copie pentru uz
individual. Copiile pentru uz colectiv sunt cele de la Bibliotec\.
- La colocviu sau examen ve]i fi examina]i de titularul cursului, eventual [i de asistent.
Asistentul are [i sarcina de a verifica partea practic\.
- Pute]i folosi acas\ mediul de programare POW, compilatorul de Oberon sau de
C++. Anul trecut s-au distribuit la cerere CD-uri cu software aferent cursului. Pute]i
desc\rca propriul set de dischete cu mediul de programare POW de pe Internet de la
adresa http://www.fim.uni-linz.ac.at/pow/download.htm sau de la alte adrese.
Cuvintele cheie pentru c\utare folosind Google (http://www.google.com ) sunt: Pow
Oberon Download.
- La sec]iile la care se pred\ C++ pute]i folosi acas\ software-ul Dev-C++ distribuit
de Bloodsheed Software prin Internet `mpreun\ cu compilatorul MingW- C++. De[i
folosirea Pow pentru a programa `n C sau C++ este posibil\ recomand\m Dev-
C++-ul, care prin modul de folosire v\ preg\te[te mai bine pentru folosirea unor
medii de programare profesionale, cum este Visual C++ (cu care de altfel seam\n\
foarte de bine). Pe de alt\ parte fiind pu]in mai simplu este mai u[or de `nv\]at.

Ocazional vom folosim o serie de simboluri pentru a marca


S I M B O L U R I
pasaje importante din curs sau care presupun o ac]iune
 Informa]ii importante
 Teste, teme anume din partea dumneavoastr\, a studen]ilor, a cititorilor.
 Lucr\ri practice Aceste simboluri au o r\sp=ndire relativ larg\, [i sunt
 Alte referin]e sugestive.
Semnificaţia simbolurilor : Informa]iile importante sunt ceva ce nu trebuie `n nici un caz s\
omite]i. Pe ele se bazeaz\ cursurile [i lucr\rile de laborator urm\toare iar necunoa[terea lor
indic\ un student nepreg\tit. Pentru a rezolva teste [i teme, pentru a scrie programme,
pune]i m=na pe creion (la propriu). Lucr\rile practice v\ sugereaz\ s\ folosi]i computerul [i
s\ rezolva]i problemele. Alte referin]e sau c\r]i sunt materiale pe care n-ar fi r\u s\ le c\uta]i,
s\ le procura]ii, s\ le `mprumuta]i sau s\ le citi]i. ~ntruc=t nici autorul acestui curs nu poate
copia pasaje `ntregi din alte c\r]i, este posibil s\ fie nevoie uneori s\ v\ indic\m astfel c\r]ile
respective. Faptul c\ un paragraf nu posed\ nici unul din simboluri nu `nseamn\ c\ ave]i
permisiunea s\-l ignora]i din start.

Programarea calculatoarelor [i limbaje de programare 23 Dan Popa, 2007


Cum veţi lucra practic (I)

Dup\ parcurgerea acestui subcapitol trebuie s\ fi]i capabili s\ realiza]i f\r\ ajutor
urm\toarele activit\]i, fie `n laborator, fie la calculatorul personal. Primele dintre ele servesc
ob]inerii de pe Internet [i instal\rii mediului de programare Pow [i compilatorului de Oberon.
Le ve]i avea de efectuat cel mult o singur\ dat\. Celelalte vizeaz\ abilitatea de a porni
mediul de programare, de a scrie un program format dintr-un singur text (`n Oberon un
asemenea text se nume[te modul [i este prefixat cu cuv=ntul cheie MODULE), de a
modifica programul, de a-l compila (`nseamn\ a-l traduce `n limbajul procesorului), de a-l
executa (pentru a vedea cum func]ioneaz\ [i dac\ func]ioneaz\ corect) [i de a-l salva
(copia) pe discheta cu lucr\ri de laborator. ~n primele ore de laborator, deci, activitatea va
consta `n a realiza lucr\rile propuse [i programele proprii, parcurg=nd urm\toarele etape:
- pornirea mediului de programare (Pow sau altul indicat)
- deschiderea unei ferestre pe ecran `n care ve]i scrie noul program (noul modul), sau
a mai multor ferestre `n cazul proiectelor mari (situa]ie c=nd va trebui sa folosi]i [i
editorul de proiect [i s\ salva]i fi[ierul proiectului – cu extensia .prj sau alta)
- compilarea (adic\ traducerea programului `n limbajul microprocesorului)
- link-editarea (construirea programului executabil – imagina]i-v\ ceva cam ca la jocul
de Lego – din modulele compilate de dumneavoastr\ [i din alte componente se
construie[te prin `mbinare rezultatul). Acest program numit “executabil” este cel
care poate fi executat, adic\ pus `n func]iune. El poate fi apoi oferit beneficiarilor
`mpreun\ cu bibliotecile (.dll) necesare.
- salvarea (`nregistrarea) lucr\rii de laborator pe dischet\ (sau USB stick).

Descărcarea şi instalarea Pow

Pagina de pe web a mediului de programare Pow, de la adresa http://www.fim.uni-


linz.ac.at/pow/download.htm con]ine [i explica]iile de mai jos, pe care, pentru simplitate, le-
am tradus `n limba rom=n\.

Programarea calculatoarelor [i limbaje de programare 24 Dan Popa, 2007


Pow!/32 (pentru Windows 95, 98 and Windows NT)

• Ultima versiune a programului Pow!/32 se nume-


[te Pow!/32 3.0b [i e compus\ din urm\toarele patru
fi[iere: Pow32_30b.exe, Pow32_30b.w02,
Pow32_30b.w03, Pow32_30b.w04. Desc\rca]i toate
cele patru fi[iere `ntr-un director temporar [i executa]i
primul program pentru a instala Pow! Acest pachet
include interfa]a pentru compilatorul de Oberon-2, cel
de Java [i `nsu[i compilatorul de Oberon-2. Dac\
dori]i s\ folosi]i mediul de programare Pow pentru a
programa `n Java ave]i nevoie [i de Java
Development Kit de la Sun. El poate fi desc\rcat de
la adresa http://java.sun.com.„

Instalarea Pow-ului decurge exact ca a oric\rei aplica]ii uzuale, tot ce v\ r\m=ne de f\cut
este s\ ap\sa]i periodic pe butonul Next.

Folosirea mediului Pow `mpreun\ cu limbajul C++ presupune s\ desc\rca]i de pe pagina


web a mediului Pow [i o versiune a compilatorului C++. Opiniem totu[i c\ un alt mediu de
dezvoltare, Dev C++ este mai indicat pentru lucrul `n C++ fiind un mediu de dezvoltare
mai modern [i pe deasupra [i oferit liber, sub licen]\ general\ public\ GNU, ceea ce v\
permite printre altele s\-l redistribui]i [i s\-l folosi]i f\r\ cheltuieli de licen]iere. Consulta]i
licen]a GNU care-l `nso]e[te pentru a afla detaliile.

Folosirea mediului Pow `mpreun\ cu limbajul Java, perfect posibil\, nu constituie `ns\ un
scop al acestui curs, dar pute]i totu[i experimenta cu diverse versiuni de JDK pentru a
vedea care func]ioneaz\ corespunz\tor.

Programarea calculatoarelor [i limbaje de programare 25 Dan Popa, 2007


Pornirea mediului de programare Pow

Simbolul, iconi]a, mediului Pow este un bec de culoare vernil. Dac\ simbolul nu figureaz\ pe
ecran, pute]i porni mediul de programare Pow din meniul Start -> Programms -> Pow(32bit)
-> Pow. Dac\ iconi]a exist\ pe ecran, da]i cu mouse-ul un clic dublu pe iconi]\. Alte medii de
programare au alte figurine asociate, `ntreba]i pe care trebuie s-o folosi]i.

Imediat dup\ pornire, un prim program simplu, cu numele hello.mod este afi[at `n fereastra
deschis\. Cursorul, cel care indic\ locul pe ecran unde pute]i scrie sau [terge are forma unei
linii verticale pulsatile [i `l vede]i `n figur\ pe ultimul r=nd.

Sfat dep\[it: Dac\ folosi]i un vechi PC cu procesor 386, 486 sau chiar Pentium 1, pe care
ruleaz\ versiunea Pow pe 16 bi]i (cea pe care o g\si]i pe Simtel Net) sub interfa]a grafic\
Windows 3.1 sau 3.11 atunci pute]i fi `n situa]ia de a porni interfa]a cu o comand\ dat\ la
prompterul DOS, C:@> Comanda este WIN urmat de ENTER. Iconi]a Pow-ului se afl\ `n
fereastra Pow a Program managerului. Actualmente foarte pu]ine firme mai folosesc
sisteme Pentium 1 [i Windows din seria 3.x.

Programarea calculatoarelor [i limbaje de programare 26 Dan Popa, 2007


Deschiderea unei ferestre pe ecran în care veţi scrie noul

program


Despre meniul File
A devenit deja o tradi]ie ca aplica]ile moderne s\ grupeze `n primul meniu,
meniul File, comenzile necesare pentru `nceperea, continuarea [i punerea
la p\strare – pentru o continuare viitoare - a unei lucr\ri. Dac\ `n locul
[oricelului (mouse) lucra]i cu tastatura – [i profesioni[tii a[a lucreaz\ ! - sau dac\ pur [i
simplul mouse-ul este uzat, incomod, defect ori lipse[te, accesa]i meniul File cu tastele ALT
[i F. ALT trebuie s\ fie ]inut\ ap\sat\ atunci c=nd ap\sa]i pe F. Sublinierea indic\ `n fiecare
meniu tasta care trebuie ap\sat\ `mpreun\ cu ALT pentru a-l deschide.

Programarea calculatoarelor [i limbaje de programare 27 Dan Popa, 2007



Despre meniul Windows
Tot prin tradi]ie, aplica]ile moderne grupeaz\ `n meniul Windows comenzile
necesare pentru a face opera]ii cu ferestrele de pe ecran, ferestre `n care
realiza]i diferite lucr\ri sau module componente ale unei lucr\ri. Ultimele
r=nduri ale meniului cuprind lista tuturor acestor ferestre. Opera]iile uzuale cu ferestre includ
aranjarea lor ca ni[te c\r\mizi, pe orizontal\ (Tile horizontal), pe vertical\ (Tile vertical), `n
cascad\ (Cascade) precum [i `nchiderea tuturor ferestrelor (Close All).
Ve]i folosi Close All la orele de laborator, at=t la `nceputul orei, pentru a `nchide
eventualele ferestre l\sate deschise de colegii dumneavoastr\ c=t [i la sf=r[itul orei,
pentru a l\sa mediul de programare cu ferestrele `nchise. Abia dup\ ce a]i `nchis
ferestrele se recomand\ s\ p\r\si]i mediul de programare.

Compilarea, linkeditarea şi execuţia


Despre meniul Compile
Mediile de programare ofer\ pe l`ng\ meniurile File [i Windows un al treilea
meniu, Compile `n care sunt grupate comenzi necesare traducerii textelor
(programelor) scrise de dumneavoastr\ `n limbajul procesorului. Nici
procesorul nici celelalte circuite ale computerului nu `n]eleg de fapt limbajul Oberon (sau un
alt limbaj de nivel `nalt) `n care se programeaz\. Se poate traduce text cu text, fereastr\ cu
fereastr\ (ceea ce face op]iunea Compile) sau tot proiectul (ori tot proiectul cu excep]ia fi-
[ierelor nemodificate [i deja compilate), ceea ce fac Make [i Build. Eventualele erori g\site
de compilator vor fi semnalate [i vor trebui corectate `nainte de a compila din nou modulul
sau proiectul. Numai ceea ce a fost compilat f\r\ erori poate trece `n faza de Linkeditare.
Make face automat [i linkeditarea, dac\ se poate. Comanda Link, utilizat\ pentru pornirea
procesului de linkeditare este ultima din meniul Compile.

Dac\ ve]i lucra ca programator ve]i folosi zilnic aceste comenzi, tast=nd dup\ caz: ALT-F9
sau F9. Linkeditarea este numit\ de unii autori “editare de leg\turi”, deoarece link se traduce
prin leg\tur\.

Programarea calculatoarelor [i limbaje de programare 28 Dan Popa, 2007


Despre meniul Run
Mediile de programare ofer\ pe l`ng\ meniurile File [i Windows [i Compile un al patrulea
meniu, Run. Comanda Run (CTRL-F9) folose[te la pornirea execu]iei programului compilat
[i linkeditat anterior. Mediile moderne de programare verific\ automat dac\ programul a fost
compilat sau nu iar `n caz de nevoie declan[eaz\ at=t compilarea c=t [i linkeditarea de care
a]i uitat. Acest lucru permite compilarea – linkeditarea [i execu]ia la o singur\ ap\sare pe
taste: CTRL-F9. }ine]i-o minte, o ve]i folosi de zeci de ori !


Compilare, linkeditare – diferenţa dintre ele
Este preferabil s\ `n]elege]i deosebirile dintre aceste faze. Compilarea se
face modul cu modul, iar linkeditarea stabile[te printre altele leg\turile dintre
module, pe baza cuvintelor marcate cu stelu]\ (a[a cum este ProgMain* `n
Oberopn) [i a numelor de module. Practic, un modul `n care un asemenea nume a fost scris
gre[it, altfel dec=t `n modulul cu care se leag\, poate fi compilat f\r\ erori dar numele nu va
fi g\sit la linkeditare. ~ncerca]i s\ compila]i programul de mai sus scriind `n loc de
«ProgMain» doar «RogMain» at=t la `nceputul c=t [i la sf=r[itul textului. Compilarea se va
termina cu mesajul de succes «Done», dar linkeditarea nu va fi posibil\.

Programarea calculatoarelor [i limbaje de programare 29 Dan Popa, 2007


2
Cap

Arhitectura calculatoarelor compatibile


IBM PC

Cuvinte cheie: arhitectura calculatoarelor, IBM PC, XT, AT, Apple, procesor, memorie,
magistrale, FSB, date, adrese, ISA, PCI, controler, cipset, bridge, server, biprocesor, procesoare
X86, hardware, software, sistem de operare, resurse, BIOS, driver, aplicaţii, mediu de
dezvoltare, editor, compilator, linkeditor.

Istoria a ceea ce numim azi calculatoare personale, PC-uri, `ncepe pu]in `naintea anilor ‘80.
De[i termenul PC (personal computer) era folosit deja, `n august 1981 firma IBM `l folose[te
pentru a eticheta propriul s\u model de calculator de mici dimensiuni, destinat a fi folosit de
c\tre o singur\ persoan\. Ulterior a fost urmat de modele numite XT (extended technology)
apoi de AT (Advanced Technology). Ambele denumiri [i standarde mai exist\ doar prin
succesori. (De exemplu noile surse de calculator se numesc ATX, de la AT eXtins. )
~n anii 1981-1987, computerele de acest tip au constituit un standard de facto, datorit\
politicii firmei IBM de a face publice specifica]iile tehnice. Astfel, o sumedenie de produc\tori
au `nceput s\ fabrice subansamble sau chiar computere `ntregi care respectau standardele
IBM. Aceast\ popularizare a afectat puternic cota de pia]\ a firmei Apple (adev\rata
inventatoare a calculatorului personal), f\c=nd-o s\ scad\, iar pia]a s\ fie dominat\ acum de
ceea ce numim calculatoare compatibile IBM-PC sau, mai pe scurt PC-uri.
Defini]ie: Un PC este o ma[in\ de calcul al c\rei model a fost, primul IBM PC.

Programarea calculatoarelor [i limbaje de programare 30 Dan Popa, 2007



Microprocesorul s\u este produs de Intel, sau, dac\ e produs de alt\
firm\, folose[te acelea[i instruc]iuni sau emuleaz\ un procesor Intel.
Celelalte componente hardware respect\ o serie de standarde industriale,
care permit compatibilitatea diverselor subansamble, provenite de la diver[i
produc\tori.

PROCESOR

Magistrala ISA

MEMORIE

Magistrala ISA

ADAPTOR VIDEO

CONTROLERE PENTRU PERIFERICE

UNITATEA TASTATURA MONITOR


DE
DISCHETE


ALTE COMPONENTE

Schematic, un IBM-PC era compus din: memorie, procesor, magistral\ ISA, controlere
ale perifericelor, periferice. Perifericele uzuale erau: tastatur\, monitor (display), unit\]i
de dischete, apoi disc hard (primele PC-uri nu posedau a[a ceva). Prin intermediul
porturilor seriale [i porturilor paralele se puteau conecta alte periferice: imprimant\,modem,
mai t=rziu mouse etc.

ISA # Industry Standard Architecture. Ce putem spune despre aceast\ veche magistral\ ?

Programarea calculatoarelor [i limbaje de programare 31 Dan Popa, 2007


- ISA standardul magistralei primelor PC-uri
- ISA era o magistral\ lent\ (6-8MHz) pe 8 bi]i, cele mai rapide modele atingeau 11MHz
- a fost urmat\ de o extensie a ei pe 16 bi]i
- [i de o alt\ extensie, EISA, (o g\si]i la vechile sisteme Pentium 1) la care configurarea se
f\cea cu ajutorul unor fi[iere de date [i a unui program numit Eisa Setup Utility. Fiecare
component\ avea propriul fi[ier de configurare iar pierderea dischetelor provoca
imposibilitatea de a utiliza componente). De[i rapid\ EISA a fost nepopular\, incomod\.

Avantajele acestei arhitecturi: Toate componentele lucrau la acelea[i frecven]e. Se


puteau ad\uga pl\ci de extensie (“add-on cards”) fabricate de al]i produc\tori. Aceste
pl\ci de extensie erau standardizate. Se puteau moderniza PC-urile, `nlocuindu-se pl\cile
vechi cu altele mai performante, de exemplu un adaptor video monocrom cu unul color
[.a.m.d.

Dezavantajele acestei arhitecturi: Viteza de transfer a informa]iilor era limitat\ de


magistral\. (Extensia ISA la 16 bi]i a rezolvat pentru o vreme problema. A existat apoi, din
acela[i motiv, `nc\ o magistral\ - o dezvoltare a magistralei ISA pe 16 bi]i - numit\,
reamintim, EISA.) Procesorul lucra la aceea[i vitez\ cu restul sistemului [i cum au ap\rut
ulterior procesoare mai rapide, acestea nu putreau fi montate `n asemenea sisteme. De
asemenea, memorii mai rapide ar fi avut nevoie de o magistral\ separat\.

Evolu]ia [i dezvoltarea procesoarelor a dus, printre alte `mbun\]iri la o cre[tere a vitezei


acestora. Au existat procesoare 80286 (12Mhz, 16Mhz), 80386 (25Mhz, 33Mhz), 80486
(40Mhz, 50Mhz, 66Mhz, 80Mhz, 100Mhz), 5x86 (fabricat de AMD nu de Intel - 133Mhz,
160Mhz) apoi `ntreaga serie de Procesoare Pentium (I,II,III, IV) dep\[ind actualmente 3
GHz. Memoriile au evoluat [i ele, iar pentru a asigura conectarea unor circuite rapide,
asigur=ndu-se [i o vitez\ mai mare de transfer a datelor, a ap\rut magistrala PCI
(Peripheral Component Interface). AMD, Cyrix, Transmeta au produs propriile lor cipuri.
Magistrala de extensie a PC-ului permite dezvoltarea sistemului. Ea asigur\ o conexiune
de mare vitez\ pentru dispozitivele periferice interne. Existen]a magistralelor standardizate
(ISA, apoi PCI) a dat na[tere unei `ntregi industrii produc\toare de pl\ci de extensie
interschimbabile.

Programarea calculatoarelor [i limbaje de programare 32 Dan Popa, 2007


Existen]a noilor procesoare [i memorii mai rapide, standardizarea magistralei PCI [i
existen]a la utilizatori a vechilor componente hardware (pl\ci destinate a func]iona pe
magistrala ISA) a determminat proiectarea unor alte arhitecturi asem\n\toare acestei
scheme (devenite `ntre tip [i ele sunt dep\[ite):
PROCESOR

Magistrala
circuitele " FrontSide
cipsetului
MEMORIE

HDD / CD
C
P
I

Controllere discuri
hard ( ATA-IDE), .
SCSI, SATA etc
PCI to
ISA
BRidge
DISPLAY
DISPLAY
A
S
I

Controlere
periferice lente
TASTATURA
Alte
periferice
Unitate de dischete

Not\ la `ncheierea edi]iei: La ora actual\ schemele pl\cilor de baz\ s-au diversificat [i mai
mult. Magistralele ISA [i EISA ([i bine`n]eles vechiul VLB – Vesa Local Bus) au disp\rut
practic din PC-urile moderne sau, dac\ exist\, exist\ numai pentru a conecta anumite
periferice mo[tenite (legacy) cum este controllerul de tastatur\. Sloturi ISA, EISA [i VLB nu
mai sunt vizibile pe mainboard-urile moderne. Au ap\rut sloturi noi pentru altfel de extensii.
Cartela Video este montat\ de obicei `ntr-un slot special de mare vitez\ (AGP 4 x.. 8 x...).
Se folosesc `nc\ denumiri ca NorthBridge [i SouthBridge dar leg\tura `ntre aceste circuite
se face printr-o magistral\ mult mai rapid\ dec=t PCI. Exist\ deja de ani buni [i solu]ii
integrate, totul (incluz=nd NorthBridge [i SouthBridge) `ntr-un singur chip.

Voi comenta totu[i schema de mai `nainte pentru a se `n]elege `n ce direc]ie s-a `ndreaptat
evolu]ia calculatoarelor `n timp, sub presiunea tehnologiilor noi [i a cererilor utilizatorilor.

Programarea calculatoarelor [i limbaje de programare 33 Dan Popa, 2007



Procesorul este conectat cu restul sistemului printr-o magistral\ rapid\,
numit\ FSB (Front Side Bus). O frecven]\ mai mare a acesteia indic\ o
vitez\ mai mare a transferurilor de date `nspre [i dinspre procesor.
Memoriile beneficiaz\ [i ele de o magistral\ aparte, cu alt\ frecven]\ de
tact, care la r=ndul ei poate fi realizat\ `n conformitate cu diverse tehnologii (una dintre
acestea a fost RAMBUS). Leg\tura cu magistrala PCI este realizat\ de un set de circuite
numit "bridge" (s-ar putea traduce prin "punte"). La magistrala PCI se conecteaz\ periferice
prin intermediul unor controlere dintre care unele sunt deja circuite integrate plasate direct
pe placa de baz\ a calculatorului (mainboard # placa `n conectorii c\ruia care se monteaz\
celelalte componente). Magistrala PCI `ns\[i este acesibil\ pentru conectarea altor pl\ci de
extensie, `n ni[te conectori albi. De exemplu, discurile hard [i unit\]ile CD-ROM, CD-RW,
DVD, DVD-RW (aten]ie, exist\ mai multe standarde cu denumiri confuze, cum ar fi DVD-
RW [i DVD^RW, incompatibile `ntre ele, documenta]i-v\) [i uneori cartelele de re]ea (NIC #
Network Interface Card) au circuitele integrate pe placa principal\ (mainboard) [i conectate
la magistrala PCI. Adesea `ns\ cartelele de re]ea sunt pl\ci cu circuite separate.

Nevoia de a folosi `nc\ unele din vechile cartele de extensie proiectate pentru Magistrala
ISA, obliga sistemele s\ aib\ [i o magistral\ ISA. Leg\tura `ntre magistrala PCI [i magistrala
ISA se face printr-un alt "bridge", a[anumitul "PCI to ISA bridge". Verifica]i dac\ o plac\ de
baz\ pentru un computer are [i conector(i) ISA. Au tradi]ional culoarea neagr\. ~n lipsa lor
nu pute]i folosi `ntr-un nou computer vechile pl\ci de sunet, modemuri [i alte pl\ci de
extensie destinate magistralei ISA. Decide]i ce e avantajos: s\ cump\ra]i o plac\ de baz\
care mai are m\car un conector ISA sau s\ cump\ra]i alt\ cartel\ de extensie (`n englez\
«ad on card»). Deja magistrala ISA a disp\rut din PC-urile noi [i n-o mai g\si]i dec=t pe
c=teva pl\ci de baz\ destinate upgrade-ului sau `n PC-urile second hand mai lente.

Unii autori de documenta]ii, desen=nd schema pl\cii de baz\ cu procesorul [i memoria sus
[i perifericele lente jos, numesc cele dou\ bridge-uri, «northbridge» [i «southbridge», ca [i
cum le-ar indica pozi]ia pe o hart\.

Programarea calculatoarelor [i limbaje de programare 34 Dan Popa, 2007



Schema precedent\ este orientativ\, didactic\. ~n practic\, sunt proiectate
computere mai complexe [i mai performante. Un exemplu de modificare
este cuplarea adaptorului video pe magistrala PCI, `mpreun\ cu
controlerele ATA-IDE destinate discurilor hard. (Desena]i schema sau
corecta]i diagrama anterioar\!) Alt\ variant\ const\ `n existen]a unei magistrale proprii,
destinate adaptorului grafic [i a unei magistrale proprietare, specifice, care face leg\tura
`ntre NorthBridge [i South Bridge. Actualmente se folose[te pentru conectarea adaptorului
video magistrala AGP. (Accelerated Graphic Port). ~n anii ‘90, `nainte de introducerea
standardului de magistral\ PCI, a mai existat o magistral\ pentru conectarea adaptorului
video, numit\ VLB (VESA Local Bus). VESA Local Bus iar apoi AGP sunt mai cur=nd un fel
de interfe]e de mare vitez\, destinate eclusiv adaptoarelor video. Practica multor utilizatori
de birotic\ a ar\tat c\ nu ave]i neaparat\ nevoie de AGP, o plac\ video PCI f\c=nd bine fa]\
majorit\]ii sarcinilor unui loc de munc\.

Magistrala SCSI este de fapt o conexiune destinat\ a func]iona ~NTRE ni[te computere [i
periferice. Unele sisteme o folosesc pentru a conecta la computer discurile hard interne sau
externe. Dac\ dori]i s\ conecta]i dou\ computere (de exemplu dou\ servere redundante) la
acelea[i discuri hard ele trebuie s\ posede magistrale SCSI.

Servere de re]ea:
Termenul ‘server’ descrie un calculator cu func]ii speciale dintr-o re]ea de calculatoare.
(Aten]ie: pentru programatori server este altceva, este un strat de software - grup de func]ii
sau proceduri care ofer\ servicii altor module ale aplica]iei). El distribuie din resursele sale
(periferice, informa]ie - mai rar procesor [i memorie) altor calculatoare din re]ea. ~n re]elele
mici orice calculator poate `ndeplini o asemenea func]ie. ~n re]elele mari, sunt folosite
calculatoare special proiectate, inclusiv modele cu mai multe procesoare. Cel mai simplu
este biprocesorul. Deosebirea fa]\ de PC-urile obi[nuite este c\ pe placa de circuite a
biprocesorului exist\ un soclu pentru al doilea procesor [i exist\ circuite care asigur\
accesul procesoarelor la memorie [i magistrale, inclusiv transferul semnalelor de
`ntrerupere, f\r\ conflicte. (Vom vedea c\ electronica lor pune la dispozi]ia sistemului de
operare de pe aceste calculatoare func]ii suplimentare [i nu orice sistem de operare [tie s\
le foloseasc\. - Din acest motiv unele versiuni de Windows nu folosesc al doilea procesor
dintr-un asemenea computer, `n timp ce LINUX-ul `l poate folosi.) Cipsetul (setul de circuite

Programarea calculatoarelor [i limbaje de programare 35 Dan Popa, 2007


integrate al…) pl\cii de baz\ asigur\ conectarea celui de-al doilea procesor.
Desena]i schema [tiind c\ mai exist\ ni[te procesoare legate la FSB [i mai exist\ o
magistral\ suplimentar\ pentru transferul `ntreruperilor, conectat\ la fiecare procesor [i la
Bridge-uri. Mai nou, procesoarele sunt integrate `n aceea[i capsul\ [i oferite pe pia]\ sub
denumiri ca Dual Core sau Quad Core. ~n acest caz placa de baz\ are un singur soclu (cum
este de exemplu LGA 775 – un soclu pentru procesoare dual core f\r\ pini).

Arhitectura func]ional\ a calculatorul: Piramida func]iilor:

APLICA}II MEDII DE DEZVOLTARE

SISTEMUL DE OPERARE

FUNC}II BIOS {I DRIVERE

HARDWARE

Nivelul de la baz\: HARDWARE-ul. Este construit din componentele electronice [i se


conformeaz\ uneia dintre schemele de mai sus. Asigur\ conectarea `ntre componente.
Pune la dispozi]ia nivelului superior PORTURI, ni[te «loca[uri» numerotate unde driverele
pot trimite (sau de unde pot primi) informa]ii execut=nd anumite instruc]iuni (numite IN [i
OUT). Trimiterea unor date la diverse porturi este un mod de a pune `n func]iune
componentele hardware.

Nivelul 2: FUNC}IILE BIOS [i DRIVERELE: Sunt programe care [tiu s\ comande


hardware-ului s\ `ndeplineasc\ diverse opera]ii. (De exemplu display-ului i se poate schimba
num\rul de r=nduri de pe ecran, i se poate cere s\ afi[eze o liter\ sau s\ deseneze un punct
etc.) Practic, func]iile BIOS sunt mici programe stocate `n circuite de memorie ROM (Read
Only Memory) aflate pe placa de baz\ [i pe pl\cile de extensie ale calculatorului. Practic
fiecare periferic are o memorie `n care sunt stocate programe necesare lui.
Driverele sunt componente `nc\rcate de sistemul de operare care preiau func]iile BIOS-ului,
`n colaborare sau, cel mai des, `n locul acestuia.

Nivelul 3: SISTEMUL DE OPERARE: Este acel program care interac]ioneaz\ cu utilizatorul

Programarea calculatoarelor [i limbaje de programare 36 Dan Popa, 2007


[i cu aplica]iile. El este gestionarul - managerul - RESURSELOR calculatorului. Resursele
pe care le gestioneaz\ S.O. sunt:
- procesorul (mai exact timpul de lucru al procesorului)
- memoria
- perifericele (disc, dischet\, imprimant\, ecran etc)
- informa]ia (cea mai mult\ gestionat\ de sistemul de gestiune al fi[ierelor)
Pentru a-[i desf\[ura activitatea, sistemul de operare apeleaz\ la func]iile nivelului inferior.
BIOS-ul [i/sau driverele comand\ mai departe Hardware-ul pentru a `ndeplini ceea ce s-a
cerut. BIOS-ul e folosit mai mult la pornirea sistemului de calcul apoi driverele `i preiau locul.

Nivelul 4: APLICA}IILE [i MEDIILE DE DEZVOLTARE:


Sunt programele pe care le folose[te utilizatorul final.

Exemple de aplica]ii:
- Procesorul de texte
- Programul de calcul tabelar
- Browser-ul (navigatorul) internet
- Programul de grafic\ vectorial\
- Programul de arhivare sau compresie
- Mediul de programare (sau pe scurt IDE-ul)
- Aplica]iile multimedia, etc.

Mediile de dezvoltare sunt acele instrumente complexe pentru realizarea aplica]iilor. Ele
includ:
- un editor de text (pentru scris programele)
- un compilator (pentru traducerea programelor `n limbajul procesorului);
Re]ine]i: compilatorul este de fapt un translator din limbajul `n care scrie]i programme `n cel
al procesorului.
- un linkeditor (pe rom=ne[te: editor de leg\turi; combin\ codul rezultat `n urma traducerii cu
alte module de program [i ob]ine un PROGRAM EXECUTABIL, care poate fi rulat)

Alte componente (software):


- componente destinate proiect\rii `n mod VIZUAL a interfe]elor (Vizual, de exemplu, o

Programarea calculatoarelor [i limbaje de programare 37 Dan Popa, 2007


fereastr\ cu butoane se ob]ine lu=nd dintr-o colec]ie de componente dou\ butoane [i
plas=ndu-le `n locul dorit din cadrul viitoarei ferestre, totul f\r\ a scrie nici o linie de cod.
Ulterior ve]i `nzestra acel obiect cu instruc]iuni plasate `n corpul metodelor sale ocazie cu
care `ncepe]i s\ scrie]i cod. Totu[i ve]i avea nevoie s\ [ti]i limbajul, dac\ ve]i dori s\
modifica]i sau s\ `n]elege]i codul generat [i mai ales s\ ad\uga]i altul. Instrumentel vizuale
v\ ajut\ doar la realizarea interfe]elor grafice a programelor, (ferestre, butoane, etc.) Altfel
ve]i ob]ine `n cel mai bun caz o fereastr\ cu butoane care nu fac nimic (neav=nd cod
asociat) la ap\sare pe ele.
- un depanator (DEBUGGER) - permite execu]ia pas cu pas a programelor
- programe pentru editarea unor date specifice, de exemplu pentru realizarea corpurilor 3D.
Sunt de fapt ni[te editoare specializate cu care se pot ob]ine anumite fi[iere cu informa]ii
care vor fi prelucrate de viitoarea aplica]ie. Se folosesc `n proiectarea jocurilor video [i nu
numai.

Paradigme ale programării

Cuvinte cheie: programare imperativă, programare structurată, programare funcţională,


programare logică, programare orientată obiect, obiecte, date, metode, clase, ierarhie de clase,
moştenire, polimorfism.


Programarea calculatoarelor este activitatea de a transpune o
problem\ din universul real `n universul calculatorului. Ea poate fi
abordat\ `n mai multe moduri iar diversele limbaje `ncurajeaz\ mai mult
sau mai pu]in o anumit\ abordare a program\rii:

1. Programarea imperativ\

Programatorul instruie[te calculatorul CE opera]ii are de f\cut [i ~N CE ORDINE trebuie s\


le execute. Iat\ ni[te secven]e de instruc]iuni, p\r]i dintr-un program mai mare:

Programarea calculatoarelor [i limbaje de programare 38 Dan Popa, 2007


Exemplu: (`n limbajul PASCAL, comentariile nu fac parte din program)

X:#2; “ x ia valoarea 2”
Y:#3; "y ia valoarea 3"
Z:#X^Y; " z ia valoarea care rezult\ ca sum\ a lui x cu y "
write(Z); “ scrie valoarea variabilei Z”

Exemplu: (`n C [i succesoarele sale; Observa]i c\ `n C x [i X sunt variabile diferite !)

X#2; “ X ia valoarea 2”
Y#3; "Y ia valoarea 3"
x#X^Y; " x ia valoarea care rezult\ ca sum\ a lui X cu Y "
printf(%d, x); “ scrie valoarea variabilei x, sub form\ de num\r zecimal ”

Programarea structurat\ (este tot programare imperativ\):

Programul este format din structuri (un fel de instruc]iuni complexe care con]in `n interiorul
lor alte instruc]iuni). Instruc]iunea GOTO nu se mai folose[te, nu exist\ sau nu se
`ncurajeaz\ folosirea ei. Fiecare structur\ (asemenea unei piese de LEGO) are un `nceput [i
un sf=r[it ([i numai unul din fiecare). Cea mai mare structur\ posibil\ este chiar programul.
Fiecare structur\ se comport\ ca o instruc]iune [i poate fi inclus\ ca atare `n alte structuri.

Exemplu: (`n PASCAL)

read(x);
if (x div 2) # 0 then write ( ’x este par’) else write( ’x este impar’);

Se observ\ pe r=ndul al II-lea instruc]iunile WRITE interioare instruc]iunii if

Exemple de limbaje imperative: TCL (pronun]at « tickle ») PASCAL, BASIC, FORTRAN, C ,


Oberon, Java. Dintre ele PASACAL, C, OBERON au instruc]iuni structurate. La fel [i C^^

Programarea calculatoarelor [i limbaje de programare 39 Dan Popa, 2007


care este o extensie a limbajului C, adic\ un limbaj mai bogat ca C. Java e mai cur=nd un
fel de C^^ simplificat [i modificat pe alocuri, pentru a-l face mai sigur (`n sensul securit\]ii
informatice).

2.Programarea func]ional\:

Programatorul poate opera nu numai cu date ci [i cu func]ii. Se pot scrie, de exemplu,


programe care primesc dou\ func]ii [i un argument apoi calculeaz\ compunerea func]iilor
(care e tot o func]ie). Pe aceasta o putem compune cu alte func]ii sau `i putem oferi
argumente. Ob]inem astfel alte func]ii av=nd mai pu]ine variabile sau ob]inem chiar
rezultate, valori ale func]iilor (dac\ am `nlocuit toate variabilele cu valori). Aceste limbaje au
la baz\ teoria matematic\ a lambda-calculului dar nu e necesar s-o `nv\]a]i ca s\ le folosi]i.
Unele dintre cele mai noi limbaje func]ionale (Haskell, Gopher) permit utilizarea rapid\ de
no]iuni de matematici superioare care sunt deja incluse `n limbaj. (Exemple: functori,
monade [i alte no]iuni din teoria categoriilor.) ~ntregi [abloane de programare pot fi
codificate sub forma unor func]ii de ordin superior, care manipuleaz\ alte func]ii. Un algoritm
de sortare (punere `n ordine a unor elemente) scris `ntr-un limbaj fun-c]ional nu trebuie s\
cunoasc\ func]ia de comparare a dou\ valori, o va primi ulterior, dar poate fi scris `n lipsa ei
[i va fi valabil la clase `ntregi de tipuri de date. (este cazul Haskell-ului dar nu numai al lui)

Exemplu: (`n LISP # LISt Processor )

(DEFUN F (X) (^ X 1) ) - am definit func]ia f(x)#x^1

Observa]i nota]ia specific\ pentru opera]ii - cu operatorul scris primul - [i pentru func]ii -
prima parantez\ se pune `naintea numelui func]iei.

(F 2) - doresc s\ calculez f(2)


3 - sistemul r\spunde d=nd rezultatul

Programarea calculatoarelor [i limbaje de programare 40 Dan Popa, 2007


Exemplu: ~n Haskell, care este un limbaj `n care nu se folosesc a[a multe paranteze ca `n
Lisp.

f :: Integer -> Integer


f x = x+1

Aten]ie: Programul de proiectare asistat\ de calculator AutoCAD (Computer Aided Design al


firmei Autodesk) folose[te un dialect de LISP numit AutoLISP. Inginerii care vor face
proiectare asistat\ de calculator vor avea nevoie s\ [tie LISP pentru a `nv\]a AutoLISP. Alte
produse CAD includ alte feluri de limbaje. LISP a fost deja s\ fie `nlocuit cu Scheme `n
universit\]i din Fran]a [i din `ntreaga lume iar din Marea Britanie se r\sp=nde[te deja un
limbaj mai elegant, mai simplu [i mai puternic (pe deasupra [i oferit gratuit fie `n variant\
interpretat\: Hugs 98 fie compilat\: GHC – Glasgow Haskell Compiler): este vorba de
Haskell 98. Haskell ofer\ pe l=ng\ elemente specifice limbajelor func]ionale [i no]iuni cum ar
fi clas\ [i instan]\, este aproape lipsit de paranteze, are o sintax\ bidimensional\ [i po]i scrie
`n el un algoritm Quicksort `n numai 4-5 r=nduri, nu `n 40-50 ca `n C. Productivitatea
muncii de programare `n Haskell este de 9-20 ori mai mare ca `n alte limbaje !!
(accesa]i www.haskell.org pentru mai multe detalii [i da]i click pe link-ul ro al comunit\]ii
rom=ne de Haskell). Acest lucru `l face deja s\ fie c\utat de companiile care pentru a
satisface cerin]e mereu schimb\toare venite de la clien]i au nevoie de un limbaj pentru
dezvoltare [i service de soft rapid.

3.Programarea logic\:

Un colectiv de cercet\tori din Marsilia a pus bazele program\rii logice [i al limbajului


PROLOG. Modelarea lumii pe care dorim s-o reprezent\m `n limbaj se face `n mod
declarativ, nu imperativ. Descriem universul dorit prin reguli de forma unor implica]ii. Se
adaug\ [i a[a zisele fapte, folositoare ca puncte de pornire ale ra]ionamentului. Pe baza
faptelor, aplic=nd SINGUR regulile, sistemul ob]ine concluzii. E un limbaj folosit de exper]ii
`n inteligen]a artificial\.

Prolog-ul nu face parte dintre limbajele care vor fi studiate `n cadrul acestui curs. Re]ine]i

Programarea calculatoarelor [i limbaje de programare 41 Dan Popa, 2007


totu[i c\ PROLOG-ul este un limbaj declarativ, `n care ordinea efectu\rii instruc]iunilor NU
E SPECIFICAT| DE PROGRAMATOR, spre deosebire de limbajele imperative `n care
programatorul descrie pas cu pas procesul de calcul.
Exemple de limbaje destinate program\rii logice: PROLOG, DATALOG.

4.Programarea orientat\ obiect:

Programarea orientat\ obiect este una dintre cele mai moderne paradigme. Universul
modelat este reprezentat ca o colec]ie de OBIECTE. Un obiect este o entitate care con]ine
DATE [i METODE (metodele sunt `n general func]ii – ca `n matematic\ - dar dac\ ele nu
returneaz\ nimic se numesc proceduri). Datele descriu propriet\]i statice ale obiectului iar
metodele implementeaz\ comport\ri ale obiectului la ac]iunea altor entit\]i (uzual tot
obiecte) asupra lui. Interac]iunea a dou\ obicte se realizeaz\ astfel: Unul din obiecte
apeleaz\ o metod\ a celuilalt. Metoda respectiv\ preia informa]ii (parametrii transmi[i de
primul obiect) [i `i prelucreaz\ a[a cum “[tie” al doilea obiect. Rezultatul interac]iunii depinde
astfel de ambele obiecte. De exemplu `ntr-un joc video cu arte mar]iale `n care lovesc
adversarul meu care are 100 de puncte de via]\ cu lovitura mea de for]a a 70 de unit\]i, `i
apelez de fapt metoda (procedura/func]ia) lui numit\ «prime[te_lovitura» cu parametrul
meu, 70 de unit\]i. Iar fiecare adversar put=nd avea alt\ metod\ «prime[te_lovitura», va
putea reac]iona altfel la lovituri. Metoda lui va face calculele dup\ formulele specifice
acestuia sc\z=nd din energia sa num\rul de puncte al loviturii (eventual multiplicat sau
diminuat sau altfel transformat). Vom vedea c\ un asemenea comportament diferen]iat al
obiectelor se nume[te polimorfism.


Obiecte cu aceea[i structur\ (acelea[i metode [i doar diferite valori ale
datelor) formeaz\ o clas\. De exemplu cuburi care pot avea diferite
dimensiuni. Clasa de obiecte este un tip de date descris de utilizator,
compus din informa]ii plasate `n c=mpuri – cum ar fi dimensiunea [i din
metode – func]iile care implementeaz\ diverse comportamente ale obiectelor. ~n
program pot exista mai multe obiecte din aceea[i clas\. Ele se numesc instan]e ale
clasei. Pentru simplificare, se pot defini clase noi, asem\n\toare cu o clas\ deja existent\,
specific=nd doar deosebirile (ce date [i metode are noua clas\ `n plus). O asemenea clas\

Programarea calculatoarelor [i limbaje de programare 42 Dan Popa, 2007


se nume[te clas\ derivat\ iar procesul automat prin care ea cap\t\ toate atributele (date [i
metode) ale clsei p\rinte se nume[te mo[tenire. Se formeaz\ astfel, `n cadrul unui proiect
de mari dimensiuni un adev\rat “arbore genealogic” numit ierarhie de clase. (Cu aceste
concepte vom lucra la laborator.)

Exemple de limbaje obiectuale: Borland PASCAL, Turbo PASCAL, C^^, C#, Oberon,
ITCL [i lista ar putea continua (a]i auzit cumva de Python [i Ruby ?).

Programarea calculatoarelor [i limbaje de programare 43 Dan Popa, 2007


3
Cap

Elemente de ingineria programării


(metoda SA/SD)

Cuvinte cheie: ingineria programării, modelarea fluxurilor de date, programare structurată,


analiză, modelare, implementare, model static, model dinamic, model funcţional, I/O, iterarea
etapelor proiectării, client - server, apeluri, funcţii şi proceduri, reengineering, schemă logică,
automat finit determinist, stare, stare iniţială, stare finală, funcţie, semnătura funcţiei, parametri
formali, tip de date, nil, Oberon, N. Wirth, module, IMPORT, Display, ProgMain, * ,
proceduri exportate, operatorul “.” , sintaxă, apel de metodă,

Paragraful “Ghid pentru studierea unui limbaj de programare imperativ” este însoţit de propriul
său set de cuvinte cheie. Dacă aţi studiat un astfel de limbaj, probabil vă sunt cunoscute. Oricum,
citiţi totuşi paragraful, măcar pentru cazul când aţi fi în situaţia de a explica (cuiva) ceva din el.

Ingineria program\rii cuprinde ansamblul de tehnici [i metode utilizate `n procesul proiect\rii


aplica]iilor informatice. Aceste metode permit analistului-programator s\ abordeze problema
dat\, s\ conceap\ elementele unui sistem informatic, s\ depisteze rela]iile `ntre componente
[i felul datelor pe care le prelucreaz\ componentele. Ulterior ob]inerii unei asemenea
perspective asupra problemei se face o documenta]ie (adeseori omis\ la firmele din
Rom=nia, care const\ printre altele `ntr-un set de scheme) [i se scrie un set de specifica]ii
pentru programatori. Pe baza specifica]iilor, membrii echipei (se lucrez\ `ntr-o echip\

Programarea calculatoarelor [i limbaje de programare 44 Dan Popa, 2007


condus\ de un programator [ef) pot `ncepe s\ scrie modulele componente ale aplica]iei.
Odat\ proiectarea corect f\cut\ [i fluxul de date `ntre componentele aplica]iei fiind astfel
definit [i standardizat, componentele pot fi realizate de persoane care nu se cunosc `ntre ele
sau care lucreaz\ independent. Programul principal al aplica]iei va face apeluri la modulele
celelalte, `n calitate de client, pun=nd `n func]iune diversele componente ale aplica]iei.

Filosofia care permite separarea aplica]iei `n componente a fost prezentat\ `n cursul


precedent, acolo unde am prezentat calculatorul personal ca o piramid\ de nivele, `ncep=nd
de la hardware [i termin=nd cu nivelul aplica]iilor [i mediilor de dezvoltare. Rela]ia dintre
dou\ nivele din piramid\ este o rela]ie CLIENT - SERVER. Nivelul client, cel mai de sus din
ierarhie, cere servicii nivelului server, apel=nd func]ii (func]iile se numesc `n Oberon
"proceduri func]ionale") sau proceduri ale acestuia. Aceste proceduri sau func]ii, atunci c=nd
apar]in unor obiecte, se numesc [i metode. (Vom folosi des denumirea de “metode” `n
cadrul paradigmei program\rii orientate obiect). Fiecare metod\ (func]ie sau procedur\)
posed\ un nume [i o semn\tur\ care este practic mul]imea ordonat\ a tipurilor parametrilor
s\i formali. (Este exact ca la matematic\ unde func]ia f: N x R -> R este prezentat\ prin
numele “f” [i informa]ia “: N x R -> R” , care este echivalentul semn\turii). Apelurile de pe un
nivel se fac, (recomandabil) la func]ii ale nivelului imediat inferior.

Exist\ mai multe tehnici de apel:


– Apelul direct al metodelor
– Apelul prin intermediul unui tabel de pointeri (adrese) ale metodelor av=nd
aceea[i semn\tur\ dar nume diferite. (Este numit uneori “apel prin tablou
dispatch” ). ~n Oberon poate fi implementat [i ca un tabel de c`mpuri procedurale,
un fel de variabile ale c\ror valori sunt nume de procedur\ [i care pot fi apelate
pe numele lor (vor apela procedura al c\rei nume `l memoreaz\). ~n C sau C++
poate fi realizat ca un tabel de pointeri la func]ii cu aceea[i semn\tur\.
– Ierarhiile de clase de obiecte permit apelul la metode `n mod dependent dinamic
de tipul obiectului. ~n asemenea situa]ii tabelele de pointeri sunt generate de
compilator [i utilizatorul nu are grija lor, nu le observ\ nu le acceseaz\.
– Evenimentele generate de sistemul de operare (de exemplu un click de mouse
pe un obiect, buton, fereastr\ etc) pot fi asociate [i ele unor metode. Astfel,

Programarea calculatoarelor [i limbaje de programare 45 Dan Popa, 2007


metodele obiectelor vor fi apelate automat la apari]ia diverselor evenimente. Iar
programatorul [i aplica]iile pot defini [i apoi «lansa» propriile lor evenimente care
vor fi tratate de metode.
~n momentul apelului, clientul transmite nivelului server informa]ii privitoare la datele care
trebuiesc prelucrate [i prime[te r\spunsuri sau mesaje de eroare de la acesta.

Nivelul client

# apel de func]ie de
Nivelul server = procedur\ (sau de metod\ a unui
modulul importat sau obiect) de la client la server
inclus cu directiva #include

~n figur\: Reprezentare grafic\ a rela]iei CLIENT SERVER

Un proiect trece prin patru etape care sunt apoi iterate cu ocazia lans\rii versiunilor
ulterioare ale aplica]iei. Etapele sunt:
– analiza,
– modelarea,
– implementarea, (urmate evident de...)
– depanare (sau service de soft).

Analiza : caut\ s\ se afle c=t mai multe lucruri despre problem\, despre universul de
modelat format din utilizatori, re]ea de calculatoare, problem\, documente [i prelucr\ri.

Modelarea : duce la crearea a trei modele, pe care le vom discuta


1. Modelul Static (este ierarhia de module a aplica]iei)
2. Modelul Dinamic (d\ ordinea de apel a diverselor proceduri)
3. Modelul Func]ional (d\ semn\turile, adic\ parametrii procedurilor)

Implementarea: Cu ocazia implement\rii (a scrierii efective a programelor) se poate


descoperi c\ este necesar un supliment de analiz\ (chiar o refacere a analizei), o dezvoltare
sau o modificare a unuia dintre cele trei modele (deci luarea altor decizii de modelare) sau

Programarea calculatoarelor [i limbaje de programare 46 Dan Popa, 2007


rescrierea de por]iuni de cod surs\ (program). Aceast\ ultim\ opera]ie se nume[te
“reengineering” [i const\ `n rescrierea por]iunilor de cod deja existente, `n scopul cre[terii
eficien]ei sau al ob]inerii unui cod mai bun (pe diverse criterii). ~ntregul proces al proiect\rii
unei aplica]ii trebuie `n]eles ca o repetare a succesiunii acestor etape. Testarea [i validarea
codului scris e parte integral\, deloc neglijabil\, din procesul de implementare.

Testarea modulelelor de cod se poate face realiz=nd odat\ cu modulul cerut [i un modul
client specializat care `l apeleaz\, cu scopul de a-l testa, oferind func]iilor (sau
procedurilor) de acolo diverse informa]ii [i verific=nd rezultatele.


Lucrare practic\: Dac\ un modul de rezolvare a ecua]iilor de gradul `nt=i
a*x ^ b # 0 con]ine o func]ie care returneaz\ pe x, modulul de test va
`nmul]i pe x cu a, va aduna b [i va testa dac\ e egal cu zero, [i aceasta
pentru mai multe valori ale lui a [i b, fie dinainte programate, fie dintr-un
spa]iu dat, fie aleatoare. Exemplul este pur didactic. {ansa de a fi simultan gre[ite [i
modulul de testare [i cel proiectat iar cele dou\ gre[eli s\ se anuleze `ntotdeauna reciproc
este extrem de mic\. Practic dou\ gre[eli at=t de bine (a se citi «nefericit») coordonate nu
se `nt=lnesc `n realitate.


Realiza]i ca activitate practic\: implementarea celor dou\ module.
Aten]ie: Va trebui s\ `ncepe]i un nou proiect (New -> Project -> Oberon-2 ->
Use template “opal display”) [i s\ ave]i grij\ s\ include]i pe lista fi[ierelor
proiectului (Project -> Edit) ambele module, care trebuie s\ fie salvate `n
prealabil, de preferat `n acela[i dosar, cel al proiectului . Un modul nou se adaug\ la un
proiect aleg=nd fi[ierul .mod dorit [i ac]ion=nd asupra butonului “add” din fereastra
editorului de proiect.

Dac\ lucra]i la laborator cu mediul de programare Pow `n Oberon sau `n C++ ghida]i-v\
dup\ figura urm\toare. {i celelalte medii de programare, de exemplu Dev-C++-ul ofer\ un
gestionar pentru module , o fereastr\ unde vede]i modulele ca o list\ sau grupate ierarhic.

Programarea calculatoarelor [i limbaje de programare 47 Dan Popa, 2007


~n fig.: Fereastra editorului de proiecte din mediului Pow cu lista de module scrise `n limbajul Oberon-2.

Analiz\ [i analist : Analistul este persoana din echipa de dezvoltatori despre care se spune
c\ «dac\ este dat\ afar\ pe u[\, `]i intr\ `napoi pe fereastr\». Acest lucru este justificat de
rezisten]a personalului de alte specialit\]i la `ncerc\rile de a face analiza unei activit\]i de
informatizat. Practic `n faza de analiz\ va trebui s\ aduna]i informa]ii despre tot procesul de
informatizat, de la specificul procesului [i fluxul de produc]ie p=n\ la formatul documentelor
la intrare [i ie[ire, regulile de calcul ale noilor valori numerice [i regulile de realizare a
documentelor finale. N-ar fi r\u s\ cere]i sau s\ realiza]i `mpreun\ cu beneficiarul m\car un
set de documente complet, a[a cum va trebui s\ le produc\ viitoarea aplica]ie. Ele vor servi
[i ca date de test pentru aplica]ia pe are o ve]i realiza. Analistul caut\ deci s\ culeag\
maximum de informa]ii despre domeniul `n care se va folosi aplica]ia [i problemele concrete
pe care le va rezolva aceasta. ~n aceast\ etap\ se adun\ specifica]iile de la beneficiar, se
pun la dosarul proiectului exemplare (copii) ale documentelor sau datelor primare (de
prelucrat) [i specifica]ii ale datelor finale (de ob]inut) plus diagrame ale fluxurilor de date. Un
exemplu de asemenea specifica]ii sunt formatele rapoartelor - dac\ aplica]ia produce a[a
ceva.
Accentul cade pe `n]elegerea specifica]iilor [i a universului problemei `n general. Aminti]i-v\
c\ nu-l pute]i `nv\]a pe calculator ceva ce nu [ti]i dumneavoastr\.

Programarea calculatoarelor [i limbaje de programare 48 Dan Popa, 2007


Observa]ie: Uneori analiza poate conduce la concluzia c\ datele ini]iale a[a cum sunt
specificate nu ajung pentru ob]inerea rezultatului. Sau c\ problema este matematic vorbind
nerezolvabil\ sau nerezolvabil\ `n timp rezonabil. Reamintim c\ exist\ un domeniu numit
teoria calculabilit\]ii care se ocup\ de analiza problemelor sub aspectul dificult\]iii sau
imposibilit\]ii lor de a fi rezolvate cu calculatorul [i de m\surarea acestei dificult\]i [i
clasificarea problemelor `n clase de complexitate. Acest domeniu, prezentat pe larg, face
obiectul cursurilor de teoria calculabilit\]ii, din cadrul sec]iilor de Informatic\.

Modelul static: Separ\ aplica]ia `n unit\]i constitutive numite module [i stabile[te ordinea
(bazat\ pe rela]ii CLIENT-SERVER) dintre modulele care vor forma ierarhia modulelor. (A
nu se confunda cu ierarhia claselor de la paradigma program\rii orientate obiect din cursul
precedent. Acea ierarhie era bazat\ pe «derivare de clase», adic\ pe rela]ii `ntre clase de
obiecte ale c\ror instan]e (obiectele din clas\) sunt construite unele prin extinderea altora
(din clasa p\rinte). ~n implementarea fiec\rui nivel pot s\ existe una sau mai multe ierarhii
de clase, cu obiecte necesare pentru rezolvarea sarcinilor nivelului respetiv.)

Practic, modelul static permite separarea aplica]iei `n componente mai mici, fiecare
asemenea component\ va deveni un fi[ier cu cod surs\ scris de un programator. ~n aceast\
etap\ se stabile[te din c=te fi[iere surs\ se compune aplica]ia, ce fel de proceduri [i func]ii
(adic\ proceduri func]ionale) vor con]ine acestea. Se aleg numele modulelor. ~n general se
recomand\ ca un modul s\ cuprind\ proceduri [i func]ii similare ca utilitate, structur\, scop
sau mod de apel.
Observa]ie: Modelarea static\ are un anumit grad de arbitrarietate. Felul cum va grupa
procedurile `n module depinde de experien]a proiectantului.

Modelul dinamic: Descrie ordinea `n care programul principal al aplica]iei va pune `n func]
iune (va face apeluri de pe pozi]ia de client la) alte module ale aplica]iei.
Accentul cade pe ordinea `n timp a evenimentelor care determin\ trecerea aplica]iei dintr-o
stare `n alta. Succesiunea acestor apeluri f\cute de programul principal poate fi
reprezentat\ grafic, asem\n\tor cu o schem\ logic\ sau, pentru cunosc\tori, ca un automat
finit determinist. Exist\ [i autori care deseneaz\ diagrama modelului dinamic `ntr-un mod
asem\n\tor cu o schem\ logic\.

Programarea calculatoarelor [i limbaje de programare 49 Dan Popa, 2007


Observa]ie: utilizarea tot mai frecvent\ a program\rii bazate pe evenimente, `n care
programatorul specific\ (scriind metodele unor obiecte) ce se `nt=mpl\ c=nd obiectul
respectiv recep]ioneaz\ un eveniment (de exemplu un clic de mouse asupra sa ori o pozi]
ionare de cursor `n dreptul s\u), [i existen]a `n aplica]iile Windows a unei bucle principale
care proceseaz\ o coad\ de evenimente (bucl\ de implementarea c\reia mediile moderne
de programare ne scutesc), face ca modelul dinamic s\ fie mai pu]in important, cu toate c\
cei care programeaz\ dispozitive automate `l vor considera util.


Defini]ie: Automatul finit determinist (AFD) este o ma[in\ imaginar\ care
posed\ o mul]ime finit\ de configura]ii numite st\ri [i trece (`ntr-un mod
determinist, binedefinit, dup\ reguli precis determinate), dintr-o stare `n
alta. Dac\ ajunge `ntr-o stare special\ numit\ stare final\, AFD-ul se opre-
[te. Pot exista mai multe st\ri finale. Exist\ o singur\ stare ini]ial\. AFD-ul este reprezentat
ca un graf orientat (cam ca planul unui ora[ format din pie]e [i str\zi cu sens unic), `n care
nodurile sunt st\rile. Nodul - stare ini]ial\ este marcat cu o s\geat\ care intr\ `n nod. Un nod
stare-final\ e desenat ca dou\ cercuri concentrice de raze apropiate. Pe fiecare arc este
marcat evenimentul sau comanda care determin\ parcurgerea arcului.

Modelul func]ional: Descrie transferul datelor `ntre componentele aplica]iei. Fiecare


prelucrare poate fi considerat\ un proces independent ([i o problem\ independent\ de
rezolvat totodat\). Acest model define[te exact ceea CE FACE o unitate component\ a
aplica]iei, f\r\ a indica CUM (adic\ ALGORITMUL), C+ND (starea din modelul dinamic [i
evenimentul care a dus la acea stare) [i DE CE se face (decizia s-a luat `n faza de analiz\).
~n aceast\ etap\ se stabilesc denumirile func]iilor [i procedurilor precum [i semn\turile
acestora. Fiecare func]ie se deseneaz\ conform unor scheme tip, preciz=nd pe s\ge]ile care
apar `n acele scheme semnifica]ia [i denumirea datelor transmise. Se scrie pentru fiecare
func]ie numele func]iei [i semn\tura acesteia, preciz=nd tipurile de date. Dac\ spre
deosebire de func]iile matematice vreo func]ie nu `ntoarce nici un rezultat se trece ca
rezultat “nil”. “Nil” este tipul de date care `nseamn\ nimic, iar func]iile care `ntorc date de tip
nil sunt de fapt proceduri. Proceduri este un termen folosit `n limbajele din familia Pascalului
pentru func]ii care nu `ntorc nimic [i se scriu folosind o sintax\ special\ exemplu: ~n Pascal
numele lor `ncepe cu «procedure». Vom mai folosi `n continuare termenul proceduri pentru
func]iile care nu `ntorc rezultat, chiar dac\ sunt scrise `n alte limbaje.

Programarea calculatoarelor [i limbaje de programare 50 Dan Popa, 2007


Re]ine]i: deoarece comportarea modului/programului principal al aplica]iei, (care apeleaz\
func]ii [i proceduri din alte module) este descris\ de modelul dinamic, uneori nu mai este
necesar\ descrierea acestui modul `n modelul func]ional. Aceast\ afirma]ie este motivat\ [i
de altceva, a]i observat de ce ? G`ndi]i-v\ c\ acest modul nu presteaz\ dec=t serviciul de a
porni programul.

~ntrebare: Cum [i din ce model afl\m ce date trimite acest modul principal spre func]iile pe
care le apeleaz\ ? (Dac\ nu pute]i r\spunde la `ntrebare ar fi cazul s\ mai citi]i o dat\
ultimele paragrafe). G`ndi]i-v\ c\ este vorba de func]ii.

Dezavantajele acestei metode de proiectare (numit\ [i SA/SD : Structured Analysis /


Structural Design):

1. Alegerea [i identificarea subansamblelor unei aplica]ii, realizarea modelului static,


este arbitrar\. Ea nu reflect\ universul problemei [i conceptele de acolo, `n mod necesar [i
`n manier\ unic\. Diver[i anali[ti pot propune modele statice diferite pentru aceea[i aplica]ie.
La preluarea `n service de soft a unui proiect anterior, modelul static utilizat poate fi diferit
de cel a[teptat. A moderniza un proiect realizat de un alt programator, conform unui model
static care nu este conform opiniei dumneavoastr\ este o sarcin\ cel pu]in ingrat\. Partea
important\ a model\rii se centreaz\, tradi]ional, pe modelul func]ional. Vom vedea c\ abia
modelarea obiectual\ [i realizarea aplica]iilor conform paradigmei program\rii orientate
obiect au schimbat aceast\ tradi]ie.

2. Modelul dinamic poate fi [i el prezentat [i implementat `n diverse moduri, conform


diagramei care seam\n\ cu schema logic\ sau conform teoriei automatelor, implement=nd
un AFD. (Da! Se pot construi aplica]ii [i a[a!) Sunt posibile [i alte solu]ii de realizare (de
exemplu folosind principiul “buclei de evenimente”). Nu [ti]i dinainte ce manier\ a ales un
implementator anterior.

3.Modelul func]ional este constr=ng\tor sub raportul definirii semn\turilor func]iilor.


Orice modificare a tipurilor de date vehiculate afecteaz\ modelul func]ional. Preferabil ar fi
ca anumite modific\ri ale datelor transferate s\ nu fie vizibile `nafar\, la nivelul model\rii sau

Programarea calculatoarelor [i limbaje de programare 51 Dan Popa, 2007


s\ poat\ fi `ncapsulate, ascunse cumva. (Ceea ce se va putea face cu obiecte.) Protocolul
dup\ care comunic\ elementele aplica]iei este fix, inflexibil. Este dificil\ ad\ugarea de noi
componente care s\ r\spund\ la noi comenzi.

4. Programarea structurat\ presupune separarea datelor de program. Acest lucru este


util `n situa]ia programelor care manipuleaz\ baze de date, [i nu este neaparat util la alte
aplica]ii. Ba dimpotriv\, separarea datelor de programele care le prelucreaz\ e adesea
incomod\. (Fanii multimedia `[i amintesc probabil ce a `nsemnat s\ ob]ine\ un fi[ier cu un
film sau cu muzic\ pentru care s\ nu aveu player-ul sau codec-ul necesar.) Modific\rile
aplica]iei atrag uneori dup\ ele nevoia reproiect\rii simultane a datelor [i func]iilor, av=nd
`ns\ grija de compatibilitatae lor. Ideal ar fi ca datele [i func]iile s\ poat\ fi extinse f\r\ s\ mai
conteze prea mult cum erau `nainte, ci doar ceea ce dorim s\ ad\ug\m.

Por]iunea veche a datelor e recomandat s\ r\m=n\, pentru compatibilitate. Problema este


rezolvabil\ program=nd `n maniera numit\ “programming by difference” (ceea ce s-ar
traduce prin programare prin diferen]\).

5. Se presupune c\ programul este mai important [i mai complex dec=t datele. Ceea
ce este fals. Structurarea datelor nu este vizibil\ `n etapa de proiectare, de[i este necesar\.
( Cum a]i implementa o informa]ie compus\, de tipul “tabl\ de [ah cu piese” ?). ~n practic\,
de multe ori, pentru o aplica]ie, datele sunt mai importante, mai complexe sub raportul
structur\rii dec=t programele. Da]i exemple de asemenea situa]ii din lumea jocurilor video .

6.Proiectarea aplica]iei presupune colaborare `ntre echipa de anali[ti-programatori [i


echipa de speciali[ti din domeniul aplica]iei dezvoltate. De obicei, firma beneficiar\ `n
loc s\ trimit\ un expert care s\ stea la dispozi]ia dezvoltatorilor aplica]iei trimite un celebru
necunoscut `ncep\tor. Refuza]i beneficiarului un asemenea colaborator [i solicita]i asisten]a
expertului autentic atunci c=nd realiza]i un proiect pentru un beneficiar.

De ce este necesar\ totu[i cunoa[terea acestei metodologii de proiectare structurat\ ?


Deoarece exist\ aplica]ii deja realizate astfel. Proiectarea structurat\ r\m=ne de actualitate
deoarece metodologiile proiect\rii orientate obiect folosesc `n cadrul obiectelor func]ii [i
proceduri proiectate structurat. (Deci totul se va aplica `ntr-un alt cadru.) E necesar `n

Programarea calculatoarelor [i limbaje de programare 52 Dan Popa, 2007


aceste condi]ii s\ pute]i `nv\]a (`n circa o s\pt\m=n\) un limbaj imperativ `n care e proiectat\
o anume aplica]ie. Pentru aceasta oferim `ntr-un subcapitolul urm\tor un mic ghid care v\
spune ce va trebui s\ c\uta]i `n manualul limbajului.

Schema unei aplicaţii cu baze de date


Cuvinte cheie: baza de date, formular, ecran, interogare, meniu

Programatorii de aplica]ii din domeniul economic folosesc alt\ diagram\ pentru a reprezenta
structura unei aplica]ii. Observa]i c\ nu specific\m `n diagram\ tipul datelor prelucrate ci
doar direc]ia fluxurilor de date. Diagrama (o g\si]i `n paginile urm\toare) e suficient de
general\ `nc=t s-o pute]i folosi pentru aproape orice aplica]ie, particulariz=nd-o
corespunz\tor.

~n esen]\ o aplica]ie din domeniul economic, de exemplu una realizt\ folosind FoxPro sau
Visual Fox Pro ar putea avea urm\toarele componente:

– meniul principal al aplica]iei, (care `nlocuie[te meniul Fox Pro). Din acest meniu se
apeleaz\ diferite instruc]iuni, diferite proceduri (grupuri de instruc]iuni) sau diferite alte
programe
– pentru cre[terea productivit\]ii aceste programe pot fi produse `n serie cu ni[te softuri
numite generatoare: generator de ecrane sau formulare (eng; forms), generator de
rapoarte, generator de interog\ri, generator de etichete etc.
– unele module introduc date `n baza de date, le-am figurat `n st=nga
– unele module prelucreaz\ date din baza de date (de exemplu fac verificari suplimentare
de consistenta), sunt programme scrise la de m=n\; le-am desenat la mijloc
– ultimele module extrag date din baza de date pentru a oferi rezultate (rapoarte de obicei).
Uneori aceste module sunt activate din alte p\r]i dec=t meniul principal (de pe WEB).

Programarea calculatoarelor [i limbaje de programare 53 Dan Popa, 2007


Modulul Principal (interfa]\, Meniu)

Module pentru Module care Module pentru afi-


introducerea de prelucreaz\ datele [area de date,
date din baza de date interogare [i
( formulare, ecrane generarea de
de introducere a rapoarte
datelor)

Baza de date

~n fig.: o reprezentare a modelului unei aplica]ii, folosit\ de cei care lucreaz\ `n domeniul bazelor de date.

Ghid pentru studierea unui limbaj de


programare imperativ
Cuvinte cheie: tipuri de date, delaraţii de variabile,instrucţiuni de I/O,atribuire, expresii,
operatori, decizie(if), instrucţiuni repetitive, secvenţa, funcţii, proceduri, încapsulare, programare
structurată, date structurate, tablouri, înregistrări, pointeri, variabile dinamice, fişiere, biblioteci,
obiecte, clase, moştenire, polimorfism.

Interac]iunea om calculator [i nevoia de universalitate (s\ pot aborda `ntr-un limbaj orice

Programarea calculatoarelor [i limbaje de programare 54 Dan Popa, 2007


problem\) face ca limbajele imperative destinate program\rii structurate s\ con]in\ mai toate
urm\toarele elemente. (Modul de numerotare este similar cu cel al elementelor vectorilor
din C, C^^ [i Oberon, adic\ `ncepe de la zero).

0. Cum arat\ cel mai simplu program. Dar unul complex va fi la fel?
1. Tipuri de date. Afla]i cum se numesc tipurile: `ntreg, real, logic, caracter, [ir de caractere.
Alte tipuri mai exist\ `n limbaj ?
2. Variabile, declara]ii de variabile. Exist\ ? Sunt cu ini]ializare sau f\r\ ?
3. Mecanisme pentru intrarea [i ie[irea datelor: Instruc]iuni de intrare ie[ire (cazul PASCAL-
ului), biblioteci de func]ii pentru intrare/ie[ire (cazul C-ului), sau module cu proceduri de
intrare/ie[ire (cazul Oberon-ului). Alte mecanisme [i structuri algebrice pentru opera]ii de I/O
exist\ ?
4. Mecanisme pentru schimbarea valorilor variabilelor: instruc]iunea de atribuire. Exist\ alte
mecanisme (ex: pattern matching).
5. Un mod de a descrie noile valori: sintaxa expresiilor, operatori, operanzi.
Se precizeaz\ aici operatorii asocia]i diverselor tipuri de date [i prioritatea operatorilor
(ordinea opera]iilor !). Expresii aritmetice [i logice. Alte mul]imi cu opera]iile lor. Exist\ nota]ii
pentru mai multe valori deodat\ (ex: expresii regulate folosite `n limbaje de scripting sau `n
TCL/TK [amd)
6. Decizia este modul `n care se ramific\ fluxul execu]iei programului. Instruc]iunea IF [i
altele similare ei (CASE). Exist\ un mod de a scrie expresii condi]ionale ? (`n C exist\ un
operator “semn de `ntrebare - dou\ puncte” ? Expresia (a>b) ? 1 : 2 este `n C egal\ cu
unu dac\ este mai mare ca b altfel este egal\ cu doi.)
7. Prelucrarea seturilor de date de lungime aprioric necunoscut\ necesit\ reluarea execu]iei
unui program. Programele care execut\ instruc]iuni `n secven]\ nu pot face a[a ceva.
(Demonstra]i! ) Exist\ `n orice limbaj imperativ instruc]iuni de ciclare cu test ini]ial sau/[i cu
test final. (~n Pascal: WHILE DO. REPEAT UNTIL ) Este suficient ca `n limbaj s\ existe doar
una, cealat\ poate fi simulat\. (Ar\ta]i cum!) Exist\ tehnici de prelucrare a datelor structurate
imbricat (cu structuri [i substructuri conforme unei gramatici )?
8. Pentru prelucrarea seturilor de date de lungime cunoscut\ exist\ structura repetitiv\ cu
num\r cunoscut de opera]ii. ~n multe limbaje se nume[te FOR.
9. Secven]a de instruc]iuni. Afla]i cum se scrie aceasta: `n PASCAL: BEGIN ...; ... END ; `n

Programarea calculatoarelor [i limbaje de programare 55 Dan Popa, 2007


C {...;...} , `n Oberon ...; ... f\r\ acolade. ~n Oberon felul cum sunt definite alte structuri
reduce num\rul de perechi BEGIN ...END, fa]\ de Pascal. Se pot grupa mai multe expresii
`n una singur\ ? (`n C este posibil separ=ndu-le cu virgul\)
10. ~ncapsularea permite ca o por]iune de program s\ poarte un nume [i s\ fie apelat\
folosind acest nume. ~n momentul apelului, pentru nivelul care face apelul (un nivel client)
nu conteaz\ cum face ac]iunea programul `ncapsulat, ci doar ce face. Limbajele ofer\ dou\
concepte: Func]ii - similare cu cele din matematic\, utilizabile [i `n scrierea de expresii [i
Proceduri - un fel de func]ii care nu returneaz\ nimic [i nu pot fi apelate din expresii.
Limbajul Pascal face distinc]ia dintre ele. ~n C , C^^ [i limbajele derivate toate sunt numite
func]ii iar `n Oberon – proceduri.
~n limbajele orientate obiect cum este C++ no]iunea de `ncapsulare denume[te regula ca
un obiect s\-[i prelucreze doar el propriile date (nu se d\ voie unei alte entit\]i s\-i afecteze
datele). ~n aceste limbaje func]iile sau procedurile apar]in=nd unui obiect (dintr-o mul]ime
numit\ clas\) se numesc metode. Ele chiar descriu metodele dup\ care obiectul r\spunde la
ni[te cereri.
11. Cum construim programme, func]ii sau metode complexe din instruc]iuni ? Programarea
structurat\, construirea de structuri mari `n care componentele sunt structuri mai mici [amd
p`n\ la instruc]iuni [i expresii este posibil\ ? Programarea structurat\.
12. Structurarea datelor. Afla]i cum se pot crea tipuri noi de date [i tipuri de date structurate,
vectori, matrice, (sunt colec]ii de date de acela]i tip) obiecte, record-uri (con]in date de tipuri
diferite), apoi pointeri, mul]imi, fi[iere. R\spunde]i la `ntreb\rile despre existen]a `n limbaj a
diverselor tipuri de date compuse pe baza altora: Exist\ tablouri ? Exist\ `nregistr\ri? Exist\
obiecte ? Exist\ date procedurale ? Exist\ pointeri ? Exist\ variabile dinamice? Fiecare
limbaj ofer\ majoritatea acestor posibilit\]i dar sintaxa poate fi diferit\. ~n FORTRAN de
exemplu nu se folosea paranteza p\trat\ pentru vectori [i matrici, a[a cum se folose[te `n
limbajele moderne.
13. Folosirea fi[ierelor pentru citirea sau scrierea datelor. (Foarte important pentru aplica]iile
concrete!) Folosirea bibliotecilor. Crearea de biblioteci [i module. Folosirea limbajului de
asamblare `n limbajele de programare de nivel `nalt (nu face obiectul acestui material).
Includerea modulelor scrise `n alte limbaje. Interfa]a cu sistemul de operare, accesul la
func]ii API.

Programarea calculatoarelor [i limbaje de programare 56 Dan Popa, 2007


Pute]i ad\uga pe lista de no]iuni [i alte elemente, moderne, specifice noilor limbaje de
programare.

14. Clase, obiecte, ierarhii de clase, mo[tenire [i polimorfism . No]iunea de instan]\ a unei
clase.
15. Felul de tipizare al limbajului, este un limbaj cu tipizare strict\ sau nu ? Este un limbaj cu
tipuri polimorfice sau nu ? Exist\ mecanisme de genul «template-urilor» din C^^? alte
metode de a prelucra unitar date de tipuri diferite exist\ ?
16. Moduri speciale de a face opera]ii cu obiecte. Exist\ posibilit\]i de redefinire a
operatorilor astfel `nc=t ace[tia s\ opereze cu obiecte ? Exist\ conversii implicite de la
obiecte la tipuri simple ? (C++ ofer\ r\spunsuri afirmative la aceste ultime dou\ `ntreb\ri ).

Programarea calculatoarelor [i limbaje de programare 57 Dan Popa, 2007


4
Cap

Instrumente practice pentru programatori

Cuvinte cheie: editor de text, procesor de text, bloc, compilare, analizor lexical, analiză lexicală,
identificatori, analizor sintactic, analiză sintactică, arbore sintactic, analizor semantic, analiză
semantică, domeniu semantic, arbore operatorial, notaţie poloneză postfixată, stivă, PUSH,
POP, CALL, generare de cod, optimizare de cod, tabela de simboluri, tratarea erorilor, limbaj
de asamblare, cod intermediar, cvadruple (quadruple), interpretor, maşină virtuală, Java,
portabilitate, cod obiect, calculul valorilor constantelor, factorizarea invarianţilor, cod echivalent,
linkeditare, modul obiect, program executabil, .exe, .obj, .sym, debugger, bugg, debugging,
breakpoint, evaluator de expresii, execuţie pas cu pas, Object Inspector

Mediile de programare cu care se lucreaz\ la laborator, fie ele produse al firmei Borland,
(Turbo Pascal, Turbo C, Borland C^^,etc.), fie medii freeware (Free Pascal, Pow –
Programmers Open Workbench, Dev C++) cuprind, cel pu]in urm\toarele componente,
despre care vom discuta `n continuare:
- editorul de text (cu facilit\]i de: operare cu blocuri, c\utare [i `nlocuire de texte, editare `n
ferestre multiple, salv\ri, copieri, [tergeri de blocuri de text)
- compilatorul limbajului
- alte componente

Defini]ie: Compilatorul este programul care traduce din limbajul de nivel `nalt (`n care
programa]i) `n limbaj ma[in\, adic\ `n limbajul procesorului (real sau virtual) sau `n alt limbaj

Programarea calculatoarelor [i limbaje de programare 58 Dan Popa, 2007



de nivel inferior.
Observa]ie: - link-editor–ul, o alt\ component\ a mediului de programare
care este apelat\ atunci c=nd tasta]i CTRL-F9 este teoretic un modul
separat al mediului de programare. Uneori `ns\ (cazul gcc-ului –
Compilatorul GNU) ambele func]ionalit\]i sunt `ncredin]ate aceluia[i program executabil care
`ns\ poate fi pornit cu dou\ op]iuni diferite.

Mai interesant [i mai sofisticat din punct de vedere tehnic, dintre toate acestea trei, este
compilatorul. Cum este el alc\tuit nu se observ\ din func]ionarea sa. A[a c\ propunem s\
«ridic\m capota» care ascunde acest «motor» [i s\ descoperim componentele sale [i modul
cum realizeaz\ traducerea.

Uzual, c=nd se deseneaz\ schema bloc a unui compilator, programului principal nu `i este
reprezentat meniul. Alteori meniul nici nu exist\ compilatorul fiind un simplu program
executabil lansat dintr-o linie de comand\ cu parametri. Atunci c=nd compilatorul este inclus
`ntr-un mediu de programare, interfa]a acestuia preia rolul programului principal (mai exact
al nivelului client). Nu uita]i c\ de obicei compilatorul prime[te diverse op]iuni sub form\ de
linie de comand\ sau, la unele compilatoare, sub forma unor comentarii speciale incluse `n
programul de compilat. Unele medii de programare permit s\ stabili]i dumneavoastr\ cum
arat\ linia de comand\ dat\ pentru pornirea compilatorului (Eclipse, Emacs, Pow )

Analizor Analizor Analizor Generator Optimiz


lexical sintactic semantic de cod ator de
cod

Gestionar de tabele Tratarea Erorilor

~n fig.: Schema unui compilator (programul de compilat intr\ prin st=nga figurii [i rezultatul iese prin dreapta)

~n realitate aceste faze nu sunt succesive ci mai cur=nd subordonate. Se poate desena [i `n

Programarea calculatoarelor [i limbaje de programare 59 Dan Popa, 2007


acest caz o piramid\ a modulelor componente iar ea va avea `n v=rf o component\ mixt\
care face leg\tura `ntre sintax\ [i semantic\: Analizorul-sintactico-semantic. Deoarece la
constructia majorit\]ii compilatoarelor moderne s-a folosit teoria traducerii bazate pe sintax\
componenta principal\ a devenit Analizorul-sintactico-semantic iar celelalte componente
presteaz\ servicii folosite de acesta `n momemtele c=nd el are nevoie. (Poate avea nevoie
s\ citeasc\ de la intrare, s\ genereze un fragment de cod, s\ scrie un mesaj de eroare la ie
[ire [amd.)Ca urmare schema practic\ a unui compilator arat\ mai cur=nd ca `n figur\:

~n fig: Schema practic\ a unui compilator (programul de compilat intr\ prin st=nga figurii [i rezultatul iese prin dreapta
jos) – dup\ P.D.Terry – Compilers and Compilers Generators

Componentele principale ale unui compilator sunt tot:


- analizorul lexical
- analizorul sintactic [i analizorul semantic care `n practic\ formeaz\ `mpreun\ analizorul
sintactico-semantic (ce poate include [i func]ii privitoare la verificarea tipurilor de date)
- generatorul de cod
- optimizatorul de cod (nu este desenat `n a doua figur\ - poate uneori lipsi)
- gestionarul de tabele (nu este desenat `n a doua figur\ - dar nu poate lipsi)
- modulul pentru tratarea erorilor

Ultimele dou\ sunt la nevoie apelate de oricare din celelalte module componente. S\ le lu\m
`n discu]ie r=nd pe r=nd, pe toate:
Analizorul lexical: Prime[te la intrare programul surs\, care, pentru el, este un [ir de litere.

Programarea calculatoarelor [i limbaje de programare 60 Dan Popa, 2007


Produce la ie[ire secven]a atomilor lexicali (cuvinte, numere, operatori [.a.m.d). Depisteaz\
identificatorii defini]i de programator (care vor fi `nscri[i `n tabela de simboluri). Recunoa[te
identificatorii rezerva]i ai limbajului, dac\ limbajul are a[a ceva, iar majoritatea limbajelor
moderne au identificatori (sau cuvinte) rezerva]i(te). Elimin\ spa]iile suplimentare, TAB-urile
[i ENTER-urile din program. Acest modul este realizat folosind tehnici din teoria
automatelor, fiind adesea implementarea unui AFD (automat finit determinist). Nu este `ns\
obligatoriu – exist\ [i alte solu]ii, cum ar fi combinatorii de parsere folosi]i la unele
compilatoare din categoria «scannerless».

Exemplu:
PROGRAM Nume;
VAR x , y : INTEG ER;
BE G I N
EN D.

~ncadra]i `ntr-un p\tr\]el fiecare liter\ din textul de mai sus, pentru a v\ face o idee cum sose
[te textul, simbol cu simbol, la analizorul lexical.
El devine, dup\ analiza lexical\, o secven]\ de identificatori:

PROGRAM IdentificatorNUME PUNCT{IVIRGUL|


VAR IdentificatorX VIRGUL| IdentificatorY DOU|PUNCTE INTEGER
PUNC{IVIRGUL| BEGIN END PUNCT

(Exemplul este pur didactic. Dac\ dori]i v\ pute]i imagina analizorul lexical ca un foarfece
care taie panglica textului limbajului `n buc\]i cuprinz=nd fiecare un cuv=nt [i clasific\ `n
categorii lexicale cuvintele ob]inute astfel. ~n consecin]\, identificatorii introdu[i de
programator sunt separa]i de cuvintele rezervate [i de operatorii scri[i cu mai multe litere,
cum este “mai mare sau egal” .)

Sau a[a: PROGRAM NUME ;

VAR X , Y : INTEGER ;

BEGIN

END .

Programarea calculatoarelor [i limbaje de programare 61 Dan Popa, 2007



~ncadra]i `ntr-un dreptunghi fiecare din cuvintele sau simbolurile de mai
sus. Observa]i diferen]a fa]\ de desenul anterior.
Practic, `n compilatoarele reale, analizorul lexical este implementat ca un
modul server (o procedur\ sau cel mai frecvent o func]ie ) pentru a fi apelat
de analizorul sintactico-semantic. (Revede]i v\ rog ultima schem\ de compilator.)


Analizorul sintactic este clientul analizorului lexical adic\ cel care are
nevoie de aceste cuvinte deoarece regulile gramaticii, pe care
analizorul sintactic le folose[te sunt reguli de succesiune a
cuvintelor, nu a literelor.

La fiecare apel, analizorul lexical cite[te din textul programului literele una c=te una p=n\
determin\ urm\torul atom lexical (adic\ un simbol simplu, unul compus - ca atribuirea - sau
un cuv=nt.) Pe acesta `l returneaz\ analizorului sintactic. La urm\torul apel citirile continu\
de unde s-au terminat citirile precedente. Exist\ [i implement\ri de compilatoare `n care
analizorul lexical este un modul separat.

Dac\ inten]ion\m s\ `n]elegem `n profunzime func]ionarea analizorului lexical vom descoperi


c\ ea poate fi considerat\ a avea loc `n trei etape, ceea ce va duce la proiectarea unui
analizor lexical alc\tuit din trei module mai mici. Primul face «transliterarea» clasific=nd pur
[i simplu caracterele din textul surs\ prin ata[area de fiecare a unei etichete ( %LIT, %CIF,
%BL, %MI, %DP, %EG … am dat exemple pentru liter\, cifr\, blanc, minus, dou\ puncte
[.a.m.d.). Al doilea face «explorarea» care identific\ efectiv atomii lexicali (de exemplu un
[ir de litere [i cifre care `ncepe cu o liter\ va fi un identificator iar un [ir de cifre va fi un
num\r `n timp ce o secven]\ format\ dintr-un %DP [i un %EG va fi simbolul atribuirii :=).
Dup\ explorare rezult\ alt [ir de etichete `ntre care %ID (identificator) , %OP (operator, dar
p\streaz\ [i eticheta anterioar\ de minus sau plus `mpreun\ cu un indicator numit pointer
c\tre cuv=nt, dac\ e cazul). Urmeaz\ faza de «selectare» astfel c\, dup\ o eventual\
c\utare `n dic]ionarul limbajului, ace[ti identificatori sunt clasifica]i. De exemplu, %ID
«while» va deveni exact %WHILE iar ceilal]i identificatori, de exemplu variabilele cap\t\ [i
num\rul r=ndului lor din tabela de simboluri. ~n final nu va conta dac\ dou\ variabile sunt X
[i Y sau A [i B ci doar c\ una a fost prima declarat\ iar cealalt\ a doua.

Programarea calculatoarelor [i limbaje de programare 62 Dan Popa, 2007


 Re]ine]i c\: Analizorul lexical apeleaz\ la gestionarul de tabele care se
ocup\ de tabela de simboluri unde se vor p\stra to]i identificatorii,
ca `ntr-un dic]ionar ([i nu numai ei, ci [i alte informa]ii despre tipul ata[at
acelui identificator, lungimea datei respective etc.). ~n caz de eroare,
analizorul lexical apeleaz\ la modulul de tratare a erorilor,iar acesta anun]\ eroarea [i
`ncearc\ s\ redea controlul analizorului lexical pentru reluarea analizei.

{tia]i c\: Distribu]iile sistemului de operare LINUX con]in [i generatoare de analizoare


lexicale [i sintactice ( Yacc, Bison, Lex, Flex sau similare)? Instal=nd pe computerul
personal o distribu]ie LINUX ob]ine]i un mediu complet de programare bun [i pentru
dezvoltare de compilatoare sau interpretoare. Distribu]iile con]in [i o serie de compilatoare [i
interpretoare gratuite pentru alte limbaje: Basic, Fortran, C, C^^, LISP, Prolog, (unele
distribu]ii), SQL, Assembler dar [i limbaje mai exotice: Perl, Java, TCL. Acesta din urm\
beneficiaz\ [i de un mediu de dezvoltare vizual, VisualTCL, care este extrem de productiv,
fiind [i gratuit pe deasupra. Exist\ [i o versiune de Delphi, oferit\ de firma Borland, dar
numai varianta educa]ional\, limitat\, este gratuit\. Se nume[te Kylix (nu confunda]i cu
Klycs). Se ofer\ [i un translator Pascal – C, numit p2c (cite[te «Pascal to C». Un mediu de
programare se poate ob]ine de exemplu combin=nd EMACS (un editor foarte puternic) sau
XWPE (XWindows Programming Environment) cu un compilator al limbajului dorit. Rezult\
un mediu de programare foarte asem\n\tor cu mediile Borland. Nu este singurul posibil,
pentru LINUX fiind disponibile [i medii de programare comerciale dar combina]ia de mai sus
este o combina]ie popular\ [i gratuit\. Despre alte medii de programare sub Linux vom mai
pomeni `n alt capitol. La ora actual\ Emacs este adesea `nlocuit de mai noul Eclipse.

Concluzii practice: Toate analizoarele lexicale recunosc drept identificator secven]a de


litere [i cifre care `ncepe cu o liter\ (unele limbaje consider\ [i liniu]a de subliniere numit\
«underscore» drept liter\). Toate entit\]ile pe care le ve]i defini (declara) `ntr-un limbaj de
programare (variabile, constante, tipuri, proceduri, func]ii, clase etc) vor primi nume date de
dumneavoastr\ conform acestei reguli. Toate analizoarele lexicale vor elimina automat spa]
iile, TAB-urile [i ENTER-urile `n plus. Un spa]iu, TAB sau ENTER `n plus nu este niciodat\ o
gre[eal\, cu condi]ia s\ nu-l tasta]i `n mijlocul unui cuv=nt, desp\r]ind astfel un atom lexical

Programarea calculatoarelor [i limbaje de programare 63 Dan Popa, 2007


`n dou\. Unele analizoare lexicale nu recunosc dec=t literele alfabetului englezesc `n calitate
de simboluri constituente ale programelor. Intercal=nd `n programe simboluri speciale pute]i
provoca erori de analiz\ lexical\. Dac\ v\ trebuiesc simboluri deosebite pentru afi[are pe
ecran se recomand\ s\ folosi]i func]ii (proceduri func]ionale) care genereaz\ simboluri
speciale, a[a cum este, `n multe limbaje, func]ia CHR(). A[a s-ar putea face rapid un joc
de c\r]i deoarece trefla, caroul, cupa [i pica sunt simboluri din codul ASCII extins.

Analizorul sintactic: Prime[te la intrare [irul atomilor lexicali. Depisteaz\ [i valideaz\


construc]iile sintactice corecte (expresii, instruc]iuni de I/O, structuri ale program\rii
structurate etc) `n conformitate cu gramatica limbajului. Construie[te un arbore sintactic
sau simuleaz\ construirea lui gener=nd nodurile arborelui [i parcurg=ndu-le `n ordinea
determinat\ de pozi]ia lor `n arborele neconstruit efectiv.

Erori de sintaxa cum ar fi cele de mai jos sunt semnalate `n faza analizei sintactice.

Exemplul 1.
((3^5-))) este o expresie cu gre[eli de sintax\

Exemplul 2.

REPEAT
...
BEGIN
...
UNTIL
...
END

Acesta este un program cu erori de imbricare (`ncuib\rire) a structurilor program\rii


structurate. Este o eroare similar\ cu a scrie parantezele rotunde [i p\trate `nchise gre[it
`ntr-o `ntr-o expresie aritmetic\ din matematic\. De asemenea toate erorile de sintax\ ale
instruc]iunilor vor fi depistate `n faza aceasta. Aten]ie, compilatorul depisteaz\ existen]a unei
erori, faptul c\ programul nu respect\ gramatica dar nu poate [ti precis ce trebuia scris
acolo. Mesajele de eroare ale compilatoarelor sunt `n cel mai bun caz exacte (exemplu
«missing ; » ) [i `n cel mai r\u caz produc\toare de confuzii, deoarece indic\ destul de exact
LOCUL erorii dar nu v\ l\muresc CE trebuia scris acolo. Unele erori sunt semnalate adesea
`n alt loc, a[a cum este lipsa unui «;» `n Pascal, care e semnalat\ un r=nd mai jos dec=t ne-

Programarea calculatoarelor [i limbaje de programare 64 Dan Popa, 2007


am a[tepta, (la `nceputul r=ndului urm\tor). De asemenea, `n limbaje ca Pascal-ul, lipsa
unui END putea fi semnalat\ abia mult mai departe, c=nd se constat\ c\ toate END-urile din
program n-au fost de ajuns pentru a `nchide BEGIN-urile existente.

Exemplu: ~ncercarea de a scrie o atribuire V = 3+5 `n PASCAL va duce la depistarea


erorii “ := lips\” deoarece analizorul sintactic are implementat\ o regul\ care valideaz\
ca atribuire `n[iruirea <variabil\> <dou\ puncte egal> <expresie> . Elementele marcate cu
< > sunt , `n nota]ia folosit\ curent, structuri sintactice (sau, la limit\, atomi lexicali). O
nota]ie a sintaxei limbajelor de programare, bazat\ pe aceast\ idee este nota]ia BNF (vine
de la numele lui John W. Backus), `n care regula de mai sus s-ar scrie:

<atribuire> :: = <variabila> : = <expresie>

Semnul ::= `l pute]i citi prin «se scrie».


Vom vedea `ntr-o discu]ie viitoare c\ `n st=nga atribuirii poate fi ceva mai complex ca o
simpl\ variabil\, poate fi o expresie care indic\ spre o loca]ie de memorie.

{tia]i c\ `n Pascal exist\ structuri ambigue din punct de vedere al analizei sintactice ?
Exemplu:
if <condi]ie1> then if < condi]ie2> then <instruc]iune1>
else <instruc]iune2>

~ntrebare: Cui apar]ine else <instruc]iune2>, primului sau celui de-al doilea if ? ~n Pascal
dezambiguizarea se face conform regulii:
“else apar]ine ultimului if .. then care nu are else.

~n Oberon if are forma IF ... THEN ... ELSE ... END , respectiv forma
IF ... THEN ... END ceea ce duce la distinc]ia `ntre:
IF ... THEN IF ... THEN ... END ... ELSE ... END [I
IF ... THEN IF ... THEN ... ELSE ... END ... END

Problema nu se mai pune `n Oberon. ~n primul caz ELSE apar]ine primului IF [i `n cel de-al
doilea caz urm\torului.

Programarea calculatoarelor [i limbaje de programare 65 Dan Popa, 2007


Practic, `n Pascal, folosirea secven]elor BEGIN . . . END rezolv\ asem\n\tor problema. ~n
limbajele ca C, C^^, Java, Perl se folosesc `n acela[i scop acoladele. Acolada deschis\ e
un fel de BEGIN iar cea `nchis\ un fel de END. Cu ajutorul lor un grup de instruc]iuni
plasate `n secven]\ [i astfel delimitat se va comporta ca o singur\ instruc]iune, put=nd fi
scris oriunde exist\ loc pentru exact o instruc]iune.

~n urma analizei sintactice rezult\ un arbore sintactic. Nodurile sale corespund cu regulile
din gramatic\. De exemplu instruc]iunea
WHILE (1 < P ) & ( P < 9) DO P:=P+Q;
produce un arbore cu alura celui din imagine (`n realitate va fi ceva mai `mpodobit cu
diverse valori auxiliare numite atribute).

~n fig: Arborele sintactic al instruc]iunii WHILE (1 < P ) & ( P < 9) DO P:=P+Q; – dup\ P.D.Terry – Compilers
and Compilers Generators

Practic ce `nseamn\ s\ cunoa[te]i sintaxa ? : Va trebui s\ cunoa[te]i diversele `n[iruiri de


atomi lexicali sau de atomi lexicali [i alte construc]ii sintactice simple, care formeaz\ o
construc]ie sintactic\ mai complex\. Va trebui s\ pute]i r\spunde la `ntreb\ri de forma: “~ntr-
un program Pascal / Oberon corect sintactic, ce urmeaz\ dup\ un if ? Dar dup\ un then ?
Dar dup\ un «dou\ puncte egal» :# ?
Observa]i c\ regula `nv\]at\ la liceu: “ ~nainte de else nu se pune “; ” este o regul\ care ]ine
de domeniul sintactic. Mai pute]i enumera altele ?

Analizorul semantic: Pentru a da sens sintaxei abstracte reprezentate de arborele


sintactic, el va fi transformat `n altceva. Aceste “altceva”-uri posibile sunt elementele unei
mul]imi numite domeniu semantic . Acesta ar putea fi tot o mul]ime de arbori dar poate fi [i o
mul]ime de entit\]i av=nd alt\ natur\. Elementele domeniului semantic au leg\tur\ cu modul

Programarea calculatoarelor [i limbaje de programare 66 Dan Popa, 2007


practic de calcul. ~n teorie se spune c\ o semantic\ face leg\tura `ntre sintax\ [i modelul
de calcul, model care este `n esen]\ o structur\ algebric\, cu mai multe opera]ii [i cu un
mecanism de `nl\n]uire a calculelor.
De exemplu, domeniul semantic poate fi format din arbori operatoriali, av=nd opera]iile
(operatorii) `n noduri [i argumentele `n subarbori. Un alt exemplu: domeniul semantic poate
fi format din expresii scrise `n form\ polonez\ postfixat\, cu operatorii dup\ operanzi.

Exerci]ii:


1) Desena]i arborii operatoriali (aten]ie, operatorii sunt `n noduri) pentru:

IF ... THEN IF ... THEN ... ELSE ... END ... END

[i pentru suma lui a [i b cu c: (a^b )^ c

Indica]ie: Argumentele lui if…then…else sunt expresia boolean\ [i cele dou\ instru]iuni.
Dac\ vi se pare greu `ncepe]i cu a doua expresie, cea a sumei celor trei valori a,b,c.


2) Transcrie]i `n form\ polonez\ postfixat\ (adic\ operatorul este plasat
dup\ operanzi) expresia (a^b)^c . Verifica]i felul cum cum aceast\
transcriere, a b ^ c ^ permite calculul rezultatului cu ajutorul unei stive de
valori `n care valorile variabilelor se depun iar fiecare operator scoate
argumentele necesare, face calculul [i pune rezultatul la loc `n stiv\.

~ntrebare: Cum se poate calcula valoarea expresiei aritmetice c=nd se cunoa[te arborele ei
operatorial ? Indica]ie: Se poate defini o func]ie recursiv\ de evaluare a unui arbore, pe
ideea c\ arborele este format din operator [i ... al]i arbori care sunt operanzii.

~n urma analizei semantice rezult\ o valoare din domeniul semantic ( e vorba de o informa]ie
complex\, structurat\). Aceast\ informa]ie permite mai departe generarea de cod.

Generatorul de cod: Pe baza rezultatului analizei semantice el genereaz\ cod ma[in\ sau
program `n limbaj de asamblare, bytecode (cazul limbajului Java) sau alt fel de cod
intermediar. Practic aici se produce codul care este rezultatul compil\rii.

Programarea calculatoarelor [i limbaje de programare 67 Dan Popa, 2007


~ntrebare: Cum se execut\ programul `n limbaj de asamblare rezultat din exemplul dat, cel
cu suma (a^b)^c?

R\spuns posibil:

PUSH A ; pune valoarea lui A `n stiv\


PUSH B ; pune valoarea lui B `n stiv\
CALL Plus ; subrutina Plus face adunarea ultimelor valori din stiv\
PUSH C ; se pune valoare lui C `n stiv\
CALL Plus ; se apeleaz\ iar Plus pentru a calcula rezultatul final

(Exemplul este un exemplu didactic. Deci nu m\ `ntreba]i ce limbaj de asamblare e acesta.


Cunosc\torii unui limbaj de asamblare vor recunoa[te totu[i instruc]iunile: PUSH care pune
o valoare `n stiv\ [i CALL care apeleaz\ o subrutin\ - adic\ o procedur\ - scris\ `n limbaj de
asamblare.)
Exerci]iu pentru “asambli[ti”: Scrie]i procedura Plus `n Assembler. Dar pe Minus cum l-a]i
scrie ? (Not\: pentru tipurile uzuale opera]iile + [i – le face procesorul.)

S-a observat c\ asemenea instruc]iuni au maxim patru operanzi. Se numesc cvadruple.


Exist\ o teorie a gener\rii codului sub form\ de cvadruple, cvadruplele fiind [i ele o form\ de
cod generat.

Observa]i c\ teoria nu exclude posibilitatea ca `ns\[i mul]imea secven]elor de cod ma[in\ s\


fie chiar domeniul semantic. ~n acest caz analizorul sintactico-semantic ar produce direct
codul obiect. ~n general `ns\ acest proces de generare de cod nu este l\sat `n seama
analizei sintactico-semantice fiind f\cut de alt modul.
Un exemplu din practic\: Generarea de cod intermediar (destinat unui calculator ipotetic
numit ma[in\ virtual\ Java) este folosit\ pentru a asigura portabilitatea programelor scrise `n
Java. Este suficient s\ scrie]i un program capabil s\ simuleze execu]ia instruc]iunilor din
codul generat, pe oricare tip de calculator, astfel ca, folosindu-l, s\ pute]i rula programele
Java (de fapt codul `n care au fost traduse) pe acel calculator. Este suficient s\ scrie]i un
interpretor pentru codul respectiv (e o implementare a specifica]iilor ma[inii virtuale Java) [i

Programarea calculatoarelor [i limbaje de programare 68 Dan Popa, 2007


ve]i putea rula cu ajutorul lui programele scrise `n Java, pe computerul dorit, indiferent de
arhitectura acestuia. Astfel este asigurat\ portabilitatea programelor Java.

Optimizatorul de cod: Prelucreaz\ codul rezultat `n urma gener\rii pentru a ob]ine un cod
echivalent, mai compact sau/[i mai rapid. Optimizatorul se poate ocupa de:
-calculul expresiilor constante
-`nlocuirea unor grupuri de instruc]iuni din cod cu c=te-o instruc]iune echivalent\ grupului
respectiv
- factorizarea invarian]ilor din cicluri [i alte optimiz\ri

Exemplul 1:
X:=3^5^7
se poate compila gener=nd cod ca [i cum a]i fi programat X:#15

Exemplul 2:
for i : = 1 to 100 do begin
z:=x+12;(*calcul ce nu depinde de i *)
j:=j+i;
end;
Optimizatorul de cod depisteaz\ c\ atribuirea z:=x+12 se execut\ inutil de 100 de ori
(deoarece valoarea lui x nu se modific\ `n interiorul buclei) [i va scoate `nafara acesteia
atribuirea cu pricina, gener=nd un cod ca [i cum a]i fi scris programul:
z:=x+12;
for i : = 1 to 100 do begin
j:=j+i;
end;
Observa]ie: Codul generat `n urma optimiz\rii nu este totdeauna func]ional echivalent cu cel
scris de dumneavoastr\. De exemplu difer\ timpul `n care se execut\ el, ceea ce uneori
poate fi dezastruos. (Dac\ programatorul folose[te bucla ca pe o temporizare, codul
optimizat va face o pauz\ mai scurt\. A[a ceva este inadmisibil pentru anumite sisteme
informatice, de exemplu cele destinate a lucra `n tip real.)
Recomandare: Scrie]i dumneavoastr\ codul surs\ (programul surs\) astfel `nc=t s\ nu fie
nevoie de asemenea optimiz\ri. Prefera]i s\ face]i dumneavoastr\ optimiz\rile scriind din
start c=t mai bine, ba chiar optimal, programul ! ~n general un compilator m\re[te prin
optimizare viteza codului de 2-4 ori pe c=nd un programator care scrie cod corect [i folose
[te un algoritm mai bun poate ob]ine o vitez\ de peste 10 ori mai mare.

Programarea calculatoarelor [i limbaje de programare 69 Dan Popa, 2007


~n urma compil\rii rezult\ module obiect, cel mai adesea sub forma fi[ierelor cu
extensia .obj (sau uneori .o) .

Nota]i c\ modul de realizare a analizoarelor lexical, sintactic, semantic


se studiaz\ `n detaliu `n cadrul cursurilor de “Teoria compilatoarelor”. Semanticile, func]iile
care transform\ descrierile sintactice `n succesiuni de calcule sau `n alte elemenete
constituie obiectul unui curs separat (“Semantica limbajelor de programare“), domeniu al
informaticii care prezint\ diverse metode de a trece de la o descriere sintactic\ la modelul
de calcul.
Totu[i programatorii, f\r\ a fi autori de compilatoare, cu ocazia realiz\rii diverselor
proiecte sunt adeseori pu[i `n situa]ia de a realiza p\r]i dintr-un compilator - chiar f\r\
s\ [tie aceasta. (De exemplu un analizor lexical pentru a citi datele, un analizor sintactic
pentru a verifica scrierea datelor, un evaluator de expresii pentru a evalua expresii introduse
dinamic de utilizator, un mic translator de structuri de date etc). De fapt ne putem imagina
orice problem\ rezolvat\ de un compilator, `n sensul c\ datele ei se vor scrie conven]ional
`ntr-un limbaj care respect\ reguli de sintax\ iar rezultatul prelucr\rii lor este de fapt
semantica acelui text (s\-i zicem «program») care a fost dat spre rezolvare (s\ zicem «spre
execu]ie»). Cel mai dificil este s\ pute]i scrie func]ia semantic\, cea care leag\ datele de
rezultat. A o g\si este la modul general o problem\ nedecidabil\ algoritmic, deci numai
creativitatea uman\ o poate rezolva [i numai pentru anumite seturi de cazuri.

Alte componente ale unui mediu de programare:

- link-editor (este cel care combin\ modulele de cod obiect rezultate din urma compil\rii
divereselor fi[iere surs\ ale unei aplica]ii `ntr-un singur program executabil.) Este cel care
produce fi[ierele .exe .
Practic: Dac\ `n Oberon scrie]i gre[it numele procedurii ProgMain dar consecvent, eroarea
nu va fi sesizat\ la compilare ci doar la link-editare, atunci c=nd link-editorul caut\ `n diferite
module obiect punctele de intrare ale procedurilor. (Tabelele de simboluri ale diverselor
module se folosesc `n acest scop.)
- debugger (depanator)
Denumirea vine de la “bugg” care are `n jargonul informatic sensul de “scam\”, “defect”.
Depanarea programelor se nume[te [i “debugging”. Istoric vorbind, “debugging” cu sensul

Programarea calculatoarelor [i limbaje de programare 70 Dan Popa, 2007


de depanare vine de la un defect – devenit anecdot\ - al unuia dintre primele calculatoare
cu tuburi electronice [i relee. ~ntruc=t `ntr-o zi computerul n-a func]ionat, depanatorul a venit
[i a g\sit cauza, un g=ndac (`n englez\ “bug”) r\m\sese `n]epenit `ntr-un releu. Depanatorul
a purces deci la “debugging” sco]=nd g=ndacul din releu iar programul a func]ionat. L\s=nd
gluma la o parte, depanatorul sau debuggerul este deci componenta mediului de
programare destinat\ depist\rii erorilor [i urm\ririi pas cu pas a execu]iei programului. El
permite printre altele:
- plasarea de “breakpoint”-uri (puncte de oprire pentru program). Execu]ia se va opri acolo [i
ve]i putea inspecta valorile variabilelor, apoi continua execu]ia p=n\ la urm\torul punct de
oprire.
- inspectarea valorilor variabilelor din program [i a valorilor diverselor expresii scrise cu
aceste variabile
- execu]ia programului instruc]iune cu instruc]iune (pas cu pas - step by step)
- execu]ia pas cu pas trat=nd apelurile de proceduri ca pe ni[te instruc]iuni unitare

Mediile de programare vizuale, destinate limbajelor bazate pe paradigma OOP (programare


orientata obiect) de]in [i alte instrumente printre care:
- un Object Inspector destinat examin\rii [i modific\rii datelor [i metodelor care formeaz\
diversele obiecte
- instrumente pentru a ordona, organiza ierarhia de clase disponibil\ cu ocazia realiz\rii unei
aplica]ii.
- diverse instrumente pentru a oferi ajutor `n context [i diver[i «vr\jitori» (eng. Wizards) care
ofer\ sugestii, sfaturi sau indic\ ni[te continu\ri posibile ale programului `n lucru.

{tia]i c\: Exist\ limbaje a c\ror distan]\ fa]\ de limbajul ma[in\ este foarte mare iar
traducerea se face via o serie de mai multe limbaje intermediare ?

Programarea calculatoarelor [i limbaje de programare 71 Dan Popa, 2007


5
Cap

Instrumente teoretice pentru programatori

Cuvinte cheie: sintaxă, tehnici de programare, problema opririi, decidabilitate algoritmică,


complexitate, ordin de complexitate, măsuri ale complexităţii, limbaj de programare, structura
unui program.

Se consider\ `n general, dup\ absolvirea liceului, c\ a cunoa[te unul, dou\ sau trei
limbaje de programare te face s\ fii programator. Din nefericire aceast\ opinie este
FALS|, falsitatea ei fiind recunoscut\ de patronii care au angajat ca programatori unii
studen]i. Limbajul de programare r\m=ne pe lista instrumentelor teoretice necesare dar
mai trebuie [i altceva. S\ facem deci lista (lista nu este exhaustiv\.):

Ca programator este indicat s\ cunoa[te]i: - Limbajul (limbajele) de programare (v\ spune


CU CE cuvinte s\ scrie]i programe, `n ce ordine le ve]i folosi)
- Ingineria program\rii (v\ spune DESPRE CE ve]i scrie `n fiecare modul, fi[ier, ce
proceduri / servicii vor fi implementate, cum e organizat\ aplica]ia)
- Tehnici de programare (v\ spun CUM se vor implementa procedurile, serviciile de pe
diverse nivele din aplica]ie)
- Teoria calculabilit\]ii (ofer\ metode matematice pentru a clasifica problemele d.p.d.v. al
gradului de complexitate intrinsec\ [i metode de studiu al eficien]ei procedurilor
implementate).

Programarea calculatoarelor [i limbaje de programare 72 Dan Popa, 2007


Limbajul (limbajele) de programare v\ `nva]\ cuvintele din care se scriu programele
(vocabularul limbajului), regulile de `mbinare ale lor [i de “punctua]ie” (adic\
sintaxa), [i ce va face calculatorul c=nd va executa instruc]iunea respectiv\ sau
programul respectiv (semantica : face leg\tura dintre sintax\ [i modelul de calcul).
Mai rar, odat\ cu limbajul se ofer\ [i elemente de “pragmatic\” (cuno[tin]e
desprefelul adecvat, recomandat de a programa `ntr-un limbaj, gre[eli frecvente,
informa]ii despre optimizarea programelor [i alte reguli). Pragmatica nu este, din
nefericire, de cele mai multe ori obiect de curs, cel pu]in ca obiect separat. Vom
reveni pe larg asupra limbajelor de programare, folosind ca exemplu limbajul Oberon.

Ingineria program\rii v\ ajut\, atunci c=nd proiecta]i o aplica]ie mare, s\ stabili]i din ce
componente este ea realizat\, cum se vor reflecta aceste componente `n fi[ierele
(modulele) proiectului. Pentru am\nunte revede]i paragrafele anterioare despre ingineria
program\rii structurate. Paradigma OOP beneficiaz\ [i ea de reguli de inginerie a
program\rii.

Tehnici de programare : V\ conduc spre a afla cum se vor implementa diversele servicii
ale aplica]iei sub form\ de proceduri. ~naintea acestei etape nu [ti]i de obicei CUM se
rezolv\ problema pe care trebuie s-o rezolve o procedur\, ci doar CE are ea de rezolvat.
Teoria const\ `ntr-o list\ de metode uzuale pentru abordarea problemelor noi, atunci c=nd
algoritmii lor de rezolvare nu sunt din start eviden]i. Exemplu: O tehnic\ de programare
comun\ este “Divide et impera” : O problem\ dat\ se rezolv\ imediat dac\ e foarte
simpl\ sau, dac\ este complex\ se `mparte `n dou\ (ori mai multe) probleme analoage dar
mai simple (d.p.d.v. al datelor). Pentru a le rezolva se apeleaz\ acela[i algoritm, el `mp\r]
ind iar problema rezultat\ `n probleme mai simple, [amd p=n\ le poate rezolva pe toate.
Trebuie s\ existe `n acest caz [i o modalitate de a construi solu]ia problemei mari din solu]
iile problemelor mici. Ilustrare: Algoritmul de sortare rapid\ Quicksort, se bazeaz\ pe
aceast\ idee, el caut\ (sau a[eaz\ prin c=teva permut\ri ) la mijlocul [irului un element
care este mai mare ca primele [i mai mic ca ultimele. Cele dou\ p\r]i ale [irului sunt
sortate mai departe tot cu Quicksort (recursiv). Cele mai simple [iruri sunt cele de un
element sau dou\, care nu se mai `mpart mai departe.

Programarea calculatoarelor [i limbaje de programare 73 Dan Popa, 2007


Teoria calculabilit\]ii (ofer\ metode matematice pentru a clasifica problemele d.p.d.v. al
gradului de complexitate intrinsec\). Ea v\ permite s\ demonstra]i inclusiv c\ unele
probleme sunt nedecidabile algoritmic, adic\ NU POATE exista un algoritm general care
s\ le rezolve orice instan]\ adic\ orice caz particular.

Exemplu: Problema opririi: S\ se scrie un algoritm A care primind la intrare un alt


algoritm P [i setul de date ini]iale D se opre[te dup\ un timp finit [i ofer\ unul din
r\spunsurile:
DA: dac\ algoritmul P se opre[te din prelucrarea datelor D
NU: dac\ algoritmul P nu se opre[te din prelucrarea datelor D
Demonstra]ie: Presupun=nd existen]a lui A se construieste alt algoritm A’ conform
schemei logice (din figura urm\toare). Ideea este c\ dac\ A a stabilit c\ “DA” (adic\ ceea
ce i s-a dat se opre[te) atunci A’ cicleaz\ iar dac\ A a stabilit c\ “NU” (deci ce i s-a dat nu
se opre[te) atunci A’ se opre[te. Algoritmul A’ descris de ideea de mai sus `l putem
reprezenta ca `n schema logic\ de mai jos.

START

Algoritmul A
(decide dac\ programul dat se opre[te )

Algoritmul A Da # un nou algoritm, notat A’


trage concluzia
«Da» ?

Nu
STOP

~n fig.: Schema logic\ a algoritmului A’,nou creat `n ipoteza eisten]ei lui A. Dreptunghiul exterior nu face parte din schem\.
Vom nota noul algoritm cu A’, [i vom vedea c\ existen]a lui produce o contradic]ie.

Observa]ie: «A» este un program care determina comportarea altor programe. El

Programarea calculatoarelor [i limbaje de programare 74 Dan Popa, 2007


prime[te la intrare un program (sau un algoritm transcris `ntr-un limbaj, `n form\ de
program). Evident c\ [i A’ care include pe A va cere acelea[i fel de informa]ii ca date de
intrare, deci va putea analiza programe.

Demonstra]ia inexisten]ei lui A se face prin reducere la absurd. Presupunem c\ A exist\.


Atunci exist\ [i A’ construit ca `n schem\ dar existen]a lui A‘ creeaz\ absurdul. Este
suficient s\ `i d\m lui A’, ca program de analizat, chiar pe A’. Se va opri acest algoritm A‘
odat\ pornit [i av=ndu-se pe el `nsu[i ca dat\ de intrare?

Analiz\m variantele de func]ionare ale lui A’:


~n situa]ia c=nd s-ar opri A’, componenta A spune “DA” [i rezult\ c\ A’ va cicla, nu se va
opri (vede]i schema) ceea ce e absurd. Noi am pornit de la ipoteza c\ s-ar opri. ~n situa]ia
c=nd nu s-ar opri A’, A stabile[te c\ “NU” [i din schema logic\ a lui A’ rezult\ c\ se opre[te
A’, contrar ipotezei. Iar absurd. S-ar trage concluzia c\ nu se poate nici ca A ‘ s\ se
opreasc\ nici s\ cicleze, ceea ce este evident absurd. Dubla contradic]ie provine din
presupunerea ini]ial\ c\ un algoritm care poate stabili ce face altul (dac\ se opre[te sau
nu) ar putea exista. Aceast\ presupunere ini]ial\ se dovede[te a fi fost fals\. ~n concluzie,
problema opririi e nedecidabil\ algoritmic. ~n general, despre un program nu se poate
stabili `n mod mecanic ce face, nici m\car simplul fapt dac\ se opre[te sau nu. E necesar\
o inteligen]\ uman\ pentru aceasta.
Practic: Nici a determina dac\ un program e virus nu e decidabil. Industria antiviru[ilor are
deci c=mp larg de ac]iune `n viitor c\ci teoria permite s\ apar\ mereu viru[i noi. Nu orice tip
de problem\ e decidabil\ algoritmic deci nu v\ pute]i angaja s\ rezolva]i orice problem\ cu
calculatorul. Problema scrierii automate a oric\rui program e tot nedecidabil\ (ceea ce
face, nu uita]i, ca munca programatorului s\ fie o meserie dificil\, creativ\.) Nu putem
inventa un program care s\ scrie programele `n locul nostru. (Dar pentru anumite categorii
de programe foarte simple se poate, motiv pentru care s-au scris pentru mediile de
programare profesioniste fel de fel de generatoare de programe. De exemplu `n mediul de
programare FoxPro [i `n Visual Fox Pro exist\: generator de ecrane, generator de
meniuri, generator de rapoarte, apoi generator de etichete, generator de interog\ri SQL–
numite `n jargon «query-uri» ). Toate genereaz\ de fapt mici programe pentru rezolvarea
unor clase foarte simple de probleme.

Programarea calculatoarelor [i limbaje de programare 75 Dan Popa, 2007


Cunoa[terea dificult\]ii intrinseci a unei probleme e util\ `n criptografie. Un cifru bazat pe o
problem\ dificil rezolvabil\ (ca problem\) [i f\r\ alte particularit\]i care s\ simplifice
decodarea va fi greu de descifrat indiferent de metod\.

Limbajele de programare
Abordarea practic\ a unui limbaj nou poate `ncepe cu sintaxa celui mai simplu program
`n acel limbaj. El va fi minimal sub raportul faptului c\ eliminarea de cuvinte din el `l face s\
fie un program incomplet. Se pot da mai multe exemple precum [i programe pu]in mai
complicate, ilustr=nd introducerea unor noi instruc]iuni / declara]ii / concepte.

~n Pascal cel mai simplu program arat\ a[a sau a[a:


Program Identificator;
begin begin
end. End.
Unde identificatorul poate fi orice `n[iruire de litere [i cifre care `ncepe cu o liter\.~n C cel
mai simplu program arat\ a[a sau a[a:
main() #include <stdio.h>
{ void main (void)
{
} }
~n Oberon: (modulul principal al unui proiect) este cel mai simplu program.
MODULE Identificator1 ;

PROCEDURE ProgMain*;
BEGIN
END ProgMain;

END Identificator1.

Unde Identificator1 trebuie s\ coincid\ cu numele fi[ierului surs\ .Forma general\ a unui
modul este `ns\ alta:

MODULE Identificator1 ; (* antet*)


IMPORT …. (* declar\ alte module importate*)
(* Declara]ii globale unui modul:*)
CONST …. (* declara]ii de constante *)
TYPE …. (* declara]ii de tipuri de date [i clase*)
VAR … (* declara]ii de variabile *)

Programarea calculatoarelor [i limbaje de programare 76 Dan Popa, 2007


PROCEDURE Identificator2*; (* declara]ii de proceduri *)
CONST … (* declara]ii de variabile locale *)
TYPE … (* alte declara]ii locale procedurii *)
VAR….
……….. (* inclusiv procedur\ `n procedur\ *)
BEGIN
Instruc]iunile procedurii
END Identificator2;

PROCEDURE Identificatorn ( List\ de Parametri );


.... (* acum [ti]i ce poate urma dup\ antet*)
…. (* … [i `nainte de BEGIN-ul procedurii*)
BEGIN
END Identificatorn;

BEGIN
Instruc]iuni de in]ializare (* care lipsesc la multe module *)
END Identificator1. (* Se termin\ cu punct.*)

Un modul poate con]ine mai multe proceduri (`n C vor fi func]ii), fiecare procedur\ cu proprii
s\i parametri, (se vor scrie `n parantez\) cu propriile variabile locale (se declar\ dup\ VAR),
cu propriile instruc]iuni: Instruc]iunile se scriu `ntre BEGIN-ul [i END-ul fiec\rei proceduri.
Unitatea component\ a modulului e procedura. Modulul poate avea propriile lui constante
(ar\ta]i unde!), tipuri noi definite [i variabile declarate dup\ VAR -ul de la `nceput, eventual
propria lui list\ de instruc]iuni de ini]ializare, `ntre BEGIN-ul [i END-ul de la sf=r[it.
Ca [i modulele, procedurile pot avea declarate, pentru uzul lor local, constante (`n Oberon
se scriu `ntr-o sec]iune care `ncepe cu CONST), tipuri (`ntr-o sec]iune care `ncepe cu
TYPE), variabile (sec]iunea lor `ncepe cu VAR) sau alte proceduri. Acestea din urm\ pot fi
imbricate – adic\ o procedur\ poate cuprinde pe alta [.a.m.d. Doar instruc]iunile procedurii
respective [i eventualele alte proceduri interioare pot folosi ceea ce e declarat local, la
`nceputul ei. Declara]iile de clase de obiecte sunt, `n Oberon, declara]ii de tipuri de date, cu
men]iunea c\ vom vedea mai t=rziu cum se ata[eaz\ acestor tipuri procedurile necesare.
Clasele sunt deci plasate `ntr-o sec]iune care `ncepe cu TYPE.

~ntruc=t serviciile unor module sunt apelate de obicei de alte module iar apelul nu se face
numai o dat\, majoritatea instruc]iunilor sunt plasate `n proceduri, [i NU `n finalul modulelor,
acolo unde este secven]a de ini]ializare. Nu uita]i: acele instruc]iuni finale se execut\ doar o
dat\, la `nc\rcarea modulului.

Programarea calculatoarelor [i limbaje de programare 77 Dan Popa, 2007


Formalizarea unor noţiuni fundamentale.
Despre vocabular, declaraţii şi proceduri
predefinite

Cuvinte cheie: limbaje formale, identificator, operator, string, separator, designator, format
eponenţial, domeniu de vizibilitate, pointer, record, cuvinte rezervate,identificatori predeclaraţi,
export, identificatory read-only * , - ,

De studiul riguros al unui limbaj cu mijloace `mprumutate din matematic\, `n special din
algebr\, se ocup\ teoria limbajelor formale. Ca orice obiect matematic limbajul este definit
pe baza unor nota]ii stricte, care descriu cum arat\ diverse componente ale limbajului:
vocabularul, sintaxa, semantica. Pragmatica nu este complet formalizat\ iar `n domeniul
semanticii mai este `nc\ de lucru. Aceste defini]ii formale sunt at=t de riguroase [i de clare
`nc=t un cunosc\tor ajunge s\ prefere o descriere a sintaxei unui limbaj pe c=teva pagini,
uneori pu]in mai mult de zece, `n locul unui manual voluminos, pe care `l va consulta doar la
nevoie. Teoria limbajelor formale este considerat\ o ramur\ a matematicii aplicate [i
figureaz\, `mpreun\ cu capitole ale ei `n nomenclatorul de domenii matematice editat de
AMS (Amer.Math.Soc. – celebra societate american\ de [tiin]e matematice).
Exemplific\m asemenea nota]ii formale, `ncep\nd cu cele mai simple no]iuni despre un
limbaj. Antrena]i-v\ s\ le sim]i]i sensul de cum le-a]i citit. La urma urmei sunt [i ele un limbaj.

Limbajul Oberon (mai exact Oberon-2) ca [i alte limbaje folosesc no]iunile de identificator,
num\r, string ([ir de caractere), operator [i delimitator, pentru a numi entit\]ile din
vocabularul limbajului. Aceste no]iuni sunt comune majorit\]ii limbajelor moderne de
programare. Uni autori, inclusiv
H. Mössenböck [i N. Wirth,utilizeaz\ pentru toate aceste categorii luate `mpreun\, no]
iunea de “simboli” sau “simboluri”. Cuv=ntul vine din teoria gramaticilor formale, unde
asemenea cuvinte se numesc “simboluri terminale” ale unui limbaj, spre deosebire de
categorii gramaticale ca <instruc]iune>, <expresie>, <term>, <factor> care sunt numite

Programarea calculatoarelor [i limbaje de programare 78 Dan Popa, 2007


“simboluri neterminale”, din cauza nedefinirii lor. Remarca]i c\ simbolurile neterminale nu
sunt de obicei dec=t nume de categorii de construc]ii sintactice.
Regul\: aceste cuvinte, numite «simboli terminali», se scriu f\r\ a cuprinde spa]ii, tab-uri [i
retururi de car (taste ENTER). Sunt totu[i permise spa]ii [i ENTER-uri `n comentarii. De
asemenea, spa]iile dar nu [i retururile de car (ENTER) sunt permise `n string-uri, `ns\, aten]
ie, le modific\ lungindu-le !
Spa]iile sunt `n rest ignorate de compilator, putem pune c=t de multe spa]ii pentru a scrie
programe estetice, dar sunt obligatorii acolo unde altfel dou\ simboluri neterminale (deci
cuvinte) ar forma, lipindu-se, un singur cuv=nt.
Aten]ie: Limbajele moderne tind s\ adopte regula: Literele mari [i cele mici sunt diferite.
Conteaz\ deci dac\ scrie]i cu majuscule sau minuscule. ~n Pascal de exemplu nu conta, `n
C,C^^ Java, Perl [i alte limbaje conteaz\. Avanataj sau dezavantaj orice ar fi, x [i X vor fi
dou\ denumiri diferite `n majoritatea limbajelor moderne. (Pascal-ul considera]i-l o excep]ie.)

Identificatorii se definesc formal ca fiind secven]e de litere [i cifre. Primul caracter dintr-un
identificator e obligatoriu liter\. Liniu]a de subliniere, «_» este considerat\ liter\. Acolada
`nseamn\ c\ ceea ce e cuprins `n ea se poate repeta de oric=te ori. Iar acest ceva este ori o
liter\ ori o cifr\, sensul barei verticale fiind de separare a dou\ alternative posibile. Iat\
defini]ia identificatorilor (nota]ie `n stilul celor din Help-ul Pow).:

identificator = litera { litera | cifra } .

Exemple: x Read Oberon2 NumeCompus _3_Sud_Est

Numerele sunt numere `ntregi cu sau f\r\ semn sau numere reale. Tipul la care apar]in
numerele `ntregi este cel mai mic tip care le cuprinde. Numerele `n baza 16 (Hexazecimale,
formate cu cifrele 0-9, A,B,C,D,E,F ) se termin\ cu litera H. ~n lipsa sufixului H, num\rul se
consider\ zecimal.
Numerele reale con]in `ntotdeauna punct [i este exact unul. Dac\ e vorba de numere reale
`n format exponen]ial (care de asemenea e comun multor limbaje), atunci se termin\ cu E
sau D urmat de puterea lui 10 cu care trebuie `nmul]it num\rul, aceast\ putere fiind un
`ntreg cu semn. 1.75E5 `nseamn\ de fapt 175 000. Oberonul consider\ numerele reale

Programarea calculatoarelor [i limbaje de programare 79 Dan Popa, 2007


scrise `n acest format exponen]ial ca apar]in=nd tipului LONGREAL. Celelalte numere reale,
scrise obi[nuit apar]in tipului REAL. Dup\ cum observa]i, mai jos, parantezele p\trate indic\
acele elemente op]ionale. Ghilimele nu fac parte din nota]ie, rostul lor este s\ citeze anumite
caractere. De exemplu paranteza p\trat\ care va apare `n scrierea vectorilor este transcris\
`ntre ghilimele, ceea ce o deosebe[te de metasimbolurile care indic\ elemente op]ionale.

nr = intreg | real .
intreg = cifra {cifra} | cifra {cifraHexa} "H" .
real = cifra {cifra} "." {cifra} [FactorDeScala].
FactorDeScala = ("E" | "D") ["+" | "-"] digit {digit} .
cifraHexa = cifra | "A" | "B" | "C" | "D" | "E" | "F" .
cifra = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" .

Exemple de numere: 2003 0DH 11.5 4.987E9 0.5653265D-6


Constantele caracter le putem da [i prin codul lor ASCII scris `n hexazecimal, dar, spre a le
deosebi de numerele hexazecimale, constantele se termin\ cu «X». Remarca]i [i faptul c\
`ncep cu o cifr\. De exemplu caracterul «ª», cu codul zecimal 176 va fi notat 0AAX. Este
obligatoriu s\ `nceap\ cu o cifr\, fie ea [i zero deoarece altfel s-ar confunda cu un
identificator.

character = digit {HexDigit}"X".

Stringurile sunt secven]e de caractere cuprinse `ntre ghilimele simple ( ‘ ) sau duble ( " ). ~n
Oberon nu conteaz\ cu ce ghilimele scrie]i stringurile, dac\ folosi]i acela[i fel de ghilimele [i
la `nceput [i la sf=r[it. Un al treilea simbol de acest fel nu este permis `n string, deoarece l-ar
for]a s\ se termine mai devreme. Limbajul Pascal folose[te ghilimelele simple (apostrof) iar
C, C^^, Java folosesc ghilimelele duble pentru a `ncadra string-urile. Verifica]i ce fel de
ghilimele se folosesc `ntr-un limbaj pe care `l `nv\]a]i sau dac\ sunt permise ambele variante
de scriere a stringurilor. Personal am senza]ia c\ ghilimele duble vor fi mai populare `n
viitoarele limbaje. Num\rul de caractere al unui string se nume[te «lungimea stringului».
Stringurile de lungime 1 sunt `n Oberon asimilate constantelor caracter. ~n alte limbaje nu
este a[a, de exemplu `n C sau C^^, unde, al nivelul memoriei un caracter ocup\ un octet de
iar stringul terminat cu cod zero ocup\ un caracter `n plus, deci doi octe]i. Ca urmare, sunt
diferite [i au [i nota]ii diferite.

string = ' " ' {char} ' " ' | " ' " {char} " ' ".

Programarea calculatoarelor [i limbaje de programare 80 Dan Popa, 2007


Exemple: "Oberon-2" "Da’ cine-i acolo ?"

~n categoria operatorilor [i delimitatorilor intr\ anumite caractere speciale [i perechi de


caractere . ~n limbaj se folosesc o serie de cuvinte rezervate, care se scriu `ntotdeauna cu
majuscule [i care nu pot fi folosite ca identificatori utilizator.
+ := ARRAY IMPORT RETURN
- ^ BEGIN IN THEN
* = BY IS TO
/ # CASE LOOP TYPE
~ < CONST MOD UNTIL
& > DIV MODULE VAR
. <= DO NIL WHILE
, >= ELSE OF WITH
; .. ELSIF OR
| : END POINTER
( ) EXIT PROCEDURE
[ ] FOR RECORD
{ } IF REPEAT

Comentariile se scriu `ntre (* [i *) . Pot fi plasate `ntre oricare dou\ simboluri terminale din
limbaj (numere, identificatori, stringuri, operatori, delimitatori). Dac\ sunt totu[i introduse
`ntr-un string (`ncerca]i practic) sunt acceptate ca fiind un text, nu ca un comentariu [i vor
afecta execu]ia programului. Comentariile sunt complet ignorate de compilator, nu afecteaz\
func]ionarea programului. Pot con]ine orice fel de explica]ii `n orice limb\, note de copyright,
semn\tura autorului, etc. ~n Oberon pute]i scrie comentariu `n comentariu sau pute]i
transforma `n comentariu ([i elimina `n acest fel) orice por]iune de program, chiar con]in`nd
alte comentarii.

Declara]ii [i domeniile lor de vizibilitate

~ntr-un limbaj de programare modern, orice identificator, al indiferent c\rei entit\]i trebuie mai
`nt=i declarat apoi folosit. Fac excep]ie identificatorii predeclara]i, de exemplu numele
anumitor proceduri incluse `n limbaj (ex: Write di Pascal). Cu ocazia declar\rii sunt
exprimate anumite propriet\]i ale entit\]ii nou introduse: valoarea [i implicit tipul pentru
constante, tipul pentru variabile, numele [i tipul componentelor pentru o `ntregistrare
(RECORD) sau un obiect, tipul elementelor unui vector, structura unui tip de date compus
etc.

Programarea calculatoarelor [i limbaje de programare 81 Dan Popa, 2007


Ceea ce este declarat poate fi folosit `ncep=nd din locul declara]iei, mai departe `n text,
p=n\ la finalul blocului din care face parte (prin bloc `n]eleg=nd de exemplu un modul sau o
procedur\ ori func]ie). Cu o excep]ie. Dac\ `ntr-un bloc interior e declarat din nou ceva cu
acela[i nume, are prioritate ultima declara]ie, cea mai interioar\, care o acoper\ momentan
pe cea exterioar\. Acestea sunt singurele por]iuni `n interiorul unui bloc unde o declara]ie
local\ lui nu mai este vizibil\.

Reguli de valabilitate (vizibilitate) a identificatorilor (`n Oberon)

1. Un acela[i identificator nu poate referi dou\ entit\]i declarate diferit `n acela[i bloc.
Redeclararea sau dubla declarare nu este permis\ `n acela[i bloc.
2. Orice entitate poate fi folosit\ de programator doar `n domeniul ei de vizibilitate. Nu uita]i
c\ anumi]i identificatori, cei cu stelu]\, pot fi f\cu]i vizibili `nafara modului, mai exact `n alt
modul care import\ modulul respectiv. De acolo ei vor fi referi]i prin construc]ii de genul
NumeModul . Identificator unde numele de modul poate fi [i o porecl\ a modulului. Pute]i
folosi [i simbolul minus (-) `n loc de stelu]\ (*) pentru a exporta identificatori dar `n acest caz
vor fi identificatori “read-only”. Asupra lor se va putea avea acces doar `n citire. De exemplu,
`ncercarea de a atribui valori unei asemenea variabile exportate se soldeaz\ cu un mesaj de
eroare la compilare cum ar fi
« Error 76: this variable (field) is read only».
3. ~n general nu pute]i folosi un tip de date `nainte de a fi declarat sau `nafara domeniului
s\u de vizibilitate, m\car pentru faptul c\ nu se cunoa[te cantitatea de memorie necesar\
unei date de tipul respectiv. Deoarece o adres\ de memorie are `ns\ `ntotdeauna aceea[i
lungime, indiferent a c\rei date este adresa, rezult\ ca un tip POINTER TO <AltTip> poate
fi declarat [i folosit `n afara domeniului de vizibilitate a declara]iei pentru acel <AltTip>.
Practic, putem declara un tip pointer la un tip care va fi declarat mai departe, dar acesta din
urm\ trebuie totu[i declarat `n acela[i bloc. O regul\ despre vizibilitate care `[i are locul `n
acest subcapitol dar se refer\ la no]iuni `nc\ neexplicate este urm\toarea:
4. Identificatorii c=mpurilor (prin c=mpuri `n]eleg componente ale unui RECORD, care se
declar\ la fel ca variabilele) dintr-o `nregistrare sau denumirile procedurilor legate la tip (iar
tipul devine `n acest caz clas\ de obiecte) sunt utilizabili numai `n designatorii acelui tip.
Altfel spus doar dac\ o variabil\ sau o substructur\ a unei structuri de date este de un

Programarea calculatoarelor [i limbaje de programare 82 Dan Popa, 2007


anumit tip record atunci va con]ine [i c=mpurile indicate, fie c\ sunt date, c=mpuri
procedurale sau denumiri de proceduri legate la acel tip. Asupra acestei reguli vom reveni
cu ocazia subiectelor: designatori, recorduri, obiecte, c=mpuri procedurale, proceduri legate
la tip.

identCalificat = [ident "."] ident.

identDeclaratExportat = ident ["*" |"-"].

De exemplu `n limbajul Oberon exist\ urm\torii identificatori predeclara]i,(tipuri, proceduri,


proceduri func]ionale):

ABS LEN COPY NEW


ASH LONG DEC ODD
BOOLEAN LONGINT ENTIER ORD
CAP LONGREAL EXCL REAL
CHAR MAX FALSE SET
CHR MIN HALT SHORT
INC SHORTINT INCL SIZE
INTEGER TRUE


Extrage]i din documenta]ia electronic\ sau dintr-un volum despre limbajul
Oberon-2 semnifica]iile [i/sau m\car contextul de folosire pentru fiecare
cuv=nt rezervat [i fiecare identificator predeclarat, astfel `nc=t s\ pute]i
relata ce [ti]i despre el, din ce construc]ie sintactic\ face parte (dac\ e
cuv=nt rezervat) [i ce `nseamn\, apoi la ce este folosit. Ce deosebire g\si]i `ntre
identificatorii predeclara]i [i cuvintele rezervate ? De care dintre aceste categorii nu se poate
lipsi un limbaj ?


Extrage]i din documenta]ia electronic\ sau dintr-un volum despre limbajul
C++ (sau C# sau Java) semnifica]iile [i/sau m\car contextul de folosire
pentru fiecare cuv=nt rezervat [i fiecare identificator predeclarat, astfel
`nc=t s\ pute]i relata ce [ti]i despre el, din ce construc]ie sintactic\ face
parte (dac\ e cuv=nt rezervat) [i ce `nseamn\, apoi la ce este el folosit.

Programarea calculatoarelor [i limbaje de programare 83 Dan Popa, 2007


6
Cap

Programarea structurată: Cum îmbinăm


instrucţiunile unei viitoare proceduri

Despre cuvinte cheie, despre secvenţa, IF, CASE, FOR, REPEAT, WHILE, WITH

Am v\zut c\ metodele moderne de realizare a unei aplica]ii informatice presupun munca `n


echip\, modularizarea aplica]iilor, astfel `nc=t fiecare programator s\ lucreze un modul,
adic\ o colec]ie de proceduri destinate a face anumite servicii sau a calcula anumite
rezultate. Prin urmare aplica]ia v-o pute]i imagina ca o colec]ie de proceduri, grupate `n
module. Modulul principal, care d\ [i numele aplica]iei, con]ine procedura ProgMain (`n C i
se spune: func]ia main) [i import\ (`n C termenul este include) alte module, apel=nd apoi
alte proceduri din aceste module. Discut\m acum felul `n care se construie[te corpul unei
proceduri, acel text cuprins `n Oberon `ntre BEGIN –ul procedurii [i END-ul acesteia. Acest
din urm\ END `l recunoa[te]i dup\ numele procedurii, care apare [i acolo.


Defini]ie: Programarea structurat\ const\ `n scrierea programelor din
instruc]iuni simple (atribuiri, apeluri de proceduri, instruc]iuni de I/O) puse
ori una dup\ alta ori incluse unele `n altele. Fiecare mod de a grupa
`mpreun\ mai multe instruc]iuni se face conform unei reguli. Numim o
asemenea regul\ «structur\». Ea ne spune cum s\ `mbin\m structurile mai mici cu un fel de
“mortar” care e format din cuvinte cheie [i alte simboluri ca s\ ob]inem o nou\ structur\.

Programarea calculatoarelor [i limbaje de programare 84 Dan Popa, 2007


Exemplu: instruc]iunea if din C sau C++ se compune din condi]ie (este o expresie) [i dou\
instruc]iuni structurate sau simple `mpreun\ cu dou\ paranteze, una deschis\ una `nchis\ [i
cuvintele rezervate if [i else. O asemenea combina]ie este prezentat\ scriindu-se:
if ( <expresie>) <instruc]iune> else <instruc]iune>
unde parantezele unghiulare nu fac parte din limbaj.

Teoria calculabilit\]ii a studiat deja c=te structuri sunt necesare pentru realizarea tuturor
programelor posibile: Sunt NECESARE: secven]a, alternativa, o structur\ repetitiv\ (nu
conteaz\ care e, dac\ e cu test final sau cu test ini]ial). A prezenta teorema respectiv\ dep\-
[e[te scopul acestui volum.
~n practic\ `ns\, limbajele de programare, `n dorin]a de a ajuta programatorul `n construirea
instruc]iunilor structurate, ofer\ mai multe reguli. Incluz=nd cea mai simpl\ regul\ (de a scrie
instruc]iunile `n secven]\ una dup\ alta separate prin “ ; ”) l=ng\ celelalte, rezult\
urm\toarea list\ de instruc]iuni structurate:
- Structura alternativ\ (permite s\ execut ceva sau altceva func]ie de o condi]ie) ~n
multe limbaje poart\ numele IF, (sau IF … THEN …ELSE…etc.) Re]ine]i c\ va con]
ine o condi]ie boolean\ [i (cel pu]in) dou\ secven]e de instruc]iuni.
- Structura alternativ\ generalizat\ (permite ca, `n func]ie de valoarea unei expresii
s\ execut una sau alta dintre ni[te instruc]iuni sau secven]e de instruc]iuni. Instruc]
iunuile pot fi [i ele compuse, adic\ structurate. ~n Oberon [i Pascal se nume[te
CASE. ~n alte limbaje (Ex: C [i derivatele), o g\si]i sub numele de «switch» . Pot fi [i
alte denumiri.
Aten]ie: Limbajele obiectuale (adic\ orientate obiect) au permis apari]ia unei noi
structuri alternative, care alege nu dup\ valoarea ci dup\ tipul rezultatului. ~n
Oberon aceasta se nume[te WITH [i este ceva diferit de WITH–ul din Pascal.
Deci cunosc\torii de Pascal vor trebui s\-[i actualizeze cuno[tin]ele despre WITH.
- Bucla cu num\r cunoscut de itera]ii: Acea structur\ care permite s\ programezi
de c=te ori s\ se execute o instruc]iune sau o secven]\ de instruc]iuni. Bucla folose
[te o variabil\ contor care `[i schimb\ valoarea la fiecare pas, iar valoarea ei poate fi
folosit\ `n calcule. ~n multe limbaje se nume[te FOR. Aten]ie, «for»-ul din C este mult
mai puternic [i mai complex dec=t cel din Pascal sau Oberon, put=nd la nevoie ]ine
[i locul urm\toarelor structuri cu num\r necunoscut de itera]ii:

Programarea calculatoarelor [i limbaje de programare 85 Dan Popa, 2007


- Bucla cu test final: A]i `nt=lnit-o prima. Este structura care permite s\ program\m
repeti]ia instruc]iunilor cuprinse `n ea, p=n\ la `ndeplinirea unei condi]ii. ~n multe
limbaje, inclusiv Oberon [i Pascal se nume[te REPEAT … UNTIL . Con]ine o instruc]
iune structurat\ sau o secven]\ de instruc]iuni [i o condi]ie logic\ (expresie boolean\)
la sf=r[it. Acolo poate fi [i o procedur\ / func]ie care d\ un rezultat boolean
(deoarece [i o func]ie formeaz\ o expresie). Execu]ia instruc]iunilor din bucl\
continu\ `n mod repetat, p=n\ c=nd condi]ia devine adev\rat\.
Aten]ie: la bucla urm\toare execu]ia continu\ p=n\ c=nd condi]ia devine fals\ !
- Bucla cu test ini]ial: Este structura care permite s\ program\m execu]ia instruc
]iunilor cuprinse `n ea, de fiecare dat\ c=nd condi]ia este adev\rat\. Condi]ia exprim\
de obicei faptul c\ mai sunt prelucr\ri de efectuat. ~n multe limbaje, inclusiv Oberon
[i Pascal se nume[te WHILE … DO. ~n C o g\si]i sub denumirea de do… while .
Con]ine o instruc]iune structurat\ sau o secven]\ de instruc]iuni [i o condi]ie logic\
(expresie boolean\) la `nceput. Acolo poate fi [i o procedur\ / func]ie care d\ un
rezultat boolean (deoarece [i o func]ie formeaz\ o expresie). Execu]ia instruc]iunilor
din bucl\ continu\ `n mod repetat, p=n\ c=nd condi]ia devine fals\, semn c\ nu mai
are nimic de f\cut.
- Secven]a: este tot o structur\. Mai multe instruc]iuni scrise una dup\ alta formeaz\ o
secven]\. ~n Pascal secven]a e delimitat\ de BEGIN [i END, `n C [i limbajele
derivate din el (C^^, Java , Perl etc) este delimitat\ de acolade, care ]in rol de
BEGIN [i END. ~n Oberon, deoarece fiecare structur\ (cu excep]ia secven]ei) are un
cuv=nt final, secven]ele cuprinse `n acea structur\ sunt precis delimitate [i nu au
nevoie de BEGIN [i END sau altceva.

Limbajele de programare ofer\ [i alte moduri de structurare a instruc]iunilor. De exemplu `n


Pascal, WITH era folosit pentru a scrie o instruc]iune compus\ care manipula datele dintr-un
tip de date compus, numit RECORD. Asupra acestui subiect, WITH, vom reveni deoarece
are alt sens `n Oberon. ~n Oberon ([i `n alte c=teva limbaje) mai exist\ o alt\ bucl\ numit\
LOOP…END.

Programarea structurat\ permite s\ folose[ti o structur\ sau o singur\ instruc]iune

Programarea calculatoarelor [i limbaje de programare 86 Dan Popa, 2007



pe post de component\ `ntr-o structur\ mai complicat\. Aceasta la
r=ndul ei poate fi component\ `ntr-o alt\ structur\ mai complicat\ [i a
[a mai departe p=n\ ob]ine]i o structur\ mare, capabil\ s\ fac\ ceea ce
dori]i. Ei i se poate pune un nume [i va deveni procedur\, func]ie,
metod\ a unui obiect sau chiar program principal .

Metafora care descrie acest fenomen de `nghi]ire a unei/unor structuri de c\tre alta mai
mare este: Pe[tele cel mare `nghite pe cel mic. (sau pe cei mici.) Nu uita]i c\ la urma
urmei [i el este `nghi]it de altul. Balena sau rechinul balen\ care i-a `nghi]it pe to]i este de
fapt procedura, func]ia, metoda sau programul principal. Dar deja aici ie[im din cadrul
subiectului: «modul de `mbinare al instruc]iunilor» deoarece procedura poate con]ine [i
altceva dec=t instruc]iuni,de exemplu declara]ii. La fel [i modulul.

S\ prezent\m aceste structuri pe `ndelete, ar\t=nd la fiecare:

DE: denumirea
SI: sintaxa `n Oberon
SE: semantica, explica]iile
EX: un exemplu de folosire

Structura alternativ\, sau pe scurt IF


DE: IF … THEN … ELSIF … ELSE … END
SI: IfStatement =
IF Expression THEN StatementSequence
{ ELSIF Expression THEN StatementSequence }
[ELSE StatementSequence]
END .
SE: Instruc]iunea IF (IfStatement) const\ `n

Cuv=ntul rezervat IF urmat de o expresie cu valoare boolean\ Expression apoi de


cuv=ntul rezervat THEN [i de secven]a de instruc]iuni StatementSequence care se vor
executa dac\ a fost condi]ia adev\rat\ Pot urma mai multe p\r]i de instruc]iune de forma

Programarea calculatoarelor [i limbaje de programare 87 Dan Popa, 2007


ELSIF urmat de expresia boolean\ Expression (acesta e rostul metasimbolului acolad\, s\
anun]e c\ ceea ce e `n acolad\ se poate repeta de oric=te ori) apoi `nc\ un THEN [i `nc\ o
secven]\ de instruc]iuni StatementSequence . Re]ine]i c\ acest grup care `ncepe cu ELSIF
[i se termin\ cu secven]\ de instruc]iuni se poate repeta de oric=te ori. Sensul s\u este c\
se va executa secven]a de instruc]iuni dac\ `n urma evaluarii condi]iei corespunz\toare,
condi]ia este g\sit\ adev\rat\. Urmeaz\ o alt\ parte a instruc]iunii IF, care este op]ional\ [i
`ncepe cu ELSE continu=ndu-se cu alt\ secven]\ de instruc]iunui StatementSequence .
Acestea din urm\ vor fi executate ca ultim\ alternativ\, `n cazul c=nd niciuna din condi]iile
precedente (care ar fi declan[at execu]ia altei secven]e) n-a fost adev\rat\. IF-ul se termin\
obligatoriu cu END iar dac\ urmeaz\ alt\ instruc]iune va fi `ntre ele un “ ; ”

Observa]i c\ prin felul cum este IF `n Oberon, fiecare secven]\ de instruc]iunui este cuprins\
`ntre dou\ cuvinte cheie: THEN …ELSIF, THEN… ELSE sau ELSE … END. Aten]ie: Alte
limbaje (cum este limbajul Pascal) nu permit folosirea lui ELSIF, deci va trebui s\ scrie]i IF-
urile unul `n altul, imbricate. Este o veritabil\ prob\ de programare structurat\, mai ales c=nd
ve]i num\ra END-urile de la sf=r[it!
EX:
IF (ch>="A") & (ch<="Z") THEN ReadIdentifier
ELSIF (ch>="0") & (ch<="9") THEN ReadNumber
ELSIF (ch="'") OR (ch='"') THEN ReadString
ELSE SpecialCharacter
END

Explica]ia exemplului: ~n situa]ia `n care valoarea lui ch este o liter\ din alfabetul cu
majuscule, se va executa procedura ReadIdentifier. ~n cazul c=nd caracterul ch este o
cifr\ de la 0 la 9 se va executa procedura ReadNumber. Iar dac\ valoarea variabilei ch
este una din cele dou\ (feluri de) ghilimele se va executa procedura ReadString. Altfel se
va executa procedura SpecialCharacter.
Structura alternativ\ generalizat\ CASE
DE: CASE … OF …. : … ELSE … END
SI: CaseStatement =
CASE Expression OF

Programarea calculatoarelor [i limbaje de programare 88 Dan Popa, 2007


Case
{"|" Case}
[ELSE StatementSequence]
END
Unde:
Case = [CaseLabelList ":" StatementSequence]
CaseLabelList = CaseLabels {"," CaseLabels}
CaseLabels = ConstExpression [".." ConstExpression]
Sintactic vorbind, instruc]iunea CASE se scrie a[a:
Cuv=ntul rezervat CASE apoi expresia dup\ care se face selec]ia alternativelor,
Expression, cuv=ntul rezervat OF , o prim\ alternativ\ obligatorie Case urmat\ de altele op]
ionale. Fiecare alternativ\ op]ional\ `ncepe cu semnul bar\-vertical\ (SHIFT plus Backslash,
SHIFT plus frac]ie invers\) care este semnul de separare `ntre dou\ alternative succesive
Case. Urmeaz\ o parte op]ional\ format\ din cuv=ntul rezervat ELSE [i secven]a de
instruc]iuni StatementSequence care se va executa `n caz de nepotrivire a valorii cu
etichetele. Ca [i IF, CASE se termin\ cu END.
Cum descriem o alternativ\: pentru CASE ? Facem observa]ia c\ alternativa vid\ este
posibil\ deci ar trebui s\ pute]i scrie dou\ bare “|” una l`ng\ alta a[a cum pute]i scrie dou\
semne “;” unul l=ng\ altul.
Alternativa e format\ din dou\ p\r]i separate prin simbolul dou\-puncte (“:”) . Seam\n\ cu o
declara]ie de variabil\, dar se deosebe[te prin faptul c\ `nainte de cele dou\ puncte este
scris\ o list\ de constante [i/sau intervale (nu o list\ de denumiri de variabile) iar dup\ dou\
puncte este scris\ secven]a de instruc]iuni de executat (nu tipul variabilelor). A[a figureaz\
`n documenta]ie :
Case = [CaseLabelList ":" StatementSequence]
CaseLabelList = CaseLabels {"," CaseLabels}
Ultima regul\ ne d\ o alt\ posibilitate de a scrie constantele dup\ care se face selec]ia. O
constant\ poate fi `nlocuit\ cu un interval de constante c\reia `i preciz\m capetele,( prima [i
ultima valoare). ~ntre cele dou\ valori se pune o pereche de puncte al\turate, unul dup\
altul.
CaseLabels = ConstExpression [".." ConstExpression]
SE: Semnifica]ia lui CASE. ~n Help g\si]i: “Case statements specify the selection and

Programarea calculatoarelor [i limbaje de programare 89 Dan Popa, 2007


execution of a statement sequence according to the value of an expression. First the case
expression is evaluated, then that statement sequence is executed whose case label list
contains the obtained value. The case expression must either be of an integer type that
includes the types of all case labels, or both the case expression and the case labels must
be of type CHAR. Case labels are constants, and no value must occur more than once. If
the value of the expression does not occur as a label of any case, the statement sequence
following the symbol ELSE is selected, if there is one, otherwise the program is aborted.”
Am dat cuv=ntul autorilor, invit=ndu-v\ s\ verifica]i dac\ pute]i `n]elege asemenea explica]ii
`n limba englez\. Considera]i acest text un test, iar dac\ este cazul pune]i-v\ la punct cuno-
[tin]ele de limb\ englez\. Este practic limba profesional\ a “calculatori[tilor” din Rom=nia [i
de pe alte meleaguri. ~ntr-o traducere comentat\, textul ar fi a[a:

“Instruc]iunea CASE specific\ selectarea spre execu]ie a unei secven]e de instruc]iuni


aleas\ dup\ valoarea unei expresii. La `nceput, expresia selectoare este evaluat\, apoi
taman acea secven]\ de instruc]iuni este executat\, care are valoarea ob]inut\ `n lista ei de
valori (Case Label List). Expresia selectoare trebuie s\ fie de tip `ntreg, suficient de vast ca
s\ cuprind\ toate valorile de pe liste. Este posibil [i ca expresia [i valorile s\ fie de tipul
CHAR. Aceste valori – etichete ale alternativelor – sunt constante (nu expresii) [i niciuna
dintre ele nu poate s\ apar\ de mai multe ori. Dac\ valoarea expresiei nu se potrive[te cu
niciuna dintre valorile etichetelor case este executat\ secven]a de instruc]iuni de dup\
ELSE. Altfel programul este oprit.

EX: CASE ch OF
"A" .. "Z" : ReadIdentifier
| "0" .. "9" : ReadNumber
| " ' ", ' " ' : ReadString
ELSE SpecialCharacter
END

permite ca, `n func]ie de valoarea unei expresii, care aici este variabila ch, s\ se execute
una sau alta dintre procedurile ReadIdentifier , ReadNumber ,
ReadString sau, `n cazul altui fel de caracter, procedura SpecialCharacter.

Programarea calculatoarelor [i limbaje de programare 90 Dan Popa, 2007


Bucla cu num\r cunoscut de itera]ii, sau pe scurt, bucla FOR
DE: FOR … TO … BY …DO …END
SI: FOR v := low TO high [BY step] DO statements END
Discut=nd strict sintactic, for se scrie astfel: Cuv=ntul FOR , urmat de numele variabilei
(obligatoriu de tip `ntreg), v , apoi semnul atribuirii ":=", prima expresie (care d\ prima
valoare a variabilei contor ) low, cuv=ntul obligatoriu TO, apoi a doua expresie care d\
valoarea final\ a variabilei contor, notat\ cu high. Op]ional pot urma cuv=ntul rezervat BY
`nso]it de o expresie constant\ numit\ pas (`n englez\ “step”). Dup\ accea sunt obligatorii
cuv=ntul rezervat DO , secven]a de instruc]iuni statements [i cuv=ntul END
Descrierea sintaxei din Help-ul nediului de programare Pow, care `nso]e[te compilatorul de
Oberon-2 dat ca exemplu este:
ForStatement =
FOR ident ":=" Expression TO Expression [BY ConstExpression] DO
StatementSequence
END .
Tradi]ional, instruc]iunile din bucla FOR se scriu cu dou\ litere mai la dreapta dec=t FOR [i
END, ceea ce face vizibil grupul de instruc]iuni ce se vor repeta (care poate fi format [i dintr-
o singur\ instruc]iune) .
SE: ~n principiu FOR execut\ secven]a de instruc]iuni de un num\r [tiut dinainte de ori,
folosind contorul pentru a num\ra de la valoarea primei expresii la valoarea ultimei
(inclusiv). Num\r\toarea se face din 1 `n 1 (pasul implicit) dac\ nu este specificat `n instruc]
iune alt pas (prin BY urmat de o constant\ cu semn). Pasul poate fi deci [i negativ. ~n cazul
`n care ordinea valorii celor dou\ expresii este invers\ modului cum specific\ pasul, bucla
nu se parcurge, instruc]iunile nu se execut\. Este evident c\ nu putem num\ra din 1 `n 1
sau din 2 `n 2 de la 20 la 10. {i nici din –1 `n –1 de la 1 la 10.
Observa]ie: `n Oberon prima expresie se evalueaz\ `n contextul atribuirilor dinaintea FOR-
ului iar a doua expresie `n contextul creat dup\ prima atribuire (cea de dup\ cuv=ntul
FOR).

Practic: ~ncerca]i s\ stabili]i `ntre ce valori ale contorului a se va «`nv=rti» bucla FOR din
exemplul de mai jos. Observa]i c\ el are dou\ particularit\]i: Pe de o parte contorul este
folosit `n interiorul buclei (ceea ce este permis cu condi]ia s\ nu-i modifica]i valoarea), pe de

Programarea calculatoarelor [i limbaje de programare 91 Dan Popa, 2007


alt\ parte at=t expresia care d\ valoarea ini]ial\ a contorului c=t [i expresia care d\ valoarea
final\ a contorului depind de o valoare anterioar\ a aceluia[i contor. ~ntrebarea e de care
valoare, de valoarea dinafara buclei sau de care alta ?


Test: dac\ pute]i spune numai pe baza cuno[tin]elor teoretice (de mai sus)
ce numere afi[eaz\ programul, `nseamn\ c\ st=p=ni]i perfect semantica
buclei FOR.

Pute]i s\ rula]i programul de mai sus pentru a vedea rezultatele.


EX: FOR a:= 1 TO 10 BY 2 DO
Display.WriteInt(a,3)
END;

Programarea calculatoarelor [i limbaje de programare 92 Dan Popa, 2007


Va afi[a pe ecran, `n fereastra aplica]iei numerele impare de la 1 la 10 adic\:

Remarca]i faptul c\ fiecare num\r a fost scris pe trei spa]ii, aliniat la st=nga, acesta fiind un
efect al parametrului al doilea al procedurii WriteInt.

Acea structur\, FOR-ul este deci cea care permite s\ programezi de c=te ori s\ se execute
o instruc]iune sau o secven]\ de instruc]iuni. Bucla folose[te o variabil\ contor care `[i
schimb\ valoarea la fiecare pas, iar valoarea ei poate fi folosit\ `n calcule. Este
recomandabil s\ nu folosi]i valoarea variabilei contor `n calculul celei de-a doua expresii,
rezultatele execu]iei unor asemenea bucle FOR fiind contrare primei impresii. Dac\ totu[i
ave]i nevoie de o bucl\ a c\rei limit\ superioar\ poate fi modificat\ `n cursul rul\rii
programului folosi]i bucla REPEAT … UNTIL , sau WHILE …DO …END.

Bucla cu test final sau bucla REPEAT … UNTIL.

DE: REPEAT …UNTIL


SI: RepeatStatement =
REPEAT StatementSequence
UNTIL Expression

Sintaxa lui REPEAT…UNTIL ne spune c\ el este format din cuv=ntul rezervat REPEAT
urmat de o secven]\ de instruc]iunui notat\ `n documenta]ie StatementSequence, apoi
cuv=ntul rezervat UNTIL [i expresia Expression care trebuie s\ fie obligatoriu de tip logic
(BOOLEAN). Expresia poate consta [i `ntr-un apel de procedur\ func]ional\, eventual (din
alt modul).

SE: “A repeat statement specifies the repeated execution of a statement sequence until a
condition specified by a Boolean expression is satisfied. The statement sequence is
executed at least once.” A[a o g\si]i explicat\ dac\ apela]i la meniul Help -> Compiler topic
search [i scrie]i cuv=ntul FOR. Explica]ia de mai sus `n traducere adaptat\ `nseamn\:

Programarea calculatoarelor [i limbaje de programare 93 Dan Popa, 2007


" O instruc]iune REPEAT programeaz\ computerul s\ execute `n mod repetat o secven]\ de
instruc]iuni p=n\ c=nd o condi]ie specificat\ de o expresie boolean\ devine adev\rat\.
Secven]a de instruc]iuni este executat\ m\car o singur\ dat\.

EX: Bucla repeat until din programul de mai jos va scrie mesajul de salut `ncontinuu, `n mod
repetat, p=n\ va ap\sa cineva o tast\.

Acesta este un caz mai pu]in obi[nuit (de[i `n unele jocuri video simple exist\ asemenea
bucle). De obicei condi]ia buclei REPEAT … UNTIL depinde de unele variabile ale
programului, ale c\ror valori sunt modificate de instruc]iunile din bucl\. Astfel condi]ia
(expresia boolean\) devine adev\rat\ iar bucla ajunge s\ se opreasc\. O bucl\ REPEAT …
UNTIL a c\rei condi]ie nu poate fi modificat\ de instruc]iunuile din bucl\ se va “roti” ori o
singur\ dat\ (condi]ia era deja adev\rat\) ori de un num\r infinit de ori, provoc=nd aparenta
«blocare» a programului.
Re]ine]i deci c\: REPEAT … UNTIL este structura care permite s\ program\m repeti]ia
instruc]iunilor cuprinse `n ea, p=n\ la `ndeplinirea unei condi]ii. ~n multe limbaje, inclusiv
Oberon [i Pascal se nume[te REPEAT … UNTIL . Con]ine o instruc]iune structurat\ sau o
secven]\ de instruc]iuni [i o condi]ie logic\ (expresie boolean\) la sf=r[it. Acolo poate fi [i o

Programarea calculatoarelor [i limbaje de programare 94 Dan Popa, 2007


procedur\ / func]ie care d\ un rezultat boolean (deoarece [i o func]ie formeaz\ o expresie).
Execu]ia instruc]iunilor din bucl\ continu\ `n mod repetat, p=n\ c=nd condi]ia devine
adev\rat\. (Repeti]ia paragrafului de mai sus nu este `nt=mpl\toare - cei care au `nv\]at o
limb\ str\in\ sau un limbaj de programare studiind simultan dou\ manuale [tiu ei de ce.)

Bucla cu test ini]ial, cunoscut\ [i sub denumirea de bucla WHILE …DO ..END sau pe
scurt bucla WHILE.

DE: WHILE …DO ... END


SI: WhileStatement =
WHILE Expression DO
StatementSequence
END

Din punct de vedere sintactic se scrie astfel: Cuv=ntul rezervat WHILE urmat de condi]ia
dat\ de expresia boolean\ Expression. Urmeaz\ cuv=ntul rezervat DO [i secven]a de
instruc]iunui StatementSequence terminat\ cu END.

SE: Folosind bucla WHILE …DO …END program\m execu]ia repetat\ a unei secven]e de
instruc]iunui at=ta vreme c=t condi]ia sa este satisf\cut\. Condi]ia este testat\ `naintea
fiec\rei execu]ii a buclei. Observa]i c\ este preferabil s\ existe instruc]iuni `n bucl\ capabile
s\ modifice valoarea condi]iei. Este posibil s\ folosi]i o func]ie (procedur\ func]ional\)
capabil\ s\ returneze un rezultat boolean pe post de condi]ie (sau chiar o expresie boolean\
cu func]ii).

EX: ~n documenta]ia electronic\ exist\ urm\toarele exemple.


k :=0 ;
WHILE i > 0 DO
i : = i DIV 2;
k := k + 1
END

Programarea calculatoarelor [i limbaje de programare 95 Dan Popa, 2007


Acesta `mparte un num\r i `n mod repetat la doi, p=n\ c=nd nu se mai poate, num\r=nd
`mp\r]irile. Practic stabile[te c=te cifre are un num\r `n nota]ie binar\.

WHILE (t # NIL) & (t.key # i) DO


t := t.left
END

Aceast\ bucl\ caut\ `ntr-o list\ simplu `nl\n]uit\ (sau mai cur=nd pe ramura unui arbore)
elementul t cu cheia i. Cei care au studiat Pascal-ul `nainte vor observa c\ sintaxa Oberon-
ului difer\ doar `n dou\ locuri (`n acest exemplu) de cea a Pascalului (diferit se scrie ca un
diez [i nu ca mai-mic-mai-mare "<>" iar conjunc]ia logic\ se scrie & nu "and" ). Acest
exemplu nu e accesibil acelora care nu au studiat liste [i arbori.

V\ da]i seama cu ce e echivalent\ secven]a de mai jos?


v := low; temp := high;
IF step > 0 THEN
WHILE v <= temp DO statements; v := v + step END
ELSE
WHILE v >= temp DO statements; v := v + step END
END

R\spuns: Cu FOR v := low TO high BY step DO statements END .

Remarcabil: Cu WHILE putem simula [i pe FOR [i pe REPEAT, la fel [i cu REPEAT


pe WHILE [i FOR.

~ncerca]i s\ scrie]i secven]ele de instruc]iuni respective. Indica]ie: folosi]i [i IF.

Programarea calculatoarelor [i limbaje de programare 96 Dan Popa, 2007


7
Cap

De la structuri de date la Programarea


Orientată Obiect

Despre: tip de date abstract, limbaje orientate obiect (object-oriented), moştenire, (inheritance),
obiect (object), polimorfism, supraîncărcare, verificare dinamică a tipurilor, clasă, instanţă,
metodă, mesaj.

De ce s-a ajuns la programarea orientat\ pe obiecte? Exist\ nevoi reale de a inventa un nou
tip de date, obiectul, pe l=ng\ cele deja existente? Ce aduce el `n plus? De ce mai este
nevoie pentru a modela un col] de univers, transpun=ndu-l `n program de calculator?
~ncerc\m s\ r\spundem la aceste `ntreb\ri, pentru a justifica de fapt urm\toarea:


Defini]ie: Programarea orientat\ obiect este programarea care folose[te
obiecte (transpuneri ale unor entit\]i din universul problemei sau din natur\)
[i mesaje (cereri pe care le fac unele obiecte altora de a realiza ceva).
Mesajele pot fi provocate de ni[te evenimente produse de sistemul de
operare. Obiectele con]in date (cam ca ni[te variabile) [i metode (care sunt de fapt
proceduri sau func]ii ata[ate obiectului). Pentru u[urarea muncii programatorului clasele (`n
fond ni[te tipuri de date nou definite) se grupeaz\ `ntr-o ierarhie de clase, legat\ prin rela]ie
de mo[tenire (astfel c\ o clas\ poate prelua totul de la o clas\ veche [i poate avea [i ceva `n
plus – date sau metode - dar f\r\ s\ se mai scrie din nou `n program ce con]inea clasa

Programarea calculatoarelor [i limbaje de programare 97 Dan Popa, 2007


veche). Reac]ia diferit\ a obiectelor (`n fond un fel de grupuri de variabile care con]in [i
proceduri) din clasele ierarhiei la anumite cereri de a presta altor obiecte servicii diverse
este asigurat\ de polimorfism. Astfel diverse obiecte din clasele ierarhiei, indicate de un
pointer (practic indicate prin adres\ de memorie), pot executa sarcini diferite de[i metoda
c\reia i se cer serviciile are acela[i nume pentru toate obiectele. Vom vedea c\ `n limbaje
ca Oberon este posibil s\ avem obiecte c\rora li se schimb\ dinamic, din mers,
comportamentul sau dimpotriv\, obiecte care au metode neschimbate, declarate ca atare
atunci c=nd s-a definit clasa. Cum se folosesc obiectele `n realizarea unei aplica]ii, adic\
“metode de inginerie a program\rii obiectuale” vom prezenta `n alt capitol, ceva mai departe.
Dar `nainte de a ajunge la obiecte trebuiesc reamintite sau prezentate no]iunile
fundamentale premerg\toare: vectori [i `nregistr\ri.

Vectori şi înregistrări, abordarea clasică


neobiectuală
Cuvinte cheie: vectori, matrice, înregistrāri (RECORD-uri)

Limbaje de programare uzuale ofer\ modalit\]i de structurare a datelor `n structuri de date


compuse. Deoarece datele care vor fi agregate pot fi ori de tipuri diferite ori de acela[i tip,
limbajele ofer\ posibilitatea de a declara:
- vectori [i matrice - au elemente de acela[i tip
- structuri (struct) sau `nregistr\ri (RECORD) – cu elemente de tipuri `n general
diferite.
Denumirile sunt de fapt sinonime dou\ c=te dou\ dar vectorul e un caz particular de matrice
cu o linie sau o coloan\. Cuv=ntul rezervat pentru no]iunea de «`nregistrare», destinat a
denumi structuri de date compuse, difer\ de la limbaj la limbaj. Se nume[te RECORD `n
Oberon [i Pascal [i «struct» - de la structur\, `n C. C^^ folose[te tot «struct» pentru
compatibilitate dar atunci c=nd unui asemenea set de date i se adaug\ metode [i devine
clas\ de obiecte «struct» e `nlocuit cu «class». Tot «class» se folose[te [i `n Java iar `ntre
programatorii de C^^ tendin]a este de a se renun]a la «struct» deoarece o clas\ f\r\

Programarea calculatoarelor [i limbaje de programare 98 Dan Popa, 2007


metode este practic o structur\ similar\ celei declarate cu «struct». Re]ine]i totu[i c\
termenul clas\ denume[te un tip de date care con]ine [i metode deci `n tipul de date rezultat
e loc [i pentru procedurile care prelucreaz\ datele respective. Pentru asemenea date
structurate `n limbaj se ofer\ [i operatori, care acceseaz\ componente ale structurii de date.
Operatorul parantez\ p\trat\ «[ ]» serve[te la desemnarea unei componente a unui vector
iar punctul la alegerea unei componente a unei `nregistr\ri «.». E momentul s\ `ncerc\m s\
definim aceste structuri de date:


Defini]ie: vectorul sau matricea este o structur\ de date compus\.
format\ din elemente de acela]i tip, f\r\ nume proprii¸ dar accesibile pe
baza indicilor. Indicii pot fi da]i fie sub form\ de constante fie sub form\ de
expresie . Fiecare element poate avea unul, doi, trei sau mai mul]i indici,
dup\ dimensiunea matricii. Vectorul e o matrice unidimensional\. O
matrice bidimensional\ e analogul unui cofraj de ou\ dar nu con]ine ou\ ci date de acela[i
tip. Num\rul de linii nu e neap\rat egal cu cel de coloane. O matrice tridimensional\ v-o
pute]i imagina ca mul]imea cubule]elor care compun un cub asemenea cunoscutelor juc\rii
cubul Rubik sau cubul Soma. ~ntr-un asemenea cub fiecare element (cubule]) are trei indici.
Se pot folosi [i matrici cu mai mult de trei dimensiuni. Memoria ocupat\ de matrici este
propor]ional\ cu produsul indicilor maximi.


Defini]ie: RECORD-ul sau `nregistrarea este o structur\ de date compus\.
format\ din elemente de tipuri diferite, av=nd nume proprii
(identificatori), cu ajutorul c\rora denumim componentele unei astfel de
structuri. Imagina]i-v\ o asemenea structur\ ca o colec]ie de declara]ii de
variabile, scris\ `ntre dou\ cuvinte care o delimiteaz\. (~n Pascal [i Oberon cuvintele sunt
RECORD [i END.)
Orice variabil\ de tipul respectiv (sau `n general orice e declarat de tipul respectiv
va avea componentele declarate, a[a cum orice num\r complex are partea real\ [i cea
imaginar\.) Imagina]i-v\ un RECORD nu ca un cofraj de ou\ (acelea ar fi identice) ci ca pe
trus\ de unelte a me[terului venit s\ v\ dea g\uri `n zid. Valiza lui are ni[te l\ca[uri `n care
se pun: ma[ina de g\urit, o mandrin\ de rezerv\, cheia, un set de burghie, c=teva dibluri [i
[uruburi etc. Fiecare compartiment din valiz\ are forma [i dimensiunea piesei / dispozitivului

Programarea calculatoarelor [i limbaje de programare 99 Dan Popa, 2007


respectiv. Imagina]i-v\ [i c\ fiecare compartiment are o etichet\ minuscul\. Analogia cu un
record e perfect\. Cum se denume[te o component\ C a unei variabile R de tip RECORD?
Exact ca o procedur\ C dintr-un modul R, folosind operatorul punct pentru a separa
denumirile: R . C

Un exemplu de utilizare a datelor compuse, dar f\r\ obiecte:


Jocul «palatul califului». Urm\ri]i maniera de realizare a unui program neobiectual. Accentul
cade pe structurile de date [i pe programul principal care face ini]ializarea lor [i punerea `n
func]iune a `ntregii aplica]ii. Ve]i vedea c\ programul principal este lung. Datele nu sunt
legate de func]ii ci sunt practic separate de ele [i grupate, `ntr-un mare conglomerat.

Iat\ povestea: Lumea pe care o avem de modelat `ntr-o structur\ de date compus\ este
imaginarul palat al califului din Bagdad. ~n jocul nostru el va fi compus din Camere, fiecare
av=nd o denumire, un artefact, o sum\ de bani [i,4 u[i similare. Imagina]i-v\, pentru u[urin]a
desemn\rii lor c\ aceste camere [i aceste u[i sunt numerotate, de la 0 la 2 (aici vom da ca
exemplu un palat minuscul, cu trei camere) [i de la 0 la 3 pentru cele 4 u[i. Re]ine]i c\ `n
unele limbaje , Oberon, C, C^^, numerotarea elementelor unui vector `ncepe
obligatoriu de la 0. Convenim ca eticheta fiec\rei u[i s\ poarte num\rul camerei `n care d\
u[a respectiv\, num\rul –1 s\ desemneze o u[\ `nchis\, iar num\rul –2 s\ marcheze u[a
care d\ `n de[ert, acolo unde (dac\ a ajuns juc\torul) se `ncheie jocul.

~n Oberon, putem `ncepe modulul principal cu urm\toarele declara]ii:

MODULE Calif;
IMPORT Display; (* folosim modulul cu func]ii de Intrare / Ie[ire *)
CONST NrCamere= 3 ;
inchisa= -1 ; (* u[a `nchisa va fi –1 *)
desert= -2 ; (* sala –2 va fi de[ertul *)

TYPE Camera=RECORD
nr : INTEGER ;
nume : ARRAY 30 OF CHAR ; (* String de 30 de caractere *)
artefact : ARRAY 10 OF CHAR ; (* String de 10 caractere *)
usa : ARRAY 4 OF INTEGER ; (* Vector de 4 numere de camere *)
bani : INTEGER;
END ;
Palat=ARRAY NrCamere OF Camera ;

Programarea calculatoarelor [i limbaje de programare 100 Dan Popa, 2007


Observa]i c\ ne-am concentrat asupra structurilor de date. S\ coment\m pu]in. Informa]iile
dintr-o camer\ a palatului sunt de tipuri diferite, deci ea va fi un RECORD. Dintre ele, cele
patru u[i (de acela[i tip – care e chiar tipul num\rului etichet\ - adic\ INTEGER - vor forma
un vector). El se comport\ ca orice alt\ component\ a RECORD-ului. Acest tip de date nou
`l numim Camera. El reprezint\ mul]imea camerelor av=nd structura de mai sus. Dup\ nume
am scris semnul egal [i apoi descrierea tipului RECORD cu tot ce con]ine el. Declara]iile de
tip, `n Oberon [i `n Pascal sunt plasate `ntr-o sec]iune de text care `ncepe cu TYPE.
Deoarece nu-s incluse `n procedura ProgMain, ele vor fi declara]ii globale, vizibile la nivel de
modul. Teoretic toate procedurile modulului pot folosi noile tipuri. Aici avem doar o
procedur\. Deoarece palatul califului e format din camere de acela[i tip el este declarat tot
`n sec]iunea TYPE ca fiind:
Palat=ARRAY NrCamere OF Camera ;
unde NrCamere este o constant\ cu valoarea 3, mai u[or de modificat, fiind scris\ la `nceput
de modul.

Procedura ProgMain* va fi implementarea jocului propriu-zis. ~ncepem cu variabilele. Califul


are un palat «p» iar juc\torul dou\ variabile care `i reflect\ mi[carea: num\rul s\lii curente
(salacrt) [i num\rul u[ii pe care iese dintr-o `nc\pere (nru[a). Aceasta este alegerea sa, deci
va fi sigur o variabil\, mai ales c\ valoarea ei se schimb\ trec=ndu-se de la o sal\ la alta (din
alt\ sal\ ie[i, de obicei, printr-o alt\ u[\).

Variabila «err» este un parametru cerut de instruc]iunile procedurale de intrare ie[ire,


importate din modulul Display. Se declar\ de tipul CHAR [i poate avea orice nume. Ca
utilizare este al treilea parametru (ultimul) la Read-uri. Purcedem la a scrie procedura
principal\:

PROCEDURE ProgMain* ;

VAR p : Palat ; salacrt : INTEGER ; nrusa : INTEGER ;


err :CHAR ;

S\ `ncepem ini]ializarea variabilelor. O poate face at\t procedura principal\ c\t [i modulul la
`nc\rcare. B\nui]i cum este mai avantajos ? Am optat pentru ini]ializare f\cut\ chiar de
procedura principal\. Cu ocazia ini]ializ\rii practic “mobil\m” palatul.

Programarea calculatoarelor [i limbaje de programare 101 Dan Popa, 2007


BEGIN
p[0].nr:=0;
p[0].nume:="Sala de intrare ";
p[0].artefact:="tablou ";
p[0].usa[0]:=inchisa;
p[0].usa[1]:=inchisa; (*din palatul p, din sala 0, o u[a, cu num\rul 1 e…*)
p[0].usa[2]:=1; (* a doua u[a din sala 0 din palat ne duce `n sala 1*)
p[0].usa[3]:=inchisa;
p[0].bani:=10;
p[1].nr:=1;
p[1].nume:="Sala tronului";
p[1].artefact:="tron ";
p[1].usa[0]:=0;
p[1].usa[1]:=inchisa;
p[1].usa[2]:=inchisa;
p[1].usa[3]:=2;
p[1].bani:=500;
p[2].nr:=2;
p[2].nume:="Sala tezaurului ";
p[2].artefact:="tezaur";
p[2].usa[0]:=0;
p[2].usa[1]:=1;
p[2].usa[2]:=desert;
p[2].usa[3]:=inchisa;
p[2].bani:=10000;
salacrt:=0; (* intr\m `n palat `n sala 0 *)

Observa]i c\ am ini]ializat [i variabila salacrt, cu num\rul primei s\li. Observa]i apoi cum
sunt scri[i designatorii din st=nga atribuirilor.
Jocul decurge `n felul urm\tor: De fiecare dat\ computerul ne scrie pe ecran `n ce sal\ am
ajuns, `ntreab\ ce u[\ folosim ca s\ plec\m mai departe, verific\ num\rul u[ii (element de
programare defensiv\) apoi schimb\ num\rul s\lii. Ca efect al schimb\rii, atunci c\nd se reia
bucla principal\, vom vedea c\ suntem `n alt\ sal\. Observa]ie: Trebuie verificate datele
introduse de utilizator [i doar atunci c=nd sunt valide pot fi prelucrate. Bucla principal\ este
o bucl\ WHILE …DO…. Sintaxa instruc]iunii WHILE … DO … este (reamintim):

Instruc]iuneaWhile =
WHILE Expresie DO Secven]\Instructiuni END .

Astfel se programeaz\ ca reluarea secven]ei de instruc]iuni s\ aib\ loc de fiecare dat\ c=nd
«Expresie» se evalueaz\ la TRUE. Dialogul decurge a[a cum se vede `n imaginea
urm\toare iar instruc]iunile sunt:

Programarea calculatoarelor [i limbaje de programare 102 Dan Popa, 2007


WHILE salacrt # desert DO (* WHILE se va termina cu un END *)
Display.WriteStr("Esti in camera nr:");
Display.WriteInt(p[salacrt].nr,6);Display.WriteLn();
Display.WriteStr("Aceasta este ");
Display.WriteStr(p[salacrt].nume);Display.WriteLn();
Display.WriteStr("Aici gasesti un:");
Display.WriteStr(p[salacrt].artefact);Display.WriteLn();
Display.WriteStr("Sunt si bani in numar de;");
Display.WriteInt(p[salacrt].bani,6);Display.WriteLn();
Display.WriteStr("Pe ce usa vrei sa iesi?"); Display.WriteLn();
Display.ReadInt(nrusa, 2,err);

Ultima instruc]iune pune computerul s\ a[tepte de la utilizator num\rul «nrusa», fapt


semnalat de liniu]a cursor.

Iar dup\ introducerea num\rului acesta va fi testat, urm=nd ca abia apoi num\rul de pe
eticheta u[ii s\ devin\ noul num\r al s\lii curente, dovad\ c\ am ajuns `ntr-o nou\ sal\. Iat\
instruc]iunea compus\ IF…THEN …ELSE …END, extins\ cu o ramur\ ELSIF, folosit\ `n
acest scop:

IF (nrusa < 0) OR (nrusa > 3)


THEN Display.WriteStr("Usa nu exista ! ");
ELSIF p[salacrt].usa[nrusa] = inchisa
THEN Display.WriteStr("Usa e inchisa ! ")

Programarea calculatoarelor [i limbaje de programare 103 Dan Popa, 2007


ELSE
salacrt:=p[salacrt].usa[nrusa]
END;
Nu ne r\m=ne dec`t s\ `nchidem bucla WHILE cu END [i s\ scriem finalul, la care se ajunge
atunci c=nd condi]ia de dup\ WHILE e fals\ (juc\torul a ie[it `n de[ert).
END; (* de la WHILE *)
Display.WriteStr("Game Over ! Apasa o tasta ! ");
REPEAT UNTIL Display.KeyPressed()
END ProgMain;
END Calif.


Edita]i programul cu editorul Pow-ului, salva]i modulul Calif.mod, compila]i,
link-edita]i [i rula]i programul. Trebuie s\ pute]i pune `n func]iune acest mic
joc conversa]ional (a[a cum erau `nc\ multe altele pe vremea terminalelor
f\r\ moduri grafice...).

~n figura care urmeaz\ am surprins jocul `n plin\ ac]iune. Deja s-au succedat c=teva
dialoguri `ntre juc\tor [i calculator. Observa]i cum fiecare reluare a buclei folose[te datele
din alt\ structur\ de date (din alt\ camer\) pentru a construi mesajele calculatorului.

Programarea calculatoarelor [i limbaje de programare 104 Dan Popa, 2007


Concluziile:

~n lipsa unei modulariz\ri acceptabile programele care rezult\ separ=nd datele de proceduri
au tendin]a s\ devin\ mari. Ele au procedurile lungi [i greu de scris. Imbricarea (scrierea
una `n alta a) structurilor program\rii structurate trebuie verificat\ cu grij\, un END uitat
(cum este cel din finalul buclei WHILE), put=nd fi o surs\ de complica]ii. Cu excep]ia tipurilor
de date nu putem refolosi altceva din aplica]ie. Datele formeaz\ un veritabil conglomerat, `n
cazul de fa]\ un vector de record-uri. E adev\rat c\ este adesea util s\ putem stoca toate
datele problemei `ntr-o variabil\ structurat\, dar nu are rost `ntotdeauna s\ grup\m prea
multe date, mai ales c=nd apar]in unor p\r]i diferite ale problemei [i se pot prelucra separat,
pe categorii. Remarca]i faptul c\ e mai natural ca “salacrt” [i “nrusa” s\ NU fac\ parte din
palat, ele fiind informa]ii care-l privesc pe juc\tor. Lucru de care am ]inut cont c=nd am scris
programul, declar=ndu-le ca variabile distincte. Vom vedea c\ se poate merge mai departe
cu aceast\ abordare.

Matricele bi, tri, .. n, dimensionale (Not\: `n Oberon) se declar\ scriind num\rul de


coloane, cel de linii c=t [i cel de «etaje» [amd. Tot num\rul de coloane/linii se scrie [i la
declararea `n C.

Exemplu:

X : ARRAY 3,4,5 OF INTEGER

este o matrice tridimensional= de 3 r=nduri, 4 coloane, 5 etaje.


Iar elementul X[1,4,3] este elementul ei de pe r=ndul 1, coloana 4, etajul 3.

~n Pascal matricele bi, tri, .. n, dimensionale se declar\ scriind intervalele de numere


de coloane [i intervalele de numere de linii, de «etaje» [amd.

Exemplu:

X : ARRAY [1..3,1..4,0..5] OF INTEGER

Programarea calculatoarelor [i limbaje de programare 105 Dan Popa, 2007


O instrucţiune deosebită din Oberon: Bucla
LOOP … END
Părăsirea unei bucle, cum este cea a jocului dinainte, atunci când are loc o eroare sau se cere
expres acest lucru, este o chestiune dificilă. În mod normal ar trebui să schimbăm valoarea unei
variabile care face parte din condiţie şi să parcurgem toată bucla. Dar aceasta obligă la execuţia
altor instrucţiuni care ar putea produce efecte nedorite. Soluţia: O buclă cu instrucţiune de ieşire
explicită.

Sintaxa instruc]iunii LOOP… END este foarte simpl\. Deoarece bucla LOOP … END are o
instruc]iune explicit\ de p\r\sire a buclei, nu mai este nevoie s\ aib\ o condi]ie (test) nici la
`nceput (test ini]ial) nici la sf=r[it (test final). Prin urmare expresia boolean\ pe care o
`nt=lnea]i la buclele WHILE… DO …END [i REPEAT … UNTIL lipse[te iar bucla are
sintaxa:
LoopStatement =
LOOP StatementSequence END

Adic\ este format\ din cuv=ntul rezervat LOOP, secven]a de instruc]iuni


StatementSequence [i cuv=ntul rezervat END.

Semantica: Folosind bucla LOOP … END program\m computerul s\ execute `n mod repetat
(teoretic la infinit) instruc]iunile din secven]\. Execu]ia unei instruc]iunui EXIT opre[te
bucla, transfer=nd controlul execu]iei la prima instruc]iune de dup\ bucl\. Exemplu:
LOOP
Display.ReadInt(n,3,error);
IF n < 0 THEN EXIT END;
Display.WriteInt(n,3)
END
Este bucla care cite[te numerele `ntregi date de utilizator [i le afi[eaz\, oprindu-se la
`nt=lnirea unui num\r mai mic dec=t zero, care r\m=ne neafi[at.

Programarea calculatoarelor [i limbaje de programare 106 Dan Popa, 2007


Din punct de vedere al categoriie de construc]ii sintactice, LOOP …END este tot o instruc]
iune structurat\ (mai exact o structur\ repetitiv\). Poate participa pe post de component\ la
crearea unor structuri sintactice mai complexe (instruc]iuni structurate complexe) dup\
principiul pe[telui `nghi]it de alt pe[te. De asemenea poate con]ine alte instruc]iuni,
structurate sau nu, inclusiv secven]a de instruc]iuni (care e tot o structur\).


Obligatoriu, structura LOOP … END va trebui s\ con]in\ o alt\
structur\ alternativ\, care la r=ndul ei va con]ine printre alternative
instruc]iunea EXIT. ~n exemplul de mai sus, structura alternativ\ este IF…
THEN…END. ~n lipsa unei asemenea structuri ave]i ori o bucl\ care se
opre[te de prima dat\ (deoarece con- ]ine un EXIT, ori o bucl\ ce se va executa la infinit,
deoarece nu con]ine nici unul. Re]ine]i c\: instruc]iunea LOOP…END `[i arat\ utilitatea la
programarea acelor repet\rii de secven]e de instruc]iuni care au mai multe puncte de ie
[ire sau la cele la care punctul de ie[ire este `n mijlocul secven]ei ce se repet\.


Exerci]ii:
1.Rescrie]i jocul de mai sus, folosind bucla LOOP …END.
2. Ad\uga]i o variabil\ pentru colectarea banilor care se g\sesc `n s\lile
palatului. Valoarea ei va fi m\rit\ automat la intrarea `ntr-o nou\ sal\ iar din
acel moment suma r\mas\ `n sal\ va fi zero. Not\: Cele dou\ exerci]ii pot fi lucrate `n orice
ordine, independent sau simultan.


Despre sec]iunea TYPE a unei proceduri sau a unui modul: Ea con
]ine declara]ii de tipuri a[a cum sec]iunea VAR con]inea declara]ii de
variabile. Sec]iunea `ncepe cu TYPE. Urmeaz\ perechi de forma
identificator [i descriere de tip. ~ntre identificator [i descriere este
semnul egal (nu ':' ca la declara]iile de variabile). Descrierile de tip pot con]ine alte
descrieri de tip [.a.m.d, dup\ principiul pe[telui care a `nghi]it alt pe[te. Un tip care
poart\ un nume se nume[te tip nominal. Dac\ o variabil\ este declarat\ ca fiind de un
tip compus iar acest tip nu are nume, el se nume[te tip anonim. {i `n limbajele din
familia C-ului exist\ declara]ii de tipuri (cu nume dat de utilizator). Se scriu cu typedef.

Programarea calculatoarelor [i limbaje de programare 107 Dan Popa, 2007


8
Cap

De la RECORD-uri şi proceduri la obiecte


În capitolul precedent am făcut cunoştinţă cu noţiunea de RECORD.
În acest capitol intenţionăm să trecem de la RECORD-uri la Obiecte conform «ecuaţiei» :
Obiecte = RECORD-uri + Proceduri. Începem cu procedurile.
Conceptul matematic cel mai apropiat lor este cel de funcţie.

Func]ia este pentru matematicieni o rela]ie `ntre dou\ mul]imi de valori. Pe de o parte
valorile (grupate) ale argumentelor [i, pe de alt\ parte – corespunz\tor fiec\rui set de
argumente – valoarea func]iei. Pentru un programator care lucreaz\ `ntr-un limbaj imperativ,
func]ia (v\zut\ `n cel mai simplist mod cu putiin]\) este ceva asem\n\tor: un mod de a
calcula un rezultat pornind de la un set de valori date. Iat\ un exemplu:
Pentru matematician: f:R -> R prin rela]ia f(x) = x+1 este o func]ie. Remarca]i c\ el
trebuie s\ noteze despre ea urm\toarele elemente:
- Numele func]iei : f
- Tipul argumentului , mul]imea din care argumentul ia valori: R
- Tipul rezultatului: R
- Denumirea formal\ a argumentului : x
- {i la urm\ dar nu lipsit\ de importan]\, formula de calcul a rezultatului: x+1
Pentru un programator care transcrie func]ia `n tr-un limbaj de programare, de exemplu
limbajul Oberon, situa]ia este foarte asem\n\toare. La r=ndul s\u, va trebui s\ specifice
practic acelea[i elemente, dar `n limbajul de programare. Ordinea lor este doar pu]in diferit\.

Programarea calculatoarelor [i limbaje de programare 108 Dan Popa, 2007


- Numele func]iei : f
- Tipul argumentului , mul]imea din care argumentul ia valori: REAL
- Denumirea formal\ a argumentului : x
- Tipul rezultatului: REAL
- {i , la urm\ dar nu cea mai de pe urm\, formula de calcul a rezultatului: x+1
La modul cel mai general, func]ia poate face mai multe calcule, folosind mai multe variabile
pentru uzul ei intern dar `n final va trebui s\ returneze una din valorile ob]inute. Aceasta va
fi valoarea final\ a func]iei. ~n acest scop `n Oberon c=t [i `n limbajele din familia C-ului
exist\ o instruc]iune special\, RETURN, care se scrie urmat\ de o expresie:
RETURN <expresie>
Aceast\ instruc]iune `i spune practic func]iei: «Opre[te-te, ai g\sit rezultatul, este cel dat de
expresia urm\toare, po]i s\-l returnezi !». Cui ? Bine`n]eles expresiei `n care era nevoie de
valoarea func]iei, deoarece func]iile sunt cel mai des folosite (apelate) din expresii. De altfel
chiar fiind singure func]iile sunt un caz particular de expresii simple. Exemplu: f(3) este o
expresie.

Iat\ func]ia f, transcris\ `n Oberon:

PROCEDURE f (x: REAL) : REAL;


VAR rezultat : REAL;
BEGIN
rezultat:= x+1;
RETURN rezultat
END f;

C=rcota[ii vor replica : Este posibil s-o scriem mai simplu ! Le dau dreptate, func]ia de mai
sus se putea implementa sub forma:

PROCEDURE f (x: REAL) : REAL;


BEGIN
RETURN x+1
END f;

Programarea calculatoarelor [i limbaje de programare 109 Dan Popa, 2007


Dar `n acest caz nu mai erau vizibile `n exemplu dou\ lucruri: Faptul c\ func]ia sau
procedura poate folosi variabile locale (care dispar, se dealoc\, la terminarea ei), faptul c\
ea poate con]ine `ntre BEGIN [i END (`ntre acoladele din C [i limbajele derivate) o `ntreag\
secven]\ de instruc]iuni structurate [i faptul c\ RETURN (`n C se scrie cu minuscule:
return) este instruc]iunea prin care se anun]\ care este rezultatul final – lucru a c\rui
necesitate este evident\ `n cazul c=nd, av=nd mai multe variabile locale iar func]ia
calculeaz\ mai multe rezultate par]iale [i doar unul este cel returnat. Acest rezultat va
participa ca operand `n expresia `n care e folosit\ func]ia. (Ex: f(3) * 5 va da rezultatul 20 )

Observa]ie: Func]iile pot fi [i func]ii recursive, ca `n exemplul urm\tor care calculeaz\


valoarea factorialului unui num\r. Aten]ie: Pentru a evita `ns\ apelurile la infinit, succesive
ale func]iei, cazul (sau cazurile) de ie[ire din recursie trebuie s\ fie primul (primele) testat
(e). Dac\ suntem `n acea situa]ie, func]ia nu mai apeleaz\ recursiv o copie a ei. Programul
complet (un modul) este dat `n continuare.

MODULE FactRec;
IMPORT Display;
PROCEDURE Fact(n:INTEGER) :INTEGER;
VAR prod :INTEGER;
BEGIN
IF n=0 THEN
prod :=1
ELSE
prod :=n * Fact(n-1)
END;
RETURN (prod)
END Fact;

PROCEDURE ProgMain*;
VAR k:INTEGER;
BEGIN
FOR k:= 1 TO 10 DO

Programarea calculatoarelor [i limbaje de programare 110 Dan Popa, 2007


Display.WriteInt(k,10);
Display.WriteStr("!=");
Display.WriteInt(Fact(k),10);
Display.WriteLn;
END;
REPEAT UNTIL Display.KeyPressed();
END ProgMain;

END FactRec.

Procedura ProgMain nu face dec=t s\ afi[eze valorile lui n! Pentru n de la 1 la 7.

Nota]i c\: Demonstrarea corectitudinii felului cum calculeaz\ un rezultat o func]ie recursiv\
trebuie f\cut\ prin induc]ie matematic\.

C=teva observa]ii privitoare la folosirea func]iilor de acest fel (la care parametrul sau
parametrii sunt declara]i `n antetul func]iei f\r\ cuv=ntul VAR !):

- Func]ia poate apare `n expresii complexe: f(5)* f(x) -2*f(f(x) )


- Argumentul func]iei poate fi:
a) O constant\
b) O variabil\
c) O expresie
d) Sau chiar alt apel de func]ie, al alteia sau (caz rar) tot al ei

Programarea calculatoarelor [i limbaje de programare 111 Dan Popa, 2007


- Valoarea argumentului este evaluat\, calculat\. Aceast\ valoare se transmite func]iei.
Func]ia aloc\ memorie pentru parametrul s\u x (ca [i cum ar fi o nou\ variabil\), `i atribuie
valoarea rezultat\ din calculul de mai sus [i apoi trece la executarea sale instruc]iunilor ce o
compun. (Evident c\ `nainte de aceasta poate aloca [i memorie pentru variabilele ei locale –
cum era variabila «rezultat» din precedentul exemplu).Dat fiind c\ procedura f utilizeaz\ o
variabil\ nou\ c\reia `i atribuie valoarea expresiei ce-i este dat\ ca argument, acest tip de
transfer de parametri se nume[te TRANSFER PRIN VALOARE.

Important: Dac\ parametrul a fost o variabil\, valoarea acestuia nu este afectat\, orice ar fi
f\cut func]ia cu variabila ei x. (~n fond x e o alt\ variabil\ dec=t cea transmis\ ca argument
func]iei!).Re]ine]i c\ `n cazul transferului parametrilor prin valoare, procedura care
implementez\ func]ia (sau orice procedur\ care primeste datele prin mecanismul de
transfer prin valoare) nu poate modifica datele primite ci lucreaz\ cu copii ale acelor valori.

Acest lucru este [i bun [i r\u.


1) Dac\ nu doresc ca procedura s\ modifice valorile variabilelor transmise ca parametri,
transferul prin valoare este ideal, el protejeaz\ parametrii de modific\ri. Dezavantajul este
c\ dac\ ceea ce se transmite este o dat\ complex\, structurat\, care ocup\ mult\
memorie, (de exemplu o matrice de 100 x 100 elemente) atunci la fiecare apel se
consum\ o asemenea cantitate de memorie, iar copierea valorii consum\ un timp `n plus
(chiar dac\ uneori el nu este semnificativ).
2) Dac\ dimpotriv\ doresc s\ fac economie de memorie, s\ nu consum timp cu transferul
parametrilor sau am nevoie explicit\ ca procedura s\ opereze asupra variabilei
respective, (Ex: Imagina]i-v\ o procedur\ de Mobilare a palatului califului din jocul
anterior: prime[te palatul gol [i-l completeaz\ cu artefacte [i tot ce mai trebuie.), ei bine,
atunci va trebui s\ apelez la un alt fel de transfer de parametri, transferul prin referin]\
ceea ce implic\ s\ declar variabilele al c\ror con]inut se transfer\ astfel cu un VAR
`naintea listei lor. ~n acest caz nu se transfer\ valoarea variabilei parametru ci doar o
referin]\ la aceasta ( practic o adres\ asociat\ eventual cu ceva informa]ii despre tip). De
aceea mai este numit [i transfer prin referin]\. Procedura va lucra exact cu variabila
transmis\ ca parametru. Numele formal al parametrului (cel din antetul procedurii) devine
pe durata execu]iei acesteia o veritabil\ porecl\ a variabilei date ca argument. (Aten]ie
`ns\ s\ n-o modifice altfel dec=t am dori !)

Programarea calculatoarelor [i limbaje de programare 112 Dan Popa, 2007


Exemplul clasic al de folosire al parametrilor variabil\ este cel din povestea cu [colarul
care avea ca tem\ s\ scrie o procedur\ ce inverseaz\ valorile a dou\ variabile. Iat\
programul s\u, la prima `ncercare (nota bene, gre[it\) de a-l scrie:

MODULE Schimbare;
IMPORT Display;

PROCEDURE Schimb(a,b :INTEGER);


VAR aux :INTEGER;
BEGIN
aux :=a; (* aux ia valoarea lui a *)
a :=b; (* a ia valoarea lui b *)
b :=aux; (* b ia valoarea fostului a , din variabila aux *)
END Schimb;

PROCEDURE ProgMain*;
VAR x,y :INTEGER;
BEGIN
x :=3; y :=5;
Schimb(x,y);
Display.WriteInt(x,2);
Display.WriteInt(y,2);
REPEAT UNTIL Display.KeyPressed()
END ProgMain;
END Schimbare.
Spre marea surpriz\ a elevului de care povesteam, execu]ia programului duce la un rezultat
neasteptat, x are tot valoarea 3, iar y tot valoarea 5.

Programarea calculatoarelor [i limbaje de programare 113 Dan Popa, 2007


Pur [i simplu variabilele x [i y din procedura principal\ ProgMain r\m`n cu vechile valori,
lucru de altfel de `n]eles la o analiz\ atent\. Parametrii fiind transmi[i prin valoare, procedura
“Schimba” a operat asupra copiilor acestor valori (parametrii s\i a [i b), nicidecum asupra
originalelor x [i y. Acestea din urm\ au r\mas neafectate.

Solu]ia este simpl\, declara]i parametrii procedurii schimb\ ca fiind parametri variabil\,
transmi[i prin referin]\ (sinonim). Se scrie un VAR `naintea listei parametrilor viza]i. Acum
procedura va ar\ta a[a:

PROCEDURE Schimb(VAR a,b :INTEGER);


VAR aux :INTEGER;
BEGIN
aux :=a; a :=b; b :=aux;
END Schimb;

Iar la momentul execu]iei schimbarea celor dou\ valori va fi vizibil\:

Am vorbit `n acest capitol despre func]ii [i implementarea lor apoi am trecut la proceduri.
Oberon [i C nu fac deosebire ca limbajul Pascal `ntre func]ii (FUNCTION) [i proceduri
(PROCEDURES). ~n Oberon toate sunt numite proceduri. Iar `n limbajele din familia C-ului
toate sunt numite func]ii !! E drept, unele posed\ un tip (al rezultatului) declarat, con]in
instruc]iunea RETURN [i pot fi apelate din expresii, fiind numite `n Oberon “function
procedure”, ceea ce am tradus prin proceduri func]ionale. Celelalte nu au un tip declarat al
rezultatului iar dac\ folosesc RETURN (far\ expresie dup\ el) `l folosesc doar pentru a
programa astfel terminarea imediat\ a procedurii. ~n C, “return” se scrie cu minuscule.
O prezentare scurt\ dar bine f\cut\ a procedurilor g\si]i `n Help-ul mediului de programare
POW. ~n continuare o vom traduce [i o vom comenta, comentariile fiind `n paranteze:

Programarea calculatoarelor [i limbaje de programare 114 Dan Popa, 2007


O declara]ie de procedur\ const\ `n antetul procedurii [i corpul procedurii. (Deci de fapt
procedura este o declara]ie care introduce o nou\ instruc]iune sau o nou\ func]ie care poate
apare `n expresii.) Antetul con]ine identificatorul procedurii [i lista de parametri formali.
(Vom vedea c\ unii autori trateaz\ procedura ca [i cum tipul rezultatului ar face parte dintre
parametri. ) Corpul procedurii con]ine declara]iile [i instruc]iunile. (Procedura poate folosi `n
cursul execu]iei sale ni[te entit\]i locale, care vor fiin]a doar `n timpul c=t ea ruleaz\ [i vor
dispare la sf\r[itul ei. Ele trebuie `ns\ declarate, orice-ar fi fiind acestea: constante, tipuri,
variabile sau de ce nu alte proceduri de uz intern.) Identificatorul procedurii se scrie `nc\ o
dat\ la finalul acesteia (regul\ specific\ Oberon-ului).

Exist\ dou\ categorii de proceduri: procedurile proprii (propriu-zise) [i procedurile-func]ie


(am tradus adesea “function-procedure” prin “proceduri func]ionale”). Ultimele sunt apelate,
puse `n execu]ie, atunci c=nd sunt folosite `n expresii. Ca urmare a apelului de procedur\
func]ional\ (sau pe scurt func]ie) valoarea `ntoars\ de aceasta particip\ ca operand `ntr-o
expresie. Recunoa[te]i o asemenea procedur\ dup\ specificarea tipului rezultatului care
`nso]e[te lista de parametri. Corpul unei asemenea proceduri, `ntre BEGIN [i END sau `ntre
acolade (cazul C-ului) va con]ine obligatoriu o instruc]iune RETURN <expresie> (return
<expresie> `n C) unde <expresie> este expresia aritmetic\ a rezultatul acesteia.
Toate constantele, variabilele, tipurile [i procedurile declarate `n interiorul corpului procedurii
(`n zona pentru declara]ii) sunt entit\]i locale procedurii. Deoarece printre entit\]ile care se
declar\ sunt [i procedurile, rezult\ c\ declara]iile de proceduri pot fi imbricate (`ncuib\rite
adic\ puse una `n alta). Apelul unei proceduri f\cut de undeva din grupul de instruc]iuni al
care-i apar]ine determin\ o activare recursiv\. (Porne[te deci o nou\ copie a procedurii, cu
noi entit\]i locale [i a[a mai departe – eventual de c=te ori este nevoie. Starea vechii
proceduri `mpreun\ cu entit\]ile ei locale – variabile cel mai adesea – r\m=ne memorat\
`ntr-o stiv\, a[tept=nd pentru continuarea execu]iei ca procedura copie s\-[i termine ea `nt=i
treaba.)

Pe l=ng\ entit\]ile locale [i parametrii formali (a[a cum sunt ei declara]i `n antetul
procedurii), alte entit\]i (de obicei variabile) existente `n exteriorul procedurii (deci `n
procedura exterioar\ sau `n modulul ce o cuprinde) sunt de asemenea vizibile [i deci
utilizabile de c\tre instruc]iunile procedurii. Excep]ie fac acele entit\]i din exterior care au
acelea[i nume ca entit\]ile declarate local.

Programarea calculatoarelor [i limbaje de programare 115 Dan Popa, 2007


~n documenta]ia electronic\ a limbajului Oberon sunt date urm\toarele reguli de sintax\ (`n
limba englez\):

ProcedureDeclaration = ProcedureHeading ";" ProcedureBody ident.


ProcedureHeading = PROCEDURE [Receiver] IdentDef [FormalParameters].
ProcedureBody = DeclarationSequence [BEGIN StatementSequence] END.
DeclarationSequence = {CONST {ConstantDeclaration ";"} TYPE
{TypeDeclaration ";"} | VAR {VariableDeclaration ";"}} {ProcedureDeclaration
";" | ForwardDeclaration ";"}.
ForwardDeclaration=PROCEDURE"^"[Receiver] IdentDef [FormalParameters].

Printre nout\]ile care deosebesc Oberon-ul de bunicul s\u Pascal-ul, figureaz\:


Identificatorul din finalul procedurii (pu]in spectaculos!), un parametru (de obicei parametru
variabil\ de un tip record sau pointer la record) numit Receiver adic\ Receptor (care
introduce un nume pentru obiectul curent) [i o alt\ form\ de declara]ie a unei proceduri `n
avans. Despre ultimele dou\ g\si]i explica]iile de mai jos `n documenta]ia electronic\:
Dac\ o declara]ie de procedur\ specific\ un parametru receptor, procedura este
considerat\ ca fiind ata[at\ unui tip de date (de obicei un tip RECORD care devine `n
acest fel o clas\ de obiecte).
O declara]ie `n avans (ForwardDeclaration – cum exist\ `n Pascal sau Oberon) serve[te la
anun]area anticipat\ a unei proceduri a c\rei declara]ie apare mult mai departe `n text.
(Acest lucru permite compilatorului s\ compileze apeluri ale unor proceduri pe care nu le-a
`nt=lnit deja.) Evident, listele parametrilor formali din declara]ia procedurii [i din declara]ia
f\cut\ `n avans (care const\ dintr-un sinplu antet `n care apare c\ciuli]a dup\ PROCEDURE)
trebuie s\ se potriveasc\ perfect.

Apelul procedurilor se face astfel: Din acela[i modul: Scrie]i numele procedurii [i lista de
parametri actuali. Din alt modul: Scrie]i numele sau aliasul (porecla) modulului care g\zduie-
[te procedura, operatorul punct , identificatorul procedurii [i lista de parametri. ~n acest caz
identificatorul procedurii trebuie marcat cu *, la prima apari]ie `n declara]ie (nu [i la finalul
procedurii). La fel [i la procedurile func]ionale apelate din expresii.

Programarea calculatoarelor [i limbaje de programare 116 Dan Popa, 2007


Şi totuşi cum gîndim o problemă în mod
“bazat pe obiecte” ?

În loc să ne gîndim la program, funcţii şi proceduri, ne gîndim la obiectele lumii de modelat şi la


interacţiunile dintre ele. Proiectarea obiectelor (de fapt a claselor de obiecte) include proiectarea
datelor şi metodelor (proceduri), acestea din urmă fiind de fapt acţiunile pe care le fac obiectele, la
cerere, asupra datelor proprii sau asupra altor obiecte.


Defini]ie: O clas\ de obiecte este un nou tip de date. De fapt un tip de
date obiect este un tip RECORD (`nregistrare) care pe l=ng\ componentele
statice (datele) mai are ni[te componente dinamice (metodele). Este
suficient s\ g\sim o modalitate de a descrie metodele `n limbajul de
programare – ceea ce se face scriind proceduri [i apoi s\ ata[\m aceste proceduri tipului
de date RECORD care astfel va deveni obiect. Mai `nt=i trebuie cunoscute c=teva
generalit\]i despre obiecte.Ideea central\ este: OBIECTE = RECORD-uri + Proceduri
~n Oberon spre deosebire de alte limbaje moderne mai s\race, sunt posibile dou\ moduri de
a ata[a procedurile de un record:
a) RECORD-ul este indicat ca receptor (receiver) al unei proceduri legate la tip. Aceasta `i
devine ata[at\, devenind metod\. Toate obiectele unei clase au ata[ate acelea[i proceduri.
De aceea se spune c\ ele sunt legate de tipul de date (clasa) nu de un obiect anume din
acea clas\.
b) RECORD-ul con]ine c=mpuri procedurale, acele c=mpuri a c\ror valoare nu este un
num\r un string ci un nume de procedur\. Exist\ o restric]ie aici: E vorba de proceduri av=nd
aceea[i semn\tur\,(acelea[i tipuri la parametri [i rezultat) lucru de altfel normal deoarece
denumirea c=mpului se va comporta ca un alias al acelei proceduri. Vom putea pune
procedura din record la treab\ chem=nd-o dup\ numele c=mpului procedural [i d=ndu-i
parametri. Ace[tia `i vor fi transmi[i exact procedurii a c\rui nume e stocat `n c=mp. Re]ine]i
deci c\ vom `nt=lni un nou tip de date a c\rui valoare este o procedur\ (cu o anumit\
semn\tur\ dat\ din momentul declar\rii c=mpului). Astfel se pot realiza obiecte din aceea[i
clas\ dar care, sub un nume de metod\ comun ascund algoritmi diferi]i de la un obiect la
altul. Nota]i [i faptul c\ `n C (C++) `n locul c=mpurilor procedurale folosim pointeri la func]ii.

Programarea calculatoarelor [i limbaje de programare 117 Dan Popa, 2007



Re]ine]i: Procedurile legate la tip sunt un prim mod de a `nzestra
RECORD-urile cu metode, ceea ce le face s\ devin\ obiecte. Aceste
metode nu se pot schimba pentru un obiect - deci toate obiectele dintr-o
clas\ vor procesa date dup\ acela[i algoritm - dar pot prelucra date ale
obiectului respectiv , date diferite ca valoare de la o instan]\ a unui obiect la alta. Algoritmul
dup\ care se face prelucrarea este `ns\ acela[i [i este dat de procedura legat\ la tip.
Majoritatea limbajelor moderne de programare, bazate pe obiecte sau orientate obiect
folosesc aceast\ legare a procedurilor la tip.


Sintactic vorbind se scriu ca ni[te proceduri obi[nuite care prelucreaz\ un
parametru de tip RECORD, declarat cu VAR. (Vom vedea c\ asemenea
parametri declara]i cu VAR pot fi modifica]i ca efect al instruc]iunilor din
procedur\.) Iat\ un exemplu de procedur\ care afi[eaz\ ziua luna [i anul na
[terii unei persoane, presupuse a fi stocate `ntr-un RECORD cu componentele respective.
Declara]ia tipului RECORD numit DataNa[terii o scrie]i dumneavoastr\. Variabila se putea
s\ fie declarat\ a[a: VAR pers : DataNa[terii. (Observa]ie: Am scris cu [ de[i nu e din
alfabetul limbajului !)

PROCEDURE Afi[are( …..); (*pot fi [i al]i parametri*)


BEGIN
Display.WriteInt( pers.ziua,3);
Display.WriteInt( pers.luna,3);
Display.WriteInt( pers.anul,3);
END Afi[are;

Pentru a lega procedura la tip trebuie s\-i punem `n antet tipul de date la care se leag\ [i s\
preciz\m cum se va numi, `n corpul procedurii, obiectul respectiv. Unele limbaje au o
denumire generic\ pentru obiectul `nsu[i: de exemplu `n C^^ aceasta este this iar acest this
este un pointer la obiectul `nsu[i aflat chiar `n structura lui. Oberon permite s\ numi]i obiectul
`nsu[i cu orice nume (identificator) de variabil\, iar aceasta trebuie declarat\ cu VAR [i
plasat\ `ntr-o parantez\ ~NAINTEA numelui procedurii dar DUP| cuv=ntul rezervat
PROCEDURE. Procedura de mai `nainte s-ar rescrie, dac\ o leg\m la tipul DataNa[terii,a[a:

Programarea calculatoarelor [i limbaje de programare 118 Dan Popa, 2007


PROCEDURE (VAR pers : DataNa[terii ) Afi[are( …..);
BEGIN
Display.WriteInt( pers.ziua,3);
Display.WriteInt( pers.luna,3);
Display.WriteInt( pers.anul,3);
END Afi[are;

Ca [i la orice declara]ie de parametru al unei proceduri, numele parametrului poate fi


oricare, procedura va func]iona la fel. De exemplu se putea scrie:

PROCEDURE (VAR q: DataNa[terii ) Afi[are( …..);


BEGIN Display.WriteInt( q.ziua,3);
Display.WriteInt( q.luna,3);
Display.WriteInt( q.anul,3);
END Afi[are;
Noutatea: Atunci c=nd avem o variabil\ (sau alt\ entitate: element de vector, c=mp dintr-un
RECORD , pointer dereferen]iat – vom vorbi de el cu alt\ ocazie) care este de tipul DataNa-
[terii este posibil s\-i folosim denumirea exact ca pe un nume de modul [i s\ apel\m
procedura legat\ la tip, exact cum apelam procedurile dintr-un modul. Numai c\ acum e
vorba de procedura “dintr-un obiect”. Concret, dac\ avem variabila ZiuaMea: DataNa[terii,
putem apela:
ZiuaMea. Afi[are (….)
Sau putem folosi aceast\ valoare `n expresii, dac\ e vorba de o procedur\ func]ional\,
capabil\ a returna o valoare (adic\ de o procedur\ care implementeaz\ o func]ie
matematic\).
Ceilal]i parametri ai procedurii nu i-am mai scris dar `n practic\ ei exist\. Ideea c\ metoda
obiectului prelucreaz\ numai datele proprii ale acestuia este gre[it\. Metoda poate prelucra
[i date venite dinafar\, parametrii da]i `n momentul apelului. De fapt a[a interac]ioneaz\
obiectele, un obiect `ncredin]eaz\ ni[te valori (de obicei provenite din datele proprii) unei
metode a unui alt obiect. Acesta ac]ioneaz\ asupra datelor primite conform cu specificul
obiectului al doilea, specific memorat `n datele sale. Algoritmul de calcul va fi `ns\ acela[i
pentru toate prelucr\rile f\cute de obiectele din clasa obiectului al doilea. Cred c\ v\ este

Programarea calculatoarelor [i limbaje de programare 119 Dan Popa, 2007


deja este clar c\ un tip de date nou definit, ale c\rui valori sunt obiecte (corect se spune
a c\rui instan]e sunt obiectele) se nume[te clas\ de obiecte sau pe scurt clas\.

Obiectele au un ciclu de via]\. Na[terea lor este urmat\ de o ini]ializare a c=mpurilor cu


date din cadrul lor ([i a tabelei de metode redefinibile, ceea ce se face automat – pentru cei
care vor s\ afle mai mult). Procedurile care ini]ializeaz\ obiecte se numesc `n unele limbaje
Constructori. ~n Turbo Pascal, un nume tradi]ional pentru ele este Init. ~n alte limbaje (ex.
`n C^^) constructorul este obligat s\ poarte numele clasei [i, spre deosebire de
procedurile obi[nuite este apelat AUTOMAT `n momentul declar\rii unei variabile sau intr\rii
`n procedura ori unitatea de program (modulul) care are o asemenea variabil\ local\. ~n
Oberon va trebui `ns\ apelat explicit deoarece spre deosebire de C++ Oberon nu apeleaz\
automat constructorii la declararea unor variabile sau obiecte. Unele limbaje (inclusiv C++)
permit s\ defini]i [i un Destructor, procedur\ care poart\ tot numele clasei dar este `nso]it
de un simbol special (pentru a-l deosebi de constructor). Destructorul este `n asemenea
limbaje apelat automat la dealocarea variabilei sau la ie[irea din blocul `n care variabila este
local\. Acolo (ex. `n C^^), pentru fiecare variabil\ local\ care este distrus\ la ie[irea dintr-o
procedur\ sau dintr-o unitate de program este apelat automat destructorul corespunz\tor `n
caz c\ a]i scris dumneavoastr\ unul. Efectele pot fi spectaculoase: dac\ variabila are o
reprezentare grafic\ pe ecran destructorul poate fi pus s-o [tearg\, s-o fac\ s\ explodeze
(de exemplu `n jocurile video) f\r\ s\ scrie]i o linie de cod ! Sau pot fi mai pu]in
spectaculoase dar la fel de utile: dac\ variabila (care poate fi structur\ sau obiect) are ata[at
un vector sau o matrice referit(\) printr-o component\ pointer (cam ca un om care poart\ o
pung\ cu efecte uzate) destructorul poate fi pus s\ dealoce automat zona de memorie a
matricei (imagina]i-v\ aruncarea la co[ a pungii cu efecte!).

Programarea calculatoarelor [i limbaje de programare 120 Dan Popa, 2007


Un exemplu comentat :
palatul califului … bazat pe obiecte.

Ideea centrală este: a ne imagina aplicaţia ca fiind formată din obiecte capabile să facă ceea ce au
de făcut.

S\ ne imagin\m palatul califului format din s\li iar aceste s\li `nzestrate cu capacitatea de a
interac]iona cu noi, cu alte cuvinte de a se juca cu noi. Fiecare sal\ va fi un obiect [i va
avea metode: O metod\ Init pentru ini]ializarea datelor din obiect (un constructor, dar apelat
explicit) [i o metod\ Play care surprinde desf\[urarea jocului `ntr-o camer\ din palat, cu tot
dialogul.
Practic `n clipa `n care dispunem de obiecte din clasa Camera, capabile s\ «se joace» cu
noi, programul principal devine extrem de simplu. Dup\ ini]ializarea obiectelor (care se va
face cu metoda Init a fiec\rui obiect) este suficient s\ stabilim drept camer\ curent\ camera
ini]ial\ [i s\ apel\m metoda Play pentru camera curent\ (salacrt). Metoda va actualiza,
modific=nd dac\ este cazul, num\rul s\lii curente pe care-l prime[te ca parametru variabil\.
Programul principal este practic concentrat `n c=teva r=nduri:

salacrt:=0;
WHILE TRUE DO
p[salacrt].Play(salacrt)
END

Not\: variant\ de mai sus corespunde unui joc jucat la infinit, f\r\ acea ie[ire `n de[ert
(codificat prin –2). ~n acest al doilea caz ar fi fost:

salacrt:=0;

Programarea calculatoarelor [i limbaje de programare 121 Dan Popa, 2007


WHILE salacrt # -2 DO
p[salacrt].Play(salacrt)
END
Dar r\m=nea `n continuare la fel de simplu.

S\ coment\m programul, realizat de data aceasta `ntr-un mod bazat pe obiecte, singura
clas\ fiind clasa Camera, iar obiectele folosite ca elemente ale vectorului Palat. (Afl\m deci
c\ se pot declara [i vectori de obiecte, tipul de dat\ obiect put=nd participa la creare de date
complexe, structurate.) Declara]iile ini]iale sunt la fel, cu observa]ia c\ vom ad\uga ulterior
procedurile (metodele) necesare transform\rii tipului de date Camera `n clas\ de obiecte.

MODULE PalatObj;
IMPORT Display;

TYPE Camera=RECORD
Nr : INTEGER;
Denumire : ARRAY 30 OF CHAR;
Artefact : ARRAY 20 OF CHAR;
Bani : INTEGER;
Usa : ARRAY 4 OF INTEGER;
END;

Palat=ARRAY 6 OF Camera;

Constructorul, procedura de ini]ializare pentru tipul de date Camera, ar putea ar\ta ca mai
jos. Ea prime[te informa]iile ca parametri [i le stocheaz\ `n obiect. Remarca]i cum se
face copierea unui string, liter\ cu liter\, cu ajutorul unei bucle FOR. Unele limbaje au o
func]ie sau o procedur\ proprie pentru a realiza asemenea copieri de stringuri. ~n C se nume
[te «strcpy». ~n Oberon, o colec]ie de proceduri care fac opera]ii cu stringuri g\si]i `n
modulul Strings.

Programarea calculatoarelor [i limbaje de programare 122 Dan Popa, 2007


PROCEDURE(VAR c:Camera) Init (NrP:INTEGER;
DenumireP:ARRAY 30 OF CHAR;
ArtefactP: ARRAY 20 OF CHAR; BaniP: INTEGER;
Usa0P, Usa1P, Usa2P, Usa3P:INTEGER);
BEGIN
c.Nr:=NrP;
c.Bani:=BaniP;
c.Usa[0]:=Usa0P;
c.Usa[1]:=Usa1P;
c.Usa[2]:=Usa2P;
c.Usa[3]:=Usa3P;
COPY (DenumireP, c.Denumire);
COPY (ArtefactP, c.Artefact);
END Init;

Observa]i c\ parametrii procedurii au denumiri asem\n\toare c=mpurilor din structura


obiectului, dar terminate cu litera P. Acest lucru NU ESTE OBLIGATORIU fiind doar un
artificiu mnemotehnic. Procedura copie valorile primite ca parametri `n c=mpurile din
obiectul c. Observa]i cum este declarat c, el asigur\ legarea procedurii la tip.
Cum se va face ini]ializarea (la noi este de fapt «mobilarea» ) unei camere?
Apel=nd metoda Init. Fie X camera vizat\, sau designatorul ei. Se va scrie, de exemplu
pentru sala de intrare, cu conven]ia noastr\ din capitolul precedent –
«u[a `nchis\ este notat\ cu –1» , ca mai jos:

X.Init(0,"Sala de intrare", "strajer", 100, -1,-1,-1,1);

Valorile date ca parametri actuali vor fi `n final stocate `n c=mpurile obiectului X. B\nui]i c\
X va fi `nlocuit cu p[0], elementul cu indicele zero din vectorul palat.
Ce mai [tiu s\ fac\ obiectele noastre din clasa Camera? S\ se joace cu juc\torul uman.
Scriem instruc]iunile respective, grupate `ntr-o procedur\ pe care o vom numi chiar Play
(`nseamn\ joc `n englez\, dar pute]i s\-i da]i [i un nume autohton, ceea ce e chiar indicat,
deoarece face programul mai u[or de citit):

Programarea calculatoarelor [i limbaje de programare 123 Dan Popa, 2007


PROCEDURE(VAR c: Camera) Play(VAR salacrt:INTEGER);
VAR err:CHAR; nrusa:INTEGER;
BEGIN
Display.WriteStr(" Esti in sala nr ");
Display.WriteInt(salacrt,2); Display.WriteLn;
Display.WriteStr(" Este sala ");
Display.WriteStr( c . Denumire); Display.WriteLn;
Display.WriteStr(" Gasesti un");
Display.WriteStr(c . Artefact); Display.WriteLn;
Display.WriteStr(" Sunt si bani in nr de ");
Display.WriteInt(c . Bani,6); Display.WriteLn;
Display.WriteStr(" Pe ce usa iesi ?");
Display.ReadInt( nrusa, 2,err);
IF (nrusa <0) OR (nrusa >3)
THEN Display.WriteStr(" Usa nu exista !")
ELSIF c.Usa[nrusa]= -1
THEN Display.WriteStr(" Usa e inchisa!")
ELSE
salacrt:=c.Usa[nrusa]
END;
END Play;

Ca de obicei, num\rul de pe eticheta u[ii indic\ sala destina]ie, aceasta fiind conven]ia dup\
care am realizat planul palatului. Ea asigur\ astfel leg\tura `ntre s\li. Remarca]i [i c=t de
mult s-au simplificat designatorii. Nici vorb\ de

P[salacrt].Usa[nrusa]

Se scrie doar: c.Usa[nrusa].


De asemenea, remarca]i c\ variabila nrusa, o informa]ie care prive[te decizia juc\torului
luat\ `ntr-o camer\ a fost declarat\ variabil\ local\ la nivelul acestei proceduri. Ea nu mai

Programarea calculatoarelor [i limbaje de programare 124 Dan Popa, 2007


trebuie declarat\ `n procedura principal\ ProgMain, contribuind astfel la simplificarea
acesteia. Iat\ [i aceast\ procedur\ principal\:

PROCEDURE ProgMain*;
VAR p: Palat; (* e un vector de obiecte de tip Camera*)
salacrt:INTEGER;

BEGIN
p[0].Init(0,"Sala de intrare", "strajer", 100, -1,-1,-1,1);
p[1].Init(1,"Sala de judecata", "cadiu",200,-1,0,4, 2);
p[2].Init(2,"Sala armurilor", "pumnal", 500,-1,1,5,3);
p[3].Init(3,"Sala de mese", "oaspete", 1000, -1, 2, -1,-1);
p[4].Init(4,"Sala cu tezaur","tezaur", 10000, 1,-1,-1,5);
p[5].Init(5,"Sala de arme", "jungher", 300, 2,4,-1,-1);
salacrt:=0;
WHILE TRUE DO
p[salacrt].Play(salacrt)
END
END ProgMain;
END PalatObj.

Remarca]i ce simpl\ este descrierea unui palat cu 6 s\li! Doar 6 r=nduri de program, nu
aproape 50! De asemenea, jocul propriu-zis este mult simplificat, deoarece la acest nivel tot
ce am de f\cut este s\ apelez metoda Play a s\lii curente [i s\-i dau drept parametru de
prelucrat tocmai variabila salacrt, `n vederea modific\rii. Observa]i c\ `n procedura Play,
parametrul salacrt este declarat cu un VAR `n fa]\, ceea ce `nseamn\ (conform unei
conven]ii care exist\ [i `n Pascal), exact c\ procedura poate MODIFICA valoarea acestei
variabile date ca parametru [i nu va lucra cu o copie a ei ci cu `ns\[i variabila transmis\.

~n continuare vom ilustra alt mod, al doilea, de transformare a RECORD-urilor `n obiecte:

Programarea calculatoarelor [i limbaje de programare 125 Dan Popa, 2007


Utilizarea cîmpurilor procedurale
Idee: Se pot defini variabile a căror valoare este o procedură.O dată de acest tip poate fi
componentă a unui RECORD. Aceste tipuri noi de date se numesc tipuri procedurale. Unor
obiecte din aceeaşi clasă li se pot astfel atribui, la execuţie, comportamente (metode) diferite,
ascunse sub un aceleaşi nume.

Expresia `n limba englez\ care denume[te tipurile procedurale este: «Procedure types». ~n
documenta]ia electronic\ (a mediului Pow) o g\si]i `n dreptul cuv=ntului rezervat procedure,
unde este a doua pe lista de no]iuni legate de acest cuv=nt.l Textul inclus ca explica]ie este
scurt:

“Variables of a procedure type T have a procedure (or NIL) as value. If a procedure P is


assigned to a variable of type T, the formal parameter lists of P and T must match. P must
not be a predeclared or type-bound procedure nor may it be local to another procedure.

ProcedureType = PROCEDURE[FormalParameters].“ (am `ncheiat citatul)

Ceea ce `n traducere s-ar transcrie a[a: Variabilele de un tip procedural T pot avea ca
valoare o procedur\ sau constanta NIL (care `nseamn\ “nimic”). Dac\ o procedur\ P este
atribuit\ ca valoare a unei variabile de un asemenea tip T, lista parametrilor formali ai
procedurii [i lista parametrilor formali din declara]ia tipului T trebuie s\ se potriveasc\. P nu
poate fi o procedur\ predeclarat\ [i nici o procedur\ legat\ la tip sau o procedur\ interioar\
alteia.

Practic descrierea unui tip procedural poate fi ori cuv=ntul PROCEDURE f\r\ nume sau
parametri, ori cuv=ntul PROCEDURE neurmat de numele procedurii dar cu o list\ de
parametri formali. {tim deja c\ la proceduri, felul cum numim parametrii este nerelevant,
deci cea ce conteaz\ este tipul lor [i ordinea acestor tipuri `n antetul procedurii.
Iat\ cum ar putea ar\ta vechiul program cu palatul califului dac\ am utiliza c=mpuri
procedurale pentru a `nzestra fiecare camer\ din palat cu o procedur\ “Int`mplare” - diferit\

Programarea calculatoarelor [i limbaje de programare 126 Dan Popa, 2007


de la camer\ la camer\ . La aceast\ implementare clasa de obiecte Camera este definit\
`ntr-un modul separat (al doilea modul al proiectului).Iat\-l:

MODULE camere;

IMPORT Display,S:=Strings;

CONST xxx=6 ; (* 6 spatii pentru afisat numere*)

TYPE
Actiune=PROCEDURE (*fara nume*) (expnum:INTEGER);
Camera*=RECORD
nr*:INTEGER;
nume*: ARRAY 30 OF CHAR; (* String de 30 de caractere *)
obiect*: ARRAY 10 OF CHAR; (* String de 10 caractere *)
usa*: ARRAY 4 OF INTEGER; (* Vector de 4 numere de camere *)
bani*:INTEGER;
intamplare*: Actiune; (* Camp procedural *)
END;

PROCEDURE AiciEste*(c:Camera);
BEGIN
Display.WriteStr("Esti in camera nr:");
Display.WriteInt(c.nr,xxx);
Display.WriteStr("Aceasta este ");
Display.WriteStr(c.nume);
Display.WriteStr("Aici gasesti un:");
Display.WriteStr(c.obiect);
Display.WriteStr("Sunt si bani in numar de;");
Display.WriteInt(c.bani,xxx);
END AiciEste;

Programarea calculatoarelor [i limbaje de programare 127 Dan Popa, 2007


PROCEDURE Strajeri*(expnum:INTEGER);
VAR nrstrajer:INTEGER; err:CHAR;
BEGIN
Display.WriteStr(" Te opresc trei strajeri.");
Display.WriteStr(" Te intreaba care e mai puternic dintre ei.") ;
REPEAT
Display.WriteStr(" Alege intre numarul 1 2 si 3");
Display.ReadInt(nrstrajer,xxx,err);
UNTIL nrstrajer=expnum MOD 3 +1 ; (*MOD e operatorul modulo*)
Display.WriteStr("Strajerii te lasa sa pleci");
END Strajeri;

PROCEDURE Fantome*(expnum:INTEGER);
VAR nrmagic,i:INTEGER; cuvant:ARRAY 10 OF CHAR; err:CHAR;
BEGIN
Display.WriteStr(" Te sperie niste fantome.");
Display.WriteStr(" Trebuie sa le spui de cateva ori fraze magice. ") ;
nrmagic:=expnum MOD 3 +1 ;
FOR i:= 1 TO nrmagic DO
Display.ReadStr(cuvant,10,err);
END;
Display.WriteStr("Fantomele te lasa sa pleci");
END Fantome;

PROCEDURE Tezaur*(expnum:INTEGER);
VAR
BEGIN
Display.WriteStr("Tezaurul te orbeste cu stralucirea lui.")
END Tezaur;

END camere.

Programarea calculatoarelor [i limbaje de programare 128 Dan Popa, 2007


Primul modul, modulul principal, arat\ aproape la fel cu cel de la solu]ia din capitolul
precedent. Diferen]ele sunt dou\: Prima e faptul c\ se import\ modulul Camera [i folose[te
tot ceea ce export\ acesta. A doua e c\ `n fiecare camer\ se plaseaz\ o alt\ `nt=mplare (o
alt\ valoare a c=mpului procedural):
MODULE Calif;
IMPORT Display, C:=Camere;
CONST NrCamere=3;
inchisa= -1;
desert=3;
cifre=3;
TYPE Palat=ARRAY NrCamere OF C.Camera;
(* vector cu elementele de un tip declarat `n alt modul*)
PROCEDURE ProgMain*;
VAR p:Palat; salacrt:INTEGER; nrusa:INTEGER;
err:CHAR;
BEGIN
p[0].nr:=0;
p[0].nume:="Sala de intrare ";
p[0].obiect:="tablou ";
p[0].usa[0]:=inchisa;
p[0].usa[1]:=inchisa;
p[0].usa[2]:=+1;
p[0].usa[3]:=inchisa;
p[0].bani:=100;
p[0].intamplare:=C.Strajeri; (* dau valoare c=mpului procedural*)
p[1].nr:=1;
p[1].nume:="Sala tronului ";
p[1].obiect:="tron ";
p[1].usa[0]:=0;
p[1].usa[1]:=inchisa;
p[1].usa[2]:=inchisa;
p[1].usa[3]:=2;

Programarea calculatoarelor [i limbaje de programare 129 Dan Popa, 2007


p[1].bani:=500;
p[1].intamplare:=C.Fantome; (* dau valoare c=mpului procedural*)
p[2].nr:=2;
p[2].nume:="Sala tezaurului ";
p[2].obiect:="tezaur";
p[2].usa[0]:=0;
p[2].usa[1]:=1;
p[2].usa[2]:=desert;
p[2].usa[3]:=inchisa;
p[2].bani:=10000;
p[2].intamplare:=C.Tezaur; (* dau valoare c=mpului procedural*)
salacrt:=0;
WHILE salacrt # desert DO
C. AiciEste(p[salacrt]);
p[salacrt].intamplare( p[salacrt].nr ); (* indiferent care! *)
Display.WriteStr("Pe ce usa vrei sa iesi?"); Display.WriteLn;
Display.ReadInt(nrusa, cifre,err);
IF (nrusa < 0) OR (nrusa > 3)
THEN Display.WriteStr("Usa nu exista");
ELSIF p[salacrt].usa[nrusa] = inchisa
THEN Display.WriteStr("Usa e inchisa !")
ELSE
salacrt:=p[salacrt].usa[nrusa]
END;
END;
Display.WriteStr("Game Over ! Apasa o tasta");
REPEAT UNTIL Display.KeyPressed()
END ProgMain;

END Calif.

Programarea calculatoarelor [i limbaje de programare 130 Dan Popa, 2007



Observa]i c\ toate procedurile din modulul “camere” sunt exportate [i
folosite la ini]ializarea c=mpurilor procedurale. La fel sunt exportate [i
toate c=mpurile obiectelor din clasa Camera. Ca un minus al acestei
solu]ii remarca]i lipsa constructorului [i a procedurii (metodei) Play.
Totu[i `n locul ei `n modulul Camere figureaz\ o procedur\ mai scurt\, numit\
“AiciEste”. Ea afi[eaz\ mesajele explicative din fiecare camer\, apoi va urma
`nt=mplarea. Num\rul camerei este transmis ca parametru `nt=mpl\rii, modific=nd-o
pu]in. Rula]i aplica]ia ca s\ vede]i efectele.


Exerci]iu: Reface]i aplica]ia `n Oberon utiliz=nd ambele tehnici de ata[are
a metodelor de RECORD-uri, pentru a le transforma `n obiecte: proceduri
legate la tip pentru constructor [i metodele unice respectiv c=mpuri
procedurale pentru metodele care difer\ de la o instan]\ la alta a
obiectului din clas\ camera.


Exerci]iu: Reface]i aplica]ia `n C++ utiliz=nd ambele tehnici de ata[are a
metodelor de RECORD-uri, pentru a le transforma `n obiecte: metode
implementate ca func]ii [i constructori ai clasei (pentru constructor [i
metodele comune tuturor obiectelor clasei) respectiv pointeri la func]ii
pentru metodele care difer\ de la o instan]\ la alta a obiectului din clasa camera. Pentru
detalii de implementare folosi]i [i fi[ele de laborator dac\ le ave]i la dispozi]ie.

Programarea calculatoarelor [i limbaje de programare 131 Dan Popa, 2007


9
Cap

Liste de RECORD-uri, liste de obiecte

Sau cum pune programatorul unui univers format din oricîte obiecte ordine în haos.

A fi realizatorul unei aplica]ii realizate prin metodele program\rii orientate obiect este, am
putea zice, mai mult sau mai pu]in un act aproape demiurgic. {i ca un veritabil st\p=n al
lumii create, programatorul va trebui s\ [tie cum s\ comande ( a se citi - «s\ instruiasc\
computerul») s\ creeze un nou obiect (`n englez\: NEW object), s\ distrug\ un obiect ([i ve]i
vedea c\ de distrugere – a se citi «dealocarea memoriei» se ocup\ alt «dr\cu[or» numit
Garbage Collector) [i ceea ce este foarte important, s\ fie capabil s\ nu piard\ leg\tura cu
niciunul dintre obiectele create. Pentru aceast\ din urm\ treab\ este nevoie de o structur\
de date flexibil\, care se poate lungi oric=t sau scurta dup\ nevoie, pe m\sur\ ce obiectele
sunt create sau distruse. Cea mai simpl\ structur\ de date de acest fel este LISTA iar cel
mai simplu mod de a o implementa este s\ integr\m `n fiecare RECORD sau obiect ceva
care s\-l indice pe urm\torul. Acel ceva va fi POINTERUL.

Fire[te, cunosc\torii Pascalului vor observa c\ exist\ [i metode mai avansate de a g\si un
element dintr-un univers dat, de exemplu organizarea obiectelor sub form\ de arbore de
c\utare. Dar m\ `ndoiesc c\ o vor face. Manualul de Informatic\ de liceu al domnului Tudor
Sorin (foarte popular datorit\ reclamei de pe copert\ `n care scrie c\ este aprobat ...etc) are
niscaiva lipsuri `n acel capitol ceea ce face ca arborii s\ fie un subiect mai greu de `n]eles,

Programarea calculatoarelor [i limbaje de programare 132 Dan Popa, 2007


dac\ citi]i despre ei de acolo. (Nu mint deloc, de exemplu c\uta]i s\ afla]i din manualul
amintit DE CE se promoveaz\ `n r\d\cin\ cel mai mare nod din subarborele st=ng [i nu cel
mai mic din subarborele drept, la [tergerea r\d\cinii din arborele binar de c\utare! A]i g\sit
cumva ? Eu unul nu am g\sit explica]ia de[i am citit [i edi]ia `n C [i pe cea `n Pascal a
manualului.~n final am g\sit-o singur realiz\nd c\ de fapt se poate `n ambele moduri, iar al
doilea lipse[te complet din manualul `n cauz\.) Arborii nu vor face `ns\ obiectul acestui
capitol de[i, `ntr-adev\r, organizarea unui nivel dintr-o aplica]ie (nivel care con]ine o clas\ de
obiecte) sub form\ de arbore este mai eficient\ dec=t organizarea sa ca list\, cel pu]in
pentru anumite opera]ii.


Re]ine]i totu[i ideea central\: Un nivel (modul) al unei aplica]ii care con]
ine o clas\ de obiecte poate avea acces la toate aceste obiecte dac\
este organizat ca o list\. Lista e util\ [i pentru a transmite un mesaj
(care poate fi un apel de metod\) tuturor obiectelor. Toate obiectele
vor primi mesajul [i dup\ caz vor r\spunde `ntr-un fel sau altul ori ... nu vor r\spunde
deloc.

Aceasta ar fi implementarea unei forme simple de broadcasting – tehnic\ frecvent folosit\ `n


programarea orientat\ obiect.
Nota]i [i existen]a altor tehnici de a pune ordine `n haos: `ntr-un model al unui univers cu
mai multe feluri (clase) de obiecte se poate lucra cu liste de obiecte generice.

Dar mai `nt=i s\ vedem cum se programeaz\ «na[terea» RECORD-urilor sau a obiectelor [i
modul cum putem indica (`n englez\ se spune: to point – ceea ce ar trebui s\ v\ dea o idee)
un obiect (variabil\) care fiind nedeclarat(\) nu are un identificator (nume) al ei. ~n acest caz
singurul lucru care poate referi variabila este adresa ei din memorie. Iar pentru a o putea
folosi corect ar fi bine s\ [tim ce tip de dat\ exist\ acolo, la acea adres\. Vom vedea c\
aceste adrese (imagina]i-v\ c\ sunt `nso]ite de o informa]ie de tip) formeaz\ un tip pointer
(tipul pointerilor care indic\ acel fel de date). Despre ei vorbim `n paragrafele urm\toare:

Programarea calculatoarelor [i limbaje de programare 133 Dan Popa, 2007


Pointeri şi variabile dinamice

Sau cum fac programatorii şi programele care au mereu nevoie mereu de alte variabile. Cuvinte
cheie: alocare,pointeri, variabile dinamice, NEW, DISPOSE, NIL.

Hei! Ce e nou aici? {tim c\ a urma urmei putem declara oric=te variabile dorim noi `ntr-un
program. Ce aduce nou povestea aceasta? Doar un mic, periculos de mic, am\nunt:
`ntotdeauna p=n\ acum num\rul de variabile utilizate `n program era fix, b\tut `n cuie, iar
programul putea prelucra numai acele variabile, deci o cantitate finit\ de informa]ii, stabilt\
clar din momentul scrierii sale. Evident asemenea programe sunt limitate la a prelucra
informa]ii despre ni[te universuri destul de statice. Un asemenea program n-ar putea ]ine
eviden]a culorilor frunzelor dintr-un arbore ori dintr-o p\dure , a greut\]ilor puilor ie[i]i din ou
la sec]ia «Incubatoare» sau lista clien]ilor unei firme `n dezvoltare. Ambele din acela[i motiv:
mul]imea informa]iilor de gestionat este `n cre[tere continu\, nu se [tie c=t de mult va cre[te
[i nici nu i se poate da u[or o margine dinainte. La asemenea probleme a ap\rut nevoia de
variabile noi. ~nainte, c=nd aveam de scris mici programe [tiam cu c=te variabile lucr\m.
Surprinz\tor este faptul c\ dac\ lua]i sursele programelor dintr-un proiect serios, care face o
chestie util\, ave]i foarte multe [anse s\ g\si]i c\ s-au folosit variabile dinamice .

Observa]ie despre nume: Noile variabile care se nasc prin aceast\ opera]ie de alocare a
memoriei nu pot s\ aib\ nume, nefiind declarate. ({tim deja c\ numele de variabile sunt
citite de compilator din textul programului.) Ele vor fi g\site pe baza adresei lor `n memorie.


Defini]ie: O asemenea adres\, `nso]it\ de o informa]ie despre tipul
datei care exist\ acolo, `n memorie, o vom numi pointer. Aceast\
pereche inseparabil\ este stocat\ `ntr-o alt\ variabil\ , `ntr-un c=mp al
unui record, al unui obiect sau `ntr-o alt\ structur\ de date. Tipul
acestei variabile se nume[te generic tot pointer, de[i `n practic\ se declar\ tipuri de date
distincte dup\ tipul informa]iei indicate de pointer. Spre deosebire de Pascal limbaj `n care
se puteau declara pointeri la aproape orice tip de date, OBERON este mai restrictiv. Se

Programarea calculatoarelor [i limbaje de programare 134 Dan Popa, 2007


declar\ pointeri la obiecte. (Documenta]ia care `nso]e[te compilatorul de OBERON livrat
`mpreun\ cu POW sus]ine c\ se pot declara [i pointeri la ARRAY-uri, adic\ la vectori sau
matrice dar s\ fie cu lungime fix\ - nu «open array» - ca s\ se poat\ [ti de c=t\ memorie
este nevoie.)

Contrar ideilor din unele manuale sau lec]ii de la liceu care prezentau pointerul ca o adres\
[i at=t, v\ rog s\ v\ imagina]i pointerul ca o pereche format\ din adres\ [i tip. Adresa ne
spune unde se afl\ `n memorie ceea ce ne intereseaz\ iar informa]ia despre tip ne spune
ce tip de dat\, (care poate fi [i un obiect) g\sim acolo.

Observa]ie despre na[terea variabilelor: Dac\ programul `[i produce singur oric=te variabile
care nu apar `n declara]ii atunci singurul loc unde poate face aceasta este `ntr-o secven]\
de instruc]iuni, printre care exist\ una anume pentru acest scop. (Nu uita]i c\ programele
con]in `n principiu declara]ii care spun ce entit\]i exist\ [i instruc]iuni care fac ceea ce este
de f\cut cu datele.) Prin urmare exist\ neaparat o instruc]iune pentru creat variabile.
Aceasta este `n Oberon (ca [i `n Pascal) NEW(p). ~n C se scrie cu minuscule:new. Litera p
din parantez\ are rolul de a v\ aminti c\ NEW prime[te ca parametru o variabil\ de tip
pointer. Imagina]i-v\ o asemenea variabil\ p ca o cutie `n care pute]i pune o adres\ [i o
informa]ie de tip. Intuitiv vorbind, NEW(p) prime[te o asemena cutie p spre a o umple cu
adres\ [i tip.

Ce face de fapt NEW ? G\se[te o por]iune din memorie liber\ (nu `ntreba]i cum, de
acest lucru se ocup\ mecanismele de alocare a memoriei `ncorporate `n limbaj iar algoritmii
pot fi destul de sofistica]i) apoi plaseaz\ adresa respectiv\ `n variabila care i-a fost
transmis\ lui NEW. ~n exemplul nostru ar pune adresa `n variabila p. Dac\ nu-i reu[e[te
alocarea – ceea ce s-ar putea `nt=mpla `n anumite situa]ii c=nd memoria este epuizat\,
c=nd buc\]ile de memorie liber\ sunt prea mici sau c=nd a avut loc o alt\ eroare – valoarea
special\ stocat\ `n variabila pointer este NIL.

NIL este un fel de zerou al mul]imii pointerilor. Un programator profesionist (care lucreaz\ `n
stil defensiv) va testa o dac\ valoarea unei asemenea variabile este diferit\ de NIL [i abia
apoi ar folosi valoarea pentru a accesa obiectul sau structura de date de la acea adres\.

Programarea calculatoarelor [i limbaje de programare 135 Dan Popa, 2007



Re]ine]i c\ `n practic\ una din primele prelucr\ri pe care le face o
procedur\ utilizator care prime[te un pointer este de a compara
valoarea acestuia cu NIL. Semnifica]ia unui pointer NIL depinde [i de
inten]ia programatorului. De exemplu, ar putea `nsemna c\ nu mai sunt
elemente pe lista elementelor de prelucrat, c\ am parcurs-o p`n\ la cap\t. Sau c\ acel
obiect nu mai este `n rela]ie cu un altul, cu care fusese `n rela]ie mai `nainte.

Cu ce pute]i asem\na activitatea lui NEW ? Intuitiv, cu cea a unui chelner de restaurant
care caut\ o mas\ pentru clientul ce-o solicit\ (atunci c=nd acesta, telefonic, solicit\ o
rezervare). Chelnerul afl\ din eviden]ele lui ce va fi liber, marcheaz\ locul ca fiind ocupat
apoi comunic\ clientului unde [i de ce fel este masa, zic=nd: «Ave]i rezervat\ o mas\ de 4
persoane, masa 7, prima la dreapta cum intra]i pe u[\.» sau «V\ putem oferi o mas\ de
patru persoane `n separeul al doilea.»

DISPOSE(p). Este instruc]iunea invers\ lui NEW(p). Prime[te ca argument o valoare a unui
pointer, diferit\ de NIL. Dealoc\ (elibereaz\) explicit memoria ocupat\ de obiectul sau
structura aflat\ la acea adres\. Mo[tenit\ din Pascal [i p\strat\ mai mult pentru o anumit\
compatibilitate, aceast\ instruc]iune nu mai este obligatoriu de folosit `n Oberon deoarece
acest din urm\ limbaj are `ncorporat un mecanism care face singur dealoc\rile, atunci c=nd
este `n criz\ de spa]iu sau are nevoie. Acest mecanism are un nume destul de prozaic:
«Garbage collector» - «colectorul de gunoaie». Avantajul este c\ el func]ioneaz\ automat
iar programatorul scap\ de grija de a mai dealoca cu DISPOSE() ceea ce a alocat cu NEW
(). Imagina]i-v\ acela[i chelner zelos preg\tind imediat masa pentru al]i viitori clien]I, dup\
plecarea celor care [i-au terminat consuma]ia, f\r\ ca ei. s\-i comande explicit acest lucru
Observa]ie privitoare la limbajele moderne: tot mai multe au tendin]a s\ foloseasc\ aceste
mecanisme de dealocare automat\ ( Garbage collector ).

Comentarii despre folosirea unui pointer la un tip simplu `n Pascal (a[a ceva nu se
mai poate face `n OBERON dar ve]i vedea c\ nu pierdem mai nimic ):

Dac\ P,Q - erau pointeri la `ntregi , `n Pascal atunci


P^,Q^ - erau de tip `ntreg [i se comportau exact ca orice dat\ de tip `ntreg.

Programarea calculatoarelor [i limbaje de programare 136 Dan Popa, 2007


Puteau participa la orice calcule [i orice alte opera]ii care implicau `ntregi.
Exemple:
P^ := 7;
Q^ := P^ * 2;
P^ := Q^ + Q^;

Asemenea pointeri nu-s spectaculo[i, ba par chiar incomozi ([i mul]i cititori ai c\r]ilor de
informatic\ r\m=n cu aceast\ fals\ impresie, dup\ citirea unui capitol despre pointeri)
deoarece, printre altele, `n exemple ca cel de mai sus, pentru fiecare variabil\ dinamic\ de
un anume tip aveam nevoie de un pointer asociat ei, adic\ de o alt\ variabil\ static\ de tipul
«pointer la acel tip al variabilei dinamice». Aceste variabile trebuiau `ns\ declarate, iar
declara]iile erau `n Pascal, asem\n\toare cu cele din OBERON (numai c\ simbolul «
c\ciuli]\» din Pascal a fost `nlocuit `n OBERON de expresia «POINTER TO»). ~n C se
folose[te o o stelu]\ * pus\ `ntre numele variabilei [i tipul acestuia. ~n exemplul de mai sus
am fi avut nevoie s\ declar\m pointerii P [i Q astfel:

VAR P,Q: ^ INTEGER;

(Pentru cititorii familiariza]i cu Pascalul precizez c\ `n OBERON combina]ia de cuvinte


«POINTER TO» se folose[te `n locul c\ciuli]ei numai `n declara]ii nu [i `n instruc]iuni. Acolo
dereferen]ierea – adic\ trecerea de la pointer la obiectul indicat – se face tot cu operatorul
«c\ciuli]\») .
Etapa urm\toare const\ `n a aloca spa]iu pentru variabile dinamice, folosind instruc]iunile
NEW(… ) (plasate `ntr-un bloc de instruc]iuni ale programului, cum vede]i mai jos, loc unde
cu … am indicat c\ pot exista [i alte instruc]iuni):

BEGIN

NEW(P);
NEW(Q);

END;

Programarea calculatoarelor [i limbaje de programare 137 Dan Popa, 2007


Subliniez: Este clar c\ dac\ inten]ion\m s\ folosim multe variabile dinamice, nu e bine s\
folosim c=te o variabil\ declarat\ pentru fiecare variabil\ dinamic\. Ideal ar fi s\ declar\m c=t
mai pu]in (restul vor fi produse dinamic). Foarte bine (simplu) ar fi s\ existe doar o singur\
declara]ie de variabil\ pentru toate obiectele dintr-o clas\ sau dintr-un modul. Ceea ce se
poate face foarte bine dac\ le organiz\m `ntr-o list\ (sau abore – dar despre el nu discut\m
nimic `n acest capitol).


Re]ine]i c\: fiecare structur\ de date alocate poate fi un RECORD sau un
obiect care s\ con]in\ datele de interes pentru noi (culoarea frunzei din
exemplul anterior) [i `mpreun\ cu acestea, un c=mp pointer la RECORD-ul
sau obiectul urm\tor. Astfel odat\ cu fiecare alocare reu[it\ cu NEW ob]in
[i loc pentru datele mele [i o nou\ «variabil\» capabil\ s\ «pointeze» un alt
obiect (de fapt «variabila» e un c=mp de tip pointer din recordul sau obiectul nou creat).
Adic\ nu mai am de declarat variabila pointer, ea fiind practic creat\ automat `mpreun\ cu
recordul sau obiectul.

Deci variabila de tip pointer care va indica urm\torul obiect sau RECORD este inclus\ `n
record-ul sau obiectul anterior ca un c=mp oarecare. Astfel obiectele sau RECORD-urile se
indic\ unul pe altul iar pentru a-l indica pe primul am nevoie s\ declar doar o singur\
variabil\ pointer:

Exemplu `n Pascal sau Oberon: VAR P : MyType;

Unde MyType e tipul pointer la tipul record sau obiect declarat mai `nainte astfel:

TYPE
MyType # POINTER TO MyTypeO;
MyTypeO# RECORD
DataUtila: ….;
P: MyType;
END;

Programarea calculatoarelor [i limbaje de programare 138 Dan Popa, 2007


Observa]i c\ tipul obiect MyTypeO este folosit `ntr-o declara]ie (cea a tipului MyType)
~NAINTE de a fi declarat acest MyTypeO!!! Surprinz\tor , compilatorul nu este deranjat de
acest lucru deoarece n-are nevoie s\ [tie cum arat\ MyTypeO. Secretul: Pentru compilator
toate tipurile pointer sunt la fel din punct de vedere al memoriei alocate, indiferent spre ce
fel de date indic\ ele. Exemplu de mai sus este generic, pute]i pune orice nume tipurilor
record (obiect) [i pointer `n locul numelor MyTypeO [i MyType. Iar obiectul poate con]ine
mai mul]i pointeri spre obiecte de acela[i tip cu el sau, de ce nu, spre alte tipuri de date.

Logic: Dac\ fiecare obiect con]ine exact un pointer c\tre obiectul urm\tor, atunci ele se `n-
[ir\ ca ardeii iu]i pe sfoar\, unul dup\ altul, iar ceea ce ob]inem este o list\. Ce valoare are
ultimul pointer, cel care nu mai indic\ nimic? NIL! Not\: O excep]ie este lista circular\ dublu
`nl\n]uit\, care are `n fiecare obiect doi pointeri, unul arat\ `nainte (spre urm\torul obiect) iar
altul `napoi (spre precedentul obiect). Dac\ `ns\ fiecare obiect are doi pointeri care indic\
spre alte dou\ obiecte noi, iar graful format este conex (nu exist\ obiecte neindicate) [i f\r\
cicluri (nu revenim niciodat\ la un obiect anterior) atunci avem un arbore binar.

A]i mai scris programe cu liste [i sunte]i capabil s\ desena]i o list\ [i elementele ei, pentru a
urm\ri prelucr\rile ? ~ncercui]i mai jos r\spunsul:

DA NU

Dac\ a]i r\spuns DA pute]i s\ri peste povestea piciorului, care urmeaz\, dar re]ine]i c\ cel
mai sigur mod de a nu gre[i programele cu pointeri este s\ desena]i ceea ce dori]i s\
programa]i, `nainte de a scrie programul.. Se folose[te creionul [i radiera. Vom vedea
cum.

Dac\ a]i r\spuns NU este cazul s\ citi]i povestea piciorului [i s\ deprinde]i o metod\ de a
`nv\]a rapid pe care n-a]i cunoscut-o. Dar mai `nt\i povestea piciorului, pe care v\ rog s-o
relua]i de c\te ori ave]i nevoie astfel ca s-o pute]i scrie cu cartea `nchis\. Nu tri[a]i!

Start!

Programarea calculatoarelor [i limbaje de programare 139 Dan Popa, 2007



Povestea piciorului (dup\ Vera Birkenbil):
Un dou\ picioare [ade pe un trei picioare [i m\n=nc\ un picior. Vine un
patru picioare [i smulge piciorul lui dou\ picioare. Sup\rat, dou\ picioare ia
pe trei picioare [i love[te cu el pe patru picioare. Patru picioare fuge `n trei
picioare cu piciorul `n din]i.

Acum `nchide]i cartea [i scrie]i corect povestea piciorului ! De c=te ori a trebuit s-o citi]i
p=n\ s-o pute]i reproduce? De 4-5 ori? De mai multe ori?

De asemenea dificult\]i se lovesc to]i elevii care `nva]\ pe de rost, care buchisesc. ~n
realitate creierul nostru poate fi folosit altfel la `nv\]atul rapid dar probabil nimeni nu v-a spus
p=n\ acum acest lucru! Haide]i s\ citim iar\[i povestea piciorului, imagin=nd-o sau chiar
desen=nd-o! Desena]i-o dac\ vre]i chiar acum. Ceea ce ar trebui s\ v\ imagina]i [i/sau s\
desena]i am scris cu litere grase, `ntre paranteze. Desena]i !


Un dou\ picioare (un om) [ade pe un trei picioare (un taburet) [i m\n=nc\
un picior (un copan). Vine un patru picioare (un c=ine) [i smulge piciorul
(copanul) lui dou\ picioare (al omului). Sup\rat, dou\ picioare (omul) ia
pe trei picioare (taburetul) [i love[te cu el pe patru picioare (pe c=ine).
Patru picioare (c=inele) fuge `n trei picioare ([chiop\t=nd), cu piciorul (copanul furat) `n
din]i.

Iat\ deci scena pe care ar fi trebuit s\ v-o imagina]i de la `nceput, `n `ncercarea de a `nv\]a
povestea de mai sus. A[a-i c\ era o poveste u[or de `nv\]at, din prima citire? Nu uita]i c\ n-
a]i fi reu[it f\r\ a-i construi o reprezentare vizual\.

Iat\ deci povestea piciorului, a[a cum trebuia s\ v-o imagina]i de la `nceput:
«Un om [ade pe un taburet [i m\n=nc\ un copan . Vine un un c=ine [i smulge copanul
omului. Sup\rat, omul ia taburetul [i-l love[te cu el pe c=ine. C=inele fuge [chiop\t=nd, cu
copanul furat `n din]i.»

A[a-i c\ este mult mai clar\ ? Acum, dup\ ce am v\zut filmul ac]iunii, dup\ ce ne-am

Programarea calculatoarelor [i limbaje de programare 140 Dan Popa, 2007


imaginat ce poate fi fiecare tip de picior, putem scrie imediat povestea piciorului a[a cum era
la `nceput, cu multe picioare:


Povestea piciorului (reprodus\ cu u[urin]\):
Un dou\ picioare [ade pe un trei picioare [i m\n=nc\ un picior. Vine un
patru picioare [i smulge piciorul lui dou\ picioare. Sup\rat, dou\ picioare ia
pe trei picioare [i love[te cu el pe patru picioare. Patru picioare fuge `n trei
picioare cu piciorul `n din]i.

Este clar de ce de acum `ncolo va trebui s\ [tim s\ desen\m obiecte [i recorduri cu


c=mpuri pointer, apoi s\ desen\m pointerii care arat\ c\tre alte obiecte. Este un mod
sigur de a `n]elege, de a sim]i [i de a imagina cum func]ioneaz\ programele cu
pointeri. Altfel, aceste programe cu pointeri vi se vor p\rea la fel de `nc=lcite ca
multele picioare de la prima citire a pove[tii.


Desena]i ! Un record sau obiect se deseneaz\ ca un dreptunghi vertical,
`mp\r]it cu linii orizontale `n mai multe zone, corespunz\toare fiecare unui
c=mp. Dac\ sunt doar dou\ c=mpuri pute]i desena recordul ca pe un
dreptunghi orizontal, `mp\r]it `n dou\ de o linie vertical\. La acele
componente care sunt pointeri pune]i un punct `n mijloc. Dac\ sunt pointeri NIL bara]i por]i-
unea, diagonal, din dreapta sus `n st=nga jos.

Pointerul `l desena]i ca pe o s\geat\ dreapt\ sau curb\ care pleac\ din punctul central al
c=mpului (sau variabilei) de tip pointer [i ajunge pe conturul obiectului (variabilei dinamice,

Programarea calculatoarelor [i limbaje de programare 141 Dan Popa, 2007


recordului), etc. Variabila static\ de tip pointer se deseneaz\ tot ca un punct `ntr-un
dreptunghi dar uneori dreptunghiul poate lipsi. Al\turi i se scrie numele.

Exemplu: A[a se deseneaz\ o list\, al c\rui cap e indicat de variabila L:


L

Exemplul de mai sus are urm\toarele declara]ii `n Oberon:

VAR L: MyLista;

Unde MyLista e tipul pointer la tipul record sau obiect declarat mai `nainte astfel prin dou\
declara]ii de tip, una pentru tipul pointer alta pentru record sau obiect:

TYPE
MyLista # POINTER TO MyElement;
MyElement # RECORD
Info : ….;
Urm : MyLista;
END;

Observa]i c\ informa]ia util\ privitoare la un element de pe list\ este memorat\ `n c=mpul


Info (dar pot fi mai multe asemenea c=mpuri) iar pointerul Urm ne permite s\ g\sim
urm\torul element din orice list\ concret\.

Ca urmare a acestor declara]ii [i a aloc\rii elementelor listei - ceea ce va presupune execu]i-


a de trei ori a instruc]iunii NEW(…) - vom putea opera cu:
L - este de tipul MyLista adic\ pointer la MyElement
L^ - este un record sau un obiect, de tipul MyElement
L^.Info - este o informa]ie dintr-un element MyElement, informa]ia util\.

Programarea calculatoarelor [i limbaje de programare 142 Dan Popa, 2007


~n acest caz este chiar din primul element. ~n general dac\ P este pointer la MyElement
atunci:
P^.Info – este informa]ia din elementul indicat de variabila P
P^.Urm – este pointerul la urm\torul element. Iar dac\ atribuim :
P := P^.Urm

Putem acum g\si iar\[i:


P^.Info – este informa]ia din elementul nou indicat de variabila P
P^.Urm – este pointerul la urm\torul element [.a.m.d.

Desenarea efectului lui NEW(p): Uita]i-v\ la tipul variabilei sau c=mpului p dat ca
argument lui NEW. Va fi cel mai probabil un tip record (sau obiect, rareori `ntreg, real sau alt
tip simplu). Dac\ e tip simplu desena]i un dreptunghi ca pentru orice variabil\. Dac\ este un
tip compus desena]i dreptunghiul corespunz\tor, `mp\r]it ca mai sus. Pentru componentele
pointer pune]i c\te un punct `n fiecare parte a dreptunghiului. Acum c\uta]i pe desen
variabila p sau c=mpul p . Acolo ar trebui s\ g\si]i un punct cu o s\geat\ sau un NIL (bar\
oblic\). {terge]i s\geata sau bara lui NIL, pune]i punctul dac\ lipse[te [i pornind de acolo
desena]i o s\geat\ p=n\ la dreptunghiul pe care l-a]i desenat mai `nainte.

Desenarea efectului unei atribuiri: Dac\ este vorba de o atribuire asupra informa]iilor [i v\
intereseaz\ s-o desena]i, scrie]i valoarea `n c=mpul corespunz\tor. La fel proceda]i [i pentru
variabile care nu-s de tip pointer.

Desenarea efectului unei atribuiri cu pointeri: Se [terge vechea s\geat\ sau bara lui NIL
[i se deseneaz\ noua s\geat\, indic=nd acolo unde arat\ membrul drept. O atribuire de
pointeri se deseneaz\ adesea practic ca o s\geat\ indic=nd spre destina]ia alteia. Excep]ie:
Dac\ membrul drept e nil, c=mpul din structur\ se bareaz\ cu bara oblic\. (vezi primele
figuri).

Exerci]iu de desen: Urm\toarele trei instruc]iuni, puse `ntr-o bucl\, adaug\ noi
elemente `n lista L.
Desena]i ce se `nt=mpl\ prin executarea repetat\ a instruc]iunilor:

Programarea calculatoarelor [i limbaje de programare 143 Dan Popa, 2007



NEW(Q);
Q^ . Urm := L ;
L := Q ;
Observa]ie (Pascal): Nota]ia cu ^. este specific\ limbajului Pascal, `n care
^ este un operator numit dereferen]iere care transform\ pointerul `n obiectul (data)
indicat\ .

Observa]ie (Oberon): ~n Oberon pute]i folosi direct “.” `n loc de combina]ia “^.” Deoarece
Oberon aplic\ automat operatorul ^ acolo unde lipse[te, pointerul poate fi folosit de
programator ca `ns\[i obiectul f\r\ s\ apar\ mesaje de eroare.

Nu uita]i: ~n Oberon pute]i folosi cu `ncredere pointerul ca [i cum el ar fi chiar obiectul sau
structura indicat\. Ba chiar se obi[nuie[te ca tipurile pointeri s\ aib\ denumiri care s\
sugereze clase de obiecte. Acum a]i `n]eles de ce tipul pointer `l numisem MyLista, `n
exemplul precedent !?!

R\spunsul la exerci]iu: Se adaug\ de fiecare dat\ c=te un nou element la list\. Dac\ este
primul, ultimul sau la mijloc v\ las s\ stabili]i desen=nd.
Dup\ acest antrenament la desen v\ pute]i `ncerca imagina]ia cu urm\toarele :

 Ex1. Desena]i crearea unei liste de numere `ntregi la care:


a) elementele se adaug\ la sf\r[it
b) elementele se adaug\ la `nceput
c) elementele se adaug\ la mijloc. (Indica]ie: mai ave]i nevoie de cel
pu]in o variabil\ de tip pointer.


Ex2. Scrie]i programul pentru crearea unei liste de numere `ntregi la
care:
a) elementele se adaug\ la sf\r[it
b) elementele se adaug\ la `nceput
c) elementele se adaug\ la mijloc

Programarea calculatoarelor [i limbaje de programare 144 Dan Popa, 2007


Surs\ de inspira]ie: Orice manual de limbaj Pascal `n care sunt tratate listele. Deosebiri:
“POINTER TO” `n loc de “c\ciuli]\” `n declara]ii [i faptul c\ se poate `nlocui ^. cu ^
(deoarece `n Oberon dereferen]ierea pointerilor este implicit\)

Concluzia : Cum se pot implementa listele sau rela]iile dintre obiecte ? Folosind
c=mpuri pointer aflate `n structura RECORD-ului sau obiectului!

Exemplul «Serpa.prj»

Prezentăm un nivel (modul) care conţine o listă extras dintr-o aplicaţie.

Prezent\m ca exemplu o variant\ simplificat\ (dictonul preferat al profesorului Wirth este


«F\ simplu dar nu simplist» [i e preluat de la Einstein) a unui joc clasic – Snake - `n care
intervine o list\ de RECORD-uri. Pentru a ne concentra asupra listei vom renun]a la a mai
`nzestra elementele sale cu metode. Ele r\m=n simple RECORD-uri (articole) dar este clar
c\ oric\nd vom avea nevoie de faciulit\]i suplimentare se pota ad\uga datele [i metodele
necesare. (Vom vedea `ntr-un capitol ulterior c\ se poate ob]ine o clas\ de obiecte din alta
mai s\rac\ `n date [i metode folosind mecanismul tipurilor extensibile (din OBERON)
cunoscut `n alte limbaje sub denumirea de «derivare de clase»).

Proiectantul unei aplica]ii orientate obiect sau a uneia `n care (m\car pe un nivel) se afl\ o
list\, are nevoie de o viziune mai larg\ asupra no]iunii de nivel (modul) dintr-o aplica]ie.
Dac\ p=n\ acum un nivel (modul) era o colec]ie de proceduri care ofereau servicii nivelelor
superioare din aplica]ie,acum situa]ia se complic\.


De la un nivel al aplica]iei putem cere:
- efectuarea anumitor servicii (proceduri obi[nuite)
- crearea de obiecte sau elemente din list\ (aceasta include [i inserarea lor
`n structura de list\, deci crearea leg\turilor, rela]iilor cu alte obiecte de pe

Programarea calculatoarelor [i limbaje de programare 145 Dan Popa, 2007


nivel). Practic se va scrie un constructor mai sofisticat, care ini]ializeaz\ RECORD-ul [i face
[i leg\turile.
- distrugerea explicit\ a unor obiecte sau elemente din list\ (sau m\car deconectarea lor de
la structur\ c\ci de rest se ocup\ Garbage collectorul – colectorul de zone de memorie
neutilizate).

Pentru `nceput o descriere a jocului Snake care poate fi rezumat\ `n: Pe o tabl\ de joc
`mp\r]it\ `n p\trate se mi[c\ un [arpe (format dintr-o succesiune de segmente care ocup\
p\trate vecine) la fiecare mutare deplas\ndu-[i capul `ntr-un p\trat vecin. {arpele are ca
scop s\ ajung\ `n alt p\trat `n care `i apare hrana (pozi]ia ei se schimb\ pseudoaleator) [i
totodat\ de a se feri s\-[i mu[te coada sau s\ se loveasc\ cu capul de zidul `nconjur\tor.
Dar fiindc\ o imagine e mai gr\itoare dec\t o mie de cuvinte s\ d\m cuv=ntul imaginii.
Figura o gasi]i pe una din paginile urm\toare.

Deoarece OBERON este un limbaj pentru programare modular\, analistul echipei care
realizeaz\ proiectul opteaz\ pentru o ierarhie de trei nivele, trei module, dintre care:

1.Primul de sus con]ine jocul propriuzis. El se bazeaz\ pe serviciile oferite de al doilea nivel,
servicii care manipuleaz\ elementele sarpelui [i ocazional pe grafica oferit\ de cel de-al
treilea nivel.
2.Nivelul al doilea se ocup\ de lista de elemente care formeaz\ [arpele. El permite:
- Inserarea unui element `ntr-o lista (elementul va fi capul [arpelui, `n noua pozi]ie)
- {tergerea ultimului element dintr-o list\. Observati c\ `n lipsa dealoc\rii cu DISPOSE este
suficient ca pointerul din penultimul element (segment de [arpe) s\ capete valoarea NIL [i
astfel ultimul element se va pierde. (Fi]i f\r\ grij\, `l recupereaz\ colectorul de gunoaie -
Garbage collectorul.) Dac\ lucra]i `n C va trebui dealocat cu instruc]iunea explicit\: delete.
- Prelucrarea unei liste, parcurgerea unei liste, c\utarea `n list\ (pentru a vedea dac\
[arpele nu [i-a mu[cat coada sau dac\ viitoarea sa «hran\» `n loc s\ apar\ undeva pe tabla
de joc i-ar apare suprapus\ peste unul dintre propriile segmente.)

Toate procedurile de prelucrare a listelor s-a decis s\ fie recursive, bazate pe ideea c\ o
list\ este sau lista vid\ (sau lista de un element) sau un prim element de care se leag\ o
alt\ list\. Aceasta este o abordare clasic\ a prelucr\rii listelor.

Programarea calculatoarelor [i limbaje de programare 146 Dan Popa, 2007




Not\: Aceast\ abordare nu exclude defel posibilitatea abord\rii listei ca pe
o `n[iruire de elemente de lungime necunoscut\, terminat\ cu NIL [i deci
prelucrarea ei cu ajutorul unei structuri repetitive (de exemplu bucla while).
Pute]i deci proiecta ca exerci]iu o variant\ a modulului / nivelului realizat\
cu proceduri nerecursive, bazate pe itera]ii.

3.Nivelul al treilea asigur\ leg\tura cu tastatura [i ecranul. Echipa decide s\ foloseasc\ `n


faza de prototip modulul Display, s\ ]in\ eviden]a serviciilor cerute acestuia [i apoi s\
`nlocuiasc\ acest modul cu altul care va furniza o interfa]\ mai estetic\, bazat\ pe grafic\
color `n dou\ dimensiuni. Practic acest nivel se va ocupa de afisarea pe tabl\, `ntr-unul din
p\trate, a ceea ce este de afi[at. Ca urmare, dac\ pe post de nivel al treilea import\m
Display scriind:

IMPORT ... Grafica:=Display;

Ca rezultat vom ob]ine o aplica]ie care func]ioneaz\ afi[=nd imaginea ca pe un text. Aici
segmentele [arpelui sunt afi[ate ca stelu]e iar hrana ca un fel de @.

A[a arat\ programul demonstrativ “Serpa.prj” `n func]iune, cu afi[aj realizat `n mod text.

Programarea calculatoarelor [i limbaje de programare 147 Dan Popa, 2007


Not\: Programatorii `n C [i limbaje derivate vor folosi directiva preprocesor #include pentru
a importa module. Modulul va fi de obicei un fisier surs\ cu extensia c (pentru un modul
scris `n c) sau cpp (atunci c=nd se lucreaz\ `n C++)

~n fig.: A[a arat\ programul demonstrativ “Serpa.prj” `n func]iune, cu grafica color `n dou\ dimensiuni.

A doua imagine prezint\ ce se poate ob]ine atunci c=nd modulul destinat graficii este un
modul ce realizeaz\ grafic\ bidimensional\ color. Acest modul trebuie importat de modulele
care apeleaz\ la serviciile sale. Va fi suficient s\ importa]i / include]i modulul nou `n locul
celui vechi (`n dou\ locuri, `n cele dou\ module):

IMPORT ... Grafica:=Grafco;

[i programul devine unul al c\rui efect se vede `n a doua imagine. Remarca]i cum simpla
schimbare a unui modul cu altul av=nd aceea[i interfa]\ [i capabil s\ realizeze mai bine
acelea[i lucruri schimb\ complet aspectul unei aplica]ii. De altfel exist\ o tendin]\ actual\ de

Programarea calculatoarelor [i limbaje de programare 148 Dan Popa, 2007


a se realiza aplica]iile `n acest mod, pe trei sau mai multe nivele care ne indic\ s\ separ\m:
-programul principal de
-clasele de obiecte care sunt folosite [i de
-interfa]a lui cu lumea exterioar\, cu utilizatorul.
~n cele ce urmeaz\ vom comenta pentru `nceput opera]iile cu liste din modulul
Segmente.mod.

Modulul `ncepe cu declararea a dou\ tipuri de date, pointerii la lan]uri de segmente [i


segmentele `nsele, care vor fi ni[te `nregistr\ri (articole implementate ca RECORD-uri)
fiecare cu coordonatele unde se afl\ pe tabla de joc: x,y.

MODULE Segmente;
IMPORT Grafica:=Grafco; (* Deoarece apeleaza: Grafica.WriteCharXY(x,y," "); *)

TYPE
GrupSegmente* = POINTER TO Segment;
Segment* = RECORD
x,y : INTEGER;
urmator : GrupSegmente;
END;

E momentul s\ desena]i record-ul a[a cum este descris `n prima parte a capitolului, ca un
dreptunghi `mp\r]it `n trei por]iuni verticale.

Inserarea unui asemenea element `nc\ necreat `ntr-o list\ (`n fa]a ei) se face `n etape:
Aloc `nt=i memorie pentru element cu NEW, apoi completez c=mpurile structurii cu
informa]ii (x,y – pozi]ia segmentului pe tabl\). Tot acum se completeaz\ c=mpul pointer cu
valoarea care indic\ spre restul listei. Adic\ de fapt cu adresa vechiului cap al listei. Pentru a
fi evident [i pentru juc\tor efectul afisez pe tabla un simbol (*) `n pozi]ia dat\ de x,y.
Juc\torul va vedea capul [arpelui `n noua pozi]ie.
Aten]ie: Vechea variabil\ (Lista) care indica `nceputul listei va ar\ta acum spre noul
segment.

Programarea calculatoarelor [i limbaje de programare 149 Dan Popa, 2007


(* Inserarea unui element `ntr-o list\ *)

PROCEDURE NouSegment* (X,Y:INTEGER;VAR Lista:GrupSegmente);


VAR S:GrupSegmente; (* pointer la un segment dintr-un grup de segmente *)

BEGIN
NEW(S); (* aloc memoria pentru segmentul nou,*)
S.x:=X; (* `i pun coordonatele *)
S.y:=Y;
S.urmator:=Lista; (* GrupSegmentele o urmeaza *)
Grafica.WriteCharXY(X,Y,"*"); (* apare grafic - poate lipsi*)
Lista:=S; (* lista incepe cu noul segment *)
END NouSegment;

{tergerea ultimului element din list\ presupune s\ parcurgem lista p=n\ `n locul `n care un
element din list\ (segment) nu mai are succesor, adic\ pointerul s\u indic\ nimic (NIL). Nu
uita]i c\ acel c=mp pointer este denumit «urm\tor». ~n general, prelucrarea recursiv\ a
unei liste `nseamn\ prelucrarea elementului curent urmat\ de prelucrarea restului
listei. Evident, testul dac\ s-a ajuns la sf=r[it e situat `naintea apelului recursiv care declan-
[eaz\ prelucrarea restului listei. Totu[i procedura de mai jos este pu]in atipic\, deoarece
testul obi[nuit dac\ o list\ s-a terminat se face verific\nd dac\ pointerul primit (capul listei)
este NIL sau nu.
(*{tergerea ultimului element din lista. Observa]i lipsa dealoc\rii cu DISPOSE *)
PROCEDURE LasaCoada* (VAR S:GrupSegmente);
BEGIN
IF S.urmator=NIL THEN
(* Pot sterge acest segment daca nu are succesor *)
Grafica.WriteCharXY(S.x,S.y, " ");
(* Iar pointerul din seg. anterior S, nu mai indica nimic *)
S:=NIL;
ELSE (* altfel il caut mai departe in restul listei *)

Programarea calculatoarelor [i limbaje de programare 150 Dan Popa, 2007


LasaCoada(S.urmator);
END;
END LasaCoada;
Nu putem s\ nu observ\m c\ `n cazul acestui joc `n care e nevoie de acces la ambele
capete ale structurii ([arpelui), era mai indicat s\ folosim structura de date numit\ chiar
coad\ nu o list\ de tip stiv\. Coada e caracterizat\ de prezen]a a doi pointeri (alte dou\
variabile), unul indic\ un cap\t iar cel\lalt pointer cel\lalt cap\t al cozii.

Prelucrarea tipic\ a unei liste se face astfel. Dac\ pointerul primit e NIL, lista e vid\ [i nu
am sau nu mai am ce prelucra. Altfel prelucrez elementul curent, acces=nd componentele
sale (c=mpurile) iar apoi prelucrez (dac\ mai este cazul) restul listei. De obicei mai este
cazul, excep]ie f\c=nd ni[te prelucr\ri la care prezen]a unui anumit element `n list\
determin\ oprirea prelucr\rii. Este cazul c\ut\rii `ntr-o list\, c\utare care se opre[te, evident,
`n momentul g\sirii elementului cerut.
~n jocul cu [arpele procedura care confirm\ sau infirm\ faptul c\ [arpele trece printr-un
p\trat anume (de coordonate x,y) este chiar o c\utare a pozi]iei date `n recordurile
elementelor adic\ de-a lungul [arpelui:

(* Prelucrarea unei liste, parcurgerea unei liste, c\utarea in list\ *)

PROCEDURE Contine* ( S:GrupSegmente;xdat,ydat:INTEGER) : BOOLEAN;


BEGIN
IF S=NIL THEN RETURN FALSE; (*capatul listei => n-am g\sit *)
ELSIF (S.x=xdat) & (S.y=ydat) THEN RETURN TRUE (* am g\sit *)
ELSE RETURN Contine(S.urmator, xdat,ydat) (* mai caut *)
END;
END Contine;

END Segmente.

Jocul propriuzis formeaz\ modulul principal al proiectului. A fost programat structurat, clasic.
Iat\-l, f\r\ alte comentarii.

Programarea calculatoarelor [i limbaje de programare 151 Dan Popa, 2007


MODULE Serpa;
IMPORT Segmente,Grafica:=Grafco;
PROCEDURE ProgMain*;
CONST LinMin=1;LinMax=20; ColMin=1; ColMax=20;
VAR Key:CHAR;
X,Y,XFRUCT,YFRUCT:INTEGER;
S: Segmente.GrupSegmente;
GameOver:BOOLEAN;
i,j:INTEGER;
BEGIN
FOR i:= LinMin TO LinMax DO
Grafica.WriteCharXY(ColMin,i,"#");
Grafica.WriteCharXY(ColMax,i,"#");
END;
FOR i:= ColMin TO ColMax DO
Grafica.WriteCharXY(i,LinMin,"#");
Grafica.WriteCharXY(i,LinMax,"#");
END;
XFRUCT:=9; YFRUCT:=19;
S:=NIL;
FOR i:=5 TO 15 DO
Segmente.NouSegment(i,10,S);
END;
X:=15;Y:=10;
REPEAT
Grafica.WriteCharXY(XFRUCT,YFRUCT,"@"); (* apare fructul*)
Key:= Grafica.ReadKey();
CASE Key OF (* calculul noilor coordonate*)
"a": Y:=Y+1 |
"q": Y:=Y-1 |
"o": X:=X-1 |

Programarea calculatoarelor [i limbaje de programare 152 Dan Popa, 2007


"p": X:=X+1
ELSE ;
END;
GameOver:=Segmente.Contine(S,X,Y) OR (X<=ColMin) OR
(X>=ColMax) OR (Y<=LinMin) OR (Y>=LinMax);
IF ~ GameOver THEN (* dac\ nu s-a terminat jocul*)
Segmente.NouSegment(X,Y,S); (* mut\ capul sarpelui *)
IF (X=XFRUCT)& (Y=YFRUCT)THEN (* Dac\ a mancat fructul *)
(* creste cu un segment = nu-si va pierde unul din coada *)
REPEAT
XFRUCT:=(13 * XFRUCT) MOD 17+1;(* coordonate fruct *)
YFRUCT:=(19 * YFRUCT) MOD 17+1;
UNTIL ~Segmente.Contine(S,XFRUCT,YFRUCT);
Grafica.WriteCharXY(XFRUCT,YFRUCT,"@");(* apare fructul nou *)
ELSE Segmente.LasaCoada(S); (* Altfel isi trage coada *)
END;
END;
UNTIL GameOver;
REPEAT UNTIL Grafica.KeyPressed();
END ProgMain;

END Serpa.

Modulul care realizeaz\ partea grafic\ a fost scris pe ideea compatibilit\]ii cu modulul
Display. El trebuie s\ ofere acelea[i servicii ca Display sau (dintre ele) macar pe cele cerute
de aplica]ia noastra.
MODULE Grafco;
IMPORT CP:=ColorPlane;

CONST MaxY=500; (*limita de sus pe display *)


LatP=20; (*latura patratelor *)

Programarea calculatoarelor [i limbaje de programare 153 Dan Popa, 2007


VAR x1,y1,x2,y2 :INTEGER;
xt1,xt2,yt1,yt2 :INTEGER; (* treimile pe x *)
ym:INTEGER; (* jumatatea pe y *)
PROCEDURE SetPoz(x,y:INTEGER);
BEGIN
x1:=LatP * x; x2:= x1 +LatP; y1:=MaxY - LatP * y; y2:= y1 - LatP;
xt1:= (2 * x1 + x2) DIV 3; xt2:= (2 * x2 + x1) DIV 3;
ym:= (y1 + y2) DIV 2;
END SetPoz;

PROCEDURE Space;
BEGIN
CP.SetBackColor(0,255,0); CP.Bar(x1,y1,x2,y2,CP.ERASE);
END Space;

PROCEDURE Zid;
VAR
BEGIN
CP.SetBackColor(120,120,0);CP.Bar(x1,y1,x2,y2,CP.ERASE);
CP.SetForeColor(0,0,0);
CP.Line(x1,y1,x2,y1,CP.DRAW); (* sus*)
CP.Line(x1,y2,x2,y2,CP.DRAW); (* jos *)
CP.Line(x1,ym,x2,ym,CP.DRAW); (* mijloc *)
CP.Line(xt1,y1,xt1,ym,CP.DRAW); CP.Line(xt2,ym,xt2,y2,CP.DRAW);
END Zid;

PROCEDURE Segment;
VAR
BEGIN
CP.SetBackColor(0,255,0); CP.SetForeColor(0,0,0);
CP.Bar(x1,y1,x2,y2,CP.ERASE);
CP.Line(xt1,y1,x1,ym,CP.DRAW);

Programarea calculatoarelor [i limbaje de programare 154 Dan Popa, 2007


CP.Line(x1,ym,xt1,y2,CP.DRAW);
CP.Line(xt1,y2,xt2,y2,CP.DRAW);
CP.Line(xt2,y2,x2,ym,CP.DRAW);
CP.Line(x2,ym,xt2,y1,CP.DRAW);
CP.Line(xt2,y1,xt1,y1,CP.DRAW);
END Segment;

PROCEDURE Cireasa;
BEGIN
CP.SetBackColor(0,255,0);
CP.SetForeColor(255,0,0);
CP.Bar(x1,y1,x2,y2,CP.DRAW);
END Cireasa;

PROCEDURE WriteCharXY*(x,y:INTEGER;c:CHAR);
VAR
BEGIN
SetPoz(x,y);
CASE c OF
" " : Space; |
"#" : Zid; |
"*" : Segment |
"@" : Cireasa
ELSE ;
END;
END WriteCharXY;

PROCEDURE KeyPressed*():BOOLEAN;
BEGIN
RETURN CP.KeyPressed()
END KeyPressed;

Programarea calculatoarelor [i limbaje de programare 155 Dan Popa, 2007


PROCEDURE ReadKey*():CHAR;
BEGIN
RETURN CP.ReadKey()
END ReadKey;

BEGIN
CP.Open;
CP.SetBackColor(0,255,0);
CP.SetForeColor(0,0,0);
CP.Clear;
END Grafco.

Comentarii: Acest modul ofer\ servicii nivelurilor superioare prin aceste trei proceduri, care
`ntr-un limbaj din familia C-ului ar fi fost trei func]ii:

PROCEDURE WriteCharXY*(x,y:INTEGER;c:CHAR);
PROCEDURE KeyPressed*():BOOLEAN;
PROCEDURE ReadKey*():CHAR;

Ultimele dou\ au aceea[i semnifica]ie ca suratele lor din Display sau ColorPlane. Prima nu
este at=t de complet\ ca omoloaga sa din modulul Display. Aceast\ nou\ WriteChar [tie s\
afi[eze doar anumite caractere [i anume cele care ne interesau pe noi: # * @ [i spa]iul.

Programarea calculatoarelor [i limbaje de programare 156 Dan Popa, 2007


Constructori, destructori (II)

Sau cine se ocupă de operaţiile necesare la crearea şi la distrugerea unui obiect.

A[a cum a]i v\zut `n exemplul anterior, imediat dup\ crearea cu NEW obiectele au nevoie
de o ini]ializare. Obiectul nou creat este «tabula rasa», nu are informa]ii `n c=mpuri, nu are
nume de metode `n c=mpurile procedurale, nu are nici pointerii (care-l leag\ de alte obiecte)
ini]ializa]i. Iar uneori, «na[terea» sa trebuie acompaniat\ de «na[terea» altor obiecte care-i
sunt cumva subordonate sau trebuie s\ fie `n rela]ie cu el dar `nc\ nu exist\. ~n acest caz
acestea trebuiesc [i ele produse (cu new) [i ini]ializate.
La fel, la «moartea» obiectului ar trebui desf\cute anumite leg\turi ale lui cu alte obiecte.
Aceste leg\turi pot fi uneori `n dublu sens – ca la liste dublu `nl\n]uite - deci uneori presupun
[i modific\ri ale altor obiecte ce vor r\m=ne alocate. Chiar [i alte opera]ii suplimentare pot fi
necesare la «na[terea [i moartea» obiectelor: Afi[area de mesaje, `nregistrarea obiectelor
`ntr-o eviden]\, deschiderea sau `nchiderea unor fi[iere asociate, etc. Cum proced\m dat
fiind c\ sunt at=t de multe de f\cut la `nceputul [i la sf=r[itul existen]ei unui obiect?


Simplu, [tim deja cum! Grup\m toate aceste opera]ii `n c=te-o procedur\
(sau func]ie, `n C++). Una pentru «na[terea» alta pentru distrugerea
obiectului. Prima o ve]i apela imediat dup\ NEW(…), pe a doua imediat
`nainte de DISPOSE(…), dac\ limbajul nu permite apelarea lor automat\
(un limbaj care permite apelarea lor automat\ este C++). Ele se vor numi constructor
respectiv destructor [i au `n unele limbaje denumiri specifice. ~n Turbo Pascal se numesc,
prin tradi]ie, Init (constructorul) [i Done (destructorul). ~n limbajele orientate obiect
derivate din C (C^^, Java etc) constructorul poart\ numele clasei iar destructorul numele
clasei prefixat cu un simbol, cu semnifica]ia de nega]ie, de distrugere. Acest lucru este
justificat deoarece `n C^^, de exemplu, constructorul este automat apelat la declararea unei
variabile din acea clas\, prin `nse[i declararea ei. La fel, la ie[irea din bloc, din procedur\,
(vede]i no]iunea de domeniu de vizibilitate a variabilelor), c=nd variabila urmeaz\ s\ fie
dealocat\ C++ apeleaz\ automat destructorul. (Este foarte facil pentru programator dar

Programarea calculatoarelor [i limbaje de programare 157 Dan Popa, 2007


pune [i probleme delicate c=nd se lucreaz\ cu ierarhii de clase, probleme de genul: care
constructor este apelat primul, al clasei de la baza ierarhiei sau al clasei derivate?).

~n Oberon constructorii [i destructorii nu au nimic special, limbajul nu con]ine acest concept


dar dac\ ave]i nevoie de ei – [i ave]i nevoie - pute]i s\-i scrie]i ca pe ni[te proceduri absolut
normale. Dumneavoastr\ ve]i [ti c\ aceste proceduri au rolurile respective. Ele vor avea (ca
[i suratele lor, func]iile din C++) o mul]ime de parametri prin care vor primi datele de
transferat `n c=mpurile obiectului. ~n Oberon singura manier\ posibil\ este s\-i implementa]i
pe constructor [i destructor ca «proceduri legate la tip». ~n acest caz ei vor exista, `mpreun\
cu toate celelalte metode ale obiectului, chiar de la crearea acestuia, dinainte de ini]ializare.
Ve]i putea scrie atunci f.Init(…) pentru ini]ializarea obiectului f . Ceea ce este uzual pentru
cineva care programeaz\ cu obiecte.

Programarea calculatoarelor [i limbaje de programare 158 Dan Popa, 2007


Curs

10
Tipuri şi tipizare; De la tipuri simple la tipuri
de obiecte polimorfe

Noţiuni: Tipuri, tipuri simple , tipuri conpuse, ARRAY, RECORD, POINTER, indexare,
selectare câmp, dereferenţiere, tipuri de date şi operaţii, compatibilitate de tipuri la atribuire, ...la
apel de proceduri şi returnare de valori, povestea clientului de la CEC, lumi de obiecte polimorfe,
tipul static şi tipul dinamic, ce sunt extensiile de tip, tipul dinamic şi pointerii sau referinţele,
exemplul cec.mod, clase derivate, metode suprascrise, (invocarea metodei clasei părinte),
instrucţiunea with şi alte teste de tip, calea spre extensibilitate.

~n capitolele anterioare am `nt=lnit o serie de no]iuni legate de un subiect comun, tipuri [i


tipizare, iar exemplele practice ne-au ar\tat c\ nu putem ignora aspectele legate de tipuri fie
c\ e vorba de atribuiri (care nu “merg” dec=t dac\ e `ndeplinit\ o condi]ie privitoare la tipuri
– pe care am numit-o [i o voi numi `n glum\ “regula elefantului [i frigiderului” (Nu `ncape o
dat\ de tip “elefant” `ntr-o variabil\ de tip “frigider”.) - sau fie c\ e vorba de proceduri (care
se `nc\p\]=neaz\ s\ primeasc\ parametri [i s\ dea rezultate numai de anumite tipuri
declarate `n antet dup\ reguli numai de ele [tiute). E momentul s\ reunim `ntr-un capitol
comun aceste reguli [i cuno[tin]e, `n mare parte `nt=lnite pe ici pe colo prin exemple `ntr-o
expunere coerent\ despre tipuri [i s\ introducem noi no]iuni extrem de utile privind tipurile
de obiecte [i polimorfismul.

De ce ne intereseaz\ tipurile ? Practic, deoarece ele exprimn\ proprietatea limbajului de a


manipula diferite feluri de date. Un limbaj care manipuleaz\ numai bi]i, a[a cum e limbajul

Programarea calculatoarelor [i limbaje de programare 159 Dan Popa, 2007


cod ma[in\ este evident un limbaj mai dificil de folosit, fie [i pentru faptul c\ trebuie s\ ne
batem capul cum s\ prelucr\m [i s\ reprezent\m (mai `nt=i de toate) datele care ne
intereseaz\. Un limbaj care ne ofer\ mai mult `n materie de tipuri va trebui deci s\ rezolve
aceste probleme: reprezentarea [i prelucrarea datelor de diverse tipuri.Aceste tipuri de
date pot fi fie tipuri arhicunoscute, numere `ntregi, numere reale, litere cifre [i alte simboluri
tipografice fie, `n extrema cealalt\, h\r]i `ntregi ale palatelor califului sau cine [tie ce altceva
mai complicat dore[te utilizatorul. Evident, e bine s\ existe `n limbaj tipuri simple (m\car
`ntregii, realii, simbolurile tipografice [i valorile logice – iar ultimele lipsesc din limbajele
derivate din C dar nu [i din cele derivate din Pascal ! ) [i fire[te – foarte apreciate vor fi –
modalit\]ile de a creea tipuri noi pornind de la cele vechi, ob]in=ndu-se tipuri compuse,
tipuri provenite din alte tipuri, unele care con]in alte tipuri.

Not\ despre mul]imi: Un caz aparte dar oarecum minor `n Oberon este tipul mul]ime
(SET), care `n Pascal era un tip compus. Prof. Wirth, creatorul Oberonului a p\strat doar
tipul mul]ime sub form\ de tip predefinit SET cu semnifica]ia de mul]ime de numere `ntregi.
(La urma urmei a[a ceva nu prea reduce generalitatea deoarece cu asemenea indici putem
indexa [i astfel putem alege un element dintr-u vector de orice fel de componente. Deci o
mul]ime de indici induce astfel o mul]ime de orice fel de elemente, de tip simplu, compus
sau – de ce nu – de obiecte). C\uta]i tipul SET `n documenta]ia electronic\ [i ve]i `n]elege [i
de ce Oberon nu mai folose[te acoladele pentru comentarii ca Pascalul. Da, a]i ghicit, cu ele
se noteaz\ mul]imile, exact ca `n matematic\. Cu mul]imi se fac opera]ii notate cu plus [i
minus (reuniunea [i diferen]a de mul]imi). Operatorul “apar]ine” se scrie cu majuscule: IN,
apartenen]a elementului x la mul]imea M scriindu-se evident: x IN M. {i alte limbaje au un
asemenea operator pentru a testa apartenen]a elementelor la liste sau mul]imi, cum este
operatorul 'elem' din Haskell.

Tipurile simple pe care le-a]i `nt=lnit [i de care v\ aminti]i cu siguran]\ (de altfel acestea
patru exist\ aproape `n orice limbaj modern) sunt `ntregii, realii, caracterele tipografice [i
valorile logice.

~n Oberon aceste tipuri se numesc:

Programarea calculatoarelor [i limbaje de programare 160 Dan Popa, 2007



INTEGER - numerele `ntregi
REAL - numerele reale (`n simpl\ precizie)
CHAR - simbolurile tipografice (de exemplu de pe tastatur\)
BOOLEAN - valorile logice TRUE [i FALSE scrise cu majuscule
semnific=nd adev\rul [i falsul din logic\.


~n C aceste tipuri se numesc:
int - numerele `ntregi
float - numerele reale (`n simpl\ precizie)
char - simbolurile tipografice (de exemplu de pe tastatur\)
int - valorile logice TRUE [i FALSE sunt `n C `nlocuite de constantele 0 [i 1. ~n
esen]\ 1 `nseamn\ adev\r iar 0 fals.


Este de semnalat `n C [i prezen]a lui void, tipul care ]ine cumva loc de
mul]ime vid\. O procedur\ se va implementa `n C ca o func]ie care
returneaz\ un nimic, “elementul mul]imii vide” adic\ ceva din tipul void. De
re]inut aceast\ marc\ a procedurilor implementate ca func]ii `n C [i C++.


~n C++ principalele tipuri se numesc:
int - numerele `ntregi
float - numerele reale (`n simpl\ precizie)
char - simbolurile tipografice (de exemplu de pe tastatur\)
bool - un tip special nou introdus `n C++ pentru valorile logice TRUE [i FALSE.
Dar programatorii pot folosi [i folosesc `nc\ vechile conven]ii din C dup\ care adev\rul [i
falsul sunt `nlocuite,reprezentate de constantele (de tip int) 0 [i 1.

Aten]ie: Un tip de date nu este numai o mul]ime de valori ci o mul]ime de valori


`nzestrat\ cu opera]ii. S\ intre `n scen\ opera]iile ! Iat\-le (a[a cum sunt ele `n Oberon),
pentru fiecare din tipurile de mai sus.
INTEGER + - * DIV (`mp\r]irea `ntreag\ 10 DIV 3 d\ 3 ) [i MOD
care este operatorul “modulo” [i d\ nu c=tul (ca DIV) ci
restul `mp\r]irii a dou\ numere `ntregi

Programarea calculatoarelor [i limbaje de programare 161 Dan Popa, 2007


REAL + - * / (`mp\r]irea care d\ rezultate cu zecimale ). Nu e
nevoie de ridicare la putere, o combina]ie de logaritm [i
exponen]ial\ poate calcula pe a la b dup\ formula:
“ridica]i pe e la puterea b * log( a) )”. Verifica]i !
CHAR uzual nu se fac opera]ii cu ele, cel mult transform\ri din
caracter `n cod numeric (ASCII – American Standard
Code for Information Interchange) [i invers dar de
aceasta se ocup\ func]iile predefinite (ORD, CHR).
BOOLEAN - valorile logice TRUE [i FALSE pot fi supuse opera]iilor
din logic\: nega]ia scris\ “tilda” ~ , conjunc]ia scris\ &
(cum altfel s-ar putea mai simplu ?) [i disjunc]ia OR.
Deci sunt trei opera]ii: ~ & OR.


C=t despre opera]ii, unele sunt opera]ii interne pe mul]imea respectiv\
dar altele nu sunt, rezultatul fiind din alt\ mul]ime. ~mp\r]irea ( / ) a doi
`ntregi d\ un num\r real iar compararea (cu operatorii de compara]ie <, >,
>=,<=, = [i # adic\ diferit) a dou\ valori comparabile va da un rezultat
BOOLEAN, TRUE sau FALSE cu care apoi se pot face opera]ii logice ~ & OR. Aten]ie [i la
prioritatea operatorilor. Compara]iile sunt mai pu]in prioritare dec=t opera]iile logice
deci se vor scrie obligatoriu `ntre paranteze. Exemplu: o not\ este un num\r `ntreg n
astfel `nc=t (n>=1) & (n <= 10). {i fi]i siguri c\ doar a[a este corect `n Oberon! (~n C++ ar
fi fost: (n>=1) && (n <= 10)

Unele limbaje ofer\ [i tipuri numerice cu un interval mai mare de valori, cu mai multe
zecimale ([i care evident ocup\ pentru fiecare valoare mai mult\ memorie, adesea dublu.)
Oberon nu face excep]ie, lista tipurilor fiind dat\ `n documenta]ie (c\uta]i-o la Help ->
Compiler topics help):

1. BOOLEAN the truth values TRUE and FALSE


2. CHAR the characters of the extended ASCII set (0X..0FFX)
3. SHORTINT the integers between MIN(SHORTINT) and MAX(SHORTINT)
4. INTEGER the integers between MIN(INTEGER) and MAX(INTEGER)

Programarea calculatoarelor [i limbaje de programare 162 Dan Popa, 2007


5. LONGINT the integers between MIN(LONGINT) and MAX(LONGINT)
6. REAL the real numbers between MIN(REAL) and MAX(REAL)
7. LONGREAL the real nr. between MIN(LONGREAL) and MAX(LONGREAL)
8. SET the sets of integers between 0 and MAX(SET)

Am citat din Help-ul care `nso]e[te Pow, preciz=nd pentru ne[tiutorii de englez\ c\
“between” `nseamn\ “`ntre” iar expresiile scrise cu majuscule ne dau valoarea minim\
(prima) [i maxim\ (ultima) pentru fiecare dintre tipuri. Dac\ `n loc de valori concrete folosi]i
aceste nota]ii atunci programul dumneavoastr\ va rula pe orice implementare de Oberon,
adapt=ndu-se tipurilor din acea implementare.

La r=ndul lor, limbajele din familia C-ului ofer\ ni[te modificatori de tip, cuvinte cheie cum ar
fi: unsigned, signed, short, long, double. Traducerea lor este imediat\. (Signed [i short sunt
desemantizate, prezen]a sau absen]a lor nu schimb\ nimic din reprezentare.) folosi]i `n
general ace[ti modificatori `n situa]iile `n care opera]i cu valori mai mari dec=t cele din tipul
uzual. (Exemplu: Dac\ folosi]i `ntregi pozitivi dincolo de 32768 [i p`n\ la 65535 opta]i pentru
unsigned int care se poate prescurta la unsigned. Dac\ utiliza]i `ntregi mult mai mari, cu
semn, cam p`n\ pe la dou\ miliarde pute]i folosi `ntregii pe 32 de bi]i: long int. Numerele
reale cu 5-6 zecimale exacte sunt float iar cele cu 10 zecimale exacte sunt double.)

Compatibilitatea de tipuri la atribuire (“regula elefantului [i frigiderului”): La scrierea unei


atribuiri tipul expresiei din dreapta atribuirii trebuie s\ fie `n compatibil cu tipul variabilei sau
elementului / designatorului din st=nga atribuirii, `n sensul c\:
1) Este vorba de acela[i tip
2) Tipul expresiei este inclus (din punct de vedere al matematicianului) `n tipul
designatorului sau variabilei asupra c\reia se face atribuirea. Exemplu evident: variabila
real\ r poate lua valoarea constantei `ntregi 1 sau a altei constante sau expresii `ntregi.
Deoarece numerele `ntregi sunt numere reale.
3) La recorduri [i pointeri avem reguli speciale de compatibilitate care, `n principiu
statueaz\ faptul c\ un record extins (vom vedea cum se scrie a[a ceva `n Oberon) este
compatibil cu un record din care a provenit prin extinderi succesive. Ceva similar exist\ [i
`n C++ la clase de obiecte derivate una din alta. ~ntr-un fel acest lucru este natural,

Programarea calculatoarelor [i limbaje de programare 163 Dan Popa, 2007


recordul extins (cu mai multe c=mpuri) posed\ [i c=mpurile din recordul ini]ial. Vom
reveni la ele pe parcursul acestui capitol. Definim ceva mai t=rziu ce este extensia la
tipurile pointeri (lor nu li se adaug\ c=mpuri noi).

Compatibilitatea de tipuri la apelul de proceduri. Procedurile, [tim deja, au `n antet


(primul r=nd) o list\ de parametri (numi]i parametri formali – incluz=nd eventual aici [i tipul
rezultatului, dac\ vre]i). Ea specific\ ce tipuri de date schimb\ procedura cu lumea
exterioar\, `n ce ordine le prime[te (scrise ca argumente, separate prin virgule) cum le
nume[te procedura pentru uzul ei intern [i pe care are voie s\ le modifice (cele
decalarate cu VAR - parametrii variabil\, transmi[i prin referin]\). At=t ceea ce prime[te
procedura (parametri actuali) din momentul apelului c=t [i ceea ce returneaz\ trebuie s\ se
potriveasc\ acestei scheme. Regula de compatibilitate este la fel ca la atribuire. Imagina]i-v\
c\ `n momentul primirii parametrilor [i return\rii rezultatului cu RETURN se fac ni[te
atribuiri invizibile.

Cum afl\ sistemul tipul unei expresii ? Compilatorul include un modul numit “type
checker” adic\ “verificator de tipuri” capabil s\ aplice asupra unei expresii reguli de tipul
“dac\ operanzii sunt de anume tipuri [i operatorul este cutare atunci rezultatul este de tipul
cutare (exemplu: `mp\r]irea a doi `ntregi folosind operatorul “/” d\ un rezultat real). Astfel,
din aproape `n aproape, sistemul afl\ la compilare tipul expresiei. Faptul c\ la aceast\
verificare se folosesc a[a-zisele “gramatici cu atribute” e un seceret [tiut doar de
constructorii de compilatoare.

Problema determin\rii tipului designatorului din st=nga atribuirii are o rezolvare mai
complex\ atunci c=nd e vorba de tipuri compuse. Reamintim c=te ceva despre ele:

~n Oberon putem defini tipuri compuse `n mai multe feluri. Descrierile de tipuri compuse pot
fi folosite direct pentru a declara variabile (se numesc tipuri anonime) sau pot primi un
nume (tipuri nominale) `n cadrul sec]iunii TYPE (sec]iune care poate exista at=t la nivel de
modul – tipuri globale modulului – c=t [i la nivel de procedur\ - [i atunci doar acolo, `n
procedur\, sunt valabile noile tipuri).

Programarea calculatoarelor [i limbaje de programare 164 Dan Popa, 2007


~n acest caz se scrie `n sec]iunea TYPE o egalitate <identificator tip nou> = <descriere
de tip>
Descrierile pot fi de mai multe feluri [i se pot imbrica (pune una `n alta pe principiul pe[telui
care a m=ncat alt pe[te) p=n\ ob]inem tipul dorit. Sau se pot baza pe tipuri anterior definite.
Se pot declara `n Oberon ([i foarte asem\n\tor `n Pascal – dar cu totul altfel `n C,C++):

1) Vectori sau matrice cu :


ARRAY <lista de dimensiuni> OF <tip element>
Vectorul are doar o dimensiune, num\rul de elemente, iar indexarea `ncepe `n Oberon de la
zero ca [i `n C.
Operatorul folosit la separarea, desemnarea unei componente a unui vector este paranteza
p\trat\ [ ], `n care se scrie indicele sau, la matrice, lista indicilor separa]i prin virgule (deci vi
se va scrie v [ i ] pentru un element de vector iar ma,b se va scrie m[a,b] pentru a
desemna un element dintr-o matrice).

2) Record-uri (articole) sau obiecte ([tim c\ obiectul e un record `nzestrat cu proceduri


numite metode)
RECORD <list\ de c=mpuri> END
unde (`n Oberon!) c=mpurile se declar\ ca ni[te variabile, cu nume [i tip dar f\r\ VAR.
Selectarea unui c\mp dintr-un record se face cu operatorul punct, la fel ca selectarea unei
instruc]iuni (proceduri apelate) dintr-un modul sau a unei metode dintr-un obiect. Nu uita]i c\
record-ul poate con]ine [i c=mpuri procedurale (“procedure types”). (Apropos de c=mpurile
procedurale: s-ar putea folosi a[a ceva [i declar=nd variabile procedurale. Eu le folosesc
adesea `n loc de declara]iile FORWARD din Pascal [i le ini]ializez la final de modul. Sunt
utile atunci c=nd am `n modul proceduri mutual recursive, care apel=ndu-se una pe alta
genereaz\ problema clasic\: “pe care o scriem prima ?”. {i nu numai atunci.)

Atribuirile cu recorduri se fac prin proiec]ie. Valoarea unui variabile record cu mai multe
c=mpuri dec=t a altuia (vom vedea c\ se poate declara un asemenea tip extins) se poate
atribui unei variabile (designator) al unui record cu mai pu]ine c=mpuri. Evident c\ se
copie din record-ul mai amplu doar c=mpurile care `ncap, adic\ cele comune celor dou\
structuri.

Programarea calculatoarelor [i limbaje de programare 165 Dan Popa, 2007


3) Tipurile pointer. Sunt necesare atunci c=nd avem obiecte (record-uri) care trebuie s\ se
nasc\ (cu NEW) [i s\ dispar\ dinamic [i c=nd vrem s\ realiz\m structuri de date pun=nd
obiectele (record-urile) `n rela]ii. Exemple: atunci c=nd avem nevoie de liste, arbori [i
grafuri. Descrierea tipului nou declarat este `n Oberon de forma:
POINTER TO <alt tip>
unde <alt tip> este de obicei un tip record (sau obiect - de[i teoria spune c\ poate fi [i un
ARRAY). Acest <alt tip> nu poate fi tip simplu ca `n Pascal.
Cum desemnez obiectul (record-ul) indicat de pointer ? Cu operatorul ^ “c\ciuli]\” numit
operator de dereferen]iere. Deci dac\ S este pointerul S^ este obiectul sau recordul (sau
vectorul – teoretic poate fi [i vector) indicat.


Aten]ie: ~n Oberon dereferen]ierea este implicit\ dac\ urmeaz\ o selec]
ie, deci dac\ S e un pointer la record sau obiect pute]i folosi pe S ca [i
cum ar fi `nsu[i obiectul, av=nd acces cu S.<c=mp> la c=mpurile lui.

Cum afl\ sistemul tipul designatorului din st=nga atribuirii ? Dup\ declara]iile de tip. ~n
exemplul cu palatul califului, nota]iei (designatorului) p[salacrt].usa[nrusa] i se stabile[te
tipul astfel:
p – e de tipul Palat conform declara]iei variabilei p
p[salacrt] – e o component\ a tipului palat, care e vector (ARRAY ...
OF Camera) deci este de tipul Camera, un tip record.
Cu ocazia aceasta se verific\ [i tipul indicelui, care e corect
fiind `ntreg. (variabila salacrt era declarat\ de tip INTEGER).
p[salacrt].usa - are sens deoarece din tipul Camera, care e un record, se
alege o component\ numit\ “usa”. La r=ndul ei aceasta e un
vector (vede]i declara]iile din acel program) [i are sens s\ scriu:
p[salacrt].usa[nrusa] ... fiindc\ nru[\ are tipul `ntreg [i
este deci bun ca indice.
p[salacrt].usa[nrusa] - este din palat, dintr-o anume sal\, o u[\ din vectorul de u[i
anume cea cu num\rul nrusa [i are tipul tuturor elementelor
vectorului u[a, adic\ `ntreg deoarece a[a era declarat vectorul.

Programarea calculatoarelor [i limbaje de programare 166 Dan Popa, 2007


Din nefericire, `n lumea exemplelor reale, tipurile nu sunt a[a de simple cum erau camerele
din palatul califului iar uneori se manifest\ de parc\ ar fi [i totodat\ n-ar fi tipuri diferite. Un
asemenea exemplu, cu tipuri deosebite, prezent\m odat\ cu povestea clientului de la CEC,
care urmeaz\;

Povestea clientului de la CEC


Sau un exemplu că în lumea reală tipurile sunt capabile de polimorfism. Şi că este natural să ne
gândim la tipuri extinse.
Tipul static şi tipul dinamic, ce sunt extensiile de tip, tipul dinamic şi pointerii sau referinţele,
exemplul cec.mod, clase derivate, metode suprascrise, (invocarea metodei clasei părinte),
instrucţiunea with şi alte teste de tip.

Povestea clientului de la CEC v\ este binecunoscut\ multora, deoarece p=n\ la aceast\


v=rst\ a]i fost nu o dat\ `n situa]ia de a depune sau a retrage bani de la CEC sau de la o
banc\ oarecare. Dat fiind c\ vom face [i o implementare a acestui fragment de realitate, voi
povesti pas cu pas ac]iunile clientului nostru. Imagina]i-v\ scena. Ac]iunea se petrece `ntr-o
mic\ localitate unde exist\ un singur ghi[eu CEC [i, eventual, o mas\ plin\ cu formulare de
depunere [i restituire, mas\ la care ia loc clientul `n timp ce-[i completeaz\ formularul
necesar pentru opera]iunea dorit\. Exist\ un singur func]ionar la singurul ghi[eu (deci nu
vom implementa clasa de obiecte “func]ionar” - ceea ce am fi f\cut dac\ model\m ac]iunea
clien]ilor unui sediu CEC central. Oricum, nu sc\pa]i din g=nd acest al doilea scenariu
pentru a v\ putea r\spunde singuri la `ntrebarea ce modific\ri antreneaz\ el.)
Povestea decurge a[a: Vine clientul, ia un formular de pe mas\, `l completeaz\. Formularul
este apoi citit de client (s\ vad\ cum l-a completat – [i s\-l vedem [i noi) apoi prelucrat de
func]ionar care anun]\ ce opera]ie a f\cut spun=nd “V\ adaug `n cont depunerea.” sau “V\
scad din cont restituirea.” La urma urmei poate c\ func]ionarul nu roste[te exact aceste
cuvinte dar important e un lucru: el are dou\ opera]ii de f\cut [i va trebui s\ decid\ ce face
dup\ tipul formularului primit (dar vom vedea c\ exist\ [i un al treilea caz, cel al
formularului necompletat sau completat gre[it, caz `n care func]ionarul trebuie s\ fac\
altceva, s\-l ignore pur [i simplu sau s\ protesteze, de exemplu `ntreb\nd ce formular e
acela). {i am ajuns iar s\ vorbim despre tipuri.

Programarea calculatoarelor [i limbaje de programare 167 Dan Popa, 2007


Dac\ a[ declara variabila formular cum a[ declara-o ? La urma urmei sunt dou\ feluri de
formulare, deci mi-ar trebui la prima vedere dou\ clase de obiecte (Vom vedea, paradoxal `n
aparen]\, c\ treaba se simplific\ cel mai mult dac\ folosim o ierarhie de clase cu trei tipuri
de obiecte, primul tip con]in=nd informa]iile comune ambelor tipuri derivate din el.)
Cum voi declara aceste obiecte formular, ca recorduri sau ca pointeri ? ({tim deja c\ `n
Oberon se pot folosi pointeri la obiecte ca [i obiectele `nse[i, dereferen]ierea cu operatorul
“c\ciuli]\” fiind automat\ nu va trebui s\-l scriem pentru a transforma pointerul, adresa, `n
obiectul `nsu[i.) Aici r\spunsul e simplu, fiind vorba de obiecte care sunt create dup\
necesit\]i [i din care exist\ o rezerv\ teoretic infinit\ vom lucra cu pointeri [i vom crea
obiectele cu NEW. Problema e c\ formularul oferit func]ionarului ar trebui s\ poat\ s\-[i
schimbe tipul, fiind o dat\ formular de depunere, alt\ dat\ formular de restituire. Aici intr\ `n
scen\ tipurile dinamice. S\ `ncerc\m s\ le definim:


Defini]ie: ~n Oberon obiectele (recordurile) [i (printr-un fenomen de
inducere) pointerii au at=t un tip static c=t [i un tip dinamic. Tipul static
este tipul care apare `n declara]ie. ~l pute]i afla citind pur [i simplu
programul. Tipul dinamic este sau egal cu tipul static (ceea ce se `nt=mpl\
foarte des la record-uri [i obiecte nereprezentate prin pointeri) sau este o extensie a tipului
static.

Acesta din urm\ `n cazul c=nd lucr\m cu pointeri. (At=t tipurile extinse c=t [i pointerii la ele,
vom vedea c\ sunt compatibil la atribuire cu tipul de baz\ din care provin, pe care `l extind.
De altfel este evident c\ dac\ un record are mai multe c=mpuri ca altul valorile din el ne
ajung pentru a le atribui unui record care are doar o parte dintre aceste c=mpuri. La fel [i la
pointeri. Valoarea (adresa de fapt) care e un pointer ce indic\ o structur\ cu mai multe
c\mpuri poate fi atribuit\ unui pointer care indic\ o structur\ cu mai pu]ine c=mpuri – prima
parte din acele multe c=mpuri.)

Figura 1: Atribuirea dintre obiectul extins [i obiectul de baz\ (pointeri), desen preluat din lucrarea Object-Oriented Programming
in Oberon-2, de Hanspeter MÖSSENBÖCK, de pe site-ul Universit\]ii din Linz – citat anterior.

Programarea calculatoarelor [i limbaje de programare 168 Dan Popa, 2007


Vi se pare complicat, dificil ? Probabil c\ da, deoarece n-am explicat ce sunt tipurile record
extinse [i cum se scriu ele `n Oberon. Iat\ ceva mai jos un exemplu.


~n versiunea de Oberon cu care este livrat mediul Pow (Red Chili Oberon-
2 compiler) tipurile record sunt toate implicit extensibile ([i nu se cere
s\ preciz\m nimic pentru aceasta ca `n alte dialecte de Oberon). Ca
urmare putem defini un nou fel de tip record (sau obiect) indic=nd
doar ce au `n plus obiectele din noua clas\ (tip record) fa]\ de predecesoarele lor din
clasa p\rinte, acel tip record de la care mo[tenesc totul. Pe scurt, dac\ o clas\ de obiecte
pe care o am `n program este destul de bun\ pentru ceea ce vreau s\ fac dar mai are
nevoie de ceva `n plus (date sau comportamente exprimate prin metode) nu este nevoie s\
o scriu din nou, ci doar s\ indic tipul din care provine (clasa p\rinte sau – sinonim – tipul din
care deriveaz\, pe care `l extinde) [i s\ mai scriu doar ce are ea `n plus, c=mpuri de date
sau metode. Sintactic (`n Oberon) recordurile extensibile se scriu `n sec]iunea TYPE a
modulului sau a unei proceduri scriind dup\ cuv=ntul RECORD o parantez\ ce con]ine tipul
p\rinte, (tipul pe care `l extind, de la care mo[tenesc). Mo[tenirea multipl\ nu este posibil\ `n
Oberon. Deci:

TYPE IdentificatorTipNou = RECORD (IdentificatorTipVechi)


...
END

E simplu de ]inut minte, dup\ RECORD scrie]i numele tipului p\rinte `ntr-o parantez\.
O nota]ie similar\ exist\ [i `n limbajul C++. Acolo clasele derivate au [i ele `n declara]ia lor
numele clasei din care au derivat dar numele nu este pus `ntr-o paranteza ci este precedat
de un ':' [i un cuv=nt care specific\ felul de mo[tenire (public, private sau protected).


Dac\ vreau s\ schimb un comportament (adic\ ceea ce face o metod\
existent\) ei bine, scriu noua metod\ (cu acela[i nume [i aceea[i
semn\tur\ adic\ schem\ de parametri) iar noua metod\ o va acoperi,
o va `nlocui pe cealalt\, `n noua clas\. E cam la fel ca la variabile globale
[i locale, unde o variabil\ local\ cu acela[i nume o acoperea pe cea global\ sau pe cea

Programarea calculatoarelor [i limbaje de programare 169 Dan Popa, 2007


declarat\ `n procedura exterioar\. Acest fenomen de suprascriere a metodelor `n clasele
derivate (tipurile extinse) nu produce nici o eroare. De altfel el constituie unul din
mecanismele realiz\rii extensibilit\]ii `n Oberon.


Astfel noile clase de obiecte vor r\spunde la acelea[i cereri de a presta
servicii ca [i precedentele (serviciile, metodele, se solicit\ `n mod unitar
indiferent de tipul dinamic al obiectului) dar se vor comporta polimorfic,
f\c=nd ce li se cere dar `n diverse feluri. A[a c\ vom putea extinde un
enorm program deja existent dar f\r\ s\ schimb\m un r=nd `n el. Sun\ promi]\tor, nu-i a[a ?
(O tehnic\ modern\ de programare de acest fel – de care eu cel pu]in n-am auzit [i nici n-
am citit nimic `n publica]iile rom=ne[ti, tehnic\ cu care noile func]ionalit\]i sunt ad\ugate
treptat este “programming by difference” - programarea prin diferen]\). Revin la `ns\ ideea
extinderii:

Este nevoie doar s\-l punem pe program s\ prelucreze obiectele unei clase extinse, iar noile
func]ionalit\]i vor fi incluse `n metodele (suprascrise evident) ale noii clase de obiecte.
Programul r\m=ne la fel [i asemena func]ionarului de la CEC prime[te [i alte feluri de
documente (adic\ mesaje), eventual cu riscul de a nu [ti ce s\ fac\ cu ele. De altfel `ntr-un
mediu de obiecte care interac]ioneaz\ prin mesaje transmise prin difuzare (broadcasting)
adesea unele mesaje ajung [i la obiectele (“ascult\torii”) neaviza]i, care nu [tiu ce s\ fac\
recep]ion=ndu-le. Obiectele respective vor ignora aceste mesaje sau, dac\ sunt programate,
le vor trimite mai departe.
Totu[i acest lucru nu produce erori `n sistem iar obiectele [tiu s\ diferen]ieze mesajele
(cam ca func]ionarul de la CEC formularele) ceea ce fac de exemplu cu ajutorul instruc]iunii
WITH (Care WITH din Oberon nu seam\n\ deloc cu cel din Pascal). Ca idee, instruc]iu-
nea WITH este un fel de CASE pentru tipuri. CASE alegea ce avea de executat dup\
valoarea unei expresii. WITH alege ceea ce are de executat dup\ tipul dinamic al unei
variabile. Teoria mai spune c\ WITH trateaz\ acea variabil\, pe fiecare ramur\ respectiv, ca
[i cum ar fi chiar de tipul static depistat prin test. Iat-o, explicat\ pe scurt (`n documenta]ia
electronic\ exist\ o explica]ie succint\ dar mai tehnic\, folosind no]iunea de gard\ sau
gardian de tip - `n englez\ “type guard”, neexplicat\ `ns\ de noi aici):

Programarea calculatoarelor [i limbaje de programare 170 Dan Popa, 2007



Sintactic WITH se scrie astfel: Cuv=ntul rezervat WITH urmat de ni[te
alternative formate dintr-un test de tip aplicat unei variabile apoi
cuv=ntul rezervat DO urmat de secven]a de instruc]iuni care urmeaz\ a fi
executate `n acel caz. Pot fi mai multe asemenea alternative separate prin
simbolul “bar\ vertical\” (cel care se ob]ine tast=nd SHIFT `mpreun\ cu “backslash”.)
Aceast\ instruc]iune pentru test\ri de tipuri are `n Oberon sintaxa:

Instruc]iuneaWith = WITH TestDeTip DO Secven]\DeInstruc]iuni


{"|" TestDeTip DO Secven]\DeInstruc]iuni }
[ELSE StatementSequence]
END.

TestDeTip = ldentificatorDeVariabil\ ":" ldentificatorDeTip. Poate fi “caliifcat”, prefixat


cu un nume de modul [i separat de acesta cu punct.

Aten]ie: Ca de obicei acoladele nu fac parte din instruc]iune, sunt doar un mod de a marca
partea op]ional\ care poate apare de oric=te ori este nevoie (inclusiv niciodat\) iar
parantezele p\trate marcheaz\ partea op]ional\ care apare f\r\ repeti]ii (o dat\ sau
niciodat\). Egalul [i punctul final nu fac nici ele parte din instruc]iune ci sunt specifice
modului de descriera a sintaxei folosit.

Un exemplu comentat : cec.mod


Implementarea sub forma unei ierarhii de trei clase (cu cîte două metode fiecare) a poveştii
clientului de la CEC. Prelucraea obiectelor polimorfice se face sub controlul unei instrucţiuni
WITH.

Tipurile de date vor fi primele pe care le declar\m. Avem nevoie de dou\ tipuri derivate
Depunere [i Restituire. Ele con]in ambele Numele, Prenumele [i Num\rul de cont al
clientului plus un c=mp suplimentar, Suma depus\, pentru formularul de depunere [i
respectiv suma restituit\, pentru formularul de restituire. Componentele lor comune se
declar\ `n clasa (tipul) de la baza ierarhiei. Ambele tipuri derivate vor mo[teni aceste

Programarea calculatoarelor [i limbaje de programare 171 Dan Popa, 2007


c=mpuri. (Unii programatori prefer\ la baza ierarhiei un tip f\r\ componente din care
deriveaz\ toate. V\ spun peste `nc\ un paragraf la ce este el util.)

Curio[ii vor g\si `n documenta]ia electronic\ ce `nso]e[te POW un modul OOPBase care
ofer\ de-a gata o clas\ de baz\ numai bun\ pentru a `ncepe o ierarhie de clase. Are chiar [i
metoda Init (constructorul obiectelor) declarat\, (o ve]i suprascrie `n clasele derivate)
precum [i alte facilit\]i. Acest modul poate fi importat de c\tre alte module `n care sunt
definite noi clase de obiecte. Astfel clasele de obiecte pot fi ad\ugate modul cu modul
extinz=nd aplica]ia. Nici clasa de la baza ierarhiei [i nici ProgMain-ul nu mai trebuie s\ fie `n
acela[i modul cu clasele derivate (cum este `n exemplul nostru din dorin]a de a nu-l r\sfira
pe trei-patru module). Profesioni[tii adaug\ clasele noi modul cu modul [i declar\ `n fiecare
asemenea modul c\ import\ modulul OOPBase. Alte medii de programare [i alte limbaje
pentru OOP ofer\ [i ele ceva asem\n\tor.


Foarte important [i util: Pointerii la tipul de la baza ierarhiei vor fi
compatibili cu pointerii la tipurile extinse, derivate. Practic ei pot ar\ta
orice fel de obiect, dup\ o atribuire ca cea din Figura1 (aflat\ cu circa 10
pagini `napoi). {i tocmai tipul acelui obiect va fi tipul lor dinamic!.
Practic dac\ vrem s\ indic\m un obiect oarecare declar\m o variabil\ pointer la tipul
de obiecte care este baza ierarhiei.

~n exemplul nostru cu CEC-ul pentru fiecare fel de formular declar at=t pointerul la tipul lui
c=t [i tipul record care-i descrie c=mpurile. Vor fi trei feluri de formulare, formularul generic
numit Formular, cel de Depunere (`l extinde pe Formular) [i cel de restituire (`l extinde tot pe
Formular). De fapt sunt pointeri [i iat\ un motiv `n plus s\ lucr\m cu pointeri `n Oberon:
Rela]ia de extindere `ntre tipurile record din Oberon este transferat\ [i la pointeri
astfel c\ tipurile pointeri corespunz\toare sunt tot extinderi unul altuia `n aceea[i
ordine. Iar cu operatorul «.» putem accesa at=t datele c=t [i metodele obiectului indicat de
pointer. Ceea ce face ca metodele ata[ate tipului record (proceduri legate la tip) s\ par\ c\
apar]in [i tipului pointer ce indic\ acele recorduri.

MODULE Cec; (* Dan Popa v.3, decembrie 2004 *)

Programarea calculatoarelor [i limbaje de programare 172 Dan Popa, 2007



(* Mesajul = adica foaia, este primit si prelucrat de o procedura *)
(* In mod normal ea ar apartine, fiind o metoda, unui obiect care
primeste mesaje – aici inexistent *)

IMPORT D:=Display;
TYPE Formular=POINTER TO FormularT;
FormularT=RECORD
nume:ARRAY 10 OF CHAR;
prenume:ARRAY 10 OF CHAR;
nrcont:INTEGER;
END;

Am declarat tipul record de la baza ierarhiei(va deveni obiect c=nd `i vom scrie metodele).
Inten]ion\m s\ lucr\m cu pointeri la obiecte (`n locul obiectelor `nse[i) deoarece vrem s\
gener\m dinamic obiectele (pointerul va fi argumentul pentru NEW) [i vrem s\ beneficiem [i
de polimorfism.
La modul general, un formular oarecare va con]ine: nume, prenume, nrcont. Tipurile record
extinse le vom numi DepunereT [i RestituireT. Declar\m [i tipurile pointer aferente.

Depunere=POINTER TO DepunereT;
DepunereT=RECORD (FormularT);
SumaDepusa : INTEGER;
END;

Restituire=POINTER TO RestituireT;
RestituireT=RECORD (FormularT);
SumaRestituita : INTEGER;
END;

Tipul DepunereT `mpreun\ cu tipul RestituireT sunt extinderi ale tipului FormularT. Prin
urmare [i tipul Depunere c`t [i tipul Restituire sunt extinderi ale tipului Formular (rela]ia de
la recorduri se transmite la pointeri).

Programarea calculatoarelor [i limbaje de programare 173 Dan Popa, 2007


Aten]ie: aceste declara]ii de tipuri ne dau practic schemele comune ale viitoarelor obiecte
din tipurile (clasele) respective. Nu sunt declara]iile variabilelor obiect. Vom vedea c\ `n
programul principal va fi o singur\ variabil\ de tip static Formular, pointerul la obiectul
polimorf (care obiect va fi creat pentru a simula momentul c=nd clientul ia formularul de pe
mas\).

VAR err :CHAR;

De aceast\ variabil\ ca parametru au nevoie instruc]iunile (apelurile de proceduri) Read...


din modulul Display. {tia]i deja.
Urmeaz\ s\ scriem metodele claselor de obiecte ca proceduri legate la tipurile respective
(recordurile). Fiecare clas\ de obiecte va avea dou\ metode numite Completeaz\ (e practic
constructorul clasei) [i A[aArat\ (metoda care afi[eaz\ datele din obiect pentru uzul nostru,
ca s\ vedem pe ecran ce se petrece [i cum se manifest\ polimorfismul).

PROCEDURE (VAR f:FormularT) Completare ();


BEGIN
D.WriteStr(" Completare formular "); D.WriteLn;
D.WriteStr(" Numele = "); D.ReadStr(f.nume,10,err); D.WriteLn;
D.WriteStr(" Prenume = "); D.ReadStr(f.prenume,10,err); D.WriteLn();
D.WriteStr(" Nr. cont = "); D.ReadInt(f.nrcont,10,err); D.WriteLn();
END Completare;

Completarea formularului generic ? Computerul `ntreab\ care sunt numele, prenumel [i


num\rul de cont. Observa]i c\ procedura e legat\ la tipul FormularT iar obiectul formular
curent e numit f. Iat\ [i metoda care afi[eaz\ datele introduse.
PROCEDURE (VAR f:FormularT) AsaArata();
BEGIN
D.WriteStr(" Numele = "); D.WriteStr(f.nume); D.WriteLn;
D.WriteStr(" Prenume = "); D.WriteStr(f.prenume); D.WriteLn();
D.WriteStr(" Nr. cont = "); D.WriteInt(f.nrcont,10); D.WriteLn();
END AsaArata;

Programarea calculatoarelor [i limbaje de programare 174 Dan Popa, 2007


Observa]i c\ nu face dec=t s\ scrie cu Write-uri acelea[i date din obiectul curent. La
completarea formularului de depunere ar trebui s\ se `ntrebe din nou de con]inutul
c=mpurilor nume, prenume, nrcont dar, bucurie mare, putem apela metoda clasei p\rinte !
Observa]i prima instruc]iune de dup\ BEGIN:

PROCEDURE (VAR f : DepunereT) Completare ();


BEGIN f.Completare^();
D.WriteStr(" Depunere = "); D.ReadInt(f.SumaDepusa,10,err); D.WriteLn();
END Completare;

Sintactic vorbind, apelul metodei din clasa p\rinte se face scriind designatorul obiectului
(variabila obiect aici), punctul, numele metodei [i semnul c\ciuli]\ care indic\ faptul c\
metoda va fi cea de la clasa precedent\.

PROCEDURE (VAR f : DepunereT) AsaArata ();


BEGIN
D.WriteStr(" = Formular de DEPUNERE = "); D.WriteLn;
f. AsaArata^();
D.WriteStr(" Depunere = "); D.WriteInt(f.SumaDepusa,10); D.WriteLn();
END AsaArata;

La cererea de a se afi[a a[a cum arat\, formularul de depunere va afi[a un titlu, va apela
metoda clasei p\rinte pentru a afi[a numele, prenumele [i nrcont apoi va afi[a informa]ia
despre depunere, valoarea sumei.

PROCEDURE (VAR f:RestituireT) Completare ();


BEGIN
f.Completare^();
D.WriteStr(" Restituire = "); D.ReadInt(f.SumaRestituita,10,err); D.WriteLn();
END Completare;

PROCEDURE (VAR f:RestituireT) AsaArata ();

Programarea calculatoarelor [i limbaje de programare 175 Dan Popa, 2007


BEGIN
D.WriteStr(" = Formular de RESTITUIRE = "); D.WriteLn;
f.AsaArata^();
D.WriteStr(" Restituire = "); D.WriteInt(f.SumaRestituita,10); D.WriteLn();
END AsaArata;

La fel au decurs lucrurile [i pentru Restituire. Urmeaz\ o procedur\ func]ional\ capabil\ s\


creeze obiectul polimorf [i care va returna adresa lui. Tipul acestuia va fi Formular (tipul
static,declarat) dar va putea returna adrese ale unor obiecte de alte feluri
(foaie_de_depunere [i foaie_de_restituire sunt de alte tipuri). Observa]i mai jos ce
returneaz\ cele dou\ RETURN-uri [i cum sunt declarate foaie_de_depunere [i
foaie_de_restituire).

PROCEDURE IaUnFormular() : Formular;


VAR foaie_de_depunere:Depunere;
foaie_de_restituire:Restituire;
foaie:Formular;
tasta:CHAR;

Deoarece va trebui s\ creeze cu NEW trei feluri de obiecte, acelor NEW-uri li se vor da ca
parametri trei feluri de pointeri, capabili a indica un FormularT, o DepunereT sau o
RestituireT. Utilizatorul va indica prin apasare pe o tasta (variabila tasta de tip CHAR) ce fel
de obiect dore[te s\ se returneze. Dac\ nu alege corect d sau r se va genera [i returna un
formular generic. Alegerea felului de formular ce se va genera o face procedura dup\
valoarea variabilei tasta. Fiind o alegere dup\ valoare se folose[te CASE.

BEGIN
D.WriteStr("Ce formular doriti ? d=Depunere, r=restituire = ");
D.ReadChar(tasta); D.WriteLn;
CASE tasta OF
"d" : NEW(foaie_de_depunere); RETURN foaie_de_depunere
| "r" : NEW(foaie_de_restituire); RETURN foaie_de_restituire;

Programarea calculatoarelor [i limbaje de programare 176 Dan Popa, 2007


ELSE
NEW (foaie); RETURN foaie;
END;
END IaUnFormular;


Procedura IaUnFormular e deosebit\ de tot ce am `nt=lnit: Cele trei
RETURN-uri au ca argument c=te o dat\ de alt tip dar toate aceste tipuri
sunt pointeri la obiectele de pe o ierarhie de clase de obiecte (tipuri
extensibile `n fond) iar aceste obiecte pot fi indicate de un pointer la clasa
de baz\. Deci adresele celor trei obiecte sunt compatibile cu tipul rezultatului scris `n
antet, pointer la clasa de baz\, deoarece sunt extensii ale acestuia.Verifica]i recitind
declara]iile [i nu uita]i c\ rela]ia de extindere de la tipurile RECORD se transmite [i la
pointeri.

PROCEDURE Prelucrare (VAR o:Formular);


BEGIN
WITH
o:Depunere DO
D.WriteStr(" Va adaug in cont depunerea ");D.WriteLn();
| o:Restituire DO
D.WriteStr(" Va scad din cont restituirea "); D.WriteLn();
ELSE
D.WriteStr(" Ce fel de formular e acesta ? "); D.WriteLn();
END;
END Prelucrare;

Ni[te preciz\ri tehnice pentru viitorii exper]i `n OOP: Procedura de prelucrare este de
fapt un «handler» , un manipulator de mesaje. (Considera]i acele formulare ca fiind exemple
de mesaje ce se pot transmite `ntr-un univers de obiecte). ~n teoria OOP-ului obiectele
din universul modelat care vor r\spunde la mesaje implementate prin asemenea
record-uri (sau obiecte – Da, mesajele ar putea fi ele `nsele obiecte ca [i `n exemplul

Programarea calculatoarelor [i limbaje de programare 177 Dan Popa, 2007


nostru!) vor avea printre metode un asemenea handler. Acesta `ns\ merit\ s\ fie
implemetat nu prin procedur\ legat\ la tip ci prin c=mp procedural. Astfel unor `ntregi clase
mai vechi de obiecte li se pot schimba handlerele pentru a le implementa noi
comportamente, dac\ e cazul, comportamente care descriu reac]iile lor la noile tipuri de
mesaje ad\ugate `n aplica]ie. Dar cele de mai sus sunt mai cur\nd o anticipare a unui alt
capitol despre OOP. Revenim la exemplul nostru, din care mai avem de scris ProgMain-ul.

PROCEDURE ProgMain*;
VAR foaie:Formular; (* polimorfism *)
BEGIN
foaie:=IaUnFormular(); (* rezultaul are tip dinamic *)
foaie.Completare(); (* alegerea metodei e dinamica *)
foaie.AsaArata(); (* alegerea metodei e dinamica *)
Prelucrare(foaie); (* Prelucrarea se face diferentiat *)
(* E procedura "handler" de mesaje=foi *)
(* locul ei ar fi fost intr-un obiect *)
REPEAT UNTIL D.KeyPressed();
END ProgMain;

END Cec.

C=teva comentarii: Programul e unitar, alternativele, diferitele detalii ale celor dou\ feluri
de formulare sunt ascunse. Foaie va fi obiect polimorfic, tipul s\u dinamic (Depunere sau
Restituire sau Formular fiind determinat de alegerea clientului din metoda IaUnFormular).
Comportamentul formularului la Completare [i c=nd vrem s\ vedem c\ A[aArat\ depinde
de tipul dinamic al obiectului. Conform lui se apeleaz\ metoda clasei respective.
(Foaia de depunere va cere [i suma depus\, cea de restituire va cere [i suma restituit\ [i la
fel vor face [i la afi[are, afi[=nd [i suma depus\ respectiv cea restituit\).

Putem ad\uga oric=nd noi clase de obiecte, formularele noi cu care va lucra func]ionarul,
f\r\ a modifica programul principal. Tot ce e de scris sunt declara]iile claselor noi de
obiecte, comportamentul lor adic\ metodele (la noi Completare [i AsaArata). Dac\ ne oprim

Programarea calculatoarelor [i limbaje de programare 178 Dan Popa, 2007


aici func]ionarul (`n alte aplica]ii un obiect receptor de mesaje) va prelucra aceste mesaje
f\r\ eroare `ntreb=nd candid «Ce fel de formular e acesta?» . Iar dac\ vrem s\-l instruim s\
prelucreze altfel mesajele, inclusiv cele noi, va trebui modificat\ sau rescris\ procedura
Prelucrare adic\ handlerul de mesaje (`n englez\ cuv=ntul handler `nseamn\ «cel ce
manipuleaz\»). Acum v\ este clar, sper, de ce el ar fi bine s\ fie un c=mp procedural (sau
un pointer la func]ie `n C++) `ntr-un obiect. A[ scrie procedura, i-a[ da o nou\ valoare
handler-ului (care valoare este numele sau adresa noii proceduri) [i gata. Aplica]ia este
extins\. Obiectele prelucreaz\ noile mesaje.

Programarea calculatoarelor [i limbaje de programare 179 Dan Popa, 2007


Cap

11
Tipul BOOLEAN, expresii logice. Evaluarea
lor interactivă

Noţiuni: Tipul BOOLEAN (provenit din logică), Un nume celebru: G.Boole, Structurile în
care apare acest tip de date , Valori şi operaţii, Tabelele operaţiilor, Proprietăţi, Prioritate şi
paranteze, Sintaxa, regulile gramaticii expresiilor logice, Evaluarea «leneşului» - lazy evaluation,
avantaje şi dezavantaje, Interpretarea expresiilor logice – mod de a le evalua interactiv,
Implementarea interpretorului, Recursivitate mutuală, Folosirea tipurilor procedurale în locul
directivei FORWARD.

Este momentul s\ ne ocup\m mai aproape de un tip de date provenit din logic\, pe care l-
am `nt\lnit p=n\ acum ocazional, tipul BOOLEAN. R\spundem `n cele ce urmeaz\ la
`ntreb\rile: Unde `l `nt=lnim ? Cum sunt formate expresiile de acest tip – expresiile booleene
? Cum se evalueaz\ valoarea unei astfel de expresii ? (`ntr-un program [i respectiv
imperativ).

Ciudatul [i amuzantul (pentru unii) nume al acestui tip, care apare printre altele `n limbaje ca
Pascal, Oberon [i altele similare lor provine de la numele lui George Boole, matematician
[i logician englez, n\scut la 2 noiembrie 1815 `n Lincoln, Lincolnshire, Anglia [i decedat la
8 dec 1864. Din via]a acestui logician englez care a fost c\s\torit cu nepoata lui Sir George
Everest (da, cel al c\rui nume e dat celebrului munte!) merit\ s\ not\m c=teva date:
Autodidact `n matematic\ (`nv\]ase primele no]iuni de la tat\l s\u) George Boole a debutat
`n publica]iile de specialitate cu o serie de lucr\ri ap\rute `n Cambridge Mathematical

Programarea calculatoarelor [i limbaje de programare 180 Dan Popa, 2007


Journal, `n 1839 [i `n anii urm\tori. Cinci ani mai t=rziu, `n 1844 prime[te Medalia Societ\]ii
Regale, pentru contribu]iile sale algebrice `n analiz\. (Aceea[i Societate Regal\ `l va primi
ca membru peste al]i 13 ani .)
Convins c\ modelele sale algebrice sunt aplicabile [i `n logic\ public\ `n 1847 un veritabil
pamflet intitulat “Analiza matematic\ a logicii” `n care insinueaz\ c\ logica ar trebui s\
devin\ un domeniu al matematicii, nu al filosofiei, cum era `n acea epoc\. ~n acela[i an,
de altfel, alt logician englez, Augustus de Morgan va publica lucrarea Formal Logic (logica
formal\). Pentru clarviziunea sa matematic\ De Morgan `l va stima [i aprecia pe George
Boole. Rezultatele acestuia din urm\ erau at=t de meritoase `nc=t `n 1849 Boole va fi
angajat ca profesor la Queens's College, caz excep]ional deoarece Boole nu poseda o
diplom\ universitar\.
~n 1854 a publicat “Legile g=ndirii” - titlul complet: O investiga]ie `n legile g=ndirii pe care se
bazeaz\ teoria matematic\ a logicii [i probabilit\]ilor.
Studiile sale au vizat [i alte domenii ale matematicii: ecua]iile defieren]iale [i calculul cu
diferen]e finite.
George Boole se poate m=ndri cu faptul c\ peste ani [i ani, studiile sale de logic\ formal\ au
contribuit la na[terea telefoniei digitale [i calculatoarelor programabile pe care le folosim
ast\zi.

Unde `nt=lnim, `n limbajele calculatoarelor programabile, expresiile booleene, acele expresii


care, `n urma calcul\rii valorii lor dau un rezultat logic? Ar trebui s\ [ti]i deja unde. Sunt
prezente `n toate acele structuri ale program\rii structurate, `n care fluxul execu]iei este
schimbat condi]ionat (Cum de cine ? De o condi]ie logic\ !). G\sim expresiile booleene `n:

1) structurile alternative (decizionale) din diverse limbaje:

if <exp booleana> then ...else... din Pascal

if (<exp> ) ... else ... din C, C++

IF <exp booleana> THEN ...


ELSIF <exp booleana> THEN ...
ELSE ... END din Oberon

Programarea calculatoarelor [i limbaje de programare 181 Dan Popa, 2007


Reaminti]i-v\ aici [i faptul c\ limbajul C nu are un tip BOOLEAN specializat, folosesc `n locul
lui tipul `ntreg, cu conven]ia c\ 0 `nseamn\ FALS iar orice e diferit de zero, inclusiv 1
`nseamn\ adev\rat.

2) structurile repetitive din diverse limbaje, fie ele structuri cu test in]ial:

while <exp booleana> do ... din Pascal

while ( <exp> ) .... din C, ++

WHILE <exp booleana> DO ... END din Oberon

sau cu test final:

repeat ... until <exp booleana> din Pascal

do ... while <exp> din C, ++

REPEAT ... UNTIL <exp booleana> din Oberon

Nota bene: Bucla do ...while din C se execut\ c=t\ vreme condi]ia dat\ prin expresia <exp>
este nenul\, adic\ adev\rat\. (~n C zeroul `nsemna FALS). De asemenea este de remarcat
c\ `n limbajul C, instruc]iunea for poate avea a doua expresie, (expresia care determin\
oprirea buclei for) o expresie oarecare, fie c\ o consider\m boolean\ fie c\ o consider\m
`ntreag\.

Teoretic, atunci c=nd definim un tip de date o facem cu g=ndul la “ecua]ia”:

Tip de date = mul]imea valorilor + opera]ii

Mul]imea valorilor tipului BOOLEAN este format\ din dou\ valori, TRUE [i FALSE. TRUE
`nseamn\ adev\rat iar FALSE `nseamn\ fals. Opera]iile sunt cele din logica matematic\. Nu
este absolut necesar s\ existe toate opera]iile din logic\ `ntr-un limbaj de programare,

Programarea calculatoarelor [i limbaje de programare 182 Dan Popa, 2007



deoarece unele se pot ob]ine din altele. Totu[i unele nu se pot ob]ine din
altele, ceea ce face ca s\ existe un set minimal de opera]ii logice pe
care v\ a[tepta]i s\ le g\si]i `ntr-un limbaj. Acest set este format din... care
se noteaz\ `n Pascal,C [i respectiv Oberon astfel:

Nota]ia din Pascal, din C, [i din Oberon

- Disjunc]ia (sau): or || OR
- Conjunc]ia ([i): and && &
- Nega]ia (nu): not ! ~


Remarca]i c\ diversele limbaje nu au nota]ii unitare pentru opera]iile logice
deci la `nv\]area unui limbaj va trebui s\ `nv\]a]i separat pentru fiecare
limbaj denumirile acestor opera]ii. Aceste opera]i pot fi descrise prin tabele,
a[a cum adunarea era dat\ prin tabla adun\rii iar `nmul]irea prin tabla
`nmul]irii.

Am notat adev\rul, TRUE, cu 1 [i falsul, FALSE, cu zero. Nega]ia lui 1 (TRUE) este zero
(FALSE) iar nega]ia lui zero (FALSE) este 1 (TRUE). Aceste tabele pot servi la evaluarea
expresiilor logice exact cum tabelele adun\ri [i `nmul]irii servesc la calculul valorii expresiilor
aritmetice.
Aceste opera]ii au, de altfel, propriet\]i similare cu adunarea [i `nmul]irea. OR este ca un fel
de adunare iar & este un fel de `nmul]ire. Printre propriet\]ile analoage suratelor lor
aritmetice se num\r\ de exemplu distributivitatea lui & fa]\ de OR, exact ca distributivitatea
adun\rii fa]\ de `nmul]ire. Astfel pentru trei variabile booleene a,b, c declarate `n modul la
care suntem obi[nui]i:

VAR a,b,c :BOOLEAN ;

Programarea calculatoarelor [i limbaje de programare 183 Dan Popa, 2007


expresiile de mai jos sunt echivalente, av=nd aceea[i valoare `ntotdeauna (cu condi]ia ca
a,b [i c s\ fie definite. Deci s\ nu fie printre ele ceva de felul (3/0 > 4/0):

c & (a OR b) respectiv c & a OR c & b

Ultima expresie trebuie `n]eleas\ ca (c & a) OR (c & b) dar a fost scris\ f\r\ paranteze
deoarece, exact ca la aritmetic\ (unde `nmul]irea are prioritate mai mare ca a adun\rii) la
logic\ conjunc]ia (&) are prioritatea mai mare ca a disjunc]iei(OR). Nega]ia are cea mai
mare prioritate dintre toate cele trei opera]ii logice.

Alte opera]ii care pot produce ca rezultat o valoare bolean\, logic\, sunt compara]iile.
Prin compararea a dou\ valori dintr-un alt tip de date se ob]ine o valoare logic\. De exemplu
3 < 7 d\ TRUE iar 3 > 7 sau 3 = 7 dau ambele FALSE. C=nd sunt implicate variabile,
valoare expresiei booleene se calculeaz\ pornind de la valorile lor.
Aten]ie: Prioritatea acestor operatori de compara]ie este mai mic\ dec=t a oper-a]iilor
logice OR, &, ~ . ~n limbaje ca Oberon, Pascal, Delphi aceste compara]ii se vor scrie
obligatoriu `ntre paranteze. Exemplu: condi]ia ca un `ntreg n s\ fie o not\ din catalog se va
putea scrie a[a:

(n <= 1) & (n >= 10)

De[i teoria recomand\ s\ `nv\]a]i priorit\]ile tuturor operatorilor, de multe ori, atunci c=nd un
programator nu e sigur `n ce ordine se face calculul, el pune explicit parantezele necesare.
~n condi]ii de examen `ns\, un examinator poate sanc]iona un candidat printr-o not\ mic\
dac\ descoper\ c\ acesta nu cunoa[te teoria.

Operatorii de compara]ie nu au nici ei nota]ii standardizate, `n sensul c\ `n diverse limbaje


unii dintre ei se noteaz\ diferit. ~n mai multe limbaje, dar nu toate, pentru operatorii “mai mic”
( < ), “mai mare” ( > ) [i “egal” ( = ) pute]i folosi nota]iile din matematic\ iar pentru “mai mic
sau egal” [i “mai mare sau egal” se folosesc respectiv <= [i >=. Cele mai multe probleme
le pune “diferit”.Diferit-ul este notat cu <> `n Pascal, cu != `n C [i cu cu # `n Oberon [i –
lista nu se termin\ aici - cu /= `n Haskell.

Programarea calculatoarelor [i limbaje de programare 184 Dan Popa, 2007


Cum sunt formate expresiile booleene ? Expresiile aritmetice erau sume (sau diferen]e)
de termeni, ace[tia la r=ndul lor erau produse (sau c=turi) de factori iar factorii puteau fi
constante, variabile, func]ii sau expresii `n parantez\. Lucrurile decurg la fel pentru expresii
logice, cu diferen]a c\ locul adun\rii `l ia disjunc]ia (sau - OR), locul `nmul]irii `l ia conjunc]ia
([i - &) iar nega]ia unui factor este tot un caz particular de factor. Sintaxa expresiilor
booleene ar putea fi descris\ de urm\toarele reguli de gramatic\. Am marcat cu liter\ gras\
(bold) ceea ce difer\ la sintaxa expresiilor logice fa]\ de sintaxa expresiilor aritmetice :

Expresie -> Term { OperatorAdunare Term } adic\ OR

Term -> Factor { Operator~nmul]ire Factor } adic\ &

Factor -> Constant\ | Variabil\ | Func]ie | (Expresie) |


OperatorNega]ie Factor adic\ ~

Comentariile din extrema dreapt\ nu fac parte din sintax\. Nota]ia este cea cunoscut\: Tot
ce e `n parantez\ acolad\ se poate repeta de oric=te ori (`n practic\, at=ta vreme c=t
urmeaz\ alt operator va urma [i un alt term). Bara vertical\ separ\ alternativele. Altfel ar fi
trebuit s\ scriem 5 reguli diferite pentru a explica cum e format un factor.
Preciz\m c\ vom `n]elege prin OperatorAdunare disjunc]ia (sau, OR).

Prin Operator~nmul]ire vom `n]elege conjunc]ia ([i, &) iar prin OperatorNega]ie vom `n]elege
nega]ia (~). Mai observ\m c\ la expresiile booleene nu exist\ ceva asem\n\tor minusului
sau plusului cu care `ncep uneori expresiile aritmetice.

~n Oberon, cuv=ntul “func]ie” folosit mai sus trebuie `n]eles ca apel al unei proceduri func
]ionale definite de utilizator sau ca apel al unei func]ii predefinite `n sistem.

Programarea calculatoarelor [i limbaje de programare 185 Dan Popa, 2007


Lazy Evaluation
Sau cum se pot evalua mai încet sau mai rapid expresiile booleene. Metoda folosită de unele
compilatoare. Avantaje şi dezavantaje.

Evaluarea unei expresii logice se poate face `n mod banal, exact ca evaluarea expresiilor
aritmetice. Opera]iile se fac `n ordinea priorit\]ilor, `ncep=nd cu cele mai prioritare [i cu cele
din parantezele interioare. (Practic dac\ descompunem expresia conform regulilor
gramaticale de mai sus – [i asta `nseamn\ practic s\-i facem analiza sintactic\ - ultimele
reguli aplicate vor corespunde opera]iilor care vor fi efectuate primele.)

Acest mod de evaluare presupune ca la `nt=lnirea unui operator binar (cu doi operanzi) s\
se calculeze valorile ambilor operanzi [i apoi s\ se efectueze opera-
]ia (conform tabelei). Se poate mai repede ? S\ vedem cum:


Am putea efectua calculele mai repede dac\, de exemplu, am [ti
rezultatul unei opera]ii `nainte de a calcula valoarea tuturor
operanzilor ! La expresiile aritmetice acest lucru nu era posibil. Acolo
suma, produsul, c=tul sau diferen]a a dou\ numere depindea efectiv de
ambele. La expresii logice se poate. S\ examin\m iar tabelele opera]iilor:

Observa]i c\ dac\ la disjunc]ie (OR) particip\ o valoare adev\rat\ (notat\ cu 1) rezultatul


este adev\rat indiferent de valoarea celuilalt operand. La conjunc]ie (&), dimpotriv\, dac\
particip\ o valoare fals\ (notat\ cu 0) rezultatul este fals indiferent de valoarea celuilalt
operand. ~n aceste cazuri rezultatul poate fi ob]inut f\r\ a mai evalua al doilea operand. ~n
general, sistemul am=n\ evaluarea unei expresii sau subexpresii c=t mai mult cu putin]\, `n
speran]a c\ va pute calcula rezultatul final f\r\ ea. Metoda se nume[te Lazzy evaluation [i
multe compilatoare de Pascal, C, etc, folosesc efectiv acest mod de evaluare a

Programarea calculatoarelor [i limbaje de programare 186 Dan Popa, 2007


expresiilor logice. Printre ele este [i compilatorul de Oberon pe care l-am folosit la testarea
aceste exemple de programe. {i interpretoarele folosesc lazy evaluation, de exemplu
interpretorul de Haskell 98, numit Hugs. Putem chiar preciza c\ lazzy evaluation nu este
specific\ nici compilatoarelor, nici interpretoarelor (ambele pot s-o foloseasc\ sau nu) ci este
doar un aspect al semanticii limbajului, a[a cum este ea implementat\ `n compilator sau
interpretor. Cititorii doritori de detalii pot consulta un curs sau un volum despre semantic\
(din bibliografie sau nu).

Avantaje:
1) Vitez\ mai mare la evaluarea expresiilor booleene.
2) Unele expresii «periculoase» `n sensul c\ pot produce nedetermin\ri nu mai dau erori la
execu]ie. De exemplu condi]ia (a # 0 ) & (x = 3 /a ) poate fi folosit\ [i testat\ f\r\
probleme chiar c=nd a are valoarea zero. Rezultatul va fi fals dar `mp\r]irea la zero nu va
provoca eroare de execu]ie deoarece algoritmul de lazzy-evaluation nu mai evalueaz\
paranteza a doua (al doilea operand al opera]iei & dintre un fals [i altceva nefiind necesar la
calcul). Dac\ `ns\ compilatorul nu implementeaz\ lazy-evaluation, expresia va da o eroare
la execu]ie, `n `ncercarea de a `mp\r]i pe 3 la zero.


Dezavantaje:
1) Lipsa evalu\rii unei p\r]i dintr-o expresie poate fi periculoas\ pentru
program, dac\ `n cursul evalu\rii por]iunii de expresie ignorate se mai
f\ceau [i alte opera]ii (`n principal de I/O dar nu numai).
C=nd este posibil ca odat\ cu evaluarea unei p\r]i de expresie s\ se fac\ [i
alte calcule ? Atunci c=nd acea parte de expresie este un apel de procedur\ func]
ional\, implementare a ceea ce numim func]ie cu efect-lateral (side efect).
Ce este o func]ie cu side-efect ? O func]ie care mai face [i alte opera]ii (modific\ri de
variabile, opera]ii de I/O, alte apeluri de proceduri care produc la r=ndul lor astfel de efecte)
`nafar\ de simplul calcul al valorilor returnate.
Caz banal: O func]ie care scrie [i pe ecran, `n scop de depanare, valoarea rezultat\.Dac\
func]ia este al doilea operand iar lazzy-evaluation nu o mai evalueaz\, efectul nu se mai
produce. (de exemplu nu se mai scriu pe ecran valorile ob]inute, chiar dac\ func]ia era
programat\ s\ fac\ a[a ceva).

Programarea calculatoarelor [i limbaje de programare 187 Dan Popa, 2007


2) Uneori, din cauza mecanismelor de lazzy-evaluation ve]i fi sili]i pentru buna func]ionare a
programului s\ scrie]i altfel anumite opera]ii logice `n care intervin func]ii (proceduri
func]ionale) capabile de efecte laterale, deci implement\ri de func]ii care mai fac [i
altceva dec=t s\ returneze rezultate.

Exemplu: b := f1(...) OR f2(...)


sau b := f1(...) & f2(...)
unde b este o variabil\ boolean\

Aceste expresii, evaluate prin lazzy-evaluation nu garanteaz\ c\ procedura func-


]ional\ f2 va fi apelat\ `ntotdeauna.
~n cazul unor expresii aritmetice acest lucru era `ns\ garantat. Pentru

n := f1(...) + f2(...)
sau n := f1(...) - f2(...)

(oricare ar fi fost opera]ia aritmetic\) la execu]ie erau apelate cu siguran]\ ambele


proceduri func]ionale f1 [i f2.
Solu]ia: ~nlocui]i calculul lui b din formulele de mai sus cu o secven]\ de atribuiri succesive:

b1 := f1(...);
b2 := f2(...); (* A doua func]ie va fi apelat\ obligatoriu acum!*)
b := b1 OR b2;

O situa]ie de acest fel vom `nt=lni mai departe, cu ocazia scrierii unui program care s\
evalueze interactiv expresii booleene, date de la tastatur\. Un asemenea program, numit
uneori interpretor alteori parser (deoarece parcurge expresia citind-o caracter cu caracter)
vom realiza `n continuare, pe baza regulilor din gramatica expresiilor logice, a[a cum este
dat\ mai sus.

Programarea calculatoarelor [i limbaje de programare 188 Dan Popa, 2007


Evaluarea (interpretarea) expresiilor logice
Sau cum scriem un program (numit interpretor) care primind o expresie logică şi un set de
variabile de la A la Z (ale căror valori sunt date într-o matrice) calculează valoarea expresiei.
Comentarii despre recursivitatea indirectă şi ordinea scrierii unor funcţii care se apelează unele pe
altele circular.

Problema evalu\rii unei expresii logice dat\ `n mod interactiv este ceva mai rar `n practic\
(spre deosebire de evaluarea expresiilor aritmetice care ar fi de mai mare folos). Are `ns\
aplica]ii, fie c\ e vorba de scrierea unor interpretoare pentru limbajele de programare sau a
unor subrutine de[tepte pentru evaluarea solu]iilor date unui program de `nv\]are asistat\,
unul dintre acelea c\ruia s\-i po]i scrie `n fi[ierul cu `ntreb\ri [i r\spunsuri c\ solu]ia este
A&B&C&~D (adic\ A [i B [i C f\r\ D) sau de ce nu A&D|B&C (adic\ r\spunde corect cel
care indic\ m\car una din variantele A [i D sau B [i C. ~ntrebarea putea fi de exemplu “ce
tehnologii se pot folosi la realizarea unor anumite produse industriale” cu r\spuns corect
dac\ se indic\ m\car perechea A D sau m\car perechea B C.
A fost `ns\ propus\ la examene, teze, olimpiade [i concursuri, inclusiv la clase de liceu (dar
la olimpici). O variant\ a acestei probleme care presupunea evaluarea mai multor expresii
booleene exist\ `n arhiva cu probleme de pe site-ul Info Arena, versiunea de acolo fiind
semnat\ de Adrian Vladu. O reproducem `n continuare :

Boolean
“Haralambie a primit la scoal\ o tem\ destul de dificil\! El trebuie sa evalueze o expresie
logic\. Aceasta expresie con]ine variabile (litere mari ale alfabetului englez de la „A” la „Z”),
constante („TRUE” [i „FALSE”), paranteze rotunde („(” si „)”) [i operatorii logici „NOT”,
„AND” [i „OR”. „NOT” are prioritatea cea mai mare, „OR” are prioritatea cea mai mica. Ini]ial
toate variabilele au valoarea „FALSE”. Lui Haralambie `i place s\ evalueze expresii, dar
variabilele `[i mai schimb\ uneori valoarea [i expresia trebuie reevaluat\. Speriat din
aceast\ cauz\, a decis s\ apeleze la ajutorul vostru! ”
Problema cere s\ se evalueze ([i s\ se reevalueze) o expresie logic\ aprioric necunoascut\
pentru un set de valori ale unor variabile ce-[i schimb\ valorile.

Programarea calculatoarelor [i limbaje de programare 189 Dan Popa, 2007


Cum expresia poate fi oricare avem nevoie de un evaluator, de un interpretor. Acesta este
piesa principal\ a solu]iei [i asupra ei ne vom concentra aten]ia.

Pentru simplitate vom presupune c\ expresiile sunt formate `n urm\torul mod, descris mai
pe scurt. Presupunem c\ au toate elementele, constante, variabile, operatori, paranteze,
formate dintr-un singur caracter, f\r\ alte spa]ii. O asemenea expresie se ob]ine imediat
(printr-o preprocesare) din expresia ini]ial\, dac\ expresia ini]ial\ nu se conforma
presupunerii. Conven]ia noastr\ de nota]ie pentru noile expresii va fi:

TRUE se va nota cu t
FALSE se va nota cu f
Variabilele se vor nota cu majuscule astfel c\ variabilele T [i F nu se vor confunda cu
constantele t [i f (TRUE [i FALSE).
Operatorii se vor nota astfel:
and se va transcrie &
or se va transcrie |
not se va transcrie !
Cu aceast\ conven]ie la fiecare citire a unui caracter din expresie citim `n `ntregime un
operand, operator sau o parantez\. Acest caracter, vom vedea, va fi stocat `ntr-o variabil\ [i
va servi la a afla ce regul\ a gramaticii s-a aplicat acolo. Dar s\ nu anticip\m.

Proiectul nostru (`n Oberon) va fi format din dou\ module, unul va fi interpretorul cel\lalt
programul care `l apeleaz\. Voi comenta interpretorul:


MODULE Intbool;
(* Evaluarea expresiilor booleene cu operatorii
& , | , ! , variabile majuscule si constantele t,f *)

IMPORT D:=Display,Strings;

CONST TAB=CHR(8);

Programarea calculatoarelor [i limbaje de programare 190 Dan Popa, 2007


Vom declara trei variabile: Prima este acea variabil\ care stocheaz\ mereu urm\torul
caracter de interpretat. A doua este un alias pentru numele unei proceduri. Deoarece sunt
trei reguli `n gramatic\ vom avea trei proceduri. Dac\ privi]i cu aten]ie regulile gramaticii ve]i
vedea c\ expresia e format\ din termi, termii din factori iar factorii pot fi expresii. Aceast\
circularitate se va reflecta `n program sub forma prezen]ei a trei proceduri recursive mutual,
care deci se apeleaz\ una pe alta `n cerc. Necazul e c\ atunci c=nd prima procedur\ o
apeleaz\ pe a treia, compilatorul nu-i [tie, la compilare, adresa acestei de-a treia proceduri.
Fapt firesc deoarece acum o compileaz\ pe prima, n-a ajuns la a treia ! Variabila
procedural\ Use Expression va stoca chiar aceast\ adres\. Ea va fi ini]ializat\ la
`nc\rcarea modulului.
Remarca]i c\ procedurile importante ale interpretorului inclusiv cea indicat\ de variabila
procedural\ UseExpression returneaz= o valoare boolean\. Este exact valoarea
subexpresiei procesate de procedur\.
Mem este un vector destinat a stoca valorile acelor variabile booleene notate de la A la Z `n
problem\. S\ le declar\m:

VAR Look*:CHAR; (*Var pt privit inainte*)


UseExpression:PROCEDURE ():BOOLEAN; (* Alias pt o procedura*)
Mem*:ARRAY ORD('Z')-ORD('A')+1 OF BOOLEAN; (* Memoria *)

(* Memoria are valori booleene iar procedurile returneaza valori booleene*)

Orice program de mari dimensiuni are o serie de proceduri care fac lucrurile de rutin\.
Citirea urm\toarei informa]ii, semnalarea erorilor, anumite teste des folosite sunt asemenea
exemple. Aceast\ prim\ serie de mici proceduri o ve]i copia de fiecare dat\ c=nd scrie]i un
interpretor. Am prefixat-o cu un comentariu vizibil:

(********************************************************************
Toate accesoriile
********************************************************************)

Programarea calculatoarelor [i limbaje de programare 191 Dan Popa, 2007


PROCEDURE GetChar; (* Interfata cu sursa de caractere,aici tastatura*)
BEGIN (* Apelata pentru a continua analiza expresiei *)
D.ReadChar(Look);
END GetChar;

PROCEDURE Error(s:ARRAY OF CHAR); (* Interfata cu receptorul de erori*)


BEGIN (* aici ochiul care vede mesaje pe dispaly*)
D.WriteLn();
D.WriteStr(" Error: ' ");
D.WriteStr(s);
D.WriteChar(".");
END Error;

PROCEDURE Abort(s:ARRAY OF CHAR); (* Oprirea si afisarea erorii *)


BEGIN
Error(s);
HALT(0);
END Abort;

PROCEDURE Expected(s:ARRAY OF CHAR); (* Tratarea erorii de neprimire a ceva


asteptat*)
BEGIN
Abort(s); (* Aici eroarea e tratata prin oprirea programului *)
(* Stringul trimis mai departe lui Abort() poate contine si alte explicatii*)
(* de exemplu: "Lipseste", s *)
END Expected;

PROCEDURE Match(x:CHAR); (* Verifica si parcurge un caracter asteptat *)


VAR s:ARRAY 2 OF CHAR; (* apoi mai cere unul,apelind GetChar *)
BEGIN

Programarea calculatoarelor [i limbaje de programare 192 Dan Popa, 2007


s:="a";
s[0]:=x;
IF Look = x THEN GetChar;
ELSE Expected(s);
END;
END Match;

Dintre cele de mai sus sunt importante GetChar care aduce din sursa de date urm\torul
caracter de evaluat [i, mai important\, Match, care verific\ dac\ ceea ce a fost adus `n
variabila Look este ceea ce a[tepta el (adic\ Match) deoarece `l primise ca parametru.
Match compar\ parametrul s\u (care semnific\ ceea ce m\ astept s\ urmeze `ntr-o
expresie corect\) cu ceea ce vine efectiv `n variabila Look.

(* Testele pentru a gasi diferse categorii de operatori *)


(* In fiecare categorie pot fi mai multi operatori cu aceeasi
prioritate *)
(* Testele se fac fara sa avansa in expresie, ele NU apeleaza GetChar *)

PROCEDURE IsAddop(c:CHAR):BOOLEAN;
BEGIN
RETURN (c="|")
END IsAddop;

PROCEDURE IsMulop(c:CHAR):BOOLEAN;
BEGIN
RETURN (c="&")
END IsMulop;

PROCEDURE IsNegop(c:CHAR):BOOLEAN;
VAR
BEGIN
RETURN (c="!")

Programarea calculatoarelor [i limbaje de programare 193 Dan Popa, 2007


END IsNegop;

(* Similar, un test de prezenta a unei variabile,MAJUSCULA *)

PROCEDURE IsVar(c:CHAR):BOOLEAN;
BEGIN
RETURN (c>='A') & (c<='Z');
END IsVar;

(* Similar, un test de prezenta a unei constante t,f*)

PROCEDURE IsConst(c:CHAR):BOOLEAN;
BEGIN
RETURN (c='t') OR (c='f');
END IsConst;

Observa]i c\ testele verific\ dac\ ceea ce le e dat ca parametru este un operator similar
adun\rii (la noi disjunc]ia), unul similar `nmul]irii (la noi e conjunc]ia), unul pentru nega]ie, o
variabil\ sau o constant\. Pot fi modificate aceste teste func]ie de operatorii [i conven]iile
folosite `n scrierea expresiei. Aten]ie s\ nu apar\ confuzii, cazuri `n care dou\ teste diferite
dau simultan r\spunsuri pozitive. (dac\ TRUE ar fi fost T nu t am fi avut o confuzie de acest
fel).
Urmeaz\ parte acea mai important\ a interpretorului. O serie de proceduri care atunci c=nd
sunt apelate citesc o por]iune din expresie [i returneaz\ valoarea ei.

(*************************************************************
Proceduri care calculeaza valorile unor parti din expresie
*************************************************************)
(* Acestea avanseaza in expresie, fie folosind Match, daca
stiu ce va urma fie apeland direct GetChar *)
(* Daca se apeleaza insa alte proceduri cu numele Get...
atunci sarcina de a avansa cade in seama lor *)

Programarea calculatoarelor [i limbaje de programare 194 Dan Popa, 2007


PROCEDURE GetVar():BOOLEAN; (*Pt.valoarea unei variabile booleene*)
VAR Value:BOOLEAN;
BEGIN
IF ~ IsVar(Look) THEN Expected(" Variable expected ")
END;
Value:=Mem[ORD(Look)-ORD('A')];
GetChar;
RETURN Value;
END GetVar;

PROCEDURE GetConst():BOOLEAN; (*Pt. valoarea unei constante*)


VAR Value:BOOLEAN;
BEGIN
IF ~ IsConst(Look) THEN Expected(" TRUE or FALSE' Expected ")
END;
IF Look='t' THEN Match('t');
Value:=TRUE (* t -> TRUE *)
ELSIF Look='f' THEN Match('f');
Value:=FALSE; (* f -> FALSE*)
END;
RETURN Value;
END GetConst;

Get Var, de mai sus, calculeaz\ valoarea unei variabile c\ut=nd acea valoare `n vectorul
Mem. Iar GetConst [tie c\ “t” va `nsemna TRUE iar “f” va `nsemna FALSE [i returneaz\
corespunz\tor acea valoare, dup\ cum variabila Look con]inea un “t” sau un “f”.

Urm\toarea procedur\ calculeaz\ valoarea unui factor. Factorul poate fi (vezi ultima
regul\ din gramatic\) o variabil\ - caz `n care valoarea sa o va afla GetVar, o constant\ -
caz `n care valoarea sa o va afla GetConst, un factor negat – caz `n care procedura factor

Programarea calculatoarelor [i limbaje de programare 195 Dan Popa, 2007



sare peste nega]ie folosind, se autoapeleaz\ pentru a afla valoarea
factorului apoi neag\ rezultatul [i-l stocheaz\ `n variabila value, de unde va
fi returnat. Ultima ramur\ din IF ... THEN ...ELSE ... ELSIF a fost scris\
pentru cazul c=nd sunt date alte caractere `n loc de de factor.Observa]i c\
procedura folose[te o variabil\ local\ `n care va stoca rezultatul evalu\rii factorului `n curs
de analiz\.Pentru factorul de forma expresie `n parantez\ ar trebui apelat\ procedura
capabil\ s\ evalueze o expresie, dar ea `nc\ nu e scris\. Dar valoarea variabilei procedurale
UseExpression este un bun alias (o bun\ porecl\) pentru procedura Expression (o vom fi ini]
ializat `n faza de ini]ializare a modulului).

PROCEDURE Factor():BOOLEAN; (* valoarea unui factor *)


VAR Value:BOOLEAN;
BEGIN
IF IsVar(Look) THEN Value:=GetVar();
ELSIF IsConst(Look) THEN Value:=GetConst();
ELSIF IsNegop(Look) THEN Match('!') ;Value:= ~ Factor()
ELSIF Look = "(" THEN Match("(");
Value:=UseExpression();
Match(")")
ELSE GetChar (* pentru factori eronati de un caracter*)
END;
RETURN Value;
END Factor;


Procedura Term va calcula valoarea unui term care tocmai `ncepe.
Termul este un fel de produs (f&g&...), realizat dintr-o valoare a primului
s\u factor (aici apel\m procedura factor) c\ruia i se face “produsul”, pardon
opera]ia & cu eventualul factor urm\tor. Treaba aceasta mege at\ta vreme
c=t mai urmeaz\ al]i operatori “de `nmul]ire” cu aceea[i prioritate. Case-ul are doar acest
rost, de a selecta operatorii `n caz c\ sunt mai mul]i (dar nu e cazul la asemenea expresii
booleene) deci poate fi redus la textul marcat. Cum se g\se[te `n variabila Look un

Programarea calculatoarelor [i limbaje de programare 196 Dan Popa, 2007


asemenea operator '&' se va trece de el cu Match('&'), se va calcula noua valoare a
factorului urm\tor [i se va face opera]ia. Valoarea final\ se returneaz\.

PROCEDURE Term():BOOLEAN; (*valoarea unui term*)


VAR OldValue,NewValue:BOOLEAN;
BEGIN
OldValue:=Factor();
WHILE IsMulop(Look) DO
CASE Look OF
'&' : Match('&'); NewValue:=Factor(); OldValue:=OldValue &
NewValue;
(* Aici nu puteti face operatia direct din cauza evaluarii
tip lazy-evaluation folosita de compilator. Riscam sa pierdem
al doilea apel recursiv ! *)
(* Alte operatii cu aceeasi prioritate se trateaza aici *)
END;
END;
RETURN OldValue;
END Term;


Expresia este o “sum\” de termi a[a cum termul era un “produs” de
factori. Deci procedura care va calcula valoarea unei expresii va fi similar\
cu cea care calculeaz\ valoarea unui factor. Expresia are valoarea primului
term eventual dac\ urmeaz\ al]i operatori [i alti termi se face opera]ia
(disjunc]ia) `ntre valoarea veche [i cea nou\. {i tot a[a c\t\ vreme (while)
mai exist\ termi. Valoarea unui term care urmeaz\ se va calcula apel=nd procedura pentru
evalu\ri de termi, Term. Ea parcurge [i evalueaz\ termnul care urmeaz\. Dac\ ar fi fost mai
multe opera]ii similare ca prioritate, CASE-ul ar fi avut mai multe ramuri.

PROCEDURE Expression*():BOOLEAN; (*valoarea unei expresii *)


VAR OldValue,NewValue:BOOLEAN;
BEGIN

Programarea calculatoarelor [i limbaje de programare 197 Dan Popa, 2007


OldValue:=Term();
WHILE IsAddop(Look) DO
CASE Look OF
'|' : Match('|'); NewValue:=Term(); OldValue:=OldValue OR
NewValue;
(* Aici nu puteti face operatia direct din cauza evaluarii
tip lazy-evaluation folosita de compilator. Riscam sa pierdem
al doilea apel recursiv ! *)
(* Alte operatii cu aceeasi prioritate se trateaza aici *)
END;
END;
RETURN OldValue;
END Expression;

Pentru a avea valori (fie ele [i toate false) pentru variabilele de la A la Z din problem\,
vectorul Mem `n care ele sunt p\strate va trebui ini]ializat, fie [i cu FALSE peste tot.

(**** Initializarea Memoriei *********************************)

PROCEDURE MemInit;
VAR i:INTEGER;
BEGIN
FOR i:= 0 TO ORD('Z')-ORD('A') DO
Mem[i]:=FALSE;
END;
END MemInit;

De preg\tirile pentru punerea interpretorului `n func]iune se ocup\ procedura Init, care


trebuie s\ fie apelat\ `naintea fiec\rei evalu\ri. Ea ini]ializeaz\ vectorul de variabile ale
problemei, Mem, [i aduce cu GetChar urm\torul caracter de interpretat `n variabila Look.

(********************** Initializarea evaluatorului **********)

Programarea calculatoarelor [i limbaje de programare 198 Dan Popa, 2007


PROCEDURE Init*;
BEGIN
MemInit;
GetChar;
END Init;

Deoarece `n momentul compil\rii procedurii Factor procedura Expression nu era compilat\


[i deci nu se [tia adresa ei, ea nu putea fi apelat\ din procedura Factor. Dar din Factor
putem apela o procedur\ indicat\ de o variabil\ procedural\. Ini]ializarea variabilei
procedurale UseExpression (care se folo-
se[te la fel ca Expression) o fac aceste instruc]iuni, care de[i scrise la finalul modulului se
vor executa primele, imediat dup\ `nc\rcarea modulului `n memorie.

(******* Initializarea modulului *****************************)


BEGIN
UseExpression:=Expression; (* In loc de directiva Forward *)
END Intbool.

Astfel cele trei proceduri mutual recursive pot fi declarate f\r\ a se folosi ca `n Pascal
directiva FORWARD.
Modulul principal al proiectului nu face dec\t s\ exemplifice cum se foloseste evaluatorul.


~n principiu are de f\cut dou\ lucruri:
1) S\ ini]ializeze evaluatorul de expresii. Cu aceast\ ocazie se cite[te deja
primul caracter [i se ini]ializeaz\ variabila Look.
2) S\ apeleze procedura de evaluare a unei expresii, Expression.
Bine`n]eles, dac\ dori]i, pute]i scrie c=teva atribuiri `n plus `n program
pentru a schimba valorile unora dintre variabilele din vectorul Mem.

MODULE Evalbool;

IMPORT Display,Intbool;

Programarea calculatoarelor [i limbaje de programare 199 Dan Popa, 2007


PROCEDURE ProgMain*;
BEGIN

Display.WriteLn;
Display.WriteStr("Dati expresia");
Display.WriteLn;
Intbool.Init;
IF Intbool.Expression() THEN Display.WriteStr("TRUE")
ELSE Display.WriteStr("FALSE")
END;
Display.WriteStr("Caracter neprelucrat:");
Display.WriteChar(Intbool.Look);
Display.WriteChar("'");
REPEAT UNTIL Display.KeyPressed();

END ProgMain;

END Evalbool.

Procedura Expression din modulul Intbool returneaz\ un TRUE sau un FALSE iar IF serve
[te doar la a alege ce afi[\m pe ecran `n fiecare din cazuri. Ultimul caracter introdus de
dumneavoastr\, dup\ ce se termin\ expresia, va aparea `precedat de mesajul "Caracter
neprelucrat:", dup\ valoarea expresiei.

Nota]i [i faptul c\ modulul Display nu con]ine proceduri specializate pentru afi[area valorilor
“ADEVARAT” [i “FALS” nici `n limba rom=n\ [i nici `n limba englez\. Dar deja v-a]i dat
probabil seama cum se putea scrie o asemenea procedur\ WriteBool folosind un if.

Realizarea proiectului
Faceţi implementarea ! Succes !

Programarea calculatoarelor [i limbaje de programare 200 Dan Popa, 2007


Cap

12
Fractali; Elemente de grafică folosind
modulul ColorPlane

Noţiuni: dimensiune geometrică, dimensiune fractală, autoasemănare, fractali, cel mai simplu
fractal, feriga matematică

Aceast\ incursiune final\ `n universul limbajelor de programare dore[te s\ v\ duc\ `ntr-o


lume la care nici cu g=ndul nu v-a]i dus. Aceast\ lume (a fractalilor), se afl\ `n jurul nostru
de c=nd ne-am n\scut. Ei, fractalii sunt ascun[i `n norii de pe cer, `n ramurile copacilor, `n
frumuse]ea st=nc\riilor montane sau `n aceea a ]\rmurilor m\rii. Ori, de ce nu, le putem
vedea `n formele cristalelor, ale minereurilor [i ale efemerilor fulgi de nea.

De ce ne intereseaz\ fractalii?. ~nt=i pentru c\ sunt, dup\ cum a]i dedus deja, forme
fundamentale `n natur\. Apoi pentru c\ au aplica]ii. B\nui]i deja c\ dac\ li se cunoa[te
geometria [i propriet\]ile se poate da r\spuns la o serie `ntreag\ de probleme, altfel de loc
simple. ~ncep=nd cu estimarea cantit\]ilor de minereu ascunse `ntr-un volum cubic dat de
exploatare (a unui mineral `n carier\) [i termin=nd cu calculul masei lemnoase dintr-un
hectar de p\dure sau al volumului ploii care se va rev\rsa dintr-un cer par]ial acoperit de
nori. (At=t minereurile, filoanele c=t [i copacii din p\dure sau norii de pe cer sunt fractali !)

Programarea calculatoarelor [i limbaje de programare 201 Dan Popa, 2007


Ce-ar trebui s\ `n]elegemi prin fractali ? Deocamdat\ ni[te forme fr=nte, `ntrerupte cumva de
ni[te neregularit\]i, dar forme care mai au pe deasupra [i proprietatea de autoasem\nare.
E ceva ca la o holografie. Forma cea mare seam\n\ cu o por]iune mai mic\ a ei. A[a
cum o ramur\ seam\n\ cu componenta ei care este o r\muric\, a[a cum panta cu bolovani
a muntelui de piatr\ seam\n\ `n mic cu suprafa]a cu asperit\]i a unei singure pietre sau cum
un golf zim]at de mare, dintre dou\ peninsule este la r=ndul lui marcat de mici abateri de la
linia dreapt\ sau cea de arc de cerc, `n form\ de, a]i ghicit, alte peninsule mai mici care
delimiteaz\ golfuri tot mici [i a[a mai departe. O `ncercare mai bun\ de a defini asemenea
structuri se poate face cu ajutorul geometriei, pornind de la no]iunea de dimensiune a spa]
iului. (De[i, nota bene, exist\ [i unii fractali pentru care dimensiunea lor fractal\ e
necunoscut\ matematicienilor.)

S-o lu\m de la no]iunea cunoscut\ de num\r de dimensiuni sau de dimensiune. Desena]i


un mic segment de dreapt\, cam ca litera i majuscul\. Apoi m\ri]i-l la scar\ de 3 ori, ca la
fotograf. Evident a]i ob]inut un segment mai mare adic\ mai lung. Lungimea noului segment
este de 3 ori mai mare ca cea a segmentului ini]ial. Iar acest 3 este de fapt 3 la puterea
`nt=i (1), dovad\ c\ segmentul este un obiect geometric de dimensiune 1, deci
unidimensiunal. Face]i, v\ rog, desenele `n timp ce citi]i aceste explica]ii !!
Apoi lu\m un mic p\trat cam cu aceea[i latur\. Desena]i-l ! ~l m\rim la scar\ de 3 ori [i ob]
inem un p\trat cu latura de trei ori mai mare. M\rimea p\tratului ob]inut care este suprafa]a
este de 3 la puterea a doua (adic\ de nou\ ori) mai mare. Ca amuzament `l pute]i `mp\r]i `n
cele 3 x 3 p\trate, identice toate cu p\tratul ini]ial. 9 este egal cu 3 la puterea a doua.
Observa]i c\ puterea, exponentul, este acum 2. De aceea putem spune c\ p\tratul este o
figur\ bidimensional\.
S\ trecem mai departe: Lua]i un cub. Construi]i apoi un cub cu latura de trei ori mai mare.
C=te cubule]e asemenea celui ini]ial v\ sunt necesare ? 3 x 3 adic\ nou\ pentru
“parter”(care are baza un p\trat), `nc\ 9 pentru etajul `nt=i [i `nc\ 9 pentru etajul al doilea.
Ob]inem deci c\ un cub de 3 ori mai mare este de fapt de 27 de ori mai voluminos (9 x 3
fiind egal cu 27). Adic\ de 3 la puterea a treia. Cubul este deci o figur\ tridimensional\.
Nu trecem la hipercuburi `n patru dimensiuni deoarece dep\[esc limitele intui]iei [i imagina]
iei curente. Am uitat ceva ? Unii ar spune: da ! Punctul este zerodimensional, are lungimea
0 `l m\rim de c=te ori vrem [i tot punct r\m=ne. Orice n (factor de m\rire) la puterea zero d\

Programarea calculatoarelor [i limbaje de programare 202 Dan Popa, 2007


unu. Deci dup\ “m\rire” punctul este exact la fel ca [i `nainte, nici mai mare nici mai
mic.Este o figur\ zero-dimensional\. Iar alte dimensiuni intermediare nu mai sunt !

M\ crede]i ? R\u face]i ! Tocmai preg\team intrarea `n scen\ a unui obiect matematic, un
fractal bine`n]eles, a c\rui dimensiune nu este nici zero nici unu nici doi nici trei ci exact
logaritm `n baza trei din patru. Deci cam dimensiunea 1.261... Aproxim=nd-o cu o eroare
cam de 1% `i putem spune “1 [i un sfert”. Cum arat\ un asemenea obiect “unu [i un sfert “
dimensional ? ~l vom desena imediat `mpreun\, dar mai `nt\i procura]i-v\ o coal\ de h=rtie, o
rigl\, (ba chiar [i un compas – de[i el poate lipsi), un creion [i o radier\. Ultima este cea mai
important\.

Pornim de la un mare segment de dreapt\, desena]i-l orizontal [i numi]i-l AB. A este cap\tul
st=ng iar B este cap\tul drept. M\sura]i segmentul [i `mp\r]i]i-l cu dou\ puncte T1 [i T3 `n
trei p\r]i egale. T1 este mai aproape de A iar T3 mai aproape de B.
Aici un cunosc\tor de geometrie analitic\ ar observa c\:

1) Punctul T1 e de dou\ ori mai aproape de A dec=t de B.


2) Punctul T3 este de dou\ ori mai aproape de B dec=t de A.
3) Ambele puncte au valorile coordonatelor calculabile ca ni[te medii ale coordonatelor lui A
[i B dar este vorba de medii ponderate, `n care exact unul din capetele A sau B intr\ de
dou\ ori iar `mp\r]irea se face la trei.

Programatorul va exploata observa]ia de mai sus scriind `n program urm\toarele formule


pentru calculul coordonatelor punctelor din [irul de puncte T:

t[1]. x :=(2 * a. x + b. x) / 3;
t[1]. y :=(2 * a. y + b. y) / 3;
t[3]. x :=(a. x + 2 * b. x) / 3;
t[3]. y :=(a. y + 2 * b. y) / 3;

Aici fiecare punct este v\zut de programator ca un record (`nregistrare) cu dou\ c=mpuri
numite x [i y, semnific\nd coordonata x respectiv y a acelui punct. Ve]i `ntreba acum unde

Programarea calculatoarelor [i limbaje de programare 203 Dan Popa, 2007


este punctul T2 , deoarece pe segmentul AB nu este. A]i observat corect. Iar punctul T2 va
fi `nafara segmentului AB, deasupra mijlocului acestuia, astfel `nc=t T1, T2, T3 s\ formeze
un triunghi echilateral (sau m\car unul isoscel cu baza T1T3 [i o anumit\ `n\l]ime propor]
ional\ cu aceast\ baz\.)
A]i desenat triunghiul ? Acum [terge]i por]iunea dintre T1 [i T3 [i ob]ine]i o linie fr=nt\ din
patru segmente, care (dac\ triunghiul T1T2T3 era echilateral) ar trebui s\ fie [i egale `ntre
ele. ~n principiu trebuie s\ ob]ine]i o figur\ similar\ cu aceasta.

Procedeul se repet\ `n mod similar pentru toate segmentele AT1, T1T2, T2T3, T3B.

Pe r=nd, `nlocui]i AT1, T3B cu cele dou\ desene de mai sus. La fel pentru T1T2 [i T2T3, dar
`n cazul lor, mica figur\ va fi rotit\ cu v=rful spre st=nga, respectiv spre dreapta.
La pasul urm\tor s-ar ob]ine o figur\ ca `n schi]a urm\toare.

Cum continu\m o asemenea construc]ie pentru a deveni un fractal, o figur\

Programarea calculatoarelor [i limbaje de programare 204 Dan Popa, 2007


autoasemenea ? Deocamdat\ por]iunile figurii de la pasul acesta (cele 4 p\r]i AT1, T1T2,
T2T3, T3B) sunt similare doar cu cu figura de la pasul anterior.
Cele 4 p\r]i ale figurii ar deveni identice cu originalul doar dac\ procesul descris mai sus, de
scoatere a segmentelor din mijloc [i `nlocuire a lor cu laturile triunghiului ar continua la
infinit.

Aceasta este [i ideea. Considera]i c\ procesul continu\ similar ... la infinit. Ceea ce
ob]inem este fractalul din figura urm\toare:

Observa]i perfecta asem\nare a p\r]ilor cu originalul precum [i felul cum detaliile par a se
pierde la infinit. A]i dori o imagine mai mare, pentru a fi mai clar\ ? Inutil. Imaginea m\rit\
arat\, pe por]iuni, exact la fel cu originalul [i d\ o aceea[i senza]ie de neclaritate.

Cum a fost desenat ? Fire[te, nu f\c=nd o infinitate de opera]ii. Calculatorul a fost


programat s\ se opreasc\ din desenat `n momentul c=nd dimensiunea segmentelor
desenate (micile segmente AB care se tot formau) a devenit mai mic\ dec=t distan]a dintre
dou\ puncte (pixeli) de pe display. Mai departe detaliile sunt prea mici pentru a fi vizibile pe
ecranul computerului.

Care este dimensiunea unei asemenea figuri ? Vom `ncerca s\ ne ocup\m de por]iunea
AT1 a ei, care m\rit\ la scar\ de 3 ori reproduce figura `ntreag\. Dar aceast\ figur\ (curb\)
e format\ din 4 fractali, cei care se sprijin\ pe capetele AT1, T1T2, T2T3, T3B, deci este de
4 ori mai mare. ~n concluzie, dimensiunea acestei figuri este num\rul x cu proprietatea c\ 3
la puterea x este egal cu 4. De unde rezult\ c\ x este egal cu logaritmul `n baza 3 al lui 4 [i
este un num\r cuprins `ntre 1 [i 2.

Programarea calculatoarelor [i limbaje de programare 205 Dan Popa, 2007


Fractalul de mai sus este prin urmare ceva intermediar `ntre figurile unidimensionale
[i cele bidimensionale.

Dori]i vede]i [i al]i fractali sau vre]i o dovad\ `n plus c\ forme din natur\ sunt fractali ?
Compila]i [i rula]i proiectul (scris `n Oberon) numit Fern, care e livrat `mpreun\ cu versiunea
pe 16 bi]i a mediului de programare Pow. ~l ve]i g\si `n directorul
c:\pow\examples\opal\fern dup\ instalarea mediului de programare pe discul c. Ve]i ob
]ine ca efect desenul unui fractal poreclit “feriga matematic\”.

Programarea calculatoarelor [i limbaje de programare 206 Dan Popa, 2007


Exemplul Fract.mod
Implementarea algoritmului recursiv de desenare a fractalului dat ca prim exemplu.

S\ coment\m r=nd pe r=nd p\r]ile programului care a generat imaginea primului fractal
prezentat mai `nainte. Computerul va fi programat at=t s\ fac\ calculele cu numere reale c=t
[i s\ deseneze fractalul pe o suprafa]\ `mp\r]it\ `n pixeli – ecranul s\u. Imagina]i-v\ aceast\
suprafa]\ ca o coal\ de caiet de matematic\ av=nd circa 800 x 650 p\trate. Acesti pixeli au
coordonate `ntregi, sistemul coordonatelor fiind cu originea `n col]ul din st=nga jos al
ferestrei grafice. Modulul `ncepe prin a importa celelalte modulele necesare, Float – pentru
calcule cu numere reale [i ColorPlane – pentru grafica Color. Programul este o traducere [i
adaptare `n Oberon a unui program similar scris `n Pascal [i publicat `n revista IF 2/1991.

MODULE Fract ; (* Dan Popa v.3, decembrie 2004 *)


IMPORT cp:=ColorPlane, f:=Float;

Iat\ [i declara]iile: o singur\ declara]ie de constant\ `n sec]iunea CONST (ele sunt de forma
<identificator> = <valoare>, separate prin punct [i virgul\), dou\ declara]ii de tip care
introduce tipurile Punct [i {ir (de puncte). Fiecare punct este o pereche de coordonate reale
x [i y. Variabilele a,b vor reperezenta punctele extreme ale segmentului.

CONST n=3;
TYPE Punct = RECORD x,y : REAL END;
Sir=ARRAY n+1 OF Punct;
VAR a,b:Punct ;

Procedura Plot are rolul de a desena pixelul de coordonate x, y pe ecran. Dar coordonatele
sunt reale (x,y :REAL) iar ecranul are pixeli cu coordonate `ntregi. Conversia se face

Programarea calculatoarelor [i limbaje de programare 207 Dan Popa, 2007


recurg=nd la dou\ func]ii din limbajul Oberon (identificatorii lor sunt predefini]i): ENTIER
transform\ un real `ntr-un num\r `ntreg lung (LONGINT) iar SHORT transform\ num\rul
`ntreg lung `ntr-un `ntreg obi[nuit. Desenarea punctului se face apel=nd la procedura
(instruc]iunea) Dot din modulul ColorPlane. Observa]i c\ procedura Dot are 3 parametri.
Sunt cele dou\ coordonate `ntregi ale punctului [i o constant\ (care poate fi DRAW sau
ERASE) care spune ce se va `nt=mpla cu pixelul: apare aprins, `n culoarea cernelii (DRAW)
sau stins, `n culoarea h=rtiei (ERASE). Cele dou\ culori se pot stabili folosind SetForeColor
[i respectiv SetBackColor, instruc]iuni tot din modulul CorlorPlane. Procedura prime-[te ca
parametru un punct, ce va fi desenat.

PROCEDURE Plot(a:Punct);
BEGIN
cp.Dot(SHORT(ENTIER(a.x)), SHORT(ENTIER(a.y)), cp.DRAW)
END Plot;

Procedura urm\toare verific\ dac\ distan]a `ntre dou\ capete succesive ale unui fractal
(fractalul ini]ial sau micii fractali care se vor desena pe treimile de segment) este mai mare
ca o constant\ epsilon, stabilit\ la un pixel. Evident c\ dac\ distan]a este mai mare ca 1
pixel mai avem `nc\ ce desena [i detaliile se disting pe ecran. La o distan]\ mai mic\ de un
pixel cu siguran]\ nu se vor distinge detaliile interioare segmentului AB.
Distan]a `ntre dou\ puncte se calculeaz\ cu teorema lui Pitagora. Este ipotenuza adic\
radical (se scrie Sqrt) din suma p\tratelor catetelor, (adic\ a produselor lor cu ele `nsele).
Care sunt lungimile catetelor ? Distan]ele dintre puncte pe axa Ox respectiv Oy adic\
diferen]ele dintre coordonatele x ale punctelor (respectiv coordonatele y).

PROCEDURE BigDist(a,b:Punct):BOOLEAN;
CONST eps=1;
BEGIN RETURN (eps < f.Sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)))
END BigDist;

De calculul coordonatelor punctelor intermediare din sirul t (T1,T2,T3) se ocup\ procedura


Puncte. Variabilele au urm\toarea semnifica]ie: xm,ym sunt coordonatele mijlocului
segmentului (media coordonatelor capetelor) iar sc este un fel de factor de scal\.

Programarea calculatoarelor [i limbaje de programare 208 Dan Popa, 2007


Modific=ndu-l se poate varia pozi]ia punctului T2 fa]\ de segmentul AB. Observa]i c\ valorile
coordonatelor (pentru punctele T1 [i T2) se calculeaz\ ca ni[te medii ponderate, a[a cum
am mai explicat. Variind factorul de scal\ pute]i ob]ine diver[i fractali `nrudi]i cu curba pe
care am prezentat-o.

PROCEDURE Puncte(a,b:Punct; VAR t :Sir);


VAR xm,ym,sc:REAL;
BEGIN
t[1].x:=(2*a.x+b.x)/3;
t[1].y:=(2*a.y+b.y)/3;
t[3].x:=(a.x+2*b.x)/3;
t[3].y:=(a.y+2*b.y)/3;
sc:=1/3; (* 0.33 - 0.9 *)
xm:=(a.x+b.x)/2;
ym:=(a.y+b.y)/2;
t[2].x:=xm+sc*(b.y-a.y);
t[2].y:=ym-sc*(b.x-a.x); (* + sc *)
END Puncte;

Amuzament: Pute]i schimba simultan [i semnul factorului de scal\ din penultimul r=nd al
procedurii [i valoarea acestuia. ~ncerca]i cu «plus» [i 0.63 pentru a ob]ine o veritabil\ oper\
de art\ abstract\, evident, tot un fractal. Ce am ob]inut noi cu aceste valori vede]i pe pagina
al\turat\:


Cum se deseneaz\ asemenea figuri ? Cu o procedur\ recursiv\. Ideea
este c\ fractalul de la A la B este (dup\ ce calcul\m coordonatele
punctelor intermediare T1,T2,T3 cu procedura Puncte) format din
fractalul de la A la T1, urmat de punctul T1, apoi urmat de fractalul de la
T1 la T2, urmat de punctul T2, de fractalul de la T2 la T3 [i de punctul T3 [i `n final de
fractalul de la T3 la B [i de punctul B. Evident are rost s\ intr\m `n profunzimea detaliilor
doar dac\ distan]a AB este suficient de mare. Ceea ce explic\ testul f\cut cu instruc]iunea
IF.

Programarea calculatoarelor [i limbaje de programare 209 Dan Popa, 2007


PROCEDURE Fractal(a,b:Punct);
VAR t :Sir;
BEGIN
IF BigDist(a,b) THEN
Puncte(a,b,t);
Fractal(a,t[1]); Plot(t[1]);
Fractal(t[1],t[2]); Plot(t[2]);
Fractal(t[2],t[3]); Plot(t[3]);
Fractal(t[3],b); Plot(b);
END;
END Fractal;

Am uitat ceva: ~ntregul fractal de la A la B cuprinde [i punctul ini]ial A. De desenarea lui se


ocup\ procedura principal\ ProgMain. ~nainte de aceasta ea va trece fereastra de afi[are `n
mod de lucru grafic folosind instruc]iunea Open din modulul ColorPlane. Altfel desenul nu se
poate realiza. Instruc]iunea Close dezactiveaz\ modul de lucru grafic.

Programarea calculatoarelor [i limbaje de programare 210 Dan Popa, 2007


PROCEDURE ProgMain*;
BEGIN
cp.Open();
a.x:=100; a.y:=200; b.x:=600; b.y:=200;
Plot(a);Fractal(a,b);
REPEAT UNTIL cp.KeyPressed();
cp.Close();
END ProgMain;
END Fract.

Pentru o list\ complet\ a instruc]iunilor disponibile `n modulul ColorPlane (sau `n general `n


biblioteca grafic\ a mediului de programare cu care lucra]i) pute]i consulta documenta]ia
electronic\ a acestuia.

Programarea calculatoarelor [i limbaje de programare 211 Dan Popa, 2007


Anexa A:
Mici programme `n diverse limbaje de programare.
Primul program `n C:

#include <stdio.h>

void main (void)


{ printf ("%s","Hello world!");
getchar();
}

Primul program `n C++:


#include <iostream.h>

void main(void)
{ char press_a_key;
cout << "Hello world !" << endl;
cin.get(press_a_key);
}

Primul program `n Java:


public class j1 {
public static void main(String[] args) {
System.out.println("Hello");
}
}

Programarea calculatoarelor [i limbaje de programare 212 Dan Popa, 2007


Anexa B:

Mic program `n C++ cu obiecte c\rora li se cer servicii. Aici ni[te obiecte numite becuri c\rora li
se solicit\ ni[te servicii cu nume familiare: s\ se aprind\ [i s\ se sting\.

#include <iostream.h>
#include <stdio.h>

// declaratiile clasei Becuri

class bec
{ public:
int tensiune ;
int putere ;
/***************************************************/
void set_putere(int p) { putere=p;};
void set_tensiune(int t) {tensiune = t; };

void se_aprinde() { cout << "Se aprinde becul de "


<< tensiune << "volti si "
<< putere << "wati !\n" ; };
void se_stinge () { cout << "Se stinge becul de "
<< tensiune << "volti si "
<< putere << "wati !\n" ; };
};

// Aplicatia

void main (void)


{ //declaratii si initializari
bec b1,b2;
b1.set_putere(50); b1.set_tensiune(220);
b2.set_putere(100); b2.set_tensiune(220);
// utilizarea obiectelor
b1.se_aprinde();
b1.se_stinge() ;
b2.se_aprinde() ;
b2.se_stinge() ;
getchar();
}

Mini - aplica]ia `n execu]ie:

Programarea calculatoarelor [i limbaje de programare 213 Dan Popa, 2007


Anexa C:

Editarea codului [i compilarea unei aplica]ii cu Dev -C++ [i MingW C++ Compiler:

Programarea calculatoarelor [i limbaje de programare 214 Dan Popa, 2007


Anexa D:

Editorul de proiect al mediului Dev C++ [i gestionarea claselor [i func]iilor din proiect.

Un simplu click pe func]ia sau clasa corespunz\toare v\ trimite `n acel fi[ier surs\ unde este ea
scris\ ! Pe monitoarele color func]iile /metodele sunt marcate cu un cub albastru iar variabilele /
c=mpurile cu un cub galben.

Programarea calculatoarelor [i limbaje de programare 215 Dan Popa, 2007


Anexa E:

Opera]ii cu obiecte realizate cu ajutorul operatorilor.

Un exemplu minimalist dar care ilustreaz\ modul de definire al operatorilor ce fac opera]ii cu
obiecte. Aici obiectele sunt numere complexe iar opera]ia este o adunare. Solu]iile elaborate
folosesc `ntotdeauna alocarea dinamic\ a obiectelor intermediare calculului [i dealocarea lor de
c\tre operatorul urm\tor. Observa]i c=t de natural se scrie programul principal – func]ia main().

#include <iostream.h>

class complex
{
private:
float real, imaginar;
public:
complex (int r=0, int i=1) {real=r; imaginar=i;}
complex& operator+(complex&);
void afiseaza_complex(void);
};

// creeaza un nou nr complex , care va fi


// initializat cu suma partilor reale, respectiv
// imaginare

complex& complex::operator+(complex& s2)


{
complex& t=* new complex (real+s2.real, imaginar+s2.imaginar);
// dupa cum am mai spus, in cadrul unei metode este
// permisa accesarea tuturor membrilor clasei. Din
// acest motiv se pot face si accesdari de genul 's2.real'.
return t;
}

Programarea calculatoarelor [i limbaje de programare 216 Dan Popa, 2007


// tipareste partile reale si imaginare ale unui
// numar complex

void complex::afiseaza_complex(void)
{ cout <<"\nComplex : " <<real <<"+i*"<<imaginar;
}

void main (void)


{
complex a(10,11), b(1,1);
complex& c=a+b;

a.afiseaza_complex();
b.afiseaza_complex();
c.afiseaza_complex();
}

Programarea calculatoarelor [i limbaje de programare 217 Dan Popa, 2007


Anexa F:
Dac\ dori]i s\ folosi]i Pow cu Java: Nu uita]i s\ schimba]i «preferin]ele» la mediul Pow dup\ ce a]i
instalat Java development Kit-ul furnizat de SUN:

Chiar [i pentru o aplica]ie dintr-un singur fi[ier java trebuie s\ face]i [i fi[ier proiect (.prj) asociat.

Programarea calculatoarelor [i limbaje de programare 218 Dan Popa, 2007


Anexa G:
Configurarea IDE-ului Dev C++:

Deoarece mediul Dev C++ poate fi folosit cu diverse versiuni de compilator [i acesta
poate fi instalat `n diverse directoare (exclud aici cazul favorabil c=nd a]i desc\rcat de
pe Internet un pachet complet con]in=nd [i IDE-ul [i compilatorul de C++) o mic\
“sincronizare” a lor este uneori necesar\ pentru ca IDE-ul s\ poat\ g\si rapid
compilatorul. Vizita]i [i la nevoie modifica]i op]iunile referitoare la directoare din meniul
Compiler Options. Asigura]i-v\ [i c\ locul bibliotecilor (directorul / folder-ul cu
biblioteci) este corect specificat..

Programarea calculatoarelor [i limbaje de programare 219 Dan Popa, 2007


Anexa H:
Jocul cu palatul califului, o variant\ C++ (a[a cum am testat-o cu studen]ii mei):
// Palatul califului - v3 - Bazat pe obiecte ! (o clasa)
// Obiectele sunt din clasa Camera si sunt camere capabile
// sa se joace cu jucatorul.
// Dan Popa 2004-2005 refacut in aprilie 2006

#include <stdio.h> // pentru getchar() apelat in final


#include <iostream.h> // Pentru operatii de I/O cu cin si cout

class Camera
{ int nr;
char denumire[40];
char artefact[40];
int usa[4];
int bani;
public:
/* N-am constructor explicit; la vectorul de camere vom initializa
fiecare camera ulterior, cu metoda Init */
void Init(int, char *, char *, int, int,int,int,int );
void Play(int & salacrt);
};

void Camera::Init(int unnumar, char * odenumire, char * unartefact,


int nistebani, int usa0, int usa1, int usa2, int usa3)
{ cout << "... mobilez camera "<< unnumar <<endl;
nr=unnumar;
strcpy( denumire,odenumire);
strcpy( artefact,unartefact);
bani=nistebani;
usa[0]=usa0;
usa[1]=usa1;

Programarea calculatoarelor [i limbaje de programare 220 Dan Popa, 2007


usa[2]=usa2;
usa[3]=usa3;
cout << usa[0] << ".." ; /* Se pot inlocui cu o bucla for ! */
cout << usa[1] << ".." ;
cout << usa[2] << ".." ;
cout << usa[3] << endl;
}

void Camera::Play(int & salacrt)


/* Transmis prin referinta deoarece se schimba*/
{int nrusa;
cout << "Esti in sala:" << salacrt << endl;
cout << "Este sala:" << denumire << endl; /* a obiectului curent! */
cout << "Gasesti un " << artefact << endl;
cout << "Sunt si bani in numar de:" << bani << endl;
cout << usa[0] << ".." ;
cout << usa[1] << ".." ;
cout << usa[2] << ".." ;
cout << usa[3] << endl;
cout << "Pe ce usa iesi ? " ;
cin >> nrusa;
cout << nrusa;
/* Urmeaza o scara if .. else if .. */
if (nrusa < 0 || nrusa > 3 )
cout << "Usa nu exista !" << endl;
else if ( usa[nrusa] == -1)
cout << "Usa este inchisa !" << endl;
else
salacrt = usa[nrusa];

Programarea calculatoarelor [i limbaje de programare 221 Dan Popa, 2007


void main(void)
{ Camera p[6];
p[0].Init(0,"Sala de intrare", "strajer" ,100, -1,-1,-1, 1);
p[1].Init(1,"Sala de judecata", "cadiu" ,200, -1,0,4, 2);
p[2].Init(2,"Sala armurilor", "pumnal" ,500, -1,1,5, 3);
p[3].Init(3,"Sala de mese", "oaspete" ,1000, -1,2,-1, 1);
p[4].Init(4,"Sala cu tezaur", "tezaur" ,10000, 1,-1,-1, 5);
p[5].Init(5,"Sala de arme", "jungher" ,300, 2,4,-1, 1);
int salacrt = 0;
while (salacrt != -2)
/* p[salacrt].Play(salacrt); */
(p+salacrt)->Play(salacrt);
cout << "Game Over !";
getchar();
}

Programarea calculatoarelor [i limbaje de programare 222 Dan Popa, 2007


Bibliografie

Makkai Andras, Cecilia Cri[an, Kovács Sándor, Ghid de utilizare Turbo Pascal 5.0-5.5,
micro Informatica, Cluj-Napoca, 1991

Birkenbil, Vera – Antrenamentul comunic\rii sau arta de a ne `n]elege, Gemma Press,1998

Birkenbil, Vera – Tare de cap ? - Mod de `ntrebuin]are a creierului – De la “a poseda” la “a


[ti s\-]i folose[ti” creierul, Gemma Press, 2000

C\prariu,Vlad; Ghid de utilizare Turbo C 2.0, micro Informatica,Cluj-Napoca 1991

Cristian Calude, Complexitatea Calcului, Aspecte calitative, Editura {tiin]ific\ [i


Enciclopedic\, 1982

Ciobanu Gabriel, Semantica Limbajelor de Programare , Editura Universit\]ii Ia[i, 1996

Dima, Gabriel; Dima Mihai; Visual Fox Pro 7, Teora,2003

F
***, Visual FoxPro 6.0 – Ghidul Programatorului, Teora, 2000 (p.16, 29-30,41-45 [.a.m.d)

Giumale C.R. [i colectiv: LISP ; Editura tehnic\; Bucure[ti – 1987

Gamma, Erich: Helm, Richard; Johnson, Ralph;Vlissides, John: Design Patterns – {abloane
de proiectare – elemente de software reutilizabil orientat obiect, (trad. Radu Biri[) Editura
Teora, 2002

*** Site-ul comunit\]ii Haskell de la Yale University, SUA, http://www.haskell.org

Programarea calculatoarelor [i limbaje de programare 223 Dan Popa, 2007


I
Info Arena – site-ul web al funda]iei Info Arena: http:/infoarena.ro/ actualmente ref\cut.

Java Development Kit (de la Sun). De la adresa http://java.sun.com.

Jamsa Kriss & Klander Lars – Totul despre C [i C++ – Manual fundamental de programare
`n C [i C++,Teora 2004

Johanson A.-L, Eriksson-Granskog A., Edman,A.: Prolog versus you; Springer Verlag 1985

Kalisz Eugenia, Athanasiu Irina, Cristea Valentin, Ini]iere `n Turbo Pascal, Teora, 1995,
1998 etc.

Winfried Kassera, Volker Kassera, Turbo Pascal 6.0, Micro ATCI Tirgu Mures, 1992

Kovács Sándor , Turbo Pascal 6.0, Ghid de Utilizare, microInformatica, Cluj-Napoca 1992

Knuth,Donald E.; Arta Program\rii Calculatoarelor, Vol1 – Algoritmi fundamentali, Teora


1999

Gheorghe Musc\, Programare `n limbaj de asamblare, Teora 1996

Mu[lea Ionu]: Ini]iere `n C^^, Programare orientat\ pe obiecte; Ed. Micro Informatica, Cluj-
Napoca 1992

Mössenböck H. , Wirth N., "The Programming Language Oberon - 2", (p\r]ile incluse `n
Help-ul mediului de programare Pow.)

Norton,Peter; Secrete PC; Ed.Teora 1998

Pappas, Chris H. & Murray, William H.; Visual C++ : the Complete Reference, Osborne /
McGraw-Hill, Berkelley, California, SUA, 1998

Programarea calculatoarelor [i limbaje de programare 224 Dan Popa, 2007


P=rv, Bazil; Vancea,Alexandru; Fundamentele Limbajelor de Programare, Cluj-Napoca,1996

Popa, Dan; Introducere `n Haskell 98 prin Exemple, Editura Edusoft, Bac\u, 2007

POW – Programmers Open Workbench & Red Chili Oberon 2 Compiler, Univ. Johannes
Keppler, Linz, http://www.fim.uni-linz.ac.at/pow/download.htm

Roman,Dan, Ingineria Program\rii Obiectuale, Editura Albastr\, Cluj-Napoca,1996

Rosch,Winn L. ; Totul despre hardware; Editura Teora 1998.

Schildt, Herbert; C++ Manual complet, Editura Teora, Bucure[ti, 2003

Schildt, Herbert; C Manual complet, Editura Teora, Bucure[ti, 2003

Stroustrup, Bjarne; C++, Editura Teora 2003

Luca Dan {erb\na]i, Limbaje de Programare [i Compilatoare, Editura Academiei, 1987

Terry, P.D., Compilers and Compilers Generators – an introduction with C^^, International
Thomson, 1996, disponibil\ [i pe web `n edi]ia revizuit\ din 2000

Programarea calculatoarelor [i limbaje de programare 225 Dan Popa, 2007

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