Sunteți pe pagina 1din 165

Cristian Constantin IOSIFESCU

Programarea
calculatoarelor i
limbaje de programare
Lucrri de laborator

Galai University Press- 2014

Cuvnt nainte
Volumul de fa reprezint suportul pentru lucrrile de laborator efectuate la
disciplina Programarea Calculatoarelor i Limbaje de Programare, care se pred
studenilor din anul I al Facultii de Mecanic de la Universitatea Dunrea de
Jos din Galai.
Cartea conine exemple de programe redactate n limbajul de programare C,
nsoite de explicaii i noiuni teoretice sumare, precum i unele probleme propuse
spre rezolvare. Ea reprezint o completare a elementelor teoretice predate la curs,
iar scopul ei este utilizarea direct i intensiv la scrierea programelor la calculator.
Programele prezentate au o complexitate progresiv i abordeaz principalele
elemente ale unui limbaj de programare.

Galai, 2014

Autorul

Cuprins
Bibliografie..........................................................................................................................6
1.
Generaliti ..............................................................................................................7
1.1
Tastatura ..............................................................................................................7
1.2
Ecranul aplicaiei Borland C .............................................................................8
1.3
Principalele meniuri i comenzi ale aplicaiei ................................................9
2.
Scheme logice i pseudocod................................................................................12
2.1
Reprezentarea algoritmilor prin scheme logice ...........................................12
2.2
Reprezentarea algoritmilor prin pseudocod.................................................12
2.3
Exemple .............................................................................................................13
3.
Noiuni de baz .....................................................................................................16
3.1
Structura unui program n C++......................................................................16
3.2
Principalele mesaje de avertizare i eroare ale compilatorului..................17
3.3
Date n limbajului C .........................................................................................18
3.4
Exemple .............................................................................................................20
4.
Intrri/ieiri n C/C++...........................................................................................21
4.1
Citirea/scrierea datelor ...................................................................................21
4.2
Intrri/ieiri n C++ .........................................................................................21
4.3
Intrri/ieiri n C ..............................................................................................22
4.4
Exemple .............................................................................................................23
4.5
Probleme propuse ............................................................................................26
5.
Operatori i expresii .............................................................................................28
5.1
Operatori ...........................................................................................................28
5.2
Prioritatea operatorilor ....................................................................................30
5.3
Conversia ntre bazele de numeraie .............................................................30
5.4
Exemple .............................................................................................................31
5.5
Probleme propuse ............................................................................................38
6.
Structuri de decizie (alternative, de selecie) ...................................................42
6.1
Structura de decizie: instruciunea if...........................................................42
6.2
Structura de selecie cu ramuri multiple: instruciunea switch...............42
6.3
Exemple if, switch ............................................................................................43
6.4
Probleme propuse ............................................................................................45
7.
Structura ciclic cu test iniial.............................................................................47
7.1
Instruciunea while ........................................................................................47
7.2
Exemple while ................................................................................................47
7.3
Instruciunea for .............................................................................................49
7.4
Exemple for .....................................................................................................49
7.5
Probleme propuse ............................................................................................51
8.
Structura ciclic cu test final ...............................................................................53
8.1
Instruciunea do - while ............................................................................53
8.2
Exemple do - while...........................................................................................53
8.3
Prelucrarea numerelor .....................................................................................56
8.4
Faciliti de ntrerupere a unei secvene........................................................59
8.5
Exemple break, continue ...........................................................................60
8.6
Probleme propuse ............................................................................................60
9.
Tablouri unidimensionale...................................................................................63
9.1
Declaraia de tablou .........................................................................................63

9.2
9.3

Vectori................................................................................................................64
Exemple .............................................................................................................64
10.
iruri de caractere .................................................................................................71
10.2
Probleme propuse ..........................................................................................74
11.
Tablouri multidimensionale...............................................................................76
11.1
Exemple ...........................................................................................................76
11.2
Probleme propuse ..........................................................................................78
12.
Pointeri i adrese ...................................................................................................80
12.1
Exemple ...........................................................................................................80
12.2
Probleme propuse ..........................................................................................85
13.
Funcii : generaliti, operaii cu tablouri .........................................................86
13.1
Structura unei funcii .....................................................................................86
13.2
Transferul parametrilor unei funcii............................................................86
13.3
Funcii definite de utilizator .........................................................................88
13.4
Exemple ...........................................................................................................88
13.5
Probleme propuse ..........................................................................................98
14.
Funcii: analiz matematic, biblioteci de funcii...........................................99
14.1
Exemple ...........................................................................................................99
14.2
Funcii predefinite........................................................................................103
14.3
Biblioteci de funcii scrise de ctre utilizator............................................108
14.4
Exemple .........................................................................................................108
15.
Funcii recursive ..................................................................................................111
15.1
Exemple - Recursivitate direct..................................................................111
15.2
Exemple - Recursivitate indirect ..............................................................121
15.3
Probleme propuse ........................................................................................122
16.
Tipuri de date definite de utilizator ................................................................124
16.1
Structuri .........................................................................................................124
16.2
Uniuni ............................................................................................................132
16.3
Exemple uniuni ............................................................................................132
16.4
Enumerri......................................................................................................138
16.5
Exemple .........................................................................................................138
16.6
Declaraii de tip ............................................................................................139
16.7
Alocarea dinamic a memoriei...................................................................140
16.8
Exemple .........................................................................................................141
16.9
Probleme propuse ........................................................................................142
17.
Fiiere ....................................................................................................................144
17.1
Deschiderea unui fiier................................................................................144
17.2
nchiderea unui fiier...................................................................................145
17.3
Prelucrarea fiierelor text ............................................................................146
17.4
Intrri/ieiri binare ......................................................................................152
17.5
Poziionarea ntr-un fiier ...........................................................................157
17.6
Funcii utilitare pentru lucrul cu fiiere ....................................................158
17.7
Alte operaii cu fiiere..................................................................................159
17.8
Exemple .........................................................................................................159
17.9
Probleme propuse ........................................................................................164

Bibliografie

Cerchez, E., erban, M., Programarea n limbajul C/C++ pentru liceu - Editura
Polirom, 2005.
Deaconu, A., Programare avansat n C i C++, Univ. "Transilvania" Braov, 2003.
Iorga, V., Chiri, P., Opincaru, C., Stratan, C., Programare n C/C++ - culegere de
probleme - Editura Niculescu, 2003.
Kernigham Brian W i Ritchie Dennis M., The ANSI C programming language
2nd ed. - Prentice Hall, 1998.
Negrescu, L., Limbajele C i C++ pentru nceptori. Vol. 1: Limbajul C, Editura
Microinformatica SRL, Cluj-Napoca, 1994.
Novac, C., Limbajul Turbo C++, Universitatea "Dunrea de Jos", Galai, 1993;
Ptru, B., Aplicaii n C i C++. Editura Teora, Bucureti, 1998.
Prisecaru, T., Ene, A.S., Limbajul de programare C++ - Noiuni de baz, Editura
Matrix Rom B, Editura Bucureti, 2000.
Schildt, H., C - Manual complet, Editura Teora, Bucureti, 1998.
Stoilescu, D., Culegere de C/C++, Editura Radial, Galai, 1998.
tefnescu, D., Segal, C., Iniiere n limbajele C/C++, Editura Fundaiei Univ.,
Galai, 2000.
Vlad, S., Ursu, M.F., Informatica tehnic, Univ. Tehnic Cluj-Napoca, ClujNapoca, 1996.

TASTATURA

1.

GENERALITI

1.1 Tastatura
Tastatura este component hardware a calculatorului ce permite utilizatorului s
introduc date prin apsarea unor taste. Cele mai folosite tastaturi sunt cele
QWERTY. Denumirea vine de la primele ase taste de pe rndul al treilea.

Ea cuprinde urmtoarele grupuri de taste:

1.1.1

Tastele funcionale/rapide (Hotkeys)

Sunt simbolizate cu F1F12, iar rolul lor este s lanseze n mod direct comenzi
pentru calculator, comenzi care sunt diferite n funcie de softul pe care l folosim
la un anumit moment.

1.1.2

Grupul principal de taste (QWERTY)

Acesta conine tastele alfanumerice (litere, cifre, simboluri), dintre care enumerm
denumirile i funciile tastelor speciale:
Shift (), Alt, Ctrl (dou din fiecare) Nu au efect singure (se apas simultan
cu alt tast)
Caps Lock - folosit la scrierea cu
majuscule
Backspace - terge caracterul din stnga
cursorului
Esc - Escape
Backslash (\)
Asperand (@, "a" rond, coad de
maimu)
Shift+2

Tab - insereaz mai multe spaii n


textul editat sau trece la cmpul
urmtor din fereastra de dialog
Enter - lanseaz n execuie o comand
Space (spaiu) - introduce un blank
Slash (/)
Tilda (~)
Diez (#)

Shift+
Shift+3

GENERALITI

Procent (%) Shift+5


And (&)
Shift+7
Ghilimele (") - NU dou apostrofuri !

1.1.3

Cciulia (^) Shift+6


Apostrof (')
Bar vertical (|)

Tastele de navigare

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

1.2 Ecranul aplicaiei Borland C


Pentru Borland C++ versiunea 3.1, acesta conine:
Bara de meniuri (sus) - prezint mai multe meniuri (System, File - fiiere, Edit editare, Search - cutare) 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)

PRINCIPALELE MENIURI I COMENZI ALE APLICAIEI

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).

1.3 Principalele meniuri i comenzi ale aplicaiei


1.

Meniul System [] - conine comenzi de 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 (F3) - localizeaz i deschide un fiiere (creat deja)
c. Save (F2) - 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 (Alt+X) - iese din aplicaia Borland C++
3.
Meniul Edit - conine comenzi pentru operaii de editare, anulare i
acces la Clipboard
a. Undo (Alt+BkSpc) - anuleaz ultima comand de editare (consecutiv)
b. Redo (Shift+Alt+BkSpc) - reface ultima comand anulat
c. Cut (Shift+Del) - terge textul selectat i l pune n Clipboard

GENERALITI

d. Copy (Ctrl+Ins)- copiaz n Clipboard textul selectat


e. Paste (Shift+Ins)- insereaz coninutul Clipboard-ului n fereastra
curent la poziia cursorului
f. Clear (Ctrl+Del) - 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. Find - caut un text
b. Replace - caut un text i l nlocuiete cu unul nou
c. Search again (Ctrl+L) - 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 (Ctrl+F9) - lanseaz programului n execuie
b. Program reset (Ctrl+F2) - termin sesiunea de depanare
c. Go to cursor (F4) - execut programul pn la linia cursorului
d. Trace into (F7) - execut instruciunea urmtoare; ptrunde n corpul
funciilor
e. Step over (F8) - 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 (Alt+F9) - compileaz fiierul din fereastra de editare activ
b. Make (F9) - Actualizeaz inta prin compilare i legare, dup caz
c. Link - Leag fiierele intei fr recompilare
d. Build all - Reconstruiete toate fiierele
7.
Meniul Debug - conine comenzi pentru inspectare, evaluare, stabilire
de puncte de ntrerupere i urmrire a variabilelor
a. Inspect (Alf+F4) - deschide o fereastr inspector pentru a examina
valorile unei date
b. Evaluate/Modify (Ctrl+F4) - evalueaz o variabil sau expresie i
afieaz valoarea
c. Call stack (Ctrl+F3) - arat funciile apelate de program pn n punctul
curent
d. Watches - adaug, terge sau editeaz variabile urmrite
e. Toggle breakpoint (Ctrl+F8) - 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

10

PRINCIPALELE MENIURI I COMENZI ALE APLICAIEI

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 (Ctrl+F5) - modific dimensiunea sau poziia ferestrei active
b. Zoom (F5) - 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 (F6) - activeaz fereastra urmtoare
f. Close (Alt+F3) -nchide fereastra activ
g. Close all - nchide toate ferestrele
h. Message/Output/Watch/User screen (Alt+F5) - deschide una din
ferestrele speciale: de mesaje, de rezultate, de urmrire sau ecranul
utilizatorului
i. List all (Alt+0) - 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 (Shift+F1) - arat index-ul sistemului de ajutor
c. Topic search (Ctrl+F1) - arat informaii despre cuvntul din dreptul
cursorului sau afieaz index-ul
d. Previous topic (Alt+F1) - 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
Obs.:
1. Selectarea unei poriuni de text cu ajutorul tastaturii 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 durata etapei de redactare a programelor se poate proceda
astfel:
a. textul de pe o linie de dup //, precum i cel de pe mai multe linii
dintre /* i */ reprezint comentarii i poate fi omis
b. instruciunile care afieaz valorile variabilelor pe ecran (cout,
printf) pot fi omise, iar valorile variabilelor pot fi urmrite n
fereastra Watches din meniul Debug.
3. Programele au fost scrise cu editorul de texte al aplicaiei Borland C, iar
cartea a fost tehnoredactat cu ajutorul unui procesor de texte. Din acest
motiv, uneori instruciunile sunt desparite pe mai multe rnduri. La
scrierea programelor la calculator nu se va respecta forma din carte a
instructiunilor, ci ele vor fi scrise corect (din punct de vedere al limbajului),
o instruciune (care se termin cu ";") fiind scris ntotdeauna pe un singur
rnd.

11

SCHEME LOGICE I PSEUDOCOD

2.

SCHEME LOGICE I PSEUDOCOD

2.1 Reprezentarea algoritmilor prin scheme logice


Primitivele utilizate n schemele logice sunt simboluri grafice, cu funciuni
(reprezentnd procese de calcul) bine precizate. Aceste simboluri sunt unite prin
sgei (arce) orientate care indic ordinea de execuie a proceselor de calcul.
START

STOP

CITETE a,b

AFIEAZ a,b

a6

Condiie

Simboluri de nceput i sfrit. Simbolul START desemneaz nceputul unui


program sau al unui subprogram. Simbolul STOP desemneaz sfritul unui
program sau al unui subprogram. Prezena lor este obligatorie.
Simbolul paralelogram: semnific procese (operaii) de intrare/ieire (citirea
sau scrierea-afiarea).
Simbolul dreptunghi: semnific o atribuire (modificarea valorii unei date).
Simbolul romb este utilizat pentru decizii. Se testeaz dac condiia din blocul
de decizie este adevrat (A) sau fals (F).

Cu ajutorul acestor simboluri grafice se poate reprezenta orice algoritm.


Repetarea unei secvene se realizeaz prin combinarea simbolurilor de decizie
i de atribuire.

2.2 Reprezentarea algoritmilor prin pseudocod


Pseudocodul este inspirat din limbajele de programare, nefiind ns att de
formalizat ca acestea. Pseudocodul reprezint o punte de legtur ntre limbajul
natural i limbajele de programare. Nu exist un standard pentru regulile lexicale.
Limbajul pseudocod permite comunicarea ntre oameni, i nu comunicarea ommain (precum limbajele de programare). Pseudocodul utilizeaz cuvinte cheie
(scrise cu majuscule subliniate) cu urmtoarele semnificaii:

12

EXEMPLE

Sfrit algoritm:
nceput algoritm:
Citire (introducere) date:
Scriere (afiare) date:
Atribuire:
Structura de decizie (alternativ):

Structuri repetitive cu test iniial:

SFRIT
NCEPUT
CITETE lista
SCRIE lista

DAC condiie
ATUNCI aciune1
ALTFEL aciune2
CT TIMP condiie
REPET aciune

sau:
PENTRU contor=val_ini LA val_fin [PAS]
REPET aciune
Structuri repetitive cu test final:
REPET aciune CT TIMP condiie
sau:
REPET aciune PN CND condiie
Pe lng cuvintele cheie, n reprezentarea algoritmilor n pseudocod pot apare
i propoziii nestandard a cror detaliere va fi realizat ulterior.
n cazul n care se realizeaz un algoritm modularizat, pot apare cuvintele
cheie:
SUBALGORITM nume (lista_intrri)
CHEAM nume (lista_valori_efective_de_intrare)

2.3 Exemple
2.3.1

Maximul a trei numere

2.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. AFIEAZ max

2.3.2 Suma primelor n numere naturale


2.3.2.1
Pseudocodul
1. CITETE n

13

SCHEME LOGICE I PSEUDOCOD

2. suma=0
3.CT TIMP i<n
3.1 i++
3.2 suma=suma+i
4. AFIEAZ suma

2.3.3

Ecuaia de gradul 2

2.3.3.1

Schema logic
Start
Citete a,
b, c
F

Dac
a=0

= b2 4ac
A

Dac
>0

Dac
b=0

Scrie Ec e de
gradul unu
x1 = -c/b
F

-b
x1,2 = 2a

Scrie Ec are
doua rad dif
x1 i x2

-b
x1,2 = 2a

Scrie Ec are
rad dubla
x1 = x 2

Dac
<0

Daca
c=0

-b
re = 2a
-
im = 2a
Scrie Ec are
rad compl
x1,2 = reiim

Stop

14

Scrie Ec nu
are nici o
solutie

Scrie Ec are
o infinit ate
de solutii

EXEMPLE

2.3.4

Maximul a 3 numere, calculul unei sume, cmmmc i


cmmdc, factorial - scheme logice

Start

Start

Citete
a, b, c

Citete
a,b,m,n

Dac
a>b

max=b

i=1, j=1, s=0

A
max=a
F

Dac
c>max

Dac
im, jn

s=s+sin(a+3*i)*cos(b+5*j)

max=c
max=c

Scrie
Max = , max

Scrie
S = , s

Stop

Stop

Start
Citete
a,b
F

Dac
a0, b0

Start
A

Citete n

cmmmc=a*b
r=a%b
a=b
b=r
cmmmc=0
cmmdc=0

F
F

cmmmc=a
cmmdc=
cmmmc/
cmmdc
Scrie
cmmdc, cmmmc
Stop

i=1
fact=1

Dac
r0

Dac
in

fact*=i
i++
r=a%b
a=b
b=r
Scrie
n! =, fact
Stop

15

NOIUNI DE BAZ

3.

NOIUNI DE BAZ

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*/
typedef int intreg;
/*declaraii de variabile globale*/
/*definiii de funcii sau/i descrierea unor functii*/
int 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.
Un nume (identificator) 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 s 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.

16

PRINCIPALELE MESAJE DE AVERTIZARE I EROARE ALE COMPILATORULUI

3.2 Principalele mesaje de avertizare i eroare ale


compilatorului
Tabelul 3.1 Mesaje de avertizare i eroare
Text mesaj (alfabetic)
'' is assigned a value
that is never used
Bad file name format in
include directive
Compound
statement
missing }
Declaration
syntax
error
Declaration terminated
incorrectly
Expression syntax
For statement missing ;
Function
''
should
have a prototype

Function should return


a value
If statement missing )
Illegal
structure
operation
Incorrect number format
Misplaced else
Multiple
declaration
for
No file name ending
Statement missing ;
Unable to open include
file ''
Undefined symbol ''
Unexpected
Unterminated string or
character constant
While statement missing
)

Explicaii
Avertisment: Valoarea calculat nu este folosit
nicieri n continuare
Denumire greit n directiva de preprocesare
Caracter } sau { omis la o instruciune
compus
Eroare de sintax a declaraiei
Declaraie terminat incorect
Eroare de sintax
Caracter omis ; la scrierea instruciunii "for"
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 <>)
Funcia ar trebui s returneze o valoare - lips
"void" la tipul valorii returnate din antet sau
lips instruciune "return" n corpul funciei
Caracter ) sau ( omis la scrierea instruciunii
if
Structur greit a instruciunii (scriere/citire) la >> sau <<
Variabil iniializat cu un format
numeric incorect
Ramura else din instruciunea if este
poziionat greit
Variabila este declarat de mai multe ori
Caracter > omis la o directiv de preprocesare
dup numele bibliotecii
Caracter ;omis (la instruciunea precedent)
Numele bibliotecii a fost scris greit
Simbol '' (variabil sau funcie) nedefinit
Simbol neateptat - parantez sau acolad n
plus
ir de caractere sau constant caracter
neterminat - lips ' sau "
Caracter )sau ( omis la scrierea instruciunii
"while"
17

NOIUNI DE BAZ

Text mesaj (alfabetic)

Explicaii

Pentru a obine mai multe informaii despre o anumit eroare, atunci cnd
eroarea este selectat n fereastra cu mesaje (Message), se apas tasta F1.

3.3 Date n limbajului C


3.3.1

Tipuri de date

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:

Tabelul 3.2 Tipurile de baz de date


Cuvnt
cheie
int

Lungime
n bii
16

char

float

32

double

64

short
long

16
32

unsigned
char
unsigned
int
unsigned
long

3.3.2

16
32

Format de reprezentare intern


ntreg binar reprezentat prin complement fa de 2
pe 2 octei, cuprins n intervalul [-32768, 32767]
Caracter reprezentat prin codul ASCII, cuprins n
intervalul [-128, 127]
Numr real reprezentat n virgul flotant n simpl
precizie, cuprins ntre [3.410-38, 3.41038]
Numr real reprezentat n virgul flotant n dubl
precizie, cuprins ntre [1.710-308, 1.710308]
Idem int
ntreg binar reprezentat prin complement fa de 2
pe 4 octei, cuprins n intervalul [-2.147.483.648 to
2.147.483.647]
Caracter reprezentat prin codul ASCII, cuprins n
intervalul [0, 255]
ntreg binar fr semn reprezentat prin complement
fa de 2 pe 2 octei, cuprins n intervalul [0, 65535]
ntreg binar reprezentat prin complement fa de 2
pe 4 octei, cuprins n intervalul [0, 4.294.967.295]

Constante

Sunt caracterizate prin tip i valoare. Att tipul ct i valoarea se definesc prin
caracterele care o compun

Tabelul 3.3 Reprezentarea constantelor n C/C++


Tip
dat

18

Format de
reprezentare
zecimal

Mod de reprezentare
[- / +] <cifra de la 1 la 9> [<lista

Exemple
125

DATE N LIMBAJULUI C

Tip
dat
ntreg
*)

real

(flotant)

Format de
reprezentare
(n baza 10)
octal
(n baza 8)
hexazecimal
(n baza 16)
n
virgul
fix

n
virgul
mobil

ntre
apostroafe

Mod de reprezentare
cifre de la 0 la 9>]
[- / +] 0 <cifra de la 1 la 7>
[<lista cifre de la 0 la 7>]
[- / +] 0 {x / X} <cifra 1-9 sau
litera a-f sau A-F> [<lista cifre 07 sau litere a-f sau A-F>]
[- / +] <partea ntreag> .
<partea zecimal>
Aceasta este scrierea unui
numr raional n baza zece,
unde virgula zecimal este
nlocuit de punctul zecimal.
Partea zecimal poate fi vid
[- / +] <partea ntreag> .
<partea zecimal> {e sau E} [- /
+] <nr. ntreg zecimal>
Aceasta reprezint mantisa (ceea
ce este nainte de E) nmulit cu
10 la puterea dat de exponent
(ceea ce este dup E)
<caracter>
\<codul ASCII>

caracter

cu secvene
escape

\<caracter special>

ir
de
carac

ntre
ghilimele
cu secvene
escape

<ir>
ir caractere i secv.escape

Exemple
-11
0127
-022
0xa12f
-0Xad105
123
123.7
.25

78E4
.1e-3
1234.567e-4

\65 \7
\42 \140
\t
Tab
\n
Rnd nou
\a
Alarm (sunet)
\b
Backspace
\r
Retur de car
(pozi cursorul n
rndul curent col 1)
\v
Tabulator
vertical
\\
Backslash
\
Apostrof
Acesta este un sir de
caractere
Alte
\tsecvente
\tescape \nintr-un
sir

Obs.: *) 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.

19

NOIUNI DE BAZ

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
Ex:
123,
0123,
40000,
04000,
0123456,
123L,
0123l,
0x123,
0xa1b2c3,
0XABCFL

3.3.3

Variabile

3.3.3.1
Declararea variabilelor
Modul general de declarare a variabilelor este:
tip_variabile list_nume_variabile;
Se specific tipul variabilei(lor) i o list format din unul sau mai muli
identificatori ai variabilelor de tipul respectiv.
Ex.:
int i, j; /*declararea var. simple i, j, de tip int. Se rezerv pentru i i j cte 16
bii (2 octei)*/
char c; /*declararea variabilei simple c, de tip char. Se rezerv un octet.*/
float lungime; /* declararea variabilei simple lungime de tip float; se
rezerv 4 octei */
3.3.3.2
Iniializarea variabilelor n declaraii
n momentul declarrii unei variabile, acesteia i se poate atribui o anumit valoare.
n acest caz, n memorie se rezerv numrul de locaii corespunztor tipului
variabilei respective, iar valoarea va fi memorat n acele locaii. Forma unei
declaraii de variabile cu atribuire este:
tip_variabil nume_variabil=expresie;
Se evalueaz expresia, iar rezultatul acesteia este atribuit variabilei specificate.

3.4 Exemple
char backslash=\\; /*declararea i iniializarea variabilei simple de tip
caracter backslash */
int a=7*9+2; /* declararea variabilei simple a, de tip int i iniializarea ei cu
rezultatul unei expresii - valoarea 65*/
float pi=3.14; /*declararea i iniializarea variabilei pi*/
short int z=3;
//declararea i iniializarea variabilei simple z
char d=\011;
char LinieNoua=\n;
double x=9.8, y=0;

20

INTRRI/IEIRI N C++

4.

INTRRI/IEIRI N C/C++

4.1 Citirea/scrierea datelor


Prin citirea datelor vom nelege operaia prin care una sau mai multe variabile
primesc valori prin introducerea lor de la tastatur sau prin extragerea lor de pe un
suport de memorare extern.
Prin scrierea datelor vom nelege operaia prin care rezultatele obinute n
urma prelucrrii datelor de intrare sunt fie afiate pe ecranul monitorului, fie
stocate pe un suport extern de memorare.
Aceste operaii sunt denumite frecvent i operaii de intrare/ieire. n acest
capitol vom prezenta doar citirea datelor de la tastatur i afiarea datelor pe ecran.
n limbajul C/C++ nu exist instruciuni specializate pentru citirea/scrierea
datelor. Aceste operaii se realizeaz prin intermediul unor funcii existente n
bibliotecile standard ale limbajului.
Aceste operaii de intrare/ieire difer n limbajul C++ fa de limbajul C,
diferenele fiind majore, deoarece operaiile de intrare/ieire din C++ sunt
proiectate din perspectiva programrii orientate pe obiect.

4.2 Intrri/ieiri n C++


Conceptul central n operaiile de intrare/ieire n limbajul C++ este fluxul de
intrare/ieire (denumirea original fiind stream). Simplificnd, putem privi un
stream ca pe o succesiune de caractere. Dac stream-ul este de intrare, secvena de
caractere curge" dinspre exterior (n cazul nostru, dinspre tastatur) ctre
memoria calculatorului. Dac stream-ul este de ieire, secvena de caractere "curge"
dinspre memoria calculatorului ctre exterior (n cazul nostru, ecranul
monitorului).
n fiierul antet iostream.h sunt declarate dou fluxuri standard: un flux de
intrare de la tastatur, denumit cin (console input) i un flux de ieire ctre ecran,
denumit cout (console output). Pentru a le utiliza trebuie s declarm n program:
#include <iostream.h>
Dac dorim s scriem date pe ecran, vom utiliza operatorul de inserie n fluxul
de ieire << (care poate fi utilizat nlnuit atunci cnd dorim s scriem mai
multe date). Instruciunea din C++ care scrie (pe ecran) valori i/sau text este:
cout<<expr.1[<<var1<<expr.2 [...]]
unde var.1, var.2 - reprezint nume de variabile iar expr.1, expr.2 - reprezint
expresii.

21

INTRRI/IEIRI N C/C++

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
Cnd dorim s citim date de la tastatur, le vom extrage din fluxul de intrare,
folosind operatorul de extragere >> (care poate fi utilizat nlnuit atunci cnd
dorim s citim succesiv mai multe variabile). Instruciunea 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;

4.3 Intrri/ieiri n C
Citirile i scrierile n limbajul C se realizeaz prin intermediul unor funcii
specifice.

4.3.1

Citirea datelor cu format specificat

Funcia scanf (din biblioteca stdio.h) 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 variabilelor 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.

22

EXEMPLE

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);

4.3.2

Afiarea datelor cu format specificat

Funcia printf (din biblioteca stdio.h) 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 i/sau cifre, ce indic tipul i eventual formatul
numeric al variabilelor ce se vor scrie. Caracterele de formatare au urmtoarea
semnificaie:
c - variabil de tip caracter
d - variabil de tip decimal (ntreg)
e - n format tiinific
f - variabil de tip float (real)
g - cel mai scurt dintre f i e
o - n octal
s - variabil de tip ir de caractere
x - n hexazecimal
0 - cu zerouri nesemnificative
- - 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.4 Exemple
4.4.1

cout

#include <iostream.h>
void main(void)
{ cout<<"ACESTA ESTE PRIMUL PROGRAM\n"; }

4.4.2

cin, cout

#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 aaaa/ll/zz
23

INTRRI/IEIRI N C/C++

int ziua, luna, anul;


cin>>ziua>>luna>>anul;
cout<<anul<</<<luna<</<<ziua;

4.4.3 Operatorul sizeof


S se scrie un program care ilustreaz folosirea operatorului sizeof.
#include <iostream.h>
#include <values.h>
#define PI 3.1415926
void main ()
{
cout<<"tipul int memorat pe: "<<sizeof(int)<< " octeti\n";
cout<<"tipul int memorat pe: "<<sizeof(23)<<" octeti\n";
//23-const.zecimala int
cout<<"int maxim="<<MAXINT<<'\n';
//const
simbolice
MAXINT,MAXLONG,
ETC.
-definite
in<values.h>
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";

24

EXEMPLE

cout<<"Tipul short int memorat pe: "<<sizeof(short int)<<"


octeti\n";
cout<<"Short int maxim="<<MAXSHORT<<'\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";
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 F din HEXA are val.: "<<0xF<<"\n";
cout<<"valoarea
B+C
din
hexa
in
baza
10
este
"<<0xB+0xc<<"\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";
cout<<"2<9:"<<(2<9)<<'\n';
}

4.4.4

Intrri-ieiri standard (scanf, printf)

S se scrie un program care ilustreaz folosirea funciilor scanf, printf.


//Intrari/iesiri standard
#include<conio.h>
25

INTRRI/IEIRI N C/C++

#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);
printf("\nc=%c cod=%d",c,c);
//caracter si cod caracter
printf("\ni=%d",i);
//intreg
printf("\ni=%6d",i);
//cu lungime de cimp
printf("\ni=%-6d;i=%d",i,i);
//aliniat la stinga
printf("\ni=%06d",i);
//cu zerouri nesemnificative
printf("\ni in octal=%o",i);
//in octal
printf("\ni in hexa=%x",i);
//in hexa
printf("\nf=%f",f);
//float
printf("\nf=%10.2f",f);
//cu lungime si precizie
impusa
printf("\nf=%e",f);
//format stiintific
printf("\nf=%.3e",f);
//format
stiintific
cu
precizie data
printf("\nf=%g",f);
//cel
mai
scurt
dintre
formatele f si e
printf("\nsir=%4.6s",sir);
//sir cu lungime fixa
getch();
}

4.5 Probleme propuse


1.

S se scrie un program care s tipreasc urmtoarele:


*******************************************
*Bine ai venit la ora de programare !*
*******************************************
2. Care dintre programele de mai jos nu conin erori i afieaz cuvintele pe cte
un rnd ?
#include <iostream.h>
void main() ;
{cout<<Program;
cout<< \n<<simplu;}
#include <iostream.h>
void main ()
{cout<<Program \n;
cout<<simplu;}
#include <iostream.h>
void main ()

26

PROBLEME PROPUSE

{cout<<Program \nsimplu;
cout<< \n;}
#include <iostream.h>
void main ()
{cout<<Program;
cout<<simplu<< \n;}

27

OPERATORI I EXPRESII

5.

OPERATORI I EXPRESII

5.1 Operatori
Operatorul de atribuire: =
n tabelul de mai jos sunt prezentate principalele variante ale instruciunii de
atribuire.

Tabelul 5.1 Principalele variante ale instruciunii de atribuire


operaia
Atribuire
simpl
Atribuirea
combinat
cu
un
operator

sintaxa
<variabil>
=
<expresie>;
<variabil> <op> =
<expresie>;

exemple
x=y+z/3;
x+=y;
i-=2;
a*=ln(a);
alfa /=n;

observaii

Este echivalent cu:


<variabil> = <variabil>
op <expresie>;

Operatori aritmetici unari (3): -, ++ , -++ - Incrementare - Mrete valoarea variabilei cu 1,


-- - Decrementare - Micoreaz valoarea variabilei cu 1.
Pot fi n form prefixat (Ex. ++a), sau postfixat (Ex. b--). n cazul n care un
operator de incrementare sau decrementare este prefixat, se folosete valoarea
operandului la care s-a aplicat operatorul respectiv, iar n cazul n care un operator
de incrementare sau decrementare este postfixat, se folosete valoarea operandului
dinaintea aplicrii operatorului respectiv.
Operatori aritmetici binari (5): +, -, *, /, % (restul mpririi ntregi).
Obs.: n C, prin mprirea a doi ntregi se obine tot un ntreg
Operatori aritmetici binari compui (cu atribuire) (5): +=, -=, *=, /=, %=
Semnificaie: expr1 op = expr2 expr1 = expr1 op expr2.
Ex. a+=2 a=a+2
Operatori relaionali binari (6): >, >=, <, <=, == (egal cu), != (diferit de)
Operatori logici pe cuvnt (3): && (I), || (SAU), ! (NOT)
Ordinea descresctoare a prioritii: !, >, >=, <, <=, &&, ||

Tabelul 5.2 Compunerea operatorilor logici pe cuvnt


a
0
0
1
1

28

b
0
1
0
1

a&&b
0
0
0
1

a||b
0
1
1
1

aXORb
0
1
1
0

!a
1
1
0
0

OPERATORI

Pentru aXORb nu exist operator, dar se poate folosi (a||b)&&!(a&&b).


Operatori logici pe bit (6):
~ (NOT), & (I), | (SAU), ^ (XOR), <<, >>
(deplasare bii stnga/dreapta)
Operatorul condiional
" ? :"
Este un operator ternar (necesit 3 operanzi), utilizat n construcii de forma:
expresie1 ? expresie2:expresie3
Se evalueaz expresie1. Dac aceasta are o valoare diferit de zero, atunci tipul i
valoarea ntregii expresii vor fi aceleai cu tipul i valoarea expresie2. Altfel (dac
expresie1 are valoarea zero), tipul i valoarea ntregii expresii vor fi aceleai cu tipul
i valoarea expresie3. Deci operatorul condiional este folosit pentru a atribui
ntregii expresii tipul i valoarea expresie2 sau a expresie3, n funcie de o anumit
condiie. Acest lucru este echivalent cu:
DAC expresie1 0
ATUNCI evalueaz expresie2
ALTFEL evalueaz expresie3

Tabelul 5.3 Prioritatea operatorilor


1.

Clas de
operatori
Primari

2.

Unari

Nr.

3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.

Multiplicativi
Aditivi
Deplasare pe bit
Relaionali
De egalitate

14.

De atribuire

15.

Virgul

Condiional

Operatori
() [] . -> ::
! (NOT pe cuvnt) ~ (NOT
pe bit) ++ -- sizeof
(tip)
-(unar)
*(defereniere)
&(refereniere)
* / %
+ << >>
< <= > >=
== !=
& (I logic pe bit)
^ (XOR pe bit)
| (SAU logic pe bit)
&& (I logic pe cuvnt)
|| (SAU logic pe cuvnt)
?:
=
+=
-=
*=
%=
&= ^= |= <<= >>=
,

Asociativitate
de la stnga la dreapta
de la stnga la dreapta
de la dreapta la stnga
de la stnga la dreapta
de la stnga la dreapta
de la stnga la dreapta
de la stnga la dreapta
de la stnga la dreapta
de la stnga la dreapta
de la stnga la dreapta
de la stnga la dreapta
de la stnga la dreapta
de la stnga la dreapta
de la dreapta la stnga
de la dreapta la stnga
de la stnga la dreapta

Operatorul de forare a tipului sau de conversie explicit (expresie cast)


Adesea dorim s specificm conversia valorii unui operand spre un tip dat.
Acest lucru este posibil folosind o construcie de forma:
29

OPERATORI I EXPRESII

(tip) operator
Printr-o astfel de construcie, valoarea operandului se convertete spre tipul
indicat n paranteze. n construcia de mai sus (tip) se consider c este un operator
unar. l vom numi operator de forare a tipului sau de conversie explicit.
Construcia de mai sus o vom numi expresie cast.
Exemplu: int x; float y; y= (float)x/2;

5.2 Prioritatea operatorilor


Tabelul 5.3 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.

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.: 2410 = 110002. Acest lucru s-a obinut conform
operaiilor din tabelul alturat.

5.3.2

Operaie
24:2
12:2
6:2
3:2
1:2

Ct
12
6
3
1
0

Rest
0
0
0
1
1

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.: 110102 = 124 + 123 + 022 + 121 + 020 = 2610

5.3.3

Conversia hexazecimal-binar

Se scrie fiecare simbol al numrului hexazecimal sub form binar.


Ex.: DFH = 110111112 deoarece DH = 1310 = 11012, iar FH = 1510 = 11112

30

EXEMPLE

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 = 610 = 6H, iar 1010 = 1010 = AH

5.4 Exemple
5.4.1

Operatori aritmetici

//Program cu operatii aritmetice


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

5.4.2

<<a*b<<\nDiferenta=

Aria i perimetrul unui disc de raz r

Fie r un numr real, citit de la tastatur, care reprezint lungimea razei unui cerc.
S se scrie un program care s calculeze i s afieze aria i perimetrul discului de
raz r.
5.4.2.1
Soluie
Vom citi valoarea razei n variabila r. Vom calcula aria discului dup formula r2,
iar perimetrul, dup formula 2r. Numrul este un numr iraional. Calculatorul
nu poate memora numere iraionale (care au o infinitate de zecimale), ci doar
aproximri ale acestora. n fiierul antet math.h este definit o constant numit
M_PI care reprezint o aproximare a numrului iraional .
5.4.2.2
Programul
//Cerc
#include <iostream.h>
#include <math.h>
void main()
{
double r;
cout<<"\nRaza r= "; cin>>r;
cout<<"Aria=\t\t"<<M_PI*r*r <<"\nPerimetrul=\t" << 2*M_PI*r;
}

31

OPERATORI I EXPRESII

5.4.3

Aria triunghiului - formula lui Heron

S se calculeze aria S a unui triunghi cu laturile a,b,c citite de la tastatur


a+b+c
folosind formula lui Heron: S = p(p-a)(p-b)(p-c) , unde p = 2 .
//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.4

Rezolvarea unui sistem de dou ecuaii


a11x + a12y = b1

S se rezolve sistemul de 2 ecuaii cu 2 necunoscute:

a21x + a22y = b2

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.SCRIE x,y

5.4.5

Incrementri/decrementri/atribuiri

Care sunt valorile variabilelor a,b i dup execuia succesiv a urmtoarelor


instruciuni (valorile iniiale sunt: 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

32

EXEMPLE

c*=4
a/=2
Rezultatele programului se vor interpreta urmrind valorile variabilelor a, b i c
n fereastra Watch

5.4.6

Operatori relaionali i logici - exemplul 1

//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();
}

5.4.7

Operatori relaionali i logici - exemplul 2

#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)
||
<<rezult<<\n;
//Afisare (a>b) || (b>c) =1(sau valoare nenula)
rezult=!(c<d);cout<<!(c<d)=<<rezult<<\n;
//Afisare !(c>d)=0
rezult=(a-b)&&1;cout<<(a-b)&&1=<<rezult<<\n;
//Afisare (a-b)&&1 =1(sau valoare nenula)
rezult=d||b&&a;cout<<d||b&&a=<<rezult<<\n;
//Afisare d||b&&a =1

(b>c)=

33

OPERATORI I EXPRESII

5.4.8

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%400==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
5.4.8.1
Programul
//An bisect
#include <stdio.h>
void main ( )
{
int an, bisect;
printf("Anul: ");
scanf("%d", &an);
bisect=an>=1600 && an<=4900 &&
an%400==0);
printf("an=%d\t%d\n",an,bisect);
}

5.4.9

(an%4==0

Operatori pe bii

Programul afieaz rezultatul urmtoarelor expresii:


Val iniial x= 7, n binar
00000111
Deplasare bii
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

34

&&

an%100!=0

||

EXEMPLE

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
5.4.9.1
Programul
//Operatii pe biti
#include<conio.h>
#include<iostream.h>
//Functie ajutatoare ptr afisarea rezultatelor - se va scrie
ca atare
void dectobin(int x)
{
int i=8,bin,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);
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);
35

OPERATORI I EXPRESII

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.10

Operatorul ternar - maximul a dou numere

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

5.4.11

Operatorul ternar - modulul unui numr

S se scrie un program care citete un numr i afieaz valoarea lui absolut.


//modulul unui numar
#include <stdio.h>
void main()
{
double a;
scanf("%lf", &a);
printf("a=%g\tabs(a)=%g\n",a, a < 0 ? -a : a );
}

5.4.12

Operatorul cast - rdcina ptrat a unui numr

S se scrie un program care citete un ntreg i afieaz rdcina ptrat din


numrul respectiv.
#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));

36

EXEMPLE

}
Obs.: 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.

5.4.13

Operatorul cast - calculul unei expresii

S se scrie un program care citete pe n de tip ntreg i afieaz valoarea expresiei


n/(n+1) cu 15 zecimale.
#include <stdio.h>
void main( )
{
long n;
scanf("%ld", &n);
printf("n=%ld\tn/(n+1)=%.15g\n", n,
(double)n/(n+1));
}
Obs.: 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 tipul double. n felul
acesta, conform regulii conversiilor implicite, se convertete spre double i cel de
al doilea operand i apoi se face mprirea celor doi operanzi flotani.

5.4.14

Operatorul virgul

S se scrie un program care citete doi ntregi i afieaz maximul dintre valorile
lor absolute.
#include <stdio.h>
void main( )
{
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);
}
Obs.: 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.

37

OPERATORI I EXPRESII

5.5 Probleme propuse


1.
2.

3.

S se scrie declaraiile pentru definirea constantelor simbolice: pi, g (acceleraia


gravitaional), unghi_drept, dimensiune_MAX.
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;
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

38

PROBLEME PROPUSE

6.
7.
8.
9.
10.

11.

12.

13.

14.

15.

16.

Ce operaie logic i ce masc trebuie s folosii pentru a converti codurile


ASCII ale literelor mici n litere mari ? Dar pentru conversia invers ?
S se seteze pe 1 toi biii dintr-un octet, cu excepia bitului cel mai
semnificativ.
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.
S se citeasc dou valori ntregi. S se calculeze i s se afieze restul
mpririi celor dou numere.
S se realizeze programe care execut urmtoarele aciuni:
a. Se citete un unghi n grade; se cere s se transforme n radiani (360 =
2 rad);
b. Calculeaz perimetrul i aria unui cerc de raz r citit de la tastatura;
c. Calculeaz perimetrul i aria unui triunghi de laturi date;
d. Calculeaz expresia: -3x2 + xy - y/x.
S se scrie un program care s converteasc o temperatur n grade Celsius n
echivalentul ei n grade Fahrenheit. Formula de conversie este F = 32 + 9/5 C.
Programul trebuie s tipreasc ambele valori ale temperaturii (n grade
Celsius i grade Fahrenheit) cu mesaje corespunztoare.
Care dintre variabilele care intervin n secvena de operaii urmtoare i vor
pstra valoarea avut iniial?
a b+c;
a i c;
c a-c;
b i c
b c;
b i a;
c a-b;
a, b i c
Care dintre operaiile urmtoare atribuie variabilei ntregi x una din cifrele
sale, tiind c x > 10000:
x x mod 100;
x x mod 10;
x x div 10 mod 10;
x x div 100 mod 10;
x x mod 10 div 1;
x x mod 50;
Fie a, b, c i d patru variabile reale. Care dintre urmtoarele instruciuni
atribuie variabilei d media aritmetic a valorilor variabilelor a, b i c?
d=(a+b+c)/2;
d=a/3+b/3+c/3;
d=a+b+c/3;
d=(a+b+c)/4-1;
Care dintre urmtoarele declaraii de variabile sunt eronate sintactic i de ce?
float a=b=0;
double z=x/2;
char d=120;
int k;i;
long a=0, b=a+3;
unsigned float a;
Care dintre urmtoarele expresii sunt adevrate dac i numai dac numrul
ntreg x este impar negativ?
x%2==l) && (x<0)
(x%2!=0) || (x<0)
!((x%2==0) || (x>=0))
!((x%2==0) && (x>=0))
x%2=l && x<0
39

OPERATORI I EXPRESII

17. Care dintre urmtoarele expresii sunt adevrate dac i numai dac valorile
variabilelor x i y sunt numere naturale consecutive?
x-y==1
(x==1) && (y==2)
(x-y==1) && (y-x==1)
y==x1
(x-y==1) || (y-x==1)
18. S considerm urmtoarele declaraii de variabile:
int x=0XF0A8, v=0XFFFD;
unsigned y=0XF0A8, z=1;
float a=s.5, b=4;
char c=8;
Evaluai urmtoarele expresii:
a+z/2
-1 > z
(v+z)/2
c>='0' && c <= '9' ? "da" : "nu"
(v+1) /2
x>>3&z<<4
c-'0'
y>>10|z
19. n contextul declaraiilor de variabile de la exerciiul precedent, care sunt
erorile din urmtoarele expresii?
(a+z)%2
a+++x
b*b-4ac
x=(a2)
c=a?"da" : "nu"
x&&=10
20. n condiiile urmtoarelor declaraii i iniializri de variabile:
unsigned char x=250, z=x+7, a='8';
Care este valoarea expresiei: z | (a-' 0') ?
Expresia nu se poate evalua, deoarece este eronat sintactic,
1
265
0
true
9
21. Se consider x, y i z trei variabile ntregi. Care dintre urmtoarele expresii are
valoarea diferit de 0 dac i numai dac y=max (x, y, z) ?
x>z?y>=x?1:0:y>=z?1:0
!(y<x || y<z)
!(y<x && y<z)
x>z && y>x || z>x && y>z
y>x && y>z
2ab - c2
22. Pentru a atribui variabilei reale x rezultatul expresiei 0.25 ,unde a, b i c
desemneaz variabile reale, se utilizeaz instruciunea:
x=(2*a*b)-(c*c)/0.25;
x=2*a*b-c*c/0.25;

40

PROBLEME PROPUSE

x=(2*a*b)-(c*c)*4;
x=(2*a*b-c*c)*4;
23. Fie A i B dou puncte n plan, specificate prin coordonatele lor carteziene. S
se scrie un program care s calculeze i s afieze lungimea segmentului AB.

41

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>;
Obs.: 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


instruciunea switch

cu

ramuri

multiple:

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.

42

EXEMPLE IF, SWITCH

Sintaxa:
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; ]
}
Instruciunea switch este o generalizare a instruciunii if. Spre deosebire de
if, care permite selectarea unei alternative din maximum dou posibile, switch
permite selectarea unei alternative din maximum n+1 posibile. O alt diferen
major const n faptul c n if se execut instruciunea corespunztoare valorii
expresiei i att, n timp ce n switch se execut i toate secvenele de instruciuni
ale alternativelor case urmtoare.

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()
{
43

STRUCTURI DE DECIZIE (ALTERNATIVE, DE SELECIE)

float x,y,z; char op;


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"); z=0;
}
printf("%.2f %c %.2f= %.2f",x,op,y,z);
}

6.3.3

Sum

Orice sum de bani S (S>7) poate fi pltit numai cu monede de 3 lei i de 5 lei. Dat
fiind S>7, scriei un program care s determine o modalitate de plat a sumei S
numai cu monede de 3 lei i de 5 lei. Cum se poate obine numrul minim de
monede ?
6.3.3.1
Soluie
Problema cere, de fapt, s gsim dou numere naturale x i y, astfel nct s s poat
fi scris sub forma S = 3*x+5*y (n unele cazuri exist dou soluii ale problemei !)
Vom analiza urmtoarele trei cazuri:
1. S%3 (restul mpririi lui S la 3) este 0. n acest caz, x = S/3, iar y = 0.
2. S%3 este 1. Deoarece S>7, vom considera x = S/3 - 3 i y = 2, pentru c S = 3 *
S/3 + l = 3 * (S/3 - 3) + 3*3 + 1 = 3*(S/3 - 3) + 10 = 3*(S/3 - 3) + 5*2.
3. S%3 este 2. n acest caz vom considera x = S/3 - l i y = l, deoarece S = 3*S/3
+ 2 = 3*(S/3 - l) + 3 + 2 = 3*(S/3 - l) + 5.
6.3.3.2
Programul
#include <stdio.h>
void main()
{
int S, x, y, r;
printf("Introduceti suma S: ");
scanf("%d", &S);
r=S%3;
switch (r)
{
case 0: x=S/3; y=0; break;
case 1: x=S/3-3; y=2; break;
case 2: x=S/3-1; y=1;
}
printf("%d = 3*%d + 5*%d\n",S,x,y);
}

44

PROBLEME PROPUSE

6.4 Probleme propuse


S se alctuiasc programe care s rezolve urmtoarele probleme:
1. Calculul valorii unei funcii - S se calculeze i s se afieze valoarea funciei f
pentru un x dat:
4x3 + 5x2 - 2x + 1,
x<0
f(x)=
100,
x=0
ex - ln x,
x>0
2. Ecuaia de gradul 2 (vezi i schema logic). Pseudocodul:
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."
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)
2.2.1.2. x2=(-b+ d )/(2*a)
2.2.1.3. SCRIE "x1=",x1,"x2=",x2

ALTFEL
2.2.1.2 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


3.

Modulul i argumentul unui numr complex. Pseudocodul:


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

ALTFEL
3.1.2 arg = -pi/2
3.2 ALTFEL
DAC re>0 ATUNCI
3.2.1 arg=arctg(im/re)

ALTFEL
3.2.2 arg=-arctg(im/re)
4.SCRIE modul, arg

45

STRUCTURI DE DECIZIE (ALTERNATIVE, DE SELECIE)

4.

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 paralelipiped, 2 - cilindru, 3 - con, 4 - sfer, 0 - terminare program), citete
dimensiunile necesare i calculeaz i afieaz n cadrul unui mesaj volumul
corpului respectiv (Vp = HBL; Vcil = R2H; Vcon = R2H/3; Vsf = D3/6).
5. Care este efectul urmtoarei secvene de instruciuni?
int a, b, c, x;
a=3; b=5; c=7;
if (a-b/2<0) x=1;
else if (a+b-c/2<b) x=2;
else if (a%b+c>b) x=3;
else x<-4;
cout<<x;
6. Ce valoare iniial ar putea avea variabila x, astfel nct la sfritul execuiei
urmtoarei secvene de instruciuni variabila y s aib valoarea 2?
if (x>3) if (x<7) if (x%2==0) y=1; else y=2; else y=3;
else y=4;
7. Fie x i y dou numere reale, citite de la tastatur. Scriei un program care
calculeaz i afieaz valoarea funciei:

f(x,y)=

8.

46

x+y
5xy dac x, y > 0
min (x, y), dac x = 0 sau y = 0
1 1 1 1

x + y x + y + x2 + y2 , altfel

Fie x un numr natural de trei cifre. Scriei un program care s elimine una
dintre cifrele numrului astfel nct numrul de dou cifre rmas s fie maxim.

EXEMPLE WHILE

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 ciclic cu test iniial.
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

7.2.1.1
Pseudocodul (vezi i schema logic de la 2.3.4)
1.CITETE a,b
2.cmmmc=a*b
3.CT TIMP b<>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
7.2.1.2
Programul
//Algoritmul lui Euclid
#include<iostream.h>
int main()
{
long int a,b,rest,cmmmc,cmmdc;
cout<<"\na=";cin>>a; cout<<"b=";cin>>b;
cmmmc=a*b;
while(b)
{
rest=a%b;

47

STRUCTURA CICLIC CU TEST INIIAL

cout<<"\n"<<a<<" = "<<b<<" * "<<a/b<<" + "<<rest;


a=b; b=rest;

}
cmmdc=a;
cmmmc=cmmmc/cmmdc;
cout<<"\n\ncmmmc= "<<cmmmc<<" cmmdc= "<<cmmdc;
return 0;
}
Obs.: Nu se verific dac iniial a > b; acest lucru nu este necesar, deoarece, dac
iniial a < b, dup prima executare a instruciunii compuse subordonate
instruciunii while, valorile lui a i b vor fi schimbate.

7.2.2

Produsul primelor n numere naturale (factorialul)

#include <iostream.h>
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.2.4

Descompunerea unui numr n factori primi

7.2.4.1

Pseudocodul

48

EXEMPLE FOR

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 (e0) SCRIE f," la ",e
4.4.DAC (f=2) f=f+1 ALTFEL f=f+2

7.3 Instruciunea for


n majoritatea limbajelor de programare de nivel nalt, instruciunea for
implementeaz structura ciclic cu numr cunoscut de pai. n limbajul C,
instruciunea for poate fi utilizat ntr-un mod mult mai flexibil.
Reprezentare n pseudocod:
evaluare expresie1
CT TIMP expresie2 REPET
NCEPUT
instructiune
evaluare expresie3
SFRSIT
Sintaxa:
for (expresie1; expresie2; expresie3)
instructiune;
unde:
expresie1 - reprezint iniializarea contorului;
expresie2 - condiia de rmnere n ciclu;
expresie3 - modificarea contorului i/sau instruciuni.
Nu este obligatorie prezena expresiilor, ci doar a instruciunilor vide.

7.4 Exemple for


7.4.1

Calculul factorialului

//Calculul factorialului
#include<iostream.h>
#include<conio.h>
void main()
{

49

STRUCTURA CICLIC CU TEST INIIAL

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 duble


m

S se calculeze suma dubl

sin(a+3*i)*cos(b+5*j).

j=1

i=1

7.4.2.1
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
7.4.2.2
Programul
#include<iostream.h>
#include<math.h>
void main()
{
float s=0,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

irul lui Fibonacci, termenii mai mici dect o valoare n.

Dac n=0: f0=0, n=1: f1=1, altfel: fi = fi-2 + fi-1


7.4.3.1
Pseudocodul
1. CITETE n

50

PROBLEME PROPUSE

2. DAC n>=2
2.1. PENTRU f0=0 i f1=1, CT TIMP f1<n, f0=f1, f1=fi, REPETA
2.1.1. fi=f0 + f1
2.1.2. SCRIE fi
7.4.3.2
Programul
//Genereaza numerele Fibonacci
#include<stdio.h>
#include<conio.h>
void main()
{
int f0,f1,fi,n;
clrscr();
printf("Introd n: "); scanf("%d",&n);
if(n>=2)
{
for(f0=0,f1=1,fi=1;fi<n;f0=f1,f1=fi,fi=f0+f1)
{printf("\nf0=%d; \tf1=%d; \tfi=%d;",f0,f1,fi); }
}
getch();
}

7.4.4

Afiarea 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");
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();
}

7.5 Probleme propuse


1.

Se consider urmtoarea secven de instruciuni:


51

STRUCTURA CICLIC CU TEST INIIAL

2.

3.

4.

5.

6.

52

int n, d=2;
cin>>n;
while (n>l)
if (n%d==*0) n/=d;
cout<<d;
a. Ce valoare va fi afiat dac valoarea citit pentru variabila n este 720?
b. Dai exemplu de valori (cel puin dou) care ar putea fi introduse pentru
variabila n, astfel nct valoarea afiat s fie 11.
c. Care este efectul acestei secvene de instruciuni?
Se consider urmtoarea secven de instruciuni:
int x, a, b, i;
cin>>a>>b;
i=a; x=0;
while (i<=b) { x+=i;i++; }
cout<<x;
a. Ce valoare va fi afiat pe ecran dac se introduc valorile 1 i 10?
b. Ce valori ar putea fi introduse pentru a i b astfel nct programul s afieze
valoarea 22?
c. Dai exemplu de valori distincte care ar putea fi introduse astfel nct
programul s afieze valoarea 0.
d. Scriei un program echivalent mai eficient.
Care dintre urmtoarele secvene de instruciuni atribuie variabilei ntregi u
valoarea primei cifre a numrului natural reprezentat de variabila x ?
u=x/10;
u=x; while (u>=10) u=u%10;
u=x%10;
while (x>=10) x=x/10; u=x;
Ce valoare iniial ar trebui s aib variabila x astfel nct dup execuia
urmtoarei secvene de instruciuni s se afieze valoarea 640?
d=2;
while (d<50) { x=x*d; d=d*d;}
coutx;
Numere prietene - Dou numere naturale a i b se numesc prietene dac a este
egal cu suma divizorilor lui b (exclusiv b), iar b este egal cu suma divizorilor lui
a (exclusiv a). De exemplu, a=220 i b=284 sunt prietene. Scriei un program
care s determine primele trei perechi de numere prietene, cu a<b.
Plata sumei - Se citesc de la tastatur dou numere naturale S i x (0<S<10000,
0<x<l00). S reprezint o sum pe care trebuie s o pltim, utiliznd un numr
minim de bancnote. Bancnotele au ca valori numai puteri ale lui x (1, x, x2, x3,
...) i presupunem c dispunem de un numr suficient de mare de bancnote.
Scriei un program care afieaz pe ecran o modalitate de a plti suma,
utiliznd un numr minim de bancnote. De exemplu, pentru S=107 i x=5, vei
afia:
4 bancnote cu valoarea 25
1 bancnote cu valoarea 5
2 bancnote cu valoarea 1

EXEMPLE DO - WHILE

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>;
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

8.2.1.1
Pseudocodul
1.s=0
2.REPET
2.1. CITETE x
2.2. s=s+x
CT TIMP (x!=0)
3. SCRIE s
8.2.1.2
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<<"suma este: "<<s;
}

53

STRUCTURA CICLIC CU TEST FINAL

8.2.2

Calculul unei sume cu o precizie impus

S se calculeze suma S =

(-1)kxk
k! pn cnd |T/S| < .

k=1

Obs.: Tk = -Tk-1x/k, iar Sk = Sk-1 + Tk


8.2.2.1
Pseudocodul
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.2.2
Programul
//Calculul unei sume
#include<conio.h>
#include<math.h>
#include<stdio.h>
void main()
{
int k=1; float x,T,S,eps=1e-05;
//clrscr();
printf("\nIntroduceti val x: "); scanf("%f",&x);
T=S=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();
}

8.2.3

Radical de ordinal 3

3
Fie x un numr real. S se calculeze x (radical de ordin 3 din x), folosind relaia
de recuren:
;
ri = (2*ri - 1 + x/(ri-1 * ri-1))/3, dac i>1
r1 = 1
Rezultatul trebuie s fie obinut cu o precizie mai bun dect 10-4.

54

EXEMPLE DO - WHILE

8.2.3.1
Soluie
Observm c pentru a calcula termenul i din acest ir recurent este necesar numai
termenul i-1. Prin urmare, vom utiliza dou variabile r1 (n care reinem termenul
calculat la pasul precedent) i r2 (n care reinem termenul pe care urmeaz s l
calculm).
Pentru a obine precizia cerut n problem, vom calcula termeni din ir pn
cnd diferena n valoare absolut dintre doi termeni consecutivi este mai mic
dect precizia specificat. Pentru a calcula diferena n valoare absolut dintre doi
termeni consecutivi, vom utiliza funcia fabs() din biblioteca de funcii
matematice (aceast funcie calculeaz modulul unui numr de tip double
specificat ca parametru).
8.2.3.2
Programul
//Radical de ord 3
#include <iostream.h>
#include <math.h>
#define EPS 0.0001
void main()
{
double x, r1, r2=1;
cout<<"\nx= "; cin>>x;
do
{
r1=r2;
r2=(2*r1+x/(r1*r1))/3;
}
while (fabs(r2-r1)>=EPS);
cout<<"Radical de ord 3: "<<r2;
}

8.2.4

Funcii pentru ridicarea lui 2 la o putere ntreag i pentru


calculul radicalului de ordinul doi

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 2 pe baza
irului lui Newton.
8.2.4.1
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
a2b. 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).

55

STRUCTURA CICLIC CU TEST FINAL

Construcia funciei ce calculeaz rdcina ptrat a unui numr x are la baz


x
irul lui Newton, dat prin relaia de recuren an+1 = 0.5an + a , unde primul
n

element a1 = 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.
8.2.4.2
Programul
/*Calculul ridicarii lui 2 la o putere intreaga -i calculul
radacinii patrate fara utilizarea funct sqrt */
#include<iostream.h>
#include<conio.h>
#include<math.h>
void main()
{
int a; float p, q=1, err=1e-6; char Exit;
do
{
clrscr();
cout<<"\nDati un numar A ="; cin>>a;
cout<<"\n2^"<<a<<" = "<<(1<<a);
//Se calculeaza radacina patrata a lui x.
do
{
p=q;
q=(p+a/p)/2;
//cout<<"\n"<<p<<'\t'<<q;
}
while(fabs(q-p)>err);
cout<<"\nRadical din "<<a<<"="<<q;
cout<<"\nPentru iesire apasati-> e..";
Exit=getch();
}
while(Exit!='e');
}

8.3 Prelucrarea numerelor


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
Secvenele urmtoare descriu strict metoda prezentat i nu ntreg programul !

56

PRELUCRAREA NUMERELOR

8.3.1

Suma cifrelor unui numr "n"

s=0;nl=n;
do
{
s+=nl%10; //se obtine pe rind fiecare cifra
nl/=10;
//incepind cu cea a unitatilor
}
while(nl);
cout<<"\nSuma cifrelor nr. "<<n<<" = "<<s;

8.3.2

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.3.3

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.3.4

Trecerea unui numr "n" din baza 10 n baza b[29]

n_b=0; ord=1; aux=n;


do
{
c=aux%b;
n_b+=c*ord;
ord*=10;
aux/=b;
}
57

STRUCTURA CICLIC CU TEST FINAL

while(aux);
cout<<"\nNumarul "<<n<<" in baza "<<b<<" este "<<n_b;

8.3.5

Trecerea unui numr "n" din baza b[29] n baza 10

n_10=0;p=l;
do
{
n_10=n_10+n%10*p;
p*=b;
}
while(n);
cout<<n_10;

8.3.6

n/=10;

Apariia unei cifre "a" ntr-un numr "n"

nr=0;nl=n;
do
{
if(nl%10==a) nr++;
nl/=10;
}
while(nl);
cout<<"\nCifra "<<a<<" apare de "<<nr<<" ori";

8.3.7

Inserarea unei cifre "a" pe o poziie "k" a unui numr "n"

nl=0;i=0;//poz.se numr de la 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.3.8

Cifra maxim "cmax" a unui numr "n"

cmax=0;nl=n;
do
{
if(cmax<n%10)

58

cmax=nl%10;

FACILITI DE NTRERUPERE A UNEI SECVENE

nl/=10;
}
while (nl) ;
cout<<"\ncmax="<<cmax;

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
instruciunii 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 expresii 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;
}

59

STRUCTURA CICLIC CU TEST FINAL

8.5 Exemple break, continue


8.5.1

break - ziua din sptmn

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.).
#include <stdio.h>
#include <stdlib.h>
void main( )
{
int i;
scanf("%d", &i);
switch(i)
{
case 1: puts("luni");break;
case 2: puts("marti");break;
case 3: puts("miercuri"); break;
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);
}
}

8.5.2

continue - inversele unor numere

S se calculeze inversele unor numere reale introduse pe rnd de la tastatur


#include<iostream.h>
void main()
{
float n;
for(int i=0; i<=3; i++)
{
cout<<"\nn= "; cin>>n;
if(n==0)
continue;
cout<<1/<<n<<= "<<1/n;
}
}

8.6 Probleme propuse


1. S se calculeze aria unui triunghi, cunoscndu-se mrimea laturilor sale.
Numerele care reprezint mrimile laturilor vor fi introduse de utilizator.

60

PROBLEME PROPUSE

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 numrului 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
ex-3
, x [0, 1)
f(x)=
sin(x)+cos(x)
, x [1, 2)
0,9ln(x+3)
, x [2, 100]
S se calculeze f(x), unde x e citit de la tastatur.
7. S se scrie un program care calculeaz i afieaz maximul i minimul a 3
numere reale (a, b i c) citite de la tastatur.
8. S se citeasc 2 caractere care reprezint 2 litere mari. S se afieze
caracterele citite n ordine alfabetic.
9. S se citeasc 3 caractere care reprezint 3 litere mici. S se afieze caracterele
citite n ordine alfabetic.
10. S se calculeze valoarea polinomului Cebev de ordin n ntr-un punct x
dat, cunoscnd relaia:
T0(x)=1, T1(x)=x i Tk+1(x) - 2xTk(x) + Tk -1(x) = 0
11. 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.
12. Se citesc cte 3 numere reale, pn la ntlnirea numerelor 9, 9, 9. Pentru
fiecare triplet de numere citit, s se afieze maximul.
13. Se citete cte un caracter pn la ntlnirea caracterului @. S se afieze
numrul literelor mari, numrul literelor mici i numrul cifrelor citite;
care este cea mai mare (lexicografic) liter mare, liter mic i cifr
introdus.
14. 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.
15. S se calculeze suma seriei 1 + x3/3 - x5/5 + x7/7 - cu o eroare mai mic
dect (citit de la tastatur). S se afieze i numrul de termeni ai sumei.
16. 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.
17. S se scrie un program care afieaz literele mari ale alfabetului n ordine
cresctoare, iar literele mici - n ordine descresctoare.

61

STRUCTURA CICLIC CU TEST FINAL

18. 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).
19. S se calculeze, pentru 0<=x<=1, x citit de la tastatur, valoarea sumei
urmtoare, cu o eroare < 0.0001:
S=1+(x+1)/ 2! + (x+2)/ 3! + (x+3)/ 3! + ... ,
20. S se genereze toate numerele naturale de 3 cifre pentru care cifra sutelor
este egal cu suma cifrelor zecilor i unitilor.
21. S se citeasc cte un numr ntreg, pn la ntlnirea numrului 90.
Pentru fiecare numr, s se afieze un mesaj care indic dac numrul este
pozitiv sau negativ. S se afieze cel mai mic numr din ir.
22. S se genereze toate numerele naturale de 3 cifre pentru care cifra zecilor
este egal cu diferena cifrelor sutelor i unitilor.
23. S se calculeze suma:
(1 + 2!) / (2 + 3!) - (2+3!) / (3+4!) + (3+4!) / (4+5!) - .....

62

DECLARAIA DE TABLOU

9.

TABLOURI UNIDIMENSIONALE

Numim tablou o colecie (grup, mulime ordonat) de date, de acelai tip, situate
ntr-o zon de memorie continu (elementele tabloului se afl la adrese succesive i
pot fi referite prin indici.).
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 n care 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, iar cea superioar este (dimensiunea-1). De
exemplu, dac vect este un tablou cu 10 elemente (de dimensiune 10), 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.1 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_tabl [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.

63

TABLOURI UNIDIMENSIONALE

9.2 Vectori
Vectorii sunt tablouri unidimensionale. Declararea (i eventual iniializarea) lor se
face astfel:
tip nume_tabl[lim_1] = {lista valori}
Ex.:
int v[3]; float vec[2] = {66.1, 39.7} //Tablou unidimensional
numit vec[2] cu 2 elemente reale, initializat

9.3 Exemple
9.3.1

Citirea primelor n elemente ale unui vector

for(i=0; i<n; i++) cin>>a[i];

9.3.2

Scrierea primelor n elemente ale unui vector

for(i=0; i<n; i++) cout<<a[i];

9.3.3

Operaii cu elementele 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.
9.3.3.2
Programul
/* Operaii cu elementele unui vector*/
#include<stdio.h>

64

EXEMPLE

#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=0;i<N;i++)
{
printf("A[%2d]=",i);
scanf("%f",&temp);
a[i]=temp;
}
min=a[0];max=a[0];//initializare min si max cu valoarea
primului element
for(i=1;i<N;i++)//de la al doilea element
{
if(a[i]<min) min=a[i];
if(a[i]>max) max=a[i];
}
suma=0;
for(i=0;i<N;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
Programul
#include<iostream.h>
void main()
{
unsigned n,i; float a[100],b[100],p;
cout<<\nDati 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;
}
65

TABLOURI UNIDIMENSIONALE

9.3.5

Sortarea cresctoare a elementelor unui vector

9.3.5.1
Pseudocodul
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];
}

66

EXEMPLE

9.3.6

Casierul automat

S se scrie algoritmul pentru "casierul automat" care citete de pe mediul de intrare


suma (ntreag) datorat de un client i calculeaz "restul" pe care acesta l
primete n numr minim de bancnote i monezi de 100000, 50000, 10000, 5000,
1000, 500, 100, 50, 25, 10, 5, 3 i 1 leu considernd c suma pltit este cel mai mic
multiplu de 100000 mai mare dect suma datorat.
9.3.6.1
Rezolvare:
Vom folosi o metod care ntoarce cel mai mic multiplu de 100000 mai mare dect
suma datorat (pentru a afla suma pltit). Plata se va face "iterativ": se vor da ct
mai multe bancnote de 100000 posibile, apoi ct mai multe bancnote de 50000
posibile, apoi de 10000, etc. pn se epuizeaz suma datorat.
9.3.6.2
Programul
//Casier automat
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <math.h>
void main (void)
{
long suma;
int i ;
// Valorile monezilor
const long valori[13] = {100000, 50000, 10000, 5000, 1000,
500, 100, 50, 25, 10, 5, 3, 1};
// Cantitatile din fiecare moneda
int cantitati[13];
// Cel mai mic multiplu de 100000 al sumei de plata
long platit;
// Restul de plata
long rest;
clrscr();
printf ("Introduceti suma de plata: ");
scanf ("%ld", &suma);
// Prelucrarea datelor
// Calculeaza cel mai mic multiplu de 100000 al sumei date
platit = ((suma / 100000) + 1) * 100000;
rest = platit - suma;
printf ("Restul de plata de la %ld este: %ld\n", platit,
rest);
// Resetam cantitatile din fiecare bancnota
for (i = 0; i < 13; i++)
cantitati [i] = 0;
// Calculam cantitatile din fiecare bancnota
for (i = 0; (i < 13) && (rest > 0); i++)
{
cantitati[i] = rest / valori[i] ;
67

TABLOURI UNIDIMENSIONALE

rest %= valori[i];
}
for(i=0; i<13; i++)
if(cantitati[i])
printf ("Avem %d
cantitati[i], valori[i]);
getch();
}

9.3.7

bancnote

de

valoare

Valoarea unui polinom ntr-un punct, unde coeficienii


polinomului sunt memorai ntr-un vector

9.3.7.1
Pseudocodul
1 CITETE g,x
2 i=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 reprezinta valoarea, iar xi reprezinta xi
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

9.3.8

Produsul a dou polinoame

9.3.8.1
Pseudocodul
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

68

%ld\n",

EXEMPLE

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

9.3.9

Numrul din an al unei zile

Dndu-se trei numere ntregi reprezentnd data unei zile (an, lun, zi), s se
stabileasc a cta zi din an este aceasta.
9.3.9.1
Rezolvare
Definim doi vectori ce conin numrul de zile din fiecare lun i numele fiecrei
luni (de fapt, vom defini trei vectori, deoarece numrul de zile din luna februarie este
diferit n anii normali i cei biseci). Nu rmne dect s facem o simpl adunare.
9.3.9.2
Programul
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <math.h>
void main (void)
{
// Numarul de zile din fiecare luna (an normal si bisect)
const int zile[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31,
30, 31};
const int zile_b[] = {31, 29, 31, 30, 31, 30, 31, 31, 30,
31, 30, 31};
// Numele fiecarei luni
const char nz[12][15] = {"Ianuarie", "Februarie", "Martie",
"Aprilie", "Mai", "Iunie", "Iulie", "August", "Septembrie",
"Octombrie", "Noiembrie", "Decembrie"};
int an, luna, zi;
int nr_zilei = 0;
int index;
// Indexul lunii curente
// Citim datele de intrare
printf("Introduceti anul:"); scanf("%d",&an);
printf("Introduceti luna:"); scanf("%d",&luna);
printf("Introduceti ziua:"); scanf("%d",&zi);
// Testam daca anul este bisect
if((an%4==0) && ((an%100!=0)||(an%400==0)))
{
// Adaugam lunile anterioare
for(index=0;index<luna-1;index++)
nr_zilei += zile_b[index];
// Adaugam numarul zilei din luna curenta
69

TABLOURI UNIDIMENSIONALE

nr_zilei += zi;
}
else
{
// Adaugam lunile anterioare
for(index=0; index<luna-1;index++)
nr_zilei += zile[index];
// Adaugam numarul zilei din luna curenta
nr_zilei += zi;
}
// Afisare rezultate
printf("Ati introdus ziua de %d %s, a %d-a zi din %d\n", zi,
nz[luna-1], nr_zilei, an);
getch();
}

70

EXEMPLE

10. IRURI DE CARACTERE

irurile sunt tablouri unidimensionale de caractere, care au ca ultim element un


terminator de ir, caracterul NULL (zero ASCII), \0. Funciile care lucreaz cu
iruri de caractere se gsesc n biblioteca string.h

10.1.1

Prefixele unui cuvnt

Fiind dat un cuvnt, s se afieze toate prefixele acestuia.


Se va determina mai nti lungimea cuvntului folosind funcia strlen.
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.
10.1.1.1 Programul
#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

Palindrom

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 ntrun 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.
10.1.2.1 Programul
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
void main()
{
71

IRURI DE CARACTERE

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

Rime cuvinte

Fiind date n iruri de caractere care reprezint n cuvinte, s se determine toate


perechile de rime formate.
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.
10.1.3.1 Programul
#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 citit

S 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 spaii. Vom
presupune c un cuvnt nu are mai mult de 100 de caractere. Cuvintele sunt
separate prin spaii. La sfrit se tasteaz sfritul de fiier (Ctrl+Z) pentru a
termina succesiunea de cuvinte.

72

EXEMPLE

10.1.4.1 Programul
#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 cuvant[MAX+1]; char cuvant_max[MAX+1];
printf("\nIntroduceti cuvintele urmate de Ctrl-Z: \n");
while(scanf("%100s",cuvant) != EOF)
if(max < (i=strlen(cuvant)))
{ max = i; strcpy(cuvant_max,cuvant);}
if(max)
printf("Cel mai lung cuvant: %s", cuvant_max);
}
Obs.:
1. Cuvntul citit se pstreaz n tabloul cuvant 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 cuvant. n acest caz sa utilizat expresia:
i = strlen(cuvant)
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 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(cuvant_max, cuvant);

10.1.5

Citire i ordonare cuvinte

S se scrie un program care citete dou cuvinte i le afieaz n ordine cresctoare.


Cuvntul se definete ca o succesiune de cel mult 100 de caractere care nu sunt
albe. Cuvintele sunt separate prin spaii (caractere albe).
10.1.5.1 Programul
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX 100
void main () /* citeste doua cuvinte si le afiseaza in ordine
crescatoare */
{
char cuv1[MAX+1]; char cuv2[MAX+1] ;
73

IRURI DE CARACTERE

if(scanf("%100s",cuv1) != 1)
{ printf("nu s-a tastat un cuvant\n"); exit(1); }
if(scanf("%100s",cuv2) != 1)
{ printf("nu s-a tastat un cuvant\n"); exit(1); }
if(strcmp(cuv1,cuv2) < 0)
{
/* primul cuvant 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); }
}

10.1.6

Cel mai mare cuvnt

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 sfritul de fiier.
10.1.6.1 Programul
#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
cuvant
este\n");
printf("%s\n",
cuv_max);
}

10.2 Probleme propuse


10.2.1

Eliminare vocale

Se citete un ir de caractere format din cel mult 100 de caractere. S se numere i


s se tearg vocalele din ir. Ex: Pentru irul abracadabra se afieaz 5 si brcdbr

74

PROBLEME PROPUSE

10.2.2

Cuvinte formate prin eliminarea unei litere dintr-un cuvnt


citit

Se citete un cuvnt a cu cel mult 100 de litere. S se afieze pe linii separate toate
cuvintele care se pot forma prin eliminarea unei singure litere din cuvntul citit.
Ex: dac se citete cuvntul alin se vor afia: lin, ain, aln, ali

10.2.3

Interschimbare litere

Se citete un cuvnt format din numr par de litere. S se interschimbe litera de pe


prima poziie cu cea de pe a doua, a treia cu a patra, etc. Ex. cosmin => ocmsni

10.2.4

Comparare cuvinte

Se citesc 2 cuvinte a si b. Sa se determine daca sunt anagrame.

75

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
float mat2[10][10];
//Tablou bidimensional numit mat2 cu
10x10 elemente reale

11.1.2

Citirea primelor m linii i n coloane ale unei matrice

for(i=0; i<m; i++)


for(j=0; j<n; j++)
cin>>a[i][j];

11.1.3

Scrierea primelor m linii i n coloane ale unei matrice

for(i=0; i<m; i++,cout\n)


for(j=0; j<n; j++)
cout<<a[i][j];

11.1.4

Rearanjarea liniilor unei matrice

S se fac rearanjarea liniilor unei matrice astfel nct elementele de pe diagonala


principal s fie elementele de maxim ale fiecrei linii. Se consider c elementele
matricei sunt distincte.
Vom determina mai nti coloanele elementelor de maxim ale fiecrei linii ntrun vector c. Apoi vom verifica dac valorile coloanelor sunt distincte, n caz contrar
nu este posibil rearanjarea liniilor conform cerinelor problemei.
2 1 8
Exemplu: Dimensiunea matricei: 3. Elementele matricei: 9 2 0 . O soluie
5 7 6
9
2
0

este: 5 7 6 .
2 1 8
11.1.4.1 Programul
#include<stdio.h>
int c[5], mat1[5][5], mat[5][5],i, j, poz, max1, n=3;

76

EXEMPLE

void main()
{// Citire dimensiune
printf("Dimensiunea matricei: "); scanf("%d",&n);
// Citire matrice
printf("Elementele matricei: ");
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++)
{
// Se determina coloana poz a unui element de maxim al
liniei i
poz=1; max1=mat[i][1];
for(j=2;j<=n;j++)
{
if(mat[i][j]>max1)
{ max1=mat[i][j]; poz=j; }
c[i]=poz;
}
}
// 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]);
puts(" ");
}
}

11.1.5

Suma a dou matrice

11.1.5.1 Programul
#include<iostream.h>
void main()
{
unsigned m,n,j,i;
float a[10][10],b[10][10],c[10][10];
cout<<nr de linii:;cin>>m; cout<<nr de coloane:;cin>>n;
77

TABLOURI MULTIDIMENSIONALE

for (i=0;i<m;i++)
for (j=0;j<n;j++)
{ cout<<a[<<i<<,<<j<<]= ; cin>>a[i][j]; }
for (i=0;i<m;i++)
for (j=0;j<n;j++)
{ cout<<b[<<i<<,<<j<<]= ; cin>>b[i][j]; }
for (i=0;i<m;i++)
for (j=0;j<n;j++)
c[i][j]=a[i][j]+b[i][j];
for (i=0;i<m;i++,cout<<\n)
for (j=0;j<n;j++)
cout<<c[i][j]<<\t;
}

11.1.6

Produsul a dou matrice

11.1.6.1 Pseudocodul
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
4.1
c[i][j]=0
PENTRU k = 1,n
4.2
c[i][j]= c[i][j] + a[i][k]*b[k][j]
5. PENTRU i=1,m
PENTRU j=1,p
SCRIE c[i][j]

11.2 Probleme propuse


S se alctuiasc programe care s rezolve urmtoarele probleme:
1. Se citesc de la tastatura elementele unei matrice 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 de pe
diagonala principal a matricei A;
c) S se calculeze i s se afieze numrul de litere mari, litere mici i cifre
din matrice;

78

PROBLEME PROPUSE

2.

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.
Se citesc de la tastatur elementele unei matrice cu elemente reale, B (NxN),
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 + BT)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 matricei
A,
aflate
n
triunghiurile
haurate:
f)

3.

S se calculeze procentul elementelor pozitive aflate pe diagonala


secundar;
g) S se calculeze i s se afieze matricea C, unde: C = 3 * BT + B2;
h) S se calculeze i s se afieze matricea D, unde: D = B + B2+ B3 + B4;
i) S se interschimbe coloanele matricei A astfel: prima cu ultima, a doua
cu antepenultima, etc.
Se citesc de la tastatur elementele unei matrice de numere ntregi C (NxN),
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 = C2;
d) S se calculeze i s se afieze matricea E, unde: E = (C + CT)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 matricei C care sunt numere prime;
h) S se calculeze i s se afieze sumele i produsele elementelor matricei
A, aflate n triunghiurile haurate (inclusiv elementele de pe laturi):

79

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.
Ex.:
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.
Obs.: 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 derefereniere
(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;

80

EXEMPLE

// ptr - variabila pointer catre


predefinite, simple, de tip int

un

int;

x,y-variabile

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
q+=1;
// echivalenta cu ( q)++ sau cu x++
int *r;
r=q;
/* copiaza continutul lui q(adresa lui x) in 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 siruri de caractere
#include <iostream.h>
#include<conio.h>
void main(void)
{
textmode(3);
81

POINTERI I ADRESE

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';
}
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.

12.1.3

Pointer la vector - exemplul 1

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[5] = {2,4,6,8,10}; int *pi1 = a;
int *pi2 = &a[0]; int *pi3;
cout<<"a="<<a<<"&a="<<&a<<"*a="<<*a<<'\n';

82

EXEMPLE

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';
x=*pi1++; // x = *pi1 = a[0] = 0, iar apoi *pi1= a[1] = 1
cout<<"x="<<x<<'\n';
x=(*pi1)++; /* x = 1: intai atribuirea, apoi incrementarea
valorii spre care indica pi1.
In urma incrementarii, valoarea lui a[1] devine 2 */
cout<<"x="<<x<<'\n'; cout<<*pi1<<'\n';
x=*++pi1; //echivalent cu *(++pi1)
cout<<"x="<<x<<'\n';
x=++(*pi1); cout<<"x="<<x<<'\n'; pi1=a;
pi3=pi1+3;
cout<<"pi1="<<pi1<<"*pi1="<<*pi1<<"&pi1="<<&pi1<<'\n';
cout<<"pi3="<<pi3<<"*pi3="<<*pi3<<"&pi3="<<&pi3<<'\n';
cout<<"pi3-pi1="<<(pi3-pi1)<<'\n';
//pi3-pi1=3
}

12.1.4

Pointer la vector - exemplul 2

//Pointer la vector
#include <iostream.h>
#define DIM 3
void main()
{
int i; float tablou[DIM], *ptablou;
ptablou=tablou;
cout<<"Introduceti elementele tabloului\n";
for(i=0;i<DIM;i++)
{
cout<<"a("<<(i+1)<<")=";
cin>>tablou[i];
}
cout<<"Elementele tabloului sunt:\n";
for(i=0;i<DIM;i++)
cout<<"a("<<(i+1)<<")="<<*(ptablou+i)<<"\n";
}

12.1.5

Pointer la matrice - exemplul 1

#include<iostream.h>
#include<conio.h>
void main()
{int a[3][3]={{5,6,7}, {55,66,77}, {555,666,777}};
83

POINTERI I ADRESE

clrscr();
cout<<"a="<<a<<" &a="<<&a<<" &a[0]="<<&a[0]<<'\n';
cout<<"Pointeri catre vectorii linii\n";
for (int i=0; i<3; i++){
cout<<" *(a+"<<i<<")="<<*(a+i);
cout<<" a["<<i<<"]="<<a[i]<<'\n';
}
// afiarea matricei
for (int i=0; i<3; i++){
for (int j=0; j<3; j++)
cout<<*(*(a+i)+j)<<'\t'; //sau: cout<<*(a[i]+j)<<'\t';
cout<<'\n';
}
}

12.1.6

Pointer la matrice - exemplul 2

//Pointer la matrice
#include <iostream.h>
#define DIM1 3
#define DIM2 2
float cere_element(int i,int j)
{
float elem;
cout<<"a("<<(i+1)<<","<<(j+1)<<")=";
cin>>elem;cout<<"\n";
return elem;
}
void afis_tablou(float **ptablou)
{
int i,j;
for(i=0;i<DIM1;i++)
for(j=0;j<DIM2;j++)
cout
<<"a("
<<(i+1)
<<","
*((*ptablou)+i*DIM2+j)<< "\n";
}

<<(j+1)<<

void main()
{
float tablou[DIM1][DIM2];
int i,j; float *ptablou;
ptablou=*tablou;
cout<<"Introduceti elementele tabloului\n";
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);

84

")="

<<

PROBLEME PROPUSE

12.2 Probleme propuse


1.

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;

85

FUNCII : GENERALITI, OPERAII CU TABLOURI

13. FUNCII : GENERALITI, OPERAII CU


TABLOURI

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 obligatorii:
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

Transferul prin valoare

Exemplul devenit clasic este cel al funciei de permutare (interschimbare) a dou


variabile. Fie funcia schimb_v definit astfel:
void schimb_v (float x, float y)
{ float t=x; x=y; y=t; }
void main()

86

TRANSFERUL PARAMETRILOR UNEI FUNCII

{ float a=4.7, b=9.7;


. . . . . . . . . . .
schimb_v(a, b);
// apel functie
. . . . . . . . . . . }
Parametri funciei schimb_v sunt transmii prin valoare: parametrilor formali
x, y li se atribuie (la apel) valorile parametrilor efectivi a, b. Funcia schimb_v
permut valorile parametrilor formali x i y, dar permutarea nu are efect asupra
parametrilor efectivi a i b.

13.2.2

Transferul 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 schimb_p(float *x, float *y)
{ float t=*x; *x=*y; *y=t; }
void main()
{ float a=4.7, b=9.7;
. . . . . . . . . . .
schimb_p(&a, &b);
// apel functie
/* SAU:
float *pa, *pb;
pa=&a; pb=&b;
schimb_p(pa, pb);*/
. . . . . . . . . . .
}
Se atribuie pointerilor x i y valorile pointerilor pa, pb, deci adresele variabilelor
a i b. Funcia schimb_p permut valorile spre care pointeaz pointerii x i y, deci
valorile lui a i b.

13.2.3

Transferul prin referin

n limbajul C++, aceeai funcie de permutare se poate defini cu parametri formali


de tip referin.
void schimb_r(float &x, float &y)
{ float t=x; x=y; y=t; }
void main()
{ float a=4.7, b=9.7;
. . . . . . . . . . . .
schimb_r(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.

87

FUNCII : GENERALITI, OPERAII CU TABLOURI

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)
<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 folosit pentru ntoarcerea 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.
Obs.: 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, adic descrierea detaliat (inclusiv prototipul).

13.4 Exemple
13.4.1

Funcie pentru calculul maximului a dou numere reale

float max(float x, float y)


{

88

EXEMPLE

float a;
if (x>y) a=x; else a=y;
return a;
}

13.4.2

Schimbarea valorilor a
parametrilor unei funcii

dou

variabile

transferul

//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

Cel mai mare ptrat perfect mai mic sau egal cu un numr
dat

De la tastatur se citesc n valori ntregi pozitive. Pentru fiecare element s se indice


cel mai mare ptrat perfect mai mic sau egal cu el.
13.4.3.1 Rezolvare
Definim o funcie int patrat(int), care introduce ptratul perfect cel mai
mare, mai mic sau egal cu numrul dat.
13.4.3.2 Programul
//Cel mai mare patrat perfect mai mic sau egal cu un nr

89

FUNCII : GENERALITI, OPERAII CU TABLOURI

#include
#include
#include
#include

<stdio.h>
<stdlib.h>
<conio.h>
<math.h>

// Calculeaza cel mai mare patrat perfect mai mic sau egal cu
a
int patrat (int a)
{
int i=0;
while(i*i<=a)
i += 1;
return (i*i>a)?(i-1)*(i-1):i*i;
}
void main (void)
{
int n, a;
clrscr () ;
printf("Introduceti nr de valori: "); scanf("%d",&n);
// Prelucrare date si afisare rezultate
for(int i=0;i<n;i++)
{
printf("Introduceti elementul %d: ",i+1);
scanf("%d", &a);
printf("Patratul perfect mai mic sau egal cu %d este:
%d\n", a, patrat(a));
}
getch();
}

13.4.4

Perechi

Se citete un ntreg n i n perechi (a, b) de ntregi. S se afieze, acele perechi al


cror cmmdc este un numr prim.
13.4.4.1 Programul
#include<stdio.h>
#include<conio.h>
int cmmdc(int a, int b) //cmmdc cu algoritmul lui Euclid
{
int r;
do
{ r = a % b; a=b; b=r;}
while (r);
return a;
}
int prim(int n) //stabileste daca n este prim

90

EXEMPLE

{
int div;
for (div=2; div*div<=n; (div==2) ? div=3 : div+=2)
if(n%div==0) return 0;
return 1;
}
void main (void)
{
int n;
int a, b;
// Citire date de intrare
printf ("Introduceti numarul de perechi: ");
scanf ("%d", &n);
for(int i=0; i<n; i++)
{
printf (" Introduceti perechea %d: ", i);
scanf("%d%d", &a, &b);
if (prim(cmmdc(a, b)))
printf("cmmdc(%d,%d)=%d\n", a, b, cmmdc(a,b));
}
getch();
}

13.4.5

Elementul de valoare minim al unui tablou

13.4.5.1 Programul
//Minimul elementelor unui tablou
#include <iostream.h>
#define DIM 5
float min2v(float a,float b)
{return (a<b?a:b);}
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++)
91

FUNCII : GENERALITI, OPERAII CU TABLOURI

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.6

Operaii cu matrice cu ajutorul unor funcii

13.4.6.1 Programul
//Operatii cu matrice 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
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];
}

92

nl,int

EXEMPLE

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))
{
93

FUNCII : GENERALITI, OPERAII CU TABLOURI

suma(m1,m2,a,b,sum);
afisare(a,b,m1);
cout<<"\n +\n\n";
afisare(c,d,m2);
cout<<"\n=\n";
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.7

Calculul puterii i transpusei unei matrice ptrate

S se alctuiasc un program pentru ridicarea la putere a unei matrice ptratice i


pentru calculul transpusei acesteia.
13.4.7.1 Strategia de rezolvare
n cazul matricelor ptratice A(n,n) numrul de linii i de coloane este egal cu
ordinul matricei. Transpusa se obine prin interschimbarea elementelor din partea
dreapt a diagonalei principale cu cele avnd indicii liniei i coloanei inversai.
13.4.7.2 Programul
/* Ridicarea la o putere a unei matrice patratice. Calculul
transpusei unei matrice patratice.*/
#define NMAX 20 //Nr maxim de linii/coloane al matricelor

94

EXEMPLE

#include <stdio.h>
#include <conio.h>
/*Functia citeste valorile elementelor unei matrice */
void citire (float ta[NMAX][NMAX], int ordin, char numev)
{
float temp;
printf("\nElementele matricei %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 matrice */
void scriere(float ta[NMAX][NMAX], int ordin, char numev)
{
int trec;
printf("\nAfisarea
valorii
elementelor
pentru
matricea
%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 efect ridicarea la patrat, a unei matrice */
void patrat(float ta[NMAX][NMAX],float tb[NMAX][NMAX],
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];
}
}

int

/*Functia calculeaza transpusa unei matrice*/


void transpusa(float ta[NMAX][NMAX], int ordin)
{
float temp;
for(int i=1,j; i<ordin; i++)
95

FUNCII : GENERALITI, OPERAII CU TABLOURI

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 matricei 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 matricei s nu se piard n timpul operaiei de
transpunere, se utilizeaz o variabil intermediar care stocheaz valoarea uneia
dintre variabilele ce trebuie 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: patrat(a,a,n); nu ar fi dus la
calculul ptratului matricei 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.4.8

Funcie cu pointer la tablou unidimensional

//Pointer la vector
#include <iostream.h>
#define DIM 3
float cere_element(int i)
{float elem;
cout<<"a("<<(i+1)<<")=";
cin>>elem; cout<<"\n";

96

EXEMPLE

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

13.4.9

Funcie cu pointer la tablou bidimensional

//Pointer la matrice
#include <iostream.h>
#define DIM1 3
#define DIM2 2
float cere_element(int i,int j)
{
float elem;
cout<<"a("<<(i+1)<<","<<(j+1)<<")=";
cin>>elem;cout<<"\n";
return elem;
}
void afis_tablou(float **ptablou)
{
int i,j;
for(i=0;i<DIM1;i++)
for(j=0;j<DIM2;j++)
cout
<<"a("<<(i+1)<<","<<(j+1)<<")="<<*((*ptablou)+i*DIM2+j)<<"\n"
;
}
void main()
{
float tablou[DIM1] [DIM2];
int i,j; float *ptablou;
ptablou=*tablou;
97

FUNCII : GENERALITI, OPERAII CU TABLOURI

cout<<"Introduceti elementele tabloului\n";


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);
}

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.

98

EXEMPLE

14. FUNCII: ANALIZ MATEMATIC,


BIBLIOTECI DE FUNCII

14.1 Exemple
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) - f(x-h)
f'(x) = lim
h
h0
14.1.1.1 Programul
//Calculul derivatei unei functii
#include <stdio.h>
#include <math.h>
double fd(double);
double deriv(double,double,double(*)(double));
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); }

99

FUNCII: ANALIZ MATEMATIC, BIBLIOTECI DE FUNCII

14.1.2

Calculul integralei definite a unei funcii prin metoda


trapezelor

Relaia de calcul:
b
f(a)+f(b) +f(a+h) +f(a+2h)+f(a+(n-1)h) ,
I=
f(x) dx = h
2

b-a
unde: h = n , n fiind numrul de diviziuni

f(x)

x
h
a

x1

x2

xn-1

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;

100

EXEMPLE

for(k=1,S=0.0;k<n;k++)
S=S+(*f)(x+k*h);
it=(h/2)*((*f)(x)+(*f)(y))+h*S;
return it;
}
double fc(double x)
{ return x*x; }

14.1.3

Rezolvarea ecuaiilor neliniare prin metoda biseciei

S se rezolve ecuaia neliniar cos(x)-x = 0 prin metoda biseciei.


14.1.3.1 Algoritmul
DATE DE INTRARE:
a, b
{capetele intervalului}

{eroarea maxim admisibil}
DATE DE IEIRE:
x
{rdcina}
zero
{variabil logic de control}
1. CITETE a, b,
2. zero = adevrat
{exist o rdcin}
3. x = a; fa = f(x);
DAC |fa| ATUNCI EXIT
{rdcina este x=a}
4. x = b; fb = f(x);
DAC |fb| ATUNCI EXIT
{rdcina este x=b}
5.
DAC fa fb < 0 ATUNCI
{exist rdcin n intervalul (a,b)}
REPET
x = (a+b)/2; fx = f(x)
{f((a+b)/2)}
DAC fa fx < 0 ATUNCI b = x ALTFEL a = x
dx = b-a; DAC x 0 ATUNCI dx = dx/x
{eroarea}
PN CND |dx| sau |fx|
{testeaz convergena}
ALTFEL zero = fals
{nu exist rdcin}
6. STOP
14.1.3.2 Programul
/*Rezolvarea ecuatiilor neliniare prin metoda injumatatirii
intervalului
xs,xd - limitele intervalului in care se presupune ca se
afla solutia;
eps
- toleranta admisa;
it_lim - limita numarului de iteratii;*/
#include<conio.h>
#include<math.h>
#include<stdio.h>
101

FUNCII: ANALIZ MATEMATIC, BIBLIOTECI DE FUNCII

float xs=0,xd=5,sol,eps=1e-05;
float f(float x)
{ return cos(x)-x;}
float bisec(float xs, float xd, float eps, float (*f)(float))
{
float x,ys,y,yd; int it=0,it_lim=100,gata=0;
ys=f(xs);
yd=f(xd);
if(ys*yd>0)
{ printf("f(xs)*f(xd) > 0"); x=0;}
else
{
while(!gata)
{
gata=0;
it++;
x=(xs+xd)/2;
y=f(x);
printf("%2d
%8.5f
%8.5f
%8.5f
%8.5f
%8.5f
%8.5f\n",it,xs,x,xd,ys,yd,fabs((yd-ys)/2));
if(it>it_lim)
{printf("\nS-a
depasit
numarul
maxim
de
iteratii !"); gata=1;
}
else
if(fabs(x-xs)<eps) gata=1;
else
{if(ys*y<=0) {xd=x; yd=y;}
else
{xs=x; ys=y;}
}
}
}
return x;
}
void main()
{
clrscr();
printf(" it
xs
x
xd
f(xs)
f(xd)
|f(xd)-f(xs)|/2\n");
printf("-------------------------------------------------------------\n");
sol= bisec(xs, xd, eps, f);
printf("\nRadacina aproximata x= %g radiani",sol);
}

102

FUNCII PREDEFINITE

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:

Tabelul 14.1 Funcii matematice


Nume

abs

sqrt
acos
asin

cos

cosh
exp

Sintaxa
double
abs
(double x)
double
(double
double
(double
double
(double

sqrt
x)
acos
x)
asin
x)

double
cos
(double x)
double cosh
(double x)
double
exp
(double x)

Ce returneaza
valoarea
absolut a
unui numr
real

Exemplu
#include <iostream.h>
#include <math.h>
void main(void)
{ int number = -1234;
cout<<"valoarea
absoluta
a
nr."<<number<<=<<abs(number));}

radical
arccosinus
arcsinus
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);}

cosinus
hiperbolic
exponeniala

floor

double floor
(double x)

rotunjire prin
lips

ceil

double ceil
(double x)

rotunjire prin
adaus

#include <stdio.h>
#include <math.h>
void main(void)
{ double number=123.54; double
down,
up;
down=floor(number);
up=ceil(number);
cout<<"numarul
original="<<number<<"nr.rotunjit
prin
lipsa<<down<<"nr.rotunjit
prin adaus<<up;}

103

FUNCII: ANALIZ MATEMATIC, BIBLIOTECI DE FUNCII

Nume

Sintaxa

Ce returneaza

fmod

double fmod
(double
x,double y)

restul
mpririi lui x
la y

hypot

double hypot
(double
x,double y)

ipotenuza
triunghiului
de catete x i y
calculeaz
produsul
dintre primul
parametru i 2
la puterea
dat de cel de
al doilea
parametru

ldexp

log
log10

pow

pow10
sin
sinh
tan
tanh

double
ldexp(double
x, int exp);

double
log(double
x);
double
log10(double
x);
double
pow(double
x,
double
y);
double
pow10(int
p);
double
sin(double
x);
double
sinh(double
x);
double
tan(double
x);
double
tanh(double
x);

14.2.2

Exemplu
#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;}

#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;}

logaritm
natural
logaritm
zecimal
puterea unui
numr la alt
numr
puterea lui 10
la un numr
ntreg
sinus
sinus
hiperbolic

sin_hyp = sinh(x);
sin_hyp = (exp(x) - exp(-x))/2

tangenta
tangenta
hiperbolic

Biblioteca pentru iruri de caractere (string.h)

Conine funcii pentru iruri de caractere

104

FUNCII PREDEFINITE

Tabelul 14.2 Funcii pentru iruri de caractere


Nume

strcat

Sintaxa

strcat(s1,s2)

Ce face

Concateneaz
irul s2 la
sfritul irul
s1

Exemplu
#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);
}
#include <string.h>
#include <stdio.h>
int main(void)
{
char *buf1 = "aaa",
*buf2 = "bbb", *buf3 =
"ccc";
int ptr;

strcmp

strcmp(s1,s2)

Comparare
de iruri; d
valoarea
0
dac s1=s2,
negativ dac
s1<s2
i
pozitiv dac
s1>s2.

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");
}

105

FUNCII: ANALIZ MATEMATIC, BIBLIOTECI DE FUNCII

Nume

Sintaxa

Ce face

strcpy

strcpy(s1,s2)

Copiaz irul
s2 n s1

strlen

strlen(s1)

Determina
lungimea
sirului s1

14.2.3

Exemplu
#include <stdio.h>
#include <string.h>
int main(void)
{
char string[10]; char
*str1 = "abcdefghi";
strcpy(string,
str1);
printf("%s\n", string);
}
#include <stdio.h>
#include <string.h>
int main(void)
{
char *string = "Borland
Internat";
printf("%d\n",
strlen(string));
}

Biblioteca standard (stdlib.h)

Aceasta conine funciile de conversie pe care le vom prezenta n urmtorul tabel:

Tabelul 14.3 Funcii de conversie


Nume
atof

Sintaxa
double
atof(const
char *s);

atol

long
atol(const
char *s);

atoi

int atoi(const
char *s);

itoa

char* itoa(int
value;char*
string;int
radix);

106

Ce face
conversia
unui ir la
real dubl
precizie
conversia
unui ir la
ntreg
long
conversia
unui ir la
ntreg
simplu
conversia
unui
ntreg la
ir
de
caractere
cu
lungimea

Exemplu

#include <iostream.h>
#include<stdlib.h>
void main (void)
{ long l;
char*
str=9876;
l=atol(str);
cout<<atol(<<str<<)=<<l;}

#include <stdlib.h>
#include <iostream.h>
void main(void)
{
int
n=123;
char
str[5];
itoa(n,str,4);
cout<<itoa(<<n<<)=<<str;}

FUNCII PREDEFINITE

Nume

Sintaxa

ltoa

char*
ltoa(long
value;char*
string;int
radix);

ultoa

char*
ultoa(unsigned
long
value;char*
string;int
radix);

ftoa

char*
ftoa(float
value;char*
string;int
radix);

rand

int rand(void)

random

int
num)

rand(int

Ce face
dat de al
treilea
parametru
conversia
unui
ntreg
long la ir
de
caractere
cu
lungimea
dat de al
treilea
parametru
conversia
unui
ntreg
unsigned
long la ir
de
caractere
cu
lungimea
dat de al
treilea
parametru
conversia
unui real
dubl
precizie la
ir
de
caractere
cu
lungimea
dat de al
treilea
parametru
genereaz
un numr
aleator
cuprins
ntre 0 i
10000
genereaz
un numr

Exemplu

#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;}

107

FUNCII: ANALIZ MATEMATIC, BIBLIOTECI DE FUNCII

Nume

system

Sintaxa

void
system(char*
string)

Ce face
aleator
cuprins
ntre 0 i
num-1

Exemplu

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 ntrun 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

Funcii din biblioteca matematic

//Functii din biblioteca matematica


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

108

EXEMPLE

#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);
}

14.4.2

Operaii cu iruri de caractere utiliznd funcii predefinite

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

FUNCII: ANALIZ MATEMATIC, BIBLIOTECI DE FUNCII

cout<<str3=<<str3<<\n;
strcat (str3, str1);
cout<<str1=<<str1<<\n;
cout<<str3=<<str3<<\n;
}

110

EXEMPLE - RECURSIVITATE DIRECT

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,
programul 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 Exemple - Recursivitate direct


15.1.1

Calculul permutrilor, aranjamentelor i combinrilor:


n!
n!
Pn = n! ; Anm = (n-m)! ; Cnm = m!(n-m)!

15.1.1.1

Programul
111

FUNCII RECURSIVE

//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);
}

15.1.2

Funcia recursiv Ackerman

S se calculeze matricea A(LxL), L10 unde:


ACK2(i,j),
dac i>j,
a(i,j)=
1,
dac i=j,
sqrt(ACK(j,i)),
dac i<j,
unde funcia ACK(m,n) este o funcie recursiv Ackerman definit pentru m0
i n0 prin:
ACK(0,n) = n+1;
ACK(m,0) = ACK(m-1,1);
ACK(m,n) = ACK(m-1, ACK(m,n-1);
15.1.2.1 Programul:
//Functii recursive - Ackerman
#include<conio.h>
#include<stdio.h>
#include<math.h>
#define DIM 4
double ack(int m, int n);//prototipul
void scrie(double mat[DIM][DIM]);//prototipul
void main()
{

112

EXEMPLE - RECURSIVITATE DIRECT

double a[DIM][DIM]; int i,j;


clrscr();
for(i=0;i<DIM;i++)
for(j=0;j<DIM;j++)
if(i>j) a[i][j]=ack(i,j)*ack(i,j);
else
if(i==j) a[i][j]=1;
else
a[i][j]=sqrt(ack(j,i));
scrie(a);
getch();
}
//Definirea functiilor
double ack(int m, int n)
{
if(m==0) return n+1;
else
if(n==0) return ack(m-1,1);
else return ack(m-1,ack(m,n-1));
}
void scrie(double mat[DIM][DIM])
{
int i,j;
for(i=0;i<DIM;i++)
{
printf("\n");
for(j=0;j<DIM;j++)
printf("A[%d,%d]= %5.2f;",i,j,mat[i][j]);
}
}

15.1.3

Cel mai mare divizor comun a dou numere (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>
#include <stdlib.h>
//FUNCTIA

113

FUNCII RECURSIVE

long cmmdc(long m, long n) /* calculeaza si returneaza pe cel


mai mare divizor comun al numerelor m si n */
{
if(m==0) return n;
else
if(n==0) return m;
else
if(m>n)
return cmmdc(n, m%n);
else
return cmmdc(m, n%m);
}
void main() /* citeste pe m si n de tip long, calculeaza si
afiseaza (m,n) */
{
long m,n;
printf("\nValorile lui m si n: ");
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
sau 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)
{

114

EXEMPLE - RECURSIVITATE DIRECT

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;

115

FUNCII RECURSIVE

permuta(n);
}

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.
15.1.5.1 Programul
//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);

116

EXEMPLE - RECURSIVITATE DIRECT

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.
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.
15.1.6.1

Programul
117

FUNCII RECURSIVE

//Problema rucsacului
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#define DIM 10
float gx, vx, gmax=9, vmax, g[DIM] = {0,1,2,4,5,8}, v[DIM] =
{0,5,9,12,15,25};
int s[DIM],smax[DIM],n=4;
void rucsac(int i) //i - nr curent max de obiecte
{
int j,k;
for(j=0;j<=1;j++)
/* 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 decat
maximul de pana acum se actualizeaza selectia de maxim */
if(vx>vmax)
{
vmax=vx;
printf("\nvmax=%5.2f: ",vmax);
for(k=1;k<=i;k++)
{
smax[k]=s[k];
printf("%2d*%4.2f(%4.2f)",smax[k],v[k],g[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 */
//Citire din fisier

118

EXEMPLE - RECURSIVITATE DIRECT

/* f=fopen("rucsac.txt","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:\t%g
\nGreut
max:\t%g
\nObiectele:\t",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

Problema prjiturilor

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;
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".
15.1.7.1 Programul
//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;
119

FUNCII RECURSIVE

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
solutiilor
f.open("prajitur.out",ios::out);
nr_sol=0;
rec(1);
f<<"Numarul de solutii: "<<nr_sol ;
f.close();
}

120

scrierea

EXEMPLE - RECURSIVITATE INDIRECT

15.2 Exemple - 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:
proc2 - se nmulete numrul cu 2. Dac ultima cifr este 0 sau 4, se apeleaz
proc0, altfel se apeleaz proc2.
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);
}
}
121

FUNCII RECURSIVE

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 Probleme propuse


1.

2.

3.

4.

5.

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.
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.
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;}
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).
S se calculeze valoarea funciei g, cu o eroare EPS (a, b, EPS citite de la
tastatur):
b

b
g(x)=
x2 + x + 1 *ln|x+a|dx + x*arctgb+x dx
a

6.

7.

122

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.
S se scrie un program care genereaz toate numerele palindrom, mai mici
dect o valoare dat, LIM. Un numr palindrom are cifrele simetrice egale

PROBLEME PROPUSE

8.

(prima cu ultima, a doua cu penultima, etc). Se va folosi o funcie care testeaz


dac un numr este palindrom.
Fie matricea C (NXN), N<=10, ale crei elemente sunt date de relaia:
j

j! +

sin(kx) ,

dac i<j

k 0

Ci,j =

xi,
i! + i

dac i=j

cos(kx) ,

dac i>j

k 0

unde x[0,1], x introdus de la tastatur.


a) S se implementeze urmtoarele funcii: de calcul a elementelor matricei;
de afiare a matricei; de calcul i de afiare a procentului elementelor
negative de pe coloanele impare (de indice 1, 3, etc);
b) S se afieze matricea B, unde: B = C - C2 + C3 - C4 + C5.
9. S se creeze o bibliotec de funcii pentru lucrul cu matrice, care s conin
funciile utilizate frecvent (citirea elementelor, afisarea matricei, adunare a
dou matrice, etc). S se foloseasc aceast bibliotec.
10. S se creeze o bibliotec de funcii pentru lucrul cu vectori, care s conin
funciile utilizate frecvent. S se foloseasc aceast bibliotec.

123

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 x i y ale punctului mediu situat la jumtatea distanei


dintre dou puncte date dintr-un plan.
//Structuri
#include <iostream.h>
typedef struct{float x,y;} punct2D;
punct2D punct_mediu(punct2D p1, punct2D p2)
{
punct2D pm;
pm.x=(p1.x+p2.x)/2;
pm.y=(p1.y+p2.y)/2;
return pm;
}

124

STRUCTURI

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

Simetricul unui punct

S se gseasc simetricele unui punct A(x,y) fa de axa Oy i fa de originea O.


//Structuri-pointer
#include <iostream.h>
struct punct2D {float x,y;};
void simetric_oy(struct punct2D *pct)
{
//in cazul utilizarii pointerilor catre structuri accesarea
campurilor structurii se face cu ajutorul operatorului "->"
pct->x=-pct->x;
}
void simetric_o(struct punct2D *pct)
{
pct->x=-pct->x;
pct->y=-pct->y;
}
void main ()
{
struct punct2D A={5,3};
cout<<"\nPunctul original A are x="<<A.x<<" si y= "<<A.y;
simetric_oy(&A);
cout<<"\nPunctul simetric fata de axa Oy are x="<<A.x<<" si
y=" <<A.y;
simetric_o(&A);
cout<<"\nPunctul simetric fata de orig O are x="<<A.x<<" si
y=" <<A.y;
}

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>

125

TIPURI DE DATE DEFINITE DE UTILIZATOR

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
modul=%.2f",nr.real,nr.imag,modul(&nr));
getch();
}

imag=%.2f

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 le afieaz mpreun cu


modulul i argumentul lor.
Programul folosete o funcie care calculeaz i returneaz modulul unui numr
complex z.
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

126

STRUCTURI

#include <stdio.h>
#include <math.h>
typedef struct {
double x;
double y; } COMPLEX;
double d_modul(COMPLEX *z)
/*calculeaza si returneaza modulul numarului complex z */
{ return sqrt(z->x*z->x+z->y*z->y) ;}
/* functia foloseste constanta M_PI=3.1415...
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;
}

definita

in

void main() /* citeste numere complexe si le afiseaza


impreuna cu modulul si argumentul corespunzator */
{
COMPLEX complex;
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

Ordinea a dou date calendaristice

Scriei o funcie avnd ca parametri dou date calendaristice (precizate prin an,
lun i zi), care stabilete una din situaiile:
Prima dat o precede pe cea de-a doua
Cele dou date sunt egale
A dou dat o precede pe prima
127

TIPURI DE DATE DEFINITE DE UTILIZATOR

Funcia va ntoarce una din valorile -1,0, 1.


#include <stdio.h>
typedef struct
{
unsigned int an;
unsigned int luna;
unsigned int zi;
} Data;
/* vector in care retinem ultima zi pentru fiecare luna: */
int zile[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30,
31};
/* verificare daca anul este bisect (daca da, se intoarce o
valoare nenula): */
int bisect(int an)
{
return ((an%4==0 && an%100!=0) || an%400==0);
}
/* verifica daca o data este valida (daca da, se intoarce o
valoare nenula):*/
int e_valida(Data d)
{
/* daca anul este bisect si luna este februarie: */
if (bisect(d.an) && d.luna==2)
return (d.zi <= 29);
/* anul nu este bisect sau luna nu este februarie: */
return (d.zi <= zile[d.luna-1]);
}
/* Functie care compara 2 date calendaristice
* Rezultat intors. -1 daca d1 precede d2
*
1 daca datele sunt egale
*
1 daca d2 precede d1
*/
int compara_date(Data d1, Data d2)
{
if(d1.an<d2.an) return -1;
if(d1.an>d2.an) return 1;
/* d1.an = d2.an : */
if(d1.luna<d2.luna) return -1;
if(d1.luna>d2.luna) return 1;
/* d1.an = d2.an si d1.luna = d2.luna */
if(d1.zi<d2.zi) return -1;
if(d1.zi>d2.zi) return 1;
/* d1.an = d2.an si d1.luna = d2.1una si d1.zi=d2.zi */
return 0;
}

128

STRUCTURI

void main(void)
{
Data d1, d2;
do
{
printf("introduceti data d1 (zi luna an):\n");
scanf("%d %d %d", &d1.zi, &d1.luna, &d1.an);
if(!e_valida(d1))
printf("Data
nu
este
valida,
introduceti
corecta:\n");
}
while(!e_valida(d1));
do
{
printf("introduceti data d2 (zi luna an):\n");
scanf("%d %d %d", &d2.zi, &d2.luna, &d2.an);
if(!e_valida(d2))
printf("Data
nu
este
valida,
introduceti
corecta:\n");
}
while(!e_valida(d2));
switch(compara_date(d1,d2))
{
case -1: printf("d1 precede d2\n"); break;
case 0: printf("Datele sunt egale\n"); break;
case 1: printf("d1 urmeaza dupa d2\n");
}
}

16.1.6

una

una

Prelucrare informaii 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
#include
#include
#include

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

#define DIM_PAG
#define FALSE 0
#define TRUE 1

24

// dimensiunea paginii de afisare

struct elev{
129

TIPURI DE DATE DEFINITE DE UTILIZATOR

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;
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);
}
}
}

//sau

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

130

STRUCTURI

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++){
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');// afisarea nscrisilor
ord_medii(p, nr_elevi);
afis_elev(p,
nr_elevi,
'R');//
afisarea
n
ordinea
descrescatoare a mediilor
ord_alf(p, nr_elevi); //ordonare alfabetica
afis_elev(p,
nr_elevi,
'O');//
afisarea
n
ordinea
descrescatoare a mediilor
}
131

TIPURI DE DATE DEFINITE DE UTILIZATOR

16.1.7

Media notelor la un examen

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.

16.3 Exemple uniuni


16.3.1

Dat de tip dublu

//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.3.2

Citirea i afiarea datelor despre mai multe persoane

S se exemplifice folosirea uniunilor (union) pentru citirea i afiarea datelor


despre mai multe persoane de ambele sexe.

132

EXEMPLE UNIUNI

Vom folosi o structur pentru a memora numele, vrsta i sexul unei persoane,
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.
#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);
}
}
133

TIPURI DE DATE DEFINITE DE UTILIZATOR

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.3.3

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;
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

134

EXEMPLE UNIUNI

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 elemente 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.
#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
#define
#define
#define
#define

EROARE -1
CERC 0
PATRAT 1
DREPTUNGHI 2
TRIUNGHI 3

#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 */
135

TIPURI DE DATE DEFINITE DE UTILIZATOR

{
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*/
}
int citire_fig(FIG *p)
/* - citeste elementele figurii definite de p->tip; returneaza:
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");
}

136

EXEMPLE UNIUNI

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 mare 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)
137

TIPURI DE DATE DEFINITE DE UTILIZATOR

{ printf(er); exit(1); }
/* calculeaza si afiseaza aria figurii */
if((a=aria(&f))==0)
exit(1);
printf("Aria figurii= %g\n", a);
}

16.4 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 sunt 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, nume1, nume2,..., numek} d1,d2,...,dn;
unde:
nume - este numele tipului de enumerare introdus prin aceast declaraie.
nume0, nume1,..., numek - sunt nume care se vor utiliza n continuare n
locul valorilor numerice i anume numei are valoarea i.
d1,d2,...,dn - sunt date care se declar de tipul nume. Aceste date sunt
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 d1,d2,...,dn;

16.5 Exemple
16.5.1

Exemplul 1 - enumerare nume luni

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

138

DECLARAII DE TIP

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 n acest fel este o dat identic cu data luna declarat la
nceput.

16.5.2

Exemplul 2 - enumerare tip Boolean

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
sau
bisect == true

16.6 Declaraii de tip


Limbajul C permite atribuirea unui nume pentru un tip (predefinit sau utilizator)
de date. Pentru aceasta se folosesc declaraiile 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;
139

TIPURI DE DATE DEFINITE DE UTILIZATOR

COMPLEX x, y;

16.7 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:
o pentru instruciunile de control propriu-zise;
o 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.7.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).

16.7.2

Funcia calloc

Sintaxa:
void *calloc(size_t nr_elemente, size_t mrimea_n_octeti_
a_unui_elem);
Funcia calloc aloc memorie pentru un tablou de nr_elemente, numrul de
octei pe care este memorat un element este mrimea_n_octei_a_unui_elem i
returneaz un pointer ctre zona de memorie alocat.

16.7.3

Funcia realloc
void *realloc(void *ptr, size_t mrime);

140

EXEMPLE

Funcia realloc permite modificarea zonei de memorie alocat dinamic cu


ajutorul funciilor malloc sau calloc.
Obs.: n cazul n care nu se reuete alocarea 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).
Eliberarea memoriei (alocate dinamic cu una dintre funciile malloc, calloc
sau realloc) se realizeaz cu ajutorul funciei free.
void free(void *ptr);

16.8 Exemple
16.8.1

malloc

#include
#include
#include
#include

<iostream.h>
<malloc.h>
<string.h>
<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);}
else
{for(i=0;i<nrart;i++)
if(
(psir[i] = (char *) malloc((strlen(sirstoc) + 1) *
sizeof(char)))== 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);
}

141

TIPURI DE DATE DEFINITE DE UTILIZATOR

16.8.2

calloc

//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)
{int i;
for(i=0;i<n;i++) cout << "a(" <<
*(tablou+i) << "\n";
}

(i+1)

<<

")="

<<

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.9 Probleme propuse


1.

142

Realizai urmtoarele modificri la exemplul 16.1.6:


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.

PROBLEME PROPUSE

2.

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)<600
ii. I=50+20%
pentru 600<=SB<1500 (20% din ceea ce
depete 600)
iii. I=100+30% pentru 1500<=SB<3000
iv. I=250+40% pentru 3000<=SB<15000
v. I=45%
pentru SB>=1500

143

FIIERE

17. FIIERE

Noiunea de fiier desemneaz o colecie de informaii memorat pe un suport


permanent (de obicei discuri magnetice), perceput ca un ansamblu, creia i se
asociaz un nume (n vederea conservrii i regsirii ulterioare).
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.1 Deschiderea unui fiier


17.1.1.1 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.
17.1.1.2 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).

144

NCHIDEREA UNUI FIIER

17.1.1.3 Funcia open


int open(const char *nume_fisier, int acces [,int mod]);
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 "|"
17.1.1.4

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).

17.1.1.5

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.2 nchiderea unui fiier


17.2.1.1

Funcia fclose
int fclose(FILE *pf);

145

FIIERE

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).
17.2.1.2

Funcia fcloseall
int fcloseall(void);
nchide toate fluxururile de date i returneaz numrul fluxurilor de date
nchise (prototip n stdio.h).
17.2.1.3

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.3 Prelucrarea fiierelor text


17.3.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).
17.3.1.1

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.

17.3.1.2

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.3.2

Exemplul 1

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;

146

PRELUCRAREA FIIERELOR TEXT

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++],stdout);
exit(1);
}
while((c=getchar())!=EOF)// sau while((c=getc(stdin))!= EOF)
putc(c,pfcar);
// scrierea caracterului n fiier
fclose(pfcar);
// nchiderea fiierului
}

17.3.3

Exemplul 2

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++],stdout);
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.3.4

Exemplul 3

#include <stdio.h>
#include <process.h>

147

FIIERE

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 in fisier
fclose(pfcar); // Inchiderea fisierului
}

17.3.5

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.3.6

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
// . . .
}
}
printf("Sfarsit de fisier\n");

148

PRELUCRAREA FIIERELOR TEXT

17.3.7

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 c funcia puts scrie n fiierul standard de ieire
(stdout).
17.3.7.1

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.
17.3.7.2

Funcia fgets
char *fgets(char *s, int dim, FILE *pf);
Funcia citete maximum dim-1 octei (caractere) din fiier, sau pn la ntlnirea
sfritului 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.3.8

Exemplul 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);
149

FIIERE

17.3.9

Exemplul 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.3.10 Exemplul 3
S 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");
f_tab.txt pentru scriere
fputs("i\tsin\tcos\n",pfsir);
fisierului text
for(i=0;i<=90;i+=10)
// for(j=0;j<=90;j+=10)
{

150

//deschiderea
//

scrierea

fisierului
antetului

PRELUCRAREA FIIERELOR TEXT

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,tab);
x=cos(PI/180*i);
gcvt(x,5,sir);
printf("\n%s",all);
strcat(all,cr);
fputs(all,pfsir);
}
fclose(pfsir);
}

strcat(all,sir);
strcat(all,sir);

// scrierea n fisierul text

17.3.11 Exemplul 4
Scriei un program care s fac o copie (caracter cu caracter) a unui fiier text dat.
#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);
}

151

FIIERE

17.4 Intrri/ieiri binare


17.4.1

Exemplul 1

S se scrie un program care creeaz 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;
}

17.4.2

Exemplul 2

S se scrie un program care 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';

152

INTRRI/IEIRI BINARE

return 0;
}

17.4.3

Fiier binar cu structuri

S se scrie un program pentru crearea unui fiier binar, avnd articole structuri cu
urmtoarele cmpuri:
Nume depuntor - ir de maxim 30 de caractere;
Data depunerii - o structur avnd cmpurile ntregi: zi, lun, an;
Suma depus - o valoare real.
Articolele sunt grupate pe zile n ordine cronologic. Datele se introduc de la
consol, fiecare pe trei linii. S se afieze apoi coninutul fiierului.
17.4.3.1 Rezolvare
Vom introduce mai nti datele ntr-o ordine aleatoare, apoi le vom sorta dup
dat. n final, vectorul de structuri va fi scris n fiierul "output.dat".
17.4.3.2 Programul
//Fisiere binare - Depuneri
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
void main (void)
{
// Cream un vector de articole pentru a le sorta ulterior
dupa data depunerii.
// Articolul suplimentar este necesar la sortare.
// In plus, vom citi ceea ce am scris in fisier intr-un
vector separat de articole.
struct {
char nume[30];
struct {
int zi, luna, an;
} data;
double suma;
} articole [20], articol, citite[20];
FILE *f;
int n; // Numarul de articole
int found;// Folosit la sortare
// Citire date de intrare
printf("Introduceti numarul de articole: ");
scanf ("%d", &n);
for (int i=0; i<n; i++)
{
printf ("Introduceti numele depunatorului: ");
scanf ("%s", articole[i].nume);
printf ("Introduceti data depunerii <ZZ/LL/AAAA>: ") ;
scanf ("%d/%d/%d", &articole[i].data.zi, \
153

FIIERE

&articole[i].data.luna, &articole[i].data.an);
printf("Introducei suma depusa: ");
scanf ("%lf", &articole[i].suma);
}
// Sortam dupa data depunerii
do
{
found=0;
for (i=0; i<n-1; i++)
// Testam cazurile in care data articolului curent este
'mai mare' decat data articolului urmator
if ( (articole[i].data.an > articole[i+1].data.an) \
|| (articole[i].data.an == articole[i+1].data.an \
&& articole[i].data.luna > articole[i+1].data.luna) \
|| (articole[i].data.an == articole[i+1].data.an \
&& articole[i].data.luna == articole[i+1].data.luna \
&& articole[i].data.zi > articole[i+1].data.zi) )
{
articol = articole[i];
articole[i] = articole[i+1];
articole[i+1] = articol;
found = 1;
}
}
while (found);
// Deschidere fisier
if((f=fopen("output.dat","wb")) == NULL)
{
printf(" Eroare la deschiderea fisierului! ");
exit(1);
}
// Scriem in fisier si il inchidem
// Scriem intai numarul de articole
fwrite(&n, sizeof(int), 1, f) ;
fwrite(&articole, sizeof(articol), n, f);
fclose(f);
if ((f=fopen ("output.dat","rb")) == NULL )
{
printf (" Eroare la deschiderea fi-ierului! ");
exit (1);
}
fread (&n, sizeof(int), 1, f);
fread (&citite, sizeof(articol), n, f);
for (i=0; i<n; i++)
printf (" Articolul %d: %s, %d/%d/%d, %lf\n", i+1, \
citite[i].nume, citite[i].data.zi, \
citite[i].data.luna, citite[i].data.an, \
citite[i].suma);
fclose(f);
getch();
}

154

INTRRI/IEIRI BINARE

17.4.4

Fiier cu structuri - linie de comand cu parametri

Un fiier conine articole cu structura: cod (ir de caractere), nume (ir de caractere)
i cantitate (real). S se scrie un program care permite:
creare;
consultare;
tergere.
Opiunea se introduce ca argument al liniei de comand, prin numele complet
al operaiei:
Creare Nume_fisier - Se creeaz fiierul Nume_fisier prin citirea de la tastatur
a articolelor. Dup fiecare linie introdus se interogheaz dac se continu;
Consultare Nume_fisier - Coninutul fiierului Nume_fisier este listat pe ecran,
cte 20 de linii. Pentru continuarea afirii se apas ENTER;
tergere Nume_fisier cod_articol - Este cutat articolul n fiier i se marcheaz
punndu-i codul xxx.
17.4.4.1 Programul
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#define FALSE 0
#define TRUE 1
struct ARTICOL
{
char cod[10];
char nume[30];
float cantitate; };
// Executa functia de creare fisier
void creare(char *fisier)
{
FILE *f;
struct ARTICOL a;
// Deschid fisierul pentru scriere in mod binar
if ((f=fopen(fisier,"wb")) == NULL)
{
printf (" Nu pot deschide fisierul. \n");
exit (1);
}
do
{
//Articolele citite unul cate unul si scrise in fisier
printf (" Introduceti codul, numele si cantitatea: ");
scanf("%s %s %f", &a.cod, &a.nume, &a.cantitate);
fwrite(&a,sizeof(ARTICOL),1,f);
printf("Doriti sa continuati ? (d/n)\n");
}
while (getch()=='d');
fclose(f);

155

FIIERE

}
// Executa functia de consultare fisier
void consultare(char *fisier)
{
FILE *f;
struct ARTICOL a;
int i=1;
// Deschid fisierul pentru citire in mod binar
if ((f=fopen(fisier,"rb")) == NULL)
{
printf("Nu pot deschide fisierul. \n");
exit (1) ;
}
while(fread(&a,sizeof(ARTICOL),1,f)>0)
// Am grija sa nu afisez articolele care au fost sterse
if(strcmp(a.cod,"xxx")!=0)
{
printf("%10s %30s %10.2f\n",a.cod,a.nume,a.cantitate);
// Daca am afisat 20 de articole, ma opresc si intreb
if (i++%20==0)
{
printf("Doriti sa continuati ? (d/n)\n");
if (getch()=='n') break;
}
}
fclose(f);
}
// Executa functia de stergere
void stergere(char *fisier,char *cod)
{
FILE *f;
struct ARTICOL a; int gasit=FALSE;
// Fisierul este deschis pentru citire/scriere in mod binar
f=fopen(fisier,"r+b");
while(fread(&a,sizeof(ARTICOL),1,f)>0)
if(strcmp(a.cod,cod)==0)
{
// Marchez articolul ca fiind sters
strcpy(a.cod,"xxx") ;
//Ma pozitionez cu o Inregistrare inainte pentru a
suprascrie articolul
fseek(f,ftell(f)-sizeof(ARTICOL),SEEK_SET);
fwrite(&a,sizeof(ARTICOL),1,f);
gasit=TRUE; break;
}
if (!gasit)
printf("Eroare: Articolul nu a fost gasit\n");
fclose(f);
}

156

POZIIONAREA NTR-UN FIIER

void main(int argc, char **argv)


{
if(strcmp(argv[1],"Creare")==0)
creare(argv[2]);
if (strcmp(argv[1],"Consultare")==0)
consultare(argv[2]);
if (strcmp(argv[1],"Stergere")==0)
stergere(argv[2],argv[3]);
}

17.5 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.
17.5.1.1 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);
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).
17.5.1.2

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).
17.5.1.3

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).
17.5.1.4

Funcia fsetpos

157

FIIERE

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 prin 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.
17.5.1.5

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).
17.5.1.6

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).
17.5.1.7

Funcia rewind
void rewind(FILE *flux_date);
Poziioneaz indicatorul la nceputul fluxului de date specificat ca argument
(prototip n stdio.h).

17.6 Funcii utilitare pentru lucrul cu fiiere


17.6.1

Funcii de testare a sfritului de fiier

17.6.1.1

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).
17.6.1.2

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).

17.6.2

Funcii de golire a fluxurilor de date

17.6.2.1

Funcia fflush

158

EXEMPLE

int fflush(FILE *flux_date);


Golete fluxul de date specificat ca argument. Returneaz 0 n caz de succes i -1
(EOF) n caz de eroare (prototip n stdio.h).
17.6.2.2

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).

17.7 Alte operaii cu fiiere


Funcii care permit operaii ale sistemului de operare asupra fiierelor
17.7.1.1

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).

17.7.1.2 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).
17.7.1.3

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).

17.8 Exemple
17.8.1

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

159

FIIERE

{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(angajat),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);
}

17.8.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);

160

EXEMPLE

lungfisis() - determinarea lungimii fiierului existent;


crefis()
- creare fiier.
Funcii pentru adugarea, 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(),list(),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;
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':case 'E':
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);
161

FIIERE

posf=ftell(f); fseek(f,posi,SEEK_SET);
return posf;
}
void scrieb(int nr,void *a,FILE *f)
//scriere n
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); }
}

fisierul

void citireb(int nr,void *a,FILE *f) //citire din


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); }
}

fisierul

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;

162

EXEMPLE

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<<"Contractat "<<i+1<<" : ";cin>>a->cant_c[i]; }
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("material.dat","r"))!=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");//deschidere 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);
}
}
163

FIIERE

}while(na);
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) cout<<"Articol eronat"<<'\n';
}while(!(n>=0 && n<=na));
if(n) scrieb(n,&mat,pf);
}while(n);
fclose(pf);
}
void list()
//afisare informatii despre un anumit
material
{
int na; pf=fopen("material.dat","r");
do
{cout<<"Numarul articolului de listat este (0=END):
";cin>>na;
if(na)
{citireb(na,&mat,pf);
afismat(&mat);
cout<<'\n';
}
}while(na);
fclose(pf);
}

17.9 Probleme propuse


1.

2.

164

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).
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.

PROBLEME PROPUSE

3.

4.
5.

6.

7.

8.
9.

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!).
Scriei un program care s compare coninutul a dou fiiere, i afiai primele
linii care difer i poziia caracterelor diferite n aceste linii.
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).
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.
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.
Scriei un program care citete un text introdus de la tastatur, ordoneaz
alfabetic liniile acestuia i le afieaz.
Scriei o aplicaie pentru gestiunea informatiilor despre crile existente ntr-o
bibliotec. Aplicaia va avea un meniu principal care va permite:
Memorarea datelor ntr-un fiier (un fiier binar cu structuri), al crui
nume se introduce de la tastatur. Fiierul va conine 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).
Adugarea de noi cri;
Afiarea informaiilor despre o anumit carte;
Cutarea titlurilor dup un anumit autor;
Modificarea informaiilor existente;
Lista alfabetic a tuturor autorilor;
tergerea unei cri din bibliotec;
Ordonarea descresctoare dup anul apariiei;
Numele celei mai vechi cri din bibliotec;
Numele celei mai scumpe cri din bibliotec;
Numele autorului cu cele mai multe cri;
Valoarea total a crilor din bibliotec.

165

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