Documente Academic
Documente Profesional
Documente Cultură
PROGRAMAREA CALCULATOARELOR
LIMBAJUL C
Adriana ALBU
Loredana STANCIU
PROGRAMAREA CALCULATOARELOR
LIMBAJUL C
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
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
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
Reprezentare
Implementare
START
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
STOP
Figura 2.1.1 Schem logic n care este utilizat doar blocul de ie ire
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
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
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
Cite te a,b
NU
NU
b 0
a 0
DA
x=-b/a
DA
Scrie Ecua ia nu
are solu ii
Scrie x
STOP
Figura 2.1.5 Schema logic pentru rezolvarea ecua iei de gradul nti
19
Programarea calculatoarelor
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 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
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
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
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) 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 .
b) cerc;
c) romb;
d) arc de cerc;
e) parabol .
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
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
de
Multiplii octetului
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
float
real (virgul
flotant )
32 bi i
double
real (virgul
flotant ,
dubl precizie)
64 bi i
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
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
ntreg cu semn
16 sau
32 bi i
unsigned
short int
ntreg
scurt
f r semn
8 bi i
0 255
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
ntreg lung cu
semn
32 bi i
-2.147.483.648 2.147.483.647
float
real
32 bi i
f r
cu
(virgul
33
Programarea calculatoarelor
flotant )
double
real (virgul
flotant , dubl
precizie)
64 bi i
long double
real
lung
(virgul
flotant ,
dubl
precizie)
80 bi i
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.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
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
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
se scrie
. Aceast expresie este diferit
care calculeaz de fapt
.
de
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
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
int a, x;
x = 7;
a = ++x;
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;
45
Programarea calculatoarelor
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-
b) 0;
c) -24;
d) 24;
b) 1;
c) 32;
d) 65;
b) -6;
c) -12;
d) 2;
b) 1;
c) 14;
d) 49;
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
c) signed;
d) unsigned;
e) toate
c) boolean;
d) char;
e) toate r spunsu-
b) 2;
c) 4;
d) 8;
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;
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-
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
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)
{
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
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
57
Programarea calculatoarelor
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
c) executabil;
b) void;
c) integer;
d) main;
e) nimic.
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) <!--.
b) .obj;
c) .exe;
d) .c;
e) .txt.
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
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
}
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.
2.71828;
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 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
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 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();
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();
de
b) %7.3f;
c) %d;
d) %c;
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
6 Instruc iuni
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;
82
6 Instruc iuni
fals
EXPRESIE
Bloc de
instruc iuni 2
adev rat
Bloc de
instruc iuni 1
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", ¬a);
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);
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
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");
}
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.
Programarea calculatoarelor
Ini ializare
EXPRESIE
fals
adev rat
Bloc de
instruc iuni
Ac iune
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
EXPRESIE
adev rat
Bloc de
instruc iuni
fals
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
Bloc de
instruc iuni
adev rat
EXPRESIE
fals
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);
}
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
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
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
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 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) ==;
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-
b) +=;
c) -=;
d) %=;
18. Care dintre urm toarele numere are valoarea logic adev rat?
a) 1;
b) -1;
c) 7.5;
d) -7;
e) toate.
b) if;
c) while;
d) do while;
e) for.
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.
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-
s ( s a )( s b)( s c)
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
Programarea calculatoarelor
-3
12
-9
n-2
n-1
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).
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 Tablouri
m-1
-3
11
-7
-1
17
.
.
.
.
.
n-1
117
Programarea calculatoarelor
7 Tablouri
119
Programarea calculatoarelor
a) pe orizontal
b) pe vertical
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.
a) diagonala principal
d) diagonala secundar
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.
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 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);
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 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
Programarea calculatoarelor
c elementul a[7] este egal cu 7;
i ini ializeaz primul s u element;
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
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
\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
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);
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).
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.");
}
iruri s1 i s2
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();
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)
c) un operator;
d) o
a) strcat();
b) strconcatenate();
te(); d) strconc(); e) conc().
c) concatena-
c) strlen();
d) strcmp();
b) strcpy(s2,s1);
c) s2=s1;
d)
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 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
..
.
65528
9.5
.
.
.
65520
nota
*p
65528
..
.
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=¬a.
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=¬a;
nota=9.5;
printf("%.2f",nota);
printf("\n%.2f",*p);
}
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.
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
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.
b) &;
c) ++;
d) --;
e) /.
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.
d)
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
Programarea calculatoarelor
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
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
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
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
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
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
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();
}
}
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
}
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
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 .
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
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
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
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();
}
}
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
Programarea calculatoarelor
calcul(a);
printf("%d",a);
b) un int;
c) un float;
d) un char;
e) un poin-
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)
c) static ;
d) automatic ;
e) toate r s-
b) adres ;
c) po t ;
d) fax;
e) r spunsurile a i b
192
193
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 .
tipn varn;
} lista_variabile;
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
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
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
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
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);
}
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
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
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
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
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();
}
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
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;
b) &;
c) *;
d) #;
e) \.
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.
b) 3;
c) 2;
d) 4;
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.
b) 17;
c) 9.75;
d) nimic;
217
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
219
&
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
Descriere
auto
break
case
char
const
continue
default
do
double
else
ramur a instruc iunii if care se execut dac rezultatul condiiei este fals
enum
extern
Programarea calculatoarelor
float
for
goto
if
int
long
register
return
short
signed
sizeof
static
struct
switch
typedef
union
unsigned
222
volatile
indic faptul c variabila poate fi modificat ntr-un mod impredictibil (de exemplu printr-o ntrerupere)
while
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
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]
[BK03]
[CH96]
[GP00]
[HS98]
[NR01]
[PT12]
[SL12]