Sunteți pe pagina 1din 233

Colec ia CALCULATOARE

PROGRAMAREA CALCULATOARELOR

LIMBAJUL C

Editura Politehnica, Timioara, 2015


ISBN 978-606-554-999-9

Adriana ALBU

Loredana STANCIU

PROGRAMAREA CALCULATOARELOR

LIMBAJUL C

Editura Politehnica, Timioara, 2015


ISBN 978-606-554-999-9

Cuprins
Prefa .................................................................................................................. 9
Capitolul 1 No iuni de baz n programare ........................................................ 11
Capitolul 2 Scheme logice ................................................................................. 15
2.1 Principalele elemente ale unei scheme logice .......................................... 15
2.2 Probleme rezolvate................................................................................... 20
2.3 Probleme propuse..................................................................................... 24
Capitolul 3 Date i tipuri de date ....................................................................... 30
3.1 No iuni generale ....................................................................................... 30
3.1.1 Tipuri de date .................................................................................... 31
3.1.2 Variabile ............................................................................................ 34
3.1.3 Constante........................................................................................... 35
3.1.4 Operatori ........................................................................................... 36
3.1.5 Expresii ............................................................................................. 39
3.2 Descrierea tipurilor de date ...................................................................... 41
3.2.1 Tipul ntreg........................................................................................ 41
3.2.2 Tipul real ........................................................................................... 43
3.2.3 Tipul caracter .................................................................................... 44
3.2.4 Tipul logic ......................................................................................... 45
3.2.5 Tipul void .......................................................................................... 46
3.2.6 Conversia de tip ................................................................................ 46
3.3 Probleme propuse..................................................................................... 47
Capitolul 4 Un prim program C ......................................................................... 51
4.1 Etapele realiz rii unui program C ............................................................ 51
4.2 Structura unui program C......................................................................... 52
4.3 Posibile erori ............................................................................................ 57
4.4 Probleme propuse..................................................................................... 58
Capitolul 5 Func ii de bibliotec ........................................................................ 61
5.1 Func ii pentru citire/scriere ...................................................................... 61

Programarea calculatoarelor
5.2 Func ii matematice ................................................................................... 69
5.3 Func ii de conversie ................................................................................. 72
5.4 Alte func ii ............................................................................................... 73
5.5 Probleme propuse..................................................................................... 76
Capitolul 6 Instruc iuni ...................................................................................... 80
6.1 Instruc iuni simple ................................................................................... 80
6.1.1 Instruc iunea de atribuire .................................................................. 81
6.1.2 Apelul de func ie ............................................................................... 82
6.2 Instruc iuni alternative ............................................................................. 82
6.2.1 Instruc iunea if ................................................................................ 82
6.2.2 Instruc iunea switch ...................................................................... 87
6.3 Instruc iuni repetitive ............................................................................... 91
6.3.1 Instruc iunea for ............................................................................. 91
6.3.2 Instruc iunea while ......................................................................... 97
6.3.3 Instruc iunea do while ............................................................... 100
6.4 Probleme rezolvate................................................................................. 102
6.5 Probleme propuse................................................................................... 108
Capitolul 7 Tablouri ......................................................................................... 113
7.1 Tablouri unidimensionale ...................................................................... 113
7.1.1 Declararea unui tablou unidimensional .......................................... 114
7.1.2 Accesarea elementelor .................................................................... 114
7.1.3 Ini ializarea elementelor.................................................................. 114
7.1.4 Introducerea de la tastatur a valorilor elementelor ........................ 115
7.1.5 Afi area elementelor / Parcurgerea unui vector .............................. 115
7.1.6 Un exemplu complet ....................................................................... 116
7.2 Tablouri bidimensionale ........................................................................ 117
7.2.1 Declararea tablourilor bidimensionale ............................................ 117
7.2.2 Accesarea elementelor .................................................................... 118
7.2.3 Ini ializarea elementelor.................................................................. 118
6

Cuprins
7.2.4 Introducerea de la tastatur a valorii elementelor ........................... 119
7.2.5 Afi area unei matrice ...................................................................... 119
7.2.6 Parcurgeri ntr-o matrice ................................................................. 120
7.2.7 Particularit i de parcurgere a matricelor p tratice ......................... 121
7.2.8 Un exemplu complet ....................................................................... 123
7.3 Probleme rezolvate................................................................................. 124
7.4 Probleme propuse................................................................................... 130
Capitolul 8 iruri de caractere ......................................................................... 134
8.1 Caractere ................................................................................................ 134
8.2 iruri de caractere .................................................................................. 136
8.3 Probleme propuse................................................................................... 144
Capitolul 9 Pointeri .......................................................................................... 148
9.1 Variabile pointer .................................................................................... 148
9.2 Opera ii cu pointeri ................................................................................ 150
9.3 Pointerii i alte elemente ........................................................................ 151
9.4 Probleme propuse................................................................................... 154
Capitolul 10 Func ii definite de utilizator ........................................................ 157
10.1 Func ii definite de utilizator ................................................................. 158
10.1.1 Prototipul unei func ii ................................................................... 158
10.1.2 Descrierea unei func ii .................................................................. 159
10.1.3 Apelul unei func ii ........................................................................ 161
10.1.4 Cmpul de ac iune al variabilelor ................................................. 167
10.1.5 Modificarea argumentelor unei func ii ......................................... 172
10.1.6 Transmiterea tablourilor ca argumente ......................................... 174
10.2 Recursivitate ........................................................................................ 176
10.3 Probleme rezolvate............................................................................... 178
10.4 Probleme propuse................................................................................. 186
Capitolul 11 Tipuri definite de utilizator ......................................................... 194
7

Programarea calculatoarelor
11.1 Structura ............................................................................................... 194
11.1.1 Definire i utilizare ....................................................................... 194
11.1.2 Structuri i func ii ......................................................................... 201
11.1.3 Tablouri de structuri ...................................................................... 203
11.1.4 Pointeri de tip structur ................................................................. 205
11.2 Enumerarea .......................................................................................... 206
11.3 Uniunea ................................................................................................ 208
11.4 Probleme propuse................................................................................. 212
Anexa 1 Setul de caractere ............................................................................... 220
Anexa 2 Cuvintele cheie ale limbajului C ....................................................... 221
Anexa 3 R spunsuri ......................................................................................... 224
Bibliografie ...................................................................................................... 233

Prefa
n ultimele decenii comunicarea a devenit un concept foarte des vehiculat,
avnd un rol important n orice activitate. A a cum este necesar ca oamenii s
comunice ntre ei pentru a reu i s convie uiasc i s realizeze ceva mpreun ,
tot astfel se cere ca ntre om i calculator s existe o modalitate prin care s aib
loc comunicarea. Un limbaj de programare este folosit pentru a-i transmite unui
calculator cum s ndeplineasc o anumit sarcin . La fel ca limbajele utilizate
n comunicarea interuman , un limbaj de programare con ine cuvinte, fraze i
reguli sintactice bine definite. Frazele unui limbaj de programare sunt aranjate
astfel nct s alc tuiasc un program cu ajutorul c ruia se va realiza comunicarea ntre om i calculator. F r programe, un calculator nu ar fi nimic. Pe de alt
parte, o persoan care este capabil s scrie astfel de programe are o serie de
avantaje n fa a celor care tiu doar s utilizeze calculatoarele i aplica iile lor.
Se dore te ca acest manual s fie folositor celor care ncearc s se familiarizeze
cu programarea, el fiind u or de parcurs, rapid i eficient. Cei care vor utiliza
aceast carte n formarea lor ca dezvoltatori de programe (incluznd aici i
proiectarea, nu doar implementarea acestora) vor avea ocazia s devin competen i n domeniul program rii, deoarece elementele oferite conduc la dobndirea
cuno tin elor i la dezvoltarea abilit ilor corespunz toare acestui domeniu.
Aceast carte este destinat a adar cu prec dere celor care realizeaz primii pa i
n domeniul program rii i prezint caracteristici care conduc la nv area limbajului C (un limbaj puternic, portabil i foarte popular, utilizat n realizarea de
aplica ii n domenii diverse). nainte de a fi prezentate aspectele specifice limbajului C, sunt trecute n revist i cteva dintre conceptele fundamentale ale
program rii. Astfel, nv area i utilizarea ulterioar a altor limbaje de programare se va realiza mult mai u or, pentru c baza de cuno tin e legate de
programarea structurat exist deja.
Cartea este atent mp r it pe capitole. Conceptele de programare sunt introduse
treptat, ntr-o ordine fireasc , astfel nct leg tura dintre o no iune nou i precedentele s fie foarte clar , iar descrierea unei noi no iuni s se poat face pe
baza unor concepte deja explicate. Se asigur n acest mod n elegerea i nsu irea rapid a elementelor prezentate.
Primele dou capitole con in aspecte generale, valabile pentru toate limbajele de
programare. Sunt introduse astfel cteva no iuni de baz necesare acestui domeniu (capitolul 1) i este descris modul n care se pot rezolva grafic problemele prin intermediul schemelor logice (capitolul 2). Se trece apoi la elementele
specifice limbajului de programare C, ncepndu-se cu descrierea datelor i a

Programarea calculatoarelor
tipurilor de date existente (capitolul 3) i continund cu un prim exemplu de
program C (capitolul 4). Urm toarele dou capitole pun la dispozi ia programatorului func ii de bibliotec (n capitolul 5) i instruc iuni (capitolul 6) disponibile n C. Capitolul 7 prezint felul n care se lucreaz cu tablourile n C,
punndu-se accent pe tablourile uni i bidimensionale. Un caz particular de
tablouri unidimensionale sunt n C irurile de caractere, prezentate n capitolul 8. Descrierea limbajului C continu cu elemente legate de pointeri (capitolul 9). Urmeaz dou capitole referitoare la posibilitatea programatorului de a- i
mp r i programele n func ii (capitolul 10) i de a- i defini propriile tipuri de
date (capitolul 11).
n toate aceste capitole prezentarea aspectelor teoretice se realizeaz simplu i
clar, permi nd astfel cititorului s n eleag rapid elementele puse n discu ie.
De asemenea, capitolele con in numeroase exemple nso ite de comentarii i
explica ii, care au scopul de a sus ine partea teoretic . Exemplele sunt cu prec dere programe ntregi (nu doar fragmente izolate) i au fost testate nainte de a
fi introduse n text.
Cei care utilizeaz aceast carte au i posibilitatea de a- i testa cuno tin ele
dobndite, fiecare capitol (cu excep ia celui introductiv) ncheindu-se cu un set
de ntreb ri i cerin e structurate n general n patru categorii. Prima categorie
de ntreb ri se axeaz pe identificarea erorilor; n acest sens sunt aduse n discuie secven e cu gre eli care trebuie localizate. n urm toarea categorie de ntreb ri cititorul trebuie s determine ce fac buc ile de program, schemele sau
expresiile prezentate. Urmeaz un set de ntreb ri gril referitoare la con inutul
capitolului; ntreb rile surprind att aspecte teoretice, ct i elemente practice
(expresii, secven e de cod). R spunsurile i explica iile la ntreb rile din aceste
prime trei categorii se g sesc n ultima anex a c r ii. Partea de verificare a
cuno tin elor se ncheie de obicei cu cteva cerin e de probleme care necesit
scrierea unor programe ntregi. Pentru acestea cartea nu ofer rezolv ri, l snd
cititorului posibilitatea de a gndi o solu ie.
Claritatea aspectelor teoretice, multitudinea de exemple explicate, de probleme
rezolvate i de ntreb ri cu r spunsuri fac posibil parcurgerea i n elegerea
materialului chiar i f r ajutorul unui expert. Cei interesa i s p trund n
lumea program rii vor g si a adar n aceast carte un real sprijin.

10

Capitolul 1 No iuni de baz n programare


Calculatorul este capabil s execute diverse opera ii i s ofere solu ii numeroaselor probleme care se cer a fi rezolvate cu ajutorul s u. Trebuie doar s fie
programat n acest sens. Cu alte cuvinte, calculatorul face orice i se spune, cu
condi ia s n eleag ceea ce se dore te de la el. Prin urmare e necesar un
anumit mod de comunicare ntre om i calculator, comunicare ce se realizeaz
prin intermediul limbajelor de programare.
Cu ajutorul no iunilor prezentate n aceast carte, se ncearc transmiterea unor
cuno tin e de baz legate de informatic i de programarea structurat pentru
cei care se afl la nceputul acestui drum. Cartea poate fi de asemenea util i
celor care au o oarecare experien n acest domeniu, ajutndu-i s i consolideze i s i ordoneze cuno tin ele pe care le-au acumulat deja.
Un concept foarte intens vehiculat n ultimul timp este informa ia, avnd diferite semnifica ii strns legate de: control, comunicare, percep ie, date, cuno tin e,
reprezent ri, tipare. n lumea calculatoarelor datele i cuno tin ele nu sunt ns
strict semnifica ii ale cuvntului informa ie, ci sunt conectate de acesta, avnd i
n elesuri specifice. Astfel, datele reprezint materialul brut. n urma prelucr rii,
acestea se transform n informa ii, care, printr-o anumit interpretare (adic
dndu-li-se un anumit n eles) devin cuno tin e. Figura 1.1.1 este o reprezentare
grafic sugestiv a rela iei dintre aceste trei no iuni care pot forma o construc ie
piramidal bazat pe date (cantitatea cea mai mare), consolidat de informa ii
(aflate la mijlocul piramidei) i ncununat de cuno tin e.
CUNO TIN E

INFORMA II

DATE
Figura 1.1.1 Reprezentarea piramidal a datelor, informa iilor i cuno tin elor

De exemplu se pot considera ca date analizele medicale ale unui pacient; mai
precis, nivelul globulelor albe care este foarte ridicat n cazul respectivului
pacient. Informa ia poate fi legat de faptul c un nivel al globulelor albe mai

Programarea calculatoarelor
mare dect o anumit valoare conduce la apari ia leucemiei (acest lucru presupune o prelucrare a datelor ini iale prin compararea lor cu valoarea limit ). n
fine, cuno tin ele constau n con tientizarea faptului c pacientul respectiv este
n pericol.
La nivel elementar un calculator prelucreaz date. Sarcina programatorului este
s proiecteze i s scrie programe prin care s determine calculatorul s preia
datele brute i s le transforme n informa ii cu o anumit semnifica ie pentru
utilizator.
Strns legat de informa ie se afl un alt concept: informatica tiin a care se
ocup cu studiul prelucr rii informa iei cu ajutorul sistemelor automate de
calcul [DEX09]. Alte defini ii arat de asemenea c informatica presupune
achizi ionarea datelor, stocarea, manipularea, clasificarea acestora, studiind
structura, comportamentul i interac iunile ntre sistemele care memoreaz ,
proceseaz i comunic informa ii. Astfel se ajunge la nc o no iune, foarte
important n aceast er , comunicarea. ntre oameni comunicarea se realizeaz
printr-un anumit limbaj care cuprinde expresii, semne, gesturi. Unui calculator
ns nu i se poate comunica nimic dect dac se cunoa te un limbaj pe care
acesta s -l n eleag , adic un limbaj de programare.
Unitatea central de prelucrare (Central Processing Unit) este responsabil cu
rezolvarea oric ror probleme, ns nu n elege niciun limbaj uman, acceptnd
doar instruc iuni scrise n a a numitul limbaj ma in . Fiecare instruc iune a
acestui limbaj este o n iruire de cifre binare 0 i 1 programarea fiind foarte
greoaie. Din acest motiv s-au inventat un fel de prescurt ri (formate din cteva
litere) pentru instruc iunile limbajului ma in , ajungndu-se astfel la limbajul
de asamblare. Chiar i a a, cele mai simple opera ii erau realizate cu dificultate
i presupuneau parcurgerea mai multor etape.
S-a observat apoi c unele opera ii se repetau i au fost scrise mici programe
separate pentru aceste opera ii. Apoi a ap rut ideea cre rii unui limbaj de programare care s fie format din aceste mici programe c rora li s-au dat denumiri
sugestive. Astfel, s-a ajuns ca rezolvarea unei probleme s se realizeze utiliznd
cuvinte n limba englez . Evident programarea devenea n acest fel mult mai
simpl i mai atractiv . Deoarece limbajele astfel create au un nivel ridicat de
abstractizare n compara ie cu limbajul de asamblare, ele se numesc limbaje de
nivel nalt. Primele limbaje de acest fel au fost COBOL i FORTRAN, urmate
de Basic, Pascal, Lisp, C i altele.

12

1 No iuni de baz n programare


Limbajul C a fost inventat de Dennis RITCHIE n 1972. Cu toate c au trecut
foarte mul i ani de atunci, acest limbaj continu s fie utilizat pe scar larg
datorit avantajelor pe care le are [CH96], [GP00]:
este un limbaj de nivel nalt (oferind programatorilor u urin n utilizare
datorit sintaxei), dar cu toate acestea asigur puterea i flexibilitatea unui
limbaj ma in datorit faptului c p streaz o serie de caracteristici specifice unui limbaj de asamblare;
are o eficien deosebit , fiind conceput pentru scrierea sistemelor de operare (este un limbaj proiectat de c tre programatorii de sistem pentru scrierea
sistemului de operare UNIX [BK03]);
este puternic, programele scrise n C putnd realiza un num r mare de calcule ntr-un num r mic de etape;
este succint datorit utiliz rii unui num r foarte mare de operatori (unii
operatori sunt matematici, al ii nlocuiesc anumite comenzi);
este portabil, putnd fi instalat pe o mul ime de calculatoare diferite;
este popular datorit for ei i portabilit ii sale, fiind folosit de un num r
impresionant de programatori;
este ntr-un permanent progres, suportnd complet ri i extensii.
Toate aceste caracteristici fac din limbajul C un limbaj pe care orice programator trebuie s -l cunoasc . Utiliznd uneltele puse la dispozi ie de C, dezvoltarea
diverselor programe se poate face ntr-un mod eficient, rezultnd produse finale
de calitate ridicat .
Limbajul C are tr s turi care suport i ncurajeaz programarea structurat .
Acest tip de programare are la baz o teorem conform c reia orice algoritm
poate fi implementat utiliznd doar trei structuri de control (figura 1.1.2):
secven a se execut o entitate a programului i apoi entitatea imediat
urm toare; cu alte cuvinte, p r ile unei secven e de cod se execut una dup
alta i f r a face salturi peste anumite p r i (figura 1.1.2 a);
selec ia se execut doar una din dou alternative, n func ie de valoarea
unei condi ii (figura 1.1.2 b);
itera ia o entitate a unui program este executat n mod repetat atta timp
ct o condi ie este adev rat (figura 1.1.2 c).

13

Programarea calculatoarelor

a) Secven a

b) Selec ia

c) Itera ia

Figura 1.1.2 Cele trei elemente de control care stau la baza program rii structurate

Rezolvarea unei probleme presupune de fapt implementarea unui algoritm,


adic a unui num r de pa i bine defini i care trebuie executa i pentru solu ionarea respectivei probleme. Pentru aceasta se parcurg trei faze (reprezentate i n
figura 1.1.3):
analizarea problemei pentru a se stabili exact care sunt datele ini iale i care
sunt cerin ele;
reprezentarea problemei ntr-un mod adecvat solu ion rii cu ajutorul calculatorului;
implementarea, adic scrierea ntr-un anumit limbaj de programare a unui
program care va rezolva problema.
Analiz

Reprezentare

Implementare

Figura 1.1.3 Fazele parcurse n rezolvarea unei probleme

Chiar dac implementarea, ultima faz parcurs n rezolvarea unei probleme,


pare a fi cea mai important , totu i celelalte dou nu sunt deloc de neglijat.
Analiza ini ial a datelor de intrare i a cerin elor este esen ial pentru g sirea
unei solu ii corecte. De asemenea, este foarte important ca programul realizat s
fie bine structurat i s existe un flux clar de elemente care sunt executate.
Pentru a asigura corectitudinea rezolv rii unei probleme se recomand reprezentarea grafic a algoritmului utilizat. Acest lucru se realizeaz prin intermediul unor elemente care alc tuiesc o a a-numit schem logic . Fiecare pas executat pentru rezolvarea problemei are asociat o imagine care de obicei prezint
un aspect geometric i este nso it de texte cu ajutorul c rora se descrie ceea ce
trebuie executat n acel pas. Detalii despre reprezentarea grafic a unei probleme de reg sesc n capitolul dedicat schemelor logice.
14

Capitolul 2 Scheme logice


2.1 Principalele elemente ale unei scheme logice
Primii pa i n domeniul program rii structurate vor fi f cu i prin intermediul
schemelor logice, o metod foarte bun pentru dezvoltarea ra ionamentului.
Independente de limbajul de programare, schemele logice sunt reprezent ri
grafice ale programelor, oferind o imagine clar asupra acestora i permi nd o
dezvoltare mai u oar , ele fiind cel mai simplu mod de exprimare a unui algoritm. Schemele logice pot p rea arhaice. Cu toate acestea, ele stau la baza conceperii unui program, fiind foarte folositoare mai ales celor care se afl la nceput n ceea ce prive te programarea. Se spune c o imagine valoreaz ct o mie
de cuvinte, iar schemele logice reprezint exact imaginea unui program, scrierea efectiv a programului, dup reprezentarea lui grafic , fiind doar o munc
de rutin [GP00].
Schemele logice sunt compuse din cteva simboluri cu ajutorul c rora se poate
reprezenta orice algoritm. Elementele care pot intra n componen a unei scheme
logice sunt prezentate n continuare.
Blocul START marcheaz nceputul programului:

START

Blocul STOP marcheaz sfr itul programului:


STOP

Prin intermediul acestor dou blocuri se poate ti cu precizie unde ncepe i


unde se ncheie reprezentarea unui program. Se elimin astfel orice nel muriri
privitoare la delimitarea schemelor logice.
Blocul de ie ire este folosit pentru afi area rezultatelor:
De exemplu:

Scrie a

Utiliznd aceste trei blocuri se poate contura schema logic a unui prim program care s tip reasc mesajul Acesta este primul meu program
(figura 2.1.1). A a cum se poate observa, schema cuprinde un bloc de ie ire

Programarea calculatoarelor
(utilizat pentru tip rirea mesajului) i cele dou blocuri care marcheaz nceputul, respectiv sfr itul programului.
START

Scrie Acesta este


primul meu program

STOP
Figura 2.1.1 Schem logic n care este utilizat doar blocul de ie ire

Blocul de intrare este folosit pentru citirea/introducerea datelor.


De exemplu:

Cite te a

n schema logic din figura 2.1.2 blocul de intrare este folosit pentru introducerea numelui unei persoane, nume care este apoi afi at prin intermediul unui bloc
de ie ire.
START

Cite te nume

Scrie Numele introdus este: nume

STOP
Figura 2.1.2 Schem logic n care sunt utilizate blocurile de intrare i de ie ire

Blocul de calcul execut opera ii i este utilizat atunci cnd are loc un proces
de prelucrare a datelor (calcule sau ini ializ ri):
16

2 Scheme logice

De exemplu:

b=2*a

Cu ajutorul blocului de calcul se pot rezolva o serie de probleme. n continuare


este prezentat schema logic pentru aflarea sumei i produsului a dou numere
introduse de la tastatur (figura 2.1.3). Pentru citirea numerelor se folose te un
bloc de intrare. Apoi, prin intermediul unui bloc de calcul se realizeaz suma i
produsul care, n final, sunt tip rite cu ajutorul unui bloc de ie ire.
START

Cite te a,b

suma=a+b
produsul=a*b
Scrie suma, produsul

STOP
Figura 2.1.3 Schema logic pentru calcularea sumei i produsului a dou numere

Avnd la dispozi ie i blocul de calcul, se pot solu iona i probleme ceva mai
complexe. De exemplu ecua ia de gradul nti: ax+b=0. Se citesc de la tastatur dou numere a i b, reprezentnd coeficien ii i se calculeaz valoarea necunoscutei x, valoare care apoi este afi at . n figura 2.1.4 este prezentat o prim
schem logic pentru rezolvarea ecua iei de gradul nti.

17

Programarea calculatoarelor
START

Cite te a,b

x=-b/a
Scrie x

STOP
Figura 2.1.4 Schema logic (incomplet ) pentru rezolvarea ecua iei de gradul nti

A a cum se poate observa, aceast schem realizat pentru rezolvarea ecua iei
de gradul nti are un neajuns: nu trateaz situa ia n care coeficientul a este
egal cu zero (caz n care mp r irea lui b la a nu se mai poate executa). Din
punct de vedere matematic o ecua ie de forma ax+b=0 se rezolv astfel:
Se verific valoarea coeficientului a:
dac a e diferit de zero, atunci x=b/a;
dac nu, atunci ecua ia devine b=0 i trebuie verificat valoarea coeficientului b:
o dac b e diferit de zero, atunci expresia b=0 e fals , deci nu exist
solu ii pentru necunoscuta x;
o dac b este egal cu zero, atunci expresia b=0 e adev rat i orice
num r real reprezint o solu ie a ecua iei considerate (adic necunoscuta x are o infinitate de solu ii).
Pentru a rezolva ns aceast problem , mai e nevoie de un bloc: cel prezentat
n continuare.
Blocul decizional evalueaz condi ii i este utilizat atunci cnd ntr-un program
trebuie s se ia o decizie bazat pe dou alternative. Blocul trebuie s con in o
ntrebare la care s se poat r spunde prin da sau nu:

18

2 Scheme logice

NU

De exemplu:

DA

NU

DA

a 0

Folosind i blocul decizional, se poate rezolva, corect, ecua ia de gradul nti


conform algoritmului descris anterior. Schema logic prezentat n figura 2.1.5
urmeaz ntocmai pa ii acestui algoritm.
START

Cite te a,b

NU

NU

b 0

a 0

DA

x=-b/a

DA

Scrie Ecua ia nu
are solu ii

Scrie x

Scrie Ecua ia are o


infinitate de solu ii

STOP

Figura 2.1.5 Schema logic pentru rezolvarea ecua iei de gradul nti

19

Programarea calculatoarelor

2.2 Probleme rezolvate


Schemele logice sunt o modalitate simpl i clar de reprezentare a unui algoritm i de rezolvare a unei probleme, oferind celor care fac primii pa i n programarea structurat o excelent unealt prin care i pot mbun t ii modul n
care gndesc solu ionarea unei probleme. n continuare, pentru a fi n elese ct
mai bine no iunile privitoare la schemele logice, se vor rezolva sau, mai bine
spus, se vor propune rezolv ri pentru alte cteva probleme.
2.2.1 Pentru nceput se dore te calcularea ariei unui p trat cu latura L dat .
Aceast arie va fi aflat utiliznd formula Aria=L*L. O prim schem logic
pentru rezolvarea acestei probleme este redat n figura 2.2.1. Utilizatorul trebuie s introduc (prin intermediul unui bloc de intrare) latura p tratului. Se calculeaz aria, care (utiliznd un bloc de ie ire) este apoi afi at .
START

Cite te L

aria=L*L

Scrie aria

STOP
Figura 2.2.1 Aria unui p trat varianta 1

Ce se ntmpl ns dac utilizatorul, din gre eal sau din ne tiin , introduce un
num r negativ pentru latura p tratului? Valoarea nu poate fi acceptat deoarece
o dimensiune nu poate fi negativ . Prin urmare schema logic din figura 2.2.1
nu func ioneaz corect pentru toate cazurile i trebuie modificat . Problema ar
putea fi par ial solu ionat dac , nainte de a fi calculat aria, s-ar testa valoarea
lui L. n cazul n care latura este strict pozitiv , se poate calcula i afi a aria;
altfel, se va afi a un mesaj de eroare (figura 2.2.2).

20

2 Scheme logice
START

Cite te L

NU

L>0

DA

aria=L*L

Scrie Valoarea introdus nu este corect

Scrie aria

STOP
Figura 2.2.2 Aria unui p trat varianta 2

Exist ns situa ii n care aria (sau ceva similar) trebuie neap rat calculat . Cu
alte cuvinte utilizatorul trebuie for at s introduc o valoare valid (n cazul de
fa , o valoare pozitiv ). Acest lucru se realizeaz prin intermediul unei structuri repetitive (figura 2.2.3). Utilizatorul va trebui s reintroduc valoarea cerut
atta timp ct aceasta nu este valid . A adar, se va trece mai departe,
calculndu-se aria, numai dup ce este introdus o valoare pozitiv pentru
latur .

21

Programarea calculatoarelor
START

Scrie Valoarea introdus nu este


corect . Introduce i
o valoare pozitiv .

Cite te L

NU

L>0

DA

aria=L*L
Scrie aria

STOP
Figura 2.2.3 Aria unui p trat varianta 3 (complet )

2.2.2 Urm toarea problem este tot un exemplu de structur repetitiv . Utilizatorul introduce n numere de la tastatur (unde n este num r natural). Se va
calcula i se va afi a media aritmetic a acestor numere (figura 2.2.4). Pentru a
putea rezolva aceast problem , n trebuie s fie un num r pozitiv. Se va folosi
n acest sens o structur repetitiv de validare a citirii lui n asem n toare cu cea
de la calculul ariei unui p trat de latur L. Dup ce se cite te un num r n pozitiv, se poate trece la calculul mediei aritmetice. Aceasta reprezint suma elementelor introduse raportat la num rul de elemente. Prin urmare se ini ializeaz cu zero o variabil numit suma (ini ial, adic nainte de a se introduce
vreun num r, suma este evident zero). De asemenea, n orice moment al execuiei programului, trebuie tiut cte numere au fost deja citite. Pentru acest lucru
se folose te o alt variabil , numit contor, i ini ializat tot cu valoarea zero.
Se poate trece apoi la citirea celor n numere. Acest lucru se realizeaz ntr-o
structur repetitiv . De fiecare dat cnd un num r este citit, el se adun la
sum , iar contorul se m re te cu o unitate. Aceast bucl se repet atta timp ct
contorul este mai mic dect n. n momentul n care condi ia nu mai este ndeplinit , se iese din structura repetitiv i se continu execu ia programului cu
opera ia de calculare a mediei aritmetice, care apoi poate fi afi at .
22

2 Scheme logice

START

Cite te n

Scrie Introduce i o
valoare pozitiv
NU

n>0
DA

contor=0
suma=0

Cite te numar

suma=suma+numar
contor=contor+1
DA

contor<n
NU

media=suma/n
Scrie media

STOP
Figura 2.2.4 Media aritmetic a n numere

23

Programarea calculatoarelor

2.3 Probleme propuse


A. Specifica i unde este gre eala.
1.

START

Cite te x

x=x+1

Scrie x

STOP

2.

START

Cite te x

NU

x>0

DA

Scrie Pozitiv

Scrie Negativ

STOP

24

2 Scheme logice
3.

START

Cite te x

NU

x>0

DA

Scrie Pozitiv

Scrie Negativ

Scrie Zero

STOP

B. Se consider urm toarele scheme logice. Specifica i ce ac iuni realizeaz


acestea.
4.

START

Cite te xA,xB,yA,yB

Scrie AB

STOP

25

Programarea calculatoarelor
5.

START

Cite te a3,a2,a1,a0

Scrie
a3x3+a2x2+a1x+a0

b2=3a3
b1=2a2
b0=a1

Scrie b2x2+b1x+b0

STOP

6.

START

Cite te n

r = n modulo 10

Scrie r

STOP

26

2 Scheme logice
7.

START

Cite te n

Scrie Introduce i o
valoare pozitiv
NU

n>0
DA

contor=1
p=1

contor=contor+1
p=p*contor
DA

contor<n
NU

Scrie p

STOP

C. Alege i r spunsul corect (unul singur).


8. Care dintre urm toarele afirma ii referitoare la schemele logice este
adev rat ?
a) sunt reprezent ri grafice ale programelor;
b) sunt independente
de limbajul de programare;
c) reprezint o metod foarte bun pentru
dezvoltarea ra ionamentului; d) ofer o imagine clar asupra programelor; e) toate r spunsurile sunt corecte.
9. Care dintre urm toarele blocuri nu exist ?
a) blocul decizional; b) blocul de ie ire;
blocul de calcul; e) blocul de intrare.
10. Blocul decizional are form de:
27

c) blocul repetitiv;

d)

Programarea calculatoarelor
a) triunghi;

b) romb;

c) dreptunghi;

d) trapez;

e) stea.

11. Care dintre urm toarele forme geometrice nu apar ntr-o schem logic ?
a) dreptunghi;

b) romb;

c) trapez;

d) triunghi;

e) elips .

12. Blocul de calcul are form de:


a) dreptunghi;

b) cerc;

c) romb;

d) arc de cerc;

e) parabol .

13. Cte ie iri are un bloc decizional?


a) niciuna; b) una: Da; c) dou : Da i Nu; d) trei: Da, Nu,
Unknown; e) oricte, n func ie de expresia evaluat .
D. S se realizeze scheme logice pentru rezolvarea urm toarelor probleme:
14. Se cite te un num r real x. Se cere calcularea i afi area valorii expresiei:

15. Se citesc trei numere a, b i c, reprezentnd coeficien ii ecua iei de gradul doi ax2+bx+c=0. S se g seasc i s se afi eze solu iile acestei
ecua ii.
Indica ie: Din punct de vedere matematic rezolvarea ecua iei de gradul
doi presupune mai mul i pa i. Mai nti se verific valoarea coeficientului a:
o dac a e diferit de zero, atunci se calculeaz
rific valoarea ob inut :

=b2-4ac i se ve-

dac <0, ecua ia nu are solu ii reale i se afi eaz un


mesaj n acest sens;
dac

=0, atunci ecua ia are dou solu ii egale:


;

dac

>0, ecua ia are dou solu ii distincte:


i

o dac a este egal cu zero, atunci ecua ia devine bx+c=0 i trebuie verificat valoarea coeficientului b:
28

2 Scheme logice
dac b este diferit de zero, atunci x=c/b;
dac nu, atunci ecua ia devine c=0 i trebuie verificat
valoarea coeficientului c:
dac c e diferit de zero, atunci expresia c=0 e
fals , deci nu exist solu ii pentru necunoscuta x;
dac c este egal cu zero, atunci expresia c=0 e
adev rat i orice num r real reprezint o solu ie
a ecua iei considerate (adic necunoscuta x are o
infinitate de solu ii).
16. S se calculeze aria i lungimea unui cerc de raz R.
Indica ie: Introducerea razei trebuie validat (raza trebuie s fie pozitiv ). Se vor folosi urm toarele formule: aria= R2, iar lungimea=2 R.
17. S se afi eze primele n numere ale irului lui Fibonacci.
Indica ie: irul lui Fibonacci este un exemplu n care se folose te structura repetitiv . irul este reprezentat de o secven de numere definit de
urm toarea rela ie:

Cu alte cuvinte, primele dou numere se dau, ele fiind 0 i 1, iar fiecare
din urm toarele numere se calculeaz ca sum a precedentelor dou numere. Astfel, primele 10 numere din irul lui Fibonacci sunt:
0, 1, 1, 2, 3, 5, 8, 13, 21, 34.

29

Capitolul 3 Date i tipuri de date


3.1 No iuni generale
A a cum s-a ar tat n capitolul 1, calculatorul stocheaz i prelucreaz date,
acestea avnd diferite semnifica ii i fiind indispensabile rezolv rii oric rui tip
de problem . Exist dou categorii de date:
unele care i pot modifica valoarea pe parcursul execu iei unui program,
numite variabile;
altele care i p streaz valoarea stabilit ini ial, f r s existe vreo modalitate de a o modifica, numite constante.
Indiferent dac este vorba de variabile sau de constante, nainte de a putea fi
folosite ntr-un program, acestea trebuie declarate. Variabilelor li se specific
numele, tipul i op ional valoarea ini ial , iar constantelor numele, tipul i obligatoriu valoarea. n urma declar rii, variabilelor i constantelor li se aloc
spa iu n memorie.
Numele unei variabile sau al unei constante este alc tuit prin al turarea unor
caractere (litere, cifre, semne speciale), respectnd anumite reguli. n acest sens
e bine ca un programator s cunoasc ntregul set de caractere pe care le are la
dispozi ie. Acestea pot fi consultate n anexa 1. Atunci cnd se stabile te numele unei variabile sau al unei constante trebuie inut cont de cteva restric ii
[CH96]:
primul caracter al numelui trebuie s fie neap rat o liter sau o liniu
subliniere (de exemplu nume sau _nume);

de

dup primul caracter se pot utiliza orice combina ii de cifre i litere cu


excep ia caracterelor care nu sunt alfanumerice, cum ar fi #, $ sau spa iu (de
exemplu se pot folosi denumiri ca variabila1, cuv2nou, dar nu sunt
acceptate nume de genul var$);
limbajul C este case sensitive, adic face diferen a ntre litere mari i mici;
atunci cnd se declar i se utilizeaz variabile sau constante, trebuie s se
in cont i de acest lucru (de exemplu variabilele nume1 i Nume1 sunt diferite);
exist o serie de cuvinte rezervate care nu se pot utiliza ca nume de variabile sau de constante; lista complet a acestor cuvinte, numite i cuvinte cheie,
se g se te n anexa 2.

3 Date i tipuri de date

3.1.1 Tipuri de date


Tipul unei variabile sau constante este dependent de ceea ce trebuie reprezentat,
de aici rezultnd felul n care informa ia este stocat n memorie. Orice entitate
care se dore te a fi procesat de calculator trebuie transpus din forma n care
ea este achizi ionat (de la utilizator sau din alte surse) ntr-o form fizic definit prin tensiuni electrice. Astfel se ajunge la unitatea de baz pentru reprezentarea informa iei n memorie, care este bitul. Acesta poate lua valorile logice 0
(dac tensiunea se afl n intervalul 0 0.4 vol i) sau 1 (pentru o tensiune n
intervalul 2.4 5 vol i). A adar, un bit [NR01] este informa ia elementar ,
ireductibil , caracterizat prin aceea c surprinde una din dou posibilit i care
sunt contradictorii i complementare.
De obicei bi ii se grupeaz n coduri de lungimi care sunt puteri ale lui 2. Codurile uzuale sunt pe 8, 16, 32, 64, 128, 256 bi i. Opt bi i formeaz un byte sau
octet. n tabelul 3.1.1 sunt prezenta i multiplii bitului i ai octetului [NR01].
Tabelul 3.1.1 Multiplii bitului i ai octetului
Multiplii bitului

Multiplii octetului

1 Kilobit (Kbit) = 210 bi i

1 Kilooctet (Kilobyte KB) = 210 octe i

1 Megabit (Mbit) = 220 bi i

1 Megaoctet (Megabyte MB) = 220 octe i

1 Gigabit (Gbit) = 230 bi i

1 Gigaoctet (Gigabyte GB) = 230 octe i

1 Terabit (Tbit) = 240 bi i

1 Teraoctet (Terabyte TB) = 240 octe i

1 Petabit (Pbit) = 250 bi i

1 Petaoctet (Petabyte PB) = 250 octe i

1 Exabit (Ebit) = 260 bi i

1 Exaoctet (Exabyte EB) = 260 octe i

1 Zettabit (Zbit) = 270 bi i

1 Zettaoctet (Zettabyte ZB) = 270 octe i

1 Yottabit (Ybit) = 280 bi i

1 Yottaoctet (Yottabyte YB) = 280 octe i


31

Programarea calculatoarelor
Tipul reprezint mul imea valorilor pe care le poate lua o variabil sau o constant . Tipurile au un nume i se mpart n dou mari categorii:
tipuri standard sunt deja definite n limbajul de programare C i pot fi
utilizate ca atare (int, float, double, char);
tipuri definite de utilizator n func ie de contextul i de cerin ele unei
probleme, utilizatorul poate defini i folosi ulterior propriile sale tipuri de
date.
Principalele tipuri de date standard care pot fi folosite n limbajul de programare C (numite i tipuri primare) sunt prezentate n tabelul 3.1.2. Al turi de numele i semnifica ia tipului, apare num rul de bi i pe care se face reprezentarea,
precum i domeniul n care pot lua valori datele definite utiliznd acel tip. Un
caz mai special este tipul ntreg, a c rui reprezentare este dependent de sistem.
Tabelul 3.1.2 Principalele tipuri de date ale limbajului C
Denumirea
tipului

Semnificaia tipului

Dimensiunea

Domeniul de valori

char

caracter

8 bi i

-128 127

int

ntreg

16 sau 32 bi i

-32.768 32.767 sau


-2.147.483.648 2.147.483.647

float

real (virgul
flotant )

32 bi i

3.4 e-38 3.4 e+38

double

real (virgul
flotant ,
dubl precizie)

64 bi i

1.7 e-308 1.7 e+308

Al turi de tipurile de date, apar deseori a a-numi ii modificatori, prin intermediul c rora se poate specifica lungimea spa iului de memorie alocat unui element. Ace tia sunt:
short scurt;
long lung;
32

3 Date i tipuri de date


signed cu semn;
unsigned f r semn.
Tabelul 3.1.3 con ine tipurile de date din C, mpreun cu modificatorii posibili
(au rezultat astfel tipurile derivate) [HS98], [DL06].
Tabelul 3.1.3 Tipurile de date i modificatorii limbajului C
Denumirea
tipului

Semnifica ia
tipului

Dimensiunea

Domeniul de valori

unsigned
char

caracter
semn

8 bi i

0 255

char
sau
signed char

caracter
semn

8 bi i

-128 127

unsigned int

ntreg
semn

f r

16 sau
32 bi i

0 65.535 sau
0 4.294.967.295

int sau signed


int

ntreg cu semn

16 sau
32 bi i

-32.768 32.767 sau


-2.147.483.648 2.147.483.647

unsigned
short int

ntreg
scurt
f r semn

8 bi i

0 255

short int sau


signed short
int

ntreg scurt cu
semn

8 bi i

-128 127

unsigned long
int

ntreg
lung
f r semn

32 bi i

0 4.294.967.295

long int sau


signed long
int

ntreg lung cu
semn

32 bi i

-2.147.483.648 2.147.483.647

float

real

32 bi i

3,4 e-38 3,4 e+38

f r
cu

(virgul

33

Programarea calculatoarelor
flotant )
double

real (virgul
flotant , dubl
precizie)

64 bi i

1,7 e-308 1,7 e+308

long double

real
lung
(virgul
flotant ,
dubl
precizie)

80 bi i

3.4 e-4932 3.4 e+4932

Numele tipurilor de date i ai modificatorilor reprezint cuvinte cheie n limbajul de programare C, prin urmare ele sunt rezervate doar acestui scop. Nu se pot
declara variabile sau constante care s poarte aceste nume i de asemenea nu se
pot crea noi tipuri de date sau func ii care s fie denumite astfel. Lista cuvintelor cheie din C poate fi consultat n anexa 2.

3.1.2 Variabile
La declararea unei variabile, a a cum s-a ar tat, se va specifica tipul informa iei
care va fi re inut n acea variabil , precum i numele ei. Forma general a unei
instruc iuni prin intermediul c reia se declar variabile este:
tip var1,var2, , varn;
n declara ia de mai sus, var1, var2, , varn sunt numele unor variabile,
iar tip este denumirea unuia dintre tipurile prezentate n tabelul 3.1.3 sau un
tip definit de utilizator. Variabilele sunt separate prin virgul , iar declara ia
trebuie s se ncheie cu punct i virgul .
Exemple:
int numar1, numar2, suma;
double media;
La declarare, exist posibilitatea ca unei variabile s i se dea i o valoare ini ial , care poate fi modificat pe parcursul execu iei programului. De exemplu:
int contor=0;
Astfel se declar o variabil de tip ntreg, c reia i se d numele contor i care
are valoarea ini ial zero.
34

3 Date i tipuri de date

3.1.3 Constante
Atunci cnd ntr-un program se folose te n mod repetat o anumit valoare, este
bine ca acea valoare s fie declarat drept constant . I se va atribui un nume i
va putea fi folosit pe tot parcursul programului prin intermediul acelui nume. E
la fel ca n matematic unde pentru calcularea ariei unui cerc de exemplu, se va
folosi constanta n locul valorii 3.14159265
Utilizarea constantelor ntr-un program are o serie de avantaje [CH96]. Cele
mai importante sunt legate de faptul c datorit constantelor codul devine simplu de n eles i u or de modificat. Dac ntr-un program se folose te constanta
, este destul de clar pentru toat lumea c ea reprezint raportul dintre circumferin a unui cerc i diametrul s u n geometria euclidian . Dac ns este utilizat valoarea 3.1415, lucrurile nu mai sunt att de evidente. n ceea ce prive te
modificarea valorilor constante folosite ntr-un program, totul e foarte simplu:
modificare se face doar n locul unde constanta este declarat i se reflect
oriunde este utilizat . n cazul n care nu se declar o constant , ci se folose te
valoarea ei pe tot parcursul programului, atunci codul este mai greu de modificat pentru c trebuie c utate i nlocuite toate apari iile acelei valori.
nainte de a putea fi utilizate, constantele trebuie declarate. Acest lucru se realizeaz prin cuvntul cheie const. Forma general a instruc iunii prin care se
declar o constant este:
const tip nume_constanta = valoare;
unde:
tip este tipul de dat al constantei (de exemplu int, char, float etc.);
nume_constanta este denumirea cu care constanta va fi utilizat n
program;
valoare reprezint valoarea pe care o va avea constanta.
n urm torul exemplu se declar o constant n virgul mobil care are numele
pi i valoarea 3.1415:
const float pi = 3.1415;
Pe lng constantele pe care utilizatorul i le define te, n limbajul de programare C pot fi folosite i o serie de constante simbolice care sunt predefinite. De
exemplu exist o constant cu numele M_PI i valoarea 3.14159265.
35

Programarea calculatoarelor

3.1.4 Operatori
Variabilele i constantele pot fi incluse n diverse opera ii pentru a ob ine noi
valori. n acest sens se vor utiliza operatori, cu ajutorul c rora variabilele i
constantele vor forma expresii. n func ie de felul opera iei n care sunt implica i, operatorii se mpart n mai multe categorii. Cei care sunt utiliza i mai
frecvent vor fi prezenta i n continuare [CH96], [DL06], [GP00].
operatori rela ionali rezultatul aplic rii lor este 1 n cazul n care compara ia este adev rat i 0 n caz contrar:
< mai mic (a<b);
<= mai mic sau egal (a<=b);
> mai mare (a>b);
>= mai mare sau egal (a>=b);
== egal (a==b);
!= diferit (a!=b).
operatori aditivi:
+ plus (adunare: a=b+c);
minus (sc dere: a=b-c).
operatori multiplicativi:
* nmul ire (a=b*c);
/ mp r ire n cazul mp r irii a dou numere ntregi, ofer ca rezultat
ctul; dac cel pu in unul dintre operanzi este num r real, rezultatul este real (a=b/c);
% modulo operator care furnizeaz drept rezultat restul mp r irii a dou
numere ntregi (a=b%c); nu poate fi folosit cu operanzi reali.
operatori compu i se folosesc pentru scrierea mai rapid a unor expresii:
+= adunare al c rei rezultat se salveaz n primul operand (de exemplu:
x+=y este echivalent cu x=x+y);

36

3 Date i tipuri de date


= sc dere al c rei rezultat se salveaz n primul operand (de exemplu:
x=y este echivalent cu x=xy);
*= nmul ire al c rei rezultat se salveaz n primul operand (de exemplu:
x*=y este echivalent cu x=x*y);
/= mp r ire al c rei rezultat se salveaz n primul operand (de exemplu:
x/=y este echivalent cu x=x/y);
%= opera ia modulo, al c rei rezultat se salveaz n primul operand (de
exemplu: x%=y este echivalent cu x=x%y).
operatori logici:
! operatorul de negare (p=!q);
&& I logic, numit i conjunc ie logic (p=p1&&p2);
|| SAU logic, numit i disjunc ie logic (p=p1||p2).
al i operatori:
= operatorul de atribuire copiaz valoarea din dreapta sa n variabila din
stnga sa; se formeaz astfel o expresie, ob inndu-se o nou valoare
(de exemplu: x=7; sau i=i+2;);
++ operatorul de incrementare este un operator unar (adic are nevoie
doar de un element), se aplic doar asupra variabilelor de tip ntreg i
are ca efect m rirea cu o unitate a valorii variabilei respective (x++
sau ++x sunt echivalente cu x=x+1). Operatorul poate ap rea nainte
sau dup numele variabilei; diferen a e c variabila i schimb valoarea nainte, respectiv dup utilizare;
operatorul de decrementare mic oreaz cu o unitate valoarea variabilei asupra c reia este aplicat (x sau x sunt echivalente cu x=x
1) i are acelea i caracteristici ca operatorul de incrementare;
& operatorul de adresare indic adresa de memorie a unei variabile i este plasat n fa a numelui variabilei (&x);
?: operatorul condi ional: a?e1:e2 dac a e diferit de zero (sau adev rat), se execut expresia e1; dac a e zero (sau fals) se execut expresia e2;
() apel de func ie se realizeaz prin numele func iei, urmat eventual de
o list de argumente (de exemplu: afisare(a,b));
37

Programarea calculatoarelor
(tip) conversie de tip operator folosit pentru a schimba tipul unei variabile (de exemplu, dac se consider variabila a de tip real, prin executarea instruc iunii (int)a, se ob ine o valoare ntreag );
sizeof() operator unar care calculeaz dimensiunea unui tip de dat ,
adic num rul de octe i necesari pentru a reprezenta o variabil de acel
tip (de exemplu, sizeof(int)).
Ordinea n care se execut opera iile (denumit i preceden a operatorilor) este
cea cunoscut din matematic . n tabelul 3.1.4 se reg sesc operatorii prezenta i
n acest paragraf n ordinea preceden ei pe care o au, ncepnd cu cei mai puternici i ncheind cu cei mai slabi [BK03], [HS98].
Tabelul 3.1.4 Preceden a operatorilor
Categoria

Operatorii

unari

++, , (tip) , sizeof()

multiplicativi

*, /, %

aditivi

+,

rela ionali

<, <=, >, >=

de egalitate

==, !=

I logic

&&

SAU logic

||

condi ional

?:

de atribuire

=, +=, -=, *=, /=, %=

Pentru a evita gre elile care pot ap rea din cauza unor nen elegeri legate de
preceden a operatorilor, e indicat a se folosi paranteze atunci cnd sunt create
,e
expresii mai ample. De exemplu, dac se dore te calcularea expresiei
38

3 Date i tipuri de date


indicat s

se scrie
. Aceast expresie este diferit
care calculeaz de fapt
.

de

Preceden a operatorilor are un rol foarte important n evaluarea expresiilor, iar


cunoa terea ordinii n care operatorii sunt aplica i este obligatorie. De exemplu
expresia (1||1&&0) are valoarea 1 deoarece operatorul && este aplicat naintea operatorului ||[PT12]. Dac ar fi invers, valoarea expresiei s-ar schimba.

3.1.5 Expresii
ntr-un limbaj de programare expresiile reprezint , la fel ca n matematic ,
opera ii care se fac asupra unor operanzi (variabile, constante sau alte expresii)
utiliznd operatori. n acest fel se ob ine o valoare nou , al c rei tip este dependent de tipul operanzilor. Forma general a unei expresii este urm toarea:
E = expresie_simpl [operator_rela ional alt _expresie_simpl ]
ncadrarea unor entit i n paranteze drepte indic faptul c acele entit i au
caracter op ional. A adar, o expresie este format din una sau mai multe expresii simple conectate prin operatori rela ionali. La rndul s u, o expresie simpl
con ine termeni lega i prin operatori aditivi. Un termen are mai mul i factori
uni i prin operatori multiplicativi. n fine, un factor poate fi: o constant , o
variabil (reprezentat de valoarea sa), adresa unei variabile (operatorul de
adresare urmat de numele variabilei), o variabil negat , un apel de func ie, o
transformare de tip sau o alt expresie simpl ncadrat n paranteze rotunde.
n func ie de rezultatul pe care l produc, expresiile pot fi mp r ite n trei categorii [CH96]:
expresii matematice
Acestea au ntotdeauna ca rezultat un num r i sunt alc tuite din valori conectate prin intermediul unor simboluri reprezentnd opera ii matematice. Pentru a
specifica ordinea efectu rii opera iilor se pot folosi paranteze.
De exemplu:
expresia 3+4*2 va avea ca rezultat valoarea 11;
n schimb (3+4)*2 este 14.
expresii de tip text

39

Programarea calculatoarelor
Rezultatul acestora este un ir de caractere, adic o secven de caractere care
poate include cifre, litere, semne de punctua ie i alte simboluri (de exemplu
"Dennis M. RITCHIE"). Din p cate limbajul C nu dispune de operatori
pentru prelucrarea irurilor de caractere. n locul operatorilor, n expresiile de
tip text se folosesc func ii specifice, care vor fi prezentate n capitolul dedicat
irurilor de caractere.
expresii logice
Pot avea ca rezultat valoarea 1 sau valoarea 0, cu semnifica ia adev rat,
respectiv fals i sunt create cu ajutorul operatorilor rela ionali. O expresie
logic este un fel de ntrebare la care r spunsul este da sau nu.
De exemplu:
5>1 este o expresie adev rat , deci va avea ca rezultat valoarea 1;
7==0 este fals , a adar rezultatul evalu rii expresiei este 0;
a>=b poate fi 0 sau 1, n func ie de valorile celor dou variabile luate n
considerare.
Rezultatele expresiilor logice, precum i elemente care pot fi interpretate logic,
pot fi combinate cu ajutorul operatorilor logici, ob inndu-se astfel condi ii
complexe. Pentru aceasta trebuie n primul rnd cunoscut modul n care ac ioneaz operatorii logici. n tabelul 3.1.5 se consider dou variabile logice, a i
b, i se aplic operatorii AND ( I), OR (SAU) i NOT (negare), eviden iindu-se
toate rezultatele posibile.
Tabelul 3.1.5 Aplicarea operatorilor logici
a

!a

a&&b

a||b

40

3 Date i tipuri de date


De exemplu:
expresia (7>=5)&&(0!=10) con ine dou expresii adev rate, legate
prin operatorul logic I; expresia final este adev rat , deci va avea ca
rezultat valoarea 1;
expresia (7==0)&&(3<4) este format dintr-o expresie fals (prima) i
una adev rat (a doua), legate prin I logic; rezultatul este fals, adic 0;
expresia (7==0)||(3<4) con ine acelea i dou expresii ca precedenta
(una adev rat i una fals ), dar legate prin operatorul SAU logic; prin
urmare se ob ine valoarea 1 pentru c este suficient ca cel pu in una
din expresii s fie adev rat pentru ca expresia final s fie adev rat ,
a a cum rezult i din tabelul 3.1.5;
expresia !(7==0) este adev rat deoarece se neag o expresie fals .

3.2 Descrierea tipurilor de date


Urm toarele paragrafe prezint tipurile de date standard care au fost descrise
succint anterior. De asemenea sunt adu i n discu ie operatorii care pot fi aplica i fiec rui tip. La sfr itul paragrafelor sunt prezentate exemple de utilizare a
respectivelor tipuri de dat .

3.2.1 Tipul ntreg


n C exist mai multe tipuri prin intermediul c rora se pot reprezenta numere
ntregi, fiecare dintre aceste tipuri fiind un subset al mul imii numerelor ntregi
(Z) din matematic . Descrise succint n tabelul 3.1.3, tipurile ntregi vor fi
detaliate n cele ce urmeaz .
unsigned int este utilizat pentru numere ntregi f r semn. Un astfel de
num r se reprezint pe 16 bi i i poate lua valori n intervalul 0 65.535. n C
exist definit o constant prin intermediul c reia se poate determina care este
limita maxim a acestui interval. Este vorba de constanta UINT_MAX a c rei
valoare este 65.535. Acest tip poate fi reprezentat i pe 32 de bi i, putnd lua
valori n intervalul 0 4.294.967.295.
int sau signed int sunt tipurile prin care se reprezint numere ntregi cu
semn. Pentru aceasta sunt necesari tot 16 bi i, domeniul n care pot lua valori
41

Programarea calculatoarelor
astfel de numere fiind -32.768 32.767. Constantele C care delimiteaz acest
domeniu sunt INT_MIN, avnd valoarea -32.768, respectiv INT_MAX, cu
valoarea 32.767. A a cum s-a specificat i n tabelul 3.1.3, pot exista i reprezent ri pe 32 de bi i ale acestor tipuri, cu valori ntre -2.147.483.648 i
2.147.483.647.
unsigned short int este tipul utilizat pentru numere ntregi scurte, f r
semn. Pe cei 8 bi i dedica i se pot reprezenta numere n intervalul 0 255.
Pentru a accesa ntr-un program limita superioar a acestui interval se poate
folosi constanta USHRT_MAX care are valoarea 255.
short int sau signed short int definesc numere ntregi scurte, cu
semn. Aceste tipuri se reprezint pe 8 bi i, iar numerele iau valori n domeniul 128 127. Limitele acestui domeniu pot fi aflate prin constantele SHRT_MIN,
care are valoarea -128, respectiv SHRT_MAX, cu valoarea 127.
unsigned long int este un tip de data utilizat pentru numere ntregi mari
i pozitive. Pe cei 32 de bi i afla i la dispozi ie se pot reprezenta numere n
intervalul 0 4.294.967.295. Constanta ULONG_MAX re ine limita superioar a
acestui interval.
long int sau signed long int se folosesc pentru numere ntregi de
dimensiuni mari, pozitive sau negative. Reprezentarea se face pe 32 de bi i, iar
numerele se g sesc n domeniul -2.147.483.648 2.147.483.647. Pentru a
accesa limitele acestui domeniu se pot folosi constantele LONG_MIN i
LONG_MAX.
Toate constantele care specific limitele domeniilor de reprezentare pentru
aceste tipuri de date sunt definite n biblioteca limits.h. Detalii despre
utilizarea bibliotecilor limbajului C vor fi date n capitolul dedicat func iilor de
bibliotec .
Atunci cnd se scriu programe, variabilele trebuie definite n mod corespunz tor. De exemplu, dac se dore te reprezentarea vrstei unei persoane, aceasta
poate fi o variabil de tip unsigned short int pentru c vrsta este totdeauna pozitiv i, de asemenea, este un num r scurt. Dac se lucreaz ns cu o
for , prin definirea variabilei trebuie s se asigure faptul c acesteia i se pot da
att valori pozitive, ct i negative i, de asemenea, domeniul de valori trebuie
s fie suficient de mare (int de exemplu).
Datele de tip ntreg pot fi implicate n diverse opera ii. Astfel, se pot realiza
opera ii cu caracter rela ional (<, <=, >, >=, ==, !=), opera ii aritmetice (+, -,
42

3 Date i tipuri de date


*, /, %) sau opera ii logice (&&, ||). De asemenea, variabilele ntregi pot fi
incrementate (++) sau decrementate(--).
Utilizarea tipului ntreg
n cele ce urmeaz se vor declara, utiliznd tipul ntreg, trei variabile (x, a i
b) i o constant (lambda). Constanta are, evident, o valoare ini ial (n cazul
acesta 3). Variabilele nu sunt ini ializate la declarare; a i b primesc valori
ulterior (2, respectiv -7), iar valoarea lui x este calculat prin intermediul unei
expresii. Rezultatul acestei expresii este -15.
const unsigned int lambda = 3;
int x, a, b;
a = 2; b = -7;
x = lambda * (a + b);
Variabilele de tip ntreg sunt frecvent utilizate mpreun cu operatorii de
incrementare i decrementare. Ace ti operatori pot ap rea naintea variabilei sau
dup ea, diferen a fiind eviden iat n cele dou secven e de cod care urmeaz .
Se declar dou variabile de tip ntreg a i x. Cea de a doua variabil , x, prime te valoarea 7. Diferen a apare n momentul n care variabilei a i se atribuie
valoarea lui x incrementat dup atribuire (n primul caz) i nainte de atribuire
(n al doilea caz).
int a, x;
x = 7;
a = x++;

int a, x;
x = 7;
a = ++x;

n urma rul rii acestor trei linii de cod


rezultatele sunt a=7 i x=8 pentru c
incrementarea lui x s-a realizat dup
opera ia de atribuire.

Deoarece incrementarea lui x se face


naintea opera iei de atribuire, n acest
al doilea caz rezultatele sunt a=8 i
x=8.

3.2.2 Tipul real


Numerele reale (mul imea R din matematic ) pot fi introduse ntr-un program C
prin intermediul tipurilor float, double i long double descrise n
tabelul 3.1.3. Aceste tipuri ofer posibilitatea de a utiliza numere reale, de
diferite precizii i dimensiuni, ajungnd pn la valoarea 3.4 e+4932.
43

Programarea calculatoarelor
float este un tip de dat prin intermediul c ruia se reprezint , pe 32 de bi i,
numere reale cu o precizie de 6 zecimale. Dac e nevoie de o acurate e mai
mare, atunci numerele se pot declara double (cu reprezentare pe 64 de bi i),
iar pentru a extinde precizia se poate utiliza tipul long double (care are o
reprezentare pe 80 de bi i).
Variabilele de tip real se pot introduce n expresii al turi de operatori rela ionali
(<, <=, >, >=, ==, !=) i aritmetici (+, -, *, /). n cazul opera iilor cu caracter
rela ional, rezultatul este o valoare care poate fi interpretat ca adev rat sau
fals (de exemplu 7.14 < 17.2 este o expresie adev rat , iar 3.5 == 7.8
este fals ).
Utilizarea tipului real
n secven a urm toare de instruc iuni se declar , i se ini ializeaz totodat ,
dou variabile de tip float care vor re ine pre ul, respectiv cantitatea dintr-un
anumit produs vndut ntr-un interval de timp. O a treia variabil , de acela i tip,
este declarat , iar apoi valoarea ei se calculeaz ca produs al primelor dou ,
reprezentnd suma total ncasat .
float pret = 4.5, cantitate = 125.75, total;
total = pret * cantitate;

3.2.3 Tipul caracter


Aceast categorie de date constituie mul imea tuturor caracterelor posibile. Ele
se pot reprezenta pe 8 bi i, cu sau f r semn, prin intermediul a dou tipuri de
date (unsigned char i char sau signed char) ale c ror propriet i
sunt descrise n tabelul 3.1.3.
Pe cei 8 bi i disponibili se pot codifica 256 de caractere. Toate caracterele sunt
convertite la numere ntregi conform codului ASCII (American Standard Code
for Information Interchange). n anexa 1 se reg sesc cteva dintre aceste caractere, mpreun cu codurile ASCII asociate.
Utilizarea tipului caracter
Pentru a exemplifica felul n care se poate lucra cu caracterele ntr-un program C, se declar i se ini ializeaz cteva caractere.
char c1 = 'A';
char c2 = '7';
Aceste caractere pot fi supuse unor opera ii standard:
44

3 Date i tipuri de date


char c3;
c3 = c1 + c2;
n urma execut rii opera iei de adunare, variabila c3 va avea valoarea 'x'
deoarece se adun de fapt codurile ASCII asociate variabilelor c1 i c2.
Asupra caracterelor se pot aplica i operatori rela ionali. Astfel, 'D'<'b' e
o evaluare al c rei rezultat este adev rat, iar '8'<'6' e fals. Asta pentru c se
compar codurile ASCII asociate caracterelor respective.

3.2.4 Tipul logic


n limbajul C nu exist un tip de dat standard dedicat informa iilor cu caracter
logic, a a cum exist tipul boolean n limbaje precum Pascal sau Java. Pentru a
reprezenta valoarea de adev r a unei expresii sau orice element cu caracter logic
n limbajul de programare C se vor folosi valori numerice. Astfel, zero nseamn fals i orice altceva nseamn adev rat.
Asupra elementelor de tip logic se pot aplica operatori rela ionali (==, <, >, <=,
>=, !=), rezultatul fiind tot de tip logic. De asemenea, operatorii logici ( i, sau,
nega ie) se pot aplica asupra datelor cu caracter logic.
Utilizarea tipului logic
Se consider o variabil x, de tip ntreg. La un moment dat, pe parcursul
execu iei unui program, trebuie verificat dac x este un num r par. Un num r
este par dac el este divizibil cu 2, adic dac restul mp r irii la 2 este 0. Pentru
a verifica acest lucru se folose te operatorul % (modulo). Expresia x%2==0 va
avea valoarea adev rat dac i numai dac x este par. Rezultatul acestei
expresii este a adar o valoare logic .
Fie dou variabile x i y de tip ntreg. Se dore te scrierea unei expresii care
s aib valoarea adev rat dac i numai dac cel pu in una dintre cele dou
variabile are valoare strict pozitiv . Respectiva expresie va ar ta astfel:
(x>0)||(y>0).
Variabila nota de tip float nregistreaz nota ob inut de un student la un
anumit examen. Pentru a verifica dac acea not se afl n intervalul (8; 10] se
va scrie expresia (nota>8)&&(nota<=10).

45

Programarea calculatoarelor

3.2.5 Tipul void


Acesta nu este chiar un tip de dat sau poate fi considerat un tip de dat vid,
care nu are un domeniu de valori. Din punct de vedere sintactic el e situat acolo
unde, n mod normal, este a teptat un tip de dat . Void este folosit pentru a
specifica faptul c o func ie nu returneaz nimic (de exemplu void
funtie1(int x)). De asemenea el poate ap rea i ca unic argument n
prototipul unei func ii ar tnd astfel c func ia nu prime te niciun argument (de
exemplu float functie2(void)).

3.2.6 Conversia de tip


Exist situa ii n care e nevoie ca tipul unei entit i s fie schimbat (de obicei
pentru a beneficia de avantajele oferite de anumite propriet i ale tipurilor).
Acest lucru se poate realiza prin intermediul unei conversii de tip. Exist dou
astfel de conversii implicit i explicit [BK03], [HS98].
Conversia implicit se realizeaz n mod automat de c tre compilator i este
necesar atunci cnd ntr-o expresie apar date de tipuri diferite. Aceast conversie are dou direc ii.
Pe de o parte conversia presupune modificarea unui tip de dat ntr-unul care l
include pe cel ini ial, a a cum se ntmpl n exemplul urm tor. Variabila b, de
tip int este convertit la float, iar rezultatul ob inut este x = 9.47.
float a = 2.47, x;
int b = 7;
x = a + b;
n acest caz, la evaluarea expresiei s-a c utat tipul cel mai cuprinz tor. Toate
elementele expresiei au fost convertite la acest tip. Ordinea tipurilor de date,
ncepnd cu cel mai cuprinz tor este: double, float, long, int, char
[CH96].
Pe de alt parte, dac este vorba de o instruc iune de atribuire, datele surs vor
fi for ate la tipul destina iei [CH96], chiar dac acest lucru duce la trunchierea
informa iei. Exemplul precedent a fost modificat, considerndu-se rezultatul x
de tip ntreg. Drept consecin , toate datele din partea dreapt a semnului egal
sunt for ate s devin variabile ntregi, rezultatul fiind x = 9.
float a = 2.47;
int b = 7, x;
46

3 Date i tipuri de date


x = a + b;
Conversia explicit este introdus clar n cadrul programului prin intermediul
unui modificator de tip. Acesta este un operator unar care apare sub forma unui
prefix la o variabil sau la o expresie i prin care se for eaz transformarea
informa iei respective la tipul specificat. Forma general de realizare a conversiei explicite este:
(tip)expresie;
Utilizarea unei astfel de conversii n cadrul unui program este foarte simpl . De
exemplu, se consider o variabil a de tip int care memoreaz codul ASCII al
unui caracter. O variabil x de tip char va re ine caracterul asociat codului
ASCII specificat, transformnd con inutul variabilei a din int n char.
int a=65;
char x;
x=(char)a;

3.3 Probleme propuse


A. Specifica i unde este gre eala.
1. const int alfa=2;
int beta=3;
alfa=beta+10;
2. int a=7, double=2, x;
x=double*a;
3. unsigned int a=22, b=35;
x=a+b;
4. unsigned int x=12, y=-15, q;
q=x-y;
5. float a=2, b=-3;
x=-a/b;
float x, y;
y=2*x+a-b;
6. int x=1, y=2, z=3, e;
e=x+2y-z;
47

Programarea calculatoarelor
7. float x=7.5, y;
y=x%2;
8. float 1_nota, 2_nota, final_nota;
final_nota=(2*1_nota+2_nota)/final_nota;
B. Fiind date defini iile int a=3, b=4;, evalua i urm toarele expresii i
men iona i care este rezultatul.
9. E=a/5+1;
10. E=(a++)-(a%2);
11. E=(a++)-(--b);
12. E=(-a)-(--a);
13. E=(a==b);
14. E=(a+b)%4;
15. E=(((--b)+a)++)%2;
C. Alege i r spunsul corect (unul singur).
16. Care dintre urm toarele tipuri nu exist n limbajul de programare C?
a) int; b) float;
le sunt gre ite.

c) double;

d) char;

e) toate r spunsuri-

17. Care dintre urm toarele declara ii de variabile este gre it ?


a) float nota_unu;
b) float nota unu;
c) float
notaunu; d) toate declara iile sunt corecte; e) toate declara iile
sunt gre ite.
18. Ce valoare are expresia E=((2+4)*3-1)*(3-5)?
a) -34;

b) 0;

c) -24;

d) 24;

e) expresia con ine o gre eal .

19. Ce valoare va avea variabila x dup executarea urm toarei secven e de


instruc iuni?
int a=65, x;
x=a/2;
a) 32.5;

b) 1;

c) 32;

d) 65;

e) toate r spunsurile sunt gre ite.

20. Ce valoare are expresia E = 2*(7-(9+5)+4*(21-19)?


48

3 Date i tipuri de date


a) 8;

b) -6;

c) -12;

d) 2;

e) expresia con ine o gre eal .

21. Ce valoare va avea variabila m dup executarea urm toarelor linii de


cod?
double a=7, m;
m=a%2;
a) 3.5;

b) 1;

c) 14;

d) 49;

e) atribuirea m=a%2 este imposibil .

22. Care dintre urm toarele expresii este adev rat dac x=1 i y=3?
a) (x>=0)&&(y<3);
b) (x>=0)||(y<3);
c) ((x==0)||
(y!=3))&&(x!=y); d) (x==y)||(y<=0); e) toate expresiile
sunt false.
23. Care dintre urm toarele declara ii de variabile este corect ?
a) int n1#;
b) int #n1;
c) int n1_#;
#_n1; e) toate declara iile sunt gre ite.

d) int

24. Care dintre urm toarele cuvinte nu reprezint nume de modificatori n


limbajul de programare C?
a) short; b) long;
r spunsurile sunt gre ite.

c) signed;

d) unsigned;

e) toate

25. Care dintre urm toarele tipuri nu exist n limbajul de programare C?


a) int; b) float;
rile sunt gre ite.

c) boolean;

d) char;

e) toate r spunsu-

26. C i bi i formeaz un octet?


a) 1;

b) 2;

c) 4;

d) 8;

e) un octet nu este alc tuit din bi i.

27. Ce valoare va avea variabila x dup executarea urm toarelor instruc iuni?
float a=3.1415;
int x=0;
x=(int)a;
a) 3; b) 3.14;
imposibil .

c) 3.1415;

d) 0;

e) atribuirea x=(int)a este

28. Care dintre urm toarele expresii este fals dac a=1, b=-3 i c=7?
49

Programarea calculatoarelor
a) !((a+b+c)<0); b) !((a<b)||(b>c)); c) ((a+b)>c)||
((a!=0)&&(b!=0)); d) !(a>b); e) toate expresiile sunt adev rate.
29. Care dintre urm toarele tipuri nu exist n limbajul de programare C?
a) int; b) float;
surile sunt gre ite.

c) string;

50

d) double;

e) toate r spun-

Capitolul 4 Un prim program C


4.1 Etapele realiz rii unui program C
Un program este o list de instruc iuni care descriu calculatorului ceea ce trebuie s fac . Practic programul reprezint transcrierea unui algoritm cu ajutorul
c ruia se rezolv o anumit problem . Instruc iunile componente ale unui program se pot referi la: citirea informa iilor de la tastatur sau dintr-un fi ier,
afi area informa iilor pe ecran sau ntr-un fi ier, executarea unor opera ii aritmetico-logice, compararea unor entit i.
Realizarea unui program ncepe cu scrierea ( i evident salvarea) acestuia utiliznd un editor de texte. Se ob ine astfel un fi ier surs care va avea extensia .c
(de exemplu program.c). Codul surs ns nu are niciun sens pentru calculator. El trebuie supus n continuare ctorva transform ri.
Astfel, urm torul pas n realizarea unui program este compilarea fi ierului
surs , adic traducerea programului din limbajul de programare n care a fost
scris de utilizator (C, n cazul de fa ) n limbajul ma inii numit calculator,
altfel spus n cod-ma in [NR01]. Acest proces este realizat cu ajutorul unui
compilator. n cazul n care programul are erori, ele vor fi afi ate i trebuie
corectate. Este eviden iat linia de program n care apare eroarea, iar un scurt
mesaj indic posibila cauz a erorii. n urma compil rii cu succes a programului
se ob ine fi ierul obiect un fi ier care are acela i nume ca fi ierul surs , dar
extensia .obj (de exemplu program.obj).
Urmeaz faza de link-editare realizat cu ajutorul editoarelor de leg turi. Acestea au rolul de a interconecta codul obiect creat anterior cu coduri obiect ale
programelor de bibliotec , ale driver-elor de intrare-ie ire i/sau ale programelor aferente sistemului de operare [NR01]. Rezultatul este crearea unui nou
fi ier, numit fi ier executabil. Acesta are acela i nume ca fi ierul surs , dar
extensia .exe (de exemplu program.exe). Fi ierul executabil poate fi rulat,
ob inndu-se astfel rezultatele pentru care programul a fost creat.
Figura 4.1.1 eviden iaz grafic pa ii care trebuie parcur i n procesul de realizare a unui program C, de la scrierea acestuia, pn la ob inerea rezultatelor. Se
observ c fi ierul surs reprezint de fapt datele de intrare pentru compilator,
iar fi ierul obiect este intrarea editorului de leg turi.

Programarea calculatoarelor

Editare
Fi ier surs
Compilare

Corectare
erori
Afi are erori

DA

exist
erori?

NU

Fi ier obiect
Link-editare
Fi ier executabil
Rulare
Rezultate

Figura 4.1.1 Realizarea unui program C

Dac se dore te executarea repetat a programului este suficient s se ruleze


fi ierul executabil. n cazul n care se fac modific ri asupra codului surs , compilarea i link-editarea programului trebuie reluate nainte ca acesta s poat fi
lansat din nou n execu ie.

4.2 Structura unui program C


Toate programele scrise n C sunt alc tuite din una sau mai multe func ii. Pentru nceput se va considera un program care con ine o singur func ie i care
afi eaz pe ecran mesajul Acesta este un prim program C. Codul surs este
prezentat n programul 4.2.1.
Programul 4.2.1
#include <stdio.h>
void main(void)
{
printf("Acesta este un prim program C");
}
52

4 Un prim program C
Orice program trebuie s aib un punct de nceput. n cazul limbajului de programare C, execu ia unui program ncepe cu func ia main(). Fiecare program
scris n C trebuie s aib aceast func ie. Altfel, nu se poate determina locul n
care programul ncepe i se va genera o eroare de link-editare.
Att n exteriorul ct i n interiorul func iei main() se afl o serie de alte
elemente eviden iate prin numere n figura 4.2.1 care descrie structura programului prezentat. Acestea au un rol bine definit, unele dintre ele fiind obligatorii
n anumite contexte.
1

#include <stdio.h>
10
4

void main(void)
{

printf("Acesta este un prim program C");

6
}

11
Figura 4.2.1 Structura unui program C

Cu toate c singurul lucru pe care programul din figura 4.2.1 l face este afi area pe ecran a unui simplu mesaj, el are nevoie de diverse instrumente pentru a
ndeplini aceast sarcin . Rolul acestora este descris n cele ce urmeaz .
1. #include
se nume te directiv preprocesor;
specific faptul c al turi de codul surs al programului mai trebuie
luat n considerare i un alt program/fi ier pentru ca aplica ia s funcioneze corespunz tor;
de obicei fi ierele incluse prin aceast directiv sunt biblioteci i conin o serie de func ii care sunt utilizate n program.
53

Programarea calculatoarelor
2. <stdio.h>
numele fi ierului care se dore te a fi inclus;
trebuie ncadrat n paranteze unghiulare (indica ia num rul 10 din figura 4.2.1);
n acest caz este vorba de biblioteca standard de intrare/ie ire, cea care
con ine func ii utilizate pentru a citi i a scrie datele; programul de faare nevoie de includerea acestui fi ier deoarece trebuie s afi eze un
text pe ecran (afi area se face cu ajutorul unei func ii care este descris n aceast bibliotec ).
3. main
este numele unei func ii;
n cazul de fa este numele func ie main(), dar poate fi vorba de
orice alt func ie.
4. void sau denumirea unui tip de dat scris n fa a numelui func iei
reprezint tipul func iei, mai precis, tipul valorii pe care func ia o returneaz ;
func ia main() din exemplul prezentat nu returneaz nimic, motiv
pentru care n fa a numelui s u apare cuvntul void; a a cum s-a ar tat n capitolul dedicat tipurilor de date, void poate fi considerat un
tip de dat vid;
aten ie: dac nu se scrie nimic n fa a numelui unei func ii, unele
compilatoare consider c func ia trebuie s returneze o valoare de tip
ntreg.
5. (void) sau o list de variabile separate prin virgul
tipul s u

i fiecare precedat de

lista de argumente pe care func ia le prime te;


se scriu n paranteze rotunde, dup numele func iei, a a cum se observ i prin indica ia num rul 11 din figura 4.2.1;
dac func ia nu are argumente (a a cum este cazul de fa ), atunci cuvntul void va fi utilizat pentru a specifica acest lucru n locul n care func ia este descris .
6. { i }
54

4 Un prim program C
acoladele marcheaz nceputul i sfr itul unei func ii sau al unui bloc
de instruc iuni;
de fiecare dat cnd un num r de instruc iuni trebuie executate mpreun , se vor folosi acoladele ca elemente de grupare.
7. reprezint apelul unei func ii
prin intermediul acestui apel se specific ce trebuie s execute programul n acel moment;
n cazul de fa , func ia printf() apelat va afi a un mesaj pe ecran
(detalii despre aceast func ie se afl n capitolul dedicat func iilor de
intrare/ie ire din cadrul func iilor de bibliotec ).
8. lista argumentelor cu care o func ie este apelat
n cazul n care func ia are argumente, acestea trebuie transmise atunci
cnd func ia este apelat ;
argumentele sunt separate prin virgul (dac sunt mai multe) i sunt
ncadrate n paranteze rotunde;
parantezele rotunde trebuie s apar chiar dac func ia nu are argumente;
n exemplu prezentat func ia printf() prime te ca argument un ir
de caractere delimitat prin ghilimele.
9. semnul punct i virgul ;
fiecare instruc iune n C se ncheie cu punct i virgul ;
este semnul utilizat pentru a delimita instruc iunile (cu ajutorul lui
compilatorul va ti unde se ncheie o instruc iune i unde ncepe alta);
chiar dac func ia main() considerat aici are o singur instruc iune
(apelul func iei printf()), totu i delimitatorul punct i virgul este
necesar la sfr itul acestei instruc iuni;
se observ n exemplu c linia care con ine nceputul func iei
main() nu are punct i virgul ; acest lucru se datoreaz faptului c
instruc iunea nu se ncheie pe aceast linie, ci pe ultima linie a programului, acolo unde apare acolada nchis ;
pe de alt parte dup acolad nu este necesar semnul punct i virgul
deoarece acolada este doar un caracter de grupare i nu face nimic
singur [GP00].
55

Programarea calculatoarelor
A a cum se poate observa n exemplul din figura 4.2.1, ntr-un program C pot
ap rea trei tipuri de paranteze [GP00]: paranteze unghiulare <> (marcate cu
num rul 10), acolade {} (marcate cu num rul 6) i paranteze rotunde () (marcate cu num rul 11). Parantezele drepte [] sunt de asemenea utilizate (a a cum
se va vedea n unele din capitolele urm toare). Acestea trebuie bine n elese i
utilizate corect. n unele cazuri utilizarea lor incorect duce la apari ia unor
erori de compilare care ofer posibilitatea corect rii programului. n alte situa ii
compilatorul nu semnaleaz o eroare (chiar dac aceste simboluri nu sunt plasate corespunz tor cu ceea ce fluxul de instruc iuni trebuie s execute), ns programul nu va produce rezultate corecte.
Comentarii n C
ntr-un program C pot fi introduse i comentarii. Acestea sunt texte scrise n
limbaj natural, utilizate de programator pentru a marca anumite sec iuni ale
programului sau pentru a da unele explica ii, astfel nct codul scris s fie ct
mai clar. Comentariile sunt marcate corespunz tor i sunt ignorate de compilator, ele nefiind luate n considerare atunci cnd programul este rulat.
Limbajul de programare C ofer posibilitatea introducerii a dou tipuri de comentarii:
comentariu pentru o singur linie este marcat de dou linii oblice (de tip
slash) // care trebuie plasate la nceputul liniei;
comentariu pentru un grup de linii ncepe cu marcajul /* i se ncheie cu
marcajul */.
n programul considerat anterior se introduc cteva comentarii pentru a exemplifica utilizarea acestora. Rezult astfel programul 4.2.2.
Programul 4.2.2
#include <stdio.h> //biblioteca de intrare/iesire
void main(void)
{
/*Urmatoarea
functie
este
utilizata
pentru
afisarea unui mesaj pe ecran. Ea primeste ca argument textul mesajului.*/
printf("Acesta este un prim program C");
}
56

4 Un prim program C

4.3 Posibile erori


Atunci cnd un program este compilat i link-editat e posibil s apar erori dac
el nu este realizat n acord cu regulile program rii n limbajul C. Mesajele de
eroare afi ate sunt de cele mai multe ori clare i ajut la depistarea i nl turarea
gre elilor. n continuare sunt prezentate cteva dintre cele mai frecvente erori.
Function 'nume_f' should have a prototype sau Undefined
reference to 'nume_f'. n acest caz compilatorul nu cunoa te func ia
nume_f(). Exist mai multe cauze ale acestui fapt. Dac func ia face parte
dintr-o bibliotec , atunci probabil s-a omis specificarea bibliotecii printr-o
directiv preprocesor #include. n cazul n care func ia e una definit de
utilizator, atunci e posibil ca ea s nu fi fost nc definit , lucru care trebuie
f cut nainte de a o putea utiliza. n fine, dac niciunul dintre aceste cazuri nu
este adev rat (adic este specificat biblioteca sau este definit func ia), atunci
cauza ar putea fi scrierea gre it a numelui func iei.
Statement missing ; sau Expected ; before 'something'.
Acest mesaj de eroare apare dac lipse te delimitatorul punct i virgul . De
obicei mesajul este asociat cu linia imediat urm toare celei eronate deoarece
compilatorul nu are posibilitatea de a le separa.
Compound statement missing }. Mesajul de eroare se datoreaz lipsei
unei acolade care nchide un bloc de instruc iuni.
Unexpected }. Dac acest mesaj este afi at, atunci o acolad de nchidere
este n plus.
Undefined symbol 'x' sau 'x' undeclared. n acest caz se ncearc
utilizarea unei variabile (x) f r ca ea s fie declarat . A a cum s-a ar tat n
capitolul despre date i tipuri de date, orice variabil trebuie declarat nainte ca
ea s fie folosit . La nceputul programului sau la nceputul func iei trebuie
specificat ce tip are acea variabil .
Undefined symbol _main in module c0.asm sau Undefined
reference to 'WinMain@16'. Aceast eroare apare n faza de linkeditare, nu n cea de compilare i se datoreaz faptului c programul nu are o
func ie main(); fie a fost omis , fie a fost scris gre it. Un program C trebuie
neap rat s aib aceast func ie pentru a putea fi executat.

57

Programarea calculatoarelor

4.4 Probleme propuse


A. Specifica i unde este gre eala.
1. void main(void){
float x,a=2,b=-4;
x=-b/a
}
2. void main(void)
//aceasta functie incrementeaza varsta
int varsta=18;
varsta++;
}
3. void main(void){
/*aceasta functie initializeaza coeficientii
ecuatiei de gradul I si calculeaza valoarea
necunoscutei x
float x,a=2,b=-4;
x=-b/a;
}
4. void main(void){
float x=3,y=4,z=5;
aria=(x*y)/2;
}
B. Se consider urm toarele programe. Specifica i care este valoarea expresiilor calculate.
5. void main(void){
int a, b;
float E1, E2;
a=7; b=2;
E1=a/b;
E2=(float)a/b;
}
6. void main(void){
int a, b, E;
a=7; b=3;
E=a++ + ++b;
}
58

4 Un prim program C
7. void main(void){
int a, b, E;
a=7; b=3;
E=a>b;
}
C. Alege i r spunsul corect (unul singur).
8. Pentru traducerea unui program C n cod-ma in este folosit un:
a) dic ionar;
nist.

b) compilator;

c) copiator;

d) lingvist;

e) ma i-

d) remunerabil;

e) toate

9. Editorul de leg turi creeaz un fi ier:


a) surs ;
b) obiect;
r spunsurile sunt gre ite.

c) executabil;

10. Care func ie trebuie s fie prezent n orice program C?


a) include; b) void(); c) main(); d) r spunsurile a, b i c
sunt corecte; e) toate r spunsurile sunt gre ite.
11. Dac o func ie nu returneaz nimic, ce se va scrie n fa a numelui acelei
func ii?
a) return;

b) void;

c) integer;

d) main;

e) nimic.

12. n C gruparea unor instruc iuni ntr-un bloc se face utiliznd:


a) ( i );

b) [ i ];

c) { i };

d) < i >;

e) begin i end.

13. Care dintre urm toarele marcaje poate fi folosit pentru a introduce un
comentariu ntr-un program C?
a) //;

b) #;

c) ||;

d) &;

e) <!--.

14. Delimitarea instruc iunilor n C se face prin:


a) ;; b) :; c) .; d) ,; e) nu e nevoie de un delimitator, fiind
suficient scrierea instruc iunilor pe rnduri diferite.
15. Un fi ier surs C are extensia:
a) .src;

b) .obj;

c) .exe;

d) .c;

e) .txt.

D. R spunde i urm toarelor cerin e:


16. Scrie i, compila i i rula i programul 4.2.1. Apoi modifica i-l dup cum
urmeaz :
59

Programarea calculatoarelor
schimba i mesajul pe care l afi eaz ;
determina i-l s returneze o valoare ntreag ;
verifica i ce se ntmpl dac prima linie (cea cu directiva #include) este omis ;
ncerca i s declara i o variabil cu numele while, compila i
programul i observa i mesajul de eroare; modifica i numele variabilei n void sau float, compila i din nou i observa i
mesajul de eroare.
17. Crea i un nou program care:
declar i ini ializeaz trei variabile a, b i c;
declar o variabil de tip float, numit medie;
calculeaz media aritmetic a variabilelor ntregi ini ializate anterior i o stocheaz n variabila medie.
18. Folosind operatorul condi ional cond?mesaj1:mesaj2 verifica i
dac o variabil de tip ntreg (declarat i ini ializat la nceputul programului) este par sau impar . Se va afi a un mesaj adecvat fiec rui
caz, utiliznd func ia printf().
19. Un student prime te dou note: una pentru examen (nota_e) i una
pentru laborator (nota_l). Nota final , care este
, poate fi
calculat doar dac att nota_e ct i nota_l sunt mai mari sau egale
cu 5. Crea i un program care, utiliznd operatorul condi ional, informeaz utilizatorul dac studentul a promovat sau nu.

60

Capitolul 5 Func ii de bibliotec


Limbajul de programare C este un limbaj foarte simplu. El are la dispozi ie doar
cteva instruc iuni prin intermediul c rora se pot rezolva diverse probleme. ns
aceste instruc iuni nu sunt ntotdeauna suficiente. Limbajul C nu asigur de
exemplu nicio modalitate de a citi informa ii de la tastatur sau dintr-un fi ier,
de a le afi a pe ecran sau de a le scrie ntr-un fi ier, de a prelucra iruri de caractere, de a lucra cu func ii matematice i a a mai departe. Din acest motiv, toate
compilatoarele de C includ i o bibliotec standard de func ii care implementeaz cele mai des utilizate sarcini. Aceast bibliotec este alc tuit din mai multe
fi iere antet (header) care grupeaz anumite categorii de func ii. Programatorul
poate face apel la oricare func ie de bibliotec ; este ns obligat ca la nceputul
programului, ntr-o directiv #include, s men ioneze numele fi ierului antet
care con ine func ia utilizat .
n subcapitolele urm toare vor fi descrise cteva dintre cele mai utilizate func ii
de bibliotec [BH92], [SL12]. Acestea sunt grupate pe cteva categorii, raportat
la domeniul n care se folosesc.

5.1 Func ii pentru citire/scriere


Acest paragraf prezint func ii utilizate pentru a citi informa ii de la tastatur i
pentru a le afi a pe ecran. Valorile vehiculate pot fi caractere, iruri de caractere sau numere de orice tip. Descrierea ncepe cu func ii de afi are (putchar,
puts, printf) i continu cu func ii de citire (getchar, gets, scanf).
5.1.1 int putchar(int caracter);
Func ia afi eaz pe ecran caracterul primit ca argument. Dac scrierea se realizeaz cu succes, func ia returneaz caracterul scris; altfel, se va returna constanta EOF (end-of-file). Fi ierul antet care con ine aceast func ie este stdio.h.
Programul 5.1.1 afi eaz pe ecran caracterul A. Se observ specificarea fi ierului antet necesar pentru func ia putchar().
Programul 5.1.1
#include <stdio.h>
void main(void){
putchar('A');

Programarea calculatoarelor
}
Un al doilea exemplu de program (5.1.2) transmite func iei putchar() ca
argument o variabil de tip caracter. Aceasta este declarat i ini ializat , iar
apoi afi at pe ecran.
Programul 5.1.2
#include <stdio.h>
void main(void){
char var;
var='A';
putchar(var);
}
Pentru afi area unui caracter pe ecran se poate folosi i func ia int
putch(int c) din fi ierul antet conio.h. Dac afi area se face cu succes,
func ia returneaz caracterul afi at, altfel returneaz EOF. Exemplul de program
5.1.3 utilizeaz aceast func ie pentru afi area caracterului A.
Programul 5.1.3
#include <conio.h>
void main(void){
putch('A');
}
5.1.2 int puts(const char *s);
n urma apelului acestei func ii, se afi eaz pe ecran irul de caractere s primit
ca argument i se pozi ioneaz cursorul pe linia urm toare. Dac execu ia funciei se realizeaz cu succes, se va returna o valoare ne-negativ ; n caz contrar,
valoarea returnat este EOF. Func ia face parte din fi ierul antet stdio.h.
n programul 5.1.4 func ia puts() prime te ca argument direct irul care
trebuie afi at. Exist i posibilitatea ca func iei s i se trimit o variabil de tip
ir de caractere declarat anterior.
Programul 5.1.4
#include <stdio.h>
void main(void){
62

5 Func ii de bibliotec
puts("Acesta este un curs de programare.");
}
5.1.3 int printf(const char* format [, argument, ...]);
Func ia este utilizat atunci cnd e necesar o tip rire formatat . Fi ierul antet
care trebuie inclus este stdio.h. Func ia returneaz num rul de caractere
tip rite n caz de succes sau o valoare negativ dac apare o eroare.
ntr-o form foarte simpl , aceast func ie poate fi folosit pentru a tip ri pe
ecran un text, caz n care lista de argumente [, argument, ...] lipse te,
iar irul de caractere format con ine doar textul care trebuie scris. Programul
5.1.5 arat aceast modalitate de utilizare a func iei printf().
Programul 5.1.5
#include <stdio.h>
void main(void){
printf("Limbajul de programare C este util.");
}
Func ia printf() ns i dovede te calit ile atunci cnd este utilizat pentru
a tip ri pe ecran valori formatate. Aceast func ie accept o serie de argumente
(variabile sau constante) c rora li se aplic un anumit format specificat printr-un
ir de caractere. Argumentele formatate sunt apoi afi ate pe ecran.
irul de caractere format poate con ine:
text simplu care este afi at ca atare;
semnul special % urmat de un descriptor de format care, la rndul s u, poate
con ine:
o semnul minus (-) care determin ca elementele tip rite s fie
aliniate la stnga (implicit alinierea este la dreapta);
o semnul plus (+) care for eaz afi area semnului plus sau minus
n fa a unui num r, chiar dac num rul este pozitiv (implicit,
semnul este afi at doar pentru numere negative);
o un num r prin care se precizeaz lungimea minim a cmpului n
care se face afi area;

63

Programarea calculatoarelor
o un punct (.) care separ lungimea cmpului de precizia cu care
se face afi area;
o un num r prin care se specific precizia (num rul de zecimale
care vor fi afi ate);
o specificatorul de conversie un caracter prin care se indic ce tip
va avea argumentul afi at; cei mai utiliza i specificatori de conversie sunt:
c caracter;
s ir de caractere;
d, i ntreg cu semn;
u ntreg f r semn;
f num r n virgul mobil (float, double).
o exemplu: %c tip re te un caracter, %d tip re te un num r ntreg,
%5.2f tip re te un num r real pe cel pu in 5 caractere dintre care dou caractere sunt dedicate p r ii zecimale, %-15s tip re te
pe minim 15 caractere un ir aliniat la stnga.
semnul special \ urmat de:
o un caracter prin care se specific locul unde se va face urm toarea afi are:
\b deplaseaz punctul de afi are cu un caracter n urm , tergnd-ul;
\n urm toarea afi are se va face pe o linie nou ;
\t deplaseaz punctul de afi are peste un spa iu de tabulare orizontal (tab).
o un caracter care nu poate fi tip rit altfel:
\\ tip re te caracterul backslash (\);
\ tip re te un apostrof;
\" tip re te ghilimele.
Programul din exemplu 5.1.6 apeleaz func ia printf() pentru a tip ri valoarea variabilei v, declarat i ini ializat anterior. Dup rularea programului, pe
64

5 Func ii de bibliotec
ecran se va afi a textul Eu am 17 ani. Se observ c valoarea variabilei v a
fost introdus n text, acolo unde apare descriptorul de format %d.
Programul 5.1.6
#include <stdio.h>
void main(void){
int v=17;
printf("Eu am %d ani.", v);
}
Func ia printf() permite i utilizarea unor expresii ca argumente. Exemplul
5.1.7 afi eaz suma a dou numere, sum care este calculat la apelul func iei
printf(). Rezultatul adun rii este un num r real (float), afi at cu o precizie de dou zecimale. Aceste caracteristici sunt specificate prin descriptorul de
format %.2f. n urma execu iei programului, pe ecran va ap rea textul Suma
numerelor este: 7.50.
Programul 5.1.7
#include <stdio.h>
void main(void){
float x=3.5, y=4;
printf("Suma numerelor este: %.2f.", x+y);
}
Prin intermediul func iei printf() se pot tip ri mai multe argumente, a a
cum se arat n exemplul 5.1.8. Textul afi at n urma execu iei programului este
Studentul are 177 cm i 80.7 kg. Trunchierea valorii greut ii se
face datorit specifica iei din descriptorul de format %.1f.
Programul 5.1.8
#include <stdio.h>
void main(void){
int h=177;
float g=80.73;
printf("Studentul are %d cm
}

i %.1f kg.", h,g);

A a cum s-a precizat, func ia printf() permite specificarea locului n care se


face urm toarea tip rire. Programul 5.1.9 arat cum se scrie un text pe o linie
nou .
65

Programarea calculatoarelor
Programul 5.1.9
#include <stdio.h>
void main(void){
int m=7, p=3;
printf("Ana are:\n\t%d mere\n\t%d pere", m, p);
printf("\nIn total sunt %d fructe.", m+p);
}
Caracterele \n au fost utilizate pentru a trece cursorul pe linie nou , loc n
care se continu scrierea textului. Pentru deplasarea textului mai la dreapta (tab)
s-au folosit caracterele \t. Atunci cnd programul este rulat, pe ecran se va
afi a:
Ana are:
7 mere
3 pere
In total sunt 10 fructe.
5.1.4 int getchar(void);
Func ia cite te un caracter de la tastatur i returneaz acel caracter dup ce l
converte te la un ntreg f r semn. n caz de eroare se returneaz EOF. Fi ierul
antet care con ine aceast func ie este stdio.h.
n exemplul 5.1.10 se cite te, utiliznd func ia getchar(), un caracter de la
tastatur . Acesta este salvat n variabila c i apoi este tip rit pe ecran cu ajutorul
func iei printf(). La rularea programului se afi eaz pe ecran textul
Introduceti un caracter i se a teapt ca utilizatorul s tasteze acel
caracter. Dac se introduce, de exemplu, caracterul a, programul va afi a n
continuare mesajul Caracterul citit este: a.
Programul 5.1.10
#include <stdio.h>
void main(void){
int c;
printf("Introduceti un caracter ");
c=getchar();
printf("Caracterul citit este: %c.", c);
}
66

5 Func ii de bibliotec
Tot pentru citirea unui caracter de la tastatur se poate folosi i func ia int
getch(void) din fi ierul antet conio.h. Aceasta returneaz caracterul
citit. Deseori func ia getch() este utilizat pentru a determina programul s
a tepte ap sarea unei taste (practic se introduce o pauz n execu ia programului, pauz care se ncheie n momentul n care utilizatorul apas o tast ). Caracterul citit nu e folosit n program, ns acest artificiu este util atunci cnd informa iile afi ate trebuie vizualizate nainte de a fi terse sau nainte ca programul
s - i ncheie execu ia.
Exemplu de program 5.1.11 afi eaz un simplu text pe ecran i apoi apeleaz
func ia getch() astfel nct execu ia programului s nu se ncheie imediat
dup afi are, ci doar atunci cnd utilizatorul specific acest lucru prin ap sarea
unei taste. Se observ c acest program are nevoie de dou fi iere antet:
stdio.h pentru func ia printf() i conio.h pentru func ia getch().
Programul 5.1.11
#include <stdio.h>
#include <conio.h>
void main(void){
printf("Apasati o tasta pentru a continua.");
getch();
}
5.1.5 char *gets(char *s);
Func ia cite te un ir de caractere de la tastatur i se afl n fi ierul antet
stdio.h. Citirea include spa iile i tab-urile i se ncheie cnd apare o linie
nou (ENTER). n caz de eroare func ia returneaz EOF.
Exemplu 5.1.12 arat cum poate fi utilizat aceast func ie. La nceputul programului se define te un ir de 100 de caractere. Mai multe informa ii despre
irurile de caractere se pot afla din capitolul dedicat acestora. Apoi se afi eaz
textul Introduceti sirul de caractere, dup care se a teapt ca
utilizatorul s tasteze secven a de caractere ncheiat de tasta ENTER. Dac se
introduce irul A fost odata, programul va afi a textul Sirul introdus este: A fost odata.
Programul 5.1.12
#include <stdio.h>
67

Programarea calculatoarelor
void main(void){
char sir[100];
printf("Introduceti sirul de caractere ");
gets(sir);
printf("Sirul introdus este: %s.", sir);
}
5.1.6 int scanf(const char* format [, adres , ...]);
Aceast func ie este utilizat pentru a citi o serie de cmpuri care sunt convertite n acord cu un anumit format i care sunt apoi salvate la adresele de memorie transmise ca argument dup irul de formatare. Pentru fiecare element citit
trebuie s existe un specificator de conversie i o adres pentru stocare. Func ia
se afl n fi ierul antet stdio.h. n caz de succes se returneaz num rul de
cmpuri citite, convertite i memorate. Dac nu are ce s citeasc sau dac
apare o eroare nainte de a putea face citirea, func ia returneaz EOF.
Argumentele func iei sunt, ntr-o oarecare m sur , similare celor de la func ia
printf(). Astfel:
irul de caractere format con ine o serie de caractere de conversie precedate, fiecare dintre ele, de caracterul special %; cele mai utilizate caractere
de conversie sunt:
o c caracter;
o s ir de caractere;
o d, i ntreg cu semn;
o u ntreg f r semn;
o f num r n virgul mobil (float, double).
adresa fiec rui element citit este de fapt numele variabilei n care se
salveaz valoarea citit precedat de operatorul de adresare &(de exemplu:
&nr); n cazul n care variabila este de tip ir, operatorul de adresare poate
lipsi, deoarece adresa primului element al irului este dat chiar de numele
irului.
n programul 5.1.13 se citesc informa ii despre o persoan nume (definit ca ir
de caractere) i vrst . n final, aceste informa ii sunt afi ate pe ecran. Aten ie,
operatorul de adresare nu trebuie s lipseasc dac variabila nu este de tip ir de
68

5 Func ii de bibliotec
caractere; n exemplu de observ c variabila varsta are nevoie de acest
operator atunci cnd se face citirea i stocarea ei n memorie.
Programul 5.1.13
#include <stdio.h>
#include <conio.h>
void main(void){
char nume[100];
int varsta;
printf("Introduceti numele ");
scanf("%s", nume);
printf("Introduceti varsta ");
scanf("%d",&varsta);
printf("%s are %d ani.",nume,varsta);
getch();
}
Dac , de exemplu, informa iile pe care utilizatorul le introduce cnd ruleaz
programul sunt Ana pentru nume i 7 pentru vrst , atunci pe ecran va ap rea
mesajul Ana are 7 ani. Func ia getch() de la sfr itul programului este
plasat pentru ca dup afi area mesajului s se a tepte ap sarea unei taste nainte ca programul s se ncheie.

5.2 Func ii matematice


Deseori programele scrise pentru rezolvarea unor probleme implic anumite
func ii matematice. Biblioteca standard a limbajului de programare C con ine
implement ri pentru cele mai utilizate func ii din matematic , grupate n fi ierul
antet math.h. n continuare sunt descrise cteva dintre ele.
double exp(double x);
o func ia exponen ial ;
o calculeaz valoarea ex, unde e

2.71828;

double log(double x);


o logaritm natural din x;
o argumentul trebuie s fie strict pozitiv, n caz contrar
generndu-se o eroare de domeniu;
69

Programarea calculatoarelor
double log10(double x);
o logaritm n baz 10 din x, cu x strict pozitiv;
double pow(double x, double y);
o x la puterea y;
double pow10(int x);
o 10 la puterea x;
double sqrt(double x);
o radical (r d cin p trat ) din x;
o func ia este definit pentru numere pozitive; dac x este negativ
se genereaz o eroare de domeniu;
double fabs(double x);
o modul (valoare absolut ) din x;
double sin(double x);
o sinus de x, cu x exprimat n radiani;
double cos(double x);
o cosinus de x, cu x exprimat n radiani;
double tan(double x);
o tangent de x, cu x exprimat n radiani;
Implement ri cu prototip similar exist i pentru func iile arcsinus (asin()),
arccosinus (acos()), arctangent (atan()), sinus hiperbolic (sinh()),
cosinus hiperbolic (cosh()), tangent hiperbolic (tanh()). Acestea primesc
ca argument o valoare de tip double, reprezentnd unghiul exprimat n radiani
i returneaz tot o valoare de tip double.
Tot din biblioteca matematic fac parte dou func ii, floor() i ceil(),
utilizate pentru a determina cel mai mare num r ntreg mai mic sau egal cu
argumentul, respectiv cel mai mic num r ntreg mai mare sau egal cu argumentul. Prototipurile acestor dou func ii sunt specificate n continuare.
double floor(double x);
double ceil(double x);
70

5 Func ii de bibliotec
Cu alte cuvinte floor() realizeaz o rotunjire n jos, iar ceil() o rotunjire
n sus a argumentului. Cele dou func ii returneaz ntregul ca un double. De
exemplu:
floor(6.3)=6
floor(-1.73)=-2
floor(0.5)=0

ceil(6.3)=7
ceil(-1.73)=-1
ceil(0.5)=1

floor(-0.5)=-1

ceil(-0.5)=0

floor(7)=7

ceil(7)=7

Exemplul 5.2.1 arat cum se pot utiliza, ntr-un program, cteva dintre func iile
matematice prezentate n acest paragraf. n cadrul programului se dau valori
unor variabile x i y i apoi se apeleaz o anumit func ie, valoarea returnat de
aceasta fiind tip rit direct sau fiind salvat mai nti ntr-o variabil f.
Se observ utilizarea constantei M_PI pentru func iile trigonometrice. Aceast
constant are valoarea 3.1415 i face parte din biblioteca math.h.
Programul 5.2.1
#include <stdio.h>
#include <conio.h>
#include <math.h>
void main(void){
double x, y, f;
x=3; f=exp(x);
printf("\nexp(%.2f) = %.2f",x,f);
x=2; y=3;
printf("\n%.0f la puterea %.0f=%.0f",x,y,pow(x,y));
x=49;
printf("\nradical din %.1f este %.2f",x,sqrt(x));
x=1.7; f=log(x);
printf("\nln(%.2f) = %.3f",x,f);
x=-7;
printf("\n|%.2f| = %.2f",x,fabs(x));
f=sin(M_PI/6);
printf("\nsinus de 30 de grade este %.2f", f);
getch();
}
n urma rul rii programului, pe ecran sunt afi ate urm toarele rezultate:
71

Programarea calculatoarelor
exp(3.00) = 20.09
2 la puterea 3 = 8
radical din 49.0 este 7.00
ln(1.70) = 0.531
|-7.00| = 7.00
sinus de 30 de grade este 0.50

5.3 Func ii de conversie


Exist situa ii n care, din diferite motive, un num r este reprezentat sub forma
unui ir de caractere. Pentru a putea fi utilizat n opera ii, acest num r trebuie
convertit. Urm toarele dou func ii pot fi utilizate pentru a realiza conversia
unui ir de caractere ntr-un num r ntreg, respectiv real. Acestea sunt declarate
n fi ierul antet stdlib.h.
int atoi(const char *str);
o converte te irul de caractere primit ca argument ntr-o valoare
ntreag ;
o denumirea func iei este o prescurtare de la ASCII to integer;
o func ia returneaz valoarea 0 dac argumentul con ine secven e
nenumerice i nu poate fi convertit.
double atof(const char *str);
o converte te irul str, primit ca argument, ntr-un num r real
(virgul flotant );
o denumirea func iei este o prescurtare de la ASCII to float;
o func ia returneaz 0 dac str este un ir care nu are sens numeric.
Programul 5.3.1 exemplific felul n care aceste dou func ii pot fi utilizate. Se
cite te un ir de la tastatur i se afi eaz num rul ntreg, respectiv real, pe care
irul l reprezint .
Programul 5.3.1
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
72

5 Func ii de bibliotec
void main(void){
char sir[20];
printf("Introduceti sirul: ");
scanf("%s", sir);
printf("Sirul convertit la intreg: %d", atoi(sir));
printf("\nSirul convertit la real: %f", atof(sir));
getch();
}
Atunci cnd programul este rulat, utilizatorului i se cere s introduc un ir de
caractere. Dac , de exemplu, irul citit este 14.7, programul va afi a:
Sirul convertit la intreg: 14
Sirul convertit la real: 14.700000
n cazul n care utilizatorul introduce o valoare nenumeric (de exemplu
abc2,7), atunci rezultatul afi at va fi:
Sirul convertit la intreg: 0
Sirul convertit la real: 0.000000

5.4 Alte func ii


Acest subcapitol prezint cteva func ii foarte utilizate. Ele fac parte din diverse
categorii; din acest motiv au fost grupate aici sub numele alte func ii.
5.4.1 int fflush(FILE *flux);
Func ia este folosit pentru a goli un buffer (o zon temporar de memorie care
stocheaz date). Golirea acestei zone permite stocarea altor date. Este ntlnit
al turi de opera ii de intrare/ie ire (care se execut mult mai lent dect celelalte
opera ii, motiv pentru care sunt uneori amnate), atunci cnd se dore te for area
execut rii acestor opera ii. Func ia returneaz valoarea 0, dac se execut corect, sau constanta EOF, dac apare o eroare.
Pentru golirea bufferului tastaturii, argumentul este stdin (standard input), iar
pentru ecran argumentul necesar este stdout (standard output). Func ia este
parte a fi ierului antet stdio.h.
Programul 5.4.1 eviden iaz necesitatea folosirii acestei func ii. Se ncearc
citirea a dou caractere; al doilea apel al func iei scanf() va cauza o func io73

Programarea calculatoarelor
nare eronat a programului dac nu se gole te bufferul tastaturii ntre cele dou
apeluri.
Programul 5.4.1
#include <stdio.h>
void main(void){
char ch1, ch2;
printf("Primul caracter: ");
scanf("%c", &ch1);
//fflush(stdin);
printf("Al doilea caracter: ");
scanf("%c", &ch2);
printf("S-au citit %c si %c", ch1, ch2);
}
Apelul func iei fflush() ntre cele dou citiri for eaz executarea primei
citiri n acel moment (ea ar putea fi altfel amnat pn cnd programul are
nevoie de informa ia citit ) i asigur golirea bufferului tastaturii. Astfel, cea de
a doua citire se poate executa f r riscuri.
5.4.2 int rand(void);
Prin utilizarea func iei rand() se poate genera un num r aleatoriu, de tip
ntreg, cuprins ntre 0 i RAND_MAX. Constanta RAND_MAX este dependent de
implementare, dar are cel pu in valoarea 32767. Dac se dore te generarea unor
numere ntr-un anumit domeniu, de exemplu 0 99, atunci se va considera
restul mp r irii la 100 a valorii returnate de rand(), a a cum se poate observa i n programul 5.4.2.
Programul 5.4.2
#include <stdio.h>
#include <stdlib.h>
void main(void){
printf("%d",rand()%100);
}
Dac programul este rulat de mai multe ori, se constat c num rul generat este
acela i. n cazul n care acest lucru nu poate fi acceptat ntr-un program, trebuie
mai nti apelat func ia void srand(unsigned seed); cu parametrul
74

5 Func ii de bibliotec
time(0), care ini ializeaz generatorul de numere aleatorii f cnd leg tura cu
ceasul sistemului. Acesta, evident, se modific mereu, astfel nct func ia
rand() apelat ulterior nu va mai porni de la acela i num r. Programul 5.4.3
este un exemplu complet de generare a unui num r aleatoriu.
Programul 5.4.3
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void main(void){
srand(time(0));
printf("%d",rand()%100);
}
Func iile rand() i srand() se g sesc n fi ierul antet stdlib.h, iar
func ia time() este parte a fi ierului time.h.
5.4.3 void exit(int stare);
n momentul n care aceast func ie este apelat , programul se ncheie. Dac
exist alte instruc iuni dup exit(), acestea nu vor mai fi executate. Func ia
nu returneaz nimic i prime te ca argument starea n care se ncheie programul,
stare pe care o transmite procesului apelant (de obicei sistemul de operare).
Uzual, zero indic o ie ire normal din program, iar o valoare diferit de zero
este asociat cu o anumit eroare. Pentru utilizarea func iei este necesar includerea fi ierului antet stdlib.h.
Exemplul 5.4.4 apeleaz func ia exit() pentru a ie i din program dup afi area primului mesaj (Programul se incheie aici.). Instruc iunea care
tip re te cel de al doilea mesaj (Acest mesaj nu va mai fi
afisat.) nu se mai execut .
Programul 5.4.4
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
void main(void){
printf("Programul se incheie aici.");
getch();
75

Programarea calculatoarelor

exit(0);
printf("Acest mesaj nu va mai fi afisat.");

5.5 Probleme propuse


A. Specifica i unde este gre eala.
1. #include <stdio.h>
#include <math.h>
void main(void){
float a=49,x;
x=sqrt(a);
printf("Rezultatul este: ",x);
}
2. void main(void){
int a;
float b,x;
a=7; b=3.54;
x=a+b;
printf("Rezultatul este: %5.2f",x);
}
3. #include <stdio.h>
#include <math.h>
void main(void){
int a,x;
scanf("%d",a);
x=fabs(a);
printf("Modulul este: %d",x);
}
4. #include <stdio.h>
void main(void){
int a,b,x;
scanf("%d",&a); scanf("%d",&b);
x=a+b;
printf("Rezultatul este: " %5d,x);
}
76

5 Func ii de bibliotec
5. #include <stdio.h>
void main(void){
int a;
float b,x;
a=7; b=3.54;
x=a+b;
printf("Rezultatul este: %5.2d",x);
}
6. #include <stdio.h>
void main(void){
int a,b,x;
a=7; b=3;
x=a+b;
printf("Rezultatul este: x=%4.1f",x);
}
7. #include <stdio.h>
#include <math.h>
void main(void){
float a=-49.7,x;
x=sqrt(a);
printf("Rezultatul este: %.2f",x);
}
B. Se consider urm toarele programe. Specifica i ce va fi afi at pe ecran dup
rularea acestora.
8. #include <stdio.h>
void main(void){
float x=39;
printf("%.1f",x/4);
}
9. #include <stdio.h>
void main(void){
int x=19;
printf("Duminica \\ora %d\\\t\"Tosca\"
Giacomo PUCCINI",x);
}
10. #include <stdio.h>
#include <stdlib.h>
77

Programarea calculatoarelor
void main(void){
float x=20, y=5.5;
exit(0);
printf("%.1f/%.1f=%.3f",x,y,x/y);
}
C. Alege i r spunsul corect (unul singur).
11. Care dintre urm toarele func ii este folosit pentru afi are?
a) gets(); b) getch();
e) getchar().

c) printf();

d) scanf();

12. Care dintre urm toarele func ii este o func ie de citire?


a) gets(); b) printf();
e) toate r spunsurile sunt gre ite.

c) prints();

d) #include;

13. Ce liter poate fi utilizat pentru a specifica tipul variabilei tip rite prin
intermediul func iei printf()?
a) d;

b) c;

c) f;

d) s;

e) toate.

14. Care dintre urm toarele func ii este o func ie de ie ire (afi are)?
a) printf();
e) toate.

b) puts();

c) putch();

d) putchar();

15. Ce se ntmpl la executarea func iei scanf("%f",x)?


a) este citit o variabil de tip float; b) este tip rit o variabil de
tip float; c) este scanat o imagine; d) programul se opre te datorit unei erori ap rute la executarea func iei; e) toate r spunsurile sunt
gre ite.
16. Alinierea implicit n cazul tip ririi utiliznd func ia printf() este:
a) la stnga; b) centrat; c) la dreapta; d) egal dep rtat fa
margini (justify); e) toate r spunsurile sunt gre ite.

de

17. Care dintre urm torii descriptori de format (utiliza i n func ia


printf()) sunt gre i i?
a) %-7s;
gre ite.

b) %7.3f;

c) %d;

d) %c;

e) toate r spunsurile sunt

18. Ce fel de variabile se citesc prin apelul func iei scanf("%d%c",


&x,&a);?
78

5 Func ii de bibliotec
a) un num r real i un caracter;
b) un num r ntreg i un caracter;
c) un num r ntreg i un ir de caractere; d) un num r real i un ir
de caractere; e) instruc iunea con ine o eroare.
D. S se scrie programe pentru rezolvarea urm toarelor probleme.
19. Calcularea i afi area sumei a dou numere reale ale c ror valori se citesc de la tastatur .
20. Transformarea dimensiunii unui unghi din grade n radiani (180 = radiani). Se presupune c num rul introdus de utilizator este valid.
21. Utilizarea func iilor matematice sqrt, log, exp, pow, fabs. Se va
verifica i ce se ntmpl pe parcursul execu iei programului dac argumentele nu sunt corecte (de exemplu radical dintr-un num r negativ).
22. Determinarea ultimei cifre a unui num r ntreg.
23. Afi area pe ecran (prin intermediul unei singure instruc iuni) a urm toarelor linii de text:
"Limbajul C" \ Dennis RITCHIE
#1972

79

Capitolul 6 Instruc iuni


A a cum s-a observat n capitolele anterioare, programele C cuprind mai multe
entit i cum ar fi: directive preprocesor, declara ii de variabile sau diverse mecanismele prin care se execut ac iunile pentru care programul este conceput.
Acestea din urm se numesc instruc iuni [HS98], [BH92] i pot fi supuse urm toarei clasific ri:
instruc iuni simple: atribuiri i apeluri de func ii;
instruc iuni compuse:
o asociative: blocurile de instruc iuni; grupeaz dou sau mai multe instruc iuni care au o anumit leg tur n logica de executare a
programului; delimitarea blocurilor de instruc iuni se face prin
acolad deschis { la nceputul blocului i acolad nchis } la
sfr itul blocului;
o alternative: if, switch; sunt instruc iuni utilizate atunci cnd,
dependent de o condi ie, se execut doar anumite ramuri ale programului;
o repetitive: for, while, do while; se folosesc n cazurile n
care una sau mai multe instruc iuni trebuie repetate.
Instruc iunile compuse sunt utilizate pentru a controla modul n care programul
se comport atunci cnd este rulat. n cadrul lor vor fi prezentate i dou modalit i de salt: break i continue.
Numele instruc iunilor reprezint cuvinte cheie n C, adic ele sunt cuvinte
rezervate doar utiliz rii n scopul pentru care au fost create. Nu se pot defini
variabile, constante, tipuri de date sau func ii care s poarte numele acestor
instruc iuni. Lista cuvintelor cheie din limbajul de programare C poate fi consultat n anexa 2.
Instruc iunile sunt componente ale limbajului C. Ele nu fac parte din vreo biblioteca, prin urmare nu trebuie inclus niciun fi ier antet atunci cnd sunt utilizate.

6.1 Instruc iuni simple


n cadrul acestei categorii se nscriu instruc iunile de atribuire i apelurile de
func ii. Ele au fost deja utilizate n programele date ca exemplu n capitolele
precedente, f r ns a se eviden ia c de fapt acestea sunt instruc iuni.

6 Instruc iuni

6.1.1 Instruc iunea de atribuire


Aceasta este o modalitate simpl prin care programul execut o anumit sarcin , dnd valoare unei variabile. Forma general a instruc iunii de atribuire este:
nume_variabil

operator_de_atribuire expresie;

Expresia poate fi o simpl constant sau o entitate mai complex care cuprinde
opera ii aritmetice, logice sau rela ionale. Rezultatul expresiei este convertit la
tipul variabilei din partea stng a atribuirii. Membrul stng al atribuirii, adic
destina ia, locul n care se memoreaz rezultatul atribuirii, trebuie s fie o variabil ; nu poate fi o constant sau un nume de func ie. Operatorul de atribuire
poate fi, la rndul s u, simplu sau compus.
Operatorul de atribuire simplu = face ca variabila din stnga s primeasc
valoarea expresiei din dreapta. n continuare sunt cteva exemple de utilizare a
acestui operator:
x=7;
y=3+4;
delta=b*b-4*a*c;
z=sqrt(x);
Operatorii de atribuire compu i sunt de forma op=, unde op poate fi, printre
altele, +, -, *, /, %. n ceea ce prive te efectul produs de ace ti operatori, instruc iunea
var op= expresie;
este echivalent cu
var = var op expresie;
Despre operatorii de atribuire compu i s-a vorbit pe larg i n capitolul dedicat
datelor i tipurilor de date. Ca exemple de atribuiri care utilizeaz acest tip de
operatori se pot considera urm toarele:
suma+=x; //echivalent cu suma=suma+x;
a*=(3*m+n); //echivalent cu a=a*(3*m+n);
Atribuirile multiple se pot utiliza n C pentru a da aceea i valoare mai multor
variabile prin intermediul aceleia i instruc iuni. n urm torul exemplu se atribuie valoarea zero variabilelor a, b i c:
81

Programarea calculatoarelor
a=b=c=0;

6.1.2 Apelul de func ie


Apelul unei func ii, fie ea func ie de bibliotec sau func ie definit de utilizator,
este considerat de asemenea o instruc iune simpl . La apelul func iei se precizeaz numele acesteia i lista de argumente, iar valoarea returnat de func ie
poate fi utilizat mai departe, a a cum se observ n exemplele care urmeaz :
puts("Acesta este un apel de functie");
printf("Rezultatul este: %.2f", sqrt(x));
y=log(fabs(x));
getch();

6.2 Instruc iuni alternative


Prin intermediul instruc iunilor alternative, programul este structurat pe dou
sau mai multe ramuri, iar secven ele de cod care compun ramurile respective
sunt executate condi ionat. Prin urmare, n func ie de valoarea de adev r a unei
expresii, blocul de instruc iuni de pe o anumit ramur este executat sau nu.
Testul realizat are valoare logic , rezultatul s u putnd fi adev rat sau fals. n
limbajul de programare C, adev rat este echivalent cu orice valoare nenul
(inclusiv numerele negative au, din punct de vedere logic, valoarea adev rat),
iar fals este reprezentat de zero.
Din aceast categorie fac parte instruc iunile if i switch. Ele se mai numesc
i instruc iuni de selec ie i sunt descrise n urm toarele dou subcapitole.

6.2.1 Instruc iunea if


Este cea mai simpl instruc iune alternativ . Ea are dou ramuri i, dependent
de o condi ie, permite executarea uneia din ele. Figura 6.2.1 este o reprezentare
grafic a modului n care instruc iunea if func ioneaz . O anumit expresie
este evaluat ; dac rezultatul este adev rat, se merge pe o ramur , n caz contrar, pe cealalt . Apoi programul continu cu instruc iunile care urmeaz .

82

6 Instruc iuni

fals

EXPRESIE

Bloc de
instruc iuni 2

adev rat

Bloc de
instruc iuni 1

Figura 6.2.1 Instruc iunea if

Forma general a instruc iunii if este:


if(expresie)
//bloc de instructiuni 1
else
//bloc de instructiuni 2
Blocurile de instruc iuni pot con ine una sau mai multe instruc iuni. Dac sunt
mai multe instruc iuni, gruparea lor utiliznd acoladele este obligatorie. n caz
contrar vor ap rea erori la compilare sau func ionarea programului va fi necorespunz toare.
Atunci cnd, pe parcursul execu iei unui program, se ajunge la o instruc iune
if, mai nti este evaluat expresia (care, obligatoriu, trebuie s fie ncadrat de
paranteze rotunde). Dac ea este adev rat (adic se ob ine orice altceva n
afar de zero), se execut blocul de instruc iuni num rul 1 (cel care-i urmeaz
lui if). Altfel (dac evaluarea condi iei este fals , adic zero), se execut blocul de instruc iuni num rul 2 (cel care urmeaz dup else).

83

Programarea calculatoarelor
Expresia pe care instruc iunea if o evalueaz poate fi rela ional , logic sau
aritmetic . Operatorii care pot fi utiliza i n aceste expresii au fost prezenta i n
capitolul dedicat datelor i tipurilor de date. n continuare sunt cteva exemple
care pot constitui expresii evaluate de instruc iunea if.
a>b este adev rat dac a e mai mare dect b;
x==0 este adev rat dac x este zero;
m!=n este adev rat dac m este diferit de n;
(x<y)&&(z!=0) este adev rat dac x este mai mic dect y i dac z este
diferit de zero;
a||b este adev rat dac a este diferit de zero sau dac b este diferit de zero
(cu alte cuvinte dac cel pu in una dintre variabilele a i b e diferit de zero);
a+b este adev rat dac suma numerelor a i b este diferit de zero;
1 este mereu adev rat ;
7 este mereu adev rat ;
-7 este mereu adev rat ;
0 este tot timpul fals .
n programul 6.2.1 se cite te de la tastatur nota unui student. Dac aceasta
este mai mare sau egal cu 5, se afi eaz mesajul Promovat, altfel Nepromovat.
Programul 6.2.1
#include <stdio.h>
void main(void){
int nota;
printf("Nota="); scanf("%d", &nota);
if (nota>=5)
printf("Promovat");
else
printf("Nepromovat");
}
n cazul n care pe ramurile aferente lui if sau else sunt necesare mai multe
instruc iuni, acestea trebuie grupate ntr-un bloc utiliznd acoladele. n exemplul 6.2.2 se citesc de la tastatur nota la examen i nota pe laborator. Dac
84

6 Instruc iuni
ambele sunt mai mari sau egale cu 5, atunci se calculeaz nota final
afi eaz . Altfel, se afi eaz doar un mesaj.

i se

Programul 6.2.2
#include <stdio.h>
void main(void){
float ne, nl, nf;
printf("Nota la examen: "); scanf("%f", &ne);
printf("Nota pe laborator: "); scanf("%f", &nl);
if ((ne>=5)&&(nl>=5)){
printf("Studentul a promovat");
nf=(2*ne+nl)/3;
printf("\nNota finala este: %.2f", nf);
}
else
printf("Studentul nu a promovat");
}
Componenta else a instruc iunii if este op ional , adic se pot scrie instruciuni care nu execut nimic n cazul n care expresia evaluat e fals . Programul
6.2.3 este un astfel de exemplu. Se consider un senzor de temperatur a c rui
valoare e citit de la tastatur i o variabil care determin pornirea instala iei
de aer condi ionat considerat ini ial oprit . Dac temperatura citit dep e te
25 de grade, se afi eaz mesajul Aerul conditionat a fost pornit,
iar variabila pornit este setat corespunz tor. Ramura pentru else lipse te,
motiv pentru care programul nu execut nicio ac iune n cazul n care temperatura este mai mic sau egal cu 25 de grade.
Programul 6.2.3
#include <stdio.h>
void main(void){
int temperatura, pornit=0;
printf("Temperatura=");
scanf("%d", &temperatura);
if (temperatura>25){
printf("Aerul conditionat a fost pornit");
pornit=1;
}
}
85

Programarea calculatoarelor
n interiorul unei instruc iuni if pot fi introduse alte instruc iuni if. Acest
ansamblu poart denumirea de instruc iune if imbricat sau ncuibat (nested
n varianta original ). n programul 6.2.4 se cite te de la tastatur vrsta unei
persoane care dore te s voteze. Prima verificare se face pentru a valida valoarea citit (n cazul n care e o valoare negativ , aceasta nu poate reprezenta
vrsta i este afi at mesajul Valoare incorect ). Dac num rul introdus
este valid, se verific dac persoana are drept de vot, adic dac a mplinit
vrsta de 18 ani.
Programul 6.2.4
#include <stdio.h>
void main(void){
int varsta;
printf("Varsta=");
scanf("%d", &varsta);
if (varsta>0)
if (varsta>=18)
printf("Puteti vota.");
else{
printf("Nu aveti inca drept de vot.\n");
printf("Va asteptam peste %d ani.",18-varsta);
}
else
printf("Valoare incorecta.");
}
O structur des utilizat atunci cnd se fac verific ri n cascad este structura
if-else-if. Este practic vorba despre o instruc iune if introdus pe ramura
de else a unei alte instruc iuni if. Programul 6.2.5 este o exemplificare pentru acest tip de construc ie. n func ie de media studentului citit de la tastatur
se acord o anumit burs . Setarea valorii bursei se face n urma unor teste
executate n cascad .
Programul 6.2.5
#include <stdio.h>
void main(void){
float media, bursa;
printf("Media=");
scanf("%f", &media);
86

6 Instruc iuni

if (media>=9.5)
bursa=1000;
else if (media>=8.5)
bursa=800;
else if (media>=8)
bursa=500;
else
bursa=0;
printf("Bursa este: %f", bursa);

6.2.2 Instruc iunea switch


Este o instruc iune de selec ie cu mai multe ramuri n care valoarea unei expresii (sau pur i simplu a unei variabile) e comparat succesiv cu elementele unei
liste de constante de tip ntreg sau caracter. Cnd valoarea expresiei este identic cu un element din list , instruc iunile de pe acea ramur vor fi executate.
Dac niciun element al listei nu coincide cu valoarea expresiei, atunci se execut o secven de instruc iuni final dedicat situa iilor de acest gen. Figura 6.2.2
este o reprezentare grafic a felului n care instruc iunea switch ac ioneaz .
Forma general a instruc iunii switch este:
switch (variabila){
case constanta1: secventa_de_instructiuni_1; break;
case constanta2: secventa_de_instructiuni_2; break;
...
case constantaN: secventa_de_instructiuni_N; break;
default: secventa_de_instructiuni;
}
Variabila este comparat pe rnd cu fiecare dintre constantele marcate prin
instruc iuni case. n momentul n care se ntlne te o egalitate se execut
secven a de instruc iuni asociat acelei ramuri case pn la ntlnirea instruciunii break sau pn la ncheierea instruc iunii switch. Ramura default
este dedicat situa iilor n care valoarea variabilei nu coincide cu niciuna dintre
constantele luate n considerare. Aceast ramur este op ional ; n cazul n care
87

Programarea calculatoarelor
ea lipse te, iar variabila nu este egal cu nicio constant din list , atunci ntregul
ansamblu switch nu va genera nicio ac iune.

var = val1

adev rat

Secven de
instruc iuni 1

fals
var = val2

adev rat

Secven de
instruc iuni 2

fals

var = valn

adev rat

Secven de
instruc iuni n

fals
Secven de
instruc iuni

Figura 6.2.2 Instruc iunea switch

n ceea ce prive te compara ia care se face ntre variabil i constantele din


list , aceasta nu poate fi orice expresie rela ional ci doar o verificare a egalit ii. Cu alte cuvinte, n switch nu se poate verifica dac o variabil este mai
mic sau mai mare dect o anumit valoare, ci doar dac variabila are exact
acea valoare.
Constantele din list trebuie s fie unice. Nu pot exista mai multe ramuri case
cu aceea i constant . De asemenea constantele trebuie s fie de tip ntreg sau
caracter (care e automat convertit la ntreg).
88

6 Instruc iuni
Instruc iunea break este o instruc iune de salt. Cnd ea e ntlnit n interiorul
unei instruc iuni switch are ca efect executarea unui salt pn la prima instruc iune de dup switch. n cazul n care sunt mai multe instruc iuni imbricate, break va afecta doar instruc iunea switch n care se afl , nu i o posibil alt instruc iune n interiorul c reia s-ar afla instruc iunea switch n
cauz . Cu alte cuvinte break are efect doar asupra nivelului pe care se afl .
De cele mai multe ori instruc iunea switch este folosit pentru a prelucra
op iuni ale utilizatorului atunci cnd e vorba despre selec ii n meniuri. Programul 6.2.6 este un astfel de exemplu. Utilizatorul are la dispozi ie un meniu cu
mai multe opera ii matematice (1 pentru adunare, 2 pentru sc dere, 3 pentru
nmul ire i 4 pentru mp r ire). Introduce valorile pentru variabilele x i y i
apoi tasteaz valoarea asociat op iunii sale. n cadrul unei instruc iuni switch
aceast op iune (care este un num r ntreg) este comparat cu cele 4 valori
posibile. Dac este una dintre ele, atunci se execut opera ia aferent i se afieaz rezultatul, dup care, datorit existen ei instruc iunii break, se sare la
instruc iunea imediat urm toare instruc iunii switch (finalul programului, n
acest caz). Dac utilizatorul introduce un num r diferit de 1, 2, 3 sau 4, atunci
instruc iunea de pe ramura default este executat , afi ndu-se un mesaj de
aten ionare prin care utilizatorul afl c op iunea introdus de el nu exist .
Programul 6.2.6
#include <stdio.h>
void main(void){
int optiune;
float x, y, rez;
printf("x="); scanf("%f",&x);
printf("y="); scanf("%f",&y);
printf("\n1 - Adunare");
printf("\n2 - Scadere");
printf("\n3 - Inmultire");
printf("\n4 - Impartire");
printf("\nIntroduceti optiunea ");
scanf("%d", &optiune);
switch(optiune){
case 1: rez=x+y; printf("\nx+y=%.2f",rez);
case 2: rez=x-y; printf("\nx-y=%.2f",rez);
case 3: rez=x*y; printf("\nx*y=%.2f",rez);
case 4: rez=x/y; printf("\nx/y=%.2f",rez);
89

break;
break;
break;
break;

Programarea calculatoarelor
default: printf("\nOptiune gresita");
}

Instruc iunea break, amplasat la finalul ramurilor case, nu este obligatorie.


Ea ncheie secven a de instruc iuni aferent unei constante. Dac este omis ,
atunci vor fi executate i instruc iunile de pe ramurile urm toare pn la ntlnirea unei instruc iuni break sau pn la ncheierea instruc iunii switch.
Exemplul 6.2.7 reliefeaz acest aspect. Utilizatorul introduce valoarea unei
variabile x de tip ntreg i are posibilitatea s o incrementeze o dat (op iunea 1), s o incrementeze de dou ori (2), s o decrementeze o dat (3) i s o
decrementeze de dou ori (4).
n cadrul instruc iunii switch apare mai nti ramura case aferent op iunii 2, adic dubl incrementare. Pe aceast ramur exist ns o singur instruciune de incrementare. Totu i, rezultatul afi at este cel corect. Acest lucru se
datoreaz lipsei instruc iunii break din aceast secven , motiv pentru care
instruc iunile de pe ramura urm toare (aferent op iunii 1) sunt executate. Este
vorba tot de o incrementare, urmat de break, ceea ce face ca instruc iunea
switch s se ncheie i rezultatul s fie afi at. Dac utilizatorul alege op iunea
1, variabila este incrementat , ramura case respectiv neavnd nimic special.
Op iunile 3 i 4 nu sunt nc implementate i se dore te ca atunci cnd utilizatorul le alege s fie afi at mesajul Operatie neimplementata. n cadrul
ramurii case aferent op iunii 3 nu exist nicio instruc iune (nici m car
break), ceea ce reliefeaz nc un aspect important: acela c o ramur case
poate fi vid . n acest caz vor fi executate instruc iunile de pe ramurile urm toare, adic afi area mesajului referitor la neimplementarea opera iei, mesaj care
va fi afi at i dac utilizatorul alege op iunea 4.
Programul 6.2.7
#include <stdio.h>
void main(void){
int optiune, x;
printf("x="); scanf("%d",&x);
printf("\n1 - O incrementare");
printf("\n2 - Doua incrementari");
printf("\n3 - O decrementare");
printf("\n4 - Doua decrementari");
90

6 Instruc iuni
printf("\nIntroduceti optiunea ");
scanf("%d", &optiune);
switch(optiune){
case 2: x++;
case 1: x++; break;
case 3:
case 4: printf("Operatie neimplementata"); break;
default: printf("\nOptiune gresita");
}
printf("\nx=%d", x);
}
Posibilitatea de a rula mpreun instruc iuni de pe ramuri case diferite atunci
cnd nu sunt prev zute instruc iuni break m re te eficien a programului pentru c se evit dublarea unor linii de cod. Programatorul ns trebuie s acorde o
foarte mare aten ie acestor aspecte. Ele sunt foarte utile, dar pot conduce la
func ion ri necorespunz toare ale programelor dac nu sunt utilizate corect.

6.3 Instruc iuni repetitive


Dac n execu ia unui program este necesar repetarea unui bloc de instruc iuni,
atunci trebuie folosit una din instruc iunile repetitive pe care limbajul le pune
la dispozi ie. Acestea se mai numesc i instruc iuni de itera ie, iar secven a de
cod pe care o repet poart denumirea de bucl . Repetarea secven ei de cod se
face dependent de o anumit condi ie. n limbajul de programare C exist trei
astfel de instruc iuni, for, while i do while, care vor fi descrise n continuare.

6.3.1 Instruc iunea for


Aceast instruc iune repetitiv se utilizeaz pentru a executa o secven de cod
de un num r definit de ori. Primul pas al instruc iunii const ntr-o ini ializare.
Urmeaz apoi evaluarea unei expresii. Dac aceasta e fals , nu se execut blocul de instruc iuni aferent for-ului, programul continundu-se cu instruc iunile
care urmeaz . Dac expresia este adev rat , instruc iunile din bucl sunt rulate.
La sfr itul buclei are loc o ac iune i apoi expresia este evaluat din nou. Figura 6.3.1 reprezint grafic aceste etape.
91

Programarea calculatoarelor

Ini ializare

EXPRESIE

fals

adev rat
Bloc de
instruc iuni

Ac iune

Figura 6.3.1 Instruc iunea for

Forma general a instruc iunii for este:


for(initializare;expresie;actiune)
//bloc de instructiuni
Instruc iunea for are de cele mai multe ori o variabil de control prin intermediul c reia se stabile te de cte ori se repet bucla. Valoarea ini ial a acestei
variabile e precizat printr-o atribuire n primul pas pe care instruc iunea for l
execut : initializarea.
Expresia care este evaluat apoi determin cnd se ncheie repetarea buclei.
Blocul de instruc iuni se va executa n mod repetat atta timp ct expresia este
adev rat (adic rezultatul evalu rii expresiei este diferit de zero).
Actiunea care are loc la sfr itul fiec rei itera ii specific modul n care
variabila de control este modificat pe m sur ce bucla se repet . Cel mai frecvent aici are loc o incrementare, dar i alte tipuri de opera ii sunt posibile.
Cele trei entit i ale instruc iunii for sunt op ionale. n cazul n care expresia
lipse te, se consider c ea este adev rat .
92

6 Instruc iuni
Entit ile trebuie separate prin punct i virgul . Delimitatorul este obligatoriu
chiar dac entit ile nu sunt prezente.
Programul din exemplul 6.3.1 calculeaz suma primelor 100 de numere naturale. Variabila de control i este ini ializat cu valoarea 1, iar bucla se repet pn
cnd i devine mai mare dect 100. La sfr itul fiec rei itera ii valoarea lui i
este incrementat . Deoarece bucla con ine o singur instruc iune (adunarea lui i
la suma par ial ), nu sunt necesare acoladele. La ie irea din for se tip re te
suma. Ini ializarea sumei nainte de prima ei utilizare este obligatorie i se face
cu valoarea 0 (elementul neutru al adun rii). Dac ar fi fost vorba de un produs,
acesta s-ar fi ini ializat cu 1 (elementul neutru al nmul irii).
Programul 6.3.1
#include <stdio.h>
void main(void){
int i,s=0;
for(i=1;i<=100;i++)
s=s+i;
printf("Suma este: %d", s);
}
n exemplul 6.3.2 bucla con ine mai multe instruc iuni, motiv pentru care trebuie folosite acoladele pentru a le delimita. De asemenea, variabila de control i a
suportat cteva modific ri. Se dore te calcularea i afi area n ordine descresc toare a p tratelor numerelor pare mai mici sau egale cu 20 i mai mari dect 0.
Pentru c e vorba de o afi are n ordine descresc toare, variabila de control va fi
ini ializat cu valoarea maxim (adic 20) i va sc dea la fiecare itera ie pn
ajunge la zero. Trebuie luate n calcul doar numerele pare, a a c variabila de
control nu scade cu 1, ci cu 2 (i-=2 este echivalent cu i=i-2).
Programul 6.3.2
#include <stdio.h>
void main(void){
int i,p;
for(i=20;i>0;i-=2){
p=i*i;
printf("%d ", p);
}
}
93

Programarea calculatoarelor
Datorit faptului c n cadrul instruc iunii for expresia este evaluat imediat
dup ini ializarea variabilei de control i nainte ca orice altceva s se execute,
exist posibilitatea ca, n cazul n care expresia este fals de la nceput, blocul
de instruc iuni din cadrul for-ului s nu fie executat niciodat . Programul 6.3.3
este un astfel de exemplu. Se dore te afi area numerelor naturale mai mici dect
un num r n dat. Contorul i porne te de la valoarea 0, se incrementeaz la
fiecare pas, iar condi ia de executare a buclei este ca i s fie strict mai mic
dect n. Datorit faptului c n are tot valoarea 0, condi ia nu este ndeplinit ,
deci bucla nu se execut nici m car o dat . A adar se va executa doar instruc iunea din exteriorul for-ului care afi eaz valoarea final a lui i; aceasta este 0
deoarece nu s-au operat modific ri asupra sa.
Programul 6.3.3
#include <stdio.h>
void main(void){
int i,n;
n=0;
for(i=0;i<n;i++)
printf("%d ",i);
printf("La iesirea din for i are valoarea: %d",i);
}
n cadrul instruc iunii for se pot folosi dou sau mai multe variabile de control. Ini ializ rile i modific rile acestora se vor separa prin virgul . Expresia
evaluat nu trebuie s fac neap rat referire la variabilele de control. Programul
6.3.4 exemplific aceste aspecte utiliznd variabilele i i j ale c ror valori le
tip re te pe parcursul a 10 itera ii. Expresia este un test realizat doar asupra
variabilei i.
Programul 6.3.4
#include <stdio.h>
void main(void){
int i,j;
for(i=0,j=0;i<10;i++,j=j-i)
printf("%d %d\n",i,j);
}

94

6 Instruc iuni
A a cum s-a precizat mai devreme, cele trei elemente care alc tuiesc defini ia
instruc iunii for nu sunt obligatorii. Unele (chiar toate) pot lipsi. Exemplele
care urmeaz eviden iaz acest lucru.
E posibil ca n defini ia instruc iunii for s lipseasc ac iunea care modific
variabila de control. n programul 6.3.5 valoarea acestei variabile este citit de
la tastatur n interiorul buclei. Se calculeaz i se afi eaz valoarea 1/i atta
timp ct utilizatorul introduce numere diferite de zero.
Programul 6.3.5
#include <stdio.h>
void main(void){
int i;
for(i=1;i!=0;){
printf("1/%d=%f ",i,1/(float)i);
printf("\nIntroduceti un nou numar ");
scanf("%d", &i);
}
}
Uneori ini ializarea variabilei de control se face naintea instruc iunii for, caz
n care, evident, aceast parte va lipsi din defini ia instruc iunii. n exemplul 6.3.6 se cite te un num r n de la tastatur . Dac el este impar (adic dac
restul mp r irii lui la doi este diferit de zero), atunci variabila de control i se
ini ializeaz cu 1, altfel cu 2. n cadrul instruc iunii for se tip resc numerele
pare sau impare n func ie de op iunea utilizatorului (de fapt n func ie de tipul
num rului introdus de utilizator). Tip rirea se ncheie n momentul n care se
dep e te valoarea 10.
Programul 6.3.6
#include <stdio.h>
void main(void){
int i,n;
printf("Introduceti un numar "); scanf("%d", &n);
if(n%2!=0) i=1;
else i=2;
for(;i<=10;i=i+2)
printf("%d ",i);
}
95

Programarea calculatoarelor
Instruc iunea for poate fi utilizat pentru a crea bucle executate de un num r
infinit de ori. Acest lucru se realizeaz l snd liber zona rezervat expresiei,
caz n care ea va fi considerat mereu adev rat . Desigur introducerea unei
astfel de instruc iuni ar bloca programul, el urmnd s ruleze la infinit. n interiorul for-ului trebuie prev zut o instruc iune break care s opreasc n
anumite condi ii execu ia for-ului. Exemplul 6.3.7 cite te n mod repetat un
caracter de la tastatur i se opre te n momentul n care utilizatorul introduce
litera 'z'.
Programul 6.3.7
#include <stdio.h>
void main(void){
char c;
for(;;){
c=getchar();
if(c=='z') break;
}
}
Dac ntr-o aplica ie trebuie introduse ntrzieri, atunci se poate utiliza instruciunea for cu corp vid. Programul 6.3.8 realizeaz o ntrziere prin intermediul
unui for dup a c rui defini ie urmeaz punct i virgul , ceea ce nseamn ca
nu con ine nimic, deci nu face nimic n afar de a incrementa variabila de control pn cnd aceasta atinge pragul maxim. Pentru ca ntrzierea s fie vizibil
variabila de control trebuie s aib valori mari, motiv pentru care a fost declarat de tip long int.
Programul 6.3.8
#include <stdio.h>
void main(void){
long int i;
printf("Asteptati.");
for(i=0;i<500000000;i++);
printf("\nIntervalul de timp s-a incheiat.");
}

96

6 Instruc iuni

6.3.2 Instruc iunea while


Aceast instruc iune ofer o alt modalitate prin care o secven de cod poate fi
repetat . While se folose te cu prec dere atunci cnd num rul de repeti ii nu
este cunoscut de la nceput. Bucla se repet atta timp ct condi ia este adev rat (diferit de zero). La fel ca n cazul instruc iunii for, condi ia este evaluat
la nceput, prin urmare exist i posibilitatea ca blocul de instruc iuni s nu fie
executat nici m car o dat (dac expresia este fals ). Figura 6.3.2 este o reprezentare grafic a modului de func ionare a instruc iunii while.

EXPRESIE

adev rat

Bloc de
instruc iuni

fals

Figura 6.3.2 Instruc iunea while

Forma general a instruc iunii este:


while (expresie)
//bloc de instructiuni
Primul pas const n evaluarea expresiei. Dac ea este adev rat , se execut
blocul de instruc iuni. Apoi se revine la evaluarea expresiei. Ace ti pa i se
repet pn cnd expresia devine fals , caz n care programul continu cu instruc iunea imediat urm toare ciclului while.
Exemplul 6.3.9 utilizeaz instruc iunea while pentru afi area repetat a valorii
radicalului extras dintr-un num r x introdus de utilizator. Bucla se repet pn
cnd utilizatorul introduce un num r negativ. Se observ c variabilei x i se d
o valoare ini ial ; acest lucru este necesar pentru a se asigura intrarea, cel pu in
o dat , n bucla while.
97

Programarea calculatoarelor
Programul 6.3.9
#include <stdio.h>
#include <math.h>
void main(void){
float x=0;
printf("Programul extrage radical\n.");
printf("Numar negativ->incheierea programului.\n");
while (x>=0){
printf("Radical din %f este %f", x, sqrt(x));
printf("\nIntroduceti un numar ");
scanf("%f",&x);
}
}
Deseori mpreun cu instruc iunile iterative este folosit o instruc iune de salt:
continue. Aceasta for eaz trecerea la urm toarea itera ie, ignornd liniile de
cod care mai exist pn la sfr itul buclei. Ea are efect asupra ciclului iterativ
n care se afl i nu afecteaz eventuale alte instruc iuni aflate n exterior.
Programul 6.3.10 cite te de la tastatur numere pn cnd utilizatorul introduce
valoarea zero. Dac num rul citit este negativ, el este transformat n num r
pozitiv i se afi eaz un mesaj n acest sens. Dac ns num rul introdus este
deja pozitiv, se sare la urm toarea itera ie prin folosirea instruc iunii continue. Se observ i de aceast dat ini ializarea variabilei x cu o valoare care s
asigure intrarea n while (aceast valoare va fi oricum suprascris cu primul
num r introdus de utilizator).
Programul 6.3.10
#include <stdio.h>
#include <math.h>
void main(void){
int x=1;
while (x!=0){
printf("Introduceti un numar ");
scanf("%d",&x);
if (x>0) continue;
x=-x;
printf("Numarul a fost transformat.\n");
}
}

98

6 Instruc iuni
Instruc iunea while poate fi folosit pentru a repeta de un num r infinit de ori
o secven de cod. Programul 6.3.11 creeaz un meniu a c rui afi are pe ecran
se repet pn cnd utilizatorul introduce valoarea zero. Expresia evaluat de
instruc iunea while const ntr-un num r (1 de aceast dat ) care are tot timpul valoarea logic adev rat. Acest lucru garanteaz faptul c nu se va ie i din
while datorit acestei expresii. ncheierea programului se face prin apelul
func iei exit(), n cazul n care utilizatorul i manifest aceast op iune.
Programul 6.3.11
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
void main(void){
int optiune, x;
while(1){
system("cls"); //sterge ecranul
printf("\n1 - Modul");
printf("\n2 - Exponentiala");
printf("\n0 - Iesire");
printf("\nIntroduceti optiunea ");
scanf("%d", &optiune);
switch(optiune){
case 1:
printf("x="); scanf("%d",&x);
printf("%.2f",fabs(x)); break;
case 2:
printf("x="); scanf("%d",&x);
printf("%.2f",exp(x)); break;
case 0: exit(0);
default: printf("\nOptiune gresita");
}
system("pause"); //asteapta apasarea unei taste
}
}

99

Programarea calculatoarelor

6.3.3 Instruc iunea do while


A treia modalitate prin care se poate repeta o secven de cod este oferit de
instruc iunea do while. Aceasta prezint o deosebire major fa de celelalte
dou instruc iuni repetitive (for i while): expresia este evaluat la sfr itul
fiec rei itera ii, lucru care garanteaz c blocul de instruc iuni din interiorul
ciclului do while va fi executat cel pu in o dat . Reprezentarea grafic a
instruc iunii do while este redat n figura 6.3.3.

Bloc de
instruc iuni

adev rat

EXPRESIE

fals

Figura 6.3.3 Instruc iunea do while

Forma general a instruc iunii este:


do{
//bloc de instructiuni
}while(expresie);
Blocul de instruc iuni este repetat pn cnd expresia devine fals . Dac
bucla con ine o singur instruc iune, acoladele nu sunt obligatorii. Se obi nuie te ns a fi folosite chiar i n acest caz pentru mai mult claritate i pentru a
evita confuziile ntre nceputul unui while cu corpul vid i finalul unui
do while (evident, confuziile ar putea fi f cute de cineva care se uit peste
un asemenea program i nu de compilator care nu are nicio problem din acest
punct de vedere).
100

6 Instruc iuni
Instruc iunea do while este folosit adesea pentru a valida informa iile introduse de utilizator. Programul 6.3.12 calculeaz aria unui p trat a c rui latur L
este citit de la tastatur . Fiind vorba despre o dimensiune, aceasta nu poate fi
negativ sau zero, prin urmare utilizatorul este for at s introduc o valoare
pozitiv , citirea ei repetndu-se atta timp ct num rul introdus este mai mic
sau egal cu zero (a se urm ri, n capitolul dedicat schemelor logice, varianta 3
de rezolvare a acestei probleme).
Programul 6.3.12
#include <stdio.h>
void main(void){
float L;
do{
printf("Introduceti latura: "); scanf("%f", &L);
}while(L<=0);
printf("Aria este: %.2f",L*L);
}
Prin intermediul instruc iunii do while se pot realiza i meniuri repetitive.
Programul 6.3.13 reprezint exemplul dat la instruc iunea while care este
modificat astfel nct ie irea nu se mai face prin apelul func iei exit(), ci prin
evaluarea op iunii utilizatorului n cadrul expresiei aferente ciclului
do while. Se r mne n instruc iunea repetitiv atta timp ct utilizatorul
introduce 1 sau 2. Dac op iunea sa este invalid ciclul do while se ncheie.
Programul 6.3.13
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
void main(void){
int optiune, x;
do{
system("cls"); //sterge ecranul
printf("\n1 - Modul");
printf("\n2 - Exponentiala");
printf("\nOrice alt numar - Iesire");
printf("\nIntroduceti optiunea ");
scanf("%d", &optiune);
switch(optiune){
101

Programarea calculatoarelor
case 1:
printf("x="); scanf("%d",&x);
printf("%.2f",fabs(x)); break;
case 2:
printf("x="); scanf("%d",&x);
printf("%.2f",exp(x)); break;
}
system("pause"); //asteapta apasarea unei taste
}while(optiune==1||optiune==2);
}

6.4 Probleme rezolvate


6.4.1 Calcularea i afi area modulului unui num r ntreg x a c rui valoare se
cite te de la tastatur (f r a se folosi func ia fabs()).
Programul 6.4.1
#include <stdio.h>
void main(void){
int x;
printf("x=");scanf("%d", &x);
if(x>=0)
printf("|%d|=%d",x,x);
else
printf("|%d|=%d",x,-x);
}
6.4.2 Se consider dou numere reale x i y ale c ror valori sunt citite de la
tastatur . Se calculeaz valoarea expresiei

ex

ln( x

y ) 2* y , x

,x

y
y

Programul 6.4.2
#include <stdio.h>
#include <math.h>
102

6 Instruc iuni
void main(void){
float x,y,e;
printf("x="); scanf("%f", &x);
printf("y="); scanf("%f", &y);
if (x>=y)
e=exp(x)+sqrt(x-y);
else
e=log(fabs(x-y))+2*y;
printf("E=%.2f",e);
}
6.4.3 Se verific dac un num r ntreg citit de la tastatur este par. Un num r
este par dac restul mp r irii lui la doi este zero. Evident num rul considerat
trebuie s fie ntreg i nu real, deoarece operatorul modulo nu se poate aplica
numerelor reale i de asemenea numerele reale nu pot fi asociate cu no iunile de
par sau impar.
Programul 6.4.3
#include <stdio.h>
void main(void){
int n;
printf("n="); scanf("%d", &n);
if(n%2==0) printf("Numarul este par");
else printf("Numarul este impar");
}
6.4.4 Se calculeaz maximul dintre trei numere reale introduse de la tastatur .
Algoritmul consider c primul num r citit este maximul. Apoi compar acest
maxim cu fiecare dintre celelalte numere. n momentul n care se g se te un
num r mai mare dect maximul, valoarea maximului se modific .
Programul 6.4.4
#include <stdio.h>
void main(void){
float a,b,c,max;
printf("a="); scanf("%f", &a);
printf("b="); scanf("%f", &b);
103

Programarea calculatoarelor

printf("c="); scanf("%f", &c);


max=a;
if(b>max) max=b;
if(c>max) max=c;
printf("MAX:%.2f",max);

6.4.5 Se citesc de la tastatur dou numere reale a i b, reprezentnd coeficienii unei ecua ii de gradul nti care apoi este rezolvat afi ndu-se rezultatul (a
se vedea i schema logic propus pentru rezolvarea acestei probleme n capitolul 2).
Programul 6.4.5
#include <stdio.h>
void main(void){
float a,b,x;
printf("a=");scanf("%f", &a);
printf("b=");scanf("%f", &b);
if(a==0)
if(b==0)
printf("Ecuatia are o infinitate de solutii");
else
printf("Ecuatia nu are solutii");
else{
x=-b/a;
printf("Rezultatul este: %5.2f", x);
}
}
6.4.6 Se afi eaz numerele naturale i [a,b] care sunt divizibile cu n. Valorile a, b i n se citesc de la tastatur . n cazul n care a i b nu sunt n ordine
cresc toare, ele se inverseaz prin intermediul unei variabile auxiliare.
Programul 6.4.6
#include <stdio.h>
void main(void){
int i, n, a, b, aux;
104

6 Instruc iuni

printf("a="); scanf("%d", &a);


printf("b="); scanf("%d", &b);
printf("n="); scanf("%d", &n);
if(b<a){ //daca ordinea numerelor nu e corecta
aux=a; a=b; b=aux; //se inverseaza
}
for(i=a;i<=b;i++) //se parcurge intervalul [a,b]
if(i%n==0) //daca numarul e divizibil cu n
printf("%d ",i); //e afisat

6.4.7 Se citesc n numere ntregi. Se afi eaz media numerelor pozitive. Deoarece numerele sunt ntregi, atunci cnd se calculeaz media e necesar o transformare de tip.
Programul 6.4.7
#include <stdio.h>
void main(void){
int i, n, suma=0, nr=0, x;
float media;
printf("n="); scanf("%d", &n);
for(i=1;i<=n;i++){
printf("\nx="); scanf("%d",&x);
if(x>0){
/*daca numarul introdus e pozitiv, se adauga la
suma si se incrementeaza numarul de elemente
pozitive*/
suma=suma+x;
nr++;
}
}
if(nr==0)
printf("Nu exista numere pozitive!");
else{
media=(float)suma/nr;
printf("Media este: %.2f",media);
}
}
105

Programarea calculatoarelor

6.4.8 Problema este un exemplu de repetare a unui set de instruc iuni atta timp
ct utilizatorul confirm . ntr-un ciclu do while se cite te un num r real i se
afi eaz p tratul s u. La sfr itul fiec rei itera ii utilizatorul este ntrebat dac
dore te s continue.
Programul 6.4.8
#include <stdio.h>
void main(void){
float n;
int raspuns;
do{
printf("\nIntroduceti un numar: ");
scanf("%f", &n);
printf("Patratul lui %.2f este: %.2f", n, n*n);
printf("\n\nDoriti sa continuati (1=DA/0=NU)? ");
scanf("%d", &raspuns);
}while(raspuns==1);
}
6.4.9 Se verific dac un num r natural n e prim. n primul rnd, ntr-un ciclu
do while, utilizatorul este for at s introduc un num r natural. Se porne te
de la premisa c num rul este prim (acest lucru este memorat ntr-o variabil
numit fanion, c reia i se d valoarea 1). Se parcurge apoi intervalul
[2, n/2], iar dac n se mparte la cel pu in unul dintre aceste numere, el nu
este prim; variabila fanion prime te valoarea 0 i se iese din ciclul for
printr-o instruc iune break. La sfr itul programului se verific fanionul; dac
a r mas pe 1, nseamn c num rul e prim.
Programul 6.4.9
#include <stdio.h>
#include <math.h>
void main(void){
int i, n, fanion=1;
do{
/*utilizatorul este fortat sa introduca un numar
pozitiv*/
106

6 Instruc iuni

printf("n="); scanf("%d", &n);


}while(n<=0);
for(i=2;i<=n/2;i++)
if(n%i==0){
/*daca n e divizibil cu i, atunci nu este prim;
se poate iesi din for, verificarile urmatoare
nu mai au sens*/
fanion=0;
break;
}
if(fanion==0)
printf("%d nu e prim", n);
else
printf("%d e prim", n);

6.4.10 Determinarea celui mai mare divizor comun a dou numere naturale
utiliznd algoritmul lui Euclid. n primul rnd utilizatorul trebuie obligat s
introduc dou numere naturale. Acest lucru se face plasnd citirea fiec rui
num r ntr-o instruc iune do while din care se iese doar cnd num rul este
valid. n al doilea rnd numerele trebuie s fie n ordine descresc toare. Dac nu
au fost introduse a a, atunci ele sunt inversate. Dup ce aceste dou condi ii
sunt satisf cute, se poate determina cel mai mare divizor comun.
Programul 6.4.10
#include <stdio.h>
void main(void){
int m, n, r, aux;
do{
printf("M="); scanf("%d", &m);
}while(m<=0);
do{
printf("N="); scanf("%d", &n);
}while(n<=0);
if (m<n){
aux=m;
m=n;
n=aux;
}
107

Programarea calculatoarelor
/*Aici incepe algoritmul lui Euclid*/
r=m%n;
while (r!=0){
m=n;
n=r;
r=m%n;
}
printf("\nCMMDC: %d", n);
}

6.5 Probleme propuse


A. Specifica i unde este gre eala (se consider c toate variabilele sunt corect
definite i c sunt incluse toate fi ierele antet necesare).
1. if(a>b)
printf("a mai mare ca b");
E=(a+2*b)/3;
else
printf("a mai mic sau egal cu b");
E=(2*a+b)/3;
printf("E=%.2f", E);
2. for(i=0, i<n, i++){
//instructiuni
}
3. if a<0
a=fabs(a);
4. for(i=0; i<n; i++);{
//instructiuni
}
5. if((a<0)&(b<0)){
//instructiuni
}
6. do while(n<=100){
//instructiuni
}
108

6 Instruc iuni
7. for(i==0;i<n;i++){
//instructiuni
}
8. for(i=100;i>0;i++)
printf("%d ", i);
9. n=10;
do{
n--;
}while(n<10);
B. Se consider urm toarele programe. Specifica i ce va fi afi at pe ecran dup
rularea acestora.
10. #include <stdio.h>
void main(void){
int a=5, b=7, x=0, y=0;
if((a<b)&&(a!=0))
x=a+b;
else if((a>0)&&(b>0))
y=a*b;
printf("x=%d, y=%d", x, y);
}
11. #include <stdio.h>
void main(void){
int i;
for(i=1;i<0;i++)
printf("%d ",i);
}
12. #include <stdio.h>
#include <math.h>
void main(void){
float r;
do{
printf("r="); scanf("%f",&r);
}while(r<=0);
printf("%.2f", 2*M_PI*r);
}
C. Alege i r spunsul corect (unul singur).
109

Programarea calculatoarelor
13. Care dintre urm torii operatori nu poate fi folosit ntr-o compara ie?
a) >=;

b) <=;

c) +=;

d) ==;

e) toate r spunsurile sunt gre ite.

14. Care dintre urm toarele instruc iuni este o instruc iune alternativ ?
a) while;
sunt corecte.

b) if;

c) break;

d) for;

e) toate r spunsurile

15. Dup executarea instruc iunii for(i=0; i<5; i++) valoarea variabilei i va fi:
a) 0;

b) 1;

c) 4;

d) 5;

e) 6.

16. Care dintre urm toarele instruc iuni este o instruc iune repetitiv ?
a) while; b) if;
le sunt gre ite.

c) switch;

d) break;

e) toate r spunsuri-

17. Care dintre urm torii operatori este un operator de atribuire?


a) =;

b) +=;

c) -=;

d) %=;

e) toate r spunsurile sunt corecte.

18. Care dintre urm toarele numere are valoarea logic adev rat?
a) 1;

b) -1;

c) 7.5;

d) -7;

e) toate.

19. Cuvntul cheie else are leg tur cu instruc iunea:


a) switch;

b) if;

c) while;

d) do while;

e) for.

20. Ce valoare va avea variabila x dup executarea urm toarei secven e de


instruc iuni: x=0; a=2; b=3; if(a>0) if(a>b) x++; else
x--; else if(a>b) x+=2; else x-=2;
a) -2;

b) -1;

c) 0;

d) 1;

e) 2.

21. Care dintre urm toarele instruc iuni poate fi folosit pentru executarea
unui salt?
a) break;

b) for;

c) while;

d) do while;

e) niciuna.

22. Cuvntul cheie default are leg tur cu instruc iunea:


a) for; b) if;
menea cuvnt cheie.

c) while;

d) switch;

e) nu exist un ase-

23. Care instruc iune iterativ garanteaz faptul c secven a de cod pe care o
repet va fi executat cel pu in o dat ?
110

6 Instruc iuni
a) for;

b) while;

c) do while;

d) toate;

e) niciuna.

24. Care dintre urm toarele cuvinte cheie reprezint numele unei instruc iuni de salt?
a) if;

b) switch;

c) case;

d) continue;

e) default.

25. Care este instruc iunea repetitiv cu test ini ial i cu num r necunoscut
de itera ii?
a) while;
peat.

b) do while;

c) for;

d) continue;

e) re-

D. S se scrie programe pentru rezolvarea urm toarelor probleme.


26. Se consider x un num r real a c rui valoare e citit de la tastatur . S
se calculeze i s se afi eze valoarea func iei
f(x)=max{7x2-3,|25-x|}.
27. S se calculeze i s se afi eze r d cinile ecua iei de gradul doi (coeficien ii a, b i c sunt numere reale i se citesc de la tastatur ).
28. Se introduc de la tastatur valorile pentru trei numere reale a, b i c reprezentnd dimensiunile laturilor unui triunghi. S se calculeze i s se
afi eze aria triunghiului. Se va utiliza formula lui Heron:
A

s ( s a )( s b)( s c)

unde s este semiperimetrul (a+b+c)/2. Pentru a se putea calcula aria,


numerele introduse trebuie s fie pozitive i s formeze un triunghi, adic suma oric ror dou laturi s fie mai mare dect a treia (de exemplu
valorile 2, 4 i 100 nu pot fi dimensiuni ale laturilor unui triunghi).
29. Se citesc trei numere reale a, b i c. S se verifice dac numerele pot
reprezenta laturile unui triunghi dreptunghic. Pe lng faptul c numerele trebuie s fie pozitive, ele trebuie s verifice i teorema lui Pitagora
(suma p tratelor catetelor este egal cu p tratul ipotenuzei).
30. S se simuleze comportarea unui calculator electronic pentru numere reale; programul trebuie s permit citirea a dou numere i a unui caracter ce reprezint opera ia (+, , *, /).
31. Se cite te de la tastatur valoarea unui num r real x. S se scrie un program care apeleaz cteva func ii matematice prin intermediul urm torului meniu repetitiv:
111

Programarea calculatoarelor
1 - ex
2 - ln x
3 -

4 - |x|
5 - 10x
0 - Ie ire
32. S se afi eze p tratele primelor n numere naturale.
33. Se cite te un num r natural n. S se calculeze n! (n factorial).
34. Se cite te un num r natural n. S se calculeze suma cifrelor din care este
alc tuit n. Ultima cifr a unui num r este restul mp r irii acelui num r
la 10. Ceea ce r mne din num r este ctul mp r irii lui la 10.
35. Se cite te de la tastatur un num r natural n. S se determine to i divizorii s i. Orice num r natural n are ca divizori valorile 1 i n. Exceptnd
aceste valori, cel mai mic divizor al unui num r poate fi 2, iar cel mai
mare n/2. Prin urmare, pentru a afla divizorii unui num r natural n, se
va baleia intervalul [2, n/2].
36. Se citesc de la tastatur n numere ntregi. S se determine care este cel
mai mic i care este cel mai mare num r citit.
37. Se introduc de la tastatur notele unor studen i, pn la introducerea valorii 0. S se afi eze c i studen i au promovat examenul.
38. Se citesc n numere reale. S se afi eze produsul valorilor nenule.
39. S se afi eze primele 20 de numere din irul lui Fibonacci:
f1=0, f2=1, f3=1, f4=2, , fi=fi-2+fi-1.

112

Capitolul 7 Tablouri
Un tablou este o colec ie omogen de variabile, prin urmare elementele care
alc tuiesc un tablou trebuie s aib acela i tip. Fiecare element al unui tablou
are alocat o zon de memorie. n limbajul de programare C tablourile sunt
alc tuite din loca ii de memorie adiacente; primul element al tabloului are
adresa de memorie cea mai mic , iar ultimul pe cea mai mare [HS98].
n cadrul unui tablou, fiecare element este identificat i accesat prin unul sau
mai mul i indici. Pentru indici sunt permise doar valori ntregi [DL06]. n C
numerotarea indicilor porne te de la 0, iar fiecare indice se scrie n interiorul
unei perechi de paranteze drepte.
Atunci cnd este declarat, unui tablou i se asociaz un nume i un tip de date. El
poate avea una sau mai multe dimensiuni. Raportat la acest aspect, tablourile se
clasific n:
tablouri unidimensionale corespund vectorilor din matematic
asemenea folosite pentru reprezentarea irurilor de caractere;

i sunt de

tablouri bidimensionale organizate pe linii i coloane, acestea reprezint


matricele matematice;
tablouri multidimensionale sunt mai rar utilizate datorit cantit ii de
memorie necesar pentru stocarea acestora i a timpului consumat pentru
accesarea elementelor lor; deseori se folose te alocarea dinamic a memoriei pentru astfel de tablouri [HS98].
n paragrafele care urmeaz sunt descrise pe larg tablourile cu una i cu dou
dimensiuni, acestea fiind cele mai utilizate. n strns leg tur cu tablourile se
afl irurile de caractere; ele sunt de fapt tablouri unidimensionale cu elemente
de tip caracter. Prezentarea lor este f cut separat, n unul din capitolele urm toare.

7.1 Tablouri unidimensionale


Sunt de asemenea numite vectori datorit faptului c reflect caracteristicile
acestor entit i matematice. Un tablou unidimensional are un nume, un tip i un
num r de elemente. Indicii acestor elemente ncep de la valoarea 0. Figura 7.1.1
este reprezentarea grafic a unui vector cu numele v, care con ine n elemente
de tip ntreg.

Programarea calculatoarelor

-3

12

-9

n-2

n-1

Figura 7.1.1 Reprezentarea grafic a unui tablou unidimensional

7.1.1 Declararea unui tablou unidimensional


La fel ca orice alt variabil , pentru a putea utiliza un tablou unidimensional,
acesta trebuie declarat. Forma general pentru declararea unui astfel de tablou
este:
tip nume[dimensiune];
Tipul tabloului este de fapt tipul fiec rui element al s u. Numele este supus
acelora i restric ii valabile pentru denumirea oric rei variabile (a se vedea
indica iile referitoare la numele unei variabile din capitolul dedicat datelor i
tipurilor de date). Dimensiunea indic num rul de elemente care alc tuiesc
tabloul.
Urm toarele exemple declar dou tablouri unidimensionale. Primul este un
vector de maxim 10 numere ntregi care se nume te v. Cel de al doilea se
nume te note i poate con ine 50 de elemente de tip real.
int v[10];
float note[50];

7.1.2 Accesarea elementelor


Indicii elementelor sunt numere ntregi consecutive care pornesc de la zero.
Dac , de exemplu, un tablou are dimensiunea 10, indicii vor fi: 0, 1, 2, , 9.
Ace ti indici identific un element al tabloului, specificnd pozi ia sa. Prin
intermediul indicilor, elementul poate fi accesat.
Dac se consider vectorul din figura 7.1.1, elementul v[2] este al treilea
element al tabloului i are valoarea 7. Valoarea lui poate fi modificat printr-o
instruc iune de genul: v[2]=14;.

7.1.3 Ini ializarea elementelor


Elementele unui tablou unidimensional pot fi ini ializate atunci cnd tabloul
este declarat. Exemplul urm tor declar un tablou de cinci numere reale. Prime114

7 Tablouri
le trei elemente ale tabloului primesc valori n momentul declar rii; ultimele
dou vor avea valoarea zero.
float valori[5]={2.4, 7.1, -3};
n cazul n care nu se specific explicit dimensiunea tabloului, dar se dau valori
ini iale elementelor sale, atunci se consider c tabloul are attea elemente cte
au fost ini ializate. n exemplul care urmeaz se declar un tablou de numere
ntregi i se dau valori pentru apte astfel de numere; dimensiunea tabloului va
fi considerat 7.
int numere[]={1, 7, -9, 17, 20, -70, 4};
Dac elementele tabloului nu au fost ini ializate, atunci ele con in, cel mai
probabil, ni te valorile f r sens pentru program care se g sesc n loca iile de
memorie respective. Acestea nu trebuie utilizate nainte de a li se da valori (prin
citirea de la tastatur , dintr-un fi ier sau prin calcul).

7.1.4 Introducerea de la tastatur a valorilor elementelor


Una din modalit ile prin care elementele unui tablou pot primi valori este
citirea acestora de la tastatur . n acest sens se va folosi o instruc iune repetitiv , de obicei for (pentru c de cele mai multe ori se cunoa te num rul de
elemente pe care tabloul le con ine).
n urm toarea secven de cod sunt introduse de la tastatur elementele unui
tablou v care con ine n numere ntregi. Cnd programul este rulat, pe ecran
apare textul v[0]= i se a teapt introducerea unui num r; apoi este afi at
textul v[1]= i a a mai departe pn cnd toate elementele primesc valori.
printf("Numarul de elemente: ");
scanf("%d", &n);
for(i=0;i<n;i++){
printf("v[%d]=", i);
scanf("%d", &v[i]);
}

7.1.5 Afi area elementelor / Parcurgerea unui vector


Pentru afi area con inutului unui tablou unidimensional exist de asemenea o
secven standard de cod care parcurge tabloul, accesnd fiecare element al s u.
Se folose te tot o instruc iune repetitiv for, a a cum se poate vedea n exem115

Programarea calculatoarelor
plul urm tor care afi eaz elementele aceluia i vector v de n numere ntregi.
Acestea vor fi tip rite unul dup cel lalt, cu un spa iu ntre ele.
for(i=0;i<n;i++)
printf("%d ", v[i]);
Dup ce elementele unui tablou unidimensional au fost citite i, eventual, afi ate, probabil se dore te realizarea unor opera ii care s implice tabloul. Secven a
de cod urm toare parcurge tabloul pentru a calcula suma tuturor elementelor
sale. Aceast sum este ini ializat cu zero nainte de a intra n instruc iunea
repetitiv i este afi at cnd parcurgerea tabloului se ncheie.
suma=0;
for(i=0;i<n;i++)
suma=suma+v[i];
printf("\nSuma este: %d", suma);

7.1.6 Un exemplu complet


Programul 7.1.1 este un exemplu complet de lucru cu un tablou unidimensional.
El cuprinde citirea elementelor tabloului, afi area acestuia i calcularea sumei
tuturor elementelor.
Programul 7.1.1
#include <stdio.h>
void main(void){
int v[20], n, i, suma=0;
printf("Numarul de elemente: ");
scanf("%d", &n);
for(i=0;i<n;i++){//citirea elementelor vectorului
printf("v[%d]=", i);
scanf("%d", &v[i]);
}
for(i=0;i<n;i++)//afisarea vectorului
printf("%d ", v[i]);
for(i=0;i<n;i++)//calcularea sumei elementelor
suma=suma+v[i];
printf("\nSuma este: %d", suma);
}
116

7 Tablouri

7.2 Tablouri bidimensionale


Corespund matricelor din matematic . Au un num r de linii i un num r de
coloane a c ror numerotare ncepe cu indicele 0. Din punct de vedere grafic
acestea pot fi reprezentate ca n figura 7.2.1.
0

m-1

-3

11

-7

-1

17

.
.
.
.
.
n-1

Figura 7.2.1 Reprezentarea grafic a unui tablou bidimensional

7.2.1 Declararea tablourilor bidimensionale


Tablourile bidimensionale sunt declarate i accesate n limbajul de programare
C folosind dou seturi de paranteze drepte, cte unul pentru fiecare dimensiune.
Forma general pentru declararea unui astfel de tablou este:
tip nume[linii][coloane];
Ca la orice declarare de variabil , matricea are un nume i un tip. Prima
dimensiune specificat este num rul de linii, iar cea de a doua num rul de
coloane. Matricea va avea un num r de elemente egal cu linii*coloane.
Urm torul exemplu declar o matrice de numere ntregi organizate pe 3 linii
i 4 coloane. Matricea va avea n total 12 elemente.
int matr[3][4];

117

Programarea calculatoarelor

7.2.2 Accesarea elementelor


Fiecare dimensiune a matricei are propriul set de indici. Dac o matrice are n
linii i m coloane, indicii acestora vor fi de la 0 la n-1 pentru linii i de la 0 la
m-1 pentru coloane, a a cum se observ i n figura 7.2.1.
Pentru accesarea unui anumit element al matricei trebuie specificat indicele
liniei i apoi indicele coloanei care con in elementul. De exemplu, n figura 7.2.1, elementul aflat la intersec ia liniei cu indicele 1 i a coloanei cu indicele 2 este matr[1][2] i are valoarea 11. Aceasta poate fi modificat
printr-o instruc iune de atribuire de genul: matr[1][2]=13;.

7.2.3 Ini ializarea elementelor


n cazul n care se dore te, elementele unei matrice pot primi valori la declarare.
Exemplul urm tor ini ializeaz un tablou bidimensional de 2 linii i 3 coloane
con innd numere ntregi.
int matr[2][3]={
{7,-10,1},
{4,0,-32}
};
Nu este obligatoriu ca la ini ializare s se specifice valori pentru toate elementele matricei. Cele neini ializate explicit vor fi automat ini ializate cu valoarea 0.
n exemplul urm tor se declar o matrice cu 3 linii i 4 coloane, dar se dau
valori doar elementelor de pe primele trei coloane. Pe ultima coloan elementele vor fi 0.
int matr[3][4]={
{1, 9, 12},
{-7, 40, 3},
{3, -2, 8}
};
Ini ializarea n acest mod a elementelor matricei este o procedur foarte simpl ,
dar poate deveni incomod pentru tablouri bidimensionale de dimensiuni mari
sau nepotrivit n cazul n care valorile trebuie citite sau calculate. Din aceste
motive, de cele mai multe ori, elementele unei matrice primesc valori prin
intermediul unor instruc iuni pe parcursul execu iei programului.
118

7 Tablouri

7.2.4 Introducerea de la tastatur a valorii elementelor


Citirea valorilor pentru elementele unei matrice va fi f cut ntr-o structur
iterativ . Aceasta cuprinde dou instruc iuni for imbricate. Primul for este
folosit pentru parcurgerea liniilor, iar n interiorul fiec rei linii e folosit un al
doilea for pentru a parcurge elementele de pe acea linie.
Urm toarea secven de cod cite te de la tastatur elementele unei matrice cu n
linii i m coloane. Se afi eaz pe ecran mesaje de genul: matr[0][0]=,
matr[0][1]= i a a mai departe, a teptndu-se de fiecare dat introducerea
valorii de c tre utilizator.
printf("Numarul de linii: "); scanf("%d", &n);
printf("Numarul de coloane: "); scanf("%d", &m);
for(i=0;i<n;i++)
for(j=0;j<m;j++){
printf("matr[%d][%d]=", i, j);
scanf("%d", &matr[i][j]);
}

7.2.5 Afi area unei matrice


Pentru afi area matricei sunt necesare acelea i doua cicluri for imbricate, a a
cum se observ n secven a de cod urm toare. Dup afi area elementelor de pe
o linie trebuie deplasat cursorul pe linia urm toare; acest lucru se face printr-o
instruc iune printf("\n"); plasat n interiorul primului for, dup ce al
doilea for s-a ncheiat. Pentru o aliniere mai buna, fiec rui element i-au fost
alocate 5 caractere.
for(i=0;i<n;i++){
for(j=0;j<m;j++)
printf("%5d ", a[i][j]);
printf("\n");
}

119

Programarea calculatoarelor

7.2.6 Parcurgeri ntr-o matrice


O matrice bidimensional poate fi parcurs n mai multe feluri, cele mai des
ntlnite fiind parcurgerile pe orizontal i pe vertical , reprezentate grafic n
figura 7.2.2. Aceste parcurgeri se fac prin intermediul celor dou instruc iuni
for i au anumite particularit i una fa de cealalt .

a) pe orizontal

b) pe vertical

Figura 7.2.2 Parcurgerea unei matrice

Pentru o parcurgere pe orizontal a matricei, for-un exterior corespunde liniilor, iar cel interior coloanelor (la fel ca la afi are). Exemplul urm tor parcurge o
matrice pe orizontal i calculeaz suma tuturor elementelor.
suma=0;
for(i=0;i<n;i++)
for(j=0;j<m;j++)
suma=suma+matr[i][j];
printf("Suma: %d", suma);
La o parcurgere pe vertical , for-ul exterior se refer la coloane, iar cel interior la linii. Prin urmare indicele liniei este cel care se modific mai des, spre
deosebire de parcurgerea pe orizontal unde mai des se modifica indicele coloanei. Exemplul care urmeaz parcurge o matrice pe vertical i afi eaz elementele n ordinea n care le acceseaz .
for(j=0;j<m;j++)
for(i=0;i<n;i++)
printf("%3d ", a[i][j]);
Se observ c cele dou for-uri de parcurgere s-au inversat n compara ie cu
parcurgerea pe orizontal . Acest lucru se datoreaz faptului c parcurgerea se
face pe coloan , nu pe linie.
120

7 Tablouri
Dac matricea este
1 2 3 4
5 6 7 8
pe ecran se va afi a (datorit parcurgerii pe vertical )
1 5 2 6 3 7 4 8.

7.2.7 Particularit i de parcurgere a matricelor p tratice


Matricea p tratic este un caz particular de matrice, n care num rul de linii este
egal cu num rul de coloane. O astfel de matrice are cteva elemente specifice,
eviden iate n figura 7.2.3: diagonalele principal i secundar i triunghiurile
superioare i inferioare acestor diagonale.

a) diagonala principal

b) triunghiul superior diagonalei principale

c) triunghiul inferior diagonalei principale

d) diagonala secundar

e) triunghiul superior diagonalei secundare

f) triunghiul inferior diagonalei secundare

Figura 7.2.3 Particularit i ale unei matrice p tratice

Exist situa ii n care e necesar doar parcurgerea acestor zone, nu a ntregului


tablou bidimensionale. Secven ele de cod care urmeaz arat cum se fac aceste
121

Programarea calculatoarelor
parcurgeri particulare pe o matrice p tratic de numere ntregi numit a. Indicele liniei este reprezentat de variabila i i indicele coloanei de variabila j. Elementele accesate sunt afi ate pentru a putea fi identificate.
parcurgerea diagonalei principale aceste elemente au caracteristic faptul
c indicele liniei este egal cu cel al coloanei, prin urmare e suficient o singur instruc iune for pentru a le accesa; un element al diagonalei principale are coordonatele i i i;
for(i=0;i<n;i++)
printf("%3d ", a[i][i]);
parcurgerea triunghiului superior diagonalei principale pentru elementele
aflate deasupra diagonalei principale, indicele liniei, i, apar ine intervalului
[0,n), iar cel al coloanei, j, porne te de la i+1 i merge pn la n-1;
for(i=0;i<n;i++)
for(j=i+1;j<n;j++)
printf("%3d ", a[i][j]);
parcurgerea triunghiului inferior diagonalei principale la elementele poziionate sub diagonala principal , i-ul merge de asemenea de la 0 la n-1, iar
j-ul porne te de la 0 i se opre te nainte de a ajunge la elementul aflat pe
diagonal (cel de pe coloana i);
for(i=0;i<n;i++)
for(j=0;j<i;j++)
printf("%3d ", a[i][j]);
parcurgerea diagonalei secundare liniile trebuie parcurse de jos n sus (n
intervalul [n,0)), iar ntre indicele liniei i cel al coloanei exist o rela ie
bine definit , a adar i n acest caz e suficient un singur ciclu for pentru
parcurgere; elementele de pe diagonala secundar au coordonatele i-1 i
n-i;
for(i=n;i>0;i--)
printf("%3d ", a[i-1][n-i]);
parcurgerea triunghiului superior diagonalei secundare pentru elementele
aflate deasupra diagonalei secundare, ambii indici pornesc de la 0; i-ul se
opre te nainte de a ajunge la n, iar j-ul nainte de n-i-1;
122

7 Tablouri
for(i=0;i<n;i++)
for(j=0;j<n-i-1;j++)
printf("%3d ", a[i][j]);
parcurgerea triunghiului inferior diagonalei secundare i la elementele
pozi ionate sub diagonala secundar indicele liniei, i, parcurge intervalul
[0,n); indicele coloanei, j, porne te de la n-i i se opre te la n-1.
for(i=0;i<n;i++)
for(j=n-i;j<n;j++)
printf("%3d ", a[i][j]);
Se consider matricea p tratic de 4 linii i 4 coloane, ini ializat cu valorile:
1

9 10 11 12
13 14 15 16
Dac se ruleaz secven ele de cod prezentate anterior, acestea vor afi a:
pentru diagonala principal : 1 6 11 16;
pentru triunghiul superior diagonalei principale: 2 3 4 7 8 12;
pentru triunghiul inferior diagonalei principale: 5 9 10 13 14 15;
pentru diagonala secundar : 13 10 7 4;
pentru triunghiul superior diagonalei secundare: 1 2 3 5 6 9;
pentru triunghiul inferior diagonalei secundare: 8 11 12 14 15 16.

7.2.8 Un exemplu complet


Programul 7.2.1 este un exemplu complet de lucru cu tablourile bidimensionale.
El cuprinde citirea elementelor unei matrice, afi area acesteia i calcularea
sumei tuturor elementelor.
Programul 7.2.1
#include <stdio.h>
123

Programarea calculatoarelor
void main(void){
int a[50][50], n, m, i, j, suma=0;
printf("Numarul de linii: ");
scanf("%d", &n);
printf("Numarul de coloane: ");
scanf("%d", &m);
for(i=0;i<n;i++)//citirea elementelor matricei
for(j=0;j<m;j++){
printf("a[%d][%d]=", i, j);
scanf("%d", &a[i][j]);
}
for(i=0;i<n;i++){//afisarea matricei
for(j=0;j<m;j++)
printf("%3d ", a[i][j]);
printf("\n");
}
for(i=0;i<n;i++)//calcularea sumei
for(j=0;j<m;j++)
suma=suma+a[i][j];
printf("Suma: %d\n", suma);
}

7.3 Probleme rezolvate


7.3.1 G sirea valorii minime ntr-un tablou unidimensional. Pentru rezolvarea
acestei probleme se porne te de la premisa c primul element al vectorului este
minimul. Apoi se parcurge vectorul pornind de la al doilea element i se compar fiecare element cu valoarea minim din acel moment. n cazul n care se
g se te o valoare mai mic , minimul este modificat astfel nct s re in valoarea g sit .
Programul 7.3.1
#include <stdio.h>
void main(void){
int v[20], n, i, min;
printf("Numarul de elemente: ");
scanf("%d", &n);
for(i=0;i<n;i++){//citirea
printf("v[%d]=", i); scanf("%d", &v[i]);
124

7 Tablouri
}
for(i=0;i<n;i++)//afisarea
printf("%d ", v[i]);
//cautarea minimului
min=v[0];//primul element se considera minimul
for(i=1;i<n;i++)
/*se compara minimul cu fiecare element*/
if (v[i]<min)
/*daca se gaseste un element mai mic, se modifica minimul*/
min=v[i];
printf("\nMinimul este: %d", min);
}
7.3.2 Calcularea vrstei medii corespunz toare angaja ilor unei firme. Vrstele
angaja ilor sunt citite de la tastatur i re inute ntr-un tablou unidimensional.
De fiecare dat cnd o vrst este citit , aceasta este adunat la o variabil care
calculeaz vrsta total (a adar nu se folose te nc o structur repetitiv pentru
parcurgere, ci prelucrarea informa iei se face direct la citire). n final, la ie irea
din for, se mparte vrsta total la num rul de angaja i pentru a se ob ine
vrsta medie. ntruct att vrsta total ct i num rul de angaja i sunt variabile
de tip ntreg, pentru a ob ine un rezultat corect e necesar o conversie de tip.
Programul 7.3.2
#include <stdio.h>
void main(void){
int varsta[100];
int n, i, v_totala=0;
printf("Cati angajati are firma? ");
scanf("%d", &n);
printf("Introduceti varsta fiecarui angajat.\n");
for(i=0;i<n;i++){
/*se citeste varsta fiecarui angajat si se aduna
la varsta totala*/
scanf("%d", &varsta[i]);
v_totala=v_totala+varsta[i];
}
/*varsta totala este convertita la float pentru ca
rezultatul sa fie corect*/
printf("Varsta medie: %.2f", (float)v_totala/n);
125

Programarea calculatoarelor
}
7.3.3 Aflarea i afi area primelor 20 de elemente din irul lui Fibonacci utiliznd un tablou unidimensional. Se declar un tablou de 20 de elemente, iar
primele doua loca ii se ini ializeaz cu valorile 0, respectiv 1. Se parcurge apoi
tabloul ncepnd cu indicele 2 i fiecare element i se calculeaz ca sum a
elementelor cu indicii i-1 i i-2.
Programul 7.3.3
#include <stdio.h>
void main(void){
int fibo[20];
int i;
/*se
initializeaza
primele
doua
elemente
ale
sirului a caror valoare este cunoscuta*/
fibo[0]=0; fibo[1]=1;
/*se calculeaza valoarea urmatoarelor elemente*/
for(i=2;i<20;i++)
fibo[i]=fibo[i-1]+fibo[i-2];
/*se afiseaza toate elementele*/
for(i=0;i<20;i++)
printf("%d ", fibo[i]);
}
7.3.4 Minimul ntr-un tablou bidimensional. Se ini ializeaz minimul cu valoarea primului element al matricei. Se parcurge apoi matricea n ntregime,
comparndu-se minimul cu fiecare element; n cazul n care se g se te o valoare
mai mic , se modific minimul.
Programul 7.3.4
#include <stdio.h>
void main(void){
int a[50][50], n, m, i, j, min;
printf("Numarul de linii: ");
scanf("%d", &n);
printf("Numarul de coloane: ");
scanf("%d", &m);
for(i=0;i<n;i++)//citirea
for(j=0;j<m;j++){
printf("a[%d][%d]=", i, j);
126

7 Tablouri

scanf("%d", &a[i][j]);
}
for(i=0;i<n;i++){//afisarea
for(j=0;j<m;j++)
printf("%3d ", a[i][j]);
printf("\n");
}
min=a[0][0];//initializarea minimului
for(i=0;i<n;i++)
for(j=0;j<m;j++)
/*se compara fiecare element cu minimul*/
if (a[i][j]<min)
/*daca se gaseste o valoare mai mica, se modifica minimul*/
min=a[i][j];
printf("\nValoarea minima: %d", min);

7.3.5 Suma elementelor de pe diagonala principal . Se parcurge doar diagonala


principal . E suficient o singur instruc iune for. Elementele diagonalei
principale avnd indicele liniei egal cu cel al coloanei, vor fi accesate prin
coordonatele [i][i].
Programul 7.3.5
#include <stdio.h>
void main(void){
int a[50][50], n, i, j, suma=0;
printf("Numarul de linii: ");
scanf("%d", &n);
for(i=0;i<n;i++)//citirea
for(j=0;j<n;j++){
printf("a[%d][%d]=", i, j);
scanf("%d", &a[i][j]);
}
for(i=0;i<n;i++){//afisarea
for(j=0;j<n;j++)
printf("%3d ", a[i][j]);
printf("\n");
}
for(i=0;i<n;i++)//parcurgerea diagonalei
127

Programarea calculatoarelor

suma=suma+a[i][i];
printf("Suma: %d", suma);

7.3.6 Num r cte elemente impare se afl sub diagonala principal a unui
tablou bidimensional i afi eaz aceste elemente. Se analizeaz doar zona de
sub diagonala principal , utilizndu-se secven a de cod specific : indicele liniilor parcurge intervalul [0,n), iar cel al coloanelor ia valori n intervalul
[0,i).
Programul 7.3.6
#include <stdio.h>
void main(void){
int a[50][50], n, i, j, nr=0;
printf("Numarul de linii: ");
scanf("%d", &n);
for(i=0;i<n;i++)
for(j=0;j<n;j++){
printf("a[%d][%d]=", i, j);
scanf("%d", &a[i][j]);
}
for(i=0;i<n;i++){
for(j=0;j<n;j++)
printf("%3d ", a[i][j]);
printf("\n");
}
printf("Elementele impare sunt: ");
for(i=0;i<n;i++)
for(j=0;j<i;j++)
if(a[i][j]%2!=0){
nr++;
printf("%d ", a[i][j]);
}
printf("\nSunt %d elemente impare", nr);
}
7.3.7 Produsul a dou matrice. Pentru a se putea realiza acest produs, num rul
de coloane al primei matrice trebuie s fie egal cu num rul de linii al celei de a
doua. A adar prima matrice are n linii i p coloane; cea de a doua are p linii i
m coloane. Elementele matricei produs se ini ializeaz cu 0 i se calculeaz
128

7 Tablouri
conform expresiei c[i][j]=c[i][j]+a[i][k]*b[k][j], unde i i k
parcurg liniile, respectiv coloanele primei matrice, iar k i j parcurg liniile,
respectiv coloanele celei de a doua matrice.
Programul 7.3.7
#include <stdio.h>
void main(void){
int a[20][20], b[20][20], c[20][20];
int i, j, k, n, m, p;
printf("Matricea 1 - numarul de linii ");
scanf("%d", &n);
printf("Matricea 1 - numarul de coloane ");
scanf("%d", &p);
/*numarul de linii pentru a doua matrice este egal
cu numarul de coloane pentru prima matrice*/
printf("Matricea 2 - numarul de coloane ");
scanf("%d", &m);
for(i=0;i<n;i++)//citirea primei matrice
for(k=0;k<p;k++){
printf("a[%d][%d]=",i,k);
scanf("%d", &a[i][k]);
}
for(k=0;k<p;k++)//citirea celei de a doua matrice
for(j=0;j<m;j++){
printf("b[%d][%d]=",k,j);
scanf("%d", &b[k][j]);
}
printf("Prima matrice este:\n");
for(i=0;i<n;i++){
for(k=0;k<p;k++)
printf("%3d",a[i][k]);
printf("\n");
}
printf("A doua matrice este:\n");
for(k=0;k<p;k++){
for(j=0;j<m;j++)
printf("%3d",b[k][j]);
printf("\n");
}
for(i=0;i<n;i++)//initializarea matricei produs
129

Programarea calculatoarelor
for(j=0;j<m;j++)
c[i][j]=0;
for(i=0;i<n;i++)//calcularea matricei produs
for(j=0;j<m;j++)
for(k=0;k<p;k++)
c[i][j]=c[i][j]+a[i][k]*b[k][j];
printf("Matricea produs este:\n");
for(i=0;i<n;i++){
for(j=0;j<m;j++)
printf("%3d",c[i][j]);
printf("\n");
}
}

7.4 Probleme propuse


A. Specifica i unde este gre eala (se consider c toate variabilele au fost
corect definite i toate fi ierele antet necesare au fost incluse).
1. Se dore te citirea elementelor unui vector de 10 numere ntregi.
for(i=0;i<10;i++)
printf("a[%d]=",i);
scanf("%d",&a[i]);
2. Tip rirea unei matrice de numere reale cu 3 linii i 4 coloane.
for(i=0;i<3;i++)
for(j=0;j<4;j++){
printf("%7.2f ",a[i][j]);
printf("\n");
}
3. Afi area unui vector de 10 numere ntregi ale c rui elemente au fost corect citite.
for(i=1;i<=10;i++)
printf("%d ",v[i]);
B. Se consider urm toarele secven e de cod. Specifica i ce va fi afi at pe
ecran dup rularea acestora.
4. contor=0;
for(i=0;i<n;i++)
for(j=0;j<m;j++)
130

7 Tablouri
if(a[i][j]==0)
contor++;
printf("%d",contor);
5. contor=0;
for(i=0;i<n;i++)
if(a[i][i]==0)
contor++;
printf("%d",contor);
6. for(i=n-1;i>=0;i--)
printf("%d ",v[i]);
7. for(j=0;j<3;j++)
for(i=0;i<2;i++)
printf("%3d ", a[i][j]);
C. Alege i r spunsul corect (unul singur).
8. Un tablou este o colec ie de variabile care au:
a) aceea i culoare; b) aceea i n l ime;
indice; e) toate r spunsurile sunt gre ite.

c) acela i tip;

d) acela i

9. Care dintre urm toarele tipuri de tablouri poate fi utilizat n limbajul de


programare C?
a) tablou unidimensional;
b) tablou bidimensional;
c) tablou
multidimensional; d) r spunsurile a, b i c sunt corecte; e) toate r spunsurile sunt gre ite.
10. Care dintre urm toarele afirma ii referitoare la indicii elementelor unui
tablou unidimensional este adev rat ?
a) sunt numere ntregi; b) sunt numere consecutive; c) pornesc de
la valoarea zero; d) identific un element al tabloului; e) toate.
11. La declararea unui tablou unidimensional trebuie specificat:
a) numele; b) tipul; c) num rul de elemente; d) r spunsurile a, b
i c sunt corecte; e) toate r spunsurile sunt gre ite.
12. Ce realizeaz instruc iunea a[7]=7;?
a) verific dac variabila a este egal cu 7; b) atribuie valoarea 7
elementului cu indicele 7 din tabloul unidimensional a; c) verific da131

Programarea calculatoarelor
c elementul a[7] este egal cu 7;
i ini ializeaz primul s u element;

d) declar un vector de 7 elemente


e) toate r spunsurile sunt gre ite.

13. Ce efect are linia de cod float medie[20][10];?


a) declar un tablou bidimensional de numere reale cu maxim 20 de
linii i 10 de coloane; b) declar un tablou unidimensional cu maxim
200 de numere reale; c) declar un tablou unidimensional cu dou
elemente ini ializate cu valorile 20, respectiv 10;
d) realizeaz o
transformare de tip a valorilor 20 i 10 de la int la float; e) calculeaz media aritmetica a numerelor 20 i 10.
14. Care dintre urm toarele afirma ii referitoare la elementul a[2][3] al
unei matrice aste adev rat ?
a) se afl pe linia a doua i pe coloana a treia; b) se afla pe coloana a
doua i pe linia a treia; c) se afl pe linia a treia i pe coloana a patra;
d) se afl pe coloana a treia i pe linia a patra; e) toate r spunsurile
sunt gre ite.
D. S se scrie programe pentru rezolvarea urm toarelor probleme.
15. S se calculeze i s se afi eze suma elementelor cu valori impare
dintr-un tablou unidimensional.
16. S se afi eze de la dreapta la stnga valorile dintr-un vector.
17. S se calculeze i s se afi eze media general a unui student ale c rui
note sunt re inute ntr-un tablou unidimensional. Se impune restric ia ca
notele introduse s fie mai mari sau egale cu 5.
18. S se determine indicele primei apari ii a unei valori date ntr-un vector
de n elemente ntregi.
19. Se citesc elementele unui tablou unidimensional de numere reale. S se
afi eze valorile care dep esc o valoare prag introdus de asemenea de
la tastatur .
20. Se re in ntr-un tablou unidimensional coeficien ii unui polinom. S se
afi eze derivata polinomului.
Dac polinomul este
p(x) = anxn + an-1xn-1 ++ a3x3 + a2x2 + a1x + a0
derivata sa este
132

7 Tablouri
p(x)= nanxn-1 + (n-1)an-1xn-2 ++ 3a3x2 + 2a2x + a1
21. S se realizeze suma a dou matrice.
22. Se cite te un num r. S se verifice dac acea valoare exist ntr-o matrice de n linii i m coloane ale c rei elemente sunt introduse de asemenea
de la tastatur .
23. Se citesc elementele unei matrice. S se numere cte dintre acestea sunt
mai mari dect media lor aritmetic .
24. S se verifice dac o matrice p tratic este matrice unitate (elementele
de pe diagonala principal au valoarea 1, iar celelalte 0). Matricea se
consider ini ial unitate i dac se g se te un element care nu ndepline te criteriile, atunci verificarea se ncheie, matricea nefiind unitate.
25. S se verifice dac o matrice p tratic este simetric fa de diagonala
principal . Se parcurge triunghiul superior sau cel inferior diagonalei
principale i se verific dac a[i][j]==a[j][i].

133

Capitolul 8 iruri de caractere


O variabil de tip ir memoreaz o secven de caractere. Limbajul C nu are un
tip de dat dedicat irurilor de caractere (a a cum exist tipul string n Java
sau Pascal). irurile de caractere sunt de fapt tablouri unidimensionale care
con in n fiecare loca ie cte un caracter i au pe ultima pozi ie, ca marcaj al
sfr itului de ir, caracterul nul '\0'. Deoarece elementul de baz al unui ir
este caracterul, capitolul de fa va ncepe cu prezentarea unor aspecte legate de
caractere; apoi sunt descrise pe larg caracteristicile irurilor.

8.1 Caractere
Pentru definirea unui caracter se folose te tipul de dat char. Acesta are la
dispozi ie 8 bi i, prin urmare se pot reprezenta 28, adic 256 de caractere. Fiecare caracter este memorat sub forma unui num r ntreg cuprins n intervalul
[0, 255], num r ce reprezint codul ASCII asociat caracterului [CH96]. n
anexa 1 se reg sesc cele mai utilizate caractere i codurile ASCII corespunz toare.
Declararea unei variabile de tip caracter se face utiliznd cuvntul cheie char
urmat de un nume pentru noua variabil . Dac se dore te ini ializarea unei astfel
de variabile, atunci valoarea atribuit trebuie ncadrat ntre ghilimele simple
(nu duble). Instruc iunea urm toare declar o variabil cu numele caracter
i i atribuie valoarea ASCII a literei A.
char caracter='A';
Pentru opera ii de intrare/ie ire asupra variabilelor de tip caracter se pot folosi
func iile getchar(), respectiv putchar(). O abordare formatat a acestor
variabile se poate realiza prin intermediul func iilor printf() i scanf(),
folosindu-se descriptorul %c. Instruc iunea urm toare tip re te pe ecran variabila caracter, adic litera A.
printf("%c",caracter);
Caracterele pot fi analizate sau prelucrate cu ajutorul unor func ii aflate n
fi ierul antet <ctype.h>. Cteva dintre acestea sunt descrise n cele ce urmeaz (fiecare func ie prime te ca argument un caracter).
isalpha(c) returneaz o valoare nenul dac argumentul este o liter ;
isdigit(c) returneaz o valoare nenul dac argumentul este o cifr ;

8 iruri de caractere
isalnum(c) returneaz o valoare nenul dac argumentul este o liter sau o
cifr ;
isupper(c) returneaz o valoare nenul dac argumentul este liter mare;
islower(c) returneaz o valoare nenul dac argumentul este liter mic ;
isspace(c) returneaz o valoare nenul dac argumentul este spa iu
toupper(c) returneaz argumentul transformat n liter mare;
tolower(c) returneaz argumentul transformat n liter mic .
Programul 8.1.1 este un exemplu de utilizare a unei variabile de tip caracter.
Este vorba de op iunea utilizatorului de a incrementa i de a afi a un contor a
c rui valoare ini ial este zero. Contorul este afi at, apoi incrementat, iar utilizatorul este ntrebat dac dore te continuarea acestor ac iuni. Op iunea lui este
citit prin intermediul func iei getch() ntr-o variabil de tip char i sec iunea de cod se repet n interiorul unui do while pn cnd utilizatorul introduce litera 'N' sau 'n'. Pentru a nu obliga utilizatorul s introduc doar 'N'
(mare) sau doar 'n' (mic) i pentru a nu nc rca programul cu dou teste
(compararea op iunii att cu 'N' ct i cu 'n'), s-a ales transformarea literei
citite de la tastatur n liter mic utiliznd func ia tolower() i compararea
ei doar cu litera 'n'.
Programul 8.1.1
#include <stdio.h>
#include <ctype.h>
void main(void){
int contor=0;
char optiune;
do{
printf("Contor: %d", contor++);
printf("\nDoriti incrementarea contorului? (D/N)");
optiune=getch();
}while(tolower(optiune)!='n');
}

135

Programarea calculatoarelor

8.2 iruri de caractere


Un ir este o secven de caractere, ncheiat cu caracterul '\0' (caracter care
are codul ASCII 0) i ncadrat ntre ghilimele duble ("Acesta este un
sir"). Utilizarea ghilimelelor duble specific programului c este vorba de un
ir de caractere i determin compilatorul s i adauge terminatorul de ir
[CH96]. Caracterul nul de la sfr itul irului exist doar n memoria calculatorului, programatorul nefiind obligat s se preocupe prea mult de el. irul dat ca
exemplu mai sus va fi reprezentat n memorie astfel:
A

\0

Pentru a crea un element de tip ir de caractere se va utiliza, a a cum s-a precizat deja, un tablou unidimensional de variabile de tip caracter. Declararea se
face la fel ca n cazul altor variabile, specificnd tipul (char), num rul de
elemente i dnd un nume valid variabilei:
char nume_sir[lungime-sir];
Num rul de elemente specificat la declararea variabilei trebuie s in cont de
faptul c un ir de caractere se ncheie cu caracterul nul ('\0'), prin urmare
trebuie s i se aloce spa iu i acestui caracter. A adar, dac de exemplu se dore te stocarea irului "Programare", care are 10 caractere, atunci variabila
folosit trebuie s fie declarat de cel pu in 11 caractere.
Un ir de caractere poate fi declarat i ca pointer (mai multe despre pointeri n
Capitolul 9). Variabila respectiv va re ine adresa primului caracter din ir:
char *nume;
Ini ializarea unei variabile de tip ir de caractere se poate face pe parcursul
programului sau chiar la declararea sa, caz n care se poate omite specificarea
lungimii irului ( irul va avea un caracter n plus fa de num rul caracterelor
utilizate la ini ializare). Dac irului i se atribuie valoare caracter cu caracter,
atunci programatorul trebuie s adauge manual terminatorul de ir '\0'.
Instruc iunile urm toare eviden iaz trei tipuri de ini ializare:
char prenume[8]="Adriana";
char prenume[]="Adriana";
char prenume[8]={'A','d','r','i','a','n','a','\0'};
De i un ir de caractere este un tablou, nu este necesar accesarea sa loca ie cu
loca ie. El poate fi manipulat ca un ntreg, a a cum se poate observa i din
136

8 iruri de caractere
primele dou ini ializ ri f cute mai devreme. Func iile care l prelucreaz pornesc de la primul s u caracter (a c rui adres este con inut n numele irului) i
merg pn la caracterul nul (prin care se specific sfr itul irului). De aceea
este foarte important s nu se omit acest ultim caracter atunci cnd irul este
construit din caractere individuale, a a cum este cazul n cea de a treia ini ializare de mai sus.
Opera iile de intrare/ie ire asupra irurilor se pot face cu func iile gets() i
scanf(), respectiv puts() i printf(). Descriptorul de format pentru
func iile scanf() i printf() este "%s". Datorit faptului c numele unui
tablou con ine adresa de memorie a primului s u element, variabilele de tip ir
nu au nevoie de operatorul de adresare (&) atunci cnd sunt citite utiliznd
func ia scanf().
Prin intermediul programului 8.2.1 se declar un ir, se cite te de la tastatur
valoarea sa i se afi eaz pe ecran. Aten ie, func ia scanf() cite te pn la
ntlnirea unui spa iu, iar gets() pn la apari ia unei linii noi (Enter).
Programul 8.2.1
#include <stdio.h>
#include <ctype.h>
void main(void){
char nume[30];
printf("Introduceti numele ");
scanf("%s", nume);
//sau:
//gets(nume);
//daca numele contine spatii
printf("Numele este: %s", nume);
}
Neexistnd un tip de dat dedicat irurilor de caractere, nu exist nici operatori
pentru iruri. Cu alte cuvinte, instruc iuni de genul if(sir1==sir2)sau
sir="Abc"+"def"; sunt imposibile n limbajul C. Prelucrarea irurilor
(copiere, concatenare, comparare) se face prin intermediul unor func ii care
apar in fi ierului antet <string.h>. n continuare sunt descrise cteva dintre
aceste func ii [BH92].
int strlen(const char *s);

137

Programarea calculatoarelor
Returneaz lungimea irului s, f r a lua n considerare terminatorul de ir.
Programul 8.2.2 eviden iaz modul n care poate fi utilizat aceast func ie. Pe
ecran vor fi afi ate n urma rul rii programului valorile 14 i 17 (lungimile
celor dou iruri).
Programul 8.2.2
#include <stdio.h>
#include <string.h>
void main(void){
char nume[]="Dennis Ritchie";
int l;
l=strlen("Bell Laboratories");
printf("%d, %d", strlen(nume), l);
}
char *strcpy(char *destinatie, const char *sursa);
Func ia este folosit pentru a face atribuiri ntre dou iruri, copiind un ir surs
ntr-un ir destina ie. Se returneaz irul destina ie i se presupune c acesta a
fost declarat de o lungime suficient astfel nct s poat g zdui irul surs (n
caz contrar, chiar dac nu apar erori de compilare, programul poate func iona
defectuos). Aceast func ie este necesar deoarece n limbajul C atribuirile de
iruri nu se pot face scriind simplu sir1=sir2. Programul 8.2.3 este un scurt
exemplu care utilizeaz aceast func ie. Pe ecran se va afi a textul abcdefg.
Se remarc faptul c func ia strcpy() produce modificarea con inutului
irului destina ie (cu pierderea con inutului ini ial al acestui ir), n timp ce irul
surs r mne neschimbat (de altfel irul surs este declarat constant n prototipul func iei).
Programul 8.2.3
#include <stdio.h>
#include <string.h>
void main(void){
char dest[20];
char surs[] = "abcdefg";
strcpy(dest, surs);
printf("%s", dest);
}
char *strcat(char *destinatie, const char *sursa);
138

8 iruri de caractere
Prin intermediul acestei func ii se realizeaz concatenarea (lipirea) a dou iruri
de caractere. Adresa irului destina ie va fi returnat ; el va con ine rezultatul
concaten rii i trebuie s aib o lungime care s -i permit stocarea noului ir.
Programul 8.2.4 concateneaz variabila sir1 cu un spa iu; la rezultat se concateneaz apoi variabila sir2, ob inndu-se textul Programare C.
Programul 8.2.4
#include <stdio.h>
#include <string.h>
void main(void){
char sir1[20]="Programare";
char sir2[]="C";
strcat(sir1, " ");
strcat(sir1, sir2);
printf("%s", sir1);
}
int strcmp(const char *s1, const char *s2);
Aceast func ie este utilizat pentru a compara dou iruri de caractere (se are
n vedere ordinea lexicografic ). Func ia este case sensitive, adic face diferen
ntre litere mari i litere mici (literele mici au cod ASCII mai mare dect literele
mari, iar rezultatul func iei va ine cont de acest aspect). Valoarea returnat este
un num r ntreg cu urm toarea semnifica ie:
o o valoare negativ dac irul s1 este mai mic dect irul s2
(calculator este mai mic dect tast );
o 0 dac

irurile s1 i s2 sunt identice;

o o valoare pozitiv dac

irul s1 este mai mare dect irul s2.

Programul 8.2.5 compar parola introdus de utilizator cu parola setat prin


program, afi nd un mesaj corespunz tor. Parolele sunt salvate ca iruri de
caractere.
Programul 8.2.5
#include <stdio.h>
#include <string.h>
void main(void){
char parola[20]="Secret!";
char parolaCitita[20];
139

Programarea calculatoarelor

gets(parolaCitita);
if(strcmp(parola, parolaCitita)==0)
printf("Parola corecta. Bine ati venit!");
else
printf("Parola incorecta");
char *strchr(const char *s, int c);

Func ia caut caracterul c n irul s. Dac l g se te returneaz un pointer c tre


prima sa apari ie, altfel returneaz valoarea null.
char *strrchr(const char *s, int c);
i n acest caz se caut caracterul c n irul s, dar parcurgerea se face de la
dreapta la stnga, prin urmare se va returna adresa ultimei apari ii (sau null
dac n irul s nu apare caracterul c).
char *strstr(const char *s1, const char *s2);
Caut irul s2 n irul s1. Returneaz un pointer care indic adresa lui s2 n
s1 sau null dac s2 nu exist n s1.
Programul 8.2.6 este un exemplu de utilizare a precedentelor trei func ii. Se
consider irul de caractere "Programare C" i se extrag din el trei sub iruri: primul ncepe acolo unde apare prima oar caracterul 'r', al doilea ncepe
acolo unde apare ultima oar caracterul 'r', iar cel de al treilea ncepe acolo
unde apare irul "gram". Prin urmare pe ecran se va afi a:
Substringul 1: "rogramare C"
Substringul 2: "re C"
Substringul 3: "gramare C"
Programul 8.2.6
#include <stdio.h>
#include <string.h>
void main(void){
char str1[] = "Programare C", str2[] = "gram";
char substr1[20], substr2[20], substr3[20];
char ch='r';
strcpy(substr1,strchr(str1,ch));
strcpy(substr2,strrchr(str1,ch));
strcpy(substr3,strstr(str1,str2));
140

8 iruri de caractere
printf("\nSubstringul 1: \"%s\"", substr1);
printf("\nSubstringul 2: \"%s\"", substr2);
printf("\nSubstringul 3: \"%s\"", substr3);
}
char *strncpy(char *dest,const char *sursa, int n);
Func ionarea este similar cu a func iei strcpy(), cu diferen a c se copiaz
doar maxim n caractere din irul surs n irul destina ie. Aceast func ie poate
fi folosit i pentru a extrage un substring din interiorul unui string (nu doar de
la nceputul s u) dac la adresa irului surs se adaug un num r care specific
indicele de unde se ncepe copierea (de exemplu, strncpy(dest, surs +3, 10); va ignora primele trei caractere din surs i va realiza copierea
ncepnd cu al patrulea). Dac valoarea n (ultimul argument al func iei) nu
surprinde i terminatorul irului surs , atunci acesta trebuie ad ugat manual
(dest[n]='\0';).
char *strncat(char *dest,const char *sursa, int n);
Func ionarea este similar cu a func iei strcat(), cu diferen a c se concateneaz doar maxim n caractere de la irul surs la irul destina ie.
int strncmp(const char *s1, const char *s2, int n);
Func ionarea este similar cu a func iei strcmp(), cu diferen a c se compar
doar primele maxim n caractere ale celor dou iruri. Func ia este case
sensitive.
int stricmp(const char *s1, const char *s2);
Func ionarea este similar cu a func iei strcmp(), doar c nu se face diferena ntre litere mari i mici, prin urmare func ia nu este case sensitive ( irurile
"ABC" i "abc" vor fi considerate identice de aceast func ie).
int strnicmp(const char *s1,const char *s2, int n);
Func ionarea este similar cu a func iei strncmp(), doar c nu se face diferen a ntre litere mari i mici, prin urmare func ia nu este case sensitive.
Func ii de conversie acestea sunt folosite pentru a transforma un ir de
caractere ntr-un alt tip de dat (de obicei ntr-un num r) i invers. Ele fac
parte din fi ierul antet <stdlib.h>.
o int atoi(const char * str );
141

Programarea calculatoarelor
Func ia transform irul primit ca argument ntr-un num r ntreg. Mai nti
func ia ignor spa iile de la nceputul irului (dac acestea exist ), apoi interpreteaz un eventual semn plus sau minus, dup care transform urm toarele caractere ntr-un num r ntreg (dac acestea au o astfel de semnifica ie). n momentul n care g se te un caracter care nu poate fi transformat, func ia se opre te, returnnd num rul ob inut pn atunci i ignornd restul irului. Dac irul
nu ncepe cu o secven care s poat fi transformat n num r ntreg, atunci
func ia returneaz zero.
o long int atol(const char * str );
Are o func ionare asem n toare cu func ia atoi(), cu diferen a c returneaz
o variabil de tip long int.
o double atof(const char * str );
Func ioneaz similar cu func ia atoi(), dar transform
irului) ntr-un num r real (de tip double).

irul (sau parte a

o char *itoa(int val, char * sir, int baza);


Aceasta nu este o func ie standard, dar este acceptat de unele compilatoare. Cu
ajutorul ei se transform un num r ntreg ntr-un ir de caractere. Num rul este
primul argument al func iei, irul ob inut prin transformare este returnat de
func ie i este de asemenea salvat n cel de al doilea argument. Al treilea argument al func iei specific baza care trebuie folosit pentru conversie (de exemplu 10).
Programul 8.2.7 utilizeaz func iile atoi() i itoa() pentru a converti un
ir ntr-un ntreg i dou numere ntregi n iruri de caractere (al treilea ir este
reprezentarea n baz 2 a celui de al treilea num r). n urma rul rii programului,
pe ecran se va afi a:
numar1=-987, sir1=-987
numar2=12345, sir2=12345
numar3=7, sir3=111
Programul 8.2.7
#include <stdlib.h>
#include <stdio.h>
void main(void){
int numar1, numar2=12345, numar3=7;
char sir1[25]="-987", sir2[25], sir3[25];
142

8 iruri de caractere
numar1=atoi(sir1);
itoa(numar2, sir2,
itoa(numar3, sir3,
printf("numar1=%d,
printf("numar2=%d,
printf("numar3=%d,

10);
2);
sir1=%s\n",numar1,sir1);
sir2=%s\n",numar2,sir2);
sir3=%s",numar3,sir3);

}
Chiar dac de obicei un ir de caractere este tratat ca un ntreg, el poate fi analizat sau prelucrat i caracter cu caracter datorit faptului c este un tablou. Programul 8.2.8 verific dac un ir de caractere citit de la tastatur este palindrom
(cuvnt identic cu inversul s u: cojoc, 123321, aerisirea, abc7cba,
capac, rar). Pentru aceasta trebuie verificat simetria caracterelor fa de
mijlocul irului. Se declar o variabil ntreag numit palindrom, c reia i se
d valoarea ini ial 1, considerndu-se c irul este palindrom. n momentul n
care se va constata c irul nu este palindrom, variabila va primi valoarea 0.
Algoritmul ncepe prin determinarea lungimii irului de caractere (utiliznd
func ia strlen()). Apoi se parcurge irul caracter cu caracter pn la jum tate i se compar caracterele simetrice fa de mijloc (primul cu ultimul, al doilea cu penultimul i a a mai departe). Atunci cnd se g se te o pereche de
caractere care nu sunt identice, variabila palindrom prime te valoarea 0 i se
ncheie verificarea ie indu-se din for prin apelul instruc iunii break. Dac la
ie irea din for variabila palindrom i-a p strat valoarea 1, nseamn c
toate caracterele irului sunt simetrice fa de mijlocul s u, prin urmare irul
este palindrom; altfel, nu.
Programul 8.2.8
#include <stdio.h>
#include <string.h>
void main(void){
char sir[25];
int palindrom=1;
int i, n;
printf("Introduceti sirul: ");
gets(sir);
n=strlen(sir);
for(i=0;i<n/2;i++)
if(sir[i]!=sir[n-i-1]){
palindrom=0;
143

Programarea calculatoarelor
break;
}
if(palindrom)
printf("Sirul este palindrom.");
else
printf("Sirul nu este palindrom.");
}

8.3 Probleme propuse


A. Specifica i unde este gre eala.
1. Se dore te declararea i ini ializarea unei variabile de tip caracter.
char caracter="A";
2. Se atribuie valoarea 'a' unei variabile de tip caracter i apoi se afi eaz
acea variabil .
char caracter='a';
printf("%d",caracter);
3. Se dore te declararea i ini ializarea unei variabile de tip ir.
char sir[5]="Programare C";
4. Se dore te compararea a dou
if(s1==s2)
//ceva
else
//altceva

iruri s1 i s2

B. Se consider urm toarele sec iuni de program. Specifica i ce se ntmpl n


timpul rul rii acestora.
5. char tasta;
do{
tasta=getch();
}while(toupper(tasta)!='X');
6. char s1[10], s2[10];
int fanion;
strcpy(s1,"abc"); strcpy(s2,"abc");
if(strcmp(s1,s2))
fanion=1;
else
144

8 iruri de caractere
fanion=2;
printf("%d",fanion);
7. char sir[25]={'a','b','c','\0','1','2','3'};
printf("%s, %d",sir,strlen(sir));
8. char s1[10], s2[10];
strcpy(s1,"abc"); strcpy(s2,"123");
if(strcmp(s1,s2)==0)
strcpy(s1,s2);
else
strcat(s1,s2);
printf("%s, %s",s1,s2);
C. Alege i r spunsul corect (unul singur).
9. Care dintre urm toarele func ii poate fi aplicat unei variabile de tip caracter?
a) isalnum();
b) isspace();
c) toupper();
tolower(); e) toate r spunsurile sunt corecte.

d)

10. Fie dou iruri a="abra" i b="cadabra". Dup execu ia instruc iunii strcat(a,b); variabilele a i b vor avea urm toarele valori:
a) a="abra", b="cadabra";
b) a="abra si cadabra",
b="cadabra";
c) a="abracadabra", b="cadabra";
d)
a="abra
cadabra", b="cadabra";
e) a="abra",
b="abracadabra".
11. Fie dou iruri s1="abc" i s2="abc" i dou variabile ntregi a=0
i
b=0.
Se
execut
urm toarea
secven
de
cod:
if(strcmp(s1,s2)==0) a++; else b+=1;. Ce valori vor
avea variabilele a i b dup aceast execu ie?
a) a=0, b=0;
b) a=1, b=0;
toate r spunsurile sunt gre ite.

c) a=1, b=1;

d) a=0, b=1;

e)

12. Care dintre urm toarele func ii poate fi utilizat pentru a determina lungimea unui ir de caractere?
a) strlength(); b) length();
strlen(); e) len().

c) String.Len();

13. Care dintre urm toarele opera ii este posibil cu dou


145

iruri s1 i s2?

d)

Programarea calculatoarelor
a) s=s1+s2; b) s=s1-s2;
toate r spunsurile sunt gre ite.

c) s=s1*s2;

d) s=s1/s2;

e)

14. Un ir de caractere este:


a) un tip de dat ; b) un tablou de caractere;
func ie; e) un program.
15. Func ia care concateneaz dou

c) un operator;

d) o

iruri de caractere este:

a) strcat();
b) strconcatenate();
te(); d) strconc(); e) conc().

c) concatena-

16. Care dintre urm toarele func ii este case sensitive?


a) strcpy(); b) strcat();
e) stricmp().

c) strlen();

17. Care dintre urm toarele instruc iuni copiaz


a) strcpy(s1,s2);
s2==s1; e) niciuna.

d) strcmp();

irul s1 n irul s2?

b) strcpy(s2,s1);

c) s2=s1;

d)

D. S se scrie programe pentru rezolvarea urm toarelor probleme.


18. S se citeasc de la tastatur ntr-un ir de caractere prenumele i numele unei persoane (ambele introduse pe aceea i linie).
19. S se citeasc , n variabile separate, prenumele i numele unei persoane.
S se concateneze aceste valori f r a se pierde vreuna dintre ele i s se
afi eze numele complet.
20. Se introduce de la tastatur un ir de caractere. S se numere cte cifre,
cte litere mici i cte litere mari con ine irul.
21. Se cite te un ir de caractere. S se tip reasc
ga.

irul de la dreapta la stn-

22. S se determine frecven a de apari ie a unui caracter ntr-un text.


23. Se citesc de la tastatur 10 cuvinte. S se afi eze un avertisment pentru
cele care sunt identice cu primul cuvnt.
24. n dou iruri se citesc prenumele i numele unei persoane. S se modifice irurile astfel nct prenumele s aib prima liter mare i restul
mici, iar numele s aib toate literele mari.

146

8 iruri de caractere
25. Se citesc de la tastatur numele mai multor studen i i se stocheaz
ntr-o matrice (fiecare nume pe cte un rnd). S se caute un student n
aceast matrice (numele s u e citit de asemenea de la tastatur ).
Indica ie: Rndurile matricei vor fi accesate ca stringuri, nu caracter cu
caracter.

147

Capitolul 9 Pointeri
Pointerii sunt esen iali n programarea C, ei avnd leg tur att cu tablourile i
cu irurile de caractere, studiate n capitolele anterioare, ct i cu func iile i cu
tipurile definite de utilizator, care vor fi abordate n capitolele urm toare. De
asemenea, accesarea fi ierelor i alocarea dinamic a memoriei sunt strict legate
de pointeri. Pentru un bun programator este esen ial s poat utiliza corect
aceste variabile.
Se consider c pointerii reprezint una dintre cele mai puternice caracteristici
ale limbajului C. Pe de alt parte ns ei sunt o unealt foarte periculoas aflat
la ndemna oricui. Pointerii neini ializa i sau ini ializa i cu valori incorecte pot
duce la apari ia unor erori greu de localizat n program sau chiar la disfunc ionalit i ale sistemului de operare [HS98], [CH96].

9.1 Variabile pointer


Un pointer este o variabil care con ine adresa de memorie a unei alte variabile.
Se spune despre un pointer c indic (n englez point) c tre o variabil . Deoarece pointerii sunt variabile mai speciale, ei au nevoie i de o sintax mai special care s permit att manipularea loca iilor de memorie pe care le stocheaz ,
ct i a valorilor de la acele adrese [PT12]. Compilatorul trebuie s fie i el
informat c o anumit variabil este de tip pointer. Declararea unei variabile
pointer se face utilizndu-se un tip de dat (orice tip din C) i dndu-i-se un
nume variabilei, nume precedat de operatorul unar asterisc (*). Forma general
pentru declararea unui pointer este:
tip *nume_pointer;
Tipul pointerului define te tipul de variabile care pot fi indicate de acel pointer
[HS98]. Este foarte important ca un pointer s fie corect declarat pentru c
opera iile cu pointeri (a a cum se va vedea mai trziu n acest capitol) in cont
de tipul de baz al pointerului.
mpreun cu pointerii se folosesc doi operatori speciali [HS98]:
& Operatorul de adresare (ampersand) este un operator unar i returneaz
adresa de memorie a operandului s u. Instruc iunea p=&nota1; atribuie
pointerului p adresa variabilei nota1. Aceast adres este loca ia n care
variabila este memorat .

9 Pointeri
* Operatorul de dereferen iere (asterisc) este de asemenea un operator
unar, fiind complementul operatorului de adresare. Acesta returneaz valoarea de la adresa indicat de operandul s u. Instruc iunea nota2=*p; va
atribui variabilei nota2 valoarea aflat la adresa indicat de pointerul p.
A adar ini ializarea unui pointer se face printr-o instruc iune cu forma general :
nume_pointer=&nume_variabil ;
nainte de ini ializare un pointer are valoarea NULL. El nu indic spre nicio
adres de memorie, spre niciun element.
Forma general a unei instruc iuni prin care se acceseaz valoarea memorat la
adresa indicat de un pointer este:
nume_variabila=*nume_pointer;
Un exemplu referitor la felul n care se petrec aceste lucruri n memorie este
prezentat n figura 9.1.1 prin care se reflect urm toarele linii de cod:
float nota, *p; //se declar o variabil obi nuit

i un pointer

p=&nota; //pointerul va stoca adresa variabilei nota


nota=9.5; //nota i implicit *p vor avea valoarea 9.5
Adresele de memorie

Valorile variabilelor din memorie

..
.
65528

9.5

.
.
.
65520

nota

*p

65528

..
.

Figura 9.1.1 Reprezentarea pointerilor

149

Programarea calculatoarelor
Pentru a accesa valoarea notei se poate folosi fie direct variabila nota, fie
pointerul dereferen iat (adic *p). Prin urmare urm toarele dou instruc iuni au
acela i efect, tip rirea notei pe ecran:
printf("%.2f", nota);
printf("%.2f", *p);
Programul 9.1.1 prezint acest exemplu n ntregime. Se remarc faptul c i
nota i pointerul p au acela i tip pentru a fi posibil atribuirea p=&nota.
Pointerii trebuie s aib un tip corespunz tor datelor spre care indic . Adic nu
este firesc ca un pointer de tip int s stocheze adresa unei variabile de tip
float (chiar dac unui pointer i se poate atribui orice adres ).
Programul 9.1.1
#include <stdio.h>
void main(void){
float nota, *p;
p=&nota;
nota=9.5;
printf("%.2f",nota);
printf("\n%.2f",*p);
}

9.2 Opera ii cu pointeri


Un pointer poate fi folosit ca membru drept ntr-o opera ie de atribuire, dnd
valoarea sa unui alt pointer. Acest lucru este eviden iat n programul 9.2.1.
Pointerul p2 va con ine i el adresa variabilei nota, datorit faptului c lui p2
i se atribuie adresa stocat de p1, adic adresa variabilei nota. Prin urmare
valoarea notei poate fi ob inut i prin intermediul pointerului p2.
Programul 9.2.1
#include <stdio.h>
void main(void){
float nota=9.5,*p1,*p2;
p1=&nota;
p2=p1;
printf("%.2f",*p2); //se afiseaza nota
}

150

9 Pointeri
Asupra pointerilor se pot aplica i opera iile aritmetice de adunare i de sc dere
(doar acestea). Aceste opera ii depind de tipul pointerului pentru c adunarea i
sc derea se fac cu un num r ntreg de octe i propor ional cu num rul de octe i
utiliza i de tipul de dat pentru reprezentarea variabilelor.
Ca exemplu se consider un pointer p de tip ntreg; tipul ntreg este reprezentat
n anumite cazuri pe doi octe i. Dac pointerul p are valoarea 65522, atunci
incrementarea lui (adic opera ia p++) l va transforma n 65524, f cndu-l s
indice spre urm toarea loca ie care con ine un ntreg. Decrementarea (p--) va
aduce valoarea pointerului de la 65522 la 65520, indicnd spre loca ia precedent . Prin urmare un pointer se va incrementa sau se va decrementa cu un
num r de octe i egal cu lungimea tipului de dat a c rui adres o con ine: 1
octet pentru char, 2 sau 4 octe i pentru int, 4 octe i pentru long int, 4
octe i pentru float, 8 octe i pentru double i a a mai departe.
La pointeri se pot de asemenea aduna sau sc dea numere ntregi. De exemplu,
dac p este un pointer de tip float i asupra lui se executa opera ia p=p+8,
practic pointerul ca avansa cu 8x4=32 loca ii de memorie, indicnd spre elementul de tip float care se afl acolo. Evident, asupra pointerilor nu se pot
face opera ii de adunare sau sc dere cu numere float sau double (adic
opera ii de genul p=p+4.5 sunt imposibile cu pointeri).
Doi pointeri pot fi compara i prin intermediul unei expresii rela ionale. O
instruc iune de genul if(p1==p2) va verifica dac cei doi pointeri sunt identici din punct de vedere al adresei de memorie pe care o con in.

9.3 Pointerii i alte elemente


Exist o leg tur strns ntre pointeri i tablouri deoarece elementele unui
tablou sunt amplasate n loca ii de memorie consecutive. Dac se consider , de
exemplu, tabloul
int tab[15]={10, 12, -7, 17, 29};
elementele lui pot fi accesate prin intermediul unor indici: tab[0] este primul
num r, tab[1] urm torul, tab[4] ultimul.
Pointerii pot fi de asemenea utiliza i pentru a face referire la elementele unui
tablou. Mai nti se declar un pointer de acela i tip cu tabloul:
int *p;
151

Programarea calculatoarelor
Apoi pointerul trebuie s indice spre primul element al tabloului:
p=&tab[0];
Adresa primului element al unui tablou este con inut chiar n numele tabloului.
Prin urmare instruc iunea urm toare are acela i efect cu precedenta:
p=tab;
Accesarea elementelor tabloului cu ajutorul pointerului se face astfel: *p este
con inutul primului element, *(p+1) este al doilea, *(p+4) este ultimul.
Programul 9.3.1 afi eaz elementele unui tablou att prin intermediul indicilor
s i, ct i cu ajutorul unui pointer. n prima parte, printr-un for, se parcurge
tabloul n stilul clasic i se afi eaz elementele sale (tab[i]). n partea a doua
se porne te cu pointerul p de la primul element al tabloului; se tip re te cte un
element al tabloului, apoi se incrementeaz pointerul, acesta indicnd spre
urm toarea loca ie a tabloului. Acest lucru se repet atta timp ct pointerul
con ine o valoare nenul . Datorit faptului c doar primele 5 loca ii ale tabloului
au fost ini ializate, restul au primit valoarea 0, deci instruc iunea while se
ncheie dup primele 5 itera ii. O alt solu ie pentru instruc iunea while este
r mnerea n bucl atta timp ct pointerul p indic o adres mai mic dect
adresa de nceput a tabloului la care se adaug num rul de elemente utile
(p<tab+5). Manipularea tablourilor cu ajutorul pointerilor trebuie f cut cu
aten ie, deoarece n acest caz compilatorul C nu verific limitele tabloului i
exist riscul ca spa iul tabloului s fie dep it i s se suprascrie (sau n general,
s se acceseze) zonele adiacente de memorie.
Programul 9.3.1
#include <stdio.h>
void main(void){
int tab[15] = {10, 12, -7, 17, 29};
int *p;
int i;
for (i = 0; i < 5; i++)
printf("%d ",tab[i]);
printf("\n");
p = tab;
while(*p) // sau while(p<tab+5)
printf("%d ",*(p++));
}
152

9 Pointeri
Pointerii pot fi de asemenea utiliza i n lucrul cu irurile de caractere. Majoritatea func iilor care prelucreaz iruri primesc argumentele sub form de pointeri, transmi ndu-se astfel adresa primului caracter din ir. Aici un rol important l are marcatorul '\0' f r de care nu s-ar putea stabili sfr itul irului.
Programul 9.3.2 ini ializeaz un ir de caractere. Adresa primului s u element o
atribuie unui pointer. Se afi eaz apoi irul de caractere att prin intermediul
variabilei sir, ct i cu ajutorul pointerului p.
Programul 9.3.2
#include <stdio.h>
void main(void){
char sir[15]="Programare C";
char *p;
p = sir;
printf("%s\n",sir);
printf("%s",p);
}
Pentru c pointerii sunt deseori utiliza i mpreun cu irurile de caractere, n
continuare este prezentat nc un exemplu din aceast zon (programul 9.3.3).
Se dore te c utarea primei apari ii a unui caracter ntr-un ir i afi area indicelui
acestei apari ii. Pentru aceasta se declar un ir de caractere, str, folosindu-se
varianta clasic (tablou de caractere) i se memoreaz n el textul "Programare C". Un alt ir de caractere, ptr, este declarat ca pointer. Acestuia i se
atribuie adresa primei apari ii a caracterului 'r' memorat n variabila c. Dac
se scade din adresa primei apari ii a caracterului n ir (adic din ptr) adresa de
nceput a irului (adic str) se ob in num rul de loca ii aflate ntre cele dou
adrese, adic exact indexul primei apari ii a caracterului c n irul str. Dac
n irul str nu apare caracterul memorat n variabila c, atunci pointerul ptr
va avea valoarea NULL i se va afi a un mesaj corespunz tor.
Programul 9.3.3
#include <stdio.h>
#include <string.h>
void main(void){
char str[20];
char *ptr, c = 'r';
strcpy(str, "Programare C");
153

Programarea calculatoarelor

ptr = strchr(str, c);


if (ptr)
printf("\'%c\' are indicele: %d", c, ptr-str);
else
printf("Caracterul nu a fost gasit");

Utilizarea pointerilor nu se opre te aici. n capitolele urm toare se vor descrie


leg turile dintre pointeri i func ii (ace tia sunt folosi i ndeosebi la transmiterea parametrilor prin adres ) sau tipuri definite de utilizator (de exemplu
structurile pot fi accesate prin intermediul pointerilor).

9.4 Probleme propuse


A. Specifica i unde este gre eala.
1. Se dore te declararea unui pointer de tip ntreg.
int &m;
2. int *m, x=3;
m=*x;
3. int *m, x;
m=&x;
*m=3;
x=&m;
4. float medie=8.75;
int *m;
m=&medie;
5. float *p, x=9.5;
p=&x;
if(p+0.5!=NULL) printf("Numar valid");
B. Se consider urm toarele secven e de cod. Specifica i ce va fi afi at pe
ecran dup rularea acestora.
6. int *p, a=17;
p=&a;
printf("%d",*p);

154

9 Pointeri
7. int *p, tab[3]={21, -12, 103};
p=tab;
printf("%d",*(p+1));
8. char *s1="Abra", *s2="cadabra";
printf("%s",strcat(s1,s2));
C. Alege i r spunsul corect (unul singur).
9. Dac se dore te ca n loca ia de memorie indicat de pointerul int *p
s se salveze valoarea 7, atunci se va scrie:
a) *p=7;

b) p=7;

c) &p=7;

d) p=&7;

e) p=*7.

10. Care dintre urm torii operatori nu pot fi aplica i pointerilor?


a) *;

b) &;

c) ++;

d) --;

e) /.

11. Care dintre urm toarele afirma ii este fals ?


a) & este operatorul de adresare;
b) * este operatorul pentru
dereferen iere; c) * poate fi utilizat pentru a nmul i doi pointeri; d)
& nu poate fi utilizat pentru a nmul i doi pointeri; e) toate r spunsurile
sunt gre ite.
12. Care dintre urm toarele secven e reprezint adresa unei variabile indicat de pointerul p?
a) p;

b) &p;

c) *p;

d) &&p;

e) niciuna.

13. Care dintre urm toarele secven e reprezint valoarea unei variabile indicat de pointerul p?
a) p;

b) &p;

c) *p;

d) &&p;

e) niciuna.

14. Se consider secven a de cod float *p1, *p2, x=3, y=4;


p1=&x; p2=&y;. Care dintre urm toarele instruc iuni nu se poate
executa?
a) p1=p1+7.25;
b) p1=p1+7;
c) p1=p1-7;
if(p1==p2); e) toate instruc iunile sunt corecte.

d)

D. S se scrie programe pentru rezolvarea urm toarelor probleme.


15. Se citesc de la tastatur dou note (nota la examen i nota pe laborator)
i se re in n variabile pointer. S se afi eze nota final (nota la examen
are pondere 2/3 din nota final , iar nota pe laborator 1/3).
155

Programarea calculatoarelor
16. Se introduc de la tastatur elementele unui tablou de numere ntregi. S
se parcurg acest tablou cu ajutorul unui pointer i s se afi eze valoarea
primului element negativ.
17. Se citesc n dou variabile char * numere, respectiv prenumele unui
student. S se creeze un al treilea ir de caractere (tot de tip pointer la
caracter) care s con in prenumele urmat de nume (desp r ite printr-un
spa iu).
18. Se cite te un text t ntr-un ir de caractere i dou cuvinte c1 i c2. S
se afi eze irul ob inut prin nlocuirea n t a tuturor apari iilor lui c1 cu
c2.

156

Capitolul 10 Func ii definite de utilizator


Rezolvarea unei probleme complexe nu se poate face ntr-un singur grup de
instruc iuni, plasat n func ia main(). Acest lucru ar nsemna pe de o parte
scrierea unui program foarte lung i nclcit, iar pe de alt parte repetarea inutil
a unor sec iuni care execut acelea i calcule (eventual cu date diferite). Pentru
eliminarea acestor dezavantaje se mparte problema care trebuie rezolvat n
mai multe sub-probleme i se scriu buc i separate de cod pentru fiecare subproblem care are caracteristici distincte. Aceste buc i de cod sunt de fapt
func iile.
Un program C poate con ine dou categorii de func ii:
func iile predefinite (sau func ii de bibliotec )
o sunt deja implementate pentru rezolvarea unor probleme simple
i bine precizate;
o fac parte din biblioteca standard a limbajului C, prin urmare utilizarea lor n program necesit introducerea unei directive #include urmat de numele fi ierului antet care con ine func ia;
o exemple: func ii matematice (math.h): sqrt(), exp();
func ii pentru gestionarea opera iilor de intrare/ie ire
(stdio.h, conio.h): printf(), scanf(); func ii pentru
prelucrarea irurilor de caractere (string.h): strlen(),
strcpy();
func ii definite de utilizator
o sunt scrise de c tre dezvoltatorul programului;
o folosirea lor face programul mai clar, mai u or de corectat, de ntre inut, de modificat i permite reutilizarea codului.
Func iile reprezint a adar o caracteristic important a limbajului C, ele fiind
practic locul n care se desf oar activitatea unui program [HS98]. Cea mai
bun solu ie, atunci cnd e vorba de structurarea programelor C, este mp r irea
lor n unit i mai mici, adic n func ii. Aceste blocuri sunt u or de manevrat i
pot fi utilizate n diverse configura ii [CH96].
O func ie este o secven de cod care are un nume i care execut o anumit
sarcin . Un program C trebuie s aib cel pu in o func ie (func ia main(), f r
de care nu se poate executa), dar poate con ine multe alte func ii.

Programarea calculatoarelor

10.1 Func ii definite de utilizator


Pentru a lucra cu func ii definite de utilizator trebuie parcur i mai mul i pa i:
n primul rnd compilatorul trebuie n tiin at c n program urmeaz s fie
definit o func ie; acest lucru se realizeaz prin prototipul func iei cteva
caracteristici ale func iei, care trebuie specificate nainte de nceputul funciei main();
descrierea func iei con ine defini ia i corpul func iei i reprezint locul
unde apare codul pentru care func ia este creat ; aceast implementare a
func iei poate fi plasat dup ncheierea func iei main() sau nainte ca
aceasta s nceap (caz n care defini ia se suprapune prototipului);
apelul func iei este de fapt utilizarea func iei n program.

10.1.1 Prototipul unei func ii


Prototipul func iei este primul lucru care trebuie specificat atunci cnd se dore te crearea i utilizarea unei func ii. Prin el se men ioneaz numele func iei,
informa ii despre datele pe care aceasta le prime te din exterior precum i despre rezultatul produs de func ie. Compilatorul va utiliza acest prototip pentru a
verifica dac instruc iunile care se refer la func ie o fac n mod corect (n caz
contrar, se va genera un mesaj de eroare).
Specificarea prototipului unei func ii se face astfel:
tip_val_returnata
nume_functie(tip_arg1
nume_arg1,
tip_arg2 nume_arg2, , tip_argn nume_argn);
unde:
o tip_val_returnata este tipul valorii pe care func ia o returneaz (o trimite napoi spre locul de unde a fost apelat );
o nume_functie este un nume valid, prin care func ia va fi apelat (se supune acelora i reguli ca numele unei variabile: trebuie
s nceap cu o liter sau cu liniu de subliniere, nu poate con ine caracterele #, $ sau spa iu, trebuie evitate cuvintele rezervate
ale limbajului etc.);
158

10 Func ii definite de utilizator


o tip_argi nume_argi specific tipul i numele fiec rui argument pe care func ia l prime te din exterior;
o prototipul este urmat de separatorul ; (punct i virgul ).
Urm toarea linie de cod specific prototipul unei func ii care se nume te media i care va calcula i va returna media aritmetic a primelor n numere
naturale (n este un parametru de tip ntreg pe care func ia l va primi n momentul n care va fi apelat ):
float media(int n);
n cazul n care func ia nu transmite spre exterior un rezultat, atunci se va specifica void ca tip al valorii returnate (se spune c func ia este de tip void).
Urm torul prototip define te o func ie care prime te un argument de tip caracter, dar care nu returneaz nimic:
void o_functie(char a);
Unele compilatoare accept ca n fa a numelui unei func ii s nu apar nimic
(adic se omite specificarea tipului valorii returnate). Aten ie, n acest caz se
consider c func ia va returna o valoare de tip ntreg (a nu se confunda cu o
func ie care nu returneaz nimic i care are specificat void ca tip returnat).
Urm toarea func ie va primi dou argumente (unul de tip float, cel lalt de tip
int) i va returna o valoare de tip ntreg:
alta_functie(float x, int y);

10.1.2 Descrierea unei func ii


Este vorba mai exact despre defini ia i despre corpul func iei. Defini ia trebuie
s fie identic cu prototipul (acela i num r de argumente, acelea i tipuri att
pentru argumente ct i pentru valoarea returnat ), ns nu este urmat de separatorul punct i virgul . Corpul func iei reprezint secven a de cod prin care se
rezolv sarcina pentru care func ia a fost creat . Instruc iunile care formeaz
corpul func iei urmeaz imediat dup defini ia acesteia i sunt ncadrate ntre
acolade. Defini ia i corpul func iei media al c rei prototip a fost specificat
anterior ar putea fi:
float media(int n){
int i;
float suma=0;
159

Programarea calculatoarelor
for(i=1;i<=n;i++)
suma=suma+i;
return suma/n;
}
Despre return
n cazul n care o func ie trebuie s returneze o valoare, atunci n corpul ei
trebuie s existe cel pu in o instruc iune return urmat de valoarea care se
dore te a fi returnat (a a cum se ntmpl n cazul func iei media prezentat
mai sus). Forma general a acestei instruc iuni este:
return [expresie];
Execu ia instruc iunii return are ca efect p r sirea imediat a func iei n care
apare i revenirea la instruc iunea care a produs apelul func iei. Dac func ia
returneaz o valoare, atunci expresia care urmeaz dup return va fi evaluat
i apoi transmis spre exterior. n cazul n care dup return nu urmeaz o
expresie, o variabil sau o valoare sau chiar nu exist return, atunci are loc
doar p r sirea func iei, f r a se returna o valoare (desigur, n acest caz func ia
trebuie s fie de tip void). Urm toarea func ie prime te ca argument un ir de
caractere i l afi eaz n sens invers, f r a returna ns nimic:
void invers(char *s){
int i;
for(i=strlen(s)-1;i>=0;i--)
printf("%c",s[i]);
}
ntr-o func ie pot exista mai multe instruc iuni return; se va executa prima
care va fi ntlnit . Aceste instruc iuni return multiple apar pe ramuri diferite
ale unor instruc iuni condi ionate (de exemplu if else) i prin intermediul lor de returneaz valori distincte, dependent de calea pe care a urmat-o
execu ia programului. Func ia urm toare prime te ca argument un num r real
(float) i returneaz semnul acestuia (-1 dac este negativ, 0 dac e nul
sau 1 dac este pozitiv):
int semn(float x){
if(x<0) return -1;
160

10 Func ii definite de utilizator


else
if(x==0) return 0;
else return 1;
}
Despre argumente
Argumentele (sau parametrii unei func ii) sunt plasate ntre paranteze rotunde i
apar n prototip i n defini ie imediat dup numele func iei. Transmiterea datelor c tre func ii se face prin intermediul acestor argumentelor. Ele pot fi utilizate apoi n func ie, la fel ca orice alt variabil declarat n interiorul func iei.
Fiecare argument are un nume i un tip. Tipul specificat n prototip trebuie s
fie identic cu cel folosit la apelul func iei, numele ns poate s difere. Urm toarea func ie returneaz produsul a dou numere ntregi primite ca argument:
int produs(int x, int y){
return x*y;
}
n cazul n care o func ie nu admite argumente, atunci n prototipul i n definiia func iei va ap rea tipul void n locul listei de argumente. Func ia urm toare
nu prime te argumente (returneaz suma primelor 5 numere naturale):
int suma(void){
int i, s=0;
for(i=1;i<=5;i++)
s=s+i;
return s;
}

10.1.3 Apelul unei func ii


Utilizarea unei func ii presupune apelarea ei. Acest lucru se face foarte simplu,
prin scrierea numelui func iei urmat de parametrii necesari (ace tia vor fi scri i
ntre paranteze rotunde). n programele scrise pn acum, chiar dac nu s-a
161

Programarea calculatoarelor
discutat explicit despre func ii, s-au realizat apeluri ale func iilor de bibliotec .
Urm toarele instruc iuni apeleaz cteva dintre aceste func ii:
printf("Aceasta este o functie de biblioteca");
getch();
sqrt(49);
strlen("text");
n aceea i manier se realizeaz i apelul func iilor definite de utilizator. Urm toarea instruc iune apeleaz func ia invers() care a fost definit anterior i
care afi eaz un ir de caractere de la dreapta la stnga:
invers("Programare C");
Parantezele rotunde care urmeaz dup numele func iei n cadrul apelului s u
sunt obligatorii, chiar dac func ia nu are parametrii. De exemplu, func ia care
calculeaz suma primelor 5 numere naturale (definit anterior) este apelat
corect astfel:
suma();
n cazul n care o func ie returneaz o valoare (a a cum este func ia suma()),
aceast valoare poate fi folosit n mai multe feluri:
este atribuit unei variabile (este membrul drept ntr-o opera ie de atribuire):
x=suma();
face parte dintr-o expresie (apelul func iei apare tot n membrul drept al
unei atribuiri):
medie=suma()/5;
este parametru al unei alte func ii:
printf("Suma este: %d", suma());
apare ntr-o condi ie:
if(suma()>0) printf("Suma este pozitiva");
se pierde, nefiind nici atribuit , nici utilizat ntr-o expresie (evident, folosirea n acest fel a func iei este lipsit de sens):
suma();
n cazul n care func ia trebuie apelat cu parametrii, ace tia pot fi (se va lua ca
exemplu func ia media() descris anterior):
162

10 Func ii definite de utilizator


valori:
a=media(3);
variabile:
n=7;
a=media(n);
expresii:
n=1;
m=2;
a=media(n+m);
Apelul unei func ii nu poate ap rea ca membru stng ntr-o opera ie de atribuire. Instruc iunea urm toare este gre it i va genera o eroare de compilare:
suma()=100; //apel incorect
Nu e obligatoriu ca numele parametrilor de la apelul unei func ii s coincid cu
numele argumentelor din prototipul func iei (doar num rul i tipurile lor trebuie
s fie acelea i). Prin urmare o func ie cu prototipul
void calcul(float x, int y);
poate fi apelat astfel:
calcul(a,b);
Programul 10.1.1 reprezint un exemplu complet n care o func ie este declarat
i apelat . Func ia calculeaz i returneaz media aritmetic a primelor n numere naturale (evident, media se poate calcula doar dac n este diferit de zero).
Programul 10.1.1
#include <stdio.h>
float media(int nr);
void main(void){
int n=2;
if(n!=0)
printf("Media este: %.2f",media(n));
else
printf("Eroare: impartire la zero!");
163

Programarea calculatoarelor
}
float media(int nr){
int i;
float suma=0;
for(i=1;i<=nr;i++)
suma=suma+i;
return suma/nr;
}
Este posibil ca defini ia i corpul unei func ii s apar naintea func iei
main(); n acest caz, defini ia i prototipul se suprapun. Separatorul punct i
virgul de la sfr itul prototipului dispare, pentru c urmeaz corpul func iei
(ntre acolade). Programul 10.1.2 prezint acela i exemplu cu media aritmetic ,
dar plaseaz descrierea func iei media() la nceputul programului. Aten ie,
dac se alegea aceast variant de implementare, atunci func ia main() trebuie
s fie ultima func ie din program.
Programul 10.1.2
#include <stdio.h>
float media(int nr){
int i;
float suma=0;
for(i=1;i<=nr;i++)
suma=suma+i;
return suma/nr;
}
void main(void){
int n=2;
if(n!=0)
printf("Media este: %.2f",media(n));
else
printf("Eroare: impartire la zero!");
}
Este posibil ca apelul unei func ii s fie f cut i n alte func ii, nu doar n func ia
main(). Exemplul 10.1.3 calculeaz tot media aritmetic a primelor n numere
naturale, dar n interiorul func iei media() se face apel la o func ie suma()
164

10 Func ii definite de utilizator


care va returna suma primelor n numere naturale; apoi se calculeaz
neaz media.

i se retur-

Programul 10.1.3
#include <stdio.h>
float suma(int nr){
int i;
float s=0;
for(i=1;i<=nr;i++)
s=s+i;
return s;
}
float media(int nr){
return suma(nr)/nr;
}
void main(void){
int n=2;
if(n!=0)
printf("Media este: %.2f",media(n));
else
printf("Eroare: impartire la zero!");
}
Unul din avantajele majore ale func iilor este legat de faptul c sunt scrise o
singur dat i pot utilizate (apelate) de mai multe ori, oferind rezultate diferite
dac li se transmit parametri diferi i. n programul 10.1.4 func ia semn() este
apelat de trei ori.
Programul 10.1.4
#include <stdio.h>
int semn(float x){
if(x<0) return -1;
else
if(x==0) return 0;
else return 1;
}
165

Programarea calculatoarelor

void main(void){
printf("\n%d", semn(-7.17));
printf("\n%d", semn(0));
printf("\n%d", semn(70));
}
Revenirea din func ie
Dup ce execu ia unei func ii se ncheie, programul continu din locul n care
func ia a fost apelat . Exist dou moduri prin care o func ie i nceteaz execu ia [HS98]:
instruc iunile din func ie sunt executate una cte una, pn cnd se ajunge la
ultima (practic la acolada de ncheiere). Func ia din programul 10.1.5 afieaz un ir de la dreapta la stnga parcurgndu-l caracter cu caracter. Dup
ce irul a fost afi at n ntregime, func ia nu mai are nimic de realizat, deci
se ncheie, revenindu-se n main(), la instruc iunea care urmeaz dup
apelul s u (n acest caz nu mai urmeaz nimic, deci se ncheie i programul).
Programul 10.1.5
#include <stdio.h>
#include <string.h>
void invers(char *s){
int i;
for(i=strlen(s)-1;i>=0;i--)
printf("%c",s[i]);
}
void main(void){
invers("Programare C");
}
execu ia func iei este oprit de apari ia instruc iunii return. Aceasta este
utilizat fie pentru a returna o valoare (caz n care este urmat de acea valoare sau de o expresie), fie pentru a m ri eficien a func iei (de exemplu o
func ie care caut un caracter ntr-un ir i poate ncheia execu ia n momentul n care g se te prima apari ie a caracterului n ir, f r s mai piard
166

10 Func ii definite de utilizator


timpul cu continuarea c ut rii pn la sfr itul irului). O astfel de func ie
poate con ine mai multe instruc iuni return. Func ia din programul 10.1.6
returneaz 1 dac g se te caracterul c utat i 0 n caz contrar.
Programul 10.1.6
#include <stdio.h>
#include <string.h>
int cauta(char *s, char c){
int i;
for(i=0;i<strlen(s);i++)
if(s[i]==c) return 1;
return 0;
}
void main(void){
char sir[20], caracter;
int gasit;
printf("Introduceti sirul: ");
gets(sir);
printf("Introduceti caracterul cautat: ");
scanf("%c", &caracter);
gasit=cauta(sir,caracter);
if(gasit)
printf("Caracterul a fost gasit");
else
printf("Caracterul nu exista in sir");
}

10.1.4 Cmpul de ac iune al variabilelor


n func ie de locul n care este declarat o variabil , ea va avea un anumit cmp
de ac iune [CH96]. Cmpul de ac iune al unei variabile (sau sfera sa de ac iune)
se refer la vizibilitatea variabilei, mai precis la cine o poate vedea (adic
utiliza), cnd este creat i cnd este distrus . Se diferen iaz astfel dou mari
categorii de variabile:
variabile locale:
o sunt declarate n interiorul unei func ii;
167

Programarea calculatoarelor
o sunt create la fiecare apel al func iei;
o sunt distruse n momentul n care execu ia func iei se ncheie;
o sunt disponibile doar n interiorul func iei, orice ncercare de a le
accesa din afara func iei fiind o eroare;
o sunt necesare pentru a izola pe ct posibil func iile ntre ele (n
general o func ie nu trebuie s afecteze alte func ii sau variabilele acestora); o func ie prime te date din exterior prin argumentele sale i trimite valori n exterior prin instruc iuni return; tot
ceea ce se ntmpl n rest, n corpul func iei, are caracter privat.
variabile globale:
o sunt declarate n afara oric rei func ii, la nceputul programului,
dup directivele preprocesor (#include, #define);
o sunt disponibile pe toat durata execu iei programului;
o pot fi accesate i modificate din orice func ie a programului;
o sunt utilizate atunci cnd mai multe func ii din program trebuie
s acceseze o anumit dat ;
o trebuie evitate dac nu e neap rat nevoie de ele pentru c ocup
inutil memoria pe toat durata execu iei programului i pentru c
reduc gradul de generalitate al func iilor care le utilizeaz (funciile respective nu vor putea fi folosite n alte programe pentru c
fac referire la ceva care trebuie definit n exteriorul lor) [HS98].
O func ie p streaz leg tura cu mediul extern prin argumentele sale i prin
variabilele globale. Argumentele pe care o func ie le prime te pot fi tratate ca
variabile locale.
Valorile cu care o func ie este apelat se numesc parametrii actuali. n momentul n care ajung n func ii aceste valori se numesc parametrii formali.
Programul 10.1.7 calculeaz media aritmetic a dou numere. Prin intermediul
lui sunt exemplificate toate aceste tipuri de variabile. Variabila n este o variabil global ; ea e declarat la nceputul programului, e ini ializat n func ia
main() i e folosit n func ia calcul_medie(). Variabilele n1, n2 i
rezultat sunt locale func iei main() i pot fi folosite doar n interiorul
acestei func ii. n1 i n2 sunt de asemenea parametrii actuali transmi i la apelul
func iei calcul_medie(). n momentul n care ajung n func ie, aceste
valori vor ap rea sub numele parametrilor formali a i b. Func ia cal168

10 Func ii definite de utilizator


cul_medie() are de asemenea o variabil local , m, creat n momentul n
care se intr n func ie i distrus la ncheierea func iei.
Programul 10.1.7
#include <stdio.h>
int n; //n - variabila globala
float calcul_medie(float a, float b){
//a, b - parametri formali
float m; //m - variabila locala
m=(a+b)/n;
return m;
}
void main(void){
float n1=5, n2=10, rezultat;
//n1, n2, rezultat - variabile locale
n=2;
rezultat=calcul_medie(n1,n2);
//n1, n2 - parametri actuali
printf("Media este: %.2f", rezultat);
}
Este indicat ca ori de cte ori e posibil s se foloseasc variabile locale i parametri mai de grab dect variabile globale. De exemplu, o func ie care face
suma a dou numere poate fi imaginat n mai multe feluri:
varianta 1 func ia poate fi folosit doar pentru calcularea sumei variabilelor globale x i y:
int x, y;
int suma(void){
return x+y;
}
varianta 2 func ia prime te ca argumente cele dou numere; ea are un
caracter general, iar datorit faptului c este parametrizat , poate fi folosit
la calculul sumei oric ror dou numere:
int suma(int x, int y){
169

Programarea calculatoarelor
return x+y;
}
n cazul n care o variabil local are acela i nume cu o variabil global , toate
trimiterile la numele variabilei realizate n interiorul func iei n care este declarat variabila local se vor referi doar la variabila local i nu vor avea efect
asupra variabilei globale [HS98]. Programul 10.1.8 eviden iaz acest lucru. La
rularea sa se va afi a:
x in main: 10
x in functie_1: 100
x in functie_2: 10
Se declar o variabil global x care este ini ializat cu valoarea 10 n main()
i apoi este tip rit . La rndul s u, functie_1() declar o variabil local cu
acela i nume c reia i d valoarea 100 i pe care o tip re te; x din interiorul
acestei func ii se va referi la variabila local i nu la cea global . Apelul la
functie_2() verific acest lucru, variabila global x avnd aceea i valoare,
10, stabilit ini ial n main().
Programul 10.1.8
#include <stdio.h>
int x;
void functie_1(void){
int x=100;
printf("\nx in functie_1: %d", x);
}
void functie_2(void){
printf("\nx in functie_2: %d", x);
}
void main(void){
x=10;
printf("\nx in main: %d",x);
functie_1();
functie_2();
}
170

10 Func ii definite de utilizator


Variabilele locale, la rndul lor pot fi de dou tipuri:
automatice;
statice.
Dac nu se specific altceva, atunci variabilele locale sunt distruse n momentul
n care func ia i ncheie execu ia. Asta pentru c ele sunt n mod implicit
automatice.
Exist ns posibilitatea de a p stra con inutul unei variabile ntre dou execu ii
ale func iei care a creat-o. Ea poate fi accesat doar de func ia respectiv , dar
con inutul ei se p streaz pn la ncheierea execu iei ntregului program. Cu
alte cuvinte, o variabil local static ofer posibilitatea de a stoca informa ii
ntr-un mod privat (pentru c informa iile sunt disponibile doar func iei n care
variabila e definit ) i n acela i timp permanent (informa iile sunt disponibile
pe parcursul execu iei ntregului program) [BK03]. Acest lucru se realizeaz
utiliznd cuvntul cheie static n fa a declara iei variabilei:
static int contor=0;
Programul 10.1.9 eviden iaz diferen a ntre variabilele statice i cele automatice. Func iile increment1() i increment2() incrementeaz i afi eaz
valoarea unui contor care este ini ializat cu 0 la intrarea n aceste func ii. Ele
sunt apelate din main() n mod repetitiv de 10 ori. Diferen a ntre cele dou
func ii este felul n care este declarat variabila local contor. n func ia
increment1() ea este l sat automatic , iar n func ia increment2()
este declarat static . Acest lucru face ca variabila contor din func ia increment2() s i p streze valoarea de la o execu ie la alta.
n urma execu iei programului, pe ecran se va afi a:
Variabil

automatica:

1 1 1 1 1 1 1 1 1 1
Variabil

statica:

1 2 3 4 5 6 7 8 9 10
Variabila contor este ini ializat cu 0 la intrarea n fiecare din cele dou
func ii. Trebuie specificat faptul c n cazul variabilelor statice aceast linie este
executat doar la primul apel al func iei (acesta este motivul pentru care valoarea variabilei nu este alterat cnd func ia este reapelat ).

171

Programarea calculatoarelor
Programul 10.1.9
#include <stdio.h>
void increment1(void){
int contor=0;
contor++;
printf("%d ",contor);
}
void increment2(void){
static int contor=0;
contor++;
printf("%d ",contor);
}
void main(void){
int i;
printf("Variabila automatica:\n");
for(i=1;i<=10;i++){
increment1();
}
printf("\nVariabila statica:\n");
for(i=1;i<=10;i++){
increment2();
}
}

10.1.5 Modificarea argumentelor unei func ii


Exist dou moduri de a trimite argumentele c tre func ii:
prin valoare;
prin adres .
n mod implicit transmiterea argumentelor se face prin valoare (cu excep ia
tablourilor, despre transmiterea c rora se va discuta separat), ceea ce nseamn
c argumentele folosite la apelul func iei nu pot fi alterate de codul executat n
interiorul func iei. Acest lucru se ntmpl deoarece valoarea parametrului
actual (cel folosit la apel) este copiat n parametrul formal al func iei (parame172

10 Func ii definite de utilizator


tru care are aspect temporar). n interiorul func iei, aceast valoare poate suferi
modific ri, dar datorit faptului c ea este doar o copie a variabilei folosit la
apel, aceste modific ri nu au efect asupra parametrului actual.
Programul 10.1.10 creeaz i ini ializeaz o variabil x n func ia main() i o
transmite apoi func iei trans_valoare() care incrementeaz argumentul
primit. Variabila x este tip rit la revenirea din aceast func ie pentru a se
vedea c i-a p strat valoarea.
Programul 10.1.10
#include <stdio.h>
void trans_valoare(int x){
x++;
}
void main(void){
int x=10;
trans_valoare(x);
printf("x=%d", x); //se tipareste x=10
}
Transmiterea parametrilor prin valoare face ca programele s fie mai compacte
i cu mai pu ine variabile globale (parametrii formali fiind trata i n interiorul
func iei ca variabile locale) [BK03]. Func iile nu au (n aceast modalitate de
transfer al parametrilor) acces la variabilele originale, ci doar la copii ale lor.
Exist ns situa ii n care modificarea parametrilor actuali este necesar , caz n
care ace tia trebuie transmi i prin adres . La apel se transmite adresa unei
variabile, iar n prototipul func iei parametrul este declarat ca pointer i variabila este accesat indirect prin intermediul acestui pointer [BK03]. Acest lucru
face ca modific rile s se realizeze direct asupra variabilei originale.
Programul 10.1.11 eviden iaz transmiterea parametrilor prin adres . Codul este
foarte asem n tor cu cel de la transmiterea prin valoare. Prima diferen care
trebuie notat apare la apelul func iei trans_adresa() care prime te ca
argument adresa variabilei x (&x). Al doilea aspect este legat de prototipul
func iei, n care x este declarat ca pointer (*x). n fine, al treilea lucru vizeaz
felul n care se lucreaz cu x n interiorul func iei (aici intervin opera iile cu
pointeri): prin instruc iunea (*x)++; se acceseaz i se incrementeaz valoarea de la adresa indicat de pointer. Prin urmare modificarea se face chiar asu173

Programarea calculatoarelor
pra variabilei originale, care este ulterior tip rit n main() pentru a se verifica
acest lucru.
Programul 10.1.11
#include <stdio.h>
void trans_adresa(int *x){
(*x)++;
}
void main(void){
int x=10;
trans_adresa(&x);
printf("x=%d", x); //se tipareste x=11
}

10.1.6 Transmiterea tablourilor ca argumente


n ceea ce prive te tablourile, transmiterea lor ca argumente este diferit de a
celorlalte variabile, fiind o excep ie de la regula uzual a transferului prin valoare [HS98]. Datorit faptului c numele unui tablou este chiar adresa primului
s u element, tablourile sunt ntotdeauna transmise prin adres , f r a fi necesar
specificarea explicit a acestui lucru prin operatorul de adresare &. Prin urmare,
o func ie poate accesa i altera orice element al unui tablou primit ca argument.
n programul 10.1.12 se transmite ca parametru un tablou unidimensional. Se
remarc faptul c func ia dubleaz () nu prime te informa ii despre dimensiunea maxim a tabloului (100), ci doar despre num rul efectiv de elemente
care sunt procesate (n, adic 10). Tabloul este declarat n main() i ini ializat
cu valori de la 0 la 9. n func ia dubleaz () fiecare element al tabloului i
dubleaz valoarea. La revenirea din func ie tabloul este tip rit, constatndu-se
c valorile elementelor au fost modificate.
Programul 10.1.12
#include <stdio.h>
void dubleaza(int n, int v[]){
int i;
174

10 Func ii definite de utilizator

for(i=0;i<n;i++)
v[i]=v[i]*2;

void main(void){
int v[100], i;
for (i=0;i<10;i++) v[i]=i; //0 1 2 3 4 5 6 7 8 9
dubleaza(10,v);
for(i=0;i<10;i++)
printf("%d ", v[i]); //0 2 4 6 8 10 12 14
16 18
}
Un tablou bidimensional (matrice) se transmite ca parametru n mod asem n tor. Programul 10.1.13 este un exemplu n acest sens. Apare ns o deosebire:
func ia care prime te matricea ca argument (modifica()) are nevoie de
informa ii legate de num rul maxim de coloane ale matricei (100), asta pe
lng num rul efectiv de linii (n, adic 2) i de coloane (m, adic 3) pe care
matricea le utilizeaz .
Programul 10.1.13
#include <stdio.h>
void modifica(int n, int m, int a[][100]){
int i, j;
for(i=0;i<n;i++)
for(j=0;j<m;j++)
a[i][j]++;
}
void main(void){
int a[100][100]={

{1, 2, 3},
{4, 5, 6}

};

int i, j;
modifica(2, 3, a);
for(i=0;i<2;i++){
for(j=0;j<3;j++)
printf("%d ", a[i][j]);
175

Programarea calculatoarelor
printf("\n");
}

10.2 Recursivitate
Recursivitatea este procesul prin care o entitate se define te folosind aceea i
entitate [HS98]. O func ie este utilizat recursiv dac se apeleaz pe ea ns i
direct sau indirect [BK03].
Unul din cele mai simple exemple de recursivitate este calcularea factorialului
unui num r ntreg. Factorialul unui num r ntreg n l reprezint produsul tuturor
numerelor ntregi cuprinse ntre 1 i n (inclusiv) i din punct de vedere matematic se noteaz n!. De exemplu 4 factorial este 4!=1x2x3x4=24.
n continuare vor fi prezentate implement ri att pentru varianta recursiv , ct
i pentru cea nerecursiv
(programul 10.2.1). Func ia factorial_nerecursiv() este foarte simpl ; ea parcurge numerele de la 1 la n i
nmul e te fiecare num r i la produsul deja calculat al numerelor anterioare lui.
Pentru calculul recursiv al factorialului, func ia factorial_recursiv()
se autoapeleaz . De exemplu, dac trebuie calculat 3 factorial:
n este ini ial 3, prin urmare se execut instruc iunea de pe ramura else;
rezultatul va fi 3 nmul it cu ceea ce returneaz un nou apel al func iei, de
data aceasta cu parametru n-1, adic 2;
n este 2, deci rezultatul este 2*factorial_recursiv(1);
n este 1, deci rezultat=1 (se intr pe ramura true a instruc iunii if) i
acest al treilea apel al func iei se ncheie, returnndu-se valoarea 1 spre al
doilea apel;
n al doilea apel al func ie se face calculul rezultat=2*1=2 i se returneaz spre primul apel al func iei;
n primul apel al func iei se calculeaz rezultat=3*2=6 i se returneaz
acolo unde func ia a fost apelat ini ial (n main()).
Programul 10.2.1
#include <stdio.h>
176

10 Func ii definite de utilizator


int factorial_nerecursiv(int n){
int i, rezultat=1;
for(i=1;i<=n;i++)
rezultat=rezultat*i;
return rezultat;
}
int factorial_recursiv(int n){
int rezultat;
if(n==1)
rezultat=1;
else
rezultat=n*factorial_recursiv(n-1);
return rezultat;
}
void main(void){
int n;
printf("n="); scanf("%d", &n);
printf("Nerecursiv: %d", factorial_nerecursiv(n));
printf("\nRecursiv: %d", factorial_recursiv(n));
}
n general o func ie recursiv va avea o instruc iune if prin care se determin
dac s-a ajuns la ultimul apel al func iei sau ea mai trebuie apelat . F r o astfel
de instruc iune apelurile func iilor nu se vor ncheia niciodat , iar programul va
func iona eronat, de cele mai multe ori n bucl infinit . Pentru ca lucrurile s
fie mai clare, se pot plasa instruc iuni printf() n corpul func iilor recursive,
astfel nct anumite mesaje s fie afi ate la fiecare apel al func iei.
Atunci cnd o func ie se autoapeleaz , se aloc spa iu pentru un nou set de
variabile locale automatice i de parametri i se execut func ia de la nceput cu
noul set de variabile. Dup executarea unui apel recursiv i revenirea din func ie
(cu sau f r valoare returnat ), variabilele locale i parametrii vechi se pierd i
execu ia programului continu din punctul interior n care s-a f cut apelul care
tocmai s-a ncheiat [HS98].
Versiunile recursive ale unor programe nu determin neap rat mbun t iri
legate de rapiditatea execu iei, de dimensiunea programului sau de utilizarea
memoriei. Cu toate acestea, recursivitatea are cteva avantaje demne de semnalat [HS98], [BK03]:
177

Programarea calculatoarelor
codul este mai compact, mai u or de scris i de n eles dect echivalentul
nerecursiv;
mul i algoritmi devin mai clari i mai simpli dac sunt implementa i recursiv; exist algoritmi a c ror implementare iterativ (nerecursiv ) este foarte
dificil de realizat;
unele probleme, mai ales cele din domeniul inteligen ei artificiale, au doar
solu ii recursive;
exist dezvoltatori de programe care judec mai u or pe cale recursiv .

10.3 Probleme rezolvate


10.3.1 Se cite te un num r real care e transmis c tre dou func ii: prima transform num rul din Celsius n Fahrenheit, iar cea de a doua din Fahrenheit n
Celsius.
Programul 10.3.1
#include <stdio.h>
float C_F(float celsius){
return ((celsius*9)/5)+32;
}
float F_C(float fahrenheit){
return ((fahrenheit-32)*5)/9;
}
void main(void){
float n;
printf("Numarul care trebuie transformat: ");
scanf("%f", &n);
printf("%.2f Celsius=%.2f Fahrenheit",n,C_F(n));
printf("\n%.2f Fahrenheit=%.2f Celsius",n,F_C(n));
}
10.3.2 Suma a dou matrice (cu func ii definite de utilizator). n main() se
declar trei matrice: a, b i suma. Se apeleaz func ia de citire mai nti pentru
178

10 Func ii definite de utilizator


matricea a, apoi pentru b i se tip resc cele dou matrice, apelndu-se func ia
de afi are pentru a, respectiv pentru b. Se verific apoi dac exist o concordan n ceea ce prive te num rul de linii i de coloane ntre cele dou matrice.
Dac nu e ndeplinit aceast condi ie se afi eaz un mesaj de eroare i programul se ncheie. Dac matricele se pot aduna, atunci e apelat func ia care face
suma lor, tip rindu-se apoi matricea rezultat.
Func iile care au fost create au urm toarele caracteristici:
Func ia de citire cit() are un caracter general i va fi folosit pentru
citirea ambelor matrice. Parametrii s i sunt:
o n, m num rul de linii, respectiv de coloane, variabile transmise
prin adres , deci valorile citite n func ie se vor reg si n
main();
o mat matricea care se cite te, transmis implicit prin adres ;
o nume numele matricei care se cite te un ir de caractere
transmis ca pointer.
Func ia de afi are afis() este de asemenea folosit pentru tip rirea oric rei matrice. Are urm torii parametri:
o n, m num rul de linii, respectiv de coloane, variabile transmise
prin valoare;
o mat matricea care se tip re te;
o nume numele matricei care se tip re te un ir de caractere
transmis ca pointer.
Func ia care calculeaz suma a dou matrice sum() are urm torii parametri:
o n, m num rul de linii, respectiv coloane ale celor 3 matrice (se
presupune c matricele se pot aduna);
o m1, m2 matricele care se adun ;
o m3 matricea rezultat.
Din punct de vedere al codului, func iile nu ridic probleme. E de remarcat
faptul c func iile de citire i de afi are sunt apelate de mai multe ori, cu parametrii diferi i, programul beneficiind astfel de avantajele folosirii repetate a
179

Programarea calculatoarelor
codului din func iile definite de utilizator. Func ia main() devine de asemenea
deosebit de simpl i de clar .
Programul 10.3.2
#include <stdio.h>
void cit(int *n, int *m, int mat[][50], char *nume){
int i, j;
printf("Citire - matricea %s\n", nume);
printf("Numarul de linii: ");
scanf("%d", &(*n));
printf("Numarul de coloane: ");
scanf("%d", &(*m));
for(i=0;i<(*n);i++)
for(j=0;j<(*m);j++){
printf("%s[%d][%d]=", nume, i, j);
scanf("%d", &mat[i][j]);
}
}
void afis(int n, int m, int mat[][50], char *nume){
int i, j;
printf("Afisare - matricea %s\n", nume);
for(i=0;i<n;i++){
for(j=0;j<m;j++)
printf("%3d ", mat[i][j]);
printf("\n");
}
}
void sum
(int n,int m,int m1[][50],int m2[][50],int m3[][50]){
int i, j;
for(i=0;i<n;i++)
for(j=0;j<m;j++)
m3[i][j]=m1[i][j]+m2[i][j];
}
void main(void){
int a[50][50], b[50][50], suma[50][50];
180

10 Func ii definite de utilizator


int n_a, m_a, n_b, m_b;
cit(&n_a, &m_a, a, "a");
cit(&n_b, &m_b, b, "b");
system("cls");
afis(n_a, m_a, a, "a");
afis(n_b, m_b, b, "b");
if((n_a!=n_b)||(m_a!=m_b))
printf("Nu coincide numarul de linii/coloane!");
else{
sum(n_a, m_a, a, b, suma);
afis(n_a, m_a, suma, "suma");
}
}
10.3.3 Implementarea unor expresii matematice. Utilizatorul va putea s aleag ,
prin intermediul unui meniu repetitiv, ce expresie dore te s evalueze. Fiecare
expresie trebuie implementat ntr-o func ie separat . Func iile vor primi parametri transmi i prin valoare sau prin adres (dependent de context) i vor returna dac este cazul o valoare. Meniul este urm torul:
1 Aria unui p trat;
2 Aria unui cerc;
3 Aria i n l imea unui triunghi echilateral;
0 Ie ire.
Pentru ca meniul s fie repetitiv, se va folosi o structur while cu condi ie
mereu adev rat ; ie irea din while se face cu ajutorul func iei exit() apelat dac se alege op iunea 0. n interiorul instruc iunii while se afi eaz meniul
i se cere utilizatorului s introduc op iunea sa; aceste lucruri se ntmpl n
func ia meniu() care va returna op iunea utilizatorului. n continuare ea este
evaluat ntr-o instruc iune switch, executndu-se ramura aferent op iunii.
Dac utilizatorul alege op iunea 1, i se cere introducerea laturii p tratului.
Aceast valoare se transmite ca argument func iei patrat() care va returna
aria sau 0 dac latura nu are o valoare pozitiva (din punct de vedere geometric
un p trat nu poate avea latura negativ sau zero).

181

Programarea calculatoarelor
Pentru op iunea 2 lucrurile se petrec n aceea i manier , calculndu-se (dac
este posibil) aria cercului. n func ia cerc() se remarc folosirea constantei
M_PI din biblioteca math.h.
n ceea ce prive te op iunea 3 lucrurile se complic pu in deoarece func ia
triunghi() trebuie s calculeze i s transmit dou valori. Instruc iunea
return nu poate fi folosit pentru a returna dou variabile separate. O solu ie
este stocarea acestor valori n parametri transmi i prin adres . A adar, func ia
triunghi() va avea trei parametri: pe de o parte latura triunghiului (transmis prin valoare), pe de alt parte aria i n l imea (transmise prin adres : &a,
&h). Valorile atribuite n interiorul func iei acestor ultimi doi parametri vor
putea fi folosite n main(), dup revenirea din func ie.
Programul 10.3.3
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
float patrat(float l){
if(l>0)
return l*l;
else
return 0;
}
float cerc(float r){
if(r>0)
return M_PI*r*r;
else
return 0;
}
int triunghi(float l, float *a, float *h){
if(l>0) {
*a=l*l*sqrt(3)/4;
*h=l*sqrt(3)/2;
return 1;
}
else
182

10 Func ii definite de utilizator


return 0;
}
int meniu(void){
int o;
printf("1-Patrat-arie\n");
printf("2-Cerc-arie\n");
printf("3-Triunghi echilateral-arie, inaltime\n");
printf("0-Iesire\n");
printf("Introduceti optiunea: ");
scanf("%d", &o);
return o;
}
void main(void){
int optiune;
float lat, raza;
float a, h;
while(1){
system("cls"); //sterge ecranul
optiune=meniu();
switch(optiune){
case 1: printf("Introduceti latura: ");
scanf("%f", &lat);
a=patrat(lat);
if(a==0)
printf("Eroare!");
else
printf("Aria=%.2f",a);
break;
case 2: printf("Introduceti raza: ");
scanf("%f", &raza);
a=cerc(raza);
if(a==0)
printf("Eroare!");
else
printf("Aria=%.2f",a);
break;
case 3: printf("Introduceti latura: ");
scanf("%f", &lat);
183

Programarea calculatoarelor
if(triunghi(lat,&a,&h)==0)
printf("Eroare!");
else{
printf("Aria=%.2f\n",a);
printf("Inaltimea=%.2f",h);
}
break;
case 0: exit(0);
default: printf("Optiune gresita!");

}
getch(); //asteapta apasarea unei taste
}
}

10.3.4 Se tip resc primele n numere din irul lui Fibonacci (0, 1, 1, 2, 3, 5, 8,
) folosindu-se trei variante de implementare. Fiecare variant este realizat
ntr-o func ie separat , iar func iile sunt puse la dispozi ia utilizatorului prin
intermediul unui meniu repetitiv.
Prima variant utilizeaz trei variabile: f1 ini ializat cu 0, f2 ini ializat cu 1
i f3 care se calculeaz ca fiind f1+f2. La sfr itul fiec rei itera ii f1 avanseaz prelund valoare lui f2, iar f2 pe cea a lui f3. Func ia fibo_var(),
care implementeaz aceast variant , prime te ca argument variabila n i nu
returneaz nimic.
A doua variant este probabil cea mai simpl , stocnd ntr-un tablou elementele
irului. Primele dou elemente ale tabloului sunt ini ializate cu 0, respectiv 1,
iar urm toarele se calculeaz ca sum a precedentelor dou . Func ia
fibo_tab() prime te ca argument variabila n i nu returneaz nimic.
n cea de a treia variant se calculeaz recursiv fiecare element al irului. Astfel,
func ia fibo_rec() este apelat pentru fiecare num r care trebuie afi at.
Dac n este mai mare dect doi, atunci func ia se va autoapela.
Programul 10.3.4
#include <stdio.h>
#include <stdlib.h>
void fibo_var(int n){
int i, f1=0, f2=1, f3;
184

10 Func ii definite de utilizator


if(n==1)
printf("%d ", f1);
else if(n==2)
printf("%d %d ", f1, f2);
else{
printf("%d %d ", f1, f2);
for(i=3;i<=n;i++){
f3=f1+f2;
printf("%d ", f3);
f1=f2;
f2=f3;
}
}
}
void fibo_tab(int n){
int i, tab[100];
tab[0]=0; tab[1]=1;
for(i=2;i<n;i++)
tab[i]=tab[i-2]+tab[i-1];
for(i=0;i<n;i++)
printf("%d ",tab[i]);
}
int fibo_rec(int n){
if(n==1) return 0;
else if(n==2) return 1;
else
return fibo_rec(n-1)+fibo_rec(n-2);
}
int meniu(void){
int o;
printf("1-Variabile simple\n");
printf("2-Tablou\n");
printf("3-Recursivitate\n");
printf("0-Iesire\n");
printf("Introduceti optiunea: ");
scanf("%d", &o);
185

Programarea calculatoarelor
return o;
}
void main(void){
int optiune, n, i;
while(1){
system("cls"); //sterge ecranul
do{
printf("Introduceti un numar pozitiv.\n");
printf("n=");
scanf("%d", &n);
}while(n<=0);
optiune=meniu();
switch(optiune){
case 1: fibo_var(n); break;
case 2: fibo_tab(n); break;
case 3: for(i=1;i<=n;i++)
printf("%d ",fibo_rec(i));
break;
case 0: exit(0);
default: printf("Optiune gresita!");
}
getch();
}
}

10.4 Probleme propuse


A. Specifica i unde este gre eala.
1. #include <stdio.h>
//si alte biblioteci necesare
void calcul(void){
//executa ceva
}
void main(void){
int x;
printf("x="); scanf("%d",&x);
calcul(x);
}
186

10 Func ii definite de utilizator


2. #include <stdio.h>
void calcul(int a, int b){
x=a+b;
}
void main(void){
int x, a, b;
printf("a="); scanf("%d",&a);
printf("b="); scanf("%d",&b);
calcul(a,b);
printf("x=%d",x);
}
3. #include <stdio.h>
void calcul(int a, int b){
int c;
c=a+b;
return c;
}
void main(void){
int x, a, b;
printf("a="); scanf("%d",&a);
printf("b="); scanf("%d",&b);
x=calcul(a,b);
printf("x=%d",x);
}
4. #include <stdio.h>
int x;
void calcul(void){
x=a+b;
}
void main(void){
int a, b;
printf("a="); scanf("%d",&a);
printf("b="); scanf("%d",&b);
calcul();
printf("x=%d",x);
}
5. #include <stdio.h>
void calcul(int x){
x++;
187

Programarea calculatoarelor
}
void main(void){
int x;
printf("x="); scanf("%d",&x);
calcul(&x);
printf("x=%d",x);
}
6. #include <stdio.h>
void calcul(int *a, int *b){
int aux;
aux=*a;
*a=*b;
*b=aux;
}
void main(void){
int a, b;
printf("a="); scanf("%d",&a);
printf("b="); scanf("%d",&b);
calcul(a,b);
printf("a=%d, b=%d",a, b);
}
7. #include <stdio.h>
void calcul(int x){
x++;
}
void main(void){
int x;
printf("x="); scanf("%d",&x);
calcul(x)=100;
}
8. #include <stdio.h>
int calcul(int x, int y){
return x+y;
}
void main(void){
int suma, a=2, b=3;
suma=calcul(a+b);
}
188

10 Func ii definite de utilizator


9. #include <stdio.h>
int calcul(void){
int contor=0;
//numara de cate ori e apelata functia
contor++;
return contor;
}
void main(void){
int i, c;
for(i=1;i<=10;i++) c=calcul();
printf("Functia a fost apelata de %d ori",c);
}
10. #include <stdio.h>
int calcul(int x){
if(x==1) return 1;
else return x*calcul();
}
void main(void){
int i;
for(i=1;i<=7;i++)
printf("%d ",calcul(i));
}
B. Se consider urm toarele programe. Specifica i ce va fi afi at pe ecran dup
rularea acestora.
11. #include <stdio.h>
float calcul(int a, int b){
return a/b;
}
void main(void){
int a=1, b=2;
printf("%.2f",calcul(a,b));
}
12. #include <stdio.h>
void calcul(int x){
x++;
}
void main(void){
int a=1;
189

Programarea calculatoarelor

calcul(a);
printf("%d",a);

13. #include <stdio.h>


void calcul(int *x){
(*x)++;
}
void main(void){
int a=1;
calcul(&a);
printf("%d",a);
}
14. #include <stdio.h>
int x;
void calcul(int a){
x=++a;
}
void main(void){
int y=1;
calcul(y);
printf("%d %d",x,y);
}
15. #include <stdio.h>
int x;
int calcul(int a){
x=++a;
return a;
}
void main(void){
int y=1,z;
z=calcul(y);
printf("%d",z);
}
16. #include <stdio.h>
void calcul(int x, int *y){
x++;
(*y)++;
}
190

10 Func ii definite de utilizator


void main(void){
int a=1, b=1;
calcul(a,&b);
printf("%d %d",a,b);
}
17. #include <stdio.h>
#include <conio.h>
void functie(void){
char c;
printf("\nO litera sau / pentru sfarsit ");
c=getch();
if(c!='/'){
functie();
putch(c);
}
}
void main(void){
functie();
}
C. Alege i r spunsul corect (unul singur).
18. Prototipul unei func ii con ine:
a) numele func ie; b) tipul valorii returnate; c) tipul i numele argumentelor; d) r spunsurile a, b i c sunt corecte; e) toate r spunsurile sunt gre ite.
19. Ce va returna o func ie care are prototipul numara(float nota)?
a) nimic;
ter.

b) un int;

c) un float;

d) un char;

e) un poin-

20. O variabil care este vizibil n ntregul program se nume te:


a) local ;
sal .

b) na ional ;

c) interna ional ;

d) global ;

e) univer-

21. O variabil care este creat la fiecare apel al unei func ii i este distrus
la revenirea din acea func ie se nume te:
a) local ;
sal .

b) na ional ;

c) interna ional ;

191

d) global ;

e) univer-

Programarea calculatoarelor
22. Care dintre urm toarele apeluri ale func iei cu prototipul int
f1(void); este gre it (n este un num r ntreg)?
a) n=f1();;
b) n=2*f1();;
c) f1()=n;;
printf("%d",f1());; e) if(f1()==n) n++;.

d)

23. Se consider func ia cu prototipul void f2(int x);. Care dintre


urm toarele apeluri este gre it?
a) f2(7);; b) int n=1; f2(n);; c) f2(3+4);; d) int
a=1, b=2; f2(a+b);; e) int a=1, b=2; f2(a,b);.
24. Care dintre urm toarele tipuri de variabile nu exist n limbajul de programare C?
a) local ;
b) global ;
punsurile sunt gre ite.

c) static ;

d) automatic ;

e) toate r s-

25. Argumentele unei func ii pot fi transmise prin:


a) valoare;
sunt corecte.

b) adres ;

c) po t ;

d) fax;

e) r spunsurile a i b

D. S se scrie programe pentru rezolvarea urm toarelor probleme.


26. Se consider un tablou de numere reale. S se scrie o func ie care s returneze elementul cu valoare maxim .
27. Se citesc de la tastatur dou numere naturale. S se scrie o func ie care
afl i returneaz cel mai mare divizor comun al celor dou numere (algoritmul lui Euclid).
28. S se scrie o func ie care verific dac un num r n primit ca argument
este prim sau nu.
29. S se realizeze produsul a dou matrice (cu func ii definite de utilizator).
30. S se scrie o func ie care num r de cte ori apare un caracter c ntr-un
ir de caractere s.
31. Se citesc n main() trei numere reale (a, b i c) i se transmit unei
func ii care verific dac acestea pot forma un triunghi (a+b>c, a+c>b
i b+c>a); func ia va returna 1 dac numerele pot fi laturile unui triunghi i 0 n caz contrar.

192

10 Func ii definite de utilizator


32. S se scrie o func ie care prime te ca parametru un tablou de numere reale reprezentnd coeficien ii unei func ii polinomiale (f(x)=anxn+an-1xn-1
+ +a1x+a0) i un num r x i returneaz valoarea func iei n punctul x.
33. S se scrie o func ie care prime te ca parametru un tablou de numere reale reprezentnd coeficien ii unei func ii polinomiale (f(x)=anxn+an-1xn-1
+ +a1x+a0) i creeaz , ntr-un alt tablou, coeficien ii derivatei func iei.

193

Capitolul 11 Tipuri definite de utilizator


Pe lng tipurile de date standard (char, int, float, double), limbajul de
programare C ofer cteva mecanisme prin care se pot crea tipuri de date personalizate (tipuri definite de utilizator). Trei dintre acestea fac obiectul capitolului
de fa :
structura o entitate care grupeaz sub acela i nume mai multe variabile
rela ionate din punct de vedere logic;
enumerarea o list de constante ntregi cu nume;
uniunea un spa iu de memorie utilizat, la momente diferite, de mai multe
variabile.

11.1 Structura
O structur este o colec ie de variabile la care se face referire utilizndu-se un
singur nume. Datorit faptului c permit gruparea mai multor variabile (ntre
care exist o anumit rela ie ntr-un context dat) i tratarea lor n mod unitar i
nu ca entit i separate, structurile sunt cu succes utilizate n organizarea datelor
complexe [BK03].
Variabilele din interiorul structurii se numesc membri sau cmpuri i pot avea
tipuri diferite. Fiecare membru are la rndul s u un nume, utilizat pentru a-l
selecta din structur .

11.1.1 Definire i utilizare


Pentru definirea unei structuri se folose te cuvntul cheie struct ntr-o instruc iune a c rei form general este [BH92]:
struct nume_structura{
tip1 var11, var12;
tip2 var2;

tipn varn;
} lista_variabile;

11 Tipuri definite de utilizator


unde:
nume_structura are caracter op ional i este o etichet prin intermediul
c reia tipul de dat tocmai definit poate fi folosit n continuare pentru declararea unor variabile;
var11, var12, var2, , varn sunt membrii structurii;
tip1, tip2, , tipn reprezint tipurile membrilor structurii;
variabilele de acela i tip pot fi definite ntr-o singur instruc iune i vor fi
separate prin virgul (,);
definirea variabilelor de tipuri diferite se face n instruc iuni diferite, separate prin punct i virgul (;);
variabilele membru sunt declarate ntr-un bloc delimitat de acolade ({});
lista_variabile are de asemenea caracter op ional i este o list care
declar una sau mai multe variabile;
definirea structurii se ncheie cu punct i virgul (;), aceast definire fiind,
n ansamblu, o instruc iune;
de i att nume_structura, ct i lista_variabile au caracter
op ional, ele nu pot lipsi n acela i timp; cu alte cuvinte m car una dintre ele
trebuie s apar pentru c altfel definirea structurii n-ar avea sens (de vreme
ce nici nu s-au declarat variabile, nici nu s-a dat un nume structurii pentru a
putea fi folosit ulterior).
Un prim exemplu, foarte simplu, de structur este reprezentat de coordonatele
unui punct n plan. Structura poate fi definit astfel:
struct punct{
int x;
int y;
};
sau:
struct punct{
int x, y;
};
195

Programarea calculatoarelor
Membrii unei structuri pot avea i tipuri diferite, a a cum se poate vedea n
exemplul urm tor, care define te cteva caracteristici ale unui student:
struct student{
int id;
char nume[20];
float nota;
};
Definirea unei structuri nu aloc memorie. Ea doar descrie un nou tip de dat
care poate fi privit ca un ablon.
Declararea variabilelor folosind acel tip se poate face chiar n instruc iunea care
define te tipul. Exemplul urm tor declar dou variabile A i B de tip punct:
struct punct{
int x;
int y;
}A,B;
Dac structurii i s-a dat un nume, atunci declararea variabilelor se poate face
ulterior, n orice loc al programului n care structura este vizibil . La declarare
se va folosi numele structurii precedat de cuvntul cheie struct. Instruc iunea
urm toare declar o variabil folosind tipul student definit anterior:
struct student stud1;
n limbajul de programare C++ declararea unei variabile structur poate fi
f cut i f r cuvntul cheie struct, fiind suficient numele tipului structur .
Prin urmare declararea variabile anterioare s-ar face: student stud1;.
Ini ializarea membrilor unei variabile structur se poate face chiar la declararea
variabilei. Instruc iunea urm toare declar i ini ializeaz dou puncte: A de
coordonate (3,4) i B de coordonate (10,4):
struct punct A={3,4}, B={10,4};
Fiecare membru al unei structuri poate fi utilizat i ca o variabil de sine st t toare, ns numele s u va fi ceva mai lung, el incluznd i numele variabilei de
tip structur din care face parte. Pentru accesarea membrilor unei structuri se
folose te operatorul . plasat ntre numele variabilei structur i numele variabilei membru:
196

11 Tipuri definite de utilizator


A.x=3;
A.y=4;
stud1.nota=9.75;
strcpy(stud1.nume,"Ritchie");
printf("%s %.2f",stud1.nume,stud1.nota);
Numele unei variabile membru poate fi identic cu numele unei variabile obi nuite (ne-membru) f r a se crea conflicte, diferen a dintre cele dou variabile
f cndu-se de contextul n care sunt accesate [BK03] (variabila membru va fi
ntotdeauna precedat de numele variabilei structur din care face parte). Bazat
pe aceea i diferen iere, un membru al unei structuri poate avea acela i nume cu
un membru al unei alte structuri (acest lucru nu se recomand dect pentru
elemente foarte apropiate ca semnifica ie de exemplu raza poate fi o variabil att pentru o structur care descrie un cerc, ct i pentru una care descrie un
arc de cerc).
Programul 11.1.1 este un exemplu complet n care structura student este
utilizat . Definirea structurii este f cut global, pentru a-i extinde vizibilitatea
asupra ntregului program (n cazul de fa , programul compunndu-se doar din
func ia main(), structura putea fi definit i n interiorul acestei func ii). Se
declar o variabil s de tip student i se citesc o parte dintre caracteristicile
ei (id, nume, not la examen, not pentru laborator). Se calculeaz i se afi eaz
nota final . Programul este foarte simplu, fiind doar un exerci iu pentru definirea i utilizarea unei structuri.
Programul 11.1.1
#include <stdio.h>
struct student{
int id;
char nume[20];
float examen, laborator, finala;
};
void main(void){
struct student s;
printf("Id: ");
scanf("%d",&s.id);
printf("Nume: ");
197

Programarea calculatoarelor

scanf("%s",s.nume);
printf("Nota examen: ");
scanf("%f", &s.examen);
printf("Nota laborator: ");
scanf("%f", &s.laborator);
s.finala=(2*s.examen+s.laborator)/3;
printf("%s are nota finala %.2f",s.nume,s.finala);

ntreaga cantitate de informa ie con inut ntr-o variabil de tip structur poate
fi copiat ntr-o alt variabil de acela i tip folosind o singur opera ie de atribuire (nu trebuie atribuite separat valorile fiec rei variabile membru). Pentru a
exemplifica acest lucru, programul 11.1.2 folose te structura punct. Se definesc dou variabile A i B utiliznd aceast structur . Coordonatele x i y ale
variabilei A sunt ini ializate cu valorile 3, respectiv 4. Variabila A este atribuit
apoi variabilei B, care este tip rit , pe ecran afi ndu-se B(3,4).
Programul 11.1.2
#include <stdio.h>
struct punct{
int x;
int y;
};
void main(void){
struct punct A, B;
A.x=3; A.y=4;
B=A;
printf("B(%d,%d)",B.x,B.y);
}
Tipurile membrilor unei structuri pot fi la rndul lor tipuri standard sau tipuri
definite de utilizator. Prin urmare, n interiorul unei structuri pot fi definite
variabile care au ca tip o structur . De exemplu (programul 11.1.3), se poate
imagina o structur numit cerc, care con ine un membru de tip punct,
reprezentnd coordonatele centrului cercului i un membru de tip float,
reprezentnd raza cercului:
struct cerc{
struct punct centru;
198

11 Tipuri definite de utilizator


float raza;
}c;
Pentru accesarea coordonatelor centrului cercului e nevoie de trei nume: al
coordonatei (x), al centrului (centru) i al cercului (c):
c.centru.x=10;
Programul 11.1.3
#include <stdio.h>
struct punct{
int x;
int y;
};
struct cerc{
struct punct centru;
float raza;
};
void main(void){
struct cerc c;
c.centru.x=10;
c.centru.y=20;
c.raza=5.37;
printf("centru: (%d,%d)",c.centru.x,c.centru.y);
printf("\nraza: %.2f",c.raza);
}
O structur poate con ine de asemenea n interiorul s u un tablou (cu una sau
mai multe dimensiuni):
struct tablou{
int v[10];
int max;
}t;
Accesarea unui element al tabloului (de exemplu cel de la indicele 3) se face,
firesc, astfel:
199

Programarea calculatoarelor
t.v[3];
Programul 11.1.4 folose te aceast structur , care con ine un tablou de ntregi i
o variabil n care se va re ine valoarea maxim din tablou. Func iile din program (citire(), afisare() i maxim()) ac ioneaz asupra unei variabile
globale, t, de tip structur .
Programul 11.1.4
#include <stdio.h>
const n=10;
struct tablou{
int v[n];
int max;
}t;
void citire(){
int i;
for(i=0;i<n;i++){
printf("v[%d]=",i);
scanf("%d",&t.v[i]);
}
}
void afisare(void){
int i;
for(i=0;i<n;i++)
printf("%d ",t.v[i]);
}
void maxim(void){
int i;
t.max=t.v[0];
for(i=1;i<n;i++)
if(t.v[i]>t.max)
t.max=t.v[i];
}
void main(void){
200

11 Tipuri definite de utilizator


citire();
afisare();
maxim();
printf("\nMax: %d", t.max);
}

11.1.2 Structuri i func ii


Variabilele de tip structur pot fi, la fel ca alte variabile, transmise ca argumente
func iilor (prin valoare sau prin adres ) sau returnate din func ii. n aceste cazuri structura trebuie declarat global pentru a fi disponibil mai multor elemente ale programului.
Pentru a exemplifica returnarea unei variabile de tip structur s-a creat o func ie
n care se citesc de la tastatur caracteristicile unui student i se salveaz ntr-o
variabil structur care este returnat spre func ia main() (programul 11.1.5).
Aceast citire este apelat pentru dou variabile de tip student.
Programul 11.1.5
#include <stdio.h>
struct student{
int id;
char nume[20];
float nota;
};
struct student citire(void){
struct student stud;
printf("Id: ");
scanf("%d",&stud.id);
printf("Nume: ");
scanf("%s",stud.nume);
printf("Nota: ");
scanf("%f", &stud.nota);
return stud;
}
void main(void){
201

Programarea calculatoarelor
struct student s1,s2;
s1=citire();
s2=citire();
printf("%s: %.2f\n",s1.nume,s1.nota);
printf("%s: %.2f",s2.nume,s2.nota);
}
Programul 11.1.6 este un exemplu de transmiterea prin valoare a unor variabile
de tip structur . n main() se declar i se ini ializeaz dou variabile, A i B,
de tip punct i apoi se transmit unei func ii care calculeaz i returneaz distan a dintre cele dou puncte (
).
Programul 11.1.6
#include <stdio.h>
#include <math.h>
struct punct{
int x;
int y;
};
float distanta(struct punct a, struct punct b){
return sqrt(pow((b.x-a.x),2)+pow((b.y-a.y),2));
}
void main(void){
struct punct A={3,4}, B={10,4};
printf("AB=%.2f", distanta(A,B));
}
Programul 11.1.7 transmite prin adres o variabil de tip structur . n main()
se declar i se ini ializeaz un punct A. Se dore te mutarea acestui punct la alte
coordonate. Deoarece mutarea trebuie s se produc efectiv, punctul trebuie
transmis prin adres c tre func ia care face mutarea. Noile coordonate se transmit prin valoare. La revenirea din func ie se tip re te noua loca ie a punctului
pentru a se verifica dac mutarea a avut loc. Se constat c valorile variabilelor
structurii au fost modificate.
Programul 11.1.7
#include <stdio.h>
202

11 Tipuri definite de utilizator

struct punct{
int x;
int y;
};
void mutare(struct punct *a, int x_nou, int y_nou){
(*a).x=x_nou;
(*a).y=y_nou;
}
void main(void){
struct punct A={3,4};
mutare(&A,10,14);
printf("A(%d,%d)", A.x,A.y);
}

11.1.3 Tablouri de structuri


Tipurile structur pot fi utilizate pentru a crea tablouri, fiecare element al tabloului fiind de fapt o structur (un grup de variabile). Evident, mai nti se define te structura i apoi tabloul.
Dac se dore te, de exemplu, contorizarea num rului de apari ii ale fiec rei
vocale (a, e, i, o, u) ntr-un text, se poate folosi un tablou de 5 elemente,
fiecare element fiind o structur definit astfel:
struct numara_vocale{
char vocala;
int contor;
};
Programul 11.1.8 reprezint rezolvarea acestei probleme. Se define te structura
numara_vocale i apoi un tablou tab de 5 elemente de tipul structurii
definit anterior. Elementele tabloului sunt i ini ializate la declarare: membrii
vocala cu cte o vocal , iar membrii contor cu 0. n main() se cite te un
text declarat ca ir de caractere i se transmite acest text spre func ia
numara(). n interiorul acestei func ii se parcurg vocalele, iar pentru fiecare
vocal tab[i].vocala se parcurge textul i se caut acea vocal ,
comparndu-se fiecare liter a textului (text[j]) cu vocala c utat . Dac sunt
203

Programarea calculatoarelor
identice, contorul asociat vocalei (tab[i].contor) va fi incrementat. Pentru
a nu se face diferen a ntre litere mari i litere mici, fiecare liter a textului este
transformat n liter mic (tolower(text[j])), a a cum apare ea n tabloul vocalelor. n finalul programului este apelat o func ie care afi eaz fiecare vocal mpreun cu contorul s u.
Programul 11.1.8
#include <stdio.h>
#include <string.h>
#include <ctype.h>
struct numara_vocale{
char vocala;
int contor;
};
struct numara_vocale tab[5]={
{'a',0},
{'e',0},
{'i',0},
{'o',0},
{'u',0}
};
void numara(char *text){
int i, j;
for(i=0;i<5;i++)
for(j=0;j<strlen(text);j++)
if(tolower(text[j])==tab[i].vocala)
tab[i].contor++;
}
void afisare(void){
int i;
for(i=0;i<5;i++)
printf("\n%c:
%d",tab[i].vocala,tab[i].contor);
}
void main(void){
char text[50];
204

11 Tipuri definite de utilizator


printf("Introduceti textul: ");
gets(text);
numara(text);
afisare();
}

11.1.4 Pointeri de tip structur


Limbajul C permite declararea de pointeri c tre structuri, a a cum se declar
orice al i pointeri. Considerndu-se structura student, definit la nceputul
acestui capitol, un pointer se declar astfel:
struct student *p;
Unui pointer de tip structur i se poate atribui ca valoare adresa unei variabile
care are ca tip aceea i structur :
p=&stud;
unde stud este o variabil de tip student.
Exist dou modalit i de acces la membrii structurii prin intermediul pointerului:
varianta clasic , prin dereferen ierea pointerului i folosirea operatorului
.: (*p).nota;; aceast variant a fost exemplificat la transmiterea
prin adres a unei structuri;
varianta special , folosind operatorul ->: p->nota;; programul 11.1.9
eviden iaz acest mod de referire a unei structuri. Folosindu-se structura
student, se declar o variabil stud i un pointer p c ruia i se atribuie
apoi adresa variabilei stud. Prin intermediul pointerului se dau valori
membrilor structurii. Pentru verificare, se tip re te variabila stud.
Programul 11.1.9
#include <stdio.h>
#include <string.h>
struct student{
int id;
char nume[20];
float nota;
205

Programarea calculatoarelor
};
void main(void){
struct student stud, *p;
p=&stud;
p->id=1;
strcpy(p->nume,"Ritchie");
p->nota=10;
printf("%s: %.2f",stud.nume, stud.nota);
}

11.2 Enumerarea
O enumerare este un set de constante ntregi cu nume, care specific toate valorile legale pe care le poate lua o variabil de acel tip [HS98]. Forma general a
unei instruc iuni care define te o enumerare este [BH92]:
enum nume_enumerare{
nume_const1=val1;
nume_const2=val2;

nume_constn=valn;
} lista_variabile;
unde:
enum este cuvntul cheie necesar pentru definirea enumer rii;
nume_enumerare este o etichet op ional care se ata eaz enumer rii;
nume_const1, nume_const2, , nume_constn sunt numele constantelor care alc tuiesc enumerarea;
val1, val2, , valn sunt valorile asociate constantelor; aceste valori
sunt op ionale; dac apar, ele trebuie s fie ntregi; dac lipsesc, atunci se
consider c valoarea asociat unei constante este valoarea asociat precedentei constante la care se adaug 1, cu men iunea c prima constant are
asociat valoarea 0;
206

11 Tipuri definite de utilizator


lista_variabile este o modalitate op ional de a declara variabile
utiliznd enumerarea care tocmai a fost definit .
Ca exemplu se poate considera o enumerare care con ine zilele s pt mnii:
enum zi {luni, marti, miercuri, joi, vineri, sambata,
duminica};
i dou variabile de acest tip:
enum zi azi, maine;
Variabila de tip enumerare poate fi utilizat n instruc iuni de genul:
azi=duminica;
if(azi==duminica) maine=luni;
else maine=azi+1;
printf("%d", azi); //va afi a un num r ntre 0

i 6

Trebuie subliniat faptul c fiecare constant din cadrul unei enumer ri are
asociat (implicit sau explicit) o valoare ntreag . Prin urmare, aceste constante
pot fi folosite oriunde este necesar un ntreg.
Asocierea explicit a valorilor pentru constantele unei enumer ri se face astfel:
enum luna {ian=31, feb=28, mar=31, apr=30, mai=31,
iun=30, iul=31, aug=31, sep=30, oct=31, nov=30,
dec=31};
Corect este i o enumerare n defini ia c reia doar unele constante au asociate
explicit valori. Fiecare din celelalte va avea valoare mai mare cu o unitate dect
constanta precedent . n exemplul urm tor, constanta cvinta va avea implicit
valoarea 5 pentru c urmeaz dup cvarta c reia i s-a asociat explicit valoarea 4:
enum intervale_perfecte{prima=1,
octava=8};

cvarta=4,

cvinta,

Programul 11.2.1 define te ntr-o enumerare cele trei culori ale semaforului
auto. Acestea vor avea asociate implicit valorile 0, 1 i 2. n func ia main()
se genereaz aleator un num r ntreg (0, 1 sau 2) care este transmis func iei
semafor(). n momentul transmiterii, num rul se identific cu una din cele
trei constante ale enumer rii. Func ia nu face dect s genereze o comanda
(simulat printr-un mesaj text) dependent de culoarea semaforului primit ca
argument. Comanda este tip rit , iar apoi func ia i programul se ncheie.
207

Programarea calculatoarelor
Programul 11.2.1
#include
#include
#include
#include

<stdio.h>
<stdlib.h>
<time.h>
<string.h>

enum culoare{ROSU,GALBEN,VERDE};
void semafor(enum culoare culoare_sem){
char comanda[30];
switch(culoare_sem){
case ROSU:
strcpy(comanda,"Opriti neconditionat!");
break;
case GALBEN:
strcpy(comanda,"Opriti daca e posibil!");
break;
case VERDE:
strcpy(comanda,"Treceti!");
break;
}
printf("%s",comanda);
}
void main(void){
srand(time(0));
semafor(rand()%3);
}

11.3 Uniunea
O uniune este o zon de memorie folosit de dou sau mai multe variabile (de
obicei de tipuri diferite) la momente diferite de timp [BH92]. Se utilizeaz
frecvent atunci cnd un element are la un moment dat unul i numai unul din
mai multe formate. Definirea ei este similar cu cea a unei structuri, dar folose te cuvntul cheie union:
union nume_uniune{
208

11 Tipuri definite de utilizator


tip1 var11, var12;
tip2 var2;

tipn varn;
} lista_variable;
Exemplul urm tor este o uniune care con ine doi membri, un ntreg n i un
num r real x. O variabil , numar, este declarat folosind acest nou tip de dat :
union exemplu{
int n;
float x;
}numar;
O variabil de tip uniune poate fi de asemenea declarat ntr-o instruc iune
separat , dup ce tipul de data a fost definit. Regulile de vizibilitate sunt acelea i: tipul de dat trebuie s fie accesibil n interiorul secven ei de cod care
con ine declararea variabilei:
union exemplu altNumar;
Membrii unei uniuni pot fi accesa i prin intermediul acelora i operatori folosi i
i n cazul structurilor. Operatorul punct (.) este utilizat pentru a accesa
membrii unei variabile uniune (de exemplu numar.n=7;), n timp ce operatorul s geat (->) trebuie utilizat atunci cnd membrii sunt accesa i prin intermediul unui pointer. Urm toarea func ie prime te ca argument un pointer c tre
o variabil uniune i atribuie valoarea 7 membrului s u de tip ntreg:
void oFunctie(union exemplu *pNumar){
pNumar->n=7;
}
Atunci cnd o variabil de tip uniune (de exemplu numar) este declarat , i se
va aloca un spa iu de memorie suficient pentru a stoca cel mai mare (ca num r
de octe i necesari reprezent rii n memorie) element al uniunii. Aceasta este
diferen a ntre structur i uniune: membrii numar.n i numar.x ocup
aceea i zon de memorie, avnd, n mod natural, aceea i adres de memorie.
Prin urmare, scrierea unuia din membri va suprascrie pe cel lalt.
209

Programarea calculatoarelor
Nu exist posibilitatea de a determina tipul de dat al unei variabile stocate
ntr-o uniune la un moment dat. Con inutul unei variabile dintr-o uniune (din
punct de vedere al tipului de dat ) este responsabilitatea programatorului, fiind
cel mai recent tip de dat stocat n acea uniune [DL06] [BK03].
Programul 11.3.1 este un exemplu simplu care utilizeaz uniunea declarat
anterior pentru a demonstra c membrii s i au to i aceea i adres de memorie.
n func ia printf() apare ca descriptor de format %X; acesta este utilizat
pentru a afi a valoarea hexazecimal a unei adrese de memorie. Programul va
afi a mesajele:
Adresa membrului n: 28FF1C
Adresa membrului x: 28FF1C
Chiar dac adresa variabilelor membru (28FF1C n acest exemplu) poate fi alta
la fiecare rulare a programului, aceasta va fi aceea i pentru to i membrii uniunii
la un moment dat.
Programul 11.3.1
#include <stdio.h>
union exemplu{
int n;
float x;
};
void main(void){
union exemplu numar;
printf("Adresa membrului n: %X", &numar.n);
printf("\nAdresa membrului x: %X", &numar.x);
}
A a cum se poate observa n exemplele anterioare, asupra uniunilor se pot
realiza acelea i opera ii care se efectueaz i asupra structurilor: accesarea
membrilor, atribuirea, preluarea adresei. n ceea ce prive te ini ializarea, uniunea poate fi ini ializat doar cu o valoare de tipul primului s u membru [BK03];
a adar, uniunea exemplu, considerat aici, poate primi la ini ializare doar o
valoare ntreag .
Uniunile pot con ine structuri i tablouri i, de asemenea, pot ap rea n structuri
i n tablouri. Dac o variabil membru a unui astfel de element imbricat trebuie
accesat , nota ia este identic cu cea utilizat la structuri imbricate. Urm torul
exemplu declar un vector de elemente imbricate; fiecare loca ie a vectorului e
o structur care con ine cteva variabile, inclusiv o uniune.
210

11 Tipuri definite de utilizator


struct{
char nume[20]; //si alte date daca sunt necesare
int tipUniune; //0->nota sau 1->calificativ
union{
int nota; //de exemplu 7
char calificativ; //de exemplu 'A'
}rezultat;
}studenti[50];
Vectorul con ine informa ii despre studen i; acestea sunt stocate ntr-o structur :
numele ( i alte posibile date despre student) i de asemenea rezultatul
ob inut de student la examinare. Acest rezultat poate fi o not sau un
calificativ i este re inut ntr-o uniune. Pentru a ti care membru al uniunii este folosit pentru fiecare student, o variabil de tip ntreg (tipUniune)
este setat pe 0 pentru not i pe 1 pentru calificativ. Programul 11.3.2 prezint
ntregul exemplu.
Programul 11.3.2
#include <stdio.h>
struct{
char nume[20];
int tipUniune;
union{
int nota;
char calificativ;
} rezultat;
} studenti[50];
int n;
void citire(void){
int i;
printf("Numarul de studenti: ");
scanf("%d", &n);
for(i=0;i<n;i++){
printf("\nStudent %d:\n", i+1);
printf("Nume: ");
scanf("%s", studenti[i].nume);
211

Programarea calculatoarelor
do{
printf("Nota (0) sau calificativ (1)? ");
scanf("%d", &studenti[i].tipUniune);
}while(studenti[i].tipUniune!=0 &&
studenti[i].tipUniune!=1);
if(studenti[i].tipUniune==0){
printf("Nota: ");
scanf("%d", &studenti[i].rezultat.nota);
}
else{
printf("Calificativul: ");
fflush(stdin);
scanf("%c",
&studenti[i].rezultat.calificativ);
}
}

void afisare(void){
int i;
for(i=0;i<n;i++){
printf("\n%s ", studenti[i].nume);
if(studenti[i].tipUniune==0)
printf(" nota %d", studenti[i].rezultat
.nota);
else
printf(" calificativul %c", studenti[i]
.rezultat.calificativ);
}
}
void main(void){
citire();
afisare();
}

11.4 Probleme propuse


A. Specifica i unde este gre eala.
212

11 Tipuri definite de utilizator


1. struct persoana{
char nume[20];
int varsta;
}
2. struct cerc{
int x;
int y;
float raza;
unCerc;
};
3. struct
char nume[20];
float salariu;
}unAngajat;
4. struct{
char nume[20];
float salariu;
};
5. struct angajat{
char nume[20];
float salariu;
};
struct angajat unAngajat;
salariu=2500;
6. struct angajat{
char nume[20];
float salariu;
};
struct angajat unAngajat, *unPointer;
unPointer=&unAngajat;
unPointer.salariu=2500;
7. enum punct_cardinal{est,vest,nord,sud};
enum punct_cardinal punct=est;
printf("%s", punct);
8. union exemplu{
int n;
213

Programarea calculatoarelor
float x;
}numar;
numar.n=7;
numar.x=9.75;
printf("%d", numar.n);
9. union exemplu{
int n;
float x;
}numar={9.75};
printf("%f", numar.x);
10. union exemplu{
int n;
float x;
}numar, *p;
numar.n=7;
p=&numar;
printf("%d", p.n);
B. Se consider urm toarele programe. Specifica i ce va fi afi at pe ecran dup
rularea acestora.
11. #include <stdio.h>
struct produs{
char denumire[20];
float cantitate,pret;
};
void main(void){
struct produs produs1={"paine",20,1.5}, produs2;
produs2=produs1;
printf("%.2f",produs2.pret);
}
12. #include <stdio.h>
#include <string.h>
struct poligon{
char denumire[20];
int numar_laturi;
};
void modifica(struct poligon pol){
strcpy(pol.denumire,"Heptagonul");
pol.numar_laturi=7;
214

11 Tipuri definite de utilizator


}
void main(void){
struct poligon p={"Patratul",4};
modifica(p);
printf("%s are %d laturi", p.denumire,
p.numar_laturi);
}
13. #include <stdio.h>
#include <string.h>
struct poligon{
char denumire[20];
int numar_laturi;
};
void modifica(struct poligon *pol){
strcpy((*pol).denumire,"Heptagonul");
(*pol).numar_laturi=7;
}
void main(void){
struct poligon p={"Patratul",4};
modifica(&p);
printf("%s are %d laturi", p.denumire,
p.numar_laturi);
}
14. #include <stdio.h>
enum boolean{fals,adevarat};
void main(void){
enum boolean f;
float nota=7.25;
if(nota<5) f=fals;
else f=adevarat;
printf("%d",f);
}
15. union exemplu{
int n;
float x;
}numar={7};
union exemplu altNumar;
altNumar.x=9.75;
printf("%d", numar.n);
215

Programarea calculatoarelor
16. union exemplu{
int n;
float x;
}numar, *p;
numar.n=7;
p=&numar;
printf("%d", p->n);
C. Alege i r spunsul corect (unul singur).
17. O structur este alc tuit din:
a) o singur variabil ; b) mai multe variabile care au obligatoriu
acela i tip; c) mai multe variabile grupate sub acela i nume; d) mai
multe variabile care au obligatoriu aceea i valoare ini ial ; e) mai multe constante.
18. O structur se define te folosind cuvntul cheie:
a) user;
b) defined;
e) structure.

c) type;

d) struct;

19. Pentru accesarea membrilor unei structuri se poate folosi operatorul:


a) .;

b) &;

c) *;

d) #;

e) \.

20. n contextul unei structuri, un membru este:


a) tipul de dat al structurii; b) o variabil a structurii; c) un pointer c tre structur ; d) un tablou de structuri; e) toate r spunsurile
sunt gre ite.
21. Care dintre urm toarele instruc iuni acceseaz corect un membru m al
unei variabile structur s?
a) s.m;

b) s&m;

c) s(m);

d) s[m];

e) niciuna.

22. Care dintre urm toarele instruc iuni acceseaz corect un membru m prin
intermediul unui pointer p c tre o structur ?
a) p.m;

b) p[m];

c) p&m;

d) p*m;

e) p->m.

23. Enumerarea este:


a) o list de constante de tip ntreg; b) o list de variabile de acela i
tip; c) o list de a teptare la procesor; d) o list de variabile care pot
avea diferite tipuri; e) toate r spunsurile sunt gre ite.
216

11 Tipuri definite de utilizator


24. Ce va fi afi at pe ecran dup executarea urm torului program?
#include <stdio.h>
void main(void){
enum anotimp{primavara=1,vara,toamna,iarna};
enum anotimp acum=toamna;
printf("%d",acum);
}
a) toamna;

b) 3;

c) 2;

d) 4;

e) programul con ine o eroare.

25. Care membru al urm toarei uniuni determin dimensiunea spa iului de
memorie alocat pentru variabila numar?
union exemplu{
char c;
float x;
}numar;
a) c; b) x; c) c i x; d) spa iul de memorie alocat nu are leg tur cu membrii uniunii; e) toate r spunsurile sunt gre ite.
26. Care dintre urm toarele elemente pot fi utilizate pentru a crea un nou tip
de dat ?
a) struct;

b) enum;

c) union;

d) toate;

e) niciunul.

27. Care tip poate fi utilizat pentru a crea un spa iu de memorie folosit de
dou sau mai multe variabile?
a) struct;

b) enum;

c) union;

d) toate;

e) niciunul.

28. Ce va afi a pe ecran urm toarea secven de cod:


union exemplu{
int n;
float x;
}numar={7};
union exemplu altNumar;
altNumar.x=9.75;
altNumar.n=17;
printf("%d", numar.n);
a) 7;

b) 17;

c) 9.75;

d) nimic;
217

e) uniunea con ine o eroare.

Programarea calculatoarelor
29. Cum poate fi accesat nota primului student din urm torul vector?
struct{
char nume[20];
int tipUniune;
union{
int nota;
char calificativ;
}rezultat;
}stud[50];
a) stud.rezultat.nota;
b) union.rezultat.nota;
c) stud[0].nota; d) stud[0].rezultat.nota; e) toate
r spunsurile sunt gre ite.
D. S se scrie programe pentru rezolvarea urm toarelor probleme.
30. Se dore te crearea unui buchet de flori. Buchetul poate con ine mai multe tipuri de flori i mai multe flori de acela i tip (de exemplu: 5 trandafiri, 3 frunze de ferig i un bambus). S se simuleze componen a unui
buchet. Indica ie: buchetul va fi un tablou de variabile structur , structura con innd denumirea florii i num rul de flori cu acea denumire prezente n buchet.
31. S se calculeze, folosind formula lui Heron, aria unui triunghi descris de
trei puncte ale c ror coordonate se citesc de la tastatur . Indica ii: Se va
folosi o structur de tip punct (cu cele dou coordonate); se pot folosi n
continuare structuri de tip segment (dou puncte) sau triunghi (trei puncte). Se vor calcula lungimile celor trei segmente care formeaz triunghi, unde a, b i c
ul i apoi aria cu formula
sunt lungimile laturilor, iar s este semiperimetrul.
32. Se define te o structur care descrie o dat calendaristic prin trei cmpuri (an, lun , zi). S se scrie o func ie care compar dou date calendaristice primite ca argument. Func ia va avea trei variante:
a. returneaz 0 dac datele sunt egale i 1 n caz contrar;
b. returneaz 0 dac datele sunt egale, -1 dac prima dat calendaristic este mai mic dect a doua i 1 dac prima este mai mare
dect a doua;
c. returneaz num rul de ani, luni i zile diferen
date.
218

ntre cele dou

11 Tipuri definite de utilizator


33. S se imagineze un joc de c r i cu doi participan i. Se va folosi o enumerare con innd cele patru culori ale c r ilor (inim , trefla, frunz i
romb), fiecare avnd asociat o valoare dat de programator. Celor doi
participan i la joc li se va genera aleator cte o carte i va c tiga cel care are cartea cu valoare mai mare.
34. C iva copii i vor petrece vacan a n str in tate. Informa iile care trebuie nregistrate despre ei se refer la:
a. numele copilului, care este un ir de caractere;
b. vrsta copilului, care este un ntreg i va determina dac el va
merge singur sau va fi nso it de unul dintre p rin i;
c. n cazul n care copilul are sub 18 ani, numele p rintelui trebuie
specificat; altfel, se va nregistra suma de care copilul are nevoie
n excursie.
Programul trebuie s afi eze o list cu toate persoanele implicate (copii
i p rin i acolo unde este cazul) i trebuie s calculeze ntreaga sum
de bani pe care copiii peste 18 ani o au asupra lor.
Indica ie: Ar putea fi folosit un vector de elemente care au urm torul tip
de dat :
struct copil{
char numeCopil[20];
int varstaCopil;
union{
char numeParinte[20];
int bani;
}informatiiAditionale;
};

219

Anexa 1 Setul de caractere


Aceast anex prezint caracterele uzuale, al turi de codurile lor ASCII. n total
sunt 256 de caractere. Pe lng cele enumerate aici, mai exist un set de 32 de
caractere (de la 0 la 31), asociate codurilor de control (de exemplu 9 este tab
orizontal, iar 10 este linie nou ) i, de asemenea, partea a doua a domeniului
(codurile de la 128 la 255), care variaz de la calculator la calculator (, , ).
blank

&

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

<

>

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

Anexa 2 Cuvintele cheie ale limbajului C


Tabelul urm tor con ine cuvintele cheie ale limbajului C standard. Aceste cuvinte nu pot fi folosite ca nume de variabile, constante, func ii sau tipuri definite
de utilizator pentru c ele sunt deja n uz.
Cuvnt
cheie

Descriere

auto

arat c variabila are o existen local (e implicit)

break

determin p r sirea blocului de instruc iuni n care apare

case

este o ramur a instruc iunii alternative switch; cu ajutorul ei


se creeaz un bloc de instruc iuni care se execut dac este
ndeplinit o anumit condi ie

char

tip de dat (caracter)

const

este folosit la declararea unei constante

continue

aduce execu ia programului la nceputul buclei n care apare

default

este o ramur a instruc iunii alternative switch; specific ce se


ntmpl dac nu este ndeplinit nicio condi ie case

do

instruc iune repetitiv

double

tip de dat (real dubl precizie)

else

ramur a instruc iunii if care se execut dac rezultatul condiiei este fals

enum

define te un set de constante care formeaz o enumerare

extern

arat c un element e definit n alt parte

Programarea calculatoarelor
float

tip de dat (real simpl precizie)

for

instruc iune repetitiv

goto

salt necondi ionat (transfer execu ia programului ntr-o loca ie


specificat printr-o etichet )

if

instruc iune alternativ

int

tip de dat (ntreg)

long

modificator asociat unui tip de dat (lung)

register

indic faptul c variabila declarat va fi stocat ntr-un registru

return

are ca efect p r sirea unei func ii

short

modificator asociat unui tip de dat (scurt)

signed

modificator asociat unui tip de dat (cu semn)

sizeof

returneaz dimensiunea (n octe i) a unei expresii sau a unui tip

static

variabila sau func ia va exista i dup ce obiectivul ei se ncheie

struct

grupeaz variabile ntr-o singur nregistrare, formnd o structur

switch

instruc iune alternativ

typedef

creeaz un nou tip de dat

union

grupeaz variabile ntr-o uniune

unsigned

modificator asociat unui tip de dat (f r semn)

222

Anexa 2 Cuvinte cheie


void

tipul de dat vid

volatile

indic faptul c variabila poate fi modificat ntr-un mod impredictibil (de exemplu printr-o ntrerupere)

while

instruc iune repetitiv

223

Anexa 3 R spunsuri
Capitolul 2 Scheme logice
A. 1. Pentru afi area lui x s-a folosit un bloc decizional n locul unuia de ie ire.
2. Condi ia x>0 e testat ntr-un bloc de calcul; trebuia utilizat un bloc decizional. 3. Un bloc decizional are doar dou ramuri, nu trei.
B. 4. Calculeaz i afi eaz distan a ntre dou puncte ale c ror coordonate se
citesc. 5. Se citesc coeficien ii unei func ii polinomiale de gradul trei, se afi eaz func ia, se calculeaz coeficien ii derivatei i se afi eaz derivata.
6. Calculeaz i afi eaz ultima cifr a num rului ntreg n citit (ultima cifr a
unui num r ntreg este de fapt restul mp r irii acelui num r la 10).
7. Calculeaz i afi eaz n! (factorial); n este pozitiv datorit valid rii de la
nceput.
C. 8. e). 9. c) Se poate crea o structur repetitiv punnd un bloc decizional
ntr-o bucl , dar un bloc repetitiv n sine nu exist . 10. b). 11. d). 12. a). 13. c).
Capitolul 3 Date i tipuri de date
A. 1. alfa, fiind o constant , nu are voie s - i modifice valoarea. Instruc iunea
alfa=beta+10; nu se poate executa dect dac alfa ar fi declarat variabil , nu constant . 2. double este un cuvnt rezervat n C i nu poate fi utilizat
ca nume de variabil . 3. Variabila x nu este declarat . 4. Variabila y este declarat de tip unsigned int, deci nu poate avea valoare negativ . 5. Variabila
x trebuie declarat nainte de a fi folosit , nu dup . 6. Lipse te operatorul de
nmul ire (*); expresia corect este: e=x+2*y-z;. 7. Operatorul modulo se
aplic doar numerelor ntregi, prin urmare opera ia y=x%2; nu se poate efectua
deoarece x este float. 8. Numele unei variabile nu poate ncepe cu o cifr ,
a adar variabilele 1_nota i 2_nota nu sunt denumite corect.
B. 9. E=a/5+1=3/5+1=0+1=1. a/5 este 0 deoarece a este declarat ntreg,
iar operatorul / aplicat numerelor ntregi are ca rezultat ctul mp r irii.
10. E=(a++)-(a%2)=(3++)-(3%2)=3-1=2. Incrementarea lui a se face
dup utilizarea valorii sale n expresie. 11. E=(a++)-(--b)=(3++)-(-4)=3-3=0. Incrementarea lui a se face dup utilizarea valorii sale n expresie,
iar decrementarea lui b se face nainte de a fi utilizat (pentru c operatorul -apare ca prefix al variabilei b). 12. E=(-a)-(--a)=-3-(--3)=-3-2=-5.
13. E=(a==b)=0. Expresia are caracter logic i este zero deoarece a==b este

Anexa 3 R spunsuri
o propozi ie fals . 14. E=(a+b)%4=(3+4)%4=7%4=3. 15. E=((--b)+
a++)%2=((--4)+3++)%2=(3+3++)%2=6%2=0.
C. 16. e) pentru c int, float, double i char sunt tipuri de dat care
exist n limbajul de programare C. 17. b) deoarece numele unei variabile nu
poate fi format din dou cuvinte nelegate. 18. a). 19. c) deoarece a este un
num r ntreg, iar rezultatul mp r irii va fi tot ntreg. 20. e) pentru c se deschid
trei paranteze rotunde i se nchid doar dou . 21. e) deoarece opera ia modulo
(%) se poate realiza doar ntre numere ntregi. 22. Evaluarea expresiilor este
urm toarea: a) true&&false=false, b) true||false=true,
c) (false||false)&&true=false&&true=false,
d) false||
false=false; prin urmare r spunsul corect este b). 23. e) pentru c numele
unei variabile nu poate con ine caracterul #. 24. e) pentru c toate celelalte
variante de r spuns reprezint nume de modificatori n limbajul de programare
C. 25. c). 26. d). 27. a) variabila de tip float, cu valoarea 3.1415 este
transformat prin trunchiere n num r ntreg. 28. Evaluarea expresiilor este
urm toarea: a) not false=true, b) not (false||false)=not
false=true,
c)
false||(true&&true)=false||true=true,
d) not true=false; a adar r spunsul corect este d). 29. c).
Capitolul 4 Un prim program C
A. 1. Lipse te separatorul punct i virgul de la sfr itul liniei a treia. 2. Nu se
deschide acolada pentru func ia main() (la sfr itul primei linii trebuie o
acolad deschis ). 3. Nu se ncheie comentariul multilinie; la sfr itul textului
care se dore te a fi comentariu trebuie pus marcajul */. 4. Nu e declarat variabila aria.
B. 5. Expresia E1 are valoarea 3 pentru c prin mp r irea a dou numere ntregi se ob ine tot un num r ntreg (chiar dac E1 e declarat de tip float); n
cazul expresiei E2, primul num r este supus unei transform ri de tip, astfel
nct se mparte un num r de tip float la un num r ntreg, rezultatul fiind
3.5. 6. Variabila a este incrementat dup utilizare, iar variabila b nainte de
utilizare, a adar E=7+4=11. 7. Expresia este de tip logic, iar valoarea ei e 1
deoarece propozi ia a>b este adev rat .
C. 8. b). 9. c). 10. c) r spunsurile a i b sunt gre ite deoarece include este o
directiv preprocesor, iar void este numele tipului vid. 11. b). 12. c) acolade225

Programarea calculatoarelor
le sunt utilizate n C pentru a grupa instruc iunile. 13. a). 14. a) delimitarea
instruc iunilor n C este obligatorie i se realizeaz prin punct i virgul . 15. d).
Capitolul 5 Func ii de bibliotec
A. 1. Lipse te descriptorul de format %f n printf(); instruc iunea corect
este printf("Rezultatul este: %f",x);. 2. A fost omis specificarea fi ierului antet pentru func ia printf(); la nceputul programului trebuie
ad ugat directiva #include <stdio.h>. 3. Lipse te operatorul de adresare
& de la citirea valorii variabilei a; instruc iunea corect
este
scanf("%d",&a);. 4. Descriptorul de format %5d trebuie s fie n interiorul
irului de caractere trimis ca prim argument func iei printf(); corect este
printf("Rezultatul este: %5d",x);. 5. x este o variabil de tip
float, prin urmate litera care trebuie s apar la afi are n descriptorul de
format este f, nu d; instruc iunea corect este printf("Rezultatul
este: %5.2f",x);. 6. Variabila x este de tip ntreg, a adar descriptorul de
format pentru afi area acesteia este gre it; corect ar fi fost
printf("Rezultatul este: x=%d",x);. 7. Variabilei a i s-a dat o
valoare negativ , lucru care conduce la ntreruperea execu iei programului
atunci cnd se apeleaz func ia sqrt(); pentru ca programul s func ioneze,
variabila a trebuie s aib o valoare nenegativ .
B. 8. Descriptorul de format %.1f specific faptul c afi area se face cu o
zecimal , a adar rezultatul este 9.8. 9. Textul afi at este Duminica
\ora 19\
"Tosca" - Giacomo PUCCINI, scris pe un singur
rnd, cu un spa iu de tabulare orizontal (tab) naintea cuvntului Tosca.
10. Programul nu afi eaz nimic deoarece instruc iunea exit(0) face ca el s
se ncheie nainte ca func ia printf() s fie apelat .
C. 11. c). 12. a). 13. e). 14. e). 15. d) datorit lipsei operatorului de adresare
&, valoarea citit pentru variabila x nu poate fi salvat n memorie, a a c apare
o eroare n momentul n care func ia este executat ; n cazul n care nu se face
nicio verificare asupra valorii returnate de func ia scanf(), programul se va
opri. 16. c). 17. e), to i descriptorii de format enumera i fiind corec i. 18. b).
Capitolul 6 Instruc iuni
A. 1. Lipsesc acoladele care grupeaz instruc iunile n blocuri de instruc iuni.
Din acest motiv va ap rea, n primul rnd, o eroare de compilare pentru c
226

Anexa 3 R spunsuri
else-ul nu este plasat corespunz tor. A adar, att pe ramura principal a instruc iunii if, ct i pe ramura else sunt necesare acolade. 2. Delimitatorul
celor trei p r i ale instruc iunii for este punct i virgula, nu virgula. 3. Condi ia
de la if trebuie pus n paranteze rotunde. 4. Nu este o eroare de compilare.
Dac dup for apare punct i virgul , nseamn c instruc iunea se ncheie,
adic are corpul vid. Prin urmare blocul de instruc iuni care urmeaz nu este
considerat bucl a for-ului i nu va fi repetat, ci va fi executat o singur dat ,
dup ie irea din for. 5. Operatorul SI logic este &&, nu &. 6. Condi ia
while(n<=100) trebuie pus la sfr itul blocului de instruc iuni. 7. Este
gre it ini ializarea variabilei de control. Trebuie folosit operatorul de atribuire
(i=0), nu cel de verificare a identit ii (i==0). 8. Nu este o eroare de compilare. Programul va func iona, dar nu se va opri pentru c expresia din for este
mereu adev rat . Ar trebui prev zut un break n interiorul buclei sau ar trebui
modificate specifica iile de la for. 9. Dup condi ie e necesar delimitatorul
punct i virgul .
B. 10. Programul va afi a valoarea 12 pentru x i 0 pentru y. Condi ia de la
primul if este adev rat , prin urmare se execut instruc iunea de pe acea ramur (atribuirea x=a+b). Pe ramura de else nu se mai intr , a a c cel de al
doilea if nu se execut , deci nici atribuirea de pe ramura sa (y=a*b). 11. Nu
se va afi a nimic deoarece condi ia for-ului este fals nc de la nceput. 12. Se
afi eaz perimetrul unui cerc a c rui raz e citit de la tastatur . Prin instruc iunea do while utilizatorul este for at s introduc o valoare pozitiv pentru
raz .
C. 13. c) este operator de atribuire. 14. b). 15. d) n momentul n care i
ajunge la valoarea 5, condi ia de r mnere n for nu mai este satisf cut i
instruc iunea se ncheie; a adar, la ie irea din for, variabila de control are
valoarea 5. 16. a). 17. e) primul este operator de atribuire simplu, ceilal i trei
sunt operatori de atribuire compu i. 18. e) orice valoare diferit de zero este
considerat adev rat din punct de vedere logic. 19. b) else este ramura care
s execut n cazul n care condi ia evaluat de o instruc iune if este fals .
20. b) condi ia de la primul if este adev rat , prin urmare se continu cu al
doilea if a c rui condi ie este fals , a a c se execut instruc iunea de pe ramura else a celui de al doilea if, adic decrementarea valorii lui x; pe ramura
else a primului if nu se mai intr , deci al treilea if nu se execut . 21. a). 22.
d) default marcheaz secven a de instruc iuni care se execut dac niciuna
din valorile ramurilor case ale instruc iunii switch nu a corespuns cu valoa227

Programarea calculatoarelor
rea variabilei considerate. 23. c) n cazul instruc iunii do while condi ia
este evaluat la sfr itul fiec rei itera ii, ceea ce garanteaz faptul c bucla este
executat cel pu in o dat . 24. d). 25. a) do while are test final, for are
num r cunoscut de itera ii, continue nu e instruc iune repetitiv , iar repeat
nu e instruc iune C.
Capitolul 7 Tablouri
A. 1. Cele dou func ii din interiorul for-ului trebuie grupate utiliznd acoladele. 2. Secven a de cod prezentat va tip ri cte un num r pe fiecare linie.
Pentru o tip rire corect a matricei, func ia printf("\n"); trebuie s aparin de for-ul exterior, nu de cel interior, prin urmare for-ul exterior este cel
care are nevoie de acolade; for-ul interior con ine doar func ia
printf("%7.2f", a[i][j]);. 3. n C indicii elementelor ncep de la 0,
nu de la 1. Secven a de cod considerat va pierde primul element al tabloului,
ncepnd tip rirea cu al doilea; de asemenea va tip ri ceva n plus (o valoare
f r semnifica ie pentru program, con inut n loca ia de memorie care se afl n
continuarea tabloului). Pentru o tip rire corect , indicele din for trebuie s
parcurg intervalul [0,10).
B. 4. Afi eaz cte valori nule sunt n matrice. 5. Afi eaz cte valori nule se
afl pe diagonala principal a unei matrice p tratice. 6. Afi eaz de la dreapta la
stnga elementele unui vector. 7. Afi eaz pe vertical elementele unei matrice.
C. 8. c). 9. d). 10. e). 11. d). 12. b). 13. a). 14. c).
Capitolul 8 iruri de caractere
A. 1. Variabila este declarat corect, dar este ini ializat gre it, deoarece se
folosesc ghilimele duble (care arat compilatorului c este vorba despre un ir
de caractere) n locul ghilimelelor simple. Compilatorul va ncerca ad ugarea
terminatorului de ir '\0', dar nu va putea memora aceast valoare deoarece
variabila e definit drept caracter, nu ir de caractere. 2. Gre eala apare la tip rirea caracterului. Descriptorul de format "%d" este folosit pentru a tip ri numere ntregi, prin urmare se va afi a codul ASCII asociat caracterului i nu caracterul n sine, a a cum s-a dorit. Pentru tip rirea caracterului trebuie folosit descriptorul "%c". 3. Variabila sir nu are alocat suficient spa iu pentru a stoca
valoarea care i s-a dat. Exist dou solu ii: fie se m re te num rul de caractere
alocat irului, astfel nct s ncap valoarea dorit , fie se terge acest num r,
228

Anexa 3 R spunsuri
l snd compilatorul s calculeze de cte caractere are nevoie. 4. Pentru compararea a dou iruri de caractere nu se folose te operatorul ==, ci func ia
strcmp().
B. 5. ntr-o bucl do while se cite te n mod repetat o tast . Sec iunea de cod
se ncheie cnd utilizatorul apas 'X' sau 'x'. 6. Se atribuie irului s1 valoarea "abc", iar irului s2 aceea i valoare "abc". Datorit faptului c cele
dou iruri sunt egale, func ia strcmp() va returna valoarea 0 ceea ce din
punct de vedere logic are valoare fals , prin urmare se va executa ramura else
a instruc iunii if, variabila fanion primind valoarea 2. 7. Se afi eaz "abc,
3", adic irul este abc i are lungime 3 deoarece irul creat se ncheie n
momentul ntlnirii caracterului '\0'. 8. Se atribuie irului s1 valoarea
"abc", iar irului s2 valoarea "123". Func ia strcmp() returneaz ceva
diferit de zero, deoarece irurile nu sunt identice. Prin urmare condi ia instruc iunii if este fals i se execut func ia strcat() de pe ramura else. Astfel,
irul s1 devine "abc123", iar irului s2 r mne "123".
C. 9. e). 10. c) Se concateneaz irurile a i b; rezultatul este returnat n irul
a, iar irul b i p streaz valoarea ini ial . 11. b) Cele dou iruri sunt identice, func ia strcmp() va returna valoarea 0, deci condi ia de la if este adev rat ; se incrementeaz variabila a, iar b r mne la valoarea 0. 12. d). 13. e). 14.
b). 15. a). 16. d). 17. b).
Capitolul 9 Pointeri
A. 1. Pentru declararea unui pointer se folose te operatorul *, nu &.
2. Ini ializarea unui pointer cu adresa unei variabile se face utiliznd operatorul
de adresare & (m=&x). 3. Ob inerea valorii aflate la adresa indicat de un pointer se realizeaz prin dereferen ierea pointerului (x=*m). 4. Pointerul m i variabila medie trebuie s aib acela i tip (n cazul de fa , float). 5. La valoarea
unui pointer nu se pot ad uga dect numere ntregi (pentru a indica alte loca ii
de memorie); a adar expresia p+0.5 este f r sens.
B. 6. Se va afi a 17, adic valoarea stocat la adresa indicat de pointerul p
(adresa variabilei a). 7. p+1 indic spre loca ia a doua a tabloului, prin urmare
se afi eaz valoarea -12. 8. Se concateneaz dou iruri de caractere indicate
de pointerii s1 i s2. Rezultatul afi at este Abracadabra.
C. 9. a). 10. e). 11. c) Pointerii nu se nmul esc. 12. a). 13. c). 14. a) Unui
pointer i se poate aduna doar un num r ntreg.
229

Programarea calculatoarelor

Capitolul 10 Func ii definite de utilizator


A. 1. Func ia calcul() este apelat cu parametru, ns prototipul s u specific faptul c ea nu accept parametri. 2. Variabila x, local func iei main(), nu
este vizibil n func ia calcul(), deci nu poate fi folosit acolo dect dac
este declarat . 3. Func ia calcul() este de tip void, deci nu poate returna
nimic. 4. Variabilele a i b sunt locale func iei main(); ele nu pot fi utilizate
n alte func ii. 5. Variabila x este transmis prin adres la apel, dar nu este
tratat ca pointer de func ia calcul(). 6. Func ia calcul() lucreaz cu
argumentele transmise prin adres , ns la apel acestea i sunt transmise prin
valoare. 7. Apelul unei func ii nu poate ap rea ca membru stng ntr-o opera ie
de atribuire. 8. Func ia calcul() are nevoie de doi parametri, dar i se transmite unul singur (prin intermediul expresiei a+b). 9. Pentru a putea contoriza
de cte ori a fost apelat func ia, variabila contor trebuie declarat static ;
altfel ea este reini ializat la fiecare apel al func iei. 10. S-a omis transmiterea
parametrului la autoapelarea func iei recursive calcul().
B. 11. De i func ia calcul() realizeaz opera ia 1/2, aceste valori fiind
transmise prin intermediul unor variabile de tip ntreg, rezultatul mp r irii va fi
0, care este apoi convertit la float i tip rit cu dou zecimale, deci 0.00.
12. Variabila a este ini ializat cu 1 i transmis func iei calcul() care
incrementeaz ceea ce prime te, dar pentru c transmiterea se face prin valoare,
aceast incrementare nu va fi vizibil n main(), unde a r mne la valoarea 1
care va fi afi at . 13. Deoarece variabila a este transmis prin adres , incrementarea care are loc n func ia calcul() se face chiar asupra variabilei (nu
asupra unei copii), prin urmare valoarea tip rit va fi 2. 14. Variabila x este
global , deci accesibil ntregului program; ea este ini ializat n func ia calcul() cu valoarea ++1, adic cu 2, aceast valoare fiind vizibil i n
main(). Variabila y este declarat local n main(); incrementarea ++a care
se face asupra valorii sale transmis func iei calcul() nu este vizibil n
main(), prin urmare y r mne la valoarea 1. 15. Variabilele x i y se comport la fel ca n programul precedent. Variabila z prime te valoarea incrementat
n func ia calcul(), adic 2. 16. Variabila a este transmis prin valoare, iar
b prin adres , a adar, la revenirea din func ia care incrementeaz ambele valori
primite, a va r mne la valoarea 1, iar b va avea valoarea 2. 17. Afi eaz caracterele n ordinea invers a introducerii lor.
230

Anexa 3 R spunsuri
C. 18. d). 19. b). 20. d). 21. a). 22. c) Apelul unei func ii nu poate ap rea ca
membru stng ntr-o opera ie de atribuire. 23. e) Func ia definit accept doar
un parametru i este apelat cu doi. 24. e) Variabilele pot fi locale sau globale.
La rndul lor, cele locale pot fi automatice (implicit) sau statice. 25. e).
Capitolul 11 Tipuri definite de utilizator
A. 1. Dup acolada nchis e necesar separatorul punct i virgul . 2. Variabila
unCerc este amplasat gre it; ea trebuie declarat ntre acolada nchis i
separatorul punct i virgul . 3. Lipse te acolada deschis care trebuie plasat
dup struct. Faptul c lipse te numele structurii nu este o eroare deoarece
instruc iunea care define te structura declar i o variabil de acel tip, ceea ce
este suficient. 4. De i numele structurii i lista de variabile declarate la sfr it au
ambele caracter op ional, ele nu pot lipsi n acela i timp. Pentru ca definirea
structurii s fie corect e nevoie fie de o etichet pentru structur , fie de una sau
mai multe variabile declarate la sfr itul instruc iunii care define te structura.
5. Variabila salariu nu are sens de sine st t tor. Ea este un membru al structurii i poate fi accesat prin intermediul variabilei unAngajat astfel:
unAngajat.salariu=2500;. 6. Pentru accesarea unui membru al unei
structuri prin intermediul unui pointer se folose te operatorul ->, deci corect
este: unPointer->salariu=2500;. 7. Valoarea asociat unei constante
dintr-o enumerare este de tip ntreg, prin urmare constanta trebuie tip rit cu
specificatorul "%d", nu cu "%s". 8. Nu este o eroare de compilare, dar programul nu va avea func ionalitatea dorit . Variabilele membru n i x folosesc
acela i spa iu de memorie. Atribuirea numar.x=9.75 va suprascrie variabila
numar.n, prin urmare valoarea afi at nu are sens. 9. Uniunea exemplu
poate primi la ini ializare doar o valoare ntreag (pentru c o uniune poate fi
ini ializat numai cu o valoare de tipul primului s u membru). 10. Dac o uniune este accesat prin intermediul unui pointer, atunci trebuie utilizat operatorul
->. Forma corect a func iei de tip rire este: printf("%d", p->n);.
B. 11. ntregul con inut al variabilei produs1 a fost copiat n variabila produs2, prin urmare pe ecran se afi eaz 1.50. 12. Deoarece poligonul este
transmis prin valoare, modific rile care se realizeaz asupra lui n interiorul
func iei modifica() nu sunt vizibile n main(), prin urmare pe ecran se va
afi a Patratul are 4 laturi 13. Poligonul este transmis prin adres
c tre func ia modifica(), a adar modific rile vor fi vizibile n main(), pe
ecran afi ndu-se Heptagonul are 7 laturi. 14. Pe ecran se afi eaz
231

Programarea calculatoarelor
1 deoarece variabila enumerare f indic spre constanta adevarat care are
asociat valoarea 1. 15. 7. 16. 7.
C. 17. c). 18. d). 19. a). 20. b). 21. a). 22. e). 23. a). 24. b). 25. b) pentru c cel
mai cuprinz tor element al uniunii (din punct de vedere al num rului de octe i
pe care se reprezint ) este float-ul. 26. d). 27. c). 28. a). 29. d).

232

Bibliografie
[BH92]

Borland C++ Help, Versiunea 3.1, Borland International, Inc., 1992

[BK03]

Brian KERNIGHAN, Dennis RITCHIE: Limbajul C, Editura


Teora, 2003, ISBN 973-20-0476-2, Authorized translation from the
English Language Edition entitled The C Programming Language, 2nd Edition, by Brian W. Kernighan, Dennis M. Ritchie,
Prentice-Hall, 1988, ISBN 0-13-110370-9

[CH96]

Clint HICKS: Utilizare C. U or i repede, Editura Teora, 1996,


ISBN 973-601-335-9

[DEX09] Dic ionarul explicativ al limbii romne, Academia Romn ,


Institutul de Lingvistic Iorgu Iordan Al. Rosetti, Editura Univers Enciclopedic, 2009, http://dexonline.ro
[DL06]

Doina LOGOF TU: Bazele program rii n C. Aplica ii, Editura


Polirom, 2006, ISBN 973-46-0219-5

[GP00]

Greg PERRY: Ini iere n programarea calculatoarelor, Editura


Teora, 2000, ISBN 973-20-0538-6

[HS98]

Herbert SCHILDT: C manual complet, Editura Teora, 1998,


ISBN 973-601-471-1

[NR01]

Nicolae ROBU: Arhitectura calculatoarelor, Editura Politehnica,


2001, ISBN 973-8247-01-2

[PT12]

Programming Tutorials C Tutorial,


http://www.cprogramming.com/tutorial/c-tutorial.html, ultima
accesare: februarie 2012

[SL12]

The C Standard Library,


http://www.utas.edu.au/infosys/info/documentation/C/CStdLib.html
ultima accesare: februarie 2012

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