Sunteți pe pagina 1din 171

by Crios

Varianta din 15 martie 2007



PROGRAMAREA CALCULATOARELOR I LIMBAJE DE PROGRAMARE
LUCRRI DE LABORATOR

Recomandri..................................................................................................................................... iv
Regulamentul Activitatii Universitare a Studentilor (RAUS) - Extras .......................................... v
SEMESTRUL 1........................................................................................................... 2
1. GENERALITI ..................................................................................................... 2
1.1 Tastatura ...................................................................................................................................... 2
1.2 Ecranul aplicaiei Borland C ...................................................................................................... 3
1.3 Principalele meniuri i comenzi ale aplicaiei .......................................................................... 4
1.4 Tipuri de fiiere............................................................................................................................ 5
2. SCHEME LOGICE I PSEUDOCOD ..................................................................... 7
2.2 NTREBRI I EXERCIII............................................................................................................ 9
3. INTRODUCERE ................................................................................................... 10
3.1 Structura unui program n C++................................................................................................ 10
3.2 Mesaje de eroare ale compilatorului ....................................................................................... 10
3.3 Elementele limbajului C++........................................................................................................ 11
4. INTRRI/IEIRI N C/C++.................................................................................... 14
4.1 Exemple...................................................................................................................................... 15
5. OPERATORI I EXPRESII................................................................................... 18
5.1 Instruciunea de atribuire ......................................................................................................... 18
5.2 Operatori aritmetici, relaionali i logici, i pe bii ................................................................. 18
5.3 Conversia ntre bazele de numeraie....................................................................................... 20
5.4 Exemple...................................................................................................................................... 20
5.5 Probleme propuse..................................................................................................................... 24
5.6 NTREBRI I EXERCIII.......................................................................................................... 24
6. STRUCTURI DE DECIZIE (ALTERNATIVE, DE SELECIE) .............................. 27
6.1 Structura de decizie: instruciunea if ...................................................................................... 27
6.2 Structura de selecie cu ramuri multiple: instruciunea switch ........................................... 27
6.3 Exemple if, switch ..................................................................................................................... 28
6.4 Probleme propuse..................................................................................................................... 29
7. STRUCTURA CICLIC CU TEST INIIAL. ......................................................... 31
7.1 Instruciunea while.................................................................................................................... 31
7.2 Exemple - while ......................................................................................................................... 31
7.3 Instruciunea for ........................................................................................................................ 32
7.4 Exemple - for.............................................................................................................................. 32
8. STRUCTURA CICLIC CU TEST FINAL ............................................................ 35
8.1 Instruciunea do - while ............................................................................................................ 35
8.2 Exemple - do - while.................................................................................................................. 35
8.3 Exerciii....................................................................................................................................... 38
8.4 Faciliti de ntrerupere a unei secvene................................................................................. 38
8.5 Exemple break, continue.......................................................................................................... 39
8.6 NTREBRI I EXERCIII.......................................................................................................... 39
9. TABLOURI UNIDIMENSIONALE......................................................................... 41
9.1 Vectori ........................................................................................................................................ 41
9.2 Declaraia de tablou .................................................................................................................. 41
9.3 Exemple...................................................................................................................................... 41
10. IRURI DE CARACTERE.................................................................................. 45
11. TABLOURI MULTIDIMENSIONALE.................................................................. 48
11.1 Exemple.................................................................................................................................... 48
11.2 Probleme propuse................................................................................................................... 48

i
by Crios
11.3 NTREBRI I EXERCIII ........................................................................................................ 50
SEMESTRUL 2......................................................................................................... 51
12. POINTERI I ADRESE....................................................................................... 51
12.1 Exemple.................................................................................................................................... 51
12.2 NTREBRI I EXERCIII ........................................................................................................ 54
13. FUNCII.............................................................................................................. 55
13.1 Structura unei funcii .............................................................................................................. 55
13.2 Transferul parametrilor unei funcii....................................................................................... 55
13.3 Funcii definite de utilizator.................................................................................................... 56
13.4 Exemple.................................................................................................................................... 57
13.5 Probleme propuse................................................................................................................... 61
14. FUNCII - CONTINUARE................................................................................... 62
14.2 Funcii predefinite ................................................................................................................... 63
14.3 Biblioteci de funcii scrise de ctre utilizator....................................................................... 66
14.4 Exemple.................................................................................................................................... 66
15. FUNCII RECURSIVE........................................................................................ 68
15.1 Recursivitate direct............................................................................................................... 68
15.2 Recursivitate indirect............................................................................................................ 73
15.3 NTREBRI I EXERCIII ........................................................................................................ 74
16. TIPURI DE DATE DEFINITE DE UTILIZATOR.................................................. 77
16.1 Structuri.................................................................................................................................... 77
16.2 Uniuni ....................................................................................................................................... 80
16.3 Enumerri................................................................................................................................. 84
16.4 Exemple.................................................................................................................................... 84
16.5 Declaraii de tip........................................................................................................................ 85
16.6 Alocarea dinamic a memoriei............................................................................................... 85
16.7 NTREBRI I EXERCIII ........................................................................................................ 87
17. FIIERE.............................................................................................................. 88
17.1 Caracteristicile generale ale fiierelor .................................................................................. 88
17.2 Deschiderea unui fiier........................................................................................................... 88
17.3 nchiderea unui fiier .............................................................................................................. 89
17.4 Prelucrarea fiierelor text ....................................................................................................... 89
18. FIIERE - CONTINUARE................................................................................... 93
18.1 Intrri/ieiri binare................................................................................................................... 93
18.2 Poziionarea ntr-un fiier ....................................................................................................... 93
18.3 Funcii utilitare pentru lucrul cu fiiere................................................................................. 94
18.4 Alte operaii cu fiiere............................................................................................................. 95
18.5 NTREBRI I EXERCIII ........................................................................................................ 99
19. LISTE................................................................................................................ 100
19.1 Lista simplu nlnuit .......................................................................................................... 100
19.2 Stive i cozi ............................................................................................................................ 103
20. LISTE - CONTINUARE..................................................................................... 106
20.1 List circular simplu nlnuit .......................................................................................... 106
20.2 List dublu nlnuit ............................................................................................................ 109
21. GESTIUNEA ECRANULUI N MOD TEXT....................................................... 113
21.1 Setarea culorilor .................................................................................................................... 113
21.2 Gestiunea textelor ................................................................................................................. 114
22. GESTIUNEA ECRANULUI N MOD GRAFIC .................................................. 123
22.2 Gestiunea culorilor................................................................................................................ 123
23. GESTIUNEA ECRANULUI N MOD GRAFIC - CONTINUARE 1..................... 129
23.1 Tratarea erorilor..................................................................................................................... 129
23.2 Desenare i colorare............................................................................................................. 130
24. GESTIUNEA ECRANULUI N MOD GRAFIC - CONTINUARE 2..................... 133

ii
by Crios
25. SORTARE I CUTARE ................................................................................. 137
25.1 SORTARE............................................................................................................................... 137
26. SORTARE I CUTARE - CONTINUARE ...................................................... 140
26.1 Cutare................................................................................................................................... 140
27. METODE NUMERICE ...................................................................................... 142
27.1 Rezolvarea ecuaiilor neliniare ............................................................................................ 142
27.2 Rezolvarea sistemelor de ecuaii prin metoda Gauss....................................................... 144
27.3 Metoda celor mai mici ptrate de aproximare a sistemelor de ecuaii supradeterminate145
28. DIVERSE.......................................................................................................... 147
28.1 Preprocesorul ........................................................................................................................ 147
28.2 Misc......................................................................................................................................... 148
28.3 Baze de numeraie................................................................................................................. 152
28.4 Prelucrri numerice............................................................................................................... 155
28.5 1.4. Prelucrarea tablourilor................................................................................................... 162


iii
by Crios

Recomandri:

Oprirea telefonului celular n timpul orelor e un semn de bun sim, att fa de cadrul
didactic, ct i fa de colegi.
"Nu am fcut programare n liceu" sau "Nu am calculator acas" nu reprezint o
scuz, ci ar trebui s fie o motivare n plus pentru studiu n orele de laborator.
Informai-v asupra chestiunilor colare (datele de susinere a examenelor,
restanelor, numr de credite, etc.) de la surse autorizate (cadre didactice sau
secretariat).
Studenii trebuie s aib asupra lor carnetul de student att la susinerea probelor de
examen, ct i la trecerea notelor.
La nceputul orelor de laborator, fiecare grup de lucru trebuie s aib asupra ei, listat
n prealabil, un exemplar din referatul lucrrii care se va efectua n ora respectiv.
Lipsa acestuia atrage notarea cu absen pentru ntreaga grup de lucru. Nu este
permis "detaarea" membrilor unei grupe la alta (care are eventual referat).
Exemplele prezentate n lucrri au fost testate n prealabil n C, deci este foarte puin
probabil s conin greeli. Redactarea acestui material a fost facut ns cu un
procesor de texte care a desparit i aliniat instruciunile din C. Atenie la ceea ce
scriei n program !.
Copierea mecanic a programelor prezentate, fr a nelege efectul fiecrei
instruciuni n parte, va avea cu siguran efecte catastrofale la examinare.
Dac exist chestiuni asupra carora nu suntei lmurii, citii mai nti referatul de
laborator, i abia apoi solicitai informaii cadrului didactic. Nu punei ntrebri doar ca
s v aflai n treab.
Acumularea de cunotine temeinice este un proces de durat, care nu se poate face
peste noapte.
Lsai sala de clas cel puin n aceeai stare de ordine (scaune, mese) i curenie n
care ai gsit-o.
Sesizai din timp eventualele probleme aprute i nu atunci cnd este prea trziu.

"Gndete cauzal i scrie sintactic !"

iv
by Crios

Regulamentul Activitatii Universitare a Studentilor (RAUS) - Extras

Cap. 3. Frecvena
Art.9. Studentii au dreptul sa participe la cele doua tipuri de activitati didactice prevazute in
planurile de invatamant si anume: activitati teoretice, concretizate prin cursuri, si
activitati aplicative, concretizate prin seminarii, tutoriate, lucrari practice, proiecte si
practica. Ei au obligatia sa efectueze integral toate activitatile aplicative
prevazute in planurile de invatamant ale programelor de studiu la care sunt
inmatriculati si anume: seminariile, tutoriatele, lucrarile practice, proiectele si
practica.
Art.10. (1) Pentru absente la activitatile aplicative ale unei discipline, studentul pierde
dreptul de a se prezenta la examen. Isi recapata dreptul de a se prezenta la examen
dupa recuperarea activitatilor aplicative neefectuate, prin participarea cu alte grupe la
aceste activitati, in cadrul programului didactic normal. In masura posibilitatilor,
catedrele pot oferi un program suplimentar de recuperare a unora dintre activitatile
aplicative. Pentru a recupera activitati aplicative in cadrul acestui program, studentii
vor plati taxele stabilite de Senatul Universitatii.
In cazuri exceptionale (spitalizare, graviditate, etc.) decanatul facultatii poate aproba
scutirea de plata acestor taxe, precum si recuperarea activitatilor aplicative
neefectuate din aceste cauze, cu acordul titularului de disciplina.
(2) In cursul unui an universitar studentul nu poate recupera mai mult de 50%
din activitatile obligatorii ale unei discipline de studiu, indiferent de motivul
pentru care a absentat. Pentru a putea fi admis la examen, studentul care
absenteaza mai mult de 50% din activitatile obligatorii ale unei discipline de studiu
trebuie sa refaca, intr-un alt an universitar, intreaga activitate didactica a disciplinei
respective.
(4) Evidenta frecventei studentilor la activitatile obligatorii ale unei discipline de studiu
si aplicarea prevederilor acestui articol este responsabilitatea titularului disciplinei
respective.
Art.11. Studentul de la invatamantul de zi se poate angaja ca salariat al unei institutii
sau societati comerciale, in conformitate cu normele in vigoare, dar trebuie sa
indeplineasca in intregul lor obligatiile scolare ce decurg din planul de
invatamant.
Cap. 4. Promovarea disciplinelor de studiu
Art.12. (1) Pn la data de 15 octombrie a fiecarui an universitar decanatul va comunica
studentilor, pentru fiecare an de studiu, lista disciplinelor obligatorii, optionale si
facultative, forma si algoritmul de evaluare corespunzatoare fiecarei discipline
(examen sau verificare, scris sau oral), precum si numarul de credite aferent fiecarei
discipline. Studentul va depune optiunea sa pentru disciplinele la alegere - optionale si
facultative - in limita numarului de locuri stabilit pentru fiecare disciplina.
(2) Pentru promovarea disciplinelor programate intr-un an universitar, studentii
inmatriculati la invatamantul de zi au la dispozitie, de regula, trei sesiuni de

v
by Crios
examene, indiferent de anul de studiu sau programul in care sunt inamatriculati,
universitar sau postuniversitar.
Studentii de la invatamantul la distanta sau cu frecventa redusa au anual la dispozitie
patru sesiuni de examene, indiferent de anul de studii in care sunt inscrisi.
Intr-o sesiune de examene, studentul poate sustine o singura data setul de
teste/ examenul de promovare a unei discipline de studiu.
Pentru imbunatatirea notei, Biroul Consiliului Profesoral poate aproba studentului care
a obtinut rezultate profesionale bune examinarea suplimentara, fara taxa, in sesiunea
de toamna, la cel mult trei discipline.
Art.13. Evaluarea pregatirii studentilor la o disciplina de studiu se face pe parcursul
semestrului (prin testare in cadrul seminariilor, a lucrarilor de laborator ori de
proiectare, sau a altor activitati practice) si in cursul sesiunilor de examene prevazute
in structura fiecarui an universitar.
La disciplinele ce nu sunt prevazute cu examen, testarea pregatirii studentilor
se incheie in ultima saptamana a semestrului. Studentii pot fi retestati la aceste
discipline de cel mult doua ori si numai in cursul semestrului urmator sau in sesiunea
de toamna, dupa care, in caz de nepromovare, este obligatorie refacerea tuturor
testelor, in cursul unui alt an universitar.
La propunerea justificata a cadrului didactic, Biroul Consiliului Profesoral poate
decide ca studentul care incearca promovarea frauduloasa a unei discipline sa
piarda dreptul de a se prezenta pentru promovarea acestei discipline in
urmatoarele doua sesiuni de examene.

Textul complet al RAUS se gsete pe net la adresa http://www.rectorat.ugal.ro/docs/73.htm



vi
Laboratorul 1 Generaliti
1. Generaliti
1.1 Tastatura
1.1.1 Tastele rapide (Hotkeys) F1F12
1.1.2 Tastele alfanumerice:

Shift (), Alt, Ctrl - (dou din fiecare) Nu au
efect singure (se apas simultan cu alt
tast)
Tab
Caps Lock = folosit la scrierea cu majuscule
Enter = lanseaz n execuie o comand
Backspace = terge caracterul din stnga
cursorului
Space (spaiu) = introduce un blank
Esc = Escape
Slash (/)
Backslash (\)
Tilda (~) Shift+
Ampersand, coad de maimu,
a rond, (@) Shift+2
Diez (#): Shift+3
Procent (%) Shift+5
Cciulia (^) Shift+6
And (&) Shift+7
Apostrof (')
Ghilimele (") - NU dou apostrofuri !
Bar vertical (|)
1.1.3 Taste speciale
Insert = comut ntre modul inserare i suprascriere
Delete = terge caracterul din dreptul cursorului
Home = (acas) mut cursorul la nceputul rndului
End = (sfrit) mut cursorul la sfritul rndului curent
Page up = deplaseaz coninutul fiierului cu un ecran ctre nceputul acestuia
Page down (pereche)
Ctrl + Home = mut cursorul la nceputul ecranului (primul rnd)
Ctrl + End = mut cursorul la sfritul ecranului (ultimul rnd)
Ctrl + Page up = deplaseaz cursorul (i implicit coninutul afiat pe ecran) la
nceputul fiierului
Ctrl + Page down = deplaseaz cursorul la sfritul fiierului
1.1.4 Tastele numerice
Sunt active dac led-ul lui Num Lock este aprins, altfel funcioneaz ca Taste speciale

2
Laboratorul 1 Generaliti
1.2 Ecranul aplicaiei Borland C


Acesta conine:
Bara de meniuri (sus) - prezint mai multe meniuri (System, File - fiiere, Edit - editare,
Search) care conin grupuri de comenzi specifice. Activarea ei se face cu tasta rapida F10 -
aa cum se arat n bara de stare; deschiderea unui meniu se face apsnd simultan tastele
Alt i litera evideniat din numele meniului.
Zona de lucru (la mijloc) - conine una sau mai multe ferestre, din care, la un moment dat, e
activ una singur.
Elementele unei ferestre sunt:
Rama ferestrei - dubl, dac fereastra este activ, simpl dac este inactiv
Buton de nchidere - n partea din stnga sus a ramei ([])
Titlul ferestrei - pentru ferestrele de editare este numele fiierului deschis.
Numrul ferestrei - automat
Buton de maximizare/revenire - n partea din dreapta sus a ramei ([])
Bara de defilare vertical ce conine sgeile de deplasare la extremiti i butonul
care indic poziia coninutului ecranului n lungul fiierului (nceput/sfrit)
Bara de defilare orizontal ce conine sgeile de deplasare la extremiti i butonul
care indic poziia coninutului ecranului n latul fiierului (stnga/dreapta)
Poziia cursorului - indicat prin numrul liniei i cel al coloanei - n partea din
stnga jos a ramei
Buton care indic modificarea coninutului ferestrei dup ultima salvare - n partea
din stnga jos a ramei [*]

Bara de stare (jos) - conine comenzile disponibile la un moment dat i combinaiile de taste
pentru lansarea acestora. Coninutul ei se modific n funcie de context (poziia cursorului n
diferitele zone ale ecranului).

3
Laboratorul 1 Generaliti
1.3 Principalele meniuri i comenzi ale aplicaiei
Acestea sunt:
1. Meniul System [] - conine comenzi sistem i pentru programe de transfer
2. Meniul File - conine comenzi pentru gestiunea fiierelor (Deschidere, Salvare,
Tiprire, etc.)
a. New - Creeaz un nou fiier ntr-o nou fereastr de editare
b. Open - Localizeaz si deschide un fiiere (creat deja)
c. Save - Salveaz fiierul din fereastra de editare activ
d. Save as - Salveaz fiierul din fereastra de editare activ cu un nume nou
e. Save all - Salveaz toate fiierele modificate
f. Change dir - Schimb directorul de lucru curent
g. Print - Tiprete coninutul ferestrei active
h. DOS shell - iese temporar n sistemul de operare
i. Quit - Iese din aplicaia Borland C++
3. Meniul Edit - conine comenzi pentru operaii de editare, anulare i acces la
Clipboard
a. Undo - anuleaz ultima comand de editare (consecutiv)
b. Redo - reface ultima comand anulat
c. Cut - terge textul selectat i l pune n Clipboard
d. Copy - copiaz n Clipboard textul selectat
e. Paste - insereaz coninutul Clipboard-ului n fereastra curent la poziia
cursorului
f. Clear - terge textul selectat
g. Copy example - copie n Clipboard exemplul dintr-o fereastr Help
h. Show Clipboard - arat coninutul Clipboard-ului
4. Meniul Search - conine comenzi pentru cutarea textului i erorilor
a. Fiind - caut un text
b. Replace - caut un text i l nlocuiete cu unul nou
c. Search again - repet ultima comand de cutare sau cutare i nlocuire
d. Go to line number - mut cursorul la linia specificat
e. Previous error - mut cursorul la linia erorii anterioare
f. Next error - mut cursorul la linia erorii urmtoare
g. Locate function - caut la depanare o declaraie de funcie
5. Meniul Run - conine comenzi pentru lansarea n execuie a programului integral
sau pas cu pas
a. Run - lanseaz programului n execuie
b. Program reset - termin sesiunea de depanare
c. Go to cursor - execut programul pn la linia cursorului
d. Trace into - execut instruciunea urmtoare; ptrunde n corpul
funciilor
e. Step over - execut instruciunea urmtoare; pete peste corpul
funciilor
f. Arguments - stabilete parametrii liniei de comand cu care va fi
executat programul
6. Meniul Compile - conine comenzi pentru verificarea corectitudinii (compilarea)
programului
a. Compile - compileaz fiierul din fereastra de editare activ
b. Make - Actualizeaz inta prin compilare i legare, dup caz
c. Link - Leag fiierele intei fr recompilare
d. Build all - Reconstruiete toate fiierele

4
Laboratorul 1 Generaliti
7. Meniul Debug - conine comenzi pentru inspectare, evaluare, stabilire de puncte
de ntrerupere i urmrire a variabilelor
a. Inspect - deschide o fereastr inspector pentru a examina valorile unei date
b. Evaluate/Modify - evalueaz o variabil sau expresie i afieaz valoarea
c. Call stack - arat funciile apelate de program pn n punctul curent
d. Watches - adaug, terge sau editeaz variabile urmrite
e. Toggle breakpoint - insereaz sau terge un punct de oprire necondiionat
a programului la linia curent
f. Breakpoints - insereaz puncte de oprire necondiionat; vizualizeaz sau
editeaz aceste puncte
8. Meniul Project - conine comenzi pentru gestiunea proiectelor: adugare, tergere
sau vizualizarea fiierelor proiect
9. Meniul Options - conine comenzi pentru stabilirea opiunilor mediului de
programare, a compilatorului i depanatorului
10. Meniul Window - conine comenzi pentru deschiderea, aranjarea i afiarea listei
ferestrelor
a. Size/Move - modific dimensiunea sau poziia ferestrei active
b. Zoom - maximizeaz sau readuce fereastr activ la dimensiunea iniial
c. Cascade - dispune ferestrele din zona de lucru suprapuse
d. Tile - dispune ferestrele din zona de lucru alturat
e. Next - activeaz fereastra urmtoare
f. Close - nchide fereastra activ
g. Close all - nchide toate ferestrele
h. Message/Output/Watch/User screen - deschide una din ferestrele speciale:
de mesaje, de rezultate, de urmrire sau ecranul utilizatorului
i. List all - afieaz lista tuturor ferestrelor deschise
11. Meniul Help - conine comenzi pentru accesarea sistemului de ferestre de ajutor.
a. Contents - arat cuprinsul sistemului de ajutor
b. Index - arat index-ul sistemului de ajutor
c. Topic search - arat informaii despre cuvntul din dreptul cursorului sau
afieaz index-ul
d. Previous topic - arat din nou ultima fereastr de informaii
e. Help on help - arat modul de utilizare a sistemului de ajutor
f. About - arat numrul versiunii programului

Observaii:
1. Selectarea unei poriuni de text se face astfel:
a. Se poziioneaz cursorul cu ajutorul sgeilor la un capt al textului de selectat;
b. innd tasta Shift apsat se deplaseaz cursorul cu ajutorul sgeilor
(,,,) ctre cellalt capt al textului de selectat.
2. Pentru a scurta lungimea programelor i deci i durata etapei de redactare a acestora,
instruciunile care afieaz valorile variabilelor pe ecran (cout, printf) pot fi omise,
iar valorile variabilelor pot fi urmrite n fereastra Watches din meniul Debug
1.4 Tipuri de fiiere
Executabile: EXE, COM, BAT
Neexecutabile:
text: TXT
documente: WRI, RTF, DOC

5
Laboratorul 1 Generaliti
imagini: BMP, JPG, GIF, TIF, PCX
sunete: MP3, WAV, MIDI
surse: C, CPP, BAS, PAS, FOR, M
arhive: ZIP, ARJ, ACE, RAR
imagini de disc: ISO, BIN

6
Laboratorul 2 Scheme logice i pseudocod
2. Scheme logice i pseudocod

Start
Citete
x
Dac
x=0
Dac
x<0
f(x) = 4x
3
-5x
2
f(x) = e
x
- ln x
scrie
f(x)
Da Nu
Stop
f(x)=0
f(a
Nu
Calculul unei functii
Start
Citete re,im
modul=
im im re re +

Dac
re=0
Dac
im>=0
Dac
re>0
arg=pi/2 arg=-pi/2 arg=arct(im/re
)
arg=-
arctg(im/re)
scrie
re,im
Da
Da Da
Nu
Nu
Nu
Stop
Modulul si argumentul unui nr complex
2.1.1 Maximul a trei numere
1. citete a, b, c
2. dac a>b
atunci max=a
altfel max=b
3. dac c>max
atunci max=c
4. afieaz max

2.1.2 Suma primelor n numere naturale
1. citete n
2. suma=0
3. ct timp i<n
i++
suma=suma+1
4. afieaz suma

7
Laboratorul 2 Scheme logice i pseudocod
START
CITETE a,b,c
max=b max=a
Dac a>=b
A F
max=c
Dac c>max
A F
AFIEAZ max
STOP






Start
Citete
a,b,m,n
i<m
j<n
scrie s
Stop
) 5 cos(
) 3 sin(
j b
i a s s
+
+ + =
Da
Nu
i=1, j=1
i=i+1
j=j+1

Start
Citete
b
Dac `
a0,b
0
Daca
r0
scrie
cmmdc
cmmmc
Stop
cmmmc=a*b
r=a%b;
a=b;b=r
Da
Da
r=a%b;
a=b;b=r;
Nu
cmmmc=a
cmmmc=
cmmdc
cmmmc
Nu
cmmmc=0
cmmdc=0
Start
Citete n








i<=n
scrie
fact
Stop
fact*=i
Da
Nu
i=i+1
i=1
fact=1
START
STOP
CITETE n
AFIEAZ sum
i<n
A F
i++
sum=sum+i


8
Laboratorul 2 Scheme logice i pseudocod
2.2 NTREBRI I EXERCIII
2.2.1 Chestiuni teoretice
1. Care este deosebirea ntre algoritm i program ?
2. Care sunt proprietile fundamentale ale algoritmilor ?
3. Care sunt modalitile de reprezentare a algoritmilor ?
2.2.2 Chestiuni practice
1. Reprezentai algoritmul lui Euclid (pentru calculul celui mai mare divizor comun a 2
numere ntregi) prin schema logic.
2. Proiectai un algoritm care s rezolve o ecuaie de gradul I (de forma ax + b = 0), unde
a,b sunt numere reale. Discuie dup coeficieni.
3. Proiectai un algoritm care s rezolve o ecuaie de gradul II (de forma ax2 + bx + c = 0),
unde a,b,c sunt numere reale. Discuie dup coeficieni.
4. Proiectai un algoritm care s testeze dac un numr ntreg dat este numr prim.
5. Proiectai un algoritm care s afieze toi divizorii unui numr ntreg introdus de la
tastatur.
6. Proiectai un algoritm care s afieze toi divizorii primi ai unui numr ntreg introdus de la
tastatur.
7. Proiectai un algoritm care calculeaz factorialul unui numr natural dat. (Prin definiie
0!=1)

9
Laboratorul 3 Introducere
3. Introducere
3.1 Structura unui program n C++
Un program C obinuit are urmtoarea structur (textul dintre /* i */ reprezint comentarii):
/*directive de preprocesare*/
#include <fisier>
/*includeri de fiiere sau biblioteci*/
/*atribuirea de nume simbolice i definiii de macrocomenzi*/
#define <def.constante>
/*directive de compilare condiionat*/
/*definiii de tipuri de date*/
/*declaraii de variabile globale*/
/*definiii de funcii sau/i descrierea unor functii*/
void main(void) /*antetul funciei principale main*/
{ /*nceputul corpului funciei main*/
/*declaraii de variabile locale*/
/*instruciunile funciei principale*/
return 0; /*valoarea returnat de funcia main*/
} /*sfritul corpului funciei main*/
/*descrierea funciilor care au definiiile mai sus*/
Precizare: compilatoarele pentru C i C++ fac distincie ntre litere mari i mici.

Un program C++ const n una sau mai multe funcii din care numai una singur este funcia
principal. Fiecare funcie are un nume; al funciei principale este main. Celelalte funcii au
nume definite de utilizator.
Def.: Un nume este o succesiune de litere i eventual cifre, primul caracter fiind o liter.
Literele pot fi a-z, A-Z sau caracterul de subliniere (_). Numai primele 32 caractere sunt luate
n seam.

Pentru ca un fiier text sau poat fi considerat un program surs n limbajul C, acesta trebuie
s conin minim antetul i corpul funciei principale main, adic:
void main()
{

}
Aceste lucruri se gsesc n orice program C, indiferent de scopul acestuia.
3.2 Mesaje de eroare ale compilatorului
Mesaje eroare (alfabetic) Explicaii
'' is assigned a value that is never
used
Avertisment: Valoarea calculat nu este
folosit nicieri n continuare
Bad file name format in include directive: Denumire greit n directiva de preprocesare
Compound statement missing }: Caracter } sau { omis la o instruc compus
Declaration syntax error: Eroare de sintax a declaraiei.

10
Laboratorul 3 Introducere
Mesaje eroare (alfabetic) Explicaii
Declaration terminated incorrectly Declaraie terminat incorect
Expression syntax Eroare de sintax
For statement missing ; Caracter omis ; la scrierea instructiunii for.
Function '' should have a prototype: Funcia ar trebui s aib un prototip;
pentru a putea fi folosit, ea trebuie fie definit
de utilizator, fie folosit o directiv de
preprocesare (#include <>)
Function should return a value: Funcia ar trebui s returneze o valoare - lips
void la tipul valorii returnate sau lips
instruciune return n corpul funciei
If statement missing ): Caracter ) sau ( omis la scrierea
instruciunii if.
Illegal structure operation: Structur greit a instruciunii (scriere/citire) -
la >> sau <<.
Misplaced else: Ramura else din instruciunea if este
poziionat greit.
Statement missing ; Caracter ;omis (la instructiunea precedent)
Undefined symbol '' Simbol '' (variabil sau funcie) nedefinit
Unexpected Simbol neateptat - parantez-acolad n plus.
While statement missing ) Caracter )sau ( omis la scrierea instruciunii
while.



Pentru a obine mai multe informaii despre o anumita eroare, atunci cnd eroarea este
selectat n fereastra cu mesaje (Message), se apas tasta F1.
3.3 Elementele limbajului C++
3.3.1 Caractere
La scrierea programelor C++ se folosete setul de caractere al codului ASCII (American
Standard Code for Information Interchange). Caracterele din acest set se codific prin ntregi
din intervalul [0, 255]. Un astfel de ntreg poate fi pstrat n binar pe un octet (8 bii)
Mulimea caracterelor poate fi mprit n trei grupe:
caractere tipribile
caractere grafice (semitipribile)
caractere netipribile
Caracterele tipribile sunt cele ce pot fi scrise cu tastatura. Ele au codul ASCII ntre 32-127 i
pot fi: litere mari i mici, cifre, semne de punctuaie, semnele operaiilor aritmetice sau alte
caractere speciale. Atunci cnd scriem un program n C++ utilizm de regul aceste
caractere (32 - codul tastei spaiu, 65-90 - literele mari, 87-122 - literele mici, 48-57 - cifrele)
Caracterele grafice(semitipribile) nu au corespondent pe taste, ele se scriu numai dup
regula ALT + <codul ASCII>. Nu se folosesc n scrierea elementelor de limbaj
Caracterele netipribile nu se pot scrie cu tastele, ele reprezint coduri ale unor aciuni
speciale (7 - codul unui sunet emis de difuzor, 8 - tergerea unui caracter oarecare la stnga,
13 - trecerea la un rnd nou, 10 - trecerea la nceputul rndului curent, 9 - tasta TAB)

11
Laboratorul 3 Introducere
3.3.2 Tipuri de date n limbajul C++
Datele care intervin n programe sunt de mai multe tipuri. n acest laborator vom prezenta
tipurile simple iar tipurile compuse vor fi prezentate n alte laboratoare. Tabelul de mai jos va
prezenta tipurile de baz:
Cuvnt
cheie
Lungime in
bii
Format de reprezentare intern
int 16 ntreg binar reprezentat prin complement fa de 2 pe 2 octei,
cuprins n intervalul [-32768, 32767]
char 8 Caracter reprezentat prin codul ASCII, cuprins ntre 0 i 255
float 32 Numr real reprezentat n virgul flotant n simpl precizie,
cuprins ntre [3.410
-38
, 3.410
38
]
double 64 Numr real reprezentat n virgul flotant n dubl precizie,
cuprins ntre [1.710
-308
, 1.710
308
]
short 16 Idem int
long 32 ntreg binar reprezentat prin complement fa de 2 pe 4 octei,
cuprins n intervalul [-231, 231)
unsigned 16 ntreg binar fr semn reprezentat prin complement fa de 2 pe 2
octei, cuprins n intervalul [0, 65535]
unsigned
long
32 ntreg binar reprezentat prin complement fa de 2 pe 4 octei,
cuprins n intervalul [0,232)
3.3.3 Constante
Sunt caracterizate prin tip i valoare. Att tipul ct i valoarea se definesc prin caracterele
care o compun
REPREZENTAREA CONSTANTELOR N C / C++
Tip dat Format de
reprezentare
Mod de reprezentare Exemple
zecimal
(n baza 10)
[- / +] <cifra de la 1 la 9> [<lista cifre de la 0
la 9>]
125
-11
ntreg
*)
octal
(n baza 8)
[- / +] 0 <cifra de la 1 la 7> [<lista cifre
de la 0 la 7>]
0127
-022
hexazecimal
(n baza 16)
[- / +] 0 {x / X} <cifra 1-9 sau litera a-f
sau A-F> [<lista cifre 0-7 sau litere a-f
sau A-F>]
0xa12f
-0Xad105

real
n virgul fix [- / +] <partrea ntreaga> . <partea
zecimala>
Aceasta este scrierea unui numr raional n
baza zece, unde virgula zecimal este
nlocuit de punctul zecimal. Partea
zecimal poate fi vid
123
123.7
.25
(flotant) n virgul
mobil
[- / +] <partrea intreaga> . <partea
zecimala> {e sau E} [- / +] <nr. intreg
zecimal>
Aceasta reprezint mantisa (ceea ce
este nainte de E) nmulit cu 10 la
puterea dat de exponent (ceea ce este
dup E)
78E4
.1e-3
1234.567e-4
ntre
apostroafe
<caracter> a A
\<codul ASCII> \65 \7
\42 \140
caracter cu secvene \<caracter special> \t Tab

12
Laboratorul 3 Introducere
Tip dat Format de
reprezentare
Mod de reprezentare Exemple
escape \n Nou rnd
\a Bell (sunet)
\b Backspace
\r Retur de car
(pozi cursorul in
rndul curent col 1)
\v Tabulator
vertical
\\ Backslash
\ Apostrof
ir de
carac
ntre ghilimele <sir> Acesta este un sir de
caractere
cu secvene
escape
sir caractere i secv.escape Alte \tsecvente
\tescape \nintr-un sir

Observaie:
*) Ceea ce am scris anterior era valabil pentru constantele ntregi de pn la 16 bii.
Constantele de 32 bii sunt de tip long i pentru a le nota le postfixm una din: l sau L.
Pentru a specifica o constant ca fiind de tip unsigned (fr semn) o postfixm una din: u sau
U. Dac o constant este long i unsigned n acelai timp, o postfixm cu una din:
ul, lu, UL, LU
Exemple: 123, 0123, 40000, 04000, 0123456,
123L, 0123l, 0x123, 0xa1b2c3, 0XABCFL

13
Laboratorul 4 Intrri/ieiri n C/C++
4. Intrri/ieiri n C/C++
Cele mai simple instruciuni care pot fi utilizate n acest scop sunt cin i cout. Ele se gsesc
n header-ul iostream.h (ce conine funcii pentru fluxuri de intrare-ieire a datelor: in-out
stream) deci pentru a le utiliza trebuie s declarm n program:
#include <iostream.h>
Instruciunea din C++ care scrie (pe ecran) variabile i/sau expresii este:
cout <<expr.1[<<var1<<expr.2 [...]]
unde var.1, var.2 - reprezint nume de variabile iar expr.1, expr.2 - reprezint expresii.

Ex.: Pentru a afia pe ecran pe o linie nou, n cadrul unui mesaj, valorile a dou variabile a
i b folosim instruciunea:
cout<<"\na="<<a<<"\tb="<<b;
Instruciunea are urmtorul efect:
1. se trece pe o linie nou (\n)
2. se afieaz textul a=
3. se afieaz valoarea variabilei a
4. se las un spaiu (tab) (\t)
5. se afieaz textul b=
6. se afieaz valoarea variabilei b
Dac a=2 i b=5 atunci rezultatul instruciunii este:
a=2 b=5

Instruciunea din C++ care citete (de la tastatur) una sau mai multe variabile este:
cin >>var.1[>>var.2 [...]]
Ex.: Pentru a citi de la tastatur valorile a dou variabile a i b folosim instruciunea:
cin>>a>>b;
Alte instruciuni, mai puternice (dar cu o sintax mai complex sunt) printf i scanf din
biblioteca stdio.h (ce conine funcii standard de intrare-ieire: standard input-output).
Instruciunea scanf are urmtoarea sintax:

scanf(sir_car_ctrl,adr_var.1[,adr_var.2 [...]])
unde:
sir_car_ctrl - ir de caractere de control ce indic tipul variabileleor ce se vor citi:
%d - variabil de tip decimal (ntreg);
%f - variabil de tip float (real);
%c - variabil de tip caracter;
%s - variabil de tip sir de caractere;
adr_var.1 - adresa variabilei 1
Obs: Numrul caracterelor de control trebuie s coincid cu cel al variabilelor care se vor citi.
Ex. Pentru a se citi de la tastatur variabilele denumite: car (de tip caracter - char), intrg (de
tip ntreg - int), re (de tip real - float) i sir (de tip ir de caractere) sintaxa instruciunii este:
scanf("%c%d%f%s",&car,&intrg,&re,sir);
Instruciunea printf are urmtoarea sintax:
printf(sir_car_ctrl,var.1[,var.2 [...]])
unde:
sir_car_ctrl - ir de caractere de control reprezentat de o succesiune de simboluri
% urmate de caractere si/sau cifre, ce indic tipul i eventual formatul numeric al
variabilelor ce se vor scrie. Caracterele de formatare au urmtoarea semnificaie:

14
Laboratorul 4 Intrri/ieiri n C/C++
c - variabil de tip caracter; o - n octal
d - variabil de tip decimal (ntreg); s - variabil de tip ir de caractere;
e - n format tiinific x - n hexazecimal
f - variabil de tip float (real); 0 - cu zerouri nesemnificative
g - cel mai scurt dintre f i e - - aliniere la stnga
Formatul numeric se indic prin numrul total i numrul de zecimale pentru cifrele
variabilelor numerice, separate prin ..
Obs: Numrul caracterelor de control trebuie s coincid cu cel al variabilelor care se vor
scrie.
Ex. Pentru a se afia pe ecran variabilele denumite: car (de tip caracter - char), intrg (de tip
ntreg - int), re (de tip real - float) - pe ase spaii dintre care trei zecimale - i sir (de tip ir
de caractere) sintaxa instruciunii este:
printf("%c %d %6.3f %s",car,intrg,re,sir);
Sintaxa lor detaliat i complet poate fi obinut din Help-ul aplicaiei BC.
4.1 Exemple
4.1.1 Exemplu
#include <iostream.h>
void main(void)
{ cout<<"ACESTA ESTE PRIMUL PROGRAM\n"; }
4.1.2 Exemplu
#include <iostream.h>
void main() //Citeste un intreg de 4 cifre apoi rescrie cifrele respective
precedate de cte un spatiu
{ int cif1, cif2, cif3, cif4;
cin>>cif1>>cif2>>cif3>>cif4;
cout<<cif1<< <<cif2<< <<cif3<< <<cif4;
}
4.1.3 Exemplu
#include <iostream.h>
void main() //Citeste o data calendaristica sub forma zzllaaaa (ziua-2
cifre, luna-2 cifre, anul-4 cifre) si o rescrie in forma aaaallzz
{ int ziua, luna, anul;
cin>>ziua>>luna>>anul;
cout<<anul<</<<luna<</<<ziua;
}
4.1.4 Exemplu - sizeof
//sizeof.cpp
#include <iostream.h>
#include <values.h>
#define PI 3.14359

void main ()
{
cout<<"tipul int memorat pe: "<<sizeof(int)<< " octeti\n";
cout<<"tipul int memorat pe: "<<sizeof(23)<<" octeti\n";
//23-const.zecimala int

15
Laboratorul 4 Intrri/ieiri n C/C++
cout<<"int maxim="<<MAXINT<<'\n';
//const simbolice MAXINT,MAXLONG, ETC. -definite in<values.
cout<<"Const. octala 077 are val decimala:"<<077<<'\n';
cout<<"Const. hexagesimala d3 are val decimala :"<<0xd3<<'\n';
cout<<"Tipul unsigned int memorat pe: "<<sizeof(unsigned int)<<" octeti\n";
cout<<"Tipul unsigned int memorat pe: "<<sizeof(23U)<<" octeti\n";
cout<<"Tipul unsigned int memorat pe: "<<sizeof(23u)<<" octeti\n";
cout<<"Tipul long int memorat pe: "<<sizeof(long int)<<" octeti\n";
cout<<"Tipul long int memorat pe: "<<sizeof(23L)<<" octeti\n";
cout<<"Tipul long int memorat pe: "<<sizeof(23l)<<" octeti\n";
//23 sau 23l-const. decimala long int
cout<<"Long int maxim="<<MAXLONG<<'\n';
cout<<"Tipul unsigned long memorat pe: "<<sizeof(unsigned long int)<<" octeti\n";
cout<<"Tipul unsigned long memorat pe: "<<sizeof(23UL)<<" octeti\n";
cout<<"Tipul unsigned long memorat pe: "<<sizeof(23Ul)<<" octeti\n";
//23UL sau 23ul-const. decimala unsigned long int
cout<<"Tipul unsigned long memorat pe: "<<sizeof(long long int)<<" octeti\n";long
long int d;
cout<<"Tipul unsigned long memorat pe: "<<sizeof(d)<<" octeti\n";
cout<<"Tipul short int memorat pe: "<<sizeof(short int)<<" octeti\n";
cout<<"Short int maxim="<<MAXSHORT<<'\n';
cout<<"Tipul float memorat pe: "<<sizeof(float)<<" octeti\n";
cout<<"Tipul float memorat pe: "<<sizeof(23.7f)<<" octeti\n";
//23.7f-const. decimala float
cout<<"Float maxim="<<MAXFLOAT<<'\n';
cout<<"Float minim="<<MINFLOAT<<'\n';
cout<<"Tipul double memorat pe: "<<sizeof(double)<<" octeti\n";
cout<<"Tipul double memorat pe: "<<sizeof (23.7)<<" octeti\n";
//23.7-const. decimala double
cout<<"Const. decim. doubla in notatie stiintifica: "<<23.7e-5<<'\n';
cout<<"Const. PI este:"<<PI<<'\n';
cout<<"Constanta PI este memorata pe: "<<sizeof(PI)<<"octeti\n";
cout<<"Double maxim="<<MAXDOUBLE<<'\n'<<"Double minim ="<<MINDOUBLE<<'\n';
cout<<"Tipul long double memorat pe: "<<sizeof(long double)<<" octeti\n";
cout<<"Tipul long double memorat pe: "<<sizeof(23.7L)<<" octeti\n";
//23.7L-const. decimala long double
cout<<"Cifra A din HEXA are val.: "<<0xA<<"\n";
cout<<"Cifra B din HEXA are val.: "<<0xB<<"\n";
cout<<"Cifra C din HEXA are val.: "<<0xC<<"\n";
cout<<"Cifra D din HEXA are val.: "<<0xD<<"\n";
cout<<"Cifra E din HEXA are val.: "<<0xE<<"\n";
cout<<"Cifra F din HEXA are val.: "<<0xF<<"\n";
cout<<"Val. const. hexa 0x7acle este: "<<0x7ac1e<<'\n';
cout<<"Val. const. octale 171 este: "<<0171<<'\n';
cout<<"O const. octala se memoreaza pe "<<sizeof(011)<<" octeti\n";
cout<<"O const.oct.long. se mem pe "<<sizeof(011L)<<" octeti\n";
}

4.1.5 Exemplu
#include<iostream.h>
#include<values.h>
#include<stdio.h>
#include<conio.h>

void main()
{
int a=8,b,c=8,g=9;
clrscr();
cout<<"nr.maxim este: "<<MAXLONG<<'\n';
cout<<"Un char este memorat pe "<<sizeof('m')<<" octeti\n";
cout<<"sirul jhgkk este memorat pe "<<sizeof("jhgkk")<<" octeti\n";
cout<<"sirul j\thgkk este memorat pe "<<sizeof("j\thgkk")<<" octeti\n";

16
Laboratorul 4 Intrri/ieiri n C/C++
cout<<"UN nr int este memorat pe "<<sizeof(a)<<"octeti\n";
cout<<"valoarea 12000*3L este "<<12000*3L<<'\n';
cout<<"valoarea cifrei B din hexa in baza 10 este "<<0xB<<"\n";
cout<<"valoarea B+C din hexa in baza 10 este "<<0xB+0xc<<"\n";
cout<<"2<9:"<<(2<9)<<'\n';
cout<<"c="<<c<<" si g="<<g<<'\n';
cout<<"c==g rezulta "<<(c==g)<<'\n';cout<<"c="<<c;cout<<" g="<<g<<'\n';
cout<<"c=g da rezultatul "<<(c=g)<<'\n';cout<<"c="<<c;cout<<" g="<<g<<'\n';
cout<<"c="<<(c=9);b=++c;cout<<".Pentru b=++c se obtine b="<<b<<" si
c="<<c<<'\n';
getch();
}
4.1.6 Exemplu - intrri-ieiri standard
//Intrari/iesiri standard //in octal
#include<conio.h>
#include<stdio.h>

void main()
{
char c;int i;float f;char sir[10];
clrscr();
printf("Introduceti un
char/intreg/float/sir: \n");
scanf("%c%d%f%s",&c,&i,&f,sir);
//caracter si cod caracter
printf("\nc=%c cod=%d",c,c);
//intreg
printf("\ni=%d",i);
//cu lungime de cimp
printf("\ni=%6d",i);
//aliniat la stinga
printf("\ni=%-6d;i=%d",i,i);
//cu zerouri nesemnificative
printf("\ni=%06d",i);
printf("\ni in octal=%o",i);
//in hexa
printf("\ni in hexa=%x",i);
//float
printf("\nf=%f",f);
//cu lungime si precizie impusa
printf("\nf=%10.2f",f);
//stiintific
printf("\nf=%e",f);
//stiintific cu precizie data
printf("\nf=%.3e",f);
//c m scurt dintre f si e
printf("\nf=%g",f);
//sir cu lungime fixa
printf("\nsir=%4.6s",sir);
getch();
}


17
Laboratorul 5 Operatori i expresii
5. Operatori i expresii
5.1 Instruciunea de atribuire
Este instruciunea prin care unei variabile i se atribuie o expresie. Simbolul folosit este
semnul =.
n tabelul de mai jos sunt prezentate principalele variante ale instruciunii de atribuire
operaia sintaxa exemple observaii
Atrib. simpl <variabil> = <expresie>; x=tan(pi()/3)
;

Atribuirea
combinat cu
un operator
<variabil> <op> =
<expresie>;
x+=y;
i-=2;
a*=ln(a);
alfa /=n;
Este echivalent cu:
<variabil> = <variabil> op
<expresie>;
5.2 Operatori aritmetici, relaionali i logici, i pe bii
5.2.1 Operatori aritmetici unari: -, ++ , --
++ - Incrementare - Mrete valoarea variabilei cu 1.
-- - Decrementare - Micoreaz valoarea variabilei cu 1
Pot fi n form prefixat (Ex. ++a) - prioritate mare, sau postfixat (Ex. b++) - prioritate mic.
5.2.2 Operatori aritmetici binari: +, -, *, /, % (modulo)
5.2.3 Operatori aritmetici binari compui (cu atribuire): +=, -=, *=, /=, %=
Semnif: expr1 op = expr2 expr1 = expr1 op expr2.
Ex. a+=2 a=a+2
5.2.4 Operatori relaionali binari: >, >=, <, <=, ==, != (diferit)
5.2.5 Operatori logici pe cuvnt: && (I), || (SAU), ! (NOT)
Ordinea descresctoare a prioritaii: !, >, >=, <, <=, &&, ||
a b a&&b a||b aXORb !a
0 0 0 0 0 1
0 1 0 1 1 1
1 0 0 1 1 0
1 1 1 1 0 0
Pentru aXORb nu exista operator dar se poate folosi (a||b)&&!(a&&b)

18
Laboratorul 5 Operatori i expresii
5.2.6 Operatori logici pe bit: ~ (NOT), & (I), | (SAU), ^ (XOR), <<, >> (deplasare bii
stnga/dreapta)
5.2.7 Operatorul condiional ? :
Este un operator ternar (necesit 3 operanzi), utilizat n construcii de forma:
expresie1 ?expresie2:expresie3
Se evalueaz expresia1. Dac aceasta are o valoare diferit de zero, atunci tipul i valoarea
ntregii expresii vor fi aceleai cu tipul i valoarea expresiei2. Altfel (dac expresie1 are
valoarea zero), tipul i valoarea ntregii expresii vor fi aceleai cu tipul i valoarea expresiei3.
Deci operatorul condiional este folosit pentru a atribui ntregii expresii tipul i valoarea
expresiei2 sau a expresiei3, n funcie de o anumit condiie. Acest lucru este echivalent cu:
Dac expresie1 diferit de zero
Atunci evalueaz expresie2
Altfel evalueaz expresie3
5.2.8 Prioritatea operatorilor
Tabelul 5.1 prezint ierarhia tuturor operatorilor (grupai pe categorii) folosii n limbajul C cu
prioritile lor i regulile de asociativitate. Operatorii dintr-o categorie au aceeai prioritate.
Reinei c toi operatorii, cu excepia operatorilor unari, a acelor combinai cu atribuire i a
operatorului ?, se asociaz de la stnga la dreapta. Operatorii unari (*, &, -) i operatorul ? se
asociaz de la dreapta la stnga.
Tabelul 5.1 Prioritatea operatorilor
Nr.
Clas de
operatori
Operatori Asociativitate
1. Primari
() [] . -> ::
de la stnga la dreapta
2. Unari
! (NOT pe cuvnt) ~ (NOT pe bit) ++
-- sizeof (tip)
de la stnga la dreapta

- (unar) *(defereniere) &
(refereniere)
de la dreapta la stnga
3. Multiplicativi
* / %
de la stnga la dreapta
4. Aditivi
+ -
de la stnga la dreapta
5. Deplasare pe bit
<< >>
de la stnga la dreapta
6. Relaionali
< <= > >=
de la stnga la dreapta
7. De egalitate
== !=
de la stnga la dreapta
8. & (I logic pe bit) de la stnga la dreapta
9. ^ (XOR pe bit) de la stnga la dreapta
10. | (SAU logic pe bit) de la stnga la dreapta
11. && (I logic pe cuvnt) de la stnga la dreapta
12. || (SAU logic pe cuvnt) de la stnga la dreapta
13. Condiional
?:
de la dreapta la stnga
14. De atribuire
= += -= *= %=
&= ^= |= <<= >>=
de la dreapta la stnga
15. Virgul
,
de la stnga la dreapta


19
Laboratorul 5 Operatori i expresii
5.3 Conversia ntre bazele de numeraie
5.3.1 Conversia zecimal-binar
Aceasta se realizeaz prin mpriri succesive la doi pn cnd ctul
devine zero; irul resturilor n ordine invers formeaz numrul n
baza doi.
Ex.: 24
10
= 11000
2
. Acest lucru s-a obinut conform operaiilor din
tabelul alturat.
5.3.2 Conversia binar-zecimal
Numrul n baza 10 este suma produselor dintre cifrele numrului n baza doi i doi ridicat la
o putere egal cu poziia cifrei n numr; numerotarea ncepe din dreapta cu poziia zero.
Ex.: 11010
2
= 12
4
+ 12
3
+ 02
2
+ 12
1
+ 02
0
= 26
10
5.3.3 Conversia hexazecimal-binar
Se scrie fiecare simbol al numrului hexazecimal sub form binar.
Ex.: DFH = 11011111
2
deoarece DH = 13
10
= 1101
2
, iar FH = 15
10
= 1111
2
5.3.4 Conversia binar-hexazecimal
Numrul binar se mparte n grupuri de cte patru cifre, ncepnd de la dreapta la stnga, iar
apoi fiecare grup de cifre este scris n baza aisprezece.
Ex.: 1101010 = 01101010 = 6AH deoarece 0110 = 6
10
= 6H, iar 1010 = 10
10
= AH

5.4 Exemple
5.4.1 Operatori aritmetici
#include <iostream.h>
void main(void) //Citeste cantitatea
si pretul apoi calculeaza valoarea
expresiei
{
float pret, cantitate;
cout<<Dati cantitatea si pretul:
;
cin>>cantitate>>pret;
cout<<Valoarea=<<cantitate*pret;
}

//Program cu operatii aritmetice
#include<iostream.h>
void main(void)
{ int a,b; float c,d,e;
cout<<Dati doua numere intregi:;
cin>>a>>b;
cout<<Suma=<<a+b<<\nProdusul=<<a
*b<<\nDiferenta=<<a-
b<<\nCtul=<<a/b;
}

//Aria triunghiului- formula lui Heron
#include <iostream.h>
#include <math.h>

main()
{
unsigned int a,b;
float c,S,p;

cout<<"\nIntroduceti prima latura a
";cin>> a;
cout<<"\nIntroduceti a doua latura b
";cin>> b;
/*cout<<"\nIntroduceti a treia latura
c ";cin>> c;*/
c=hypot(a,b);
p=(a+b+c)/2;
S=sqrt(p*(p-a)*(p-b)*(p-c));
cout<<"\nIpotenuza este "<<c;
cout<<"\nSemiperimetrul este "<<p;
cout<<"\nAria este "<<S;
}


5.4.2 Incrementari/decrementari/atribuiri
Care sunt valorile variabilelor a,b i dupa
execuia fiecreia dintre urmtoarele
instruciuni:

Operaie Ct Rest
24:2 12 0
12:2 6 0
6:2 3 0
3:2 1 1
1:2 0 1

20
Laboratorul 5 Operatori i expresii
Valori initiale: a= 0; b= 0; c= 0
a=(++b)+(++c)
a=b+++c++
a=(++b)+c++
a=b--+--c
a=(++c)+c
a+=2
b-=3
c*=4
a/=2

// Incrementari/decrementari/atribuiri
#include<conio.h>
#include<iostream.h>

void main()
{
int a=0,b=0,c=0;
clrscr();
cout<<"\nValori initiale:\n\ta=
"<<a<<";\t b= "<<b<<";\t c= "<<c;
a=(++b)+(++c);
cout<<"\na=(++b)+(++c) duce la ...";
getch();
cout<<"\n\ta= "<<a<<";\t b= "<<b<<";\t
c= "<<c;
a=b+++c++;
cout<<"\na=b+++c++ duce la ...";
getch();
cout<<"\n\ta= "<<a<<";\t b= "<<b<<";\t
c= "<<c;
a=(++b)+c++;
cout<<"\na=(++b)+c++ duce la ...";
getch();
cout<<"\n\ta= "<<a<<";\t b= "<<b<<";\t
c= "<<c;
a=b--+--c;
cout<<"\na=b--+--c duce la ...";
getch();
cout<<"\n\ta= "<<a<<";\t b= "<<b<<";\t
c= "<<c;
a=(++c)+c;
cout<<"\na=(++c)+c duce la ...";
getch();
cout<<"\n\ta= "<<a<<";\t b= "<<b<<";\t
c= "<<c;
a+=2;
cout<<"\na+=2 duce la ..."; getch();
cout<<"\n\ta= "<<a<<";\t b= "<<b<<";\t
c= "<<c;
b-=3;
cout<<"\nb-=3 duce la ..."; getch();
cout<<"\n\ta= "<<a<<";\t b= "<<b<<";\t
c= "<<c;
c*=4;
cout<<"\nc*=4 duce la ..."; getch();
cout<<"\n\ta= "<<a<<";\t b= "<<b<<";\t
c= "<<c;
a/=2;
cout<<"\na/=2 duce la ..."; getch();
cout<<"\n\ta= "<<a<<";\t b= "<<b<<";\t
c= "<<c;
cout<<"\nAsta-i tot !";
getch();

}

5.4.3 Operatori relaionali i logici
//Operatori relationali si logici
#include<conio.h>
#include<stdio.h>

void main ()
{
int x1=1,x2=20,x,cond;
printf("\nx= "); scanf("%d",&x);
//verifica daca un nr indepl o
conditie
cond=x1<x&&x<x2||(x%2);
printf("\nconditia
x1<x&&x<x2||(x%%2) este %d",cond);
cond=10>5&&!(10<9)||3<=4;
printf("\nconditia
10>5&&!(10<9)||3<=4 este %d",cond);

printf("\n!0&&0||0 este %d,
dar",!0&&0||0);
printf("\n!(0&&0)||0 este
%d",!(0&&0)||0);
getch();
}


//Operatori logici
#include <iostream.h>
void main()
{ int a=0, b=10, c=100, d=200;
int rezult; rezult=a&&b;
cout<<a&&b=<<rezult<<\n;
//Afisare a&&b=0
rezult=a||b;
cout<<a||b=<<rezult<<\n;
//Afisare a||b=1 (sau valoare
nenula)
rezult=!a;cout<<!a=<<rezult<<\n;
//Afisare !a=1 (sau valoare nenula)
rezult=!b;
cout<<!b=<<rezult<<\n;
//Afisare !b=0
rezult=(a>b) || (b>c);cout<<(a>b)
|| (b>c)=<<rezult<<\n;
//Afisare (a>b) || (b>c) =1(sau
valoare nenula)
rezult=!(c<d);cout<<!(c<d)=<<rezul
t<<\n;
//Afisare !(c>d)=0
rezult=(a-b)&&1;cout<<(a-
b)&&1=<<rezult<<\n;

21
Laboratorul 5 Operatori i expresii
//Afisare (a-b)&&1 =1(sau valoare
nenula)
rezult=d||b&&a;cout<<d||b&&a=<<rez
ult<<\n;
//Afisare d||b&&a =1
}
5.4.3.1 An bisect
S se scrie un program care citete un ntreg
din intervalul [1600, 4900], ce reprezint un
an calendaristic, afieaz 1 dac anul este
bisect i 0 n caz contrar sau dac anul nu
aparine intervalului indicat mai sus.
Un an, din calendarul gregorian, este bisect
dac este multiplu de patru i nu este
multiplu de 100 sau dac este multiplu de
400. Aceast regul este valabil pentru anii
care nu sunt anteriori anului 1600.
Dac notm cu an anul calendaristic, atunci
el este bisect dac de exemplu:
an%4==0 (an este multiplu de 4)
an%100!=0 (an nu este multiplu de 100).
Deci anul este bisect dac expresia
(1) an%4==0 && an%100!=0 este adevrat.
De asemenea, anul este bisect i n cazul n
care expresia
(2) an%40()==0 (an este multiplu de 400)
este adevrat.
Deci anul este bisect dac este adevrat
expresia (1) sau (2), adic dac este
adevrat expresia:
an%4==0 && an%100! =0 || an%400==0

//PROGRAMUL BIII12
#include <stdio.h>
void main ( )
/* citeste un intreg care reprezinta
un an calendaristic din
intervalul [1600,4900] si afiseaza 1
daca anul este bisect
si zero daca nu este sau nu apartine
intervalului indicat */
{
int an, bisect;
printf("Anul: ");
scanf("%d", &an);
bisect=an>=1600 && an<=4900 &&
(an%4==0 && an%100!=0 || an%400==0);
printf("an=%d\t%d\n",an,bisect);
}

5.4.4 Operatori pe bii
Programul afieaz rezultatul urmtoarelor
expresii:

Val iniial x= 7, n binary 00000111
x=x<<1 d x= 14, n binar 00001110
x=x<<3 d x= 112, n binar 01110000
x=x<<2 d x= 192, n binar 11000000
x=x>>1 d x= 96, n binar 01100000
x=x>>2 d x= 24, n binar 00011000
x=~x d x= 231, n binar 11100111

SI
7, n binar 00000111
14, n binar 00001110
x=(7&14) d x= 6, n binar 00000110

SAU
128, n binar 10000000
3, n binar 00000011
x=(128|3) d x= 131, n binar 10000011

XOR
127, n binar 01111111
120, n binar 01111000
x=(127^120) d x= 7, n binar 00000111

//Operatii pe biti
#include<conio.h>
#include<iostream.h>

dectobin(int x)
{
int i=8,bin,c,r[8]={0,0,0,0,0,0,0,0};
do
{
r[i-1]=x%2; x/=2; i--;
}
while(x);
for(i=0;i<8;i++)
cout<<r[i];
}

void main()
{
unsigned char x=7;
clrscr();
cout<<"\n\t\tx= "<<int(x)<<"\tin binar
";dectobin(x);
x=x<<1; cout<<"\nx=x<<1 d\tx=
"<<int(x)<<"\tin binar ";dectobin(x);
x=x<<3; cout<<"\nx=x<<3 d\tx=
"<<int(x)<<"\tin binar ";dectobin(x);
x=x<<2; cout<<"\nx=x<<2 d\tx=
"<<int(x)<<"\tin binar ";dectobin(x);
x=x>>1; cout<<"\nx=x>>1 d\tx=
"<<int(x)<<"\tin binar ";dectobin(x);

22
Laboratorul 5 Operatori i expresii
x=x>>2; cout<<"\nx=x>>2 d\tx=
"<<int(x)<<"\tin binar ";dectobin(x);
x=~x; cout<<"\nx=~x d\tx=
"<<int(x)<<"\tin binar ";dectobin(x);
//SI
cout<<"\n\nSI\t\t7\tin binar
";dectobin(7);
cout<<"\n\t\t 14\tin binar
";dectobin(14);
x=7&14; cout<<"\nx=(7&14) d\tx=
"<<int(x)<<"\tin binar ";dectobin(x);
//SAU
cout<<"\n\nSAU\t\t128\tin binar
";dectobin(128);
cout<<"\n\t\t 3\tin binar
";dectobin(3);
x=128|3; cout<<"\nx=(128|3) d\tx=
"<<int(x)<<"\tin binar ";dectobin(x);
//SAU exclusiv
cout<<"\n\nXOR\t\t127\tin binar
";dectobin(127);
cout<<"\n\t\t120\tin binar
";dectobin(120);
x=127^120; cout<<"\nx=(127^120) d\tx=
"<<int(x)<<"\tin binar ";dectobin(x);
getch();
}
5.4.5 Operatorul ternar
//Op ternar ?
#include<conio.h>
#include<iostream.h>

void main()
{
int x,y;
clrscr();
cout<<"Introd x: "; cin>>x;
y=(x>5) ?1:0;
cout<<"y= "<<y;
getch();

}
S se scrie un program care citete dou
numere i afieaz maximul dintre ele.
//PROGRAMUL BIII19
#include <stdio.h>
void main () /* citeste doua numere si
afiseaz maximul dintre ele */
{
double a,b;
scanf("%lf %lf",&a,&b);
printf("a=%g\tb=%g\tmax(a,b)=%g\n",
a,b, a > b ? a : b);
}

S se scrie un program care citete un
numr i afieaz valoarea lui absolut.
//PROGRAMUL BIII20
#include <stdio.h>
void main( ) /* citeste un numr si
afiseaz valoarea lui absoluta */
{
double a;
scanf("%lf", &a );
printf("a=%g\tabs(a)=%g\n",a, a < 0 ?
-a : a );
}

5.4.6 Operatorul cast
S se scrie un program care citete un ntreg
i afieaz rdcina ptrat din numrul
respectiv.
//PROGRAMUL BIII17
#include <stdio.h>
#include <math.h>
void main( )
{/* - citeste pe n; - calculeaz si
afiseaz rdcina ptrata din n *
long n;
scanf("%ld", &n);
printf("n=%ld\tsqrt(n)=%g\n",n,
sqrt((double)n));
}
Observaie:
n acest program, pentru extragerea rdcinii
ptrate s-a utilizat funcia sqrt. Ea are
prototipul: double sqrt(double);
Acest prototip este definit n fiierul math.h.

S se scrie un program care citete pe n de
tip ntreg i afieaz valoarea expresiei
n/(n+1) cu 15 zecimale.
//PROGRAMUL BIII18
#include <stdio.h>
void main( ) /* - citeste pe n;
- calculeaz si afiseaz pe n/(n+1)
cu 15 zecimale */
{
long n;
scanf("%ld", &n);
printf("n=%ld\tn/(n+1)=%.15g\n", n,
(double)n/(n+1));
}
Observaie:
Expresia n/(n+1) realizeaz mprirea
ntreag a lui n la n + 1. Pentru a obine ctul
mpririi cu 15 zecimale este necesar s se
efectueze mprirea nentreag. n acest
scop s-a convertit operandul n spre lipul
double. n felul acesta, conform regulei
conversiilor implicite, se convertete spre
double i cel de al doilea operand i apoi se
face mprirea celor doi operanzi flotani.

23
Laboratorul 5 Operatori i expresii
5.4.7 Operatorul virgul
S se scrie un program care citete doi
ntregi i afieaz maximul dintre valorile lor
absolute.
//PROGRAMUL BIII23
#include <stdio.h>
void main( ) /* citeste doi intregi
si afiseaz maximul dintre valorile
!or absolute */
{
int a,b,c,d;
scanf("%d%d", &a,&b);
printf("a=%d\tb=%d\tmax(abs(a),abs(b
))=%d\n", a, b, ((c=a<0 ?-a:a),
(d=b<0 ? -b : b), (c>d)) ? c : d);
}
Observaie:
Expresia:
(c = a<0 ?-a), (d = b<0 ?-b:b), (c>d) se
compune din trei expresii care se evalueaz
de la stnga la dreapta.
Prima atribuie lui c valoarea absolut a lui a,
a doua atribuie lui d valoarea absolut a lui
b, iar a treia testeaz relaia c>d. Valoarea
ntregii expresii coincide cu 1 dac c>d i cu
zero n caz contrar.

5.5 Probleme propuse
1. S se realizeze programe care execut urmtoarele aciuni:
2. Se citete un unghi n grade; se cere s se transforme n radiani (360 = 2 rad)
3. Calculeaz perimetrul i aria unui cerc de raz r citit de la tastatura
4. Calculeaz perimetrul i aria unui triunghi de laturi date.
5. Calculeaz expresia: -3x2 + xy - y/x
?
5.6 NTREBRI I EXERCIII
5.6.1 Chestiuni teoretice

1. Ce reprezint datele i care sunt
atributele lor ?
2. Care sunt diferenele ntre constante i
variabile ?
3. Cine determin tipul unei constante ?
4. Ce sunt identificatorii ?
5. Ce sunt directivele preprocesor ?
6. Ce reprezinta variabilele ?
7. Ce sunt constantele ?
8. Enumerai tipurile simple de variabile.
9. Cte tipuri de directive preprocesor
cunoastei ? Exemple.
10. Care este modalitatea de a interzice
modificarea valorii unei variabile ?
11. Ce loc ocup declararea varibilelor n
cadrul unui program surs scris n
limbajul C++ ?
12. Ce conin fiierele header ?
13. Ce tipuri de variabile se utilizeaz
pentru datele numerice ?
14. Care sunt calificatorii folosii alturi de
tipurile de baz pentru obinerea
tipurilor derivate de date ?
15. Ce semnific parantezele unghiulare <
> care ncadreaz numele unui fiier
header ?
16. Care este diferena ntre constantele
35.2e-1 i 3.52 ? Dar ntre "\t" i '\t' ?
17. Ce tip are constanta 6.44 ?
18. Care este diferena ntre operatorii = i
= = ?
19. Ce reprezint caracterele "escape" ?
20. Constante ntregi.
21. Constante caracter.
22. Ce tipuri de conversii cunoatei ?
23. Care sunt conversiile realizate n mod
automat, de ctre compilator ?

24
Laboratorul 5 Operatori i expresii
24. Constante ir de caractere.
25. Constante reale.
26. Ce operatori ternari cunoastei ?
27. Operatorul virgul.
28. Operatorul sizeof.
29. Operatori aritmetici binari compui.
30. Operatorul de refereniere.
31. Operatori relaionali binari.
5.6.2 Chestiuni aplicative
1. S se scrie declaraiile pentru definirea constantelor simbolice: pi, g (acceleraia
gravitaional), unghi_drept, dimensiune_MAX.
2. Care va fi rezultatul afiat pe ecran n urma execuiei urmtoarelor secvene de
instruciuni:
double a=9/2; cout<<a*5<<\n;
double a=9.7, b=5.6; cout<<(a+6<b)<<\n;
double a=9/4; cout<<a*6<<\n;
double x=3;int y=++x+5;cout<<y<<\n;
int a=7; cout<<(!a)<<\n;
int a=10.5; cout<<a++<<\n; cout<<a<<\n;
int a=7; cout<<++a<<\n; cout<<a<<\n;
int a=10; cout<<a++<<\n; cout<<a<<\n;
double a=7/2; cout<<a<<\n;
int x=3; int y=x++-2; cout<<y<<\n;
int x=3; int y=++x+5; cout<<y<<\n;
double a=5.6, b=7.45; cout<<(a>b)<<\n;
3. S se verifice corectitudinea urmtoarelor secvene. Pentru cele incorecte, explicai sursa
erorilor.
double a=9.7, b=5.2; int c=(a+6<b)++; cout<<c<<\n;
double a=7/5; double c=a*5++; cout<<c<<\n;
double a=9.7, b=5.6; int c=(a%6<b)++; cout<<c<<\n;
double a=5.6, b=7.45; cout<<++(a+5>b)<<\n;
double a=9.8; double b=9.7; cout<<a%b<<\n;
cout<<&(a+8)<<'\n';
int I=8; cout<<(I+10)++<<'\n';
double a=8.7; A=(a+8)/56; cout<<A<<'\n';
int x=3/5; int y=x++; char x='J'; cout<<"y="<<y<<'\n';
char a='X'; const int b=89; b+=8; cout<<"b="<<b<<"
a="<<a<<'\n';
4. S se scrie un program care afieaz urmtoarele mesaje:
Sirul "este dupa-amiaza" este memorat pe .... octeti.
marime intreaga este memorata pe ... octeti.
marime reala, in simpla precizie este memorata pe ... octeti!
marime reala, in dubla precizie este memorata pe ... byti!
Constanta caracter 'Q' memorata pe ... octeti!
Sirul "a\n\n" este memorat pe ... octei!
Sirul "\n" este memorat pe ... biti!
Caracterul '\' este memorat pe .... biti.
5. S se evalueze expresiile, tiind c: int i=1;int j=2;int k=-7;double x=0;double y=2.3;
-i - 5 * j >= k + 1
3 < j < 5
i + j + k == -2 * j
x && i || j - 3
6. Ce operaie logic i ce masc trebuie s folosii pentru a converti codurile ASCII ale
literelor mici n litere mari ? Dar pentru conversia invers ?
7. O deplasare la dreapta cu 3 bii este echivalent cu o rotaie la stnga cu ci bii ?

25
Laboratorul 5 Operatori i expresii
8. S se seteze pe 1 toi biii dintr-un octet, cu excepia bitului cel mai semnificativ.
9. S se scrie un program care citete o valoare ntreag. S se afieze un mesaj care s
indice dac numrul citit este par sau impar.
10. S se citeasca dou valori ntregi. S se calculeze i s se afieze restul mpririi celor
dou numere.

26
Laboratorul 6 Structuri de decizie (alternative, de selecie)
6. Structuri de decizie (alternative, de selecie)
6.1 Structura de decizie: instruciunea if
Aceasta corespunde cazurilor cnd n algoritmul problemei intervine o decizie.
Este instruciunea principal n C care descrie structura alternativ. Pentru un pseudocod
de forma:
dac (<condiie>) atunci <instruciune>
instruciunea if este:
if (<condiie>) <instruciune>;
iar pentru un pseudocod de forma:
dac (<condiie>) atunci <instr1> altfel <instr2>
instruciunea if este:
if (<condiie>) <instr1>; else <instr2> ;
OBSERVAIE: Dac una din instruciunile de pe ramura "if" sau "else" este o instruciune
compus, atunci ea se ncadreaz ntre acolade:
{ <instr1>; <instr2>; ... }
i nu se mai termin cu punct-virgul. n caz contrar programul va executa numai prima
instruciune de pe ramur.
6.2 Structura de selecie cu ramuri multiple:
instruciunea switch
n unele cazuri este necesar o decizie multipl special.
Instruciunea switch permite acest lucru.

DAC expresie=expr_const_1
instruciune1;
[ieire;]
ALTFEL DAC expresie=expr_const_2
instruciune2;
[ieire;]

ALTFEL DAC expresie=expr_const_n-1
instruciune_n-1;
[ieire;]
ALTFEL instruciune_n;

Se testeaz dac valoarea pentru expresie este una
dintre constantele specificate (expr_const_1,
expr_const_2, etc.) i se execut instruciunea de pe
ramura corespunztoare. n schema logic test_expresie este una din condiiile:
expresie=expr_const_1, expresie=expr_const_2, etc.
break
break
instruciune1
instruciune2
instruciune_n
test expr
Sintaxa:

27
Laboratorul 6 Structuri de decizie (alternative, de selecie)
switch (expresie)
{
case expresie_const_1: instructiune_1; [break;]
case expresie_const_2: instructiune_2; [break;]
. . . . . . . . . . . . . .
case expresie_const_n-1: instructiune_n-1;[break;]
[ default: instructiune_n; ]
}
6.3 Exemple if, switch
6.3.1 Maximul a trei numere

6.3.1.1 Pseudocodul:
1.citete a,b,c
2.dac a>b atunci max=a altfel max=b
3.dac c>max atunci max=c
4.scrie max

6.3.1.2 Programul:
#include<iostream.h>
main()
{
int a,b,c,max;
cout<<"Dati a b c"; cin>>a>>b>>c;
if(a>b) max=a;
else max=b;
if(c>max) max=c;
cout<<"maximul="<<max;
}
6.3.2 Calculator de buzunar
//Instruc de selectie switch
#include<stdio.h>

void main()
{
int cod=1; float x,y,z; char op;
while(cod)
{
printf("\nIntroduceti expresia
(valoare operator valoare): ");
Start
Dac
a>b
Dac
c>max
Scrie Max = , max
max=b
Citete
a, b, c
Stop
Da Nu
max=a
max=c
Da
scanf("%f %c %f",&x,&op,&y);
switch(op)
{
case '+':z=x+y;break;
case '-':z=x-y;break;
case '*':z=x*y;break;
case '/':z=x/y;break;
default: printf("\nOperator
eronat"); cod=0; z=0;
}
printf("%.2f %c %.2f=
%.2f",x,op,y,z);
}
}
S se scrie un program care citete o cifr
din intervalul [1,7] i afieaz denumirea
zilei din sptmn corespunztoare cifrei
respective (1-luni, 2-mari etc).
//PROGRAMUL BIV25
#include <stdio.h>
#include <stdlib.h>
void main( )
/* citestc o cifra din intervalul
[1,7] si afiseaza denumirea zilei
din saptamina corespunzatoare
cifrei respective */
{
int i;
scanf("%d", &i);
switch(i)
{
case 1: puts("luni");break;
case 2: puts("marti");break;
case 3: puts("miercuri"); break;

28
Laboratorul 6 Structuri de decizie (alternative, de selecie)
case 4: puts("joi"); break;
case 5: puts("vineri"); break;
case 6: puts("simbata"); break;
case 7: puts("duminica"); break;
default: puts("Valoare gresita
!");exit(1);
}
}

6.4 Probleme propuse
S se alctuiasc programe care s rezolve urmtoarele probleme:
6.4.1 Calculul volumului unui corp geometric
S se scrie un program care afieaz un mesaj de tip meniu i n funcie de un caracter citit
de la tastatur (1 pentru paralelipiped, 2 - Cilindru, 3 - Con, 4 - Sfer, 0 - terminare program)
citete dimensiunile necesare i calculeaz i afieaz n cadrul unui mesaj volumul corpului
respectiv (V
p
= HBL; V
cil
= R
2
H; V
con
= R
2
H/3; V
sf
= D
3
/6).

6.4.2 Ecuaia de gradul 2 (vezi i schema
logic)
1.citete a,b,c
2.dac a=0 atunci
2.1.dac b=0 atunci
2.1.1.dac c=0 atunci
2.1.1.1 scrie "ec.are o infinitate de
sol."
Start
Dac
a=0
Dac
>0
Dac
<0
Scrie Ec are
rad dubla
x
1
= x
2
Scrie Ec are
rad compl
x
1,2
= reiim
Dac
b=0
Daca
c=0
Scrie Ec are
doua rad dif
x
1
i x
2
re =
-b
2a

im =
-
2a

Scrie Ec e de
gradul unu
x
1
= -c/b
x
1,2
=
-b
2a
x
1,2
=
-b
2a

= b
2
4ac
Citete
a, b, c
Stop
Scrie Ec are
o infinit ate de
solutii
Scrie Ec nu
are nici o
solutie
Da
Da
Da Nu Nu
Nu
Da
i<iter
Scrie Ec
are rad x
x0=x
Nu Da
Da Nu
2.1.1.2 altfel scrie "ec.nu are sol"
2.1.2 altfel scrie "ec.are sol.unic x=",-c/b
altfel
2.2 d=b*b-4*a*c
2.2.1 dac d>0 atunci
2.2.1.1.x1=(-b- d )/(2*a)

29
Laboratorul 6 Structuri de decizie (alternative, de selecie)
x2=(-b+ d )/(2*a)
scrie "x1=",x1,"x2=",x2
2.2.1.2 altfel
dac d=0 atunci
2.2.1.2.1 scrie "ec.are
rad.dubla x=",-b/(2*a)
altfel
2.2.1.2.2 re = -b/(2*a)
im = -d /(2*a)
scrie "ec.are
sol.complexe re = ", re," im = ",im
6.4.3 Modulul i argumentul unui numr
complex
1.citete re,im
2.modul = re*re+im*im
3.dac re=0 atunci
3.1
dac im>=0 atunci
3.1.1 arg=pi/2
3.1.2 altfel arg = -pi/2
3.2 altfel
dac re>0 atunci
3.2.1 arg=arctg(im/re)
3.2.2 altfel arg=-arctg(im/re)
4.scrie re,im
6.4.4 Rezolvarea unui sistem de dou
ecuaii cu dou necunoscute x,y
1.citete a11,a12,a21,a22,b1,b2
2.det = a11*a22-a21*a12
3.detx = b1*a22-b2*a12
4.dety = a11*b2-a21*b1
5.x = detx/det; y = dety/det
6.4.5 Sa se calculeze i sa se afieze
valoarea funciei f pentru un x dat:
4x
3
+ 5x
2
- 2x + 1, x<0
f(x)= 100, x=0
e
x
- ln x, x>0



Start
Citet
e
modul= im im re re +
Dac
re=0
Dac
im>=0
Dac
re>0
arg=pi/2
arg=-pi/2
arg=arct(im/r arg=-
scrie re,im
D
D D
N
N N
Stop

30
Laboratorul 7 Structura ciclic cu test iniial.
7. Structura ciclic cu test iniial.
Aceasta corespunde cazurilor cnd n algoritmul problemei intervine iteraia unei aciuni pn
la o condiie de oprire.
7.1 Instruciunea while
Este principala instruciune n C++ care descrie structura alternativ.
Pentru un pseudocod de forma:
ct timp (<condiie>) execut <instruciune>
instruciunea while este:
while (<condiie>) <instruciune>;
7.2 Exemple - while

7.2.1 Algoritmul lui Euclid



Pseudocodul:
1.citete a,b
2.dac (a<>0) i (b<>0)
2.1.cmmmc=a*b
2.2. r = a%b //restul
2.3.a = b
2.4.b = r
2.5.ct timp r<>0
2.5.1.r = a%b //restul
2.5.2.a = b
2.5.3.b = r
2.6.cmmdc = a
2.7.cmmmc = cmmmc/cmmdc
2.8.scrie cmmmc,cmmdc

Programul:
//Algoritmul lui Euclid
#include<iostream.h>

main()
{
long int a,b,r,cmmmc,cmmdc;
cout<<"a=";cin>>a; cout<<"b=";cin>>b;
if(a!=0&&b!=0)
{
cmmmc=a*b; r=a%b; a=b; b=r;
while (r!=0)
{
r=a%b; a=b; b=r;
cout<<"\na=
"<<a<<"\tb="<<b<<"\tr="<<r;
}
cmmdc=a;
cmmmc = cmmmc/cmmdc;
Start
Citete a,b
Dac
a0,
Daca
r0
scrie
cmmdc; cmmmc;
N D
cmmmc=0
cmmdc=0
Stop
cmmmc=a*b
r=a%b;
a=b;b=r
D
r=a%b;
a=b;b=r;
N
cmmmc=a;
cmmmc=
cmmdc
cmmmc
;

31
Laboratorul 7 Structura ciclic cu test iniial.
cout<<"\ncmmmc= "<<cmmmc<<" cmmdc=
"<<cmmdc;
}
}

7.2.2 Produsul primelor n numere
.h>
naturale=factorial
#include <iostream
void main()
{int prod=1,i=0,n; char c;
cout << "\nSpecificati numarul n:";
cin >> n;
while(i<n) {i++; prod=prod*i;}
cout << "\nFactorial de " << n << "="
<< prod << "\n";
cin >> c;
}
7.2.3 Suma primelor n numere naturale
#include <iostream.h>
void main()
{int suma=0,i=0,n;
cout << "\nSpecificati numarul
n:";
cin >> n;
while(i<n)
{
i++;
suma=suma+i;
}
cout << "\nSuma primelor " << n <<
" numere naturale=" << suma <<
"\n";
}

7.3 Instruciunea for
n majoritatea limbajelor de programare de nivel nalt, instruciunea for implementeaz



intaxa:
for (expresie1; expresie2; expresie3)
unde:
expresie1 reprezint initializarea contorului;
expresie3
iilor, ci doar a instruciunilor vide.
7.4
structura ciclic cu numr cunoscut de pai. n limbajul C instruciunea for poate fi utilizat
ntr-un mod mult mai flexibil.












S
instructiune;
expresie2 conditia de rmnere in ciclu;
modificarea contorului
Nu este obligatorie prezena expres
Exemple - for
Reprezentare n pseudocod:
valuare expresie1
evaluare expresie1 (particular iniializare contor)


e
CT TIMP expresie2
REPET
NCEPUT
une
T
instructi
evaluare
expresie3
SFRSI
0
expresie2
instruciune
evaluare expresie3 (particular
incrementare contor)
1
Figura 3.3. Structura ciclic cu test iniial

32
Laboratorul 7 Structura ciclic cu test iniial.
7.4.1 Calculul factorialului
//Calculul factorialului
#include<iostream.h>
#include<conio.h>

void main()
{
long int i,n,fact=1;
clrscr();
cin>>n;
for(i=1;i<=n;i++)
fact*=i;
cout<<fact;
getch();
}

7.4.2 Calculul unei sume
S se calculeze suma dubl

i=1
m

j=1
n
sin(a+3*i)*cos(b+5*j).
Pseudocodul:
1.citete a,b,m,n
2.i=1 3.j=1 4.s=0
5.ct timp (i<=m)
5.1.ct timp (j<=n)
5.1.1.s=s+ sin(a+3*i)*cos(b+5*j)
5.1.2.j=j+1
5.2.i=i+1
6.scrie s

Programul:
#include<iostream.h>
#include<math.h>
main()
{
float s,a,b; int m,n,i,j;
cout<<"a="; cin>>a; cout<<"b=";
cin>>b; cout<<"m="; cin>>m;
cout<<"n="; cin>>n;
for(i=1,j=1; i<=m,j<=n; i++,j++)
s=s+ sin(a+3*i)*cos(b+5*j);
cout<<"Suma="<<s;
}


7.4.3 Afisarea codurilor ASCII ale
caracterelor
//Coduri ASCII caractere
#include<conio.h>
#include<stdio.h>

void main()
{
int i,j;
clrscr();
// printf("\ncaracASCII\tcod
zecimal\tcod octal");
Start
Citete n
i<=n
scrie
fact
Stop
fact*=i
Da
Nu
i=i+1
i=1
Start
Citete
a,b,m,n
i<m
j<n
scrie
s
i=1, j=1
Stop
s=s+sin(a+3*i)*cos(b+5*j)
Da
Nu
i=i+1
j=j+1

33
Laboratorul 7 Structura ciclic cu test iniial.
for(i=0;i<=255;i+=10)
{
printf("\n");
for(j=1;j<=10;j++)
if(i+j<=255) printf("%d: %c
",i+j,i+j);
//if(!(i%25)) getch();
}
getch();
}

Sirul lui Fibonacci, primii n
termeni.
Dac n=0: f(0)=0, n=1: f(1)=1, altfel:
f(i) = f(i-2) + f(i - 1)
Pseudocodul:
1. f0=0, 2.f1=1
3. citete n
4.dac n>=2
4.1.pentru f0=0 i f1=1, ct timp
f1n, f0=f1, f1=fi, repeta
4.1.1.fi=f0 + f1
4.1.2.Scrie fi
Programul:
//Genereaza numerele Fibonacci
#include<stdio.h>
#include<conio.h>

void main()
{
int f0=0,f1=1,fi,n;
clrscr();
printf("Introd n:");
scanf("%d",&n);
if(n>=2)
{
for(f0=0,f1=1;f1<=n;f0=f1,f1=fi)
{
fi=f0+f1;
printf("\nfi=%d",fi);
//
printf("\nf0=%d\tf1=%d\tfi=%d",f0,f
1,fi);
}
}
getch();
}


34
Laboratorul 8 Structura ciclic cu test final
8. Structura ciclic cu test final
8.1 Instruciunea do - while
Pentru un pseudocod de forma:
<instruciune 1>
ct timp (<condiie>) execut <instruciune 1>
instruciunile C++ sunt:
<instruciune 1>; while (<condiie>) <instruciune 1>;
Dar aceste instruciuni se pot nlocui cu o singur instruciune do-while astfel:
do <instruciune 1> while (<condiie>);
Aceasta nu reprezint dect structura iterativ cu test final, "repet instruciune ct timp
condiie"
8.2 Exemple - do - while
8.2.1 Calculul sumei unor numere citite
de la tastatur pn la introducerea
numrului zero.
Pseudocodul:
1.s=0
2.repet
2.1.citete x
2.2.s=s+x
ct timp (x!=0)

Programul:
#include<iostream.h>
void main()
{
float s,x; s=0;
cout<<"Dati numerele de adunat
(0-oprire)";
do
{ cin>>x; s+=x;}
while (x!=0);
cout<<s;
}
8.2.2 Problema 1:
S se alctuiasc un program n care s fie implementate o funcie pentru ridicarea lui 2 la o
putere ntreag i una pentru calculul radicalului de ordinul doi pe baza irului lui Newton.
Strategia de rezolvare: Funcia care va calcula puterea ntreag a lui 2 se bazeaz pe efectul
de deplasare a biilor din reprezentarea binar a unui numr. Astfel, o deplasare la stnga a
lui a de b ori (a<<b) presupune o nmulire a lui a cu 2 de b ori: a<<b este echivalent cu a2
b
.
La fel, o deplasare la dreapta la nivel de bit, a lui a cu b poziii (a>>b) presupune o mprire
a lui a cu 2 de b ori (a2
-b
).
Construcia funciei ce calculeaz rdcina ptrat a unui numr x are la baz irul lui
Newton, dat prin relaia de recuren a
n+1
= 0.5

a
n
+
x
a
n
, unde primul element a
1
= 1, iar n>2.
Funcia calculeaz termenii succesivi ai irului pn cnd diferena, n valoare absolut,
dintre doi termeni succesivi este mai mic dect eroarea acceptat pentru calcul.

/*Program 8.

35
Laboratorul 8 Structura ciclic cu test final
Calculul ridicarii lui 2 la o
putere intreaga si
calculul radacinii patrate fara
utilizarea functiei sqrt*/

#include<iostream.h>
#include<conio.h>
#include<math.h>

int pow2(int x)
{//Functia calculeaza 2^n.
int y=1;
return (y<<x);
}

float rad2(float x)
{//Functia calculeaza radacina
patrata a lui x.
float p=1, q=(1+p)/2, err=1e-6;
do
{p=q; q=(p+x/p)/2;}
while(fabs(q-p)>err);
return q;
}

void main()
{
int a; char Exit;
do
{
clrscr();
cout<<"Dati un numar A =";
cin>>a;
cout<<"2^"<<a<<" =
"<<pow2(a)<<endl;
cout<<"Radical
(2^"<<a<<")="<<rad2(pow2(a))<<endl;
cout<<"Pentru iesire apasati->
e..";
Exit=getch();
}
while(Exit!='e');
}
8.2.3 Calculul unei sume cu o precizie
impus
S se calculeze suma S =

k=1
(-1)
k
x
k
k!
pn
cnd |T/S| < .
Obs: T[k] = -T[k-1]x/k, iar S[k] = S[k-1] +
T[k]

8.2.3.1 Pseudocod:
1. Citete x, eps,
2. T = S = k = 1,
3. Repet
3.1. T = -Tx/k,
3.2. S = S + T,
3.3. k = k + 1
ct timp |T/S|
4. Scrie S

8.2.3.2 Programul
//Calculul unei sume
#include<conio.h>
#include<math.h>
#include<stdio.h>

void main()
{
float x,T; double S,eps=1e-05; int
k;
//clrscr();
printf("\nIntroduceti val x: ");
scanf("%f",&x);
T=S=1; k=1;
do
{
printf("\nk= %d\tT= %12.4f\tS=
%14.10f\t|T/S|=
%14.10f",k,T,S,fabs(T/S));
T=-T*x/k; S+=T; k++;
}
while(fabs(T/S)>=eps);
getch();
}

Secvenele urmtoare descriu strict
metoda prezentat i nu ntreg
programul !

Programele urmtoare se bazeaz pe
urmtoarele instruciuni:
1. mprire ntreag (modulo) a unui
numr ntreg la 10 prin care se obine
cifra unitilor numrului. Ex: 1234%10
4
2. mprire propriu-zis a unui numr
ntreg la 10 prin care se obine tot un
ntreg. Ex: 1234/10 123 i NU 123.4
8.2.4 Suma cifrelor unui numr "n"
s=0;nl=n;
do
{
s+=nl%10;//se obtine pe rind
nl/=10; //fiecare cifra incepind

36
Laboratorul 8 Structura ciclic cu test final
//cu cea a unitatilor
}
while(nl);
cout<<"\nSuma cifrelor nr. "<<n<<"
= "<<s;
8.2.5 tergerea unei cifre "a" dintr-un
numr "n"
nl=0;
do
{
if (n%10!=a) nl=nl*10+n%10;
n/=10;
}
while(n);
do
{
n=n*10+nl%10;
nl/=10;
}
while(nl);
cout<<"\nNoul numar: "<<n;
8.2.6 Oglindirea unui numr "n"
n_o=0;nl=n;
do
{
n_o=n_o*10+nl%10;
nl/=10;
}
while(nl);
cout<<"\nOglinditul lui "<<n<<"
este "<<n_o;
8.2.7 Trecerea unui numr "n" din baza
10 n baza b[2..9]
aux=n_b=0;
do
{
aux=aux*10+n%b;
n/=10;
}
while(n);
do
{
n_b=n_b*10+aux%10;
aux/=10;
}
while(aux);
cout<<"\nNumarul in baza "<<b<<"
este "<<n_b;
8.2.8 Apariia unei cifre "a" ntr-un
r "n" num
nr=0;nl=n;
do
{
if(nl%10==a)
nr++;
nl/=10;
}
while(nl);
cout<<"\nCifra "<<a<<" apare de
"<<nr<<" ori";
8.2.9 Inserarea unei cifre "a" pe o poziie
"k" a unui numr "n"
numr de la nl=0;i=0;//poz.se
sfrsit
while(i++<k)
{
nl=nl*10+n%10;
n/=10;
}
nl=nl*10+a;
do
{
n=n*lD+nl%10; nl/=10;
}
while(nl);
cout<<"\nNoul numar este: "<<n;
8.2.10 Cifra maxim "cmax" a unui
r "n" num
cmax=0;nl=n;
do
{
if(cmax<n%10)
cmax=nl%10;
nl/=10;
}
while (nl) ;
cout<<"\ncmax="<<cmax;
8.2.11 Trecerea unui numr "n" din baza
..9] n baza 10 b[2
n_10=0;p=l;
do
{
n_10=n_10+n%10*p;
n/=10;
p*=b;
}
while(n);
cout<<n_10;


37
Laboratorul 8 Structura ciclic cu test final
8.3 Exerciii
S se alctuiasc programe care s rezolve urmtoarele probleme:
8.3.1 Descompunerea unui numr n
factori primi
8.3.1.1 Pseudocodul:
1.citete n
2.n=abs(n)
3.f=2 //factorul prim de testat
4.ct timp (f<=n)
4.1.e=0 //exponentul la care apare
factorul n descompunere
4.2.ct timp (n%f==0) //n se divide la f
4.2.1.n=n/f
4.2.2.e=e+1
4.3.dac (e<>0) scrie f," la ",e
4.4.dac (f==2) f=f+1 altfel f=f+2

8.4 Faciliti de ntrerupere a unei secvene
8.4.1 Instruciunea break
Utilizat n cadrul instruciunilor ciclice, instruciunea break "foreaz" ieirea din acestea.
Fr a se mai testa valoarea expresiei (condiia) care determin repetarea corpului
instruciunii ciclice, se continu execuia cu instruciunea care urmeaz instructiunii ciclice.
Astfel, se ntrerupe repetarea corpului instruciunii ciclice, indiferent de valoarea condiiei de
test.
Utilizarea n cadrul instruciunii switch: n situaia n care s-a ajuns la o valoare a unei
expresiei constante egal cu cea a expresiei aritmetice, se execut instruciunea
corespunztoare acelei ramuri. Dac se ntlnete instruciunea break, parcurgerea este
ntrerupt (nu se mai compar valoarea expresiei aritmetice cu urmtoarele constante), deci
se va trece la execuia primei instruciuni de dup switch. Dac nu este ntlnit break,
parcurgerea continu. Instruciunea break cauzeaz deci, ieirea imediat din switch.
8.4.2 Instruciunea continue
ntlnirea instruciunii continue determin ignorarea instruciunilor care o urmeaz n corpul
instruciunii ciclice i reluarea execuiei cu testarea valorii expresiei care determin repetarea
sau nu a corpului ciclului.
8.4.3 Modul de utilizare a instruciunilor break i continue
do
{ instructiune1;
instructiune2;
if (expresie2)
break;
else
continue;
instructiune3;
}
while (expresie1);
while(expresie1)
{ instructiune1;
instructiune2;
if (expresie2)
break;
else
continue;
instructiune3;
}
for(expr1; expr2;
expr3)
{ instructiune1;
instructiune2;
if (expresie2)
break;
else
continue;
instructiune3;
}

38
Laboratorul 8 Structura ciclic cu test final
8.5 Exemple break, continue
8.5.1 Calculator de buzunar
//Instruc de selectie switch
#include<stdio.h>

void main()
{
int cod=1; float x,y,z; char op;
while(cod)
{
printf("\nIntroduceti
expresia (valoare operator
valoare): ");
scanf("%f %c %f",&x,&op,&y);
switch(op)
{
case '+':z=x+y;break;
case '-':z=x-y;break;
case '*':z=x*y;break;
case '/':z=x/y;break;
default: printf("\nOperator
eronat"); cod=0; z=0;
}
printf("%.2f %c %.2f=
%.2f",x,op,y,z);
}
}

8.6 NTREBRI I EXERCIII
8.6.1 Chestiuni teoretice
1. Care sunt instruciunile care implementeaz n limbajul C structura condiional ?
2. Care sunt instruciunile care implementeaz n limbajul C structura secvenial ?
3. Care sunt instruciunile care implementeaz n limbajul C structura repetitiv cu test iniial ?
4. Care sunt instruciunile care implementeaz n limbajul C structura repetitiv cu test final ?
5. Ce deosebiri sunt ntre instruciunea while i instruciunea do-while ?
6. Pornind de la sintaxa instruciunii for, stabilii echivalena ntre aceasta i instruciunile while i
do-while.
8.6.2 Chestiuni practice
1. S se calculeze aria unui triunghi, cunoscndu-se mrimea laturilor sale. Numerele care
reprezint mrimile laturilor vor fi introduse de utilizator. Se va testa mai nti dac cele 3
numere reprezentnd mrimea laturilor pot forma un triunghi ( a <= b+c, b <= c+d, c <= a+b).
2. S se rescrie urmtoarea secven, folosind o singur instruciune if.
if (n<0)
if (n>=90)
if (x!=0)
int b= n/x;
3. S se gseasc toate numerele de dou cifre care satisfac relaia: xy __ = (x+y)
2

4. S se citeasc un ir de numere reale, pn la ntlnirea numarului 800 i s se afieze
valoarea minim introdus, suma i produsul elementelor irului.
5. Scriei un program care s verifice inegalitatea 1/(n+1) < ln[(n+1)/n] < 1/n, unde n este un
numr natural pozitiv, introdus de la tastatur.
6. Fie funcia
e
x-3
, x[0, 1)
f(x)= sinx+cosx , x[1, 2)
0,9ln(x+3) , x[2, 100]
7. S se scrie un program care calculeaz i afieaz maximul a 3 numere reale (a, b i c) citite
de la tastatur.
S se calculeze f(x), x citit de la tastatur.
8. S se scrie un program care calculeaz i afieaz minimul a 3 numere reale (a, b i c) citite
de la tastatur.

39
Laboratorul 8 Structura ciclic cu test final
9. S se citeasc 2 caractere care reprezint 2 litere mari. S se afieze caracterele citite n
ordine alfabetic.
10. S se citeasc 3 caractere care reprezint 3 litere mici. S se afieze caracterele citite n
ordine alfabetic.
11. S se scrie un program care citete o cifr. n funcie de valoarea ei, s se fac urmtorul
calcul: dac cifra este 3, 5 sau 7 s se afieze ptratul valorii numerice a cifrei; dac cifra este
2, 4 sau 6 s se afieze cubul valorii numerice a cifrei; dac cifra este 0 sau 1 s se afieze
mesajul "Valori mici"; altfel., s se afieze mesajul "Caz ignorat!".
12. Fie irul lui Fibonacci, definit astfel:
f(0)=0, f(1)=1, f(n)=f(n-1)+f(n-2) n cazul n care n>1.
S se scrie un program care implementeaz algoritmul de calcul al irului Fibonacci.
13. S se calculeze valoarea polinomului Cebev de ordin n ntr-un punct x dat, cunoscnd
relaia:
T
0
(x)=1, T
1
(x)=x i T
k+1
(x) - 2xT
k
(x) + T
k -1
(x) = 0
14. S se citeasc cte 2 numere ntregi, pn la ntlnirea perechii (0, 0). Pentru fiecare pereche
de numere, s se calculeze i s se afieze cel mai mare divizor comun.
15. Se citesc cte 3 numere reale, pn la ntlnirea numerelor 9, 9, 9. Pentru fiecare triplet de
numere citit, s se afieze maximul.
16. Se citete cte un caracter pn la ntlnirea caracterului @. S se afieze numrul literelor
mari, numarul literelor mici i numrul cifrelor citite; care este cea mai mare (lexicografic) liter
mare, liter mic i cifr introdus.
17. Se citesc cte 2 numere ntregi, pn la ntlnirea perechii de numere 9, 9. Pentru fiecare
pereche de numere citite, s se afieze cel mai mare divizor comun al acestora.
18. S se calculeze suma seriei
1 + x
3
/3 - x
5
/5 + x
7
/7 -
cu o eroare mai mic dect epsilon (epsilon citit de la tastatur). S se afieze i numrul de
termeni ai sumei.
19. S se citeasc un numr ntreg format din 4 cifre (abcd). S se calculeze i s se afieze
valoarea expresiei reale: 4*a + b/20 -c + 1/d.
20. S se scrie un program care afieaz literele mari ale alfabetului n ordine cresctoare, iar
literele mici - n ordine descresctoare.
21. S se scrie un program care genereaz toate numerele perfecte pn la o limit dat, LIM. Un
numr perfect este egal cu suma divizorilor lui, inclusiv 1 (exemplu: 6=1+2+3).
22. S se calculeze valoarea sumei urmatoare, cu o eroare EPS mai mic de 0.0001:
S=1+(x+1)/ 2! + (x+2)/ 3! + (x+3)/ 3! + ... , unde 0<=x<=1, x citit de la tastatur.
23. S se genereze toate numerele naturale de 3 cifre pentru care cifra sutelor este egal cu
suma cifrelor zecilor i unitilor.
24. S se citeasc cte un numr ntreg, pn la ntlnirea numrului 90. Pentru fiecare numar s
se afieze un mesaj care indic dac numrul este pozitiv sau negativ. S se afieze cel mai
mic numr din ir.
25. S se genereze toate numerele naturale de 3 cifre pentru care cifra zecilor este egal cu
diferena cifrelor sutelor i unitilor.
26. S se calculeze suma:
(1 + 2!) / (2 + 3!) - (2+3!) / (3+4!) + (3+4!) / (4+5!) - .....

40
Laboratorul 9 Tablouri unidimensionale
9. Tablouri unidimensionale
9.1 Vectori
Adeseori n programe se folosesc grupe mari de date. Gruparea acestora se face n mai
multe moduri. Un mod simplu de a grupa datele este de a grupa datele este de a considera
date de acelai tip n aa fel nct grupa respectiv s formeze o mulime ordonat de
elemente la care ne referim prin indici. O astfel de grup se numete tablou. Unui tablou i se
d un nume; tipul comun al elementelor este i tipul tabloului respectiv. De exemplu o
mulime ordonat de ntregi reprezint un tablou de tip ntreg.
n cazul cnd elementele care se grupeaz ntr-un tablou sunt ele nsele tablouri vom avea
nevoie de mai muli indici pentru a ne referi la ele; n acest caz avem un tablou
multidimensional (n-dimensional, n fiind numrul de indici) altfel - tablou unidimensional.
Exemple simple de tablouri unidimensionale sunt vectorii cu componentele de acelai tip. O
matrice este un tablou bidimensional.
Referirea la elementele unui tablou se face printr-o variabil cu indici. O variabil cu indici se
compune din numele tabloului urmat de valorile indicilor fiecare indice fiind reprezentat de o
expresie inclus ntre paranteze ptrate.
Valoarea inferioar a indicilor este 0. De exemplu dac vect este un tablou cu 10 elemente
atunci ne referim la elementele lui cu ajutorul variabilelor cu indici:
vect[0] primul element
............
vect[9] ultimul element
Dac mat este o matrice de 3 linii a dou coloane fiecare atunci elementele vor fi referite
prin:
mat[0][0] mat[0][1] prima linie
mat[1][0] mat[1][1] a doua linie
mat[2][0] mat[2][1] a treia linie
9.2 Declaraia de tablou
Un tablou ca orice variabil simpl trebuie declarat nainte de a fi utilizat. Declaraia de tablou
n forma cea mai simpl conine tipul comun elementelor sale, numele tabloului i limitele
superioare pentru fiecare indice incluse ntre paranteze ptrate:
tip nume [lim_1][lim_2]...[lim_n] = {lista valori}
unde tip este tipul de baz al tabloului iar lim_i este limita superioar a celui de al i-lea indice;
nseamn c indicele al i-lea poate lua valorile: 0, 1,..., lim_n-1 (lim_n - sunt expresii
constante).
La ntlnirea unei declaraii de tablou compilatorul aloc o zon de memorie necesar
pstrrii valorii elementelor sale.
9.3 Exemple

41
Laboratorul 9 Tablouri unidimensionale
9.3.1 Instruciunile de citire a primelor n
elemente ale unui vector
for(i=0; i<n; i++) cin>>a[i];
9.3.2 Instruciunile de scriere a primelor
n elemente ale unui vector
for(i=0; i<n; i++) cout<<a[i];
9.3.3 Operaii cu elemente unui vector
S se alctuiasc un program care s
determine valoarea minim, maxim, suma
i media elementelor unui ir de numere
reale.
9.3.3.1 Strategia de rezolvare:
Va fi citit mai nti numrul curent de
elemente ale irului, iar apoi vor fi citite
succesiv elementele irului folosind o
variabil intermediar temp.
Pentru determinarea valorii minime i
maxime a irului se iniializeaz att
minimul ct i maximul cu prima poziie din
ir, dup care, succesiv, vor fi comparate
elementele irului cu minimul curent i
respectiv cu maximul curent. Dac valoarea
comparat a elementului irului este mai
mare dect maximul curent, atunci aceast
valoare devine maximul curent. Similar se
petrec lucrurile pentru valoarea minim.
Pentru calculul sumei elementelor irului,
variabila suma se iniializeaz cu zero,
dup care fiecare element al irului se
adaug la valoarea curent a sumei,
conform relaiei: suma= suma + a[i], relaie
ce poate fi scris simplificat astfel:
suma+=a[i]. Media aritmetic se calculeaz
prin raportarea sumei elementelor la
numrul de elemente din ir.

/* Program 6.
Determinarea valorilor minima si
maxima ale unui sir de numere
reale.
Determinarea sumei elementelor
sirului si a mediei aritmetice a
acestora.*/
#include<stdio.h>
#include<conio.h>

void main()
{
int i,N;
float
temp,suma,media,min,max,a[100];
clrscr();
printf("Dati nr. de elem ale
sirului N=");
scanf("%2d",&N);
for(i=1;i<N+1;i++)
{
printf("A[%2d]=",i);
scanf("%f",&temp);
a[i]=temp;
}
min=a[1];max=a[1];
for(i=2;i<N+1;i++)
{
if(a[i]<min) min=a[i];
if(a[i]>max) max=a[i];
}
suma=0;
for(i=1;i<N+1;i++)
suma+=a[i];
media=float(suma)/N;
printf("Valoarea minima a sirului
MIN =%g\n",min);
printf("Valoarea maximii a siruJui
MAX =%g\n",max);
printf("Suma elementelor sirului
SUMA =%g\n",suma);
printf("Valoarea medie a sirului
MED =%g\n",media);
N=getche();
}

9.3.4 Produsul scalar a doi vectori
9.3.4.1 Program:
#include<iostream.h>
main()
{
unsigned n,i; float
a[100],b[100],p;
cout<<dati dimensiunea:;cin>>n;
for (i=0;i<n;i++)
{ cout<<a[<<i<<]; cin>>a[i];
}
for (i=0;i<n;i++)
{ cout<<b[<<i<<]; cin>>b[i];
}
p=0; for (i=0;i<n;i++)
p+=a[i]*b[i]; cout<<Produsul=<<p;
}

42
Laboratorul 9 Tablouri unidimensionale
9.3.5 Sortarea cresctoare a elementelor
unui vector cu n elemente reale
9.3.5.1 Pseudocod:
1. Citete n
2. Pentru i=0,n-1 citete v[i]
3. m=n, sort=0
4. Ct timp (m>0) i (sort=0)
4.1. sort=1
4.2. Pentru i=0,m-1
dac (v[i]>v[i+1])
4.2.1. sort=0
4.2.2. aux=v[i]
4.2.3. v[i]=v[i+1]
4.2.4. v[i+1]=aux
4.3. m=m-1
5. Pentru i=0,n-1 scrie v[i]

9.3.5.2 Programul:
//Sortarea elementelor unui vector
#include<iostream.h>

void main()
{
int i,n,m,sort=0,v[10],aux;
cout<<"\nDati dimens vect n:
";cin>>n;
for(i=0;i<n;i++)
{
cout<<"Elem v["<<i<<"]= ";
cin>>v[i];
}
m=n;
while((m>0)&&(sort==0))
{
sort=1;
for(i=0;i<m-1;i++)
if(v[i]>v[i+1])
{
sort=0;
aux=v[i]; v[i]=v[i+1];
v[i+1]=aux;
}
m--;
}
for(i=0;i<n;i++)
cout<<"\nv["<<i<<"]= "<<v[i];
}

9.3.6 Problema 5:
S se fac rearanjarea liniilor unei matrici
astfel nct elementele de pe diagonala
principal s fie elementele de maxim ale
fiecrei linii. Se consider c elementele
matricii sunt distincte.
Vom determina mai nti coloanele
elementelor de maxim ale fiecrei linii ntr-
un vector c. Apoi vom verifica dac valorile
coloanelor sunt distincte, n caz contrar nu
este posibil rearanjarea liniilor conform
cerinelor problemei.
Exemplu: Dimensiunea matricii: 3.
Elementele matricii:

2 1 8
9 2 0
5 7 6
. O soluie
este:

9 2 0
5 7 6
2 1 8
.
9.3.6.1 Programul este urmtorul:

#include<stdio.h>
int
c[10],mat1[10][10],mat[10][10],i,j,
poz,max1,n;

int maxim(int i) ;

void main()
{/* Citire dimensiune*/
printf("Dimensiunea matricii: ");
scanf("%d",&n);
/* Citire matrice */
printf("Elementele matricii: ");
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
scanf("%d",&mat[i][j]);
/* Aflarea maximelor pe linii */
for(i=1;i<=n;i++)
c[i]=maxim(i);
/* Se verifica daca coloanele
obtinute sunt unice */
for(i=1;i<n;i++)
for(j=i+1;j<=n;j++)
if(c[i]==c[j])
{puts ("Problema nu are
solutie"); return; }
/* Copierea liniilor cu maximul pe
diagonala principala in alta
matrice */
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
mat1[c[i]][j]=mat[i][j];
puts("O solutie este: ");
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
printf ("%5d",mat1[i][j]);

43
Laboratorul 9 Tablouri unidimensionale
puts(" ");
}
}

int maxim(int i)
{
poz=1;
/* Se
max1=mat[i][1];
for(j=2;j<=n;j++)
if(mat[i][j]>max1)
{max1=mat[i][j]; poz=j; }
return poz;
}

determina coloana unui
element de maxim al liniei i */


44
Laboratorul 10 iruri de caractere
10. iruri de caractere
10.1.1 Problema 1:Fiind dat un cuvnt, s se afieze toate prefixele acestuia.
Se va determina mai nti lungimea cuvntului. ntruct nu se cere o anumit ordine a
prefixelor, le vom genera de la cel mai lung (ntregul cuvnt) la cel mai scurt (prima liter).
Pentru a reduce dimensiunea vom nlocui la fiecare pas ultima liter cu terminatorul de ir.
#include<stdio.h>
#include<string.h>

void main()
{
int n; char cuv[128];
printf("\nIntroduceti cuvantul: ");scanf ("%s",cuv);
n=strlen(cuv);
while(n--)
{printf ("\n%s",cuv);
cuv[n]=0;
}
}

10.1.2 Stoilescu 202 Problema 2:
S se verifice dac un numr este palindrom. Un numr este considerat palindrom dac citit
de la stnga la dreapta sau invers, are aceeai valoare. Exemple: 1221, 121, 50905.
Numrul se va converti ntr-un ir de caractere cu ajutorul funciei ltoa din biblioteca
standard, apoi irul se caractere se va compara cu inversul su. Pentru obinerea inversului
unui ir se va folosi funcia strrev din biblioteca string.h.
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

void main()
{
long n;
char sir1[100], sir2[100];
printf("Introduceti numarul: ");
scanf("%ld",&n);
ltoa(n,sir1,10); //transforma numarul in sir
strcpy(sir2,sir1);
strrev(sir2); //inverseaza ordinea caracterelor din sir
if(strcmp(sir1,sir2)==0)
puts("\nNumarul este palindrom!");
else
puts("\nNumarul nu este palindrom!");
}
10.1.3 Problema 5:
Fiind date n iruri de caractere care reprezint n cuvinte, s se determine toate perechile de
rime formate.

45
Laboratorul 10 iruri de caractere
Pentru aceasta se vor compara cu ajutorul funciei strcmp pe rnd ultimele dou litere ale
fiecrui cuvnt cu ultimele dou litere ale celorlalte cuvinte. Dac acestea coincid atunci se
va tipri perechea de iruri gsit.

//Stoilescu 2.05
#include<string.h>
#include<stdio.h>

void main()
{
char a[20][20]; int i,n,j;
printf("Numarul de cuvinte: ");scanf("%d",&n);
puts("Cuvintele: ");
for(i=0;i<n;i++)
scanf("%s", &a[i]);
puts("Se formeaza rimele:");
for(i=0;i<n-1;i++)
for (j=i+1;j<n;j++)
if(strcmp(&a[i][strlen(a[i])-2], &a[j][strlen(a[j])-2]) == 0)
printf("%s------------%s\n",a[i],a[j]);
}

10.1.4 Cel mai lung cuvnt cititS se scrie un program care citete o succesiune de
cuvinte i-l afieaz pe cel mai lung dintre ele.
Prin cuvnt nelegem o succesiune de caractere diferite de caracterele albe. Vom presupune
c un cuvnt nu are mai mult de 100 de caractere. Cuvintele sunt separate prin spaii. La
sfrit se tasteaz sfritul de fier (Ctrl+Z) pentru a termina succesiunea de cuvinte.
//PROGRAMUL BVIII11
#include <stdio.h>
#include <string.h>
#define MAX 100
void main () /* citeste o succesiune de cuvinte si-l afiseaza pe cel mai
lung dintre ele */
{
int max=0,i; char cuvint[MAX+1]; char cuvint_max[MAX+1];
printf("\nIntroduceti cuvintele urmate de Ctrl-Z: \n");
while(scanf("%100s",cuvint) != EOF)
if(max < (i=strlen(cuvint)))
{ max = i; strcpy(cuvint_max,cuvint);}
if(max)
printf("Cel mai lung cuvint: %s", cuvint_max);
}

Observaii:
1. Cuvntul citit se pstreaz n tabloul cuvint de MAX+1 elemente. La citire se utilizeaz
specificatorul de format: %100s care permite s se citeasc cel mult 100 de caractere diferite
de cele albe. Funcia scanf pstreaz caracterul NULL dup ultimul caracter citit. Deci, un
cuvnt de 100 de caractere ocup 101 octei.
2. Dup citirea unui cuvnt se apeleaz funcia strlen pentru a determina numrul
caracterelor citite prin scanf i pstrate n tabloul cuvint. n acest caz s-a utilizat expresia:
i = strlen(cuvint)
Apoi se compar lungimea cuvntului citit cu max.
Variabila max are ca valoare lungimea maxim a cuvintelor citite naintea celui curent. Iniial
max = 0, deoarece nu exist nici un cuvnt citit. Dac max este mai mic dect lungimea

46
Laboratorul 10 iruri de caractere
cuvntului citit curent, atunci lui max i se atribuie aceast valoare, iar cuvntul citit este
transferat n zona de memorie alocat tabloului cuvnt_max. n acest scop se apeleaz
funcia strcpy:
strcpy(cuvint_max, cuvint);
10.1.5 Program citire i ordonare cuvinteS se scrie un program care citete dou cuvinte
i le afieaz n ordine cresctoare.
Cuvntul se definete ca n exerciiul precedent, adic este o succesiune de cel mult 100 de
caractere care nu sunt albe. Cuvintele sunt separate prin spaii (caractere albe).
//PROGRAMUL BVIII12
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX 100

void main ( ) /* citeste doua cuvinte si lc afiseaza in ordine crescatoare
*/
{
char cuv1[MAX+1]; char cuv2[MAX+1] ;
if(scanf("%100s",cuv1) != 1)
{ printf("nu s-a tastat un cuvint\n"); exit(1); }
if(scanf("%100s",cuv2) != 1)
{ printf("nu s-a tastat un cuvint\n"); exit(1); }
if(strcmp(cuv1,cuv2) < 0)
{ /* primul cuvint tastat este mai mic decit cel de-al doilea */
printf("%s\n",cuv1) ; printf("%s\n",cuv2);
}
else
{ printf("%s\n",cuv2) ; printf("%s\n",cuv1); }
}

S se scrie un program care citete o succesiune de cuvinte i-l afieaz pe cel mai mare.
Prin cuvnt nelegem o succesiune de cel mult 100 de caractere care nu sunt albe.
Cuvintele sunt separate prin caractere albe. Succesiunea de cuvinte se termin cu sfiritul de
fiier.
//PROGRAMUL BVIII13
#include <stdio.h>
#include <string.h>
#define MAX 100

void main() /* citeste o succesiune de cuvinte si-l afiseaza pe cel mai
mare */
{
char cuv_crt[MAX+1]; char cuv_max[MAX+1];
cuv_max[0] = '\0'; /* cuv_max se initializeaza cu cuvintul vid */
while(scanf("%100s",cuv_crt) != EOF)
if(strcmp(cuv_crt,cuv_max) > 0)
/* cuvintul curent este mai mare decit cel pastrat in cuv_max */
strcpy(cuv_max,cuv_crt);
printf("cel mai mare cuvint este\n"); printf("%s\n", cuv_max);
}


47
Laboratorul 11 Tablouri multidimensionale
11. Tablouri multidimensionale
11.1 Exemple
11.1.1 Declararea unui tablou bidimensional
int mat1[2][3]; //Tablou bidimensional numit mat1 cu 2x3 elemente intregi
int mat2[10][10]; //Tablou bidimensional numit mat2 cu 10x10 elemente
reale
11.1.2 Instruciunile de citire a primelor m linii i n coloane ale unei matrici
for(i=0; i<m; i++)
for(j=0; j<n; j++)
cin>>a[i] [j];
11.1.3 Instruciunile de scriere a primelor m linii i n coloane ale unei matrici
for(i=0; i<n; i++,cout\n)
for(j=0; j<n; j++)
cout<<a[i] [j];
11.1.4 Suma a dou matrici:
Programul:
#include<iostream.h>
main()
{
unsigned n,m,j,i;
float a[10][10],b[10][10],c[10][10];
cout<<nr linii:;cin>>n; cout<<nr coloane:;cin>>m;
for (i=0;i<n;i++)
for (j=0;j<m;j++)
{ cout<<a[<<i<<,<<j<<]; cin>>a[i][j]; }
for (i=0;i<n;i++)
for (j=0;j<m;j++)
{ cout<<b[<<i<<,<<j<<]; cin>>b[i][j]; }
for (i=0;i<n;i++)
for (j=0;j<m;j++)
c[i][j]=a[i][j]+b[i][j];
for (i=0;i<n;i++,cout<<\n)
for (j=0;j<m;j++)
cout<<c[i][j]<<\t;
}
11.2 Probleme propuse
S se alctuiasc programe care s rezolve urmtoarele probleme:

48
Laboratorul 11 Tablouri multidimensionale
11.2.1 Valoarea unui polinom ntr-un
punct, unde coeficienii polinomului
sunt memorai ntr-un vector
11.2.1.1 Pseudocod:
1 citete g,x
2 1=0
3 ct timp i<n
3.1 citete p[i]
3.2 i=i+1
4 v=p[0], xi=x, i=1
// v - valoarea, xi - x
i
5 ct timp i<n
5.1 xi=xi*x
5.2 v=v+xi*p[i]
5.3 i=i+1
6 scrie v
11.2.2 Produsul a dou polinoame
11.2.2.1 Pseudocod:
1 citete g1,g2
2 i=0
3 ct timp i<g1
3.1 citete p1[i]
3.2 i=i+1
4 i=0
5 ct timp i<g2
5.1 citete p2[i]
5.2 i=i+1
6 i=0
7 ct timp i<(g1+g2)
7.1 q[i]=0
7.2 i=i+1
8.i=0
9 ct timp i<g1
9.1 j=0
9.2 ct timp j<g2
9.2.1 q[i+j]= q[i+j]+p1[i]*p2[j]
9.2.2 j=j+1
9.3 i=i+1
10 i=0
11 ct timp i<g1+g2
10.1 scrie q[i]
10.2 i=i+1
11.2.3 Produsul a dou matrici
11.2.3.1 Pseudocod:
1. Citete m,n,p
2. Pentru i=1,m
pentru j=1,n
citete a[i][j]
3. Pentru i=1,n
pentru j=1,p
citete b[i][j]
4. Pentru i=1,m
pentru j=1,p
c[i][j]=0
5. Pentru i=1,m
pentru j=1,n
pentru k = 1,p
c[i][j]= c[i][j] + a[i][k]*b[k][j]
6. Pentru i=1,m
pentru j=1,p
scrie c[i][j]


49
Laboratorul 11 Tablouri multidimensionale
11.3 NTREBRI I EXERCIII
11.3.1 Chestiuni teoretice
1. Care este diferena dintre irurile de caractere i vectorii de caractere ?
2. Ce sunt tablourile ?
3. De ce tablourile reprezint date structurate ?
4. Prin ce se refer elementele unui tablou ?
5. Cine impune tipul unui tablou ?
11.3.2 Chestiuni aplicative
1. Se citesc de la tastatura elementele unei matrici de caractere (nr. linii=nr. coloane),
A(NXN), N<=10.
a) S se afieze matricea A;
b) S se formeze i s se afieze cuvntul format din caracterele pe pe diagonala principal
a matricii A;
c) S se calculeze i s se afieze numrul de litere mari, litere mici i cifre din matrice;
d) S se afieze cuvntul format din caracterele de pe diagonala secundar;
e) S se afieze procentul literelor mari, al literelor mici i al cifrelor de pe cele 2 diagonale;
f) S se afieze caracterele comune aflate pe liniile p i q (p, q < N, p i q citite de la
tastatur);
g) S se afieze n ordine alfabetic, cresctoare, literele mari aflate pe coloanele impare.
2. Se citesc de la tastatur elementele unei matrici cu elemente reale, B (N X N), N<=8.
a) S se afieze matricea B;
b) S se calculeze i s se afieze produsul elementelor de pe coloanele impare;
c) S se calculeze i s se afieze matricea A, unde: A = ( B + B
T
)
2
;
d) S se formeze i s se afieze vectorul V, ale crui elemente sunt elementele pozitive din
matricea A;
e) S se calculeze i s se afieze sumele i produsele elementelor matricii A, aflate n
triunghiurile haurate:
f) S se calculeze procentul elementelor pozitive aflate pe diagonala secundar;
g) S se calculeze i s se afieze matricea C, unde: C = 3 * B
T
+ B
2
;
h) S se calculeze i s se afieze matricea D, unde: D = B + B
2
+ B
3
+ B
4
;
i) S se interschimbe coloanele matricii A astfel: prima cu ultima, a doua cu antipenultima,
etc.
3. Se citesc de la tastatur elementele unei matrici de numere ntregi C (N X N), N<=10.
a) S se afieze matricea C;
b) S se calculeze i s se afieze procentul elementelor impare de pe liniile pare;
c) S se calculeze i s se afieze matricea B, unde: B = C
2
;
d) S se calculeze i s se afieze matricea E, unde: E = (C + C
T
)
2
+ I, unde I este matricea
unitate;
e) S se afle elementul minim din matricea C;
f) S se nlocuiasc elementul maxim din matricea C cu valoarea val, introdus de la
tastatur;
g) S se afieze elementele matricii C care sunt numere prime;
h) S se calculeze i s se afieze sumele i produsele elementelor matricii A, aflate n
triunghiurile haurate:


50
Laboratorul 12 Pointeri i adrese
12. Pointeri i adrese
Exist doi operatori unari care permit utilizarea variabilelor pointer:
& - operatorul adres (de refereniere) - pentru aflarea adresei din memorie a unei variabile;
* - operatorul de indirectare (de defereniere) - care furnizeaz valoarea din zona de memorie
spre care pointeaz pointerul operand.

Sintaxa declaraiei unui pointer de date este:
tip *identificator_pointer;
Simbolul * precizeaz c identificator_pointer este numele unei variabile pointer de
date, iar tip este tipul obiectelor a cror adres o va conine.
Exempl u:
int u, v, *p, *q; // *p, *q sunt pointeri de date (ctre int)
double a, b, *p1, *q1; // *p1, *q1 sunt pointeri ctre date de tip double

Operatorul "*" se numete operatorul de refereniere i este aplicat unei adrese, ntorcnd
valoarea memorat la acea adres.
De exemplu, n declaraia:
int *n;
n este adresa unei variabile de tip ntreg, iar *n este valoarea memorat la adresa n.
OBSERVAIE: Orice adres este memorat sub forma unui numr ntreg, pe 2, 4 sau 8
octei (n mod implicit 2)

Operatorul invers se noteaz "&" i se numete operatorul de dereferentiere (operatorul
adres)
De exemplu instruciunea: &x=y are semnificaia: adresa lui x ia valoarea y.
12.1 Exemple
12.1.1 Pointeri
//Pointeri - exemple
#include<iostream.h>

void main()
{
int x=5, y, *ptr;
// ptr - variabila pointer catre un
int; x,y-variabile predefinite,
simple, de tip int

cout<<"\n\nValoarea lui x:
"<<x<<"\nAdresa variabilei x este:
"<<&x<<'\n';
ptr=&x;// atribuire: variabila ptr
contine adresa variabilei x
cout<<"Variabila pointer ptr are
valoarea: "<<ptr<<" si adreseaza
obiectul: "<< *ptr<<'\n';
y=*ptr; cout<<"y="<<y<<'\n'; // y=5
x=4; cout<<"x= "<<x<<'\n';
cout<<"*ptr= "<<*ptr<<'\n';
// x si *ptr reprezinta acelasi
obiect, un intreg cu valoarea 4
x=70; // echivalenta cu
*ptr=70;
y=x+10; // echivalenta cu
y=*ptr+10

int *q;
q=&x;
*q=8; // echivalenta cu
x=8;
//q=&5; // invalida - constantele
nu au adresa
//*x=9; // invalida - x nu este
variabila pointer
//x=&y; //invalida: x nu este
variabila pointer, deci nu poate fi
folosita cu operatorul de indirectare
y=*q+3; // echivalenta cu y=x+3;
q=0; // seteaza x pe 0

51
Laboratorul 12 Pointeri i adrese
q+=1; // echivalenta cu ( q)++
sau cu x++
int *r;
r=q;
/* copiaza continutul lui q(adresa
lui x) n r, deci r va pointa tot
catre x (va conine tot adresa lui
x)*/

double w=3.5, *r1, *r2; r1= &w;
r2=r1;
cout<<"r1="<<r1<<'\t';
//afiseaza valoarea pointerului
r1(adresa lui w)
cout<<"&r1="<<&r1<<'\t'; //
afiseaza adresa variabilei r1
cout<<"*r1= "<<*r1<<'\n';
double z=*r1; //
echivalenta cu z=w
cout<<"z="<<z<<'\n';
}

12.1.2 Legtura pointeri - iruri de
caractere
S se scrie urmtorul program i s se
urmreasc rezultatele execuiei acestuia.
//Pointeri si sirurie de caractere
#include <iostream.h>
#include<conio.h>

void main(void)
{
textmode(3);
int a=-5, b=12, *pi=&a;
double v=-2.24, *pd=&v;
char sir1[]="Sirul 1", sir2[]="Sirul
2", *psir=sir1;


cout<<"a="<<a<<"\t&a="<<&a<<"\tb="<<b<
<"\t&b="<<&b<<'\n';

cout<<"*pi="<<*pi<<"\tpi="<<pi<<"\t&pi
="<<&pi<<'\n';
cout<<"*pd="<<*pd<<"\tpd="<<pd<<"\t
&pd="<<&pd<<'\n';

cout<<"*sir1="<<*sir1<<"\tsir1="<<sir1
<<"\t&sir1="<<&sir1<<'\n';
// *sir1=s sir1=Sirul 1
&sir1=0xffd6

cout<<"*sir2="<<*sir2<<"\tsir2="<<sir2
<<"\t&sir2="<<&sir2<<'\n';
// *sir2=s sir2=Sirul 2
&sir1=0xffce

cout<<"*psir="<<*psir<<"\tpsir="<<psir
<<"\t&psir="<<&psir<<'\n';
// *psir=s psir=Sirul 1
&sir1=0xffcc

cout<<"sir1+2="<<(sir1+2)<<"\tpsir+2="
<<(psir+2)<<'\n';
// sir1+2=rul 1 psir+2=rul 1
cout<<"*(sir1+2)="<< *(sir1+2)<<'\n';
// *(sir1+2)=r valoarea elementului
de indice 2
void *pv1, *pv2;
pv1=psir; pv2=sir1;

cout<<"pv1="<<pv1<<"\t&pv1="<<&pv1<<'\
n';

cout<<"pv2="<<pv2<<"\t&pv2="<<&pv2<<'\
n';
pi=&b; pd=&v; psir=sir2;

cout<<"*pi="<<*pi<<"\tpi="<<pi<<"\t&pi
="<<&pi<<'\n';

cout<<"*pd="<<*pd<<"\tpd="<<pd<<"\t&pd
="<<&pd<<'\n';

cout<<"*psir="<<*psir<<"\tpsir="<<psir
<<"\t&psir="<<&psir<<'\n';
}

12.1.3 Pointer la vector - ex 1
n limbajul C, cazul parametrilor tablou
constituie o excepie de la regula
transferului parametrilor prin valoare.
Numele unui tablou reprezint, de fapt,
adresa tabloului, deci a primului element
din tablou.

S se scrie urmtorul program (care
ilustreaz legtura dintre pointeri i vectori)
i s se urmreasc rezultatele execuiei
acestuia.
#include <iostream.h>

void main(void)
{int a[10] = {0,1,2,3,4,5,6,7,8,9};
int *pi1 = a;
int *pi2 = &a[0]; int *pi3;
cout<<"a="<<a<<"&a="<<&a<<"*a="<<*a
<<'\n';
cout<<"a+1="<<(a+1)<< " &a[1]="<<
&a[1]<<'\n';
cout<<"a[1]="<<a[1]<< " *(a+1)="<<
*(a+1)<<'\n';
cout<<"pi1="<<pi1<<"pi2="<<pi2<<'\n
';
int x=*pi1; /* x primeste valoarea
locatiei a carei adresa se afla in
variabila pointer pi1, deci valoarea
lui a[0] */
cout<<"x="<<x<<'\n';

52
Laboratorul 12 Pointeri i adrese
x=*pi1++; // x = *pi1 = a[0] = 0,
iar apoi *pi1= a[1] = 1
void main()
{int a[3][3]={{5,6,7}, {55,66,77},
{555,666,777}}; cout<<"x="<<x<<'\n';
x=(*pi1)++; /* x = 1: intai
atribuirea, apoi incrementarea valorii
spre care indica pi1.
clrscr();
cout<<"a="<<a<<" &a="<<&a<<"
&a[0]="<<&a[0]<<'\n';
In urma incrementarii, valoarea lui
a[1] devine 2 */
cout<<"Pointeri catre vectorii
linii\n";
cout<<"x="<<x<<'\n'; cout<<*pi1<<'\n';
for (int i=0; i<3; i++){
x=*++pi1; //echivalent cu *(++pi1)
cout<<"x="<<x<<'\n';
x=++(*pi1); cout<<"x="<<x<<'\n';
pi1=a;
cout<<" *(a+"<<i<<")="<<*(a+i);
cout<<" a["<<i<<"]="<<a[i]<<'\n';
}
// afiarea matricii
pi3=pi1+3;
for (int i=0; i<3; i++){
cout<<"pi1="<<pi1<<"*pi1="<<*pi1<<"&pi
1="<<&pi1<<'\n'; for (int j=0; j<3; j++)
cout<<*(*(a+i)+j)<<'\t'; //sau:
cout<<*(a[i]+j)<<'\t';
cout<<"pi3="<<pi3<<"*pi3="<<*pi3<<"&pi
3="<<&pi3<<'\n';
cout<<"pi3-pi1="<<(pi3-pi1)<<'\n';
//pi3-pi1=3
cout<<'\n';
}
}
}

12.1.6 Pointer la matrice - 2
12.1.4 Pointer la vector - ex 2
//Pointer la matrice
//Pointer la vector
#include <iostream.h>
#include <iostream.h>
#define DIM1 3
#define DIM 3
#define DIM2 2


float cere_element(int i)
float cere_element(int i,int j)
{float elem;
{
cout<<"a("<<(i+1)<<")=";
float elem;
cin>>elem; cout<<"\n";
cout<<"a("<<(i+1)<<","<<(j+1)<<")=";
return elem;
cin>>elem;cout<<"\n";
}
return elem;
void afis_tablou(float *ptablou)
}
{int i;

for(i=0;i<DIM;i++)
void afis_tablou(float **ptablou)

cout<<"a("<<(i+1)<<")="<<*(ptablou+i)<
<"\n";
{
int i,j;
for(i=0;i<DIM1;i++)
}
for(j=0;j<DIM2;j++)

cout
<<"a("<<(i+1)<<","<<(j+1)<<")="<<*((*p
tablou)+i*DIM2+j)<<"\n";
void main()
{
float tablou[DIM];
}
int i;

float *ptablou;
void main()
ptablou=tablou;
{
cout<<"Introduceti elementele
tabloului\n";
float tablou[DIM1] [DIM2];
int i,j; float *ptablou;
for(i=0;i<DIM;i++)
tablou[i]=cere_element(i);
ptablou=*tablou;
cout<<"Introduceti elementele
tabloului\n";
cout<<"Elementele tabloului sunt:\n";
afis_tablou(ptablou);
for(i=0;i<DIM1;i++)
}
for(j=0;j<DIM2;j++)
tablou[i][j]=cere_element(i,j);

cout<<"Elementele tabloului sunt:\n";
afis_tablou(&ptablou);
12.1.5 Pointer la matrice - 1
}
#include<iostream.h>

#include<conio.h>


53
Laboratorul 12 Pointeri i adrese
12.2 NTREBRI I EXERCIII
12.2.1 Chestiuni teoretice
1. n ce const operaia de incrementare a pointerilor ?
2. Tablouri de pointeri.
3. Ce sunt pointerii generici ?
4. Ce operaii se pot realiza asupra variabilelor pointer ?
5. De ce numele unui pointer este rvalue ?
6. Ce fel de variabile pot constitui operandul operatorului de defereniere ?
7. Operatorul de refereniere.
8. Unui pointer generic i se poate atribui valoarea unui pointer cu tip ?
9. Care este legtura ntre tablouri i pointeri ?
10. De ce numele unui tablou este lvalue ?
12.2.2 Chestiuni practice
1. S se implementeze programele cu exemplele prezentate.
2. S se scrie programele pentru exerciiile rezolvate care au fost prezentate.
3. Analizai urmtoarele secvene de instruciuni. Identificai secvenele incorecte (acolo
unde este cazul) i sursele erorilor:
int a,b,*c; a=7; b=90; c=a;
double y, z, *x=&z; z=&y;
char x, **p, *q; x = 'A'; q = &x; p = &q; cout<<x=<<x<<\n;
cout<<**p=<<**p<<\n; cout<<*q=<<*q<<\n;
cout<<p=<<p<< q=<<q<<*p=<<*p<<\n;
char *p, x[3] = {'a', 'b', 'c'}; int i, *q, y[3] = {10, 20, 30};
p = &x[0];
for (i = 0; i < 3; i++)
{
cout<<*p=<<*p<< p=<<p<<\n;
p++;
}
q = &y[0];
for (i = 0; i < 3; i++)
{
cout<<*q=<<*q<<q=<<q<<\n;
q++;
}
const char *sirul=s programm; *(sirul)++;
double a, *s; s=&(a+89); cout<<s=s<<\n;
double a1, *a2, *a3; a2=&a1; a2+=7.8; a3=a2; a3++;
int m[10], *p;p=m;
for (int i=0; i<10; i++)
cout<<*m++;
void *p1; int *p2; int x; p2=&x; p2=p1;
char c=A; char *cc=&c; cout<<(*cc)++<<\n;


54
Laboratorul 13 Funcii
13. Funcii
13.1 Structura unei funcii
O funcie este format din antet i corp:
antet_functie
{
corp_functie
}
Sau:
tip_val_return nume_func(lista_declaratiilor_param_ formali)
{
declaratii_variabile_locale
instructiuni
[return valoare] //optional
}
Antetul funciei conine deci urmtoarele 3 elemente:
tipul valorii returnate de funcie
numele funciei
lista declaraiilor parametrilor formali

O funcie poate fi apelat printr-o construcie urmat de punct i virgul, numit instruciune
de apel, de forma:
nume_functie (lista_parametrilor_efectivi);
Parametrii efectivi trebuie s corespund cu cei formali ca ordine i tip.
13.2 Transferul parametrilor unei funcii
Funciile comunic ntre ele prin argumente (parametri). Exist urmtoarele moduri de
transfer (transmitere) a parametrilor ctre funciile apelate:
13.2.1 Transfer prin valoare;
Exemplul devenit clasic este cel al funciei de permutare (interschimbare) a dou variabile.
Fie funcia vschimb definit astfel:
void vschimb (float x, float y)
{ float t=x; x=y; y=t; }

void main()
{ float a=4.7, b=9.7;
. . . . . . . . . . .
schimb(a, b); // apel functie
. . . . . . . . . . . }
Parametri funciei vschimb sunt transmii prin valoare: parametrilor formali x, y li se atribuie
(la apel) valorile parametrilor efectivi a, b. Funcia vschimb permut valorile parametrilor
formali x i y, dar permutarea nu are efect asupra parametrilor efectivi a i b.

55
Laboratorul 13 Funcii
13.2.2 Transfer prin pointeri
Pentru ca funcia de interschimbare s poat permuta valorile parametrilor efectivi, n limbajul
C/C++ parametrii formali trebuie s fie pointeri ctre valorile care trebuie interschimbate:

void pschimb(float *x, float *y)
{ float t=*x; *x=*y; *y=t; }

void main()

{ float a=4.7, b=9.7;
. . . . . . . . . . .
pschimb(&a, &b); // apel functie
/* SAU:
float *pa, *pb;
pa=&a; pb=&b;
pschimb(pa, pb);*/
. . . . . . . . . . . }
Se atribuie pointerilor x i y valorile pointerilor pa, pb, deci adresele variabilelor a i b.
Funcia pschimb permut valorile spre care pointeaz pointerii x i y, deci valorile lui a i b.
13.2.3 Transfer prin referin.
n limbajul C++ acceai funcie de permutare se poate defini cu parametri formali de tip
referin.
void rschimb(float &x, float &y)
{ float t=x; x=y; y=t; }

void main()
{ float a=4.7, b=9.7;
. . . . . . . . . . . . . . .
rschimb(a, b); // apel funcie
. . . . . . . . . . . . . . . }
n acest caz, x i y sunt sinonime cu a i b (nume diferite pentru aceleai grupuri de locaii de
memorie). Interschimbarea valorilor variabilelor x i y nseamn interschimbarea valorilor
variabilelor a i b.
13.3 Funcii definite de utilizator
n afar de funciile predefinite existente n header-ele <stdlib.h>, <math.h>,
<iostream.h>, <string.h> - exist posibilitatea de a se construi noi funcii de ctre
programator(utilizator).
Sintaxa definiiei unei funcii este:
<tip valoare returnat> <nume funcie> (<tip parametru> [*] <nume
parametru> [,...])
{
<lista variabile auxiliare>;
<instructiuni>;
[return <variabila>;]
}
unde:
<tip valoare returnat> - poate fi oricare din tipurile de baz sau void (tipul vid)

56
Laboratorul 13 Funcii
<tip parametru> - poate avea orice tip cu excepia lui void
[*] - este un parametru opional, utilizat numai pentru parametrii a cror valoare se
modific (spunem c funcia are efecte laterale)
<instruciuni> - au aceeai sintax cu cele dintr-un program, servesc la calculele
intermediare din corpul funciei
<lista variabile auxiliare> - sunt variabile locale funciei, nu sunt vzute n afara funciei
instruciunea return este principala instruciune a unei funcii, ea nseamn returnarea de
ctre funcie a rezultatului care va fi transmis programului principal sau altei funcii care o
apeleaz; ea este obligatorie n toate funciile cu excepia celor de tip void

Sintaxa apelului unei funcii este:
<nume funcie> ( <nume parametru> [,...])
deci numele funciei urmat de lista parametrilor ntre paranteze; acetia poart numele de
parametrii actuali iar parametrii din definiia funciei se numesc parametrii formali. Este
necesar ca parametrii actuali s corespund ca numr i tip cu parametrii formali.

OBSERVAIE: De obicei funciile se declar i se definesc la nceputul programului, dar se
mai pot declara i astfel: se declar la nceput prototipul i apoi la sfrit definirea =
descrierea detaliat (inclusiv prototipul).
13.4 Exemple

13.4.1 Funcie pentru calculul
maximului a dou numere reale.
float max(float x, float y)
{
float a;
if (x>y) a=x; else a=y;
return a;
}
13.4.2 Schimbarea valorilor a dou
variabile - transferul parametrilor unei
funcii
//Transferul parametrilor unei
functii
#include<iostream.h>

//Transfer prin valoare
void schimb_v (float x, float y)
{ float t=x; x=y; y=t; }

//Transfer prin pointeri
void schimb_p(float *x, float *y)
{ float t=*x; *x=*y; *y=t; }

//Tansfer prin referinta
void schimb_r(float &x, float &y)
{ float t=x; x=y; y=t; }

void main()
{
float a=4.5, b=9.3;
cout<<"\nInitial\ta= "<<a<<"\tb=
"<<b;
schimb_v(a, b); // apel
functie
cout<<"\nValoare\ta= "<<a<<"\tb=
"<<b;
schimb_p(&a, &b); // apel
functie
cout<<"\nPointer\ta= "<<a<<"\tb=
"<<b;
schimb_r(a, b); // apel
functie
cout<<"\nRef\ta= "<<a<<"\tb=
"<<b;
}

13.4.3 Minimul elementelor unui tablou
Programul:
//Minimul elementelor unui tablou
#include <iostream.h>
#define DIM 5

float min2v(float a,float b)
{return (a<b?a:b);}

57
Laboratorul 13 Funcii

int sorttab(float tablou[DIM])
{
int i,indmin; float valmin;
valmin=tablou[0]; indmin=0;
for(i=1;i<DIM;i++)
{
valmin=min2v(valmin,tablou[i]);
if(valmin==tablou[i]) indmin=i;
}
return indmin;
}

void tiptab(float tablou[DIM])
{
int i;
for(i=0;i<DIM;i++)

cout<<"tabl("<<i<<")="<<tablou[i]<
<"\n";
}

void main()
{
float tabl [DIM]; int imin,i;
cout<<"introduceti elementele
tabloului\n";
for(i=0;i<DIM;i++)
{
cout<<"tabl ("<<i<<")=";
cin>>tabl[i];
cout<<"\n";
}
cout<<"Tabloul initial\n";
tiptab(tabl);
imin=sorttab(tabl);
cout<<"Elementul minim din tablou
este: tabl("<<imin<<")="<<
tabl[imin]<<"\n";
}

13.4.4 Realizarea apelului prin referin
utiliznd parametri de tip pointer
13.4.4.1 S se scrie o funcie (pcit_int)
care afieaz caracterele unui tablou i
citete un ntreg de tip int.
Funcia are doi parametri:
text - Tablou unidimensional de t i p
caracter.
x - Pointer spre ntregi de ti p int; are ca
valoare adresa zonei de memorie n care
se pstreaz valoarea ntregului citit.
Funcia de fa returneaz 0 la ntlnirea
sfritului de fiier i 1 altfel.
//FUNCTIA BVIII2
int pcit_int(char text[], int *x)
/* - citeste un intreg si-l pastreaza
in zona de memorie a carei adresa este
valoarea lui x;
- returneaza:
0 - la intilnirea sfirsitului de
fisier;
1 - altfel */
{
char t[255];
for( ; ; )
{
printf(text);
if(gets(t) == NULL) return 0;
if(sscanf(t,"%d", x) == 1) return 1;
}
}

13.4.4.2 S se scrie o funcie
(pcit_int_lim) care citete un ntreg
de ti p int care aparine unui interval dat.
Ea are parametrii:
text - Tablou unidimensional de t i p
char
int - ntreg de ti p int .
sup - ntreg de tip int.
pint - Pointer spre ntregi de tip int; are
ca valoare adresa zonei de memorie n
care se pstreaz numrul citit.
funcia de fa returneaz:
0 - La nltlnirea sfritului de fiier.
1 - Altfel.
//FUNCTIA BVIII3
int pcit_int(char[], int *); /*
prototip */

int pcit_int_lim(char text[], int
inf, int sup, int *pint)
/* - citeste un intreg de tip int
ce apartine intervalului [inf.sup]
si-l\
pastreaza in zona de memorie a
carei adresa este valoarea
parametrului pint;
- returneaza:
0 - la intilnirea sfirsilului de
fisier;
1 - altfel. */
{
for(;;)
{
if(pcit_int(text, pint) == 0)
return 0; /* s-a intilnit EOF */
if(*pint >= inf && *pint <= sup)
return 1;

58
Laboratorul 13 Funcii
printf("intregul tastat nu
apartine intervalului:");
printf("[%d,%d]\n", inf,sup);
printf("se reia citirea\n");
}
}


13.4.5 Operaii cu matrici cu ajutorul
unor funcii:
Programul:
//Operatii cu matrici realizate cu
functii
#include<iostream.h>
#include<stdio.h>
#define DIM 10

void citire(int nl,int nc,int
mat[DIM][DIM])
{
int i,j;
for(i=0;i<nl;++i)
{
cout<<"\n ***** Linia
"<<i<<"\n";
for(j=0;j<nc;++j)
{
cout<<"Introduceti elementul
["<<i<<","<<j<<"] :
";cin>>mat[i][j];
}
}
}

int suma(int mat1[DIM][DIM], int
mat2[DIM][DIM],int nl,int nc,int
summat[DIM][DIM])
{
int i,j;
for(i=0;i<nl;++i)
{
for(j=0;j<nc;++j)

summat[i][j]=mat1[i][j]+mat2[i][j];
}
return 0;
}

void prod(int mat1[DIM][DIM], int
mat2[DIM][DIM], int m,int n,int
p,int prodmat[DIM][DIM])
{
int i,j,k;
for(i=0;i<m;++i)
for(j=0;j<n;++j)
{
prodmat[i][j]=0;
for(k=0;k<p;++k)

prodmat[i][j]=prodmat[i][j]+mat1[i]
[k]*mat2[k][j];
}
}

void afisare(int nl,int nc,int
mat[DIM][DIM])
{
int i,j;
for(i=0;i<nl;++i)
{
for(j=0;j<nc;++j)
cout<<mat[i][j]<<" ";
cout<<"\n";
}
}

void main()
{
int m1[DIM][DIM], m2[DIM][DIM],
sum[DIM][DIM];
int a,b,c,d,i,j; char selector;

cout<<"\nIntr. nr-le de linii si
coloane pentru prima matrice, m:
";cin>>a;
cout<<"
si n: ";cin>>b;
cout<<"\nIntr. nr-le de linii si
coloane pentru a doua matrice, m:
";cin>>c;
cout<<"
si n: ";cin>>d;
cout<<"\n\nPrima matrice:\n";
citire(a,b,m1);
cout<<"\n\nA doua matrice:\n";
citire(c,d,m2);
printf("Tastati:'s' pentru suma\n
'd' pentru diferenta\n 'p'
pentru produs\nAici: ");
cin>>selector;
switch (selector)
{
case's':
{
if ((a==c)&&(b==d))
{
suma(m1,m2,a,b,sum);
afisare(a,b,m1);
cout<<"\n +\n\n";
afisare(c,d,m2);
cout<<"\n=\n";

59
Laboratorul 13 Funcii
afisare(c,d,sum);
}
else
cout<<"Nu se poate efectua
suma deoarece numerele de linii si
coloane au nereguli";
break;
}
case'd':
{
cout<<"FACETI VOI DIFERENTA";
break;
}
case'p':
{
if(b==c)
{
prod(m1,m2,a,d,b,sum);
afisare(a,b,m1);
cout<<"\n*\n\n";
afisare(c,d,m2);
cout<<"\n=\n\n";
afisare(a,d,sum);
}
break;
}
default: cout<<"Nu s-a introdus
una din literele cerute !";
}
}

13.4.6 Calculul puterii i transpusei unei
sc un program pentru
13.4.6.1 Strategia de rezolvare:
n) numrul
* Program 14.
matrici ptrate
S se alctuia
ridicarea la putere a unei matrici ptratice i
pentru calculul transpusei acesteia.
n cazul matricilor ptratice A(n,
de linii i de coloane este egal cu ordinul
matricii. Transpusa se obine prin
interschimbarea elementelor din partea
dreapt a diagonalei principale cu cele
avnd indicii liniei i coloanei inversai.

/
Ridicarea la o putere a unei
matrici patratice. Calculul
transpusei unei matrici
patratice.*/
#define NMAX 20 // Numarul maxim de
linii sau coloane al matriciilor
#include <stdio.h>
#include <conio.h>

/*Functia citeste valorile
elementelor unei matrici */
void citire (float ta[NMAX][NMAX],
int ordin, char numev)
{
float temp;
printf("\nElementele matricii
%c\n",numev);
for (int i = 1,j; i<ordin+1;
i++)
for(j=1; j<ordin+1; j++)
{
printf("%c[%d,%d]=
",numev,i,j);
scanf ("%f",&temp);
ta[i][j]=temp;
}
}
/*Functia scrie valorile
elementelor unei matrici */
void scriere(float ta[NMAX][NMAX],
int ordin, char numev)
{
int trec;
printf("\nAfisarea valorii
elementelor pent atricea ru m
%c:\n",numev);
trec=1;
for(int i=1,j; i<ordin+1; i++)
for(j=1; j<ordin+1; j++)
{
printf("%c[%d,%d]= %f",numev,
i,j,ta[i][j]);
if(trec++==ordin)
{printf("\n"); trec=1;}
else printf("\t");
}
printf("\nApasa orice
tasta!");getch();
}

/*Functia efectueaza ridicarea la
patrar, a unei matrici */
void patrat(float
ta[NMAX][NMAX],float
tb[NMAX][NMAX], int ordin)
{
for (int i=1,j,k; i<ordin+1; i++)
for(k=1; k<ordin+1; k++)
{
tb[i][k]=0.0;
for(j=1; j<ordin+1; j++)

tb[i][k]+=ta[i][j]*ta[j][k];
}
}


60
Laboratorul 13 Funcii
/*Functia calculeaza transpusa unei
matrici*/
void transpusa(float
ta[NMAX][NMAX], int ordin)
{
float temp;
for(int i=1,j; i<ordin; i++)
for(j=i+1; j<ordin+1; j++)
{
temp=ta[i][j];
//interschimba valorile a doua
variabile de tip float
ta[i][j]=ta[j][i];
ta[j][i]=temp;
}
}

void main(void)
{ //Functia principala
float a[NMAX][NMAX],
b[NMAX][NMAX]; int n;
clrscr();
printf("Ordinul matricii A = ");
scanf("%d",&n);
citire(a,n,'A');
patrat(a,b,n);
puts("\nMatricea B=A*A: ");
scriere(b,n,'B');
transpusa(b,n);
puts("\nMatricea transpusa:");
scriere(b,n,'B');
}

Pentru ca elementele matricii s nu se
piard n timpul operaiei de transpunere,
se utilizeaz o variabil intermediar care
stocheaz valoarea uneia dintre variabilele
ce trebuiesc interschimbate:
temp=ta[i][j];
ta[i][j]=ta[j][i];
ta[j][i]=temp;
Dac am fi aplicat direct relaia:
ta[i][j]=ta[j][i];
valoarea variabilei ta[i][j] s-ar fi pierdut
fiind nlocuit cu cea a variabilei ta[j][i] i
astfel (valoarea variabilei ta[j][i] nefiind
modificat) matricea ar fi fost alterat,
devenind simetric fa de diagonala
principal.
n apelul funciei ptrat o scriere de tipul:
ptrat(a,a,n); nu ar fi dus la calculul
ptratului matricii a ci la alterarea valorilor
elementelor acesteia. n cazul irurilor,
aceeai variabil ir nu poate constitui
pentru o funcie i argument "valoare" i
argument "variabil".
13.5 Probleme propuse
1. S se realizeze un program care
implementeaz operaii cu vectori utiliznd
funcii (citire, scriere, produs scalar, sortare)
2. S se realizeze un program care
calculeaz valoarea unui polinom utiliznd
o funcie pentru calculul puterii


61
Laboratorul 14 Funcii - continuare
14. Funcii - continuare
14.1.1 Calculul derivatei unei funcii
Derivata unei funcii ntr-un punct
reprezint panta tangentei la graficul
funciei n punctul respectiv, adic:
f'(x) = lim
h0
f(x) - f(x-h)
h


//Calculul derivatei unei functii
#include <stdio.h>
#include <math.h>

double fd(double);
double
deriv(double,double,double(*)(doub
le));

void main()
{
double d,x,h;
printf("\nx= ");
scanf("%lf",&x);
for(h=0.1;h>=1e-06;h/=10)
{
d=deriv(x,h,fd);
printf("\nx=%f; h= %f; d=
%lf",x,h,d);
}
printf("\nx=%f; d=
%lf",x,-sin(x));
}

double deriv(double x,double
h,double (*f)(double))
{
double it;
it=((*f)(x)-(*f)(x-h))/h;
return it;
}

double fd(double x)
{
return cos(x);
}

14.1.2 Calculul integralei definite a unei
funcii prin metoda trapezelor
Relaia de calcul:
I =

a
b
f(x) dx =
= h

f(a)+f(b)
2
+f(a+h) +f(a+2h)+f(a+(n-1)h) ,
unde: h=
b-a
n
, n fiind numrul de diviziuni
f(x)
a x
1
x
2
x
n-1
b
x
h


14.1.2.1 Programul:
//Calculul integralei prin metoda
trapezelor
#include <stdio.h>
#include <math.h>

double fc(double);
double
ing(double,double,double(*)(double
));

void main()
{
double i,a,b;
printf("\nLimitele a,b: ");
scanf("%lf %lf",&a,&b);
i=ing(a,b,fc);
printf("\na=%f; b=%f; i=
%lf",a,b,i);
}

double ing(double x,double
y,double (*f)(double))
{
int n=120,k;
double it,h,S;
h=(y-x)/n;
for(k=1,S=0.0;k<n;k++)

62
Laboratorul 14 Funcii - continuare
S=S+(*f)(x+k*h); double fc(double x)
it=(h/2)*((*f)(x)+(*f)(y))+h*S; {
return it; return x*x;
} }

14.2 Funcii predefinite
14.2.1 Biblioteca matematic (math.h)
Este bibliotec care conine toate funciile matematice. Unele dintre cele mai utilizate sunt
prezentate n urmtorul tabel:
Nume Sintaxa Ce returneaza Exemplu
abs double abs (double x) valoarea
absolut a unui
numr real
#include <iostream.h>
#include <math.h>
void main(void)
{ int number = -1234;
cout<<"valoarea absoluta a
nr."<<number<<=<<abs(number));}
sqrt double sqrt (double x) radical
acos double acos (double
x)
arccosinus
asin double asin (double x) arcsinus
cos double cos (double x) cosinus (la toate
funciile
trigonometrice
argumentul e n
radiani)
#include <iostream.h>
#include <math.h>
void main(void)
{ double result, x = 0.5; result = cos(x);
cout<<"cos("<<x<<)=<<result);}
cosh double cosh (double
x)
cosinus
hiperbolic

exp double exp (double x) exponeniala
floor double floor (double
x)
rotunjire prin
lips

ceil double ceil (double x) rotunjire prin
adaus

fmod double fmod (double
x,double y)
restul mpririi
lui x la y
#include <stdio.h>
#include <math.h>
void main(void)
{ double x=5.0, y = 2.0; double result;
result=fmod(x,y);
cout<<"restul lui"<<x<<la<<y<<=<<result;}
hypot double hypot (double
x,double y)
ipotenuza
triunghiului de
catete x i y

ldexp double ldexp(double
x, int exp);
calculeaz
produsul dintre
primul parametru
i 2 la puterea
dat de cel de al
doilea parametru
#include <stdio.h>
#include <math.h>
int main(void)
{ double value; double x=7;
/* ldexp ridica 2 la puterea 3 apoi inmulteste
rezultatul cu 7*/
value = ldexp(x,3); cout<<"ldexp="<<value;}
log double log(double x); logaritm natural

63
Laboratorul 14 Funcii - continuare
Nume Sintaxa Ce returneaza Exemplu
log10 double log10(double
x);
logaritm zecimal
pow double pow(double x,
double y);
puterea unui
numr la alt
numr

pow1
0
double pow10(int p); puterea lui 10 la
un numr ntreg

sin double sin(double x); sinus
sinh double sinh(double x); sinus hiperbolic sinh(x) = (e
x
- e
-x
)/2
tan double tan(double x); tangenta
tanh double tanh(double
x);
tangenta
hiperbolic

14.2.2 Biblioteca string.h
Conine funcii pentru iruri de caractere
Nume Sintaxa Ce face Exemplu
strcat strcat(s1,
s2)
Concateneaz irul
s2 la sfritul irul s1
#include <string.h>
#include <stdio.h>

int main(void)
{
char destination[25];
char *blank = " ", *c = "C++",
*turbo = "Turbo";
strcpy(destination, turbo);
strcat(destination, blank);
strcat(destination, c);
printf("%s\n", destination);
}
strcmp strcmp(s1,
s2)
Comparare de iruri;
d valoarea 0 dac
s1=s2, negativ dac
s1<s2 i pozitiv dac
s1>s2.
#include <string.h>
#include <stdio.h>

int main(void)
{
char *buf1 = "aaa", *buf2 = "bbb",
*buf3 = "ccc";
int ptr;

ptr = strcmp(buf2, buf1);
if (ptr > 0)
printf("buffer 2 is greater than
buffer 1\n");
else
printf("buffer 2 is less than
buffer 1\n");

ptr = strcmp(buf2, buf3);
if (ptr > 0)
printf("buffer 2 is greater than
buffer 3\n");
else
printf("buffer 2 is less than
buffer 3\n");
}
strcpy strcpy(s1,
s2)
Copiaz irul s2 n s1
#include <stdio.h>
#include <string.h>

int main(void)
{

64
Laboratorul 14 Funcii - continuare
Nume Sintaxa Ce face Exemplu
char string[10]; char *str1 =
"abcdefghi";
strcpy(string, str1);
printf("%s\n", string);
}
strlen strlen(s1) Determina lungimea
sirului s1
#include <stdio.h>
#include <string.h>
int main(void)
{
char *string = "Borland
International";
printf("%d\n", strlen(string));
}
14.2.3 Biblioteca stdlib
Conine funciile de conversie; le vom prezenta n urmtorul tabel:
Nume Sintaxa Ce face Exemplu
atof double atof(const
char *s);
conversia unui ir la
real dubl precizie

atol long atol(const
char *s);
conversia unui ir la
ntreg long
#include <iostream.h>
#include<stdlib.h>
void main (void) { long l;
char* str=9876;
l=atol(str);
cout<<atol(<<str<<)=<<l
;}
atoi int atoi(const
char *s);
conversia unui ir la
ntreg simplu

itoa char* itoa(int
value;char*
string;int
radix);
conversia unui ntreg
la ir de caractere cu
lungimea dat de al
treilea parametru
#include <stdlib.h>
#include <iostream.h>
void main(void) { int
n=123; char str[5];
itoa(n,str,4);
cout<<itoa(<<n<<)=<<str
;}
ltoa char* ltoa(long
value;char*
string;int
radix);
conversia unui ntreg
long la ir de caractere
cu lungimea dat de al
treilea parametru

ultoa char*
ultoa(unsigned
long value;char*
string;int
radix);
conversia unui ntreg
unsigned long la ir de
caractere cu lungimea
dat de al treilea
parametru

ftoa char* ftoa(float
value;char*
string;int
radix);
conversia unui real
dubl precizie la ir de
caractere cu lungimea
dat de al treilea
parametru

rand int rand(void) genereaz un numr
aleator cuprins ntre 0
i 10000
#include <stdlib.h>
#include <iostream.h>
void main(void) { int i;
cout<<zece nr aleatoare de
la 0 la 99; for (i=0;
i<10; i++)
cout<<rand()%100<<\n;}
random int rand(int num) genereaz un numr


65
Laboratorul 14 Funcii - continuare
Nume Sintaxa Ce face Exemplu
aleator cuprins ntre 0
i num-1
system void system(char*
string)
lanseaz n execuie o
comand DOS
#include <stdlib.h>
#include <iostream.h>
void main(void) {
cout<<Continutul
directorului curent:\n;
system("dir");}
14.3 Biblioteci de funcii scrise de ctre utilizator
n cazul folosirii mai frecvente a anumitor funcii, acestea pot fi scrise grupat ntr-un fiier
bibliotec, i apelate apoi ori de cte ori este nevoie.
Programul urmtor apeleaz funcia suma, care se gsete ntr-un fiier header User_Lib.H
//Biblioteci de functii
#include "USER_LIB.H"
void main()
{
int a=2,b=3,c;
//functia suma se gaseste in fisierul antet USER_LIB.H
c=suma(a,b);
}

Biblioteca de funcii este un fiier header/antet (cu extensia h) scris de ctre utilizator, cruia
i pot fi adugate funcii dup nevoie.
#ifndef _USER_LIB_
#define _USER_LIB_

int suma(int x,int y)
{return x+y;}

#endif

14.4 Exemple
14.4.1 Exemplul 1: Funcii din biblioteca
matematic
//Functii din biblioteca matematica
#include<math.h>
#include<iostream.h>
#include<stdio.h>

main()
{
float a,b,c,d;
cout<<"introduceti a: ";cin>>a;
cout<<"introduceti b: ";cin>>b;
cout<<"\nvaloarea lui "<<a<<" la
puterea "<<b<<" este: "<<pow(a,b);
cout<<"\nvaloarea lui "<<10<<" la
puterea "<<b<<" este: "<<pow10(b);
cout<<"\nvaloarea log nat din
"<<b<<" este: "<<log(b);
cout<<"\nvaloarea log zecimal din
"<<b<<" este: "<<log10(b);
cout<<"\nvaloarea lui e la
puterea "<<b<<" este: "<<exp(b);
cout<<"\nvaloarea lui "<<a<<"*2
la "<<b<<" e: "<<ldexp(a,b);
cout<<"\nvaloarea absoluta a nr
real "<<b<<" este: "<<fabs(b);
cout<<"\nvaloarea partii intregi
a nr real "<<b<<" este:
"<<floor(b);

66
Laboratorul 14 Funcii - continuare
} cout<<str1=<<str1<<
str2=<<str2<<\n;
difer=strcmp(str1, str2);
if (difer == 0)
14.4.2 Operaii cu iruri de caractere
cout<<Siruri echivalente!\n;
#include <iostream.h>
else if (difer>0)
#include <string.h>
cout<<str1<< mai mare
(lexicografic) dect
<<str2<<\n;
void main()
{
char sir1[] = abcd, sir2[] =
abcde, sir3 = "abcdef, sir4 =
"de;
else
cout<<str1<< mai mic
(lexicografic) dect
<<str2<<\n;
cout<<strcmp(sir1, sir2)<<\n; //
afisare:-101
cout<<str1=<<str1<<\n;
cout<<str3=<<str3<<\n;
// e = 101, a = 97, d = 100
//0 - e = -101
strcpy (str3, str1);
cout<<str1=<<str1<<\n;
cout<<strcmp(sir2, sir1)<<\n;
//afisare: 101
cout<<str3=<<str3<<\n;
cout<<strcmp(sir1, "")<< ';
//compararea variabilei sir1 cu
constanta sir vid
strcat (str3, str1);
cout<<str1=<<str1<<\n;
cout<<str3=<<str3<<\n;
char str1[20]=hello;
}
char str2[20]=goodbye;

char str3[20];

int difer, lungime;


67
Laboratorul 15 Funcii recursive
15. Funcii recursive
O funcie este numit funcie recursiv dac ea se autoapeleaz, fie direct (n definiia ei se
face apel la ea nsi), fie indirect (prin apelul altor funcii).

n cadrul acestui capitol vom aborda ambele tipuri de recursivitate:
recursivitate direct
recursivitate indirect.
V reamintim cteva observaii fundamentale de care e bine s inei cont:
a) Studiai felul n care apare recursivitatea ntr-un program i dac sunt i alte moduri de
elaborare a programului. Dac sunt, atunci verificai dac scrierea lor este mai eficient i
dac n cele din urm optai pentru recursivitate.
b) Punei n eviden modul n care o problem se apeleaz pe ea nsi.
c) Fii ateni la modul n care definii parametrii funciilor recursive, variabilele interne i
globale. Unele definiii sunt fundamentale pentru execuia programului. Spre exemplu
variabilele folosite pentru a parcurge valorile permise ale componentelor unei soluii trebuie
s fie locale funciei, altfel nu se genereaz corect soluia. Unele definiii bine alese pot
optimiza destul de mult spaiul alocat pe stiv i timpul de execuie.
d) Pentru corectitudinea recursivitii realizate fii ateni la modul n care se pstreaz
valorile datelor la ieirea dintr-un apel recursiv. Avei grij ca dup ieirea din apelul recursiv
al unei funcii s refacei datele modificate pentru noul apel.
e) Avei grij la stocarea datelor intermediare. Dac este necesar o determinare a unui
optim, se va lucra cu dou seturi de date: unul pentru stocarea optimului i unul pentru
generarea soluiei curente. n acest caz tiprirea soluiei nu se face n interiorul recursivitii,
ci dup terminarea tuturor apelurilor.
f) Avei grij s punei corect condiiile de ieire din recursivitate. Fr acestea un program nu
se va opri niciodat.
g) Facei pregtirile necesare i stabilii valorile parametrilor pentru primul apel.
Atragem atenia c orice nerespectare a uneia dintre observaiile enumerate mai sus poate
determina erori.
15.1 Recursivitate direct
15.1.1 Calculul permutrilor,
aranjamentelor i combinrilor:
P
n
= n! ; A
n
m
=
n!
(n-m)!
; C
n
m
=
n!
m!(n-m)!

Programul:
//Analiza combinatorica
#include<stdio.h>

int fact (int n)
{
if (n==0) return 1.0;
else return n*fact(n-1);
}

void main()
int n,m,p,A,C;
printf("\nintroduceti n=");
scanf("%d",&n);
printf("introduceti m=");
scanf("%d",&m);

p=fact(n);
A=fact(n)/fact(n-m);
C=fact(n)/(fact(m)*fact(n-m));
printf ("%d! =%d",n,p);
printf ("\nA(%d,%d) = %d",n,m,A);
printf ("\nC(%d,%d) = %d",n,m,C);
}

{

68
Laboratorul 15 Funcii recursive
15.1.2 Funcia recursiv Ackerman for(i=0;i<DIM;i++)
for(j=0;j<DIM;j++)
S se calculeze matricea A(LxL), L10
unde:
if(i>j) a[i][j]=ack(i,j)*ack(i,j);
else
ACK
2
(i,j), dac i>j,
a(i,j)= 1, dac i=j,
sqrt(ACK(j,i)), dac i<j,
if(i==j) a[i][j]=1;
else
a[i][j]=sqrt(ack(j,i));
scrie(a);
unde funcia ACK(m,n) este o funcie
recursiv Ackerman definit pentru m0 i
n0 prin:
getch();
}
//Definirea functiilor
double ack(int m, int n)
ACK(0,n) = n+1;
{
ACK(m,0) = ACK(m-1,1);
if(m==0) return n+1;
ACK(m,n) = ACK(m-1, ACK(m,n-1); else
if(n==0) return ack(m-1,1);
else return ack(m-1,ack(m,n-1));
15.1.2.1 Programul:
}
//Functii recursive - Ackerman

#include<conio.h>
void scrie(double mat[DIM][DIM])
#include<stdio.h>
{
#include<math.h>
int i,j;
#define DIM 4
for(i=0;i<DIM;i++)

{
double ack(int m, int n);//prototipul
void scrie(double
mat[DIM][DIM]);//prototipul
printf("\n");
for(j=0;j<DIM;j++)
printf("A[%d,%d]=
%5.2f;",i,j,mat[i][j]);
void main()
}
{
}
double a[DIM][DIM]; int i,j;
clrscr();

15.1.3 CMMDC
S se se scrie un program care citete doi ntregi pozitivi m i n, de tip long, calculeaz i
afieaz pe cel mai mare divizor comun al lor. Programul va folosi o funcie care are ca
parametri doi ntregi m i n de tip long i care calculeaz i returneaz cel mai mare divizor
comun al lor.
Notm cu: (m,n) cel mai mare divizor comun al numerelor m i n. Calculul celui mai mare
divizor comun a dou numere se poate realiza recursiv astfel:
(m,n) = m dac n = 0;
(m,n) = n dac m = 0;
(m,n) = (n,m%n) dac att m, ct i n sunt diferii de zero i m > n (prin m%n s-a notat
restul mpririi lui m la n).

#include <stdio.h> if(m>n)
return cmmdc(n, m%n);
#include <stdlib.h>
else
return cmmdc(m, n%m);
//FUNCTIA
}
long cmmdc(long m, long n) /*
calculeaza si returneaza pe cel
mai mare divizor comun al
numerelor m si n */

void main() /* citeste pe m si n
de tip long, calculeaza si
afiseaza (m,n) */
{
{
if(m==0) return n;
long m,n;
else
printf("\nValorile lui m si n:
");
if(n==0) return m;
else

69
Laboratorul 15 Funcii recursive
if(scanf("%ld %ld", &m, &n)!=2 ||
m<0 || n<0)
{ printf("nu s-au tastat doi
intregi pozitivi\n");
exit(1);
}

printf("m=%ld\tn=%ld\t(m,n)=%ld\n"
,m,n,cmmdc(m,n));
}

15.1.4 Generarea tuturor permutrilor unei mulimi
n prima variant vom defini funcia recursiv permutare. Aceasta va genera permutrile
verificnd la fiecare poziie dac elementul curent a fost deja selectat i nu. Dac nu este
selectat, el poate fi folosit pentru aceast poziie. Ieirea din recursivitate se va face n
momentul cnd s-au generat toate cele n componente.
#include<stdio.h>
int k,n,poz[20],p[20];
void permutare(int i);

void main ()
{
printf("Numarul de elemente: ");
scanf("%d",&n);
permutare(1);
}

void permutare(int i)
{
int j;
for(j=1;j<=n;j++)
if(poz[j]==0)
{
p[i]=j;
poz[j]=1;/* selectam elementul
j pe pozitia i */
if(i==n)/*Daca s-au generat
toate pozitiile se afiseaza
solutia*/
{
for(k=1;k<=n;k++)
printf("%d",p[k]);
printf("\t");
}
else permutare(i+1);
poz[j]=0; /* deselectam
elementul j */
}
}

Varianta a doua va defini funcia recursiv permuta de generare a permutrilor, care face
generarea tuturor permutrilor prin interschimbarea elementului de pe poziia curent k, pe
rnd cu elementele din poziiile anterioare, de la 1 la k-1. Cnd se ajunge la prima poziie se
tiprete permutarea generat.
//Generarea tuturor permutarilor
unei multimi.
#include <stdio.h>
int a[100] ;
int n, k, i ;

void tipareste(int n)
{
int i;
for (i=1;i<=n;i++)
printf ("%d ", a[i]);
putchar('\n');
}

void permuta(int k)
{
int i;
if (k==1) tipareste (n);
else
{
permuta(k-1) ;
for (i=1;i<k;i++)
{
a[i] ^=a[k] ^=a[i] ^=a[k] ;
permuta(k-1);
a[i] ^=a[k] ^=a[ i] ^=a[ k] ;
}
}
}

void main()
{
printf("Introduceti n :" ) ;
scanf(" %d" , &n) ;
for(i=1; i<=n; i++) a[i] =i;
permuta(n);
}


70
Laboratorul 15 Funcii recursive
15.1.5 Problema reginelor
S se afieze toate posibilitile de aranjare a n regine pe o tabl de ah de dimensiuni n x n
astfel nct ele s nu se atace.
Pentru a simplifica determinarea configuraiilor corecte vom folosi pentru fiecare linie o
regin. Coloanele pentru fiecare regin se vor stoca n vectorul r. Generarea reginelor se
face cu ajutorul funciei recursive regina care va avea ca parametru numrul liniei.
Pentru a accepta poziia curent se verific dac regina aezat acum se atac pe coloan
sau pe diagonal cu reginele plasate anterior.
Pentru aceasta vom defini funcia ataca pentru a verifica dac la adugarea reginei de pe
linia i aceasta se atac cu una din reginele 1, 2,..., i-1. Ea va returna valoarea 0, dac regina
i nu atac nici o regin i valoarea 1 n caz contrar. Dou regine se atac dac sunt pe
aceeai coloan sau pe aceeai diagonal. A doua condiie revine la a verifica dac diferena
dintre liniile pe care sunt situate reginele este egal cu diferena dintre coloanele acestora, n
valoare absolut.
Pentru afiarea unei table de ah i a configuraiei reginelor am folosit funcia scrie. Pentru
numrarea soluiilor generate am folosit variabila nr.

//Problema reginelor
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
int r[20],n,nr;

int ataca(int);
void regina(int);
void scrie(void);

void main()
{
textmode(C80); textcolor(YELLOW);
printf("\nNumarul de regine: ");
scanf("%d",&n);
regina(1);
}

void regina(int i)
{
int j;
for(j=1;j<=n;j++)
{
r[i]=j;
if(!ataca(i))
if(i<n) regina(i+1);
else scrie();
}
}

int ataca(int i)
{
int j;
for(j=1;j<=i-1;j++)
if(r[i]==r[j]||abs(r[i]-
r[j])==abs(i-j)) return 1;
return 0;
}

void scrie()
{
int i,j;
textbackground(BLACK); clrscr();
printf("Solutia %d:\n",++nr);
for(i=1;i<=n;i++)
{
printf("\t");
for(j=1;j<=n;j++)
{
if(i%2==j%2)
textbackground(WHITE) ;
else
textbackground(BLACK);
if(r[i]==j) cprintf("R");
else cprintf(" ");
}
cprintf("\n\r");
}
printf("Ptr continuare apasati
orice tasta!");
getch();
}

15.1.6 Problema rucsacului.
O persoan are un rucsac cu care poate transporta o greutate maxim G. Persoana are la
dispoziie n obiecte diferite i cunoate pentru fiecare obiect greutatea i ctigul care se
obine n urma transportului su la destinaie. Se cere s se precizeze care obiecte trebuie s
le transporte persoana astfel nct ctigul s fie maxim.

71
Laboratorul 15 Funcii recursive
Varianta recursiv a problemei va utiliza funcia rucsac. Aceasta va calcula pentru fiecare
obiect dac selecia sa duce la depirea greutii maxime admisibile. Dac nu, se verific
dac actuala configuraie are o valoare maxim. n caz afirmativ se stocheaz obiectele care
dau pentru selecie o valoare maxim. Tiprirea obiectelor care au mpreun valoarea
maxim se va face la ieirea din recursivitate.

//Problema rucsacului
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#define DIM 10

float
gx,vx,gmax,vmax,g[DIM],v[DIM];
int s[DIM],smax[DIM],n;

void rucsac(int i) //i - nr curent
max de obiecte
{
int j,k;
for(j=0;j<=i;j++)//j nr de
obiecte de tipul curent
/* Daca nu se depaseste greutatea
maxima obiectul este selectat */
if(gx+j*g[i]<=gmax)
{
/* Se actualizeaza greutatea si
valoarea */
s[i]=j; gx+=j*g[i];
vx+=j*v[i];
/* Daca valoarea selectiei
actuale este mai mare dect
maximul de pana acum se
actualizeaza selectia de maxim */
if(vx>vmax)
{
vmax=vx;
printf("\nvmax=%4.1f:
",vmax);
for(k=1;k<=i;k++)
{smax[k]=s[k];

printf("%2d*%4.2f",smax[k],v[k]);
}
for(k=i+1;k<=n;k++)
{smax[k]=0;

printf("%2d*%4.2f",smax[k],v[k]);
}
}
/*Apelul recursiv pentru trecerea
la urmatorul obiect*/
if(i<n) rucsac(i+1);
/*Refacerea starii dupa iesirea
din recursivitate*/
gx-=j*g[i] ; vx-=j*v[i] ;
}
}

void main()
{
int i; FILE *f;
clrscr();
/* Introducerea datelor */
f=fopen("rucsac.dat","r");
fscanf(f,"%d",&n);
fscanf(f,"%g",&gmax);
for(i=1;i<=n;i++)
fscanf(f,"%g %g",&g[i],&v[i]);
fclose(f);
gx=vx=0; vmax=-1;
/* Apelul recursiv */
rucsac(1);
/* Tiparirea solutiei maxime
obtinute */
printf("\nValoarea maxima: %g
\nGreut max: %g\nObiectele:",vmax,
gmax);
for(i=1;i<=n;i++)
if(smax[i]==1)
printf("%d, ",i);
}

Observai modul n care s-a modificat programul atunci cnd se cere o configuraie de optim:
1. n interiorul funciei recursive se face doar verificarea de optim i stocarea n cazul
ndeplinirii condiiilor de optim a datelor intermediare ntr-un set de date separat.
2. tiprirea soluiei s-a fcut la ieirea din apelul recursiv i nu n interior.
15.1.7 Prjituri
Fiind date n tipuri de prjituri cu costul c[1], c[2], ..., c[n], s se determine toate modurile
posibile de a cumpra m prjituri care s nu depeasc suma s. Se consider c pot fi
cumprate oricte prjituri de un anumit tip.
Notaii fcute:
x, stocheaz cte prjituri s-au cumprat din fiecare tip;

72
Laboratorul 15 Funcii recursive
suma, valoarea prjiturilor cumprate n momentul de fa;
nr, numrul de prjituri cumprate n momentul de fa.
n procedura recursiv rec numrul maxim de prjituri care se pot cumpra este minimul
dintre numrul de prjituri rmase de cumprat, m, i numrul posibil de cumprat cu suma
rmas din prjiturile de tipul i, adic (s-suma)/c[i]. Datele se citesc din fiierul "prajitur.in" iar
soluiile se scriu n fiierul "prajitur.out". Programul a fost realizat n C++:
//Prajituri
#include<iostream.h>
#include<fstream.h>

long x[100] ,c[100];
short k,i,j,n,m,nr;
unsigned nr_sol;
unsigned long s,suma;
fstream f;

void rec(int i)
{
int max,j;
max=(s-suma)/c[i] ;
if(max>m-nr) max=m-nr;
for(j=0;j<=max;j++)
{
suma+=c[i]*j;
nr+=j;
x[i]=j ;
if(suma<=s)
if(nr<m&&i<n) rec(i+1);
else if(nr==m)
{ //Tip ?rire
nr_sol++;
f<<"Suma totala:
"<<suma<<endl;
for(k=1;k<=i;k++)
if(x[k]>0) f<<"prajitura
"<<k<<" de "<<x[ k]<<" ori\n";
f<<"-----------------------
--------------------\n";
}
nr-=j;
suma-=c[i]*j;
}
}

void main()
{
f.open("prajitur.in",ios::in);
f>>n; // Numarul de tipuri de
prajituri:
f>>s; // suma data
f>>m; // numarul de prajituri
pentru cumparat
for(i=1;i<=n;i++)
f>>c[i]; //costul fiecarei
prajituri
f.close();
// Se deschide fisierul
"prajitur.out" pentru scrierea
solutiilor
f.open("prajitur.out",ios::out);
nr_sol=0;
rec(1);
f<<"Numarul de solutii: "<<nr_sol
;
f.close();
}

15.2 Recursivitate indirect
15.2.1 N din 4
Se tie c din numrul 4 se obine orice numr natural n scris n baza zece prin aplicarea
urmtoarelor operaii:
se scrie la sfrit cifra 4;
se adaug cifra 0;
se mparte la doi dac numrul este par.
Se cere s se scrie un program care produce un ir de numere conform regulilor precedente
n care primul numr este 4 iar ultimul este n.
Se pleac de la numrul n i se genereaz operaiile inverse celor menionate. Programul
este format din 2 funcii ntre care se face recursivitatea indirect:
1. proc2 -se nmulete numrul cu 2. Dac ultima cifr este 0 sau 4 se apeleaz proc0,
altfel se apeleaz proc2.

73
Laboratorul 15 Funcii recursive
2. proc0 -se terge ultima cifr dac este 0 sau 4. Apelul recursiv este asemntor cu
proc0: dac ultima cifr este 0 sau 4 se apeleaz proc0, altfel se apeleaz proc2.
#include<conio.h>
#include<stdio.h>
int n,a[100]; /*numarul initial
si sirul de transformari*/

void proc2(int k);/*proceduri de
transformare*/
void procO(int k);

void proc2(int k) /* se inmulteste
numarul cu 2 */
{
int x;
if(k!=4)
{
a[++a[0]]=k*=2;
x=k%10;
if(x==0||x==4) procO(k);
else proc2(k);
}
}
void procO(int k) /* se elimina
ultima cifra */
{
int x;
if(k!=4)
{
a[++a[0]]=k/=10;
x=k%10;
if(x==0||x==4) procO(k);
else proc2(k);
}
}

void main(void)
{
int p;
printf("\nNumarul care se obtine:
") ; scanf("%d",&n) ;
a[1]=n;a[0]=1;
if(n!=4)
{
p=n%10;
if(p==0||p==4 ) procO(n);
else proc2(n);
}
printf("Sirul de numere este: ");
for(p=a[0];p>=1;p--) printf(" %d
",a[p]);
getch();
}

15.3 NTREBRI I EXERCIII
15.3.1 Chestiuni teoretice
1. Asemnri ntre transferul parametrilor unei funcii prin pointeri i prin referin.
2. Caracteristicile modului de transfer a parametrilor unei funcii prin pointeri.
3. Caracteristicile variabilelor globale.
4. Caracteristicile variabilelor locale.
5. Care este diferena ntre antetul unei funcii i prototipul acesteia ?
6. Care sunt modurile de alocare a memoriei ?
7. Care sunt modurile de transfer a parametrilor unei funcii ?
8. Care sunt operatorii din C++ care permit alocarea/dezalocarea dinamic a memoriei ?
9. Ce clase de memorare cunoastei ?
10. Ce este domeniul de vizibilitate a unei variabile ?
11. Ce este prototipul unei funcii ?
12. Ce este timpul de via a unei variabile ?
13. Ce loc ocup declaraiile variabilelor locale n corpul unei funcii ?
14. Ce reprezint antetul unei funcii ?
15. Ce rol are declararea funciilor ?
16. Ce se indic n specificatorul de format al funciei printf ?
17. Ce sunt funciile cu numr variabil de parametri ? Exemple.
18. Ce sunt funciile cu parametri implicii ?
19. Ce sunt pointerii ctre funcii ?

74
Laboratorul 15 Funcii recursive
20. Ce sunt variabilele referin ?
21. Cine determin timpul de via i domeniul de vizibilitate ale unei variabile ?
22. Comparaie ntre declararea i definirea funciilor.
23. Diferene ntre modurile de transfer a parametrilor prin valoare i prin referin.
24. Diferene ntre modurile de transfer a parametrilor unei funcii prin pointeri i prin referin.
25. Din apelul funciei printf se poate omite specificatorul de format ?
26. Din ce este format o funcie ?
27. n ce zon de memorie se rezerv spaiu pentru variabilele globale ?
28. O funcie poate fi declarat n corpul altei funcii ?
29. O funcie poate fi definit n corpul unei alte funcii ?
30. Parametrii formali ai unei funcii sunt variabile locale sau globale ?
31. Transferul parametrilor prin valoare.
32. Ce rol au parametrii formali ai unei funcii ?
15.3.2 Chesiuni practice
1. S se scrie un program care citete cte dou numere, pn la ntlnirea perechii de
numere 0, 0 i afieaz, de fiecare dat, cel mai mare divizor comun al acestora, folosind
o funcie care l calculeaz.
2. Se introduce de la tastatura un numr ntreg. S se afieze toi divizorii numrului
introdus. Se va folosi o funcie de calcul a celui mai mare divizor comun a 2 numere.
3. Secvenele urmtoare sunt corecte din punct de vedere sintactic ? Dac nu, identificai
sursele erorilor.
void a(int x, y) {cout<<"x="<<x<<" y="<<y<<'\n'; }
void main( ) { int b=9; a(6, 7); }
void main( ) { int x=8; double y=f(x); cout<<"y="<<y<<'\n';}
int f(int z) {return z+z*z;}
4. Scriei o funcie gseste_cifra care returneaz valoarea cifrei aflate pe poziia k n cadrul
numrului n, ncepnd de la dreapta (n i k vor fi argumentele funciei).
5. Implementai propriile versiuni ale funciile de lucru cu iruri de caractere (din paragraful
4.4).
6. S se calculeze valoarea funciei g, cu o eroare EPS (a, b, EPS citite de la tastatur):
g(x)=

+ +
b
a
x x ) 1 (
2
*ln|x+a|dx +

+
b
a
x b b arctg x )) ( ( * dx
7. Implementai funcii iterative i recursive pentru calculul valorilor polinoamelor Hermite
Hn(y), tiind c: H0(y)=1, H1(y)=2y, Hn(x)=2yHn-1(y)-2Hn-2(y) dac n>1. Comparai
timpul de execuie al celor dou funcii.
8. S se scrie un program care genereaz toate numerele palindrom, mai mici dect o
valoare dat, LIM. Un numr palindrom are cifrele simetrice egale (prima cu ultima, a
doua cu penultima, etc). Se va folosi o funcie care testeaz dac un numr este
palindrom.
9. Fie matricea C (NXN), N<=10, ale crei elemente sunt date de relaia:
j! + , dac i<j

=
j
k
kx
0
) sin(
C
i,j
= x
i
, dac i=j
i! + , dac i>j

=0
) cos(
k
kx i
, unde x[0,1], x introdus de la
tastatur
a) S se implementeze urmtoarele funcii: de calcul a elementelor matricii; de afiare a
matricii; de calcul i de afiare a procentului elementelor negative de pe coloanele
impare (de indice 1, 3, etc).
b) S se calculeze i s se afieze matricea B, unde: B = C - C
2
+ C
3
- C
4
+ C
5
.

75
Laboratorul 15 Funcii recursive
10. S se creeze o bibliotec de funcii pentru lucrul cu matrici, care s conin funciile
utilizate frecvent (citirea elementelor, afisarea matricii, adunare a dou matrici, etc). S se
foloseasc aceast bibliotec.
11. S se creeze o bibliotec de funcii pentru lucrul cu vectori, care s conin funciile
utilizate frecvent. S se foloseasc aceast bibliotec.

76
Laboratorul 16 Tipuri de date definite de utilizator
16. Tipuri de date definite de utilizator
16.1 Structuri
Structurile grupeaz date de tipuri diferite, constituind definiii ale unor noi tipuri de date.
Componentele unei structuri se numesc membrii (cmpurile) structurii. La declararea unei
structuri se pot preciza tipurile, identificatorii elementelor componente i numele structurii.
Forma general de declarare a unei structuri:
struct identificator_tip_structura
{
lista_de_declaratii_membri;
} lista_identificatori_variabile;
n care:
struct este un cuvnt cheie (obligatoriu)
identificator_tip_structura reprezint numele noului tip (poate lipsi)
lista_de_declaratii_membri este o list n care apar tipurile i identificatorii
membrilor structurii
lista_identificatori_variabile este o list cu identificatorii variabilelor de tipul
declarat.

Membrii unei structuri pot fi de orice tip, cu excepia tipului structur care se declar.

16.1.1 Punctul mediu
S se gseasc coordonatele punctului
mediu situat la jumtatea distanei dintre
dou puncte date.
//Structuri
#include <iostream.h>

typedef struct{float x,y;} punct2D;

punct2D punct_mediu(punct2D p1,
punct2D p2)
{
punct2D pm, ptemp;
pm.x=(p1.x+p2.x)/2;
pm.y=(p1.y+p2.y)/2;
ptemp=p1; p1=p2; p2=ptemp;
return pm;
}

void main ()
{
punct2D a={0,3}, b={6,4}, c;
c=punct_mediu(a,b);
cout<<"\na("<<a.x<<","<<a.y<<")";
cout<<"\nb("<<b.x<<","<<b.y<<")";
cout<<"\nc("<<c.x<<","<<c.y<<")";
}
16.1.2 Oglinda
S se gseasc imaginea n oglind a unui
punct A(x,y) fa de axa Oy
//Structuri-pointer
#include <iostream.h>
struct punct2D {float x,y;};

void oglinda_oy(struct punct2D *pct)
{
//in cazul utilizarii pointerilor
catre structuri accesarea campurilor
structurii se face cu ajutorul
operatorului "->"
pct->x=-pct->x
}

void main ()
{
struct punct2D A={5,3};
cout<<"\nPunctul original A are
x="<<A.x<<" si y= "<<A.y;
oglinda_oy(&A);
cout<<"\nPunctul oglindit A' are
x="<<A.x<<" si y=" <<A.y;
}

77
Laboratorul 16 Tipuri de date definite de utilizator
16.1.3 Modulul unui numr complex
S se calculeze modulul unui numr
complex folosind o funcie
//Functie cu structuri
#include<math.h>
#include<stdio.h>
#include<conio.h>

typedef struct{
double real;
double imag;
} COMPLEX;

double modul(COMPLEX *);//prototipul

void main()
{
COMPLEX nr;
clrscr();
while(scanf("%lf
%lf",&nr.real,&nr.imag)==2)
printf("\nreal=%.2f imag=%.2f
modul=%.2f",nr.real,nr.imag,modul(&nr)
);
getch();
}

double modul(COMPLEX *z)//definitie
{ return sqrt(z->real*z->real+z-
>imag*z->imag);}
16.1.4 Modul i argument
S se scrie un program care citete numere
complexe i Ie afieaz mpreun cu
modulul i argumentul lor.

Programul folosete o funcie care
calculeaz i returneaz modulul unui
numr complex.
Dac: z = x + iy atunci modulul numrului
complex este rdcina ptrat din: x*x + y*y
Programul mai folosete i o funcie care
calculeaz i returneaz argumentul unui
numr complex. Dac: z = x + iy atunci arg
z se calculeaz astfel:
a. Dac x = y = 0, arg z = 0.
b. Dac y = 0 i x 0, atunci
dac x > 0, arg z =0; altfel arg z = =
3.14.
c. Dac x = 0 i y 0, atunci
dac y > 0, arg z = /2; altfel arg z =
3*pi/2.
d. Dac x i y 0, atunci fie:
a = arctg(y/x)
d1. Dac x > 0 i y > 0, atunci arg z = a.
d2. Dac x > 0 i y < 0, atunci arg z = 2* +
a.
d3. Dac x < 0 i y > 0, atunci arg z = + a.
d4. Dac x < 0 i y < 0, atunci arg z = + a.
Se observ c pentru x < 0 i y 0:
arg z = pi + a;
altfel, dac x > 0 i y < 0, atunci arg z = 2*
+ a

//PROGRAMUL BX3
#include <stdio.h>
#include <math.h>

typedef struct {
double x;
double y; } COMPLEX;

//FUNCTIA BX1
double d_modul(COMPLEX *z)
/* calculeaza si returneaza
modulul numarului complex z */
{ return sqrt(z->x*z->x+z->y*z->y)
;}

//FUNCTIA BX2
/* functia foloseste constanta
M_PI=3.1415... definita in headerul
math.h */
double d_arg(COMPLEX *z)
{
double a;
if(z->x==0 && z->y==0) return 0.0;
if(z->y==0)
if(z->x>0) return 0.0;
else /*y=0 si x<0 */ return M_PI;
if(z->x==0)
if(z->y>0) return M_PI/2;
else /*x=0 si y<0*/ return
(3*M_PI)/2;
/*x!=0 si y!=0 */ a=atan(z->y/z-
>x);
if(z->x<0) /*x<0 si y!=0*/ return
a+M_PI;
else /*x>0*/
if(z->y<0) /*x>0 si y<0*/ return
2*M_PI+a;
else /*x>0 si y>0*/ return a;
}

void main() /* citeste numere
complexe si le afiseaza impreuna cu
modulul si argumentul corespunzator
*/
{
COMPLEX complex;

78
Laboratorul 16 Tipuri de date definite de utilizator
printf("Introduceti elementele nr
complex: ");
while(scanf("%lf %lf", &complex.x,
&complex.y) == 2)
{
printf("a+ib= %g + i*(%g)\n",
complex.x, complex.y);
printf("modul=%g\targ=%g\n",
d_modul(&complex),d_arg(&complex));
}
}

16.1.5 Elevi
S se citeasc (cu ajutorul unei funcii de
citire) urmtoarele informaii despre elevii
participani la un concurs de admitere:
nume, numrul de nscriere i cele trei note
obinute. S se afieze, printr-o funcie,
informaiile citite. S se afieze o list cu
elevii participani la concurs, ordonai
alfabetic, notele i media obinut (funcie
de ordonare, funcie de calculare a mediei).
S se afieze lista elevilor nscrii la
concurs, n ordinea descresctoare a
mediilor.

#include <stdio.h>
#include <string.h>
#include <iostream.h>
#include <conio.h>

#define DIM_PAG 24 // dimensiunea
paginii de afisare
#define FALSE 0
#define TRUE 1

struct elev{
char nume[20];int nr_matr;int
note[3];
}; //definirea tipului elev

void cit_elevi(elev *a, int n)
{
for (int i=0; i<n; i++){
cout<<"Nume elev:"; cin>>(a+i)-
>nume; //sau cin>>(*(a+i)).nume;
cout<<"Nr. inscriere:"; cin>>(a+i)-
>nr_matr;
for (int j=0; j<3; j++){
do{
cout<<"Nota :"<<(j+1)<<" =";
cin>>(a+i)->note[j];
if((a+i)->note[j]<0 || (a+i)-
>note[j]>10)
cout<<"Nota
incorecta!....Repeta!\n";
}while ((a+i)->note[j]<0 || (a+i)-
>note[j]>10);
}
}
}


void ord_medii(elev *a, int n)
{
int gata =FALSE;int i;double med1,
med2;elev aux;
while (!gata){
gata=TRUE;
for(i=0; i<=n-2; i++){
med1=0;med2=0;
for (int j=0; j<3; j++){
med1+=(a+i)->note[j];
med2+=(a+i+1)->note[j];// calculul
mediilor pentru elementele vecine
}
med1/=3; med2/=3;
if (med1<med2){
aux=*(a+i);
*(a+i)=*(a+i+1);*(a+i+1)=aux;
gata=FALSE;}
}
}
}
void ord_alf(elev *a, int n)
{
int gata =FALSE; int i; double med1,
med2; elev aux;
while(!gata){
gata=TRUE;
for (i=0; i<=n-2; i++){
if(strcmp((a+i)->nume,(a+i+1)->nume)
>0)
{aux=*(a+i);
*(a+i)=*(a+i+1);*(a+i+1)=aux;
gata=FALSE;}
}
}
}
//void cit_elevi(elev *a, int n); //
functie implementata anterior
void antet_afis(const char *s)
{printf("%s\n", s);
}
void afis_elev(elev *a, int n, char c)
{clrscr();
if(c=='A')
antet_afis(" LISTA
INSCRISILOR\n");
if(c=='O')
antet_afis(" LISTA
ALFABETICA\n");
if(c=='R')
antet_afis(" LISTA MEDII\n");
printf("Nr.crt.|Nr. Matricol|
NUME |Nota1|Nota2|Nota3| MEDIA\
|\n");
printf("-----------------------------
-------------------------\n");
int lin=3;
for(int i=0; i<n; i++){

79
Laboratorul 16 Tipuri de date definite de utilizator
printf("%7d|%12d|%-20s|",i+1,(a+i)-
>nr_matr,(a+i)->nume);
double med=0;
for (int j=0; j<3; j++){
printf("%-5d|", (a+i)->note[j]);
med+=(a+i)->note[j];
}
med/=3;printf("%-9.2f|\n",
med);lin++;
if (lin==(DIM_PAG-1)){
printf(" Apasa o tasta....");
getch();
clrscr();
if(c=='A') antet_afis(" LISTA
INSCRISILOR\n");
if(c=='O') antet_afis(" LISTA
ALFABETICA\n");
if(c=='R') antet_afis(" LISTA
MEDII\n");
printf("Nr.crt.| NUME
|Nota1|Nota2|Nota3| MEDIA\ |\n");
printf("----------------------------
-------------------------\ \n");
int lin=3;
}
}
printf(" Apasa o tasta....");
getch();
}
void main()
{ int nr_elevi; clrscr();
cout<<"Nr. elevi:";cin>>nr_elevi;
elev *p; p=new elev[nr_elevi];
cit_elevi(p, nr_elevi);
afis_elev(p, nr_elevi, 'A');//
afi?area nscri?ilor
ord_medii(p, nr_elevi);
afis_elev(p, nr_elevi, 'R');//
afi?area n ordinea descresc?toare a
mediilor
ord_alf(p, nr_elevi); //ordonare
alfabetica
afis_elev(p, nr_elevi, 'O');//
afi?area n ordinea descresc?toare a
mediilor
}

16.1.6 Media
S se calculeze media notelor la un
examen pentru mai muli studeni i media
notelor la toate examenele pentru un singur
student. Se vor folosi date de tip structur
(denumit student) cu urmtoarele cmpuri:
Nume, nota1, nota2, nota3.

16.2 Uniuni
Aceeai zon de memorie poate fi utilizat pentru pstrarea unor obiecte (date) de diferite
tipuri, prin declararea uniunilor. Uniunile sunt similare cu structurile, singura diferen
constnd n modul de memorare. Declararea uniunilor:
union identificator_tip_uniune {
lista de declaratii_membri;
} lista_identificatori_variabile;

Spaiul de memorie alocat corespunde tipului membrului de dimensiune maxim. Tipul
uniune folosete aceeai zon de memorie, care va conine informaii organizate n mai
multe moduri, corespunztor tipurilor membrilor.


//Uniuni
#include <iostream.h>
#include<conio.h>

union tip_dublu
{
int i; float f;
} ddata;

void main ()
{//ddata.f=1234.56e+5;
ddata.i=1234;
cout<<"ddata.f="<<ddata.f<<"\n";
cout<<"ddata.i="<<ddata.i<<"\n";
getch();
}

16.2.1 Persoane
S se exemplifice folosirea reuniunilor
(union) pentru citirea i afiarea datelor
despre mai multe persoane de ambele
sexe.
Vom folosi o structur pentru a memora
numele, vrsta i sexul unei persoane,

80
Laboratorul 16 Tipuri de date definite de utilizator
indiferent dac aceasta este femeie sau
brbat. Dar, n funcie de sex, persoana
respectiv va avea un so (dac e femeie),
respectiv o soie (dac e brbat). O
nregistrare de tip union va fi folosit,
aadar, pentru a memora partenerul unei
persoane oarecare.
O nregistrare union este similar cu o
nregistrare de tip struct, cu excepia
faptului c union va permite s definii
variabile (cmpuri) care s-i mpart
acelai spaiu de memorare.

//Patrut 6/87
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
union partener
{
char sotie[20];
char sot[20];
};

struct persoana
{
char nume[20];
char sex;
int varsta;
union partener p;
};

void Citeste(int nr_p, struct
persoana *x)
{
int vs; char sx;
printf("Se citesc datele persoanei
a %d-a:\n",nr_p);
fflush(stdin); //goleste fluxul
de date
printf("Dati numele: ");
gets(x->nume);
printf("Dati varsta: ");
scanf("%d",&vs);
x->varsta=vs;
fflush(stdin) ;
printf("Dati sexul: ");
scanf("%c",&sx) ;
x->sex=sx;
fflush(stdin);
if (x->sex=='F'|| x->sex=='f')
{
printf("Dati numexe sotului: ");
gets(x->p.sot);
}
else
{
printf("Dati numele sotiei: ");
gets(x->p.sotie);
}
}

void Scrie(int nr_p, struct
persoana x)
{
if (wherey()==20)
{
printf("\nApasati o tasta
...\n");
getch();
}
printf("Datele persoanei a %d-
a:\n",nr_p);
printf("Numele: %s.\n",x.nume);
printf("Varsta: %d.\n",x.varsta);
printf("Sexul: %c. \n",x.sex);
if(x.sex=='F'|| x.sex=='f')
printf("Numele sotului:
%s.\n",x.p.sot);
else
printf("Numele sotiei:
%s.\n",x.p.sotie);
}

void main()
{
struct persoana om[20]; int i,n;
// textmode(C80);
clrscr();
printf("Dati numarul de persoane:
");
scanf("%d",&n);
for(i=0; i<n; i++)
Citeste(i+1,&om[i]);
printf("\n
Rezultate:\n");
for(i=0; i<n; i++)
Scrie(i+1,om[i]);
getch();
}

16.2.2 Arii figuri
Fie tipul FIG declarat ca mai jos:
typedef struct {
int tip; /* tipul figurii */
union {
double raza; /* cerc */
double lat_p; /* patrat */
double lat_d[2 ];/* dreptunghi */
double lat_t[3]; /* triunghi */
} fig;
} FIG;

81
Laboratorul 16 Tipuri de date definite de utilizator
O dat de tip FIG conine elementele unei
figuri necesare pentru a calcula aria figurii
respective. Figurile avute n vedere sunt:
o cerc;
o ptrat;
o dreptunghi
o triunghi.
n cazul primelor dou figuri, data de tip FIG
conine o valoare de tip double care, n
cazul cercului reprezint lungimea razei
acestuia, iar n cazul ptratului, lungimea
laturii ptratului. n cazul dreptunghiului,
data conine dou elemente de tip double:
lungimea i limea. n sfirit, n cazul
triunghiului, data conine trei valori de tip
double care reprezint lungimile celor trei
laturi ale triunghiului.
Componenta tip definete elementele
(figura) prezente ntr-o dat de tip FIG i
are valorile:
0 Pentru cerc.
1 Pentru ptrat.
2 Pentru dreptunghi.
3 Pentru triunghi.
-1 Pentru eroare.
n locul acestor valori, considerm
constantele simbolice:
#define EROARE -1
#define CERC 0
#define PATRAT 1
#define DREPTUNGHI 2
#define TRIUNGHI 3

Funcia aria din program are ca parametru
o dat de tip FIG, calculeaz i returneaz
aria figurii ale crei clemente sunt coninute
n zona definit de parametru. Funcia
returneaz 0 n cazul n care datele sunt
eronate.
La calculul arici unui triunghi se folosete
formula lui Heron.
Funcia citire_fig din program are ca
parametru un pointer spre o dat de tip FIG
i citete i pstreaz elementele figurii
definite de componenta tip a datei de tip
FIG.

//PROGRAMUL BX40
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
typedef struct {
int tip;
union {
double raza;
double lat_p;
double lat_d[2];
double lat_t[3];
} fig;
} FIG;

#define EROARE -1
#define CERC 0
#define PATRAT 1
#define DREPTUNGHI 2
#define TRIUNGHI 3

//FUNCTIA BX38
#define PI 3.14159265358979
double aria(FIG *p)
/* calculeaza si returneaza aria
figurii definite de elementele
prezente in zona spre care
pointeaza p; la eroare returneaza 0
*/
{
double sp,a,b,c;
switch(p->tip)
{
case CERC: return PI*p-
>fig.raza*p->fig.raza;
case PATRAT: return p-
>fig.lat_p*p->fig.lat_p;
case DREPTUNGHI: return p-
>fig.lat_d[0]*p->fig.lat_d[1];
case TRIUNGHI: sp=(p-
>fig.lat_t[0] + p->fig.lat_t[1] +
p->fig.lat_t[2])/2;
if((a=sp - p->fig.lat_t[0])
> 0 && (b=sp - p->fig.lat_t[1]) > 0
&& (c=sp - p->fig.lat_t[2]) > 0 )
return sqrt(sp*a*b*c);
else
{ /* cele 3 valori nu
reprezinta lungimile laturilor unui
triunghi */
printf("a= %g\tb= %g\tc=
%g\tnu\ formeaza un triunghi\n", p-
>fig.lat_t[0], p->fig.lat_t[1], p-
>fig.lat_t[2] );
return 0;
}
default:/* eroare */ return
0;
}/*switch*/
}

//FUNCTIA BX39
int citire_fig(FIG *p)
/* - citeste elementele figurii
definite de p->tip; - returneaza:

82
Laboratorul 16 Tipuri de date definite de utilizator
0 - la intilnirea sfirsitului de
fisier sau la eroare;
1 - altfel. */
{
char t[255];
switch(p->tip)
{
case CERC:
for( ; ; )
{
printf("raza= ");
if(gets(t) == 0 ) return
0;
if(sscanf(t,"%lf",&p-
>fig.raza)== 1 && p->fig.raza>0)
return 1;
printf("nu s-a tastat un
numar pozitiv\n");
}
case PATRAT:
for( ; ; )
{
printf("latura
patratului= ");
if(gets(t) == 0 ) return
0;
if(sscanf(t,"%lf",&p-
>fig.lat_p)==1 && p->fig.lat_p>0)
return 1;
printf("nu s-a tastat un
numar pozitiv\n");
}
case DREPTUNGHI:
for( ; ; )
{
printf("lungimea si
latimea pe aceeasi linie: ");
if(gets(t)==0) return 0;
if(sscanf(t,"%lf
%lf",&p->fig.lat_d[0], &p-
>fig.lat_d[1])==2 && p-
>fig.lat_d[0] > 0 && p-
>fig.lat_d[1] > 0)
return 1;
printf("nu s-au tastat 2
numere pozitive\n");
}
case TRIUNGHI:
for( ; ; )
{
printf("laturile
triunghiului pe aceeasi linie: ");
if(gets(t) == 0 ) return
0;
if(sscanf(t,"%lf %lf
%lf",&p->fig.lat_t[0], &p-
>fig.lat_t[1], &p->fig.lat_t[2])==3
&& p->fig.lat_t[0]>0 && p-
>fig.lat_t[1]>0 && p->fig.lat_t[2]>
0 ) return 1;
printf("nu s-au tastat 3
numere\ pozitive\n");
}
default: return 0;
}
}


void main ()
/* - citeste o litera marc care
defineste o figura geometrica,
apoi citeste elementele figurii
respective;
- calculeaza si afiseaza aria
acelei figuri. */
{
char t[255]; char er[]="s-a tastat
EOF\n"; char lit[2]; FIG f; double
a;
for( ; ; )
{
printf("Tastati una din
literele mari: C\tD\tP\tT\n");
if(gets(t)==0)
{ printf(er); exit(1); }
sscanf(t,"%ls",lit);
switch(lit[0])
{
case 'C': /* cerc */ f.tip
= CERC; break;
case 'D': /* dreptunghi */
f.tip = DREPTUNGHI; break;
case 'P': /* patrat */
f.tip = PATRAT; break;
case 'T': /* triunghi */
f.tip = TRIUNGHI; break;
default: /* eroare */
printf("Nu s-a tastat una din
literele mari C,D,P sau T\n");
f.tip = EROARE;
}
if(f.tip != EROARE) break;
} /* sfirsit for */
/* citeste elementele figurii */
if(citire_fig(&f)==0)
{ printf(er); exit(1); }
/* calculeaza si afiseaza aria
figurii */
if((a=aria(&f))==0)
exit(1);
printf("Aria figurii= %g\n", a);
}


83
Laboratorul 16 Tipuri de date definite de utilizator
16.3 Enumerri
Tipul enumerare permite programatorului s foloseasc nume sugestive pentru valori
numerice. De exemplu, n locul numrului unei luni calendaristice este mai sugestiv s
folosim denumirea lunii respective sau eventual o prescurtare:
ian - Pentru ianuarie n locul cifrei 1.
feb - Pentru februarie n locul cifrei 2.
i aa mai departe.
Un alt exemplu se refer la posibilitatea de a utiliza cuvintele FALS i ADEVRAT pentru
valorile 0 respectiv 1. n felul acesta se obine o mai mare claritate n programele surs,
deoarece valorile numerice snt nlocuite prin sensurile atribuie lor ntr-un anumit context.
n acest scop se utilizeaz tipul enumerare. Un astfel de tip se declar printr-un format
asemntor cu cel utilizat n cadrul structurilor. Un prim format general este:
enum nume { nume0,numel,nume2,...,numek } dl,d2,...,dn;
unde:
nume - Este numele tipului de enumerare introdus prin aceast declaraie.
nume0, nume1,..., numek - Snt nume care se vor utiliza n continuare n locul valorilor
numerice i anume numei are valoarea i.
d1,d2,...,dn - Snt date care se declar de tipul nume. Aceste date snt similare cu
datele de tip int.
Ca i n cazul structurilor, n declaraia de mai sus nu snt obligatorii toate elementele. Astfel,
poate lipsi nume, dar atunci va fi prezent cel puin d1. De asemenea, poate lipsi n totalitate
lista d1,d2,...,dn, dar atunci va fi prezent nume. n acest caz, se vor defini ulterior date de tip
nume folosind un format de forma:
enum nume dl,d2,...,dn;
16.4 Exemple
16.4.1
enum { ileg,ian,feb,mar,apr,mai,iun,iul,aug,sep,oct,nov,dec } luna;
Prin aceast declaraie, numrul lunii poate fi nlocuit prin denumirea prescurtat a lunii
respective. De exemplu, o atribuire de forma: luna = 3 se poate nlocui cu una mai
sugestiv: luna = mar deoarece, conform declaraiei de mai sus, mar are valoarea 3.
n mod analog, o expresie de forma: luna == 7 este identic cu expresia: luna == iul
Dac n locul declaraiei de mai sus s-ar fi utilizat declaraia de tip enumerare:
enum dl {ileg,ian,feb,mar,apr,mai,iun,iul,aug,sep,oct,nov,dec };
atunci putem declara ulterior data luna de tip dl astfel: enum dl luna; Data luna declarat
in acest fel este o dat identic cu data luna declarat la nceput.
16.4.2
Fie tipul enumerare Boolean declarat astfel:
enum Boolean {false, true};
Declarm data bisect de tip Boolean:
enum Boolean bisect;
Atribuirea:
bisect = an%4 == 0&&an%100 | | an%400 ==0;
atribuie variabilei bisect valoarea 1 sau 0, dup cum anul definit de variabila an este bisect
sau nu (se presupune c anul aparine intervalului [1600,4900]).
n continuare se pot folosi expresii de forma:
bisect = = false

84
Laboratorul 16 Tipuri de date definite de utilizator
sau
bisect = = true
16.5 Declaraii de tip
Limbajul C permite atribuirea unui nume pentru un tip (predefinit sau utilizator) de date.
Pentru aceasta se folosesc delcaraiile de tip. Forma general a acestora este:
typedef tip nume_tip;
Nume_tip poate fi folosit la declararea datelor n mod similar cuvintelor cheie pentru tipurile
predefinite.
Exemplu:
//1
typedef int INTREG;
INTREG x, y;
INTREG z=4;
//2
typedef struct{
double parte_real;
double parte_imaginar;
} COMPLEX;
COMPLEX x, y;
16.6 Alocarea dinamic a memoriei
Alocarea memoriei se poate realiza n
urmtoarele moduri:
alocare static;
alocare dinamic;
alocare pe stiv.
Se aloc static memorie n urmtoarele
cazuri:
pentru instruciunile de control propriu-zise;
pentru variabilele globale i variabilele
locale declarate n mod explicit static.
Se aloc memorie pe stiv pentru
variabilele locale.
Se aloca dinamic memorie n mod explicit,
cu ajutorul funciilor de alocare dinamica,
aflate n headerul <alloc.h>.

n limbajul C, alocarea memoriei n mod
dinamic se face cu ajutorul funciilor
malloc, calloc, realloc; eliberarea
zonei de memorie se face cu ajutorul
funciei free. Funciile de
alocare/dezalocare a memoriei au
prototipurile n header-ele <stdlib.h> i
<alloc.h>:
16.6.1 Funcia malloc
Sintaxa:
void *malloc(size_t
nr_octei_de_alocat);

Funcia malloc necesit un singur
argument (numrul de octei care vor fi
alocai) i returneaz un pointer generic
ctre zona de memorie alocat (pointerul
conine adresa primului octet al zonei de
memorie rezervate).

Exemplu:
#include <iostream.h>
#include <malloc.h>
#include <string.h>
#include <stdlib.h>

void main()
{char *sirstoc="SIR DE STOCAT IN
MEMORIE"; char **psir;
int nrart=5,i; char ch;
if((psir=(char **)
malloc(nrart*sizeof(char*)))==NULL)
{cout << "Alocare esuata!\n";
exit(1);}

85
Laboratorul 16 Tipuri de date definite de utilizator
else
{for(i=0;i<n t;i++) rar
if(
(psir[i]=(char
*)malloc((strlen(sirstoc)+1)*sizeof(ch
ar)))==NULL
)
{cout << "Alocare esuata!\n";
exit(1);}
else strcpy(psir[i],sirstoc);
}
cout << "Sirul " << sirstoc << " a
fost alocat in " << nrart
<< "blocuri distincte.\n"
for (i=0;i<nrart;i++)cout << psir[i]
<<"\n";
cout << "Memoria pentru cele " <<
nrart << " blocuri " << sirstoc
<< \n";va fi eliberata apasind o
tasta\n";
cin >> ch;
for(i=0;i<nrart;i++)free(psir[i]);
free(psir);
}
16.6.2 Funcia calloc
nr_elemente,
aloc memorie pentru un
blou d mente, numrul de octei
Sintaxa:
void *calloc(size_t
size_t mrimea_n_octeti_
a_unui_elem);

Funcia calloc
ta e nr_ele
pe care este memorat un element este
mrimea_n_octei_a_unui_elem i
returneaz un pointer ctre zona de
memorie alocat.

Exemplu:
//calloc
#include <iostream.h>
#include <malloc.h>

float cere_element(int i)
{float elem;
cout << "a(" << (i+1) << ")="; cin >>
elem; cout << "\n";
return elem;
}

void afis_tablou(int n,float *tablou)
{i
for(i=0;i<n;i++) cout << "a(" <<
(i+1) << ")=" << *(tablou+i) << "\n";
}

void main()
{int n,i; float *tablou;
cout << "Specificati numarul de
elemente ale tabloului, n=";
cin >> n;
tablou=(float
*)calloc(n,sizeof(float));
if(tablou!=NULL)
{cout << "\nIntroduceti elementele
tabloului\n";
for(i=0;i<n;i++)
*(tablou+i)=cere_element(i);
cout << " Elementele tabloului
sunt:\n";
afis_tablou(n,tablou);
free(tablou);
}
else cout << "Alocare esuata!\n";
}
16.6.3 Funcia
*ptr, size_t
realloc permite modificarea zonei
realloc
void *realloc(void
mrime);

ncia Fu
de memorie alocat dinamic cu ajutorul
funciilor malloc sau calloc.
Observaie:
n cazul n care nu se reuete alocarea
liberarea memoriei (alocate dinamic cu
free(void *ptr);
dinamic a memoriei (memorie
insuficient), funciile malloc, calloc i
realloc returneaz un pointer null.
Deoarece funciile malloc, calloc, realloc
returneaz un pointer generic, rezultatul
poate fi atribuit oricrui tip de pointer. La
atribuire, este indicat s se utilizeze
operatorul de conversie explicit (vezi
exemplu).

E
una dintre funciile malloc, calloc sau
realloc) se realizeaz cu ajutorul funciei
free.
void

nt i;

86
Laboratorul 16 Tipuri de date definite de utilizator
16.7 NTREBRI I EXERCIII
16.7.1 Chestiuni teoretice
1. Variabilele tablou i variabilele de tip definit de utilizator sunt exemple de variabile
compuse (reprezint date structurate). Care este, totui, deosebirea dintre ele ?
2. Ce posibiliti de definire a unor noi tipuri de date v ofer limbajul C/C++ ?
3. n ce const diferena dintre structuri i uniuni ?
4. Cum se numesc componentele unei structuri ?
5. Ce restricii impune folosirea cmpurilor de bii ?
6. Exist vreo restricie referitoare la tipul membrilor unei structuri ? Dac d, care este
aceasta ?
16.7.2 Chestiuni practice
7. S se implementeze programele cu exemplele prezentate.
8. S se scrie programele pentru exerciiile rezolvate care au fost prezentate.
9. Realizai urmtoarele modificri la exerciiul prezentat la sfritul capitolului:
a. Completai cu o funcie de calcul i afiare a mediei notelor tuturor candidailor
pentru fiecare prob (media tuturor elevilor la proba1, media la proba2, etc).
b. Modificai lista alfabetic, astfel nct la elevii cu medie peste 5, s apar (alturi
de medie) mesajul "Promovat", iar la ceilali, mesajul "Nepromovat".
c. Considernd c rezultatelor obinute sunt utilizate la un concurs de admitere, la
care exist N locuri (N introdus de la tastatur), i de faptul c pentru a fi admis
media trebuie s fie cel puin 5, s se afieze lista admiilor i lista respinilor, n
ordinea descresctoare a mediilor, n limita locurilor disponibile.
10. S se scrie un program care s permit memorarea datelor privitoare la angajaii unei
firme mici: nume angajat, adres, numr copii, sex, data naterii, data angajrii, calificare,
salariul brut. Se vor implementa urmtoarele funcii:
a. Citirea informaiilor despre cei N angajai (N introdus de la tastatur);
b. Cutarea - dup nume - a unui angajat i afiarea informaiilor despre acesta;
c. Modificarea informaiilor despre un anumit angajat;
d. Lista alfabetic a angajailor, n care vor apare: nume, adres, data angajrii,
calificare, salariu;
e. Lista angajailor n ordine descresctoare a vechimii;
f. Lista angajatilor cu un anumit numar de copii, C, introdus de la tastatur;
g. Lista angajailor cu vrsta mai mare dect V (V introdus de la tastatur);
h. Salariul minim, salariul mediu i cel maxim din firm;
i. Lista de salarii, n care vor apare: numele, calificarea, salariul brut i salariul net.
La sfritul listei vor apare totalurile pentru salariile brute, impozite, salarii nete.
Pentru calculul salariului net se aplic urmtoarele reguli de impozitare:
i. I=15% pentru salariul brut (SB)<600000
ii. I=50000+20% pentru 600000<=SB<1500000 (20% din ceea ce
depete 600000)
iii. I=100000+30% pentru 1500000<=SB<3000000
iv. I=250000+40% pentru 3000000<=SB<15000000
v. I=45% pentru SB>=1500000


87
Laboratorul 17 Fiiere
17. Fiiere
17.1 Caracteristicile generale ale fiierelor
Operaiile care pot fi realizate asupra fiierelor sunt:
deschiderea unui fiier;
scrierea ntr-un fiier;
citirea dintr-un fiier;
poziionarea ntr-un fiier;
nchiderea unui fiier.
17.2 Deschiderea unui fiier
Funcia fopen
Creaz un flux de date ntre fiierul specificat prin numele extern (nume_fisier) i
programul C. Parametrul mod specific sensul fluxului de date i modul de interpretare a
acestora. Funcia returneaz un pointer spre tipul FILE, iar n caz de eroare - pointerul NULL
(prototip n stdio.h).
FILE *fopen(const char *nume_fisier, const char *mod);
Parametrul mod este o constant ir de caractere, care poate conine caracterele cu
semnificaiile:
r: flux de date de intrare; deschidere pentru citire;
w: flux de date de ieire; deschidere pentru scriere (creaz un fiier nou sau
suprascrie coninutul anterior al fiierului existent);
a: flux de date de ieire cu scriere la sfritul fiierului, adugare, sau crearea
fiierului n cazul n care acesta nu exist;
+: extinde un flux de intrare sau ieire la unul de intrare/ieire; operaii de scriere i
citire asupra unui fiier deschis n condiiile r, w sau a.
b: date binare;
t: date text (modul implicit).
Exemple:
"r+" deschidere pentru modificare (citire i scriere);
"w+" deschidere pentru modificare (citire i scriere);
"rb" citire binar;
"wb" scriere binar;
"r+b" citire/scriere binar.

Funcia freopen (stdio.h) FILE*freopen(const char*nume_fis,const
char*mod,FILE *flux_date);
Asociaz un nou fiier unui flux de date deja existent, nchiznd legtura cu vechiul fiier i
ncercnd s deschid una nou, cu fiierul specificat. Funcia returneaz pointerul ctre
fluxul de date specificat, sau NULL n caz de eec (prototip n stdio.h).

Funcia open int open(const char *nume_fisier, int acces [,int mod]);

88
Laboratorul 17 Fiiere
Deschide fiierul specificat conform cu restriciile de acces precizate n apel. Returneaz un
ntreg care este un indicator de fiier sau -1 (n caz de eec) (prototip n io.h).
Restriciile de acces se precizeaz prin aplicarea operatorului | (disjuncie logic la nivel de
bit) ntre anumite constante simbolice, definite n fcntl.h, cum sunt :
O_RDONLY - citire;
O_WRONLY - scriere
O_RDWR - citire i scriere
O_CREAT - creare
O_APPEND - adugare la sfritul fiierului
O_TEXT - interpretare CR-LF
O_BINARY - nici o interpretare.,
Restriciile de mod de creare se realizeaz cu ajutorul constantelor:
S_IREAD - permisiune de citire din fiier
S_IWRITE - permisiune de scriere din fiier, eventual legate prin operatorul
|.
Funcia creat int creat(const char *nume_fiier, int un_mod);
Creaz un fiier nou sau l suprascrie n cazul n care deja exist. Returneaz indicatorul de
fiier sau -1 (n caz de eec). Parametrul un_mod este obinut n mod analog celui de la
funcia de deschidere (prototip n io.h).
Funcia creatnew int creatnew(const char *nume_fiier, int mod);
Creaz un fiier nou, conform modului specificat. Returneaz indicatorul fiierului nou creat
sau rezultat de eroare (-1), dac fiierul deja exist (prototip n io.h).
Dup cum se observ, informaia furnizat pentru deschiderea unui fiier este aceeai n
ambele abordri, diferena constnd n tipul de date al entitaii asociate fiierului.
Implementarea din io.h ofer un alt tip de control la nivelul comunicrii cu echipamentele
periferice (furnizat de funcia ioctrl), asupra cruia nu vom insista, deoarece desfurarea
acestui tip de control este mai greoaie, dar mai profund.
17.3 nchiderea unui fiier
Funcia fclose int fclose(FILE *pf);
Funcia nchide un fiier deschis cu fopen i elibereaz memoria alocat (zona tampon
i structura FILE). Returneaz valoarea 0 la nchiderea cu succes a fiierului i -1 n caz
de eroare (prototip n stdio.h).
Funcia fcloseall int fcloseall(void);
nchide toate fluxururile de date i returneaz numrul fluxurilor de date nchise (prototip n
stdio.h).
Funcia close int close(int indicator);
nchide un indicator de fiier i returneaz 0 (n caz de succes) sau -1 n caz de eroare
(prototip n io.h).
17.4 Prelucrarea fiierelor text
17.4.1 PRELUCRAREA UNUI FIIER LA NIVEL DE CARACTER
Fiierele pot fi scrise i citite caracter cu caracter folosind funciile putc (pentru scriere) i
getc (citire).

89
Laboratorul 17 Fiiere
Funcia putc int putc (int c, FILE *pf);
c este codul ASCII al caracterului care se scrie n fiier;
pf este pointerul spre tipul FILE a crui valoare a fost returnat de funcia fopen.
Funcia putc returneaz valoarea lui c (valoarea scris n caz de succes), sau 1 (EOF) n
caz de eroare sau sfrit de fiier.
Funcia getc int getc (FILE *pf);
Funcia citete un caracter dintr-un fiier (pointerul spre tipul FILE transmis ca argument)
i returneaz caracterul citit sau EOF la sfrit de fiier sau eroare.

17.4.1.1 Exerciiu
S se scrie un program care creaz un
fiier text n care se vor scrie caracterele
introduse de la tastatur (citite din fiierul
standard de intrare), pn la ntlnirea
caracterului ^Z = Ctrl+Z.
#include <stdio.h>
#include <process.h>
void main()
{
int c, i=0; FILE *pfcar;
char mesaj[]="\nIntrodu caractere
urmate de Ctrl+Z (Ctrl+D sub
Linux):\n";
char eroare[]="\n Eroare
deschidere fisier \n";
while(mesaj[i])
putchar(mesaj[i++]);
pfcar=fopen("f_car1.txt","w"); //
crearea fiierului cu numele extern
f_car1.txt
if(pfcar==NULL)
{
i=0;

while(eroare[i])putc(eroare[i++],s
tdout);
exit(1);
}while((c=getchar())!=EOF) // sau:
while ((c=getc(stdin)) != EOF)
putc(c,pfcar); //
scrierea caracterului n fiier
fclose(pfcar); //
nchiderea fiierului
}
17.4.1.2 Exerciiu
S se scrie un program care citete un
fiier text, caracter cu caracter, i afieaz
coninutul acestuia.
#include <stdio.h>
#include <process.h>
void main()
{
int c, i=0;
FILE *pfcar;
char eroare[]="\n Eroare
deschidere fisier \n";
pfcar=fopen("f_car1.txt","r");
//deschiderea fiierului numit
f_car1.txt n citire
if(pfcar==NULL)
{
i=0;

while(eroare[i])putc(eroare[i++],s
tdout);
exit(1);
} while((c=getc(pfcar))!=EOF)
//citire din fiier, la nivel de caracter
putc(c,stdout);
//scrierea caracterului citit n fiierul standard
de ieire (afiare pe monitor)
fclose(pfcar);
}
17.4.2 PRELUCRAREA UNUI FIIER LA NIVEL DE CUVNT
Funciile putw i getw (putword i getword) sunt echivalente cu funciile putc i getc, cu
diferena c unitatea transferat nu este un singur octet (caracter), ci un cuvnt (un int).
int getw(FILE *pf);
int putw (int w, FILE *pf);
Se recomand utilizarea funciei feof pentru a testa ntlnirea sfritului de fiier.
17.4.2.1 Exemplul 1
int tab[100];
FILE *pf;
// . . . deschidere fisier
while (!feof(pf)){
for (int i=0; i<100; i++){
if (feof(pf))
break;
tab[i]=getw(pf);
//citire din fisier la nivel de
cuvnt si memorare n vectorul tab
// . . .

90
Laboratorul 17 Fiiere
}
}
printf("Sfarsit de fisier\n");
17.4.2.2 Exemplul 2
#include <stdio.h>
#include <process.h>

void main()
{
int c, i=0; FILE *pfcar;
char mesaj[]="\nIntrodu caractere
urmate de Ctrl+Z (Ctrl+D sub
Linux):\n";
char eroare[]="\n Eroare
deschidere fisier \n";
while(mesaj[i])
putchar(mesaj[i++]);
pfcar=fopen("f_car1.txt","w"); //
crearea fisierului cu numele
extern f_car1.txt
if(pfcar==NULL)
{
i=0;
while(eroare[i])
putc(eroare[i++],stdout);
exit(1);
}
while((c=getchar())!=EOF) // sau:
while ((c=getc(stdin)) != EOF)
putc(c,pfcar); //
scrierea caracterului n fisier
fclose(pfcar); // nchiderea
fisierului
}
17.4.3 PRELUCRAREA UNUI FIIER LA NIVEL DE IR DE CARACTERE
ntr-un fiier text, liniile sunt considerate ca linii de text separate de sfritul de linie ('\n'),
iar n memorie, ele devin iruri de caractere terminate de caracterul nul ('\0'). Citirea unei
linii de text dintr-un fiier se realizeaz cu ajutorul funciei fgets, iar scrierea ntr-un fiier - cu
ajutorul funciei fputs.
Funcia fgets este indentic cu funcia gets, cu deosebirea c funcia gets citete din
fiierul standard de intrare (stdin). Funcia fputs este indentic cu funcia puts, cu
deosebirea funcia puts scrie n fiierul standard de ieire (stdout).
Funcia fputs
int fputs(const char *s, FILE *pf);
Funcia scrie un ir de caractere ntr-un fiier i primete ca argumente pointerul spre zona
de memorie (buffer-ul) care conine irul de caractere (s) i pointerul spre structura FILE.
Funcia returneaz ultimul caracter scris, n caz de succes, sau -1 n caz de eroare.
Funcia fgets
char *fgets(char *s, int dim, FILE *pf);
Funcia citete maximum dim-1 octei (caractere) din fiier, sau pn la ntlnirea sfaritului
de linie. Pointerul spre zona n care se face citirea caracterelor este s. Terminatorul null
('\0') este plasat automat la sfritul irului (buffer-lui de memorie). Funcia returneaz un
pointer ctre buffer-ul n care este memorat irul de caractere, n caz de succes, sau
pointerul NULL n cazul eecului.

17.4.3.1 Exerciiul 1
S se scrie un program care creaz un
fiier text n care se vor scrie irurile de
caractere introduse de la tastatur.
#include <stdio.h>
void main()
{
int n=250; FILE *pfsir;
char mesaj[]="\nIntrodu siruri
car.urmate de Ctrl+Z(Ctrl+D sub
Linux):\n";
char sir[250],*psir;
fputs(mesaj,stdout);
pfsir=fopen("f_sir.txt","w");
//deschiderea fisierului
f_sir.txt pentru scriere
psir=fgets(sir,n,stdin); //
citirea sirurilor din fisierul
standard de intrare
while(psir!=NULL)
{
fputs(sir,pfsir); //
scrierea n fisierul text
psir=fgets(sir,n,stdin);
}
fclose(pfsir);
}

91
Laboratorul 17 Fiiere
17.4.3.2 Exerciul 2
S se scrie un program care citete un
fiier text, linie cu linie, i afieaz
coninutul acestuia
#include <stdio.h>
void main()
{
int n=250; FILE *pfsir; char
sir[250],*psir;
pfsir=fopen("f_sir.txt","r");
psir=fgets(sir,n,pfsir);
while(psir!=NULL)
{
fputs(sir,stdout); //sau:
puts(sir);
//afisarea (scrierea n fisierul
standard de iesire) sirului
(liniei) citit din fisierul text
psir=fgets(sir,n,pfsir);
//citirea unei linii de text
din fisier
}
fclose(pfsir);}


17.4.3.3 Exerciiul 3
Sa se scrie un program care creeaz un
fiier text tabel:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#define PI 3.1415926

void main()
{
const n=250;
int i,j,dec,sg; FILE *pfsir;
char
all[n],sir[n],*psir,*tab="\t",*cr=
"\n";
float x;

pfsir=fopen("f_tab.xls","w");
//deschiderea fisierului
f_tab.txt pentru scriere
fputs("i\tsin\tcos\n",pfsir);
// scrierea antetului
fisierului text

for(i=0;i<=90;i+=10)
// for(j=0;j<=90;j+=10)
{

gcvt(i,5,sir); //conversie
valoare reala->sir caractere
strcpy(all,sir); //copiere
caractere in sirul de scris
strcat(all,tab); //concatenare
caracter TAB

x=sin(PI/180*i);
gcvt(x,5,sir); strcat(all,sir);
strcat(all,tab);
x=cos(PI/180*i);
gcvt(x,5,sir); strcat(all,sir);
printf("\n%s",all);
strcat(all,cr);

fputs(all,pfsir); //
scrierea n fisierul text
}
fclose(pfsir);
}

17.4.3.4 Exerciiul 4
Scriei un program care s fac o copie
(caracter cu caracter) a unui fiier text dat.
//Patrut 5/113
#include <stdio.h>

void main(void)
{
FILE *in, *out; char sursa[13],
dest[13];
fflush(stdin);
printf("Dati sursa: ");
scanf("%s",&sursa); fflush(stdin)
printf("Dati destinatia: ");
scanf("%s",&dest);
if ((in = fopen (sursa, "rt")) ==
NULL)
{
printf("Nu se poate deschide
fisierul sursa.\n");
return;
}
if ((out = fopen(dest, "wt")) ==
NULL)
{
printf("Nu se poate crea fisierul
destinatie.\n");
return;
}
// se copiaza caracterele din
"in" in "out"
while (!feof(in))
fputc(fgetc(in),out);
fclose(in); fclose(out);
}



92
Laboratorul 18 Fiiere - continuare
18. Fiiere - continuare
18.1 Intrri/ieiri binare
18.1.1 Exerciiu
S se scrie un program care creaz un
fiier binar n care se vor introduce numere
reale, nenule.
#include <iostream.h>
#include <stdio.h>
int main()
{ FILE *f; double nr; int x;
if ((f= fopen("test_nrb.dat",
"wb")) == NULL) //deschidere flux
binar, scriere
{ cout<<"\nNu se poate
deschide fisierul
test_nrb.dat"<<'\n';
return 1;
}
cout<<"\nIntroduceti
numere(diferite de 0) terminate cu
un 0:"<<'\n';
cin>>nr;
while(nr!=0)
{
x=fwrite(&nr, sizeof(nr), 1,
f); //scriere n fisier
cin>>nr;
}
fclose(f);
return 0;
}
18.1.2 Exemplu
S se scrie un program ce citete dintr-un
fiier binar numere reale, nenule.
#include <iostream.h>
#include <stdio.h>
int main()
{ FILE *f; double buf;
if ((f= fopen("test_nrb.dat",
"rb")) == NULL)
{
cout<<"\nNu se poate
deschide fisierul
test_nrb.dat"<<'\n';
return 1;
}
cout<<"\nNumerele nenule citite
din fisier sunt:"<<'\n';
while((fread(&buf, sizeof(buf),
1, f))==1)
// functia sizeof(buf) care
returneaza numarul de octeti
necesari variabilei buf.
cout<<buf<<" ";
fclose(f);
cout<<'\n';
return 0;
}

18.2 Poziionarea ntr-un fiier
Pe lng mecanismul de poziionare implicit (asigurat prin operaiile de citire i scriere) se pot folosi i
operaiile de poziionare explicit.
Funcia fseek int fseek(FILE *pf, long deplasament, int referinta);
Funcia deplaseaz capul de citire/scriere al discului, n vederea prelucrrii nregistrrilor
fiierului ntr-o ordine oarecare. Funcia seteaz poziia curent n fluxul de date la n octei
fa de referint):
deplasament definete numrul de octei peste care se va deplasa capul discului;
referinta poate avea una din valorile:
0 - nceputul fiierului (SEEK_SET);
1 - poziia curent a capului (SEEK_CUR);

93
Laboratorul 18 Fiiere - continuare
2 - sfritul fiierului (SEEK_END).
Funcia returneaz valoarea zero la poziionarea corect i o valoare diferit de zero n caz
de eroare (prototip n stdio.h).
Funcia lseek int lseek(int indicator, long n, int referinta);
Seteaza poziia curent de citire/scriere n fiier la n octei faa de referint. Returneaz
valoarea 0 n caz de succes i diferit de zero n caz de eroare (prototip n io.h).
Funcia fgetpos int fgetpos(FILE *flux_date, fpos_t *pozitie);
Determin poziia curent (pointer ctre o structur, fpos_t, care descrie aceast poziie n
fluxul de date). nscrie valoarea indicatorului n variabila indicat de pozitie. Returneaz 0
la determinarea cu succes a acestei poziii sau valoare diferit de zero n caz de eec.
Structura care descrie poziia poate fi transmis ca argument funciei fsetpos (prototip n
stdio.h).
Funcia fsetpos int fsetpos(FILE *flux_date, const fpos_t *pozitie);
Seteaz poziia curent n fluxul de date (atribuie indicatorului valoarea variabilei indicate
pozitie), la o valoare obinut printr apelul funciei fgetpos. Returneaz valoarea 0 n
caz de succes, sau diferit de 0 n caz de eec (prototip n stdio.h).
Exist funcii pentru modificarea valorii indicatorului de poziie i de determinare a poziiei curente a
acestuia.
Funcia ftell long ftell(FILE *pf);
Indic poziia curent a capului de citire n fiier. Funcia returneaz o valoare de tip long int
care reprezint poziia curent n fluxul de date (deplasamentul n octei a poziiei capului fa
de nceputul fiierului) sau -1L n caz de eroare (prototip n stdio.h).
Funcia tell long tell(int indicator);
Returneaz poziia curent a capului de citire/scriere n fiier (exprimat n numr de octei
fa de nceputul fiierului), sau -1L n caz de eroare (prototip n io.h).
Funcia rewind void rewind(FILE *flux_date);
Poziioneaz indicatorul la nceputul fluxului de date specificat ca argument (prototip n
stdio.h).
18.3 Funcii utilitare pentru lucrul cu fiiere
Funcii de testare a sfritului de fiier
Funcia feof int feof(FILE *flux_date);
Returneaz o valoare diferit de zero n cazul ntlnirii sfritului de fiier sau 0 n celelalte
cazuri (prototip n stdio.h).
Funcia eof int eof(int indicator);
Returneaz valoarea 1 dac poziia curent este sfritul de fiier, 0 dac indicatorul este
poziionat n alt parte, sau -1 n caz de eroare (prototip n io.h).
Funcii de golire a fluxurilor de date
Funcia fflush int fflush(FILE *flux_date);
Golete un fluxul de date specificat ca argument. Returneaz 0 n caz de succes i -1 (EOF)
n caz de eroare (prototip n stdio.h).
Funcia flushall int flushall(void);
Golete toate fluxurile de date existente, pentru cele de scriere efectund i scrierea n
fiiere. Returneaz numrul de fluxuri asupra crora s-a efectuat operaia (prototip n
stdio.h).

94
Laboratorul 18 Fiiere - continuare
18.4 Alte operaii cu fiiere
Funcii care permit operaii ale sistemului de operare asupra fiierelor
Funcia remove int remove(const char *nume_fisier);
terge un fiier. Returneaz valoarea 0 pentru operaie reuit i -1 pentru operaie euat
(prototip n stdio.h).
Funcia rename int rename(const char *nume_vechi, const char
*nume_nou);
Redenumete un fiier. Returneaz 0 pentru operaie reuita i -1 n cazul eecului (prototip
n stdio.h).
Funcia unlink int unlink(const char *nume_fisier);
terge un fiier. Returneaz 0 la operaie reuit i -1 la eec; dac fiierul are permisiune
read-only, funcia nu va reui operaia (prototip n io.h, stdio.h).

Funcii care permit manipularea aceluiai fiier prin dou indicatoare de fiier
independente
Funcia dup int dup(int indicator);
Duplic un indicator de fiier. Returneaz noul indicator de fiier pentru operaie reuit sau -
1 n cazul eecului (prototip n io.h).
Funcia dup2 int dup2(int indicator_vechi, int
indicator_nou);
Duplic un indicator de fiier la valoarea unui indicator de fiier deja existent. Returneaz 0 n
caz de succes i -1 n caz de eec (prototip n io.h).
Funcii pentru aflarea sau modificarea dimensiunii n octei a fiierelor
Funcia chsize int chsize(int indicator, long lungime);
Modific dimensiunea unui fiier, conform argumentului lungime. Returneaz 0 pentru
operaie reuit sau -1 n caz de eec (prototip n stdio.h).
Funcia filelength long filelength(int indicator);
Returneaz lungimea unui fiier (n octei) sau -1 n caz de eroare (prototip n io.h).

Funcii de lucru cu fiiere temporare care ofer faciliti de lucru cu fiiere temporare prin
generarea de nume unice de fiier n zona de lucru.
Funcia tmpfile FILE *tmpfile(void);
Deschide un fiier temporar, ca flux de date, n mod binar (w+b). Returneaz pointerul ctre
fiierul deschis n cazul operaiei reuite, sau NULL n caz de eec (prototip n stdio.h).
Funcia tmpnam char *tmpnam(char *sptr);
Creaz un nume unic pentru fiierul temporar (prototip n stdio.h).
Funcia creattemp int creattemp(char *cale, int attrib);
Creaz un fiier unic ca nume, cu atributele specificate n argumentul attrib (prin
_fmode,O_TEXT sau O_BINARY), n directorul dat n argumentul cale. Returneaz
indicatorul (handler-ul) ctre fiierul creat sau -1 (i setarea errno) n cazul eecului
(prototip n io.h).

18.4.1 Exemplu - Fiier despre angajaii
unei ntreprinderi
S se creeze un fiier binar, care va
conine informaiile despre angajaii unei
ntreprinderi: nume, marca, salariu. S se
afieze apoi coninutul fiierului.

#include<iostream.h>
#include <stdio.h>
#include <ctype.h>
typedef struct
{ char nume[20];int
marca;double salariu;
}angajat;
union

95
Laboratorul 18 Fiiere - continuare
{angajat a;char
sbinar[sizeof(angajat)];}buffer;

int main()
{angajat a; FILE *pf; char
cont;char *nume_fis;
cout<<"Nume fisier care va fi
creat:"; cin>>nume_fis;
if ((pf= fopen(nume_fis, "wb")) ==
NULL)
{ cout<<"\nEroare creare
fisier "<<nume_fis<<"!\n";
return 1; }
do
{cout<<"Marca : ";cin>>a.marca;
cout<<"Nume : ";cin>>a.nume;
cout<<"Salariu
:";cin>>a.salariu;
buffer.a=a;

fwrite(buffer.sbinar,1,sizeof(anga
jat),pf);
cout<<"Continuati introducerea
de date (d/n) ?";
cin>>cont;
} while(toupper(cont)!='N');
fclose(pf);
//citirea informaiilor
if ((pf= fopen(nume_fis, "rb")) ==
NULL)
{ cout<<"\nEroare citire
fisier "<<nume_fis<<"!\n";
return 1; }
for(;;)
{

fread(buffer.sbinar,1,sizeof(a),pf
);
a=buffer.a1;
if(feof(pf)) exit(1);
cout<<" Marca : "<<a.marca;
cout<<" Numele :
"<<a.nume<<'\n';
cout<<" Salariul :
"<<a.salariu<<'\n';
}
fclose(pf);
}

18.4.2 Aplicaie pentru gestiunea
materialelor dintr-un depozit.
Aplicaia va avea un meniu principal i va
permite gestiunea urmtoarelor informaii:
codul materialului (va fi chiar "numrul de
ordine"), denumirea acestuia, unitatea de
msur, preul unitar, cantitatea
contractat i cea recepionat (vectori cu
4 elemente). Memorarea datelor se va face
ntr-un fiier de date (un fiier binar cu
structuri), numit "material.dat". Aplicaia
conine urmtoarele funcii:
help() - informare privind opiunile
programului
Funcii pentru fiierele binare, care s
suplineasc lipsa funciilor standard pentru
organizarea direct a fiierelor binare:
citireb() - citire n acces direct
din fiier;
scrieb() - scriere n acces
direct n fiier;
citmat() - citirea de la terminal
a informaiilor despre un material;
afismat() - afiarea informaiilor
despre un material (apelat de
list);
lungfisis() - determinarea
lungimii fiierului existent;
crefis() - creare fiier.
Funcii pentru adaugarea, modificarea,
tergerea i listarea de materiale.
#include <process.h>
#include <iostream.h>
#include <stdio.h>
#include <ctype.h>
typedef struct material
{ int
codm,stoc,cant_c[4],cant_r[4];
char
den_mat[20],unit_mas[4];
float pret;
};
material mat;
FILE *pf;
void
crefis(),adaug(),modif(),sterg(),l
ist(),help();
void main()
{
char optiune;
do //afisarea unui meniu
de optiuni si selectia optiunii
{
cout<<'\n'<<"Optiunea Dvs. de
lucru este"<<'\n'
<<"(c|a|m|s|l|e|h
pentru help) : ";
cin>>optiune;
switch(optiune)
{
case 'c':case
'C':crefis();break;

96
Laboratorul 18 Fiiere - continuare
case 'a':case
'A':adaug();break;
case 'm':case
'M':modif();break;
case 's':case
'S':sterg();break;
case 'l':case
'L':list();break;
case 'h':case
'H':help();break;
case 'E': 'e':case
break;
default:help();
break;
}
}while(toupper(optiune)!='E');
}
void help() // afisare
informatii despre utilizarea
meniului si optiunile acestuia
{cout<<"Optiunile de lucru sunt
:"<<'\n';
cout<<" C,c-creare
fisier"<<'\n';
cout<<" A,a-adaugare"<<'\n';
cout<<" M,m-
modificare"<<'\n';
cout<<" L,l-listare"<<'\n';
cout<<" S,s-stergere"<<'\n';
cout<<" H,h-help"<<'\n';
cout<<" E,e-exit"<<'\n';
}
long int lungfis(FILE *f) //
returneaz lungimea fisierului
{long int posi,posf;
posi=ftell(f);
fseek(f,0,SEEK_END);
posf=ftell(f);
fseek(f,posi,SEEK_SET);
return posf;
}
void scrieb(int nr,void *a,FILE
*f) //scriere n fisierul binar
{long depl=(nr-
1)*sizeof(material);
fseek(f,depl,SEEK_SET);

if(fwrite(a,sizeof(material),1,f)!
=1)
{cout<<"Eroare de scriere in
fisier !"<<'\n';
exit(1); }
}
vo citireb(int id nr,void *a,FILE
*f) //citire din fisierul binar
{long depl=(nr-
1)*sizeof(material);
fseek(f,depl,SEEK_SET);

if(fread(a,sizeof(material),1,f)!=
1)
{cout<<"Eroare de citire din
fisier !"<<'\n';
exit(2); }
}
void afismat(material *a)
//afisarea informatiilor
despre un anumit material
{
int i;
if(a->codm)
{cout<<"Cod material :
"<<a->codm<<'\n';
cout<<"Denumire material:
"<<a->den_mat<<'\n';
cout<<"Cantitati
contractate:"<<'\n';
for(i=0;i<4;i++)
cout<<"Contractat "<<i<<"
: "<<a->cant_c[i]<<'\n';
cout<<"Cantitati
receptionate:"<<'\n';
for(i=0;i<4;i++)
cout<<"Receptionat "<<i<<"
: "<<a->cant_r[i]<<'\n';
cout<<"Stoc :
"<<a->stoc<<'\n';
cout<<"Unitate de masura:
"<<a->unit_mas<<'\n';
cout<<"Pret unitar :
"<<a->pret<<'\n';
}
else cout<<"Acest articol a
fost sters !"<<'\n';
}
void citmat(material *a)
//citirea informatiilor
despre un anumit material
{
int i;float temp;
cout<<"Introduceti codul
materialului (0=End): ";cin>>a-
>codm;
if(a->codm==0) return;
cout<<"Introduceti denumirea
materialului : ";cin>>a->den_mat;
cout<<"Introduceti unitatea de
msur : ";cin>>a->unit_mas;
cout<<"Introduceti pretul :
";cin>>temp;a->pret=temp;
cout<<"Introduceti cantitatile
contractate : "<<'\n';
for(i=0;i<4;i++)
{cout<<"Contract "<<i+1<<" at
: ";cin>>a->cant_c[i]; }

97
Laboratorul 18 Fiiere - continuare
cout<<"Introduceti cantitatile
receptionate : "<<'\n';
for(i=0;i<4;i++)
{cout<<"Receptionat "<<i+1<<"
: ";cin>>a->cant_r[i]; }
}
void crefis() //deschidere
fisier
{

if((pf=fopen("m terial.dat","r a "))!
=NULL)
cout<<"Fisierul exista deja
!"<<'\n';
else

pf=fopen("material.dat","w");
fclose(pf);
}
void adaug() //adugare de noi
materiale
{
int na;
pf=fopen("material.dat","a");//des
chidere pentru append
na=lungfis(pf)/sizeof(material);
do
{citmat(&mat);
if(mat.codm)
scrieb(++na,&mat,pf);
} while(mat.codm);
fclose(pf);
}

void modif() //modificarea
informatiilor despre un material
existent
{
int na; char ch;
pf=fopen("material.dat","r+");
do
{cout<<"Numarul articolului de
modificat este (0=END): ";cin>>na;
if(na)
{citireb(na,&mat,pf);
afismat(&mat);
cout<<"Modificati articol
(D/N) ? :";
do
{ cin>>ch;
ch=toupper(ch);
} while(ch!='D' && ch!='N');
if(ch=='D')
{citmat(&mat);
scrieb(na,&mat,pf);
}
}
hile(n }w a);
fclose(pf);
}
void sterg() //stergerea din
fisier a unui material
{ int n;long int na;
pf=fopen("material.dat","r+");
mat.codm=0;
na=lungfis(pf)/sizeof(material);
do
{
do
{cout<<"Numarul articolului
de sters este (0=END): ";cin>>n;
if(n<0||n>na) c t<<"Articol ou
eronat"<<'\n';
}while(!(n>=0 && n<=na));
if(n) scrieb(n,& at,pf); m
}while(n);
fclose(pf);
}
void list() //afisare
informatii despre un anumit
material
{
int na;
pf=fopen("material.dat","r");
do
{cout<<"Numarul articolulu de i
listat este (0=END): ";cin>>na;
if(na)
{citireb(na,&mat,pf);
afismat(&mat);
cout<<'\n';
}
}while(na);
ose(p fcl f);
}


98
Laboratorul 18 Fiiere - continuare
18.5 NTREBRI I EXERCIII
18.5.1 Chestiuni practice
1. Scriei un program de tiprire a coninuturilor mai multor fiiere, ale cror nume se
transmit ca parametri ctre funcia main. Tiprirea se face pe ecran (lungimea paginii =
22) sau la imprimant (lungimea paginii = 61). Coninutul fiecrui fiier va ncepe pe o
pagin nou, cu un titlu care indic numele fiierului. Pentru fiecare fiier, paginile vor fi
numerotate (cu ajutorul unui contor de pagini).
2. Scriei un program care citete un fiier text. Pornind de la coninutul acestuia, se va crea
un alt fiier, prin nlocuirea spaiilor consecutive cu unul singur. Se vor afia pe ecran
coninutul fiierului de la care s-a pornit i coninutul fiierului obinut.
3. S se consulte coninutul unui fiier i s se afieze urmtoarele informaii statistice:
numrul de cuvinte din fiier, numrul de caractere, numrul de linii, numrul de date
numerice (nu cifre, numere!).
4. Scriei un program care s compare coninutul a dou fiiere, i afiai primele linii care
difer i poziia caracterelor diferite n aceste linii.
5. Scriei un program care citete coninutul unui fiier surs scris n limbajul C i afieaz n
ordine alfabetic fiecare grup al numelor de variabile care au primele n caractere identice
(n este citit de la tastatur).
6. Scriei un program care consult un fiier text i afieaz o list a tuturor cuvintelor din
fiier. Pentru fiecare cuvnt se vor afia i numerele liniilor n care apare cuvntul.
7. Scriei un program care citete un text introdus de la tastatur i afieaz cuvintele
distincte, n ordinea cresctoare a frecvenei lor de apariie. La afiare, fiecare cuvnt va fi
precedat de numrul de apariii.
8. Scriei un program care citete un text introdus de la tastatur, ordoneaz alfabetic liniile
acestuia i le afieaz.
9. Scriei o aplicaie pentru gestiunea informatiilor despre crile existente ntr-o bibliotec.
Aplicaia va avea un meniu principal care va permite:
a. Memorarea datelor ntr-un fiier (un fiier binar cu structuri), al crui nume se
introduce de la tastatur. Fiierul va contine informaiile: nume carte, autor, editura,
anul apariiei, pre. Pentru fiecare carte, se va genera o cot (un numr unic care
s constituie cheia de cutare).
b. Adaugrea de noi cri;
c. Afiarea informaiilor despre o anumit carte;
d. Cutarea titlurilor dup un anumit autor;
e. Modificarea informaiilor existente;
f. Lista alfabetic a tuturor autorilor;
g. tergerea unei cri din bibliotec;
h. Ordonarea descresctoare dup anul apariiei;
i. Numele celei mai vechi cri din bibliotec;
j. Numele celei mai scumpe cri din bibliotec;
k. Numele autorului cu cele mai multe cri;
l. Valoarea total a crilor din bibliotec.

99
Laboratorul 19 LISTE
19. LISTE
19.1 Lista simplu nlnuit
19.1.1 Se consider tipul utilizator:
typedef struct tnod{
char *cuvant;
int frecventa;
struct tnod *urm;
} TNOD
Se cere s se scrie funcia incnod care ncarc datele curente ntr-un nod de tip TNOD.
Prin cuvnt se nelege un ir de litere mici sau mari. n acest exerciiu se definete funcia
citcuv care citete un cuvnt de la intrarea standard i-l pstreaz n memoria heap. Funcia
respectiv returneaz adresa de nceput a zonei n care se pstreaz cuvntul citit sau zero
n caz c se ntlnete sfritul de fiier.
Funcia de fa apeleaz funcia citcuv i atribuie adresa returnat de ea pointerului cuvnt
din nodul curent. De asemenea, se atribuie valoarea 1, variabilei frecventa.
//FUNCTIA BX48
char *citcuv()
/* - citeste un cuvint si-l pastreaza in memoria heap;
- returneaza pointcrul spre cuvintul respectiv sau zero la sfirsit de
fisier. */
{
int c,i;
char t[255]; char *p;
/* salt peste caractere care nu snt litere */
while((c=getchar())<'A' || (c>'Z' && c<'a') || c>'z')
if(c==EOF) return 0; /* s-a tastat EOF */
/* se citeste cuvintul si se pastreaza in t */
i=0;
do
{t[i++]=c;}
while((c=getchar())>='A' && c<='Z'|| c>='a' && c<='z');
if(c==EOF) return 0;
t[i++]='\0';
/* se pastreaza cuvintul in memoria heap */
if((p=(char *)malloc(i))==0)
{
printf("memorie insuficienta\n");
exit(1);
}
strcpy(p,t);
return p;
}

Funcia incnod returneaz valoarea -1 dac citcuv returneaz valoarea zero i 1 altfel.
//BX1.cpp
int incnod(TNOD *p)

100
Laboratorul 19 LISTE
/* incarca datele curente in nodul spre care pointeaza p */
{
if((p -> cuvant = citcuv() ) == 0 )
return -1; p ->frecventa = 1; return 1;
}

S se scrie funcia elibnod care elibereaz zonele din memoria heap ocupate de nodul de
tip TNOD definit n exerciiul precedent.
void elibnod(TNOD *p)
/* elibereaza zonele din memoria heap ocupate de nodul spre care pointeaza
p */
{
free(p->cuvant);
free(p);
}

S se scrie funcia adaug, care permite adugarea unui nod de tip TNOD la o list simplu
nlnuit, dup ultimul nod al listei.
Tipul TNOD este cel definit n exerciiul 19.1.1.
TNOD *adauga()
/* - adauga un nod la o lista simplu nlantuita;
- returneaza pointerul spre nodul adaugat sau zero daca nu s-a realizat
adaugarea. */
{
extern TNOD *prim,*ultim; TNOD *p; int n;
n=sizeof(TNOD);
if(((p=(TNOD *)malloc(n))!=0) && (incnod(p)==1))
{
if(prim==0)
prim = ultim =p;
else
{
ultim->urm=p;
ultim=p;
}
p->urm=0;
return p;
}
if(p==0)
{
printf("memorie insuficienta\n");
exit(1);
}
elibnod(p);
return 0;
}

Fie o list simplu nlnuit ale crei noduri au tipul TNOD definit n exerciiul 19.1.1.
S se scrie o funcie care caut n lista respectiv, nodul pentru care pointerul cuvnt are ca
valoare adresa unui cuvnt dat.
Cu alte cuvinte, pointerul cuvnt joac rol de cheie i se cere s se gseasc nodul a crui
cheie pointeaz spre un cuvnt dat.
//BXI4.cpp
TNOD *cncs(char *c)
/* - cauta un nod al listei pentru care cuvintul spre care pointeaza cuvnt
este identic cu cel spre care pointeaza c;

101
Laboratorul 19 LISTE
- returneaza pointerul spre nodul determinat sau zero daca nu exista un
astfel de nod. */
{
extern TNOD *prim;
TNOD *p;
for(p=prim; p ; p=p->urm)
if(strcmp(p->cuvant,c)==0)
return p;
return 0;
}

S se scrie o funcie care terge ultimul nod al unei liste simplu nlnuite ale crei noduri au
aful 11.1.4.3 i ea este dependent numai de pointerul
nod definit n exerciiul 0.
tipul TNOD definit n exerciiul 19.1.1.
Aceast funcie este definit n paragr
urm din tipul nodurilor.
Ea apeleaz funcia elib
//BXI5
void sun() /* sterge ultimul nod din lista */
{
extern TNOD *prim,*ultim;
TNOD *q1,*q;

q1=0;
if(prim==0)
return;
for(q=prim; q&&q!=ultim; q=q->urm)
q1 = q;
if(q==prim )
prim=ultim=0;
else
{
q1->urm=0;
ultim=q1;
}
elibnod(q);
}

19.1.2 S se scrie un program care citete cuvintele dintr-un text i afieaz numrul
ici i/sau mari. Textul se termin prin
mul se realizeaz utiliznd o list simplu nlnuit ale crei noduri
de apariii al fiecrui cuvnt din textul respectiv.
Cuvntul se definete ca o succesiune de litere m
sfiritul de fiier (Ctrl+Z).
n exerciiul de fa progra
au tipul TNOD definit n exerciiul 19.1.1.
El se execut astfel:
1. La ntlnirea unui cuvnt se construiete un nod pentru cuvntul respectiv.
Acesta conine pointerul spre cuvnt, care este pstrai n memoria heap; frecvena de
apariie a cuvntului se face egal cu 1.
2. Nodul construit la punctul 1 se adaug la lista simplu nlnuit care se construiete.
3. Se caut n list un nod care s corespund cuvintului curent.
Dac exist un astfel de nod i acesta nu este ultimul nod al listei, atunci se mrete
frecvena din nodul respectiv i apoi se terge ultimul nod al listei (cel adugat la punctul 2)
deoarece cuvntul exist deja n list.

102
Laboratorul 19 LISTE
Dup pasul 3 se revine la pasul 1 i ciclul continu pn cnd nu mai sunt cuvinte de citit (s-a
ajuns la sfritul de fiier). n acest moment se listeaz cuvintele i frecvena lor de apariie,
corespunztoare nodurilor listei.

//BXI6.cpp
#include <stdio.h>
#include <stdlib.h>
#include <alloc.h>
#include <string.h>

typedef struct tnod{
char *cuvant;
int frecventa;
struct tnod *urm;
} TNOD;

#include "bx48.cpp" /* citcuv */
#include "bxi1.cpp" /* incnod */
#include "bxi2.cpp" /* elibnod */
#include "bxi3.cpp" /* adauga */
#include "bxi4.cpp" /* cncs */
#include "bxi5.cpp" /* sun */

TNOD *prim,*ultim;

void main() /* citeste un text si afiseaza frecventa cuvintelor din text
*/
{
TNOD *p,*q;
prim=ultim=0; /* la inceput lista este vida */
printf("\nIntroduceti textul terminat cu Ctrl-Z:\n");
while((p=adauga())!=0)
/* s-a adaugat la lista un nod corespunzator ultimului cuvint citit */
if((q=cncs(p->cuvant))!=ultim)
{
/* - cuvintul exista intr-un nod care nu este ultimul nod al listei;
- deci exista deja in lista;
- se mareste frecventa lui si se sterge ultimul nod al listei. */
q->frecventa++;
sun();
}
/* listeaza cuvintele si frecventa lor */
for(p=prim; p; p=p->urm)
printf("cuvintul: %-10s are frecventa: %d\n", p->cuvant, p->frecventa);
}

19.2 Stive i cozi
19.2.1 Tren
ntr-o gar se consider un tren de marf ale crui vagoane sunt inventariate ntr-o list, n
ordinea vagoanelor. Lista conine, pentru fiecare vagon, urmtoarele date:
1. codul vagonului (9 cifre);

103
Laboratorul 19 LISTE
2. codul coninutului vagonului (9 cifre);
3. adresa expeditorului (4 cifre);
4. adresa destinatarului (4 cifre).
Deoarece n gar se inverseaz poziia vagoanelor, se cere listarea datelor despre
vagoanele respective n noua lor ordine. n acest scop se creaz o stiv n care se pstreaz
datele fiecrui vagon. Datele corespunztoare unui vagon constituie un element al stivei,
adic un nod al listei simplu nlnuite. Dup ce datele au fost puse pe stiv, ele se scot de
acolo i se listeaz. n acest mod se obine lista vagoanelor n ordine invers celei iniiale.
Stiva este o list simplu nlnuit pe care o gestionm folosind funciile: iniprim i spn.
Funcia iniprim apeleaz funcia incnod i elibnod, iar funcia spn numai funcia elibnod.
Aceste dou funcii (incnod i elibnod) sunt specifice aplicaiei.
Funcia principal apeleaz repetat funcia iniprim pentru a pune datele pe stiv, apoi le
scoate de pe stiv i le listeaz, pn cnd aceasta devine vid.

Programul utilizeaz i funciile pcit_int i pcit_int_lim care sunt definite
nparagrafele 13.4.4.1 i 13.4.4.2

Programul principal:
//PROGRAMUL BXI8 {
#include <stdio.h> printf("cod marfa: ");
#include <alloc.h> if(gets(t) == 0 )
#include <stdlib.h> { printf(er); return 0; }
if(sscanf(t,"%ld",&cod)==1 &&
cod >= 0 && cod <= 999999999)
break;
typedef struct tnod {
long cvag;
long cmarfa; printf("cod marfa eronat\n");
int exp; }
int dest; p->cmarfa=cod;
struct tnod *urm; /* citeste cod expeditor */
} TNOD; if(pcit_int_lim("cod expeditor:
",0,9999, &icod) == 0 ) #include "bviii2.cpp" /* pcit_int
*/
#include "bviii3.cpp" /*
pcit_int_lim */
{ printf(er); return 0; }
p->exp=icod;
/* citeste cod destinatar */
if(pcit_int_lim("cod destinatar:
",0,9999, &icod) == 0 ) int incnod (TNOD *p) /* incarca un
nod cu datele despre vagoane */ { printf(er); return 0; }
{ p->dest=icod; return 1;
char t[255] ; } /* sfirsit incnod */
char er[]="s-a tastat EOF in
pozitie rea\n";

void elibnod ( TNOD *p) /*
elibereaza nodul spre care
pointeaza p */
long cod; int icod;
/* citeste cod vagon */
for( ; ; ) {
{ free(p);
printf("cod vagon: "); } /* sfirsit elibnod */
if(gets(t)==0) return -1; /*
nu mai snt date */

if(sscanf(t,"%ld",&cod)==1 &&
cod >= 0 && cod <= 999999999)
break;
TNOD *iniprim() /* insereaza nodul
curent inaintea primului nod al
listei - push */
{
printf("cod vagon eronat\n"); extern TNOD *prim,*ultim;
} TNOD *p;
p->cvag=cod; int n;
/* citeste cod marfa */ n=sizeof(TNOD);
for( ; ; )

104
Laboratorul 19 LISTE
if(((p=(TNOD *)malloc(n))!=0) &&
(incnod(p)==1))

TNOD *prim, *ultim;
{
if(prim==0) void main () /* listeaza
inventarul vagoanelor in ordinea
inversa citirii lor */
{ prim=ultim=p; p->urm =0; }
else
{ p->urm=prim; prim=p; } {
return p; prim=ultim=0; /* la inceput stiva
este vida */ }
if(p==0) /* se creaza stiva apelind
iniprim pina cind aceasta
returneaza valoarea zero */
{
printf("memorie
insuficienta\n"); while(iniprim()!=0)
exit(1); /* - se listeaza elementul
din virful stivei si apoi se
sterge din stiva;
}
elibnod(p);
return 0; - se repeta pina cind stiva
devine vida. */ } /* sfirsit iniprim */
while(prim!=0)
void spn() /* sterge primul nod
din lista - pop */
{
printf("cod vagon:
%ld\tcontinut: %ld\n", prim-
>cvag, prim->cmarfa);
{
extern TNOD *prim, *ultim;
TNOD *p; printf("expeditor:
%d\tdestinatar: %d\n", prim-
>exp, prim->dest);
if(prim==0) return;
p=prim;
prim=prim->urm; spn();
elibnod(p); }
if(prim==0) ultim=0; } /* sfirsit main */
} /* sfirsit spn */


105
Laboratorul 20 LISTE - continuare
20. LISTE - continuare
20.1 List circular simplu nlnuit
20.1.1 Se consider tipul TNOD declarat ca mai jos:
typedef struct tnod {
char *cuv;
struct tnod *urm;
} TNOD;
Acest tip se utilizeaz n toate exerciiile de la acest paragraf. Mai jos, definim funcia care
ncarc datele ntr-un nod de tipul TNOD.
//FUNCTIA BXI10
int incnod(TNOD *p)
/*- ncarca datele in nodul spre care pointeaza p; - returneaza:
-1 la intilnirca sfirsitului de fisier; 1 altfel. */
{
char t[255];
p -> cuv = 0;/* initializarea cu pointerul nul */
printf("tastati pe un rind cuvintul curent\n");
if(gets(t)==0)
return -1; /* s-a tastat EOF */
/* rezerva zona pentru rindul citit */
if((p->cuv = (char *)malloc(strlen(t)+1)) == 0 )
{
printf("memorie insuficienta\n");
exit(1) ;
}
/* pastreaza rindul citit in memoria heap */
strcpy(p->cuv,t);
return 1;
}


20.1.2 S se defineasc funcia elibnod care elibereaz zonele de memorie ocupate de
un nod de tip TNOD.
//FUNCTIA BXI11
void elibnod(TNOD *p)
/* elibereaza zonele de memorie ocupate de nodul spre care pointeaza p */
{
free(p->cuv);
free(p);
}

20.1.3 S se scrie funcia ccrelist care creaz o list circular ale crei noduri sunt de
tipul TNOD definit n exerciiul 11.10.
//FUNCTIA BXI12

106
Laboratorul 20 LISTE - continuare
int ccrelist()
/* - creaza o lista circulara; - returneaza: 0 la eroare; -1 altfel. */
{
extern TNOD *ptrnod;
int i,n; TNOD *p;

n=sizeof(TNOD);
ptrnod = 0;
while(((p = (TNOD *)malloc(n))!=0) && ((i=incnod(p))==1))
if(ptrnod == 0 )
{ ptrnod = p; ptrnod -> urm = p;}
else
{
p->urm=ptrnod->urm;
ptrnod->urm=p;
ptrnod = p;
}
if(p==0)
{ printf("memorie insuficienta\n") ; exit(1);}
elibnod(p);
return i;
}

20.1.4 S se scrie o funcie care caut un nod al listei circulare create prin funcia
ccrelist, nod pentru care pointerul cuv pointeaza spre un ir de caractere dat.
Funcia returneaza pointerul spre nodul respectiv sau zero dac nu exist un astfel de nod.
//FUNCTIA BXI13
TNOD *ccncs( char *c)
/* - cauta nodul pentru care cuv si c pointeaza spre acelasi sir de
caractere;
- returneaza:
pointerul spre nodul respectiv sau zero daca nu exista un astfel de nod.
*/
{
extern TNOD *ptrnod;
TNOD *p;
p=ptrnod;
if(ptrnod==0)
return 0; /* lista vida */
do
{
if(strcmp(p->cuv,c)==0) return p;
p=p->urm;
}
while(p!=ptrnod);
return 0;
}

20.1.5 Problema lui Josephus
Fie lista circular creat cu ajutorul funciei ccrelist definit n exerciiul 11.12., fie pnod
pointerul spre un nod al listei circulare pentru care: pnod -> cuv pointeaz spre un ir dat
i n > 1 un ntreg de tip int. Se cere nodul din list obinut n urma eliminrii nodurilor din list
n felul urmtor:

107
Laboratorul 20 LISTE - continuare
1. Se pornete cu nodul imediat urmtor nodului care conine pointerul spre irul dat i se
elimin din list al n-lea nod care urmeaz dup acest nod.
2. Se execut pasul 1 continund cu nodul imediat urmtor celui ters, pn cnd lista se
reduce la un singur nod.
Nodul la care s-a redus lista este cel cutat.
Aceast problem se d adesea ca exemplu pentru utilizarea listelor circulare. O variant a
acestei probleme este aa numita problem a lui Josephus. Ea se formuleaz ca mai jos.
O cetate este aprat de un numr de soldai care i dau seama c au nevoie de ajutoare
pentru a rezista n faa dumanului care i atac. Se pune problema de a alege pe unul dintre
ei care s plece dup ajutor.
Alegerea se face aeznd soldaii n cerc i trgnd la sori numele soldatului de la care s
nceap numrtoarea. De asemenea, se trage la sori un numr ntreg n > 1. Se numr, n
sensul acelor ceasornicului, ncepnd cu soldatul urmtor celui al crui nume a fost tras la
sori i al n-lea soldat este scos din cerc. Se continu numrtoarea n acelai fel ncepnd cu
soldatul care urmeaz dup cel scos din cerc. n felul acesta, dup un numr finit de pai,
cercul se reduce la un singur soldat cruia i revine sarcina s plece dup ajutoare.
Problema lui Josephus este o variant a formulrii descrise prin punctele 1-2 de mai sus,
dac se consider c pointerul cuv pointeaz spre numele unui soldat. La punctul 1 se
precizeaz c se pornete cu un nod care urmeaz imediat nodului care conine pointerul
spre un ir dat. Acest ir dat, este chiar numele soldatului tras la sori, care apare n
problema lui Josephus.
Programul de mai jos rezolv aceast problem conform urmtorilor pai:
a. Citete numrul n indicat n formularea problemei.
b. Citete un ir de caractere care definete nodul de la care ncepe numrtoarea.
c. Creaz lista circular care trebuie s conin un nod pentru care cuv pointeaz spre un ir
identic cu cel citit la punctul b.
d. Se elimin nodurile listei circulare conform pailor 1 i 2 indicai mai sus.
e. Se afieaz cuvntul din nodul rmas n list.
//PROGRAMUL BXI14
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <alloc.h>

typedef struct tnod {
char *cuv;
struct tnod *urm;
} TNOD;

#include "bviii2.cpp" /* pcit_int */
#include "bviii3.cpp" /* pcit_int_lim */
#include "bxi10.cpp" /* incnod */
#include "bxi11.cpp" /* elibnod */
#include "bxi12.cpp" /* ccrelist */
#include "bxi13.cpp" /* cencs */
#define MAXN 1000

TNOD *ptrnod;

void main() /* - creeaza o lista circulara si elimina nodurile ei pornind
de la un nod dat si eliminind tot al n-lea nod pina cind lista se reduce la
un singur nod;
- in final se listeaza sirul spre care pointeaza cuv al nodului la care
s-a redus lista. */
{

108
Laboratorul 20 LISTE - continuare
char t[255]; int i,n;
char er[]="s-a tastat EOF\n";
TNOD *p,*p1;
/* citeste pe n */
if(pcit_int_lim("n= ",2,MAXN,&n) == O )
{ printf(er); exit(l); }
/* citeste un sir de caractere care va defini nodul din lista pentru
pornirea numararii nodurilor */
printf("sirul pentru pornirea numararii\n");
if(gets(t) == 0 )
{ printf(er); exit(1); }
/* creaza lista circulara */
printf("tastati sirurile care intra in compunerea listei\n");
printf("cite un sir pe un rind\n");
printf("la sfirsit se tasteaza Ctrl-Z\n");
ccrelist();
/* se determina nodul pentru care cuv pointeaza spre un sir identic cu cel
pastrat in tabloul t */
if((p = ccncs(t)) == 0 )
{
/* nu exista un nod pentru care sirul spre care pointeaza cuv sa coincida
cu cel pastrat in t */
printf("nu se poate determina nodul de la care sa se inceapa
numararea\n"); exit(l); }
/* elimina nodurile din lista pina se ajunge la un singur nod */
p=p ->urm;
/* numaratoarea incepe cu nodul urmator celui pentru care cuv pointeaza
spre un sir identic cu cel pastrat in t */
while(ptrnod != ptrnod -> urm )
{
/* lista contine mai mult de un nod */
/* se cauta al n-lea nod incepind cu cel spre care pointeaza p */
for(i=1;i<n;i++)
{ pi = p; p = p -> urm; }
/* - se sterge nodul spre care pointeaza p;
- pi pointeaza spre nodul precedent nodului spre care pointeaza p. */
pi->urm=p->urm;
if(ptrnod==p) ptrnod = pi;
free(p->cuv);
free(p);
p = pi -> urm; /* numaratoarea continua incepind cu nodul urmator celui
sters */ }
/* lista s-a redus la un singur nod */
printf("sirul cautat: \n");
printf("%s\n", ptrnod -> cuv );
}

20.2 List dublu nlnuit
20.2.1
Se consider tipul utilizator:
typdef struct tnod
{

109
Laboratorul 20 LISTE - continuare
char *cuvant;
int frecventa;
struct tnod *prec;
struct tnod *urm;
} TNOD
S se scrie funcia dadauga, care permite adugarea la o list dublu nlnuit a unui nod de
a definit n paragraful 11.4.2.4, este dependent numai de
tipul TNOD definit ca mai sus.
Se observ c funcia dadaug
componentele prec i urm din TNOD. De aceea, funcia dadauga de mai jos este identic cu
cea din paragraful 11.4.2.4.
//FUNCTIA BXI15
TNOD *dadauga()
/* - adauga un nod la o lista dublu nlantuita;
- returneaza pointerul spre nodul inserat sau zero daca nu se realizeaza
inserarea. */
{
extern TNOD *prim,*ultim; TNOD *p; int n;
n = sizeof(TNOD);
if(((p = (TNOD *)malloc(n))!=0) && (incnod(p)==1))
{
if(prim==0)
{ prim = ultim = p; p -> prec = p -> urm = 0;}
else
{
ultim -> urm = p;
p -> prec = ultim;
p -> urm = 0;
ultim = p;
}
return p;
}
if(p==0)
{printf("memorie insuficienta\n"); exit(1);}
elibnod(p);
return 0;
}

20.2.2
crie o funcie S se s care terge ultimul nod al unei liste dublu nlnuite ale crei noduri au
tipul TNOD definit n exerciiul precedent.
//FUNCTIA BXI16
void dsun () /* sterge ultimul nod din lista*/
{
extern TNOD *prim,*ultim;
TNOD *p;
if(prim==0)
return;
p=ultim;
ultim=ultim->prec;
if(ultim==0) prim=0;
else ultim->urm=0;
elibnod(p);
}

20.2.3
S se scrie un program care citete cuvintele dintr-un text i afieaz numrul de apariii al
fiecrui cuvnt din textul respectiv.

110
Laboratorul 20 LISTE - continuare
n cazul de fa, se utilizeaz o list dublu nlnuit. Prin aceasta, eficiena programului este
n care realizeaz acelai lucru relativ la o list simplu
mai mare deoarece funcia dsun, care terge ultimul nod dintr-o list dublu nlnuit, este
mult mai eficient dcct funcia su
nlnuit.
Programul de fa utilizeaz funciile : citcuv; incnod; elibnod; cncs..
//PROGRAMUL BXI17
#include <stdio.h>
#include <stdlib.h>
#include <alloc.h>
#include <string.h>
typedef struct tnod {
char *cuvant;
int frecventa;
struct tnod *prec;
struct tnod *urm;
} TNOD;

#include "bx48.cpp" /* citcuv */
#include "bxi1.cpp" /* incnod */
#include "bxi2.cpp" /* elibnod */
#include "bxi15.cpp" /* dadauga */
#include "bxi4.cpp" /* cncs */
#include "bxi16.cpp" /* dsun */

TNOD *prim,*ultim;

void main () /* citeste un text si afiseaza frecventa cuvintelor din textul
respectiv */
{
TNOD *p,*q;
prim=ultim=0;
while((p=dadauga())!=0)
if((q=cncs(p->cuvant))!=ultim )
{q->frecventa++; dsun(); }
for( p=prim; p; p=p -> urm)
printf("cuvintul: %-51s are frecventa: %d\n", p->cuvant, p->frecventa);
}

20.2.4
S se scrie un program care citete cuvintele dintr-un text i scrie numrul de apariie al
fiecrui cuvnt, n ordinea alfabetic a cuvintelor respective.
problem a fost rezolvat n exerciiul 11.7. n exerciiul respectiv s-a definit funcia
alizeaz acelai lucru ca i funcia
liznd ordinea cuvintelor corespunztoare
et ele s fie nlnuite
in list.
Aceast
ordlist care s-a apelat nainte de a afia frecvena cuvintelor citite. Ea a modificat nlnuirile
nodurilor listei simplu nlnuite create prin citirea cuvintelor textului, n aa fel net cuvintele
corespunztoare nodurilor listei s fie ordonate alfabetic.
Programul definit n exerciiul 11.7. difer de cel defint n exerciiul 11.6. prin prezena funciei
ordlist i apelul ei nainte de listarea rezultatului.
n exerciiul de fa se definete funcia dordlist care re
ordlist, adic modific nlnuirile nodurilor unei liste dublu nlnuite.
Amintim c funcia ordlist parcurge lista ana
nodurilor vecine. Dac dou cuvinte, care corespund la noduri vecine, nu sunt n ordine
alfabetic, atunci se schimb nlnuirile nodurilor respective aa n
invers n list.
Inversarea nlnuirilor se realizeaz ca mai jos.
Presupunem c p pointeaz spre nodul curent din list i q = p -> urm, deci q pointeaz spre
nodul urmtor d

111
Laboratorul 20 LISTE - continuare
Dac p -> cuvnt pointeaz spre un cuvnt care este n ordine alfabetic dup cuvintul spre
implic paii:
m -> prec = p, deoarece precedentul urmtorului lui q
= q -> urm, deoarece urmtorul lui q devine urmtorul lui p.
c = p -> prec, deoarece precedentul lui p devine precedentul lui q
care pointeaz q -> cuvnt, atunci nodurile p i q se nlnuiesc invers, deci p devine
urmtorul lui q. Aceasta
1. Dac p -> prec != 0, atunci p -> prec ->urm = q, deoarece urmtorul precedentului lui p
devine q.
2. Dac q -> urm != 0, atunci q -> ur
devine p.
3. p->urm
4. q -> urm = p, deoarece p devine urmtorul lui q.
5. q -> pre
6. p -> prec = q, deoarece q devine precedentul lui p.

//PROGRAMUL BXI17
#include <stdio.h>
#include <stdlib.h>
#include <alloc.h>
#include <string.h>
typedef struct tnod {
char *cuvant;
int frecventa;
struct tnod *prec;
struct tnod *urm;
} TNOD;

#include "bx48.cpp" /* citcuv */
#include "bxi1.cpp" /* incnod */
#include "bxi2.cpp" /* elibnod */
#include "bxi15.cpp" /* dadauga */
#include "bxi4.cpp" /* cncs */
#include "bxi16.cpp" /* dsun */

TNOD *prim,*ultim;

void main () /* citeste un text si afiseaza frecventa cuvintelor din textul
respectiv */
{
TNOD *p,*q;
prim=ultim=0;
while((p=dadauga())!=0)
if((q=cncs(p->cuvant))!=ultim )
{q->frecventa++; dsun(); }
for( p=prim; p; p=p -> urm)
printf("cuvintul: %-51s are frecventa: %d\n", p->cuvant, p->frecventa);
}



112
Laboratorul 21 GESTIUNEA ECRANULUI N MOD TEXT
21. GESTIUNEA ECRANULUI N MOD TEXT
21.1 Setarea culorilor
21.1.1 Afiarea parametrilor ecranului
S se scrie o funcie care afieaz parametrii ecranului.
//FUNCTIA BXVIII1
void pecr() /* afiseaza parametrii ecranului */
{
struct text_info parecr;
clrscr();
gettextinfo(&parecr);
printf("stinga:%u\t sus:%u\t dreapta:%u\t
jos:%u\n",parecr.winleft,parecr.wintop,parecr.winright, parecr.winbottom);
printf("atribut:%u\t mod curent:%u\n", parecr.attribute,parecr.currmode);
printf("inaltimea ecranului:%u\t latimea ecranului:%u\n",parecr.screenheight,
parecr.screenwidth);
printf("coloana cursorului:%u\t linia cursorului:%u\n",parecr.curx,parecr.cury);
}


Apoi, folosind aceast funcie, s se scrie un program care seteaz pe rnd modurile text,
definite cu ajutorul constantelor simbolice: BW40, C40, BW80, C80 i C4350 i afieaz
parametrii ecranului pentru fiecare din modurile respective.
//PROGRAMUL BXVIII2
#include <stdio.h>
#include <conio.h>
#include "bxviii1.cpp"

void main ()
/* seteaza modurile definite cu
ajutorul constantelor simbolice
BW40, C40, BW80, C80 si C4350
si afiseaza parametrii ecranului
in fiecare caz */
{
int i;
int
tab[]={BW40,C40,BW80,C80,C4350} ;
char
*text[]={"BW40","C40","BW80","C80","C
4350"};
for(i=0;i<5;i++)
{
textmode(tab[i]);
pecr();
printf("\n\t\t\t%s\n\n",text[i]);
printf ("Actionati o tasta pentru a
continua\n");
getch();
}
}

21.1.2 Modurile video alb/negru
S se scrie un program care afieaz texte n modurile video intens i video normal.
#include <conio.h>
void main () /* afiscaza texte in modurile video intens si normal */
{
textmode(BW80);
window(10,4,60,4);
clrscr();
lowvideo();
cputs(" lowvideo");

113
Laboratorul 21 GESTIUNEA ECRANULUI N MOD TEXT
highvideo();
cputs(" highvideo");
normvideo();
cputs(" normvideo");
textmode(LASTMODE) ;
cprintf("\n\rActionati o tasta pentru continua" );
getch();
}

21.2 Gestiunea textelor
21.2.1 Combinaii de culori
S se scrie un program care afieaz toate combinaiile de culori posibile pentru fond i
caractere. Se consider c se dispune de un adaptor color EGA/VGA.
#include <conio.h>
#include <stdio.h>

main () /* - afiseaza toate combinatiile de culori posibile pentru fond si
caractere; - se dispune de un adaptor EGA/VGA. */
{
static char *tculoare[] = {
"0 BLACK negru",
"1 blue albastru",
"2 GREEN verde",
"3 CYAN turcoaz",
"4 RED rosu",
"5 MAGENTA purpuriu",
"6 BROWN maro",
"7 LIGHTGRAY gri deschis",
"8 DARKGRAY gri inchis",
"9 LIGHTBLUE albastru deschis",
"10 LIGHTGREEN verde deschis",
"11 LIGHTCYAN turcoaz deschis",
"12 LIGHTRED rosu deschis",
"13 LIGHTMAGENTA purpuriu deschis",
"14 YELLOW galben",
"15 WHITE alb"
};
int i,j,k;
struct text_info atr;
gettextinfo(&atr);
for(i=0; i <8; i++){
/* i alege culoarea fondului */
window(3,2,60,20); k=2;
textbackground(i);
clrscr();
for(j=0; j < 16; j++, k++) {
textcolor(j);
gotoxy(2,k);
/* j alege culoarea caracterului */
if(i == j)
continue;
cputs(tculoare[j]);

114
Laboratorul 21 GESTIUNEA ECRANULUI N MOD TEXT
}
gotoxy(1,18);
printf("actionati o tasta pentru a continua\n");
getch();
}
window(atr.winleft,atr.wintop, atr.winright, atr.winbottom);
textattr(atr.attribute);
clrscr();
}

21.2.2 Funcia fereastr
S se scrie o funcie care afieaz o fereastr limitat de un chenar i pe fondul creia se
(int st, int sus, int dr, int jos, int fond, int
unde:
) - Coordonatele col
loarea de fond a ferestrei.
caracterelor.
void far *stiva[100];
Locul liber n tablou se definete tiva: int istiva;
afieaz un ntreg. Cursorul devine invizibil la afiarea ferestrei.
Funcia are prototipul:
void fereastra
culoare, int chenar, int n);
ului din stnga sus. (st, sus
(dr, jos) - Coordonatele colului din dreapta jos.
fond - ntreg din intervalul [0,7] care definete cu
culoare - ntreg din intervalul [0,15] care definete culoarea pentru afiarea
chenar - Definete tipul chenarului: 0 - fr bordur; 1 - linie simpl; 2 - linie dubl; n -
numrul ntreg care se afieaz n fereastr ncepnd cu punctul de coordonate relative (3,3).
Zona de ecran in care se afieaz fereastra se pstreaz n memoria heap nainte de a se
afia fereastra. Adresa acestei zone de memorie se pune pe o stiv definit cu ajutorul unui
tablou de pointeri spre tipul void. Acest tablou este global i are 100 de elemente. El se
definete astfel:
cu ajutorul variabilei globale is
//PROGRAMUL BXVIII6 if((stiva[istiva]->zonfer=
void orizontal(int,int);
void vertical(int,int,int,int);
void fereastra(int st, int sus,
int dr, int jos, int fond, int
culoare, int chenar, int n)
/* afiaeaza o fereastra limitata
farmalloc(2*(dr-st+1)*(jos-
sus+1)))==0){
printf("\nmemorie insuficienta\n");
exit(1);
}
stiva[istiva]->x=st; stiva[istiva]-
de un chenar si pe fondul careia
se afiaeaza numarul ferestrei */
{
>y=sus;
stiva[istiva]->u=dr; stiva[istiva]-
>v=jos;
if((gettext(st,sus,dr,jos,stiva[istiv extern ELEM far *stiva[];
extern int istiva; a]-> zonfer))==0){
printf("\neroare la memorarea /* memoreaza partea din ecran pe
care se va afisa fereastra */
if(istiva==MAX){
ecranului\n");
exit(1);
printf("\nprea multe ferestre\n"); }
exit(1);
}
istiva++;
if((stiva[istiva]= (ELEM
/* activeaza fereastra si o afiaeaza
pe ecran */
window(st,sus,dr,jos); *)farmalloc(sizeof(ELEM)))==0){
printf("memorie insuficienta\n"); textattr(16*fond+culoare); clrscr();
/* trasare chenar */ exit(1);
if(chenar){ }
textcolor(WHITE); highvideo();
/* coltul stinga sus */

115
Laboratorul 21 GESTIUNEA ECRANULUI N MOD TEXT
switch(chenar){ /* sfirsit afi?are chenar */
case SIMPLU: putch(218); break; /* scrie pe n in fereastra */
case DUBLU: putch(201); break; } gotoxy(3,3); cprintf("%d",n);
/* chenar orizontal sus */ /* ascunde cursor */
orizontal(dr-st-2,chenar); _AH=1;
/* coltul dreapta sus */ _CH=0x20;
switch(chenar){ geninterrupt(0x10);
case SIMPLU: putch(191); break; } /* sfirsit fereastra */
case DUBLU: putch(187); break; }
/* chenar vertical sting? */ void orizontal(int a,int chenar) /*
vertical(jos-sus,1,2,chenar); traseaz? un chenar orizontal */
{ while(a--) /* coltul sting? jos */
gotoxy(1,jos-sus+1); switch(chenar){
switch(chenar){ case SIMPLU: putch(196); break;
case SIMPLU: putch(192); break; case DUBLU: putch(205); break; }
case DUBLU: putch(200); break; } }
/* chenar orizontal jos */
orizontal(dr-st-2,chenar); void vertical(int a,int col,int
/* chenar vertical dreapta */ lin,int chenar)
{ while(a--) { vertical(jos-sus-1,dr-
st,2,chenar);
/* coltul dreapta jos
gotoxy(col,lin++);
*/ switch(chenar){
gotoxy(dr-st,jos-sus+1); case SIMPLU: putch(179); break;
switch(chenar){ case DUBLU: putch(186); break; }
case SIMPLU: putch(217); break; }
case DUBLU: putch(188); break;} }
normvideo();
textattr(16*fond+culoare); }
21.2.3 Ferestre aleatoare
S se scrie un program care afieaz ferestre pe ecran n mod aleator. Ferestrele sunt de
dimensiune fix, dar au poziii aleatoare pe ecran. De asemenea, ele pot avea chenar format
dintr-o linie simpl sau dubl sau s nu aib chenar. Culorile de fond i de afiare a
caracterelor sunt aleatoare. Ferestrele se numeroteaz i numrul ferestrei se afieaz n
fereastr. Prima fereastr afiat se numeroteaz cu 1.
Dup afiarea unei ferestre se va aciona o tast oarecare, corespunztoare codului ASCII,
pentru a afia fereastra urmtoare. Se revine la fereastra precedent dac se acioneaz
tasta ESC.
Execuia programului se termin n cazul n care se acioneaz tasta ESC n momentul n
care nu este afiat nici o fereastr. Se presupune c se dispune de un adaptor color
EGA/VGA.
Programul utilizeaz i funciile pcit_int i pcit_int_lim care sunt definite
nparagrafele 13.4.4.1 i 13.4.4.2

//PROGRAMUL BXVIII7
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include<alloc.h>
#include<dos.h>
#define MAX 100
#define ESC 0x1b
#define SIMPLU 1
#define DUBLU 2

typedef struct{

116
Laboratorul 21 GESTIUNEA ECRANULUI N MOD TEXT
int x,y,u,v;
void far *zonfer; } ELEM;
ELEM far *stiva[MAX];
int istiva;

#include "bviii2.cpp" /* pcit_int */
#include "bviii3.cpp" /* pcit_int_lim */
#include "bxviii6.cpp" /* fereastra */

void main () /* afiseaza ferestre pe ecran in mod aleator */
{
int c,culoare,fond,i,inalt,j,lung,s,stanga,sus; struct text_info info, crt;
struct time ora_crt;
istiva=0; clrscr();
/* pastreaza tot ecranul */
if((stiva[istiva]=(ELEM *)farmalloc(sizeof(ELEM)))==0)
{printf("memorie insuficienta\n"); exit(1);}
if((stiva[istiva]->zonfer=farmalloc(2*80*25))==0)
{printf("memorie insuficienta\n"); exit(1);}
if(gettext(1,1,80,25,stiva[istiva]->zonfer)==0)
{printf("nu se poate salva ecranul\n"); exit(1);}
istiva++;
/* salveaza parametrii ecranului */
gettextinfo(&info);
/* citeste dimensiunile ferestrelor: lungimea si inaltimea */
if(pcit_int_lim("lungime:",8,70,&lung)==0)
{printf("s-a tastat EOF\n"); exit(1);}
if(pcit_int_lim("inaltime:",5,15,&inalt)==0)
{printf("s-a tastat EOF\n"); exit(1);}
/* coordonatele maxime pentru coltul din stinga sus a ferestrelor */
i=79-lung; j=25-inalt;
/* seteaza saminta pentru sirul de numere pseudo-aleatoare care definesc
parametrii ferestrelor:
- coltul din sting? sus;
- atributul de culoare. */
gettime(&ora_crt);
s=(3600L*ora_crt.ti_hour+60*ora_crt.ti_min+ora_crt.ti_sec)%65535;
srand(s);
printf("Actionati o tasta pentru a continua\n");
printf("cu ESC se revine la ecranul precedent\n");
for(;;){
c=getch();
if(c!=ESC)
{
/* s-a tastat un caracter diferit de ESC */
/* se genereaz? parametrii ferestrei */
stanga=random(i)+1;
sus=random(j) + 1;
fond=random(8);
while((culoare=random(15)+1)!=fond)
fereastra(stanga,sus,stanga+lung,sus+inalt,
fond,culoare,istiva%3,istiva); continue;
}
/* s-a tastat ESC */
if(--istiva>0){
/* se reface zona din ecran eliminind fereastra activa */
puttext(stiva[istiva]->x,stiva[istiva]->y, stiva[istiva]->u,
stiva[istiva]->v, stiva[istiva]->zonfer);

117
Laboratorul 21 GESTIUNEA ECRANULUI N MOD TEXT
farfree(stiva[istiva]);}
else
/* se ntrerupe execu?ia programului */
break; }
puttext(info.winleft,info.wintop,info.winright, info.winbottom,stiva[0]);
window(1,1,80,25); farfree(stiva[0]); textattr(info.attribute);
/* afiseaza cursorul */
_AH=1; _CH=6; _CL=7;
geninterrupt(0x10);
clrscr();
}

Pentru executia programului sunt necesare i urmtoarele fisiere:
FUNCTIA BVIII2 //
int pcit_int(char text[], int *x)
/* - citeste un intreg si-1 pastreaza in zona de memorie a carei adresa
este
valoarea lui x;
- returneaza:
0 - la intilnirea sfirsitului de fisier;
1 - altfel */
{
char t[255];
for( ; ; )
{
printf(text);
if(gets(t) == NULL) return 0;
if(sscanf(t,"%d", x) == 1) return 1;
}
}


//FUNCTIA BVIII3
int pcit_int(char [], int *); /* prototip */

int pcit_int_lim(char text[], int inf, int sup, int *pint)
/* - citeste un intreg de tip int ce apartine intervalului [inf.sup] si-1 p
?streaz ? in zona de memorie a c ?rei adresa este valoarea parametrului
pint; - returneaz ?:
0 - la intilnirea sfirsilului de fisier;
1 - altfel. */
{
for(;;)
{
if(pcit_int(text, pint) == 0) return 0; /* s-a intilnit EOF */
if(*pint >= inf && *pint <= sup) return 1;
printf("intregul tastat nu apartine intervalului:");
printf("[%d,%d]\n", inf,sup);
printf("se reia citirea\n");
}
}

21.2.4 Sagei
S se construiasc un program care s deplaseze pe ecran un caracter cu ajutorul sgeilor.

118
Laboratorul 21 GESTIUNEA ECRANULUI N MOD TEXT
Strategia de rezolvare: Ecranul n modul text este compus din 25 de linii i 80 de coloane,
lasarea cu o
nte);
.
execuia
acest exemplu
fiecare element din aceast matrice ecran putnd fi ocupat de ctre un caracter.
Originea ecranului este n colul din stnga sus, iar colul din dreapt jos reprezint ultima
poziie a ecranului. Afiarea unui caracter pe ultima poziie a liniei 25 duce la dep
linie n sus a poriunii afiate a ecranului (astfel, prima linie este tears iar linia 25 devine
linia 24 a ecranului). O anumit poziiei de pe ecran este accesat cu o combinaie de forma:
(coloan, linie). Deplasarea cursorului pe ecran se face n funcie de codul tastei sgeat
apsate:
Sgeat sus - codul 72 (reducerea cu o unitate a numrului liniei curente);
Sgeat jos - codul 82 (creterea cu o unitate a numrului liniei curente);
Sgeat stnga - codul 75(reducerea cu o unitate a numrului coloanei cure
Sgeat dreapta - 77(creterea cu o unitate a numrului coloanei curente)
La apsarea tastei Enter (cod 27) se iese din ciclul do-while i se ntrerupe
programului. Este de remarcat c numrul maxim de linii ecran utilizate n
este 24 iar c atingerea uneia din marginile ecranului nu are nici un efect privind deplasarea
caracterului. La deplasarea cursorului cu o poziie se terge mai nti poziia veche i apoi se
afieaz caracterul pe noua poziie.
/* Program 21. Prisecaru&Ene
Deplaseaza pe ecran cursorul cu ajutorul tastelor cu sageti */
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>

void main()
{
clrscr();
char tasta;
char x=40, y= 12;
gotoxy(x,y);
putch(1);
do
{
tasta=getch(); gotoxy(x,y); putch(' ');
switch(tasta)
{
case 72: {if(y>1) y--; break;}
case 80: {if(y<24) y++; break;}
case 75: {if (x>1) x--; break;}
case 77: {if(x<80) x++; break;}
}
gotoxy(x,y); putch(1);
}
while(tasta!=27);
}



Acelai program poate fi modificat n sensul modificrii caracterului afiat i a culorii acestuia
deplasarea pe una din marginile ecranului (x = 1 sau 80 sau y = 1 sau 24). Culoarea unui la
caracter afiat pe ecran este controlat de funcia textcolor(nr_culoare) unde nr_culoare = 0 -
15, 0 corespunznd culorii negru iar 15 corespunznd culorii alb. La deplasarea pe una din
liniile sau coloanele extreme ale ecranului, culoarea se modific aleator n intervalul 015.
/* Program 21. Prisecaru&Ene
Deplaseaza pe ecran cursorul cu ajutorul tastelor cu sageti */
#include<stdio.h>

119
Laboratorul 21 GESTIUNEA ECRANULUI N MOD TEXT
#include<conio.h>
#include<stdlib.h>

void main()
{
clrscr();
char tasta;
char x=40, y= 12;
gotoxy(x,y);
putch(1);
do
{
tasta=getch(); gotoxy(x,y); putch(' ');
switch(tasta)
{
case 72: {if(y>1) y--; break;}
case 80: {if(y<24) y++; break;}
case 75: {if (x>1) x--; break;}
case 77: {if(x<80) x++; break;}
}
gotoxy(x,y); putch(1);
}
while(tasta!=27);
}



21
modul text.
.2.5 Construirea unui meniu de comenzi tip bar orizontal cu ase cmpuri, n
Strategia de rezolvare: Pentru memorarea numelui comenzilor se va folosi un vector de iruri
de caractere. Deoarece C++ nu are predefinit un tip ir de caractere (cum ar fi n cazul
l cu lungimea maxim a numelui unei
ate.
int cit_cod()
eturna, pentru acest al doilea apel, o
Program pentru scrierea unui program cu o
limbajului Pascal tipul "string") ci doar funcii pentru prelucrarea irurilor de caractere (incluse
n biblioteca <string. h>) va trebui s definim tipul:
typedef char numeoriz[11];
avnd dimensiunea irului de caractere (11) ega
comenzi, la care se adaug o unit
Pentru citirea codului tastelor cu sgei: "stnga", "dreapta" i "enter", taste care nu ntorc
caractere afiabile, se va folosi funcia
Dac la citirea codului tastei apsate se obine valoarea 0 (caz ntlnit pentru tastele
speciale) se va apela din nou funcia getch(), care va r
valoare nenul.

/* Program 28
bara de meniu-uri orizontala,in modul text.*/
#define num 6 // Numarul de comenzi din meniu
#define true 0
#define false 1
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
typedef char nume_oriz[11];
nume_oriz items[num]={" Fisier "," Editare "," Compilare"," Optiuni ","
Depanare ","Terminare"};

int cit_cod()

120
Laboratorul 21 GESTIUNEA ECRANULUI N MOD TEXT
{ //Citeste codul tastei apasate.
int cod;
do
{cod=getch(); }
while(cod==0);
return cod;
}

void sterg_ecran()
{
window(1,1,80,25);
textcolor(15); textbackground(0);
clrscr();
}

void afisez(nume_oriz sir[num], int pos)
{
int j;
gotoxy(1,1);
textbackground(YELLOW);textcolor(BLUE);
for(j=1; j<num+1; j++)
if(j==pos)
{
textbackground(RED); textcolor (WHITE);
cprintf("%s",sir[j-1]);
textbackground(YELLOW); textcolor(BLUE);
}
else cprintf("%s",sir[j-1]);
}

void action(nume_oriz sir[num], int pos)
{
window(5,5,15,5) ;
textbackground(YELLOW); textcolor(LIGHTBLUE);
gotoxy(1,1); cprintf("%s",sir[pos-1]);
switch(pos)
{
case num: sterg_ecran(); exit(0); break;
}
}

void main()
{
const int stanga=75, dreapta=77, enter=13;
int poz_curnt, code; _setcursortype(_NOCURSOR);
sterg_ecran();
textbackground(WHITE); textcolor(LIGHTBLUE);
clrscr(); poz_curnt=1;
window(1,1,num*11+1,1);
afisez(items,poz_curnt);
while(!true)
{
fflush(stdin);
code=cit_cod();
if((code==stanga)||(code==dreapta)||(code==enter))
{
switch(code)
{

121
Laboratorul 21 GESTIUNEA ECRANULUI N MOD TEXT
case stanga:
{if(poz_curnt>1) poz_curnt=poz_curnt-1;
else poz_curnt=num; break; }
case dreapta:
{if(poz_curnt<num) poz_curnt=poz_curnt+1;
else poz_curnt=-1;break; }
case enter: action(items,poz_curnt);
}
window(1,1,num*11+1,1);
afisez(items,poz_curnt);
}
}
}

n cazul n care tasta apsat corespunde u
a incrementa, sau dup
nuia din codurile (stnga=75 sau dreapta=77),
caz decrementa, cu o unitate; nainte
ceast operaie se verific dac noua valoare a poziiei curente nu se afl n afara limitei
.num).
apsarea tastei ENTER (cod 13) se va lansa n execuie funcia
poziia curent a cursorului se v
de a
(1..
La action(items,
crtpos); care va imprima pe ecran ntr-o fereastr special numele comenzii n dreptul
creia s-a tastat ENTER. n cazul n care poziia curent este num. programul i nceteaz
execuia.
Pentru a ascunde cursorul n timpul deplasrii prin meniul orizontal de comenzi, se utilizeaz
funcia _setcursortype(_NOCURSOR);. Funcia clearscreen(); restaureaz forma i
culoarea iniial a ecranului.

122
Laboratorul 22 GESTIUNEA ECRANULUI N MOD GRAFIC
22. GESTIUNEA ECRANULUI N MOD GRAFIC
22.1.1 Setarea modului grafic
S se scrie un program care seteaz modul grafic n dou feluri: cu ajutorul funciei
detectgraph; fr aceast funcie. Programul afieaz rezultatele setrii.
#include<conio.h>
#include<stdio.h>
#include<graphics.h>

void main () /*seteaza modul grafic si afiseaza parametrii setarii */
{
int gdriv,gmod;
int mod,min,max;
/* setare prin apelul functiei detectgraph */
detectgraph(&gdriv,&gmod);
printf("valori dupa apelul functiei\ detectgraph\n");
printf("driver=%d\tmod grafic=%d\n",gdriv,gmod);
printf("Actionati o tasta pentu a continua\n");
getch();
initgraph(&gdriv, &gmod,"c:\\borlandc\\bgi");
printf("valori dupa initgraph\n");
printf("driver=%d\tmod grafic=%d\n",gdriv,gmod);
printf("Actionati o tasta pentru a continua\n");
getch();
closegraph();

/* setare fara apelul lui detectgraph */
gdriv=DETECT;
initgraph(&gdriv, &gmod, "c:\\borlandc\\bgi");
printf("initializare fara detectgraph\n");
printf("driver=%d\tmod grafic=%d\n",gdriv,gmod);
printf("Actionati o tasta pentru a continua\n");
getch();

/* afiseaza numele adaptorului grafic curent */
printf("adaptor grafic: %s\n",getdrivername());
mod=getgraphmode();
printf("cod mod=%d\tmod grafic:%s\n",mod,getmodename(mod));
getmoderange(gdriv,&min,&max);
printf("domeniul pentru adaptorul grafic=[%d,%d]\n",min,max);
printf ("Actionati o tasta pentru a continua");
getch();
closegraph();
}

22.2 Gestiunea culorilor
S se scrie un program care afieaz codurile culorilor pentru paleta implicit.
#include<graphics.h>

123
Laboratorul 22 GESTIUNEA ECRANULUI N MOD GRAFIC
#include<stdlib.h>
#include<stdio.h>
#include<conio.h>

void main() /* afiseaza:
- culoarea fondului;
- culoarea pentru desenare;
- coordonatele maxime;
- coordonatele pixelului curent. */
{
int gd=DETECT,gm,cul_fond,cul_desen,crt_x,crt_y,maxx,maxy;
initgraph(&gd,&gm,"c:\\borlandc\\bgi");
cul_fond=getbkcolor(); cul_desen=getcolor();
maxx=getmaxx(); maxy=getmaxy();
crt_x=getx(); crt_y=gety();
closegraph();
printf("culoarea fondului=%d\n", cul_fond);
printf("culoarea pentru desenare=%d\n",cul_desen);
printf("abscisa maxima=%d\n",maxx);
printf("ordonata maxima=%d\n",maxy);
printf("abscisa curenta=%d\n",crt_x);
printf("ordonata curenta=%d\n",crt_y);
printf("Actionati o tasta pentru a continua\n");
getch();
closegraph();
}


22.2.1 Starea ecranului
S se scrie un program care afieaz urmtoarele informaii:
culoarea fondului;
culoarea pentru desenare;
coordonatele maxime;
coordonatele pixelului curent.

#include<graphics.h>
#include<stdlib.h>
#include<stdio.h>
#include<conio.h>

main() /* afi ?eaz ?:
- culoarea fondului;
- culoarea pentru desenare;
- coordonatele maxime;
- coordonatele pixelului curent. */
{
int gd=DETECT,gm,cul_fond,cul_desen,crt_x,crt_y,maxx,maxy;
initgraph(&gd,&gm,"c:\\borlandc\\bgi");
cul_fond=getbkcolor(); cul_desen=getcolor();
maxx=getmaxx(); maxy=getmaxy();
crt_x=getx(); crt_y=gety();
closegraph();
printf("culoarea fondului=%d\n", cul_fond);
printf("culoarea pentru desenare=%d\n",cul_desen);
printf("abscisa maxima=%d\n",maxx);
printf("ordonata maxima=%d\n",maxy);

124
Laboratorul 22 GESTIUNEA ECRANULUI N MOD GRAFIC
printf("abscisa curenta=%d\n",crt_x);
printf("ordonata curenta=%d\n",crt_y);
printf("Ac ?iona ?i o tasta pentru a continua\n");
getch();
closegraph();
}

22.2.2 Gestiunea textelor
afieaz texte folosind toate cele 5 fonturi, caracterele avnd pe
include <graphics.h>
S se scrie un program care
rnd dimensiunile 1, 2, 3 i 4. n cazul fonturilor diferite de DEFAULT_FONT, se vor afia
texte ale cror caractere se vor afla n rapoartele: 4/3 n lime; 2/1 n nlime.

#
#include <conio.h>
#include <stdio.h>
#include <string.h>

char path[]="C:\\Soft\\BC31\\BGI";

void main() /* afiseaza texte cu diferite fonturi si dimensiuni */
{
int gdriver=DETECT,gmod;
char *denfont[]={ "Val=0 DEFAULT_FONT", "Val=1 TRIPLEX_FONT", "Val=2
SMALL_FONT", "Val=3 SANS_SERIF_FONT", "Val=4 GOTHIC_FONT" };
int stil,x=0,y=0; int dim;
char dimensiune[30];
for(dim=1;dim<5;dim++)
{
y=0;
initgraph(&gdriver,&gmod,path);
for(stil=DEFAULT_FONT;stil<=GOTHIC_FONT;stil++)
{
settextstyle(stil,HORIZ_DIR,dim);
sprintf(dimensiune,"dim=%d font:",dim);
outtextxy(x,y,dimensiune);
x+=textwidth (dimensiune);
/* avans la coloana libera de pe aceeasi linie */
outtextxy(x,y,denfont[stil]);
y+=textheight (denfont[ stil]);
/* avans la inceputul liniei urmatoare */
x=0;
/* se defineste dimensiunea de catre utilizator raport:
4/3 in latime; 2/1 in lungime. */
if(stil!=DEFAULT_FONT)
{
setusercharsize (4,3,2,1);
/* definesc raporturile pentru dimensiunile caracterelor */
strcpy(dimensiune,"dim utilizator:4/3,2/1");
outtextxy(x,y,dimensiune);
y+=textheight(dimensiune);
x=0;
}
getch();
}
closegraph();
printf("Actionati o tasta pentru a continua\n");

125
Laboratorul 22 GESTIUNEA ECRANULUI N MOD GRAFIC
getch();
}
}

22.2.3 Gestiunea imaginilor
22.2.3.1 S se scrie un program care realizeaz urmtoarele:
osind toate culorile din palet.
ul stnga sus; (120,60) - colul dreapta jos.
- colul dreapta jos.
orile din palet.
ate(l,l).
cepnd cu poziia curent din fereastr i folosind culoarea de
e tot ecranul.
fic.
ct de mai sus se vizualizeaz ecranul apelnd funcia getch.
include <graphics.h>
a. Afieaz, ntr-o zon de dimensiune 50*50, pixeli colorai fol
Zona se afl n colul din stnga sus al ecranului.
b. Definete fereastra de coordonate: (60,0) - col
Afieaz n fereastra activ pixeli colorai folosind toate culorile din palet.
c. Definete fereastra de coordonate:
(20,100) - colul stnga sus; (100,180)
Afieaz n fereastra activ pixeli colorai folosind toate cul
Afieaz n fereastra activ textul "abcdefg" ncepnd cu poziia de coordon
Se utilizeaz culoarea de index 6.
d. Se terge fereastra activ.
Se afieaz textul "abcdefg" n
index 14.
e. Se terg
f. Se revine din modul gra
Dup realizarea fiecrui pun
Pentru a continua, se acioneaz o tast oarecare.

#
#include <conio.h>
void main () /* - afiseaza in trei zone ale ecranului pixeli colorati
folosind toate culorile paletei;
- in una din zone se afiseaza si textul "abcdefg";
- in final se sterg zonele afi ?ate. */
{
int gd=DETECT,gm; int i,j,c;
initgraph(&gd,&gm,"c:\\borlandc\\bgi");
/* zona din coltul stinga sus al ecranului */
for(i=0;i<50;i++){
c=i;
for(j=0;j<50;j++,c++) {
c=c%16;
putpixel(i,j,c); }
}
getch();
/* define ?te o fereastra si afiseaza in ea pixeli colora ?i */
setviewport(60,0,120,60,1);
for(i=0;i<50;i++){
c=0;
for(j=0;j<50;j++,c++){
c=c%16;
putpixel(i,j,c); }
}
getch();
/* defineste ultima zona si afiseaza in ea pixeli colorati */
setviewport(20,100,100,180,1);
for(i=0;i<40;i++){
c=10;

126
Laboratorul 22 GESTIUNEA ECRANULUI N MOD GRAFIC
for(j=0;j<250;j++,c++){
c=c%16;
putpixel(i,j,c); }
}
/* afiseaza textul "abcdefg" */
setcolor(6);
outtextxy(1,1,"abcdefg"); getch();
/* sterge ultima zona si apoi afiseaza acelasi text folosind culoarea de
index 14 */
clearviewport(); setcolor(14); outtext("abcdefg"); getch();
/* sterge tot ecranul */
cleardevice(); getch();
/* iesire din modul grafic */
closegraph();
getch(); }


22.2.3.2 S se scrie un program care realizeaz urmtoarele:
in stnga sus al ecranului, apoi
agini oferite de funcia putimage.
nnd tasta zero; orice alt
include <graphics.h>
a. Afieaz pixeli colorai ntr-o zon dreptunghiular n colul d
o afieaz pe ecran n zone ce au poziii definite aleator.
b. La afiarea imaginii se folosesc toate operaiile dintre im
c. Culoarea de fond se schimb folosind toate culorile din palet.
Dup afirile indicate mai sus execuia se poate termina acio
tast acionat permite continuarea programului cu un nou set de imagini afiate aleator.
Se observ efectul operaiilor dintre imagini cnd acestea se suprapun.

#
#include <conio.h>
void main () /* - afiseaza in trei zone ale ecranului pixeli colorati
folosind toate culorile paletei;
- in una din zone se afiseaza si textul "abcdefg";
- in final se sterg zonele afi ?ate. */
{
int gd=DETECT,gm; int i,j,c;
initgraph(&gd,&gm,"c:\\borlandc\\bgi");
/* zona din coltul stinga sus al ecranului */
for(i=0;i<50;i++){
c=i;
for(j=0;j<50;j++,c++) {
c=c%16;
putpixel(i,j,c); }
}
getch();
/* define ?te o fereastra si afiseaza in ea pixeli colora ?i */
setviewport(60,0,120,60,1);
for(i=0;i<50;i++){
c=0;
for(j=0;j<50;j++,c++){
c=c%16;
putpixel(i,j,c); }
}
getch();
/* defineste ultima zona si afiseaza in ea pixeli colorati */
setviewport(20,100,100,180,1);
for(i=0;i<40;i++){

127
Laboratorul 22 GESTIUNEA ECRANULUI N MOD GRAFIC
c=10;
for(j=0;j<250;j++,c++){
c=c%16;
putpixel(i,j,c); }
}
/* afiseaza textul "abcdefg" */
setcolor(6);
outtextxy(1,1,"abcdefg"); getch();
/* sterge ultima zona si apoi afiseaza acelasi text folosind culoarea de
index 14 */
clearviewport(); setcolor(14); outtext("abcdefg"); getch();
/* sterge tot ecranul */
cleardevice(); getch();
/* iesire din modul grafic */
closegraph();
getch(); }



128
Laboratorul 23 GESTIUNEA ECRANULUI N MOD GRAFIC - continuare 1
23. GESTIUNEA ECRANULUI N MOD GRAFIC -
continuare 1
23.1 Tratarea erorilor
23.1.1
S se scrie un program care afieaz parametri implicii ai modului grafic setat prin apelul
funciei initgraph: numele adaptorului grafic; numele modului grafic; rezoluia;

#include <graphics.h>
#include <conio.h>
void main () /* - afiseaza in trei zone ale ecranului pixeli colorati
folosind toate culorile paletei;
- in una din zone se afiseaza si textul "abcdefg";
- in final se sterg zonele afi ?ate. */
{
int gd=DETECT,gm; int i,j,c;
initgraph(&gd,&gm,"c:\\borlandc\\bgi");
/* zona din coltul stinga sus al ecranului */
for(i=0;i<50;i++){
c=i;
for(j=0;j<50;j++,c++) {
c=c%16;
putpixel(i,j,c); }
}
getch();
/* define ?te o fereastra si afiseaza in ea pixeli colora ?i */
setviewport(60,0,120,60,1);
for(i=0;i<50;i++){
c=0;
for(j=0;j<50;j++,c++){
c=c%16;
putpixel(i,j,c); }
}
getch();
/* defineste ultima zona si afiseaza in ea pixeli colorati */
setviewport(20,100,100,180,1);
for(i=0;i<40;i++){
c=10;
for(j=0;j<250;j++,c++){
c=c%16;
putpixel(i,j,c); }
}
/* afiseaza textul "abcdefg" */
setcolor(6);
outtextxy(1,1,"abcdefg"); getch();
/* sterge ultima zona si apoi afiseaza acelasi text folosind culoarea de
index 14 */
clearviewport(); setcolor(14); outtext("abcdefg"); getch();

129
Laboratorul 23 GESTIUNEA ECRANULUI N MOD GRAFIC - continuare 1
/* sterge tot ecranul */
cleardevice(); getch();
/* iesire din modul grafic */
closegraph();
getch(); }

23.2 Desenare i colorare
23.2.1 S se scrie un program care traseaz linii orizontale folosind cele 4 stiluri
standard i ambele grosimi.

#include <graphics.h>
#include <conio.h>
void main () /* - afiseaza in trei zone ale ecranului pixeli colorati
folosind toate culorile paletei;
- in una din zone se afiseaza si textul "abcdefg";
- in final se sterg zonele afi ?ate. */
{
int gd=DETECT,gm; int i,j,c;
initgraph(&gd,&gm,"c:\\borlandc\\bgi");
/* zona din coltul stinga sus al ecranului */
for(i=0;i<50;i++){
c=i;
for(j=0;j<50;j++,c++) {
c=c%16;
putpixel(i,j,c); }
}
getch();
/* define ?te o fereastra si afiseaza in ea pixeli colora ?i */
setviewport(60,0,120,60,1);
for(i=0;i<50;i++){
c=0;
for(j=0;j<50;j++,c++){
c=c%16;
putpixel(i,j,c); }
}
getch();
/* defineste ultima zona si afiseaza in ea pixeli colorati */
setviewport(20,100,100,180,1);
for(i=0;i<40;i++){
c=10;
for(j=0;j<250;j++,c++){
c=c%16;
putpixel(i,j,c); }
}
/* afiseaza textul "abcdefg" */
setcolor(6);
outtextxy(1,1,"abcdefg"); getch();
/* sterge ultima zona si apoi afiseaza acelasi text folosind culoarea de
index 14 */
clearviewport(); setcolor(14); outtext("abcdefg"); getch();
/* sterge tot ecranul */
cleardevice(); getch();

130
Laboratorul 23 GESTIUNEA ECRANULUI N MOD GRAFIC - continuare 1
/* iesire din modul grafic */
closegraph();
getch(); }


23.2.2 S se scrie un program care traseaz urmtoarele figuri: cerc, elips,
aleator. Figurile sunt trasate folosind n mod aleator culoarea de
<graphics.h>
dreptunghi, patrulater.
Tipul figurii se stabilete
desenare.
#include
#include <conio.h>
void main () /* - afiseaza in trei zone ale ecranului pixeli colorati
folosind toate culorile paletei;
- in una din zone se afiseaza si textul "abcdefg";
- in final se sterg zonele afi ?ate. */
{
int gd=DETECT,gm; int i,j,c;
initgraph(&gd,&gm,"c:\\borlandc\\bgi");
/* zona din coltul stinga sus al ecranului */
for(i=0;i<50;i++){
c=i;
for(j=0;j<50;j++,c++) {
c=c%16;
putpixel(i,j,c); }
}
getch();
/* define ?te o fereastra si afiseaza in ea pixeli colora ?i */
setviewport(60,0,120,60,1);
for(i=0;i<50;i++){
c=0;
for(j=0;j<50;j++,c++){
c=c%16;
putpixel(i,j,c); }
}
getch();
/* defineste ultima zona si afiseaza in ea pixeli colorati */
setviewport(20,100,100,180,1);
for(i=0;i<40;i++){
c=10;
for(j=0;j<250;j++,c++){
c=c%16;
putpixel(i,j,c); }
}
/* afiseaza textul "abcdefg" */
setcolor(6);
outtextxy(1,1,"abcdefg"); getch();
/* sterge ultima zona si apoi afiseaza acelasi text folosind culoarea de
index 14 */
clearviewport(); setcolor(14); outtext("abcdefg"); getch();
/* sterge tot ecranul */
cleardevice(); getch();
/* iesire din modul grafic */
closegraph();
getch(); }



131
Laboratorul 23 GESTIUNEA ECRANULUI N MOD GRAFIC - continuare 1


132
Laboratorul 24 GESTIUNEA ECRANULUI N MOD GRAFIC - continuare 2
24. GESTIUNEA ECRANULUI N MOD GRAFIC -
continuare 2
S se scrie un program care coloreaz figurile geometrice trasate n programul precedent.
#include <graphics.h>
#include <conio.h>
void main () /* - afiseaza in trei zone ale ecranului pixeli colorati
folosind toate culorile paletei;
- in una din zone se afiseaza si textul "abcdefg";
- in final se sterg zonele afi ?ate. */
{
int gd=DETECT,gm; int i,j,c;
initgraph(&gd,&gm,"c:\\borlandc\\bgi");
/* zona din coltul stinga sus al ecranului */
for(i=0;i<50;i++){
c=i;
for(j=0;j<50;j++,c++) {
c=c%16;
putpixel(i,j,c); }
}
getch();
/* define ?te o fereastra si afiseaza in ea pixeli colora ?i */
setviewport(60,0,120,60,1);
for(i=0;i<50;i++){
c=0;
for(j=0;j<50;j++,c++){
c=c%16;
putpixel(i,j,c); }
}
getch();
/* defineste ultima zona si afiseaza in ea pixeli colorati */
setviewport(20,100,100,180,1);
for(i=0;i<40;i++){
c=10;
for(j=0;j<250;j++,c++){
c=c%16;
putpixel(i,j,c); }
}
/* afiseaza textul "abcdefg" */
setcolor(6);
outtextxy(1,1,"abcdefg"); getch();
/* sterge ultima zona si apoi afiseaza acelasi text folosind culoarea de
index 14 */
clearviewport(); setcolor(14); outtext("abcdefg"); getch();
/* sterge tot ecranul */
cleardevice(); getch();
/* iesire din modul grafic */
closegraph();
getch(); }

S se scrie un program care afieaz 15 dreptunghiuri colorate, pe trei rnduri, folosind toate
cele 15 culori ale paletei diferite de culoarea de fond.

133
Laboratorul 24 GESTIUNEA ECRANULUI N MOD GRAFIC - continuare 2
Sub fiecare dreptunghi se listeaz indicele culorii dreptunghiului, n tabloul care definete
paleta curent de culori.
Dup afiarea celor 15 dreptunghiuri se poate regla monitorul aa nct fiecare dreptunghi s
fie vizibil. Acest program poate fi utilizat ori de cte ori se constat c monitorul este dereglat.
#include <graphics.h>
#include <conio.h>
void main () /* - afiseaza in trei zone ale ecranului pixeli colorati
folosind toate culorile paletei;
- in una din zone se afiseaza si textul "abcdefg";
- in final se sterg zonele afi ?ate. */
{
int gd=DETECT,gm; int i,j,c;
initgraph(&gd,&gm,"c:\\borlandc\\bgi");
/* zona din coltul stinga sus al ecranului */
for(i=0;i<50;i++){
c=i;
for(j=0;j<50;j++,c++) {
c=c%16;
putpixel(i,j,c); }
}
getch();
/* define ?te o fereastra si afiseaza in ea pixeli colora ?i */
setviewport(60,0,120,60,1);
for(i=0;i<50;i++){
c=0;
for(j=0;j<50;j++,c++){
c=c%16;
putpixel(i,j,c); }
}
getch();
/* defineste ultima zona si afiseaza in ea pixeli colorati */
setviewport(20,100,100,180,1);
for(i=0;i<40;i++){
c=10;
for(j=0;j<250;j++,c++){
c=c%16;
putpixel(i,j,c); }
}
/* afiseaza textul "abcdefg" */
setcolor(6);
outtextxy(1,1,"abcdefg"); getch();
/* sterge ultima zona si apoi afiseaza acelasi text folosind culoarea de
index 14 */
clearviewport(); setcolor(14); outtext("abcdefg"); getch();
/* sterge tot ecranul */
cleardevice(); getch();
/* iesire din modul grafic */
closegraph();
getch(); }


S se scrie un program care afieaz dreptunghiuri utiliznd toate haurile standard.
#include <graphics.h>
#include <conio.h>
void main () /* - afiseaza in trei zone ale ecranului pixeli colorati
folosind toate culorile paletei;
- in una din zone se afiseaza si textul "abcdefg";

134
Laboratorul 24 GESTIUNEA ECRANULUI N MOD GRAFIC - continuare 2
- in final se sterg zonele afi ?ate. */
{
int gd=DETECT,gm; int i,j,c;
initgraph(&gd,&gm,"c:\\borlandc\\bgi");
/* zona din coltul stinga sus al ecranului */
for(i=0;i<50;i++){
c=i;
for(j=0;j<50;j++,c++) {
c=c%16;
putpixel(i,j,c); }
}
getch();
/* define ?te o fereastra si afiseaza in ea pixeli colora ?i */
setviewport(60,0,120,60,1);
for(i=0;i<50;i++){
c=0;
for(j=0;j<50;j++,c++){
c=c%16;
putpixel(i,j,c); }
}
getch();
/* defineste ultima zona si afiseaza in ea pixeli colorati */
setviewport(20,100,100,180,1);
for(i=0;i<40;i++){
c=10;
for(j=0;j<250;j++,c++){
c=c%16;
putpixel(i,j,c); }
}
/* afiseaza textul "abcdefg" */
setcolor(6);
outtextxy(1,1,"abcdefg"); getch();
/* sterge ultima zona si apoi afiseaza acelasi text folosind culoarea de
index 14 */
clearviewport(); setcolor(14); outtext("abcdefg"); getch();
/* sterge tot ecranul */
cleardevice(); getch();
/* iesire din modul grafic */
closegraph();
getch(); }

S se scrie un program care traseaz un cerc folosind ecuaiile parametrice ale cercului:
x = r*cos(g) + xcentru; y = r*sin(g) + ycentru;
#include <graphics.h>
#include <conio.h>
void main () /* - afiseaza in trei zone ale ecranului pixeli colorati
folosind toate culorile paletei;
- in una din zone se afiseaza si textul "abcdefg";
- in final se sterg zonele afi ?ate. */
{
int gd=DETECT,gm; int i,j,c;
initgraph(&gd,&gm,"c:\\borlandc\\bgi");
/* zona din coltul stinga sus al ecranului */
for(i=0;i<50;i++){
c=i;
for(j=0;j<50;j++,c++) {
c=c%16;

135
Laboratorul 24 GESTIUNEA ECRANULUI N MOD GRAFIC - continuare 2
putpixel(i,j,c); }
}
getch();
/* define ?te o fereastra si afiseaza in ea pixeli colora ?i */
setviewport(60,0,120,60,1);
for(i=0;i<50;i++){
c=0;
for(j=0;j<50;j++,c++){
c=c%16;
putpixel(i,j,c); }
}
getch();
/* defineste ultima zona si afiseaza in ea pixeli colorati */
setviewport(20,100,100,180,1);
for(i=0;i<40;i++){
c=10;
for(j=0;j<250;j++,c++){
c=c%16;
putpixel(i,j,c); }
}
/* afiseaza textul "abcdefg" */
setcolor(6);
outtextxy(1,1,"abcdefg"); getch();
/* sterge ultima zona si apoi afiseaza acelasi text folosind culoarea de
index 14 */
clearviewport(); setcolor(14); outtext("abcdefg"); getch();
/* sterge tot ecranul */
cleardevice(); getch();
/* iesire din modul grafic */
closegraph();
getch(); }


136
Laboratorul 25 Sortare i cutare
25. Sortare i cutare
25.1 SORTARE
25.1.1 Sortarea valorilor unui vector
S se implementeze i s se testeze un program care:
a) Genereaz aleator i afieaz elementele unui vector ;
b) Sorteaz aceste elemente, cresctor, aplicnd diferite metode de sortare;
S se compare viteza de sortare pentru vectori de diverse dimensiuni (10, 30, 50, 100
elemete).

/* Program de sortare*/ {
#include <stdlib.h> double aux=v[i];
v[i]=v[i+1]; v[i+1]=aux; #include <stdio.h>
#include <time.h>
printf("Interschimbare element %2d
cu %2d: ",i,i+1);
#include <conio.h>

#define TRUE 1 afis(v,n);
#define FALSE 0 gata=FALSE;
}
void gener(double v[], int n) }
//functia de generare aleatoare a
elementelor vectorului v, cu n
elemente
while(!gata);
}

{for (int i=0; i<n; i++) /* Sortare prin selectie */
v[i]=rand()%50; //Generare
de numere aleatoare de la 0 la 49
void Sortare_select(double v[],
int n)
} {
void afis(double v[], int n) register int i, ind_el_ref,
ind_el_min, gata; //functia de afisare a vectorului
{for (int i=0; i<n; i++) double el_min;
printf("%3.0f",v[i]); for(ind_el_ref=0; ind_el_ref<n-1;
++ind_el_ref) printf("\n");
} {
gata=1; ind_el_min=ind_el_ref ;
void copie_vect(double v1[],
double v[], int n)
el_min=v[ind_el_ref];
//Elementul de referinta curent cu
care se compara elem urmatoare //functie de "duplicare "a unui
vector; copie vectorul v in
vectorul v1
for(i=ind_el_ref+1; i<n; ++i)
if(v[i]<el_min) // Sortare
crescatoare {for (int i=0; i<n; i++)
v1[i]=v[i]; {
} ind_el_min=i; //Indicele
elementului minim
/* Sortare prin met bulelor*/ el_min=v[i]; //Valoarea
elementului minim void Sortare_bule(double v[], int
n) gata=0; //Se va face un
schimb {
int i,gata; }
do if(!gata)
{ {//Schimbarea elementului minim
cu cel de de referinta gata=TRUE;
for(i=0; i<n-1; i++) v[ind_el_min]=v[ind_el_ref];
v[ind_el_ref]=el_min;} if (v[i]>=v[i+1])

137
Laboratorul 25 Sortare i cutare
} while (j>stg &&
v[j]>pivot) j--; }
if
(i<=j)//interschimbare elemente /* Sortarea prin inserare*/
void Sortare_insert(double v[],
int n)
{
aux=v[i];v[i]=v[j];v[j]=aux; i++;
j--; } {
register int ind, i; double
el_min;
}
if(j>stg)
Sortare_rapida(v,stg,j); for(ind=1; ind<n; ++ind)
{ if(i<drt)
Sortare_rapida(v,i,drt); el_min=v[ind];
for(i=ind-1; i>=0 &&
el_min<v[i]; i--)
}
}
v[i+1]=v[i];
v[i+1]=el_min; void main()
} {
} clock_t ti,tf; int n; //n =
nr elemente vector
/* Sortarea prin metoda Shell */
void Sortare_Shell (double v[],int
n)
printf("Nr componente vector:");
scanf("%d", &n);
{ double v[200], v1[200];
int inc,i,j; double aux; gener(v, n);
for(inc=n/2;inc>0;inc/=2) printf("\nInainte de ordonare:
v="); afis(v, n); /* se realizeaza o parcurgere a
sirului */
for(i=inc;i<n;i++) printf("\n****** SORT BULE
******\n"); /* se compara doua elemente
aflate la distanta inc unul de
altul
copie_vect(v1,v,n);
ti=clock();
si daca este cazul se permuta; Sortare_bule(v1,n); tf=clock();
double dif_b=tf-ti; - daca s-a realizat o permutare,
atunci elementul deplasat in fata printf("Dupa ordonare BULE:
v1="); afis(v1, n); se compara cu precedentele lui
si se permuta daca este cazul. */ printf("Durata: %lf", dif_b);
for(j=i-inc; j>=0 &&
v[j]>v[j+inc]; j-=inc)

printf("\n****** SORT SELECT
******\n"); { aux=v[j]; v[j]=v[j+inc];
v[j+inc]=aux; copie_vect(v1, v, n);
printf("Interschimbare
element %2d cu %2d, increment %2d:
",j,j+inc,inc);afis(v,n);
Sortare_select(v1, n);
printf("Dupa ordonare SELECT:
v1="); afis(v1, n);
}
} printf("\n****** SORT INSERT
******\n");
void Sortare_rapida(double v[],
int stg, int drt)
copie_vect(v1, v, n);
Sortare_insert(v1, n);
{ printf("Dupa ordonare INSERT:
v1="); afis(v1, n); int i,j; i=stg; j=drt; double
pivot, aux;
if (i<j){ printf("\n****** SORT SHELL
******\n"); pivot=v[(stg+drt)/2];
while (i<=j) copie_vect(v1, v, n);
{ //extindere partitie st si dr
pana i se incrucis cu j
Sortare_Shell(v1, n);
while (i<drt &&
v[i]<pivot) i++;
printf("Dupa ordonare SHELL:
v1="); afis(v1, n);


138
Laboratorul 25 Sortare i cutare
printf("\n****** SORT QUICK
******\n");
int st=0; int dr=n-1;
copie_vect(v1, v, n);
printf("Dupa ordonare QUICK:
v1="); afis(v1, n);
getch();
}
Sortare_rapida(v1, st, dr);


139
Laboratorul 26 Sortare i cutare - continuare
26. Sortare i cutare - continuare
26.1 Cutare
26.1.1
S se implementeze i s se testeze un program care:
a) Genereaz aleator i afieaz elementele unui vector ;
b) Sorteaz aceste elemente, cresctor, aplicnd o metod de sortare;
c) Caut prin metoda secvenial sau binar un element de o anumit valoare dat citit de
la tastatur.

/* Program de cautare */ for(inc=n/2;inc>0;inc/=2)
#include <stdlib.h> /* se realizeaza o parcurgere a
sirului */ #include <stdio.h>
#include <time.h> for(i=inc;i<n;i++)
#include <conio.h> /* se compara doua elemente
aflate la distanta inc unul de
altul #define TRUE 1
#define FALSE 0 si daca este cazul se permuta;
- daca s-a realizat o permutare,
atunci elementul deplasat in fata void gener(double v[], int n)
//functia de generare aleatoare a
elementelor vectorului v, cu n
elemente
se compara cu precedentele lui
si se permuta daca este cazul. */
for(j=i-inc; j>=0 &&
v[j]>v[j+inc]; j-=inc) {for (int i=0; i<n; i++)
v[i]=rand()%50; //Generare
de numere aleatoare de la 0 la 49
{ aux=v[j]; v[j]=v[j+inc];
v[j+inc]=aux;
} printf("Interschimbare
element %2d cu %2d, increment %2d:
",j,j+inc,inc);afis(v,n);
void afis(double v[], int n)
//functia de afisare a vectorului
{for (int i=0; i<n; i++) }
printf("%3.0f",v[i]); }
printf("\n");
} Cautare_secventiala(double v[],
int n, double val)
void copie_vect(double v1[],
double v[], int n)
{
register int t;
//functie de "duplicare "a unui
vector; copie vectorul v in
vectorul v1
for(t=0; t<n; ++t )
if (val==v[t]) return t;
//Indice elem cautat
{for (int i=0; i<n; i++) return -1; //Nu s-a gasit elem
cautat v1[i]=v[i];
} }

/* Sortarea prin metoda Shell */ /* Cautare binara*/
void Sortare_Shell (double v[],int
n)
Cautare_binara(double v[], int n,
double val)
{ {
int inc,i,j; double aux; int med, min, max;

140
Laboratorul 26 Sortare i cutare - continuare
min = 0; max =n-1; gener(v, n);
printf("\nInainte de ordonare:
v="); afis(v, n);
while (min<=max)
{

med=(min+max)/2;
printf("Val elem cautat:");
scanf("%d", &val);
if(val<v[med]) max=med-1;
else
printf("Indice elem cautat: i=
%d",Cautare_secventiala(v,n,val));
if(val>v[med])
min = med+1;

else
printf("\n****** SORT SHELL
******\n");
return med; //Indice elem
cautat
Sortare_Shell(v, n);
}
printf("Dupa ordonare SHELL:
v1="); afis(v, n);
return -1; //Nu s-a gasit elem
cautat

}
printf("Val elem cautat:");
scanf("%d", &val);
void main()
printf("Indice elem cautat: i=
%d",Cautare_binara(v,n,val));
{
clock_t ti,tf; int n, val; //n =
nr elemente vector

getch();
}
printf("Nr componente vector:");
scanf("%d", &n);

double v[200],v1[200];


141
Laboratorul 27 Metode numerice
27. Metode numerice
27.1 Rezolvarea ecuaiilor neliniare
27.1.1 Metoda iteraiilor succesive
S se rezolve ecuaia x - sin(x) = 0.25 prin
metoda iteraiilor succesive
//Metoda iteratiilor sucesive
#include <stdio.h>
#include<math.h>
int ok;

double f(double);
double iter(double ,double ,int,double
(*)(double));

main()
{
double sol;
sol=iter(50,1e-06,50,f);
if(ok) printf ("\nsolutia e
x=%lf",sol);
else printf("\nnu e solutie");
}

double f(double x)
{return x-sin(x)-0.25;}

double df(double x)
{return 1-cos(x);}

double iter(double x,double eps,int
imax,double (*f)(double))
{
int i=0; double fx,dx; ok=1;
do
{
i++;
dx=f(x);
x-=dx;
if (x!=0) dx=dx/x;
printf("\ni=%2d; x=%lf;
dx=%lf;",i,x,dx);
}
while ((fabs (dx)>eps)&&(i<imax));
if (i>=imax) ok=0;
return x;
}

Se cere s se calculeze soluia ecuaiei f(x)
= 0 pentru
f(x)=x
3
- 2*cos(x)*x
2
+ x - 3
prin metoda: njumtirii, coardei i
tangentei.
27.1.2 Metoda njumtirii
27.1.2.1 Pseudocod:
citete a,b,iter, eps
x0=a, x1=b
dac f(a)*f(b)<0 i=0, x=x0
ct timp (f(x)>eps) i (i<iter)
x=(x0+x1)/2
dac f(x0)*f(x)<0 atunci x1=x altfel x0=x
dac i>iter scrie "probl. nu se poate rez. n
nr.max.de iteraii" altfel return x
27.1.2.2 Program:
#include<iostream.h>
#include<math.h>
#define eps 1e-10
#define iter 200

double f(double x)
{ return x*x*x-2*x*x*cos(x)+x-3; }

void main()
{
unsigned char i;
double x,x0,x1,a,b,y;
cout<<"a=";cin>>a;cout<<"b=";cin>>b;
i=0;x0=a;x1=b;x=x0;y=f(x);
if (f(x0)*f(x1)<0)
{
while ( (i<=iter) && ((y<-eps) ||
(y>eps)) )
{
x=(x0+x1)/2;y=f(x);
if (f(x0)*f(x)<0) x1=x; else
x0=x;
cout<<"\n\nf("<<x<<")="<<f(x)<<"
la iteratia "<<(int)i;
i++;
}
if (i>iter) cout<<"problema nu se
poate rezolva in nr.maxim de
iteratii";
}
else cout<<"interval invalid";
}

142
Laboratorul 27 Metode numerice
Start
f(x)>eps
i=0
x=x0
Citete a, b,
iter, eps
Stop
Nu Da
Da Nu
i=i+1
x=(x0+x1)/2
f(x0)f(x)<0
x1=x
Da Nu
Scrie Ec nu
are rad n
interv [a,b]
x0=a; x1=b
x0=x
Scrie Ec
are rad x
i<iter
Da Nu
27.1.3 Metoda coardei
27.1.3.1 Pseudocod:
citete a,b,iter
x0=a,x1=b
dac f(a)*f(b)<0
i=0, x=x0
ct timp (f(x)>eps) i (i<iter)
x=x0-f(x0)*(x1-x0)/(f(x1)-f1(x0))
dac f(x0)*f(x)<0 atunci x1=x altfel x0=x
dac i>iter scrie "probl. nu se poate rez. n
nr.max.de iteraii" altfel return x
27.1.4 Metoda tangentei
Am notat:
prima derivata:
f1(x)=3*x*x+2*x*x*sin(x)-4*x*cos(x)+1
a doua derivata:
f2(x)=6*x+2*x*x*cos(x)+8*x*sin(x)-4*cos(x)

27.1.4.1 Pseudocod:
citete a,b,iter
dac (f(a)*f2(a)>=0) x=a altfel x=b; i=0
dac f(a)*f(b)<0
ct timp (f(x)>eps) i (i<iter)
y=f(x), y1=f1(x)
x=x-f(x)/f1(x)
dac i>iter scrie "probl. nu se poate rez. n
nr.max.de iteraii" altfel return x
27.1.5 Metoda secantei
Am notat:
prima derivata:
f1(x)=3*x*x+2*x*x*sin(x)-4*x*cos(x)+1
a doua derivata:
f2(x)=6*x+2*x*x*cos(x)+8*x*sin(x)-4*cos(x)
27.1.5.1 Pseudocod:
citete a,b,iter,x
dac (f(a)*f2(a)>=0) x0=a
altfel x0=b; i=0;x1=x
dac f(a)*f(b)<0

143
Laboratorul 27 Metode numerice
ct timp (f(x)>eps) i (i<iter)
y1=f(x1)
y0=f(x0)
x=(x0*y1-x1*y0)/(y1-y0)
i++
x1=x0
x0=x
dac i>iter scrie "probl. nu se poate rez. n
nr.max.de iteraii"
altfel return x
27.2 Rezolvarea sistemelor de ecuaii prin metoda Gauss
#include <math.h>
#include <stdio.h>

main()
{
int i,j,k,l,m=1,n=3;
double A[3][3]={{0,10,1},{1,3,-
1},{2,4,1}},
B[3][1]={23,4,13}, det, t;

/*printf("\nIntroduceti ordinul
matricii (max. 10) n=");
scanf("%d",&n);
for (i=0;i<n;i++)
for (j=0;j<n;j++)
{printf ("A[%d,%d]= ", i,j); scanf
("%lf",&A[i][j]); }
for (i=0;i<n;i++)
{printf ("B[%d]= ", i); scanf
("%lf",&B[i][1]);}*/

/*Faza eliminarii*/
det=1;
for (k=0;k<n;k++)
{
t=0;
for (i=k;i<n;i++)
if (t<fabs(A[i][k])) {
t=fabs(A[i][k]);l=i; }
if (l!=k)
{
det=-det;
for (j=k;j<n;j++) {
t=A[k][j]; A[k][j]=A[l][j]; A[l][j]=t;
}
for (j=0;j<m;j++) {
t=B[k][j]; B[k][j]=B[l][j]; B[l][j]=t;
}
}
t=1/A[k][k];det=A[k][k]*det;
for (j=k;j<n;j++) {
A[k][j]=A[k][j]*t; }
for (j=0;j<m;j++) {
B[k][j]=B[k][j]*t; }
if (k!=n)
{
for (i=k+1;i<n;i++)
{
t=A[i][k];
for (j=k;j<n;j++)
A[i][j]=A[i][j]-A[k][j]*t;
for (j=0;j<m;j++)
B[i][j]=B[i][j]-B[k][j]*t;
}
}
for (i=0;i<n;i++)
{for (j=0;j<n;j++)
printf("%6.3lf\t",A[i][j]);
printf ("%8.3lf \n", B[i][0]);
}
printf("\n");
}

/*Faza substitutiei inverse*/
for (k=n-2;k>=0;k--)
{
for(j=0;j<m;j++)
{
t=0;
for (i=k+1;i<n;i++)
t=t+A[k][i]*B[i][j];
B[k][j]=B[k][j]-t;
}
}

printf ("\nSolutie\n*********\ndet A =
%lf\n", det);
for (i=0;i<n;i++)
{
printf("X[%d]= %8.3lf \n",
i,B[i][0]);
}
}/*main*/



144
Laboratorul 27 Metode numerice
27.3 Metoda celor mai mici ptrate de aproximare a sistemelor de ecuaii
supradeterminate
S considerm cazul cel mai simplu cnd se cere dreapta minimal ce unete un sistem de n
puncte n spaiul k-dimensional R
k
.
Avem:
A0.x0,0 + A1.x0,1 + A2.x0,2 + ..... + Ak-1.x0,k-1 + B
= y0
A0.x1,0 + A1.x1,1 + A2.x1,2 + ..... + Ak-1.x1,k-1 + B
= y1
....................................................................................................................................................
.....
A0.xi,0 + A1.xi,1 + A2.xi,2 + ..... + Ak-1.xi,k-1 + B
= yi
....................................................................................................................................................
....
A0.xn-1,0 + A1.xn-1,1 + A2.xn-1,2 + ..... + Ak-1.xn-1,k-1 + B = yn

Se cere minimizarea funciei:
F(A0,A1,...,An-1,B) = (A0.x0,0 + A1.x0,1 + A2.x0,2 +...+ Ak-1.x0,k-1 + B - y0)
2
+ ...+ (A0.xn-
1,0 + A1.xn-1,1 + A2.xn-1,2 +...+ Ak-1.xn-1,k-1 + B - yn-1)
2
Pentru aceasta trebuie gsit punctul n care toate derivatele pariale se anuleaz iar hessiana este
pozitiv definit.
F`A0(A1,...,Ak,B) = 2[X0,0.(A1.X1,1+...+Ak.X1,k +B-Y1)+...+Xn,1.(A0.Xn,1+...+Ak.Xn,k +B-
Yn)]
F`
A1
(A1,...,Ak,B) 2[X0,1.(A1.X1,1+...+Ak.X1,k +B-Y1)+...+Xn,1.(A0.Xn,1+...+Ak.Xn,k +B-
Yn)]
F`
A2
(A1,...,Ak,B) 2[X0,2.(A1.X1,1+...+Ak.X1,k +B-Y1)+...+Xn,2.(A0.Xn,1+...+Ak.Xn,k +B-
Yn)]
F`
A3
(A1,...,Ak,B) 2[X0,3.(A1.X1,1+...+Ak.X1,k +B-Y1)+...+Xn,3.(A0.Xn,1+...+Ak.Xn,k +B-
Yn)]
. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
F`
Ai
(A1,...,Ak,B) 2[X0,i.(A1.X1,1+...+Ak.X1,k +B-Y1)+...+Xn,i.(A0.Xn,1+...+Ak.Xn,k +B-
Yn)]
. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
F`
An
(A1,...,Ak,B) 2[X0,n.(A1.Xn,1+...+Ak.Xn,k +B-Yn)+...+Xn,k.(A0.Xn,1+...+Ak.Xn,k +B-
Yn)]
F`
B
(A1,...,Ak,B) 2[(A0.Xn,1+...+Ak.Xn,n +B-Yn) +...+ (A0.Xn,1+...+Ak.Xn,k +B-Yn)]

Pentru ca gradientul sa fie nul trebuie rezolvat un sistem de (n+1) ecuaii cu (n+1)
necunoscute,
iar matricea necunoscutelor este egala cu hessiana funciei F in punctul (A1,A2,...,Ad,B).

Sa notam aceasta matrice cu H. Avem:

2.[ X1,i.X1,j + X2,i.X2,j +...+ Xn,i.Xn,j ], dac i,j=1,k
H[i][j] = 2.[ X1,i + X2,i +...+ Xn,i], dac i=1,k; j=k+1
2.[ X1,j + X2,j +...+ Xn,j], dac i=k+1; j=1,k

145
Laboratorul 27 Metode numerice
2.n, dac i=k+1,j=k+1

Se demonstreaz ca aceasta matrice este nu nedegenerata, ci, mai mult, pozitiv definita.
Aceasta nseamn ca sistemul este compatibil determinat i se poate rezolva prin metoda lui
Gauss.
De asemenea fiind pozitiv definita rezulta ca punctul de extrem relativ este de minim.

Vectorul termenilor liberi, fie acesta V, este urmtorul:

V[i] = X1,i.y1 + X2,i.y2 + ... + Xn,i.yn dac i=1,n
y1 + y2 + ... + yn dac i=n+1

Am calculat matricea sistemului. Mai avem nevoie i de o procedura Gauss pentru
rezolvarea generica a sistemelor de aceasta forma.




146
Laboratorul 28 Diverse
28. Diverse
28.1 Preprocesorul
28.1.1
S se defineasc un macro care apoi s fie apelat la evaluarea expresiilor de mai jos:
i = (|a| + |b|)/(1+|a-b|)
unde: i, a, b - Sunt de tip int.
z = (|x+y| - |x-y|)/(l + |x+y||x-y|)
unde: x, y, z - Sunt de tip double.
Definiia macroului i apelurile lui pentru evaluarea acestor expresii intr n compunerea
programului de mai jos.
Valorile variabilelor a, b, x i y se citesc de la intrarea standard.
//PROGRAMUL BXV1
#include <stdio.h>
#include <stdlib.h>
#define ABS(X) ((X)<0 ? -(X) : (X))
#include "BVIII2.CPP" /* pcitint */
#include "BVIII3 .CPP" /* pcitintlim */
int pcit_double(char *p,double *d);

void main () /* citeste valorile variabilelor a, b, x si y,
evalueaza expresiile de mai jos si afiseaza valorile variabilelor i si z:
i=(|a| + |b|)/(1+|a-b|); z=(|x+y|-|x-y|)/(1 + |x+y||x-y|)*/
{
int a,b,i; double x,y,z; double s,d;
char er[]="s-a tastat EOF\n";
/* citeste valoarea lui a */
if(pcit_int_lim("a=",-32768,32767,&a)==0)
{ printf(er); exit(1); }
/* citeste valoarea lui b */
if (pcit_int_lim("b=",-32768,32767,&b)==0)
{ printf(er); exit(1); }
/* citeste valoarea lui x */
if(pcit_double("x=",&x)==0)
{printf(er);exit(1); }
/* citeste valoarea lui y */
if(pcit_double("y=",&y)==0)
{printf(er);exit(1); }
/* calculul valorii lui i */
i=(ABS(a)+ABS(b))/(1+ABS(a-b));
/* calculul valorii lui z */
s=ABS(x+y); d=ABS(x-y); z=(s-d)/(1+s*d);
/* afisare rezultate */
printf("a = %d\tb = %d\n",a,b);
printf("(ABS(a)+ABS(b))/(1+ABS(a-b))=%d\n",i);
printf("x = %f\ty = %f\n",x,y);
printf("(ABS(x+y)-ABS(x-y))/(1+ABS(x+y)*\ ABS(x-y))=%g\n",z);
} /* sfirsit main */

int pcit_double(char *p,double *d) /* - afiseaza textul spre care pointeaza p;
- citeste un numar si-1 pastreaza in zona spre care pointeaza d;
- returneaza zero la intilnirea sfirsitului de fisier si unu in caz contrar. */

147
Laboratorul 28 Diverse
{
char t[255];
double f;
for(; ; )
{
printf("%s",p);
if(gets(t)==0) return 0;
if(sscanf(t,"%lf",&f)==1)
break; printf("nu s-a tastat un numar\n");
}
*d=f; return 1;
}

S se scrie un program n care s se defineasc un macro pentru calculul unui polinom de
gradul doi i care s fie apelat pentru evaluarea expresiilor:
pol1 = 3x*x+7x-8; pol2 = x*x-3,5x+1,2.
Programul citete valoarea lui x i afieaz valorile variabilelor pol1 i pol2
//PROGRAMUL BXV2
#include <stdio.h>
#include <stdlib.h>
#define POL(A,B,C) ((A)*x*x+(B)*x+(C))

main () /* citeste pe x, calculeaza si afiseaza valorile expresiilor
3x*x+7x-8 si x*x-3,5x+1,2. */
{
double x; char t[255];
for(;;)
{
printf("x=");
if(gets(t)==0)
{ printf("s-a tastat EOF\n"); exit(1); }
if(sscanf(t,"%lf",&X)==1) break;
printf("nu s-a tastat un numar\n")
};
printf("x = %f\t 3x*x+7x-8 = %g\n",x,P0L(3,7,-8));
printf("x = %f\t x*x-3,5x+1,2 = %g\n",x,POL(1,-3.5,1.2));
}


28.2 Misc
28.2.1 Convergena unui ir
S se studieze convergena unui ir dat prin relaia de recuren: a
1
= x , a
n
= a
n-1
+ x cu
ajutorul calculatorului (x este o valoare ntreag).
Strategia de rezolvare: Programul va calcula termenii succesivi ai irului, iar n cazul n care
diferena, n valoarea absolut, dintre doi termeni succesivi devine mai mic dect eroarea
cu care se propune determinarea limitei, ultimul termen calculat al irului devine egal cu
limita irului. Programul nu va verifica dac irul este monoton, ns va presupune c n cazul
n care dup un numr predefinit de iteraii (n cazul nostru 500) nu a fost atins limita, irul
nu este convergent.
Instruciunea exit() se afl cuprins n bibliotecile standard <stdlib.h> i <process.h> i
determin oprirea execuiei programului.

/* Program 9.

148
Laboratorul 28 Diverse
Studiul convergentei unui sir dat
printr-o relatie de
recurenta, cu ajutorul
calculatorului*/
float a=rad2(val), b=rad2(a+val),
err=1e-7;
clrscr();
do
{
cout<<"Elementul
A["<<i<<"]="<<a<<endl;
#define modul(x) x>=0 ? x : -x
#define val 2
a=b; #include<iostream.h>
i++; #include<conio.h>
b=rad2(a+val); #include<stdlib.h>
if(i>500)
{ float rad2(float x)
cout<<"Sirul nu este
convergent!";
{
float m=1, n=0.5*(m+x/m), errrad=1e-
7; exit(stare);
} do
} {m=n; n=0.5*(m+x/m); }
while(modul(a-b)<err); while(modul(n-m)<errrad);
cout<<"Limita sirului = "<<b<<endl; return m;
cin>>i; }
}
/*Programul asteapta tastarea unui
caracter, permitand vizualizarea
rezultatelor.*/
void main()
{
int i=1, stare;
28.2.2 Transformare unghi grade - radiani
S se citeasc un unghi n grade, minute i secunde, s se transforme unghiul n radiani i
s se calculeze valorile funciilor trigonometrice standard (sinus, cosinus, tangent,
cotangent). S se transforme apoi unghiul din radiani n grade, minute i secunde.
Strategia de rezolvare: Se vor construi funcii att pentru trecerea de la grade la radiani, ct
i pentru trecerea de la radiani la grade. Formula de trecere de la grade la radiani este:
unghi
rad
=

grade +
minute
60
+
secunde
3600

180

Formula de trecere de la un unghi n radiani la un unghi n grade, minute i secunde este:
grade =

unghi
rad

180

; minute =

unghi
rad

180

- grade 60 ;
secunde =

unghi
rad

180

- grade 60 - minute 60
n implementarea funciilor de trecere de la grade la radiani i invers trebuie avut grij de
modul n care C face conversiile de tip i rotunjirile rezultatului. Notaia [x] reprezint partea
ntreag a numrului real x.
/* Program 10.
Citirea unui unghi in grade,
minute, secunde,transformarea
unghiului in radiani si calcularea
cu acest unghi a sinusului,
{/*Transforma un unghi din grade
in radiani*/
return
(g+m/60.0+s/3600.0)*PI/180.0;
cosinusului, tangentei si
cotangentei.*/
}

void rad2deg(double x1, int *g,
int *m, int *s)
#include<stdio.h> {/*Transforma un unghi din radiani
in grade*/ #include<conio.h>
#include<math.h> double degx=x1*180.0/PI;
*g=floor(degx); double PI=3.14159265358979;
//PI este definit ca variabila
globala
*m=floor((degx-*g)*60);
*s=floor(((degx-*g)*60-*m)*60);
}
double deg2rad(int g, int m, int
void main() s)

149
Laboratorul 28 Diverse
{
int grad, min, sec;
double x;
clrscr();
printf("Dati unghiul in forma:
grade.minute.secunde = ");
scanf("%d.%d.%d",
&grad,&min,&sec);
x=deg2rad(grad,min,sec);
printf("Unghiul in radiani =
%.91f\n", x);
printf(" SIN (x) =
%.91f\n", sin(x));
printf(" COS (x) =
%.91f\n", cos(x));
printf(" TANGENTA (x) =
%.91f\n", tan(x));
printf(" COTANGENTA (x) =
%.91f\n", 1/tan(x));
rad2deg(x, &grad, &min, &sec);
printf("unghiul introdus initial
in grade, minute si secunde
este:\n");
printf("grad= %d min = %d sec =
%d\n", grad, min, sec);
getch();
}

Deoarece funcia cotangent nu este implementat e necesar utilizarea expresiei
tangenta{x).
ile cu virgul (ex. 60.0 n loc de 60) pentru a ne asigura c efectul operatorului
a numrului x. Rotunjirea prin adugare a
in (pentru variabilele &grad<-*g, &min<-*m i &sec <-*s).
anisme, s lum cazul simplu al programului
.
e prototipurilor
e*/
,y,rez;
);

ilor cu prototipul
/
b
;
;

zult)
n");
irii
orie
t);
n C++, est
1/
n funcia deg2rad care face conversia de la grade la radiani, am folosit pentru constantele
numerice valor
m/60 este un rezultat n virgul mobil i nu ctul mpririi ntregi a numrului m la 60, caz n
care rezultatul expresiei ar fi fost compromis.
n C++ implementarea prii ntregi a unui numr real (n format double) este dat de funcia:
floor(x) i reprezint rotunjirea n minus
numrului x este dat de funcia ceil(x), ambele funcii fiind incluse n biblioteca math.h.
Trebuie remarcat c schimbul datelor ntre funcia main i funcia rad2deg se face prin dou
mecanisme diferite:
Transferul prin valoare (pentru variabila x->x
i
);
Transferul prin refer
Pentru exemplificarea mai simpl a acestor mec
urmtor, ce citete dou valori, calculeaz raportul acestora i afieaz rezultatul
/*Program 11.
Calculul raportului a doua numere
void citire(float *a, float *b)
{//Citirea rezultatelor a si
reale.
Programul este utilizat pentru
exemplificarea transferului prin
valoare si prin referinta intre
functii.*/
#include<stdio.h>
#include<conio.h>
/*Declaratii al
functiilor utilizat
void citire(float *a, float *b);
float calcul(float deimp, float imp);
void afisare(float *rezult);
const float INFINIT=3.4e+38;

main()
{
float x
lrscr( c
citire(&x,&y);
(x,y); rez=calcul
afisare(&rez);
}
ti /*Definirea func
clarat initial* de
printf("Dati A="); scanf("%f",a)
b) printf("Dati B="); scanf("%f",
}

oat calcul(float deimp, float imp) fl
{
if(imp==0)
return (INFINIT);
else
return(deimp/imp);
}

id afisare(float *re vo
{
if(*rezult==INFINIT)
printf("Impartire la zero!\
else
printf("Rezultatul impart
emorat la adresa de mem =%f\nM
=%p\n", *rezult, rezul
getch();
}

150
Laboratorul 28 Diverse
28.2.2.1 P5
S se elaboreze un program care s citeasc un ir de numere reale de la tastatur, s
determine maximul i minimul i s construiasc un fiier de date cu elementele irului.
Strategia de rezolvare: Programul urmtor intenioneaz s exemplifice modul de lucru cu
fiiere n C++. Mai nti va fi creat pe hard disk un fiier "date.dat" care va fi pregtit pentru a
scrie n el elementele irului citite de la tastatur. Pe msur ce sunt citite elementele irului
se determin suma acestora i maximul curent. Dup ce ntreg fiierul a fost nregistrat,
acesta va fi nchis pentru a putea fi stocat corespunztor pe harddisk. La ieirea din program,
lipsa instruciunii close (fiier) face ca fiierul creat s nu poat fi utilizat, lipsindu-i marcajul
EOF de sfrit de fiier. Dup crearea fiierului, a doua etap o constituie deschiderea
acestuia pentru citire i verificarea corectitudinii datelor nregistrate. Programul mai
contorizeaz i timpul scurs (n secunde) din momentul nceperii rulrii programului i pn la
oprirea execuiei acestuia.
/*Program 15.
programul citeste un sr de numere reale, determina maximul si media aritmetica si
construieste un fisier date.dat cu elementele sirului.*/
#define NMAX 100
#define maxim(x,y) x > y ? x : y
#define MINUS_INFINIT -3.4e+38
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include<time.h>

void main()
{
FILE *fpd, *fpc;
int i,n;
float max, media, temp;
/*Momentul de start a contorizarii timpului*/
long t=time(NULL);
clrscr();
printf("Dati numarul de elemente ale vectorului: N= ");
scanf("%2d",&n);
puts("Dati elementele sirului:");
if((fpd=fopen("date.dat","wt"))==NULL)
{
puts("Nu pot creea fisierul!");
exit('0');
}
media=0.0;
max=MINUS_INFINIT;
for(i=1; i<n+1; i++)
{
printf("A[%2d]= ",i);
scanf("%f", &temp);
media+=temp;
max=maxim(max,temp);
fwrite(&temp, sizeof(temp), n,fpd);
}
media=media/n;
fclose(fpd);
printf("Valoarea maxima MAX=a%.7f\n",max);
printf("Valoarea medie MED=%.7f\n",media);
getch();
if((fpc=fopen("date.dat", "rt"))==NULL)
{
puts("Nu pot deschide fisierul!");
exit('0');
}
puts("Sectiunea de citire a fisierului creat.");

151
Laboratorul 28 Diverse
for(i=1; i<n+1; i++)
{
fread(&temp, sizeof(temp), n,fpc);
printf("B[%2d] = %.7f\n",i,temp);
}
fclose(fpc);
/*Momentul de oprire a contorizarii timpului*/
t=time(NULL)-t;
printf("Programul a rulat %1d secunde.", t);
getch();
}

28.3 Baze de numeraie
28.3.1 Problema 1: Transformarea unui numr dintr-o baz oarecare b n baza 10.
Pentru transformarea cerut am putea
folosi algoritmul clasic de conversie dintr-o
baz n baza 10. Deoarece n limbajul C
exist predefinit o funcie care efectueaz
conversia vom prefera s exemplificm
modul ei de utilizare.
Funcia strtol este folosit pentru a face
conversia unui numr dintr-o baz b (2<= b
<=36) n baza 10. Numrul iniial, ntruct
poate conine i litere este reprezentat ca
un ir de caractere. Pentru verificarea
corectitudinii este setat un pointer la primul
caracter din ir care a generat eroarea de
conversie. Dac pointerul este NULL nu a
aprut nici o eroare, lat o exemplificare a
utilizrii:
//Transformarea unui numar dintr-o
baza oarecare b n baza 10.
#include<stdio.h>
#include<stdlib.h>

void main()
{
int baza; char numar[30],*p;long nr;
puts("/n Intr
baza:");scanf("%d",&baza);
printf("'introduceti nr in baza
%d:",baza);
scanf("%s",numar);
nr=strtol(numar,&p,baza);
if(*p) printf("Er la caracterul:
%c",*p);
else printf("Nr este:%1d",nr);
}

28.3.2 Problema 2: Conversia unui numr din baza b n baza b
k

Conversia direct a unui numr din baza b n baza b
k
const n gruparea cifrelor cte k,
ncepnd de la ultima cifr, pn la cifra cea mai semnificativ. Fiecare grup de k cifre din
baza b va genera o cifr pentru numrul din baza b
k
. Datele folosite n program sunt:
b - baza iniial;
k - puterea la care este baza final;
s - irul care conine caracterele cifrelor numrului n baza b;
a - tabloul de valori ale cifrelor numrului n baza to;
n - numrul iniial de cifre (lungimea irului s);
nr- numrul de grupe de cte k cifre ale numrului n baza to (se completeaz cu
zerouri la stnga pentru a obine un numr ntreg de grupe de cte k cifre);
c - tabloul de cifre ale numrului n baza b\ calculat dup formula:
c[j] =
i = 0(k-1)
a[i + j*k] b
i
, j = 0...(nr-1);
Pentru folosirea irurilor de caractere i transformarea lor n iruri de cifre i invers, vom
inversa ordinea elementelor din tablouri (cifra de pe poziia 0 a irului de caractere va ajunge
n irul de cifre pe poziia cea mai mare).

152
Laboratorul 28 Diverse

//Conversia unui numar din baza b n baza b^k
#include<string.h>
#include<stdio.h>
#include<conio.h>
#include<math.h>

void main()
{
int nr,i,j,k,b,n,a[15],x[15],c[15];char s[15];
printf("\nIntroduceti baza b: ");scanf("%d",&b);
printf("Introduceti puterea k: ");scanf("%d",&k);
printf("Introduceti nr in baza %d: ",b);scanf("%s",&s);
n=strlen(s);/*Se calculeaza val cifrelor numarului in baza b*/
for(i=0;i<n;i++)
if(s[i]>'9') a[i+1]=s[i]-'A'+10;
else a[i+1]=s[i]-'0';
nr=(n+k-1)/k;
/*Se completeaza ultimul grup de cifre cu 0*/
for(i=n;i<nr*(k+1);i++)
x[i]=0;
/*Se inverseaza pozitiile cifrelor*/
for(i=nr*(k+1);i>0;i--)
x[n-i]=a[i];
for(i=0;i<nr;i++)/*Se calculeaza cifra i din baza b^k*/
{
c[nr-1]=x[i*k];
/*Ptr. a ajunge din nou in sir se inverseaza ordinea elementelor*/
for(j=1;j<k;j++)
c[nr-j]+=x[i*k+j]*pow(b,j);
}
/*Se convertesc cifrele in caractere */
printf("Reprezentarea in baza %g este:",pow(b,k));
for(i=nr-1;i>=0;i--)
if(c[nr-i]>9)putchar(c[nr-i]+('A'-10));
else putchar(c[nr-1]+'0');
}

28.3.3 Problema 3: Transformarea unui numr din baza b
k
n baza b.
Conversia direct a unui numr din baza b" n baza b const n a genera dintr-o cifr din
baza b
k
un grup de k cifre n baza b. Aceasta se va face prin mpriri repetate ale cifrei la
valoarea bazei b. Chiar dac se ajunge nainte de k mpriri la valoarea 0, se pstreaz i
cifrele egale cu 0 pn la efectuarea celor k mpriri. Excepia o constituie cifra cea mai
semnificativ pentru care se vor elimina ultimele cifre de 0 obinute. Vom utiliza urmtoarele
date:
c - tablou cu cifrele n baza b
k
;
a - tablou de cifre n baza b.
n program vom considera cifra cea mai semnificativ de la poziia 0 a tablourilor.
//Transformarea unui numar din baza b^k n baza b
#include<stdio.h>
#include<string.h>

void main()
{
int a[100],c[100],k,j,nr,i,bk,b; char n[100];
printf("introduceti b si k: ");scanf("%d %d",&b,&k);
for(bk=i=1;i<=k;i++)
bk*=b;printf("Numarul in baza %d",bk);scanf("%s",n);
nr=strlen(n);strupr(n);
/*Obtinerea tabloului de cifre*/

153
Laboratorul 28 Diverse
for(i=0;i<nr;i++)
{
if(n[i]<='9')c[i]=n[i]-48;
else c[i]=n[i]-55;
if(c[i]<0||c[i]>=bk)/*Verificarea corectitudinii cifrelor*/
{ printf("Cifra de pe pozitia %d incorecta!",i+1);return;}
}
for(i=0;i<nr;i++)
for(j=0;j<=k;j++)
{/*c[i] se transforma in k cifre in baza b prin impartirea de k
ori a lui c[i]la b, resturile impartirilor fiind cele k cifre ce se
stocheaza in a*/
a[(i+1)*k-j]=c[i]%b;
c[i]/=b;
}
nr=k*nr-1;/*nr de cifre ale reprezentarii in baza b*/
i=0;
/*eliminarea cifrelor de 0 de pe pozitiile cele mai semnificative */
while(a[i]==0) i++;
/*Afisarea cifrelor numarului reprezentat in baza b*/
printf("Numarul in baza %d este: ",b);
for(j=1;j<=nr;j++)
printf("%d",a[j]);
}

28.3.4 Problema 4: Reprezentarea condensat a unul numr.
Un numr n baza 10 cu foarte multe cifre se reprezint condensat n felul urmtor: fiecare
cifr zecimal se scrie pe patru bii, iar semnul se reprezint prin numrul 15 pe patru bii
(dac numrul este pozitiv), respectiv 14 pe patru bii (dac numrul este negativ); biii de
semn sunt plasai la sfrit.
Cifrele mpreun cu semnul trebuie s ocupe un numr par de octei. Dac este cazul,
numrul se completeaz cu maximum trei zerouri nesemnificative (reprezentate pe cte
patru bii).
S se afieze reprezentarea condensata a unui numr introdus de la tastatur.
//reprezentarea condensata a unui nr introdus de la tastatura
#include<stdio.h>
#include<conio.h>
#include<string.h>
void main()
{
int nr_zerouri,c_semn, cifra,c[5],i,j,dim;
char nr[100];
printf("\nintr nr");scanf("%s",nr);
dim=strlen(nr);
if(nr[0]=='-')
{c_semn=14;j=1;}/*ignoram semnul, deci pornim de la pozitia 1*/
else
{c_semn=15;j=0;}
nr_zerouri=(4-(dim-j+1)%4)*4%16;
for(i=1;i<=nr_zerouri;i+=4) printf("0000|");
for(i=j;i<=dim;i++)
{
cifra=i==dim ?c_semn:nr[i]-'0';
for(j=4;j>=1;j--)
{c[j]=cifra%2;cifra/=2;}
for(j=1;j<=4;j++) printf("%d",c[j]);
putch('|');
}
puts("\b");/*sterge ultimul caracter '|'generat*/
}


154
Laboratorul 28 Diverse
28.4 Prelucrri numerice
28.4.1 Problema 2: N din 4
Se tie c din numrul 4 se poate obine orice numr natural N scris n baza zece prin
aplicarea urmtoarelor operaii:
a) se scrie la sfrit cifra 4;
b) se scrie la sfrit cifra 0;
c) se mparte ia 2, dac numrul este par.
Se cere s se scrie un program care produce un ir de numere construit conform regulilor
precedente, ir n care primul numr este 4, iar ultimul este N. Exemple:
pentru N = 25: 4, 2, 1, 10, 5, 50, 25;
pentru N = 250: 4, 2, 1, 10, 5, 50, 25, 250;
nainte de a rezolva problema prezentm cteva observaii ajuttoare:
irul de transformare nu este unic; Astfel, pentru primul exemplu mai putem obine irul: 4
, 40 , 20 , 10 , 100, 50 , 25 care are aceeai lungime;
de asemenea, putem obine iruri de transformare de diferite lungimi. O soluie de
generare a unui ir este urmtoarea:
Se pleac de la numrul N i aplicm urmtoarele operaii:
a) se terge ultima cifra dac aceasta este 0 sau 4;
b) n celelalte cazuri numrul se dubleaz.
Operaiile se execut pn la obinerea numrului 4. Secvena tiprit n ordine invers, de la
numrul 4 la numrul N, este o secven corect de transformare.
//din numarul 4 se poate obtine orice numar natural N scris n baza zece
#include<iostream.h>
#include<conio.h>

void main()
{
int x[20] ,n,i, j ;
cout<<"Introduceti numarul: ";cin>>n;
x[1]=n;
for(i=1;x[i]!=4;i++)
if(x[i]%10==0||x[i]%10==4) x[i+1]=x[i]/10;
else x[i+1]=x[i]*2;
for(j=i;j>=1;j--) cout<<x[j]<<' ';
getch();
}

Vom trata n primele trei probleme irurile de tip Fibonacci definite prin:
f(0) = f(1) = 1, f(i+2) = f(i+1)+f(i) pentru orice i > 0.
28.4.2 Problema 1: Descompunerea unui numr natural n ntr-o sum de termeni
Fibonacci.
Observm c descompunerea n termeni Fibonacci a unui numr se poate face n modul
urmtor:
Se ia de fiecare se dat termenul Fibonacci de valoare maxim care nu depete valoarea
numrului n. Acesta va face parte din descompunere. Se reia descompunerea n acelai mod
pentru diferena rmas pn cnd aceasta este 0.
//descompunerea in termeni Fibonacci a unui nr
#include<iostream.h>
void main()
{
int i,j,n,f[50];
cout<<"\nintrod nr";cin>>n;
f[0]=0;f[1]=1;i=1;

155
Laboratorul 28 Diverse
do
{
while(f[i]<=n)
/*se determina cel mai mare termen Fibonacci care nu depaseste n*/
{f[i+1]=f[i]+f[i-1];i++;}
cout<<f[i-1]<<' ';
n-=f[i-1];i=2;
}/*se face dif dintre nr si termen si se continua descompunerea*/
while(n>0); /*pana cand nr ramas este 0*/
}
28.4.3 Problema 2: S se determine, fr a calcula efectiv termenii irului Fibonacci,
dac dou numere m i n sunt termeni consecutivei irului.
Vom aplica urmtoarele formule:
Fi =
1
2
( ) 1+ 5 ; Fi^ =
1
2
( ) 1- 5 ; Fi
n
= F
n
Fi
n
+ F
n-1
; Fi
n
^ = F
n
Fi^ + F
n-1
; F
n
=
1
5
(Fi
n
- Fi
n
^)
pentru a afla ordinul posibil k al numrului mai mare (fie acesta n), urmnd s verificm dac
termenul de ordin k-1 este egal cu m.
/*sa se determine daca m si n sunt termeni
consecutivi ai sirului lui Fibonacci*/
#include<stdio.h>
#include<math.h>
void main()
{
double fi=(1+sqrt(5))/2,fi1=(1-sqrt(5))/2,i,mk,nk;
int n,m,k;
puts("intr numerele");scanf("%d%d",&n,&m);
if(n<m)
m^=n^=m^=n;
i=log(m*fi+n)/log(fi);
k=(int)(i+0.5);
mk=(1/sqrt(5))*(pow(fi,k)-pow(fi1,k));
nk=(1/sqrt(5))*(pow(fi,k-1)-pow(fi1,k-1));
if((int)mk!=n||(int)nk!=m)
printf("NU sunt");
else printf("Sunt");
puts("termeni fibonacci consecutivi");
}

28.4.4 Problema 3: S de determine numrul partiiilor unui numr n n m pri.
S notm cu S[i] suma primilor i termeni din partiia numrului. Avem:
0 = s[0]<s[1]<s[2]< ...< s[m]=n;
Observm c prima i ultima sum sunt fixe. Celelalte sume le putem privi ca o submulime
de m-1 termeni din mulimea {1,2,....,n-1}. Numrul posibilitilor este, dup cum tim, C
m-1
n-1
.
Notm cu p[n][m] numrul partiiilor unui numr n n m pri; dac m = 1 atunci p[n][1] =
p[n][n] = 1;
p[n+k][n] =
i=1k
p[n][i]
//nr partitiilor unui nr n in m parti
#include<iostream.h>
extern unsigned_stklen=20000U;

void main()

156
Laboratorul 28 Diverse
{
short n,m,j,i,k;
unsigned long p[50][50]={0};
cout<<"\nIntr numarul si nr de termeni descompunere: ";
cin>>n>>m;
for(i=1;i<=n;i++)
p[i][1]=p[i][i]=1;
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
{
p[i+j][j]=0;
for(k=1;k<=j;k++)
p[i+j][j]+=p[i][k];
}
cout<<"Numarul de partitii ale intregului este "<<p[n][m];
}

ncercai s studiai cazul cnd partiia este format din cel mult n termeni.
28.4.5 Problema 4: S se determine numrul de partiii n k submulimi ale unei mulimi
de n elemente.
Numrul care exprim mulimea partiiilor n k submulimi ale unei mulimi mai este cunoscut
i sub numele de Numrul Iul Stirling de spea a doua i se noteaz cu S(n,k).
Pentru a obine S(n,k) vom face urmtoarele observaii:
I) S(n,1)=1; S(n,n)=1; Numrul partiiilor unei mulimi ntr-o singur submulime i numrul
partiiilor unei mulimi de n elemente n n submulimi este 1.
II) Pentru k>n avem: S(n,k)=0.
Pentru celelalte cazuri vom face urmtoarea observaie care ne ajut s determinm iterativ
numrul partiiilor unei mulimi cu k elemente n funcie de dou numere calculate anterior:
III) S(n,k) poate fi descompus n funcie de modul n care alegem partiiile astfel:
a) Dac partiionm primele n-1 elemente n k-1 submulimi suntem obligai s punem ultimul
element la submulimea k. Deci sunt S(n-1,k-1) posibiliti.
b) Dac partiionm primele n-1 elemente n k submulimi atunci ultimul element poate fi pus
n orice submulime, deci sunt S(n-1,k)*k posibiliti de partiionare n acest caz.
Aadar S(n,k)=S(n-1,k-1)+S(n-1,k)*k.
//nr de partitii in k submultimi ale unei multimi de n elemente
#include<iostream.h>
long s[50][50];
void main()
{
int i,j,k,n;
cout<<"\nNr de elemente: ";cin>>n;
cout<<"Nr de submultimi: ";cin>>k;
if(k<=n)
{
for(i=2;i<=n;i++) s[1][i]=s[i][i+1]=0;
for(i=1;i<=n;i++) s[i][1]=1;
for(i=2;i<=n;i++)
for(j=2;j<=k;j++)
s[i][j]=s[i-1][j-1]+j*s[i-1][j];
cout<<s[n][k];
}
else cout<<"Valori incorecte!";
}


157
Laboratorul 28 Diverse
28.4.6 Problema 5: S se determine numrul de funcii surjective f: A->B , tiind c
mulimea A are n elemente i mulimea B are m elemente.
O prima variant de calcul a numrului funciilor surjective este aceea de a folosi rezultatele
problemei anterioare:
orice surjecie realizat poate fi exprimat sub forma: f
-1
(a
1
)Uf
-1
(a
2
)U....Uf
i
(a
m
)
Aadar depinde de numrul de partiii ale unei mulimi de m elemente n n submulimi.
Cum ordinea termenilor nu conteaz rezult c un numr de n! funcii surjective vor genera
aceeai partiie.
Deci numrul de funcii surjective este: S(m,n) /n! unde S este numrul lui Stirling de spea a
doua, numr ce a fost determinat n programul anterior.
Lsm aceast variant de program n seama cititorului. V propunem n ceea ce urmeaz o
nou variant.
Numrul de funcii surjective este egal cu numrul total de funcii din care:
- se scade numrul de funcii care nu conin exact un element: C
1
m
*(m-1)
n
- se adun apoi numrul de funcii care nu conin exact dou elemente: C
2
m
*(m-2)
n
- se scade apoi numrul de funcii care nu conin exact trei elemente. Observm c operaia
continu pn cnd ajungem la toate funciile care nu conin exact n-1 elemente. Formula
obinut se poate afla folosind principiul includerii i excluderii obinnd n final:

i=0n-1
C
i
m
(n-i)
m
(-1)
i

//nr de functii surjective
#include<iostream.h>
#include<math.h>

unsigned long comb(unsigned, unsigned);

void main()
{
short m,n,i;
unsigned long nr_surj=0;
cout<<"\n nr de elemente din prima multime: ";cin>>m;
cout<<"\n nr de elemente din a doua multime: ";cin>>n;
for(i=0;i<=n;i++)
nr_surj+=comb(n,i)*pow(n-1,m)*pow(-1,i);
cout<<"\n nr de func surj "<<nr_surj;
}

unsigned long comb(unsigned n, unsigned k)
{
unsigned long nr=1; register short j;
for (j=1;j<=k;j++)
nr=(n-j+1)*nr/j;
return nr;
}

28.4.7 Problema 3: Program pentru determinarea numerelor prime pn la o valoare n,
folosind "Ciurul lui Eratostene":
La nceput presupunem c toate numerele sunt prime. n momentul cnd gsim un numr
prim k, vom scoate toi multiplii lui mai mici dect numrul n (2*k,3*k,...) din mulimea
numerelor prime.
Pentru a stoca dac un numr este prim sau nu, n program vom folosi pentru fiecare numr
pn la n cte un bit care la nceput va avea valoarea 1. Pentru n numere vor fi necesari
pentru reprezentarea existenei divizorilor (n+7)/8 octei. n momentul cnd gsim un numr
prim, pentru toi multiplii lui se va seta bitul corespunztor pe 0.

158
Laboratorul 28 Diverse
#include<stdio.h>
#include<conio.h>
#include<math.h>
#define DIM 320
#define NMAX 2560
char bit[32000];
char bito[]={ 0x7F, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, 0xFE};
# define ESTE_PRIM(x) ((bit[(x-1)/8])>>(7-(x-1)%8)) & 1
# define ELIM_MULT(mx) bit[(mx-1)/8] &=bito[(int)((mx-1)%8)]

void main()
{
unsigned long n,i,prim_max,nr=2560;
clrscr();
printf("Numarul maxim: ");scanf("%lu",&nr);
for(i=0;i<=nr/8+2;bit[i++]=0xFF);
for(n=2;n<=nr;n++)
if(ESTE_PRIM(n))
{
prim_max=n;
for(i=2*n;i<=nr;i+=n)
ELIM_MULT(i);
}
printf("Cel mai mare numar prim mai mic sau egal dect %lu este %lu", nr,
prim_max);
}
28.4.8 Problema 4: Deteminarea celui mai mic numr care are exact k divizori.
Aici vom d o variant care verific pentru fiecare numr i ncepnd de la valoarea cea mai
mic, k+1, dac numrul su de divizori este k. n caz afirmativ numrul gsit are k divizori i
este i cel mai mic, deci nu se mai caut alte numere, programul terminndu-se.
#include<stdio.h>
int k,i,nr;

nr_divizori(int n) /* intoarce numarul de divizori ai lui n */
{
int i;
for(i=2,nr=0;i<=n/2;i++)
if(n%i==0) /*se verifica daca i este divizor*/
{
printf("%4d",i);
nr++; /*nr de divizori pp zisi*/
}
return nr+2 /* se adauga 1 si numarul insusi */;
}

void main()
{
printf("\nNumarul de divizori: "); scanf("%d",&k);
for(i=k+1;;i++)
{
printf("\n%4d: ",i);
if(nr_divizori(i)==k)
{
printf("\n Celmai mic numar cu %d divizori este %d \n",k,i);
return; /*se trece la urmatorul numar*/
}
}
}
28.4.9 Problema 5: S se fac un program care realizeaz urmtoarele:
o descompune un numr n factori primi;

159
Laboratorul 28 Diverse
o pe baza decompunerii numerelor n factor primi face aflarea celui mai mare divizor
comun i a celui mai mic multiplu comun a dou numere.
Programul const din trei funcii:
prima funcie face descompunerea unui numr n factori primi, se verific toi divizorii
ncepnd cu valoarea 2. Pentru a stoca numrul divizorilor primi la un anumit moment
se va folosi variabila nr_div. Dac are loc divizibilitatea (restul mpririi lui n la i este
0), se incrementeaz nr_div, se stocheazdivizorul ntr-un tablou f folosit n acest scop
i se iniializeaz exponentul stocat ntr-un tablou p cu 0. Ct timp are loc mprirea
exact a numrului la divizor, se va incrementa exponentul i se va nlocui numrul n
cu ctul mpririi ntre acesta i divizor. n momentul n care nu se mai mparte exact,
se trece la urmtorul divizor posibil. Astfel, datorit efecturii tuturor mpririlor
posibile, asigurm stocarea numai a divizorilor care sunt primi, verificarea primaritii
unui divizor nemaifiind necesar.
a doua funcie va face aflarea celui mai mare divizor comun plecnd de la
descompunerile celor dou numere. Se vor selecta divizorii primi care sunt comuni
ambelor numere, la puterea cea mai mic.
a treia funcie va face aflarea celui mai mic multiplu comun folosind descompunerea n
factori primi a celor dou numere. Se vor selecta toi divizorii care apar n una din
descompuneri. Dac apar n ambele descompuneri se va selecta puterea maxim.
#include<iostream.h>
#include<conio.h>

typedef int tablou[30];
int n,n1,n2;
tablou f,p,f1,p1,f2,p2;
int k,nr_div1,nr_div2,i1,i;

void divizori(int n, int *nr, tablou f, tablou p)
{
short i=2, nr_div=0;
while(i<=n)
{
if(n%i==0)/* Daca se gaseste un divizor al lui n */
{f[++nr_div]=i;
p[nr_div]=0;
/* Se determina puterea maxima la care apare divizorul in descompunere */
do
{n/=i;
++p[nr_div];
}
while(n%i==0);
}
++i;/*se trece la urmatorul divizor*/
}
*nr=nr_div;
}

void cmmdc(tablou p1, tablou p2, tablou f1, tablou f2, int n1, int n2, int *nr,
tablou p, tablou f)
{
short i1=1,i2=1,n=0;
/* Se determina daca apare un factor prim comun in cele doua descompuneri */
while(i1<=n1 && i2<=n2)
{
if(f1[i1]==f2[i2] )/* Se determina puterea minima */
if(p1[i1]<=p2[i2])
{f[++n]=f1[i1]; p[n]=p1[i1]; ++i1;++i2; }
else
{f[++n]=f2[i2]; p[n]=p2[i2]; ++i1;++i2; }
else

160
Laboratorul 28 Diverse
if(f1[i1]<f2[i2])
++i1;/* Altfel se trece la urmatorul element */
else ++i2;
if(n==0) {f[++n]=1; p[n]=1;}
*nr=n;
}
}

void cmmmc(tablou p1,tablou p2,tablou f1,tablou f2,int n1,int n2, int *n,tablou
p,tablou f)
{
short i1=1,i2=1,i=0;
/* Se ia pe rand fiecare factor din cele doua descompuneri */
while(i1<=n1 && i2<=n2)
{
if(f1[i1]==f2[i2])
/* Daca un factor apare in ambele descompuneri */
{
++i;/* selectam divizorii comuni la puterea cea mai mare */
f[i]=f1[i1];
if(p1[i1]<=p2[i2]) p[i]=p2[i2];
else p[i]=p1[i1];
++i1; ++i2;
}
else
if(f1[i1]<f2[i2] )
{/*si divizorii necomuni */
f[++i]=f1[i1]; p[i]=p1[i1++];}
else {f[++i]=f2[i2]; p[i] =p2[i2++]; }
}
while(i1<=n1)
{p[++i]=p1[i1]; f[i]=f1[i1++]; }
while(i2<=n2)
{
++i; p[i]=p2[i2]; f[i]=f2[i2]; ++i2;
}
*n=i;
}

void main()
{
clrscr();
cout<<"Introduceti primul numar: ";cin>>n1;
cout<<"Introduceti al doilea numar: ";cin>>n2;
divizori(n1,&nr_div1,f1,p1);
divizori(n2,&nr_div2,f2,p2);
cout<<"\nPrimul numar are "<<nr_div1<<" divizori: ";
for(i=1;i<=nr_div1;i++)
cout<<f1[i]<<'^'<<p1[i]<<" * ";
cout<<"\b\b ";
cout<<"\nAl doilea numar are "<<nr_div2<<" divizori: ";
for(i=1;i<=nr_div2;i++)
cout<<f2[i]<<'^'<<p2[i]<<" * ";
cout<<"\b\b ";
cmmdc(p1,p2,f1,f2,nr_div1,nr_div2,&n,p,f);
cout<<"\nCMMDC: ";
for(k=1;k<=n;k++)
cout<<f[k]<<'^'<<p[k]<<" * ";
cout<<"\b\b "; //stergem ultima '*'
cmmmc(p1,p2,f1,f2,nr_div1,nr_div2,&n,p,f);
cout<<"\nCMMMC: ";
for(k=1;k<=n;k++)
cout<<f[k]<<'^'<<p[k]<<" * ";
cout<<"\b\b "; //stergem ultima '*'

161
Laboratorul 28 Diverse
}

28.5 1.4. Prelucrarea tablourilor
28.5.1 Problema 5: Eliminarea unei linii i a unei coloane dintr-o matrice.
Pentru tergerea unei linii i dintr-o matrice vom face deplasarea liniilor de sub linia i cu o
poziie mai sus. Pentru a indica tergerea, ultima linie va fi completata cu 0. La fel pentru
tergerea unei coloane j vom deplasa celelalte coloane de la dreapta lui j cu o poziie spre
stnga.

#include <stdio.h>
#define DIM 10

int m,n,a[DIM][DIM];
void elim_lin(int);
void elim_col(int);

void main()
{
int i,j,k1,k2;
/*Citirea matricii dintr-un fisier*/
FILE *f;
f=fopen("date.in","r");
fscanf(f," %d%d",&m,&n);
for(i=1;i<=m;i++)
for(j=1;j<=n;j++)
fscanf(f,"%d",&a[i][j]);
fclose(f);

printf("\nLinia ce trebuie eliminata: ");scanf("%d",&k1);
printf("Coloana ce trebuie eliminata: ");scanf("%d",&k2);
elim_lin(k1);
elim_col(k2);
printf("\nMatricea:");
for(i=1;i<=m;i++)
{
printf("\n");
for(j=1;j<=n;j++)
printf("%d ",a[i][j]);
}
}

void elim_lin(int lin)
{
int i,j;
for(i=lin+1;i<=m;i++)
for(j=1;j<=n;j++)
a[i-1][j]=a[i][j];
for(j=i;j<=n;j++)
a[m][j]=0;
--m;
}

void elim_col(int col)
{
int i,j;
for(i=1;i<=m;i++)

162
Laboratorul 28 Diverse
for(j=col+1;j<=n;j++)
a[i][j-1]=a[i][j];
for(j=0;j<=n;j++)
a[i][n]=0;
--n;
}

28.5.2 Problema 9: Adunarea, scderea, nmulirea i mprirea a dou polinoame.
Reprezentarea unui polinom se face n felul urmtor:
o gradul polinomului se stocheaz ntr-o variabil de tip int
o coeficienii polinomului se stocheaz ntr-un tablou de tip float.
Pentru acesta am definit tipul coef ca un tablou de 50 de elemente de tip float. Elementul
de pe poziia i conine coeficientul termenului de grad i.
Pentru adunarea i scderea polinoamelor vom aduna, respectiv vom scdea, termen cu
termen, coeficienii cu acelai indice. Rezultatul operaiei de nmulire este un polinom z de
grad m+n, iar coeficientul fiecrui termen al su va fi calculat dup formula:
z[i+j] =
i=0 m; j=0n
x[i]y[j]
Pentru mprirea polinoamelor se vor afla coeficienii ctului mprind pe rnd coeficientul
termenului de cel mai mare grad, care a rmas nenul, din polinomul dempritului, la
coeficientul termenului dominant al mpritorului.

//Operatii cu polinoame
#include<iostream.h>
#include<conio.h>
#include<mem.h>
#include<math.h>
typedef float coef[50];

void introducere(int &n,coef x);
void afisare(int n, coef x);
void adunare(int n, coef x, int m, coef y,int &p, coef z);
void scadere(int n, coef x, int m, coef y, int &p, coef z);
void inmultire(int n, coef x, int m, coef y, int &p, coef z);
void impartire(int n, coef x, int m, coef y,int &p, coef z, int &q, coef t);

void main()
{
float x[50], y[50], z[50], t[50];
int n,m,p,q;
clrscr();
cout<<"\nPrimul polinom"; introducere(n,x);
cout<<"\nAl doilea polinom"; introducere(m,y);
adunare(n,x,m,y,p,z);
cout<<"\nPolinomul suma "; afisare(p,z);
scadere(n,x,m,y,p,z);
cout<<"\nPolinomul diferenta "; afisare(p,z);
inmultire(n,x,m,y,p, z) ;
cout<<"\nPolinomul produs "; afisare (p,z);
impartire(n,x,m,y,p,z,q,t);
cout<<"\nPolinomul cat "; afisare(p,z);
cout<<"\nPolinomul rest "; afisare (q,t) ;
}

void introducere(int &n,coef x)
{
cout<<"\nGradul polinomului:" ;cin>>n;
cout<<"Introduceti cei "<<n+1<<" coeficienti ai polinomului: \n";

163
Laboratorul 28 Diverse
for(int i=n;i>=0;i--)
cin>>x[i];
}

void afisare(int n,coef x)
{
cout<<"\nGradul polinomului: "<<n<<". Polinomul are coeficientii: ";
for (int i=n;i>=0;i--)
cout<<x[i]<<' ';
}

void adunare(int n, coef x, int m, coef y, int &p, coef z)
{
int i,g;
memset(z,0,sizeof(coef));
if(n<m)
{ g=n;
for (i=n+1;i<=m;i++) z[i]=y[i];
p=m;}
else
{ g=m;
for (i=m+1;i<=n;i++) z[i]=x[i];
p=n;}
for(i=0;i<=g;i++)
z[i]=x[i]+y[i];
while(z[p]==0 && p>0) --p;
}

void scadere(int n, coef x, int m, coef y, int &p, coef z)
{
int i,g;
memset(z,0,sizeof(coef));
if (n<m)
{ g=n; for(i=n+1;i<=m;i++) z[i]=-y[i]; p=m;}
else
{ g=m; for(i=m+1;i<=n;i++) z[i]=x[i]; p=n;}
for (i=0;i<=g;i++)
z[i]=x[i]-y[i];
while(z[p]==0 && p>0) --p;
}

void inmultire(int n, coef x, int m, coef y, int &p, coef z)
{
p=m+n;memset(z,0,sizeof(coef));
for(int i=0;i<=n;i++)
for(int j=0;j<=m;j++)
z[i+j]+=x[i]*y[j];
}

void impartire(int n, coef x, int m, coef y, int &p, coef z, int &q, coef t)
{
if (n<m)
{ p=0; z[0] =0;q=n; memcpy(t, x, sizeof (coef));}
else
{
p=n-m; memcpy(t,x,sizeof(coef));
for(int i=p;i>=0;i--)
{
z[i] =t[i+m]/y[m];
for(int j=0;j<=m;j++)
t[i+j] -=z[i]*y[j] ;
}
q=m-1;
while (t[q] ==0&&q>0) --q;

164
Laboratorul 28 Diverse
}
}


165

S-ar putea să vă placă și