Sunteți pe pagina 1din 22

Ll.

1 SDA Tema Analiza eficienei prelucrrii structurilor de date cu pointeri

Sarcina i obiectivele: 1. De studiat i nsuit materialul teoretic din lucrarea dat cu lansarea exerciiilor, din text, la execuie pentru evidenierea esenialului prelucrrii structurilor de date cu pointer n elaborarea modelelor soluiei prin or ani rame. !. Lansai problemele propuse "1#$ spre implementare i anali%ai modurile speci&ice de repre%entare i prelucrare ale datelor. '. S se recapitule%e materialul teoretic din lucrrile de lab. ()* "+,$ din semestrul - i s se anali%e%e al oritmii i pro ramele cu i &r pointeri "declarri i parcur eri$. #. +entru apro&undarea nele erii s se preia variantele problemelor de la pro&esor i s se elabore%e scenariile succinte de soluionare prin pointeri cu calculele de veri&icare i explicaii. .ularea
pro ramelor n limba/ul , cu a&iarea tuturor variabilor de intrare i &inale.

(. 0n raport s &ie expuse toate pro ramele cu comentarii i re%ultatele calculelor e&ectuate. S se anali%e%e te1nica pro ramrii e&iciente cu pointeri n ba%a exerciiilor i variantelor problemelor e&ectuate pentru diverse situaii cu ar umentri.

Consideraii teoretice:
1. Noiuni, exe ple i i portana i ple entrii pointelor
1.1. 23T-425A D5 +3-2T5. 4n pointer este o variabila care are ca valoare adresa unei %one de memorie. %ona de memorie este o succesiune 1 , ! , # , 6 sau mai multe locatii " octeti $ consecutive de memorie . Adresa unei %one de memerie este numarul de ordine a primei locatii de memorie " cea mai din stin a $ . Sunt doua mari cate orii de pointeri 7 pointeri catre variabile si pointeri catre &unctii .
Deci pointerii sunt variabile care contin adresa de memorie a unei alte variabile. Din aceste considerente, pointerii se numesc si variabile de adresa. +resupunem ca avem o variabila de tip ntre numita entitate locali%ata la adresa de memorie 8x1888 "adresele sunt automat asi ante variabilelor de catre compilator$. Daca dorim sa re&erim aceasta variabila prin intermediul unui pointer entitate_ptr, atunci valoarea pointerului va &i 8x1888 " entitate_ptr = 0x1000$, ast&el spunem ca entitate_ptr 9arata9 spre variabila entitate "+entru a se evita con&u%iile, se recomanda ca numele pointerilor sa aiba su&ixul _ptr$. +entru a ntele e mai bine mecanismul de &unctionare a pointerilor, introducem o analo ie pointeri ) adrese postale, n care adresa de memorie este adresa postala, numele variabilei pointer este numele cladirii, iar entitatea re&erita este cladirea propriu) %isa. Aceasta analo ie este pre%entata n tabelul *.1. Se observa ca doi pointeri di&eriti " Fac_AC si Fac_ETC$ au aceeasi valoare, indic:nd spre aceeasi locatie, ast&el re&erind aceeasi entitate. Tabela *.17 Analo ie pointeri ) adrese postale ;ariabila "nume pointer$ <ac=<,-> ;aloare adresa str. Studeneasc? 5ntitate ,ladire <,->

+ointerii se utili%ea%a pentru a &ace re&erine " a avea acces $ . la valoarea unei variabile atunci cind se cunoaste adresa ei . Dar o variabila se memorea%a intr ) o %ona de memorie de o anumita lun ime , &unctie de tipul ei . De exemplu , o variabila de tip int se memorea%a pe doi octeti , pe cind una de tip &loat pe # octeti . De aici urmea%a ca un pointer nu repre%inta numai adresa unei variabile ci mai mult decit atit , anume7 adresa unei %one de memorie @

tipul variabilei " int , c1ar , double etc . $ care este memorata in acea %ona de memorie .
2otiunea de pointer &ace ca limba/ul , sa &ie un puternic instrument de pro ramare , mai ales la indemina pro ramatorilor avansati . .ecomandam ca utili%area pointerilor sa se &aca numai dupa intele erea clara a mecanismului de lucru cu adrese, intrucit, &olositi &ara discernamint, asa cum actionea%a insasi creatorii limba/ului7 A . Berni 1am si D. .itec1ie, ei repre%inta o cale si ura de a scrie pro rame imposibil de inteles si uneori eneratoare de erori ciudate " pointerii neinitiali%ati, distru erea unor %one de memorie etc. $. Totusi &olositi cu economie si disciplina, ei dau nastere la pro rame clare si simple, si de cele mai multe ori mai rapide decit in varianta &ara pointeri. 1.!. D5,LA.A.5A +3-2T5.-L3. ,a si in ca%ul oricaror tipuri de variabile si pointerii trebuie declarati. 5i se declara la &el, cu deosebirea ca numele pointerului este precedat de caracterul C. Declaratia de pointer este7 tip ! nu e@ si prin aceasta se preci%ea%a ca nume este un pointer catre o %ona de memorie care contine valoarea unei variabile de tipul tip. -n declaratia de mai sus tip poate &i 7 int, unsi ned, c1ar, &loat, double etc. sau un sablon de structura "ve%i capitolul urmator$. Deci constructia tip C introduce un nou tip de date anume pointer la tip. -n a&ara de tipul int, lon , &loat etc., exista si un pointer special, anume de tip void "mai precis &ara tip$. care se re&era la o %ona de memorie ce poate contine orice tip de variabila. 5xemple

lon" !pl # DC pointer la lon @ CD c$ar !pc# DC pointer la c1ar@ CD double !x@ DC pointer la double@ CD void !v # DC pointer &ara tip @ CD int !pi% & '# DC sir de 6 pointeri la int@ CD unsi"ned !p % ( '% ) '# DCmasiv bidimensional de pointer la unsi ned. CD 1.* +tilizarea pointerilor. 4n pointer special de&init n limba/ul , este pointerul N+,,, care nu indica spre nimic
"adresa spre care arata acest pointer este 8$. Acest pointer este de&init n stdio.$ si n stdlib.$ ca &iind "void C$ 8, adica un pointer spre o locatie de tip void si care arata spre locatia de memorie 8. -nainte de toate, pointerul este o variabila, ca orice variabila, i el trebuie initiali%at, un pointer trebuie iniiali%at, de ex. cu adresa unei variabile de tipul potrivit7 int x, !p, !!pp# p - .x# pp - .p#

3 re&erin !p poate &i &olosit la st:n a sau la dreapta unei atribuiri "n ca%ul de mai sus, Cp se &olosete absolut la &el "sinonim$ cu x$

int x, /, z, !p#

p - .x#

z - !p# DC % E x CD

!p - /#

DC x E F CD

-nitiali%area se poate &ace la declararea pointerului sau in decursul pro ramului. 5xista totusi cateva restrictii , ast&el daca ptr1 si ptr! sunt pointeri de tip1 respectiv de tip!, atunci o atribuire7 ptr 1 - ptr ) # este permisa numai daca7 ) tip1 si tip! repre%inta acelasi tip, sau ) tip1 este void , sau ) se &ace o conversie explicita " cast $ a lui tip! catre tip1. 0peratii cu pointeri +ointerii se declara pun:nd un asterisc ! n &ata numelui variabilei7 int variabila# DCde&inire variabila intre CD int !variabila1ptr# DCde&inire pointer la un intre CD 3peratorii speci&ici pointerilor sunt7

operatorul de dere&erentiere ! "pentru un pointer, returnea%a entitatea re&erita de pointer$ si operatorul de adresa . "pentru o entitate, returnea%a adresa entitatii$. 5xemplul urmator explica &olosirea acestor operatori. ;ariabila pointer obiect_ptr primeste adresa variabilei obiect, ast&el obiect_ptr va indica spre %ona de memorie unde este memorata variabila obiect. 0n ultima linie, se stoc1ea%a valoarea ( la %ona de memorie spre care arata obiect_ptr, adica n variabila obiect.
int obiect@ DC variabila de tip intre CD int ! obiect1ptr# DC pointer la un intre CD obiect-2# obiect1ptr-.obiect# DC obiect=ptr va indica spre obiect CD printf345d6n4, !obiect1ptr7# DC a&isea%a valoarea spre care indica obiect=ptr CD !obiect1ptr-(# DC atribuie lui obiect valoarea ( CD

2ot7 <olosirea resita a operatorilor poate duce la &unctionri incorecte a pro ramului sau, n ca%ul &ericit, la erori semnalate de compilator7 !variabila este ile al, prin aceasta se solicita entitatea re&erita de o variabila care nu este un pointer@ .variabila1ptr este le al, dar 9neobisnuit9, se solicita adresa lui variabila=ptr, adica un pointer la un pointer. >ai multi pointeri pot indica spre aceeasi %ona de memorie7
int obiect# int !obiect1ptr1# int !obiect1ptr)# obiect - 1# obiect1ptr1 - .obiect# obiect1ptr) - obiect1ptr1# printf345d 5d6n4, !obiect1ptr1, !obiect1ptr)7# 8! se atribuie valoarea 1 lui obiect !8 DC obiect=ptr1 si obiect=ptr! vor indica spre aceasi locatie de memorie CD

3AS7 3peratorii adres . i de indirectare ! sunt unul inversul celuilalt7 !.x este c1iar x, pentru orice obiect "variabil$ x .!p are valoarea p, pentru orice variabil pointer p "dar p e o variabil i poate &i atribuit@ GCp e o expresie i nu poate$
Deci pentru a atribui unui pointer o adresa exista operatorul . , numit si de adresaH , care aplicat unei variabile , unui element al unui masiv sau unei structuri &urni%ea%a adresa %onei de memorie unde este memorat respectivul obiect. 3peratorul . este unar , are aceeasi prioritate cu a altor operatori unari II, )) , J , ) "dupa parante%e$ si se asocia%a de la dreapta la stan a. 2u se aplica expresiilor intre parante%e , constantelor sau variabilelor de tip re ister si de aceea utili%arile7 G "a I ! C b $ sau G1' sunt eronateJJJJJJJJJ Totusi , la lucru cu pointeri, cel mai mult interesea%a a&larea valorii din %ona de memorie care are ca adresa pointerul, deci actiunea complementara celei de a&lare a adresei. 3peratorul care reali%ea%a acest lucru este operatorul unar C, numit si de de&erentiereH , sau de indirectareH, care aplicat unui pointer ne &urni%ea%a valoarea datei memorata la adresa pointerului. 5xemplu 1.'.1. . . . . int x, /, !px # D C x, F K intre i @ px K pointer la int CD px - .x # DC px este initiali%at cu adresa lui x CD / - ! px # DC valoarea a&lata la adresa px se atribuie lui F CD

Se observa ca secventa de mai sus este ec1ivalenta cu atribuirea 7 / - x # 5ste permisa si notiunea de pointer la pointerH. Ast&el prin 7 int ! ! ppi # se declara ppiH ca &iind un pointer la un pointer de tip int. Alt&el spus ppi contine adresa unei %one de memorie ce contine un numar de tip int. -n acest sens urmariti exemplul urmator 7 5xemplu 1.'.!. L include studio.1H ain 3 7 9 int i, !pi, !!ppi# DC se declara un intre , un pointer la int. si un pointer la pointer la int. CD pi - . i # DC initiali%area pointerului pi cu adresa lui i CD ppi - . pi# DC initiali%area lui ppi cu adresa lui pi CD printf 3 : pi - 5p ppi - 5p 6 n , pi, ppi7 # !pi - ;# 8C5c1ivalent cu i E * CD printf 3: i - 5d 6 n :, i 7# i - !pi < * # 8 ! 5c1ivalent cu i E i ) ' @ CD printf 3 : i - 5 d 6 n :, i7 # !pi - !!ppi!)# DC 5c1ivalent cu i E iC ! @ CD printf 3 : i - 5 d 6 n :, i7 # = La executia pro ramului pe ecranul calculatorului se va a&isa 7 pi E <<D5 ppi E <<53 iE * iE # iE 6 -n pro ramul precedent se observa ca operatorul C aplicat unui pointer poate sa apara in partea stan a a unei atribuiri. Deci constructia C pointer este o valoare) stan a. 3peratii indirecte asupra variabilelor DD3peratii indirecte asupra variabilelor x F x, / se adresea% direct la variabila LincludeMstdio.1N cu valoarea * * O*

void main"$ Pint x E *, F E O*, s E 8@ int Cpx, CpF@

respectic O*.

DDLuam adresa variabilelor x, F7

px E Gx@ pF E GF@
DDSuma x I F s E "Cpx$ I "CpF$@

<ie ca variabila x se a&la pe adresa Q888, iar * (888 Q888 Q888 variabila pointer pe adresa (888. px se adresea% indirect la variabila cu valoarea *. Analo pF se adresea% indirect la variabila cu valoarea O*.

px

3peratia C, returnea% valoarea obiectului la care operandul "pointerul$ pointea%7 s E * I O*

DDA&isarea Sumei print&"9RnSumaESdR 9,s,$@ T


5xemplu 1.'.'. -n acest exemplu se va utili%a pointer de tip void , pointer care nu se poate dere&erentia. 4rmariti situatiile cand un pointer void se poate utili%a ca atare si cand este obli atorie o conversie explicita "cast $ , spre exemplu " int C $. L include stdio.1H main " $ P int i, C pi @ DC se declara un intre si un pointer la int CD void C pv @ DC se declara un pointer de tip void CD pi E G i@ DC initiali%area pointerului pi cu adresa lui i CD pv E pi@ DC corect J lui pv i se atribuie valoarea pointerului pi CD C pi E 18@ DC 5c1ivalent cu i E 18@ CD i E C pv I (@ DC Uresit J pv este pointer de tip nedeterminat "void$ CD i E C "int C7 pv I (# 8! corect J pv este convertit explicit spre pointer la intH CD DC si ast&el instructiunea este ec1ivalenta cu i E i I (@ CD T 1.'. >0?N@AB S? @AC,0+B? +N?D?EANS?0NA,A pointerii sunt intim le ai de tablouri, numele unui tablou &iind c1iar un pointer constant care are ca valoare adresa elementului de index 8 al tabloului respectiv. 3rice operaie care se &ace &olosind indicii tablourilor poate &i &cut, c1iar mai rapid, prin &olosirea pointerilor. 5xemplu7 -niiali%area elementelor unui tablou &r pointeri i cu pointeri

0n primul ca%, pentru a&larea adresei elementului x?iV compilatorul enerea% un cod care nmulete pe i cu dimensiunea unui element al tabloului. 0n varianta cu pointeri, compilatorul evaluea% o sin ur dat indicele irului, salv:nd ast&el #O de operaii de multiplicare. .e&erirea la elementul unui tablou sub &orma a?iV este identic cu C"aIi$. De &apt, imediat ce se nt:lnete o re&erin de &orma a?iV, compilatorul , convertete aceasta la C"aIi$. 5vident, construciile Ga?iV i aIi sunt de asemenea identice. 5xemplu 1.#.1. -n urmatorul exemplu de pro ram se de&ineste un sir de caractere de dimensiune maxima 6 elemente initiali%ate cu 7 abc$. main " $ P c1ar s? 6V@ s?8V E WaX@ s?1V E WbX@ s?!V E WcX@ s?'V E W $ W@ s?#V E WR oX@ print& "sirul S este S s R nH, S$@ T La executie se va a&isa 7 abc $ adica elementele sirului pana la caracterul 24LL "X R8 W$. -n exemplul de mai sus s s)a declarat ca masiv unidimensional "sir$ de maxim 6 elemente , dar in pro ram s)au utili%at ( elemente. >ai mult decat atat s se putea declara ca parametru la o &unctie ca tablou desc1is 7 c1ar s? V @ pentru ca in aceasta situatie alocarea spatiului de memorie necesar se &ace dinamic . Acest lucru este permis deoarece in limba/ul , numele s al sirului este automat convertit la un pointer catre primul element al sirului. Acest pointer este constant in sensul ca este ile al a se modi&ica " prin atribuiri$ in pro ram, deci nu este o parte stan a. -nseamna ca declaratiile7 c$ar s% ' # si c$ar !s # sunt ec1ivalente, cu observatia ca in primul ca% s este un pointer constant, initiali%at cu adresa lui s?8V, iar in al doilea ca% este un pointer obisnuit si neinitiali%at. Aceasta ec1ivalenta ne permite sa transmitem ca parametri unei &unctii siruri, matrici etc. prin pointeri catre primul lor element. Deci o &unctie care prelucrea%a elementele unui sir poate arata7 void & "c1ar s? V$ P ... T sau -n ambele exemple, s&arsitul sirului s va &i determinat de detectarea void & "c1ar C s$ caracterului W R o W . P ... T Al doilea tip de &unctie &oloseste ca ar ument o adresa si de aceea in acest ca% se mai spune ca apelul este prin re&erinta " in en le%a call bF adress$. Totusi, in ca%ul masivelor multidimensionale care sunt parametrii unei &unctii numai prin dimensiune poate lipsi. 5x. int & " &loat a ? V ?18V$ -n acest exemplu parametrul &unctiei & este un pointer catre primul element a unei matrici cu 18 coloane. 1.(. 0>ABA@?? AB?@EA@?CA C+ >0?N@AB? Deoarece pointerii contin ca valoare o adresa de memorie, operatiile aritmetice permise sunt7 atribuirea, adunarea cu un intre , scaderea cu un intre , scaderea a doi pointeri, comparatia unui pointer cu constanta simbolica 24LL si compararea a doi pointeri. Atribuirea a &ost tratata in para ra&ul (.'. Adunarea unui pointer cu un intre .e%ultatul adunarii este un pointer de acelasi tip marit cu intre ul de adunat inmultit cu numarul de octeti necesari pentru a memora o valoare de tipul pointerului. Ast&el daca 7 tip ! ptr# atunci7 ptr I i modi&ica ptr cu i ! sizeof 3tip7. Deci noua valoare a lui ptr este7 ptr F i! sizeof 3tip7. Daca intre ul i este l atunci se poate &olosi operatorul II pre&ixat sau post&ixat7 II ptr sau ptr II. 2oul ptr va &i 7 ptr I si%eo& "tip$. 5x. int C pi, i@ ... piII@ DC Aduna ! la pi "si%eo& "int$ E !$ CD i E C "pi I '$@ DC Aduna ! C ' la pi si intre ul memorat la pi I Q este atribuit lui i CD ... Daca avem de)a &ace cu un masiv unidimensional "sir$ tip a %D?E'@ atunci numele sirului neurmat de indici este considerat pointer catre primul sau element, anume pointer constant ce contine intotdeauna adresa lui a% G'. .Alt&el spus, valoarea lui a este . a%G'. Deci inseamna ca adunarea unui intre la acest tip de pointer este o constructie corecta si 7 a F i este identic cu .a% i ' iar

!3aFi7 este identic cu a % i ' . 1.5.1. Scaderea unui intre" dintrHun pointer 5&ectul scaderii unui intre dintr)un pointer este acela ca valoarea pointerului se micsorea%a cu intre ul de sca%ut inmultit cu numarul de octeti necesari pentru a memora o valoare de tipul pointerului. Daca7 tip !ptr# atunci noua valoare a pointerului dupa7 ptr K i este 7 ptr < i ! sizeof 3tip7. 4tili%and operatorul de decrementare HH ptr sau ptr < noua valoare pentru ptr va &i ptr < sizeof 3tip7. Atat operatorul de incrementare II, cat si cel de decrementare K se pot utili%a in expresii cu pointeri impreuna cu operatorul de dere&erentiere C. +entru corectitudine trebuie tinut cont ca operatorii II , )) si C sunt de aceeasi prioritate si se asocia%a de la dreapata la stan a, deci se vor &olosi parante%ele pentru a &orta ca un operator sa se execute primul. Ast&el daca7 tip !ptr# atunci7 !ptr FF respectiv !ptr K mai intai obtine valoarea de la adresa ptr si apoi incrementea%a , respectiv decrementea%a pointerul@ 3!ptr7FF respectiv 3!ptr7 K obtine valoarea de la adresa ptr pe care o incrementea%a , respectiv o decrementea%a@ !FFptr respectiv ! HH ptr mai intai incrementea%a, respectiv decrementea%a pointerul si apoi obtine valoarea de la noua adresa ptr@ FF!ptr respectiv HH!ptr obtine valoarea de la adresa ptr pe care o incrementea%a , respectiv o decrementea%a . 5xpresiile cu pointeri de mai sus permit o scriere mai compacta a pro ramului si in comparatie cu utili%area indicilor la un tablou duc la o executie a pro ramului intr)un timp mai scurt. 4n motiv in plus pentru utili%area acestor expresii este ca7 CptrII, Cptr )), CIIptr si C)) ptr, intrucat se re&era la obiectul catre care indica adresa din ptr, sunt valori)stan a "L value$ si deci pot &i utili%ate la stan a operatorului de atribuire E. -n acest ca% operatorul E va modi&ica obiectul re&erit. 1.5.2. Scaderea a doi pointeri -n eneral scaderea a doi pointeri este o operatie ile ala, cu cateva exceptii. Ast&el, daca pointerii sunt de acelasi tip , in sensul ca se re&era la obiecte de acelasi tip, ei se pot scade si re%ultatul scaderii este un intre int sau lon " &unctie de modelul de memorie$ e al cu numarul de locatii de memorie capabile sa memore%e o valoare de tipul comun al pointerilor existente intre adresa primului si adresa celui de)al doilea. .e%ultatul este po%itiv daca primul pointer este o adresa a&lata la dreapta adresei din cel de)al doilea pointer si ne ativ in ca% contrar. <ie pointerii ptrl si ptr!7 tip !ptrl , !ptr)# atunci7 ptr l < ptr ) va &i e al cu 3ptr l < ptr )78 sizeof 3tip7. Alta scadere corecta este aceea cand cei doi pointeri indica spre elementele aceluiasi tablou si in aceasta situatie re%ultatul este e al cu numarul de elemente dintre cei doi indici7 po%itiv daca indicele l N indicele ! si ne ativ in ca% contrar. 5xemplu 1.(.1. L include stdio.1H ain 3 7 9int ! pl, !p)# 8! se declara doi pointer de tip int CD int x % ' - 9 G,1,),*,2,(,I,;=# DC se declara un sir de 6 intre i care se initiali%ea%a CD pl - . x % ) '# DC +ointerul pl se initiali%ea%a cu adresa lui x ?!V . 5c1ivalent cu 7 pl E x I ! @ CD p) - x F ;# DC+ointerul p! se initiali%ea%a cu adresa de inceput a lui x plus inca * locatii a cate ! octeti adica cu adresa lui x ?*V. 5c1ivalent cu 7 p! E G x ? *V@ CD printf 3:x - 5u pl - 5u p)- 5u 6n, x,pl,p)7# printf 3:Diferente: pl < x - 5u p) < x - 5u p)H p1 - 5u 6n, pl < x, p) < x, p) < pl7# = La executia pro ramului se va a&isa7 x E Q(#O# pl E Q(#O6 p!E Q((86 Di&erente7 pl K x E ! p! K x E * p! K p1 E ( 1.(.*. Co pararea a doi pointeri. +entru ca operatia de comparare sa &ie valida, cei doi pointeri trebuie sa indice catre doua elemente ale aceluiasi tablou si re%ultatul comparatiei este e al cu re%ultatul comparatiei celor doi indici. Daca pointerul pl indica pe a ?iV, iar pointerul p! indica pe a ?/V atunci7 pl M p! E 1 "adevarata$ daca i M /@ E 8 "&alsa$ daca i N /@ pl N E p! El "adevarata$ daca i N /@ E 3 "&alsa$ daca i M /@ pl E E p! E l "adevarata$ daca i E /@ i E 8 "&alsa$ daca i / Siruri cu index ne ativ sau mai mare decat dimensiunea maxima La adunarea unui intre la un pointer spunem ca daca a este un sir7 tip a% D?E'# atunci7 a F i este identic cu .a% i ', iar !3a F i 7 este identic cu a %i'. -ntre ul i care se aduna la pointerul constant a poate &i mai mare sau e al cu dimensiunea maxima a sirului.,ompilatorul , nu &ace veri&icarea depasirii dimensiunii maxime. De asemenea ,din pointerul a se poate scade orice intre si compilatorul , nu veri&ica depasirea limitei din stan a a sirului.-ntr)adevar la &el ca si la adunare cu intr i 7 a < J este identic cu .a%HJ', iar 3aHJ7 este identic cu a%HJ'. Deci, in limba/ul , utili%area indexului ne ativ sau a indexului mai mare decat dimensiunea maxima este permisa asa cum se ilustrea%a in urmatorul exemplu. 5xemplu 1.(.!. L include stdio.1H

main " $ P int i, a ?6V@ &or "i E )'@ iME1!@ iII$ DC se initiali%ea%a 7 CD a?iV E i@ DC a ?)'V E )'@ a ?)!V E)!@ CD DC .. a?8VE8@ a?1VE1@Y CD DC a?*VE*@Y@ a ?1!VE1!@ CD print& "a?)'VE Sd a ?!V E Sd a ?1!V E Sd RnH, C"a)'$, C"aI!$, a ?1!V $@ print& " %ona neinitiali%ata a?)#V E SdH, a?)#V $@ T La executia pro ramului se va a&isa7 a?)'VE )' a?!V E ! a?1!V E 1! %ona neinitiali%ata a?)#V E Q(!!# 1..(.2. ,e"atura dintre tablouri si pointeri Numele unui tablou este un pointer constant spre primul sau element. 5xpresiile de mai /os sunt deci ec1ivalente7 nu e1tablou .nu e1tablou .nu e1tablou%G' !nu e1tablou nu e1tablou%G' Observatie 3peratorul de indirectare "C$ tine locul unui indice, deci pentru a re&eri un element din tabloul bidimensional d, avem nevoie &ie de doi indici "d [8][8]$, &ie de o indirectare si un indice "Cd [8]$, &ie de doua indirectari "CCd$. Exemple <ie urmatoarele declaratii int x[ 1G] # int a[ 1G][ 1G] # Avem urmatoarele corespondente7 xFi Gx[i] !3xFi7 x[i] !3aFi7FJ Ga[i][/] !3!3aFi7FJ7 a[i][/] aFi Ga[i] !3aFi7 a[i] a[ i] Ga[i][8] a[ i] FJ Ga[i][/]@

Exemplu: +ro ramul de mai /os citeste si a&isea%a elementele a doua tablouri, la primul accesul se &ace indexat, la al doilea prin pointeri.
Linclude Mstdio.1N Linclude Mconio.1N Lde&ine 2 ( int tab1%N', tab2[N]; void citire1"void$P DC citeste elementele lui tab1 prin accesarea indexata a elementelor CD int i@ puts"9-ntroduceti elementele lui tab179$@ &or"iE8@iM2@iII$P putc1ar"Z7Z$@scan&"9Sd9,Gtab1?iV$@ T DC&or iCD T DC citire1 CD void tiparire1"void$P DC tipareste elementele lui tab1 prin accesarea indexata a elementelor CD int i@ puts"95lementele lui tab179$@ &or"iE8@iM2@iII$ print&"9Sd 9,tab1?iV$@ putc1ar"ZRnZ$@ T DC tiparire1 CD void citire)3void79 DC citeste elementele lui tab! ) accesarea &iecarui element se &ace printrHun pointer la el CD int *pi; puts("Introduceti elementele lui tab2:"); for(pi=tab2;pi<tab2+N;pi++){ DC initiali%ari ec1ivalente sunt piEGtab! sau piEGtab?8V@ conditie ec1ivalenta piMEGtab!?2)1V CD putc1ar"Z7Z$@scan&"9Sd9,pi); T DC&or piCD T DC citire! CD void tiparire2(void){ DC tipareste elementele lui tab! prin accesare la pointeri CD int *pi; puts"95lementele lui tab!79$@ for(pi=tab2;pi<tab2+N;pi++) print&"9Sd 9, *pi); putc1ar"ZRnZ$@ T DC tiparire! CD void main(void){ clrscr"$@ citire1"$@ tiparire1"$@ citire2(); tiparire2(); etc1e"$@ T +ro ramul acesta demonstrea% dou posibiliti de prelucrare a elementelelor tabloului, unde accesul prin pointeri este ai eficient. Stilul adecvat de prelucrare a elementelelor tabloului prin pointeri const n declararea pointerilor suplimentari pentru a stabili le turile cu tablourile prin pointeri. i parcur erea, accesul, elementelelor tabloului se &ace numai prin pointeri, care se mai numete :stilul prelucrrii cu pointeri. 1..(.(. >0?N@AB S? @AC,0+B? E+,@?D?EANS?0NA,A ;ectori bidimensionali +resupunem ca avem un vector !)dimensional cu elemente intre i. int a?'V?(V@ -ncepand cu adresa de ba%a, compilatorul va aloca spatiu conti uu pentru 1( intre i. Atunci putem andi acest vector ca o matrice, ast&el7 col1 col! col' col# col( lin1 a?8V?8V a?8V?1V a?8V?!V a?8V?'V a?8V?#V lin! a?1V?8V a?1V?1V a?1V?!V a?1V?'V a?1V?#V lin' a?!V?8V a?!V?1V a?!V?!V a?!V?'V a?!V?#V +entru a?iV?/V avem expresiile, de exemplu, ec1ivalente7 !3a%i' F J7 3!3a F i77%J' !33!3a F i77 F J7 !3.a%G'%G' F (!i F J7 "#$ +utem :ndi 9a?iV9 ca a 9i9)a coloana a lui 9a9 "numarand de la 8$, si 9a?iV?/V9 ca elementul din linia 9i9, coloana 9/9 a tabloului "numarand de la 8$. 2umele tabloului "9a9$ este tot una cu 4.a%G'4@ acesta "#$ este un pointer catre un tablou de (

intre i. Adresa de ba%a este 4.a%G'%G'9, si nu 9a9. 4ltimul exemplu de mai sus re&lecta &uncia de corespondenta in memorie dintre valoarea pointerului si indicele tabloului. ,and un vector multidimensional este un parametru &ormal in de&initia unei &unctii, toate dimensiunile, exceptand prima trebuie speci&icate. 5xemplu7 +resupunem ca sunt date elementele vectorului 9a9. <unctia de mai /os se poate &olosi pentru suma elementelor unui tablou. Atentie J Trebuie speci&icat numarul de coloane. int suma"int a?V?(V$ P int i, /, suma E 8@ &or "i E 8@ i M '@ IIi$ &or "/ E 8@ / M (@ II/$ suma IE a?iV?/V@ return suma@ T -n antetul &unctiei, urmatoarele declaratii sunt ec1ivalente7 int a%'%(' int 3!a7%(' int a%*'%(' ,onstanta ' actionea%a ca o reminiscenta a omului, dar compilatorul nu tine cont de ea. Deci &iind date declaratiile int a%1G'%1G'# int !b%1G'# utili%arile lui 9a9 si 9b9 pot &i similare, in sensul ca a?(V?(V si b?(V?(V sunt ambele re&erinte le ale ale aceluiasi 9int9. ;ectori ')dimensionali ;ectorii de dimensiune mai mare decat ' lucrea%a intr)un mod similar. Daca avem declaratia int a?*V?OV?!V@ atunci compilatorul va aloca spatiu pentru *COC! intre i. Adresa de ba%a a tabloului este 9Ga?8V?8V?8V9, iar &unctia de corespondenta in memorie este speci&icata de a?iV?/V?[V care este ec1ivalent cu !3.a%G'%G'%G' F K!)!i F )!J F L7 Exemplu cu pointeri la tablouri bidimensionale : +ro ramul de mai /os determin numrul de %erouri pe liniile matricei. 0ntruc:t pointerii la primul element este pointerul la ir i e mai bine s prelucrm matricea pe r:nduri ca linie aparte, de aceea, se prvede elaborarea &unciei cnt"int x?V, int Cn, int m$, creia i se transmite ca pointeri la primele elemente a r:ndurilor matricei. +arcur erea matricei se e&ectuea% prin pointeri ") accesarea unui element se &ace indirect prin intermediul unui pointer$ i nu indeci7 Linclude Mstdio.1N Linclude Mconio.1N void cnt"intC, intC, int$@ Lde&ine L-2 ! Lde&ine ,3L ' void main"$ P int a?L-2V?,3LV, b?L-2V, !p, !M, !t, L# clrscr"$@ M - a%G'# t - b# &or "M - a%G'# M N a%G' F ,?N ! C0,@$ P puts"9citeste elementele liniei Sd9, i I 1$@ &or "p - M# p N M F C0,# pFF$ scan&"9Sd9,p7# cnt"M,.L,C0,7# !3tFF7 - L# M - p# = print&"92umrul de %erouri pe liniile matricei Rn9$@ &or "t - b# t N b F ,?N# tFF$ print&"9 S#dRn9,!t7# T void cnt"int x?V, int Cn, int m$ P int !p# !n - G# &or"p - x# p Nx F # pFF7 i& "!p -- G7 FF3!n7# = 1.I. >0?N@AB? CA ABO+EAN@A ,A P+NC@??. A>A, >B?N BAPAB?N@A Am preci%at in capitolul precedent ca la apelul prin valoare &unctia apelata prelucrea%a o copie a valorilor parametrilor, valori care au &ost puse pe stiva. -nseamna ca &unctia apelata are e&ect asupra &unctiei apelante doar printr)o sin ura valoare returnata. Dar ce posibilitati are pro ramatorul cand doreste ca &unctia apelata sa modi&ice mai multe variabile din &unctie apelanta\ -n aceste situatii pro ramatorul va transmite &unctiei apelate adresele variabilelor ce urmea%a sa &ie modi&icate. Avand la dispo%itie aceste adrese, &unctia apelata va putea lucra direct asupra valorilor a&late la aceste adrese. Deci pro ramul apelant va trebui sa transmita &unctiei apelate pointeri catre variabilele ce vor &i modi&icate. 0n limba/ul , se pot transmite parametri si returna prin adres, intr)un mod indirect, &olosind pointeri care ne permit s utili%m &unciile ca proceduriH, adic s returnm mai multe re%ultate i, c1iar, structuri complexe "tablourilor uni) i multi) dimensionale etc.$. 0n ca%ul pointerilor, &uncia apelant trebuie s &urni%e%e adresa variabilei de modi&icat "te1nic printr)un pointer la aceast variabil$, iar &uncia apelat trebuie s declare ar umentul corespun%tor ca &iind un pointer. .e&erirea la variabila de modi&icat se &ace prin adresare indirect. +rintre ar umentele &unciei pot aprea i nume de tablouri. 0n acest ca% valoarea transmis &unciei este n realitate adresa de nceput a masivului "elementele masivului nu snt copiate$. +rin indexarea acestei valori &uncia poate avea acces i poate modi&ica orice element din tablou. 4rmea%a ca parametrii &ormali ai &unctiei apelate vor &i declarati ca pointeri. Acest tip de apel de &unctie se numeste apel prin re&erinta sau prin adresa "in en le%a7 call bF adress$. 5xemplu 1.Q.1. >ai /os sunt doua variante pentru o &unctie care intersc1imba doua numere intre i. DC ;arianta 1 Uresit CD void s]ap "int x, int F$ P int temp@ temp E x@ xEF@ F E temp@ T DC ;arianta ! Corect CD void s]ap "int Cpx, int CpF$ P int temp@ te p - !px # !px - !p/# CpF E temp@ T

DC Oresit CD DC Corect CD <unctia din varianta 1 "apel prin valoare$ este resita, deoarece se intersc1imba intre ele variabilele x si F locale &unctiei s]ap si nu parametrii e&ectivi de la apel, asa cum ar dori pro ramatorul. <unctia din varinta ! lucrea%a direct cu variabilele de intersc1imbat din &unctia apelanta,intrucat are ca parametrii &ormali pointeri la acestea. 3 modalitate de apel ar &i7 sQap 3.x, ./ 7# ceea ce constituie de &apt apelul prin re&erinta . Doar in acest &el x si F sunt e&ectiv intersc1imbate intre ele. 5xemplul 1.Q.!. ,alculul lun imii unui sir de caractere terminat cu X R 3 W in varianta cu pointeri "ve%i si 7 5xemplul tradiional$ este 7 unsi ned strlen "c1ar C a$ P c1ar C b E a @ DC +ointerul b se initiali%ea%a cu adresa de inceput a sirului CD ]1ile " C b J E W R 3 W$ DC ,at timp nu s)a a/uns la s&. CD bII@ DC sirului incrementea%a l la b "adica treci la caracterul urmator$ CD return n K a@ DC Di&erenta b K a ne &urni%ea%a numarul de caractere peste CD DC care s)a trecut, de &apt lun imea sirului. CD T 3AS5.;AT-5 -nstructiunea ]1ile " C bJ E W 8 W$ se putea scrie mai concis7 ]1ile "Cb $, deoarece expresiile 7 Cb J E W R8 W , respectiv C b sunt sau ambele adevarate, sau ambele &alse. 5xemplul 1.Q.'. -n exemplul tradiional s)a pre%entat o &unctie care copie sirul s " sursa$ in sirul d "destinatie$. -ata varianta cu pointeri . void strcpF "c1ar C d, c1ar C s$ P ]1ile " " C d E C s$J E W R 3 W $ P D C ,opie caracterul CD sII@ DC curent din s in d pana cand s)a copiat si W 3 W. CD dII@ DC Avansarea la urmatorul caracter se &ace cu sII@ dII@ CD T T 5xpresiile cu pointeri ne permit o scriere mult mai compacta 7 void strcpF "c1ar C d, c1ar C s$ P ]1ile " C dII ECsII$ T 3AS5.;AT-57 -nstructiunea7 ]1ile " C dII E C sII$@ cuprinde urmatoarele operatii7 )la adresa curenta data de pointerul d atribuie caracterul curent a&lat la adresa data de pointerul s@ )incrementea%a l atat la d, cat si la s " se trece la caracterul urmator$@ )daca ultimul caracter atribuit este E W R 3 W atunci repeta observatiile de mai sus@ alt&el iese din ciclul ]1ile. -n conclu%ie , cele trei operatii de la prima varianta 7 1. !. '. C d E C s@ sII@ si dII@ CdJEWR3W\ @ DC instructiunea vida CD

se executa intr)a doua varianta cu o sin ura instructiune. 5xemplul 1.Q.#. -n exemplul tradiional se compara lexico ra&ic doua siruri de caractere a cu b. ,omparati varianta de acolo cu varianta cu pointeri de mai /os 7 int strcmp "c1ar Ca, c1ar C b $ P &or " @ C a E E C b @ a I I, bI I $ DC cat timp caracterul CD i& "C a E E WR 8X $ DC curent din a este e al CD return 8 @ DC cu cel din b si nu s)a CD return Ca ) Cb@ DC a/uns la s&arsitul lui a CD T DC trece la caracterul urmator. Daca s)a a/uns la s&arsitul lui a si cum Ca E E Cb CD DC inseamna ca sirurile sunt e ale si returnea%a 8 CD DC Daca Ca J E Cb atunci returnea%a Ca ) Cb "di&. carecterelor curente$. CD DC Daca di&erenta este ne ativa, atunci a M b, alt&el a N b CD 5xemplu 1.Q.(. <unctia urmatoare utili%ea%a pointerii pentru a sorta crescator un sir de numere prin metoda bulelor "ve%i cel tradiional$. void sortbule " &loat Ca, unsi ned n $

P unsi ned i, m E n K 1@ &loat temp@ int ind E 1@ ]1ile " ind NE 8$ P ind E ) 1@ &or " i E 8 @ i M m @ iII$ i& " C"a I i$ N C " a Ii I1$$ P temp E C" a I i $ @ C" a I i $ E C" a I i I 1$ @ C" a Ii I1$ E temp @ ind E i @ T m E ind @ T T +rin aceasta metoda sirul a ? 8 V , a ? 1 V , Y, a ? n K 1 V se parcur e de la inceput spre dreapta, ast&el incat daca a ? i V N a ? i I 1 V atunci se &ace intersc1imbarea lui a ? iV cu a ? i I 1V . -ndicele i pentru care s)a &acut intersc1imbarea se retine in ind care il va sc1imba pe m. -ntrucat de la ultimul indice i retinut in ind si pana la s&arsitul sirului este ordonat crescator la urmatoarea parcur ere se anali%ea%a sirul doar pana la ultimul indice ind minus l . Se continua ast&el pana nu se mai &ac intersc1imbari " ind E )l $ si deci sirul este ordonat. 5xemplul 1.Q.Q. <unctia urmatoare sortea%a crescator un sir de numere utili%and metoda insertiei directe. -n ce consta metoda \ Se presupune ca subsirul7 a?8V, a?1V,Y,a?i)1V este de/a ordonat crescator si se cauta locul lui a?iV in acest sir. ,autarea se &ace spre stan a, adica de la i ) 1 spre 8. Daca / este indicele pentru care "/ E )1, i@ a?)1V E )$@ a? / V a? i V M a ? / I 1V atunci toate elementele a ? / I 1V, a ?/ I !V,Y,a? i ) 1V se deplasea%a la dreapta cu o po%itie, iar in po%itia / I 1 devenita libera se inserea%a elementul a ? i V. Se aplica procedeul de mai sus pentru i de la 1 la n ) 1 si ast&el sirul este ordonat crescator. void sortinsdir "&loat C a, unsi ned n$ P int i, / @ &loat temp @ &or "i E 1 @ i M n @ i II$ P temp E C "a I i$@ &or " / E i ) 1 @ / N E8 @ / ))$ DC cauta inapoi locul CD i& "C "a I /$ N temp$ DC elementului a / CD C"aI/I1$ E C"aI/$@ DC deplasare spre dreapta CD else P C"aI/I1$ E temp@ o to s&@ DC -n locul lui CD T DC a ? / I 1 V vine a ? i V CD Ca E temp@ DC Locul lui a ? i V este cel mai CD DC din stan a CD s& 7 @ DC -nstructiune vida etic1etata CD T T 5xemplu 1.Q.*. 3 alta metoda de sortare este metoda S1ell cea pre%entata in &unctia de mai /os. +rincipiul metodei 7 ) se &ixea%a un pas @ la inceput nD! @ ) se sortea%a subsirurile avand elementele a&late la distanta pas intre ele7 a ? 8V cu a ?pasV , a ?1V cu a ?pasI1V,Y ) se in/umatateste pasul @ pasEpasD! si se sortea%a subsirurile 7 a ?8V , a ?pasV, a ?! C pasV,Y a ?1V , a ?pas I 1V, a ?! C pas I 1V,Y s.a.m.d. ) cand pas E 8 al oritmul se termina 7 sirul este ordonat crescator. Subsirurile se ordonea%a prin metoda insertiei directe pre%entata anterior. >etoda are avanta/ul ca aran/ea%a inca de la inceput elementele a&late departe de locul lor &inal. Ast&el, in etapele urmatoare "cu pasul in/umatatit$ ramane mai putin de &acut. void sort S1ell "&loat Ca, unsi ned n$ P int i , / , pas @ &loat temp @ pas E nD! @ DC +asul initial CD ]1ile "pas N8$ P &or "i E pas @ i M n @ iII$ P DC sortarea subsirurilor CD / E i ) pas @ ]1ile " / N E8 GG a ? / V N a ? / I pas V $ P temp E a ? / V @ a ? / V E a ? / I pasV @ a ? / I pasV E temp @ / E / ) pas @ T T pas E pasD! @ DC -n/umatatirea pasului. ,and CD T DC acesta devine 8 pro ramul CD T DC se termina CD 3bservatie Daca ar &i sa &acem o comparatie intre cele trei metode de sortare pre%entate anterior, cea mai rapida este metoda S1ell, urmea%a metoda insertiei directe si ultima, mai putin rapida, este metoda bulelor. 1.* P+NC@?? CABA BA@+BNAARA >0?N@AB? Sunt situatii cand nu este su&icient ca &unctia apelanta sa intoarca o sin ura valoare catre apelanta. De multe ori apelanta ar trebui sa returne%e un sir de valori, o structura sau o uniune, un sir de caractere, o matrice etc.

Toate aceste alternative sunt re%olvate in limba/ul , prin intermediul &unctiilor care returnea%a pointeri. Anume pointeri la siruri, la structuri, la uniuni, la matrice etc. 3 &unctie care returnea%a pointer se declara ast&el 7 ?tipV nume)&unctie "lista)declaratori)parametri$ @ -n aceasta constructie caracterul asterisc C este cel care indica &aptul ca va returna un pointer. Tip)ul din &ata este de &apt tipul pointerului returnat de &unctie. 5xemplu 1.*.1 4rmatoarea &unctie concatenea%a sirul S la s&arsitul lui D si returnea%a pointer catre noul sir D. Se presupune ca in D este su&icient loc pentru ambele siruri. c1ar Cstrcat "c1ar CD, c1ar CS$ P c1ar C> E D @ ]1ile " CD$ DC cat timp caracterul curent din D 8 CD IID @ DC avansea%a la urmatorul caracter CD ]1ile " CDII E CSII$ DC ,opie caracterul curent CD @ DC din S in caracterul curent de la s&. CD DC lui D si trece la caracterul urmator CD return > @ DC .eturnea%a adresa de inceput a sirului re%ultat CD 5xemplu 1.*.! <unctia ce urmea%a determina daca S 1 este subsir al sirului S ! si returnea%a pointer la elementul din S ! de unde incepe subsirul S 1, respectiv 24LL daca S 1 nu este subsir al sirului S !. L include stdio.1H c1ar Cstrstr "c1ar CS 1, c1ar CS !$ P unsi ned i @ c1ar CSA E S 1, CSA E S !, CS, E S ! @ ]1ile " CSA J E WR8X $ P iE1@ ]1ile " CSA J E WR8X$ DC ;eri&ica daca S 1 este CD i& " CSA EE CSA$ P DC subsir incepand din CD SA II@ SAII@T DC po%itia SA CD else P i E 8 @ brea[ @ T i& "i EE 1$ DC Daca este subsir atunci CD return S, @ DC returnea%a S, CD SA E S 1 @ S,II @ SA E S, @ DC Trece la urmatoarea CD T DC po%itie in S ! CD return 24LL @ DC 2u este subsir CD T 1.&. >0?N@AB? ,A P+NC@?? +ointerii la &uncii se utili%ea% pentru transmiterea &unciilor ca parametri ai

altor &uncii. Dei o &uncie nu este o variabila, aceasta are o adres &i%ic precis de lansare n execuie, numit i punct de intrare n &uncie. Aceast adres poate, deci, &i atribuit unei variabile de tip pointer, ceea ce poate duce la posibilitatea apelrii &unciei &olosind un pointer ctre &uncie. -n orice limba/ de pro ramare, deci i n L,, apelarea pentru execuie a unei &uncii presupune lansarea execuiei pro ramului n cod main, obinut dup compilare i lin[)editare, de la adresa punctului de intrare n &uncie. Acest lucru permite ca apelarea i lansarea n execuie a unei &uncii s se &ac prin intermediul unui pointer ctre &uncia respectiv. ,a i n ca%ul obinerii adreselor tablourilor "prin &olosirea numelor acestora &r utili%area indicilor$ adresele &unciilor se obin prin &olosirea numelor acestora &r parante%e si ar umente. Daca intr)o &unctie este nevoie sa se apele%e alta &unctie, atunci metoda comoda de lucru este ca aceasta din urma sa &ie declarata ca parametru pentru prima &unctie. -n limba/ul ,, o &unctie poate apare ca parametru numai ca pointer la acea &unctie. 4n pointer la o &unctie se declara prin 7 tip 3 ! nu eHfunctie7 3listaHdeclaratiiHpara etri7 # unde tipH este tipul valorii returnate de &unctie "poate &i si void$, iar lista)declaratii)parametriH este o lista de declaratori pentru parametri separati prin vir ule. Speci&icarea acestei liste nu este obli atorie.
5xemplu float 3 !func7 3unsi"ned, c$ar7 # >ai sus se declara &unc ca &iind un pointer spre o &unctie care are doi parametri, primul unsi ned si al doilea c1ar si returnea%a o valoare de tip &loat. 4n pointer catre o &unctie are ca valoare adresa de memorie unde incepe partea de instructiuni executabile a &unctiei in cau%a. -n ceea ce priveste obtinerea &acem preci%area ca numele unei &unctii neurmat de parante%e rotunde este pointer catre &unctie. Daca de exemplu avem &unctie cu prototipul 7 lon test "int, &loat$ @ atunci testH este pointer la aceasta &unctie. 3bservatie +arante%ele rotunde de la declaratia de pointer la &unctie 7 " Cnume)&unctie$ sunt necesare, deoarece &ara ele 7 tip !nu eHfunctie 3 7 # obtinem o declaratie corecta, dar de &unctie ce returnea%a pointer si nu de pointer la &unctie. Aceasta pentru ca " $H sunt mai prioritare decat !H.

Axe plu Dac dorim ca &uncia & s apele%e &uncia sub &orma &" $, &uncia av:nd antetul7 &loat "int x$ atunci antetul lui & trebuie s &ie de &orma7 double & "&loat "C$ "int$$ 5xemplu 1.6.1: double 3!fun173int x, int /7# double fun)3int L, int l7# fun1-fun)# DC iniiali%area pointerului la &uncie CD 3!fun173),;7# DC apelul &unciei CD 5xemplu 1.6.!: void "3x79 printf345d: $ere6n4, x7# = ain379 void 3!f737 - "# DC pointerul la &uncia "$ CD 3!f7317# DC <orma vec1e a apelului &unciei CD f 3)7# DC <orma nou a apelului &unciei. 0n ambele ca%uri se apelea% "x$@ CD T 5xemplu 1.6.': Ce va afiaS t/pedef void 3!3!P+N7737# P+N "3P+N f79 return f# = void ain379 P+N / - "3"3"3"3"7777# if3/ -- "7 printf340T6n47# = 5xemplu 1.6.#: Ce va afiaS c$ar !f379return 4Uello, userV4#= "3func7c$ar ! 3!func737# 9puts33!func7377# = ain379"3f7#= 5xemplu 1.6.#: Ce va afiaS int f3n79 return n!)# = int "3n79 return nF2# = int $3n79 return nH1# = int 3!arr%*'737 - 9 f, ", $ =# ain379 int i# for3i-G# i N *# iFF 7 printf3 45d6n4, 3!arr%i'73iF;7 7# = 5xemplu 1.6.(: Ce va afiaS Dv1D extern double sin37, cos37# ain379 double x# 8! cc Hl !8 for3x-G.G# x N 1.G# x F- G.)7 printf345I.2" 5I.2" 5I.2"6n4, 3x W G.( S sin : cos73x7, sin3x7, cos3x77# = Dv!D extern double sin37, cos37# ain379 double x# double 3!f737# for3x-G.G# x N 1.G# x F- G.)79 f - 3x W G.( S sin : cos7# printf345"6n4, 3!f73x77# = = 5xemplu 1.6.Q <ie de calculat valoarea aproximativa a inte ralei de&inite dintr)o &unctie &. 3 metoda su&icient de rapid conver enta este metoda Simpson. <ormula lui Simpson este7 - 1D' C ?&"a$I!"&"aI!1$I&"aI#1$IYI&"aI"!n)!$1$ $I# C"&"aI1$I&"aI'1$IYI&"aI"!n)1$1$ $ V, unde 1 E "b)a$D!n. ;om scrie o &unctie Simpson care calculea%a expresia de mai sus si in care va &i apelata &unctia f transmisa primeia ca un pointer la &unctie. L include stdio.1H L include mat1.1.H double f 3double7 # double Si pson 3double a, double b, unsi"ned n, double 3 !f7 3 7 7 # DC 4ltimul parametru al &unctiei Simpson este pointer la &unctia & CD ain 3 7 9 int n # double i 1, i ), eps, a, b # printf 3:Calculul inte"ralei prin etoda Si pson 6 n7 # do 9 printf 3:?ntroduceti a, b, eps : :7 # scanf 3:51f, 51f, 51f, .a, .b, .eps7 # = Q$ile 3a W - b XX eps N - G7 # n-2# i ) - Si pson 3a, b, n, f7 # 8! +lti ul para etru este pointer la fc. f !8 do 9 i1 - i) # n - n!) # i) - Si pson 3a, b, n, f7 # = Q$ile 3fabs 3i1 H i)7 8 1( W - eps7 # DC ,riteriul de oprire este i1 ) i! D 1( eps unde i! este urmatoarea aprox. obtinuta dubland nr. de intervale CD printf 3:Yaloarea inte"ralei - 5f 6 n, i)7 # =

double Si pson 3double a, double b, unsi"ned n, double 3 !pf7 3 7 7 9 unsi"ned i # double S, $ # $ - 3b H a7 8 n # S - 3!pf7 3a7 F 3 !pf7 3$7 # 8! Calculul su elor !8 for 3i - 1 # i N n # i - i F )7 8! ce intervin !8 S - S F 3 !pf7 3a F i!$7 ! 2 # 8! in for ula lui Si pson !8 for 3 i-) # i N n # i - iF)7 S - SF3 !pf7 3aFi!$7 !) # return $8* !S # DC .eturnea%a urmatoarea aproximatie CD = double f 3double x7 9 return exp 3Hx !x7 # DC <unctia de inte rat CD = 5xemplu 1.6.Q double proiz3double x, double dx, double 3!f73double x7 7# double fun3double z7# int ain37 9 double x# double dx# double z# scanf345f,5f4,.x,.dx7# z-proiz3x,dx,fun7# printf345f4,z7# return G#= double proiz3double x,double dx, double 3!f73double z7 7 9 8! &uncia ce calculea% derivata !8 double xL,xL1,pr# xL-fun3x7# xL1-fun3xFdx7# pr-3xL18xLH1eG7!xL8dx# return pr# = double fun3 double z7 9 8! &uncia crea se calculea% derivata !8 return 3cos3z77# = &uncia crea se calculea% derivata se sc1ib simplu, de exemplu pentru cos"x$, se apelea% %Eproi%"x,dx,cos$@ iar pentru sin"x$7 %Eproi%"x,dx,sin$@ 1.O. @AC,0+B? DA >0?N@AB?. INITIALIZAREA TABLOURILOR DE POINTERI Sa presupunem ca avem de scris o &unctie care sa returne%e un sir de caractere cu numele %ilei a n)a din saptamana. 3 &unctie nu poate intoarce un sir de caractere asa ca este clar ca trebuie sa revina cu un pointer la numele %ilei a n)a. Deci, in cadrul &unctiei trebuie sa se cree%e un sir de nume de %ile si un sir de pointeri spre aceste nume. ,lasa de memorie pentru acest sir de nume trebuie sa &ie static interna, asa &el incat sa nu se distru a la &iecare revenire din &unctie. 5xemplu 1.O.1 c1ar Cnume)%i "int n$ P static c1ar C%i ? V E P DC Declaratie de sir de CD %i ile alaH, DC pointeri si CD LuniH, DC initiali%area CD >artiH, DC acestuia CD >iercuriH ^oiH ;ineriH SambataH DuminicaH T@ i& "n N E 1 GG n M E *$ return %i ? n V @ else return %i ? 8 V @ T 5xemplu 1.O.! 4n alt exemplu clasic de utili%are de siruri de pointeri este transmiterea matricilor ca parametri ai unei &unctii. Deoarece accesul la un element al matricei se &ace prin dubla re&erinta la linie si coloana, modalitatea de transmitere a matricelor la &unctii di&era de cea de la siruri. -n acest ca% trebuie transmis un pointer la un sir de pointeri, &iecare element al sirului pointand la liniile matricei. >ai /os se pre%inta pro ramul care inmulteste doua matrice. ,atre &unctia care e&ectuea%a inmultirea se transmit pointeri la siruri de pointeri pentru matricele A ? > V ? 2 V , A ?2V ?+V respectiv spre matricea re%ultat , ? > V ? + V, de &apt pointeri la pointeri. L include stdio.1H L de&ine > # L de&ine 2 ! L de&ine + ' void inm)matr "&loat CC, &loat CC, &loat CC, unsi ned, unsi ned, unsi ned$ @ main " $ P unsi ned i, / @ &loat Cpa ?>V, Cpb ?2V, Cpc ?>V, CCppa, CCppb, CCppc @ &loat a ?>V ?2V E 1 P 1, ! T, P ', # T, P (, Q T, P *, 6 T T@

&loat b ?2V ?+V E 1 P1, !, 'T, P#, (, QT T@ inm)matr "ppa, ppb, ppc, >, 2, +$ @ print& ">atricea re%ultat E R nH$ @ &or " i E 8 @ i M > @ iII$ P &or " / E o @ / M + @ /II$ print& "H$ @ T inm)matr "ppa, ppb, ppc, >, 2, +$ P &loat c ?>V ?+V @ &or "i E 8 @ i M > @ iII $ pa? i V E a ? i V @ DC pa ? i V E adresa liniei i in matricea a &or " i E 8 @ i M 2 @ iII $ pb ? i V E b ? i V @ DC pb ? i V E adresa liniei i in matricea b &or " i E 8 @ i M >@ iII$ pc ? i V E c ? i V @ DC pc ? i V E adresa liniei i in matricea c ppa E pa @ ppb E pb @ ppc E pc @T

CD CD CD

3 situatie n care pointerii sunt mai utili este declararea structurilor recursive. 0n , nu se permite ca o structura sa contina c:mpuri de tipul aceleiasi structuri. Aceasta restrictie poate &i evitata &olosind pointeri la structuri, dupa cum se arata n exemplul urmator7 t/pedef struct pers 9 c$ar nu e%)G'# int varsta# struct pers ! ur ator# = persoana# persoana !p# +entru a re&eri un c:mp &olosind un pointer spre o structura, se &oloseste operatorul de dere&erentiere7 (*p) nume. 5c1ivalent cu acest operator exista n , un alt operator pentru accesarea c:mpurilor din structurile indicate de pointeri7 p>nume. <olosirea neadecvata a operatiilor cu pointeri. 3 reseala des nt:lnita este re&erirea pointerilor spre alte locatii de memorie7 int obiect-(# int !obiect1ptr# obiect1ptr - obiect# Lipsa operatorului de adresa . &ace ca obiect_ptr sa indice spre locatia de memorie a&lata la adresa (. 4rmatorul exemplu ilustrea%a un stil de pro ramare 9daunator9, care strica li%ibilitatea codului. Limba/ul , este &oarte &lexibil, &apt ce poate duce, n special n ca%ul pointerilor, la re%ultate imprevi%ibile7 void cop/1strin"3c$ar ! p, c$ar !M7 9 DC copia%a sirul _ in p CD Q$ile 3!pFF - !MFF7# = ,1iar daca aceasta implementare este mult mai compacta, urmarirea codului este &oarte di&icila, iar &olosirea combinata a operatorilor de incrementare si pointerilor poate duce la e&ecte necontrolate. 4rmatoarea varianta de implementare a aceleiasi &unctii copy_string pre%inta un stil adecvat pro ramarii cu pointeri7 void cop/1strin"3c$ar ! dest, c$ar ! sursa7 9 !dest - !sursa# Q$ile 3!destV-Z6GZ7 9 FFdest# FFsursa# !dest - !sursa# = =

1.1G. Alocarea dina ic a e oriei. 0n ,, deoarece limba/ul o&era o mare libertate de exprimare, este &oarte usor pentru un pro ramator neatent sa &aca erori care nu sunt semnalate la compilare, dar care duc la comportari neasteptate ale pro ramului, adic, iari, &olosirea neadecvata a operatiilor cu pointeri 3 eroare tipica este atribuirea de valori pointerilor neinitiali%ati7
int !un1pointer# !un1pointer-(# 0n aceasta situatie, deoarece un_pointer este neinitiali%at, valoarea ( este scrisa n memorie la o locatie aleatoare, poate c1iar re%ervata altei variabile. 0n ca%ul n care un pointer nu arata spre o %ona de memorie re%ervata, trebuie alocata o %ona de memorie n mod explicit, &olosind &unctia alloc7 un_pointer=(int *)malloc(si eof(int)); <unctia alloc re%erva spatiu de memorie si returnea%a adresa spatiului re%ervat@ %ona de memorie re&erita de un pointer poate &i eliberata &olosind &unctia free. Ambele &unctii sunt de&inite n stdlib.$. 0n , nu exista un mecanism de "arba"e collection, ast&el ca pro ramatorul trebuie sa aiba ri/a ca %onele de memorie alocate dinamic si care nu mai sunt utile sa &ie dealocate "&olosind &unctia free$. <aptul ca unui pointer i se atribuie o noua valoare nu nseamna ca %ona de memorie spre care arata s)a eliberat si n acest mod pro ramul poate a/un e sa tina alocata toata memoria disponibila. Ast&el utili%atorul poate solicita n timpul execuiei pro ramului alocarea unei %one de memorie. Aceast %on de memorie poate &i eliberat, n momentul n care nu mai este necesar. Alocarea i eliberarea de memorie la execuie permite estionarea optim a memoriei. Aiblioteca standard o&er # &uncii, av:nd prototipurile n <alloc!"> i <st#lib!"> Acestea sunt7 void ! alloc3unsi"ned n7# <uncia aloc un bloc de memorie de n octei. <uncia ntoarce un pointer la nceputul %onei alocate. 0n ca% c cererea de alocare nu poate &i satis&cut, &uncia returnea% N+,,. void !calloc3unsi"ned nele , unsi"ned di 7#

Aloc nele !di octei de memorie " nele blocuri &ormate din di %onei alocate sau N+,,.>emoria alocat este iniiali%at cu %erouri. void free3void !p7#

octei &iecare$. 0ntoarce un pointer la nceputul

<uncia eliberea% o %on de memorie indicat de p, alocat n prealabil prin void !realloc3void !p, unsi"ned di 7#

alloc37 sau calloc37.

>odi&ic dimensiunea spaiului alocat prin pointerul p, la di . <uncia ntoarce adresa %onei de memorie realocate, iar pointerul p va adresa %ona realocat. dac dimensiunea blocului realocat este mai mic dec:t a blocului iniial, p nu se modi&ic, iar &uncia va ntoarce valoarea lui p. dac di --G %ona adresat de p va &i eliberat i &uncia ntoarce N+,,. dac p--N+,,, &uncia aloc o %on de di octei "ec1ivalent cu alloc37$.

<unciile de alocare ntorc pointeri enerici 3void!7 la %one de memorie, n timp ce utili%atorul aloc memorie ce pstrea% in&ormaii de un anumit tip. +entru a putea accesa memoria alocat, indirect, prin intermediul pointerului, acesta va trebui s &ie un pointer cu tip, ceea ce impune conversia explicit "prin cast$ a pointerului ntors de &uncia de alocare ntr)un pointer cu tip. De exemplu, pentru a aloca un vector de ntre i, av:nd n elemente vom &olosi7 int !p: if 3p-3int!7 alloc3n!sizeof3int77--N+,,7 9 printf3:Ee orie insuficienta6n7# exit317# =

Alocarea de spaiu n heap pentru o matrice. int!! # int n,p# DC se aloc spaiu pentru vectorul cu adresele celor n linii ale matricei CD -3int!!7 alloc3 !sizeof3int!77# for3int i-G#iN #iFF7 DCse aloc spaiu pentru &iecare linie a matricei, cte p elementeCD %i'-3int!7 alloc3n!sizeof3int77#
5xemplu7 5xemplu de citire interactiva a dimensiunii si a elementelor unei matrice de intre i void main"$ P int 2@ int CC a, Cptr@ print&"9-ntroduceti dimensiunea matricii79$@ scan&"9Sd9, G2$@ a - 3int !!7 calloc3N ! N, sizeof3int77# ptrEGa?8V?8V@ print&"9RnRn-ntroduceti elementele matricii7Rn9$@ &or "i E 8@i M 2@ IIi$ &or "/ E 8@/ M 2@ II/$ P print&"9a?SdV?SdVE9, i, /$@ scan&"9Sd9, ptrII$@ T T Acest lucru va permite re%ervarea memoriei pentru un vector "de exemplu$ in care i a&lam dimensiunea abia la rularea in execuie "pana acum declararam dimensiunea unui vector cu Lde&ine$. 4n apel de tipul calloc3n, di ensiune1tip7 va returna un pointer catre un spatiu din memorie necesar pentru memorarea a 9n9 obiecte, &iecare pe 9dimensiune=tip9 octeti. Daca sistemul nu poate aloca spatiul cerut, atunci acesta va returna valoarea 24LL. -n A2S- ,, tipul 9si%e=t9 este dat ca 9tFpede&9 in . De obicei, tipul este 9unsi ned9. De&initia tipului este &olosita in prototipurile &unctiilor 9calloc"$9 si 9malloc"$97 void Ccalloc"si%e=t, si%e=t$@ void Cmalloc"si%e=t$@ Deoarece pointerul returnat de aceste &unctii are tipul 9void9, acesta poate &i asi nat altor pointeri &ara conversie explicita "cast$. Totusi unele sisteme nu accepta aceasta conversie, deci ea trebuie &acuta explicit. 3ctetii re%ervati de 9calloc"$9 sunt automat initiali%ati cu 8, pe cand cei re%ervati cu 9malloc"$9 nu sunt initiali%ati "deci vor avea valori 9 arba e9$. 2umele 9calloc9, respectiv 9malloc9, provine de la 9contiguous allocation9, respectiv 9memory allocation9. <unciile care ntorc pointeri sunt utile n alocarea de spaiu pentru variabile dinamice. ;ariabilele dinamice sunt alocate n momentul execuiei, nu au nume i sunt accesate prin pointeri. 4n constructor este o &uncie care aloc spaiu n mod dinamic pentru o variabil i ntoarce un pointer la spaiul re%ervat. 4n destructor este o &uncie care primete un pointer la o %on alocat dinamic i eliberea% aceast %on. 3 &uncie util, str#up() K salvea% un ir de caractere ntr)o %on alocat dinamic i ntoarce un pointer la acea %on sau N$%%. c$ar !strdup3c$ar !s7

9 c$ar !p# p-3c$ar!7 alloc3strlen3s7F17# if 3pV-N+,,7 strcp/3p,s7# return p# = 5xemplul 1.18.7 Citii de la intrarea standard un ir de caractere de lungime necunoscut !ntr"un vector alocat dinamic# Alocarea de memorie se va $ace progresiv% !n incremente de lungime I!"% dup citirea a I!" caractere se $ace o realocare# c$ar !citire37 9 c$ar !p, !M# int n# unsi"ned di -?NC# p-M-3c$ar!7 alloc3di 7# for3n-1# 3!p-"etc$ar377V-[6n[ ..!pV-A0P# nFF7 9 if3n5?NC--G7 9 di F-?NC# p-M-realloc3M,di 7# pFF# = !p-[6G[# return realloc3M,n7# =

pF-n#

continue#

2ot. 0n ,II, alocarea dinamic se &ace mai simplu i mai si ur, &olosind operatorii ne& i #elete. permite alocarea de memorie n 1eap. 5l se &olosete ntr)una din &ormele7 tip Cp, C_, Cr@ pEne] tip@ DDre%erva in 1eap o %ona de si%eo&"tip$ octeti _Ene] tip"expresie$@DDacelasi e&ect cu initiali%are cu val.expresiei rEne] tip?expintV@ DDre%erva o %ona neinitiali%ata de expintCsi%eo&"tip$ octeti 5liberarea memoriei alocate se &ace prin7 delete p7 delete ?V r@

3peratorul

ne&

DDeliberea%a memoria alocata pentru tablou

Exemplul 1.117 De&inii o &uncie care aloc dinamic memorie pentru o matrice av:nd l linii i c coloane con&orm or ani ramei urmtoare7

plin plin?8V plin?1V plin?!V

pelem pelem?8V?8V pelem?8V?1V pelem?1V?8V pelem?1V?1V pelem?!V?1V pelem?!V?8V

double !!aloc at3int lin, int col7 9 double !!plin# double !pele # int i# pele -3double!7calloc3lin!col, sizeof3double77# if3pele --3double!7N+,,79 printf3:spatiu insuficient6n7# exit317#= plin-3double!!7calloc3lin, sizeof3double!7# if3plin--3double!!7N+,,79 printf3:spatiu insuficient6n7# exit317# = for 3i-G# iN lin# iFF7 9 plin%i'-pele # pele F-col# = return plin# = Exemplul 1.1!7
LincludeMstdio.1N LincludeMstdlib.1N void main"$ P int n,i@ &loat Cp,Cp8@ print&"9-ntroduceti dimensiunea tabloului7 9$@ scan&"9Sd9,Gn$@ pE"&loat C$malloc"nCsi%eo&"&loat$$@ DD"&loat C$ converteste pointerul void returnat de catre malloc intr)un pointer la tipul &loat p8Ep@ i& "pEE24LL$ P print&"95roare7 >emorie nedisponibilaRn9$@ exit"1$@ T &or"iE8@iMn@iII$ P CpEi@ print&"9RnS`RtS 9,p,Cp$@ pII@ T &ree"p8$@ T

>ointeri la pointeri 3indirectare multipla$. Limba/ul , permite reali%area indirectarii multiple prin &aptul ca un pointer poate &i pointat de un alt pointer. -ndirectarea multipla este limitata la pointer catre pointer si se utili%ea%a cu precautie.

Figura &&#&# 'ointerul catre pointer retine adresa pointerului la o variabila Daca pointer& pointea%a catre pointer( atunci acesta contine adresa lui pointer(. 'ointer( contine adresa variabilei. Declararea unui pointer la pointer se &ace cu un C suplimentar &ata de declararea pointerului. De exemplu7 int [@ DC declararea variabilei CD int Cp@ DC declarare pointer CD

int CCplap@ DC declarare pointer la pointer CD float v,!p,!!pp# p-.v# pp-.p# !!pp-1.) DC vE1,! CD DC ,itirea unui sir prin indirectare multipla CD LincludeMstdio.1N void ain 3void7 9 c$ar sir%&G',!p1sir,!!p1p1sir# p-sir# p1p1sir-.p# printf346n ?ntroduceti nu ele Dvs.: 47# "ets3!p1p1sir7# printf346n Salut 5s 4, !p1p1sir7# = +entru a declara un pointer ctre un alt pointer, trebuie plasat un asterix suplimentar n &aa numelui pointerului. De exemplu7 c$ar !! pp# pp este un pointer ctre un alt pointer de tip c1ar, i nu un pointer ctre un caracter. Accesarea valorii printr)un pointer ctre un alt pointer, cere ca operatorul asterix s &ie aplicat de dou ori. De exemplu7 p - .c$# DD asi nea% lui p adresa lui c1 pp - .p# DDasi nea% lui pp adresa lui p !!pp - \c[# DD asi nea% lui c1 valoarea WcX &olosind indirectare multipl 3bservaie. +ointeri ctre pointeri pot produce con&u%ii. De aceea, indirectarea excesiv este derutant i surs de erori conceptuale.

Exemplul 1.1'7 Da)i la execuie pentru a nele e principiile principale. Anali%ai de&iniiile &unciilor, modul de or ani%are a apelurilor i obinere a re%ultatelor prin antetul &unciilor. <ace)i comentarii, mbuntiri i rulai din nou. ,omparai.
Linclude Mstdio.1N Linclude Mstrin .1N Linclude Mconio.1N void Simetric+are"c1arC$@ void Simetric-mpare"c1arC$@ void Transpune"c1arC$@ c1arC Trim"c1arC$@ void 5nter+rop"c1arC$@ void Simetric-mpare"c1arC$@ void ,alculate"c1arC$@ int count+areE)1, count-mpareE(8, index, probelsE8, len@ c1ar Cc>aiLun , Cc>aiScurt, Ccuvintele?18V@ bool b+arE&alse, b-mparE&alse, enteredE&alse@ int main"void$ P c1ar c+ropo%itia?1!(V@ int iE8, /, mi@ print&"9>enu7Rn))))))))))Rn9$@ print&"91. -ntroducerea propo%itieiRn9$@ print&"9!. ,alculeRn9$@ print&"9'. Simetric lun pe po%.pareRn9$@ print&"9#. Simetric scurt pe po%.impareRn9$@ print&"9(. TranspusaRn9$@ print&"9Q. -esireRn9$@ print&"9Rn)EAle eti un punct al meniuluiE)7Rn9$@ mi E etc1"$@ ]1ile"miJE"int$ZQZ$ P s]itc1"mi$ P case "int$Z1Z7 5nter+rop"c+ropo%itia$@ brea[@ case "int$Z!Z7 i&"Jentered$Pprint&"9-ntrod. propo%itiaJ9$@ brea[@T,alculate"c+ropo%itia$@ brea[@ case "int$Z'Z7 i&"Jentered$Pprint&"9-ntrod. propo%itiaJ9$@ brea[@Ti&"b+ar$print&"9RnSimetric Lun de pe pare7 SsRn9, c>aiLun $@else print&"9RnRnSimetric Lun pe pare nu a &ost asitRn9$@ brea[@ case "int$Z#Z7 i&"Jentered$Pprint&"9-ntrod. propo%itiaJ9$@ brea[@Ti&"b-mpar$print&"9RnSimetric Scurt de pe impare7 SsRn9, c>aiScurt$@else print&"9RnRnSimetric Scurt pe impare nu a &ost asitRn9$@ brea[@ case "int$Z(Z7 P i&"Jentered$Pprint&"9-ntrod. propo%itiaJ9$@ brea[@T &or"iE8@ iMprobelsI1@ iIE!$ P Transpune"cuvintele?iV$@

T i&"Jb+ar aa Jb-mpar$ P puts"9+ropo%itia transpusa7 9$@ &or"int iE8@ iMlen@ iII$ print&"9Sc9, c+ropo%itia?iV$@ T else print&"9,uvinte transpuse nu suntRn9$@ T brea[@ de&ault7 print&"9,omanda necunoscutaRn9$@ brea[@ T mi E etc1"$@ T return 8@ T void 5nter+rop"c1arC c$ P print&"9-ntroduceti propo%itia7 9$@ ets"c$@ c E Trim"c$@ entered E true@ return@ T void ,alculate"c1arC c$ P int i, /@ len E strlen"c$@ &or"iE8@ iMstrlen"c$@ iII$ i&"c?iVEEZ Z$probelsII@ DC S+L-T CD cuvintele?8V E strto["c, 9 9$@ &or"iE8@ iMprobels@ iII$ cuvintele?iI1V E strto["24LL, 9 9$@ DC CCC CD &or"iE8, /E1@ iMprobelsI1@ iIE!, /IE!$ DD/)pare, i)impare P Simetric-mpare"cuvintele?iV$@ i&"/MprobelsI1$Simetric+are"cuvintele?/V$@ T print&"9Rn,alcule si operatii cu propo%itia au &ost e&ectuateRn9$@ return@ T void Simetric+are"c1arC c$ P int /Estrlen"c$)1, i@ &or"iE8@ iMstrlen"c$D!@ iII, /))$ i&"c?iVJEc?/V$return@ b+ar E true@ i&"count+areM"int$strlen"c$$ P c>aiLun E c@ count+are E strlen"c$@ T return@ T void Simetric-mpare"c1arC c$ P int /Estrlen"c$)1, i@ &or"iE8@ iMstrlen"c$D!@ iII, /))$

i&"c?iVJEc?/V$return@ b-mpar E true@ i&"count-mpareN"int$strlen"c$$ P c>aiScurt E c@ count-mpare E strlen"c$@ T return@ T void Transpune"c1arC cuvintul$ P int i, /Estrlen"cuvintul$)1@ c1ar c@ &or"iE8@ iMstrlen"cuvintul$D!@ iII, /))$ P c E cuvintul?iV@ cuvintul?iV E cuvintul?/V@ cuvintul?/V E c@ T return@ T c1arC Trim"c1arC c$ P int index, i, /@ c1arC str!trim@ str!trim E c@ index E strlen"str!trim$@ &or"iE8, /E8@ iMstrlen"str!trim$@ iII$ P i&"str!trim?iVEEZ Z GG str!trim?iI1VEEZ Z$P index))@ continue@ T str!trim?/V E str!trim?iV@ /II@ T str!trim?indexV E ZR8Z@ ]1ile"Cstr!trimEEZ Z$Cstr!trimII@ index E strlen"str!trim$@ ]1ile"str!trim?index)1VEEZ Z$ index))@ str!trim?indexV E ZR8Z@ return str!trim@ T

'(! )roblemele propuse spre i ple entare i


DD >roble a 3 ! 5xemplu de transmitere a &unctiilor ca ar umente DD +SUD!888 Linclude Mstdio.1N Linclude Mmat1.1N Lde&ine 2 (8 double &"double x$@ double Suma+atrate<unctii "double "C&$"double$, double x?V, int n$@ void main"$ P double x,tab?(8V, pasE! C >=+-D2, s1,s!@ int i@ &or"iExE8@ i M2 @ xIEpas$ tab?iIIVEx@ s1ESuma+atrate<unctii "sin, tab, 2$@ s!ESuma+atrate<unctii "&, tab, 2$@ print&"9RnS1ESl& s!ESl&9, s1,s!$@ T DD))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) double Suma+atrate<unctii "double "C&$"double$, double x?V, int n$ P double sumapE8@ &or"n))@ nNE8@ n))$ sumapIE &"x?nV$ C "C&$"x?nV$@ return sumap@ T DD)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) double &"double x$ P return 1.D"xI1$@ T

odificare

Problema 3 " )e determinat schema *organigrama+de re$erin i valorile $iec reia7

LincludeMstdio.1N LincludeMconio.1N int a# int !pa# int !!ppa# int !!!pppa# void ain379clrscr37# a-**# pa-.a# ppa-.pa# pppa-.ppa# printf346n5d4,!!!!!pppppa7# "etc$37# =

int !!!!ppppa#

int !!!!!pppppa#

ppppa-.pppa# pppppa-.ppppa#

'roblema ,#, 5xempli&icai de&inirea i iniiali%area variabilelor spre pointer, i respectiv pointer ctre pointer spre pointer spre ntre . )e determinat schema *organigrama+de re$erin i valorile $iec reia LincludeMstdio.1N LincludeMconio.1N LincludeMalloc.1N int intre E!!@ int Cp=int@ DDpointer spre intre int CCpp=int@ DDpointer spre pointer void main"$P clrscr"$@ p=intE"int C$malloc"si%eo&"int$$@ p=intEGintre @ pp=intE"int CC$malloc"si%eo&"intC$$@ pp=intEGp=int@ print&"9Sd9,CCpp=int$@ etc1"$@ T Problema 3 # S 1 5xempli&icai de&inirea i iniiali%area variabilelor spre pointer, i respectiv pointer ctre pointer spre pointeri spre pointeri. )e determinat schema *organigrama+de re$erin i valorile $iec reia LincludeMstdio.1N LincludeMconio.1N LincludeMalloc.1N int !!!ppp1int# int !!pp1int# int !p1int# int intre"-22# void ain379 clrscr37# p1int-3int !7 alloc3sizeof3int77# pp1int-3int !!7 alloc3sizeof3int!77# ppp1int-3int !!!7 alloc3sizeof3int!!77# p1int-.intre"# pp1int-.p1int# ppp1int-.pp1int# printf345d4,!!!ppp1int7# printf345d4,!!pp1int7# "etc$37# = 'roblema ,#- 5xempli&icai de&inirea i iniiali%area variabilelor spre pointer, i respectiv pointer ctre pointer spre pointeri spre pointeri. )e determinat schema *organigrama+de re$erin i valorile $iec reia 5xplicai ,e va a&ia = LincludeMconio.1N LincludeMstdio.1N int 3!v%*'7%*'%*'# int 3!3!ppp7%*'7%*'%*'# int3!3!3!p$77%*'7%*'%*'# int s?'V,m?'V?'VEPP1,!,6T,P#,Q,*T,PQ,*,(TT@ void main"$P clrscr"$@ &or"int iE8@iM'@iII$ v?iVEGm@ pppEGv@ p1EGppp@ &or"iE8@iM'@iII$Ps?iVE8@ &or"int /E8@/M'@/II$ s?iVIE"C"C"Cp1$$?iV$?iV?/V@ T &or"iE8@iM'@iII$ print&"9 vE Sd 9,v?iV$@ &or"iE8@iM'@iII$ print&"9 sE Sd 9,s?iV$@ etc1"$@ T 'roblema ,#. 5xempli&icai de&inirea i iniiali%area variabilelor spre pointer, i respectiv pointer ctre pointer spre pointeri spre pointeri. )e determinat schema *organigrama+de re$erin i valorile $iec reia 5xplicai ,e va a&ia = LincludeMconio.1N LincludeMstdio.1N LincludeMdos.1N intCppc@ int c?(V?!VEPP1,!T,P',#T,P(,QT,P*,6T,PO,18TT@ int b?18VEP11,1!,1',1#,1(,1Q,1*,16,1O,!8T@ void main"$P clrscr"$@ print&"9Rn9$@ &or"int iE8@iM18@iII$P ppcE"intC$ET1P>3P>1SAO3c%i'7,<+=3<<"c?iV$$@ print&"9 Sd 9,Cppc$@ T etc1"$@ T 'roblema ,#/ )e$inii i re$erii un masiv tridimensional, pun:nd n coresponden adresa elementelor de pe prima linie i coloana masivelor bidimensionale n care se descompune, cu elementele unui vector de pointeri. -niiali%area elementelor masivului tridimensional se reali%ea% prin date introduse de la terminal utili%:nd aceti pointeri. De determinat sc1ema "or ani rama$ de re&erin i valorile &iecreia 5xplicai ,e va a&ia 7 LincludeMdos.1N LincludeMstdio.1N unsi ned int aaa,bbb@ int a?'V?'V?'V@ int Cvp?'V@ int Cpp@ int /,[@ c1ar raspEX1X@ void main"$P clrscr"$@ &or"int iE8@iM'@iII$ &or"/E1@/M'@/II$ &or"[E8@[M'@[II$ a?iV?[V?/VE8@ &or"iE8@iM'@iII$ vp?iVEGa?iV?8V?8V@ ]1ile"raspJEX X$P print&"9Rnintroduceti coordonatele7Rn 9$@ print&"9Rncoordonata i 7 9$@scan&"9Sd9,Gi$@i))@ print&"9coordonata / 7 9$@scan&"9Sd9,G/$@/))@ print&"9coordonata [ 7 9$@scan&"9Sd9,G[$@[))@ aaaEP>1SAO"vp?iV$@ bbbE<+=3<<"vp?iV$@ aaaIE"/C'I[$C!@ bbbIE"/C'I[$C!@ ppE"int C$>B=<+"aaa,bbb$@ print&"9Rndati elementul7 9$@ scan&"9Sd9,pp$@ print&"9Rn,ontinuati introducerea\ ?pentru nu,tastati spatiuV7 9$@ &&lus1"stdin$@scan&"9Sc9,Grasp$@ T &or"iE8@iM'@iII$P &or"/E8@/M'@/II$P &or"[E8@[M'@[II$ print&"9 Sd 9,a?iV?/V?[V$@ print&"9Rn9$@ T print&"9RnCCCCCCCRn9$@ T etc1"$@ T 'roblema ,#0 5xempli&icai de&inirea i iniiali%area variabilelor spre pointer, i *organigrama+de re$erin i valorile $iec reia 5xplicai ,e va a&ia = LincludeMstdio.1N LincludeMconio.1N determinai schema

&loat F?188V@ int &?188V,n@ &loat xmed?'V@ &loat "C&unctii?'V$"&loat x?188V,int &?188V,int n$@ &loat med1"&loat x?188V,int &?188V,int n$P &loat aE8,b@ &or"int iE8@iMn@iII$P &?iVE1@ aIEx?iVC&?iV@ T return aDn@ T &loat med!"&loat x?188V,int &?188V,int n$P &loat a,b@ aEbE8@ &or"int iE8@iMn@iII$P bIE&?iV@ aIEx?iVC&?iV@ T return aDb@ T &loat med'"&loat x?188V,int &?188V,int n$P &loat a,b@ aEbE8@ &or"int iE8@iMn@iII$P bIE&?iV@ aIE&?iVDx?iV@ T return bDa@ T void main"$P &unctii?8VEmed1@ &unctii?1VEmed!@ &unctii?!VEmed'@ print&"9Rn2r de elemente7 9$@&&lus1"stdin$@ scan&"9Sd9,Gn$@ &or"int iE8@iMn@iII$P print&"9Rn F?SdVE 9,iI1$@ scan&"9S&9,GF?iV$@ T &or"iE8@iM'@iII$P xmed?iVE&unctii?iV"F,&,n$@ print&"9RnS1!.18&9,xmed?iV$@ T etc1"$@ T 'roblema ,#1 2e de$inete un masiv bidimensional de pointeri spre &uncii l iniiali%ai e&ectuai traversai acset masiv pe linii i coloane. 5xempli&icai de&inirea i iniiali%area variabilelor spre pointer, i determinai schema *organigrama+de re$erin i valorile $iec reia 5xplicai ,e va a&ia <unciile LincludeMstdio.1N LincludeMconio.1N tFpede& c1arC &"$@ & Ca?!V?!V@ DDo matrice de pointeri spre &unctii c1ar Cs@ c1ar C&1"$P return 9&unctia19@ T c1arC &!"$P return 9&unctia!9@ T c1arC &'"$P return 9&unctia'9@ T c1arC &#"$P return 9&unctia#9@ T void main"$P clrscr"$@ a?8V?8VE&1@ a?8V?1VE&!@ a?1V?8VE&'@ a?1V?1VE&#@ &or"unsi ned c1ar iE8@iM!@iII$ &or"unsi ned c1ar /E8@/M!@/II$P sEa?iV?/V"$@ print&"9Rn Ss9,s$@ T etc1"$@ T DD problema matricei cu pointeri Linclude Mconio.1N@ Linclude Mstdio.1N@ Linclude Mstdlib.1N@ void main"$ P int Cp,Ca,i,/,n,[,s,l@ c1ar c1@ clrscr"$@ print&"9-ndicati dimensiunea matricei79$@ scan&"9Sd9,Gn$@ aE"int C$ malloc"nCn$@ pEa@ &or"iE8@iMn@iII$ &or"/E8@/Mn@/II$ P print&"9a?Sd,SdVE9,iI1,/I1$@ scan&"9Sd9,pII$@ T ]1ile"1$ P clrscr"$@ print&"91 ) a&isarea elementelor primeRn9$@ print&"9! ) suma elementelor impareRn9$@ print&"9' ) &recventa elementului indicatRn9$@ print&"9# ) iesireRn9$@ c1E etc1e"$@ s]itc1 "c1$ P case Z1Z 7 clrscr"$@ print&"95lementele matricei sunt7Rn9$@ pEa@ &or"iE8@iMn@iII$ P &or"/E8@/Mn@/II$ print&"9 Sd9,CpII$@ print&"9Rn9$@ T print&"95lementele prime ale liniilor impare sunt7Rn9$@ pEa@ &or"iE8@iMn@iIE!$ P &or"/E8@/Mn@/II$ P [E1@sE8@ ]1ile"[MECp GG CpJE8$ P i&"CpS[EE8$ sII@ [II@ T i&"sEE! aa CpEE1$ print&"9 Sd9,Cp$@ pII@ T pIEn@ T etc1"$@brea[@ case Z!Z 7 clrscr"$@ print&"95lementele maricei sunt7Rn9$@ pEa@ &or"iE8@iMn@iII$ P &or"/E8@/Mn@/II$ print&"9 Sd9,CpII$@ print&"9Rn9$@ T print&"9Suma elementele impare ale coloanelor pare sunt7Rn9$@ sE8@ pEa@ &or"iE8@iMn@iII$ &or"/E1@/Mn@/IE!$ i&"C"pIiCnI/$S!EE1$ sIEC"pIiCnI/$@ print&"9sESd9,s$@ etc1"$@ brea[@ case Z'Z 7 clrscr"$@ print&"95lementele maricei sunt7Rn9$@ pEa@ &or"iE8@iMn@iII$ P &or"/E8@/Mn@/II$ print&"9 Sd9,CpII$@ print&"9Rn9$@ T print&"9-ndicati numarul la care doriti sa a&lati &recventa7 9$@ scan&"9Sd9,G[$@ sE8@ pEa@ i&"nS!EE8$ lEnD!)1@ else lEnD!@ &or"iE8@iMl@iII$ &or"/EiI1@/Mn)i)1@/II$ i&"C"pIiCnI/$EE[$ sII@ print&"9Rn <recventa in cadranul 1 este7 Sd9,s$@ sE8@ &or"iEnD!I1@iMn@iII$ &or"/Ei)1@/NEn)i@/))$ i&"C"pIiCnI/$EE[$ sII@ print&"9Rn <recventa in cadranul ' este7 Sd9,s$@ etc1"$@ brea[@ case Z#Z 7 etc1"$@ exit"1$@ brea[@ de&ault7 print&"9RnTastati intre 1 si ' JRn9$@ etc1"$@ T T T

'roblema ,#&3 LincludeMstdio.1N LincludeMconio.1N LincludeMalloc.1N LincludeMstrin .1N LincludeMstdlib.1N Lde&ine 2.L-2-- !8 Lde&ine 2.,A.A,T Q8 tFpede& int "Cpointer&cmp$"const void C, const void C$@ int etText"c1ar CCtext, c1ar linieText?V$@ int compara"const c1ar CCs1, const c1ar CCs!$@ void a&isSortedText"c1ar CCtext, int nrLinii$@ void de%aloc>emorF"c1ar CCtext, int nrLinii$@ void main"void$P c1ar Ctab?2.L-2--V, linieText?2.,A.A,TV@ clrscr"$@ int n E etText"tab, linieText$@ DDsortare cu _sort _sort"tab, n, si%eo&"c1arC$, "pointer&cmp$compara$@ a&isSortedText"tab,n$@ DDde%alocarea memoriei de%aloc>emorF"tab, n$@ etc1"$@ T void de%aloc>emorF"c1ar CCtext, int nrLinii$ P &or"int iE8@ iMnrLinii@ iII$ &ree"text?iV$@ T int compara"const c1ar Cs1?V, const c1ar Cs!?V$ P return strcmp"Cs1, Cs!$@ T void a&isSortedText"c1ar CCtext, int nrLinii$ P puts"9RnTextul ordonat prin _sort este79$@ &or"int i E8@ iMnrLinii@ iII$ print&"9RnSs9, text?iV$@ T int etText"c1ar CCtext, c1ar linieText?V$ P print&"9Rn-ntroduceti liniile "inc1eiere cu linie vida$7Rn9$@ int i E 8@ ]1ile"1$ P i&"iEE2.L-2--$P DDs)a atins maximul alocat puts"9RnS)a atins maximul de linii alocat pentru text9$@ brea[@ T ets"linieText$@ DDiesirea cu linie vida i&"strlen"linieText$ EE 8$ brea[@ DDstrlen nu contori%ea%a ZR8Z text?iV E "c1arC$ malloc"strlen"linieText$I1$@ i&"text?iV EE 8$ P puts"9Rn5roare la alocarea memoriei pentru text9$@ exit"1$@ T strcpF"text?iIIV, linieText$@ T return i@ T

Aiblio ra&ie7 1. .9Limba/ul de pro ramare ,9. Arian b.Berni 1an. Dennis >..itc1ie. !. Liviu 2e rescu. H4imba5ul de programare C i C667 ;.1)#. Auc. 1OOO '. Bnut1, D. 5. ) 9Arta pro ramarii calculatoarelor, vol. 17 Al oritmi &undamentali9, 5d. Teora, 1OOO. #. Bnut1, D. 5. ) 9Arta pro ramarii calculatoarelor, vol. !7 Al oritmi seminumerici9, 5d. Teora, !888. (. Bnut1, D. 5. ) 9Arta pro ramarii calculatoarelor, vol. '7 Sortare si cautare9, 5d. Teora, !881. Q. Aacivarov, A.@ 2astac, -. ) 9Limba/ul ,. -ndrumar de laborator9, Tipo ra&ia 4+A, Aucuresti, 1OO*. *. Aates, ^@ Tomp[ins, T. ) 94tili%are ,II9, 5d. Teora !881. 6. -onescu Texe, ,.@ csa[o, -. ) 9Structuri arborescente si aplicatiile lor9, 5d. Te1nica, 1OO8. O. Andonie, ..@ Uabarcea, -. ) 9Al oritmi &undamentali. 3 perspectiva ,II9, 5d. Libris, 1OO(. 18. delp din Turbo , II-D5 ,versiunea '.8. 1OOO 11. ,3.>52, T. ) L5-S5.S32, ,d. ) .-;5ST, .. 7 -ntroducere in al oritmi, 5ditura ,omputer Libris. A ora, ,lu/) 2apoca, !888. 1!. D. Lucanu7 Aa%ele proiectarii pro ramelor si al oritmilor, 4niversitatea A.-.,u%aH -asi, 1OOQ 1'. L. Livovsc1i, d. Ueor escu7 Sinte%a si anali%a al oritmilor, 5d. Stiinti&ica si enciclopedica, 1O6Q 1#. ,ristea ;alentin. Te1nici de pro ramare. 5d.7 Aucur., Teora, 1OO'. DQ61.'@ T!OD 1(. 3da escu -oan, ,opos ,ristina s.a. >etode si Te1nici de pro ramare.Denunturi, solutii, probleme propuseD 5d.7Aucur.7 -2TA,T, 1OO# DQ61.'@ 3!'D 1Q. Tudor Alnescu. ,orectudinea a oritmilor.Aucur.75d. Te1n.1OO( 1*. ,onspectele la +, !818 i SDA)!811

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