ACADEMIA DE STUDII ECONOMICE BUCUREŞTI

FACULTATEA DE CIBERNETICĂ, STATISTICĂ ŞI INFORMATICĂ ECONOMICA
CATEDRA DE INFORMATICĂ ECONOMICĂ













Bazele programării





Autori: Bogdan Ghilic-Micu, Marian Stoica, Marinela Mircea













Acest material are la bază lucrarea
Bazele programării calculatoarelor. Teorie şi aplicaţii în C,
Ion Gh. Roşca, Bogdan Ghilic-Micu, Cătălina Cocianu, Marian Stoica, Cristian Uscatu, Marinela
Mircea, Lorena Bătăgan, Cătălin Silvestru
Editura ASE, Bucureşti, 2006, ISBN 973-594-591-6






Bucureşti 2010

TITLUL CURSULUI: Bazele programării

INTRODUCERE

Cursul de Bazele programării se adresează studenţilor înscrişi la programul de studiu ID,
organizat de facultatea Cibernetică, Statistică şi Informatică Economică şi face parte din planul
de învăţământ aferent anului I, semestrul II. Pentru o bună înţelegere a noţiunilor teoretice şi
practice prezentate în acest curs, este recomandat să se fi parcurs anterior disciplina Bazele
tehnologiei informaţiei.

OBIECTIVELE PRINCIPALE ale acestui curs, vizează însuşirea de către studenţi a
următoarelor elemente:
• noţiuni de bază în teoria programării;
• metodele de analiză a problemelor în vederea rezolvării lor cu calculatorul;
• logica elaborării algoritmilor structuraţi şi modularizaţi;
• realizarea programelor în limbajul C.

Cursul Bazele programării este structurat în patru unităţi de învăţare, corespunzătoare
elementelor principale studiate. În cadrul procesului de instruire pot fi utilizate ca resurse
suplimentare materialele puse la dispoziţie de bibliotecile Academiei de Studii Economice,
precum şi laboratoarele catedrei de Informatică economică, cu o programare prealabilă şi atunci
când nu se desfăşoară ore.

EVALUAREA CUNOŞTINŢELOR, respectiv stabilirea notei finale, se va realiza astfel:
• lucrare de control;
• un referat despre operaţiile de intrare/ieşire efectuate cu tastatura/monitorul;
• un proiect, care va conţine minim 20 de programe în limbajul C, lucru cu masive de date,
însoţite de un dosar de prezentare.
Lucrarea va fi susţinută în cadrul ultimei activităţi asistate. Referatul şi proiectul se susţin numai
în timpul activităţii didactice (activităţilor asistate), conform calendarului disciplinei.

Stabilirea notei finale se va realiza astfel:
• lucrarea de control constituie 50% din nota finală;
• referatul constituie 10% din nota finală;
• proiectul constituie 30% din nota finală;
• din oficiu se acordă 10%.











Cuprins

1. Algoritmi şi scheme logice.................................................................................................. 4
Obiectivele unităţii de învăţare 1................................................................................................. 4
1.1. Caracteristicile şi reprezentarea algoritmilor........................................................................ 4
1.2. Descrierea structurilor fundamentale ................................................................................. 10
1.3. Structurarea şi proiectarea algoritmilor .............................................................................. 13
Răspunsuri şi comentarii la testele de autoevaluare .................................................................. 17
Bibliografia unităţii de învăţare................................................................................................. 17
2. Organizarea internă a datelor..................................................................................................... 18
Obiectivele unităţii de învăţare 2............................................................................................... 18
2.1. Informaţia, data şi reprezentarea internă a datelor ............................................................. 18
2.2. Structuri de date.................................................................................................................. 27
Răspunsuri şi comentarii la testele de autoevaluare .................................................................. 39
Bibliografia unităţii de învăţare................................................................................................. 39
3. Etapele rezolvării problemelor cu calculatorul.......................................................................... 40
Obiectivele unităţii de învăţare 3............................................................................................... 40
3.1. Caracteristici generale ale PPAD ....................................................................................... 40
3.2. Fazele dezvoltării programelor........................................................................................... 44
Răspunsuri şi comentarii la testele de autoevaluare .................................................................. 46
Bibliografia unităţii de învăţare................................................................................................. 46
4. Caracteristicile limbajului C...................................................................................................... 47
Obiectivele unităţii de învăţare 4............................................................................................... 47
4.1 Elementele de bază ale limbajului C................................................................................... 47
4.2 Tipurile de date în C............................................................................................................ 51
4.3 Expresii................................................................................................................................ 60
4.4. Realizarea structurilor fundamentale de control................................................................. 68
Răspunsuri şi comentarii la testele de autoevaluare .................................................................. 74
Bibliografia unităţii de învăţare................................................................................................. 75
Bibliografie.................................................................................................................................... 75

Bazele programării 4




1. Algoritmi şi scheme logice

Cuprins
Obiectivele unităţii de învăţare 1
1.1. Caracteristicile şi reprezentarea algoritmilor
1.2. Descrierea structurilor fundamentale
1.3. Structurarea şi proiectarea algoritmilor
Răspunsuri şi comentarii la testele de autoevaluare
Bibliografia unităţii de învăţare
Obiectivele unităţii de învăţare 1
Dupa studiul acestei unitati de învatare, studenţii vor avea cunoştinţe teoretice şi abilităţi practice
despre:
caracteristicile algoritmilor;
reprezentarea algoritmilor;
descrierea structurilor fundamentale;
structurarea algoritmilor;
proiectarea algoritmilor.

Durata medie a unităţii de studiu individual - 8 ore



1.1. Caracteristicile şi reprezentarea algoritmilor

Algoritmul desemnează o mulţime exhaustivă şi univoc determinată de operaţii, împreună cu
succesiunea în care trebuie aplicate asupra datelor iniţiale ale problemei, pentru a obţine soluţia.

Principalele caracteristici ale unui algoritm sunt:

Generalitate: un algoritm nu trebuie conceput pentru o problemă particulară, ci pentru o
clasă generală de probleme.
Exemplu:
Nu se va concepe un algoritm pentru rezolvarea ecuaţiei particulare 5x
2
-2x=7, ci un algoritm pentru
rezolvarea ecuaţiei de gradul al doilea cu o necunoscută ax
2
+bx+c=0, cu a,b,c,x∈ℜ, a≠0 sau, mai general,
pentru rezolvarea ecuaţiei de forma ax
2
+bx+c=0, cu parametrii a,b,c,x∈ℜ.

Determinare (claritate): algoritmul trebuie să prevadă modul de soluţionare a tuturor
situaţiilor care pot apărea în rezolvarea problemei respective, într-o manieră fără ambiguităţi sau
neclarităţi, lucru impus de caracterul de automat al calculatorului electronic.
Bazele programării 5


Exemplu:
Să se elaboreze algoritmul pentru rezolvarea ecuaţiei: ax
2
+ bx + c = 0, a,b,c,x∈ℜ. Analiza arată că există
patru situaţii posibile care trebuie cuprinse în algoritm:
1. a ≠ 0, ecuaţie de gradul II;
2. a = 0 şi b ≠ 0, ecuaţie de gradul I;
3. a = 0 şi b = 0 şi c ≠ 0, ecuaţie imposibilă;
4. a = 0 şi b = 0 şi c = 0, nedeterminare.
Rămâne să fie rezolvate fiecare din aceste situaţii sau unele din ele să fie grupate în funcţie de cerinţe.

Finitudine: operaţiile trebuie astfel concepute încât algoritmul să se termine într-un
număr finit de paşi, cunoscut sau necunoscut.
Exemple:
Pentru însumarea tuturor elementelor unui vector B, de dimensiune n, formula de recurenţă S = S +
b
i
se repetă de n ori (număr cunoscut de paşi);
La determinarea celui mai mare divizor comun (CMMDC) dintre două numere întregi (A şi B) se
împarte A la B: A=B·Q+R, apoi se continuă împărţirea împărţitorului (B) la rest (R), până când se obţine un
rest nul, caz în care CMMDC este ultimul împărţitor (număr necunoscut de paşi).

Descrierea algoritmilor. Iterativitate şi recursivitate

Iterativitatea este procesul prin care rezultatul este obţinut ca urmare a execuţiei repetate a
unui set de operaţii, de fiecare dată cu alte valori de intrare. Numărul de iteraţii poate fi cunoscut
sau necunoscut, dar determinabil pe parcursul execuţiei. Indiferent de situaţie, numărul de iteraţii
trebuie să fie totdeauna finit. În cazul în care numărul de repetări nu este cunoscut iniţial, oprirea
ciclării se face combinând instrucţiunile de calcul cu instrucţiunile de control. Condiţiile finale ce
trebuie îndeplinite pentru terminarea ciclării se bazează pe rezultatele calculelor până la un moment
dat, de cele mai multe ori fiind corelate cu viteza de convergenţă a calculelor către o valoare stabilă
şi, implicit, cu gradul de aproximare impus unui rezultat.
Utilizarea iterativităţii în descrierea algoritmilor este uneori o cale simplificatoare, alteori
singura alternativă de a preciza modul de desfăşurare a unui proces de calcul. În general, când
numărul de iteraţii nu este cunoscut sau este variabil de la o execuţie la alta, singura modalitate de
descriere a algoritmului presupune iterativitatea. Spre exemplu, ridicarea la pătrat a elementelor
unui vector cu 3 elemente se poate descrie prin următoarea succesiune de operaţii:
V(1)=V(1) · V(1)
V(2)=V(2) · V(2)
V(3)=V(3) · V(3)
Realizarea aceluiaşi lucru pentru un vector n-dimensional, cu n variind de la o execuţie a
programului la alta, nu este posibilă în această manieră, deoarece un algoritm este corect dacă are
precizaţi toţi paşii. Singura modalitate de realizare utilizează operaţia V(I)=V(I) · V(I), plasată într-
un ciclu variind după I, de la 1 la o valoare finală N, dată explicit de utilizator la fiecare execuţie a
programului.
Recursivitatea este procesul iterativ prin care valoarea unei variabile se determină pe baza
uneia sau mai multora dintre propriile ei valori anterioare. După cum valoarea curentă a variabilei
depinde de una sau mai multe valori anterioare, procesul este unirecursiv, respectiv multirecursiv.
Recursivitatea presupune definirea uneia sau mai multor formule de start (în funcţie de
numărul valorilor anterioare de care depinde valoarea curentă) şi a unei formule recursive (de recu-
renţă). Recursivitatea apare şi în cazuri dintre cele mai simple, cum ar fi numărarea, factorialul,
însumarea sau înmulţirea elementelor unui şir.
Bazele programării 6


Exemple:
A număra înseamnă a adăuga o unitate la valoarea anterior calculată. Dacă se notează v
0
= 0
valoarea iniţială, numărarea se desfăşoară după următorul proces recursiv:

v
1
= v
0
+ 1
v
2
= v
1
+ 1
v
3
= v
2
+ 1
........
v
i
= v
i-1
+ 1
........
v
n
= v
n─1
+1

Valoarea care interesează este v
n
. În procesul descris anterior se disting:

v
0
= 0 ► formula de start
v
i
= v
i-1
+ 1 ► formula recursivă, pentru i=1,n
Când valorile obţinute prin numărare nu necesită păstrarea în memorie, nu sunt necesare mai multe
locaţii, ci una singură, care va fi suprascrisă la fiecare iteraţie:
V = 0 ► formula de start
V = V + 1 ► formula recursivă, pentru i=1,n

Utilizarea mai multor zone de memorie pentru calculele intermediare devine obligatorie în
situaţia multirecursivităţii. Practic, prin transferul dinamic al valorilor intermediare, sunt necesare
atâtea zone de memorie câte valori precedente sunt necesare calculului termenului curent.
Exemplu:
Algoritmul lui Euclid pentru determinarea celui mai mare divizor comun a două numere A şi B.
Restul curent se calculează pornind de la ultimul şi penultimul rest, după relaţia:
r
r
r
-
r r 1 + k
1 + k
k
k 2 + k

= ,
cu r
0
= A; r
1
= B şi k = 0,1,2,... Prin [ ] s-a notat partea întreagă a expresiei. Ultimul rest nenul reprezintă
cel mai mare divizor comun. Dacă se notează cu D variabila deîmpărţit, cu I variabila împărţitor şi cu R
restul, formulele de start devin: D←a; I←b. Iterativ, se calculează restul R←D-
I
I
D

şi se execută
transferurile: D←I; I←R. Împărţitorul devine noul deîmpărţit, iar ultimul rest obţinut devine împărţitor în
iteraţia următoare a algoritmului. Procesul iterativ continuă până se obţine restul zero. Ultimul rest nenul
reprezintă cel mai mare divizor comun al numerelor A şi B.


Teste de autoevaluare


1. Caracteristicile oricărui algoritm sunt: 1. Generalitate; 2. Complementaritate; 3. Claritate;
4. Finitudine; 5. Recursivitate; 6. Iterativitate.
a) toate; b) 1,3,4,5 şi 6; c) 1,2,3 şi 4; d) 1,3 şi 4; e) 1,2,5 şi 6.

2. Un algoritm recursiv este: a) un algoritm care se autoapelează ; b) un proces repetitiv
static; c) un proces repetitiv dinamic; d) un proces repetitiv prin care valoarea unei
variabile se determină pe baza a cel puţin uneia dintre valorile ei anterioare; e) un
proces alternativ prin care valoarea unei variabile se determină pe baza a cel puţin
uneia dintre valorile ei anterioare.
Bazele programării 7


Reprezentarea algoritmilor prin scheme logice
Practica programării calculatoarelor dovedeşte că schema logică este forma cea mai utilizată
de reprezentare a algoritmilor. Ea se dovedeşte utilă, în special, în iniţierea în programare, deoarece
oferă o „vizualizare” mai bună, o redare expresivă şi sintetică, uşor de urmărit, a algoritmilor. Să
considerăm un graf orientat în care arcele sunt etichetate cu anumite informaţii formând aşa-zisele
blocuri. În graf sunt admise următoarele blocuri:
Blocul START este un arc etichetat cu cuvântul START, pentru care vârful iniţial nu este
pus explicit în evidenţă, deoarece în el nu pot sosi arce:

START

Blocul STOP este un arc etichetat cu cuvântul STOP, pentru care vârful final nu este pus
explicit în evidenţă, deoarece din el nu pot pleca arce:

STOP

Blocul de citire este un arc etichetat cu informaţia: citirea unor valori de pe suportul
extern şi înscrierea lor în locaţii de memorie corespunzătoare unor variabile.

Citeşte
listă-de-variabile

Blocul de scriere este un arc etichetat cu informaţia: înscrierea pe supotul extern a
valorilor memorate în locaţiile de memorie corespunzătoare unor variabile:

Scrie
listă-de-variabile

Blocul de atribuire este un arc etichetat cu informaţia: evaluarea unei expresii e şi
înscrierea (atribuirea) rezultatului în locaţia de memorie corespunzătoare unei variabile v:

sau
v = e v ← ←← ← e e → →→ → v
sau

Blocul de ramificare (selecţie) este o mulţime de n arce care pleacă din acelaşi vârf, arce
etichetate cu predicatele C
1
, C
2
,...,C
n
(predicat = condiţie = expresie logică, care poate fi adevărată
(1) sau falsă (0)), care satisfac relaţiile:
C
1
∨ C
2
∨ ... ∨ C
n
= 1; C
i
∧ C
j
= 0, (∀) i ≠ j; i,j= n 1,
Relaţiile exprimă faptul că unul şi numai unul din aceste predicate poate fi satisfăcut
(adevărat).

c
1
c
2
c
n
...


Pentru cazul n=2 se poate scrie, echivalent:


c
c
c
Nu Da

Definiţie:
Se numeşte schemă logică un graf orientat în care:
a) Există un singur bloc START şi un singur bloc STOP;
b) Orice arc este etichetat cu una din următoarele informaţii: START sau STOP; o citire sau
o scriere; o atribuire; un predicat, în care caz extremitatea iniţială a arcului este extremitatea iniţială
a unui bloc de ramificaţie;
Bazele programării 8


c) Orice arc face parte din cel puţin un drum care începe cu blocul START şi se termină cu
blocul STOP.
În practică, schemele logice alcătuite conform regulilor enunţate anterior pot lua forme
foarte complicate, greu de urmărit, uneori chiar de cel care le-a conceput. De aceea s-a simţit
nevoia ca în construcţia schemelor logice să se folosească numai anumite configuraţii (structuri) şi
să se respecte reguli stricte, obţinându-se, astfel, scheme logice structurate.

Definiţie:
Se numeşte subschemă logică un graf orientat în care:
a) Există un unic vârf iniţial (în care nu sosesc arce) şi un vârf final (din care nu pleacă arce);
b) Oricare arc este etichetat cu una din următoarele informaţii: START sau STOP; o citire sau
o scriere; o atribuire; un predicat, în care caz extremitatea iniţială a arcului este extremitatea iniţială
a unui bloc de ramificaţie;
c) Dacă subschema conţine blocul START (STOP), atunci extremitatea iniţială (finală) a
blocului este chiar vârful iniţial (final);
d) Orice arc face parte din cel puţin un drum ce uneşte vârful iniţial cu cel final.
În particular, o schemă logică este o subschemă logică în care vârful iniţial este extremitatea
iniţială a blocului START, iar vârful final este extremitatea finală a blocului STOP.
Prin recurenţă, schema logică structurată (s.l.s.) se defineşte astfel:
(I) Blocurile START, STOP, de intrare/ieşire şi de atribuire sunt s.l.s.;
(II) Dacă s1 şi s2 sunt s.l.s., atunci şi subschemele din figura 1.1. sunt s.l.s. (cu respectarea
condiţiilor referitoare la START şi STOP).
(III) Orice s.l.s. se obţine plecând de la (I) şi aplicând de un număr finit de ori regulile (II).


S
2
S
1
S
2
S
1
S

c
c
c
c
Structura
secvenţială
Structura alternativă
IF-THEN-ELSE
Structura repetitivă
WHILE-DO

Fig. 1.1. Subscheme logice structurate

O schemă logică structurată este o s.l.s. care este chiar o schemă logică.
Se pune întrebarea: se poate genera orice schemă logică folosind numai formele impuse
schemelor logice structurate? Sau altfel spus, se poate transforma orice schemă logică într-o
schemă logică bine structurată? Răspunsul, afirmativ, este dat de teorema fundamentală a
programării structurate (teorema lui Böhm-Jacopini): orice schemă logică este echivalentă cu o
schemă logică structurată. [Dodescu et al., 1987]

Reprezentarea algoritmilor prin pseudocod
Descrierea algoritmilor cu ajutorul schemelor logice se dovedeşte, în unele cazuri, greoaie,
practica impunând în ultima vreme descrierea lor printr-un text coerent, construit pe baza unor
reguli. O astfel de descriere se numeşte metalimbaj (pseudocod). Există multe variante de
metalimbaje. Oricine poate crea un pseudocod propriu, perfect acceptabil, cu condiţia ca el să
conţină structurile de bază, suficiente pentru a descrie orice algoritm. Evident că şi la pseudocoduri
Bazele programării 9


se pune problema „portabilităţii”, mai ales atunci când se lucrează în echipă. Cel mai avansat
pseudocod „universal” a fost propus în anii ’60 de Niklaus Wirth, pseudocod care ulterior a devenit
limbajul de programare Pascal. [Roşca et al., 1998] Se propune următorul pseudocod:
Cuvinte cheie. Sunt mnemonice ale instrucţiunilor, unele fiind scrise în limba engleză,
pentru compatibilizare cu literatura de specialitate (de exemplu WHILE-DO, IF-THEN-ELSE).
Instrucţiuni. Instrucţiunile pot fi scrise liber, în sensul că o instrucţiune se poate scrie pe
mai multe rânduri, iar un rând poate conţine mai multe instrucţiuni (separate prin ";").
Instrucţiunile se împart în declaraţii (instrucţiuni neexecutabile) şi instrucţiuni efective
(executabile).
O declaraţie este formată din cuvinte cheie (de exemplu ÎNTREG, REAL, CARACTER
etc.), urmat de un şir de variabile separate prin ",", variabile pentru care se indică faptul că au tipul
întreg, real, caracter etc. Masivele se declară prin tipul elementelor sale, urmat de o construcţie
care desemnează numărul maxim de elemente pe fiecare dimensiune, sub forma [d
1
][d
2
]...[d
n
].
Exemple:
ÎNTREG a, b, c;
REAL vector[20];
ÎNTREG matrice [10][15];

Instrucţiunile executabile într-un program scris în pseudocod pot fi:
Instrucţiunea de citire are forma: CITEŞTE(listă_de_variabile).
Exemple:
CITEŞTE(A,B);
CITEŞTE(x
i
);

Instrucţiunea de scriere are forma: SCRIE(listă_de_variabile).
Exemple:
SCRIE(A,B);
SCRIE("VECTORUL ESTE =");
SCRIE(x
i
);

Instrucţiunea de atribuire are forma: v=e, unde v este variabilă, e este expresie, ambele de
aceeaşi natură (numerică, logică sau caracter).
Instrucţiunile de ramificare (IF-THEN-ELSE, IF-THEN, CASE-OF) şi cele repetitive
(WHILE-DO, DO-UNTIL, DO-FOR) sunt prezentate împreună cu structurile fundamentale.
Observaţii:
a) Instrucţiunile corespund configuraţiilor acceptate într-o schemă logică structurată, deci sunt
compatibile cu programarea structurată.
b) Instrucţiunile acestui pseudocod se pot extinde la lucrul cu fişiere.


Teste de autoevaluare
3. Blocurile dintr-o subschemă logică sunt etichetate cu una din informaţiile: 1)START;
2)citire; 3)scriere; 4)expresie aritmetică; 5)expresie logică; 6)expresie relaţională; 7)sir de
caractere; 8)atribuire; 9)salt necondiţionat; 10)STOP. a)oricare; b)1,2,3,5,6,8 sau 10;
c)1,2,3,4,8 sau 10; d)1,2,3,5,6,7,8 sau 10; e)1,2,3,4,6,8,9 sau 10
4. Reprezentarea prin arbori este permisă numai pentru structurile: 1)BLOCK; 2)IF-THEN-
ELSE; 3)CASE-OF; 4)WHILE-DO; 5)DO-UNTIL; 6)DO-FOR. a) toate; b)1,2,3,4 şi 5;
c)2,3,4,5 şi 6; d)1,2 şi 4; e)1,2 şi 5.
Bazele programării 10


1.2. Descrierea structurilor fundamentale

În prezentarea structurilor fundamentale se vor folosi, în paralel, următoarele reprezentări:
schemă logică, arbore, pseudocod si exprimare analitică. În cele ce urmează, s
1
, s
2
,...,s
n
sunt s.l.s.
(respectiv şiruri de instrucţiuni în pseudocod sau module structurate în schemele arbore).
Structura secvenţială (liniară) este prezentată în figura 1.2. şi se notează analitic cu:
BLOCK[2](S
1
,S
2
) sau BLOCK(S
1
,S
2
). Structura secvenţială poate conţine mai multe blocuri:
BLOCK
[n]
(S
1
,S
2
...S
n
)=BLOCK(BLOCK
[n-1]
(S
1
,S
2
...S
n-1
), S
n
), cu n≥2.
Poate fi definită o structură secvenţială cu un singur bloc: BLOCK
[1]
(S
1
)=S
1
.


S
1

S
2
S
2
S
1

BLOCK
s.l.s. arbore pseudocod
S
1
;
S
2
;

Fig. 1.2. Structura secvenţială
Structurile alternative sunt de mai multe tipuri:


S
1
S
2

S
2
S
1

IF-THEN-ELSE
s.l.s. arbore pseudocod
IF C THEN
S
1

ELSE
S
2

ENDIF;
C
C
a) Structura IF-THEN-ELSE
S
1

S
1

IF-THEN
s.l.s. arbore pseudocod

IF C THEN
S
1

ENDIF;
C
C
b) Structura IF-THEN
da
da
nu
nu

Fig. 1.3. Structuri alternative

Structura IF-THEN-ELSE (selecţia simplă) este prezentată în figura 1.3.a. şi se notează
analitic cu IF-THEN-ELSE(c,S
1
,S
2
).
Structura IF-THEN (pseudoalternativă) este prezentată în figura 1.3.b şi se notează analitic cu
IF-THEN(c,s). Structura IF-THEN este o formă particulară a structurii IF-THEN-ELSE, putându-se
exprima astfel:
Bazele programării 11


IF-THEN(c,s)=IF-THEN-ELSE(c,s,Φ), unde Φ este o s.l.s. vidă.
Programarea structurată acceptă şi structura IF-ELSE (cu s pe ramura fals), notată IF-ELSE(c,s), tot
ca formă particulară a structurii IF-THEN-ELSE:
IF-ELSE(c,s)=IF-THEN-ELSE(c, Φ,s)
Structurile IF-THEN şi IF-ELSE se pot exprima (pot fi înlocuite în algoritm) una prin cealaltă:
IF-THEN(c,s) = IF-ELSE( c ,s) şi IF-ELSE(c,s) = IF-THEN( c ,s)
Structura CASE-OF (selecţia multiplă) este prezentată în figura 1.4 şi se notează analitic cu
CASE-OF(i,s
1
,s
2
,...,s
n
,s), în cazul general şi CASE-OF(i,s
1
,s
2
,...,s
n
), în cazul particular, unde i este o
variabilă selector care poate lua valori în mulţimea V={v
1
, v
2
, …, v
n
}. V este o mulţime discretă,
finită şi ordonată. Structura CASE-OF este echivalentă cu structura IF-THEN-ELSE (demonstraţi
acest lucru analitic, prin s.l.s. şi prin structuri arborescente).


S
n
S
2

CASE-OF i
s.l.s. arbore pseudocod
CASE-OF i
i=1: S
1

i=2: S
2

... ... ...
i=n: Sn
ELSE: S
ENDCASE;
a) Structura CASE-OF – cazul general
i=2
i=1
i
S S
1

i=n
i≠1, 2, ..., n
S
n
S
2
S S
1

Sn-1 S2
CASE-OF i
s.l.s. arbore pseudocod
CASE-OF i
i=1: S
1

i=2: S
2

... ... ...
i=n-1: S
n-1

i=n: Sn
ENDCASE;
b) Structura CASE-OF – cazul particular
i=2
i=1
i
Sn S1
i=n-1
i=n
Sn-1 S2 Sn S1

...

...


...

...


Fig. 1.4. Structura CASE-OF

Structurile repetitive sunt de mai multe tipuri:
Structura repetitivă condiţionată anterior este prezentată în figura 1.5.a. şi se notează analitic
cu WHILE-DO(c,s).
Structura repetitivă condiţionată posterior, este prezentată în figura 1.5.b. şi se notează
analitic cu DO-UNTIL(c,s).
Structura repetitivă cu numărător este prezentată în figura 1.5.c. şi se notează analitic cu DO-
FOR(v,v
i
,v
r
,v
f
,s), unde v este o variabilă contor (numărător), iar v
i
, v
f
,v
r
sunt expresii cu rol de
valoare iniţială, valoare finală, respectiv valoare raţie. Atunci când v
r
=1, raţia se poate omite în
pseudocod.

Observaţii:
1. Diferenţa esenţială între WHILE-DO şi DO-UNTIL costă în aceea că DO-UNTIL execută s cel
puţin o dată, pe când WHILE-DO poate să nu execute pe s. Oricum, cele două structuri se pot transforma
uşor una în alta, astfel:
WHILE-DO(c,s)=IF-THEN(c,DO-UNTIL( c ,s))
DO-UNTIL(s,c)=BLOCK(s,WHILE-DO( c ,s))
2. Structura DO-FOR este un caz particular al structurii DO-UNTIL, putându-se scrie:
DO-FOR(v,v
i
,v
f
,v
r
,s)=BLOCK(v=v
i
,WHILE-DO(v≤v
f
,BLOCK(s,v=v+v
r
)))

Bazele programării 12



S
S
WHILE-DO
s.l.s. arbore pseudocod

WHILE C DO
S
ENDWHILE;
C
C
a) Structura WHILE-DO
da
nu
S
S
DO-UNTIL
s.l.s. arbore pseudocod

DO
S
UNTIL C;
ENDDO; C C
b) Structura DO-UNTIL
da
nu
v=v
i

S
DO-FOR
v=v
i
, v
f
, v
r

s.l.s. arbore pseudocod

DO-FOR v=v
i
, v
f
, v
r

S
ENDDO;
v≤v
f

c) Structura DO-FOR
da
nu
S
v=v+v
r


Fig. 1.5. Structurile repetitive


Teste de autoevaluare








5.Structura DO-FOR(v,vi,vf,vr,s) este echivalentă cu: a) BLOCK(v=vi, DO-
UNTIL(BLOCK(v=v+vr,s),v>vf)); b) BLOCK(v=vf, DO-UNTIL(BLOCK(s,v=v-
vr),v≤ ≤≤ ≤vi)); c) BLOCK(v=vi, IF-THEN(v≤ ≤≤ ≤vf, DO-UNTIL(BLOCK(s,v=v+vr),v>vf))); d)
BLOCK(v=vf, WHILE-DO(v>vi,BLOCK(s,v=v-vr))); e) BLOCK(v=vi, WHILE-
DO(v<vf,BLOCK (s,v=v+vr)));
6. Structura WHILE-DO(c,s) este echivalentă cu: a) DO-UNTIL(s, c ); b)BLOCK(s,DO-
UNTIL(s, c )); c)IF-THEN(c,DO-UNTIL(s,c)); d)BLOCK(s,IF-THEN(c,s)); e)DO-
UNTIL(IF-THEN(c,s), c )
Bazele programării 13


1.3. Structurarea şi proiectarea algoritmilor

Un algoritm se consideră structurat dacă şi numai dacă conţine structurile fundamentale
prezentate anterior. Deoarece fiecare structură are o singură intrare şi o singură ieşire, schema
logică are o singură intrare şi o singură ieşire.
Considerându-se o familie D' de structuri fundamentale (de exemplu D'={BLOCK, IF-
THEN-ELSE, IF-THEN, DO-UNTIL, WHILE-DO}), un algoritm se numeşte D'-structurat dacă
este reprezentat numai prin structuri din D'. De remarcat faptul că orice algoritm structurat poate fi
realizat numai prin structurile de bază din familia D={BLOCK, IF-THEN-ELSE, WHILE-DO}.
Un algoritm P, structurat, este echivalent cu un algoritm pus sub una din următoarele forme:
P=BLOCK(s
1
,s
2
)
P=IF-THEN-ELSE(c,s
1
,s
2
)
P=WHILE-DO(c,s)
Dacă schema logică prin care se ilustrează algoritmul de rezolvare a unei probleme nu
conţine numai structurile fundamentale, atunci ea este nestructurată.
Orice schemă logică nestructurată se poate structura, conform următoarei teoreme de
structură: Fie S o schemă logică nestructurată în care etichetele care sunt predicate formează o
mulţime P, iar etichetele care nu sunt predicate formează mulţimea A, a acţiunilor. Se pot adăuga
lui A şi P alte acţiuni, respectiv alte predicate, diferite de cele din S, astfel încât să se obţină o
schemă logică structurată echivalentă cu S. Dacă o schemă logică nestructurată este prea complica-
tă, se renunţă la structurare (care, prin adăugare de noi acţiuni şi predicate, complică şi mai mult
schema) şi se reproiectează.
În practică s-au impus următoarele metode de structurare.
Metoda dublării codurilor se foloseşte la structurarea alternativelor sau repetitivelor. Ea
constă în dublarea, ori de câte ori este nevoie, a unui cod (a unei acţiuni sau a unui predicat), astfel
încât să se obţină numai structuri fundamentale.
Metoda introducerii unei variabile booleene se foloseşte pentru structurarea repetitivelor şi
constă în:
- se copiază din vechea schemă logică toate blocurile până la intrarea în structura repetitivă
care nu este fundamentală;
- se introduce variabila booleană, de exemplu VB (VB=0 sau VB=1);
- se alege structura repetitivă fundamentală WHILE-DO sau DO-UNTIL, în care condiţia se
referă la variabila booleană introdusă, VB;
- în interiorul structurii repetitive alese, variabila booleeană îşi schimbă valoarea: VB=1
(sau VB=0) pe toate drumurile care duceau la ieşirea din vechea structură repetitivă.

Erorile în algoritmi
Un algoritm este eficient şi devine operaţional în măsura în care între resursele de calcul
utilizate (timp şi memorie calculator) şi precizia rezultatelor se stabileşte un raport acceptabil.
Cu toată precizia oferită de calculatoarele electronice, calitatea rezultatelor este influenţată
de mulţi alţi factori. Soluţia unei probleme depinde de datele iniţiale, acestea fiind obţinute în urma
unor observaţii, măsurători sau pe baza altor calcule prealabile. Precizia instrumentelor cu care se
fac observaţiile, condiţiile în care au loc acestea, precizia calculelor necesare determinării unor
parametri iniţiali generează erori în datele iniţiale. În general, pentru această clasă de erori se
stabilesc limite de eroare.
O parte din parametrii utilizaţi în formulele de calcul nu au o valoare exprimabilă printr-un
număr finit de zecimale (de exemplu 3 , π, e etc). Erorile de aproximare a lor sunt cunoscute şi
Bazele programării 14


vor fi astfel alese încât să fie corelate cu precizia dorită pentru calculele în care intră aceşti
parametri.
O altă clasă importantă de erori o constituie erorile de rotunjire. Ele apar ca urmare a
limitării numărului de zecimale cu care se poate reprezenta un număr în calculator. Aceste erori
depind de modul de reprezentare a numerelor în calculator, de sistemul de numeraţie folosit în
calcule, precum şi de conversiile dintr-un sistem de numeraţie în altul.
La rezolvarea, mai ales numerică, a unei probleme se foloseşte o metodă matematică. De
multe ori, fenomenul modelat este supus unor condiţii simplificatoare, în funcţie de acestea alegând
una sau alta din metodele de rezolvare existente. Alegerea metodei poate introduce aşa numitele
erori de metodă. Erorile introduse prin prezenţa în calculator a unor funcţii cărora în analiza
matematică le corespund serii infinite se numesc erori reziduale. Ele se explică prin imposibilitatea
calculării unei serii infinite într-un număr finit de paşi ai algoritmului.

Dacă x este valoarea exactă şi x* o valoare aproximativă a lui x, obţinută ca urmare a
prezenţei unor erori din clasele menţionate anterior, se disting următoarele situaţii:
x* > x ► x* este o aproximare a lui x prin adaos;
x* < x ► x* realizează o aproximare prin lipsă.
Diferenţa
*
x
x - x =
ε
* reprezintă eroarea, iar când nu interesează sensul ei se calculează
*
x
x x ε
*
− = , care poartă numele de eroare absolută.
Erorile pot fi acceptate sau respinse, nu numai în funcţie de mărimea lor, ci şi în funcţie de
mărimea valorilor cărora li se asociază. În acest scop se calculează raportul
*
*
x
x
x x
r
*

= care
desemnează eroarea relativă.
În cazul operaţiilor de adunare şi scădere, eroarea absolută nu depăşeşte suma erorilor
absolute a celor două numere care se adună algebric.
ε ε
= ) y
x
( - y) (x =
ε y x
*
*
y x
* * * * ± ± ±
±
, pentru eroarea absolută;
y
x
y
r
y
x
x
r
=
y
x
ε ε
=
r
*
*
*
y
*
*
*
x *
*
y x
y x
* *
* *
* *
±
±
± ±
±
±
, pentru eroarea relativă.
De reţinut că la scăderea a două numere apropiate ca valoare, eroarea relativă îşi pierde din
acurateţe datorită numitorului raportului care tinde spre zero. Relaţiile funcţionează şi pentru n>2
numere. În cazul produsului a mai multor numere aproximative şi nenule, eroarea relativă nu
depăşeşte suma erorilor relative ale numerelor:
ε ε
+
ε
y +
ε x
= y
x
- )
ε
+ y ( )
ε
+
x
( = ) y
x
- (xy -
ε y x x
*
y
*
*
*
y
*
x
*
*
*
y . x
* * * * * * * * ⋅
y .
x
ε
=
r
*
*
y . x
y . x
* *
* *
în care, logaritmând (valorile absolute permiţând acest lucru, iar x* şi y* pentru simplificare au
acelaşi semn) şi folosind formula de aproximare
x
ε
=
x
ln d
x
ln - ln x
*
x * *
*
≈ , rezultă că
r
+
r r y x y x
* * * * ≤ . În cazul operaţiei de împărţire
) y (
ε x
-
ε
y

ε
2 *
y
*
x
*
)
y
x
(
* *
* ≈ , , |
r
| + |
r
|
r y x )
y
x
(
* * *
≤ ceea ce
înseamnă că eroarea relativă a câtului nu excede suma erorilor relative ale deîmpărţitului şi
împărţitorului. Erorile în cazul unor expresii calculabile prin operaţiile elementare pot fi aproximate
folosind limita maximă a erorilor fiecărui termen în parte.

Bazele programării 15


Teste de autoevaluare



Proiectarea algoritmilor
Conceptele principale ce s-au cristalizat în domeniul programării structurate sunt:
proiectarea top-down, proiectarea modulară, proiectarea structurată. Cele trei tipuri de proiectări
nu se exclud unul pe altul, ci se intercorelează pentru desfăşurarea unei activităţi organizate şi
disciplinate, concretizată în obţinerea unor produse program care să reflecte clar ierarhizarea
prelucrărilor şi care să faciliteze testarea şi documentarea lor.
Proiectarea top-down presupune descompunerea, de la general la particular, a problemei
date în subprobleme sau funcţii de prelucrat, conducând la realizarea algoritmului în mai multe faze
succesive, fiecare fază fiind o detaliere a fazei anterioare până când algoritmul este suficient de
rafinat (detaliat) pentru a fi codificat. Apar astfel, în diferite faze succesive, algoritmi din ce în ce
mai detaliaţi. În urma descompunerii se obţine o structură liniară sau arborescentă.
Proiectarea top-down este însoţită de codificare (scriere a programelor) top-down şi testare
top-down. Codificarea top-down presupune, în principal, posibilitatea scrierii unui modul înainte de
a se proiecta modulele de nivel inferior (superior), iar testarea top-down constă în realizarea ei de
sus în jos: se porneşte cu modulul rădăcină şi cu unu sau mai multe module de ordin imediat
inferior, se continuă cu ataşarea unui alt nivel inferior etc., până când s-au inclus în testare
modulele ultimului nivel. Testarea top-down poate lua în considerare, la un moment dat, numai
legăturile unui modul cu module de pe nivelul inferior, fără testare propriu-zisă a acestora din urmă.
Proiectarea modularizată presupune descompunerea problemelor în părţi numite
module, astfel încât fiecare din acestea să îndeplinească anumite funcţii bine definite.
Descompunerea se poate face în mai multe faze (la mai multe niveluri) prin metoda top-down.
Criteriile de descompunere în module depind, în mare măsură, de experienţa proiectanţilor
(programatorilor).
Ele se referă, în principal, la: omogenizarea funcţiilor; utilizarea diverselor structuri de date;
separarea funcţiilor de intrare/ieşire de funcţiile de prelucrare; utilizarea unor module deja
existente; posibilităţile echipei în sarcina căreia intră realizarea modulelor; utilizarea eficientă a
resurselor calculatorului (periferice, timp, memorie internă) etc.
Proiectarea modularizată presupune, pe lângă identificarea modulelor şi a relaţiilor dintre
ele, şi precizarea modului şi ordinii în care modulele sunt puse în lucru. Din punct de vedere al
funcţiilor pe care le conţin, se disting: module de prelucrare (operaţionale) care conţin funcţii de
prelucrare (operaţii propriu-zise), module de comandă (monitor) care apelează (activează) alte
module şi module mixte, care conţin atât funcţii de prelucrare cât şi de comandă. În stabilirea
ordinei de punere în lucru a modulelor, arborele se parcurge în preordine. După stabilirea
modulelor, acestea se abordează algoritmic, independent unul faţă de altul.
7. Un algoritm structurat este echivalent cu un algoritm pus sub una din formele:
1)BLOCK(s1,s2); 2)IF-THEN-ELSE(c,s1,s2); 3)IF-THEN(c,s); 4)CASE-OF(i,s1,s2,...,sn,s);
5)WHILE-DO(c,s); 6)DO-UNTIL(s,c); 7)DO-FOR(v,vi,vf,vr,s). a)1,2,3,4,5,6,7; b) 1,2,3,5,6;
c) 1,2,5,6,7; d) 1,2,5; e) 1,2,6.
8. Teorema de structură stabileşte că: a) orice schemă logică este echivalentă cu o schemă
logică structurată; b) orice schemă logică poate fi pusă sub una din
formele:BLOCK(s1,s2); IF-THEN-ELSE(c,s1,s2); WHILE-DO(c,s); c) corectitudinea
unei scheme logice structurate se verifică prin examinarea fiecărui nod din arborescenţa
sa; d) o schemă logică structurată poate fi descompusă în structurile privilegiate
Bazele programării 16


Proiectarea structurată a algoritmilor constă dintr-o mulţime de restricţii şi reguli de
elaborare care forţează proiectantul (programatorul) să urmeze o formă strânsă de reprezentare şi
codificare. Într-un sens mai larg, programarea structurată - incluzând aici şi elaborarea algoritmilor
- este modalitatea de ordonare a activităţii mentale desfăşurată în scopul obţinerii de programe
(algoritmi) constituite din structuri fundamentale cu un grad de structurare cât mai mare şi în
condiţiile minimizării efortului de programare, dar obţinerii unui produs de cea mai bună calitate.

Verificarea şi analiza corectitudinii algoritmilor
În procesul de elaborare a algoritmilor se pot strecura formulări imprecise sau eronate, ceea
ce determină obţinerea unor rezultate incomplete sau eronate. Verificarea corectitudinii ar însemna
verificarea faptului că pentru orice set de date, algoritmul elaborat furnizează rezultate corecte,
lucru imposibil de realizat în practică. Există încercări, cu valoare teoretică, de a elabora o
metodologie de verificare a corectitudinii algoritmului. În practică se recomandă următoarele
verificări ale corectitudinii algoritmilor simpli:
1. încheierea algoritmului după un număr finit de paşi (în principal, modul de construire a
ciclărilor);
2. modul în care au fost construite selecţiile, astfel încât variantele să fie corect definite în
algoritm;
3. asigurarea valorilor (prin introducerea din exterior sau iniţializare în algoritm) pentru
toate variabilele referite (utilizate) în operaţii.
Dacă cele trei tipuri de verificări au condus la concluzia de corectitudine, se procedează la
un test de birou care presupune parcurgerea atentă, operaţie cu operaţie, a algoritmului, pentru
seturi de date, de obicei cazuri limită.

Analiza algoritmilor (studiul eficienţei lor) constă, în principal, în:
I) Determinarea necesarului de memorie;
II) Determinarea timpului necesar execuţiei algoritmului. Deoarece, pentru seturi diferite de
date, timpii de execuţie vor fi diferiţi, timpul necesar execuţiei algoritmului poate însemna timpul în
cazul cel mai defavorabil sau timpul mediu, rezultat ca raport între suma timpului necesar pentru
toate seturile de date considerate şi numărul acestor seturi.
III) Determinarea optimalităţii algoritmului, care este, în general, o problemă dificilă, în
care important este criteriul după care se judecă algoritmul: (I) sau (II). Cu toate progresele
tehnologice din ultimul timp (calculatoare rapide, cu memorii mari), necesarul de memorie şi
timpul UC rămân resurse importante care trebuie bine utilizate.

Test de autoevaluare



9. Care tipurile de proiectări cristalizate în domeniul programării structurate?

Bazele programării 17


Răspunsuri şi comentarii la testele de autoevaluare


Rezumat
În cadrul acestei unităţi de învăţare au fost studiate următoarele aspecte în ceea ce priveşte
algoritmii şi schemele logice:
cunoştinţe teoretice privind caracteristicile şi descrierea algoritmilor;
modalităţi de reprezentare a algoritmilor sub formă de scheme logice şi pseudocod;
reprezentarea structurilor fundamentale sub formă de schemă logică, arbore, pseudocod
şi exprimare analitică;
proiectarea, verificarea şi analiza algoritmilor.
După încheierea acestei unităţi de învăţare, studenţii au cunoştinţe şi abilităţi de rezolvare a
problemelor (în special lucrul cu masive), prin reprezentarea acestora sub formă de algoritmi
structuraţi.
Bibliografia unităţii de învăţare
1. I. Gh. Roşca, B. Ghilic-Micu, C. Cocianu, M. Stoica, C. Uscatu, M. Mircea, L. Bătăgan, C. Silvestru,
Bazele programării calculatoarelor. Teorie şi aplicaţii în C, Ed. ASE, Bucureşti, 2006, ISBN 973-594-591-
6
2. I. Gh. Roşca, B. Ghilic-Micu, C. Cocianu, M. Stoica, C. Uscatu, Programarea calculatoarelor. Ştiinţa
învăţării unui limbaj de programare, Teorie şi aplicaţii, Ed. ASE, 2003
3. Roşca I. Gh., Apostol C., Ghilic-Micu B., Roşca V., Programare sistematică în Pascal, Ed.
Didactică şi Pedagogică, Bucureşti 1998, ISBN 973-30-3341-3




1:d); 2:d); 3:b); 4:a); 5:c); 6:e); 7:d); 8:a); 9. Tipurile de proiectări care s-au
cristalizat în domeniul programării structurate sunt: proiectarea top-down, proiectarea
modulară, proiectarea structurată.

Bazele programării 18


2. Organizarea internă a datelor

Cuprins
Obiectivele unităţii de învăţare 2
2.1. Informaţia, data şi reprezentarea internă a datelor
2.2. Structuri de date
Răspunsuri şi comentarii la testele de autoevaluare
Bibliografia unităţii de învăţare
Obiectivele unităţii de învăţare 2
Dupa studiul acestei unitati de învatare, studenţii vor avea cunoştinţe teoretice şi abilităţi practice
despre:
informaţii, date, cunoştinţe;
reprezentarea internă a datelor;
structuri statice de date;
structuri dinamice de date.

Durata medie a unităţii de studiu individual - 8 ore

2.1. Informaţia, data şi reprezentarea internă a datelor

Informaţia este un concept de maximă generalitate, care poate fi definit prin raportarea la
conceptele de materie şi energie. Fondatorul ciberneticii, Norbert Wiener
1
, consideră informaţia
ca a treia formă de manifestare a realităţii obiective, apreciind că ea nu este nici materie, nici
energie, ci pur şi simplu informaţie. Se poate remarca faptul că definiţia anterioară este dată în
sens negativ.
Pentru a încerca o definiţie afirmativă, se cuvine mai întâi să se facă distincţie între două
maniere de a aborda conceptul pus în discuţie: în general, ca semnele care circulă pe diferite
canale între elementele lumii reale, cu forme specifice de receptare la diferitele niveluri de
manifestare a materiei vii; în particular, când elementul receptor este omul, ca fiinţă superioară pe
scara biologică. În acest ultim sens, informaţia trebuie considerată în raport cu procesul de
cunoaştere şi cu modul de reflectare a rezultatelor sale în conştiinţa fiinţei umane. În literatura de
specialitate sunt identificate următoarele trăsături definitorii ale informaţiei:
semn cu semnificaţie: este obligatoriu ca un mesaj să fie construit într-o limbă (limbaj) cunoscută
de receptor;
noutate: există mesaje care, deşi sunt redactate într-o limbă cunoscută, nu conţin nimic nou
pentru receptor, pierzându-se calitatea de informaţie;

1
Norbert Wiener – Cybernetics or Control and Communication in the Animal and the Machine, Herman
and Cie, Paris, The MIT Press, Cambridge (Mass), Wiley and Sons, New York (1948), ediţia a doua
revăzuită şi adăugită (două capitole noi), The MIT Press, Cambridge (Mass), Wiley and Sons, New York,
1961
Bazele programării 19


utilitate: în raport cu interesele receptorului, este posibil ca un mesaj cu caracter de noutate să fie
inutil pentru activitatea sa, pierzându-şi, de asemenea, calitatea de informaţie.
Corespunzător, se identifică următoarele niveluri la care se consideră informaţia: sintactic, semantic şi
pragmatic.
Nivelul sintactic este asociat sistemului de semne şi regulilor utilizate pentru a le reuni în
construcţii sintactice folosite pentru reprezentarea informaţiei în procesul de culegere,
transmitere, înregistrare şi prelucrare. Acestui nivel îi corespunde conceptul de dată, care,
folosind notaţia formală BNF (Backus-Nour Form), poate fi definită astfel:
<dată>: : = <identificator> <atribute> <valoare>.

Regulile de sintaxă care formează mulţimea producţiilor pot fi specificate în mai multe moduri,
dintre care se remarcă notaţia formală BNF (Backus Normal Form) şi diagramele de sintaxă. În notaţia
BNF, regulile sintactice (metadefiniţiile) au forma:
<parte-stânga> ::= parte-dreapta
unde <parte-stânga> desemnează metavariabila (variabila neterminală) care se defineşte, ::= este un
metasimbol având sensul de „este prin definiţie”, iar parte-dreapta reprezintă definiţia metavariabilei.
În cadrul definiţiei (parte-dreapta) se întâlnesc următoarele elemente:
<metavariabila>, categorie folosită în definirea altei categorii sintactice;
metaconstanta, element al alfabetului terminal;
   care separă alternativele în definiţie;
[ ] care indică o construcţie opţională;
{ } care indică posibilitatea repetării construcţiei.
Alternativele se constituie prin juxtapunerea de metavariabile şi/sau metaconstante.

Noţiunea de dată va conţine pe cea de valoare, dar presupune, în plus, o formă de
reprezentare şi manipulare, adică un sistem de reguli de transformare având ca scop să se
obţină date noi pornind de la cele existente. Pe lângă distincţia între conceptele de dată şi
valoare se constată, de asemenea, diferenţa între informaţie şi dată, ca între un obiect şi
modelul său. Se mai spune că data este o reprezentare digitală (discretă) a unei anumite
cantităţi de informaţie. În concluzie, conceptele de informaţie şi dată pot fi utilizate ca
sinonime numai în măsura în care acceptăm să identificăm un obiect cu modelul său.
La nivelul semantic, informaţia poate fi caracterizată ca semnificaţie a datelor. Sensul
informaţiei la acest nivel este dat de corespondenţa între o dată şi obiectul real sau situaţia
reprezentată prin această dată.
Nivelul pragmatic este cel mai concret nivel de abordare a informaţiei, fiind singurul care
consideră informaţia în raport cu scopurile receptorului. Pornind de la scopurile receptorului pot
fi definite caracteristici ca utilitatea sau importanţa informaţiei. Nivelul pragmatic permite
reflectarea cea mai fidelă a procesului de cunoaştere, a cărui înţelegere completă impune
utilizarea conceptului de cunoştinţă.
Procesul de cunoaştere se realizează în timp, prin acumularea progresivă de informaţii
asupra unui obiect sau a unui sistem. La un moment dat, cunoştinţele reprezintă totalitatea
informaţiilor deţinute de un observator asupra unui obiect sau sistem. Acest ansamblu de
informaţii se numeşte tezaur de cunoştinţe şi se foloseşte ca termen de referinţă pentru a evalua
rezultatele oricărui proces de informare, ca parte a procesului general de cunoaştere.
La limită, rezultatele unui proces de informare pot conduce la una din următoarele situaţii:
la o extremă, este posibil ca rezultatul să fie nul, dacă informaţia aparţine deja
tezaurului receptorului, adică ea a devenit o cunoştinţă;
la cealaltă extremă, variaţia potenţială a tezaurului receptorului este maximă dacă
intersecţia între conţinutul tezaurului şi acela al unui mesaj este vidă.
Bazele programării 20


Referitor la al doilea caz, se constată, însă, că este obligatorie existenţa unei intersecţii
nevide între cele două mulţimi, numită redundanţă, astfel încât recepţia şi înţelegerea
mesajului să aibă loc.
În final putem sintetiza o serie de concluzii clarificatoare a problematicii puse în
discuţie.
O informaţie este un mesaj susceptibil de a aduce o cunoştinţă şi poate fi generată numai de
sisteme cu număr n finit de stări (n ≥ 2). Modelul de reprezentare a informaţiei, „formula scrisă”,
reprezintă o dată. Deosebirea dintre informaţie şi dată este echivalentă cu deosebirea dintre obiect şi
modelul său. Sub aspect semantic, informaţia poate fi caracterizată ca semnificaţie a datelor.
Calculatoarele actuale prelucrează date pe baza cărora se obţin rezultate (tot date) care, prin
interpretare umană, capătă un sens, devenind informaţii.
C.E. Shannon a introdus noţiunea de cantitate de informaţie, care se poate defini astfel: fie
un experiment X, având un număr finit de evenimente elementare independente x
1
,x
2
,...,x
n
, care se
realizează cu probabilităţile p
1
,p
2
,...,p
n
:
|
|
¹
|

\
|
p ... p p

x
...
x x
= X
n 2 1
n 2 1 . Dacă X reprezintă un sistem complet de
evenimente: 0≤p
k
≤1, pentru orice k∈{1,2,...,n} (1) şi 1 = p
k
n
1 = k

(2), atunci cantitatea de informaţie
(entropia) se măsoară după relaţia:
p log p - = ) p ..., , p , p H(
k 2 k
n
1 = k
n 2 1


(3)
Cantitatea de informaţie se exprimă, cel mai adesea, în biţi. Bitul poate fi definit ca
informaţia furnizată de un sistem cu două stări echiprobabile:
|
|
¹
|

\
|
1/2 1/2

x

x
= X
2 1
(4)
Aplicând formula (3), se obţine:
bit 1 1/2 1/2 (1/2)
2
(1/2)log (1/2)
2
(1/2)log
n
1 k
k
p
2
log
k
p )
n
p ,...,
2
p ,
1
H(p = + == − − = ∑
=
⋅ − =

Prin dată se desemnează un model de reprezentare a informaţiei accesibil unui anumit
procesor (om, unitate centrală, program etc.), model cu care se poate opera pentru a obţine noi
informaţii despre fenomenele, procesele şi obiectele lumii reale.
În notaţie BNF, semnificaţia cuvintelor de definire este următoarea.
Identificatorul este un nume care se asociază datei, pentru a o distinge de alte date şi a o
putea referi în procesele de prelucrare (referire prin nume).
Valoarea datei se poate preciza prin enumerare sau printr-o proprietate comună. Ea poate fi
număr întreg, real, complex, logic, şir de caractere etc. Data care păstrează aceeaşi valoare pe tot
parcursul prelucrării este denumită constantă. În caz contrar, data se numeşte variabilă. Pentru
datele constante se foloseşte, în general, drept identificator chiar valoarea, adică o astfel de dată se
autoidentifică prin forma textuală a valorii, ceea ce justifică denumirea de literal. În unele limbaje
de programare, între care şi C, există şi posibilitatea definirii unor constante simbolice, cărora li se
asociază un identificator propriu.
Atributele precizează proprietăţi ale datei şi ele determină modul în care aceasta va fi tratată
în procesul de prelucrare. Dintre atributele care se pot asocia unei date, cel mai important este tipul.
El precizează mulţimea valorilor pe care le poate avea o dată, precum şi mulţimea de operaţii care
se pot efectua cu elementele mulţimii de valori ale datei. Pe lângă tip, unei date i se pot asocia şi
alte atribute, ca: precizia reprezentării interne, cadrarea valorilor în zona afectată, modul de alocare
a memoriei pe parcursul prelucrării (static, dinamic), valoarea iniţială etc.
Bazele programării 21



Reprezentarea internă a datelor

Data este elementară (scalară) dacă apare ca o entitate indivizibilă, atât în raport cu
informaţia pe care o reprezintă, cât şi în raport cu procesorul care o prelucrează. O dată scalară
poate fi privită la nivelul unui procesor uman (nivel logic), respectiv la nivelul calculatorului, ca
procesor (nivel fizic). La nivel fizic, unei date îi corespunde o zonă de memorie de o anumită
mărime, situată la o anumită adresă, în care sunt memorate, în timp şi într-o formă specifică,
valorile acesteia.

Datele din memoria internă pot fi clasificate în trei mari categorii.
Datele alfanumerice se reprezintă în cod ASCII extins, câte un caracter pe octet. Cele
256 de caractere codificabile ASCII se împart în afişabile şi neafişabile. Caracterele afişabile sunt
literele (mari şi mici) ale alfabetului englez, cifrele, o serie de caractere speciale (+,*,/ etc.),
spaţiul, o serie de semne grafice (≈, ±, ╣,≤, ≥), o serie de caractere greceşti (α,ß,π etc.) etc.
Caracterele neafişabile se utilizează, de regulă, pentru controlul transmisiei şi imprimării (Line
Feed, Carriage Return, Form Feed, Bell, Tab etc.). Când aceste caractere sunt folosite în alt
context decât cel de control, li se pot asocia simboluri grafice nestandardizate, cum ar fi: ☺,☻,
♂, ♀, ♠, ♣, ♪, ♫.
Datele numerice se reprezintă intern în virgulă fixă şi virgulă mobilă. UCP are
dispozitiv fizic specializat în efectuarea operaţiilor în virgulă fixă. Calculul în virgulă mobilă
poate fi realizat când microcalculatorul are coprocesor matematic 80x87 sau când limbajele de
programare dispun de biblioteci specializate pentru emularea software a operaţiilor în această
aritmetică.
Datele logice se reprezintă intern în virgulă fixă pe un octet, prin convenţie asociindu-
se 1 pentru valoarea adevărat şi 0 pentru fals.
Se face, de asemenea, menţiunea că unele limbaje de programare lucrează şi cu un alt tip
de reprezentare internă a datelor numerice, numită reprezentare zecimală.

Reprezentarea în virgulă fixă
Reprezentarea în virgulă fixă se aplică numai numerelor întregi şi se realizează pe zone de
memorie standard (un cuvânt sau două cuvinte) sau pe octeţi. Ea poate fi algebrică sau aritmetică.
Macheta de reprezentare pe un cuvânt este prezentată în figura 2.1, unde:


s M
15
0
14
1 2
a) Virgulă fixă algebrică
N
15
0
14
1 2
b) Virgulă fixă aritmetică

Fig. 2.1. Reprezentarea în virgulă fixă

s este bitul de semn (s-a adoptat convenţia ca semnul "+" să fie reprezentat prin valoarea
binară 0 iar semnul "–" prin valoarea binară 1);
M este o valoare exprimată în binar, în cod direct pentru numere pozitive şi în cod
Bazele programării 22


complementar, pentru numere negative.
N este reprezentat în cod direct. Reprezentarea aritmetică se aplică numai numerelor
pozitive, bitul de semn fiind folosit ca bit de cifră.
Codul complementar se obţine astfel:
- se reprezintă valoarea absolută a numărului în binar (cod direct). Fie aceasta N
2
;
- se realizează complementul faţă de unu (cod invers) al lui N
2
. Complementul faţă de unu
se obţine prin inversarea fiecărui bit (0 în 1 şi 1 în 0), inclusiv a bitului de semn. Fie numărul
obţinut N
2
*
;
- se adună un unu la numărul reprezentat în cod invers (N
2
*
) şi astfel se obţine
complementul faţă de doi al lui N
2
.
Exemple:

Numărul –24 se reprezintă astfel:
Se exprimă 24 în cod direct:

0 0 ... ... 0 0 1 1 0 0 0
15 14 6 5 4 3 2 1 0

Se realizează complementul faţă de unu:

1 1 ... ... 1 1 0 0 1 1 1
15 14 6 5 4 3 2 1 0
sau, exprimat în octal: 177747

Se adună unu la numărul reprezentat în complement faţă de unu:

1 1 ... ... 1 1 0 1 0 0 0
15 14 6 5 4 3 2 1 0
sau, exprimat în octal: 177750.
Pentru determinarea complementului faţă de doi se poate proceda, astfel: din biţii
numărului exprimat în cod direct se formează două grupe: grupa din dreapta cuprinde toate
zerourile din dreapta ultimului bit cu valoarea 1 precum şi ultimul bit 1; grupa din stânga
cuprinde biţii rămaşi; se complementează faţă de 1 grupa din stânga, lăsându-se nemodificată
grupa din dreapta.
Exemple:
Pentru simplificare se consideră un cuvânt format din patru biţi:

Complementul faţă de 2 pentru 0110:

01 10 - număr pozitiv (+6)
stânga dreapta
Rezultat: 10 10 - număr negativ (– 6)

Complementul faţă de 2 pentru 1101:

110 1 - număr negativ (–3)
stânga dreapta
Rezultat: 001 1 - număr pozitiv (+3)

Considerându-se o zonă de memorie de n biţi, valoarea care poate fi reprezentată algebric
aparţine mulţimii [–2
n–1
, 2
n–1
–1] iar valoarea care poate fi reprezentată aritmetic aparţine mulţimii
[0, 2
n
–1].
Bazele programării 23



Reprezentarea în virgulă mobilă
Există mai multe tipuri de reprezentare virgulă mobilă. Dintre acestea, cel mai frecvent
utilizat este standardul internaţional IEEE (Institute for Electrical and Electronics Engineers).
Conform acestui standard, datele se memorează pe 32 de biţi (simplă precizie) sau pe 64 de biţi
(dublă precizie), după machetele prezentate în figura 2.2.

semn caracteristică fracţie
1 bit 8 (11) biţi 23 (52) biţi

Fig. 2.2. Reprezentarea virgulă mobilă simplă (dublă) precizie

Ambele machete presupun că numărul de reprezentat are următoarea exprimare binară
sub formă ştiinţifică: m=(–1)
s
· 1,fracţie · 2
exponent
, unde s este valoarea bitului de semn (1 pentru
mantisă negativă şi 0 pentru mantisă pozitivă) iar fracţie este partea fracţionară a mantisei.
Mantisa este normalizată şi are întotdeauna forma 1,fracţie, ceea ce înseamnă că ea are
valori în intervalul [1,2). Pentru ca mantisa să fie adusă la această formă se modifică în mod
corespunzător exponentul numărului m. De exemplu, fie m=101,0111. Scrierea lui m normalizat
este m=1,010111*2
2
. Deoarece partea întreagă a mantisei este întotdeauna 1, aceasta nu se
reprezintă intern. Fracţia se reprezintă intern sub forma semn-mărime (nu în cod complementar).
Pentru a nu se utiliza doi biţi de semn (unul pentru mantisă şi altul pentru exponent),
convenţia IEEE a introdus în şablon înlocuirea exponentului cu o caracteristică. Aceasta este o
valoare în exces faţă de 127 pentru simplă precizie (exponent+127) sau 1023 pentru dublă
precizie (exponent+1023):
Exemplu:
Să se reprezinte în simplă precizie numărul –75,375.
–75,375 = –1001011,011
(2)
= –1,001011011*2
6

s = 1
mantisa = 1,001011011
(2)

fracţia = 001011011
(2)

caracteristica = 6 + 127 = 133 = 10000101
(2)

Reprezentarea internă: 1 10000101 00101101100000000000000

Caracteristica are următoarele valori normale:
0 < caracteristică < 255 ► pentru simplă precizie
0 < caracteristică < 2047 ► pentru dublă precizie.
Când caracteristica are valoarea zero, numărul reprezentat intern (m) este zero. Când
caracteristica este 255 (respectiv 2047) se consideră depăşire virgulă mobilă. Caracteristicile
reprezentărilor interne virgulă mobilă simplă şi dublă precizie sunt prezentate în tabelul 2.1.

Tabelul 2.1. Caracteristicile datelor reprezentate virgulă mobilă

Tip reprezentare
Caracteristici
Simplă precizie Dublă precizie
Număr biţi pentru
reprezentare
caracteristică
8 11
Număr biţi pentru 23 52
Bazele programării 24


Tip reprezentare
Caracteristici
Simplă precizie Dublă precizie
reprezentare fracţie
Valoarea minimă
caracteristică
1 1
Valoarea maximă
caracteristică
254 2047
Eroare maximă fracţie 2
-24
≈ 10
-7
2
-24
≈ 10
-7

Cel mai mic număr
pozitiv
2
1-127
≈ 10
-38
2
1-1023
≈ 10
-307

Cel mai mare număr
pozitiv
2·2
254-127
≈ 10
38
2·2
2047-1023
≈ 10
307

Domeniu de
reprezentare
[–10
38
, 10
38
] [–10
307
, 10
307
]


Prelucrarea datelor şi instrucţiunilor de către unitatea centrală
Pentru înţelegerea modului în care datele şi instrucţiunile sunt prelucrate de unitatea
centrală, se consideră că memoria conţine, din punctul de vedere al programatorului, date (D) şi
instrucţiuni (I), în succesiunea de cuvinte ilustrată în figura 2.3.


D1 D2 D3 I1 I2 D4 D5 I3 D6 I4

Adresa de start
4700 4702 4704 4706 4710 4712 4714 4716 4720 4722 4726 Adrese:

Fig. 2.3. Model de memorie

Aşa după cum s-a arătat, instrucţiunile sunt prelucrate de UCC. Încărcarea instrucţiunilor
în UCC se realizează automat. Pentru a lansa un program în execuţie, UCC trebuie să "cunoască"
adresa primei instrucţiuni de executat (adresa de start). Acesta este motivul pentru care în unele
limbaje de programare este obligatorie etichetarea primei instrucţiuni executabile. În exemplul
din figura 1.9. se presupune că adresa de start a programului este 4706
8
. Această adresă este
încărcată în contorul de adrese (un registru special numit program counter - PC).
În UCC este încărcată întotdeauna instrucţiunea aflată la adresa precizată de PC. Registrul
PC este incrementat automat, fiind astfel pregătit să adreseze următoarea instrucţiune. Deci, după
ce se execută instrucţiunea I
1
, conţinutul lui PC devine 4710
8
. Se încarcă în UCC instrucţiunea I
2
.
După execuţia acesteia, PC va conţine adresa 4712
8
. Deşi la această adresă este memorată o dată,
ea este încărcată în UCC şi, prin urmare, este tratată ca instrucţiune. Se pot ivi următoarele
situaţii:
- conţinutul lui D
4
, printr-o întâmplare, coincide cu o instrucţiune a unităţii centrale, caz în
care este executată ca atare şi conţinutul lui PC este autoincrementat;
- conţinutul lui D
4
nu coincide cu nici o instrucţiune acceptată de unitatea centrală, caz în
care programul este abandonat (terminare anormală).
Prin acest exemplu s-a arătat cum data este tratată de calculator ca instrucţiune. Deci, prin
actualizarea contorului de adrese după execuţia fiecărei instrucţiuni, se asigură înlănţuirea
normală a instrucţiunilor din program (derularea programului în secvenţă). Cum se poate proceda
Bazele programării 25


atunci când nu se face parcurgerea în secvenţă şi este nevoie să se sară peste câteva cuvinte de
memorie pentru a ajunge la instrucţiunea dorită? Programatorul are la dispoziţie instrucţiunile de
salt, prin folosirea cărora se asigură întreruperea secvenţei normale de program, prin încărcarea
forţată în PC a adresei la care se găseşte instrucţiunea de executat.
Se presupune că instrucţiunea I
2
este: SALT LA 4716
8
. După ce se execută instrucţiunea
I
1
, contorul de locaţii devine 4710
8
. Se execută, în secvenţă, instrucţiunea I
2
care pune contorul
de adrese pe valoarea 4716
8
(fiind o instrucţiune de salt).
Prin urmare, în UCC se încarcă instrucţiunea I
3
ş.a.m.d. În exemplul anterior s-a
considerat că toate instrucţiunile au lungimea de un cuvânt. În secvenţa logică a programului,
ultima instrucţiune trebuie să fie de tip STOP.
După extragerea instrucţiunii din memorie (prima etapă în prelucrarea unei instrucţiuni)
se execută următoarele etape: calculul adresei operandului; efectuarea operaţiei propriu-zise,
precizată de instrucţiune.
În cadrul fiecărei etape se execută un anumit număr de faze. Indiferent de modul de
realizare a fazelor (prin macroinstrucţiuni sau prin funcţiuni cablate), principial, modul de
prelucrare a unei instrucţiuni este asemănător. Se consideră că în UCC se găseşte instrucţiune I
3
:
ADUNA (4704) cu (4712) care adună conţinutul de la adresa 4704
8
cu conţinutul de la adresa
4712
8
iar rezultatul se depune la adresa celui de-al doilea operand. Pentru a înţelege modul cum
se execută această instrucţiune se presupune că UAL este formată din două registre (sumatoare),
în care se realizează calcule. Instrucţiunea I
3
poate fi descompusă în următorii paşi (figura 2.4.):
- preia conţinutul operandului sursă de la adresa 4704
8
(D
3
) într-un sumator;
- preia conţinutul operandului destinaţie de la adresa 4712
8
(D
4
) în al doilea sumator;
- efectuează calculul între cele două sumatoare, cu rezultatul în S1;
- depune conţinutul sumatorului S1 în memorie la adresa 4712
8
.
În mod similar se pot interpreta şi alte operaţii de calcul. Toate operaţiile realizate asupra
datelor se efectuează în unitatea aritmetico-logică. Această afirmaţie este valabilă şi în cazul
uneia din cele mai simple operaţii: MUTA (4714
8
) IN (4700
8)
, care se descompune astfel:
- preia operandul sursă de la adresa 4714
8
(D5) în sumatorul S1;
- depune conţinutul sumatorului S1 în memorie la adresa 4700
8
(D1 se pierde, depunându-
se peste el D5).
Ce se va întâmpla în cazul instrucţiunii ADUNA (4700
8
) cu (4710
8
)? Răspuns: conţinutul
de la adresa 4710
8
(I
2
) este tratat ca dată.



D1 D2 D3 I1 I2 D4 D5 I3 D6 I4
4700 4702 4704 4706 4710 4712 4714 4716 4720 4722 4726
UAL UCC
adună (4704) cu (4712)
4716 PC

(I3)
+
S2
S1


Fig. 2.4. Prelucrarea unei instrucţiuni

Prin acest exemplu s-a văzut cum instrucţiunea este tratată ca dată şi, mai mult, cum un
program îşi poate modifica instrucţiunile proprii. Nu toate limbajele de programare oferă
posibilitatea intercalării în memorie a datelor şi instrucţiunilor. De fapt, această intercalare nici nu
Bazele programării 26


este recomandată, având în vedere gestionarea greoaie a tipurilor de informaţii: date şi
instrucţiuni.
Instrucţiunile pot adresa operanzii direct sau indirect. La adresarea indirectă (figura 2.5),
instrucţiunea memorează adresa unei zone care stochează adresa operandului.

Adresă Adresă operand Operand
Instrucţiune Pointer

Fig. 2.5. Adresarea indirectă

Se spune că zona de memorie care stochează adresa operandului este de tip pointer. Toate
limbajele de programare acceptă adresarea directă a operanzilor. Unele dintre ele acceptă lucrul
cu pointeri (adresare indirectă). În acest caz, programatorul trebuie ca, înainte de adresare, să
încarce în zona de tip pointer adresa operandului.

Operaţii de intrare/ieşire
Operaţiile de intrare/ieşire realizează citirea - introducerea datelor în memorie - şi
scrierea - extragerea datelor din memorie. Deoarece datele pot fi prelucrate doar dacă se găsesc
în memoria internă, apare ca necesară operaţia de citire prin care se transferă datele furnizate de
utilizator. Cum toate operaţiile îşi depun rezultatul în memoria internă, punerea lor la dispoziţia
utilizatorilor necesită operaţia de scriere. Elementele care definesc o instrucţiune de I/E sunt:
- de unde (unde) sunt introduse/extrase datele;
- care este structura externă a datelor (formatul extern);
- care este adresa memoriei în/din care se introduc/extrag datele.
Reprezentarea numerelor pe suporturile externe la care are acces în mod direct operatorul
uman trebuie să fie ASCII. Modul de realizare a corespondenţei dintre un număr reprezentat
ASCII pe un suport extern şi acelaşi număr reprezentat intern virgulă fixă sau virgulă mobilă este
prezentat schematic în figura 2.6.
Fie a∈A⊆ℜ. Aplicaţia f este o codificare bijectivă a mulţimii A într-o mulţime de coduri
reprezentabile pe un suport intern (de exemplu, o codificare în virgulă fixă sau în virgulă mobilă).
Fiecare număr din A se reprezintă pe un suport extern sub forma unui şir de caractere (caracterele
aparţin unei mulţimi K). Imaginea pe suportul extern a unui număr a∈A nu este, în general, unică
(de exemplu a=13,9 poate fi reprezentat în mai multe feluri: +13.9; 139; +139 etc.). Se notează cu
I
a
mulţimea imaginilor pe suportul extern de intrare pentru elementul a∈A. În figura 1.11 s-a
presupus că imaginea numărului a∈A pe suportul extern de intrare este şirul de caractere a
1
, a
2
, ...
, a
n
.
Aplicaţia α este o codificare standard a mulţimii K de caractere (ASCII). Şirul c
1
,c
2
...c
n

rezultă din şirul a
1
, a
2
,...a
n
prin aplicarea funcţiei α fiecărui caracter a
i
, i=1,2,...n. Se notează cu C
a

mulţimea şirurilor de coduri care se obţine din elementele lui I
a
prin aplicarea funcţiei α, în modul
descris anterior.
Bazele programării 27



a
1
a
2
... a
n


a
1
* a
2
* ... a
n
*
c
1
c
2
c
n

f(a)
c
1
* c
2
* c
n
*
a
a*
f
f
-1
α
α α
ψ
ψ
*
α
-1
α
-2
α
-3
Suport extern
de intrare
Suport extern
de ieşire
Suport intern


Fig. 2.6. Corespondenţa între reprezentarea externă şi internă a datelor

Pentru orice a∈A se defineşte funcţia ψ :{C
a
| a∈A } → {f(a) | a∈A} dată de ψ(C
a
)=f(a).
Alegerea funcţiei ψ depinde de f şi de mulţimea {I
a
| a∈A }. Se observă, deci, că funcţia f se
realizează în calculator prin intermediul funcţiilor α şi ψ. Aceste funcţii sunt realizate pe baza
unor instrucţiuni precizate de programator. Analog se poate analiza funcţia de decodificare (f
-1
).

Teste de autoevaluare



2.2. Structuri de date

În afara datelor scalare, în aplicaţiile practice se utilizează colecţii de date. Între elementele
unei colecţii de date pot fi identificate sau, eventual, pot fi introduse relaţii care să determine pe
mulţimea respectivă o anumită structură, adică un mod de ordonare, astfel încât să se faciliteze
prelucrarea. O colecţie de date pe care s-a definit un mecanism de selectare a elementelor
(componentelor), constituie o structură de date. Ea este o entitate de sine stătătoare,
individualizabilă prin nume, ale cărei componente îşi menţin proprietăţile (tipul). Selectarea
componentelor unei structuri se poate realiza folosind identificatorii asociaţi acestora (accesul prin
nume) sau prin poziţia pe care o ocupa în structură, în conformitate cu ordinea specificată.
După modul de selectare a componentelor, se disting: structuri cu acces direct, la care o
componentă poate fi selectată fără a ţine seama de celelalte componente; structuri cu acces
1. O dată reprezentată VF algebrică pe 2o are valoarea maximă: a) 2
16
; b) 2
16
-1; c) 2
15
-1;
d) 2
15
; e) 2
16
+1.
2. Numărul în zecimal a cărui reprezentare internă în VF algebrică este 10001111 este:
a) 143; b) –15; c) –143; d) –113; e) 113.
3. Operaţia de scriere desemnează: a) afişarea datelor pe monitor; b) scrierea datelor
pe suporţi magnetici; c) transferul datelor între zone de memorie principală; d)
transferul datelor din memoria principală pe suporţi externi; e) transferul
datelor în buffer.


Bazele programării 28


secvenţial, la care localizarea unei componente se face printr-un proces de parcurgere a mai multor
componente, conform cu ordinea acestora (traversare).
După tipul componentelor, structurile de date pot fi împărţite în omogene, când
componentele sunt de acelaşi tip şi neomogene, când componentele sunt de tipuri diferite.
Componentele unei structuri de date pot să fie date elementare (scalare) sau să fie ele
însele structuri de date. Dacă o structură de date se compune din (sau se poate descompune în)
structuri de acelaşi tip, se spune că structura respectivă de date este recursivă.
Structurile de date se pot regăsi în memoria internă (structuri interne) sau pe un purtător
extern (bandă magnetică, disc magnetic, dischetă etc.), caz în care se numesc structuri externe
(fişiere).
Dacă în reprezentarea structurii de date pe suportul de memorie se înregistrează,
împreună cu componentele acesteia, şi date care materializează relaţiile de ordonare, se spune că
aceasta este o structură explicită (altfel, este implicită), iar datele suplimentare, de obicei adrese, se
numesc referinţe sau pointeri. Necesitatea acestor date suplimentare apare în cazul reprezentării
dispersate a structurilor de date, în care componentele nu ocupă zone adiacente pe suportul de
memorare. Reprezentarea componentelor în zone adiacente corespunde structurilor dense. Toate
structurile de date care au aceeaşi organizare şi sunt supuse aceloraşi operaţii formează un anumit
tip de structură de date, extinzând noţiunea de tip de dată şi asupra mulţimilor ordonate de date.
În funcţie de modul de alocare a zonelor de memorie se disting date de tip static sau
dinamic. Pentru datele de tip static sunt alocate zone de memorie bine definite, în momentul
compilării. Pentru datele de tip dinamic, zonele de memorie sunt alocate în momentul execuţiei, în
funcţie de necesităţi, fiind posibilă chiar eliberarea memoriei ocupate de unele date. Tipul dinamic
corespunde tipului referinţă (pointer).

Structuri statice de date
Pe lângă datele elementare (scalare), fie ele constante sau variabile, frecvent este necesară
introducerea în memoria internă a unor colecţii de date între elementele cărora există anumite
relaţii. Practica programării a impus, ca structuri de date frecvent utilizate, masivul (tabloul) şi
articolul. Aceste structuri îşi dovedesc utilitatea în aproape toate aplicaţiile practice, ceea ce explică
implementarea lor - cu unele diferenţe şi particularităţi - în majoritatea limbajelor de programare.

Masivul este o structură de date omogenă, cu una, două sau mai multe dimensiuni.
Pentru masivele uni, bi şi tridimensionale se utilizează denumirile de vector, matrice, respectiv
plane de matrice. Structura este cu acces direct, referirea unui element fiind realizată printr-o
construcţie sintactică numită variabilă indexată, formată din numele masivului şi un număr de
expresii indiciale (indici) corespunzând dimensiunilor acestuia.
Diversele limbaje de programare implementează structura de masiv în modalităţi diferite.
Limbajul C, care face obiectul acestei lucrări, le implementează necontiguu, bazându-se pe
adresarea prin pointeri.

Articolul este o structură de date eterogenă, de tip arborescent (figura 2.2.).
Componentele structurii arborescente, numite câmpuri, sunt individualizate prin nume. Relaţia de
ordine ierarhică dintre câmpuri se precizează fie prin numere de nivel, fie prin incluziuni de articole
în articole.
Articolul este o structură cu acces direct, adică fiecare câmp (elementar sau grupat) poate fi
referit direct prin numele său, fără a face referiri la celelalte elemente din structura înregistrării.
Articolul este o structură recursivă, deoarece datele de grup din interiorul ei corespunzând unor
Bazele programării 29


subarbori, conservă aceleaşi proprietăţi ca şi structura în ansamblul său. Una din principalele
utilizări ale acestei structuri de date apare în legătură cu fişierele.
Elementele din structura înregistrării sunt:
• câmpuri elementare corespunzând nodurilor terminale de pe fiecare ramură a arborelui (în
exemplul din figura 2.7: MARCA, NUME, ZI, LUNA, AN, OCUPATIE, SECTIE, ATELIER,
ECHIPA);
• câmpuri grupate (date de grup), corespunzând nodurilor neterminale (DATA–
INCADRARII, LOC–MUNCA) şi, în ultimă instanţă, chiar rădăcinii (PERSOANA).

PERSOANA
MARCA NUME DATA ÎNCADR. OCUPAŢIE LOC DE MUNCA
ZI LUNA AN SECTIE ATELIER ECHIPA
………………………………….…1
NIVEL
.…2
….3

Fig.2.7. Exemplu de articol

Descrierea unei structuri de tip articol se face prin parcurgerea arborelui în preordine, astfel:
se parcurge arborele de sus în jos şi de la stânga la dreapta, cu condiţia descrierii complete a
fiecărui subarbore.

Structurile dinamice de date
Pentru anumite clase de probleme structurile statice de date nu numai că nu sunt suficiente dar se
dovedesc chiar imposibil de folosit datorită limitărilor la care sunt supuse. În primul rând, spaţiul de
memorie aferent unor astfel de date se defineşte şi se rezervă în momentul compilării programului (rezervare
statică), la o dimensiune maximă (cuprinzătoare). Spaţiul nu poate fi disponibilizat şi nici împărţit cu alte
date, chiar dacă nu este în întregime utilizat în anumite momente ale execuţiei programului. În al doilea rând,
componentele structurilor statice ocupă locuri prestabilite în spaţiul rezervat, determinate de relaţia de
ordonare specifică fiecărei structuri. În al treilea rând, limbajele de programare definesc operaţiile admise cu
valorile componentelor, potrivit tipului de bază al structurii, astfel încât numărul maxim şi ordinea
componentelor structurii nu pot fi modificate.

2.4.1. Grafuri
Un graf (sau un graf neorientat) este o structură G = (V,E), unde V este o mulţime nevidă
iar E este o submulţime (posibil vidă) a mulţimii perechilor neordonate cu componente distincte
din V. Obiectele mulţimii V se numesc vârfuri, iar obiectele mulţimii E se numesc muchii. Dacă
e=(u,v)∈E se spune că muchia e are ca extremităţi u şi v (este determinată de vârfurile u şi v).
Graful G=(V,E) este finit dacă V este o mulţime finită. În continuare vor fi considerate în
exclusivitate grafurile finite, chiar dacă acest lucru nu va fi precizat în mod explicit.
Fie grafurile G
i
=(V
i
,E
i
), i=1,2. G
2
este un subgraf al grafului G
1
dacă
1 2
V V ⊆ şi
1 2
E E ⊆ . Dacă G
2
este un subgraf al lui G
1
, G
2
este un graf parţial al lui G
1
dacă V
2
=V
1
.
Un graf orientat (digraf) este o structură D=(V,E), unde V este o mulţime nevidă de
obiecte numite convenţional vârfuri, iar E este o mulţime (posibil vidă) de perechi ordonate cu
componente elemente distincte din V. Convenţional, elementele mulţimii E sunt numite arce sau
muchii ordonate. Terminologia utilizată relativ la digrafuri este similară celei corespunzătoare
grafurilor.
Bazele programării 30


Se numeşte graf ponderat o structură (V,E,W), unde G=(V,E) este un graf, iar W o
funcţie, ( ) ∞ → , 0 E : W . Funcţia W este numită pondere şi asociază fiecărei muchii a grafului un
cost/câştig al parcurgerii ei.
Fie G=(V,E) un graf, u,v∈V. Secvenţa de vârfuri Γ: u
0
, u
1
,..,u
n
este un u-v drum dacă
u
0
=u, u
n
=v, u
i
u
i+1
∈E pentru i∈[0,n]. Lungimea drumului, notată l(Γ) este egală cu n.
Convenţional, se numeşte drum trivial, un drum Γ cu l(Γ)=0.
Cea mai simplă reprezentare a unui graf este cea intuitivă, grafică: fiecare vârf este figurat
printr-un punct, respectiv muchiile sunt reprezentate prin segmente de dreaptă orientate (în cazul
digrafurilor) sau nu şi etichetate (în cazul grafurilor ponderate) sau nu, având ca extremităţi
punctele corespunzătoare vârfurilor care le determină.
Exemple:

1. Fie G = (V, E) un graf cu V = {1, 2,
3, 4, 5}, E = {(1,2),(1,3),(2,5),(3,5)}.
O posibilă reprezentare grafică este:


5 3
2
1
4


Deşi acest mod de reprezentare este foarte comod şi sugestiv în special în cazul grafurilor
cu număr mic de vârfuri, pentru prelucrări cu ajutorul calculatorului sunt necesare reprezentări
prin intermediul structurilor de date.
O modalitate de reprezentare este cea prin matrice de adiacenţă. Dacă G=(V,E) este un
graf (sau digraf) cu n V = , atunci matricea de adiacenţă A∈M
nxn
({0,1}) are componentele
¹
´
¦ ∈
=
altfel 0,
E v , v dacă 1,
a
j i
ij
) (
, unde v
i
, v
j
reprezintă cel de-al i-lea, respectiv cel de-al j-lea nod din V.
Se observă că în cazul unui graf neorientat matricea de adiacenţă este simetrică –
ji ij
a a , n 1, j i, ) ( = = ∀ (perechile de vârfuri care caracterizează muchiile sunt neordonate, deci dacă
uv∈E, atunci şi vu∈E), în timp ce, în cazul unui digraf, este posibil ca , ) , ( E v v
j i
∈ E v v
i j
∉ ) , ( ,
deci a
ij
≠ a
ji
.

În cazul grafurilor ponderate, reprezentarea matriceală este asemănătoare celei prezentate
anterior. Matricea ponderilor unui graf ponderat G=(V,E,W), n V = , W∈M
nxn
((0, ∞)) are
componentele:
¹
´
¦ ∈
=
altfel α,
E ) v , (v dacă ), v , W(v
w
j i j i
j i,
,
unde v
i
, v
j
reprezintă cel de-al i-lea, respectiv cel de-al j-lea nod din V, α =0 dacă ponderea are
semnificaţia de câştig, respectiv ∞ = α dacă are semnificaţia de pierdere, în cazul în care se
doreşte reprezentarea costurilor ca ponderi ale grafului.
Una dintre cele mai importante proprietăţi ale grafurilor o constituie posibilitatea de
accesare, prin intermediul unei secvenţe de muchii (arce), a oricărui vârf al grafului plecând
dintr-un vârf dat, proprietate cunoscută sub numele de conexitate sau conexiune.
Fie Γ: u
0
, u
1
,..,u
n
un drum în graful G=(V,E). Γ este un drum închis dacă u
0
=u
n
. În caz
contrar, Γ se numeşte drum deschis. Drumul Γ este elementar dacă oricare două vârfuri din Γ
Bazele programării 31


sunt distincte, cu excepţia, eventual, a extremităţilor. Drumul Γ este proces dacă, pentru orice
1 n j i 0 − ≤ ≠ ≤ , u
i
u
i+1
≠ u
j
u
j+1
. Orice drum elementar este un proces.
Exemplu:
3. Pentru graful G, Γ
1
: v
1
, v
2
, v
3
, v
2
,
v
5
, v
3
, v
4
este un v
1
-v
4
drum care nu
este proces; Γ
2
: v
1
, v
2
, v
5
, v
1
, v
3
, v
4
este un v
1
-v
4
proces care nu este
drum elementar; Γ
3
: v
1
, v
3
, v
4
este un
v
1
-v
4
drum elementar.

v1
v2
v3
v4 v5
G:


Fie Γ: u
0
,u
1
,..,u
n
un drum în graful G=(V,E). Γ

: v
0
,v
1
,..,v
m
este un subdrum al lui Γ dacă
Γ

este un drum şi pentru orice j, m j 0 ≤ ≤ , există i, n i 0 ≤ ≤ astfel încât u
i
=v
j
. Orice drum cu
lungime cel puţin 1 conţine cel puţin un drum elementar cu aceleaşi extremităţi. Într-adevăr, dacă
Γ: u
0
,u
1
,..,u
n
nu este elementar, atunci există n j i 0 ≤ < ≤ şi i ≠ 0 sau j ≠ n astfel încât u
i
=u
j
.
Atunci drumul
¦
¹
¦
´
¦
≠ ≠
=
=
Γ
+
+
n j , 0 i dacă , u ... u u ... u u
0 j dacă , u ... u u
0 i dacă , u ... u u
:
n 1 j i 1 0
i 1 0
n 1 j j
'
este de asemenea un u
0
-u
n
drum.
Aplicând în continuare eliminarea duplicatelor vârfurilor în modul descris, rezultă în final un u
0
-
u
n
drum elementar.
Exemplu:
4. În graful

v1
v2
v3
v4
v5
v6 v7
v8
v9
v10


dacă Γ: v
1
, v
2
, v
4
, v
5
, v
3
, v
1
, v
2,
v
5
, v
6
, v
7
, v
8
, v
9,
v
5
, v
9
, v
8
, v
10
, atunci Γ
1
: v
1
, v
2
, v
5
, v
9
, v
8
, v
10
, Γ
2
: v
1
, v
2
, v
4
,
v
5
, v
9
, v
8
, v
10
sunt v
1
-v
10
subdrumuri elementare.

Fie G=(V,E) un graf, n V = . Dacă A este matricea de adiacenţă asociată grafului atunci,
pentru orice p≥1,
) p (
ij
a este numărul v
i
-v
j
drumurilor distincte de lungime p din graful G, unde
) (
) ( p
ij
p
a A = .
Fie M
n
({0,1)} mulţimea matricelor de dimensiuni nxn, componentele fiind elemente din
mulţimea {0,1}. Pe M
n
({0,1)}se definesc operaţiile binare, notate ⊕ şi ⊗, astfel: pentru orice
A=(a
ij
), B=(b
ij
) din M
n
({0,1)}, A⊕B=(c
ij
), A⊗B=(d
ij
), unde n j , i 1 ≤ ≤ , c
ij
=max{a
ij
, b
ij
} şi
d
ij
=max{min{a
ik
, b
kj
}, n k 1 ≤ ≤ }. Dacă A=(a
ij
) ∈ M
n
({0,1)}, se notează
} 1 ); ( {
) (
≥ = k a A
k
ij
k

secvenţa de matrice definită prin:
( )
2 ) ( , ,
) 1 ( 1
≥ ∀ ⊗ = =

k A A A A A
k k
.
Dacă A este matricea de adiacenţă a unui graf G=(V,E), atunci pentru fiecare k,
1 n k 1 − ≤ ≤ ,
¹
´
¦
=
altfel 0,
j la i la de k lungime de drum există dacă 1,
a
(k)
ij
.
Bazele programării 32


Matricea
) 1 n ( ) 2 ( ) 1 (
A A A M

⊕ ⊕ ⊕ = K se numeşte matricea existenţei drumurilor în graful
G. Semnificaţia componentelor matricei M este:
¹
´
¦ −
= ≤ ≤ ∀
altfel 1,
G în drum v v un există nu dacă 0,
m n, j i, )1 (
j i
ij
.
Exemplu:
5. Pentru graful:

1
2
3
4


|
|
|
|
|
¹
|

\
|
=
|
|
|
|
|
¹
|

\
|
=
|
|
|
|
|
¹
|

\
|
=
|
|
|
|
|
¹
|

\
|
=
1 1 1 1
1 1 1 1
1 1 1 1
1 1 1 1
M ,
1 1 1 1
1 1 1 1
1 1 0 1
1 1 1 1
A ,
1 1 1 1
1 1 1 1
1 1 1 0
1 1 0 1
A ,
0 1 0 1
1 0 0 1
0 0 0 1
1 1 1 0
A
3 2


Calculul matricei existenţei drumurilor permite verificarea dacă un graf dat este conex.
Un graf este conex dacă şi numai dacă toate componentele matricei M sunt egale cu 1.
Fie G=(V,E) un graf netrivial, u,v∈V şi Γ un u-v drum în G. Γ se numeşte proces dacă
toate muchiile drumului Γ sunt distincte. Drumul Γ este trivial dacă Γ : u,u. Drumul Γeste un
circuit dacă Γeste un proces netrivial închis. Circuitul Γ: v
1
,v
2
,….,v
n
,v
1
cu n≥3 este un ciclu al
grafului dacă, pentru orice i, j, cu j i , n j , i 1 ≠ ≤ ≤ , rezultă v
i
≠v
j
. Orice ciclu este un drum
elementar închis. Graful G este aciclic dacă nu există cicluri în G.
Într-un digraf D noţiunile de proces, circuit, ciclu sunt definite ca şi în cazul
grafurilor.
Exemple:
6. În graful

v1
v2
v3
v4
v5 v6

Γ
1
: v
1
, v
2
, v
3
, v
6
, v
5
este un proces;
Γ
2
: v
1
, v
2
, v
3
, v
6
, v
5
, v
3
, v
4
, v
1
este
un circuit şi nu este ciclu;
Γ
3
: v
1
, v
3
, v
5
, v
4
, v
1
este un ciclu.

2.4.2. Arbori
În clasa grafurilor conexe, structurile cele mai simple, dar care apar cel mai frecvent în
aplicaţii sunt cele arborescente. Graful G este arbore dacă G este aciclic şi conex. Fie G=(V,E)
graf arbore. Subgraful H=(V1,E1) al lui G este un subarbore al lui G dacă H este graf arbore.

Exemple:
Graful

1
2
3
4 5
6

este arbore, deoarece pentru orice pereche
de vârfuri i,j, 1 ≤i,j ≤6, i≠j, există un i-j
drum şi graful nu conţine cicluri.

Bazele programării 33


Verificarea proprietăţii unui graf de a fi arbore poate fi efectuată pe baza unor algoritmi
care să verifice calităţile de conexitate şi aciclicitate. Aceeaşi verificare poate fi realizată şi pe
baza proprietăţilor care urmează.
Proprietatea 1: Un graf G=(V,E), cu m E , n V = = este graf arbore dacă şi numai dacă G este
aciclic şi n=m+1. Cu alte cuvinte, problema verificării dacă un graf este arbore revine la
verificarea aciclicităţii grafului şi a relaţiei existente între numărul vârfurilor şi numărul
muchiilor grafului.
Proprietatea 2: Un graf G=(V,E), cu m E , n V = = este graf arbore dacă şi numai dacă G este
conex şi n=m+1.
Notă: Fie G=(V,E) un graf. Următoarele afirmaţii sunt echivalente:
1. G este graf arbore
2. G este graf conex minimal (oricare ar fi e∈E, prin eliminarea muchiei e graful
rezultat nu este conex)
3. G este graf aciclic maximal (prin adăugarea unei noi muchii în graf rezultă cel
puţin un ciclu).
Un graf orientat D=(V,E) cu proprietatea că pentru orice V v u, ∈ dacă uv∈E, atunci
vu∉E se numeşte graf asimetric. Digraful D este simetric dacă V, v u, ) ( ∈ ∀ uv∈E, dacă şi numai
dacă vu∈E.
Fie D=(V,E) digraf netrivial. Graful G=(V,E’), unde E’={uv | uv∈E sau vu∈E} se
numeşte graf suport al digrafului D.
Un arbore orientat este un arbore direcţionat cu rădăcină. Deoarece un arbore orientat este un caz
particular de digraf, pentru reprezentarea lui poate fi utilizată oricare din modalităţile de
reprezentare a grafurilor. În plus există şi posibilitatea obţinerii unor reprezentări mai eficiente
pentru acest tip de graf. Una dintre modalităţi este reprezentarea FIU-FRATE, care constă în
numerotarea convenţională a vârfurilor grafului şi în reţinerea, pentru fiecare vârf i al arborelui, a
următoarelor informaţii:
FIU(i), care reprezintă numărul ataşat primului descendent al vârfului i;
FRATE(i), care reprezintă numărul ataşat vârfului descendent al tatălui vârfului i şi care
urmează imediat lui i;
INF(i), care reprezintă informaţia ataşată vârfului i (de obicei valoarea i).
Pentru reprezentarea arborelui se reţine rădăcina şi numărul nodurilor. Absenţa “fiului”,
respectiv a “fratelui” unui vârf este marcată printr-o valoare diferită de numerele ataşate
vârfurilor (de obicei valoarea 0).
Exemplu:
Următorul arbore orientat este reprezentat astfel:
N=15 (numărul de noduri ale arborelui);
R=1(rădăcina); FIU=(2,5,7,9,0,10,0,0,13,0,0,0,
0,0,0), “fiul” lui 1 este 2, iar vârful 9 are “fiul”
13; FRATE=(0,3,4,0,6,0,8,0,0,11,12,0,14,15, 0),
vârful 1 nu are frate, iar vârful 14 are fratele 15.

15 14 13 12 11 10
9 8 7 6 5
4 3
2
1


O parcurgere revine la aplicarea sistematică a unei reguli de vizitare a vârfurilor grafului.
Cele mai uzuale reguli de parcurgere a arborilor orientaţi sunt prezentate în continuare.
A. Parcurgerea în A-preordine presupune iniţial vârful curent ca fiind rădăcina arborelui. Se
vizitează vârful curent şi sunt identificaţi descendenţii lui. Se aplică aceeaşi regulă de vizitare
pentru arborii având ca rădăcini descendenţii vârfului curent, arborii fiind vizitaţi în ordinea dată
de numerele ataşate vârfurilor rădăcină corespunzătoare.
Bazele programării 34


B. Parcurgerea A-postordine diferă de parcurgerea în A-preordine numai prin faptul că rădăcina
fiecărui arbore este vizitată după ce au fost vizitate toate celelalte vârfuri ale arborelui.
Notă: Parcurgerile în A-preordine şi A-postordine sunt variante de parcurgeri în
adâncime, în cazul ambelor metode fiind prioritare vârfurile aflate la distanţă maximă faţă
de rădăcina arborelui iniţial.
C. Parcurgerea pe niveluri. Un vârf v al unui arbore orientat cu rădăcină r se află pe nivelul i al
arborelui, dacă distanţa de la vârf la rădăcină (lungimea r-v drumului) este egală cu i. Rădăcina
arborelui este de nivel 0. Parcurgerea pe niveluri a unui arbore orientat constă în vizitarea
vârfurilor sale în ordinea crescătoare a distanţelor faţă de rădăcină.

Un arbore binar este un arbore orientat cu proprietatea că orice vârf v are maxim doi
descendenţi (od(v)≤2). În cazul od(v)=2, cei doi descendenţi sunt desemnaţi ca descendent stâng
(fiu stânga), respectiv descendent drept (fiu dreapta). Pentru vârfurile cu od(v)=1, unicul
descendent este specificat fie ca fiu stânga, fie ca fiu dreapta.
Se numeşte nod terminal (frunză) orice vârf v al arborelui cu od(v)=0. Nodul v este
neterminal dacă od(v)>0. Reprezentarea unui arbore binar poate fi realizată prin reţinerea, pentru
fiecare nod, a legăturilor către descendenţii lui, absenţa unui descendent putând fi reprezentată
prin valoarea nulă (nil).

identificator nod legătură fiu stânga
legătură fiu
dreapta

Datorită particularităţii lor, arborii binari oferă posibilitatea aplicării de noi metode de
parcurgere (pe lângă cele aplicabile pentru arborii generali): parcurgerile în preordine (RSD),
inordine (SRD) şi postordine (SDR). Regula de vizitare pentru aceste tipuri de parcurgere
revine la parcurgerea subarborilor stâng şi drept corespunzători vârfului curent, care la
momentul iniţial este chiar rădăcina arborelui. Diferenţa între aceste trei tipuri de parcurgere
este dată de momentul în care devine vizitat fiecare vârf al arborelui. În parcurgerea RSD
(rădăcină-subarbore stâng-subarbore drept), fiecare vârf al arborelui este vizitat în momentul
în care devine vârf curent. În parcurgerea SRD (subarbore stâng-rădăcină-subarbore drept),
vizitarea vârfului este efectuată după ce a fost parcurs subarborele stâng. În parcurgerea SDR
(subarbore stâng-subarbore drept-rădăcină) vizitarea fiecărui vârf este efectuată după ce au
fost parcurşi subarborii aferenţi lui.
Exemplu:
Pentru arborele de la exemplul anterior, secvenţele de vârfuri rezultate prin aplicarea parcurgerilor
RSD, SRD, SDR sunt:
preordine: 1,2,4,7,5,3,6,8,9
inordine: 4,7,2,5,1,8,6,9,3
postordine: 7,4,5,2,8,9,6,3,1.

2.4.3. Liste
Lista este o structură dinamică de date formată din mai multe noduri. Un nod este o
structură de date care conţine două părţi distincte: o parte de informaţie utilă (memorată în nodul
respectiv) şi o parte de informaţie de legătură (folosită pentru a identifica în memorie următorul
nod din listă).
Bazele programării 35


Grafurile pot fi reprezentate prin intermediul listelor, permiţând utilizarea economică a
spaţiului de memorare şi, în anumite cazuri, implementări mai eficiente pentru anumite clase de
algoritmi. Vârfurile grafului se memorează într-o listă, fiecare celulă a listei având o legătură
către lista vecinilor acelui vârf (vârfurile din graf adiacente cu vârful corespunzător acelei celule
şi indicat ca informaţie utilă).
În cele ce urmează se consideră un spaţiu oarecare de memorie adresabilă. Se notează
mulţimea referinţelor din acest spaţiu cu P şi se adăugă la ea o valoare referinţă specială, notată
nil. Se notează cu D mulţimea informaţiilor care vor fi conţinute de nodurile unei liste. În aceste
condiţii, un nod poate fi desemnat prin perechea (d
i
,p
i
) cu d
i
∉D şi p
i
∉P.

O mulţime P}
i
s D,
i
d )
i
s ,
i
{(d
a
L ∈ ∈ = este o listă simplu înlănţuită (sau asimetrică)
dacă pe L
a
s-a definit o structură liniară şi s
1
=nil, iar s
i
(i>1) este referinţă spre succesorul direct
al lui d
i
. Pentru reprezentarea unei liste asimetrice, informaţiile de legătură (pointerii) vor fi
marcate prin săgeată, iar nil prin legătură la pământ (figura 2.8.a).

d
n
d
n-1
d
1
d
2

C

B
… d
1
d
2
d
n-1
d
n

C
b)
a)


Fig. 2.8. Liste simplu (a) şi dublu (b) înlănţuite

O mulţime P} s , p D, d ) s , d , {(p L
i i i i i i s
∈ ∈ = este o listă dublu înlănţuită (sau simetrică)
dacă pe L
s
s-a definit atât o structură liniară directă, cât şi inversa sa şi s
1
=p
n
=nil, iar s
i
, i ≠ 1 şi
p
i
, i ≠ n sunt referinţe spre succesorii direcţi în ordinea specifică (figura 2.3.b).
În cazul listelor dublu înlănţuite, un nod cuprinde două referinţe, fiind posibilă
cunoaşterea atât a predecesorului, cât şi a succesorului imediat. Se remarcă, din definiţie, că
nodurile unei liste pot apărea dispersate în spaţiul de memorare, iar referinţele creează
mecanismul care le leagă. De aici derivă şi atributul de înlănţuită, care o deosebeşte de cazul
particular, denumit listă densă. La o listă densă nodurile sunt dispuse adiacent în spaţiul de
memorare şi informaţiile de legătură, adică referinţele, devin de prisos (ca în cazul vectorilor).
Pentru listele înlănţuite, nodurile pot fi plasate în memoria calculatorului în zone diferite,
informaţia de legătură din fiecare nod asigurând regăsirea nodului următor (pentru liste
asimetrice) respectiv a nodului următor şi succesor (pentru liste simetrice). Pentru a putea lucra
cu aceste liste este nevoie să se cunoască o singură informaţie: adresa primului nod din listă,
numit în continuare capul listei. În acest sens se asociază listei o referinţă C, care conţine fie
adresa acestui nod, fie nil, dacă lista este vidă. Spunem că o listă este complet identificată dacă se
cunoaşte adresa primului nod al său şi structura unui nod.
Asupra unei liste se pot realiza o multitudine de operaţii: traversare, căutare nod,
numărare noduri etc. Sunt însă tipice operaţiile de inserare (adăugare) şi ştergere de noduri,
deoarece dau însuşi caracterul dinamic al acestor structuri. Prin inserări şi ştergeri o listă „creşte”
şi „descreşte” în timp (ca număr de noduri), solicitând spaţiu pentru noile componente şi
Bazele programării 36


eliberând spaţiul ocupat de componentele şterse. Astfel, structura şi numărul de noduri ale listei
suferă o permanentă schimbare.
1. Traversarea. Localizarea unui nod prin traversare este o operaţie de căutare. Scopul este
de a găsi un nod care să conţină în partea de informaţie utilă anumite date. Operaţia de căutare se
poate încheia cu succes, adică cu localizarea unui astfel de nod sau fără succes, în cazul în care
lista este vidă sau nu există un nod care conţine informaţiile cerute.
2. Inserarea. Inserarea unui nod într-o listă înlănţuită se poate realiza cu verificarea
existenţei anterioare a nodului în listă, caz în care nu se mai face inserarea, sau fără nici un fel de
verificare, caz în care se procedează direct la inserare (se permit noduri duplicate). În ambele
cazuri inserarea se poate face în mai multe locuri: la începutul listei, la sfârşitul listei, după sau
înaintea unui anumit nod identificat printr-o cheie.
Inserarea unui nod la începutul listei. Pentru inserarea într-o listă simetrică este necesară
crearea legăturilor între noduri în ambele sensuri. Singura diferenţă faţă de inserarea într-o listă
asimetrică este înscrierea informaţiei despre nodul precedent. Deoarece inserarea are loc la
începutul listei, nu va exista un nod precedent, deci informaţia respectivă va primi valoarea nil.
Primul nod din lista iniţială va avea acum ca precedent nodul nou creat p (figura 2.9). Se observă
că întotdeauna se modifică capul listei, nodul inserat devenind noul cap al listei.


1
1

p

p
a)
b)
cap
cap
2
2
3
4
2


Fig. 2.9. Inserarea la începutul listelor asimetrice (a) şi simetrice (b)

Inserarea unui nod la sfârşitul listei. Pentru adăugarea unui nod la sfârşitul listei se
creează întâi un nod nou cu informaţia utilă care trebuie inserată. Deoarece va fi ultimul nod în
listă, nu există un nod următor deci informaţia de legătură spre nodul următor va avea valoarea
nil.
Dacă lista este vidă atunci capul listei ia ca valoare adresa noului nod creat (va fi singurul
nod din listă). În caz contrar trebuie parcursă lista pentru a ajunge la ultimul nod, informaţia de
legătură din acesta primind ca valoare adresa noului nod creat. În cazul unei liste simetrice
trebuie creată şi legătura în sens invers (figura 2.10).

Bazele programării 37




p

p
a)
b)
cap
cap


Fig. 2.10. Inserarea la sfârşitul listelor asimetrice (a) şi simetrice (b)
Inserarea după un anumit nod al listei. Prima operaţie necesară inserării este localizarea
nodului după care se face inserarea. Acesta poate fi localizat în mai multe feluri: în mod exact,
prin furnizarea unei chei a cărei valoare trebuie să se regăsească în informaţia utilă a nodului
căutat, sau relativ, prin stabilirea unei condiţii care trebuie să fie îndeplinită de nod. În continuare
vom considera cazul căutării după cheie. Dacă nu se găseşte nici un nod care să corespundă
criteriului de căutare (cazul căutării cu eşec) sunt posibile mai multe decizii: nu se inserează noul
nod, se inserează la începutul listei sau se inserează la sfârşitul listei. Inserarea înseamnă
„ruperea” unei legături între două noduri şi crearea unor noi legături astfel ca noul nod să se
interpună în listă între cele două noduri a căror legătură a fost „ruptă”, conform figurii 2.11.



r
q
2 1
a)
r
q
3
1
2 4
b)
p p

Fig. 2.11. Inserare în listă asimetrică (a) şi simetrică (b)

3. Ştergerea. La fel ca şi inserarea, ştergerea se realizează mai eficient şi mai uşor din punct
de vedere algoritmic dacă ea priveşte nodul cap de listă, deoarece se reduce, în principiu, la
actualizarea referinţei de cap. Dacă trebuie şters un nod interior listei, atunci ştergerea propriu-
zisă trebuie precedată de o căutare după conţinutul informaţional al nodurilor. Dacă listele simplu
înlănţuite pot fi traversate într-un singur sens, în momentul în care s-a localizat nodul p de şters
nu se mai cunoaşte precedentul său q care, pentru eliminarea nodului p, trebuie să fie legat de
succesorul acestuia (figura 2.12.a). Datorită acestei situaţii, este necesară introducerea unei
referinţe suplimentare q care, în procesul de traversare, să fie în urma lui p cu un nod. De aceea,
p se numeşte referinţă de urmărire. Iniţial, când p=nil, se atribuie aceeaşi valoare lui q. Se
precede atribuirea de valoare pentru p care schimbă nodul curent, de atribuirea q=p.

Bazele programării 38



a) Liste asimetrice
p
q
1
f
2

q

r

1

p

b) Liste simetrice


Fig. 2.12. Ştergere în liste înlănţuite


2.4.4. Stive şi cozi
Stivele şi cozile sunt liste particulare din punctul de vedere al operaţiilor de ştergere şi
inserare ale nodurilor din listă.
Stiva (stack) este o listă asimetrică (figura 2.13.a) la care operaţiile de inserare, ştergere
şi citire a informaţiilor se fac numai în capul listei (top). Stivele se mai numesc şi liste LIFO
(Last-In-First-Out - ultimul intrat, primul ieşit), având în vedere că orice acces se poate face
numai la ultimul nod inserat. Acesta poate fi citit, şters sau în faţa lui se poate insera un nou nod
care devine cap de stivă. Un astfel de comportament este bine sugerat de modul în care se garează
şi se scot vagoanele într-o linie moartă (închisă) sau de modul în care se pot stivui şi utiliza
scândurile într-un depozit etc. Stiva este o structură frecvent folosită în gestionarea dinamică a
spaţiului de memorie şi reprezintă un mecanism curent în procesul transferului de parametri între
un apelator şi un subprogram etc.
Coada (queue) este o listă asimetrică la care operaţia de inserare se face la un capăt,
denumit spatele cozii, iar ştergerea şi citirea se fac de la celălalt capăt, denumit faţa cozii (figura
2.13.b). Coada este denumită şi listă FIFO (First-In-First-Out - primul intrat, primul ieşit) având
în vedere că numai nodul din faţă poate fi citit sau şters, adică primul nod al listei.
Comportamentul unei astfel de structuri este de fapt un model abstract al cozilor întâlnite în
diferite situaţii: cozi de persoane, cozi de automobile etc.

inserare
citire
ştergere

citire
ştergere
C
d
n
d
n-1
d
1
d
2

a)
stiva
F
d
n
d
n-1
d
1
d
2

b)
coadă
S
FAŢĂ SPATE
inserare


Fig. 2.13. Stivă şi coadă

În timp ce pentru a trata corect o stivă este suficientă o referinţă spre top, pentru coadă
trebuie menţinute două referinţe: una pentru faţa (f) şi alta pentru spatele cozii (s). O coadă este
vidă atunci când f=s=nil.


Bazele programării 39



Teste de autoevaluare



Răspunsuri şi comentarii la testele de autoevaluare

Rezumat
În cadrul acestei unităţi de învăţare au fost studiate următoarele aspecte în ceea ce priveşte datele
şi structurile de date:
cunoştinţe teoretice privind conceptele de informaţie, dată, cunoştinţă;
modalităţi de reprezentare internă a datelor;
structuri statice şi dinamice de date.
După încheierea acestei unităţi de învăţare, studenţii au cunoştinţe şi abilităţi de reprezentare a
datelor şi a structurilor de date.

Bibliografia unităţii de învăţare
1. I. Gh. Roşca, B. Ghilic-Micu, C. Cocianu, M. Stoica, C. Uscatu, M. Mircea, L. Bătăgan, C. Silvestru,
Bazele programării calculatoarelor. Teorie şi aplicaţii în C, Ed. ASE, Bucureşti, 2006, ISBN 973-594-591-
6
2. I. Gh. Roşca, B. Ghilic-Micu, C. Cocianu, M. Stoica, C. Uscatu, Programarea calculatoarelor. Ştiinţa
învăţării unui limbaj de programare, Teorie şi aplicaţii, Ed. ASE, 2003



4. Structura de date se defineşte ca: a) o colecţie de date pe care s-a definit un
mecanism de selectare a componentelor; b) o colecţie de date la care o
componentă este independentă de celelalte; c) o colecţie de date compusă din
subcolecţii de acelaşi tip; d) o colecţie de date compusă din subcolecţii de tipuri
diferite; e) o colecţie recursivă de date.
5. Masivul este o structură: a) recursivă; b) omogenă cu acces secvenţial; c) omogenă
cu acces direct; d) eterogenă cu acces secvenţial; e) eterogenă cu acces direct.
6. Articolul este o structură: a) dinamică; b) omogenă cu acces secvenţial; c) omogenă
cu acces direct; d) eterogenă cu acces secvenţial; e) eterogenă cu acces direct.
7. Stiva este o listă la care: a) inserarea şi ştergerea se fac la capul listei şi citirea se
face la baza listei; b) inserarea, ştergerea şi citirea se fac la capul listei; c)
inserarea, ştergerea şi citirea se fac la baza listei; d) inserarea se face la capul
listei, iar ştergerea şi citirea se fac la baza listei; e) inserarea şi ştergerea se fac la
baza listei şi citirea se face la capul listei.

1:c); 2:d); 3:d); 4:a); 5:c); 6:e); 7:b).

Bazele programării 40


3. Etapele rezolvării problemelor cu calculatorul

Cuprins
Obiectivele unităţii de învăţare 3
3.1. Caracteristici generale ale PPAD
3.2. Fazele dezvoltării programelor
Răspunsuri şi comentarii la testele de autoevaluare
Bibliografia unităţii de învăţare

Obiectivele unităţii de învăţare 3
Dupa studiul acestei unitati de învatare, studenţii vor avea cunoştinţe teoretice şi abilităţi practice
despre:
caracteristici generale ale PPAD;
organizarea procesului de rezolvare a PPAD;
fazele dezvoltării programelor.

Durata medie a unităţii de studiu individual - 2 ore


3.1. Caracteristici generale ale PPAD

„Probleme de prelucrare automată a datelor” (PPAD) este o denumire generică pentru
aplicaţiile practice ale informaticii în economie sau în alte domenii de activitate. Având în vedere
marea diversitate a PPAD, în cele ce urmează se propune o structurare pe clase a acestora şi se
analizează tipurile de soluţii între care se poate alege în procesul de informatizare. Aplicaţiile
informatice acoperă un evantai foarte larg de situaţii, ale cărui extreme pot fi caracterizate astfel:
a) existenţa unui volum relativ redus de date de intrare şi de ieşire, dublată de calcule
laborioase (aplicaţii tehnico-inginereşti, care conduc la soluţii bazate pe aproximări succesive,
exprimate matematic prin ecuaţii algebrice şi transcendente, sisteme de ecuaţii liniare, ecuaţii
diferenţiale, integrale, adică, într-o formulare globală, aplicaţii bazate pe metode de calcul
numeric);
b) existenţa unui volum mare de date de intrare şi de ieşire, asociată uzual cu calcule de
complexitate redusă (evidenţa materialelor, evidenţa personalului şi calculul salariilor, evidenţa
mijloacelor fixe, urmărirea realizării producţiei, a contractelor de aprovizionare/desfacere etc.,
adică, în general, aplicaţii de gestiune economică).
Între aceste extreme există, evident, o diversitate de aplicaţii, dintre care unele presupun
atât volume mari de date, cât şi modele economico-matematice bazate pe calcule laborioase:
gestiunea stocurilor, programarea producţiei, probleme de transport, croire, alocare a resurselor
etc. În contextul prezentului capitol se consideră suficientă şi relevantă doar investigarea
caracteristicilor celor două mari clase de aplicaţii evidenţiate, realizată succint în cele ce urmează.
PPAD din categoria a) permit, în general, soluţii simple de organizare a datelor care,
frecvent, se reduc la preluarea integrală în memoria internă a calculatorului, cu constituirea lor în
Bazele programării 41


structuri de tip masiv (vectori, matrice, plane de matrice etc.). În cazul unor volume mai mari de
date se poate folosi şi memoria externă, văzută ca o prelungire a celei interne, cu organizarea
datelor în fişiere (uzual, fişiere relative). În majoritatea cazurilor, chiar când datele sunt
organizate în fişiere, nu se ajunge la păstrarea lor pe perioade mari de timp, adică nu apare
necesitatea actualizării datelor (adăugări, modificări, ştergeri). Singura problemă în accesul la
datele organizate în fişiere o reprezintă trecerea de la memorarea liniară a elementelor în fişier, la
caracterul lor de elemente ale unor masive (tablouri) cu două sau mai multe dimensiuni.
Pe exemplul matricelor, alegând liniarizarea pe linii (ordinea lexicografică), în cazul unei
matrice A
mxn
, poziţia în fişierul relativ a unui element a
i,j
poate fi determinată printr-un calcul
simplu, folosind funcţia rang r(i,j)=n(i-1)+j, i≤ m, j≤n. Această tehnică se poate folosi la
memorarea datelor în fişier (crearea şi popularea fişierului), permiţând chiar furnizarea
elementelor într-o ordine oarecare, cu condiţia precizării coordonatelor. La regăsirea elementelor
masivului (consultarea fişierului), pornind de la poziţia în fişier, pot fi determinate coordonatele
elementului, astfel:
- dacă r modulo j = 0, atunci i=[r/n] şi j=n;
- dacă r modulo j <> 0, atunci i=[r/n]+1 şi j=r modulo n.
În concluzie, la această clasă de PPAD atenţia principală se deplasează către algoritmul
de calcul, bazat, uzual, pe aproximări succesive, ce pot conduce la apariţia unor tipuri specifice
de erori (erori de trunchiere şi erori de rotunjire), care uneori se compensează, dar frecvent se
cumulează (se propagă) pe parcursul prelucrării, afectând corectitudinea rezultatului final.
Datorită volumelor mari de date, la problemele din categoria b) accentul principal cade
pe organizarea şi întreţinerea colecţiilor de date memorate pe purtători externi. La limită, se poate
alege între două soluţii: organizarea datelor în fişiere (secvenţiale, relative sau indexate) sau
organizarea datelor în baze de date (cu structuri ierarhice, de tip reţea sau relaţionale).
Indiferent de nivelul de organizare ales, tehnologia de prelucrare conduce la lanţuri
(sisteme) de programe, în general de două tipuri: programe de creare şi actualizare (întreţinere) a
colecţiilor de date; programe de consultare (interogare), pentru satisfacerea cererilor de
informare. În algoritmi, principalele tipuri de operaţii sunt cele de prelucrare a colecţiilor de date
organizate pe purtători externi: citire, scriere, rescriere, ştergere, precum şi cele de verificare a
corectitudinii datelor (operaţii de validare). Complexitatea calculelor este redusă, adesea
nedepăşind nivelul celor patru operaţii aritmetice.
În general, în rezolvarea PPAD se poate distinge între următoarele variante de soluţii:
soluţii proprii; utilizarea pachetelor de programe aplicative; soluţii mixte. Alegerea între cele trei
variante depinde de mai mulţi factori, dintre care o importanţă aparte are aria (dimensiunile)
problemei: un domeniu de activitate strict delimitat (aplicaţie informatică), respectiv ansamblul
activităţilor unui organism economico-social (sistem informatic).
În general, soluţiile proprii sunt posibile pentru orice PPAD. Din perspectiva costurilor
implicate de diversele faze ale realizării unei soluţii informatice, această variantă este, frecvent,
cea mai neeconomică. Totuşi, adesea aceasta este singura variantă accesibilă, după cum se poate
constata şi din prezentarea următoarelor cazuri:
- la nivel de aplicaţie informatică, atunci când domeniul de activitate are o serie de
particularităţi care nu permit utilizarea unor eventuale pachete de programe aplicative şi, evident,
când nu există asemenea pachete de programe pentru domeniul respectiv;
- la nivel de sistem informatic, datorită marii diversităţi a organismelor economico-
sociale, atunci când nu se poate pune problema unor soluţii tip, cu posibilitatea ca unele
subsisteme (aplicaţii) să fie realizate prin soluţii mixte.
Utilizarea unor pachete de programe aplicative este posibilă pentru activităţile cu un
anumit grad de generalitate, care se regăsesc în forme identice (sau cu diferenţe nesemnificative)
Bazele programării 42


la mai multe organisme economico-sociale. Printre acestea pot fi menţionate aplicaţiile bazate pe
modele de programare liniară, gestiunea stocurilor, optimizarea transporturilor, optimizarea
croirii, gestiunea financiar-contabilă etc.
Adoptarea unei asemenea soluţii elimină costurile de proiectare şi realizare a aplicaţiilor
(sistemelor) informatice, dar poate conduce la unele necesităţi de adaptare a sistemului
informaţional propriu, în funcţie de datele de intrare şi modul de organizare a acestora, impuse
pachetelor de programe. Pe un plan mai general, în această categorie pot fi incluse şi produse
care, fără a furniza direct soluţii, simplifică substanţial efortul de realizare a lor, pentru domenii
specifice. De exemplu, pentru prelucrări de serii de date statistice, ca şi pentru orice alte date ce
se organizează în tabele, pot fi utilizate produsele din categoria spread-sheet (foaie de calcul),
cum este EXCEL.
Soluţiile mixte presupun încadrarea în soluţii proprii a unor pachete de programe
aplicative, destinate unora dintre aplicaţiile unui sistem informatic. Această variantă reduce, de
asemenea, costurile de realizare, dar necesită elaborarea unor interfeţe între intrările/ieşirile
pachetelor de programe şi celelalte componente ale sistemului(aplicaţiei) pentru care se
elaborează soluţii proprii.
Realizarea sistemelor (aplicaţiilor) informatice este un proces complex, structurat în mai
multe etape, cu obiective specifice. În modul de realizare a acestor etape, în resursele implicate şi
în durata lor totală vor exista o serie de diferenţe, impuse, pe de o parte, de varianta de soluţie
aleasă şi, pe de altă parte, de nivelul de abordare (aplicaţie, sistem informatic). Cu aceste
observaţii, într-o abordare schematică, redusă la enumerarea şi prezentarea obiectivelor
principale, etapele de realizare a sistemelor informatice sunt următoarele:
studiul şi analiza sistemului informaţional actual, care are ca obiectiv principal
formularea cerinţelor şi a restricţiilor pentru sistemul informatic (caietul de sarcini);
proiectarea de ansamblu, care presupune elaborarea modelului de ansamblu al
sistemului informatic şi planificarea realizării sale pe părţi componente (subsisteme, aplicaţii);
proiectarea de detaliu, care are ca obiective elaborarea modelului de detaliu al
sistemului informatic şi stabilirea soluţiilor tehnice de realizare (corespunzător, se face distincţie
între proiectarea logică de detaliu şi proiectarea fizică de detaliu);
elaborarea programelor, în care se realizează, conform priorităţilor stabilite în etapa
anterioară şi pe baza documentaţiilor reunite în proiectul logic de detaliu şi proiectul tehnic de
detaliu, programele incluse în fluxurile tehnologice specifice diverselor tipuri de prelucrări;
implementarea şi exploatarea sistemului, care presupune darea în funcţiune a
sistemului şi utilizarea curentă a acestuia.
Pe baza diferenţierilor evidenţiate, în cele ce urmează se abordează numai cazul unor
aplicaţii informatice de mai mică amploare, pentru care se menţine în continuare denumirea de
PPAD.

Organizarea procesului de rezolvare a PPAD
După complexitatea problemelor abordate în vederea rezolvării cu calculatorul electronic,
din perspectiva programelor ce vor fi elaborate, soluţiile proprii pot conduce la una din
următoarele situaţii: sisteme de programe realizate la nivelul unor aplicaţii informatice, abordate
independent sau ca parte a unor sisteme informatice; unul sau câteva programe, în cazul unor
probleme de amploare redusă.
În primul caz, realizarea programelor este doar una dintre etapele procesului de studiu,
analiză, proiectare şi implementare a sistemelor sau aplicaţiilor informatice. Depinzând de tipul
aplicaţiei, acurateţea şi generalitatea abordării, este posibil ca soluţiile de acest tip să evolueze
către realizarea unor pachete de programe aplicative. În al doilea caz, se ajunge frecvent la
Bazele programării 43


realizarea tuturor etapelor, de la punerea problemei până la rezolvarea ei, de către o singură
persoană. În general, pot fi abordate în această variantă unele probleme tehnico-ştiinţifice, care
nu conduc la cerinţe deosebite privind volumul şi organizarea datelor şi sunt, uzual, probleme
relativ independente.
Există, de asemenea, unele probleme economico-sociale sau administrative în care,
datorită numărului mic de informaţii utilizate, modificărilor reduse, precum şi cerinţelor simple
de prelucrare să nu fie necesare soluţii complexe, bazate pe realizarea unor sisteme de programe.
Etapele de rezolvare a PPAD sunt:
Formularea problemei. În această etapă se precizează rezultatele care trebuie să se
obţină şi forma lor de prezentare, datele de intrare şi modul lor de organizare, precum şi
transformările şi prelucrările care se aplică asupra datelor de intrare pentru a se obţine rezultatele.
Formularea clară, corectă şi completă a problemei reprezintă o cerinţă importantă pentru
finalizarea cu bune rezultate a activităţii de proiectare şi realizare a programelor. În cazul
aplicaţiilor de mai mari dimensiuni, a căror rezolvare se abordează de către o echipă de analiză-
proiectare-programare, formularea problemei poate fi primită de programator de la analistul-
proiectant, sub forma unor specificaţii de problemă.
Formalizarea matematică şi alegerea metodei numerice. În această etapă se exprimă
matematic toate transformările şi prelucrările la care sunt supuse datele de intrare pentru a se
obţine rezultatele, se pun în evidenţă condiţiile iniţiale şi restricţiile referitoare la soluţie. La
alegerea metodei numerice de rezolvare trebuie analizate cu atenţie stabilitatea şi convergenţa
metodei, tipul, mărimea şi propagarea erorilor, precizia rezultatelor. De asemenea, este necesar să
se estimeze necesarul de memorie, timpul de prelucrare, deoarece unele dintre metode nu pot fi
aplicate tocmai datorită solicitării acestor resurse peste limitele admisibile. Se recomandă ca în
etapa formalizării matematice să se stabilească şi ordinea de efectuare a prelucrărilor, să se reţină
informaţiile care sunt necesare următoarei etape (variaţia indicilor, momentul introducerii sau
extragerii datelor, iniţializarea variabilelor şi masivelor etc.). Este necesară precizarea că această
etapă este cu deosebire importantă în cazul problemelor tehnico-inginereşti sau economice bazate
pe folosirea modelelor matematice.
Elaborarea (proiectarea) algoritmilor. Este o etapă complexă care presupune analiza
riguroasă a problemei şi a formalizării ei matematice. Una dintre metodele uzuale de elaborare a
algoritmilor este proiectarea structurată, ale cărei reguli se vor aplica, de asemenea, în faza de
scriere a programelor. Uzual, această etapă se încheie cu reprezentarea algoritmului într-o
anumită formă (schemă logică structurată, pseudocod etc.), simplificând substanţial eforturile
depuse în etapele de scriere, testare şi definitivare a programelor. În acelaşi sens, este foarte
importantă faza testării algoritmilor.
Stabilirea resurselor. Pe baza analizei algoritmilor se precizează, pentru întregul
algoritm şi pe module, echipamentele periferice necesare, în ce limbaj urmează să fie scris fiecare
modul, care sunt seturile de date ce vor fi folosite la testare, se aproximează necesarul de
memorie internă, se stabileşte dacă este necesară segmentarea programului pentru reacoperire etc.
Scrierea programelor. Pe baza algoritmului elaborat se realizează codificarea
modulelor, eventual în paralel dacă se lucrează în echipă. Scrierea programului trebuie să se facă
respectând strict algoritmul (eventual se pot face modificări şi detalieri ale acestuia) urmărindu-
se, în acelaşi timp, optimizarea utilizării resurselor calculatorului (timp unitate centrală, memorie
internă şi echipamente periferice). În cazul programelor interactive este necesară realizarea unor
interfeţe prietenoase, care să lanseze solicitări clare, precise şi complete.
Testarea şi definitivarea programelor. Programul scris într-un limbaj sursă va fi
compilat şi consolidat. În procesul compilării programele sunt testate sintactic, iar în procesul
consolidării (editării de legături) se validează utilizarea resursei memorie, modul în care au fost
Bazele programării 44


apelate, implicit sau explicit, procedurile utilizatorului sau ale sistemului, modul în care au fost
concepute operaţiile de intrare/ieşire sau, în general, cum au fost gestionate resursele de
intrare/ieşire etc.
După parcurgerea acestor faze programul se testează în execuţie, pe baza unor seturi
stabilite de date de control. În această fază programul se consideră corect dacă rezultatele
obţinute sunt cele scontate (pentru datele de test, programatorii trebuie să determine dinainte
rezultatele - valorile şi forma lor de prezentare). Se mai face menţiunea că, într-un lanţ de
programe dintr-un sistem, trebuie testat întreg lanţul, în intercorelările lui interne. Programele
considerate corecte se memorează pe medii magnetice, eventual constituite în biblioteci.
Definitivarea documentaţiei programelor. Deşi mai puţin spectaculoasă, chiar
„birocratică”, această etapă este obligatorie pentru exploatarea, dezvoltarea şi adaptarea
programelor, mai ales dacă fac parte dintr-un sistem. Documentarea corectă a programului face
posibilă, de asemenea, folosirea lui de către alţi utilizatori. S-a arătat că, pe măsura desfăşurării
precedentelor etape, s-au realizat unele documente necesare exploatării corecte a programelor.
Acestea se completează, redactează şi ordonează, constituindu-se într-un dosar de prezentare şi
exploatare, care cuprinde:
descrierea problemei (rezultate, date de intrare, procesul de prelucrare, formalizarea
matematică şi modelul matematic, precizia algoritmului etc.);
descrierea resurselor necesare şi a restricţiilor de utilizare;
organigrama modulelor;
schemele logice structurate (sau alte forme de reprezentare a algoritmului) pentru
fiecare modul;
modul de apel al procedurilor şi funcţiilor şi structura datelor şi parametrilor care se
transferă între apelator şi apelat;instrucţiuni de utilizare (procedura de punere în lucru, lista şi
forma întrebărilor şi răspunsurilor în conversaţia cu utilizatorii, lista programelor care trebuie
executate în amonte etc.);
exemple de utilizare.
Exploatarea curentă. După punerea la punct, programele intră în utilizare, fiind
urmărite în vederea depistării unor erori care nu au putut fi sesizate anterior. Această fază asigură
menţinerea în funcţiune şi dezvoltarea programelor, proces care se poate continua pe tot parcursul
utilizării lor.

Test de autoevaluare




3.2. Fazele dezvoltării programelor

Utilizarea calculatoarelor necesită elaborarea programelor pe baza cărora se obţin
rezultate dorite, prin aplicarea unui algoritm asupra datelor de intrare. Un program reprezintă o
mulţime ordonată de instrucţiuni, asociată unui algoritm de rezolvare a problemei, care comandă
operaţiile de prelucrare a datelor. Instrucţiunea reprezintă exprimarea într-o formă riguroasă -
conform regulilor de sintaxă ale unui limbaj artificial (limbaj de programare) a unei operaţii şi
precizează funcţia şi adresele operanzilor. Prin limbaj de programare se înţelege o mulţime de
1. Într-o abordare schematică, enumeraţi etapele de realizare a sistemelor informatice.

Bazele programării 45


cuvinte (dicţionar) împreună cu regulile de utilizare a lor (gramatică). Regulile de utilizare sunt
de sintaxă (formă) şi de semantică (sens).


Editare
Compilare
Link-editare
Lansare
în execuţie
Program sursă
Program obiect
executabil
Program obiect
Biblioteci
standard
Listing
sursă
Program
asamblare
Harta alocării
memoriei
Biblioteci
utilizator

Fig. 3.1. Etapele dezvoltării unui program
Unitatea centrală a unui calculator recunoaşte un singur limbaj, numit limbaj maşină (sau
limbaj cod obiect executabil). Scrierea programelor într-un astfel de limbaj este greoaie şi
ineficientă. El este apropiat de maşină, necesită coduri numerice pentru operaţii şi adrese absolute
pentru operanzi.
În practică, utilizatorii folosesc limbaje evoluate (universale, algoritmice) apropiate de
factorul uman, cum ar fi FORTRAN, COBOL, BASIC, C, PASCAL etc. Programele scrise într-
un astfel de limbaj se numesc programe sursă, care din punct de vedere al utilizatorului sunt
fişiere de tip text, create prin editare specifică limbajului sau de utilizare generală. Transformarea
programelor sursă în programe obiect executabile se realizează, de obicei, în mai multe faze
(figura 3.1).
Compilarea este operaţia de traducere a programului sursă în program cod obiect. Ea este
realizată de componenta software numită compilator. Lucrul cu un anumit limbaj evoluat
presupune existenţa compilatorului pentru acel limbaj. În funcţie de posibilităţile compilatorului,
în urma compilării se mai pot obţine fişierul cu listingul programului sursă şi fişierul cu
programul sursă tradus în limbaj de asamblare. Unele limbaje, printre care şi C, impun ca
programele să fie supuse unei prelucrări anterioare, numită preprocesare.
Editarea de legături (link-editarea) este operaţia de transformare a programului cod
obiect, rezultat din compilare în program cod obiect executabil. Ea este realizată de componenta
software numită link-editor. Link-editorul încorporează în programul obiect atât module
Bazele programării 46


executabile din biblioteca specifică limbajului, invocate (apelate) implicit sau explicit de
programul sursă al utilizatorului, cât şi module executabile din bibliotecile realizate de utilizator.
Programul obiect executabil se lansează în execuţie cu comenzi ale sistemului de operare.


Test de autoevaluare



Răspunsuri şi comentarii la testele de autoevaluare

Rezumat
În cadrul acestei unităţi de învăţare au fost studiate următoarele aspecte în ceea ce priveşte datele
şi structurile de date:
caracteristici generale ale PPAD;
organizarea procesului de rezolvare a PPAD;
fazele dezvoltării programelor.
După încheierea acestei unităţi de învăţare, studenţii au cunoştinţe şi abilităţi de organizare a
procesului de rezolvare a problemelor şi a etapelor de dezvoltare a programelor.

Bibliografia unităţii de învăţare
1. I. Gh. Roşca, B. Ghilic-Micu, C. Cocianu, M. Stoica, C. Uscatu, M. Mircea, L. Bătăgan, C. Silvestru,
Bazele programării calculatoarelor. Teorie şi aplicaţii în C, Ed. ASE, Bucureşti, 2006, ISBN 973-594-591-
6
2. Fazele dezvoltării programelor sunt: 1) editare; 2) verificare sintaxă; 3) compilare; 4)
editare legături; 5) lansare în execuţie; 6) testare. a) toate; b) 1,2,3,4 şi 5; c) 1,3,4,5 şi 6; d)
1,2,3 şi 4; e) 1,3,4 şi 5.

1. Într-o abordare schematică, etapele de realizare a sistemelor informatice sunt
următoarele:
studiul şi analiza sistemului informaţional actual;
proiectarea de ansamblu;
proiectarea de detaliu;
elaborarea programelor;
implementarea şi exploatarea sistemului.
2:e).


Bazele programării 47




4. Caracteristicile limbajului C

Cuprins
Obiectivele unităţii de învăţare 4
4.1 Elementele de bază ale limbajului C
4.2 Tipurile de date în C
4.3 Expresii
4.4. Realizarea structurilor fundamentale de control
Răspunsuri şi comentarii la testele de autoevaluare
Bibliografia unităţii de învăţare

Obiectivele unităţii de învăţare 4
După studiul acestei unitati de învatare, studenţii vor avea cunoştinţe teoretice şi abilităţi practice
despre:
elementele de bază ale limbajului C;
tipuri de date în C;
expresii;
realizarea structurilor fundamentale de control.

Durata medie a unităţii de studiu individual - 10 ore

4.1 Elementele de bază ale limbajului C

Principalele construcţii sintactice ale limbajului C, într-o ordine relativă a procesului de
agregare sunt:
- identificatorii, care sunt denumirile (adresele simbolice) pe baza cărora sunt referite în
program datele, tipurile, funcţiile, fişierele etc.;
- comentariile, care sunt texte prezente în programul sursă, dar ignorate de compilator;
- expresiile, care sunt construcţii formate din operanzi (date numerice, logice, de tip caracter
etc.) şi operatori (aritmetici, relaţionali, logici etc.) şi a căror evaluare produce o valoare de un
anumit tip;
- declaraţiile, care sunt construcţii pentru definirea şi descrierea datelor (constante şi/sau
variabile, date scalare şi/sau structuri de date etc.);
- instrucţiunile, pentru descrierea acţiunilor realizate asupra datelor;
- funcţiile, care pe baza unor date de intrare furnizează unul sau mai multe rezultate de
ieşire;
- programul, reprezentând construcţia sintactică de cel mai înalt nivel, care poate face
obiectul prelucrării şi execuţiei de un sistem de calcul.

Bazele programării 48


Identificatorii sunt denumiri asociate entităţilor referite în program. Ele sunt
succesiuni de litere (mici şi/sau mari, din alfabetul latin), cifre zecimale (de la 0 la 9) şi _
(liniuţa de subliniere). Primul caracter trebuie să fie o literă sau liniuţa de subliniere. Nu se
recomandă însă ca primul caracter să fie „ _” pentru a nu se face confuzii nedorite cu
identificatorii rezervaţi folosiţi de diferite compilatoare. Literele mari nu sunt identice cu cele
mici (C face parte din categoria limbajelor case sensitive).
Exemple:
a, x, X, abc, Abc, x1, x_1, alfa, pret_unitar, student, _, _a, ____.
CodProdus nu are aceeaşi semnificaţie cu codprodus.

La scrierea identificatorilor se utilizează frecvent literele mici, dar pentru denumirile
compuse se recomandă ca fiecare cuvânt să înceapă cu literă mare, pentru creşterea lizibilităţii
programului sursă.
Exemple:
PretUnitar, MatrUnitate, SumaElemVector,MedAritmPond.

Lungimea unui identificator variază de la un singur caracter până la oricâte, dar se iau în
considerare numai primele 32. Dacă doi identificatori au primele 32 de caractere identice, atunci
ei vor fi consideraţi identici de compilator. Unele compilatoare permit modificarea acestei limite
de lungime.
Anumiţi identificatori sunt predefiniţi în limbaj, au destinaţie impusă şi nu pot fi utilizaţi
în alte moduri sau scop decât cele pentru care au fost definiţi. Aceştia sunt numiţi cuvinte
rezervate (sau cuvinte cheie) şi vor fi introduse pe măsură ce sunt prezentate construcţiile
sintactice ale limbajului.
Exemple:
for, do, if, else, char, long, float, while, return etc. (din K&R C);
const, enum, signed, void etc. (din ANSI C);
_AL, _AX, _DX, _BX, _FLAGS (din Turbo C).

Comentariile sunt secvenţe de text compuse din orice caractere admise în setul
limbajului, care au format liber şi care nu se compilează. În general, comentariile sunt necesare
pentru explicaţii suplimentare ale programatorului, în vederea înţelegerii ulterioare a logicii sale.
Comentariile sunt delimitate de perechile de caractere /* şi */ şi se pot întinde pe mai multe linii
sursă.
Orice caracter aflat între delimitatori este ignorat de compilator. Nu se admit comentarii
imbricate (incluse unul în altul). La compilatoarele C++ a fost adăugată posibilitatea de a scrie
comentarii pe o singură linie sursă. Începutul unui astfel de comentariu este marcat de perechea //
iar sfârşitul său este marcat de sfârşitul liniei (nu există marcator special). Orice caracter aflat
după // este ignorat, până la trecerea pe o nouă linie sursă.

Instrucţiunile sunt construcţii sintactice ale limbajului, terminate de caracterul ;
(punct şi virgulă). Ele indică operaţiile (acţiunile) care se aplică datelor în vederea obţinerii
rezultatelor scontate prin algoritm. Instrucţiunile pot fi clasificate în: simple, structurate,
compuse.

Funcţiile sunt entităţi (subprograme) care pot fi proiectate şi realizate independent,
dar care nu se execută decât împreună cu o altă entitate de program, numită apelatoare. Conceptul
a fost definit de realizatorii limbajului Fortran şi s-a impus în practica programării din
Bazele programării 49


următoarele motive: evitarea scrierii repetate în program a unor secvenţe de instrucţiuni aplicate
de mai multe ori pe seturi diferite de date; creşterea eficienţei activităţii de programare prin
crearea unor biblioteci de subprograme des utilizate, care pentru fiecare din aplicaţiile concrete
doar se apelează, fără să fie proiectate şi realizate de fiecare dată; necesitatea modularizării
problemelor cu grad înalt de complexitate.
Funcţia are un nume şi un tip. Ea se defineşte printr-un antet şi un corp (bloc) astfel:
antet
{
corp
}
Antetul are forma:
tip nume(lista_parametrilor_formali)
unde:
• tip poate fi un tip simplu de dată. Dacă lipseşte, este considerat tipul implicit (int pentru
unele compilatoare, void pentru altele);
• nume este un identificator care reprezintă numele funcţiei;
• lista-parametrilor-formali conţine parametrii formali sub forma:

[tip1 identificator1[,tip2 identificator[,tip3 identificator …]]]

Parametrii sunt separaţi prin virgulă. La limită, lista poate fi vidă. Pentru fiecare
parametru trebuie specificat tipul, chiar dacă mai mulţi parametri sînt de acelaşi tip.
Funcţiile returnează o valoare „prin nume”, dar pot returna valori şi prin parametri. Unele
funcţii (de exemplu, cele care citesc sau scriu date) execută „servicii” şi apoi returnează, prin
nume, valori care pot sau nu să fie utilizate în apelator. Funcţiilor care nu trebuie să întoarcă
valori prin nume li se poate asocia tipul void (care, la unele compilatoare, este implicit).
Corpul este o instrucţiune compusă: conţine declaraţiile locale şi instrucţiunile executabile
care implementează algoritmul. Corpul funcţiei se execută pînă la executarea ultimei instrucţiuni
sau pînă la executarea instrucţiunii return. Forma ei generală este:
return(expresie); sau
return expresie; sau
return;

Prima şi a doua formă sînt folosite în cazul funcţiilor care returnează o valoarea prin
numele lor. Prin executarea acestei instrucţiuni se evaluează expresia, valoarea sa este atribuită
funcţiei şi se încheie execuţia funcţiei. A treia formă este folosită în cazul funcţiilor care nu
returnează nici o valoare prin numele lor (poate chiar să lipsească). Dacă este prezentă, efectul ei
este încheierea execuţiei funcţiei. Tipul expresiei din instrucţiunea return trebuie să coincidă cu
tipul funcţiei.
Apelul funcţiilor se face prin referirea lor ca operanzi în expresii, sub forma:
nume(lista_parametrilor_reali)
La apel, parametrii reali se pun în corespondenţă cu cei formali, de la stânga la dreapta.
Pentru o corectă utilizare a datelor, tipurile parametrilor reali trebuie să fie aceleaşi ca ale celor
formali corespunzători.

Programul este construcţia sintactică de cel mai înalt nivel. El codifică algoritmul, fiind
constituit din declarări şi instrucţiuni executabile. Dat fiind faptul că limbajul C este puternic
orientat spre funcţii, programul principal este el însuşi o funcţie (care poate avea parametri şi
poate întoarce un rezultat de tip întreg): main (cuvânt rezervat). La modul general, un program
este o înşiruire de funcţii şi declaraţii, printre care trebuie să existe o funcţie denumită main,
Bazele programării 50


lansată în execuţie la rularea programului. Pentru funcţia main sunt permise mai multe forme ale
antetului:

main()
int main()
void main()
main(void)
void main(void)
int main(void)

Orice program este format dintr-o parte de declaraţii (formată din instrucţiuni
neexecutabile, cu rol doar în faza de compilare) şi o parte executabilă (formată din instrucţiuni
executabile). Unele limbaje impun o separare clară a acestora (de exemplu Pascal, COBOL,
FORTRAN), în care partea de declaraţii precede partea executabilă. Alte limbaje (de exemplu C,
C++) sunt mai flexibile, permiţând ca declaraţiile să alterneze cu instrucţiunile executabile,
păstrând însă regula că orice entitate referită trebuie definită anterior. Pentru a evita confuziile se
recomandă ca declaraţiile să fie reunite la începutul blocului de instrucţiuni pentru care sunt
vizibile.

Directivele de preprocesare. Înaintea compilării, în C se desfăşoară etapa de
preprocesare, în cadrul căreia se efectuează substituiri asupra textului sursă scris de programator.
Prin preprocesare se rezolvă cerinţele compilării condiţionate, se asigură inserarea unor fişiere în
textul sursă şi se expandează macrodefiniţiile. Preprocesarea este controlată prin directive, a căror
sintaxă (în format BNF) este:
<directiva>::=#<cuvant_rezervat>[<parametri>]

Directiva #include este folosită pentru includerea de fişiere cu text sursă într-un program şi
are următoarea sintaxă:
#include<specificator_de_fisier>
sau
#include”specificator_de_fisier”

Prima formă caută fişierul specificat între fişierele standard ale limbajului, folosindu-se
calea descrisă în mediul de programare. A doua formă caută fişierul specificat în calea curentă (de
obicei este folosită pentru a include fişiere scrise de utilizator). Dacă fişierul căutat nu este găsit se
produce o eroare de compilare. Dacă fişierul este găsit, conţinutul lui este inserat în program, în
locul directivei care l-a invocat, aceasta fiind ştearsă (la limită poate fi considerată o substituire de
text).
Pentru ca textul inclus să fie vizibil din tot programul, se recomandă ca directivele #include
să fie scrise la începutul programului. Un text inclus poate să conţină la rândul lui directive care
determină noi includeri de text. Textul inclus va fi compilat ca parte componentă a programului.
Pentru a putea utiliza funcţiile care realizează operaţiile de intrare/ieşire trebuie inclus
fişierul stdio.h.
Exemplu: #include<stdio.h>

Directiva #define este folosită pentru a substitui unele secvenţe de caractere cu altele şi
are forma generală:
#define sir1 sir2

Bazele programării 51


unde atât sir1 cât şi sir2 sunt şiruri de caractere. La preprocesare, se şterge directiva din program
şi se înlocuieşte secvenţa de caractere sir1 cu secvenţa de caractere sir2 peste tot unde apare în
programul sursă. Secvenţa sir1 este denumită nume iar sir2 este denumită descriere. Nu se face
înlocuirea dacă sir1 apare în interiorul unui literal de tip şir de caractere sau în interiorul unui
comentariu. sir2 poate să fie descris pe mai multe rânduri, dacă la sfârşitul fiecărui rând (în afară
de ultimul) se scrie caracterul \ (backslash). Rolul acestuia va fi discutat în alt capitol. sir2 poate
să conţină şiruri de caractere pentru care au fost definite anterior. Acestea vor fi substituite
conform definiţiilor lor.

Substituirea poate fi dezactivată din punctul în care apare directiva #undef până la
sfârşitul programului sau până la redefinirea lui sir1. Directiva are forma generală:
#undef sir1
Între cele mai frecvente utilizări ale directivei #define sunt definirea de constante
simbolice (literali cărora li se asociază identificatori) şi definirea de macrodefiniţii (necesare
simplificării scrierii).
Din punct de vedere al textului sursă, un macro se foloseşte la fel ca orice funcţie: se
apelează prin numele simbolic urmat de lista parametrilor reali. Din punct de vedere al compilării
există o diferenţă fundamentală: macro-urile sunt tratate la preprocesare. Preprocesorul şterge
din textul sursă apelul macro-ului şi îl înlocuieşte chiar cu secvenţa de definire. Parametrii
formali ai macro-ului sunt înlocuiţi cu parametrii reali, prin substituire de text (corespondenţa se
face conform regulilor de punere în corespondenţă a parametrilor reali cu cei formali: unu-la-unu,
de la stânga la dreapta).

Test de autoevaluare


4.2 Tipurile de date în C

Limbajul oferă posibilităţi multiple în declararea şi utilizarea tipurilor de date. În general,
tipurile de date se clasifică în statice şi dinamice, împărţite la rândul lor în simple şi structurate.
Tipurile de date admise de limbajul C sunt prezentate în tabelul 4.1.

Tabelul 4.1. Clasificarea tipurilor de date în C
După modul de
alocare a memoriei
După numărul de
valori memorate
Tipuri existente
Întregi
Reale
Statice
Simple
Caracter
1. Specificaţi cum va arăta secvenţa de cod următoare, după preprocesare:
#define N 10
#define M 10
#define MAX (M+N)
#define DIM(a,b) (a)*(b)
char v[N],v1[10+DIM(5+M,6)];
char v1[10*MAX];
char m[M][N];

Bazele programării 52


Masiv
Articol
Structurate
Fişier
Pointer
Dinamice Simple
Referinţă

4.2.1. Tipurile simple de date
În limbajul C există o serie de tipuri simple de date predefinite (tabelul 4.2), a căror
lungime poate să difere de la un sistem de calcul la altul şi de la o implementare la alta
(standardul C este mai elastic decât altele). De exemplu, pentru tipul char este definită lungimea
1 sau cel mult lungimea tipului int.
Tabelul 4.2. Tipuri simple de date în C
Grup
a de
dată
Tipul
Lun-
gime
(octeţ
i)
Domeniu de
valori
Mod de reprezentare
unsigned char 1 0..255 (0..2
8
-1)
[signed] char 1
-128..127 (-2
7
..2
7
-
1)
Codul ASCII al caracterului.
Poate fi prelucrat ca un caracter
sau ca un întreg cu/fără semn.
unsigned [int] 2 0..65535 Virgulă fixă aritmetică
[signed] [int] 2 -32768..32767 Virgulă fixă algebrică
unsigned long 4 0..2
32
-1 Virgulă fixă aritmetică

Întreg
[signed] long
[int]
4 -2
31
..2
31
-1 Virgulă fixă algebrică
float 4
3.4*10
-
38
..3.4*10
38

Virgulă mobilă simplă precizie
double 8
1.7*10
-308
..
1.7*10
308

Virgulă mobilă dublă precizie Real
long double 10
3.4*10
-
4932
..3.4*10
4932

Virgulă mobilă extra precizie

Variabilele
Datele variabile îşi modifică valoarea pe parcursul execuţiei programului. De aceea, ele se
asociază unor zone de memorie. Identificatorii acestora se declară şi apoi se referă în operaţii.
Operaţiile afectează conţinutul zonelor de memorie, care este interpretat ca fiind de un anumit tip.
Declararea variabilelor se realizează prin listă de identificatori (separaţi prin virgulă) pentru care
se specifică tipul.
tip lista_variabile;
Declararea se poate face oriunde în program, cu următoarea condiţie: variabilele trebuie
declarate înainte de a fi folosite (referite). Domeniul de valabilitate este limitat la blocul în care s-
a făcut declaraţia.
Exemple:
unsigned x,y,z;
Bazele programării 53


float a,b,c;
char k;

Variabilele pot fi iniţializate la momentul compilării, dacă se utilizează următoarea
declaraţie:

tip nume_variabila=valoare;
Exemple:
int dim_vector=100;
dim_vector=50; /*nu este eroare*/

Definirea de noi tipuri de date. Utilizatorul poate defini noi tipuri de date sau poate
atribui un alt nume unui tip predefinit sau definit anterior. În acest scop se foloseşte cuvântul
rezervat typedef, astfel:
typedef descriere_tip nume_utilizator;
Exemple:
typedef int INTREG;
typedef float REAL;

Particularităţile unor tipuri simple de date. Tipul caracter memorează caractere ale
codului ASCII, reprezentate pe un octet. Variabilele de tip caracter pot fi utilizate şi ca valori
numerice (modul de utilizare se alege automat, în funcţie de expresia din care face parte
operandul respectiv).
Valoarea numerică folosită depinde de modul de declarare a caracterului: cu sau fără
semn. Pentru caracterele cu coduri mai mici decât 128 nu se sesizează nici o diferenţă (se obţine
aceeaşi valoare şi pentru interpretarea ca virgulă fixă aritmetică şi pentru interpretarea ca virgulă
fixă algebrică). Pentru caracterele cu coduri mai mari de 127, valoarea obţinută este diferită.
Exemple:
Declararea şi utilizarea variabilelor de tip caracter.
unsigned char a,b;
……………………………………………
a=100;/* corect */
b=’Q’;/* corect */
b=81; /* corect, echivalent cu precedentul */

4.2.2. Constantele
Datele constante sunt predefinite la momentul scrierii programului iar valoarea lor este
generată la momentul compilării. Datele constante pot fi literali (constante propriu-zise), care se
autoidentifică prin valoare, sau constante simbolice, care sunt identificatori (denumiri) asociaţi
altor constante (literali sau constante simbolice definite anterior). În C literalii sunt întregi, reali,
caracter şi şir de caractere.

Literalii întregi sunt reprezentaţi intern în virgulă fixă. Ei pot fi exprimaţi în bazele de
numeraţie 10 (forma implicită), 8 (folosind prefixul 0 – zero) sau 16 (folosind prefixul 0x sau
0X). În funcţie de mărimea lor, se asociază implicit un tip întreg (şi implicit un mod de
reprezentare). Se încearcă întotdeauna întâi reprezentarea pe 16 biţi, conform tipului int; dacă nu
este posibilă, atunci se foloseşte reprezentarea pe 32 de biţi, conform tipului long.
Dacă se doreşte forţarea reprezentării pe 32 de biţi (pentru o valoare din domeniul tipului
int), se adaugă sufixul l sau L. Pentru a forţa tipul fără semn (unsigned int sau unsigned long) se
foloseşte sufixul u sau U. Cele două sufixe se pot folosi împreună, în orice ordine.
Bazele programării 54



Literalii reali sunt reprezentaţi intern în virgulă mobilă. Ei se pot exprima sub formă
matematică (±întreg.fracţie) sau ştiinţifică (±întreg.fracţieE±exponent). Semnul + poate lipsi
(este implicit), iar e este echivalent, ca valoare, cu E. Din exprimare poate să lipsească fie partea
fracţionară, fie partea întreagă, fie partea întreagă şi exponentul (inclusiv litera e).
Literalii reali se reprezintă intern pe 64 de biţi (tipul double). Pentru a forţa reprezentarea
în simple precizie (tipul float) se adaugă sufixul f sau F. Pentru a forţa reprezentarea pe 80 de biţi
(tipul long double) se foloseşte sufixul l sau L. Cele două sufixe nu se pot folosi împreună.

Literalii caracter se reprezintă intern prin codul ASCII al caracterului respectiv, pe
un octet. Exprimarea externă depinde de caracterul respectiv. Literalii de tip caracter pot
participa în expresii cu valoarea lor numerică, aşa cum s-a arătat anterior.
Exprimarea externă a unui caracter direct imprimabil (existent pe tastatură, cu coduri
ASCII cuprinse între 32 şi 127) se face prin caracterul respectiv inclus între apostrofuri. Excepţie
fac caracterele cu semnificaţie specială în C: ‘ (apostrof), " (ghilimele) şi \ (backslash), care se
exprimă printr-o succesiune de două caractere, fiind precedate de caracterul \.
Exemple: ′B′, ′b′, ′7′, ′ ′ (spaţiu), ′*′, ′\\′ (caracterul backslash, cod ASCII 92), ′\′′ (caracterul apostrof,
cod ASCII 39), ′\″′ (caracterul ghilimele, cod ASCII 34).

Reprezentarea folosind caracterul backslash este numită secvenţă escape. Secvenţele
escape sunt folosite şi pentru a reprezenta caracterele de control (coduri ASCII între 0 şi 31).
Pentru a reprezenta caracterele grafice ale codului ASCII extins (coduri între 128 şi 255) se pot
folosi numai secvenţele escape construite astfel: ′\ddd′, unde d este o cifră din sistemul de
numeraţie octal (0÷7). Construcţia ddd este considerată implicit ca fiind codul ASCII al
caracterului, reprezentat în baza 8. Nu este nevoie ca ea să fie precedată de un zero
nesemnificativ. Această construcţie poate fi folosită pentru a reprezenta orice caracter al setului
ASCII.
Exemple: ′\a′ şi ′\7′ reprezintă caracterul BEL, ′\b′ şi ′\10′ reprezintă caracterul BS, ′\″′ şi ′\42′
reprezintă caracterul ghilimele, ′\377′ reprezintă caracterul cu codul ASCII 255.

La iniţializarea unei variabile de tip caracter se poate folosi oricare din variantele de
reprezentare descrise anterior sau orice valoare numerică (întreagă sau reală). În acest ultim caz,
din reprezentarea internă a literalului numeric se iau în considerare primii 8 biţi care sunt
interpretaţi ca un cod ASCII, obţinându-se valoarea care se atribuie.

Literalii de tip şir de caractere. Un literal de tip şir de caractere este un şir de zero
sau mai multe caractere, delimitate prin ghilimele (ghilimelele nu fac parte din şir). Pentru a
reprezenta diferite caractere, în interiorul şirului se pot folosi secvenţe escape. Un literal de tip
şir de caractere poate fi scris pe mai multe rânduri. Pentru a semnala că un literal continuă pe
rândul următor se scrie caracterul \ la sfârşitul rândului curent.
Un şir de caractere este reprezentat intern prin codurile ASCII ale caracterelor, câte unul
pe fiecare octet, la sfârşit adăugându-se caracterul nul (cod ASCII 0 – ′\0′). Caracterul nul nu
poate să facă parte dintr-un şir, el având rolul de terminator de şir. În reprezentarea internă, un şir
de caractere ocupă cu un octet mai mult decât numărul de caractere din componenţa sa.
Exemple: literalul
"Acesta este un literal \"sir de caractere\" \
scris pe doua randuri."
reprezintă şirul Acesta este un literal "sir de caractere" scris pe doua randuri.
Bazele programării 55


" " - şir de lungime 1 (caracterul spaţiu)
"" - şirul de lungime 0 (şirul vid)

Constantele simbolice sunt literali cărora li se asociază identificatori. În limbajul C
constantele simbolice se construiesc folosind directiva:

#define nume_constanta valoare

Utilizarea constantelor simbolice în cadrul programelor are următoarele avantaje:
- literalii primesc nume sugestive, mai uşor de reţinut şi de utilizat, mai ales dacă sunt formaţi
dintr-un număr mare de cifre;
- pentru rularea succesivă a programului cu valori diferite ale unui literal utilizat des este
suficientă modificarea valorii constantei simbolice în definire (referirile nefiind modificate).
Exemple:
#define pi 3.141592653589
#define raspuns "D"

Constantele obiect sunt variabile iniţializate la declarare, pentru care se rezervă
memorie, dar conţinutul lor nu poate fi modificat pe parcursul execuţiei programului. Ele se
declară folosind modificatorul const:

const tip nume_constanta=valoare;
Exemplu:
const int dim_vector=10;
Dacă se încearcă o atribuire (de exemplu dim_vector=7) se generează eroare.

4.2.3. Tipurile structurate de date
Tipurile structurate au la bază mulţimi (colecţii) de date de tipuri simple sau structurate,
constituite după anumite reguli ierarhice şi de dependenţă bine stabilite. Nici o dată structurată nu
poate ocupa în memorie mai mult de 65520 de octeţi (lungimea unui segment de memorie).

Tipul masiv
Tipul masiv este structurat şi desemnează o mulţime finită de elemente omogene constituită
ca un tablou cu una, două sau mai multe dimensiuni. Mulţimea are un singur identificator şi oferă
posibilitatea referirii elementelor în acces direct prin poziţie, determinată printr-un număr de
expresii indiciale corespunzând dimensiunilor masivului. Masivul se declară folosind o construcţie
de forma:

tip nume[dim1][dim2]…[dimn];

unde tip este tipul comun elementelor masivului, iar dim1, dim2, …, dimn sunt expresii constante
(evaluate la compilare), care indică numărul de elemente de pe fiecare dimensiune. Se acceptă
oricâte dimensiuni, cu condiţia ca structura în ansamblul ei să nu depăşească zona de memorie
maximă permisă pentru structurile de date.
Exemple:
int x[10]; /* vector cu 10 componente intregi*/
float a[10][20]; /* matrice cu 10 linii si 20 coloane
de elemente reale */

La declararea masivelor se poate face şi iniţializarea lexicografică a acestora, astfel
(pentru masiv bidimensional):
tip nume[dim1][dim2]=
Bazele programării 56


{{lista_const1}{lista_const2}…{lista_constn}};
Exemple:
int b[10]={2,3,0,5,6,7,3,6,8,5};
/* vectorul contine valorile 2 3 0 5 6 7 3 6 8 5*/
float a[5][3]={{1,2,3},{1,2,3},{1,2,3}};
/* matricea contine valorile 1 2 3 1 2 3 1 2 3 0 0 0 0 0 0*/
Masivul poate fi referit global prin numele său. Elementele unui masiv se referă direct,
prin numele masivului urmat de indicele (indicii) corespunzători. Indicii sunt expresii incluse între
paranteze drepte (se mai numesc şi variabile indexate): [indice]. Pentru fiecare dimensiune a
masivului trebuie să existe câte o referire de indice. Indicele de pe fiecare dimensiune are valoarea
minimă 0 şi valoarea maximă egală cu dimensiunea din declarare minus o unitate. Compilatorul
nu verifică corectitudinea indicilor (în sensul de depăşire a dimensiunilor masivului la referirea
elementelor).

Tipul articol
Articolul este o structură de date eterogenă, cu acces direct la elementele sale, între care
există o relaţie de ordine ierarhică. Articolul poate fi reprezentat sub formă de arbore, ale cărui
noduri sunt asociate componentelor structurii. Componentele de pe ultimul nivel sunt scalare şi se
numesc date elementare sau câmpuri. Datele de pe celelalte niveluri, denumite date de grup, se
constituie prin agregarea datelor de pe nivelurile inferioare. Data de grup de cel mai înalt nivel
(rădăcina arborelui) corespunde articolului în ansamblu. Conceptual, datele de grup de pe diverse
niveluri au aceleaşi proprietăţi ca şi articolul, ceea ce permite ca această structură să fie construită
recursiv, prin descompunerea în structuri cu aceleaşi proprietăţi (figura 4.1).
Declararea împreună a tipului articol şi a variabilelor de acest tip se realizează conform
sintaxei:

struct tip_articol{lista_campuri} var1,var2,…,varn;

unde tip_articol este identificatorul asociat tipului articol, iar var1, var2,…, varn sunt
identificatorii asociaţi variabilelor de tipul articol declarat.
Parametrii declaraţiei pot lipsi (dar nu toţi deodată). Dacă lipsesc parametrii var1,
var2,…, varn, atunci tip_articol trebuie să fie prezent, fiind numai o declarare explicită de tip
nou, utilizabil ulterior la alte declarări. Dacă lipseşte tip_articol, atunci trebuie să fie prezentă
lista de variabile (nevidă), caz în care este vorba de o declarare de variabile de tip articol, fără
însă a declara şi un tip utilizator nou. În continuare, tip_articol este un tip nou de date, iar var1,
var2,…, varn sunt variabile de tipul tip_articol. Variabilele pot fi declarate şi ca masive, ale căror
elemente sunt de tip articol: var1[dim1][dim2]…[dimn].

Bazele programării 57



DATA
ZI LUNA AN
dată de grup (articol)
date elementare
NUME ADRESA DATA NAŞTERII
PERSOANA
dată de grup (articol)
dată de grup (articol)
ZI LUNA AN
date elementare
b)
a)

Fig. 4.1. Exemple de structuri de articole

O variabilă de tip articol poate fi declarată şi ulterior definirii tipului:
struct tip_articol var1;
Descrierea constituie o definire implicită de un nou tip de dată. Este posibilă definirea
explicită a unui nou tip de dată, adăugând cuvântul rezervat typedef în faţa declarării (în acest caz
nu mai pot fi declarate simultan şi variabile).
Lista_campuri este o înşiruire de declaraţii de câmpuri separate prin punct şi virgulă,
asemănătoare declaraţiilor de variabile, de forma tip_camp nume_camp. Câmpurile unei structuri
pot fi variabile simple, masive sau alte articole. Lista câmpurilor nu poate fi vidă.
Exemplu: pentru exemplele din figura 6.1, declararea poate fi realizată prin definire recursivă,
astfel:
struct tip_data {
unsigned zi;
char luna[3];
int an; };
struct persoana {
char nume[30];
char adresa[50];
struct tip_data data_nasterii;
} angajat;
Dacă nu ar fi existat declaraţia tipului articol tip_data, atunci tipul persoana putea fi scris astfel:
struct persoana {
char nume[30];
char adresa[50];
struct {
unsigned zi;
char luna[3];
int an;
} data_nasterii;
} angajat;

Variabilele de tip articol se reprezintă intern ca succesiuni de câmpuri elementare, cu
reprezentarea internă şi lungimea fizică specifice tipurilor lor. Lungimea zonei de memorie
rezervată pentru variabila de tip articol rezultă din însumarea lungimilor câmpurilor. Aceasta nu
poate depăşi 65520 octeţi (ca orice variabilă de tip structurat). Pentru structura unui articol îşi
dovedeşte utilitatea operatorul sizeof, care asigură determinarea lungimii zonei de memorie
asociate unei variabile sau unui tip de date.
Exemplu:
Bazele programării 58


Considerând declaraţiile anterioare, expresia sizeof(data_nasterii) are valoarea 8, iar sizeof(angajat) are valoarea
90.
Datele de tip articol pot fi referite în două moduri: global sau pe componente. Referirea
globală este permisă numai în operaţia de atribuire, cu condiţia ca ambele variabile (sursă şi
destinaţie) să fie articole de acelaşi tip.
Referirea pe componente (prin numele lor) este o reflectare a faptului că articolul este o
structură cu acces direct. Referirea unor componente de tip articol din structura altui articol este
posibilă numai în operaţia de atribuire, în condiţiile precizate anterior la referirea globală. În cele
ce urmează se are în vedere numai referirea componentelor de tip dată elementară, situate pe
ultimul nivel al structurii.
Referirea câmpurilor unei structuri se face prin calificare, folosind operatorul . (punct). În
referirea prin calificare, asigurarea identificării unice a câmpurilor se realizează prin asocierea
numelui acestora cu numele articolului care le conţine. Construcţia rămâne la această formă în
cazul în care structura are numai două niveluri: articolul şi câmpurile elementare ale acestuia.

În articolele cu structură recursivă se realizează calificarea progresivă cu articolele de pe
nivelurile superioare, primul calificator fiind numele articolului rădăcină. În lanţul de calificări,
numele articolului rădăcină este nume de variabilă, celelalte fiind nume de câmpuri ale
articolului. Dacă anumite componente sunt structuri de date de alte tipuri (de exemplu masive sau
şiruri de caractere), în referirea elementelor lor se aplică, pe lângă calificare, regulile specifice
acestor structuri.
Exemplu:
Referirea prin calificare a câmpurilor articolului angajat de tipul persoana (vezi exemplele anterioare) se
realizează astfel:
angajat.nume;
angajat.adresa;
angajat.data_nasterii.zi;
angajat.data_nasterii.luna;
angajat.data_nasterii.an
În aceste referiri, angajat este identificatorul variabilei articol, celelalte elemente sunt identificatori de
câmpuri. Construcţiile angajat.nume şi angajat.adresa corespund referirii globale a câmpurilor respective, care
sunt şiruri de caractere. Pentru a referi, de exemplu, primul caracter din şir, se scrie: angajat.nume[0].
Exemplu:
#include <stdio.h>
void main()
{
struct persoana {
char nume[40];
char adresa[30];
struct {
int zi, luna, an;} datan;
};
//Initializarea articolului din exemplul 1:
struct persoana p={"Popescu Ion", "Bucuresti, Magheru 14", 2, 4, 1960};
//sau cu evidentierea structurii data nasterii:
struct persoana p1={"Popescu Ion", "Bucuresti, Magheru 14", {2, 4, 1960}};
printf("\n%i",p1.datan.an);

În activitatea de programare pot fi întâlnite aplicaţii care reclamă utilizarea articolelor cu
structură variabilă. La iniţializarea câmpurilor unui astfel de articol, constanta de tip articol se
asociază unei singure structuri, deoarece zona de memorie rezervată pentru articol este unică.
Pentru acest tip de articol, limbajul pune la dispoziţia utilizatorilor tipul predefinit reuniune
(union), care se comportă ca şi tipul struct cu o singură diferenţă: la un moment dat al execuţiei
Bazele programării 59


programului, în zona de memorie rezervată articolului nu este memorat decât unul dintre
câmpurile acestuia.
Declararea tipului reuniune se realizează astfel:

union nume_tip { tip_camp1 camp1;
tip_camp2 camp2;
................
tip_campn campn;};

Lungimea zonei de memorie rezervate pentru o variabilă de tip reuniune va fi egală cu
maximul dintre lungimile câmpurilor componente. Gestiunea conţinutului respectivei zone de
memorie va trebui realizată de către programator.


Lucrul cu şiruri de caractere
Şirurile de caractere se reprezintă convenţional ca masive unidimensionale (vectori) cu
elemente de tipul char. Totuşi există o diferenţă semnificativă între un vector de numere şi un
vector de caractere. Vectorul de caractere (şirurile de caractere) se reprezintă intern printr-o
succesiune de octeţi în care sunt memorate codurile ASCII ale caracterelor şirului. Ultimul octet
conţine caracterul NULL (cod ASCII 0 – sau ASCIIZ), cu rol de marcator de sfârşit al şirului.
Marcatorul de sfârşit de şir este gestionat automat de către sistem. Astfel, pentru memorarea unui
şir de n caractere sunt necesari n+1 octeţi. Marcatorul de sfârşit nu face parte din şir şi este tratat
ca atare de funcţiile care lucrează cu şiruri de caractere.
Exemplu:
1. char s[10]="Limbajul C";

0 1 2 3 4 5 6 7 8 9 10
L i m b a j u l C 0x00

Pentru prelucrarea şirurilor de caractere, limbajul C pune la dispoziţia utilizatorului o serie de funcţii
specifice, definite în biblioteca standard string.h. Limbajul C dispune şi de alte funcţii care lucrează cu şiruri
de caractere (funcţii de conversie), definite în biblioteca standard stdlib.h: atof (care necesită şi includerea
bibliotecii standard math.h), atoi, atol, itoa, ltoa. De asemenea, în biblioteca stdio.h există definite funcţii de
intrare/ieşire pentru şirurile de caractere.

Teste de autoevaluare
Bazele programării 60




4.3 Expresii

Asupra datelor pot fi aplicaţi operatori din diverse clase, rezultând construcţii sintactice
numite expresii. În forma lor cea mai generală, expresiile sunt alcătuite din operanzi şi operatori.
Evaluarea expresiilor produce ca rezultat o valoare de un anumit tip. În metalimbajul BNF expresia
poate fi definită astfel:

<expresie>::=<operand>|<operator_unar><expresie>|
<expresie><operator_binar><expresie>

Prima variantă din definiţie corespunde celei mai simple forme de expresie, redusă la o
variabilă sau o constantă de un anumit tip. A doua şi a treia variantă, prin aplicare repetată, conduc
la recursivitate în construirea expresiilor, proces evidenţiat în exemplul următor:

{
( )
{ { {
4 4 4 4 3 4 4 4 4 2 1
4 4 4 3 4 4 4 2 1
43 42 1
expresie
expresie
expresie
expresie
expresie
expresie expresie
15 c b a + − − +


Ordinea de aplicare a operatorilor din expresii poate fi, total sau parţial, impusă prin
folosirea parantezelor. Acestea sunt evaluate cu prioritate, iar dacă sunt mai multe niveluri de
paranteze, evaluarea se realizează din interior spre exterior. În absenţa parantezelor, respectiv în
interiorul acestora, evaluarea se realizează în funcţie de ordinul de precedenţă a operatorilor.

4.3.1 Operanzi şi operatori
2. . Se presupune un articol cu următoarea structură:

Vânzări lunare Cod
magazin
Luna 1 Luna 2 … Luna 12
întreg real real … real
2 4 4 … 4
Scrieţi modul de declarare a articolului şi lungimea sa în număr de octeţi. Exemplificaţi referirea
câmpurilor.
3. Se presupune un articol cu următoarea structură:
forma de învăţământ
zi id
nume
data
naşterii
an de
studiu
bursa valoare
loc de
muncă
data
angajării
char[40]
z
i
l
u
n
a
a
n
int char float char[30]
z
i
l
u
n
ă
a
n
Specificaţi cum se realizează declararea şi iniţializarea câmpurilor unui student la zi pentru structura
articolului prezentat.
Bazele programării 61



Un operand poate fi una din următoarele construcţii:
• o constantă simbolică;
• un literal;
• o variabilă simplă;
• numele unui masiv;
• numele unui tip de dată;
• numele unei funcţii;
• referirea unui element de masiv;
• referirea unui câmp de articol;
• apelul unei funcţii;
• o expresie.
Din ultima posibilitate rezultă că expresia este o construcţie recursivă. Un operand are un
tip şi o valoare. Valoarea se determină fie la compilare fie la execuţie. Nu pot fi operanzi şirurile
de caractere.
Operatorii se clasifică după diferite criterii, precum numărul operanzilor asupra cărora se
aplică şi tipul de operaţie pe care o realizează. Majoritatea operatorilor sunt unari sau binari.
Limbajul utilizează şi un operator ternar (care se aplică asupra a trei operanzi). După tipul
operaţiei realizate, operatorii sunt aritmetici, logici, relaţionali etc.
Într-o expresie apar, de obicei, operatori din aceeaşi clasă, dar pot fi şi din clase diferite.
Se pot scrie expresii complexe care să conţină operatori din toate clasele. La evaluarea acestor
expresii se ţine cont de priorităţile operatorilor (numite şi clase de precedenţă), de asociativitatea
lor şi regula conversiilor implicite.
Atunci când un operator binar se aplică la doi operanzi de tipuri diferite, înainte de a
efectua operaţia, cei doi operanzi sunt aduşi la un tip comun. În general, operandul de tip inferior
se converteşte către tipul operandului de tip superior. În primul rând se convertesc operanzii de
tip char către tipul int. Dacă operatorul se aplică la doi operanzi cu acelaşi tip nu se face nici o
conversie, rezultatul având acelaşi tip cu cei doi operanzi. Dacă valoarea lui depăşeşte domeniul
asociat tipului de dată, rezultatul este eronat (eroarea de depăşire de domeniu). Dacă operatorul se
aplică la operanzi de tipuri diferite, conversia se face astfel:
1. dacă un operand este de tipul long double, celălalt se converteşte la acest tip, iar
rezultatul va fi de tip long double;
2. dacă un operand este de tip double, celălalt se converteşte la acest tip, iar rezultatul va fi
de tip double;
3. dacă un operand este de tip float, atunci celălalt se converteşte la acest tip, iar rezultatul
va fi de tip float;
4. dacă un operand este de tip unsigned long, atunci celălalt se converteşte la acest tip, iar
rezultatul va fi de tip unsigned long;
5. dacă un operand este de tip long, atunci celălalt se converteşte la acest tip, iar rezultatul
va fi de tip long;
6. dacă unul din operanzi este de tip unsigned iar celălalt de tip int acesta se converteşte la
tipul unsigned, iar rezultatul va fi de tip unsigned.
Regula se aplică pe rând fiecărui operator din cadrul unei expresii, obţinând în final tipul
expresiei.

4.3.2. Operatorii de atribuire
Atribuirea este o expresie cu forma generală: v=expresie
Bazele programării 62


unde v este o variabilă simplă, un element de masiv, un câmp al unui articol sau o expresie în
urma evaluării căreia se obţine o adresă. Entitatea care se poate afla în stânga operatorului de
atribuire se numeşte left value.
Pentru a se putea efectua atribuirea, tipul expresiei şi tipul entităţii din stânga operatorului
de atribuire trebuie să fie compatibile. Dacă sunt incompatibile se produce eroare la compilare
(deoarece compilatorul nu poate insera în codul obiect apelurile pentru operaţiile de conversie).
Efectele atribuirii constau în:
• evaluarea expresiei din dreapta operatorului de atribuire, cu determinarea unei valori şi
a unui tip;
• memorarea valorii expresiei din dreapta în variabila din stânga;
• întreaga expresie de atribuire are valoarea şi tipul variabilei din stânga.

În practica programării, se utilizează frecvent expresiile de forma v = v op (expresie)
(de exemplu a=a+b-c). Se observă redundanţa de exprimare prn specificarea variabilei v atît în
membrul stâng cât şi în cel drept. Pentru eliminarea acestei redundanţe, s-au introdus operatorii
combinaţi, cu forma generală
op=
unde op este un operator binar, aritmetic sau logic pe biţi (/, %, *, -, +, <<, >>, &, ^, |). O expresie de
forma
v op= expresie
este echivalentă cu
v = v op (expresie)
Exemple:
Expresia a=a+b-c este echivalentă cu a+=b-c.
Expresia i*=5 este echivalentă i=i*5.


4.3.3. Operatorii aritmetici
În ordinea priorităţii lor, operatorii aritmetici sunt:
i. operatori unari +, -, ++, --
ii. operatori binari multiplicativi *, /, %
iii. operatori binari aditivi +, -
Operaţiile efectuate de aceşti operatori sunt descrise în tabelul 4.3.

Tabelul 4.3. Operatorii aritmetici
Semnificaţie operaţie Operator
Schimbare semn -
Păstrare semn (nici un efect, nu este
folosit)
+
Decrementare (post sau pre) --
Incrementare (post sau pre) ++
Adunare +
Scădere -
Înmulţire *
Împărţire /
Împărţire întreagă (câtul) /
Bazele programării 63


Împărţire întreagă (restul) %

Observaţie: Cu excepţia operatorului %, care admite numai operanzi întregi, ceilalţi admit toate
tipurile numerice.

Operatorii ++ şi -- au efect diferit, depinzând de poziţia faţă de operand, astfel:
a. dacă apar înaintea operandului, valoarea acestuia este modificată înainte de a fi utilizată la
evaluarea expresiei din care face parte: ++var (preincrementare) sau --var (predecrementare);
b. dacă apar după operand, valoarea acestuia este folosită la evaluarea expresiei din care face
parte, apoi este modificată: var++ (postincrementare) sau var-- (postdecrementare).
Incrementare/decrementarea au ca efect modificarea valorii operandului cu o unitate.
Semnificaţia unei unităţi depinde de tipul operandului asupra căruia se aplică. Pentru operanzi
numerici, o unitate înseamnă unu.
Operatorul % are ca rol obţinerea restului unei împărţiri întregi. Operatorul / are efect
diferit, în funcţie de tipul operanzilor:
a. dacă cel puţin un operand este de tip real, se execută împărţire reală;
b. dacă ambii operanzi sunt întregi, se execută împărţire întreagă şi se obţine câtul.
Calculul câtului şi restului unei împărţiri întregi se poate realiza şi prin intermediul
funcţiei div. Rezultatul funcţiei are tipul div_t, definit în biblioteca stdlib.h astfel:
typedef struct {long int quot; //cît
long int rem; //rest
} div_t;
Exemplu:
Determinarea câtului (cat) şi restului (rest) împărţirii numărului m la numărul n se realizează astfel:
div_t x;
int m,n,cat,rest;
x=div(m,n);
cat=x.quot;
rest=x.rem;

4.3.4. Operatorii logici şi relaţionali
Expresiile logice sunt cele care, în urma evaluării produc, în interpretarea programatorului,
valorile adevărat sau fals. Astfel de valori sunt produse de două categorii de operatori: operatori
logici propriu-zişi şi operatori relaţionali.
Operatorii logici sunt prezentaţi în tabelul 4.4. (în ordinea priorităţii) iar operatorii relaţionali în
tabelul 4.5.
Tabelul 4.4. Operatorii logici
Semnificaţie operaţie Operator
Negare !
Şi logic &&
Sau logic ||
Sau exclusiv logic Nu există

În limbajul C nu există tipul de dată logic. Operanzii asupra cărora se aplică operatorii
logici sunt convertiţi în valori numerice şi interpretaţi conform convenţiei: adevărat pentru
valoare nenulă şi fals pentru zero. Rezultatul unei operaţii logice este de tip int, conform
convenţiei: pentru adevărat valoarea 1 iar pentru fals valoarea 0.
Bazele programării 64


La evaluarea expresiilor logice se aplică principiul evaluării parţiale: dacă expresia este de
tip aditiv (operanzi legaţi prin operatorul sau), în momentul în care s-a stabilit că un operand are
valoarea adevărat toată expresia va fi adevărată şi nu se mai evaluează restul operanzilor.
Asemănător, pentru o expresie multiplicativă (operanzi legaţi prin operatorul şi), dacă un operand
are valoarea fals, expresia are valoarea fals şi nu se mai evaluează restul operanzilor.
Operaţia sau exclusiv între doi operanzi a şi b se efectuează cu expresia !a&&b||!b&&a,
conform tabelului următor:

a b !a !b !a&&b !b&&a !a&&b||!b&&a
0 0 1 1 0 0 0
≠ 0 ≠ 0 0 0 0 0 0
≠ 0 0 0 1 0 1 1
0 ≠ 0 1 0 1 0 1

Operatorii relaţionali sunt prezentaţi în tabelul 4.5. Operatorii relaţionali au acelaşi nivel de
prioritate.
Rezultatul unei operaţii relaţionale este de tip int, conform convenţiei: pentru adevărat valoarea 1,
iar pentru fals valoarea 0.
Pentru a nu se greşi la evaluarea unor expresii complexe, este indicat să se facă raţionamentul
bazat pe logica booleană (cu valori de adevărat şi fals).

Tabelul 4.5. Operatorii relaţionali
Semnificaţie operaţie Operator
Mai mare >
Mai mare sau egal >=
Mai mic <
Mai mic sau egal <=
Egal ==
Diferit !=

4.3.7. Operatorii la nivel de bit
Limbajul permite operaţii pe biţi, ai căror operatori sunt prezentaţi în tabelul 4.6.
Tabelul 4.6. Operaţii pe biţi
Semnificaţie operaţie Operator
Şi logic pe biţi &
Sau logic pe biţi |
Sau exclusiv logic pe biţi ^
Negare (complement faţă de 1) ~
Deplasare la dreapta >>
Deplasare la stânga <<

Bazele programării 65


Operanzii pot fi de orice tip întreg. Dacă este nevoie, operanzii sunt extinşi la reprezentare pe 16
biţi. Execuţia are loc bit cu bit. Pentru o pereche de biţi (x,y), valorile posibile rezultate în urma
aplicării operatorilor logici la nivel de bit sunt prezentate în tabelul 4.7.

Tabelul 4.7 Rezultatele operaţiilor logice pe biţi
x y x&y x|y x^y ~x
0 0 0 0 0 1
0 1 0 1 1 1
1 0 0 1 1 0
1 1 1 1 0 0
Tot în categoria operaţiilor la nivel de bit se încadrează şi deplasările binare la stânga sau
la dreapta a conţinutului unei variabile întregi:
operand<<număr_poziţii şi operand>>număr_poziţii
Exemplu:
1. Următoarea secvenţă afişează, în ordine inversă, biţii unui octet (dată de tip char).
char c;
scanf("%d",&c);
for(int i=0;i<8;i++,c=c>>1)
printf("%d",c&1);

4.3.6. Operatorul virgulă (,)
Operatorul virgulă este specific limbajului C. Pe lângă rolul de separator într-o listă, virgula este
considerată şi operator într-o secvenţă de forma:
expresie_1, expresie_2, ..., expresie_n

Operatorul virgulă (,) induce evaluarea succesivă a expresiilor, de la stânga la dreapta,
întreaga secvenţă fiind tratată ca o expresie căreia i se atribuie în final valoarea şi tipul
corespunzătoare ultimei expresii evaluate (expresie_n). Operatorul se utilizează acolo unde este
legal să apară o expresie în program şi se doreşte realizarea unui calcul complex, exprimat prin
mai multe expresii.
Exemple:
int a=10, b=3, c, d;
d=(c=a+b, b+=c, a/2);
Valorile variabilelor după evaluarea expresiei sunt: a=10, c=13, b=16, d=5 (câtul împărţirii lui 10 la 2).

4.3.7. Operatorul de conversie explicită
Limbajul oferă posibilitatea conversiei explicite a tipului unei expresii către un tip dorit de
utilizator (dar compatibil). Expresia de conversie are forma generală:
(tip)operand
Se observă că operatorul nu are un simbol explicit. El este format din numele unui tip de
dată inclus între paranteze. Construcţia este numită expresie cast (conversia explicită se numeşte
typecast). Trebuie reţinut că nu se schimbă efectiv tipul operandului, doar se foloseşte în expresie
valoarea operandului convertită la un alt tip. Operaţia de conversie de tip nu are efect permanent.
Exemplu:
int a=7;
float b=(float)a;

Bazele programării 66


După execuţia secvenţei, a are valoarea 7 (nu 7.0) nefiind afectată în nici un fel de operaţia de conversie
de tip, iar b are valoarea 7.0 (obţinută prin conversia valorii lui a către tipul float).

4.3.8. Operatorul dimensiune
Operatorul dimensiune este folosit pentru a afla dimensiunea în octeţi a spaţiului de memorie
ocupat de o variabilă de sau definit de un tip. Operatorul are mnemonica sizeof şi poate fi folosit
în una din formele:
sizeof var sau sizeof(var)sau sizeof(tip)
unde tip este numele unui tip de dată iar var poate fi numele unei variabile simple, numele unui
masiv, numele unui articol, un element al unui masiv sau un câmp al unui articol.
În primele două forme, rezultatul va fi numărul de octeţi alocaţi entităţii respective. Pentru
ultima formă, rezultatul este numărul de octeţi pe care îi va ocupa o variabilă de tipul tip.

4.3.9. Operatorii paranteze
Parantezele au rolul de a include o expresie sau lista de parametri ai funcţiilor. Prin includerea
subexpresiilor între paranteze se modifică ordinea de evaluare a unei expresii. Asupra unei
expresii între paranteze nu se pot aplica orice operatori (de exemplu nu se pot aplica operatorii de
incrementare sau decrementare).
La apelul unei funcţii, parantezele rotunde „()” sunt numite operatori de apel de funcţie,
ele delimitând lista parametrilor reali. Parantezele pătrate „[]” au rolul de a include expresii care
reprezintă indici pentru accesarea elementelor unui masiv. Ele se numesc operatori de indexare.

4.3.10. Operatorul condiţional
Operatorul condiţional este singurul care are trei operanzi şi este specific limbajului C. Forma
generală este:
expresie_1?expresie_2:expresie_3
unde expresie_1, expresie_2 şi expresie_3 sunt expresii. Operatorul condiţional are simbolul ?:.
Cele două caractere care compun simbolul apar intercalate între cei trei operanzi, conform formei
generale. Construcţia se numeşte expresie condiţională. Valoarea şi tipul acestei expresii sunt
identice cu cele ale expresie_2 (dacă expresie_1 este adevărată) sau cu cele ale expresie_3 (dacă
expresie_1 este falsă).

4.3.11. Alţi operatori
Din categoria operatorilor limbajului fac parte şi următorii:
a. operatorul de calificare, cu simbolul . (caracterul punct), folosit pentru a accesa un câmp
al unui articol;
b. operatorul de calificare (cu simbolul ->) folosit pentru a accesa un câmp atunci când se
ştie adresa unei structuri;
c. operatorul de referenţiere (cu simbolul &) folosit pentru a extrage adresa unei variabile;
d. operatorul de referenţiere (cu simbolul *) folosit pentru a defini un pointer;
e. operatorul de dereferenţiere (cu simbolul *) folosit pentru a extrage valoarea de la o
anumită adresă.
Ultimii patru operatori sunt specifici lucrului cu adrese (care nu face obiectul prezentei
lucrări).

4.3.12. Evaluarea expresiilor
Expresiile sunt evaluate pe baza următoarelor reguli:
- Precedenţa: determină ordinea de efectuare a operaţiilor într-o expresie în care intervin
mai mulţi operatori (gradul de prioritate);
Bazele programării 67


- Asociativitatea: indică ordinea de efectuare a operaţiilor în cazul unui set de operatori cu
aceeaşi precedenţă;
- Regulile de conversie de tip: asigură stabilirea unui tip comun pentru ambii operanzi,
pentru fiecare operaţie care solicită acest lucru şi în care tipurile diferă.
Asociativitatea şi precedenţa operatorilor (începând cu prioritatea maximă) sunt redate în
tabelul 4.8.
În concluzie, expresiile care pot fi construite în limbajul C se încadrează în următoarele
categorii: expresii de atribuire, expresii aritmetice, expresii logice, expresii relaţionale.

Tabelul 4.8. Precedenţa operatorilor
Operatori Asociativitate
Grad de
prioritate
() [] . -> de la stânga la dreapta maxim
+ - & *
(unari) ++ --
(tip) sizeof !
~
de la dreapta la stânga
* (binar) / %
+ - (binari)
<< >>
< <= > >=
== !=
& (binar)
^
|
&&
||
?:
de la stânga la dreapta
= <<= >>=
+= -= *= /=
%= &= ^= |=
de la dreapta la stânga

, de la stânga la dreapta minim


Teste de autoevaluare





4. Specificaţi care va fi valoarea variabilei c.
int a=7,b=9,c;
c=(a>b)?a:b;
5. Scrieţi secvenţele echivalente pentru următoarele exemple:
y=x++;
y=--x;

Bazele programării 68


4.4. Realizarea structurilor fundamentale de control

4.4.1. Tipurile de instrucţiuni
Instrucţiunile unui program C se grupează într-un bloc delimitat de o pereche de acolade {}.
Instrucţiunile se încheie cu caracterul ; (punct şi virgulă), care este terminator de instrucţiune şi
este obligatoriu pentru a marca sfârşitul fiecăreia.
Un program trebuie să execute cel puţin o instrucţiune, chiar dacă, la limită, aceasta este
vidă. În limbajul C, un program se regăseşte sub forma unei funcţii rădăcină, care, la limită, poate
avea un corp vid:
void main() {}
După modul de realizare a construcţiilor sintactice şi al numărului de acţiuni descrise, se
disting instrucţiuni simple şi structurate. De asemenea, pot fi create blocuri de instrucţiuni execu-
tabile, denumite instrucţiuni compuse.
O instrucţiune compusă este o secvenţă de instrucţiuni (simple, structurate sau compuse)
delimitată de perechea de acolade {}. Ea implementează natural structura secvenţială din
programarea structurată. Mulţimea instrucţiunilor executabile ale unui program este, la limită, o
instrucţiune compusă. Orice instrucţiune (simplă sau structurată) poate fi transformată în
instrucţiune compusă.
O instrucţiune este simplă dacă descrie o singură acţiune, unic determinată şi care nu
provoacă condiţionări. Din categoria instrucţiunilor simple fac parte, de exemplu: instrucţiunea
vidă, instrucţiunea de evaluare a unei expresii, goto, break, continue, return.
Instrucţiunile structurate sunt construcţii care conţin alte instrucţiuni (simple, compuse
sau structurate) care vor fi executate alternativ sau repetitiv. Corespunzător, prin instrucţiunile
structurate se codifică structurile fundamentale alternative sau repetitive din algoritm.
Pe lângă instrucţiunile care implementează conceptele programării structurate, C conţine
şi instrucţiuni care contravin acestora, datorită orientării limbajului spre compactarea textului
sursă şi spre neconformism în stilul de programare impus de autori.

4.4.2. Instrucţiunile simple
Instrucţiunea vidă descrie acţiunea vidă. în C nu are o mnemonică explicită, fiind dedusă din
contextul unor construcţii sintactice. Ea se foloseşte acolo unde trebuie să apară o instrucţiune,
dar care nu trebuie să execute nimic. Situaţia este întâlnită de obicei în cazul instrucţiunilor
structurate.
Exemple:
if (c==1) ; else c=2;
instrucţiune vidă ↑
if (c==1) ; else ;
instrucţiuni vide ↑ ↑
{;}
instrucţiune vidă ↑

Instrucţiunea de tip expresie evaluează o expresie care, în cele mai dese cazuri, este de atribuire
sau de apel al unei funcţii (vezi şi capitolul Operatori şi expresii). Instrucţiunea de tip expresie se
obţine scriind terminatorul de instrucţiune după o expresie (acolo unde este legal să apară o
instrucţiune în program). Forma generală este:
expresie;

4.4.3. Instrucţiunea compusă
Bazele programării 69


Instrucţiunea compusă este o succesiunea de instrucţiuni şi declaraţii, cuprinse între o pereche de
acolade. Se preferă ca declaraţiile să fie plasate înaintea instrucţiunilor. Forma generală este:
{declaratii
instructiuni}
Declaraţiile sunt valabile în interiorul instrucţiunii compuse. Instrucţiunea compusă se
utilizează acolo unde este nevoie să se execute mai multe acţiuni, dar sintaxa impune prezenţa
unei singure instrucţiuni: mai multe instrucţiuni sunt „transformate” într-o singură instrucţiune
(compusă). Situaţia este întâlnită în cadrul instrucţiunilor if, while, do, for, care precizează, în
sintaxa lor o singură instrucţiune.

4.4.4. Instrucţiunile structurate
În continuare, prin instrucţiune se înţelege o instrucţiune simplă, compusă sau structurată.

Realizarea structurilor alternative
a) Structura alternativă simplă (figura 4.2) permite realizarea unei ramificări logice binare, în
funcţie de valoarea unei condiţii (expresie cu rezultat logic). Instrucţiunea care realizează această
structură este if :
if(expresie)instrucţiune_1;
[else instrucţiune_2];


adevărat
condiţie
fals
Instrucţiune 2 Instrucţiune 1

Fig. 4.2. Structura alternativă simplă

Expresia poate fi de orice tip. Dacă valoarea expresiei este diferită de zero (valoare
asociată din punct de vedere logic cu adevărat) se execută instrucţiune_1; în caz contrar se
execută instrucţiune_2 sau se iese din structură (când construcţia else lipseşte, caz în care
instrucţiunea if realizează structura pseudoalternativă).
Exemple:
1) if(a>b) a=c;
else a=b;
2. Rezolvarea ecuaţiei de gradul I, ax+b=0:
a ? printf("Solutia este %10.5f",(float)-b/a) : b ? printf("Ecuatia nu are solutii") : printf("Solutii: orice x real");

b) Structura alternativă multiplă permite alegerea unei acţiuni dintr-un grup, în funcţie de
valorile pe care le poate lua un selector (figura 9.2). În limbajul C structura se simulează cu
instrucţiunea switch, a cărei sintaxă este:

switch(expresie)
{case c_1: instrucţiuni_1;
case c_2: instrucţiuni_2;
………………
case c_n: instrucţiuni_n;
[default: instrucţiuni;]}
Bazele programării 70



unde: expresie este de tip întreg; c_1, c_2, …, c_n sunt expresii constante, de tip int, unice (o
valoare nu poate să apară de două sau mai multe ori); instrucţiuni_1, instrucţiuni_2, ...,
instrucţiuni_n, instrucţiuni sunt simple, compuse sau structurate. Dacă pe o ramură sunt mai
multe instrucţiuni, nu este nevoie să fie incluse între acolade (să fie instrucţiune compusă).
Instrucţiunea switch evaluează expresia dintre paranteze, după care caută în lista de
expresii constanta cu valoarea obţinută. Dacă este găsită, se execută instrucţiunile asociate valorii
respective şi, secvenţial, toate instrucţiunile care urmează, până la terminarea structurii de
selecţie. Dacă valoarea căutată nu este găsită în listă şi ramura default este prezentă, se execută
instrucţiunile asociate acesteia. Dacă ramura default lipseşte nu se execută nimic. Pentru a limita
acţiunea strict la execuţia instrucţiunilor asociate unei valori, trebuie inclusă instrucţiunea break,
care determină ieşirea din structura switch.
Pentru a simula structura din figura 4.3 se scrie:
switch(expresie)
{case c_1: instrucţiuni_1; break;
case c_2: instrucţiuni_2; break;
………………
case c_n: instrucţiuni_n; break;
[default: instrucţiuni;]}

selector
instrucţiune 1 instrucţiune 2 instrucţiune n … instrucţiune
selector = v1
selector = v2 selector = vn altfel


Fig. 4.3. Structura alternativă multiplă

Realizarea structurilor repetitive
a) Structura repetitivă condiţionată anterior este implementată prin instrucţiunea while cu forma
generală:
while (expresie) instrucţiune;

Instrucţiunea while se execută astfel: se evaluează expresia şi dacă este diferită de zero
(adevărată) se execută instrucţiunea (simplă, compusă sau structurată), apoi se reia procesul până
când la evaluarea expresiei se obţine valoarea zero. În acest moment se încheie execuţia
instrucţiunii while. Pentru a asigura ieşirea din ciclu, instrucţiunea trebuie să modifice valoarea
expresiei.
Dacă la prima evaluare a expresiei se obţine valoarea zero, atunci nu se execută nimic.
Instrucţiunea while implementează natural structura corespunzătoare din teoria programării
structurate. Mecanismul de execuţie este redat în figura 4.4.
Bazele programării 71



= 0
(fals)
expresie
instrucţiune
≠ 0 (adevărat)


Fig. 4.4. Mecanismul de execuţie a instrucţiunii while
Exemple:
1. while (a>b)
a=a+1;
2. i=0;
while (i<n)
{printf("\n %4.2f",v[i]);
i=i+1;}

b) Structura repetitivă condiţionată posterior este implementată (cu unele deosebiri faţă
de teoria programării structurate), prin intermediul instrucţiunii do-while. Forma generală este:
do instrucţiune
while (expresie);
Instrucţiunea do-while se execută astfel: se execută instrucţiune apoi se evaluează
expresia; dacă expresia este nenulă (adevărată), se repetă procesul, altfel se încheie execuţia.
Mecanismul de execuţie este redat în figura 4.5. Se observă că instrucţiunea do-while se abate de
la teoria programării structurate, realizând repetiţia pe condiţia adevărat, în timp ce structura
fundamentală o realizează pe condiţia fals.

= 0 (fals)
expresie
instrucţiune
≠ 0 (adevărat)

Fig. 4.5. Mecanismul de execuţie a instrucţiunii do-while

Instrucţiunea do-while este echivalentă cu secvenţa:
instrucţiune;
while(expresie) instrucţiune;
Exemple:
1. do a=a+1; while (a<=100);
2. #include <stdio.h>
main()
{ unsigned i;
i=1;
do
{ printf("+");
printf("-");
i++;}
while(i<=80);}

Bazele programării 72


c) Structura repetitivă cu numărător nu este implementată în C. Ea poate fi simulată prin
instrucţiunea for, care, datorită facilităţilor deosebite pe care le oferă, poate fi considerată ca o
instrucţiune repetitivă cu totul particulară, nedefinită în teoria programării structurate. Ea este mai
apropiată de structura while-do. Instrucţiunea for din C are următoarea formă generală:
for(expresie_1; expresie_2; expresie_3)instrucţiune;
Instrucţiunea for se execută astfel: se evaluează expresie_1; se evaluează expresie_2 şi
dacă este nulă (fals), se încheie execuţia lui for, altfel se execută instrucţiune apoi se evaluează
expresie_3. Se revine la evaluarea lui expresie_2 ş.a.m.d. Instrucţiunea for realizează structura
repetitivă din figura 4.6 şi poate fi înlocuită cu secvenţa:
expresie1;
while (expresie2)
{ instrucţiune;
expresie3;}


=0 (fals)
expresie 2
expresie 1
≠ 0 (adevărat)
expresie 3
instrucţiune

Fig. 4.6. Mecanismul de execuţie a instrucţiunii for

Pentru a simula structura repetitivă cu numărător (do-for) se folosesc forme particulare
pentru cele trei expresii:
expresie_1 va fi expresia de iniţializare: contor=valoare iniţială;
expresie_2 controlează terminarea ciclului: contor<valoare finală;
expresie_3 realizează avansul contorului: contor=contor+pas.
Exemplu:
/*citirea elementelor unui vector*/
#include <stdio.h>
void main()
{ float v[20];
int n,i;
printf("\n Nr. de elemente:");
scanf("%i",&n);
for(i=0;i<n;i++)
{ printf("\n v[%i]=",i+1);
scanf("%f",&v[i]);}
}

4.4.5. Instrucţiunile de salt necondiţionat şi ieşire forţată din structuri
Instrucţiunile de salt necondiţionat şi ieşire forţată din structuri contravin principiilor programării
structurate, dar pot fi utilizate în măsura în care, în aplicaţii complexe, uşurează munca
programatorului.

Prin instrucţiunea continue, care se poate folosi numai în interiorul unei structuri
repetitive, se abandonează iteraţia curentă şi se trece la următoarea. Forma ei este:
continue;
Bazele programării 73


Instrucţiunea are următoarele efecte:
• în interiorul instrucţiunilor while şi do-while: se abandonează iteraţia curentă şi se trece la
evaluarea expresiei care controlează terminarea buclei.
• în interiorul instrucţiunii for: se abandonează iteraţia curentă şi se trece la evaluarea
parametrului expresie_3.

Instrucţiunea break este folosită numai în interiorul unei instrucţiuni structurate şi are
ca efect terminarea imediată a execuţiei instrucţiunii respective.

Instrucţiunea goto realizează salt necondiţionat şi este moşnită din primele limbaje de
programare, care nu foloseau principiile programării structurate. Forma generală este:
goto etichetă;
O etichetă este un identificator urmat de caracterul : (două puncte), după care urmează o
instrucţiune. Rolul unei etichete este de a defini un punct de salt, către care se poate face trimitere
prin instrucţiunea goto. Etichetele au valabilitate locală, în corpul funcţiei în care sunt definite.
Din acest motiv, nu se poate face salt din corpul unei funcţii la o instrucţiune aflată în altă
funcţie.

Test de autoevaluare






6. Care din următoarele secvenţe nu realizează suma a n elemente ale unui vector:
a) s=0; for(i=0; i<n; i++) s+=x[i]; b) s=0; for(i=n-1; i>=0; i--) s+=x[i]; c) s=0; i=0; while
(i<n) {s+=x[i]; i++;} ; d) s=0; i=n-1; while (i>0) {s+=x[i]; i--;} ; e) s=0; i=0; do { s+=x[i];
i++; } while(i<n);
7. Secvenţa: for(i=0; i<n-1; i++) {z=x[i]; p=i; for(j=i+1; j<n;
j++) if(x[j]<z) {z=x[j]; p=j; } a=x[i]; x[i]=z; x[p]=a; }
realizează:
a) minimul dintr-un vector cu reţinerea poziţiei primei apariţii; b) minimul dintr-un
vector cu reţinerea poziţiei ultimei apariţii; c) sortarea unui vector prin metoda bulelor;
d) sortarea unui vector prin metoda selecţiei; e) căutarea unei valori date într-un vector.
8. Triunghiul de sub diagonala secundară (inclusiv diagonala) unei matrice pătrate se poate
parcurge numai cu secvenţele: 1. for(i=0; i<n; i++) for(j=n-i-1; j<n; j++) ...; 2.
for(i=0; i<n; i++) for(j=n-1; j>=n-i-1; j--) ...; 3. for(i=n-1; i>=0; i--)
for(j=n-i-1; j<n; j++) ...; 4. for(i=n-1; i>=0; i--) for(j=n-1; j>=n-i-1; j-
-) ...; 5. for(j=0; j<n; j++) for(i=n-j-1; i<n; i++) ...; 6. for(j=0; j<n; j++)
for(i=n-1; i>=n-j-1; i--) ...; 7. for(j=n-1; j>=0; j--) for(i=n-j-1; i<n;
i++) ...; 8. for(j=n-1; j>=0; j--) for(i=n-1; i>=n-j-1; i--) do ....
a) 1,2,5 şi 6; b) 3,4,7 şi 8; c) 1,2,3 şi 4; d) 5,6,7 şi 8; e) toate.
9. Următoarele secvenţe descriu algoritmi recursivi: 1) s=0; for(i=n-1; i>=0; i--)
s+=x[i]; 2) for(i=0; i<n; i++) y[i]=x[i]; 3) nr=0; i=0; while(i<n) {if(x[i]>0)
nr+=1; i++; }; 4) for(i=0; i<n; i++) z[i]=x[i]*y[i]; 5) i=0; z=0; do
{z+=x[i]*y[i]; i++;} while(i<n); 6) s=1; for(i=0; i<n; i++) s*=i;
a) toate; b) 1,3,5 şi 6; c) 2,4 şi 6; d) 3 şi 5; e) niciunul.
Bazele programării 74


Răspunsuri şi comentarii la testele de autoevaluare
1. După preprocesare, secvenţa de cod va deveni:
char v[10],v1[10+(5+10)*(6)];
char v1[10*(10+10)];
char m[10][10];
2. Articolul se declară astfel:
struct magazin {int cod_magazin;
float vanzari_lunare[12];
}articol;
Articolul are 50 de octeţi, iar referirea câmpurilor se realizează astfel:
articol.cod_magazin; articol.vanzari_lunare[i], cu i=0,1,…,11.

#include <stdio.h>
void main()
{ struct magazin {
int cod_magazin;
float vanzari_lunare[12]; };
//Initializarea articolului;
struct magazin gigel_srl={200, 1,2,3,4,5,6,7,8,9,10,11,12};
//sau cu evidentierea structurii de masiv:
struct magazin gigel_srl1={200, {1,2,3,4,5,6,7,8,9,10,11,12}};
printf("\n%6.2f",gigel_srl1.vanzari_lunare[10]);
3. Declararea şi iniţializarea câmpurilor unui student la zi pentru structura
prezentată se realizează astfel:
#include <stdio.h>
void main()
{ //Declararea articolului cu structura variabila:
struct articol { char nume[40];
struct { int zi, luna, an;} datan;
int an_st; char forma_inv;
union { struct {char bursa; float valoare;}zi;
struct {char loc_m[30];
struct {int zi, luna, an;}data_ang;
}id; } parte_vb; };
//Initializarea campurilor unui student la zi:
struct articol a={"Popescu Felix",{4,1,1974},1,'Z',{'D',250.5}};
printf("\nData nasterii: %i.%i.%i, Forma de inv.: %c, Val. bursa: %6.2f",
a.datan.zi, a.datan.luna, a.datan.an, a.forma_inv, a.parte_vb.zi.valoare); }
4. Variabila c primeşte valoarea maximă dintre a şi b, anume 9.
5. y=x++; este echivalent cu secvenţa y=x; x=x+1;
y=--x; este echivalent cu secvenţa x=x-1; y=x;
6:d); 7:d); 8:e); 9:b).

Bazele programării 75


Bibliografia unităţii de învăţare

1. I. Gh. Roşca, B. Ghilic-Micu, C. Cocianu, M. Stoica, C. Uscatu, M. Mircea, L. Bătăgan, C. Silvestru,
Bazele programării calculatoarelor. Teorie şi aplicaţii în C, Ed. ASE, Bucureşti, 2006, ISBN 973-594-591-
6
2. I. Gh. Roşca, B. Ghilic-Micu, C. Cocianu, M. Stoica, C. Uscatu, Programarea calculatoarelor. Ştiinţa
învăţării unui limbaj de programare, Teorie şi aplicaţii, Ed. ASE, 2003
3. Ion Smeureanu, Marian Dârdală, Programarea în limbajul C/C++, Ed. CISON, Bucureşti 2004, ISBN
973-99725-7-8

Bibliografie
1. I. Gh. Roşca, B. Ghilic-Micu, C. Cocianu, M. Stoica, C. Uscatu, M. Mircea, L. Bătăgan, C. Silvestru,
Bazele programării calculatoarelor. Teorie şi aplicaţii în C, Ed. ASE, Bucureşti, 2006, ISBN 973-594-591-
6
2. I. Gh. Roşca, B. Ghilic-Micu, C. Cocianu, M. Stoica, C. Uscatu, Programarea calculatoarelor. Ştiinţa
învăţării unui limbaj de programare, Teorie şi aplicaţii, Ed. ASE, 2003
3. Ion Smeureanu, Marian Dârdală, Programarea în limbajul C/C++, Ed. CISON, Bucureşti 2004, ISBN
973-99725-7-8
4. Roşca Gh. I., Ghilic-Micu B., Stoica M., Cocianu C., Uscatu C., Programarea calculatoarelor.
Ştiinţa învăţării unui limbaj de programare. Teorie şi aplicaţii, Ed. ASE, Bucureşti 2003, ISBN
973-594-243-7

TITLUL CURSULUI: Bazele programării INTRODUCERE
Cursul de Bazele programării se adresează studen ilor înscrişi la programul de studiu ID, organizat de facultatea Cibernetică, Statistică şi Informatică Economică şi face parte din planul de învă ământ aferent anului I, semestrul II. Pentru o bună în elegere a no iunilor teoretice şi practice prezentate în acest curs, este recomandat să se fi parcurs anterior disciplina Bazele tehnologiei informa iei. OBIECTIVELE PRINCIPALE ale acestui curs, vizează însuşirea de către studen i a următoarelor elemente: • no iuni de bază în teoria programării; • metodele de analiză a problemelor în vederea rezolvării lor cu calculatorul; • logica elaborării algoritmilor structura i şi modulariza i; • realizarea programelor în limbajul C. Cursul Bazele programării este structurat în patru unită i de învă are, corespunzătoare elementelor principale studiate. În cadrul procesului de instruire pot fi utilizate ca resurse suplimentare materialele puse la dispozi ie de bibliotecile Academiei de Studii Economice, precum şi laboratoarele catedrei de Informatică economică, cu o programare prealabilă şi atunci când nu se desfăşoară ore. EVALUAREA CUNOŞTIN ELOR, respectiv stabilirea notei finale, se va realiza astfel: • lucrare de control; • un referat despre opera iile de intrare/ieşire efectuate cu tastatura/monitorul; • un proiect, care va con ine minim 20 de programe în limbajul C, lucru cu masive de date, înso ite de un dosar de prezentare. Lucrarea va fi sus inută în cadrul ultimei activită i asistate. Referatul şi proiectul se sus in numai în timpul activită ii didactice (activită ilor asistate), conform calendarului disciplinei. Stabilirea notei finale se va realiza astfel: • lucrarea de control constituie 50% din nota finală; • referatul constituie 10% din nota finală; • proiectul constituie 30% din nota finală; • din oficiu se acordă 10%.

Cuprins

1.

Algoritmi şi scheme logice ..................................................................................................4 Obiectivele unită ii de învă are 1................................................................................................. 4 1.1. Caracteristicile şi reprezentarea algoritmilor........................................................................ 4 1.2. Descrierea structurilor fundamentale ................................................................................. 10 1.3. Structurarea şi proiectarea algoritmilor .............................................................................. 13 Răspunsuri şi comentarii la testele de autoevaluare .................................................................. 17 Bibliografia unită ii de învă are................................................................................................. 17

2. Organizarea internă a datelor.....................................................................................................18 Obiectivele unită ii de învă are 2............................................................................................... 18 2.1. Informa ia, data şi reprezentarea internă a datelor ............................................................. 18 2.2. Structuri de date.................................................................................................................. 27 Răspunsuri şi comentarii la testele de autoevaluare .................................................................. 39 Bibliografia unită ii de învă are................................................................................................. 39 3. Etapele rezolvării problemelor cu calculatorul..........................................................................40 Obiectivele unită ii de învă are 3............................................................................................... 40 3.1. Caracteristici generale ale PPAD ....................................................................................... 40 3.2. Fazele dezvoltării programelor........................................................................................... 44 Răspunsuri şi comentarii la testele de autoevaluare .................................................................. 46 Bibliografia unită ii de învă are................................................................................................. 46 4. Caracteristicile limbajului C......................................................................................................47 Obiectivele unită ii de învă are 4............................................................................................... 47 4.1 Elementele de bază ale limbajului C ................................................................................... 47 4.2 Tipurile de date în C ............................................................................................................ 51 4.3 Expresii................................................................................................................................ 60 4.4. Realizarea structurilor fundamentale de control................................................................. 68 Răspunsuri şi comentarii la testele de autoevaluare .................................................................. 74 Bibliografia unită ii de învă are................................................................................................. 75 Bibliografie....................................................................................................................................75

Bazele programării 4 1.x∈ℜ. într-o manieră fără ambiguită i sau neclarită i. a≠0 sau. structurarea algoritmilor. pentru rezolvarea ecua iei de forma ax2+bx+c=0. lucru impus de caracterul de automat al calculatorului electronic. cu parametrii a.x∈ℜ. mai general.c. Principalele caracteristici ale unui algoritm sunt: Generalitate: un algoritm nu trebuie conceput pentru o problemă particulară. Caracteristicile şi reprezentarea algoritmilor 1. studen ii vor avea cunoştin e teoretice şi abilită i practice despre: caracteristicile algoritmilor. Descrierea structurilor fundamentale 1. Structurarea şi proiectarea algoritmilor Răspunsuri şi comentarii la testele de autoevaluare Bibliografia unită ii de învă are Obiectivele unită ii de învă are 1 Dupa studiul acestei unitati de învatare. ci un algoritm pentru rezolvarea ecua iei de gradul al doilea cu o necunoscută ax2+bx+c=0. reprezentarea algoritmilor. . Exemplu: Determinare (claritate): algoritmul trebuie să prevadă modul de solu ionare a tuturor situa iilor care pot apărea în rezolvarea problemei respective. ci pentru o clasă generală de probleme. pentru a ob ine solu ia.c.1.3. împreună cu succesiunea în care trebuie aplicate asupra datelor ini iale ale problemei. Durata medie a unită ii de studiu individual . Nu se va concepe un algoritm pentru rezolvarea ecua iei particulare 5x2-2x=7.8 ore 1. descrierea structurilor fundamentale.2.b.1. proiectarea algoritmilor. Algoritmi şi scheme logice Cuprins Obiectivele unită ii de învă are 1 1.b. Caracteristicile şi reprezentarea algoritmilor Algoritmul desemnează o mul ime exhaustivă şi univoc determinată de opera ii. cu a.

formula de recuren ă S = S + bi se repetă de n ori (număr cunoscut de paşi). factorialul. Exemple: Pentru însumarea tuturor elementelor unui vector B. de fiecare dată cu alte valori de intrare. respectiv multirecursiv. Indiferent de situa ie. După cum valoarea curentă a variabilei depinde de una sau mai multe valori anterioare. Recursivitatea este procesul iterativ prin care valoarea unei variabile se determină pe baza uneia sau mai multora dintre propriile ei valori anterioare. ecua ie de gradul II. alteori singura alternativă de a preciza modul de desfăşurare a unui proces de calcul. Numărul de itera ii poate fi cunoscut sau necunoscut. În cazul în care numărul de repetări nu este cunoscut ini ial. Descrierea algoritmilor. cunoscut sau necunoscut. Recursivitatea apare şi în cazuri dintre cele mai simple. cu gradul de aproximare impus unui rezultat. Exemplu: Finitudine: opera iile trebuie astfel concepute încât algoritmul să se termine într-un număr finit de paşi. Recursivitatea presupune definirea uneia sau mai multor formule de start (în func ie de numărul valorilor anterioare de care depinde valoarea curentă) şi a unei formule recursive (de recuren ă). 4. de la 1 la o valoare finală N. dar determinabil pe parcursul execu iei. cu n variind de la o execu ie a programului la alta. Iterativitate şi recursivitate Iterativitatea este procesul prin care rezultatul este ob inut ca urmare a execu iei repetate a unui set de opera ii. . de cele mai multe ori fiind corelate cu viteza de convergen ă a calculelor către o valoare stabilă şi. a = 0 şi b = 0 şi c ≠ 0. singura modalitate de descriere a algoritmului presupune iterativitatea. a. În general. plasată întrun ciclu variind după I. La determinarea celui mai mare divizor comun (CMMDC) dintre două numere întregi (A şi B) se împarte A la B: A=B·Q+R.x∈ℜ. deoarece un algoritm este corect dacă are preciza i to i paşii. Analiza arată că există patru situa ii posibile care trebuie cuprinse în algoritm: 1. Spre exemplu. a = 0 şi b = 0 şi c = 0. procesul este unirecursiv. apoi se continuă împăr irea împăr itorului (B) la rest (R). până când se ob ine un rest nul. caz în care CMMDC este ultimul împăr itor (număr necunoscut de paşi).Bazele programării 5 Să se elaboreze algoritmul pentru rezolvarea ecua iei: ax2 + bx + c = 0. implicit. când numărul de itera ii nu este cunoscut sau este variabil de la o execu ie la alta. 2. a ≠ 0. nu este posibilă în această manieră. cum ar fi numărarea. ecua ie imposibilă. Condi iile finale ce trebuie îndeplinite pentru terminarea ciclării se bazează pe rezultatele calculelor până la un moment dat. a = 0 şi b ≠ 0. nedeterminare. ridicarea la pătrat a elementelor unui vector cu 3 elemente se poate descrie prin următoarea succesiune de opera ii: V(1)=V(1) · V(1) V(2)=V(2) · V(2) V(3)=V(3) · V(3) Realizarea aceluiaşi lucru pentru un vector n-dimensional. dată explicit de utilizator la fiecare execu ie a programului.b. numărul de itera ii trebuie să fie totdeauna finit. ecua ie de gradul I. 3. Singura modalitate de realizare utilizează opera ia V(I)=V(I) · V(I). Rămâne să fie rezolvate fiecare din aceste situa ii sau unele din ele să fie grupate în func ie de cerin e. oprirea ciclării se face combinând instruc iunile de calcul cu instruc iunile de control.c. Utilizarea iterativită ii în descrierea algoritmilor este uneori o cale simplificatoare. de dimensiune n. însumarea sau înmul irea elementelor unui şir.

.3 şi 4. pentru i=1.4. 2. Un algoritm recursiv este: a) un algoritm care se autoapelează . Dacă se notează v0 = 0 valoarea ini ială. 3.n Când valorile ob inute prin numărare nu necesită păstrarea în memorie. iar ultimul rest ob inut devine împăr itor în itera ia următoare a algoritmului. D  ⋅ I şi se execută I   transferurile: D←I. În procesul descris anterior se disting: v0 = 0 ► formula de start vi = vi-1 + 1 ► formula recursivă. d) un proces repetitiv prin care valoarea unei variabile se determină pe baza a cel pu in uneia dintre valorile ei anterioare. se calculează restul R←D. Practic. 5.. I←R. vn = vn─1+1 Valoarea care interesează este vn.3 şi 4. Procesul iterativ continuă până se ob ine restul zero..Bazele programării 6 Exemple: A număra înseamnă a adăuga o unitate la valoarea anterior calculată.n Utilizarea mai multor zone de memorie pentru calculele intermediare devine obligatorie în situa ia multirecursivită ii. Ultimul rest nenul reprezintă cel mai mare divizor comun al numerelor A şi B...  rk +1 cu r0 = A. Complementaritate. I←b.2. Teste de autoevaluare 1. Generalitate. formulele de start devin: D←a. c) 1. prin transferul dinamic al valorilor intermediare.... cu I variabila împăr itor şi cu R restul. sunt necesare atâtea zone de memorie câte valori precedente sunt necesare calculului termenului curent.5 şi 6. r1 = B şi k = 0. Caracteristicile oricărui algoritm sunt: 1. 4.2. e) 1. . 2. vi = vi-1 + 1 .. Iterativitate. a) toate.5 şi 6. Finitudine. ci una singură.. e) un proces alternativ prin care valoarea unei variabile se determină pe baza a cel pu in uneia dintre valorile ei anterioare. după rela ia: r k + 2 = r k . numărarea se desfăşoară după următorul proces recursiv: v1 = v0 + 1 v2 = v1 + 1 v3 = v2 + 1 . Dacă se notează cu D variabila deîmpăr it. Iterativ. Claritate. d) 1.. Recursivitate..3.. 6.  rk   ⋅ r k +1 . c) un proces repetitiv dinamic. Exemplu: Algoritmul lui Euclid pentru determinarea celui mai mare divizor comun a două numere A şi B. pentru i=1.. Împăr itorul devine noul deîmpăr it. b) un proces repetitiv static. nu sunt necesare mai multe loca ii. Restul curent se calculează pornind de la ultimul şi penultimul rest. Ultimul rest nenul reprezintă cel mai mare divizor comun.. care va fi suprascrisă la fiecare itera ie: ► formula de start V=0 V=V+1 ► formula recursivă. b) 1.2... Prin [ ] s-a notat partea întreagă a expresiei.1.

deoarece oferă o „vizualizare” mai bună... C2. În graf sunt admise următoarele blocuri: Blocul START este un arc etichetat cu cuvântul START.. Pentru cazul n=2 se poate scrie. Ea se dovedeşte utilă.. în care caz extremitatea ini ială a arcului este extremitatea ini ială a unui bloc de ramifica ie. a algoritmilor. n Rela iile exprimă faptul că unul şi numai unul din aceste predicate poate fi satisfăcut (adevărat). care poate fi adevărată (1) sau falsă (0)). în special. în ini ierea în programare. uşor de urmărit. arce etichetate cu predicatele C1. echivalent: c c Nu c Da Defini ie: Se numeşte schemă logică un graf orientat în care: a) Există un singur bloc START şi un singur bloc STOP. deoarece din el nu pot pleca arce: STOP Blocul de citire este un arc etichetat cu informa ia: citirea unor valori de pe suportul extern şi înscrierea lor în loca ii de memorie corespunzătoare unor variabile. care satisfac rela iile: C1 ∨ C2 ∨ . b) Orice arc este etichetat cu una din următoarele informa ii: START sau STOP.. o redare expresivă şi sintetică. Ci ∧ Cj = 0. pentru care vârful ini ial nu este pus explicit în eviden ă. o atribuire. Să considerăm un graf orientat în care arcele sunt etichetate cu anumite informa ii formând aşa-zisele blocuri. ∨ Cn = 1.Cn (predicat = condi ie = expresie logică. (∀) i ≠ j. c1 c2 cn . Citeşte listă-de-variabile Blocul de scriere este un arc etichetat cu informa ia: înscrierea pe supotul extern a valorilor memorate în loca iile de memorie corespunzătoare unor variabile: Scrie listă-de-variabile Blocul de atribuire este un arc etichetat cu informa ia: evaluarea unei expresii e şi înscrierea (atribuirea) rezultatului în loca ia de memorie corespunzătoare unei variabile v: v=e sau v←e sau e→v Blocul de ramificare (selec ie) este o mul ime de n arce care pleacă din acelaşi vârf.j= 1. un predicat. pentru care vârful final nu este pus explicit în eviden ă. ..Bazele programării 7 Reprezentarea algoritmilor prin scheme logice Practica programării calculatoarelor dovedeşte că schema logică este forma cea mai utilizată de reprezentare a algoritmilor. o citire sau o scriere. deoarece în el nu pot sosi arce: START Blocul STOP este un arc etichetat cu cuvântul STOP. i...

practica impunând în ultima vreme descrierea lor printr-un text coerent. greu de urmărit. sunt s. Subscheme logice structurate O schemă logică structurată este o s. [Dodescu et al. ob inându-se. (II) Dacă s1 şi s2 sunt s. o atribuire. se ob ine plecând de la (I) şi aplicând de un număr finit de ori regulile (II). greoaie. Defini ie: Se numeşte subschemă logică un graf orientat în care: a) Există un unic vârf ini ial (în care nu sosesc arce) şi un vârf final (din care nu pleacă arce). Oricine poate crea un pseudocod propriu. care este chiar o schemă logică. schema logică structurată (s. iar vârful final este extremitatea finală a blocului STOP. perfect acceptabil. de intrare/ieşire şi de atribuire sunt s.1. este dat de teorema fundamentală a programării structurate (teorema lui Böhm-Jacopini): orice schemă logică este echivalentă cu o schemă logică structurată. atunci extremitatea ini ială (finală) a blocului este chiar vârful ini ial (final). afirmativ.l. STOP. se poate transforma orice schemă logică într-o schemă logică bine structurată? Răspunsul. construit pe baza unor reguli.Bazele programării 8 c) Orice arc face parte din cel pu in un drum care începe cu blocul START şi se termină cu blocul STOP. Există multe variante de metalimbaje. scheme logice structurate. astfel. În particular.l.l. d) Orice arc face parte din cel pu in un drum ce uneşte vârful ini ial cu cel final.1. b) Oricare arc este etichetat cu una din următoarele informa ii: START sau STOP. S1 c S1 c S2 c c S S2 Structura secven ială Structura alternativă IF-THEN-ELSE Structura repetitivă WHILE-DO Fig.s. Se pune întrebarea: se poate genera orice schemă logică folosind numai formele impuse schemelor logice structurate? Sau altfel spus. atunci şi subschemele din figura 1. (cu respectarea condi iilor referitoare la START şi STOP).l. uneori chiar de cel care le-a conceput. cu condi ia ca el să con ină structurile de bază.s. schemele logice alcătuite conform regulilor enun ate anterior pot lua forme foarte complicate. Prin recuren ă. în unele cazuri. o citire sau o scriere.s.s.l. un predicat. suficiente pentru a descrie orice algoritm. În practică.. (III) Orice s.s. c) Dacă subschema con ine blocul START (STOP).) se defineşte astfel: (I) Blocurile START.l.. în care caz extremitatea ini ială a arcului este extremitatea ini ială a unui bloc de ramifica ie.. O astfel de descriere se numeşte metalimbaj (pseudocod). o schemă logică este o subschemă logică în care vârful ini ial este extremitatea ini ială a blocului START.s. 1987] Reprezentarea algoritmilor prin pseudocod Descrierea algoritmilor cu ajutorul schemelor logice se dovedeşte. Evident că şi la pseudocoduri . 1. De aceea s-a sim it nevoia ca în construc ia schemelor logice să se folosească numai anumite configura ii (structuri) şi să se respecte reguli stricte.

Blocurile dintr-o subschemă logică sunt etichetate cu una din informa iile: 1)START. în sensul că o instruc iune se poate scrie pe mai multe rânduri. 9)salt necondi ionat. urmat de o construc ie care desemnează numărul maxim de elemente pe fiecare dimensiune. a)oricare.).3. Instruc iunile executabile într-un program scris în pseudocod pot fi: Instruc iunea de citire are forma: CITEŞTE(listă_de_variabile).B). pseudocod care ulterior a devenit limbajul de programare Pascal. CASE-OF) şi cele repetitive (WHILE-DO. 8)atribuire. 4)WHILE-DO. 5)expresie logică. Observa ii: a) Instruc iunile corespund configura iilor acceptate într-o schemă logică structurată.5 şi 6.5.3. c)2.3. b)1. Exemple: CITEŞTE(A. Instruc iunile se împart în declara ii (instruc iuni neexecutabile) şi instruc iuni efective (executabile).2. Instruc iunea de atribuire are forma: v=e. 10)STOP.3.3. iar un rând poate con ine mai multe instruc iuni (separate prin ". Instruc iunile de ramificare (IF-THEN-ELSE.2.[dn]. DO-UNTIL. IF-THEN-ELSE).8 sau 10.3.B).8. e)1. CARACTER etc.6. 7)sir de caractere. 3)scriere.2. Teste de autoevaluare 3. ambele de aceeaşi natură (numerică. O declara ie este formată din cuvinte cheie (de exemplu ÎNTREG.4. c)1. real. REAL vector[20]. urmat de un şir de variabile separate prin ".2 şi 4. DO-FOR) sunt prezentate împreună cu structurile fundamentale.4.2. d)1.Bazele programării 9 se pune problema „portabilită ii”. sub forma [d1][d2].8 sau 10. 2)citire. Cel mai avansat pseudocod „universal” a fost propus în anii ’60 de Niklaus Wirth. 3)CASE-OF. 4)expresie aritmetică. Exemple: SCRIE(A. REAL.9 sau 10 4. pentru compatibilizare cu literatura de specialitate (de exemplu WHILE-DO.7. b.. Sunt mnemonice ale instruc iunilor. 6)expresie rela ională.6.4. unde v este variabilă. deci sunt compatibile cu programarea structurată.6.". caracter etc. 6)DO-FOR.. SCRIE("VECTORUL ESTE ="). Masivele se declară prin tipul elementelor sale.8 sau 10.. 1998] Se propune următorul pseudocod: Cuvinte cheie. ÎNTREG matrice [10][15].4 şi 5. mai ales atunci când se lucrează în echipă. SCRIE(xi). Instruc iunile pot fi scrise liber. a) toate. . b) Instruc iunile acestui pseudocod se pot extinde la lucrul cu fişiere. CITEŞTE(xi). e este expresie. e)1.2 şi 5. Reprezentarea prin arbori este permisă numai pentru structurile: 1)BLOCK.2. d)1. IF-THEN. Exemple: ÎNTREG a. Instruc iunea de scriere are forma: SCRIE(listă_de_variabile).5. 2)IF-THENELSE. logică sau caracter)."). b)1. Instruc iuni. unele fiind scrise în limba engleză. variabile pentru care se indică faptul că au tipul întreg. c. 5)DO-UNTIL. [Roşca et al.

Sn-1). S2.S2). pseudocod si exprimare analitică.s.S2. arbore BLOCK S1 S1. S1 pseudocod C S1 C b) Structura IF-THEN Fig..3.a. Descrierea structurilor fundamentale În prezentarea structurilor fundamentale se vor folosi.l.l..l. şi se notează analitic cu: BLOCK[2](S1. Poate fi definită o structură secven ială cu un singur bloc: BLOCK[1](S1)=S1. Sn).s.S2. arbore.s. Structura secven ială poate con ine mai multe blocuri: BLOCK[n](S1. şi se notează analitic cu IF-THEN-ELSE(c.2. s1. (respectiv şiruri de instruc iuni în pseudocod sau module structurate în schemele arbore).Sn)=BLOCK(BLOCK[n-1](S1.3.Bazele programării 10 1.2.sn sunt s. În cele ce urmează. a) Structura IF-THEN-ELSE s. Structura secven ială (liniară) este prezentată în figura 1. următoarele reprezentări: schemă logică.. s.2.s). nu da arbore IF-THEN-ELSE pseudocod C S2 S1 C S1 S2 IF C THEN S1 ELSE S2 ENDIF.... 1. 1. în paralel.b şi se notează analitic cu IF-THEN(c... Structura IF-THEN este o formă particulară a structurii IF-THEN-ELSE. putându-se exprima astfel: . Structura secven ială Structurile alternative sunt de mai multe tipuri: s. Structuri alternative Structura IF-THEN-ELSE (selec ia simplă) este prezentată în figura 1. S1 S2 pseudocod S2 Fig.3. nu da arbore IF-THEN IF C THEN S1 ENDIF.l.S2). Structura IF-THEN (pseudoalternativă) este prezentată în figura 1.S2) sau BLOCK(S1. s2. cu n≥2.s.S1.

vi. Programarea structurată acceptă şi structura IF-ELSE (cu s pe ramura fals).s).s.s2.l. unde Φ este o s.5.5. Oricum.s) = IF-THEN( c . pe când WHILE-DO poate să nu execute pe s...s.. n i=n S1 S2 . Observa ii: 1. unde i este o variabilă selector care poate lua valori în mul imea V={v1.Φ).. i arbore CASE-OF i pseudocod CASE-OF i i=1: S1 i=2: S2 . vidă..vf... s.s..BLOCK(s..l. cele două structuri se pot transforma uşor una în alta. şi se notează analitic cu DOFOR(v. i=n-1: Sn-1 i=n: Sn ENDCASE. şi prin structuri arborescente)..s) Structura CASE-OF (selec ia multiplă) este prezentată în figura 1.s..s) şi IF-ELSE(c. notată IF-ELSE(c.. iar vi.c.. este prezentată în figura 1.s)=BLOCK(v=vi.. i=1 i=2 i≠1... Φ.s)) DO-UNTIL(s. Structura DO-FOR este un caz particular al structurii DO-UNTIL.s1.WHILE-DO( c . Sn S a) Structura CASE-OF – cazul general s.. putându-se scrie: DO-FOR(v. în cazul particular. V este o mul ime discretă.s).a.l. .s1. unde v este o variabilă contor (numărător).. finită şi ordonată. ra ia se poate omite în pseudocod. vn}.sn.s)) 2. valoare finală. respectiv valoare ra ie.v=v+vr))) . .vr sunt expresii cu rol de valoare ini ială.. în cazul general şi CASE-OF(i.vr.vi. Sn-1 Sn S1 S2 . şi se notează analitic cu DO-UNTIL(c.s) = IF-ELSE( c . Diferen a esen ială între WHILE-DO şi DO-UNTIL costă în aceea că DO-UNTIL execută s cel pu in o dată. Atunci când vr=1. şi se notează analitic cu WHILE-DO(c.. Sn S S1 S2 .s). Structura repetitivă condi ionată posterior...s).c)=BLOCK(s. . 2.s)=IF-THEN-ELSE(c. astfel: WHILE-DO(c. Structura CASE-OF Structurile repetitive sunt de mai multe tipuri: Structura repetitivă condi ionată anterior este prezentată în figura 1.WHILE-DO(v≤vf. i=1 i=2 i=n S1 S2 .Bazele programării 11 IF-THEN(c. .s) Structurile IF-THEN şi IF-ELSE se pot exprima (pot fi înlocuite în algoritm) una prin cealaltă: IF-THEN(c.s.s2. vf.sn).b..s)=IF-THEN(c. …. prin s. i i=n-1 arbore CASE-OF i pseudocod CASE-OF i i=1: S1 i=2: S2 .. Structura CASE-OF este echivalentă cu structura IF-THEN-ELSE (demonstra i acest lucru analitic. . v2. tot ca formă particulară a structurii IF-THEN-ELSE: IF-ELSE(c.4. 1.5.DO-UNTIL( c .4 şi se notează analitic cu CASE-OF(i.l... Sn-1 Sn b) Structura CASE-OF – cazul particular Fig...vf...s)=IF-THEN-ELSE(c. Structura repetitivă cu numărător este prezentată în figura 1..vr. i=n: Sn ELSE: S ENDCASE.s).

l. d) ≤ ≤ BLOCK(v=vf.l. vf. WHILEDO(v<vf. WHILE-DO(v>vi.vr. vf.s). IF-THEN(v≤vf.s. Structura WHILE-DO(c. 1. c)IF-THEN(c. vr da S S v≤vf DO-FOR v=vi.v=v-vr))). DOUNTIL(BLOCK(v=v+vr.v=v+vr).v=v+vr))).s)). c ) . Structurile repetitive Teste de autoevaluare 5. S pseudocod 12 C a) Structura WHILE-DO s.s) este echivalentă cu: a) DO-UNTIL(s.s). v=vi nu S C b) Structura DO-UNTIL arbore pseudocod DO-FOR v=vi. c ).v>vf)).l.BLOCK(s.IF-THEN(c. c )). 6.s.DOUNTIL(s.s) este echivalentă cu: a) BLOCK(v=vi. nu v=v+vr c) Structura DO-FOR Fig.DO-UNTIL(s. arbore DO-UNTIL S DO S UNTIL C. c) BLOCK(v=vi. arbore WHILE-DO C nu da S WHILE C DO S ENDWHILE. DO-UNTIL(BLOCK(s. b)BLOCK(s.v=vvr).s. e)DOUNTIL(IF-THEN(c. ENDDO.vf.v>vf))).BLOCK (s.v≤vi)). b) BLOCK(v=vf. pseudocod C da s.vi. vr S ENDDO.5. e) BLOCK(v=vi.Structura DO-FOR(v.Bazele programării s. d)BLOCK(s.c)). DO-UNTIL(BLOCK(s.

iar etichetele care nu sunt predicate formează mul imea A. Metoda dublării codurilor se foloseşte la structurarea alternativelor sau repetitivelor. Structurarea şi proiectarea algoritmilor Un algoritm se consideră structurat dacă şi numai dacă con ine structurile fundamentale prezentate anterior. diferite de cele din S.se introduce variabila booleană.s2) P=IF-THEN-ELSE(c. măsurători sau pe baza altor calcule prealabile. . variabila booleeană îşi schimbă valoarea: VB=1 (sau VB=0) pe toate drumurile care duceau la ieşirea din vechea structură repetitivă. De remarcat faptul că orice algoritm structurat poate fi realizat numai prin structurile de bază din familia D={BLOCK. Erorile de aproximare a lor sunt cunoscute şi . Considerându-se o familie D' de structuri fundamentale (de exemplu D'={BLOCK. Dacă o schemă logică nestructurată este prea complicată. schema logică are o singură intrare şi o singură ieşire. se renun ă la structurare (care. Un algoritm P. π. a unui cod (a unei ac iuni sau a unui predicat). acestea fiind ob inute în urma unor observa ii. Se pot adăuga lui A şi P alte ac iuni. a ac iunilor. Erorile în algoritmi Un algoritm este eficient şi devine opera ional în măsura în care între resursele de calcul utilizate (timp şi memorie calculator) şi precizia rezultatelor se stabileşte un raport acceptabil. astfel încât să se ob ină o schemă logică structurată echivalentă cu S. prin adăugare de noi ac iuni şi predicate. ori de câte ori este nevoie. Deoarece fiecare structură are o singură intrare şi o singură ieşire. respectiv alte predicate.se copiază din vechea schemă logică toate blocurile până la intrarea în structura repetitivă care nu este fundamentală. IF-THEN. e etc). WHILE-DO}. Solu ia unei probleme depinde de datele ini iale. structurat. astfel încât să se ob ină numai structuri fundamentale. complică şi mai mult schema) şi se reproiectează. în care condi ia se referă la variabila booleană introdusă.s2) P=WHILE-DO(c. WHILE-DO}).s1. atunci ea este nestructurată. pentru această clasă de erori se stabilesc limite de eroare. de exemplu VB (VB=0 sau VB=1).s) Dacă schema logică prin care se ilustrează algoritmul de rezolvare a unei probleme nu con ine numai structurile fundamentale. este echivalent cu un algoritm pus sub una din următoarele forme: P=BLOCK(s1. Orice schemă logică nestructurată se poate structura. VB. IFTHEN-ELSE. condi iile în care au loc acestea.3.Bazele programării 13 1. . O parte din parametrii utiliza i în formulele de calcul nu au o valoare exprimabilă printr-un număr finit de zecimale (de exemplu 3 . DO-UNTIL.se alege structura repetitivă fundamentală WHILE-DO sau DO-UNTIL. . conform următoarei teoreme de structură: Fie S o schemă logică nestructurată în care etichetele care sunt predicate formează o mul ime P. În practică s-au impus următoarele metode de structurare. precizia calculelor necesare determinării unor parametri ini iali generează erori în datele ini iale. Metoda introducerii unei variabile booleene se foloseşte pentru structurarea repetitivelor şi constă în: . Cu toată precizia oferită de calculatoarele electronice. Ea constă în dublarea. Precizia instrumentelor cu care se fac observa iile. calitatea rezultatelor este influen ată de mul i al i factori. În general. un algoritm se numeşte D'-structurat dacă este reprezentat numai prin structuri din D'. IF-THEN-ELSE.în interiorul structurii repetitive alese.

mai ales numerică. r x*. eroarea relativă îşi pierde din acurate e datorită numitorului raportului care tinde spre zero. x* < x Diferen a ε x * = x . * * ε x* ± y* = (x ± y) . y* . iar x* şi y* pentru simplificare au * acelaşi semn) şi folosind formula de aproximare ln x . a unei probleme se foloseşte o metodă matematică.ln x * ≈ d ln x * = ε x* . Ele se explică prin imposibilitatea calculării unei serii infinite într-un număr finit de paşi ai algoritmului. Dacă x este valoarea exactă şi x* o valoare aproximativă a lui x. Erorile pot fi acceptate sau respinse. pentru eroarea absolută. eroarea relativă nu depăşeşte suma erorilor relative ale numerelor: * * * * * * * * ε x*. pentru eroarea relativă. În cazul opera iilor de adunare şi scădere. precum şi de conversiile dintr-un sistem de numera ie în altul. y* = .Bazele programării 14 vor fi astfel alese încât să fie corelate cu precizia dorită pentru calculele în care intră aceşti parametri. ► x* realizează o aproximare prin lipsă.x y ) = ( x + ε x*) ⋅ ( y + ε y*) .x y = x ε y* + y ε x* + ε x* ε y* * *± * = ε x*. O altă clasă importantă de erori o constituie erorile de rotunjire.x * reprezintă eroarea. În cazul opera iei de împăr ire ε ( x )* ≈ y y ( y* ) 2 înseamnă că eroarea relativă a câtului nu excede suma erorilor relative ale deîmpăr itului şi împăr itorului. ceea ce r x* y* ≤ r x* + r y* . r ( x )* ≤ | r x* | + | r y* | . rezultă că x * * y ε x* . În cazul produsului a mai multor numere aproximative şi nenule. * y ε x * ± ε y* = r x* * x * ± r y* * * . ob inută ca urmare a prezen ei unor erori din clasele men ionate anterior. Ele apar ca urmare a limitării numărului de zecimale cu care se poate reprezenta un număr în calculator. Rela iile func ionează şi pentru n>2 numere. iar când nu interesează sensul ei se calculează ε x * = x − x * .y în care. nu numai în func ie de mărimea lor. în func ie de acestea alegând una sau alta din metodele de rezolvare existente.(xy . fenomenul modelat este supus unor condi ii simplificatoare. În acest scop se calculează raportul rx * = care x* desemnează eroarea relativă. de sistemul de numera ie folosit în calcule. Alegerea metodei poate introduce aşa numitele erori de metodă. Erorile introduse prin prezen a în calculator a unor func ii cărora în analiza matematică le corespund serii infinite se numesc erori reziduale. ci şi în func ie de x − x* mărimea valorilor cărora li se asociază. Aceste erori depind de modul de reprezentare a numerelor în calculator. care poartă numele de eroare absolută. Erorile în cazul unor expresii calculabile prin opera iile elementare pot fi aproximate folosind limita maximă a erorilor fiecărui termen în parte. rx y * * x ±y x ±y x ±y De re inut că la scăderea a două numere apropiate ca valoare. eroarea absolută nu depăşeşte suma erorilor absolute a celor două numere care se adună algebric.( x ± y ) = ε x* ± ε y* . La rezolvarea. se disting următoarele situa ii: x* > x ► x* este o aproximare a lui x prin adaos. logaritmând (valorile absolute permi ând acest lucru. De multe ori. y* * * x .x ε y* .

. de la general la particular. 5)WHILE-DO(c.s2).2. utilizarea unor module deja existente. proiectarea structurată. IF-THEN-ELSE(c. 7)DO-FOR(v. fiecare fază fiind o detaliere a fazei anterioare până când algoritmul este suficient de rafinat (detaliat) pentru a fi codificat. Apar astfel. . 3)IF-THEN(c. la un moment dat.2.sn. d) o schemă logică structurată poate fi descompusă în structurile privilegiate Proiectarea algoritmilor Conceptele principale ce s-au cristalizat în domeniul programării structurate sunt: proiectarea top-down. la: omogenizarea func iilor. utilizarea eficientă a resurselor calculatorului (periferice. Din punct de vedere al func iilor pe care le con in. Testarea top-down poate lua în considerare. proiectarea modulară. module de comandă (monitor) care apelează (activează) alte module şi module mixte.6. Proiectarea modularizată presupune. Codificarea top-down presupune. b) orice schemă logică poate fi pusă sub una din formele:BLOCK(s1.4. se continuă cu ataşarea unui alt nivel inferior etc. d) 1. în principal. utilizarea diverselor structuri de date.3. Proiectarea modularizată presupune descompunerea problemelor în păr i numite module. de experien a proiectan ilor (programatorilor). timp. posibilitatea scrierii unui modul înainte de a se proiecta modulele de nivel inferior (superior). Cele trei tipuri de proiectări nu se exclud unul pe altul. fără testare propriu-zisă a acestora din urmă.s2).s). independent unul fa ă de altul. pe lângă identificarea modulelor şi a rela iilor dintre ele.s)..s1. memorie internă) etc. Descompunerea se poate face în mai multe faze (la mai multe niveluri) prin metoda top-down.s2). c) corectitudinea unei scheme logice structurate se verifică prin examinarea fiecărui nod din arborescen a sa.5..3. WHILE-DO(c. 8.s2. şi precizarea modului şi ordinii în care modulele sunt puse în lucru.s1.5. După stabilirea modulelor.6.5..2. posibilită ile echipei în sarcina căreia intră realizarea modulelor..7. a)1. care con in atât func ii de prelucrare cât şi de comandă.s2). e) 1.6.6. Criteriile de descompunere în module depind. iar testarea top-down constă în realizarea ei de sus în jos: se porneşte cu modulul rădăcină şi cu unu sau mai multe module de ordin imediat inferior. 6)DO-UNTIL(s. c) 1. în diferite faze succesive. b) 1. până când s-au inclus în testare modulele ultimului nivel.vf.vr.vi.Bazele programării 15 Teste de autoevaluare 7. Proiectarea top-down este înso ită de codificare (scriere a programelor) top-down şi testare top-down. Un algoritm structurat este echivalent cu un algoritm pus sub una din formele: 1)BLOCK(s1. Ele se referă. În urma descompunerii se ob ine o structură liniară sau arborescentă. se disting: module de prelucrare (opera ionale) care con in func ii de prelucrare (opera ii propriu-zise). acestea se abordează algoritmic. Teorema de structură stabileşte că: a) orice schemă logică este echivalentă cu o schemă logică structurată.s). concretizată în ob inerea unor produse program care să reflecte clar ierarhizarea prelucrărilor şi care să faciliteze testarea şi documentarea lor. în mare măsură. ci se intercorelează pentru desfăşurarea unei activită i organizate şi disciplinate.s1. numai legăturile unui modul cu module de pe nivelul inferior.s). a problemei date în subprobleme sau func ii de prelucrat. 2)IF-THEN-ELSE(c. astfel încât fiecare din acestea să îndeplinească anumite func ii bine definite. arborele se parcurge în preordine.c).s).7. separarea func iilor de intrare/ieşire de func iile de prelucrare. conducând la realizarea algoritmului în mai multe faze succesive. În stabilirea ordinei de punere în lucru a modulelor. 4)CASE-OF(i.2. în principal.5. Proiectarea top-down presupune descompunerea.2. algoritmi din ce în ce mai detalia i.

modul de construire a ciclărilor).Bazele programării 16 Proiectarea structurată a algoritmilor constă dintr-o mul ime de restric ii şi reguli de elaborare care for ează proiectantul (programatorul) să urmeze o formă strânsă de reprezentare şi codificare. Care tipurile de proiectări cristalizate în domeniul programării structurate? . timpul necesar execu iei algoritmului poate însemna timpul în cazul cel mai defavorabil sau timpul mediu. modul în care au fost construite selec iile.incluzând aici şi elaborarea algoritmilor . pentru seturi diferite de date. Deoarece. II) Determinarea timpului necesar execu iei algoritmului. în: I) Determinarea necesarului de memorie. a algoritmului. dar ob inerii unui produs de cea mai bună calitate. Dacă cele trei tipuri de verificări au condus la concluzia de corectitudine. cu valoare teoretică. timpii de execu ie vor fi diferi i.este modalitatea de ordonare a activită ii mentale desfăşurată în scopul ob inerii de programe (algoritmi) constituite din structuri fundamentale cu un grad de structurare cât mai mare şi în condi iile minimizării efortului de programare. necesarul de memorie şi timpul UC rămân resurse importante care trebuie bine utilizate. Verificarea şi analiza corectitudinii algoritmilor În procesul de elaborare a algoritmilor se pot strecura formulări imprecise sau eronate. în care important este criteriul după care se judecă algoritmul: (I) sau (II). În practică se recomandă următoarele verificări ale corectitudinii algoritmilor simpli: 1. se procedează la un test de birou care presupune parcurgerea atentă. care este. Într-un sens mai larg. Există încercări. programarea structurată . opera ie cu opera ie. Test de autoevaluare 9. lucru imposibil de realizat în practică. 3. o problemă dificilă. ceea ce determină ob inerea unor rezultate incomplete sau eronate. în principal. asigurarea valorilor (prin introducerea din exterior sau ini ializare în algoritm) pentru toate variabilele referite (utilizate) în opera ii. de obicei cazuri limită. astfel încât variantele să fie corect definite în algoritm. în general. cu memorii mari). pentru seturi de date. 2. rezultat ca raport între suma timpului necesar pentru toate seturile de date considerate şi numărul acestor seturi. algoritmul elaborat furnizează rezultate corecte. de a elabora o metodologie de verificare a corectitudinii algoritmului. III) Determinarea optimalită ii algoritmului. Verificarea corectitudinii ar însemna verificarea faptului că pentru orice set de date. Analiza algoritmilor (studiul eficien ei lor) constă. încheierea algoritmului după un număr finit de paşi (în principal. Cu toate progresele tehnologice din ultimul timp (calculatoare rapide.

proiectarea structurată. Programare sistematică în Pascal. 3:b). Didactică şi Pedagogică. Uscatu. C. I. Gh. proiectarea.Bazele programării 17 Răspunsuri şi comentarii la testele de autoevaluare 1:d).. Ed. Bătăgan. Rezumat În cadrul acestei unită i de învă are au fost studiate următoarele aspecte în ceea ce priveşte algoritmii şi schemele logice: cunoştin e teoretice privind caracteristicile şi descrierea algoritmilor. arbore. 4:a).. M. Programarea calculatoarelor. I.. M. C. Roşca. Gh. studen ii au cunoştin e şi abilită i de rezolvare a problemelor (în special lucrul cu masive). prin reprezentarea acestora sub formă de algoritmi structura i. proiectarea modulară. Ghilic-Micu B. 2003 3. Ed. Mircea. ISBN 973-594-5916 2. 2:d). verificarea şi analiza algoritmilor. Ghilic-Micu. ISBN 973-30-3341-3 . Gh. 9. Teorie şi aplica ii. ASE. Teorie şi aplica ii în C. Stoica. După încheierea acestei unită i de învă are. L. Ghilic-Micu. Bucureşti 1998. Bibliografia unită ii de învă are 1. pseudocod şi exprimare analitică. C. Apostol C. 2006. 5:c). Silvestru. 8:a). Tipurile de proiectări care s-au cristalizat în domeniul programării structurate sunt: proiectarea top-down. Roşca I. Stoica. ASE. Cocianu. Ed.. modalită i de reprezentare a algoritmilor sub formă de scheme logice şi pseudocod. Ştiin a învă ării unui limbaj de programare. Roşca. Bucureşti. Roşca V. 7:d). M. Bazele programării calculatoarelor. Uscatu. 6:e). reprezentarea structurilor fundamentale sub formă de schemă logică. Cocianu. C. B. B. C.

1. ci pur şi simplu informa ie. New York (1948). Structuri de date Răspunsuri şi comentarii la testele de autoevaluare Bibliografia unită ii de învă are Obiectivele unită ii de învă are 2 Dupa studiul acestei unitati de învatare. studen ii vor avea cunoştin e teoretice şi abilită i practice despre: informa ii. se cuvine mai întâi să se facă distinc ie între două maniere de a aborda conceptul pus în discu ie: în general. Se poate remarca faptul că defini ia anterioară este dată în sens negativ. ca semnele care circulă pe diferite canale între elementele lumii reale. The MIT Press. Paris.8 ore 2. noutate: există mesaje care. cunoştin e. 1961 . informa ia trebuie considerată în raport cu procesul de cunoaştere şi cu modul de reflectare a rezultatelor sale în conştiin a fiin ei umane. ca fiin ă superioară pe scara biologică. în particular. data şi reprezentarea internă a datelor Informa ia este un concept de maximă generalitate. Pentru a încerca o defini ie afirmativă. Informa ia. edi ia a doua revăzuită şi adăugită (două capitole noi). În acest ultim sens. nici energie. Norbert Wiener1. Durata medie a unită ii de studiu individual . reprezentarea internă a datelor. Fondatorul ciberneticii. În literatura de specialitate sunt identificate următoarele trăsături definitorii ale informa iei: semn cu semnifica ie: este obligatoriu ca un mesaj să fie construit într-o limbă (limbaj) cunoscută de receptor.2. Organizarea internă a datelor Cuprins Obiectivele unită ii de învă are 2 2. consideră informa ia ca a treia formă de manifestare a realită ii obiective. Herman and Cie. date. apreciind că ea nu este nici materie. deşi sunt redactate într-o limbă cunoscută. când elementul receptor este omul. structuri statice de date. nu con in nimic nou pentru receptor. data şi reprezentarea internă a datelor 2. The MIT Press. 1 Norbert Wiener – Cybernetics or Control and Communication in the Animal and the Machine. pierzându-se calitatea de informa ie. Wiley and Sons. Cambridge (Mass).1. Cambridge (Mass). care poate fi definit prin raportarea la conceptele de materie şi energie. Informa ia.Bazele programării 18 2. cu forme specifice de receptare la diferitele niveluri de manifestare a materiei vii. structuri dinamice de date. Wiley and Sons. New York.

este posibil ca rezultatul să fie nul. o formă de reprezentare şi manipulare. Nivelul pragmatic permite reflectarea cea mai fidelă a procesului de cunoaştere. conceptele de informa ie şi dată pot fi utilizate ca sinonime numai în măsura în care acceptăm să identificăm un obiect cu modelul său.  care separă alternativele în defini ie. rezultatele unui proces de informare pot conduce la una din următoarele situa ii: la o extremă. Pornind de la scopurile receptorului pot fi definite caracteristici ca utilitatea sau importan a informa iei. de asemenea. Pe lângă distinc ia între conceptele de dată şi valoare se constată. Acest ansamblu de informa ii se numeşte tezaur de cunoştin e şi se foloseşte ca termen de referin ă pentru a evalua rezultatele oricărui proces de informare. [ ] care indică o construc ie op ională. prin acumularea progresivă de informa ii asupra unui obiect sau a unui sistem. varia ia poten ială a tezaurului receptorului este maximă dacă intersec ia între con inutul tezaurului şi acela al unui mesaj este vidă. la cealaltă extremă. Procesul de cunoaştere se realizează în timp. Acestui nivel îi corespunde conceptul de dată. adică un sistem de reguli de transformare având ca scop să se ob ină date noi pornind de la cele existente.Bazele programării 19 utilitate: în raport cu interesele receptorului. transmitere. { } care indică posibilitatea repetării construc iei. Regulile de sintaxă care formează mul imea produc iilor pot fi specificate în mai multe moduri. de asemenea. fiind singurul care consideră informa ia în raport cu scopurile receptorului. Se mai spune că data este o reprezentare digitală (discretă) a unei anumite cantită i de informa ie. ca parte a procesului general de cunoaştere. semantic şi pragmatic. În concluzie. informa ia poate fi caracterizată ca semnifica ie a datelor. pierzându-şi. dacă informa ia apar ine deja tezaurului receptorului. Nivelul pragmatic este cel mai concret nivel de abordare a informa iei. . No iunea de dată va con ine pe cea de valoare. folosind nota ia formală BNF (Backus-Nour Form). calitatea de informa ie. metaconstanta. dar presupune. adică ea a devenit o cunoştin ă. cunoştin ele reprezintă totalitatea informa iilor de inute de un observator asupra unui obiect sau sistem. ::= este un metasimbol având sensul de „este prin defini ie”. ca între un obiect şi modelul său. În nota ia BNF. Sensul informa iei la acest nivel este dat de coresponden a între o dată şi obiectul real sau situa ia reprezentată prin această dată. în plus. La limită. Alternativele se constituie prin juxtapunerea de metavariabile şi/sau metaconstante. În cadrul defini iei (parte-dreapta) se întâlnesc următoarele elemente: <metavariabila>. iar parte-dreapta reprezintă defini ia metavariabilei. se identifică următoarele niveluri la care se consideră informa ia: sintactic. La nivelul semantic. a cărui în elegere completă impune utilizarea conceptului de cunoştin ă. Nivelul sintactic este asociat sistemului de semne şi regulilor utilizate pentru a le reuni în construc ii sintactice folosite pentru reprezentarea informa iei în procesul de culegere. categorie folosită în definirea altei categorii sintactice. Corespunzător. regulile sintactice (metadefini iile) au forma: <parte-stânga> ::= parte-dreapta unde <parte-stânga> desemnează metavariabila (variabila neterminală) care se defineşte. care. înregistrare şi prelucrare. La un moment dat. element al alfabetului terminal. dintre care se remarcă nota ia formală BNF (Backus Normal Form) şi diagramele de sintaxă. diferen a între informa ie şi dată. poate fi definită astfel: <dată>: : = <identificator> <atribute> <valoare>. este posibil ca un mesaj cu caracter de noutate să fie inutil pentru activitatea sa.

C. Pe lângă tip. reprezintă o dată. pentru a o distinge de alte date şi a o putea referi în procesele de prelucrare (referire prin nume). astfel încât recep ia şi în elegerea mesajului să aibă loc. În unele limbaje de programare. Calculatoarele actuale prelucrează date pe baza cărora se ob in rezultate (tot date) care. xn  . precum şi mul imea de opera ii care se pot efectua cu elementele mul imii de valori ale datei. În caz contrar. logic.. Deosebirea dintre informa ie şi dată este echivalentă cu deosebirea dintre obiect şi modelul său.. .. Atributele precizează proprietă i ale datei şi ele determină modul în care aceasta va fi tratată în procesul de prelucrare. având un număr finit de evenimente elementare independente x1. program etc.E. unitate centrală.x2.. cărora li se asociază un identificator propriu. Ea poate fi număr întreg. prin interpretare umană.2. devenind informa ii. ceea ce justifică denumirea de literal.. valoarea ini ială etc. semnifica ia cuvintelor de definire este următoarea. procesele şi obiectele lumii reale. şir de caractere etc.. Dacă X reprezintă un sistem complet de    p p .. Identificatorul este un nume care se asociază datei.p2. p n ) = − ∑ p k ⋅ log 2 p k = −(1/2)log 2 (1/2) − (1/2)log 2 (1/2) == 1/2 + 1/2 = 1 bit k =1 . care se poate defini astfel: fie un experiment X.n} (1) şi (entropia) se măsoară după rela ia: n ∑p k =1 n k = 1 (2).. se ob ine: Prin dată se desemnează un model de reprezentare a informa iei accesibil unui anumit procesor (om. Pentru datele constante se foloseşte.). între care şi C... unei date i se pot asocia şi alte atribute. se constată. p 2 .. Bitul poate fi definit ca informa ia furnizată de un sistem cu două stări echiprobabile:  x1 x 2  X= (4) 1/2 1/2     Aplicând formula (3). care se realizează cu probabilită ile p1. informa ia poate fi caracterizată ca semnifica ie a datelor.. În nota ie BNF. cel mai adesea.pn: X =  x1 x2 . pentru orice k∈{1.. p 2 . „formula scrisă”.. cadrarea valorilor în zona afectată. ca: precizia reprezentării interne.. El precizează mul imea valorilor pe care le poate avea o dată. Dintre atributele care se pot asocia unei date. p n ) = -∑ p k ⋅ log 2 p k k =1 Cantitatea de informa ie se exprimă.. există şi posibilitatea definirii unor constante simbolice. drept identificator chiar valoarea. atunci cantitatea de informa ie (3) H(p1 . În final putem sintetiza o serie de concluzii clarificatoare a problematicii puse în discu ie. Shannon a introdus no iunea de cantitate de informa ie. în general. O informa ie este un mesaj susceptibil de a aduce o cunoştin ă şi poate fi generată numai de sisteme cu număr n finit de stări (n ≥ 2). data se numeşte variabilă. Sub aspect semantic.. numită redundan ă.xn.Bazele programării 20 Referitor la al doilea caz. Data care păstrează aceeaşi valoare pe tot parcursul prelucrării este denumită constantă. p   1 2 n  evenimente: 0≤pk≤1. că este obligatorie existen a unei intersec ii nevide între cele două mul imi. Valoarea datei se poate preciza prin enumerare sau printr-o proprietate comună... Modelul de reprezentare a informa iei.. modul de alocare a memoriei pe parcursul prelucrării (static. cel mai important este tipul. însă. model cu care se poate opera pentru a ob ine noi informa ii despre fenomenele.. complex.. adică o astfel de dată se autoidentifică prin forma textuală a valorii.. n H(p1. dinamic). real. capătă un sens. în bi i.

în cod direct pentru numere pozitive şi în cod .☻. Când aceste caractere sunt folosite în alt context decât cel de control. situată la o anumită adresă. Tab etc. ♀. Caracterele neafişabile se utilizează. Calculul în virgulă mobilă poate fi realizat când microcalculatorul are coprocesor matematic 80x87 sau când limbajele de programare dispun de biblioteci specializate pentru emularea software a opera iilor în această aritmetică. Macheta de reprezentare pe un cuvânt este prezentată în figura 2. ♣. ♂. Form Feed. Ea poate fi algebrică sau aritmetică.ß. o serie de caractere greceşti (α. unei date îi corespunde o zonă de memorie de o anumită mărime. atât în raport cu informa ia pe care o reprezintă. cât şi în raport cu procesorul care o prelucrează. ≥). men iunea că unele limbaje de programare lucrează şi cu un alt tip de reprezentare internă a datelor numerice. O dată scalară poate fi privită la nivelul unui procesor uman (nivel logic). respectiv la nivelul calculatorului. valorile acesteia. numită reprezentare zecimală. Se face. ♫. M este o valoare exprimată în binar. li se pot asocia simboluri grafice nestandardizate.*. 2. Datele logice se reprezintă intern în virgulă fixă pe un octet. câte un caracter pe octet.). UCP are dispozitiv fizic specializat în efectuarea opera iilor în virgulă fixă. La nivel fizic./ etc.1. Reprezentarea în virgulă fixă s este bitul de semn (s-a adoptat conven ia ca semnul "+" să fie reprezentat prin valoarea binară 0 iar semnul "–" prin valoarea binară 1). unde: s 15 14 M a) Virgulă fixă algebrică 2 1 0 N 15 14 2 b) Virgulă fixă aritmetică 1 0 Fig.≤. ╣. ♪. spa iul. prin conven ie asociinduse 1 pentru valoarea adevărat şi 0 pentru fals. ca procesor (nivel fizic). de regulă. o serie de caractere speciale (+. cifrele.) etc.Bazele programării 21 Reprezentarea internă a datelor Data este elementară (scalară) dacă apare ca o entitate indivizibilă. Datele alfanumerice se reprezintă în cod ASCII extins. de asemenea. o serie de semne grafice (≈. Bell. Reprezentarea în virgulă fixă Reprezentarea în virgulă fixă se aplică numai numerelor întregi şi se realizează pe zone de memorie standard (un cuvânt sau două cuvinte) sau pe octe i. ♠. cum ar fi: ☺. ±.π etc. în timp şi într-o formă specifică. în care sunt memorate.). Datele numerice se reprezintă intern în virgulă fixă şi virgulă mobilă. Caracterele afişabile sunt literele (mari şi mici) ale alfabetului englez. Cele 256 de caractere codificabile ASCII se împart în afişabile şi neafişabile. Datele din memoria internă pot fi clasificate în trei mari categorii. Carriage Return. pentru controlul transmisiei şi imprimării (Line Feed.1.

pentru numere negative. lăsându-se nemodificată grupa din dreapta. . se complementează fa ă de 1 grupa din stânga.. grupa din stânga cuprinde bi ii rămaşi.Bazele programării 22 complementar. Fie aceasta N2. exprimat în octal: 177750. valoarea care poate fi reprezentată algebric apar ine mul imii [–2n–1. 0 6 0 5 1 4 1 3 0 2 0 1 0 0 Se realizează complementul fa ă de unu: 1 15 1 14 .se adună un unu la numărul reprezentat în cod invers (N2*) şi astfel se ob ine complementul fa ă de doi al lui N2. 1 6 1 5 0 4 1 3 0 2 0 1 0 0 sau. . Fie numărul ob inut N2*. Reprezentarea aritmetică se aplică numai numerelor pozitive. bitul de semn fiind folosit ca bit de cifră. .. exprimat în octal: 177747 Se adună unu la numărul reprezentat în complement fa ă de unu: 1 15 1 14 .număr negativ (– 6) . inclusiv a bitului de semn.. ..număr negativ (–3) . astfel: din bi ii numărului exprimat în cod direct se formează două grupe: grupa din dreapta cuprinde toate zerourile din dreapta ultimului bit cu valoarea 1 precum şi ultimul bit 1.se realizează complementul fa ă de unu (cod invers) al lui N2.. 2n–1].se reprezintă valoarea absolută a numărului în binar (cod direct).. Complementul fa ă de unu se ob ine prin inversarea fiecărui bit (0 în 1 şi 1 în 0). Codul complementar se ob ine astfel: ... . 1 6 1 5 0 4 0 3 1 2 1 1 1 0 sau. Pentru determinarea complementului fa ă de doi se poate proceda. 2n–1–1] iar valoarea care poate fi reprezentată aritmetic apar ine mul imii [0.. Exemple: Pentru simplificare se consideră un cuvânt format din patru bi i: Complementul fa ă de 2 pentru 0110: 01 10 stânga dreapta Rezultat: 10 10 Complementul fa ă de 2 pentru 1101: 110 1 stânga dreapta Rezultat: 001 1 . .. N este reprezentat în cod direct.număr pozitiv (+6) .număr pozitiv (+3) Considerându-se o zonă de memorie de n bi i.. Exemple: Numărul –24 se reprezintă astfel: Se exprimă 24 în cod direct: 0 15 0 14 ..

Bazele programării

23

Reprezentarea în virgulă mobilă Există mai multe tipuri de reprezentare virgulă mobilă. Dintre acestea, cel mai frecvent utilizat este standardul interna ional IEEE (Institute for Electrical and Electronics Engineers). Conform acestui standard, datele se memorează pe 32 de bi i (simplă precizie) sau pe 64 de bi i (dublă precizie), după machetele prezentate în figura 2.2. semn 1 bit caracteristică 8 (11) bi i frac ie 23 (52) bi i

Fig. 2.2. Reprezentarea virgulă mobilă simplă (dublă) precizie
Ambele machete presupun că numărul de reprezentat are următoarea exprimare binară sub formă ştiin ifică: m=(–1)s · 1,frac ie · 2exponent, unde s este valoarea bitului de semn (1 pentru mantisă negativă şi 0 pentru mantisă pozitivă) iar frac ie este partea frac ionară a mantisei. Mantisa este normalizată şi are întotdeauna forma 1,frac ie, ceea ce înseamnă că ea are valori în intervalul [1,2). Pentru ca mantisa să fie adusă la această formă se modifică în mod corespunzător exponentul numărului m. De exemplu, fie m=101,0111. Scrierea lui m normalizat este m=1,010111*22. Deoarece partea întreagă a mantisei este întotdeauna 1, aceasta nu se reprezintă intern. Frac ia se reprezintă intern sub forma semn-mărime (nu în cod complementar). Pentru a nu se utiliza doi bi i de semn (unul pentru mantisă şi altul pentru exponent), conven ia IEEE a introdus în şablon înlocuirea exponentului cu o caracteristică. Aceasta este o valoare în exces fa ă de 127 pentru simplă precizie (exponent+127) sau 1023 pentru dublă precizie (exponent+1023):

Exemplu:
Să se reprezinte în simplă precizie numărul –75,375. –75,375 = –1001011,011(2) = –1,001011011*26 s=1 mantisa = 1,001011011(2) frac ia = 001011011(2) caracteristica = 6 + 127 = 133 = 10000101(2) Reprezentarea internă: 1 10000101 00101101100000000000000

Caracteristica are următoarele valori normale: 0 < caracteristică < 255 ► pentru simplă precizie 0 < caracteristică < 2047 ► pentru dublă precizie. Când caracteristica are valoarea zero, numărul reprezentat intern (m) este zero. Când caracteristica este 255 (respectiv 2047) se consideră depăşire virgulă mobilă. Caracteristicile reprezentărilor interne virgulă mobilă simplă şi dublă precizie sunt prezentate în tabelul 2.1.

Tabelul 2.1. Caracteristicile datelor reprezentate virgulă mobilă Caracteristici
Număr bi i pentru reprezentare caracteristică Număr bi i pentru

Tip reprezentare Simplă precizie Dublă precizie
8 23 11 52

Bazele programării

24

Caracteristici
reprezentare frac ie Valoarea minimă caracteristică Valoarea maximă caracteristică Eroare maximă frac ie Cel mai mic număr pozitiv Cel mai mare număr pozitiv Domeniu de reprezentare

Tip reprezentare Simplă precizie Dublă precizie
1 254 2-24 ≈ 10-7 21-127 ≈ 10-38 2·2254-127 ≈ 1038 [–1038 , 1038] 1 2047 2-24 ≈ 10-7 21-1023 ≈ 10-307 2·22047-1023 ≈ 10307 [–10307 , 10307]

Prelucrarea datelor şi instruc iunilor de către unitatea centrală Pentru în elegerea modului în care datele şi instruc iunile sunt prelucrate de unitatea centrală, se consideră că memoria con ine, din punctul de vedere al programatorului, date (D) şi instruc iuni (I), în succesiunea de cuvinte ilustrată în figura 2.3.
D1 D2 D3 I1 I2 D4 D5 I3 D6 I4 Adrese: 4700 4702 4704 4706 4710 4712 4714 4716 4720 4722 4726 Adresa de start

Fig. 2.3. Model de memorie
Aşa după cum s-a arătat, instruc iunile sunt prelucrate de UCC. Încărcarea instruc iunilor în UCC se realizează automat. Pentru a lansa un program în execu ie, UCC trebuie să "cunoască" adresa primei instruc iuni de executat (adresa de start). Acesta este motivul pentru care în unele limbaje de programare este obligatorie etichetarea primei instruc iuni executabile. În exemplul din figura 1.9. se presupune că adresa de start a programului este 47068. Această adresă este încărcată în contorul de adrese (un registru special numit program counter - PC). În UCC este încărcată întotdeauna instruc iunea aflată la adresa precizată de PC. Registrul PC este incrementat automat, fiind astfel pregătit să adreseze următoarea instruc iune. Deci, după ce se execută instruc iunea I1, con inutul lui PC devine 47108. Se încarcă în UCC instruc iunea I2. După execu ia acesteia, PC va con ine adresa 47128. Deşi la această adresă este memorată o dată, ea este încărcată în UCC şi, prin urmare, este tratată ca instruc iune. Se pot ivi următoarele situa ii: - con inutul lui D4, printr-o întâmplare, coincide cu o instruc iune a unită ii centrale, caz în care este executată ca atare şi con inutul lui PC este autoincrementat; - con inutul lui D4 nu coincide cu nici o instruc iune acceptată de unitatea centrală, caz în care programul este abandonat (terminare anormală). Prin acest exemplu s-a arătat cum data este tratată de calculator ca instruc iune. Deci, prin actualizarea contorului de adrese după execu ia fiecărei instruc iuni, se asigură înlăn uirea normală a instruc iunilor din program (derularea programului în secven ă). Cum se poate proceda

Bazele programării

25

atunci când nu se face parcurgerea în secven ă şi este nevoie să se sară peste câteva cuvinte de memorie pentru a ajunge la instruc iunea dorită? Programatorul are la dispozi ie instruc iunile de salt, prin folosirea cărora se asigură întreruperea secven ei normale de program, prin încărcarea for ată în PC a adresei la care se găseşte instruc iunea de executat. Se presupune că instruc iunea I2 este: SALT LA 47168. După ce se execută instruc iunea I1, contorul de loca ii devine 47108. Se execută, în secven ă, instruc iunea I2 care pune contorul de adrese pe valoarea 47168 (fiind o instruc iune de salt). Prin urmare, în UCC se încarcă instruc iunea I3 ş.a.m.d. În exemplul anterior s-a considerat că toate instruc iunile au lungimea de un cuvânt. În secven a logică a programului, ultima instruc iune trebuie să fie de tip STOP. După extragerea instruc iunii din memorie (prima etapă în prelucrarea unei instruc iuni) se execută următoarele etape: calculul adresei operandului; efectuarea opera iei propriu-zise, precizată de instruc iune. În cadrul fiecărei etape se execută un anumit număr de faze. Indiferent de modul de realizare a fazelor (prin macroinstruc iuni sau prin func iuni cablate), principial, modul de prelucrare a unei instruc iuni este asemănător. Se consideră că în UCC se găseşte instruc iune I3: ADUNA (4704) cu (4712) care adună con inutul de la adresa 47048 cu con inutul de la adresa 47128 iar rezultatul se depune la adresa celui de-al doilea operand. Pentru a în elege modul cum se execută această instruc iune se presupune că UAL este formată din două registre (sumatoare), în care se realizează calcule. Instruc iunea I3 poate fi descompusă în următorii paşi (figura 2.4.): - preia con inutul operandului sursă de la adresa 47048 (D3) într-un sumator; - preia con inutul operandului destina ie de la adresa 47128 (D4) în al doilea sumator; - efectuează calculul între cele două sumatoare, cu rezultatul în S1; - depune con inutul sumatorului S1 în memorie la adresa 47128. În mod similar se pot interpreta şi alte opera ii de calcul. Toate opera iile realizate asupra datelor se efectuează în unitatea aritmetico-logică. Această afirma ie este valabilă şi în cazul uneia din cele mai simple opera ii: MUTA (47148) IN (47008), care se descompune astfel: - preia operandul sursă de la adresa 47148 (D5) în sumatorul S1; - depune con inutul sumatorului S1 în memorie la adresa 47008 (D1 se pierde, depunânduse peste el D5). Ce se va întâmpla în cazul instruc iunii ADUNA (47008) cu (47108)? Răspuns: con inutul de la adresa 47108 (I2) este tratat ca dată.
D1
4700 4702

D2
4704

D3
4706

I1
4710

I2
4712

D4
4714

D5
4716

I3

D6
4720 4722

I4
4726

S1

PC

4716

+
S2 UAL
adună (4704) cu (4712)

(I3)

UCC

Fig. 2.4. Prelucrarea unei instruc iuni
Prin acest exemplu s-a văzut cum instruc iunea este tratată ca dată şi, mai mult, cum un program îşi poate modifica instruc iunile proprii. Nu toate limbajele de programare oferă posibilitatea intercalării în memorie a datelor şi instruc iunilor. De fapt, această intercalare nici nu

c2.5)..an prin aplicarea func iei α fiecărui caracter ai. an.. Cum toate opera iile îşi depun rezultatul în memoria internă.9.9 poate fi reprezentat în mai multe feluri: +13. .2. Opera ii de intrare/ieşire Opera iile de intrare/ieşire realizează citirea . +139 etc.6. Toate limbajele de programare acceptă adresarea directă a operanzilor.care este structura externă a datelor (formatul extern). punerea lor la dispozi ia utilizatorilor necesită opera ia de scriere. a2. 139..de unde (unde) sunt introduse/extrase datele.n. înainte de adresare. La adresarea indirectă (figura 2. programatorul trebuie ca. 2.şi scrierea . în modul descris anterior.5. Şirul c1. Se notează cu Ia mul imea imaginilor pe suportul extern de intrare pentru elementul a∈A. i=1.cn rezultă din şirul a1. apare ca necesară opera ia de citire prin care se transferă datele furnizate de utilizator.. Elementele care definesc o instruc iune de I/E sunt: . să încarce în zona de tip pointer adresa operandului.extragerea datelor din memorie. o codificare în virgulă fixă sau în virgulă mobilă). Instruc iunile pot adresa operanzii direct sau indirect. .11 s-a presupus că imaginea numărului a∈A pe suportul extern de intrare este şirul de caractere a1. Unele dintre ele acceptă lucrul cu pointeri (adresare indirectă). Fiecare număr din A se reprezintă pe un suport extern sub forma unui şir de caractere (caracterele apar in unei mul imi K). În acest caz. instruc iunea memorează adresa unei zone care stochează adresa operandului. Aplica ia α este o codificare standard a mul imii K de caractere (ASCII). Aplica ia f este o codificare bijectivă a mul imii A într-o mul ime de coduri reprezentabile pe un suport intern (de exemplu. Imaginea pe suportul extern a unui număr a∈A nu este. Deoarece datele pot fi prelucrate doar dacă se găsesc în memoria internă. Instruc iune Adresă Pointer Adresă operand Operand Fig.care este adresa memoriei în/din care se introduc/extrag datele.). în general. . Modul de realizare a coresponden ei dintre un număr reprezentat ASCII pe un suport extern şi acelaşi număr reprezentat intern virgulă fixă sau virgulă mobilă este prezentat schematic în figura 2.. Se notează cu Ca mul imea şirurilor de coduri care se ob ine din elementele lui Ia prin aplicarea func iei α..introducerea datelor în memorie . a2. În figura 1.Bazele programării 26 este recomandată. . având în vedere gestionarea greoaie a tipurilor de informa ii: date şi instruc iuni... Reprezentarea numerelor pe suporturile externe la care are acces în mod direct operatorul uman trebuie să fie ASCII.. . unică (de exemplu a=13.. Fie a∈A⊆ℜ. Adresarea indirectă Se spune că zona de memorie care stochează adresa operandului este de tip pointer.

Între elementele unei colec ii de date pot fi identificate sau. Coresponden a între reprezentarea externă şi internă a datelor Pentru orice a∈A se defineşte func ia ψ :{Ca | a∈A } → {f(a) | a∈A} dată de ψ(Ca)=f(a). pot fi introduse rela ii care să determine pe mul imea respectivă o anumită structură. se disting: structuri cu acces direct. ale cărei componente îşi men in proprietă ile (tipul). constituie o structură de date. d) –113. în conformitate cu ordinea specificată.6. c) –143. individualizabilă prin nume. α-3 an* Suport extern de ieşire a2 * Fig. an Suport extern de intrare 27 α α α ψ f(a) Suport intern * ψ f -1 c1* c 2* cn* α-1 a* a 1* α-2 . Analog se poate analiza func ia de decodificare (f -1). e) 113.. că func ia f se realizează în calculator prin intermediul func iilor α şi ψ. 2. eventual. e) transferul datelor în buffer.. După modul de selectare a componentelor.. d) 215. d) transferul datelor din memoria principală pe supor i externi. deci. Se observă. e) 216+1. c) 215-1. b) 216-1. în aplica iile practice se utilizează colec ii de date. Teste de autoevaluare 1. O dată reprezentată VF algebrică pe 2o are valoarea maximă: a) 216.Bazele programării a a1 f c1 c2 cn a2 . la care o componentă poate fi selectată fără a ine seama de celelalte componente. adică un mod de ordonare. 2. b) –15. Structuri de date În afara datelor scalare. O colec ie de date pe care s-a definit un mecanism de selectare a elementelor (componentelor). Selectarea componentelor unei structuri se poate realiza folosind identificatorii asocia i acestora (accesul prin nume) sau prin pozi ia pe care o ocupa în structură.2. Aceste func ii sunt realizate pe baza unor instruc iuni precizate de programator. astfel încât să se faciliteze prelucrarea. structuri cu acces . Alegerea func iei ψ depinde de f şi de mul imea {Ia | a∈A }. Numărul în zecimal a cărui reprezentare internă în VF algebrică este 10001111 este: a) 143. c) transferul datelor între zone de memorie principală. Ea este o entitate de sine stătătoare.. 2. b) scrierea datelor pe supor i magnetici. 3. Opera ia de scriere desemnează: a) afişarea datelor pe monitor.

Dacă o structură de date se compune din (sau se poate descompune în) structuri de acelaşi tip.2. caz în care se numesc structuri externe (fişiere).Bazele programării 28 secven ial. Pentru datele de tip static sunt alocate zone de memorie bine definite. masivul (tabloul) şi articolul. Structura este cu acces direct. deoarece datele de grup din interiorul ei corespunzând unor . Structuri statice de date Pe lângă datele elementare (scalare). Pentru datele de tip dinamic. În func ie de modul de alocare a zonelor de memorie se disting date de tip static sau dinamic. în func ie de necesită i. respectiv plane de matrice. Articolul este o structură de date eterogenă. cu una. împreună cu componentele acesteia. la care localizarea unei componente se face printr-un proces de parcurgere a mai multor componente. este implicită). în momentul compilării. Practica programării a impus. Necesitatea acestor date suplimentare apare în cazul reprezentării dispersate a structurilor de date. adică fiecare câmp (elementar sau grupat) poate fi referit direct prin numele său. formată din numele masivului şi un număr de expresii indiciale (indici) corespunzând dimensiunilor acestuia. când componentele sunt de acelaşi tip şi neomogene. Componentele structurii arborescente. se spune că aceasta este o structură explicită (altfel. structurile de date pot fi împăr ite în omogene. fără a face referiri la celelalte elemente din structura înregistrării. de obicei adrese. fie prin incluziuni de articole în articole. de tip arborescent (figura 2. matrice. bazându-se pe adresarea prin pointeri. două sau mai multe dimensiuni. Dacă în reprezentarea structurii de date pe suportul de memorie se înregistrează. ca structuri de date frecvent utilizate. numite câmpuri. în care componentele nu ocupă zone adiacente pe suportul de memorare. şi date care materializează rela iile de ordonare. Componentele unei structuri de date pot să fie date elementare (scalare) sau să fie ele însele structuri de date. care face obiectul acestei lucrări. dischetă etc. frecvent este necesară introducerea în memoria internă a unor colec ii de date între elementele cărora există anumite rela ii. Masivul este o structură de date omogenă. Structurile de date se pot regăsi în memoria internă (structuri interne) sau pe un purtător extern (bandă magnetică. se spune că structura respectivă de date este recursivă. se numesc referin e sau pointeri. sunt individualizate prin nume.în majoritatea limbajelor de programare. Limbajul C. Toate structurile de date care au aceeaşi organizare şi sunt supuse aceloraşi opera ii formează un anumit tip de structură de date. iar datele suplimentare. când componentele sunt de tipuri diferite. zonele de memorie sunt alocate în momentul execu iei.).cu unele diferen e şi particularită i . extinzând no iunea de tip de dată şi asupra mul imilor ordonate de date. Tipul dinamic corespunde tipului referin ă (pointer). Articolul este o structură recursivă. conform cu ordinea acestora (traversare). Articolul este o structură cu acces direct. fiind posibilă chiar eliberarea memoriei ocupate de unele date.). ceea ce explică implementarea lor . Aceste structuri îşi dovedesc utilitatea în aproape toate aplica iile practice. Diversele limbaje de programare implementează structura de masiv în modalită i diferite. referirea unui element fiind realizată printr-o construc ie sintactică numită variabilă indexată. disc magnetic. Rela ia de ordine ierarhică dintre câmpuri se precizează fie prin numere de nivel. Reprezentarea componentelor în zone adiacente corespunde structurilor dense. bi şi tridimensionale se utilizează denumirile de vector. fie ele constante sau variabile. După tipul componentelor. le implementează necontiguu. Pentru masivele uni.

Dacă e=(u. LUNA. chiar rădăcinii (PERSOANA). Terminologia utilizată relativ la digrafuri este similară celei corespunzătoare grafurilor. Un graf orientat (digraf) este o structură D=(V. astfel încât numărul maxim şi ordinea componentelor structurii nu pot fi modificate. Structurile dinamice de date Pentru anumite clase de probleme structurile statice de date nu numai că nu sunt suficiente dar se dovedesc chiar imposibil de folosit datorită limitărilor la care sunt supuse. Grafuri Un graf (sau un graf neorientat) este o structură G = (V. NUME.Bazele programării 29 subarbori. Dacă G2 este un subgraf al lui G1.4. Conven ional. unde V este o mul ime nevidă de obiecte numite conven ional vârfuri. componentele structurilor statice ocupă locuri prestabilite în spa iul rezervat. i=1. limbajele de programare definesc opera iile admise cu valorile componentelor. spa iul de memorie aferent unor astfel de date se defineşte şi se rezervă în momentul compilării programului (rezervare statică). determinate de rela ia de ordonare specifică fiecărei structuri. Una din principalele utilizări ale acestei structuri de date apare în legătură cu fişierele. 2. Exemplu de articol Descrierea unei structuri de tip articol se face prin parcurgerea arborelui în preordine.1. În continuare vor fi considerate în exclusivitate grafurile finite. G2 este un subgraf al grafului G1 dacă V2 ⊆ V1 şi E 2 ⊆ E 1 . Fie grafurile Gi=(Vi.3 Fig. la o dimensiune maximă (cuprinzătoare).v) ∈ E se spune că muchia e are ca extremită i u şi v (este determinată de vârfurile u şi v).2.Ei). În al treilea rând. NIVEL PERSOANA …………………………………. astfel: se parcurge arborele de sus în jos şi de la stânga la dreapta.…1 MARCA NUME DATA ÎNCADR. AN. chiar dacă nu este în întregime utilizat în anumite momente ale execu iei programului. iar E este o mul ime (posibil vidă) de perechi ordonate cu componente elemente distincte din V. • câmpuri grupate (date de grup). cu condi ia descrierii complete a fiecărui subarbore. iar obiectele mul imii E se numesc muchii.E). chiar dacă acest lucru nu va fi precizat în mod explicit.E) este finit dacă V este o mul ime finită. Obiectele mul imii V se numesc vârfuri. conservă aceleaşi proprietă i ca şi structura în ansamblul său. OCUPA IE LOC DE MUNCA . în ultimă instan ă. Spa iul nu poate fi disponibilizat şi nici împăr it cu alte date. În primul rând. Elementele din structura înregistrării sunt: • câmpuri elementare corespunzând nodurilor terminale de pe fiecare ramură a arborelui (în exemplul din figura 2. G2 este un graf par ial al lui G1 dacă V2=V1. unde V este o mul ime nevidă iar E este o submul ime (posibil vidă) a mul imii perechilor neordonate cu componente distincte din V. potrivit tipului de bază al structurii.7. LOC–MUNCA) şi.E).7: MARCA. corespunzând nodurilor neterminale (DATA– INCADRARII. ATELIER. SECTIE.2. OCUPATIE. Graful G=(V. elementele mul imii E sunt numite arce sau muchii ordonate. ZI.…2 ZI LUNA AN SECTIE ATELIER ECHIPA …. În al doilea rând. . ECHIPA).

este posibil ca (vi .. în cazul în care se doreşte reprezentarea costurilor ca ponderi ale grafului. un drum Γ cu l(Γ)=0. v j ) ∈ E a ij =  . respectiv α = ∞ dacă are semnifica ia de pierdere. vj reprezintă cel de-al i-lea. atunci matricea de adiacen ă A ∈ Mnxn({0. Fie Γ: u0. În cazul grafurilor ponderate. v j ) ∈ E .5)}. Lungimea drumului.v∈V. grafică: fiecare vârf este figurat printr-un punct. Una dintre cele mai importante proprietă i ale grafurilor o constituie posibilitatea de accesare. iar W o func ie.Bazele programării 30 Se numeşte graf ponderat o structură (V. Func ia W este numită pondere şi asociază fiecărei muchii a grafului un cost/câştig al parcurgerii ei. având ca extremită i punctele corespunzătoare vârfurilor care le determină. Γ se numeşte drum deschis.E. ∞ ) . în cazul unui digraf.E) este un graf (sau digraf) cu V = n . Exemple: 1 1. a ij = a ji (perechile de vârfuri care caracterizează muchiile sunt neordonate. pentru prelucrări cu ajutorul calculatorului sunt necesare reprezentări prin intermediul structurilor de date. deci dacă uv ∈E. 0. respectiv cel de-al j-lea nod din V. un=v. unde G=(V. α =0 dacă ponderea are semnifica ia de câştig. u1.1}) are componentele 1. ∞ )) are componentele: W(v i . Fie G = (V. Fie G=(V. Conven ional. Γ este un drum închis dacă u0=un. 4.un este un u-v drum dacă u0=u.W).. W : E → (0.. uiui+1∈E pentru i∈[0. deci aij ≠ aji. altfel Se observă că în cazul unui graf neorientat matricea de adiacen ă este simetrică – (∀) i.(2. V = n .. j =  . a oricărui vârf al grafului plecând dintr-un vârf dat. respectiv muchiile sunt reprezentate prin segmente de dreaptă orientate (în cazul digrafurilor) sau nu şi etichetate (în cazul grafurilor ponderate) sau nu. dacă (v i . v j ) ∈ E w i. vj reprezintă cel de-al i-lea.5). u. O modalitate de reprezentare este cea prin matrice de adiacen ă. 5}. în timp ce..(1. proprietate cunoscută sub numele de conexitate sau conexiune. E = {(1. j = 1. W∈Mnxn((0. E) un graf cu V = {1. Dacă G=(V. (v j . α. altfel unde vi. unde vi.2).E). Drumul Γ este elementar dacă oricare două vârfuri din Γ . 2.E) este un graf.E) un graf. Secven a de vârfuri Γ: u0..E.n]. v j ). vi ) ∉ E . atunci şi vu ∈E). notată l(Γ) este egală cu n. Matricea ponderilor unui graf ponderat G=(V.un un drum în graful G=(V. n .W). dacă ( v i . O posibilă reprezentare grafică este: 2 4 3 5 Deşi acest mod de reprezentare este foarte comod şi sugestiv în special în cazul grafurilor cu număr mic de vârfuri. 3. u1.(3. prin intermediul unei secven e de muchii (arce). Cea mai simplă reprezentare a unui graf este cea intuitivă.3). reprezentarea matriceală este asemănătoare celei prezentate anterior. În caz contrar. respectiv cel de-al j-lea nod din V. se numeşte drum trivial.

v8.. dacă Γ: u0. Dacă A este matricea de adiacen ă asociată grafului atunci.. bij} şi dij=max{min{aik.E).. v2 G: v5 v4 v1 v3 Fie Γ: u0.1)}. se notează { A k = (a (ijk ) ). v4.. v5. v7.. v5. v3. astfel: pentru orice A=(aij).. Într-adevăr. v2. v1. 0 ≤ i ≤ n astfel încât ui=vj. v3. Dacă A este matricea de adiacen ă a unui graf G=(V. A ⊗ B=(dij). v10 sunt v1-v10 subdrumuri elementare. atunci pentru fiecare k. Exemplu: v2 v1 v4 v5 v8 v10 v6 v7 4. dacă i = 0 '  este de asemenea un u0-un drum. unde ( A p = (aij p ) ) . Pentru graful G. Γ1: v1.. Dacă A=(aij) ∈ Mn({0.. (k) 1. bkj}.u1. Γ2: v1. atunci Γ1: v1. rezultă în final un u0un drum elementar. v9. notate ⊕ şi ⊗ . v5. B=(bij) din Mn({0.1)}. Orice drum cu lungime cel pu in 1 con ine cel pu in un drum elementar cu aceleaşi extremită i.un nu este elementar.un un drum în graful G=(V. v3. v10.vm este un subdrum al lui Γ dacă Γ’ este un drum şi pentru orice j.1}. v9. v8. v1.1)}se definesc opera iile binare. v4 este un v1-v4 drum elementar. Fie Mn({0. v2. dacă există drum de lungime k de la i la j . Fie G=(V. v2.1)} mul imea matricelor de dimensiuni nxn..Bazele programării 31 sunt distincte. v2. a ij =  0. v8.. v3. v9.. a ijp ) este numărul vi-vj drumurilor distincte de lungime p din graful G.v1. Exemplu: 3. eventual... v4 este un v1-v4 drum care nu este proces. pentru orice 0 ≤ i ≠ j ≤ n − 1 .. v4 este un v1-v4 proces care nu este drum elementar. v2. dacă i ≠ 0. Atunci drumul Γ : u 0 u 1 . Γ3: v1. cu excep ia. 1 ≤ k ≤ n −1. j ≠ n  0 1 i j+1 n Aplicând în continuare eliminarea duplicatelor vârfurilor în modul descris. v6.. A ⊕ B=(cij). ( pentru orice p≥1. V = n . v8. v10 . Drumul Γ este proces dacă. u j u j+1 . v9. dacă j = 0 u u .u . Orice drum elementar este un proces.u n . (∀) k ≥ 2 . a extremită ilor. unde 1 ≤ i. v5. k ≥ 1} secven a de matrice definită prin: (1) k ( k −1) A = A. v5. În graful v3 v9 dacă Γ: v1..u1. v2.u i . cij=max{aij. există i. v3. componentele fiind elemente din mul imea {0. Γ2: v1. v5. j ≤ n .u u . altfel . Γ’: v0. 0 ≤ j ≤ m . Pe Mn({0. atunci există 0 ≤ i < j ≤ n şi i ≠ 0 sau j ≠ n astfel încât ui=uj. v5. v4.E). uiui+1 ≠ ujuj+1. A = A ⊗ A . 1 ≤ k ≤ n }.E) un graf. v2..

i≠j. Un graf este conex dacă şi numai dacă toate componentele matricei M sunt egale cu 1. altfel Exemplu: 1 5. Fie G=(V. A = 1 1 1 1   1 1 1 1   1 1 1   1 1 1 . cu 1 ≤ i. rezultă vi≠vj. v1 este un circuit şi nu este ciclu. j ≤ n. Drumul Γ este un circuit dacă Γ este un proces netrivial închis. Semnifica ia componentelor matricei M este: 0. v2. dar care apar cel mai frecvent în aplica ii sunt cele arborescente. Graful G este arbore dacă G este aciclic şi conex. Exemple: 6. dacă nu există un v i − v j drum în G .E) graf arbore. ciclu sunt definite ca şi în cazul grafurilor.j. Drumul Γ este trivial dacă Γ : u. v6. 6 . structurile cele mai simple. Γ se numeşte proces dacă toate muchiile drumului Γ sunt distincte.4.….v1 cu n≥3 este un ciclu al grafului dacă. M = 1 1 1   1 1 1   1 1 1  1 1 1 1 1 1  1 1 1  Calculul matricei existen ei drumurilor permite verificarea dacă un graf dat este conex. v5. v3. există un i-j drum şi graful nu con ine cicluri. v3.. Γ 2: v1. v5. Circuitul Γ : v1. v6 v3 v5 2.Bazele programării (1) ( 2) ( n −1) 32 Matricea M = A ⊕ A ⊕ K ⊕ A se numeşte matricea existen ei drumurilor în graful G. Subgraful H=(V1. Γ 3: v1.E1) al lui G este un subarbore al lui G dacă H este graf arbore. pentru orice i. Orice ciclu este un drum elementar închis. Graful G este aciclic dacă nu există cicluri în G. (∀)1 ≤ i. v3. j ≤ n .2. u. v3.v∈V şi Γ un u-v drum în G. v5 este un proces.j ≤ 6. Arbori În clasa grafurilor conexe. v6. v2. circuit.vn. v4. i ≠ j . 1 ≤ i. v1 este un ciclu. A =  1 1 0 0 1   1 1 0 1 0   1 1 1 1   1 1 3 1 0 . m ij =  1.E) un graf netrivial. Exemple: 3 1 Graful 4 2 5 este arbore. deoarece pentru orice pereche de vârfuri i. Pentru graful: 2 4 3 0  1 A= 1  1  1 1 1 1 0   0 0 0 2 0 1 . Fie G=(V. j. Într-un digraf D no iunile de proces. În graful v1 v4 v2 Γ 1: v1.u.v2. v4.

A.0. vârful 1 nu are frate. FRATE(i).0. care reprezintă numărul ataşat primului descendent al vârfului i. cu V = n . . E = m este graf arbore dacă şi numai dacă G este aciclic şi n=m+1. R=1(rădăcina). Parcurgerea în A-preordine presupune ini ial vârful curent ca fiind rădăcina arborelui.5. În plus există şi posibilitatea ob inerii unor reprezentări mai eficiente pentru acest tip de graf.0.4.3. FIU=(2. Notă: Fie G=(V. respectiv a “fratelui” unui vârf este marcată printr-o valoare diferită de numerele ataşate vârfurilor (de obicei valoarea 0). care reprezintă informa ia ataşată vârfului i (de obicei valoarea i). Cele mai uzuale reguli de parcurgere a arborilor orienta i sunt prezentate în continuare. INF(i). G este graf conex minimal (oricare ar fi e∈E. pentru fiecare vârf i al arborelui.E) cu proprietatea că pentru orice u. Absen a “fiului”. Proprietatea 2: Un graf G=(V.0. FRATE=(0. v ∈ V dacă uv∈E.0.E) digraf netrivial.11.10.E’).9.8. care reprezintă numărul ataşat vârfului descendent al tatălui vârfului i şi care urmează imediat lui i. Cu alte cuvinte.0). G este graf arbore 2.0. Un graf orientat D=(V. Graful G=(V. Pentru reprezentarea arborelui se re ine rădăcina şi numărul nodurilor. G este graf aciclic maximal (prin adăugarea unei noi muchii în graf rezultă cel pu in un ciclu).0. iar vârful 9 are “fiul” 13.6. Următoarele afirma ii sunt echivalente: 1. Digraful D este simetric dacă (∀) u.Bazele programării 33 Verificarea proprietă ii unui graf de a fi arbore poate fi efectuată pe baza unor algoritmi care să verifice calită ile de conexitate şi aciclicitate. Una dintre modalită i este reprezentarea FIU-FRATE. Aceeaşi verificare poate fi realizată şi pe baza proprietă ilor care urmează. dacă şi numai dacă vu∈E.0.E) un graf. prin eliminarea muchiei e graful rezultat nu este conex) 3. Se aplică aceeaşi regulă de vizitare pentru arborii având ca rădăcini descenden ii vârfului curent.0. E = m este graf arbore dacă şi numai dacă G este conex şi n=m+1. uv∈E. iar vârful 14 are fratele 15. arborii fiind vizita i în ordinea dată de numerele ataşate vârfurilor rădăcină corespunzătoare.7.0. Se vizitează vârful curent şi sunt identifica i descenden ii lui.12.15. atunci vu ∉ E se numeşte graf asimetric. 0. care constă în numerotarea conven ională a vârfurilor grafului şi în re inerea. Deoarece un arbore orientat este un caz particular de digraf. Exemplu: Următorul arbore orientat este reprezentat astfel: N=15 (numărul de noduri ale arborelui). unde E’={uv | uv∈E sau vu∈E} se numeşte graf suport al digrafului D.0. 1 2 5 10 6 7 3 8 13 4 9 14 15 11 12 O parcurgere revine la aplicarea sistematică a unei reguli de vizitare a vârfurilor grafului.13. Un arbore orientat este un arbore direc ionat cu rădăcină. “fiul” lui 1 este 2. Fie D=(V. a următoarelor informa ii: FIU(i).0.14.E). 0). pentru reprezentarea lui poate fi utilizată oricare din modalită ile de reprezentare a grafurilor. problema verificării dacă un graf este arbore revine la verificarea aciclicită ii grafului şi a rela iei existente între numărul vârfurilor şi numărul muchiilor grafului. v ∈ V.E). cu V = n . Proprietatea 1: Un graf G=(V.

2.6.8. inordine (SRD) şi postordine (SDR).1.9.3 postordine: 7. Parcurgerea pe niveluri. legătură fiu stânga legătură fiu dreapta identificator nod Datorită particularită ii lor. Rădăcina arborelui este de nivel 0. În parcurgerea RSD (rădăcină-subarbore stâng-subarbore drept). Diferen a între aceste trei tipuri de parcurgere este dată de momentul în care devine vizitat fiecare vârf al arborelui.6. fie ca fiu dreapta. respectiv descendent drept (fiu dreapta). În parcurgerea SRD (subarbore stâng-rădăcină-subarbore drept). În parcurgerea SDR (subarbore stâng-subarbore drept-rădăcină) vizitarea fiecărui vârf este efectuată după ce au fost parcurşi subarborii aferen i lui. a legăturilor către descenden ii lui.1. în cazul ambelor metode fiind prioritare vârfurile aflate la distan ă maximă fa ă de rădăcina arborelui ini ial. pentru fiecare nod. SDR sunt: preordine: 1. vizitarea vârfului este efectuată după ce a fost parcurs subarborele stâng. Notă: Parcurgerile în A-preordine şi A-postordine sunt variante de parcurgeri în adâncime. Un arbore binar este un arbore orientat cu proprietatea că orice vârf v are maxim doi descenden i (od(v)≤2). care la momentul ini ial este chiar rădăcina arborelui.3.8.2.2. Parcurgerea A-postordine diferă de parcurgerea în A-preordine numai prin faptul că rădăcina fiecărui arbore este vizitată după ce au fost vizitate toate celelalte vârfuri ale arborelui. C. . Pentru vârfurile cu od(v)=1. dacă distan a de la vârf la rădăcină (lungimea r-v drumului) este egală cu i. fiecare vârf al arborelui este vizitat în momentul în care devine vârf curent.9 inordine: 4. Liste Lista este o structură dinamică de date formată din mai multe noduri.7. 2. Un vârf v al unui arbore orientat cu rădăcină r se află pe nivelul i al arborelui. Un nod este o structură de date care con ine două păr i distincte: o parte de informa ie utilă (memorată în nodul respectiv) şi o parte de informa ie de legătură (folosită pentru a identifica în memorie următorul nod din listă).6.5.7. absen a unui descendent putând fi reprezentată prin valoarea nulă (nil). Reprezentarea unui arbore binar poate fi realizată prin re inerea. Nodul v este neterminal dacă od(v)>0.4.5. secven ele de vârfuri rezultate prin aplicarea parcurgerilor RSD. arborii binari oferă posibilitatea aplicării de noi metode de parcurgere (pe lângă cele aplicabile pentru arborii generali): parcurgerile în preordine (RSD). unicul descendent este specificat fie ca fiu stânga. cei doi descenden i sunt desemna i ca descendent stâng (fiu stânga).4.9.8. În cazul od(v)=2. Se numeşte nod terminal (frunză) orice vârf v al arborelui cu od(v)=0. Regula de vizitare pentru aceste tipuri de parcurgere revine la parcurgerea subarborilor stâng şi drept corespunzători vârfului curent.3. Exemplu: Pentru arborele de la exemplul anterior.Bazele programării 34 B.5. SRD.3.4. Parcurgerea pe niveluri a unui arbore orientat constă în vizitarea vârfurilor sale în ordinea crescătoare a distan elor fa ă de rădăcină.

dacă lista este vidă. din defini ie. iar referin ele creează mecanismul care le leagă. O mul ime L a = {(d i . Vârfurile grafului se memorează într-o listă. un nod cuprinde două referin e. numărare noduri etc. notată nil. permi ând utilizarea economică a spa iului de memorare şi.p i . cât şi a succesorului imediat. denumit listă densă. Prin inserări şi ştergeri o listă „creşte” şi „descreşte” în timp (ca număr de noduri). informa ia de legătură din fiecare nod asigurând regăsirea nodului următor (pentru liste asimetrice) respectiv a nodului următor şi succesor (pentru liste simetrice). fiecare celulă a listei având o legătură către lista vecinilor acelui vârf (vârfurile din graf adiacente cu vârful corespunzător acelei celule şi indicat ca informa ie utilă). dn C C dn dn-1 … b) d2 dn-1 … a) B d1 d2 d1 Fig.Bazele programării 35 Grafurile pot fi reprezentate prin intermediul listelor.s i ∈ P} este o listă simplu înlăn uită (sau asimetrică) dacă pe La s-a definit o structură liniară şi s1=nil. s i ) d i ∈ D. iar nil prin legătură la pământ (figura 2.a). devin de prisos (ca în cazul vectorilor). în anumite cazuri.b). Se notează mul imea referin elor din acest spa iu cu P şi se adăugă la ea o valoare referin ă specială. În cele ce urmează se consideră un spa iu oarecare de memorie adresabilă. Asupra unei liste se pot realiza o multitudine de opera ii: traversare. adică referin ele. fie nil. La o listă densă nodurile sunt dispuse adiacent în spa iul de memorare şi informa iile de legătură. fiind posibilă cunoaşterea atât a predecesorului. căutare nod. iar si. 2. Se remarcă. În acest sens se asociază listei o referin ă C. i ≠ n sunt referin e spre succesorii direc i în ordinea specifică (figura 2. d i . s i ∈ P} este o listă dublu înlăn uită (sau simetrică) dacă pe Ls s-a definit atât o structură liniară directă. Spunem că o listă este complet identificată dacă se cunoaşte adresa primului nod al său şi structura unui nod.8. iar si (i>1) este referin ă spre succesorul direct al lui di. s i ) d i ∈ D. implementări mai eficiente pentru anumite clase de algoritmi.pi) cu di ∉ D şi pi ∉ P. De aici derivă şi atributul de înlăn uită. Se notează cu D mul imea informa iilor care vor fi con inute de nodurile unei liste. Sunt însă tipice opera iile de inserare (adăugare) şi ştergere de noduri. În aceste condi ii. i ≠ 1 şi pi. care con ine fie adresa acestui nod. Pentru reprezentarea unei liste asimetrice. informa iile de legătură (pointerii) vor fi marcate prin săgeată. nodurile pot fi plasate în memoria calculatorului în zone diferite.3. Pentru a putea lucra cu aceste liste este nevoie să se cunoască o singură informa ie: adresa primului nod din listă. numit în continuare capul listei. solicitând spa iu pentru noile componente şi . deoarece dau însuşi caracterul dinamic al acestor structuri. un nod poate fi desemnat prin perechea (di. Pentru listele înlăn uite. Liste simplu (a) şi dublu (b) înlăn uite O mul ime L s = {(p i .8. În cazul listelor dublu înlăn uite. cât şi inversa sa şi s1=pn=nil. că nodurile unei liste pot apărea dispersate în spa iul de memorare. care o deosebeşte de cazul particular.

Astfel. după sau înaintea unui anumit nod identificat printr-o cheie. 2. Inserarea unui nod într-o listă înlăn uită se poate realiza cu verificarea existen ei anterioare a nodului în listă. Localizarea unui nod prin traversare este o opera ie de căutare. Inserarea. În cazul unei liste simetrice trebuie creată şi legătura în sens invers (figura 2. Singura diferen ă fa ă de inserarea într-o listă asimetrică este înscrierea informa iei despre nodul precedent. cap … 3 1 p cap … 4 2 2 1 p b) 2 a) Fig. structura şi numărul de noduri ale listei suferă o permanentă schimbare. Pentru inserarea într-o listă simetrică este necesară crearea legăturilor între noduri în ambele sensuri. informa ia de legătură din acesta primind ca valoare adresa noului nod creat. Inserarea la începutul listelor asimetrice (a) şi simetrice (b) Inserarea unui nod la sfârşitul listei. Pentru adăugarea unui nod la sfârşitul listei se creează întâi un nod nou cu informa ia utilă care trebuie inserată. Scopul este de a găsi un nod care să con ină în partea de informa ie utilă anumite date. în cazul în care lista este vidă sau nu există un nod care con ine informa iile cerute. În caz contrar trebuie parcursă lista pentru a ajunge la ultimul nod. Primul nod din lista ini ială va avea acum ca precedent nodul nou creat p (figura 2. Deoarece inserarea are loc la începutul listei. Se observă că întotdeauna se modifică capul listei. 1. .9. Deoarece va fi ultimul nod în listă. nodul inserat devenind noul cap al listei.10). Opera ia de căutare se poate încheia cu succes. nu va exista un nod precedent. caz în care se procedează direct la inserare (se permit noduri duplicate).9). adică cu localizarea unui astfel de nod sau fără succes. caz în care nu se mai face inserarea. Traversarea.Bazele programării 36 eliberând spa iul ocupat de componentele şterse. Inserarea unui nod la începutul listei. nu există un nod următor deci informa ia de legătură spre nodul următor va avea valoarea nil. În ambele cazuri inserarea se poate face în mai multe locuri: la începutul listei. Dacă lista este vidă atunci capul listei ia ca valoare adresa noului nod creat (va fi singurul nod din listă). deci informa ia respectivă va primi valoarea nil. sau fără nici un fel de verificare. 2. la sfârşitul listei.

r 2 q a) 1 3 q b) p r 2 4 p 1 Fig. deoarece se reduce. 2. p se numeşte referin ă de urmărire. ştergerea se realizează mai eficient şi mai uşor din punct de vedere algoritmic dacă ea priveşte nodul cap de listă. 2.12. În continuare vom considera cazul căutării după cheie. Inserarea la sfârşitul listelor asimetrice (a) şi simetrice (b) Inserarea după un anumit nod al listei. conform figurii 2. Inserarea înseamnă „ruperea” unei legături între două noduri şi crearea unor noi legături astfel ca noul nod să se interpună în listă între cele două noduri a căror legătură a fost „ruptă”. Acesta poate fi localizat în mai multe feluri: în mod exact. să fie în urma lui p cu un nod. La fel ca şi inserarea. Dacă listele simplu înlăn uite pot fi traversate într-un singur sens. prin stabilirea unei condi ii care trebuie să fie îndeplinită de nod. pentru eliminarea nodului p. se atribuie aceeaşi valoare lui q. Se precede atribuirea de valoare pentru p care schimbă nodul curent. la actualizarea referin ei de cap. prin furnizarea unei chei a cărei valoare trebuie să se regăsească în informa ia utilă a nodului căutat.a).10. sau relativ. când p=nil.11.11. Ştergerea. Inserare în listă asimetrică (a) şi simetrică (b) 3. Ini ial. este necesară introducerea unei referin e suplimentare q care. atunci ştergerea propriuzisă trebuie precedată de o căutare după con inutul informa ional al nodurilor. Prima opera ie necesară inserării este localizarea nodului după care se face inserarea. în procesul de traversare. De aceea. . în momentul în care s-a localizat nodul p de şters nu se mai cunoaşte precedentul său q care. în principiu.Bazele programării cap … 37 a) p cap … b) p Fig. de atribuirea q=p. se inserează la începutul listei sau se inserează la sfârşitul listei. trebuie să fie legat de succesorul acestuia (figura 2. Dacă trebuie şters un nod interior listei. Datorită acestei situa ii. Dacă nu se găseşte nici un nod care să corespundă criteriului de căutare (cazul căutării cu eşec) sunt posibile mai multe decizii: nu se inserează noul nod.

Comportamentul unei astfel de structuri este de fapt un model abstract al cozilor întâlnite în diferite situa ii: cozi de persoane. Stivă şi coadă În timp ce pentru a trata corect o stivă este suficientă o referin ă spre top.12. Coada (queue) este o listă asimetrică la care opera ia de inserare se face la un capăt. Stive şi cozi Stivele şi cozile sunt liste particulare din punctul de vedere al opera iilor de ştergere şi inserare ale nodurilor din listă. . şters sau în fa a lui se poate insera un nou nod care devine cap de stivă. Stiva (stack) este o listă asimetrică (figura 2.ultimul intrat. primul ieşit). O coadă este vidă atunci când f=s=nil. adică primul nod al listei. având în vedere că orice acces se poate face numai la ultimul nod inserat.4. Acesta poate fi citit. 2. Ştergere în liste înlăn uite 2. cozi de automobile etc. primul ieşit) având în vedere că numai nodul din fa ă poate fi citit sau şters.a) la care opera iile de inserare. Un astfel de comportament este bine sugerat de modul în care se garează şi se scot vagoanele într-o linie moartă (închisă) sau de modul în care se pot stivui şi utiliza scândurile într-un depozit etc.13. denumit fa a cozii (figura 2. denumit spatele cozii. iar ştergerea şi citirea se fac de la celălalt capăt. 2. inserare citire ştergere dn C citire ştergere FA Ă dn F dn-1 b) coadă … d2 dn-1 … d2 d1 a) stiva SPATE d1 S inserare Fig. Stiva este o structură frecvent folosită în gestionarea dinamică a spa iului de memorie şi reprezintă un mecanism curent în procesul transferului de parametri între un apelator şi un subprogram etc.Bazele programării 1 q f p a) Liste asimetrice q 2 p r 38 1 b) Liste simetrice Fig.13.b). ştergere şi citire a informa iilor se fac numai în capul listei (top).primul intrat.13. Coada este denumită şi listă FIFO (First-In-First-Out . Stivele se mai numesc şi liste LIFO (Last-In-First-Out .4. pentru coadă trebuie men inute două referin e: una pentru fa a (f) şi alta pentru spatele cozii (s).

L. C. 2003 . ASE. e) eterogenă cu acces direct. e) o colec ie recursivă de date. Bazele programării calculatoarelor. I. d) inserarea se face la capul listei. Roşca. Programarea calculatoarelor. d) o colec ie de date compusă din subcolec ii de tipuri diferite. studen ii au cunoştin e şi abilită i de reprezentare a datelor şi a structurilor de date. c) inserarea. C. 7. Ghilic-Micu. 6. Mircea. c) omogenă cu acces direct. I. M. Stiva este o listă la care: a) inserarea şi ştergerea se fac la capul listei şi citirea se face la baza listei. Stoica. 3:d). Bibliografia unită ii de învă are 1. 5:c). 7:b). Gh. 6:e). Cocianu. Ed. 2006.Bazele programării 39 Teste de autoevaluare 4. 4:a). ASE. B. După încheierea acestei unită i de învă are. C. b) inserarea. Cocianu. C. 2:d). structuri statice şi dinamice de date. Teorie şi aplica ii. iar ştergerea şi citirea se fac la baza listei. d) eterogenă cu acces secven ial. Bătăgan. Ed. Rezumat În cadrul acestei unită i de învă are au fost studiate următoarele aspecte în ceea ce priveşte datele şi structurile de date: cunoştin e teoretice privind conceptele de informa ie. Structura de date se defineşte ca: a) o colec ie de date pe care s-a definit un mecanism de selectare a componentelor. ştergerea şi citirea se fac la baza listei. Silvestru. Ştiin a învă ării unui limbaj de programare. Uscatu. cunoştin ă. Teorie şi aplica ii în C. Articolul este o structură: a) dinamică. M. b) omogenă cu acces secven ial. B. b) o colec ie de date la care o componentă este independentă de celelalte. b) omogenă cu acces secven ial. c) omogenă cu acces direct. d) eterogenă cu acces secven ial. e) eterogenă cu acces direct. c) o colec ie de date compusă din subcolec ii de acelaşi tip. Răspunsuri şi comentarii la testele de autoevaluare 1:c). Uscatu. Bucureşti. Ghilic-Micu. e) inserarea şi ştergerea se fac la baza listei şi citirea se face la capul listei. dată. Stoica. Masivul este o structură: a) recursivă. C. Gh. ştergerea şi citirea se fac la capul listei. modalită i de reprezentare internă a datelor. 5. M. ISBN 973-594-5916 2. Roşca.

adică. Având în vedere marea diversitate a PPAD. Etapele rezolvării problemelor cu calculatorul Cuprins Obiectivele unită ii de învă are 3 3. se reduc la preluarea integrală în memoria internă a calculatorului. Durata medie a unită ii de studiu individual . b) existen a unui volum mare de date de intrare şi de ieşire. PPAD din categoria a) permit. în general. urmărirea realizării produc iei. aplica ii bazate pe metode de calcul numeric). croire. solu ii simple de organizare a datelor care. aplica ii de gestiune economică). programarea produc iei. Între aceste extreme există.. Caracteristici generale ale PPAD 3. studen ii vor avea cunoştin e teoretice şi abilită i practice despre: caracteristici generale ale PPAD.1. realizată succint în cele ce urmează. sisteme de ecua ii liniare. alocare a resurselor etc. organizarea procesului de rezolvare a PPAD. într-o formulare globală. cu constituirea lor în . în general. exprimate matematic prin ecua ii algebrice şi transcendente. cât şi modele economico-matematice bazate pe calcule laborioase: gestiunea stocurilor. o diversitate de aplica ii. integrale. frecvent.2. ecua ii diferen iale. dintre care unele presupun atât volume mari de date.2 ore 3. dublată de calcule laborioase (aplica ii tehnico-inginereşti. Aplica iile informatice acoperă un evantai foarte larg de situa ii. adică. eviden a personalului şi calculul salariilor. eviden a mijloacelor fixe. asociată uzual cu calcule de complexitate redusă (eviden a materialelor. în cele ce urmează se propune o structurare pe clase a acestora şi se analizează tipurile de solu ii între care se poate alege în procesul de informatizare. a contractelor de aprovizionare/desfacere etc. care conduc la solu ii bazate pe aproximări succesive.1. În contextul prezentului capitol se consideră suficientă şi relevantă doar investigarea caracteristicilor celor două mari clase de aplica ii eviden iate. Fazele dezvoltării programelor Răspunsuri şi comentarii la testele de autoevaluare Bibliografia unită ii de învă are Obiectivele unită ii de învă are 3 Dupa studiul acestei unitati de învatare. Caracteristici generale ale PPAD „Probleme de prelucrare automată a datelor” (PPAD) este o denumire generică pentru aplica iile practice ale informaticii în economie sau în alte domenii de activitate. evident. ale cărui extreme pot fi caracterizate astfel: a) existen a unui volum relativ redus de date de intrare şi de ieşire. fazele dezvoltării programelor.Bazele programării 40 3. probleme de transport.

solu ii mixte. chiar când datele sunt organizate în fişiere. Singura problemă în accesul la datele organizate în fişiere o reprezintă trecerea de la memorarea liniară a elementelor în fişier. ştergere. În algoritmi. . uzual. matrice. programe de consultare (interogare). i≤ m.la nivel de aplica ie informatică. bazat. plane de matrice etc.la nivel de sistem informatic. atunci când nu se poate pune problema unor solu ii tip. ştergeri). Totuşi. frecvent. . adesea nedepăşind nivelul celor patru opera ii aritmetice. rescriere. folosind func ia rang r(i. la caracterul lor de elemente ale unor masive (tablouri) cu două sau mai multe dimensiuni. alegând liniarizarea pe linii (ordinea lexicografică). Pe exemplul matricelor. În cazul unor volume mai mari de date se poate folosi şi memoria externă. această variantă este. În general. În concluzie. care uneori se compensează. în rezolvarea PPAD se poate distinge între următoarele variante de solu ii: solu ii proprii. Alegerea între cele trei variante depinde de mai mul i factori. În general. care se regăsesc în forme identice (sau cu diferen e nesemnificative) . La limită. principalele tipuri de opera ii sunt cele de prelucrare a colec iilor de date organizate pe purtători externi: citire. relative sau indexate) sau organizarea datelor în baze de date (cu structuri ierarhice. pe aproximări succesive. adesea aceasta este singura variantă accesibilă.). modificări. la problemele din categoria b) accentul principal cade pe organizarea şi între inerea colec iilor de date memorate pe purtători externi. Datorită volumelor mari de date. afectând corectitudinea rezultatului final. La regăsirea elementelor masivului (consultarea fişierului). Utilizarea unor pachete de programe aplicative este posibilă pentru activită ile cu un anumit grad de generalitate. În majoritatea cazurilor. adică nu apare necesitatea actualizării datelor (adăugări.j)=n(i-1)+j. permi ând chiar furnizarea elementelor într-o ordine oarecare. respectiv ansamblul activită ilor unui organism economico-social (sistem informatic). cu posibilitatea ca unele subsisteme (aplica ii) să fie realizate prin solu ii mixte. dintre care o importan ă aparte are aria (dimensiunile) problemei: un domeniu de activitate strict delimitat (aplica ie informatică). în general de două tipuri: programe de creare şi actualizare (între inere) a colec iilor de date.Bazele programării 41 structuri de tip masiv (vectori. la această clasă de PPAD aten ia principală se deplasează către algoritmul de calcul. cu condi ia precizării coordonatelor. în cazul unei matrice Amxn. nu se ajunge la păstrarea lor pe perioade mari de timp. Indiferent de nivelul de organizare ales. j≤n.dacă r modulo j = 0.j poate fi determinată printr-un calcul simplu. utilizarea pachetelor de programe aplicative. pentru satisfacerea cererilor de informare.dacă r modulo j <> 0. cea mai neeconomică. Această tehnică se poate folosi la memorarea datelor în fişier (crearea şi popularea fişierului). după cum se poate constata şi din prezentarea următoarelor cazuri: . precum şi cele de verificare a corectitudinii datelor (opera ii de validare). solu iile proprii sunt posibile pentru orice PPAD. atunci când domeniul de activitate are o serie de particularită i care nu permit utilizarea unor eventuale pachete de programe aplicative şi. cu organizarea datelor în fişiere (uzual. pornind de la pozi ia în fişier. când nu există asemenea pachete de programe pentru domeniul respectiv. dar frecvent se cumulează (se propagă) pe parcursul prelucrării. se poate alege între două solu ii: organizarea datelor în fişiere (secven iale. de tip re ea sau rela ionale). ce pot conduce la apari ia unor tipuri specifice de erori (erori de trunchiere şi erori de rotunjire). Complexitatea calculelor este redusă. pot fi determinate coordonatele elementului. tehnologia de prelucrare conduce la lan uri (sisteme) de programe. văzută ca o prelungire a celei interne. datorită marii diversită i a organismelor economicosociale. scriere. astfel: . fişiere relative). atunci i=[r/n] şi j=n. evident. pozi ia în fişierul relativ a unui element ai. atunci i=[r/n]+1 şi j=r modulo n. Din perspectiva costurilor implicate de diversele faze ale realizării unei solu ii informatice.

este posibil ca solu iile de acest tip să evolueze către realizarea unor pachete de programe aplicative. Adoptarea unei asemenea solu ii elimină costurile de proiectare şi realizare a aplica iilor (sistemelor) informatice. dar poate conduce la unele necesită i de adaptare a sistemului informa ional propriu. proiectare şi implementare a sistemelor sau aplica iilor informatice. programele incluse în fluxurile tehnologice specifice diverselor tipuri de prelucrări. costurile de realizare. în cele ce urmează se abordează numai cazul unor aplica ii informatice de mai mică amploare. Organizarea procesului de rezolvare a PPAD După complexitatea problemelor abordate în vederea rezolvării cu calculatorul electronic. Pe baza diferen ierilor eviden iate. se face distinc ie între proiectarea logică de detaliu şi proiectarea fizică de detaliu). pot fi utilizate produsele din categoria spread-sheet (foaie de calcul). care presupune elaborarea modelului de ansamblu al sistemului informatic şi planificarea realizării sale pe păr i componente (subsisteme. elaborarea programelor. În al doilea caz. fără a furniza direct solu ii. optimizarea transporturilor. în resursele implicate şi în durata lor totală vor exista o serie de diferen e. Pe un plan mai general. În primul caz. simplifică substan ial efortul de realizare a lor.Bazele programării 42 la mai multe organisme economico-sociale. abordate independent sau ca parte a unor sisteme informatice. gestiunea financiar-contabilă etc. acurate ea şi generalitatea abordării. Realizarea sistemelor (aplica iilor) informatice este un proces complex. de asemenea. conform priorită ilor stabilite în etapa anterioară şi pe baza documenta iilor reunite în proiectul logic de detaliu şi proiectul tehnic de detaliu. Depinzând de tipul aplica iei. aplica ii). unul sau câteva programe. Această variantă reduce. realizarea programelor este doar una dintre etapele procesului de studiu. etapele de realizare a sistemelor informatice sunt următoarele: studiul şi analiza sistemului informa ional actual. care are ca obiective elaborarea modelului de detaliu al sistemului informatic şi stabilirea solu iilor tehnice de realizare (corespunzător. care are ca obiectiv principal formularea cerin elor şi a restric iilor pentru sistemul informatic (caietul de sarcini). în func ie de datele de intrare şi modul de organizare a acestora. gestiunea stocurilor. Solu iile mixte presupun încadrarea în solu ii proprii a unor pachete de programe aplicative. pentru domenii specifice. într-o abordare schematică. de nivelul de abordare (aplica ie. solu iile proprii pot conduce la una din următoarele situa ii: sisteme de programe realizate la nivelul unor aplica ii informatice. pe de altă parte. în această categorie pot fi incluse şi produse care. impuse. pentru prelucrări de serii de date statistice. în cazul unor probleme de amploare redusă. ca şi pentru orice alte date ce se organizează în tabele. De exemplu. pentru care se men ine în continuare denumirea de PPAD. impuse pachetelor de programe. Printre acestea pot fi men ionate aplica iile bazate pe modele de programare liniară. în care se realizează. cu obiective specifice. proiectarea de detaliu. care presupune darea în func iune a sistemului şi utilizarea curentă a acestuia. structurat în mai multe etape. pe de o parte. din perspectiva programelor ce vor fi elaborate. destinate unora dintre aplica iile unui sistem informatic. cum este EXCEL. analiză. proiectarea de ansamblu. implementarea şi exploatarea sistemului. În modul de realizare a acestor etape. se ajunge frecvent la . dar necesită elaborarea unor interfe e între intrările/ieşirile pachetelor de programe şi celelalte componente ale sistemului(aplica iei) pentru care se elaborează solu ii proprii. Cu aceste observa ii. optimizarea croirii. de varianta de solu ie aleasă şi. sistem informatic). redusă la enumerarea şi prezentarea obiectivelor principale.

precum şi cerin elor simple de prelucrare să nu fie necesare solu ii complexe. iar în procesul consolidării (editării de legături) se validează utilizarea resursei memorie. În cazul programelor interactive este necesară realizarea unor interfe e prietenoase.). În cazul aplica iilor de mai mari dimensiuni. Una dintre metodele uzuale de elaborare a algoritmilor este proiectarea structurată. a căror rezolvare se abordează de către o echipă de analizăproiectare-programare. optimizarea utilizării resurselor calculatorului (timp unitate centrală. de la punerea problemei până la rezolvarea ei. În procesul compilării programele sunt testate sintactic. Testarea şi definitivarea programelor. mărimea şi propagarea erorilor. de către o singură persoană. uzual. Există. În general. precizia rezultatelor. Stabilirea resurselor. care să lanseze solicitări clare. Etapele de rezolvare a PPAD sunt: Formularea problemei. memorie internă şi echipamente periferice). bazate pe realizarea unor sisteme de programe. deoarece unele dintre metode nu pot fi aplicate tocmai datorită solicitării acestor resurse peste limitele admisibile. În această etapă se exprimă matematic toate transformările şi prelucrările la care sunt supuse datele de intrare pentru a se ob ine rezultatele. În acelaşi sens. Elaborarea (proiectarea) algoritmilor. precum şi transformările şi prelucrările care se aplică asupra datelor de intrare pentru a se ob ine rezultatele. Formalizarea matematică şi alegerea metodei numerice. în acelaşi timp. să se re ină informa iile care sunt necesare următoarei etape (varia ia indicilor. modificărilor reduse. precise şi complete. sub forma unor specifica ii de problemă. datele de intrare şi modul lor de organizare.Bazele programării 43 realizarea tuturor etapelor. pentru întregul algoritm şi pe module. La alegerea metodei numerice de rezolvare trebuie analizate cu aten ie stabilitatea şi convergen a metodei. de asemenea.). tipul. Se recomandă ca în etapa formalizării matematice să se stabilească şi ordinea de efectuare a prelucrărilor. formularea problemei poate fi primită de programator de la analistulproiectant. simplificând substan ial eforturile depuse în etapele de scriere. datorită numărului mic de informa ii utilizate. se stabileşte dacă este necesară segmentarea programului pentru reacoperire etc. probleme relativ independente. care sunt seturile de date ce vor fi folosite la testare. Pe baza analizei algoritmilor se precizează. în ce limbaj urmează să fie scris fiecare modul. ini ializarea variabilelor şi masivelor etc. testare şi definitivare a programelor. eventual în paralel dacă se lucrează în echipă. este necesar să se estimeze necesarul de memorie. Este o etapă complexă care presupune analiza riguroasă a problemei şi a formalizării ei matematice. este foarte importantă faza testării algoritmilor. Formularea clară. corectă şi completă a problemei reprezintă o cerin ă importantă pentru finalizarea cu bune rezultate a activită ii de proiectare şi realizare a programelor. se aproximează necesarul de memorie internă. echipamentele periferice necesare. momentul introducerii sau extragerii datelor. unele probleme economico-sociale sau administrative în care. Pe baza algoritmului elaborat se realizează codificarea modulelor. Este necesară precizarea că această etapă este cu deosebire importantă în cazul problemelor tehnico-inginereşti sau economice bazate pe folosirea modelelor matematice. pot fi abordate în această variantă unele probleme tehnico-ştiin ifice. În această etapă se precizează rezultatele care trebuie să se ob ină şi forma lor de prezentare. timpul de prelucrare. pseudocod etc. De asemenea. această etapă se încheie cu reprezentarea algoritmului într-o anumită formă (schemă logică structurată. în faza de scriere a programelor. Uzual. se pun în eviden ă condi iile ini iale şi restric iile referitoare la solu ie. modul în care au fost . Scrierea programului trebuie să se facă respectând strict algoritmul (eventual se pot face modificări şi detalieri ale acestuia) urmărinduse. Scrierea programelor. ale cărei reguli se vor aplica. de asemenea. care nu conduc la cerin e deosebite privind volumul şi organizarea datelor şi sunt. Programul scris într-un limbaj sursă va fi compilat şi consolidat.

pe baza unor seturi stabilite de date de control. procedurile utilizatorului sau ale sistemului. Prin limbaj de programare se în elege o mul ime de . lista programelor care trebuie executate în amonte etc. După punerea la punct. Într-o abordare schematică.valorile şi forma lor de prezentare). modul în care au fost concepute opera iile de intrare/ieşire sau. Definitivarea documenta iei programelor. enumera i etapele de realizare a sistemelor informatice. Această fază asigură men inerea în func iune şi dezvoltarea programelor. s-au realizat unele documente necesare exploatării corecte a programelor. programatorii trebuie să determine dinainte rezultatele . modul de apel al procedurilor şi func iilor şi structura datelor şi parametrilor care se transferă între apelator şi apelat. precizia algoritmului etc. prin aplicarea unui algoritm asupra datelor de intrare. această etapă este obligatorie pentru exploatarea. constituindu-se într-un dosar de prezentare şi exploatare.Bazele programării 44 apelate. descrierea resurselor necesare şi a restric iilor de utilizare. în general. implicit sau explicit. proces care se poate continua pe tot parcursul utilizării lor. dezvoltarea şi adaptarea programelor. organigrama modulelor. Documentarea corectă a programului face posibilă. formalizarea matematică şi modelul matematic. în intercorelările lui interne. exemple de utilizare. Programele considerate corecte se memorează pe medii magnetice. Acestea se completează. schemele logice structurate (sau alte forme de reprezentare a algoritmului) pentru fiecare modul. Se mai face men iunea că. chiar „birocratică”. trebuie testat întreg lan ul.). După parcurgerea acestor faze programul se testează în execu ie. fiind urmărite în vederea depistării unor erori care nu au putut fi sesizate anterior. lista şi forma întrebărilor şi răspunsurilor în conversa ia cu utilizatorii. Exploatarea curentă. cum au fost gestionate resursele de intrare/ieşire etc. Instruc iunea reprezintă exprimarea într-o formă riguroasă conform regulilor de sintaxă ale unui limbaj artificial (limbaj de programare) a unei opera ii şi precizează func ia şi adresele operanzilor. Test de autoevaluare 1. care comandă opera iile de prelucrare a datelor. Fazele dezvoltării programelor Utilizarea calculatoarelor necesită elaborarea programelor pe baza cărora se ob in rezultate dorite. pe măsura desfăşurării precedentelor etape. de asemenea. eventual constituite în biblioteci. într-un lan de programe dintr-un sistem. redactează şi ordonează.). folosirea lui de către al i utilizatori. Deşi mai pu in spectaculoasă. 3. asociată unui algoritm de rezolvare a problemei.2. procesul de prelucrare. Un program reprezintă o mul ime ordonată de instruc iuni.instruc iuni de utilizare (procedura de punere în lucru. În această fază programul se consideră corect dacă rezultatele ob inute sunt cele scontate (pentru datele de test. S-a arătat că. mai ales dacă fac parte dintr-un sistem. date de intrare. programele intră în utilizare. care cuprinde: descrierea problemei (rezultate.

În practică. Ea este realizată de componenta software numită link-editor. numită preprocesare. 3. care din punct de vedere al utilizatorului sunt fişiere de tip text. create prin editare specifică limbajului sau de utilizare generală. numit limbaj maşină (sau limbaj cod obiect executabil). Scrierea programelor într-un astfel de limbaj este greoaie şi ineficientă. PASCAL etc. BASIC. COBOL. impun ca programele să fie supuse unei prelucrări anterioare. în urma compilării se mai pot ob ine fişierul cu listingul programului sursă şi fişierul cu programul sursă tradus în limbaj de asamblare. utilizatorii folosesc limbaje evoluate (universale. cum ar fi FORTRAN. algoritmice) apropiate de factorul uman. printre care şi C. Link-editorul încorporează în programul obiect atât module .1). Ea este realizată de componenta software numită compilator. Transformarea programelor sursă în programe obiect executabile se realizează.1. El este apropiat de maşină. Etapele dezvoltării unui program Unitatea centrală a unui calculator recunoaşte un singur limbaj. Programele scrise întrun astfel de limbaj se numesc programe sursă. Unele limbaje. Compilarea este opera ia de traducere a programului sursă în program cod obiect.Bazele programării 45 cuvinte (dic ionar) împreună cu regulile de utilizare a lor (gramatică). Editare Program sursă Compilare Program asamblare Listing sursă Program obiect Biblioteci utilizator Link-editare Biblioteci standard Harta alocării memoriei Program obiect executabil Lansare în execu ie Fig. Editarea de legături (link-editarea) este opera ia de transformare a programului cod obiect. În func ie de posibilită ile compilatorului. necesită coduri numerice pentru opera ii şi adrese absolute pentru operanzi. C. de obicei. Lucrul cu un anumit limbaj evoluat presupune existen a compilatorului pentru acel limbaj. rezultat din compilare în program cod obiect executabil. în mai multe faze (figura 3. Regulile de utilizare sunt de sintaxă (formă) şi de semantică (sens).

4 şi 5. L. După încheierea acestei unită i de învă are. M. Test de autoevaluare 2.3. a) toate. Gh. Programul obiect executabil se lansează în execu ie cu comenzi ale sistemului de operare. B. 6) testare. 2:e).3 şi 4. Bibliografia unită ii de învă are 1. Într-o abordare schematică. Răspunsuri şi comentarii la testele de autoevaluare 1. C. cât şi module executabile din bibliotecile realizate de utilizator. elaborarea programelor. implementarea şi exploatarea sistemului. fazele dezvoltării programelor. Silvestru. Ghilic-Micu. 3) compilare.5 şi 6. proiectarea de detaliu. organizarea procesului de rezolvare a PPAD. 2006. studen ii au cunoştin e şi abilită i de organizare a procesului de rezolvare a problemelor şi a etapelor de dezvoltare a programelor. Bucureşti.4 şi 5. b) 1. invocate (apelate) implicit sau explicit de programul sursă al utilizatorului.2. e) 1. Ed. 5) lansare în execu ie. Uscatu. 2) verificare sintaxă. Bătăgan. Roşca. 4) editare legături.2. I.4. d) 1. Fazele dezvoltării programelor sunt: 1) editare. Rezumat În cadrul acestei unită i de învă are au fost studiate următoarele aspecte în ceea ce priveşte datele şi structurile de date: caracteristici generale ale PPAD.3. ISBN 973-594-5916 . ASE. c) 1. proiectarea de ansamblu. Mircea.Bazele programării 46 executabile din biblioteca specifică limbajului. Bazele programării calculatoarelor. etapele de realizare a sistemelor informatice sunt următoarele: studiul şi analiza sistemului informa ional actual. Stoica. Teorie şi aplica ii în C. Cocianu. C. M.3. C.

date scalare şi/sau structuri de date etc. care poate face obiectul prelucrării şi execu iei de un sistem de calcul. de tip caracter etc. func iile.comentariile. Realizarea structurilor fundamentale de control Răspunsuri şi comentarii la testele de autoevaluare Bibliografia unită ii de învă are Obiectivele unită ii de învă are 4 După studiul acestei unitati de învatare. reprezentând construc ia sintactică de cel mai înalt nivel.3 Expresii 4. . Caracteristicile limbajului C Cuprins Obiectivele unită ii de învă are 4 4.programul. care sunt denumirile (adresele simbolice) pe baza cărora sunt referite în program datele.Bazele programării 47 4. care sunt construc ii formate din operanzi (date numerice.func iile. logici etc. Durata medie a unită ii de studiu individual .expresiile.).1 Elementele de bază ale limbajului C Principalele construc ii sintactice ale limbajului C. dar ignorate de compilator. tipurile.2 Tipurile de date în C 4. care pe baza unor date de intrare furnizează unul sau mai multe rezultate de ieşire. studen ii vor avea cunoştin e teoretice şi abilită i practice despre: elementele de bază ale limbajului C. logice. .1 Elementele de bază ale limbajului C 4. rela ionali. într-o ordine relativă a procesului de agregare sunt: . .instruc iunile. tipuri de date în C.) şi a căror evaluare produce o valoare de un anumit tip. pentru descrierea ac iunilor realizate asupra datelor. realizarea structurilor fundamentale de control.10 ore 4. expresii.declara iile..identificatorii. .) şi operatori (aritmetici. . .4. fişierele etc. care sunt texte prezente în programul sursă. . care sunt construc ii pentru definirea şi descrierea datelor (constante şi/sau variabile.

terminate de caracterul . MatrUnitate. float. Dacă doi identificatori au primele 32 de caractere identice. if. while. Începutul unui astfel de comentariu este marcat de perechea // iar sfârşitul său este marcat de sfârşitul liniei (nu există marcator special). else. SumaElemVector. signed. alfa. abc. (punct şi virgulă). Lungimea unui identificator variază de la un singur caracter până la oricâte. Primul caracter trebuie să fie o literă sau liniu a de subliniere. care au format liber şi care nu se compilează. _DX. numită apelatoare. Comentariile sunt delimitate de perechile de caractere /* şi */ şi se pot întinde pe mai multe linii sursă. din alfabetul latin). void etc. Abc. long. _a. Nu se admit comentarii imbricate (incluse unul în altul). Exemple: PretUnitar. dar care nu se execută decât împreună cu o altă entitate de program. Ele sunt succesiuni de litere (mici şi/sau mari. Comentariile sunt secven e de text compuse din orice caractere admise în setul limbajului. _. x. Instruc iunile sunt construc ii sintactice ale limbajului.Bazele programării 48 Identificatorii sunt denumiri asociate entită ilor referite în program. Orice caracter aflat între delimitatori este ignorat de compilator. dar se iau în considerare numai primele 32. Aceştia sunt numi i cuvinte rezervate (sau cuvinte cheie) şi vor fi introduse pe măsură ce sunt prezentate construc iile sintactice ale limbajului. În general. Conceptul a fost definit de realizatorii limbajului Fortran şi s-a impus în practica programării din . structurate. Unele compilatoare permit modificarea acestei limite de lungime. Nu se recomandă însă ca primul caracter să fie „ _” pentru a nu se face confuzii nedorite cu identificatorii rezerva i folosi i de diferite compilatoare. do. atunci ei vor fi considera i identici de compilator. ____. dar pentru denumirile compuse se recomandă ca fiecare cuvânt să înceapă cu literă mare. până la trecerea pe o nouă linie sursă. au destina ie impusă şi nu pot fi utiliza i în alte moduri sau scop decât cele pentru care au fost defini i. x_1. const. Instruc iunile pot fi clasificate în: simple. comentariile sunt necesare pentru explica ii suplimentare ale programatorului. student. Exemple: for.MedAritmPond. (din ANSI C). cifre zecimale (de la 0 la 9) şi _ (liniu a de subliniere). La compilatoarele C++ a fost adăugată posibilitatea de a scrie comentarii pe o singură linie sursă. în vederea în elegerii ulterioare a logicii sale. enum. return etc. pentru creşterea lizibilită ii programului sursă. Func iile sunt entită i (subprograme) care pot fi proiectate şi realizate independent. Ele indică opera iile (ac iunile) care se aplică datelor în vederea ob inerii rezultatelor scontate prin algoritm. _AL. Exemple: a. pret_unitar. char. Anumi i identificatori sunt predefini i în limbaj. La scrierea identificatorilor se utilizează frecvent literele mici. x1. _FLAGS (din Turbo C). CodProdus nu are aceeaşi semnifica ie cu codprodus. Literele mari nu sunt identice cu cele mici (C face parte din categoria limbajelor case sensitive). _BX. compuse. (din K&R C). Orice caracter aflat după // este ignorat. _AX. X.

de la stânga la dreapta. Ea se defineşte printr-un antet şi un corp (bloc) astfel: antet { corp } Antetul are forma: tip nume(lista_parametrilor_formali) unde: • tip poate fi un tip simplu de dată.Bazele programării 49 următoarele motive: evitarea scrierii repetate în program a unor secven e de instruc iuni aplicate de mai multe ori pe seturi diferite de date. fiind constituit din declarări şi instruc iuni executabile. Unele func ii (de exemplu. un program este o înşiruire de func ii şi declara ii. dar pot returna valori şi prin parametri. Func ia are un nume şi un tip. creşterea eficien ei activită ii de programare prin crearea unor biblioteci de subprograme des utilizate. printre care trebuie să existe o func ie denumită main. sub forma: nume(lista_parametrilor_reali) La apel. Prima şi a doua formă sînt folosite în cazul func iilor care returnează o valoarea prin numele lor. cele care citesc sau scriu date) execută „servicii” şi apoi returnează. valori care pot sau nu să fie utilizate în apelator. parametrii reali se pun în coresponden ă cu cei formali. care pentru fiecare din aplica iile concrete doar se apelează.tip3 identificator …]]] Parametrii sunt separa i prin virgulă. sau return expresie. valoarea sa este atribuită func iei şi se încheie execu ia func iei. tipurile parametrilor reali trebuie să fie aceleaşi ca ale celor formali corespunzători.tip2 identificator[. Pentru o corectă utilizare a datelor. • lista-parametrilor-formali con ine parametrii formali sub forma: [tip1 identificator1[. Pentru fiecare parametru trebuie specificat tipul. Dat fiind faptul că limbajul C este puternic orientat spre func ii. chiar dacă mai mul i parametri sînt de acelaşi tip. Corpul func iei se execută pînă la executarea ultimei instruc iuni sau pînă la executarea instruc iunii return. Corpul este o instruc iune compusă: con ine declara iile locale şi instruc iunile executabile care implementează algoritmul. La modul general. efectul ei este încheierea execu iei func iei. lista poate fi vidă. Dacă lipseşte. este implicit). fără să fie proiectate şi realizate de fiecare dată. A treia formă este folosită în cazul func iilor care nu returnează nici o valoare prin numele lor (poate chiar să lipsească). Prin executarea acestei instruc iuni se evaluează expresia. Apelul func iilor se face prin referirea lor ca operanzi în expresii. Func iile returnează o valoare „prin nume”. sau return. Forma ei generală este: return(expresie). Tipul expresiei din instruc iunea return trebuie să coincidă cu tipul func iei. void pentru altele). . Func iilor care nu trebuie să întoarcă valori prin nume li se poate asocia tipul void (care. La limită. prin nume. Dacă este prezentă. la unele compilatoare. Programul este construc ia sintactică de cel mai înalt nivel. este considerat tipul implicit (int pentru unele compilatoare. necesitatea modularizării problemelor cu grad înalt de complexitate. programul principal este el însuşi o func ie (care poate avea parametri şi poate întoarce un rezultat de tip întreg): main (cuvânt rezervat). El codifică algoritmul. • nume este un identificator care reprezintă numele func iei.

Dacă fişierul este găsit.Bazele programării 50 lansată în execu ie la rularea programului. FORTRAN). se recomandă ca directivele #include să fie scrise la începutul programului. în cadrul căreia se efectuează substituiri asupra textului sursă scris de programator. în locul directivei care l-a invocat. a căror sintaxă (în format BNF) este: <directiva>::=#<cuvant_rezervat>[<parametri>] Directiva #include este folosită pentru includerea de fişiere cu text sursă într-un program şi are următoarea sintaxă: #include<specificator_de_fisier> sau #include”specificator_de_fisier” Prima formă caută fişierul specificat între fişierele standard ale limbajului. Textul inclus va fi compilat ca parte componentă a programului. COBOL. C++) sunt mai flexibile. Pentru a putea utiliza func iile care realizează opera iile de intrare/ieşire trebuie inclus fişierul stdio. folosindu-se calea descrisă în mediul de programare. Directivele de preprocesare. permi ând ca declara iile să alterneze cu instruc iunile executabile. Alte limbaje (de exemplu C. Înaintea compilării. Unele limbaje impun o separare clară a acestora (de exemplu Pascal. păstrând însă regula că orice entitate referită trebuie definită anterior.h> Directiva #define este folosită pentru a substitui unele secven e de caractere cu altele şi are forma generală: #define sir1 sir2 . Pentru a evita confuziile se recomandă ca declara iile să fie reunite la începutul blocului de instruc iuni pentru care sunt vizibile. Un text inclus poate să con ină la rândul lui directive care determină noi includeri de text. Pentru ca textul inclus să fie vizibil din tot programul. Prin preprocesare se rezolvă cerin ele compilării condi ionate. cu rol doar în faza de compilare) şi o parte executabilă (formată din instruc iuni executabile). Dacă fişierul căutat nu este găsit se produce o eroare de compilare. aceasta fiind ştearsă (la limită poate fi considerată o substituire de text). con inutul lui este inserat în program.h. Pentru func ia main sunt permise mai multe forme ale antetului: main() int main() void main() main(void) void main(void) int main(void) Orice program este format dintr-o parte de declara ii (formată din instruc iuni neexecutabile. în care partea de declara ii precede partea executabilă. în C se desfăşoară etapa de preprocesare. se asigură inserarea unor fişiere în textul sursă şi se expandează macrodefini iile. Exemplu: #include<stdio. Preprocesarea este controlată prin directive. A doua formă caută fişierul specificat în calea curentă (de obicei este folosită pentru a include fişiere scrise de utilizator).

Rolul acestuia va fi discutat în alt capitol. prin substituire de text (coresponden a se face conform regulilor de punere în coresponden ă a parametrilor reali cu cei formali: unu-la-unu. char m[M][N].b) (a)*(b) char v[N]. sir2 poate să con ină şiruri de caractere pentru care au fost definite anterior. Clasificarea tipurilor de date în C După modul de alocare a memoriei Statice Simple După numărul de valori memorate Tipuri existente Întregi Reale Caracter . La preprocesare. sir2 poate să fie descris pe mai multe rânduri.6)]. un macro se foloseşte la fel ca orice func ie: se apelează prin numele simbolic urmat de lista parametrilor reali. Din punct de vedere al textului sursă. Preprocesorul şterge din textul sursă apelul macro-ului şi îl înlocuieşte chiar cu secven a de definire. dacă la sfârşitul fiecărui rând (în afară de ultimul) se scrie caracterul \ (backslash).1. Parametrii formali ai macro-ului sunt înlocui i cu parametrii reali. Specifica i cum va arăta secven a de cod următoare. după preprocesare: #define N 10 #define M 10 #define MAX (M+N) #define DIM(a. Acestea vor fi substituite conform defini iilor lor.Bazele programării 51 unde atât sir1 cât şi sir2 sunt şiruri de caractere. Test de autoevaluare 1. Nu se face înlocuirea dacă sir1 apare în interiorul unui literal de tip şir de caractere sau în interiorul unui comentariu. de la stânga la dreapta). tipurile de date se clasifică în statice şi dinamice. 4. În general. Tipurile de date admise de limbajul C sunt prezentate în tabelul 4. se şterge directiva din program şi se înlocuieşte secven a de caractere sir1 cu secven a de caractere sir2 peste tot unde apare în programul sursă. Substituirea poate fi dezactivată din punctul în care apare directiva #undef până la sfârşitul programului sau până la redefinirea lui sir1. Secven a sir1 este denumită nume iar sir2 este denumită descriere. Din punct de vedere al compilării există o diferen ă fundamentală: macro-urile sunt tratate la preprocesare. char v1[10*MAX].v1[10+DIM(5+M. împăr ite la rândul lor în simple şi structurate.1.2 Tipurile de date în C Limbajul oferă posibilită i multiple în declararea şi utilizarea tipurilor de date. Directiva are forma generală: #undef sir1 Între cele mai frecvente utilizări ale directivei #define sunt definirea de constante simbolice (literali cărora li se asociază identificatori) şi definirea de macrodefini ii (necesare simplificării scrierii). Tabelul 4.

. care este interpretat ca fiind de un anumit tip.7*10-308.1.28-1) -128.z.7*10308 3.4*104932 38 Mod de reprezentare Codul ASCII al caracterului.127 (-27. Virgulă fixă aritmetică Virgulă fixă algebrică Virgulă fixă aritmetică Virgulă fixă algebrică Virgulă mobilă simplă precizie Virgulă mobilă dublă precizie Virgulă mobilă extra precizie Întreg unsigned [int] [signed] [int] unsigned long [signed] long [int] float Real double long double Variabilele Datele variabile îşi modifică valoarea pe parcursul execu iei programului... 1.. Tipurile simple de date În limbajul C există o serie de tipuri simple de date predefinite (tabelul 4. Declararea se poate face oriunde în program.65535 -32768.2). pentru tipul char este definită lungimea 1 sau cel mult lungimea tipului int.y.232-1 -231.2. Poate fi prelucrat ca un caracter sau ca un întreg cu/fără semn.Bazele programării 52 Structurate Dinamice Simple Masiv Articol Fişier Pointer Referin ă 4.231-1 3. a căror lungime poate să difere de la un sistem de calcul la altul şi de la o implementare la alta (standardul C este mai elastic decât altele).32767 0.255 (0.4*104932 . ele se asociază unor zone de memorie.3. .4*10. Identificatorii acestora se declară şi apoi se referă în opera ii.. Tipuri simple de date în C Grup a de dată Lungime (octe i) 1 1 2 2 4 4 4 8 10 Tipul unsigned char [signed] char Domeniu de valori 0..3.. Exemple: unsigned x. De exemplu. cu următoarea condi ie: variabilele trebuie declarate înainte de a fi folosite (referite).271) 0.. Declararea variabilelor se realizează prin listă de identificatori (separa i prin virgulă) pentru care se specifică tipul.2.. Domeniul de valabilitate este limitat la blocul în care sa făcut declara ia. Tabelul 4.4*1038 1. tip lista_variabile.. Opera iile afectează con inutul zonelor de memorie. De aceea..

se asociază implicit un tip întreg (şi implicit un mod de reprezentare). Tipul caracter memorează caractere ale codului ASCII.Bazele programării float a.b. Dacă se doreşte for area reprezentării pe 32 de bi i (pentru o valoare din domeniul tipului int). . reali. Constantele Datele constante sunt predefinite la momentul scrierii programului iar valoarea lor este generată la momentul compilării. conform tipului int. typedef float REAL. unsigned char a. Utilizatorul poate defini noi tipuri de date sau poate atribui un alt nume unui tip predefinit sau definit anterior. sau constante simbolice. Exemple: int dim_vector=100. Exemple: typedef int INTREG./* corect */ b=81. …………………………………………… a=100. dacă se utilizează următoarea declara ie: tip nume_variabila=valoare. char k. echivalent cu precedentul */ 4. Pentru caracterele cu coduri mai mici decât 128 nu se sesizează nici o diferen ă (se ob ine aceeaşi valoare şi pentru interpretarea ca virgulă fixă aritmetică şi pentru interpretarea ca virgulă fixă algebrică). Literalii întregi sunt reprezenta i intern în virgulă fixă.2. astfel: typedef descriere_tip nume_utilizator. care se autoidentifică prin valoare. În acest scop se foloseşte cuvântul rezervat typedef.b. dacă nu este posibilă. atunci se foloseşte reprezentarea pe 32 de bi i. /*nu este eroare*/ Definirea de noi tipuri de date. caracter şi şir de caractere. Valoarea numerică folosită depinde de modul de declarare a caracterului: cu sau fără semn. care sunt identificatori (denumiri) asocia i altor constante (literali sau constante simbolice definite anterior). Exemple: Declararea şi utilizarea variabilelor de tip caracter. se adaugă sufixul l sau L. În func ie de mărimea lor. Datele constante pot fi literali (constante propriu-zise). 8 (folosind prefixul 0 – zero) sau 16 (folosind prefixul 0x sau 0X). Ei pot fi exprima i în bazele de numera ie 10 (forma implicită). în orice ordine. În C literalii sunt întregi. dim_vector=50. Particularită ile unor tipuri simple de date.c. /* corect. 53 Variabilele pot fi ini ializate la momentul compilării. Pentru caracterele cu coduri mai mari de 127. Se încearcă întotdeauna întâi reprezentarea pe 16 bi i. Pentru a for a tipul fără semn (unsigned int sau unsigned long) se foloseşte sufixul u sau U. în func ie de expresia din care face parte operandul respectiv).2. reprezentate pe un octet. conform tipului long. Variabilele de tip caracter pot fi utilizate şi ca valori numerice (modul de utilizare se alege automat./* corect */ b=’Q’. valoarea ob inută este diferită. Cele două sufixe se pot folosi împreună.

frac ieE±exponent). Pentru a for a reprezentarea pe 80 de bi i (tipul long double) se foloseşte sufixul l sau L. câte unul pe fiecare octet. ′\377′ reprezintă caracterul cu codul ASCII 255. Secven ele escape sunt folosite şi pentru a reprezenta caracterele de control (coduri ASCII între 0 şi 31). Construc ia ddd este considerată implicit ca fiind codul ASCII al caracterului. Un literal de tip şir de caractere este un şir de zero sau mai multe caractere. Pentru a semnala că un literal continuă pe rândul următor se scrie caracterul \ la sfârşitul rândului curent. ′*′. pe un octet. ca valoare.Bazele programării 54 Literalii reali sunt reprezenta i intern în virgulă mobilă. Semnul + poate lipsi (este implicit). în interiorul şirului se pot folosi secven e escape. unde d este o cifră din sistemul de numera ie octal (0÷7). În reprezentarea internă. iar e este echivalent. Un şir de caractere este reprezentat intern prin codurile ASCII ale caracterelor. Literalii caracter se reprezintă intern prin codul ASCII al caracterului respectiv. fie partea întreagă şi exponentul (inclusiv litera e). la sfârşit adăugându-se caracterul nul (cod ASCII 0 – ′\0′). Exemple: literalul reprezintă şirul Acesta este un literal "sir de caractere" scris pe doua randuri. ′\′′ (caracterul apostrof. Nu este nevoie ca ea să fie precedată de un zero nesemnificativ. cod ASCII 39). care se exprimă printr-o succesiune de două caractere. Literalii de tip şir de caractere. ′ ′ (spa iu). Pentru a reprezenta diferite caractere. Literalii de tip caracter pot participa în expresii cu valoarea lor numerică. Exemple: ′B′. ′\\′ (caracterul backslash. ′\b′ şi ′\10′ reprezintă caracterul BS. În acest ultim caz. ′b′. cod ASCII 92). Caracterul nul nu poate să facă parte dintr-un şir. fiind precedate de caracterul \. Exprimarea externă depinde de caracterul respectiv. reprezentat în baza 8. cu E. "Acesta este un literal \"sir de caractere\" \ scris pe doua randuri. Literalii reali se reprezintă intern pe 64 de bi i (tipul double). Această construc ie poate fi folosită pentru a reprezenta orice caracter al setului ASCII. Pentru a reprezenta caracterele grafice ale codului ASCII extins (coduri între 128 şi 255) se pot folosi numai secven ele escape construite astfel: ′\ddd′. el având rolul de terminator de şir. Din exprimare poate să lipsească fie partea frac ionară. fie partea întreagă. ′\″′ şi ′\42′ reprezintă caracterul ghilimele. Cele două sufixe nu se pot folosi împreună. Reprezentarea folosind caracterul backslash este numită secven ă escape. aşa cum s-a arătat anterior. cu coduri ASCII cuprinse între 32 şi 127) se face prin caracterul respectiv inclus între apostrofuri. Exprimarea externă a unui caracter direct imprimabil (existent pe tastatură.frac ie) sau ştiin ifică (±întreg. Un literal de tip şir de caractere poate fi scris pe mai multe rânduri. Exemple: ′\a′ şi ′\7′ reprezintă caracterul BEL. cod ASCII 34). Excep ie fac caracterele cu semnifica ie specială în C: ‘ (apostrof). Pentru a for a reprezentarea în simple precizie (tipul float) se adaugă sufixul f sau F. Ei se pot exprima sub formă matematică (±întreg. ob inându-se valoarea care se atribuie. un şir de caractere ocupă cu un octet mai mult decât numărul de caractere din componen a sa. La ini ializarea unei variabile de tip caracter se poate folosi oricare din variantele de reprezentare descrise anterior sau orice valoare numerică (întreagă sau reală). delimitate prin ghilimele (ghilimelele nu fac parte din şir). din reprezentarea internă a literalului numeric se iau în considerare primii 8 bi i care sunt interpreta i ca un cod ASCII. ′7′. ′\″′ (caracterul ghilimele. " (ghilimele) şi \ (backslash)." .

două sau mai multe dimensiuni. cu condi ia ca structura în ansamblul ei să nu depăşească zona de memorie maximă permisă pentru structurile de date. Masivul se declară folosind o construc ie de forma: tip nume[dim1][dim2]…[dimn]. dim2. /* matrice cu 10 linii si 20 coloane de elemente reale */ La declararea masivelor se poate face şi ini ializarea lexicografică a acestora. Exemple: #define pi 3. determinată printr-un număr de expresii indiciale corespunzând dimensiunilor masivului. const int dim_vector=10.2. În limbajul C constantele simbolice se construiesc folosind directiva: #define nume_constanta valoare Utilizarea constantelor simbolice în cadrul programelor are următoarele avantaje: .Bazele programării "" "" 55 . . mai uşor de re inut şi de utilizat. dimn sunt expresii constante (evaluate la compilare). constituite după anumite reguli ierarhice şi de dependen ă bine stabilite. Exemplu: Dacă se încearcă o atribuire (de exemplu dim_vector=7) se generează eroare. Exemple: int x[10]. /* vector cu 10 componente intregi*/ float a[10][20]. care indică numărul de elemente de pe fiecare dimensiune. Nici o dată structurată nu poate ocupa în memorie mai mult de 65520 de octe i (lungimea unui segment de memorie). …. 4.şir de lungime 1 (caracterul spa iu) .literalii primesc nume sugestive. dar con inutul lor nu poate fi modificat pe parcursul execu iei programului.141592653589 #define raspuns "D" Constantele obiect sunt variabile ini ializate la declarare. iar dim1. Ele se declară folosind modificatorul const: const tip nume_constanta=valoare. pentru care se rezervă memorie.pentru rularea succesivă a programului cu valori diferite ale unui literal utilizat des este suficientă modificarea valorii constantei simbolice în definire (referirile nefiind modificate). unde tip este tipul comun elementelor masivului. Mul imea are un singur identificator şi oferă posibilitatea referirii elementelor în acces direct prin pozi ie. astfel (pentru masiv bidimensional): tip nume[dim1][dim2]= . Se acceptă oricâte dimensiuni. mai ales dacă sunt forma i dintr-un număr mare de cifre.3. Tipurile structurate de date Tipurile structurate au la bază mul imi (colec ii) de date de tipuri simple sau structurate.şirul de lungime 0 (şirul vid) Constantele simbolice sunt literali cărora li se asociază identificatori. Tipul masiv Tipul masiv este structurat şi desemnează o mul ime finită de elemente omogene constituită ca un tablou cu una.

Componentele de pe ultimul nivel sunt scalare şi se numesc date elementare sau câmpuri. Data de grup de cel mai înalt nivel (rădăcina arborelui) corespunde articolului în ansamblu. Variabilele pot fi declarate şi ca masive. ceea ce permite ca această structură să fie construită recursiv. iar var1. Compilatorul nu verifică corectitudinea indicilor (în sensul de depăşire a dimensiunilor masivului la referirea elementelor).3. prin descompunerea în structuri cu aceleaşi proprietă i (figura 4. fără însă a declara şi un tip utilizator nou. atunci trebuie să fie prezentă lista de variabile (nevidă).2.3. În continuare. iar var1.{1.6. /* matricea contine valorile 1 2 3 1 2 3 1 2 3 0 0 0 0 0 0*/ Masivul poate fi referit global prin numele său. Elementele unui masiv se referă direct.2. var2. Dacă lipsesc parametrii var1. Indicii sunt expresii incluse între paranteze drepte (se mai numesc şi variabile indexate): [indice]. Pentru fiecare dimensiune a masivului trebuie să existe câte o referire de indice.3}}. fiind numai o declarare explicită de tip nou. Dacă lipseşte tip_articol.0. varn sunt identificatorii asocia i variabilelor de tipul articol declarat. utilizabil ulterior la alte declarări.3}. /* vectorul contine valorile 2 3 0 5 6 7 3 6 8 5*/ float a[5][3]={{1. tip_articol este un tip nou de date. se constituie prin agregarea datelor de pe nivelurile inferioare. Articolul poate fi reprezentat sub formă de arbore. ale cărui noduri sunt asociate componentelor structurii. var2. . Conceptual. varn sunt variabile de tipul tip_articol.….7.5}. caz în care este vorba de o declarare de variabile de tip articol. Tipul articol Articolul este o structură de date eterogenă. denumite date de grup.1). atunci tip_articol trebuie să fie prezent.Bazele programării {{lista_const1}{lista_const2}…{lista_constn}}. Indicele de pe fiecare dimensiune are valoarea minimă 0 şi valoarea maximă egală cu dimensiunea din declarare minus o unitate. 56 Exemple: int b[10]={2.…. datele de grup de pe diverse niveluri au aceleaşi proprietă i ca şi articolul.…. între care există o rela ie de ordine ierarhică.varn.var2. varn. ale căror elemente sunt de tip articol: var1[dim1][dim2]…[dimn]. unde tip_articol este identificatorul asociat tipului articol. prin numele masivului urmat de indicele (indicii) corespunzători.{1.2.6. cu acces direct la elementele sale. Declararea împreună a tipului articol şi a variabilelor de acest tip se realizează conform sintaxei: struct tip_articol{lista_campuri} var1.…. var2. Parametrii declara iei pot lipsi (dar nu to i deodată).3}. Datele de pe celelalte niveluri.8.5.

care asigură determinarea lungimii zonei de memorie asociate unei variabile sau unui tip de date. declararea poate fi realizată prin definire recursivă.1. Lista_campuri este o înşiruire de declara ii de câmpuri separate prin punct şi virgulă. int an. 4. Descrierea constituie o definire implicită de un nou tip de dată. }. atunci tipul persoana putea fi scris astfel: struct persoana { char nume[30]. char adresa[50]. Câmpurile unei structuri pot fi variabile simple. } data_nasterii. Este posibilă definirea explicită a unui nou tip de dată. cu reprezentarea internă şi lungimea fizică specifice tipurilor lor. Exemplu: . struct persoana { char nume[30]. asemănătoare declara iilor de variabile. Lista câmpurilor nu poate fi vidă. masive sau alte articole. Dacă nu ar fi existat declara ia tipului articol tip_data. struct { unsigned zi. int an. de forma tip_camp nume_camp. struct tip_data { unsigned zi. struct tip_data data_nasterii. } angajat. Exemple de structuri de articole O variabilă de tip articol poate fi declarată şi ulterior definirii tipului: struct tip_articol var1.Bazele programării DATA ZI LUNA AN a) PERSOANA dată de grup (articol) dată de grup (articol) NUME ADRESA ZI b) DATA NAŞTERII LUNA AN dată de grup (articol) date elementare 57 date elementare Fig. astfel: Exemplu: pentru exemplele din figura 6. } angajat. Aceasta nu poate depăşi 65520 octe i (ca orice variabilă de tip structurat). char luna[3]. adăugând cuvântul rezervat typedef în fa a declarării (în acest caz nu mai pot fi declarate simultan şi variabile). Pentru structura unui articol îşi dovedeşte utilitatea operatorul sizeof. char adresa[50]. Lungimea zonei de memorie rezervată pentru variabila de tip articol rezultă din însumarea lungimilor câmpurilor.1. Variabilele de tip articol se reprezintă intern ca succesiuni de câmpuri elementare. char luna[3].

Pentru a referi. printf("\n%i". }. În lan ul de calificări.zi. folosind operatorul .luna.nume[0]. luna. situate pe ultimul nivel al structurii. celelalte elemente sunt identificatori de câmpuri. Magheru 14". angajat este identificatorul variabilei articol. "Bucuresti.} datan. deoarece zona de memorie rezervată pentru articol este unică. de exemplu.an). angajat. În cele ce urmează se are în vedere numai referirea componentelor de tip dată elementară.data_nasterii. La ini ializarea câmpurilor unui astfel de articol. în condi iile precizate anterior la referirea globală. care se comportă ca şi tipul struct cu o singură diferen ă: la un moment dat al execu iei . asigurarea identificării unice a câmpurilor se realizează prin asocierea numelui acestora cu numele articolului care le con ine. an. //Initializarea articolului din exemplul 1: struct persoana p={"Popescu Ion". Referirea globală este permisă numai în opera ia de atribuire. angajat. Referirea câmpurilor unei structuri se face prin calificare. Dacă anumite componente sunt structuri de date de alte tipuri (de exemplu masive sau şiruri de caractere). 4.h> void main() { struct persoana { char nume[40]. struct { int zi. în referirea elementelor lor se aplică. 2. //sau cu evidentierea structurii data nasterii: struct persoana p1={"Popescu Ion".data_nasterii.nume. primul calificator fiind numele articolului rădăcină. Construc ia rămâne la această formă în cazul în care structura are numai două niveluri: articolul şi câmpurile elementare ale acestuia. Exemplu: #include <stdio. (punct). {2. cu condi ia ca ambele variabile (sursă şi destina ie) să fie articole de acelaşi tip. celelalte fiind nume de câmpuri ale articolului.adresa. 1960}. angajat.nume şi angajat. În articolele cu structură recursivă se realizează calificarea progresivă cu articolele de pe nivelurile superioare. pe lângă calificare. primul caracter din şir. "Bucuresti. 1960}}. Datele de tip articol pot fi referite în două moduri: global sau pe componente. numele articolului rădăcină este nume de variabilă. În activitatea de programare pot fi întâlnite aplica ii care reclamă utilizarea articolelor cu structură variabilă. Construc iile angajat.Bazele programării 58 Considerând declara iile anterioare. În referirea prin calificare. Referirea pe componente (prin numele lor) este o reflectare a faptului că articolul este o structură cu acces direct. iar sizeof(angajat) are valoarea 90. Pentru acest tip de articol. 4. angajat. Exemplu: Referirea prin calificare a câmpurilor articolului angajat de tipul persoana (vezi exemplele anterioare) se realizează astfel: angajat. constanta de tip articol se asociază unei singure structuri. char adresa[30].adresa corespund referirii globale a câmpurilor respective. Magheru 14". limbajul pune la dispozi ia utilizatorilor tipul predefinit reuniune (union). se scrie: angajat. Referirea unor componente de tip articol din structura altui articol este posibilă numai în opera ia de atribuire. care sunt şiruri de caractere.data_nasterii. expresia sizeof(data_nasterii) are valoarea 8.p1.datan. regulile specifice acestor structuri.an În aceste referiri.

ltoa.. atol. tip_campn campn. Marcatorul de sfârşit de şir este gestionat automat de către sistem. Limbajul C dispune şi de alte func ii care lucrează cu şiruri de caractere (func ii de conversie).. Astfel. Declararea tipului reuniune se realizează astfel: union nume_tip { tip_camp1 camp1. Exemplu: 1..h: atof (care necesită şi includerea bibliotecii standard math. cu rol de marcator de sfârşit al şirului..h există definite func ii de intrare/ieşire pentru şirurile de caractere.. Marcatorul de sfârşit nu face parte din şir şi este tratat ca atare de func iile care lucrează cu şiruri de caractere. Gestiunea con inutului respectivei zone de memorie va trebui realizată de către programator. în zona de memorie rezervată articolului nu este memorat decât unul dintre câmpurile acestuia. definite în biblioteca standard stdlib.Bazele programării 59 programului. itoa.. 0 L 1 i 2 m 3 b 4 a 5 j 6 u 7 l 8 9 C 10 0x00 Pentru prelucrarea şirurilor de caractere. Vectorul de caractere (şirurile de caractere) se reprezintă intern printr-o succesiune de octe i în care sunt memorate codurile ASCII ale caracterelor şirului. atoi. tip_camp2 camp2.h). char s[10]="Limbajul C".. Teste de autoevaluare ... în biblioteca stdio. Ultimul octet con ine caracterul NULL (cod ASCII 0 – sau ASCIIZ).. . Totuşi există o diferen ă semnificativă între un vector de numere şi un vector de caractere.. limbajul C pune la dispozi ia utilizatorului o serie de func ii specifice.. Lungimea zonei de memorie rezervate pentru o variabilă de tip reuniune va fi egală cu maximul dintre lungimile câmpurilor componente. Lucrul cu şiruri de caractere Şirurile de caractere se reprezintă conven ional ca masive unidimensionale (vectori) cu elemente de tipul char... pentru memorarea unui şir de n caractere sunt necesari n+1 octe i..}. De asemenea.h. definite în biblioteca standard string.

prin aplicare repetată. Se presupune un articol cu următoarea structură: forma de învă ământ nume data naşterii l u n a an de studiu bursa z i a n zi valoare loc de muncă char[30] id data angajării z i l u n ă a n Cod magazin char[40] int char float Specifica i cum se realizează declararea şi ini ializarea câmpurilor unui student la zi pentru structura articolului prezentat. proces eviden iat în exemplul următor: a { c { + (− b )− { + 15 { expresie expresie expresie expresie 14 4 2 3 expresie 1442443 4 4 expresie 1444 24444 4 3 expresie Ordinea de aplicare a operatorilor din expresii poate fi. În absen a parantezelor. Evaluarea expresiilor produce ca rezultat o valoare de un anumit tip.3 Expresii Asupra datelor pot fi aplica i operatori din diverse clase. A doua şi a treia variantă.1 Operanzi şi operatori .Bazele programării 60 2. Se presupune un articol cu următoarea structură: Vânzări lunare Luna 1 Luna 2 … Luna 12 întreg real real real … 2 4 4 4 … Scrie i modul de declarare a articolului şi lungimea sa în număr de octe i. 4. total sau par ial. expresiile sunt alcătuite din operanzi şi operatori. conduc la recursivitate în construirea expresiilor.3. rezultând construc ii sintactice numite expresii. redusă la o variabilă sau o constantă de un anumit tip. evaluarea se realizează din interior spre exterior. 3. 4. iar dacă sunt mai multe niveluri de paranteze. . Acestea sunt evaluate cu prioritate. evaluarea se realizează în func ie de ordinul de preceden ă a operatorilor. În metalimbajul BNF expresia poate fi definită astfel: <expresie>::=<operand>|<operator_unar><expresie>| <expresie><operator_binar><expresie> Prima variantă din defini ie corespunde celei mai simple forme de expresie. În forma lor cea mai generală. impusă prin folosirea parantezelor. respectiv în interiorul acestora. Exemplifica i referirea câmpurilor.

• o expresie. Regula se aplică pe rând fiecărui operator din cadrul unei expresii. iar rezultatul va fi de tip double. După tipul opera iei realizate. dacă unul din operanzi este de tip unsigned iar celălalt de tip int acesta se converteşte la tipul unsigned. de asociativitatea lor şi regula conversiilor implicite. operatori din aceeaşi clasă. • numele unei func ii. înainte de a efectua opera ia. 4. Majoritatea operatorilor sunt unari sau binari. Se pot scrie expresii complexe care să con ină operatori din toate clasele. ob inând în final tipul expresiei. • apelul unei func ii. Nu pot fi operanzi şirurile de caractere. Operatorii se clasifică după diferite criterii. cei doi operanzi sunt aduşi la un tip comun. 4. În general. operatorii sunt aritmetici. rezultatul având acelaşi tip cu cei doi operanzi. operandul de tip inferior se converteşte către tipul operandului de tip superior.2. dacă un operand este de tip float. iar rezultatul va fi de tip long double. Dacă operatorul se aplică la doi operanzi cu acelaşi tip nu se face nici o conversie. dacă un operand este de tip long. Atunci când un operator binar se aplică la doi operanzi de tipuri diferite. Un operand are un tip şi o valoare. • numele unui tip de dată. dacă un operand este de tip unsigned long. Din ultima posibilitate rezultă că expresia este o construc ie recursivă. • un literal. 6. Limbajul utilizează şi un operator ternar (care se aplică asupra a trei operanzi). În primul rând se convertesc operanzii de tip char către tipul int. rezultatul este eronat (eroarea de depăşire de domeniu). conversia se face astfel: 1. celălalt se converteşte la acest tip. atunci celălalt se converteşte la acest tip. • referirea unui câmp de articol. 5. 3. rela ionali etc. Într-o expresie apar. La evaluarea acestor expresii se ine cont de priorită ile operatorilor (numite şi clase de preceden ă). iar rezultatul va fi de tip long. iar rezultatul va fi de tip float. logici. iar rezultatul va fi de tip unsigned. de obicei. Dacă valoarea lui depăşeşte domeniul asociat tipului de dată.Bazele programării 61 Un operand poate fi una din următoarele construc ii: • o constantă simbolică. • referirea unui element de masiv. Operatorii de atribuire Atribuirea este o expresie cu forma generală: v=expresie . Valoarea se determină fie la compilare fie la execu ie. • numele unui masiv. atunci celălalt se converteşte la acest tip. dacă un operand este de tip double. Dacă operatorul se aplică la operanzi de tipuri diferite. 2. iar rezultatul va fi de tip unsigned long. dacă un operand este de tipul long double. atunci celălalt se converteşte la acest tip. precum numărul operanzilor asupra cărora se aplică şi tipul de opera ie pe care o realizează.3. • o variabilă simplă. celălalt se converteşte la acest tip. dar pot fi şi din clase diferite.

-ii. Entitatea care se poate afla în stânga operatorului de atribuire se numeşte left value. ^. >>. aritmetic sau logic pe bi i (/. cu determinarea unei valori şi a unui tip. s-au introdus operatorii combina i. Pentru eliminarea acestei redundan e.3. Operatorii aritmetici În ordinea priorită ii lor. • memorarea valorii expresiei din dreapta în variabila din stânga. |). Dacă sunt incompatibile se produce eroare la compilare (deoarece compilatorul nu poate insera în codul obiect apelurile pentru opera iile de conversie). *. +. se utilizează frecvent expresiile de forma v = v op (expresie) (de exemplu a=a+b-c). • întreaga expresie de atribuire are valoarea şi tipul variabilei din stânga. operatori binari multiplicativi *. ++. <<. -. % iii. tipul expresiei şi tipul entită ii din stânga operatorului de atribuire trebuie să fie compatibile. operatori unari +. 4. Expresia i*=5 este echivalentă i=i*5. operatorii aritmetici sunt: i. Pentru a se putea efectua atribuirea. Opera iile efectuate de aceşti operatori sunt descrise în tabelul 4. /. un câmp al unui articol sau o expresie în urma evaluării căreia se ob ine o adresă. &. -. nu este folosit) Decrementare (post sau pre) Incrementare (post sau pre) Adunare Scădere Înmul ire Împăr ire Împăr ire întreagă (câtul) Operator + -++ + * / / . O expresie de forma v op= expresie este echivalentă cu v = v op (expresie) Exemple: Expresia a=a+b-c este echivalentă cu a+=b-c. Se observă redundan a de exprimare prn specificarea variabilei v atît în membrul stâng cât şi în cel drept. În practica programării.3.Bazele programării 62 unde v este o variabilă simplă. %. Efectele atribuirii constau în: • evaluarea expresiei din dreapta operatorului de atribuire. un element de masiv. Operatorii aritmetici Semnifica ie opera ie Schimbare semn Păstrare semn (nici un efect. operatori binari aditivi +. Tabelul 4.3.3. cu forma generală op= unde op este un operator binar.

conform conven iei: pentru adevărat valoarea 1 iar pentru fals valoarea 0. valoarea acestuia este modificată înainte de a fi utilizată la evaluarea expresiei din care face parte: ++var (preincrementare) sau --var (predecrementare). depinzând de pozi ia fa ă de operand. Operatorul % are ca rol ob inerea restului unei împăr iri întregi. Semnifica ia unei unită i depinde de tipul operandului asupra căruia se aplică. o unitate înseamnă unu. dacă ambii operanzi sunt întregi. .4. b. se execută împăr ire reală. 4. În limbajul C nu există tipul de dată logic.4. Rezultatul func iei are tipul div_t. (în ordinea priorită ii) iar operatorii rela ionali în tabelul 4. în func ie de tipul operanzilor: a.n).h astfel: typedef struct {long int quot. Astfel de valori sunt produse de două categorii de operatori: operatori logici propriu-zişi şi operatori rela ionali. Rezultatul unei opera ii logice este de tip int.cat. Operatorii ++ şi -. astfel: a. Pentru operanzi numerici. ceilal i admit toate tipurile numerice. în interpretarea programatorului. rest=x.quot.(postdecrementare). care admite numai operanzi întregi.au efect diferit. Incrementare/decrementarea au ca efect modificarea valorii operandului cu o unitate. se execută împăr ire întreagă şi se ob ine câtul. Calculul câtului şi restului unei împăr iri întregi se poate realiza şi prin intermediul func iei div.n. valorile adevărat sau fals. cat=x. Operatorii logici şi rela ionali Expresiile logice sunt cele care. Operanzii asupra cărora se aplică operatorii logici sunt converti i în valori numerice şi interpreta i conform conven iei: adevărat pentru valoare nenulă şi fals pentru zero. //cît long int rem. valoarea acestuia este folosită la evaluarea expresiei din care face parte. în urma evaluării produc. dacă apar înaintea operandului.rest. definit în biblioteca stdlib. apoi este modificată: var++ (postincrementare) sau var-. b.3. dacă cel pu in un operand este de tip real. dacă apar după operand. //rest } div_t. Tabelul 4.5. x=div(m. Exemplu: Determinarea câtului (cat) şi restului (rest) împăr irii numărului m la numărul n se realizează astfel: div_t x.4. Operatorii logici Semnifica ie opera ie Operator Negare ! Şi logic && Sau logic || Sau exclusiv logic Nu există Operatorii logici sunt prezenta i în tabelul 4.rem.Bazele programării 63 Împăr ire întreagă (restul) % Observa ie: Cu excep ia operatorului %. int m. Operatorul / are efect diferit.

6.Bazele programării 64 La evaluarea expresiilor logice se aplică principiul evaluării par iale: dacă expresia este de tip aditiv (operanzi lega i prin operatorul sau). iar pentru fals valoarea 0.6. Operatorii rela ionali Semnifica ie opera ie Operator Mai mare > Mai mare sau egal >= Mai mic < Mai mic sau egal <= Egal == Diferit != 4. Rezultatul unei opera ii rela ionale este de tip int. Tabelul 4. Operatorii rela ionali au acelaşi nivel de prioritate.3. ai căror operatori sunt prezenta i în tabelul 4. Pentru a nu se greşi la evaluarea unor expresii complexe. conform tabelului următor: a b !a !b !a&&b !b&&a !a&&b||!b&&a 0 ≠0 ≠0 0 0 ≠0 0 1 0 0 1 1 0 1 0 0 0 0 1 0 0 1 0 0 0 1 1 ≠0 Operatorii rela ionali sunt prezenta i în tabelul 4. este indicat să se facă ra ionamentul bazat pe logica booleană (cu valori de adevărat şi fals). Asemănător. conform conven iei: pentru adevărat valoarea 1. expresia are valoarea fals şi nu se mai evaluează restul operanzilor. Opera ia sau exclusiv între doi operanzi a şi b se efectuează cu expresia !a&&b||!b&&a. dacă un operand are valoarea fals. Opera ii pe bi i Semnifica ie opera ie Operator Şi logic pe bi i & Sau logic pe bi i | Sau exclusiv logic pe bi i ^ Negare (complement fa ă de 1) ~ Deplasare la dreapta >> Deplasare la stânga << .7. pentru o expresie multiplicativă (operanzi lega i prin operatorul şi). Operatorii la nivel de bit Limbajul permite opera ii pe bi i.5. Tabelul 4. în momentul în care s-a stabilit că un operand are valoarea adevărat toată expresia va fi adevărată şi nu se mai evaluează restul operanzilor.5.

4. a/2). Trebuie re inut că nu se schimbă efectiv tipul operandului. expresie_2. . Execu ia are loc bit cu bit. d.c&1).7 Rezultatele opera iilor logice pe bi i x y x&y x|y x^y ~x 0 0 0 0 0 1 0 1 0 1 1 1 1 0 0 1 1 0 1 1 1 1 0 0 Tot în categoria opera iilor la nivel de bit se încadrează şi deplasările binare la stânga sau la dreapta a con inutului unei variabile întregi: operand<<număr_pozi ii şi operand>>număr_pozi ii Exemplu: 1. Dacă este nevoie. operanzii sunt extinşi la reprezentare pe 16 bi i. int a=10.. doar se foloseşte în expresie valoarea operandului convertită la un alt tip. Operatorul virgulă (. virgula este considerată şi operator într-o secven ă de forma: expresie_1.7.i<8.6. c=13. bi ii unui octet (dată de tip char).Bazele programării 65 Operanzii pot fi de orice tip întreg. . în ordine inversă. Pe lângă rolul de separator într-o listă.. c.i++. Pentru o pereche de bi i (x. d=5 (câtul împăr irii lui 10 la 2). Operatorul de conversie explicită Limbajul oferă posibilitatea conversiei explicite a tipului unei expresii către un tip dorit de utilizator (dar compatibil). Construc ia este numită expresie cast (conversia explicită se numeşte typecast).. Operatorul se utilizează acolo unde este legal să apară o expresie în program şi se doreşte realizarea unui calcul complex. Exemple: Valorile variabilelor după evaluarea expresiei sunt: a=10. de la stânga la dreapta.) Operatorul virgulă este specific limbajului C. char c.) induce evaluarea succesivă a expresiilor.7.c=c>>1) printf("%d". Exemplu: int a=7. b=16. scanf("%d". Opera ia de conversie de tip nu are efect permanent. valorile posibile rezultate în urma aplicării operatorilor logici la nivel de bit sunt prezentate în tabelul 4. b+=c. El este format din numele unui tip de dată inclus între paranteze. float b=(float)a. întreaga secven ă fiind tratată ca o expresie căreia i se atribuie în final valoarea şi tipul corespunzătoare ultimei expresii evaluate (expresie_n). b=3. Expresia de conversie are forma generală: (tip)operand Se observă că operatorul nu are un simbol explicit. 4. d=(c=a+b.&c). for(int i=0. exprimat prin mai multe expresii.3. Tabelul 4.3. expresie_n Operatorul virgulă (.y). Următoarea secven ă afişează.

9. operatorul de referen iere (cu simbolul &) folosit pentru a extrage adresa unei variabile. d.12. rezultatul va fi numărul de octe i aloca i entită ii respective. Ele se numesc operatori de indexare. Operatorul condi ional are simbolul ?:. .3. folosit pentru a accesa un câmp al unui articol.Preceden a: determină ordinea de efectuare a opera iilor într-o expresie în care intervin mai mul i operatori (gradul de prioritate).0) nefiind afectată în nici un fel de opera ia de conversie de tip. operatorul de dereferen iere (cu simbolul *) folosit pentru a extrage valoarea de la o anumită adresă. Construc ia se numeşte expresie condi ională. numele unui articol. Evaluarea expresiilor Expresiile sunt evaluate pe baza următoarelor reguli: . ele delimitând lista parametrilor reali. (caracterul punct).0 (ob inută prin conversia valorii lui a către tipul float). Operatorul condi ional Operatorul condi ional este singurul care are trei operanzi şi este specific limbajului C. parantezele rotunde „()” sunt numite operatori de apel de func ie. Operatorul are mnemonica sizeof şi poate fi folosit în una din formele: sizeof var sau sizeof(var)sau sizeof(tip) unde tip este numele unui tip de dată iar var poate fi numele unei variabile simple. Operatorul dimensiune Operatorul dimensiune este folosit pentru a afla dimensiunea în octe i a spa iului de memorie ocupat de o variabilă de sau definit de un tip.3. operatorul de calificare (cu simbolul ->) folosit pentru a accesa un câmp atunci când se ştie adresa unei structuri. Operatorii paranteze Parantezele au rolul de a include o expresie sau lista de parametri ai func iilor. La apelul unei func ii. 4. Prin includerea subexpresiilor între paranteze se modifică ordinea de evaluare a unei expresii. iar b are valoarea 7.3. Asupra unei expresii între paranteze nu se pot aplica orice operatori (de exemplu nu se pot aplica operatorii de incrementare sau decrementare). 4.3. 4. Al i operatori Din categoria operatorilor limbajului fac parte şi următorii: a. Valoarea şi tipul acestei expresii sunt identice cu cele ale expresie_2 (dacă expresie_1 este adevărată) sau cu cele ale expresie_3 (dacă expresie_1 este falsă). a are valoarea 7 (nu 7.3. Ultimii patru operatori sunt specifici lucrului cu adrese (care nu face obiectul prezentei lucrări). expresie_2 şi expresie_3 sunt expresii.8. cu simbolul . Forma generală este: expresie_1?expresie_2:expresie_3 unde expresie_1. În primele două forme. b.Bazele programării 66 După execu ia secven ei. 4.10.11. Cele două caractere care compun simbolul apar intercalate între cei trei operanzi. operatorul de referen iere (cu simbolul *) folosit pentru a defini un pointer. numele unui masiv. operatorul de calificare. Parantezele pătrate „[]” au rolul de a include expresii care reprezintă indici pentru accesarea elementelor unui masiv. un element al unui masiv sau un câmp al unui articol. e. Pentru ultima formă. c. rezultatul este numărul de octe i pe care îi va ocupa o variabilă de tipul tip. 4. conform formei generale.

c. Asociativitate de la stânga la dreapta de la dreapta la stânga Grad de prioritate maxim de la stânga la dreapta de la dreapta la stânga de la stânga la dreapta minim Teste de autoevaluare 4.b=9. Specifica i care va fi valoarea variabilei c. . expresii rela ionale. y=--x.(binari) << >> < <= > >= == != & (binar) ^ | && || ?: = <<= >>= += -= *= /= %= &= ^= |= . . Preceden a operatorilor Operatori () [] . Asociativitatea şi preceden a operatorilor (începând cu prioritatea maximă) sunt redate în tabelul 4.Asociativitatea: indică ordinea de efectuare a opera iilor în cazul unui set de operatori cu aceeaşi preceden ă. 5. expresii logice. În concluzie. expresiile care pot fi construite în limbajul C se încadrează în următoarele categorii: expresii de atribuire. pentru fiecare opera ie care solicită acest lucru şi în care tipurile diferă. -> +-&* (unari) ++ -(tip) sizeof ! ~ * (binar) / % + .Regulile de conversie de tip: asigură stabilirea unui tip comun pentru ambii operanzi.8. Tabelul 4. expresii aritmetice. Scrie i secven ele echivalente pentru următoarele exemple: y=x++.8.Bazele programării 67 . int a=7. c=(a>b)?a:b.

O instruc iune este simplă dacă descrie o singură ac iune. datorită orientării limbajului spre compactarea textului sursă şi spre neconformism în stilul de programare impus de autori. else c=2.1. un program se regăseşte sub forma unei func ii rădăcină. prin instruc iunile structurate se codifică structurile fundamentale alternative sau repetitive din algoritm. Ea se foloseşte acolo unde trebuie să apară o instruc iune.Bazele programării 68 4. break. denumite instruc iuni compuse. aceasta este vidă.4.4. unic determinată şi care nu provoacă condi ionări. goto. Tipurile de instruc iuni Instruc iunile unui program C se grupează într-un bloc delimitat de o pereche de acolade {}. (punct şi virgulă). ↑ ↑ instruc iune vidă ↑ Instruc iunea de tip expresie evaluează o expresie care. este de atribuire sau de apel al unei func ii (vezi şi capitolul Operatori şi expresii). la limită. C con ine şi instruc iuni care contravin acestora. Instruc iunile simple Instruc iunea vidă descrie ac iunea vidă. dar care nu trebuie să execute nimic. care este terminator de instruc iune şi este obligatoriu pentru a marca sfârşitul fiecăreia. Realizarea structurilor fundamentale de control 4. De asemenea. Orice instruc iune (simplă sau structurată) poate fi transformată în instruc iune compusă. Instruc iunile structurate sunt construc ii care con in alte instruc iuni (simple. return. Corespunzător. chiar dacă.2. poate avea un corp vid: void main() {} După modul de realizare a construc iilor sintactice şi al numărului de ac iuni descrise. structurate sau compuse) delimitată de perechea de acolade {}. compuse sau structurate) care vor fi executate alternativ sau repetitiv. Pe lângă instruc iunile care implementează conceptele programării structurate.4. instruc iunea de evaluare a unei expresii.} if (c==1) . fiind dedusă din contextul unor construc ii sintactice. Instruc iunea compusă . Din categoria instruc iunilor simple fac parte. if (c==1) . în C nu are o mnemonică explicită. else . O instruc iune compusă este o secven ă de instruc iuni (simple. se disting instruc iuni simple şi structurate. Mul imea instruc iunilor executabile ale unui program este. pot fi create blocuri de instruc iuni executabile. În limbajul C. Exemple: instruc iune vidă ↑ instruc iuni vide {. 4. în cele mai dese cazuri. Instruc iunea de tip expresie se ob ine scriind terminatorul de instruc iune după o expresie (acolo unde este legal să apară o instruc iune în program). care. 4. la limită. de exemplu: instruc iunea vidă. Instruc iunile se încheie cu caracterul . la limită. o instruc iune compusă. Situa ia este întâlnită de obicei în cazul instruc iunilor structurate. Un program trebuie să execute cel pu in o instruc iune. Forma generală este: expresie. continue.3.4. Ea implementează natural structura secven ială din programarea structurată.

for. b) Structura alternativă multiplă permite alegerea unei ac iuni dintr-un grup. Instruc iunea care realizează această structură este if : if(expresie)instruc iune_1.2). [default: instruc iuni. în func ie de valorile pe care le poate lua un selector (figura 9. dar sintaxa impune prezen a unei singure instruc iuni: mai multe instruc iuni sunt „transformate” într-o singură instruc iune (compusă). fals condi ie adevărat Instruc iune 2 Instruc iune 1 Fig. compusă sau structurată. Structura alternativă simplă Expresia poate fi de orice tip. în caz contrar se execută instruc iune_2 sau se iese din structură (când construc ia else lipseşte. a cărei sintaxă este: switch(expresie) {case c_1: instruc iuni_1. Dacă valoarea expresiei este diferită de zero (valoare asociată din punct de vedere logic cu adevărat) se execută instruc iune_1. Rezolvarea ecua iei de gradul I.4. prin instruc iune se în elege o instruc iune simplă. Realizarea structurilor alternative a) Structura alternativă simplă (figura 4.]} . ……………… case c_n: instruc iuni_n. 4. 2. while. cuprinse între o pereche de acolade. [else instruc iune_2]. Situa ia este întâlnită în cadrul instruc iunilor if. Instruc iunea compusă se utilizează acolo unde este nevoie să se execute mai multe ac iuni. do.2) permite realizarea unei ramificări logice binare. 4.(float)-b/a) : b ? printf("Ecuatia nu are solutii") : printf("Solutii: orice x real"). Se preferă ca declara iile să fie plasate înaintea instruc iunilor. în func ie de valoarea unei condi ii (expresie cu rezultat logic).5f". în sintaxa lor o singură instruc iune.2. care precizează. Instruc iunile structurate În continuare. Forma generală este: {declaratii instructiuni} Declara iile sunt valabile în interiorul instruc iunii compuse. case c_2: instruc iuni_2.Bazele programării 69 Instruc iunea compusă este o succesiunea de instruc iuni şi declara ii. ax+b=0: a ? printf("Solutia este %10. În limbajul C structura se simulează cu instruc iunea switch. Exemple: 1) if(a>b) a=c. else a=b.4. caz în care instruc iunea if realizează structura pseudoalternativă).

până la terminarea structurii de selec ie. break.3. trebuie inclusă instruc iunea break. Instruc iunea while se execută astfel: se evaluează expresia şi dacă este diferită de zero (adevărată) se execută instruc iunea (simplă. Dacă la prima evaluare a expresiei se ob ine valoarea zero. compusă sau structurată). instruc iuni sunt simple. Pentru a asigura ieşirea din ciclu. Instruc iunea switch evaluează expresia dintre paranteze.3 se scrie: switch(expresie) {case c_1: instruc iuni_1. 4.]} selector selector = v1 selector = v2 instruc iune 1 instruc iune 2 … selector = vn instruc iune n altfel instruc iune Fig. după care caută în lista de expresii constanta cu valoarea ob inută. Dacă pe o ramură sunt mai multe instruc iuni. …. compuse sau structurate. c_1. unice (o valoare nu poate să apară de două sau mai multe ori). atunci nu se execută nimic. Pentru a limita ac iunea strict la execu ia instruc iunilor asociate unei valori. break. [default: instruc iuni. Pentru a simula structura din figura 4. Dacă ramura default lipseşte nu se execută nimic. . . secven ial. Instruc iunea while implementează natural structura corespunzătoare din teoria programării structurate. nu este nevoie să fie incluse între acolade (să fie instruc iune compusă). instruc iuni_n. toate instruc iunile care urmează. case c_2: instruc iuni_2.. instruc iuni_1.. c_n sunt expresii constante. c_2. instruc iunea trebuie să modifice valoarea expresiei. se execută instruc iunile asociate acesteia. Dacă valoarea căutată nu este găsită în listă şi ramura default este prezentă. care determină ieşirea din structura switch.Bazele programării 70 unde: expresie este de tip întreg.. se execută instruc iunile asociate valorii respective şi. de tip int. În acest moment se încheie execu ia instruc iunii while. Dacă este găsită. apoi se reia procesul până când la evaluarea expresiei se ob ine valoarea zero. ……………… case c_n: instruc iuni_n. Structura alternativă multiplă Realizarea structurilor repetitive a) Structura repetitivă condi ionată anterior este implementată prin instruc iunea while cu forma generală: while (expresie) instruc iune.4. Mecanismul de execu ie este redat în figura 4. break. instruc iuni_2.

Mecanismul de execu ie a instruc iunii while Exemple: 1. printf("-"). while (i<n) {printf("\n %4. do { printf("+").} . i=i+1. Instruc iunea do-while se execută astfel: se execută instruc iune apoi se evaluează expresia.} b) Structura repetitivă condi ionată posterior este implementată (cu unele deosebiri fa ă de teoria programării structurate).4. Forma generală este: do instruc iune while (expresie).Bazele programării 71 expresie =0 (fals) ≠ 0 (adevărat) instruc iune Fig. while (a<=100). Mecanismul de execu ie a instruc iunii do-while Instruc iunea do-while este echivalentă cu secven a: instruc iune. 2.5.v[i]).} while(i<=80). while(expresie) instruc iune. dacă expresia este nenulă (adevărată). #include <stdio. 2. Exemple: 1.5. i=1. i++. în timp ce structura fundamentală o realizează pe condi ia fals. realizând repeti ia pe condi ia adevărat. 4. 4. while (a>b) a=a+1. Se observă că instruc iunea do-while se abate de la teoria programării structurate. altfel se încheie execu ia.h> main() { unsigned i. i=0. se repetă procesul. Mecanismul de execu ie este redat în figura 4. prin intermediul instruc iunii do-while. instruc iune ≠ 0 (adevărat) expresie = 0 (fals) Fig.2f". do a=a+1.

scanf("%i". nedefinită în teoria programării structurate. Mecanismul de execu ie a instruc iunii for Pentru a simula structura repetitivă cu numărător (do-for) se folosesc forme particulare pentru cele trei expresii: expresie_1 va fi expresia de ini ializare: contor=valoare ini ială. expresie_3)instruc iune.&n). se evaluează expresie_2 şi dacă este nulă (fals). care.6.Bazele programării 72 c) Structura repetitivă cu numărător nu este implementată în C. Instruc iunea for se execută astfel: se evaluează expresie_1. printf("\n Nr. Exemplu: /*citirea elementelor unui vector*/ #include <stdio.a. se abandonează itera ia curentă şi se trece la următoarea. Prin instruc iunea continue. Forma ei este: continue.&v[i]). poate fi considerată ca o instruc iune repetitivă cu totul particulară. dar pot fi utilizate în măsura în care. for(i=0. scanf("%f". int n.4. de elemente:"). uşurează munca programatorului. altfel se execută instruc iune apoi se evaluează expresie_3.h> void main() { float v[20]. care se poate folosi numai în interiorul unei structuri repetitive.d. expresie_2 controlează terminarea ciclului: contor<valoare finală. Instruc iunea for realizează structura repetitivă din figura 4. .} } 4. expresie_3 realizează avansul contorului: contor=contor+pas.} expresie 1 expresie 2 =0 (fals) ≠ 0 (adevărat) instruc iune expresie 3 Fig. datorită facilită ilor deosebite pe care le oferă.m. expresie3. Ea este mai apropiată de structura while-do.6 şi poate fi înlocuită cu secven a: expresie1.i. Ea poate fi simulată prin instruc iunea for.i++) { printf("\n v[%i]=". expresie_2. 4.5.i+1). while (expresie2) { instruc iune. se încheie execu ia lui for. Se revine la evaluarea lui expresie_2 ş. în aplica ii complexe.i<n. Instruc iunea for din C are următoarea formă generală: for(expresie_1. Instruc iunile de salt necondi ionat şi ieşire for ată din structuri Instruc iunile de salt necondi ionat şi ieşire for ată din structuri contravin principiilor programării structurate.

. 7. } a=x[i]. i<n.. for(j=n-1.} . i>=n-j-1. i++.5 şi 6.. j>=n-i-1.2. i=n-1. i--) for(j=n-1. d) s=0. do { s+=x[i].4 şi 6. i--) . while (i>0) {s+=x[i]. 6) s=1. e) s=0. i>=0. c) 1. 5) i=0. } while(i<n). 2.3 şi 4. i--) s+=x[i].. i<n.. for(i=0. i--) do . j-) . e) toate. . j<n.. z=0.6. j++) for(i=n-1. j++) for(i=n-j-1. Instruc iunea goto realizează salt necondi ionat şi este moşnită din primele limbaje de programare. j>=0. i<n-1.4. c) sortarea unui vector prin metoda bulelor..Bazele programării 73 Instruc iunea are următoarele efecte: • în interiorul instruc iunilor while şi do-while: se abandonează itera ia curentă şi se trece la evaluarea expresiei care controlează terminarea buclei. Rolul unei etichete este de a defini un punct de salt. for(i=0.. j<n. x[i]=z. j<n. c) s=0. for(i=n-1. i++) for(j=n-1... e) niciunul. for(j=0. }. for(i=n-1. i=0.. j++) . j++) . while(i<n) {if(x[i]>0) nr+=1. j>=n-i-1. i++) s+=x[i].7 şi 8... j--) for(i=n-j-1. i>=0. a) 1.. for(i=n-1. O etichetă este un identificator urmat de caracterul : (două puncte).. p=i. i++. i>=0. d) sortarea unui vector prin metoda selec iei. j--) for(i=n-1. i>=0. Următoarele secven e descriu algoritmi recursivi: 1) s=0. j<n.2. i=0.. care nu foloseau principiile programării structurate. i<n.. for(j=n-1. i=0.} . Etichetele au valabilitate locală. Secven a: for(i=0. for(i=n-1. for(i=0. i++) . i--) s+=x[i].. x[p]=a. 4. p=j. Forma generală este: goto etichetă. d) 5. i++) y[i]=x[i]. i<n. Instruc iunea break este folosită numai în interiorul unei instruc iuni structurate şi are ca efect terminarea imediată a execu iei instruc iunii respective. i<n. j<n.5 şi 6. b) 3. c) 2. i++) s*=i. 3. a) toate. i--. nu se poate face salt din corpul unei func ii la o instruc iune aflată în altă func ie. for(j=0. b) 1. după care urmează o instruc iune. j--) . 2) for(i=0. Triunghiul de sub diagonala secundară (inclusiv diagonala) unei matrice pătrate se poate parcurge numai cu secven ele: 1. i++. i<n. 3) nr=0. 9. Care din următoarele secven e nu realizează suma a n elemente ale unui vector: a) s=0.. j++) if(x[j]<z) {z=x[j].. i++) {z=x[i]. • în interiorul instruc iunii for: se abandonează itera ia curentă şi se trece la evaluarea parametrului expresie_3. for(i=0.7 şi 8. j>=0. b) minimul dintr-un vector cu re inerea pozi iei ultimei apari ii.. i<n. for(j=i+1. 8. Test de autoevaluare 6. i++.. i++) z[i]=x[i]*y[i]. către care se poate face trimitere prin instruc iunea goto. i>=n-j-1. 8. 6. do {z+=x[i]*y[i]. } realizează: a) minimul dintr-un vector cu re inerea pozi iei primei apari ii. 7...3. i--) for(j=n-i-1. i++) . while (i<n) {s+=x[i]. 4) for(i=0. b) s=0. în corpul func iei în care sunt definite. i++) for(j=n-i-1. i<n. 5. Din acest motiv. e) căutarea unei valori date într-un vector. d) 3 şi 5.} while(i<n).

1. union { struct {char bursa.10.5}}. Forma de inv.{'D'.cod_magazin.3.}zi.%i. an. Val.v1[10+(5+10)*(6)].vanzari_lunare[i]. struct magazin gigel_srl={200. articol. 8:e).…. float valoare. } 4. 5.gigel_srl1. x=x+1.4. //Initializarea articolului. char m[10][10]. struct {char loc_m[30].7. Declararea şi ini ializarea câmpurilor unui student la zi pentru structura prezentată se realizează astfel: #include <stdio. Articolul se declară astfel: struct magazin {int cod_magazin. 6:d).5.8.parte_vb.1.2f". luna.9. 7:d).%i.valoare).'Z'. an. y=x++. struct {int zi.datan. este echivalent cu secven a y=x. a. printf("\n%6.zi. char v1[10*(10+10)]. y=--x.}data_ang.h> void main() { struct magazin { int cod_magazin.} datan. 2.luna.datan. 1. . //sau cu evidentierea structurii de masiv: struct magazin gigel_srl1={200.11. cu i=0. }id. } parte_vb.: %c. După preprocesare. 9:b). Articolul are 50 de octe i.10. #include <stdio.5.12}.3. //Initializarea campurilor unui student la zi: struct articol a={"Popescu Felix". y=x.an. int an_st. a.9.11.forma_inv.250.8.datan.11.zi. struct { int zi.7. iar referirea câmpurilor se realizează astfel: articol. bursa: %6.2. float vanzari_lunare[12]. Variabila c primeşte valoarea maximă dintre a şi b.12}}.6. }. a.Bazele programării 74 Răspunsuri şi comentarii la testele de autoevaluare 1. a. }articol. {1. }. este echivalent cu secven a x=x-1.1974}.{4. luna. 3.4.vanzari_lunare[10]). float vanzari_lunare[12]. char forma_inv.1.h> void main() { //Declararea articolului cu structura variabila: struct articol { char nume[40]. secven a de cod va deveni: char v[10]. a. anume 9.2f".2. printf("\nData nasterii: %i.6.

Ed. Mircea. Teorie şi aplica ii. Cocianu. Bucureşti 2003. Programarea în limbajul C/C++. Uscatu. I. M. M. ASE. Teorie şi aplica ii. Stoica. Roşca Gh. Teorie şi aplica ii în C. Roşca. ISBN 973-99725-7-8 Bibliografie 1. Marian Dârdală. Ion Smeureanu. Ştiin a învă ării unui limbaj de programare. ASE. C. Gh. B. Silvestru. 2003 3. Programarea calculatoarelor. Bucureşti. Bătăgan. Bazele programării calculatoarelor. Ed. Ed. 2006. CISON. Ghilic-Micu. L. Stoica M. Mircea.. Cocianu. Ed. ASE. Bucureşti 2004. Ghilic-Micu. Gh.. C. Gh. CISON. Stoica. I. M. C. Ghilic-Micu B. I. Uscatu. Cocianu. Uscatu C. C. ISBN 973-99725-7-8 4. Ghilic-Micu. Stoica. M. Bucureşti 2004. ISBN 973-594-243-7 . 2006. B. Ştiin a învă ării unui limbaj de programare. Bătăgan. Ed. M. Uscatu. C. 2003 3.. C. C. C. C. ISBN 973-594-5916 2. Programarea în limbajul C/C++. M. I. Teorie şi aplica ii. Ed.. B. Stoica. Marian Dârdală. Ştiin a învă ării unui limbaj de programare. Ed. ASE.. Roşca. Bucureşti.Bazele programării 75 Bibliografia unită ii de învă are 1. Programarea calculatoarelor. Roşca. Programarea calculatoarelor. I. L. ASE. ISBN 973-594-5916 2. Uscatu. Gh. B. Teorie şi aplica ii în C. Bazele programării calculatoarelor. Silvestru. Ghilic-Micu. C. Cocianu C. Ion Smeureanu. Cocianu. Roşca.

Sign up to vote on this title
UsefulNot useful