Documente Academic
Documente Profesional
Documente Cultură
Curs C
Curs C
PROGRAMAREA CALCULATOARELOR
Florentina MOCRIENCO
Daniela VLDOIU
2006
TEHNOLOGIA INFORMAIEI
Programarea calculatoarelor
Florentina MOCRIENCO
Dana VLDOIU
2006
2006
Ministerul Educaiei i Cercetrii Proiectul pentru nvmntul Rural Nici o parte a acestei lucrri nu poate fi reprodus fr acordul scris al Ministerului Educaiei i Cercetrii
Cuprins
CUPRINS
Unitatea de nvare Nr. 1 ................................................................................................. 1 DEFINIREA NOIUNILOR DE ALGORITM, PROGRAM I LIMBAJ DE PROGRAMARE Obiectivele Unitii de nvare 1 ..................................................................................... 1 1.1 Noiunea de algoritm ................................................................................................... 1 1.2 Propietile algoritmilor .............................................................................................. 4 1.3 Programe i limbaje de programare........................................................................... 8 1.3.1 Evoluia limbajelor de programare ................................................................ 9 1.3.2 Etapele realizrii programelor ...................................................................... 16 Rspunsurile corecte la testele de autoevaluare.......................................................... 20 Bibliografie....................................................................................................................... 20 Lucrarea de verificare Nr. 1, notat de tutore ............................................................... 21 Unitatea de nvare Nr. 2 ............................................................................................... 22 PRINCIPIILE PROGRAMRII STRUCTURATE Obiectivele Unitii de nvare 2 ................................................................................... 22 2.1 Reprezentarea algoritmilor ....................................................................................... 22 2.2 Elemente de programare structurat ....................................................................... 26 2.3 Structuri de control utilizate n programarea structurat ...................................... 29 2.3.1 Secvena sau structura liniar ...................................................................... 29 2.3.2 Decizia sau structura alternativ .................................................................. 32 2.3.3 Ciclul sau structura repetitiv ....................................................................... 36 Rspunsuri corecte la testele de autoevaluare............................................................. 42 Bibliografie....................................................................................................................... 42 Lucrarea de verificare Nr. 2, notat de tutore ............................................................... 43 Unitatea de nvare Nr. 3 ............................................................................................... 44 STRUCTURA PROGRAMELOR N LIMBAJUL C. TIPURI DE DATE, OPERATORI I EXPRESII Obiectivele Unitii de nvare 3 ................................................................................... 44 3.1 Privire de ansamblu asupra limbajului C................................................................. 44 3.2 Structura programelor n limbajul C ........................................................................ 46 3.3 Variabile, tipuri de variabile i declarare ................................................................. 51 3.4 Constante ................................................................................................................... 54 3.5 Funcii aritmetice care opereaz cu valori de tip real i ntreg.............................. 57 3.6 Operatori n C............................................................................................................. 60 3.6.1 Operatorul de atribuire ................................................................................. 60 3.6.2 Operatori aritmetici....................................................................................... 61 3.6.3 Operatori relaionali i logici ......................................................................... 65 3.6.4 Operatori de atribuire compus.................................................................... 67 3.6.5 Operatorul de conversie explicit (cast) ....................................................... 68 3.6.6 Operatorul sizeof.......................................................................................... 68 3.6.7 Operatorul virgul (,) .................................................................................. 69
Proiectul pentru nvmntul Rural
Cuprins
3.6.8 Operatorul condiional (?) .............................................................................69 Rspunsuri corecte la testele de autoevaluare, sarcinile de lucru i exerciii ...........72 Bibliografie .......................................................................................................................72 Lucrarea de verificare Nr. 3, notat de tutore................................................................73 Unitatea de nvare Nr. 4 ...............................................................................................76 CITIREA I SCRIEREA DATELOR Obiectivele Unitii de nvare 4 ....................................................................................76 4.1 Noiuni introductive ...................................................................................................76 4.2 Funcia de scriere cu format .....................................................................................77 4.3 Funcia de citire cu format ........................................................................................81 Rspunsuri corecte la testele de autoevaluare, sarcinile de lucru i exerciii ...........86 Bibliografie .......................................................................................................................87 Lucrarea de verificare Nr. 4, notat de tutore................................................................87 Unitatea de nvare Nr. 5 ...............................................................................................89 INSTRUCIUNILE LIMBAJULUI C / C++ Obiectivele Unitii de nvare 5 ....................................................................................89 5.1 Instruciunea expresie ...............................................................................................89 5.2 Instruciunea compus ..............................................................................................90 5.3 Instruciunea if ..........................................................................................................90 5.4 Instruciunea switch ..................................................................................................93 5.5 Instruciunea break ....................................................................................................94 5.6 Instruciunea while.....................................................................................................94 5.7 Instruciunea do-while ...............................................................................................95 5.8 Instruciunea for.........................................................................................................97 Rspunsuri corecte la testele de autoevaluare, sarcinile de lucru............................100 Bibliografie .....................................................................................................................100 Lucrarea de verificare nr.5, notat de tutore ...............................................................101 Unitatea de nvare Nr. 6 .............................................................................................103 TABLOURI Obiectivele Unitii de nvare 6 ..................................................................................103 6.1 Tablouri unidimensionale........................................................................................104 6.2 Pointeri......................................................................................................................111 6.3 iruri de caractere ...................................................................................................115 Rspunsuri corecte la testele de autoevaluare, sarcinile de lucru i exerciii .........121 Bibliografie .....................................................................................................................121 Lucrarea de verificare Nr. 6, notat de tutore..............................................................122
ii
Cuprins
Unitatea de nvare Nr. 7 ............................................................................................. 123 FIIERE N LIMBAJUL C++ Obiectivele Unitii de nvare 7 ................................................................................. 123 7.1 Declararea fiierelor ................................................................................................ 123 7.2 Deschiderea fiierelor ............................................................................................. 124 7.3 Citirea datelor dintr-un fiier .................................................................................. 125 7.4 Scrierea datelor ntr-un fiier.................................................................................. 126 7.5 Operaii de test ........................................................................................................ 126 7.6 nchiderea unui fiier............................................................................................... 127 Rspunsuri corecte la testele de autoevaluare........................................................... 129 Bibliografie..................................................................................................................... 130 Lucrarea de verificare nr. 7, notat de tutore ........................................................ 130 Unitatea de nvare Nr. 8 ............................................................................................. 132 FUNCII Obiectivele Unitii de nvare 8 ................................................................................. 132 8.1 Funcii nerecursive.................................................................................................. 132 8.1.1 Definirea unei funcii ............................................................................................... 133 8.1.2 Declararea funciilor................................................................................................ 134 8.1.3 Apelul funciilor ....................................................................................................... 135 8.1.4 Variabile globale i variabile locale ......................................................................... 140 8.2 Funcii recursive...................................................................................................... 145 Rspunsuri corecte la testele de autoevaluare, sarcinile de lucru ........................... 153 Bibliografie..................................................................................................................... 155 Lucrarea de verificare Nr. 8, notat de tutore ............................................................. 156 ANEXE Laboratorul 1.................................................................................................................. 159 Laboratorul 2.................................................................................................................. 168 Laboratorul 3.................................................................................................................. 171 Laboratorul 4.................................................................................................................. 176 Laboratorul 5.................................................................................................................. 183 Laboratorul 6.................................................................................................................. 189 Laboratorul 7.................................................................................................................. 194 BIBLIOGRAFIE............................................................................................................... 201
iii
Introducere
INTRODUCERE
Manualul de Programarea calculatoarelor este structurat astfel nct s ofere cursanilor cunotinele necesare pentru a fi capabili s neleag i s foloseasc un limbaj de programare n scopul rezolvrii unor probleme cu ajutorul calculatorului. n elaborarea acestuia s-a urmrit abordarea ct mai complet i mai adecvat a tematicii cuprinse n programele colare ale disciplinelor de profil din nvmntul preuniversitar pentru a oferi cursanilor posibilitatea de a preda aceste discipline la orice nivel. Noiunile sunt prezentate gradat, punndu-se accent pe nelegerea i aplicarea acestora n practic. Se recomand ca n procesul de predare nvare, activitatea s fie orientat pe probleme: analiza unor situaii practice (generale sau specifice unui anumit domeniu), identificarea fluxului informaional, elaborarea unui model algoritmic de rezolvare, implementarea i testarea rezolvrii cu ajutorul limbajului de programare C i C++. Datorit caracterului pregnant aplicativ al disciplinei, se recomand desfurarea orelor ntr-o sal dotat cu un numr suficient de sisteme de calcul, astfel nct pe un sistem de calcul s lucreze cel mult doi cursani. Evaluarea activitii cursanilor se va face att pe baza activitii practice desfurate n timpul semestrului (sarcini de lucru, rezolvarea de probleme n laborator i teme de cas), ct i prin susinerea unui examen final. Bibliografia de baz va cuprinde manuale, culegeri de probleme, programe de specialitate elaborate de ctre Ministerul Educaiei i Cercetrii pentru nvmntul preuniversitar, resurse WWW.
Obiectivele modulului
Dup studiul modulului Programarea calculatoarelor, vei reui s:
programare n rezolvarea problemelor. Exprimai un mod de gndire creativ, n structurarea i rezolvarea problemelor. V formai obisnuinele de a recurge la concepte i metode informatice de tip algoritmic specifice n abordarea unei varieti de probleme. Avei capacitatea de a nelege i folosi elementele de baz ale limbajului de programare C i C++. Avei abilitatea de a rezolva probleme complexe prin organizarea corespunztoare a programelor sub forma de proiect. Manifestai iniiativ i disponibilitatea de a aborda sarcini variate. V adaptai abilitile pedagogice la domeniul specific Programrii calculatoarelor.
Proiectul pentru nvmntul Rural
iv
Introducere
Modulul Programarea calculatoarelor, este integrat domeniului Tehnologia Informaiei i face parte din categora disciplinelor opionale de specialitate studiate n semestrul al III lea. Din totalul de 56 de ore destinat modulului, 75% din ore sunt alocate aplicaiilor practice.
Unitatea de nvare este o parte component a modulului de studiu, care are urmtoarele caracteristici: Integreaz competene specifice Determin formarea unui anumit comportament al cursantului, generat prin integrarea unor competene specifice Este unitar din punct de vedere tematic Se desfoar n mod sistematic Se finalizeaz prin evaluare.
Modulul este structurat pe urmtoarele opt uniti de nvare: DEFINIREA NOIUNILOR DE ALGORITM, PROGRAM I LIMBAJ DE PROGRAMARE PRINCIPIILE PROGRAMRII STRUCTURATE STRUCTURA PROGRAMELOR N LIMBAJUL C. TIPURI DE DATE, OPERATORI I EXPRESII CITIREA I SCRIEREA DATELOR INSTRUCIUNILE LIMBAJULUI C / C++ TABLOURI FIIERE N LIMBAJUL C++ FUNCII
Construirea competenelor
Pentru fiecare unitate de nvare din acest modul, am construit cteva competene din perspectiva competenelor generale vizate de domeniul de studiu. Formarea lor este urmrit sistematic, pe parcursul fiecrei uniti de nvare, iar pentru a determina gradul de formare a competenelor specifice, la sfritul fiecrei uniti de nvare sunt prevzute lucrri de evaluare. Coninuturile sunt informaiile de diverse tipuri, transmise prin intermediul textului tiprit, al bibliografiei recomandate, al altor forme de transmitere precum Internet-ul, casete audiu sau video, CD-uri. Coninuturile acestui modul au fost alese astfel nct s rspund competenelor specifice anterior formulate.
Construirea coninuturilor
Introducere
Tem de reflecie Identificai cu ajutorul cuprinsului unitile de nvare ale modulului, apoi citii titlurile i obiectivele fiecrei uniti. Cursurile destinate Proiectului pentru nvmntul Rural au forme grafice asemntoare. Astfel, pe fiecare pagin, n partea dreapt a fost prevzut un spaiu alb care are un rol dublu, i anume:
vi
Introducere
Exist sarcini de lucru care necesit un rspuns. Pentru acestea am lsat un spaiu n care putei scrie. Dac acest spaiu este prea mic n comparaie cu necesitile, atunci rspunsurile se pot da pe foi de hrtie, care pot fi ataate ulterior cursului. Este util s rspunzi cu consecven la ntrebrile formulate, imediat dup ce ai parcurs coninuturile tematice. n acest fel, i este mult mai uor s sintetizai materia parcurs i s te pregtiti pentru a rspunde la sarcinile de lucru, la lucrrile de verificare notate de tutore, precum i la evaluarea final. Dac avei neclariti n legtur cu sarcinile de lucru propuse, poi folosi sugestiile de rezolvare ale acestora, care se afl la sfritul fiecrei uniti de nvare. Pentru a identifica mai uor rspunsurile, am numerotat sarcinile de lucru ale fiecrei uniti de nvare cu numere succesive. Atenie! Este recomandat s se pstreze legtura cu tutorele, cruia s i adresezi ntrebri, la una din ntlniri prevzute prin program. n fiecare secven a unitilor de nvare sunt formulate unul sau mai multe Sarcini de lucru. Ele sunt anunate prin simboluri i titluri specifice ca n exemplul urmtor.
Sarcin de lucru Enumer minim 3 uniti de nvare cuprinse n acest curs. Folosete spaiul liber de mai jos pentru rspuns.
Rspunsurile la aceste sarcini de lucru se gsesc la sfritul unitii de nvare respective, n seciunea Indicaii i rspunsuri i sunt asociate simbolului alturat.
vii
Introducere
Pentru modulul Programarea calculatoarelor, evaluarea are dou componente: evaluarea continu i evaluarea final. Evaluarea continu este o modalitate de apreciere a activitii cursantului, pe parcursul ntregului semestru. Evaluarea continu va fi fcut n principal pe baza Lucrrilor de verificare notate de tutore. Aceste teste se gsesc la sfritul fiecreia dintre unitile de nvare ale modulului i sunt anunate n cuprins. Prin lucrarea de verificare este evaluat gradul de ndeplinire a competenelor specifice fiecrei unitii de nvare. Pentru fiecare item de evaluare, sunt precizate modul n care trebuie formulat rspunsul i baremul de notare. Lucrrile de evaluare, rezolvate individual, vor fi transmise tutorelui n modul i la datele anunate la nceputul semestrului.
Atenie! Notele obinute prin transformarea punctajelor n note de la 1 la 10, n urma corectrii acestor lucrri de verificare, reprezint o parte important a evalurii continue.
Tem de reflecie Identificai cel puin trei lucrri de verificare - notate de tutore, pe care va trebui s le rezolvai. Folosii spaiul liber de mai jos, pentru a nota paginile la care se gsesc aceste lucrri.
O alt parte a evalurii continue provine din aprecierea activitii de-a lungul semestrului i din timpul ntlnirilor cu tutorele. Pentru aceasta, vor conta: respectarea calendarului de lucru, calitatea ntrebrilor formulate, modul n care colaborai cu tutorele, alte aspecte, dup caz. Pentru acest curs, forma de evaluare final este examenul. Evaluarea final i evaluarea continu contribuie fiecare la stabilirea notei pentru acest modul. n fixarea notei finale, evaluarea continu are ponderea de 60% din not, iar evaluarea final are ponderea de 40%. Nota minim pentru promovarea acestui modul este 5. viii
Proiectul pentru nvmntul Rural
Introducere
Evaluarea pe parcurs apreciaz activitatea desfurat de cursani n cadrul laboratorului (rezolvare de probleme) i modul de rezolvare a temelor de cas, repartizate uniform pe durata semestrului. Fiecare dintre aceste doua subcomponente are pondere de 30% n cadrul notei finale. Evaluarea final se realizeaz sub form de examen scris. Criteriile de evaluare utilizate sunt: corectitudinea i claritatea elaborrii algoritmului, folosirea corect i eficient a elementelor limbajului de programare, utilizarea unui stil adecvat de implementare, corectitudinea funcionrii aplicaiei, diversitatea i completitudinea metodelor de testare a funcionrii aplicaiei folosite.
Atenie! Pstreaz legtura cu tutorele pentru a obine alte indicaii sau precizri. Mult succes!
ix
Cuprins
Obiectivele Unitii de nvare 1 1.1 Noiunea de algoritm 1.2 Propietile algoritmilor 1.3 Programe i limbaje de programare 1.3.1 Evoluia limbajelor de programare 1.3.2 Etapele realizrii programelor Rspunsurile corecte la testele de autoevaluare Bibliografie Lucrarea de verificare Nr. 1, notat de tutore
Pagina
1 1 4 8 9 16 20 20 21
1.1
Noiunea de algoritm
Algoritmul este o noiune matematic foarte veche. Cuvntul algoritm este de origine arab. El deriv din numele matematicianului Abu Jafar Mohammed bn Ms al Horezmi care a scris o carte celebr intitulat Kitab al jabr wal - muquabala. Din titlul acestei cri provine cuvntul algebr. Termenul algorism era folosit n evul mediu cu nelesul de proces al efecturii operaiilor aritmetice cu ajutorul cifrelor arabe. Se presupune c din asocierea cuvntului algorism cu domeniul lui de referin, aritmetica, a rezultat termenul algoritm. ncepnd cu anul 1950, n toate manualele de specialitate, cuvntul algoritm era frecvent asociat cu procesul de aflare a celui mai mare divizor comun a dou numere naturale, aa
numitul algoritmul lui Euclid. De asemenea, regulile operaiilor aritmetice sunt denumite algoritmi de efectuare a operaiilor respective. Noiunea de algoritm nu are o definiie matematic. n aceeai situaie se afl i alte noiuni din matematic, cum ar fi noiunea de mulime. Prin algoritm se accept s se neleag un sistem de calcule, care, pentru o anumit clas de probleme, din condiiile iniiale ale problemei permite s se obin soluia problemei respective, cu ajutorul unui ir finit i ordonat de operaii univoc determinate, efectuate mecanic, fr aportul creator al omului. Un algoritm este compus din unul sau mai muli pai, un pas reprezentnd efectuarea unei singure operaii din irul celor care alctuiesc algoritmul.
Tabelul 1.2 Algoritmul se ncheie n momentul obinerii restului zero: rezultatul n acest caz este 6.
1.
naturale, mai puin zero (N* x N*). Aceast propietate este cunoscut i sub numele de universalitate. 3. Eficacitatea. Executarea unui algoritm urmrete ntotdeauna obinerea unui anumit rezultat. Pentru aceasta nu este suficient ca aciunile algoritmului s fie bine determinate, ci trebuie ca pentru orice sistem de date iniiale, numrul de aciuni (pai)ce trebuie executate s fie finit. De aceea, aceast propietate poart denumirea i de finitudine. La exemplele de algoritmi prezentate anterior s-a artat c numrul de pai corespunztori unui sistem oarecare de date iniiale este finit. Se poate spune, n concluzie, c un algoritm reprezint o secven finit de operaii, ordonat i complet definit, care, pornind de la o anumit valoare sau o mulime de valori ca date de intrare, produce o anumit valoare sau mulime de valori ca date de ieire.
Exemplul 1.2
S considerm o problem banal, din coala primar: Un dreptunghi are baza de 2,75 i nlimea de 1,4 uniti. Care sunt aria i perimetrul dreptunghiului? Enunul de mai sus furnizeaz persoanei care rezolv problema urmtoarele informaii: o o o o se are n vedere un dreptunghi; baza dreptunghiului este de 2,75 uniti; inlimea dreptunghiului este de 1,4 uniti; se cer aria i perimetrul dreptunghiului.
Definirea noiunilor de algoritm, program i limbaj de programare Vom considera c sistemul care rezolv problema primete pe un anumit "suport de intrare" (de exemplu pe o hrtie, n cazul omului, sau de la tastatur, n cazul calculatorului) dou numere reale, despre care noi tim c sunt baza i nlimea unui dreptunghi, dar el nu tie. Numim aceste numere date de intrare, deoarece ele sunt introduse de noi n sistem. Vom considera, de asemenea, c rezultatele obinute vor trebui scrise de sistem pe un alt suport, care poate fi citit de ctre om (de exemplu pe o hrtie sau pe un ecran), i le vom numi date de ieire, deoarece ele sunt transmise de sistem ctre exteriorul su. Pentru a "rezolva problema", sistemul trebuie s preia datele de intrare (fr s cunoasc semnificaia lor n problem), s verifice dac sunt valabile i s le nregistreze n memorie. Asupra lor trebuie s aplice apoi nite operaii de calcul, pe baza crora s obin rezultatele cerute. Aceste rezultate vor fi i ele nregistrate n memorie, atunci cnd sunt obinute. n fine, rezultatele trebuie transmise n exterior sub forma de date de ieire. Iat succesiunea de instruciuni care trebuie executate de ctre sistem pentru a rezolva problema dat: 1. Citete de pe suportul de intrare un numr real i nregistreaz-l n memorie ca valoare a variabilei b. 2. Citete de pe suportul de intrare un numr real i nregistreaz-l n memorie ca valoare a variabilei i. 3. Dac valoarea b este nul sau negativ sau dac valoarea i este nul sau negativ - atunci scrie pe suportul de ieire textul "datele de intrare sunt greite" si oprete executarea programului; - altfel treci la pasul urmtor. 4. nmulete valoarea b cu valoarea i i nregistreaz n memorie ca valoare a variabilei A. 5. Adun valoarea b cu valoarea i i nregistreaz rezultatul ca valoare a variabilei d. 6. nmulete valoarea d cu 2 i nregistreaz rezultatul ca valoare a variabilei p. 7. Scrie pe suportul de ieire textul "aria dreptunghiului este" urmat de valoarea variabilei A. 8. Scrie pe suportul de iesire textul "perimetrul dreptunghiului este " urmat de valoarea variabilei p. 9. Oprete executarea programului. Se observ imediat c, pentru a executa aceste instruciuni, sistemul nu trebuie s cunoasc problema, ci doar s "tie" modul n care se realizeaz fiecare operaie cuprins n ele: citire de pe suportul de intrare, scriere pe suportul de ieire, comparaie, memorare (nregistrare n memorie), nmulire, adunare, oprirea execuiei. Remarcm, de asemenea, c n aceste instructiuni se opereaz cu nite numere sau texte care nu au pentru sistem nici o alt semnificaie. Astfel de "materiale supuse prelucrarii" care nu au pentru sistem nici o alt semnificaie se numesc date, iar ansamblul tuturor instruciunilor (comenzilor) care trebuie executate astfel nct, pornind de la datele de intrare, s se obin datele de ieire, se numeste algoritm. Dac algoritmul se execut de ctre un calculator, fiecare dat (de intrare, de ieire sau rezultat intermediar) este nregistrat n memoria intern a acestuia la o anumit adres care este un numr. n consecin, instruciunea 1, de exemplu, ar fi trebuit scris astfel: Citete de pe suportul de intrare un numr real i nregistreaz-l n memorie la adresa 1724. La fel ar fi trebuit s procedm i cu celelalte date, fie ele de intrare, de ieire sau auxiliare. Evident c, pentru om, o astfel de notaie este foarte incomod. Din aceast cauz, n algoritmi i n programe se prefer s se foloseasc pentru indicarea locului n care se gsesc datele n memorie nite nume simbolice, numite variabile. Conversia acestor nume de variabile n adrese de memorie este una din sarcinile care revin compilatorului, atunci cnd genereaz programul binar. Este deci bine s reinem c, din punctul de vedere al compilatorului, variabilele sunt nume date adreselor de memorie la care sunt plasate anumite date.
Se obinuiete, de asemenea, ca instruciunile cuprinse n algoritm s fie scrise ntr-o form mai compact, reinnd numai cuvintele cheie i numele variabilelor i eliminnd cuvintele de prisos. Se obinuiete, de asemenea, ca operaiile aritmetice s fie scrise sub form de formule matematice i nu prin cuvinte. Procednd astfel, algoritmul de mai sus poate fi scris sub forma: 1. Citete b; 2. Citete i; 6
Proiectul pentru nvmntul Rural
3. Dac b<=0 atunci Scrie "datele de intrare sunt greite"; Stop; 4. Calculeaz A= b*i; 5. Calculeaz d=b+i; 6. Calculeaz p=d*2; 7. Scrie "aria dreptunghiului este " A; 8. Scrie "perimetrul dreptunghiului este " p; 9. Stop. Este evident c citirea se face de pe suportul de intrare i c datele citite se nregistreaz n memorie. Prin simbolul '<=' s-a notat operaia de comparaie "mai mic sau egal". Prin simbolul '=' s-a notat operaia de atribuire, prin care variabilei din partea stnga i se atribuie (i se d) valoarea din partea dreapta, iar prin simbolul '*' s-a notat operaia de nmulire. O observaie important este c algoritmul prezentat aici poate fi folosit oricnd este necesar s se calculeze aria i perimetrul unui dreptunghi, avnd ca date de intrare baza dreptunghiului i nlimea acestuia. Setul de date de intrare este constituit, n acest caz, din dou numere reale pozitive. Caracterul universal al algoritmului const n faptul c el poate fi aplicat oricrui astfel de set de date.
1.3
Avantajele utilizrii limbajelor de nivel nalt constau n: naturalee apropierea lor de limbajele naturale i/sau limbajul matematic; uurina de nelegere i utilizare; portabilitate posibilitatea ca acelai program s fie executat cu modificri minime pe calculatoare de tipuri diferite; eficiena n scriere, datorit facilitilor de definire de noi tipuri i structuri de date, operaii, etc.
Limbaje procedurale neprocedurale Cele dou tipuri de limbaje, procedurale i neprocedurale, se difereniaz prin nivelul de organizare (structurare) a unui program. Limbajele neprocedurale sunt concepute pentru a gndi un program la nivel de instruciune, pe cnd cele procedurale, oblig programatorul s conceap programe la nivel de bloc. ntr-un limbaj procedural (numit i limbaj structurat), programele sunt scrise instruciune cu instruciune, dar ele sunt organizate logic n blocuri (grupuri de instruciuni) ce realizeaz o aciune bine determinat. n general, un bloc are un punct de intrare i un punct de ieire nu mai multe. Un limbaj procedural ofer posibilitatea utilizrii unui nivel ridicat de concepere a unui program i duce la realizarea de programe coerente i protejate la erori. Prin contrast, limbajele neprocedurale nu favorizeaz programatorul n a se desprinde de nivelul instruciune i duc deseori la programe greu de controlat mai ales n cazul programelor de dimensiuni mari. Limbajele neprocedurale sunt nc preferate de unii utilizatori datorit timpului foarte scurt ct decurge nvarea i utlizarea lor. Limbaje orientate Din punctul de vedere al aplicabilitii unui limbaj, limbajele pot fi orientate pe o anumit problem sau concepute pentru soluionarea oricrui tip de problem limbaje de uz general sau altfel spus, neorientate pe o problem. Limbajele orientate prezint un grad nalt de specificitate, pe cnd un limbaj neorientat reprezint un cadru general ce permite introducerea de ctre utilizator a conceptelor i prelucrrilor dorite. Deci, diferena esenial dintre cele dou tipuri de limbaje o constitue nivelul conceptual definit. Cele specializate posed deja integral suportul necesar i permit programatorului s se concentreze la ansamblul problemei, pe cnd cele nespecializate las n sarcina programatorului manevrarea nivelelor inferioare ale problemei. Limbaje concurente Un limbaj concurent permite definirea de procese (prelucrri) paralele, execuia sa fiind ramificat la un anumit moment de timp. Prin contrast, limbajele neconcurente (majoritatea limbajelor) au o desfurare liniar, fiind activ un singur proces la un moment dat. Procesele concurente presupun n mod obligatoriu un sistem multi-tasking ce poate gestiona mai multe sarcini la un moment dat. Limbaje de nivel sczut. Aceast categorie de limbaje are un reprezentant autoritar, i anume: limbajul de asamblare. Diferenierile care se pot face pentru limbajele de nivel sczut sunt urmtoarele: a) dup tipul de main; Regulile respectate de versiunile limbajului de asamblare sunt: - o nou versiune o include complet pe cea anterioar, - versiunea nou ofer funcii suplimentare i le realizeaz pe cele vechi mai rapid. b) dup mediul de programare oferit. Aspectul unui limbaj poate fi schimbat radical de mediul de programare oferit. Pentru limbajul de asamblare exist mai multe implementri disponibile, ncepnd cu pachete ce opereaz n mod linie i culminnd cu medii integrate n care toate operaiile se pot declana de la un acelai pupitru de comand. Nu sunt luate n considerare dect aceste medii integrate (denumite generic medii Turbo), dintre care se detaeaz Turbo Asamblorul firmei Borland TASM.
10
Limbaje de nivel nalt neorientate. BASIC A fost creat n 1964 la Darmooth College (S.U.A.). Denumirea sa provine de la iniialele cuvintelor Beginners Allpurpose Symbolic Instruction Code (Cod de instruciuni simbolice, de uz general, destinat nceptorilor). Are urmtoarele caracteristici fundamentale: simplu de nvat; instruciunile sale sunt cuvinte din limba englez sau prescurtri ale acestora; neorientat pe un anumit tip de problem; permite construirea de aplicaii; este un limbaj nestructurat, ceea ce i permite s fie uor nvat. Deoarece a cunoscut o larg rspndire, au fost implementate noi versiuni de Basic: GW-BASIC, QUICK BASIC, TURBO BASIC, VISUAL BASIC (Basic for Windows). FORTRAN Limbajul Fortran este decanul de vrst al limbajelor de larg folosin. A aprut n 1956 i i datoreaz numele prescurtrii cuvintelor: FORmula TRANslation (Traducere de formule). Iniial reprezenta un limbaj orientat pe calcule tiinifice, avnd definite concepte precum: matrice, funcii trigonometrice, numere reale n dubl precizie. Versiunile ulterioare care au cunoscut o mare popularitate au extins posibilitile limbajului trasformndu-l ntr-un limbaj eficient, de uz general.n prezent exist pentru IBM-PC dou implementri mai importante ale limbajului: Microsoft Fortran, Fortran for Windows. Dei nu poate fi considerat depit din punct de vedere conceptual (este un limbaj algoritmic structurat) este neindicat folosirea lui datorit absenei unor medii de programare performante i pentru c tendina actual i este defavorabil. PASCAL Conceptualizat n anul 1970 de ctre Niklaus Wirth, limbajul PASCAL poart numele matematicianului i filosofului BLAISE PASCAL, n semn de recunoatere a meritelor sale n teoretizarea mainilor de calcul. Creat dup acumularea de cunotiine temeinice n tiina limbajelor formale, din confruntarea cu probleme concrete ale programrii, limbajul PASCAL a constituit la vremea respectiv un limbaj modern, meninndu-se ca atare i n prezent, datorit faptului c posed o solid baz conceptual. Limbajul PASCAL a introdus n versiunea sa iniial noiunea de programare structurat i ulterior noiunile de date (structuri) dinamice, date (structuri) definite de utilizator. n prezent standardul implementrilor PASCAL cuprinde urmtoarele elemente: programare structurat de tip algoritmic; definirea de noi funcii sau proceduri; tipuri de date definibile de ctre utilizator; structuri de date dinamice; adresri indirecte ale datelor; recursivitate; rutine complete de intrare / ieire; funcii de conversie a datelor din ASCII n format intern i invers; set complet de funcii matematice; funcii elementare de grafic 2D; posibilitatea inserrii direct n surs a instruciunilor n limbaj de asamblare; posibilitatea definirii de overlay-uri pentru program. Versiunile standard ale implementrilor PASCAL sunt cele oferite de Microsoft i Borland, cu avantaj pentru cele din urm (BORLAND PASCAL 7.0).
11
Limbajul C Acest limbaj de programare, cu cel mai scurt nume, a fost creat n 1971 de ctre Dennis Ritchie i Brian Kernigham pentru dezvoltarea sistemului de operare UNIX. Principalele caracteristici ale limbajului sunt: limbaj structurat de nivel nalt; posed concepte de nivel sczut, ceea ce permite exploatarea portabil a caracteristicilor intime unei maini; rutine de conversie a datelor foarte evoluate; tipuri de date definibile de ctre utilizator; gestionarea elaborat a datelor de tip dinamic; definirea de noi funcii; adresri indirecte ale datelor, variabilelor (pointeri); recursivitate; set complet de funcii matematice; funcii pentru realizarea de grafic elementar 2D; funcii de apel servicii DOS; posibilitatea definirii de overlay-uri pentru un program; concizie deosebit a limbajului. Pentru versiunile standard ale implementrilor limbajului C exist medii de programare ce aparin firmelor: Microsoft produsul QUICK C i firmei Borland produsele BORLAND C.
Limbajul ADA A fost creat special pentru a gestiona totalitatea aplicaiilor dezvoltate i utilizate de N.A.S.A. Noutatea limbajului (de tip structurat, algoritmic) o constitue concurena, deci posibilitatea lansrii de procese paralele (sincronizate interactiv n finalul execuiei lor) . Saltul calitativ este evident i deschide un nou domeniu n programare, dar nu pentru IBM-PC. Versiunile implementrilor limbajului ADA pe IBM-PC nu posed tocmai acest parte de concuren, reducnd limbajul la un simplu limbaj structurat de uz general. Deci, ADA este un limbaj ultramodern din punct de vedere teoretic, dar ineficient din punct de vedere practic pentru IBM-PC-uri. Limbaje orientate pe gestiunea bazelor de date Necesitile actuale n practica utilizrii calculatoarelor se ndreapt cu precdere spre gestionarea bazelor de date de mari dimensiuni. O explicaie a acestei orientri e dat de faptul c o baz de date reprezint o informaie, iar cel ce deine informaii complete i rapide ntr-o anumit problem este indiscutabil cu un pas naintea celorlali. Concurena din domeniul economic poate fi numit pe bun dreptate o btlie informaional. ntr-un sistem de gestionare a bazelor de date (S.G.B.D.) de tip clasic datele sunt gestionate prin intermediul unei structuri, organizat ierarhic, la un nivel de organizare logic. Tendina modern n exploatarea bazelor de date const n deplasarea interesului ctre bazele de date relaionale. Diferena esenial const n definirea unui nivel logic suplimentar ntre datele gestionate. Acestea nu mai sunt privite ca simple fie izolate ntre ele ci pot fi analizate pe baza legturilor (relaiilor) ce exist ntre ele. Spre deosebire de S.G.B.D. urile clasice, un mediu relaional presupune ca cerin minimal posibilitatea manipulrii datelor prin intermediul conexiunilor logice stabilite. Pentru aceasta exist
12
definit (i impus ca standard unanim recunoscut) limbajul de interogare SQL (Structured Query Language limbaj de cereri structurate). S.G.B.D. uri clasice. dBASE III Cel mai rspndit sistem de gestiune a bazelor de date este dBASE, n diversele lui versiuni. El poate fi considerat un BASIC al bazelor de date. La momentul apariiei a constituit o adevrat revoluie n domeniul S.G.B.D.-urilor. Cele mai importante implementri ale sale sunt: dBASE III Plus i dBASE IV. COBOL A fost creat n 1950 i reprezenta singura posibilitate de gestionare a unei baze de date. Reprezint n primul rnd un limbaj de programare special conceput pentru informatica de gestiune. Dac facem o comparaie, sugestiv, COBOL este echivalentul FORTRAN-ului pentru sistemele de gestiune a bazelor de date (din punct de vedere istoric i al performanelor). Limbajul este considerat greoi i inflexibil, iar pentru crearea unui program foarte simplu e nevoie de scrierea unui adevrat eseu. Singurul avantaj real al COBOL-ului este portabilitatea sa ridicat. FOXBASE Sistemul dBASE a incintat firmele productoare de soft, datorit popularitii sale i pe de alt parte a calitilor sczute ale implementrilor originale furnizate de firma Ashton-Tate. Au aprut noi implementri ale limbajului care au ncercat s furnizeze unelte profesionale pe baza acestui suport conceptual. Versiunile FOXBASE 2.10 i FOXBASE PRO se constitue n medii performante att pentru programatori ct i pentru utilizatori. S.G.B.D. uri relaionale ORACLE Se poate afirma fr teama de a grei c ORACLE reprezint cel mai performant S.G.B.D. disponibil la momentul actual. Pe lng faptul c posed avantajele unui mediu de tip relaional, ORACLE este gndit ca un sistem exhaustiv pentru rezolvarea problemelor de utilizare sau programare. Limbajul intern folosit este SQL Plus i este permis conectarea cu alte limbaje externe evoluate (orientate ctre C) . Putem meniona: vitez de lucru foarte bun; exploatare interactiv la nivel SQL; limitri de lucru greu sau imposibil de atins (maxim 65535 caractere ntr-un cmp, numr nelimitat de cmpuri, de nregistrri) ; exploatare eficient a spaiului pe disc (memorarea cmpurilor n format variabil) . Oracle este implementat pe majoritatea tipurilor de computere mari, ceea ce ofer portabilitatea aplicaiilor, dar mai ales posibilitatea conectrii la calculatoare puternice. PARADOX Reprezint un S.G.B.D. cu adevrat profesional. El ndeplinete toate cerinele unui produs cu adevrat modern i performant i anume: interactivitate foarte bun; vitez de lucru mare; servicii i auxiliare; limbaj de programare evoluat (PAL Paradox Application Language) , dotat cu compilator.
13
Alte limbaje orientate Limbaje orientate pe calcul matematic simbolic Specialitii din domeniul cercetrii matematice au la dispoziie unelte de lucru extrem de utile pentru eliminarea calculului matematic rutinier. n acest scop au fost create limbaje de programare care pot recunoate i rezolva formule sau ecuaii matematice complexe. Expresiile manevrate pot conine operaii algebrice elementare, operatori de derivare, de integrare, operatori difereniali care sunt recunoscui de sistem ca atare. n plus sunt oferite instruciuni absolut necesare pentru a controla un program. Cele mai importante produse de acest gen sunt REDUCE, SYMNON, MATHCAD, MATHEMATICA, MATHLAB. Limbaje orientate pe programarea inteligenei artificiale Acest tip de limbaje difer esenial de cele algoritmice. Modalitatea de programare este descriptiv i are intenia declarat de simulare a raionamentului uman. Pentru rezolvarea unei probleme sunt furnizate seturile de reguli i informaii necesare, iar apoi se descrie n ce const problema ca atare. Limbajul este capabil s opereze deduciile (deciziile) necesare pentru a rezolva problema ntr-un caz particular ce apare n practic. Aadar, aceste limbaje descriu problema de rezolvat (n termenii deduciilor logice) pe cnd limbajele de tip algoritmic descriu metoda de rezolvare a problemei. Domeniile de aplicabilitate pentru limbajele de programare a inteligenei artificiale sunt cu predilecie: realizarea de sisteme expert (programe ce nlocuiesc experii umani), computerizarea procesului de producie, robotic, tratarea limbajelor naturale. Cele mai importante limbaje de acest tip sunt: PROLOG (PROgramming in LOGic) creat n 1973 i implementat pe PC-uri abia n 1986 de firma Borland sub forma Turbo-Prolog. LISP (LISt Processing language) conceput n 1976 i implementat pe PC-uri de firma Microsoft sub forma MuLISP.
14
15
n prima etap are loc analiza problemei. Rolul analizei const n elaborarea unui enun complet i precis al problemei, cae s in seama de condiiile concrete de realizare i execuie a programului. Enunul trebuie s evidenieze ceea ce urmeaz s realizeze programul, adic funciile programului. n acest scop este necesar s se identifice informaiile de prelucrat (datele de intrare) i rezultatele cerute (datele de ieire) ale programului. Pentru referirea la datele de intrare i de ieire se folosesc variabile de intrare i respectiv de ieire. Ele furnizeaz notaii simbolice pentru date. Tot n aceast etap se stabilesc reprezentrile i organizarea datelor de intrare i de ieire pe suporturile externe de informaie. Acestea pot fi impuse prin enunul iniial al problemeisau pot fi definite de ctre utilizator. Rezultatul primei etape este specificaia programului. Exemplul 1.3 Pentru exemplificarea acestei etape, se consider urmtoarea problem: Fiind dai coeficienii unei ecuaii de gradul doi, a, b i c, de tip real, s se calculeze (dac exist!) rdcinile reale ale acesteia. n caz contrar, s se dea un mesaj corespunztor. 1) mrimi de intrare: a, b, c; mrimi de ieire: x1, x2; 2) funcia: calculeaz rdcinile reale ale ecuaiei: a*x2 + b*x + c = 0 dac exist sau afieaz mesajul Ecuaia nu are rdcini reale sau Nu este o ecuaie de gradul doi, n cazul cnd a = 0; 3) organizarea i reprezentarea datelor de intrare i ieire pe suportul extern: datele se introduc de la tastatur i rezultatele se afieaz pe display (monitor). II Determinarea algoritmului de rezolvare a problemei
Scopul acestei etape este elaborarea unui algoritm care s realizeze funciile programului. Programatorul trebuie s conceap o list de comenzi care s descrie secvena de operaii care va fi executat de calculator pentru soluionarea problemei. Un calculator devine funcional dac este programat, adic i se spune n cele mai mici amnunte ce s fac. Acest lucru se realizeaz prin program.n sens general, un program 16
Proiectul pentru nvmntul Rural
reprezint descrierea unui algoritm ntr-o form interpretabil (neleas) de ctre calculator. El rezult din codificarea algoritmului ntr-un limbaj de programare. Gsirea algoritmului constituie de cele mai multe ori cea mai grea etap a procesului programrii. Pentru obinerea algoritmului sunt necesare cunotine din matematic, discipline tiinifice i tehnice. Studiul algoritmilor constituie un domeniu clar delimitat n aria larg a tiinei calculatoarelor. n general, dezvoltarea algoritmului se realizeaz iteativ, trecndu-l prin mai multe niveluri de detaliere. Acest mod de detaliere pas cu pas este denumit proiectarea descendent, sugernd faptul c se trece treptat de la o reprezenteare general, abstract, a rezolvrii problemei la o prezentare detaliat a sa. Problemele simple conduc la un singur algoritm compact, codificat ntr-o singur unitate e program. n exemplul prezentat anterior, algoritmul poate fi explicat foarte simplu: Dac a = 0, atunci afieaz mesajul Nu este o ecuaie de gradul doi altfel dac = b2 4*a*c >=0, atunci calculeaz b+ b x1 = i x 2 = , apoi afieaz valorile lor, 2a 2a altfel afieaz mesajul Ecuaia nu are rdcini reale Problemele complexe i de dimensiuni mari sunt descompuse din punct de vedere logic n subprobleme (pri) mai simple, corelate, care pot fi tratate separat, devenind ele nsele probleme de rezolvat. Programul rezultat din codificarea unui astfel de algoritm va fi organizat ca un sistem de module program. Prin modularizare se simplific nu numai procesul de dezvoltare i verificare a algoritmului, ci i procesul de codificare, depanare i testare a programelor. Totodat, modularizarea uureaz modificarea programului i descgide posibilitatea refolosirii unitilor de program componente. III Codificarea algoritmului
Dup elaborare, algoritmul este codificat cu ajutorul unui limbaj de programare, obinndu-se astfel programul care l implementeaz. Limbajul utilizat este ales n conformitate cu specificul problemei, cu particularitile sistemului de calcul pe care urmeaz s fie executat programul i, desigur, cu experiena programatorului. Codificarea algoritmului este nlesnit de utilizarea unor simboluri i reguli speciale, precum schemele logice (organigrame) sau limbajul pseudocod. IV Testarea i validarea programului
Programul astfel obinut trebuie verificat n scopul eliminrii erorilor de sintax i al celor de logic. Chiar dac n urma execuiei programului se obin rezultate, adic s-au eliminat erorile de sintax, aceasta nu nseamn c acesta este corect, adic realizeaz fiunciile specificate. Programul poate conine erori de logic, pentru eliminarea crora trebuie
Proiectul pentru nvmntul Rural
17
executat de mai multe ori, folosindu-se seturi de date stabilite pe baza unor criterii considerate ca fiind adecvate problemei. Sintaxa si semantica limbajelor de programare Fiecare limbaj de programare, ca orice alt limbaj, se caracterizeaz prin anumite reguli de scriere corect, numite reguli de sintax. Orice instruciune a limbajului are o form i o semnificaie. Sintaxa se refer numai la forma instruciunii, n timp ce semnificaia este de domeniul semanticii. Semantica se refer la modul n care trebuie interpretat instruciunea respectiv. Este evident c, atunci cnd se concepe un program, este necesar s se acorde atenie att sintacticii, ct i semanticii. Dac ntr-un program nu sunt respectare regulile de sintax, compilatorul sesizeaz anomaliile i le semnaleaz sub forma unor mesaje de erori de sintax. n astfel de situaii, codul de octei al programului respectiv nu va mai fi generat. Programatorul trebuie s remedieze erorile de sintax semnalate i s cear repetarea compilrii. Acest procedeu se repet, pn cnd nu vor mai fi constatate erori de sintax. Faptul c un program nu mai conine erori de sintax, deci este corect sintactic, nu nseamn ns c el este corect i sub aspectul realizrii sarcinii pentru care a fost conceput. Aa cum un text scris ntr-o limb natural (n limba romn, de exemplu) poate fi corect gramatical, dar s exprime concepii greite, un program poate fi corect sintactic, dar s descrie un set de date i/sau un algoritm care nu corespund problemei rezolvate i deci nu permit obinerea soluiei corecte. Aceast situaie nu mai poate fi sesizat de compilator, ci este n ntregime pe rspunderea programatorului.
Activitatea de dezvoltare a unui program nu se ncheie n momentul validrii programului. Din acel moment ncepe etapa de ntreinere, care, spre deosebire de celelate etape, este nelimitat. n aceast etap sunt efectuate modificri ale programului, fie n scopul corectrii unor erori identificate n cursul utilizrii sale, fie pentru a-l adapta unor cerine noi. n aceast etap are o mare importan documentaia programului; aceasta faciliteaz att modificrile ulterioare, ct i nelegerea sa de ctre alte persoane dect cele care l-au creat.
18
2. Dac ntr-un program nu sunt respectate . .compilatorul descoper anomaliile, indicndu-le sub forma unor ...
3. n cadrul etapei de ............... sunt efectuate modificri ale programului, fie n scopul corectrii unor erori identificate n cursul utilizrii sale, fie pentru implementarea unor cerine noi.
5. Trecerea treptat de la o reprezenteare general, abstract, a rezolvrii problemei la o prezentare detaliat a sa poart denumirea de .
19
Vezi U1.2 Propietile algoritmilor pag. 12 Vezi U1.2 Propietile algoritmilor pag. 12 Vezi U1.2 Propietile algoritmilor pag. 12 Vezi U1.2 Propietile algoritmilor pag. 12 Vezi U1.2 Propietile algoritmilor pag. 12
BIBLIOGRAFIE
1. Dorin Stoilescu, Manual de C/C++ - Cap.1 Introducere, Editura Radial, Galati, 1998. 2. Florin. Munteanu, Traian C. Ionescu, Daniela Saru, Gheorghe Musca, Sergiu Mihai Dascalu, Programarea calculatoarelor - manual pentru liceele de informatic Cap.2 Programe. Algoritmi. Elemente de programare structurat, Editura Didactic i Pedagogic, Bucureti, 1995. 3. Valeriu Iorga si colectiv, Programare in C/C++. Culegere de probleme, Editura Niculescu, Bucureti, 2003. 4. Programe de specialitate elaborate de ctre Ministerul Educaiei i Cercetrii pentru nvmntul preuniversitar 20
Proiectul pentru nvmntul Rural
2. Descriei sub forma unui algoritm descompunerea unui numr n factori primi.
3. Explicai de ce sunt necesare limbajele orientate pe gestiunea bazelor de date, dnd cteva exemple.
4. Enumerai avantajele utilizrii limbajelor de nivel nalt i dai cteva exemple de astfel de limbaje de programare:
21
Obiectivele Unitii de nvare 2 ....................................................................................22 2.1 Reprezentarea algoritmilor........................................................................................22 2.2 Elemente de programare structurat .......................................................................26 2.3 Structuri de control utilizate n programarea structurat .......................................29 2.3.1 Secvena sau structura liniar ......................................................................29 2.3.2 Decizia sau structura alternativ ..................................................................32 2.3.3 Ciclul sau structura repetitiv .......................................................................36 Rspunsuri corecte la testele de autoevaluare .............................................................42 Bibliografie .......................................................................................................................42 Lucrarea de verificare Nr. 2, notat de tutore................................................................43
Identificai cele trei structuri de baz ale programrii Reprezentai diveri algoritmi n pseudocod Explicai principiile programrii structurate n procesul de elaborare a algoritmilor Comparai diversele metode de reprezentare ale algoritmilor
2.1
Reprezentarea algoritmilor
Limbajul natural nu permite o descriere suficient de riguroas a algoritmilor, air, pe de alt pate, o dat ce complexitatea algoritmilor crete, crete i complexitatea descrierilor n limbaj natural. De aceea, pentru reprezentarea algoritmilor se folosesc diferite forme de reprezentare caracteristice, n fapt limbajele specializate. n general, notaia folosit pentru reprezentarea algoritmilor trebuie s satisfac urmtoarele cerine: 1. S permit exprimarea ct mai natural a raionamentelor umane, s fie uor de nvat i de folosit; 2. S reflecte caracteristicile limbajelor de programare de nivel nalt pentru a uura codificarea algoritmilor.
22
Formele convenionale cele mai folosite n reprezentarea algoritmilor sunt: schemele logice sau organigramele limbajele pseudocod. Principala calitate a acestora este posibilitatea de a evidenia cu claritate fluxul controlului algoritmilor, adic succesiunile posibile ale aciunilor. Astfel, schemele logice utilizeaz pentru aceasta sgei de legtur ntre diversele forme geometrice care simbolizeaz diversele tipuri de aciuni, n timp ce limbajele pseudocod folosesc cuvinte cheie, adic nite cuvinte cu neles prestabilit ce identific operaia care se execut, i cteva reguli simple de aliniere a textului scris. n continuare sunt prezentate blocurile ce pot intra n componena unei scheme logice. Blocul delimitator are forma unei elipse alungite. El se folosete pentru a marca nceputul sau sfritul schemei logice. Dac blocul este folosit la nceputul schemei logice, atunci n interiorul su se scrie cuvntul START, iar dac blocul este folosit la sfritul schemei logice, atunci n interiorul su se scrie cuvntul STOP. Figura 2.1 conine blocul delimitator folosit n cele dou situaii.
Fig. 2.1 Blocul de intrare / ieire are forma unui paralelogram. Acest bloc se folosete la introducerea datelor n calcule i afiarea rezultatelor. De obicei, datele de intrare ale unei probleme se introduc iniial, cu ajutorul tastaturii, ntr-o zon de memorie numit zon tampon. De aici ele sunt preluate de program. Aceast operaie de preluare a datelor dintr-o zon tampon se numete operaie de citire. Datele preluate din zona tampon sunt introduse n memoria intern a calculatorului. Aceast operaie se precizeaz n schemele logice prin cuvntul CITESTE. n figura 2.2. apare o comand de citire. Aceast comand cere s se citeasc valorile variabilelor a i b i s se introduc aceste valori n memoria intern.
Fig. 2.2 Operaia de preluare a valorilor unor variabile din memoria intern i afiarea lor pe ecranul calculatorului se numete operaie de scriere. De aceea, aceast operaie se precizeaz n schemele logice prin cuvntul SCRIE. n figura 2.2. apare o comand de scriere. Aceast comand cere s se scrie valoarea variabilei x pe ecranul monitorului.
23
Blocul de calcul se folosete pentru a preciza calculele care se fac. n blocurile de acest tip apar comenzi de forma: v=e unde v este o variabil, iar e este o expresie de tip compatibil cu v. La ntlnirea comenzii v=e se determin valoarea expresiei e, se convertete, dac este cazul, valoarea lui e la o valoare de tipul lui v i se atribuie aceast valoare variabilei v. Figura 2.3. conine mai multe blocuri de calcul. Aici am presupus c toate variabilele sunt de tip numeric. n primul bloc se atribuie variabilei s valoarea 2. Al doilea bloc conine expresia c+3. Aici am presupus c c are o valoare numeric rezultat dintr-o operaie anterioar. Valoarea expresiei se convertete, dac este cazul, la o valoare de tipul lui a i se atribuie lui a. n al treilea bloc apare expresia b+3. Valoarea acestei expresii se atribuie lui b. Prin urmare, dup execuia acestei comenzi, valoarea lui b se mrete cu 3. Aadar, semnul = care apare n blocurile de calcul nu trebuie confundat cu semnul = din matematic, pentru c se ajunge la ceva fr sens. n fine, n ultimul bloc se cere s se atribuie lui m valoarea 2.3. Dac m este o variabil de tip ntreg, atunci numrul 2.3 este convertit la numrul ntreg 2 i apoi este atribuit variabilei m.
Fig. 2.3 Blocul de decizie are forma unui romb. n interiorul su se scrie o condiie care determin ramificarea calculelor. Figura 1.4. conine un asemenea bloc. Condiia din blocul de decizie se citete ca o propoziie interogativ. Astfel, n cazul din figura 1.4. citim: Este y egal cu x ? Dac rspunsul la aceast ntrebare este da, atunci se iese din blocul de decizie pe ramura pe care este scris cuvntul DA. Dimpotriv, dac rspunsul la ntrebarea de mai nainte este nu, atunci se iese din blocul de decizie pe ramura pe care este scris cuvntul NU.
Fig. 2.4 Semnul = care apare n blocul de decizie are sens de comparaie. El nu se va confunda cu semnul = din blocurile de calcul. Pentru scrierea condiiilor se mai folosesc i celelalte semne de comparaie din matematic: <, , >, i . Blocul conector are form de cerc. El se folosete pentru a conecta diferite secvene ale unei scheme logice.
24
Exemplul 2.1
n finalul acestei seciuni, prezentm o schem logic care conine toate blocurile pe care le-am descris nainte. Este vorba de schema logic de rezolvare a ecuaiei a.x+b=0 cu a i b numere reale. Evident, dac a=0 i b=0, atunci ecuaia este satisfcut de orice x. Prin urmare, n acest caz ecuaia are o infinitate de soluii. Dac a = 0 i b 0, atunci apare o incompatibilitate. n fine, dac a 0, atunci ecuaia are o singur soluie: x = -b/a, pentru orice b. Schema logic de rezolvare a problemei apare n figura 2.5. Aa cum observm, blocurile schemei logice sunt conectate ntre ele prin linii prevzute cu sgei. Aceste sgei indic ordinea de parcurgere a blocurilor.
Fig. 2.5 Schema logic de rezolvare a ecuaiei a.x+b=0 conine o comand pentru citirea datelor. Aceast comand cere s se citeasc valorile variabilelor a i b. Pe baza acestei scheme putem alctui un program care s rezolve o ecuaie de forma ax+b=0 pentru orice valori ale lui a i b. n primul bloc de decizie din schema logic apare condiia a=0. Evident, condiia a=0 poate fi adevrat sau fals. Dac condiia a=0 este adevrat, atunci din blocul de decizie se iese pe ramura pe care este scris cuvntul DA, iar dac condiia a=0 nu este adevrat, atunci din blocul de decizie se iese pe ramura pe care este scris cuvntul NU. Desigur, i condiia b=0 care apare n cellalt bloc de decizie al schemei logice determin ramificarea calculelor ntr-un fel sau altul. n fine, s mai observm c n blocul de calcul apare scris x = -b/a. Evident, x = -b/a nu este o condiie. Acum se cere s se determine valoarea lui -b/a i s se atribuie valoarea calculat lui x. Schema logic pe care o analizm conine trei drumuri care pornesc de la START i se ncheie la STOP. De aceea, pentru verificarea schemei trebuie s considerm trei seturi de date care ne conduc pe drumurile respective.
25
Facem nti verificarea schemei pentru a=2 i b=-8. Prin urmare, dorim s rezolvm ecuaia 2x-8=0. Pe schema logic parcurgem paii urmtori: START CITESTE a, b a=0 ? x=-b/a SCRIE x STOP a=2, b=-8 2=0 ? NU x=4 x=4
Considerm acum cazul n care a=0 i b=-6. Aadar, este vorba de ecuaia 0x - 6=0. Acum avem o incompatibilitate. Pe schema logic parcurgem paii urmtori: START CITESTE a, b a=0, b=-6 a=0 ? 0=0 ? DA b=0 ? -6=0 ? NU SCRIE "INCOMPATIBILITATE" STOP
INCOMPATIBILITATE
n fine, considerm cazul n care a=0 i b=0. Aadar, este vorba de ecuaia 0x+0=0. Este vorba de o nedeterminare. Pe schema logic parcurgem paii urmtori: START CITESTE a, b a=0, b=0 a=0 ? 0=0 ? DA b=0 ? 0=0 ? DA SCRIE "NEDETERMINARE" NEDETERMINARE STOP Schema pe care am prezentat-o aici este foarte simpl. De aceea, a fost posibil s o verificm cu seturi de date corespunztoare tuturor drumurilor care duc de la START la STOP. Majoritatea problemelor reale au scheme logice complexe. n asemenea situaii numrul de drumuri care duc de la START la STOP este foarte mare. De aceea, nu se poate face o verificare exhaustiv a acestor scheme logice.
26
Un program structurat este constituit din uniti funcionale bine conturate, ierarhizate conform naturii intrinseci a problemei. Programarea structurat este o metod independent de limbajul de programare, ea acionnd la nivelul stilului de lucru. n ce const de fapt programarea structurat? Programarea structurat reprezint o maniere de concepere a programelor potrivit unor reguli bine stabilite, utiliznd un anumit set, redus, de tipuri de structuri de control. O structur de control nseamn o combinaie de operaii utilizat n scrierea algoritmilor. Scopul programrii structurate este elaborarea unor programe uor de scris, de depanat i de modificat (actualizat) n caz de necesitate. Programele obinute sunt clare, ordonate, inteligibile, fr salturi i reveniri. Programarea structurat permite ca programele s poat fi scrise n limbaj pseudocod, limbaj independent de main, apropiat de cel natural, convertibil n orice limbaj de programare. Prin programarea n mod logic i clar a structurilor de control admise, programarea structurat permite abordarea eficient a funciilor de orice grad de dificultate. Programarea structurat are la baz o justificare matematic, furnizat de Boehm i Jacopini i cunoscut ca teorema de structur care precizeaz c orice algoritm avnd o intrare i o ieire, adic un singur punct de nceput i un singur punct de terminare a execuiei poate fi reprezentat ca o combinaie de trei structuri de control: 1. Secvena sau structura liniar succesiunea de dou sau mai multe operaii; 2. Decizia sau structura alternativ alegerea unei operaii dintre dou alternative posibile; 3. Ciclul sau structura repetitiv cu test iniial repetarea unei operaii atta timp ct o anumit condiie este ndeplinit. Programarea structurat admite i utilizarea altor structuri de control, cum sunt: 4. Selecia permite o alegere ntre mai mult de dou alternative; 5. Ciclul cu test final; 6. Ciclul cu contor. Ultimele dou structuri de control reprezint variante ale structurii referit n general ca structura repetitiv.
27
de la o instruciune la alta. Ulterior, Dijkstra mpreun cu ali cercettori n domeniul informaticii au conceput o teorie coerent a programrii structurate, conform creia la conceperea unui program, este recomandabil s se respecte urmtoarele principii: 1. Teorema de structur: orice program poate fi ntocmit folosind numai trei structuri de control fundamentale: structura secvenial, structura alternativ i structura repetitiv. 2. La conceperea programelor se recomand s se aplice tehnica de elaborare descendent (n englez Top-Down), numit i tehnica rafinrilor succesive. 3. Domeniile de valabilitate (de vizibilitate) ale variabilelor i structurilor de date trebuie s fie limitate.
28
A1
A2
An
Figura 2.5
Exemplul 2.2
Se citesc dou numere ntregi a i b. S se interschimbe coninutul celor dou variabile i s se afieze noile lor valori. La prima vedere am fi tentai s scriem secvena urmtoare: intregi a,b citete a, b ab ba scrie a,b
Proiectul pentru nvmntul Rural
29
Aceast secven este greit. Atunci cnd variabilei a i se atribuie valoarea variabilei b, coninutul variabilei a se pierde. S presupunem c am citit a = 3 i b = 4. Prin atribuirea a b , coninutul lui a va fi 4, iar a lui b va fi tot 4. Prin atribuirea b a coninutul celor dou variabile va fi acelai. Din acest motiv, n urma execuiei acestui algoritm se va tipri 4 i 4. Pentru a corecta aceast greeal, trebuie folosit o variabil auxiliar, aux, de acelai tip ca a i b, care va permite interschimbarea corect a valorilor celor dou variabile. Secvena corect de atribuiri este urmtoarea: aux a ab b aux n acest mod, coninutul variabilei a se salveaz n variabila auxiliar aux, deci nu se pierde la a doua atribuire. Pentru valorile 3 i 4 presupuse ca citite pentru a i b, vom avea n ordine: lui aux I se atribuie valoarea 3; lui a i se atribuie valoarea 4; lui b i se atribuie valoarea 3; n continuare este prezentat algoritmul sub form de schem logic i pseudocod ntregi a, b, aux citete a,b aux=a a=b b=aux scrie a,b stop Aceeai problem poate fi rezolvat i fr a folosi o variabil auxiliar, dar numai n cazul interschimbrii de valori numerice, deoarece se vor folosi operaiile de adunare i scdere. ntregi a, b citete a,b a=a+b b=a-b a=a-b scrie a,b stop Pentru valorile citite ale lui a i b algoritmul funcioneaz astfel: lui a i se atribuie valoarea 3+4=7; lui b i se atribuie valoarea 7-4=3; lui a i se atribuie valoarea 7-3=4; se tiprete a=4 i b=3, rezultat corect.
START
Citete a,b
aux=a
a=b
b=aux
Scrie a,b
30
2. Perimetrul unui ptrat este egal cu latura altui ptrat. tiind c suma perimetrelor este x, s se calculeze ariile celor dou ptrate.
3. Fiind date trei numere ntregi a, b ,c, s se interschimbe valorile celor trei numere, astfel: b, c, a (a primete valoarea lui b, b pe a lui c i c ia valoarea lui a); c, a, b (a primete valoarea lui c, b pe a lui a i c ia valoarea lui b); c, b, a (se inverseaz ordinea variabilelor).
4. Se dau patru numere a, b, c, d reale. S se permute valorile acestor variabile astfel nct la tiprire ele s aib valorile rezultate din permutrile lor circulare , la stnga, respectiv la dreapta, cu o poziie: b, c, d, a d, a, b, c
5. S se calculeze aria unui triunghi, cunoscndu-se una din laturile sale i nlimea corespunztoare.
True DA
Condiie
False NU
True DA
Condiie
False NU
Figura 2.7
n limbaj natural, pentru schema logic din partea stng, execuia poate fi descris astfel: se evalueaz condiia; dac rezultatul este adevrat, se execut secvena A; n caz contrar, se execut secvena B n limbaj pseudocod, structura alternativ este descris astfel: dac condiie atunci secvena A altfel secvena B Pentru cea de-a doua schem, reprezentnd decizia cu varianta unei ci nule, una din ramurile structurii nu conine nici o instruciune. n limbaj natural, execuia poate fi descris astfel: se evalueaz condiia; dac rezultatul este adevrat, se execut secvena A; n caz contrar, se continu execuia programului. n pseudocod, execuia se descrie astfel: dac condiie atunci secvena A
Exemplul 2.3
Se citesc dou numere reale a i b. S se afieze cel mai mare dintre ele. Rezolvarea acestei probleme este foarte simpl, i anume: real a, b 32
Proiectul pentru nvmntul Rural
Exemplul 2.4
Complicm puin problema. S se afieze valoarea maxim dintre trei numere reale citite de la tastatur. O posibilitate de rezolvare a problemei, reprezentat n pseudocod, este: real a, b, c, max citete a, b, c dac a>b i a>c atunci max=a altfel dac b>c atunci max=b altfel max=c scrie max stop Se observ folosirea a dou structuri alternative pentru rezolvarea problemei, a doua dintre ele fiind inclus ntr-una din ramurile de decizie ale structurii, i anume pe cea corespunztoare neverificrii condiiei testate. Se folosesc trei variabile reale corespunztoare celor trei numere citite (a, b i c) i o variabil pentru pstrarea valorii maxime, tot real, max. Dac a este mai mare dect celelalte dou numere b i c, atunci valoarea maxim va fi a, altfel ea trebuie cutat ntre celelalte dou valori; dac b este mai mare dect c, atunci b este maxim, altfel maximul va fi c.
Exemplul 2.5
S se realizeze schema logic pentru evaluarea expresiei:
33
Exemplul 2.6
Un exemplu de problem la care se folosete cea de-a doua variant a schemei logice pentru structura alternativ este: S se determine valoarea absolut a numrului real x, citit de la tastatur. Rezolvare: real x citete x dac x<0 atunci x=-x scrie x
2. S se scrie algoritmul de rezolvare a urmtoarei probleme: acum este ora h1, minutul m1 i secunda s1. Ct va fi ceasul peste h2 ore, m2 minute i s2 secunde? Rezultatul va fi reprezentat tot n ore, minute i secunde.
34
4. S se determine valoarea urmtoarei expresii, unde a, b i x sunt numere reale date: 2 x + 3 daca a b > 0 E ( x ) = x 3 2 x + 7 daca a b < 0 x 2 5 daca a b = 0
5. Dndu-se a, b i c, coeficienii unei ecuaii de gradul doi, s se determine semnul rdcinilor ecuaiei, dac exist, fr a se rezolva ecuaia (innd cont de valorile lui , P i S).
35
Exprimarea n pseudocod a acestei structuri este: cat_timp condiie execut secvena A Aceast structur mai este cunoscut ca structura de tip WHILE DO
Figura 2.8 Observaie Figura 2.8 Atunci cnd condiia este fals de la nceput, secvena A nu se execut niciodat; n acest caz numrul de iteraii este zero (adic de cte ori a fost executat secvena A).
Exemplul 2.7
S se calculeze xn, unde x este un numr real, iar n un numr natural. real x, putere ntreg n, i citete x, n i=1 putere = 1 cat_timp i<=n execut putere =putere * i i = i+1 scrie putere stop Variabila putere este folosit pentru a pstra puterea i a lui x, i fiind o variabil ntreag ce numr puterea la care este ridicat x, fiind denumit variabil de tip contor.
36
Ciclul cu test final sau structura repetitiv condiionat posterior Execuia presupune parcurgerea urmtoarelor etape: se execut secvena A se evalueaz condiia; dac rezultatul este fals, se continu cu primul pas; n caz contrar, se ncheie execuia ciclului. pseudocod a acestei
secvena A pn_cnd condiie Aceast structur mai este cunoscut ca structura de tip REPEAT UNTIL Observaie Deoarece testarea condiie se face la sfrit, secvena se execut cel puin o dat (numrul de iteraii este mai mare dect zero)
Condiie
DA
True
Figura 2.9
Exemplul 2.8
S se calculeze n! (factorialul numrului n, adic n!=1*2*...*n). Pentru a rezolva acaeast problem sunt necesare variabilele de tip ntreg n, citit de la tastatur, i, variabil necesar contorizrii pailor efectuai n calcularea produsului i variabila fact, care va memora valoarea produsului calculat. intregi n, i, fact citete n i=1 fact=1 repet fact=fact*i i=i+1 pn_cnd i>n scrie fact stop
37
Exemplul 2.9
S se calculeze suma primelor n numere naturale. Pentru rezolvarea acestei probleme, sunt necesare variabilele intregi n, i, s, primele dou variabile avnd aceeai semnificaie ca la problema precedent, iar s este variabila necesar pstrrii valorii sumei numerelor naturale de la 1 la n. intregi n, i, s citete n i=1 s=0 repet s=s+i i=i+1 pn_cnd i>n scrie s stop S probm funcionalitatea algoritmului pentru n=3: i ia valoarea 1 iar s ia valoarea 0; (se iniializeaz cu aceste valori) i se adaug la vechea valoare a lui s s=0+1=1 i crete cu o unitate (se incrementeaz) i=1+1=2 se compar i cu n; deoarece i este mai mic dect n, se trece la repetarea celor doi pai; i se adaug la vechea valoare a lui s s=1+2=3 i crete cu o unitate (se incrementeaz) i=2+1=3 se compar i cu n; deoarece i nu este mai mare dect n, se trece la repetarea celor doi pai; i se adaug la vechea valoare a lui s s=3+3=6 i crete cu o unitate (se incrementeaz) i=3+1=4 i este mai mare dect n, deci se oprete execuia ciclrii, se tiprete valoarea sumei s i algoritmul se ncheie. Observaie Dac se compar aceast problem cu precedenta, se observ o asemnare n rezolvarea lor, i anume o parte de iniializare a variabilelor i o ciclare pentru calculul celor dou valori: factorial, respectiv suma. Diferenele constau n valorile de iniializare a factorialului (1, deoarece se calculeaz un produs), respectiv a sumei (s=0) i operaiile de calcul a celor dou variabile; nmulire, respectiv adunare.
Exemplul 2.10
n primul capitol a fost prezentat, n limbaj natural, algoritmul de mprire a dou numere naturale prin scderi repetate. Iat cum se poate scrie n pseudocod acest algoritm: intregi a, b, cat 38
Proiectul pentru nvmntul Rural
citete a, b cat=0 ct_timp a>=b execut a=a-b cat=cat+1 scrie cat=, cat, rest=,a stop Pentru rezolvarea acestei probleme a fost ales ciclul cu test iniial deoarece el va da rezultatul corect i pentru cazul cnd a<b, caz n care catul va fi zero, iar restul a. Ciclul cu contor sau structura repetitiv cu numr cunoscut de pai (iteraii) Aceast structur repetitiv este folosit n cazurile n care este cunoscut numrul de iteraii ale structurii i modul n care se modific o variabil ce controleaz execuia acestuia, denumit contor. Exprimarea n pseudocod a acestei structuri este: pentru contor=vi, vf, pas execut secvena A vi, vf reprezint valorile iniiale, respectiv finale ale variabilei contor, iar pas este valoarea cu care se modific contor la terminarea execuiei secvenei A; dac nu este precizat nici o valoare pentru pas, aceasta este implicit 1. Aceast structur este echivalent cu: contor=vi ct_timp contor<=vf execut secvena A contor=contor+pas
Exemplul 2.11
S se calculeze suma primelor n numere naturale, folosind ciclul cu contor. Algoritmul a fost explicat n cadrul exemplului 2.8. Rezolvarea n acest caz este: ........... citete n s=0 pentru i=1, n execut s=s+i scrie s .......... Se observ n acest caz c, n cadrul structurii repetitive nu mai apare operaia de incrementare a variabilei contor i, aceasta fiind inclus n
Proiectul pentru nvmntul Rural
39
execuia instruciunii. Selecia: reprezint calculul unei expresii, i n funcie de rezultatul acesteia, algoritmul va continua pe una din ramurile posibile. Expresia trebuie sa fie definit ntr-un tip de date cu valori finite. expresie c1: secventa_1; c2: secventa_2; cn: secventa_n; rest: secventa_rest; endcase; Modul de utilizare a seleciei va fi prezentat ulterior, n cadrul prezentrii instruciunilor limbajului C. Pseudocod: case
2. Se citete un ir de numere naturale pn la introducerea valorii zero. S se determine media aritmetic a numerelor pare introduse i produsul numerelor impare.
3. Se citete un ir de numere naturale pn la introducerea valorii zero. S se determine suma numerelor de pe poziiile pare (suma dintre al doiea, al patrulea, etc) i produsul numerelor de pe poziiile impare (produsul dintre primul, al treilea, al cincilea, etc).
40
4. S se determine valoarea urmtoarelor expresii, unde n este un numr natural dat: 1 1 1 E1 = + ++ 1 2 2 3 n(n + 1) 2 4 2n E2 = + ++ (2n 1)(2n + 1) 1 3 3 5
5. Dndu-se a, b i c, coeficienii unei ecuaii de gradul doi, s se calculeze: n S n = x1n + x 2 , unde n este un numr natural dat, fr a se rezolva ecuaia (innd cont de valorile lui P i S).
41
BIBLIOGRAFIE
1. Dorin Stoilescu, Manual de C/C++ - Cap.1 Introducere, Editura Radial, Galati, 1998. 2. Florin. Munteanu, Traian C. Ionescu, Daniela Saru, Gheorghe Musca, Sergiu Mihai Dascalu, Programarea calculatoarelor - manual pentru liceele de informatic Cap.2 Programe. Algoritmi. Elemente de programare structurat, Editura Didactic i Pedagogic, Bucureti, 1995. 3. Valeriu Iorga si colectiv, Programare in C/C++. Culegere de probleme, Editura Niculescu, Bucureti, 2003. 4. Programe de specialitate elaborate de ctre Ministerul Educaiei i Cercetrii pentru nvmntul preuniversitar
42
43
Obiectivele Unitii de nvare 3 ....................................................................................44 3.1 Privire de ansamblu asupra limbajului C .................................................................44 3.2 Structura programelor n limbajul C.........................................................................46 3.3 Variabile, tipuri de variabile i declarare..................................................................51 3.4 Constante ...................................................................................................................54 3.5 Funcii aritmetice care opereaz cu valori de tip real i ntreg ..............................57 3.6 Operatori n C .............................................................................................................60 3.6.1 Operatorul de atribuire..................................................................................60 3.6.2 Operatori aritmetici .......................................................................................61 3.6.3 Operatori relaionali i logici .........................................................................65 3.6.4 Operatori de atribuire compus ....................................................................67 3.6.5 Operatorul de conversie explicit (cast) .......................................................68 3.6.6 Operatorul sizeof ..........................................................................................68 3.6.7 Operatorul virgul (,) ...................................................................................69 3.6.8 Operatorul condiional (?) .............................................................................69 Rspunsuri corecte la testele de autoevaluare, sarcinile de lucru i exerciii ...........72 Bibliografie .......................................................................................................................72 Lucrarea de verificare Nr. 3, notat de tutore................................................................73
3.1
Etapa iniiala de dezvoltare a limbajului de programare C a avut loc n cadrul laboratoarelor AT&T Bell ntre anii 1969 i 1973. Dup spusele lui Dennis Ritchie, cea mai creativ perioad a avut loc n 1972. A fost denumit C deoarece multe din caracteristicile sale au fost derivate din limbajul de programare B.
44
Sunt multe legende despre originea limbajului C i legtura sa cu sistemul de operare Unix, cum ar fi: Dezvoltarea limbajului C a fost rezultatul dorinei programatorilor de a juca un joc de tipul Asteroids. Acetia l jucau pe calculatorul principal al companiei, dar din lipsa de resurse i datorit faptului c acesta trebuia s suporte mai mult de 100 de utilizatori, Thompson i Ritchie, nemulumii de controlul pe care l aveau asupra navei n ncercarea de a evita asteroizii, au decis s porteze jocul pe un PDP-7, nefolosit, din birou. Dar aceast main nu avea un sistem de operare, aa c au hotrt s scrie unul. Au decis ca eventual s porteze acest sistem de operare pe mainile PDP-11 pe care acetia le foloseau n birou, dar era o munc destul de dificil avnd n vedere c totul era scris n limbaj de asamblare. Aa c au decis s foloseasc un limbaj portabil de nivel nalt astfel nct sistemul de operare s poat fi portat cu uurin de pe un computer pe altul. Au ncercat folosind limbajul de programare B, dar i lipseau unele din funcionalitile care ar fi fcut facil folosirea unor caracteristici avansate a mainii PDP-11. Astfel, a aprut un nou limbaj de programare, numit C. Justificarea pentru obinerea primului computer care a fost utilizat pentru dezvoltarea sistemului de operare Unix a fost acela de a crea un sistem pentru a automatiza completarea autorizaiilor. Prima versiune a sistemului de operare Unix a fost scris n limbaj de asamblare. Mai trziu, limbajul de programare C a fost folosit pentru a rescrie sitemul de operare.
ncepnd cu anul 1973, limbajul de programare C a devenit destul de robust, astfel nct mare parte a kernelului Unix, scris iniial n limbaj de asamblare pentru PDP 11/20, a fost rescris n C. Acesta a fost unul din primele kernele ale unui sistem de operare scris ntr-un limbaj de programare, altul dect limbajul de asamblare. ncercri anterioare au fost pentru scrierea sistemului Multics (scris n PL/I) i TRIPOS (scris n BCPL). K&R C n 1978, Dennis Rithie i Brian Kernighan au publicat prima ediie a crii Limbajul de programare C (eng. The C Programming Language). Aceast carte, cunoscut n cercul programatorilor sub numele K&R, a servit pentru muli ani ca un mijloc de informare asupra specificaiilor limbajului C. Versiunea limbajului C descris este cunoscut sub numele K&R C. K&R C este adesea considerat limbajul de baz pe care orice compilator C trebuie s-l suporte. Pentru muli ani, chiar i dup introducerea standardului ANSI C, a fost considerat ca fiind cel mai mic numitor comun pe care programatorii n C trebuie s-l respecte atunci cnd se vorbete de portabiliitate maxim, deoarece nu toate compilatoarele sunt scrise nc s suporte standardul ANSI C, iar o secven de cod scris n K&R C respect i ANSI C. ANSI C i ISO C La sfritul anilor 1970, C a nceput s nlocuiasc limbajul BASIC devenind cel mai utilizat limbaj de programare. n anii 1980 a fost adptat si de calculatoarele IBM PC, popularitatea acestuia ncepnd s creasc semnificativ. n acest timp, Bjarne Stroustrup mpreun cu ali colegi de la Bell Labs au nceput s adauge limbajului C caracteristici ale programrii orientate pe obiecte. Limbajul rezultat a fost denumit C++ i este cel mai popular limbaj de programare pe sistemele de operare Microsoft Windows; totui C-ul rmne cel mai popular limbaj de programare n Unix. Alt limbaj de programare dezvoltat n acea vreme se numete Objective-C care adaug de asemenea C-ului caracteristici ale programrii orientate pe obiecte. Dei nu la fel de popular ca C++, Obejective-C este folosit pentru dezvoltarea aplicaiilor pe ce folosesc interfaa Cocoa a sistemului de operare Mac OS X.
45
n 1983, American National Standards Institute (ANSI) a format un comitet, X3J11, pentru a stabili specificaiile unui limbaj C standard. Dup un proces ndelungat, standardul a fost terminat n 1989 i ratificat ca ANSI X3.159-1989 "Programming Language C". Aceast versiune a limbajului ne este cunoscut sub numele ANSI C. n 1990, standardul ANSI C (cu mici modificri) a fost adoptat de International Organization for Standardization (ISO) ca ISO/IEC 9899:1990. Una din intele procesului de standardizare ANSI C a fost acela de a produce un superset al K&R C, ncorpornd multe dintre caracteristicile neoficiale introduse secvenial. Totui, comitetul pentru standardizare a introdus cteva caracteristici noi, cum ar fi prototipul funciilor (mprumutat din C++) i un preprocesor mult mai capabil. ANSI C este suportat de marea majoritate a compilatoarelor folosite astzi. Mare parte din codul C scris acum este bazat pe ANSI C. Orice program scris exclusiv n standardul C este garantat s funcioneze corect pe orice platform cu o implementare C conform. Totui, multe programe sunt scrise astfel nct aceste vor putea fi compilate numai pe anumite platforme, sau folosind un anumit compilator, deoarece (i) se folosesc biblioteci non-standard, de exemplu pentru interfaa grafic, (ii) unele compilatoare ce nu respect standardul ANSI C, deci i urmaii lor n mod implicit sau (iii) bazarea pe dimensiunea unui anumit tip de date pe anumite platforme. Limbajul C est singurul limbaj de programare structurat care permite un control rigurosal hardwareuluii al perifericelor (facilitate oferit de limbajele de asamblare). Limbajul C a fost folosit iniial pentru scrierea programelor de sistem (sisteme de operare, editare, compilatoare, etc), dar o dat cu creterea popularitii lui, programatorii au nceput s-l foloseasc i la scrierea programelor de aplicaii datorit n special eficienei i portabilitii crescute a unor astfel de programe. Datorit calitilor sale incontestabile, limbajul C a devenit limbajul de baz i pentru programarea aplicaiilor de tip real.
46
O prim observaie important pe care trebuie s o facem este aceea c orice programn C este compus dintr-o serie de entiti numite funcii. O funcie, pentru a o deosebi de un cuvnt cheie oarecareal limbajului, se noteaz cu numele funciei, urmat de o pereche de paranteze rotunde: nume_funcie(); Funciile pot fi apelate att n cadrul expresiilor, ct i independent. Funcia main() este aceea ctre care sistemul de operare transfer controlul atunci cnd se lanseaz n execuie programul; fiecare program conine cel puin o funcie, i anume funcia main. Cel mai simplu program n C este urmtorul: Exemplul 3.1 main() { } Acest program nu realizeaz nimic. Se remarc funcia main, urmat de o pereche de paranteze rotunde, ce indic c aceasta este o funcie; ntre cele dou paranteze pot fi parametri formali, atunci cnd e nevoie. Se mai observ existena unei perechi de acolade ce ncadreaz corpul funciei, care n aceast situaie este instruciunea vid. Aceste paranteze se utilizeaz i pentru delimitarea altor blocuri ntlnite de exemplu n structurile iterative sau deczionale. Un program foarte simplu, care are ca rezultat afiarea textului Invatam limbajul C, este urmtorul: Exemplul 3.2 #include <stdio.h> main() { printf(Invatam limbajul C); } Pentru a realiza operaii de citire/scriere, limbajul C este nzestrat cu funcii specifice, n acest caz fiind folosit funcia printf, ce are un singur parametru, i anume textul ce va fi tiprit, cuprins ntre ghililmele. Se observ c acest program ncepe cu o prim linie de program, #include <stdio.h>, a crei semnificaie este urmtoarea: pentru ca o funcie s fie apelat (printf()), compilatorul trebuie s gseasc anumite informaii despre ea (prototipul su, care va fi explicat ulterior). Aceste informaii se gsesc ntr-un fiier, n acest caz numele lui este stdio.h. Extensia (h) este dat de faptul c un astfel de fiier este considerat de tip header (antet). Prototipurile funciilor care pot fi apelate n cadrul limbajului se gsesc grupate n fiiere de tip header; mai multe funcii nrudite au prototipurile grupate ntr-un astfel de fiier (de exemplu, cele de citire/scriere).
47
n procesul de transformare a textului surs n program executabil exist o etap care se execut naintea compilrii, i anume preprocesarea. n aceast etap fiierul header este inclus n textul surs. Linia de program: printf(Invatam limbajul C); formeaz o instruciune i ea este obligatoriu terminat cu semnul ;. Trebuie fcut observaia c spaiil albe (blank, tab, newline) sunt invizibile pentru compilator. Astfel, programul mai putea fi scris i aa: main(){printf(Invatam limbajul C);} Modul de scriere a programului folosit n exemplul anterior face ca acesta s devin mai uor de citit i de interpretat. n figura 3.1 este prezentat o sintez a celor prezentate pn acum. numele funciei parantezele pot include semn de terminare a unei instruciuni main() { printf(Invatam limbajul C); } instruciune
Programul poate conine comentarii, care pot fi plasate oriunde n text. Exist dou moduri de introducere a comentariilor: ntre perechile de caractere /* i */. Un astfel de comentariu poate ocupa mai multe linii ale programului surs. Exemplu: /*acesta este un comentariu.*/ n cazul n care dorim s scriem un comentariu pe o singur linie surs, tastm dou caractere /. De exemplu, o linie poate conine: printf(un text); //acesta este un comentariu. Comentariul ncepe dup cele dou caractere// i se termin o dat cu sfritul de linie.
48
Funcia printf() din acest exemplu este o funcie sistem, adic nu este creat de programator, care permite afiarea la consol (display) a constantelor, variabilelor i caracterelor. S observm modul de folosire al acestei funcii i n alte exemple. Considerm urmtorul program: Exemplul 3.3 main() { printf(Acesta este numarul sapte: %d,7); } n urma lansrii n execuie a programului, la consol va aprea: Acesta este numarul sapte: 7 n acest caz funcia printf() are dou argumente separate prin virgul, i anume un ir de caractere ncadrat ntre ghilimele i valoarea ntreag 7. Simbolul %d permite transferarea parametrului din dreapta virgulei valoarea 7 n stnga virgulei, alturi de irul de caractere. Acesta reprezint unul din formatele specifice utilizate de funcia printf(), i anume acela pentru scrierea numerelor ntregi. Pentru a nelege i mai bine modul de lucru al funciei printf(), s mai considerm un exemplu: Exemplul 3.4 main() { printf(%s este student in anul %d \n la facultatea ta., Mihai, 3); } n urma execuiei programului, se va afia: Mihai este student in anul 3 la facultatea ta. Aceasta nseamn c funcia printf() a nlocuit simbolul %s cu irul de caractere Mihai i simbolul %d cu numrul ntreg 3. Simbolul \n reprezint caracterul newline i are efect de carriage return and linefeed rnd nou i de la capt. Acesta este motivul c textul a fost afiat pe dou rnduri, dei el a fost scris n program ntr-un singur rnd. El formeaz o aa-numit secven escape. S considerm nc un exemplu de program:
49
Exemplul 3.5 main() { printf(Litera %c se gseste in cuvantul %s,h, Mihai); printf(pe pozitia %d.,3); } Dup executarea programului, se va afia: Litera h se gseste in cuvantul Mihai pe pozitia 3. Se observ c scrierea textului se face pe un singur rnd, cu toate c n program sunt dou linii de instruciuni. Aici heste caracter i se scrie cu formatul %c. Caracterele se delimiteaz de simbolul apostrof, iar irurile de caractere de ctre ghilimele. Din punct de vedere sintactic, un program scris n limbajul C este o secven de caractere ASCII. Este alctuit din elemente lexicale separate prin spaii: cuvinte cheie cu rol bine determinat n cadrul limbajului i care nu pot fi folosite n alt context. Exemplu for pentru instruciunea repetitiv cu contor; identificatori se folosesc pentru a denumi variabilele, funciile, etc. Se formeaz cu ajutorul literelor mari i mici, caracterul _ i cifrele de la 0 la 9. Un identificator trebuie s nceap cu o liter. Limbajul C face diferenierea dintre caracterele mari i mici. De exemplu, putem avea dou variabile cu numele Suma, respectiv suma; constante; operatori.
50
51
Limbajul C are cinci tipuri de date fundamentale, i anume: caracter: char ntreg: int real n virgul mobil, simpl precizie: float real n virgul mobil, dubl precizie: double tip de variabil neprecizat sau inexistent: void Modul de memorare a acestor tipuri de date depinde de tipul calculatorului i de varianta de implementare a limbajului C. Modul de implementare al lor poate fi modificat prin utilizarea unor declaraii suplimentare, cum ar fi: signed cu semn unsigned fr semn long lung short scurt Apelnd la o reprezentare uzual a limbajului C pe echipamentele PC, compatibile IBM sub sistemul de operare MS-DOS, tipurile de date definite de standardul ANSI i recunoscute de limbaj au reprezentarea dat n urmtorul tabel: Reprezentare Rang n bii char 8 -128 127 unsigned char 8 0 255 signed char 8 -128 127 int 16 -32768 32767 unsigned int 16 0 65535 signed int 16 -32768 32767 short int 16 -32768 32767 unsigned short int 16 0 65535 signed short int 16 -32768 - 32767 long int 32 -2 147 483 648 2 147 483 647 unsigned long int 32 0 4 294 967 295 signed long int 32 -2 147 483 648 2 147 483 647 float 32 10-17 - 1017 (6 digii precizie) double 64 10-308 - 10308 (10 digii precizie) long double 80 15 digii precizie Tabelul 3.1 Exemple de declaraii de variabile: int i, j, n; short int si; unsigned int ui; double balanta, profit; float time; S considerm un exemplu de program ce utilizeaz mai multe tipuri de variabile. Tip
53
Exemplul 3.7 main() { int n; float v; char ch; v=2.53; n=65; ch=A; printf(Caracterul %c are codul ASCII %d,ch, n); printf( si o frecventa de aparitie de %f %.,v); } n urma execuiei acestui program se va afia: Caracterul A are codul ASCII 65 si o frecventa de aparitie de 2.530000 %.
54
3.4 Constante
Exist mai multe tipuri de constante, dintre care acum se vor prezenta numai cele corespunztoare tipurilor predefinite. Constante ntregi Aceste constante se clasific astfel: zecimale n baza 10. Exemple: 23, 2314, 759. octale n baza 8. O constant n baza 8 se declar precedat de un 0 nesemnificativ. Exemplu:0523 se reine numrul ntreg 523(8). hexazecimale n baza 16. Acestea sunt precedate de 0X sau 0x. Exemplu: pentru 0X1A2 se memoreaz 1A2(16), iar pentru 0x1a2 se va memora 1a2(16). O constant ntreag poate lua valori ntre 0 i 4 294 967 295. Atenie! O constant ntreag este ntotdeauna pozitiv! n cazul n care se folosete semnul - (de exemplu -321) se consider c aceasta este o expresie constant, -fiind un operator unar Memorarea constantelor ntregi se face dup un mecanism implicit, adic fr intervenia programatorului, sau unul explicit. Mecanismul implicit const n alegerea tipului ntreg n funcie de valoare. Astfel, pentru constante ntregi zecimale: pentru valori ntre 0 i 32767 tipul int; pentru valori ntre 32768 i 2 147 483 647 tipul long int; pentru valori ntre 2 147 483 648 i 4 294 967 295 tipul unsigned long int; pentru valori peste 4 294 967 296 se reine o valoare trunchiat. Mecanismul explicit const n a fora ca o anumit constant s fie memorat aa cum o dorim prin adugarea unui sufix. Dac dorim ca o constant s fie memorat n tipul long, ea trebuie urmat de l sau L. De asemenea, dac dorim ca ea s fie de tip unsigned, aceasta trebuie s fie urmat de u sau U. Se pot folosi simultan l i u sau literele mari corespunztoare, indiferent ordinea. De exemplu, 123LU este o constant ce va fi memorat n tipul unsigned long, altfel ea ar fi fost memorat n tipul int. Constante caracter Acestea se reprezint ntre dou caractere apostrof (). Exemple: A, 1, a. Pentru memorarea lor se ytiliyeay[ tipul char, memorndu-sede fapt codul ASCII al caracterului respectiv. De exemplu, pentru 1 se memoreaz valoarea 49, iar pentru A, valoarea 65. Constantele caracter se mai pot declara i sub forma secvenelor escape. O astfel de secven ncepe prin caracterul \ (backslash). De exemplu, caracterul a are codul ASCII 97 10=141 8=61 16. Printr-o secven escape, constanta se introduce prin codul su ntr-una din
Proiectul pentru nvmntul Rural
55
bazele 8 sau 16: \141 sau \x61. Se observ c, atunci cnd este folosit baza 16, codul este precedat de caracterul x. Secvenele escape sunt utile pentru definirea caracterelor negrafice, cum ar fi caracterul newline, care are codul ASCII 1010 i care poate fi declarat sub forma \12 sau \xa. Pentru anumite caractere, exist notaii speciale sub form de secven escape. caracterul newline, amintit mai devreme, se poate scrie i \n. Alte exemple utilizate pentru secvenele escape: backslash: \\, \134, \x5c; apostrof: \, \47, \x27; bel: \a, \7, \x7; cr: \r, \15, \xd. Se admit i constante cu dou caractere, ca de exemplu AB. O astfel de constant este memorat utiliznd tipul int, cu observaia c primul caracter este memorat n al doilea octet, iar al doilea caracter n primul octet.. Constante reale Exemple de constante reale: -33.25, 2., 0.3, sau -3.75E-11(=-3.75*10-11). Constantele reale sunt memorate implicit utiliznd tipul double. i n acest caz se poate fora memorarea lor sub tipul float, dac se adaug sufixul f sau F, sau sub tipul long double, dac se adaug sufixul l sau L. 187.5 se memoreaz sub forma double; 187.5f se memoreaz sub forma float; 187.5L se memoreaz sub forma long double. Declararea constantelor Forma general a declarrii unei constante este alctuit din cuvntul const, urmat de tipul constantei (opional) tip, numele dat constantei nume i valoarea atribuit acesteia: const [tip] nume = valoare; Dac tipul constantei tip lipsete, atunci aceasta este implicit de tip int. Iat cteva exemple de declarare a constantelor: const int numar=15; constant ntreag denumit numar cu valoarea 15 const numar=15; la fel ca mai sus const float pi=3.14; constant de tip float, denumit pi i cu valoarea 3.14 Dac, de exemplu, n ultimul exemplu ar lipsi cuvntul const, asta ar nsemna c este o declarare de variabil de tip float, iniializat cu valoarea 3.14. Prezena modificatorului const determin protecia la modificare a variabilei pi. Cu alte cuvinte, pi este o variabil, are spaiu rezervat de memorie, dar reine o valoare ce nu poate fi modificat. Cuvntul cheie const este denumit modificator, pentru c are rolul de a modifica un enun, care iniial avea alt sens. 56
Proiectul pentru nvmntul Rural
Atenie! Limbajul C conine o serie de constante predefinite, foarte des utilizate n practic. Ele se gsesc m biblioteca math.h. Printre cele mai importante constante, se gsesc: numrul pi M_PI i derivate ale acestuia: M_PI_2, M_PI_4, M_1_PI, M_2_PI, M_1_SQRTPI, M_2_SQRTPI; numrul lui Euler, notat matematic cu simbolul e M_E; radical de ordinul doi din 2 M_SQRT2. Alte valori constante predefinite se gsesc n biblioteca limits.h, i anume cele care definesc limitele superioare i inferioare pe care le pot lua tipurile de date folosite n C. Iat cteva exemple: INT_MAX, INT_MIN, LONG_MAX, LONG_MIN, SGRT_MAX, SHRT_MIN, UINT_MAX, ULONG_MAX. Constantele iruri de caractere Aceste constante se scriu ntre ghilimele, iar la sfritul irului compilatorul adaug automat terminatorul de ir \0; aadar pentru memorarea unui ir se aloc un spaiu mai mare cu un octet dect lungimea irului. Un exemplu de ir constant: Exemplu de sir. n cadrul acestora se pot folosi secvee escape, precum: Mesaj sonor \a urmat de \n trecerea la o linie noua. Afiarea acestui text ntr-o instruciune de tiprire va avea ca efect producerea unui mic sunet (BELL) corespunztor secvenei escape \a i scrierea textului pe dou rnduri, datorit secvenei escape \n. Tipul enumerare Se folosete pentru a realiza o utilizare comod i sugestiv a valorilor folosite. El declar constante simbolice crora li se asociaz valori numerice ntregi. Declararea unui tip enumerare are sintaxa: enum nume_tip (lista_constante_simbolice); Compilatorul asociaz valoarea implicit zero pentru prima valoare enumerat, n cazul n care nu este specificat o anumit valoare. Pentru urmtoarele elemente din lista constantelor, valoarea lor va fi mrit cu o unitate fa de valoarea din poziia anterioar, dac nu este specificat o alt valoare. Exemplul 3.8 Se va exemplifica folosirea acestui tip enumerare prin mai multe declaraii echivalente: enum culori (rosu, galben, verde); enum culori (rosu, galben=1, verde); enum culori (rosu=0, galben, verde=2); alt valoare.
Proiectul pentru nvmntul Rural
57
Exemplul 3.9 Este definit tipul logic ca tip enumerare (Limbajul C nu are implementat acest tip de variabile, spre deosebire de alte limbaje de programare, ca de exemplu limbajul Pascal). enum boolean (false, true); Pentru false se d valoarea zero, iar pentru true se d valoarea unu. Exemplul 3.10 Un alt exemplu de definire a unei enumerri: enum timp (ieri, azi=3, maine=5); n acest caz ieri este iniializat cu valoarea zero, azi cu valoarea 3, iar maine cu valoarea 5. enum timp (ieri, azi=3, maine=azi); Este posibil ca dou constante s fie iniializate cu aceeai valoare (3 n acest caz).
58
tan()
sunt definite in biblioteca <math.h>. Toate aceste funcii, cu excepia lui "pow()" au un argument de tip "double" i returneaz o valoare de tip "double". Functia "pow()" are dou argumente de tip "double" i returneaza o valoare de tip "double".
f ( x ) = x 5 + ln (x )
Pentru rezolvarea acestui exerciiu se vor folosi dou variabile reale x i f; se vor folosi de asemenea dou funcii din cadrul bibliotecii matematice math.h. n figura 3.2 este artat programul scris n mediul BORLANDC FOR WINDOWS, mpreun cu rezultatul afiat.
Figura 3.2
59
R 2 h
3
5. Adevrat / Fals: pentru variabilele de tip logic, ce pot lua valorile true sau false, limbajul C are definit tipul de variabile boolean.
60
3.6 Operatori n C
Limbajul C este foarte dotat n materie de operatori, acordnd operatorilor mai mult importan dect majoritatea limbajelor de programare. C definete patruclase de operatori: aritmetici, relaionali, logici i pe bii. n plus, C mai dispune de anumii operatori speciali pentru anumite operaii.
61
float x; c=a; n=3; k=d; x=c+n; Dup prima atribuire caracterul c devine egal cu a. n urma celei de-a doua atribuiri n devine egal cu 3. La a treia atribuire k devine egal cu 100, deoarece expresia din membrul drept d, de tip caracter este convertit la un tip ntreg, avnd valoarea codului ASCII al caracterului respectiv. Dup ultima atribuire x devine egal tot cu 100, deoarece rezultatul adunrii dintre un operand de tip ntreg i unul de tip caracter se convertete n ntreg. Variabila c, iniial egal cu a, convertit n ntreg devine egal cu codul su ASCII, adic 97, care se adun cu 3, valoarea variabilei n. Rezultatul este deci 100. Din acest exemplu se poate observa c limbajul C permite operaii ntre operanzi de tipuri diferite, fcnd conversia tipului mai mic ca dimensiune n tipul corespunztor celeilalte variabile. Exemplul 3.13 Un exemplu de atribuire multipl: int x, y; float z; z=x=y=3; Dup evaluare, y reine valoarea 3, x devine egal cu y, adic tot 3, iar z reine valoarea 3.0, fcndu-se i conversia de la tipul ntreg la cel real.
Exemplul 3.14 Folosirea operatorilor aritmetici: int i, j, n; float x; // n=10*4-7; i=9/2; j=n%i; x=n; x=x%i; n urma primei atribuiri, n devine egal cu 33. La a doua atribuire, i va fi egal cu ctul mpririi ntregi a lui 9 la 2, adic 4. La a treia operaie, j devine egal cu restul mpririi ntregi a lui n la i,adic 1. La ultima operaie de atribuire se obine eroare, deoarece operatorul % este definit doar pentru numere ntregi. Exemplul 3.15 Un exemplu care arat obinerea unor rezultate diferite pentru aceleai calcule, datorit tipului diferit de variabile crora li se atribuie expresia respectiv: int i; float x; i=9./2; x=9./2; Valoarea expresiei din dreapta este n ambele cazuri egal cu 4.5. n cazul primei atribuiri ea este convertit la tipul ntreg, corespunztor variabilei i. Prin urmare, i devine egal cu 4, prin trunchiere. La cea de-a doua atribuire, x primete valoarea 4.5. n concluzie, rezultatul este convertit la tipul variabilei din membrul stng al atribuirii. Exemplul 3.16 n operaiile cu constante conteaz dac ele sunt de tip ntreg sau real: int i; i=3/2+9/2; i=3./2+9./2; Dup prima atribuire, i devine egal cu 5 (3/2=1, 9/2=4, 1+4=5), iar dup cea de+a doua atribuire i devine egal cu 6 (3./2=1.5, 9/2=4.5, 1.5+4.5=6).
63
n cazul n care o expresie aritmetic are operanzi de mai multe tipuri, regula general este: se convertete unul din operanzi ctre tipul celuilalt, care poate reine rezultatul. Iat paii efectuai n ordine de ctre calculator: I. 1. Orice operand de tip char este convertit ctre tipul int; 2. Orice operand de tip unsigned char este convertit ctre tipul int; 3. Orice operand de tip short este convertit ctre tipul int; II. Dac un operand este de tipul long double, atunci i cellalt operand se convertete ctre acest tip; III. Dac un operand este de tipul double, atunci i cellalt operand se convertete ctre acest tip; IV. Dac un operand este de tipul float, atunci i cellalt operand se convertete ctre acest tip; V. Dac un operand este de tipul unsigned long, atunci i cellalt operand se convertete ctre acest tip; VI. Dac un operand este de tipul long, atunci i cellalt operand se convertete ctre acest tip. Dup execuia acestor pai, cei doi operanzi sunt de acelai tip, iar rezultatul va fi de tipul comun lor. Exemplul 3.17 Fie declaraia: int a=10; Atunci expresia 4*a/3 este de tip int i la evaluare se obine 13 (4*10=40, 40/3=13 mprire ntreag). n aceleai condiii, expresia 4*(a/3) are ca rezultat valoarea 12. Mai nti se calculeaz a/3 , rezultnd valoarea 3; apoi se efectueaz 4*3=12. Acesta este un exemplu din care se poate observa c o expresie n C nu este acelai lucru cu o expresie matematic. Fie declaraia: float a=10; Atunci expresia 4*a/3 este de tip float i la evaluare se obine 13.3333 (4*10=40, numr real 40/3=13.3333 mprire real). Operatori de incrementare i decrementare Limbajul C include doi operatori utili, care n general nu apar n alte limbaje de programare, i anume operatorii de incrementare i de decrementare, ++, respectiv --. Operatorul ++ adaug o unitate la operand, iar scade o unitate din operand. Cu alte cuvinte x=x+1; este echivalent cu iar x=x-1; este echivalent cu x--; Att operatorul de incrementare, ct i cel de decrementare pot precede prefixa sau urma postfixa operandul. De exemplu, x=x+1; poate fi scris ca x++; sau ++x; x++;
64
Exist totui diferene ntre formele de prefix sau postfix la utilizarea acestor operatori ntr-o expresie. Cnd operatorul de incrementare sau de decrementare i precede operandul, C execut opearia de incrementare sau de decrementare nainte de a folosi operandul respectiv n expresie. Dac operatorul succede operandului, C calculeaz valoarea operandului nainte de a o incrementa sau decrementa. De exemplu, x=10; y=++x; stabilete valoarea lui y la 11. Dac ns codul se scrie astfel: x=10; y=x++; atunci valoarea lui y va fi egal cu 10. Indiferent de procedeu, x va fi egal cu 11; diferena const n modul n care se ajunge la aceast valoare. Majoritatea compilatoarelor de C genereaz coduri obiect foarte rapide i eficiente pentru operaiile de incrementare sau decrementare, coduri mai performante dect cele folosite de o instruciune obinuit de atribuire. Din acest motiv este bine s folosii aceti operatori ori de cte ori avei posibilitatea. Precedena sau ordinea prioritii operatorilor aritmetici este: cel mai prioritar cel mai puin prioritar ++ -- (minus unar) */% +-
Operatorii cu aceeai proritate sunt evaluai de ctre compilator de la stnga la dreapta. Se pot folosi paranteze rotunde pentru a modifica ordinea evalurii. Exemplul 3.18 main() { int n=0; printf(Numar=%d\n, n); printf(Numar=%d\n, n++); printf(Numar=%d\n, n); } n urma executrii acestui program se va afia: Numar=0 Numar=0 Numar=1 aceasta deoarece la prima afiare variabila n are valoarea zero, la a doua afiare n are la nceput aceeai valoare, zero, dup care se face
Proiectul pentru nvmntul Rural
65
incrementarea acesteia, n devenind egal cu 1; la ultima afiare va fi tiprit noua valoare a lui n, adic 1. Dac vom scrie acelai program dup cum urmeaz, execuia va fi diferit: main() { int n=0; printf(Numar=%d\n, n); printf(Numar=%d\n, ++n); printf(Numar=%d\n, n); } La executarea acestui program se va afia: Numar=0 Numar=1 Numar=1 Diferena apare la cea de-a doua afiare, cnd se face mai nti incrementarea variabilei n preincrementare urmat de afiarea ei. Operatorul de decrementare (--) lucreaz n mod similar.
Operatori relaionali Operator > >= < <= == != Aciune Mai mare dect Mai mare sau egal Mai mic Mai mic sau egal Egal Diferit Operatori logici Operator && || ! Aciune I AND SAU OR negare NOT Tabelul 3.3 Att operatorii relaionali, ct i cei logici au o prioritate mai redus dect operatorii aritmetici. O expresie de forma 7>3+5 este evaluat ca i cum ar fi fost scris 7>(3+5); reultatul este Fals, adic zero. ntr-o expresie se pot combina mai multe operaii, ca n exemplul urmtor: 10>5 && !(9<5) || 3<=5 Rezultatul acestei expresii este Adevrat (mai nti se evalueaz paranteza 9<5 fals - , apoi aceasta este negat, rezultnd adevrat; din 5&&1 rezultnd de asemenea 1, adic Adevrat; 3<=5 este tot Adevrat, 1||1este Adevrat; ultima evaluare este 10>1, deci Adevrat). Precedena relativ a operatorilor relaionali i logici este: cel mai prioritar ! > >= < <= == != && ||
Toate expresiile relaionale i logice dau un rezultat egal fie cu zero, fie cu 1 (fals sau adevrat). main() { int n; n=100;
Proiectul pentru nvmntul Rural
67
printf(%d>10 da rezultatul %d\n, n, n>10); printf(%d==100 da rezultatul %d\n, n, n==100); printf(%d<=10 da rezultatul %d\n, n, n<=10); printf(%d>10 || %d<50 da rezultatul %d\n, n, n>10 || n<50); } n urma executrii acestui program se va afia: 100>10 da rezultatul 1 100==100 da rezultatul 1 100<=10 da rezultatul 0 100>10 || 100<50 da rezultatul 1
Exist 10 combinaii posibile permise operatorilor de atribuire compus, i anume 5 combinaii cu operatori aritmetici: += -= *= /= %= i 5 combinaii cu operatori pe bii: |= &= ^= <<= >>= Folosirea operatorului de atribuire compus determin o execuie a instruciunii mult mai rapid, deoarece procesorul, cunoscnd c primul operand i rezultatul au aceeai locaie de memorie, folosete un numr mai mic de operaii, avnd nevoie de un timp de execuie mai mic dect atribuirea n cazul general. Exemplul 3.25 a) Folosirea operatorului de aflare a restului mpririi: int i=16, j=5; i%=j; Valoarea variabilei i devine 1. b) Folosirea operatorului de deplasare pe bii: int i=3, j=4; 68
Proiectul pentru nvmntul Rural
i<<=j; Valoarea variabilei i devine 48. c) Folosirea operatorului de deplasare la dreapta pe bii i apoi a operatorului aritmetic de adunare: int a=3, b=5,c; a += b >>= c = 2; Valoarea variabilei a se determin astfel: mai nti lui c i se atribuie valoarea 2, dup care b devine 1 (5/2/2); a va primi n final valoarea 4 (3+1).
69
octei, urmtorul program: float f; printf(%d ,sizeof (f)); printf(%d ,sizeof (int)); va afia numerele 8 i 2.
n ansamblu, expresia este de tipul lui Exp2 sau al lui Exp3, n funcie de cea care se evalueaz i produce valoarea corespunztoare expresiei evaluate. Exemplul 3.29 Pentru un numr real x, citit de la tastatur, s se afieze valoarea absolut a acestuia (modulul). #include <stdio.h> void main() { float x; printf(x=); scanf(%f,&x); printf(%f, x>=0? x: -x); } ntreaga expresie condiional a fost scris ca un parametru pentru printf(). Se testeaz dac x este mai mare sau egal cu zero i n cazul n care condiia este ndeplinit, se evalueaz x, a doua expresie; n cazul n care x este negativ, se evalueaz x, a treia expresie; se va tipri valoarea expresiei evaluate. Exemplul 3.30 Fie declaraiile: double x, y, aux; Expresia: x > y ? (aux=x: x=y, y=aux) : y; are ca efect ordonarea variabilelor x i y n ordine cresctoare. Ca rezultat se obine cea mai mare valoare dintre cele dou variabile.
2. Rescriei instruciunile urmtoare folosind operatorul postdecrementare sau operatorul de atribuire compus: numar=numar+1; poz=poz-1; pas=pas*3; 3. Expresiile urmtoare sunt adevrate sau false? a) 1>2; c) 1= =2; b) a<b; d) 3= =3; 4. Este corect fcut comentariul urmtor? /*Acesta este /*un comentariu care ocup /*mai multe rnduri */ 5. Scopul operatorului condiional este: a) alege dintre dou valori pe cea mai mare; b) decide dac dou valori sunt egale: c) alege alternativ una din dou valori; d) alege una din dou valori n funcie de o condiie
de
preincrementare,
72
4) A
Testul de autoevaluare 3.2 : Rspunsuri corecte: 1 a, b, d Vezi U3.3 Variabile, tipuri de variabile i declarare 2A Vezi U3.3 Variabile, tipuri de variabile i declarare 34 Vezi U3.3 Variabile, tipuri de variabile i declarare 4 -32768, 32767 Vezi U3.3 Variabile, tipuri de variabile i declarare 5F Vezi U3.3 Variabile, tipuri de variabile i declarare Testul de autoevaluare 3.3
1 a, b, d, e; Vezi U3. 4 Constante pag 54 2 math.h Vezi U3. 4 Constante pag 54 x 4 3 x , lg x, sin(a+b), 2 x + e Vezi U 3.5 Funcii aritmetice care opereaz cu valori de tip real i ntreg pag 57 4 sin(5*x*x) , sqrt(a*a+b*b+c*c), pow(3, x-2), M_PI*R*R*h/3 Vezi U 3.5 Funcii aritmetice care opereaz cu valori de tip real i ntreg pag 57 5F Vezi U3. 4 Constante pag 54 Testul de autoevaluare 3.4 1 a, c 2 ++numar; poz--; pas*=3; 3 F, A, F, F 4 Nu 5d Vezi U3.6 Operatori n C pag. 60 Vezi U3.6 Operatori n C pag. 60 Vezi U3.6 Operatori n C pag. 60 Vezi U3.6 Operatori n C pag. 60 Vezi U3.6 Operatori n C pag. 60
BIBLIOGRAFIE
1. Dorin Stoilescu, Manual de C/C++ - Cap.1 Introducere, Cap.2 Tipuri de date, Editura Radial, Galati, 1998. 2. Florin. Munteanu, Traian C. Ionescu, Daniela Saru, Gheorghe Musca, Sergiu Mihai Dascalu, Programarea calculatoarelor - manual pentru liceele de informatic Cap.17 Structura programelor n limbajul C. Tipuri de date, operatori i expresii, Editura Didactic i Pedagogic, Bucureti, 1995.
73
3. Valeriu Iorga si colectiv, Programare in C/C++. Culegere de probleme, Editura Niculescu, Bucureti, 2003. 4. Programe de specialitate elaborate de ctre Ministerul Educaiei i Cercetrii pentru nvmntul preuniversitar 5. Herbert Schildt, C manual complet Cap1 C, vedere de ansamblu, Cap2 Expresii C, Editura Teora, 2000 6. http://www. cs.umd.edu/users/cml/style/ - ghid privind stilul de programare in limbajele C si C++. 7. http://www.programmingtutorials.com tutoriale de programare pentru C, C++ precum si pentru alte limbaje. 8. http://www.snippets.org exemple de programe scrise in limbajul C.
a) x=12; y=14; b) x=9; y=7; c) x=7; y=14; 5. Care dintre urmtoarele atribuiri sunt corecte? int a, b; float d; char c; a) c=5; b) d=a%b; c) a=d/3; d) a=(d<c); e) d=sqrt(a+b);
d) e)
6. Care dintre expresiile urmtoare sunt incorecte, tiind c operanzii care intervin sunt de tip ntreg? a) (a!=b) && (c<b) b) a+-3+b c) a-a/b (a-3) d) ! (a<b) e) b+%a 7. Care din urmtoarele afirmaii sunt adevrate? a) Un algoritm se execut de un numr finit de ori pentru orice set de date de intrare. b) Un algoritm prelucreaz numai datele de intrare, fr obinerea unor date intermediare. c) La analiza enunului unei probleme sunt identificate datele de intrare i cele de ieire. 8. tiind c x este o variabil folosit pentru citirea mai multor numere ntregi, cum va fi declarat aceasta? a) integer x; b) x=int; c) int x; d) char x; 9. tiind c variabila n va fi utilizat ntr-un program pentru a reine un numr ntreg cu maxim 10 cifre, care va fi varianta corect pentru declararea sa? a) int n; b) unsigned long n; c) unsigned n; d) long n;
75
Obiectivele Unitii de nvare 4 ....................................................................................76 4.1 Noiuni introductive ...................................................................................................76 4.2 Funcia de scriere cu format .....................................................................................77 4.3 Funcia de citire cu format ........................................................................................81 Rspunsuri corecte la testele de autoevaluare, sarcinile de lucru i exerciii ..........86 Bibliografie .......................................................................................................................87 Lucrarea de verificare Nr. 4, notat de tutore............................................................... 87
Identificai diferitele tipuri de formate ale variabilelor n operaiile de citire/scriere Comparai diversele metode de citire/scriere Efectuai operaii de citire/scriere pentru diverse tipuri de variabile
4.1
Noiuni introductive
S definim, mai nti, o noiune foarte des ntlnit n limbajul C, i anume cea de stream. Stream-ul reprezint un concept abstract ce definete orice flux de date de la o surs la o destinaie. Atunci cnd sursa este memoria intern, iar destinaia este un fiier oarecare, se spune c este un stream de ieire (pe scurt, ieire sau scriere). Atunci cnd sursa este un fiier oarecare, iar destinaia este memoria intern, se spune c este un stream de intrare (pe scurt, intrare sau citire). Un caz aparte de ieire este acela n care datele sunt scrise pe monitor, situaie n care fiierul poart o denumire standard: stdout, dup cum un caz aparte de intrare este acela n care datele se preiau de la tastatur fiier standard numit stdin. Cele dou fiiere (stdout i stdin) sunt atribuite automat oricrui program scris n C. De asemenea, ele sunt deschise automat la lansarea n execuie a programului i nchise atunci cnd execuia se termin. Din acest motiv, operaiile de intrare/ieire efectuate cu ajutorul lor poart denumirea de intrri/ieiri standard.
76
Aceste fiiere sunt privite ca fiiere de caractere (fiiere text), de aceea sunt necesare anumite conversii. n memoria intern, datele au o anumit reprezentare (float, int). Pentru a putea fi vizualizate (scrise pe monitor) este necesar conversia lor n iruri de caractere. Invers, la citire se introduc iruri de caractere, iar acestea trebuie convertite ctre tipul sub care se memoreaz. Conversiile se efectueaz sub controlul unor formate specifice. Prototipurile funciilor de citire/scriere standard se gsesc n biblioteca stdio.h (standard input/output).
4.2
n plus se pot folosi urmtoarele prefixe: l cu d, i, u, o, x, X urmeaz s afieze o dat de tip long; cu f, e, E, g urmeaz s afieze o dat de tip double;
Proiectul pentru nvmntul Rural
77
h cu d, i, u, o, x, X urmeaz s afieze o dat de tip short; L cu f, e, E, g urmeaz s afieze o dat de tip long double; De exemplu, %ld va afia o dat de tip long int, iar %hu va afia o dat de tip short unsignet int. Comenzile de format pot avea modificatori care specific dimensiunea cmpului, precizia, precum i un flag (indicator) pentru alinierea la stnga. Un ntreg plasat ntre simbolul procentului i comanda de format se comport ca un specificator al dimensiunii minime de cmp, care adaug datelor de ieire un numr de cmpuri libere sau zerouri, pentru a asigura lungimea minim. Dac irul sau numrul afiat este mai mare dect lungimea minim, atunci va fi afiat integral. Bordarea prestabilit se execut cu spaii. Pentru valori numerice, dac se dorete bordarea cu zerouri, se insereaz un zero naintea specificatorului dimensiunii de cmp. De exemplu, cmanda %05d nseamn zerouri naintea unui numr cu mai puin de cinci cifre. Exemplul 4.1 n urma executrii urmtorului program: main() { int num; num=12345; printf(%d\n, num); printf(%3d\n, num); printf(%10d\n, num); printf(%03d\n, num); printf(%010d\n, num); } vor rezulta urmtoarele modaliti de scriere a valorii numerelor: 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 0 0 0 0 0 1 2 3 4 5 Efectul modificatorului de precizie depinde de tipul comenzii de format pe care o determin. Pentru a insera un modificator de precizie se adaug un punct zecimal, urmat de precizia dorit, dup specificatorul dimensiunii de cmp. Pentru formatele e, E i f modificatorul de precizie determin numrul de cifre dup virgul. De exemplu, comanda %10.4f afieaz un numr de cel mult 10 cifre, cu 4 cifre dup virgul. Cnd este folosit specificatorul g sau G, precizia determin numrul maxim de cifre semnificative afiate. 78
Cnd modificatorul de precizie se aplic numerelor ntregi, acesta indic numrul minim de cifre ce vor fi afiate. Cnd modificatorul de precizie se aplic irurilor de caractere, numrul care urmeaz dup punct indic lungimea maxim a cmpului. De exemplu, comanda %5.7s afieaz un ir care are minimum cinci caractere lungime, dar nu mai mult de apte. Dac irul este mai lung dect lungimea maxim, caracterele din final sunt omise. Exemplul 4.2 main() { printf(%.4f\n,12.1234567); printf(%3.8d\n, 1000); printf(%10.8d\n,1000); printf(%10.15s\n, Acesta este un text); printf(%10.15s\n, PROGRAM); printf(%3.1d\n,1000); } n urma execuiei acestui program, se va afia: 1 2 3 . 1 2 3 5 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 A c e s t a e s t e u n P R O G R A M 1 0 0 0 Toate datele de ieire, n mod implicit, sunt aliniate la dreapta, adic, dac limea cmpului este mai mare dect datele afiate, datele se plaseaz lng marginea din dreapta a cmpului. Se poate fora alinierea la stnga a informaiei prin plasarea unui semn - imediat dup simbolul procentului. De exemplu, comanda %-10.2f aliniaz la stnga, ntr-un cmp de 10 caractere, un numr n virgul mobil cu dou cifre dup virgul. Exemplul 4.3 Acest exemplu scoate n eviden diversele faciliti oferite de funcia printf() referitoare la diversele formate ale afirii. main() { float val; val=10.12304; printf(%8.1f%8.1f\n, 12.3,525.7); printf(%-8.1f%-8.1f\n, 12.3,525.7); printf(%f\n, val); printf(%5.2f\n, val);
Proiectul pentru nvmntul Rural
79
printf(%10f\n, val); printf(%012f\n, val); printf(%-10f\n, val); printf(%-012f\n, val); } n urma executrii acestui program, rezultatele vor fi afiate astfel: 1 2 1 2 . 5 1 0 . 1 2 3 1 0 . 1 2 1 0 . 1 2 0 0 0 1 0 . 1 0 . 1 2 3 1 0 . 1 2 3 . 5 5 2 5 0 4 0 3 1 0 0 0 2 4 4 5 2 5 . 7 . 7
4 0 3 0 4 0 0 0 0 0 0
80
4.3
n acest program, pe lng funcia scanf(), mai apar dou alte elemente noi: - operatorul de multiplicare (*) - operatorul adres (&). Pentru moment trebuie reinut faptul foarte important c funcia scanf() cere utilizarea simbolului adres - & - naintea numelui fiecrei variabile. Specificare formatelor pentru funcia scanf() este similar, cu mici excepii, cu cea pentru funcia printf(); de exemplu, nu sunt acceptate formatele %i i %g. Funcia scanf() poate accepta, n acelai timp, mai multe intrri de date de tipuri diferite. Exemplul 4.5 main() { int ev; float timp; char poz; printf(Introduceti poz, ev,timp: ) scanf(%c %d %f, &poz, &ev, &timp); printf(Evenimentul %c are numarul %d,poz,ev); printf( si a avut loc la %f timp.,timp); } Valori i spaii introduse de utilizator
12.30
poz ev
timp
12.30
Figura 4.1
82
n urma execuiei acestui program se va putea afia, n funcie de valorile introduse: Introduceti poz, ev,timp: M 5 12.30 Evenimentul M are numarul 5 si a avut loc la 12.30. Variabilele poz, ev, timp au fost introduse de la consol. Separarea lor corect la introducere se poate face numai prin spaiu (blank), return sau tab, orice alt separator (linie, virgul) nerealiznd aceast separare. Se pot introduce datele i separate prin (;) dac n funcia scanf() se specific aceasta n mod expres (ntre simbolurile de formate se va pune (;)). n figura 4.1 se explic cum lucreaz funcia scanf(). Specificatorul de format precizeaz modul n care se interpreteaz datele de intrare i are forma general: %[*] [latime] [h | l | L] tip_conversie Caracterul % marcheaz nceputul unui specificator de format; Caracterul * are rolul de a determina citirea cmpului de intrare cu specificatorul de format din care face parte, fr ca aceast valoare s fie memorat; cmpul citit astfel nu este numratn cadrul valorii ntoarse de funcia scanf() latime precizeaz numrul maxim de octei din cmpul de intrare care vor fi citii; tip_conversie indic natura conversiei. Principiul de execuie a funciei scanf() Se analizeaz cele dou iruri de caractere, i anume irul transmis ca parametru funciei i irul de caractere pe care l tastm. Pentru fiecare din ele ne imaginm o sgeat (pointer) care indic unul din caracterele irului. Iniial, pentru fiecare din iruri, sgeata indicprimul caracter. n cadrul irului parametru, un caracter poate fi: I. un caracter oarecare, care nu este alb i nu este %; II. caracterul este alb; III. caracterul este %. I Se testeaz existena n irul de intrare a caracterului respectiv (de exemplu, dac caracterul este 3, se testeaz existena n irul de intrare a acestui caracter -3-). Exist dou posibiliti: n irul de intrare este gsit acest caracter, caz n care pointerul sgeata avanseaz n ambele iruri cu cte un caracter; nu este gsit acest caracter n irul de intrare, caz n care citirea este ntrerupt, iar funcia returneaz numrul de cmpuri citite i convertite pn n acel moment. II Pointerul indic n irul parametru un caracter alb. Se analizeaz caracterul indicat n irul de intrare, existnd de asemenea dou posibiliti:
83
este caracter alb; atunci se sare peste acesta i peste eventualele caractere albe care urmeaz; n irul parametru pointerul va indica primul caracter care nu este alb, iar n cel de intrare la fel; caracterul indicat de pointer n irul de intrare nu este alb; pointerul din irul de intrare rmne nemodificat, iar cel din irul parametru va avansa pn la primul caracter care nu este alb. III Pointerul indic caracterul %; n acest caz se testeaz dac secvena urmtoare ndeplinete condiiile de sintax ale unui specificator de format, iar n caz c acestea nu sunt ndeplinite, caracterul % este tratat ca unul oarecare. Altfel, se procedeaz n mod diferit n funcie de ce avem de citit: avem de citit un caracter c ; se citete caracterul respectiv i se memoreaz codul su, indiferent dac este alb sau nu. n irul parametru pointerul va indica primul caracter care nu corespunde specificatorului de format, iar n cel de intrare, caracterul urmtor; avem de citit o valoare numeric (ntreag sau real). Dac pointerul indic n irul de intrare un caracter alb, acesta este srit, ca i urmtoarele caractere albe, pn cnd este ntlnit un caracter diferit de caracterul alb. Se citete din irul de intrare, caracter cu caracter, pn cnd este ndeplinit una din condiiile: o se ntlnete un caracter care nu poate fi convertit ctre tipul respectiv (alb, o liter, etc.); o au fost citite un numr de caractere egal cu cel precizat de lime. n continuare se convertete irul citit ctre o variabil a crei adres a fost indicat. Dup citire, n irul parametru, pointerul va idica primul caracter care urmeaz specificatorului de format, iar n cel de intrare primul caracter nu a fost convertit. Punctul care indic prezena zecimalelor este un caracter care se numr. Citirea se ntrerupe dac nu a fost citit i convertit nici un caracter. Exemplul 4.6 Fie declaraiile : int a,b; Atunci: scanf(%d, &a); citete variabila a; scanf(%1d, &a); citete prima cifr a numrului tastat; variabila a va reine valoarea 3 dac a fost tastat 357; scanf(%1d %*1d %1d, &a, &b); citete prima i a treia cifr a numrului tastat; variabila a va reine valoarea 3, iar b valoarea 7 dac a fost tastat 357, cifra 5 este citit, dar nu este memorat; Exemplul 4.7 Fie declaraiile : char a,b; scanf(%c, &a); 84 Atunci: citete variabila a;
Proiectul pentru nvmntul Rural
scanf (%c %c,&a, &b); dac s-a tastat ebbbt unde b reprezint un blank atunci a va reine caracterul e, iar b caracterul t, deoarece cele dou formate de citire au fost separate prin spaiu; scanf (%c%c,&a, &b); dac s-a tastat ebbbt unde b reprezint un blank atunci a va reine caracterul e, iar b caracterul b, blank, deoarece cele dou formate de citire nu au fost separate prin spaiu; scanf (2%c,&a); dac s-a tastat 23, atunci a va reine caracterul 3, deoarece 2 este caracterul ateptat; dac s-a tastat 32, atunci a nu se citete, deoarece 2 este caracterul ateptat, nu 3.
3. Fie declaraiile: char a,b; int c; float d; Se consider instruciunea: scanf( %c%3d%c 12 %f, &a, &c, &b, &d); Ce valori vor reine variabilele a, b, c, d dac se citete: bbabb123412-41.7 a123b412-41.7
char s[20]; Care din declaraiile urmtoare citesc corect un ir de scanf(%c,s); scanf(%c,&s); scanf(%s,s); scanf(%s,&s); scanf(%,s); scanf(,s); 85
5. Fie declaraia: int a, b, c; Ce se ntmpl dac folosind pentru citire apelul: scanf(%2d%3d%4d, &a, &b, &c); se va introduce secvena de intrare 123456? Care va fi valoarea variabilelor dup aceast introducere?
Variantele corecte de rspuns se afl la pag. 85. n Laboratorul 3 din Anexe vei descoperi i alte modaliti de citire a datelor, specifice anumitor tipuri de variabile sau mediului de programare C++.
86
n cel de-al doilea caz vor rezulta valorile: a=a c=123 b= (blank) d nu mai este citit de ce? 4. c i d Vezi U4. 3 Funcia de scriere cu format pag. 39 5. scanf(%2d%3d%4d, &a, &b, &c); a=12 b=345 c=6 Testul de autoevaluare 4.3 1. 2. 3. 4. 5. F b d iostream.h 9, respectiv 5 Vezi Laboratorul 3 Vezi Laboratorul 3 Vezi Laboratorul 3 Vezi Laboratorul 3 Programul determin valoarea maxim dintre cele trei numere citite.
BIBLIOGRAFIE
1. Dorin Stoilescu, Manual de C/C++ - Cap.3 Intrri/Ieiri standard, Editura Radial, Galati, 1998. 2. Florin. Munteanu, Traian C. Ionescu, Daniela Saru, Gheorghe Musca, Sergiu Mihai Dascalu, Programarea calculatoarelor - manual pentru liceele de informatic Cap.17 Structura programelor n limbajul C. Tipuri de date, operatori i expresii, Editura Didactic i Pedagogic, Bucureti, 1995. 3. Valeriu Iorga si colectiv, Programare in C/C++. Culegere de probleme, Editura Niculescu, Bucureti, 2003. 4. Programe de specialitate elaborate de ctre Ministerul Educaiei i Cercetrii pentru nvmntul preuniversitar 5. Herbert Schildt, C manual complet Cap.8 Operaii de intrare/ieire pentru consol, Editura Teora, 2000 6. http://www. cs.umd.edu/users/cml/style/ - ghid privind stilul de programare in limbajele C si C++. 7. http://www.programmingtutorials.com tutoriale de programare pentru C, C++ precum si pentru alte limbaje. 8. http://www.snippets.org exemple de programe scrise in limbajul C.
87
a. start() b. system() c. main() d. program() 2. Ce semn de punctuaie este folosit pentru a semnaliza nceputul i sfritul unei secvene de program? a. { } b. -> and <c. BEGIN and END d. ( and ) 3. Care este semnul de punctuaie cu care se termin cele mai multe linii de program C/C++? a. . b. ; c. : d. ' 4. Care din urmtoarele rnduri reprezint un comentariu corect? a. */ Comentariu */ b. ** Comentariu ** c. /* Comentariu */ d. { Comentariu } 5. Care cuvnt din urmtoarele nu reprezint un tip corect de variabile? a. float b. real c. int d. double 6. Care din urmtoarele reprezint varianta corect a operatorului de comparare a egalitii a dou variabile? a. := b. = c. equal d. == 7. Scriei un program care s citeasc de la tastatur valoarea temperaturii de afar (un numr ntreg) i s afieze mesajul Este frig! dac este o temperatur negativ, Este placut azi afar dac temperatura este mai mic dect 20o C, respectiv Este o zi torida! dac temperatura depete ultima valoare. Se va folosi operatorul condiional. 8. Scriei un program care calculeaz i afieaz retribuia unui salariat n funcie de grupa de vechime n care se afl. Exist 3 grupe de vechime (1, 2, i 3). Retribuia se calculeaz cu relaia: retribuie=salariu +spor Sporul depinde de grupa de vechime i este egal respectiv cu 150, 250, 350. Grupa de vechime i salariul se introduc de la tastatur. Programul va folosi operatorul condiional.
88
Cuprins
Pagina
Obiectivele Unitii de nvare 5 .................................................................................. 89 5.1 Instruciunea expresie............................................................................................... 89 5.2 Instruciunea compus ............................................................................................. 90 5.3 Instruciunea if.......................................................................................................... 90 5.4 Instruciunea switch .................................................................................................. 93 5.5 Instruciunea break.................................................................................................... 94 5.6 Instruciunea while .................................................................................................... 94 5.7 Instruciunea do-while............................................................................................... 95 5.8 Instruciunea for ........................................................................................................ 97 Rspunsuri corecte la testele de autoevaluare, sarcinile de lucru ........................... 100 Bibliografie..................................................................................................................... 100 Lucrarea de verificare nr.5, notat de tutore............................................................... 101
5.1
Instruciunea expresie
Forma general: expresie; Efect: Se evalueaz expresia. Exemplul 5.1 i++; // se incrementeaz postfixat valoarea variabilei i a*=10; // se multiplic cu 10 valoarea variabilei a getchar(); // se citete un caracter
89
Observaii: expresie poate fi vid. Instruciunea devine instruciunea vid ; orice instruciune n C / C++ se termin cu ; este permis folosirea oricrei expresii sintactic corecte, chiar i atunci cnd instruciunea nu genereaz nici un efect. Exemplul 5.2 3*( 7-4);
5.2
Instruciunea compus
Forma general: { declaraii instruciune1; instruciune2; ... instruciune n; } Efect: Se execut n ordine instruciunile specificate. Observaii: Utilizarea instruciunilor compuse este necesar atunci cnd sintaxa permite executara unei instruciuni ( if, for, do-while, while) care efectueaz mai multe operaii. Declaraiile care apar ntr-o instruciune compus sunt locale instruciunii. Mai exact, ele sunt valabile numai n corpul instruciunii compuse, din momentul declarrii lor pn la sfritul instruciunii.
5.3
Instruciunea if
Forma general: if ( expresie) instruciune1 else instruciune2 Efect: Se evalueaz expresia Dac valoarea expresiei este diferit de 0, se execut instruciune1, altfel se execut instruciune2.
90
Exemplul 5.3 if (x) cout<<x<< nu este zero ; else cout<<x<<este zero; Observaii: expresie se ncadreaz ntre paranteze rotunde; ramura else poate s lipseasc dac instruciune2 este vid. Exemplul 5.4 S se calculeze maximul dintre a i b, unde a i b sunt dou variabile ntregi. # include <iostream.h> void main() { int a,b, max; cout<< a= cin>>a; cout<< b= cin>>b; max=a; if (max<b) max=b; cout<< maximul este<<max; } Exemplul 5.5 Se citesc a,b,c coeficienii reali ai ecuaiei de gradul II ax2+ bx+c=0. Se cere s se scrie un program care s rezolve ecuaia. Varianta 1: # include <iostream.h> # include <math.h> # include <conio.h> main() { flota a,b,c,d; cout<<a=; cin>>a; cout<<b=; cin>>b; cout<<c=; cin>>c; if (a) { d=b*b-4*a*c; if (d>=0) { cout<<x1=<<(-b+sqrt(d))/(2*a)); cout<<x2=<<(-b-sqrt(d))/(2*a));} else cout <<x1 si x2 nu sunt reale; } else if (b) cout<<x=<<(-c/b); else if(c==0) cout<<infinitate de soluii; else cout<< ecuaia nu are soluii; }
Proiectul pentru nvmntul Rural
91
Observaii: 1. funcia rdacin ptrat sqrt() are prototipul n math.h; 2. clrscr() are prototipul n conio.h i are funcia de tergere 3. varianta 2 a programului folosete operatorii condiionali ? : O alt variant de rezolvare a acestei probleme este prezentat n laboratorul corespunztor acestui capitol. Test de autoevaluare 5.1
Alege, prin ncercuire, varianta corect de rspuns pentru urmtoarele teste. Rspunsul pentru fiecare cerin valoreaz 25 de puncte. Punctaj minim: 75. 1. Care din urmtoarele secvene de instruciuni atribuie variabilei reale k cea mai mare dintre valorile variabilelor a i b sau valoarea lor comun, dac acestea sunt egale: a) if (a<=b) k=a; else k=b; b) if (a<=b) k=b; else k=a; c) if ( a==b) k=a; else if (b>a) k=b; d) k=a; if (k<b) k=b; 2. Se consider secvena de program: x=1; if ( ! (a<b) || !(a<=c) if (b>=c) cout <<(-x); else if (b<c) cout<<x; Pentru care dintre tripletele de valori ale variabilelor a,b,c se va afia valoarea 1? a) b) c) d) a=3, b=2, c=4 a=2, b=3, c=4 a=4, c=3, c=2 a=2, b=4, c=3
3. Dac a i b sunt variabile de tip int, iar x i z sunt variabile de tip float, stabilii care dintre secvenele de instruciuni sunt corecte: a) b=0; if (a>b) b=a/2; b) a=8; b=10; c) a:=5; b:=5; if (a==b) x=y; 4. Care dintre instruciunile urmtoare sunt incorecte sintactic, tiind c operanzii care intervin sunt de tip ntreg? a) if ( abs(3==3) cout<< ok; b) if ( a%3=b) cout<< zz; c) if ( (b+a)/2) cout<< yy; d) if (!1) cout<<hm; Variantele corecte de rspuns se afl la pag. 99.
92
5.4
Instruciunea switch
Forma general: switch (expresie) { case constanta1: secvena instruciuni1 case constanta2: secvena instruciuni2 ... case constantan: secvena instruciunin default: secvena instruciunin+1 } Efect: Se evalueaz expresie; Se compar succesiv valoarea ei cu valorile expresiilor constante care eticheteaz alternativele case. Dac se ntlnete o alternativ case etichetat cu valoarea expresiei, atunci se execut secvena de instruciuni corespunztoare i toate secvenele de dup aceasta, pn la ntlnirea instruciunii break sau pn la sfritul instruciunii switch. Dac nici una dintre valorile etichetelor alternative case nu coincide cu valoarea expresiei, atunci se execut secvena de instruciuni de pe ramura default. Exemplul 5.6 switch (x) { case *: a*=b; break; case /: a/=b; break; case +: a+=b; break; case -: a-=b; break; default: cout << eroare!; } n funcie de valoarea variabilei char c (*, /, +, -) vom efectua operaia corespunztoare ntre variabilele a i b. Dac variabila c are orice alt valoare, vom da mesajul eroare! Observaii: Expresia se ncadreaz obligatoriu ntre paranteze rotunde. Dac secvena de instruciunin+1 este vid, ramura default poate lipsi. Instruciunea switch este o generalizare a lui if. Spre deosebire de instruciunea if, care permite selectarea unei alternative din maxim dou posibile, switch permite selectarea unei alternative din maximum n+1 posibile.
93
5.5
Instruciunea break
Forma general: break; Efect: Determin ieirea necondiionat din instruciunea switch, while, for sau do-while n care apare.
5.6
Instruciunea while
Forma general: while (expresie) instruciune Efect: 1. se evalueaz expresie; 2. dac valoarea expresiei este 0, se iese din instruciunea while, altfel, dac valoarea este diferit de 0, se execut instruciune i apoi se revine la pasul 1. Exemplul 5.7 S calculm rsturnatul numrului natural n. Ex: rsturnatul lui 821 este 128. 1 2 3 4 Linia 1 2 3 4 2 3 4 2 3 4 2 x=0; // n x obin rsturnatul lui n while (n) { x=x*10+n%10; // adaug ultima cifr din n la x n/=10; // elimin ultima cifr din n } Efect Se iniializeaz x cu 0 Se testeaz dac n este diferit de 0 Se adaug la x ultima cifr a lui n Se elimin ultima cifr din n Se testeaz dac n este diferit de 0 Se adaug la x ultima cifr a lui n Se elimin ultima cifr din n Se testeaz dac n este diferit de 0 Se adaug la x ultima cifr a lui n Se elimin ultima cifr din n Se testeaz dac n este diferit de 0; se iese din while n 821 821 821 82 82 82 8 8 8 0 0 x 0 0 1 1 1 12 12 12 128 128 128
94
Observaii: instruciunea se execut repetat ct timp valoarea expresiei este nenul. Dac expresia are de la nceput valoarea 0, instruciune nu se execut nici macar o dat. Sintaxa permite executarea n while a unei singure instruciuni, prin urmare, atunci cnd este necesar efectuarea mai multor operaii, acestea se grupeaz ntr-o instruciune compus.
Sarcin de lucru 5.1 Scrie un program C/C++ care s calculeze xn, unde n este un numr natural i x un numr real. Barem: declaraii corecte 10 puncte citirea corect a valorilor variabilelor calculul corect al puterii utilizarea corect a instruciunii while afiarea corect a rezultatului din oficiu total Indicaie: x0=1 xn= x * x ** x=x*(x * x ** x) de n ori de n-1 ori 10 puncte 50 puncte 10 puncte 10 puncte 10 puncte 100 puncte
5.7
95
Exemplul 5.8 S numrm cifrele numrului natural memorat n variabila n. Ex: n=1663 are k=4 cifre. k=0; // n k obin numrul de cifre do { n/=10; // elimin ultima cifr a lui n k++; // numr cifra } while (n); // repet algoritmul ct timp n are cifre Observaii: instruciunea do-while execut instruciunea specificat cel puin o dat, chiar dac de la nceput valoarea expresiei este 0, deoarece evaluarea expresiei se face dup executarea instruciunii. Sarcina de lucru 5.2 Se consider urmtorul program: #include< iostream.h> void main() { int a,b, nr=0, i; cout<< a=;cin>>a; cout<< b=;cin>>b; i=a; while (i<=b) { if (i%2==0) nr++; i++; cout<<nr=<<nr;} a) Ce va afia pe ecran pentru a=5 i b=8? b) Scrie un program echivalent, care s utilizeze instruciunea do-while. c) Care este efectul acestui program? Barem: a) b) c) total 10 puncte 30 puncte 10 puncte 50 puncte
5.8
Instruciunea for
Forma general: for ( expresie iniializare; expresie continuare; expresie reiniializare) instruciune
96
Efect: 1. se evalueaz expresia de iniializare; 2. se evalueaz expresia de continuare; 3. daca valoarea expresiei de continuare este 0, se iese din instruciunea repetitiv for; dac valoarea expresiei de continuare este diferit de 0, atunci se execut instruciune, se evalueaz expresia de reiniializare i se revine la pasul 2. Observaii: instruciunea for este o instruciune repetitiv, ca i while i dowhile; ea poate fi simulat cu ajutorul instruciunii while astfel: expr1; while (expr2) { instruc iune; expr3; }
Exemplul 5.9 S se calculeze factorialul numrului natural n. n!= 1 2 3 n fact=1; for(i=1;i<=n;i++) fact*=i; pentru n=4 i 1 2 3 4
Proiectul pentru nvmntul Rural
Test de autoevaluare 5.2 Alege, prin ncercuire, varianta corect de rspuns pentru urmtoarele teste. Rspunsul pentru fiecare cerin valoreaz 25 de puncte. Punctaj minim: 75. 1.Ce valoare va avea variabila x dup executarea instruciunilor urmtoare? x=4; while(x<7) x+=2; for(i=1;i<=x;i++) x+=1; a) 4 for. b) 16 c) 10 d) 8 e)9 f) x are o valoare necontrolat datorit instruciunii
2.Ce se obine n urma rulrii secvenei urmtoare: cin>>n; cif=2; for(int i=3;i<=n;i++) // I declarat local in instructiunea for { cif*=i; while(cif%10==0) cif/=10; cif%=10; } cout<<cif; a) calculeaz ultima cifr a lui n! b) calculeaz ultima cifr nenul a lui n! c) Calculeaz n! d) Determin numrul de cifre a lui n! 3.Care va fi valoarea variabilei p dup execuia secvenei: p=1; for(i=1;i<=n;i++) { s=0; for(j=1;j<=i; j++) s+=j; p*=s; } a) 180 b) 18 c) 9
d) 216
e)1
4.Pentru afiarea numerelor naturale 1,2,n , unde n este dat, propun urmtoarele secvene de program: a) for(i=1;i<=n;i++); cout<<i; b) for(i=1;i<=n;i++) cout<<i; Care din afirmaiile de mai jos este adevrat? i) nici una din secvene nu ndeplinete cerina problemei. ii) Ambele secvene ndeplinesc cerina problemei iii) Secvena a) conine erori de sintax 98
Proiectul pentru nvmntul Rural
iv) v)
Exemplul 5.11 irul Fibonacci Fie irul 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, ... . Fie n un numr natural citit de la tastatur. S se scrie un program care afieaz cel de-al n-lea termen din irul lui Fibonacci. Observ c pentru a calcula un termen Fibonacci am nevoie de doi termeni precedeni. Voi folosi variabilele f0, f1, f2; n f0 i f1 voi reine doi termeni consecutivi din ir i n f2 voi calcula termenul urmtor f2=f1+f0. La iteraia i a ciclului for voi calcula al i-lea termen Fibonacci. #include<iostream.h> void main() { int i, n, f0, f1, f2; cin>>n; f0=1; f1=1; //iniializarea primilor doi termeni for ( i=2;i<=n;i++) { f2=f1+f0; // calculez termenul curent f0=f1; /* reiniializez variabilele care definesc doi termeni f1=f2; consecutivi n ir */ } cout<< cel de-al<<n<< termen Fibonacci este<< f2; }
99
Soluiile sarcinilor de lucru 5.1 i 5.2, ca i a problemelor propuse pentru laboratorul corespunztor se gsesc n cadrul laboratorului 4.
Bibliografie
1. Cerchez, Emanuela, Informatic. Culegere de probleme pentru liceu, Editura Polirom, Iai, 2002. 2. Cerchez, Emanuela, erban, Marinel, Programarea n limbajul C-C++ pentru liceu, Cap 2 Instruciunile limbajului C / C++, Editura Polirom, Iai, 2005 3. Cormen, Thomas, Introduction in Algorithms, Cap 1 Fundamente Matematice, The Massachussets Institute of Technology, 1990.
100
10 puncte 15puncte 15 puncte 15 puncte 5 puncte declaraii corecte 15 puncte 5 puncte cutarea secvenei 13 n numr 5 puncte afiarea rezultatului 5 puncte declaraii corecte 5 puncte verificarea respectrii regulilor de 15 puncte construire a sirului 5 puncte afiarea rezultatului 5 puncte declaraii corecte 15 puncte 5 puncte determinarea divizorilor care sunt primi 5 puncte afiarea rezultatului 100 puncte
Aplicaia 6
Aplicaia 7 Total
Punctaj minim: 70 puncte. 1. Se consider urmtorul algoritm: k=1; while(n<=1000) { n*=2; k++; } cout<<k; Care este cea mai mare valoare posibil pentru variabila n astfel nct algoritmul s afieze valoarea 5? a) 10 b)3 c)6 d)7 e)1 f)12
2. Dac a i b sunt variabile de tip int, stabilete care din urmtoarele structuri repetitive sunt ciclri infinite: c) a=0; b==10; a) a=10; b=0; while((a<=10)&&(b>=0)) do{ { b++;a++;} a--;b++; }while (a!=b); b) a=1; b=5; d) a=0; b=10; while ((a<=10)||(b>=0) while(a+b<=10) {b++;a++;} { a=a+2; b=b-2;}
101
3. Fie programul: #include<iostream.h> void main() { int a,b,u,aux; cin>>a>>b; if(a<b) {aux=a;a=b;b=aux;} u=0; while(a>=b) {u++;a-=b;} cout <<u; } Pentru a=2572 i b=13 programul va afia: a) 11 b)91 c)197 d)13 e)199 4. Alegei varianta corect dac n (natural) este par: unsigned int n; a) if(n>0) if(n%2) cout<<n par; b) if(n>0) if(n/2==0) cout<<n par; c) if(n>0) if(n/2) cout<<n par; d) if(n>0) if(!(n%2)) cout<<n par; 5. Se d un numr natural n. S se scrie un program C/ C++ care s determine dac numrul conine n scrierea lui secvena 13. Ex: numrul 171310 conine secvena 13, iar numrul 171032 nu conine secvena 13.
6. Se citesc de la tastatur numere ntregi pn la introducerea numrului 0. S se verifice printr-un program dac numerele introduse se succed nti cresctor i apoi descresctor ( ) sau nti descresctor i apoi cresctor ( ). Proprietatea trebuie s fie ndeplinit pe ntreaga niruire de numere. Ex: pentru sirul 1, 5, 8, 9,11,21, 15, 13, 10,3, 0 proprietatea este ndeplinit. Nu i pentru irul 3, 5, 6, 11, 10, 8, 13, 15, 0.
7. S se scrie un program care citete de la tastatur un numr natural n i tiprete toi divizorii lui care sunt numere prime. Ex: pentru n=70, se vor tipri 1, 2, 5 i 7.
102
Tablouri
Cuprins
Pagina
Obiectivele Unitii de nvare 6 ................................................................................ 103 6.1 Tablouri unidimensionale ....................................................................................... 104 6.2 Pointeri ..................................................................................................................... 111 6.3 iruri de caractere .................................................................................................. 115 Rspunsuri corecte la testele de autoevaluare, sarcinile de lucru i exerciii ........ 121 Bibliografie..................................................................................................................... 121 Lucrarea de verificare Nr. 6, notat de tutore ............................................................. 122
Identificai diferitele tipuri de variabile structurate Comparai operaiile cu pointeri cu celelalte tipuri de operaii Efectuai diverse operaii cu variabile de tip tablou Efectuai diverse operaii cu variabile de tip ir de caractere Alegei tipul de variabil potrivit rezolvrii unei probleme
Tipurile de date descrise anterior sunt tipuri simple. Pe baza acestora se pot construi tipuri derivate: tablouri, structuri i fiiere Un tablou (array) este un ansamblu de variabile de acelai tip la care se face referire folosindu-se un acelai nume. Un anume elemant dintr-un tablou este indicat prin intermediul unui indice (index). n C, toate tablourile sunt alctuite din locaii de memorie nvecinate. Adresa de memorie cea mai mic corespunde primului element, iar adresa cea mai mare corespunde ultimului element. Tablourile pot avea de la una la mai multe dimensiuni. Tabloul cel mai des folosit n C este irul string, care este un tablou de caractere care se ncheie cu un zero. Acest mod de a privi irurile confer limbajului C mai mult putere i eficien fa de alte limbaje. n cadrul limbajului C, tablourile i pointerii sunt legai printr-o relaie strns, abordarea tablourilor necesitnd elemente de adresare, deci referire la pointeri.
103
Tablouri
unde tip_de_baza reprezint tipul tabloului, adic al fiecrui element inclus n tablou, iar dimensiune definete numrul de elemente coninute n tablou. Un element al tabloului este accesat folosind ca index poziia elementului, astfel tabloul_meu[6] va referi al aptelea element al tabloului tabloul_meu. Atenie! n C, "numerotarea" elementelor tablourilor ncepe cu poziia 0, astfel, dac avem definiia:
int tabloul_meu[100];
tabloului
va
fi
tabloul_meu[0],
iar
ultimul
Tablourile sunt stocate n memorie la locaii consecutive, un tablou ocupnd o zon contigu de memorie, cu primul element al tabloului aflat la adresa mai mica. Atentie! O problem legat de tablouri este c n C nu se face nici o verificare legat de "marginile" tabloului, astfel c se pot accesa greit elemente din afara tabloului. De exemplu, pentru definia:
int tabloul_meu[100];
dac accesm tabloul_meu[105] nu se va semnala nici o eroare, returnndu-se valoarea de la o locaie de memorie aflat la o distan de 5 locaii fa de sfritul tabloului, fapt ce va duce la comportri "bizare" ale programului. Aceeai situae, dar fa de nceputul tabloului, se ntmpl la accesarea tabloul_meu[-5]. Prelucrrile de tablouri se implementeaz de obicei prin structuri repetitive for, deoarece se cunoate aprioric numrul de iteraii. Exemplul 6.1 n urma executrii urmtorului program: main() {int a[20], n, i, min, max; printf(Introduceti dimensiunea tabloului:); 104
Proiectul pentru nvmntul Rural
Tablouri
scanf(%d, &n); for (i=0; i<n; i++) {printf(a[%d]=, i); scanf(%d, &a[i]); } min=max=a[0]; for (i=1; i<n; i++) if (a[i]>max) max=a[i]; else if (a[i]<min) min=a[i]; printf(minim=%d\tmaxim=%d\n, min,max);} se vor determina valorile minime i maxime dintr-un vector (tablou unidimensional) cu n componente. Mai nti este citit valoarea lui n i apoi sunt citite componentele vectorului cu ajutorul unei instruciuni for. Se iniializeaz cele dou variabile min i max, corespunztoare celor dou valori cerute, cu primul element al vectorului, a[0]. n continuare, fiecare element al vectorului a[i] este comparat mai nti cu valoarea maxim curent; dac este mai mare dect aceasta, variabila max i schimb valoarea max=a[i]; - , n caz contrar acesta este comparat cu valoarea minim curent; dac este mai mic dect aceasta, variabila min i schimb valoarea min=a[i]; Exemplul 6.2 Se citete un ir de n numere naturale de la tastatur i un alt numr natural x. Se afl acest numr printre componentele vectorului? n caz afirmativ, de cte ori a fost gsit? S se afieze un mesaj corespunztor fiecrei situaii. main() {unsigned int a[20], n, i, f, x; printf(Introduceti dimensiunea tabloului:); scanf(%ud, &n); for (i=0; i<n; i++) {printf(a[%ud]=, i); scanf(%ud, &a[i]); } printf(x=); scanf(%ud, &x); f=0; for (i=0; i<n; i++) if (a[i]==x) f++; if (f==0) printf(numarul %ud nu se afla in vector\n, x); else printf(numarul %ud se afla in vector, aparand de %ud ori\n, x,f);}
Proiectul pentru nvmntul Rural
105
Tablouri
Iniializarea tablourilor se face prin semnul = dup declaraia tabloului, urmat de o list de valori iniiale, separate prin virgule, care se include ntre acolade. De exemplu: int a[4]={1,2,3,4}; char s[5]={a, b, c, d, \0}; Dac lista de valori iniiale cuprinde mai puine date dect dimensiunea declarat a tabloului, celelalte valori se iniializeaz cu zero. De exemplu, n urma declaraiei: int a[20]={1,-2,3,-4,5}; elementele a[4], a[5], ,a[19], vor conine valoarea zero. n cazul unui tablou iniializat, se poate omite dimensiunea, caz n care ea este calculat implicit de ctre compilator, dup numrul de elemente din lista de iniializare. De exemplu, declaraia: float z[]={1.0, 2.7, -3.3, 4.0, -5.5}; indic faptul c z este un tablou de numere reale, cu 5 elemente, iniializate cu elementele din list. Exemplul 6.3 Un exemplu de aplicaie foarte des ntlnit este urmtoarea: s se ordoneze componentele vectorului n ordine cresctoare. Exist mai muli algoritmi de sortare, dintre care se pot aminti: sortarea prin interschimbare, sortarea prin selecia valorii minime sau maxime, sortarea prin numrare, sortarea prin inserie sau bubble sort. Algoritmul de sortare prin interschimbare este unul din cei mai simpli algoritmi de sortare, dar nu i cel mai eficient. Acesta are la baz urmtoarea metod de sortare: fiecare element din vector a[i], 0<=i<n-1, este comparat cu toate elementele situate n vector dup el, a[j], i<j<n;n cazul n care cele dou elemente nu sunt n ordinea dorit, acestea se vor interschimba. main() {int a[20], n, i, j, aux; .................................... for (i=0; i<n-1; i++) for (j=i+1, j<n; j++) if (a[i]>a[j]) {aux=a[i]; a[i]=a[j]; a[j]=aux; } . } 106
Proiectul pentru nvmntul Rural
Tablouri
Dac vectorul a coninea la nceput elementele: 7, 2, 9, 1, 3, iat civa pai din execuia algoritmului: i=0, j=1 este a[0]>a[1]? da, deci se vor interschimba primele 2 elemente: a devine: 2, 7, 9, 1, 3 i=0, j=2 este a[0]>a[2]? nu, deci nu se ntmpl nimic; i=0, j=3 este a[0]>a[3]? da, deci se vor interschimba elementele a[0] i a[3]: a devine: 1, 7, 9, 2, 3 i=0, j=4 este a[0]>a[4]? nu, deci nu se ntmpl nimic; Se trece la urmtoarea valoare pentru i, deoarece for-ul pentru j s-a terminat: i=1, j=2 este a[1]>a[2]? nu, deci nu se ntmpl nimic; i=1, j=3 este a[1]>a[3]? da, deci se vor interschimba elementele a[1] i a[3]: a devine: 1, 2, 9, 7, 3 .. n final, componentele vectorului vor fi: 1, 2, 3, 7, 9 O metod de sortare mai eficient i foarte des folosit este bubble sort, sau sortarea prin metoda bulelor. Aceast metod presupune parcurgerea vectorului i compararea elementelor alturate (a[i] i a[i+1]); dac ele nu respect ordinea dorit, i vor interschimba valorile. Vectorul va fi parcurs de attea ori, pn cnd va fi sortat, adic nu se va mai efectua nici o interschimbare de valori. n acest scop va fi folosit o variabil de tip ntreg, care s in minte dac s-au mai efectuat interschimbri. Secvena de algoritm corespunztoare este: main() {int a[20], n, i, aux, gata=0; .................................... while (!gata) { gata=1; for (i=0; i<n-1; i++) if (a[i]>a[i+1]) {aux=a[i]; a[i]=a[i+1]; a[i+1]=aux; gata=0; } } . } Dac vectorul a coninea la nceput aceleai elemente: 7, 2, 9, 1, 3, iat civa pai din execuia algoritmului: gata=0, atta timp ct gata este zero:
Proiectul pentru nvmntul Rural
107
Tablouri
gata =1 i=0 este a[0]>a[1]? da, deci se interschimb cele dou valori i gata devine zero; a devine: 2, 7, 9, 1, 3 i=1 este a[1]>a[2]? nu, deci nu se ntmpl nimic; i=2 este a[2]>a[3]? da, deci se interschimb cele dou valori i gata rmne zero; a devine: 2, 7, 1, 9, 3 i=3 este a[3]>a[4]? da, deci se interschimb cele dou valori i gata rmne zero; a devine: 2, 7, 1, 3, 9 Se reia structura while, deoarece gata este zero: gata =1 i=0 este a[0]>a[1]? nu, deci nu se ntmpl nimic; i=1 este a[1]>a[2]? da, deci se interschimb cele dou valori i gata devine zero; a devine: 2, 1, 7, 3, 9 i=2 este a[2]>a[3]? da, deci se interschimb cele dou valori i gata rmne zero; a devine: 2, 1, 3, 7, 9, i=3 este a[3]>a[4]? nu, deci nu se ntmpl nimic; Se reia structura while, deoarece gata este zero: gata =1 i=0 este a[0]>a[1]? da, deci se interschimb cele dou valori i gata devine zero; a devine: 1, 2, 3, 7, 9 i=1 este a[1]>a[2]? nu, deci nu se ntmpl nimic; i=2 este a[2]>a[3]? nu, deci nu se ntmpl nimic; i=3 este a[3]>a[4]? nu, deci nu se ntmpl nimic; Se reia structura while, deoarece gata este zero: gata =1 Se mai parcurge o dat vectorul, dar nu se mai efectueaz nici o intershimbare, cci acesta este ordonat cresctor. Condiia de meninere n structura repetitiv nu mai este ndeplinit i algoritmul se ncheie. Exemplul 6.4 Se consider un vector cu n componente numere ntregi, ordonate cresctor i un numr ntreg x. S se determine dac acest numr se afl printre componentele vectorului, iar n caz afirmativ, poziia sa n vector. Pentru acest exemplu s-ar putea folosi ca metod de rezolvare algoritmul prezentat n cazul exemplului 6.2, dar nu ar fi o metod eficient, deoarece nu se ine cont de faptul c vectorul este deja ordonat cresctor; prin urmare, cnd numrul x este comparat cu un element din vector a[i], se pot lua mai multe decizii; dac numrul x este egal cu a[i], atunci se poate spune c numrul se afl n vector pe poziia i; dac x este mai mic dect a[i], se poate deduce c acesta se poate afla pe poziiile mai mici dect i, respectiv pe poziiile mai mari dect i, n caz contrar. n Laboratorul 5 este prezentat algoritmul cutrii binare, care rspunde cerinelor acestei probleme.
108
Tablouri
2. Se citete un ir de numere ntregi pn la introducerea valorii zero. S se formeze doi vectori: unul cu numerele pare introduse, iar cellalt cu cele impare. S se afieze coninuturile celor doi vectori. Exemplu: numerele introduse sunt: 7, -5, 8, 1, 2, -6, 3, 0 cei doi vectori vor fi: a[0]=8, a[1]=2, a[2]=-6 b[0]=7, b[1]=-5], b[2]=1, b[3]=3
3. Se citete un numr natural de maxim 10 cifre. S se introduc cifrele numrului ntr-un vector. Exemplu: dac n= 725943 atunci v[0]=3, v[1]=4, v[2]=9, v[3]=5, v[4]=5, v[5]=2 i v[6]=7.
4. Pentru vectorul obinut la problema anterioar, s se permute circular la dreapta cu o poziie componentele vectorului, pn cnd acesta revine la forma iniial. Exemplu: v={3, 4, 9, 5, 2, 7} vor rezulta pe rnd: v={7, 3, 4, 9, 5, 2} v={2, 7, 3, 4, 9, 5} v={3, 4, 9, 5, 2, 7}
109
Tablouri
5. Se dau n (1<n<=100) numere naturale reinute ntr-un vector. S se ordoneze cresctor componentele pare ale vectorului, cele impare rmnnd pe locul lor. Exemplu: n=8; v={4, 7, 14, 8, 3, 2, 10, 5} dup prelucrare, va deveni: v={2, 7, 4, 8, 3, 10, 14, 5}
110
Tablouri
6.2 Pointeri
Pointerii sunt variabile care conin (sunt capabile s conin) adresele unor altor variabile sau obiecte, deci practic adrese de memorie. Dimensiunil pointerilor (ci octei ocup) depind de main, de implementarea limbajului, etc. n general, acest aspect trebuie luat n consideraie doar din punct de vedere al portabilitii programelor; un program bun nu trebuie s depind de dimensiunile concrete ale pointerilor i, n general, s funcioneze corect pe orice implementare a limbajului care respect standardul ANSI. Un pointer este asociat unui tip de variabile: exist pointeri ctre char, int, float etc. Dac T este un tip de date standard sau definit de utilizator, un pointer ctre tipul T se declar prin: T *p; Iat cteva exemple de declaraii de pointeri: int *pi; float *pf; char *pc; ceea ce nseamn c pi este un pointer ctre ntreg, pf este un pointer ctre float (real), iar pc unul ctre caracter. Se pot declara mai muli pointeri pe acelai rnd, mpreun cu variabile de acelai tip, fiecare variabil de tip pointer trebuind s fie precedat de simbolul *: char *pc, c, *pa, a; n aceast situaie, pc i pa sunt pointeri la char, iar a i c sunt variabile de tip char. Pentru variabilele de tip pointer exist doi operatori specifici, i anume: operatorul de refereniere & sau de adresare operatorul de derefereniere * sau de indirectare. Operatorul de adresare & se aplic unei variabile, furniznd adresa variabilei. Dac variabila este de tip T, atunci operatorul & ntoarce tipul de date T*, adic pointer ctre T. Astfel, operatorul & este un prim mod i cel mai important de a obine adrese de variabile sau obiecte. Urmtoarea secven de program: char *pc, c; pc=&c; determin ca, n urma atribuirii, pc s conin adresa variabilei c. Accesul la o variabil (obiect) prin intermediul pointerilor se face cu operatorul de indirectare *. Dac p este un pointer de tip T*, atunci *p este prin definiie obiectul de tip T, aflat la adresa p. n exemplul de mai sus, *pc este variabila de tip char, aflat la adresa pc, adic tocmai variabila c. Avem astfel dou moduri de acces la variabila c: prin specificarea numelui ei i prin intermediul pointerului pc, care a fost poziionat pe c. Cei doi operatori, & i * sunt operatori inveri: dac x este de tip T1 i px este de tip T2*, atunci *(&x) este identic cu x i &(*px) este identic cu px. n concluzie:
Proiectul pentru nvmntul Rural
111
Tablouri
pointerii reprezint adrese ale unor zone de memorie; putem avea acces la acele zone prin operatorul *; dimensiunea i semnificaia unei zone indicate de un pointer depinde de tipul pointerului. Observaie: dac pointerul p indic o variabil x, atunci expresia *p poate aprea n orice context n care este permis apariia lui x. Exemplul 6.5 Iat un exemplu n care un pointer indic obiecte diferite pe parcursul execuiei programului: main() { int i=1, j=5, *p=&i; *p=2; (*(p=&j))++; printf(i=%d j=%d\n,i ,j); } Se declar variabilele ntregi i i j, iniializate cu 1, respectiv 5, i o variabil p de tip pointer ctre int, iniializat cu adresa lui i. Prin intermediul lui p, se atribuie practic lui i valoarea 2 (*p=2;) i apoi se atribuie lui p adresa lui j, dup care se incrementeaz coninutul lui p, adic variabila j. Astfel programul va tipri:i=2 j=6. Exemplul 6.6 S analizm programul de mai jos: #include <stdio.h> main() { int a=59; printf(a are adresa %p si continutul %d\n,&a, a); int *adr1=&a; printf(adr1 are adresa %p si continutul %p\n,&adr1, adr1); int **adr2=&adr1; printf(Variabila adr1 are adresa %p si continutul %p\n,&adr2, adr2); printf(%p %p %p %d, &adr2, adr2, *adr2, **adr2); } Se declar o variabil a, de tip int, care reine numrul 59. Se tipresc adresa i coninutul variabilei a. Se declar o variabil adr1, de tip int*, care reine adresa variabilei a. Se tipresc adresa i coninutul variabilei adr1. 112
Proiectul pentru nvmntul Rural
Tablouri
Se declar o variabil adr2, de tip int**, (capabil s rein adrese de variabile ce rein adrese de variabile de tip int) care reine adresa variabilei adr1. Se tipresc adresa i coninutul variabilei adr2.
Figura 6.1 Se poate observa c, utiliznd exclusiv coninutul variabilei adr2, se poate adresa indirect, cu dou nivele de indirectare, coninutul variabilei a. Indirectarea s-a fcut dup schema: adresa adr1 adr2
a a
adresa a adr1
n C++ este posibil inializarea pointerilor prin alocarea unei zone de memorie, folosind operatorul new. Sintaxa pentru folosirea acestui operator este: tip_ptr=new tip; fr precizarea valorii iniiale; tip_ptr=new tip(valoare); cu precizarea valorii iniiale; tip_ptr=new tip[dim]; pentru alocarea a dim elemente; De exemplu, alocarea memoriei pentru un vector cu 10 componente numere ntregi se face astfel: int *v=new int[10]; Eliminarea variabilelor dinamice se face cu ajutorul operatorului delete. Acesta este complementarul operatorului new i are sintaxa: delete tip; De exemplu, tergerea memoriei alocate pentru vectorul v cu 10 componente numere ntregi, din exemplul precedent, se face astfel: delete v;
Proiectul pentru nvmntul Rural
113
Tablouri
Tablouri
Pe lng necesitatea de a defini un ir de caractere ca i tablou de caractere, n prelucrarea irurilor se utilizeaz deseori tipul pointer la caracter. De exemplu: char sir[30]; /* tablou de 30 de caractere */ char *psir; /* pointer la caracter */ Astfel, sir este o variabil de tipul tablou de caractere pentru care se rezerv un spaiu de memorie de 30 de octei, n timp ce psir este un pointer la caracter care poate primi ca valoare adresa unui caracter (n particular, adresa primului element dintr-un ir de caractere). Trebuie reinut c ori de cte ori se lucreaz cu variabile iruri de caractere ntr-un program, trebuie s existe fie o definiie de forma celei prezentate pentru variabila sir, prin care se rezerv static (n timpul compilrii), spaiul de memorie necesar variabilei, fie s se aloce dinamic memoria necesar. Neexistnd tipul ir de caractere, n C nu sunt prezeni nici operatorii pentru iruri. n schimb, biblioteca standard conine numeroase funcii pentru prelucrarea irurilor de caractere. O parte a funciilor pentru citirea/scrierea irurilor, declarate n fiierul antet stdio.h, le-am prezentat n Unitatea de nvare 4. n continuare, trecem n revist funciile pentru compararea, copierea, concatenarea irurilor, .a.m.d. Acestea sunt declarate n fiierul string.h. Ele primesc adresele irurilor prelucrate, prin intermediul parametrilor de tipul pointer la caracter.
int strcmp(char *s1, char *s2);
Efect: compar irurile s1 i s2 i returneaz o valoare negativ, dac irul s1 este mai mic dect irul s2, 0 dac s1 este egal cu s2, i o valoare pozitiv dac s1 este mai mare dect s2. Compararea irurilor este fcut din punct de vedere lexicografic, adic liter cu liter, pn cnd 2 caractere sunt diferite sau se termin unul din ele. De exemplu, irul Anca este mai mare dect Ana.
Exemplul 6.8 Precizai relaia de ordine dintre dou cuvinte (iruri de caractere care nu conin caractere albe), cuvinte citite de la tastatur. #include <string.h> #include <iostream.h> void main() { char s1[100],s2[100]; int p; cout<<Introduceti primul sir: ; cin>>s1; cout<<Introduceti al doilea sir: ; cin>>s2; p=strcmp(s1,s2); if (p<0) cout<<s1<s2; else
Proiectul pentru nvmntul Rural
115
Tablouri
if (p>0) cout<<s1>s2; else cout<<s1=s2; } O alt funcie care compar dou iruri de caractere, dar numai pentru primele n caractere, este:
int strncmp(char *s1, char *s2, int n);
Efect: identic cu strcmp, dar se compar irurile s1 i s2 pentru cel mult n caractere. Urmtoarele dou funcii se folosesc pentru copierea unui ir denumit surs s ntr-un ir destinaie d:
char *strcpy(char *d, char *s);
Efect: copiaz irul surs s n irul destinae d i returneaz adresa irului destinaie. Copierea se termin dup ce a fost copiat caracterul \0
char *strncpy(char *d, char *s, int n);
Efect: copiaz maxim n caractere de la sursa s la destinaia d i returneaz adresa irului destinaie. Exemplul 6.9 Un exemplu de folosire a celor dou funcii este urmtorul, n care trebuie remarcat c este necesar punerea pe ultima poziie a caracterului \0 n cazul funciei ce copiaz primele n caractere: #include <string.h> #include <iostream.h> void main() { char s1[100]=sirul copiat,s2[100]=sirul destinatie; strcpy(s2,s1); cout<<s2<<endl; strncpy(s2, s1, 5); s2[5]=\0; cout<<s2<<endl; } O funcie util n lucrul cu irurile de caractere
int strlen(char *s);
116
Tablouri
Exemplul 6.10 Urmtorul program citete un ir de caractere afieaz lungimea lui: #include <string.h> #include <iostream.h> void main() { char s[100]; cin.get(s,100);
cout<<sirul <<s<< are <<strlen(s)<< caractere<<endl;
} Urmtoarele dou funcii sunt folosite pentru a concatena (a aduga la sfritul primuui ir pe al doilea) dou iruri de caractere.
char *strcat(char *d, char *s);
Efect: concateneaz cel mult n caractere din irul surs s la irul destinaie d i returneaz adresa irului rezultat. Exemplul 6.11 Un exemplu de folosire a funciilor de concatenare este urmtorul: #include <string.h> #include <iostream.h> void main() { char s1[100]=Astazi ,s2[100]=invatam; strcat(s1,s2); cout<<s1<<endl; strncpy(s1, s2, 5); s2[5]=\0; cout<<s2<<endl; } Funcia strchr() are rolul de a cuta caracterul c n irul s i are forma:
char *strchr(const char *s, int c);
Cutarea se face de la stnga la dreapta i, n cazul n care caracterul este gsit, funcia returneaz un pointer al primei apariii a caracterului c n irul s, iar n caz contrar, funcia returneaz pointerul nul.
117
Tablouri
Exemplul 6.12 Un exemplu de folosire a funciei de cutare a unui caracter ntr-un ir este urmtorul: #include <string.h> #include <iostream.h> void main() { char *p=; p=strchr(Acesta este un test, ); cout<<p<<endl; } n urma execuiei acestui program, se va afia este un test. Funcia strstr() are rolul de a cuta subirul s2 n irul s1 i are forma:
char *strstr(const char *s1, const char *s2);
Cutarea se face de la stnga la dreapta i, n cazul n care subirul s2 este gsit, funcia returneaz un pointer al primei apariii a acestuia n irul s1, iar n caz contrar, funcia returneaz pointerul nul. Exemplul 6.13 Un exemplu de folosire a funciei de cutare a unui subir ntr-un ir este urmtorul: #include <string.h> #include <iostream.h> void main() { char *p=; p=strchr(Acesta este un exemplu,este); cout<<p<<endl;} n urma execuiei acestui program, se va afia este un exemplu. Exemplul 6.14 Un alt exemplu de folosire a funciei de cutare a unui caracter ntr-un ir este urmtorul: s se determine poziia primei apariii a unui caracter ntrun ir de caractere #include <string.h> #include <iostream.h> void main() { char s[50]= Acesta este un test; p= (Acesta este un test, ); cout<< strchr (s,t)-s<<endl; } 118
Proiectul pentru nvmntul Rural
Tablouri
Acest program va afia valoarea 4, corespunztoare poziiei primei apariii a caracterului t n irul s.
2. Fie secvena de instruciuni: strcpy(a,calculator); strcpy(b,lat); p=strstr(a,b); tiind c a i b sunt variabile de tip ir de caractere, ce reine p? A. 6 B. 7 C. lat A. lator
3. Fie declaraiile: char a[50];unsigned int i; tiind c irul de caractere a se termin cu caracterul punct, care din secvenele de mai jos este echivalent cu funcia strlen()?: a) i=0; while (a[i++]!=.) {} cout<<i; b) i=0; while (a[i++]==.) {} cout<<i; c) i=0; if (a[i]==.) cout<<i; d) if (a[i]!=.) cout<<i; 119
Tablouri
4. Care din urmtoarele afirmaii sunt adevrate? A. Tipul char* permite manipularea irurilor de caractere; B. Lungimea efectiv a unui ir de caractere s se poate obine prin apelul strlen(s); C. strcpy() este o funcie ce extrage un anumit subir dintr-un ir dat; D. Un ir vid este acela care conine doar blankuri.
5. Operaia de alipire a dou iruri de caractere poart numele de , iar funcia care caut un caracter dat ntr-un ir de caractere se numete ....
120
Tablouri
BIBLIOGRAFIE
1. Dorin Stoilescu, Manual de C/C++ - Cap.7 Tablouri i pointeri, Editura Radial, Galati, 1998. 2. Florin. Munteanu, Traian C. Ionescu, Daniela Saru, Gheorghe Musca, Sergiu Mihai Dascalu, Programarea calculatoarelor - manual pentru liceele de informatic - Cap.20 Tablouri i pointeri, Editura Didactic i Pedagogic, Bucureti, 1995. 3. Valeriu Iorga si colectiv, Programare in C/C++. Culegere de probleme, Editura Niculescu, Bucureti, 2003. 4. Programe de specialitate elaborate de ctre Ministerul Educaiei i Cercetrii pentru nvmntul preuniversitar 5. Herbert Schildt, C manual complet Cap.4 Tablouri i iruri, Cap.5 Pointeri, Editura Teora, 2000 6. http://www. cs.umd.edu/users/cml/style/ - ghid privind stilul de programare in limbajele C si C++. 7. http://www.programmingtutorials.com tutoriale de programare pentru C, C++ precum si pentru alte limbaje. 8. http://www.snippets.org exemple de programe scrise in limbajul C.
121
Tablouri
Aplicaia 6
1. Ce valori vor fi afiate n urma rulrii urmtorului program? #include <iostream.h> void main() { int a[11],I; for(i=1;i<=10;i++) a[i]=i-1; cout<<a[2]<< ; cout<<a[a[2]]<< ; cout<<a[a[a[3]]]<< ; cout<<a[a[2]+a[3]]<< ; }
a) b) c) d)
2. Alegei varianta corect a instruciunilor care conduc la deplasarea cu o poziie spre stnga a tuturor elementelor tabloului a ncepnd cu cel situat pe poziia p+1, n vederea tergerii elementului de pe poziia p. a) for (i=p+1;i<=n;i++) a[i]=a[i-1]; b) for (i=p;i<n;i++) a[i]=a[i+1]; c) for (i=n;i>p;i--) a[i-1]=a[i]; d) for (i=n;i>=p;i--) a[i+1]=a[i];
Tablouri
#include <iostream.h> #include <string.h> void main() { char s[20],t[20]; cout<<s=;cin.get(s,20); cin.get(); cout<<t=;cin.get(t,20);
while (s[0]==t[0] && strlen(s)!=0) && strlen(t)!=0) {strcpy(s,s+1); strcpy(t,t+1);} if (strlen(s)==0 && strlen(t)==0) cout<<DA; else cout<<NU; }
Determinai ce face acest program: a) afieaz DA dac irurile s i t au lungimi egale sau NU n caz contrar; b) afieaz DA dac irurile s i t sunt identice sau NU n caz contrar; c) afieaz DA dac primul caracter din irul s este egal cu primul caracter din irul t sau NU n caz contrar; d) afieaz DA dac irurile s i t au lungimi nenule sau NU n caz contrar; 4. Fie s un ir de caractere. Care din urmtoarele secvene elimin spaiile de la nceputul irului s: a) char *p=s; c) char *p=s; while (*p== ) p++; while (*p== ) p++; strcpy(s,p); strcpy(s,p-1); b) char *p=s; while (*p!= ) p++; strcpy(s,p); d) char *p=s; while (*p!= ) p++; strcpy(s,p+1);
5. Fie doi vectori a i b formai din n, respectiv m numere ntregi nenule (m,n<=50). Scriei un program care citete, pe rnd, numrul de elemente i valorile din vectorul a, respectiv b, i afieaz valorile din vectorul a care sunt prime cu toate valorile din vectorul b. Dou numere ntregi sunt prime ntre ele dac cel mai mare divizor comun al lor este 1. Exemplu: Fie n=6, a=(77, 35, 55, 15, 121) i m=3, b=(18, 20, 10). Se vor afia numerele 77, 121. 6. S se determine cuvintele ce conin 3 vocale dintr-un ir de caractere s dat. 7. ntr-un ir de caractere s cuvintele sunt separate de unul sau mai multe spaii. S se elimine spaiile n plus din irul s.
123
Obiectivele Unitii de nvare 7 ..................................................................................123 7.1 Declararea fiierelor.................................................................................................123 7.2 Deschiderea fiierelor..............................................................................................124 7.3 Citirea datelor dintr-un fiier...................................................................................125 7.4 Scrierea datelor ntr-un fiier ..................................................................................126 7.5 Operaii de test .........................................................................................................126 7.6 nchiderea unui fiier ...............................................................................................127 Rspunsuri corecte la testele de autoevaluare ...........................................................129 Bibliografie .....................................................................................................................130 Lucrarea de verificare nr.7, notat de tutore ...............................................................130
Exemplul 7.1 ifstream f1; ofstream f2; fstream h; Observaii: 1. f1, f2, h sunt variabile de tip fiier ( obiecte de tip clas). // am declarat un stream de intrare numit f1 // am declarat un stream de ieire numit f2 // am declarat un stream de intrare-ieire numit h
2) la declarare, specificnd dup numele stream-ului care se declar numai parametrii corespunztori funciei open, ncadrai ntre paranteze. Exemplul 7.3 ifstream f1( date.txt); Observaie: Se deduce c fiierul date.txt se afl pe hard-disc n directorul curent. Exemplul 7.4 ofstream f2; f2.open(c:\\dana\\date.out); Observaie: // am declarat un stream de ieire f2 /* l-am asociat lui date.out, care se afl pe discul C:, n directorul dana */
125
Nu am specificat nici un mod de deschidere; deci se deschide implicit ( se creeaz un fiier vid cu numele date, n care se vor face numai operaii de scriere. Exemplul 7.5 fstream f3; f3.open (info.in, ios::in); Observaie: Deoarece tipul fstream nu are asociat un mod de deschidere implicit, f3 a fost deschis cu modul ios::in, ca fiier de intrare (numai pentru operaii de citire). Exemplul 7.6 fstream f4( info.out, ios::out); Observaie: Modul de deschidere specificat este ios::out, ceea ce nseamn c fiierul este a fost deschis pentru operaii de scriere. Exemplul 7.7 fstream f5( info.ad, ios::app); Observaie: Modul de deschidere specificat este ios::app (append), ceea ce nseamn c deschidem fiierul ca fiier de ieire, pentru adugare de informaii la sfrit. /*am declarat un stream f5 pe care l-am asociat fiierului info.ad.*/ /*am declarat un stream f4 pe care l-am asociat fiierului info.out.*/ // am declarat un stream f3 //l-am asociat fiierului info.in
126
Exemplul 7.8 ifstream f1(aplicatie.in); char c; f1>>c; // am citit primul caracter din fiierul f1. Observaie: Operatorul >> ignor caracterele albe ( spaiu, tab, enter). Exemplul 7.9 ifstream f1(aplicatie.in); char c; f1.get(c); /* am citit primul caracter din fiierul f1, indiferent dac este sau nu character alb, folosind funcia get()*/
127
2. Pentru a afla anticipat ce caracter urmeaz n fiierul de intrare (fr a-l extrage din stream) putem utiliza funcia membru peek(), care returneaz urmtorul caracter din stream. Exemplul 7.11 Voi determina frecvena unui caracter c n fiierul text.in. ifstream fisier(text.in); char c, car; int x=0; cin>>c; // in c retin caracterul a carui frecventa o determin while (! fisier.eof()) {fisier.get(car); // citesc un caracter din fisier if(car==c) x++;} // si daca este egal cu c incrementez x cout<< frecventa lui<<car<< in fisier este<< x;
Sarcin de lucru 7.1 Scrie secvena de program care numr toate caracterele existente ntr-un fiier.
Barem:
declaraii corecte citirea corect din fiier Numrarea caracterelor din fiier afiarea corect a rezultatului total Varianta corect de rspuns se afl la pag. 130. 10 puncte 10 puncte 20 puncte 10 puncte 50 puncte
128
Test de autoevaluare 7.1 Alege, prin ncercuire, varianta corect de rspuns pentru urmtoarele dou teste. Rspunsul pentru fiecare cerin valoreaz 20 de puncte. 1. Se consider urmtorul program: #include <fstream.h> #include<string.h> void main() fstream fisier; char c; fisier.open(test.txt,ios::in); while (f>>c) cout<<c<< ; fisier.close(); } Dac fiierul test.txt are urmtorul coninut: 187 abc 6 7 8 gg 5 90, ce se va afia pe ecran dup executarea programului? a) b) c) d) 187 abc 6 7 8 gg 5 90 187abc678 gg590 187abc678gg590 187 ab c67 8gg 5 90
2. Stabilete care dintre urmtoarele secvente de program adaug la sfritul fiierului test.txt o linie nou care s conin irul ultima linie. a) fstream f; f.open(test.txt, ios::in); f<<ultima linie; f.close(); b) fstream f; f.open(test.txt, ios::app); f<<ultima linie<<endl; f.close(); Exemplul 7.15 c) fstream f; f.open(test.txt, ios::app); f<<endl<<ultima linie; f.close(); d) fstream f; f.open(test.txt, ios::out); f<<endl<<ultima linie; f.close();
n fiierul NUMERE.TXT se afl numere naturale din intervalul [0,5000], separate prin spaii. Voi creea fiierul PARE.TXT care s conin doar valorile pare din fiierul NUMERE.TXT, cte o valoare pe linie. ( variant Bacalaureat 2000) #include<fstream.h>
Proiectul pentru nvmntul Rural
{ int x; ifstream f("NUMERE.TXT"); ofstream g("PARE.TXT"); while(!f.eof()) { f>>x; if((x%2)==0) g<<x<<endl; } f.close(); g.close(); }
/* se citete cte un numr din streamul f att timp ct nu s-a ajuns la sfritul fiierului f, apoi se verific dac num[rul e par i n caz afirmativ se scrie n stream-ul g */
Figura 7.2
130
Test de autoevaluare 7.1 1. b) 2. c) Vezi U7.2, pag 124, U7.3, pag 125, U7.6, pag. 127 Vezi U7.2, pag 124, U7.3, pag 125, U7.6, pag. 127
Bibliografie
4. Cerchez, Emanuela, Informatic. Culegere de probleme pentru liceu, Editura Polirom, Iai, 2002. 5. Cerchez, Emanuela, erban, Marinel, Programarea n limbajul C-C++ pentru liceu, Cap 3 Fiiere , Editura Polirom, Iai, 2005
25 puncte Aplicaia 1 25 puncte Aplicaia 2 25 puncte Aplicaia 3 25 puncte Aplicaia 4 Total 100 puncte
5 puncte - declaraii corecte 5 puncte deschideri nchideri corecte de fiiere 10 puncte nlocuirea tuturor apariiilor numrului x cu y 5 puncte - redenumirea fiierului 5 puncte - declaraii corecte 5 puncte deschidere nchidere corect de fiiere 10 puncte determinarea numrului lips 5 puncte afiarea numrului 5 puncte - declaraii corecte 5 puncte deschidere nchidere corect de fiier 10 puncte verificarea proprietii impuse de regul dat 5 puncte afiarea numrului maxim 5 puncte - declaraii corecte 5 puncte deschidere nchidere corect de fiiere 10 puncte verificarea coninutului fiierelor 5 puncte afiarea rezultatului testrii
Punctaj minim: 75 puncte. 1. Un fiier text conine numere ntregi dispuse pe mai multe linii. Se cere nlocuirea n fiier a tututor apariiilor unui numr x cu un alt numr y, unde x i y sunt citite de la tastatur. Realizeaz un program care permite efectuarea acestei modificri asupra coninutului fiierului.
131
2. n fiierul lipsa.in exist dispuse pe fiecare linie cte un numr din irul primelor n (n<100) numere naturale nenule. Excepie face un singur numr care a fost omis. Scrie un program care determin numrul lips. Ex: lipsa.in conine 4 1 3 5 si se va afia 2
3. n fiierul numar.in exist pe prima linie un ir cresctor de numere naturale. Citirea din fiier a unui nou numr este condiionat de obinerea, ca sum de termeni distinci din fiier, a unui ir de numere consecutive ncepnd cu 1. Determin care este numrul maxim care se poate obine respectnd regula dat. Ex: numar.in conine 1, 2, 4, 10, 13, 132, 562, 1200. Se va afia 7, deoarece citirea din fiier se ncheie odat cu citirea numrului 10. Valoarea 8 nu se poate forma ca sum de termeni preluai din fiier. Algoritmul verific valorile i valideaz 1, 2, 3(1+2), 4, 5(1+4), 6(2+4), 7(1+2+4).
4. Scrie un program care s testeze dac dou fiiere ale cror nume este cunoscut sunt identice.
132
Funcii
Cuprins
Pagina
Obiectivele Unitii de nvare 8 ................................................................................. 132 8.1 Funcii nerecursive.................................................................................................. 132 8.1.1 Definirea unei funcii ............................................................................................... 133 8.1.2 Declararea funciilor................................................................................................ 134 8.1.3 Apelul funciilor ....................................................................................................... 135 8.1.4 Variabile globale i variabile locale ......................................................................... 140 8.2 Funcii recursive...................................................................................................... 145 Rspunsuri corecte la testele de autoevaluare, ......................................................... 153 Bibliografie..................................................................................................................... 155 Lucrarea de verificare Nr. 8, notat de tutore ............................................................. 156
8.1 Funcii nerecursive n limbajul C / C++, subprogramele se numesc funii. Ele reprezint un element fundamental al limbajului. Aa cum stii, orice program C / C++ este contituit dintr-o succesiune de funcii, dintre care una este fun. principal, denumit main(). La lansarea n execuie a unui program C / C++ este apelat funcia main(). Pn acum. n cadrul ei am apelat numai funcii Standard ale limbajului, precum clrscr(), sqrt(), get(), etc. n acest capitol vei nva cum s descrii propriile tale funcii, numite n continuare funcii utilizator.
133
Funcii
Atenie! ntr-un program C / C++ toate prelucrrile sunt organizate sub forma unei ierarhii de apeluri de funcii, baza ierarhiei fiind funcia principal main(). Pentru a dezvolta i utiliza funcii proprii este necesar s cunoti cum se definesc, cum se declar i cum se apeleaz funciile. 8.1.1 Definirea unei funcii n definiia unei funcii ntlnim un antet care conine numele funciei, tipul rezultatului returnat de funcie i lista parametrilor funciei i un bloc de instruciuni, care descrie prelucrrile efectuate de funcie. Forma general a definiiei unei funcii este: tip nume(lista parametrilor formali) { declaratii variabile locale instructiuni funciei } // antetul funciei
//
blocul
unde: tip este tipul rezultatului returnat de funcie; nume este numele funciei; lista parametrilor formali este alctuit din una sau mai multe declaraii de parametri cu care funcia opereaz, separate prin virgul. Aceast list poate fi vid. Parametrii formali se numesc astfel deoarece cu ajutorul lor voi descrie n mod formal operaiile care se vor efectua cu datele transmise de programul apelant. Exemplul 8.1 void suma(int x, int y) { cout<<x+y=<<x+y; } Observaii: 1. funcia suma are tipul void, adic nu ntoarce un rezultat; 2. parametrii formali sunt de tip intreg. 3. funcia afieaz suma celor dou numere transmite ca parametri de programul apelant.
134
Funcii
Exemplul 8.2 int suma(int x, int y) { int i,s; s=x for(i=1;i<=y; i++) s++; return s; } Observaii: 1. funcia suma are tipul intreg i calculeaz suma a dou numere intregi, transmite ca parametri de programul apelant; 2. variabilele i i s sunt declarate n blocul funciei i se numesc variabile locale; 3. n blocul funciei intervine instruciunea return. Ea returneaz programului apelant valoarea variabilei s. 8.1.2 Declararea funciilor Compilatorul C / C++ va fi informat de existena funciei i a formatului acesteia odat cu declaraia funciei. Forma general a declaraiei funciei este: tip nume( lista parametrilor); Atenie! Declaraia unei funcii este alctuit din antetul funciei urmat de caracterul ;, nu de blocul de instruciuni al funciei. De aceea, declaraia funciei se mai numete i prototip. Este necesar ca naintea oricrui apel de funcie s apar fie definiia funciei, fie declaraia funciei. Atenie! Un program C / C++ poate conine pentru a funcie o singur definiie, dar oricte declaraii. Exemplul 8.3 double sqrt(double); Observaii: 1. funcia sqrt() are tipul double i returneaz radicalul valorii primite ca parametru; 2. are prototipul n math.h.
Proiectul pentru nvmntul Rural
135
Funcii
Exemplul 8.4 float calcul(int x, int v[10]); Observaii: 1. funcia calcul() are tipul real, are doi parametri: unul de tip int i un tablou de 10 valori de tip int; 2. n declaraia funciei calcul() este specificat numele parametrilor, nu doar tipul acestora.
Test de autoevaluare 8.1 Stabilete valoarea de adevr a urmtoarelor afirmaii prin ncercuirea literelor A sau F, corespunztoare valorilor de adevarat sau fals. Rspunsul pentru fiecare cerin valoreaz 20 de puncte. Punctaj minim: 80. A F 1) ntr-un program toate prelucrrile sunt organizate sub forma unei ierarhii de apeluri de funcii, baza ierarhiei fiind funcia principal main(). A F 2) Definiia unei funcii se mai numete i prototip. A F 3) n definiia unei funcii se ntlnesc antetul i blocul de instruciuni al funciei. A F 4) Lista parametrilor formali este alctuit din una sau mai multe declaraii de parametri cu care funcia opereaz, separate prin virgul. A- F 5) Orice apel de funcie este succedat fie de definiia funciei, fie de declaraia acesteia. Rspunsurile corecte se gsesc la pag. 153. 8.1.3 Apelul funciilor Apelul unei funcii se poate face n dou moduri: ntr-o instruciune de apel: nume(lista parametrilor actuali); ca operand ntr-o expresie: v= nume(lista parametrilor actuali);
136
Funcii
lista parametrilor actuali este format dintr-o succesiune de expresii, separate prin virgul. La apelul unei funcii, valorile parametrilor actuali sunt atribuite, n ordine, parametrilor formali corespunztori. Atenie! Parametrii actuali trebuie s corespund cu parametrii formali ca numr, ordine i tip.
Exemplul 8.5 Fie declaraiile de variabile: float ma; int a,b; Voi putea atribui variabilei ma valoarea mediei aritmetice a numerelor a i b, apelnd funcia suma() calculat la exemplul 1.2, astfel: ma= suma(a,b)/2; Observaii: 1. valoarea parametrului actual a nlocuiete parametrul formal x, iar valoarea parametrului actual b nlocuiete valoarea parametrului formal y. Ce se ntmpl cu parametrii actuali? Unde sunt memorate valorile lor? Funciile folosesc o zon de memorie numit stiv (snack) care funcioneaz pe principiul ultimul intrat este primal ieit (last input, first output) LIFO. La apelarea unei funcii, se aloc spaiul de memorie pe stiv pentru valorile parametrilor actuali. Se realizeaz astfel transferul prin valoare al parametrilor. La terminarea execuiei funciei, zona de memorie alocat pe stiv se elibereaz. Atenie! Deoarece zona de memorie alocat pentru parametri se elibereaz, valorile modificate n funcie se pierd.
137
Funcii
Exemplul 8.6 Consider funcia care afieaz valorile a doi parametri intregi x i y: void afisare(int x, inty) { cout<<x=<<x; cout<< y=<<y<<endl; x++; y++; } Mai consider declaraiile de variabile: int a=10, b=75; Voi constata c secvena de instruciuni: cout<<a=<<a; cout<< b=<<b<<endl; afisare(a,b); cout<<a=<<a; cout<< b=<<b<<endl; afieaz pe ecran: a=10 b=75 x=10 y=75 a=10 b=75 fr a se ine cont de modificrile valorilor parametrilor x i y n cadrul funciei.
Tem de reflecie 8.1 Scrie o nou analogie (maxim 300 cuvinte) prin care s ilustrezi transferul parametrilor prin valoare. Se noteaz cu 10 puncte ingeniozitatea ideii, cu 10 puncte coerena n exprimare i se acord 30 puncte expunerii analogiei. Punctaj minim: 30.
138
Funcii
Dac vreau ca la ieirea din funcie s se pstreze valorile modificate ale parametrilor, nu voi transmite ca parametrii expresii ale cror valori s fie copiate pe stiv, ci voi transmite adresele variabilelor ale cror valori dorim s le modificm. Utilizez astfel transmiterea prin adres sau prin referin. Exemplul 8.7 Voi considera funcia din exemplul trecut care afieaz valorile a doi parametri intregi x i y i voi schimba modul de transmitere parametri: Transmiterea parametrilor se face prin adres, folosind operatorul &. void afisare(int &x, int &y) { cout<<x=<<x; cout<< y=<<y<<endl; x++; y++; } consider aceleai declaraiile de variabile: int a=10, b=75; Dar acum voi constata c secvena de instruciuni: cout<<a=<<a; cout<< b=<<b<<endl; afisare(a,b); cout<<a=<<a; cout<< b=<<b<<endl; afieaz pe ecran: a=10 b=75 x=10 y=75 a=11 b=76
Test de autoevaluare 8.2 Alege, prin ncercuire, varianta corect de rspuns pentru urmtoarele teste. Rspunsul pentru fiecare cerin valoreaz 20 de puncte. Punctaj minim: 80. 1. Ce se afieaz n urma executrii urmtorului program? #include<iostream.h> int a;
Proiectul pentru nvmntul Rural
139
Funcii
void f1(int a) {a=20; cout<<a;} void f2(int &a) {a=30; cout<<a;} void main() {int a=10; f1(a);cout<<a; f2(a);cout<<a; } a) b) c) d) 10 10 20 30 20 10 30 10 20 10 30 30 20 20 30 30
2. Indicai care dintre urmtoarele antete de funcii sunt corecte sintactic: a) b) c) d) e) int f1(int y) int f2(int x,y) iostream f3 float f4(char c) double f5(int x, float y)
3. Indicai care dintre funciile urmtoare returneaz media aritmetic dintre ctul i restul la mprirea a dou numere ntregi: a) int medie(int x,y) { return (x/y+x%y)/2;} b) float medie(int x, int y) { float med; med=x/y+x%y; return med/2;} c) float medie(int x, int y) { return x/y+x%y;} 4. Fie funcia: void interschimbare(char a, char & b) { char aux; aux=a; a=b; b=aux; } Dac x i z sunt dou variabile de tip char ce memoreaz valorile 1 respectiv 2, ce valori se vor afia dup executarea secvenei de instruciuni: interschimbare(x,y); cout<<x<< <<z; 140
Proiectul pentru nvmntul Rural
Funcii
a) 1 2 b) 2 1
c) 2 2 d) 1 1
5. Cte erori va produce execuia programului urmtor: #include<iostream.h> #include< math.h> int radical(int p, int q) { return (sqrt(p*q);} void main() {cout<<radical(1,2);} Rspunsurile corecte se gsesc la pag. 153 8.1.4 Variabile locale i variabile globale Pentru a face diferena ntre cele dou categorii de variabile trebuie s analizm urmtoarele caracteristici ale lor: - poziia declaraiei variabilei; - clasa de memorare ( segmentul de date al programului, pe stiv yona de memorie n care este alocat variabila); - durata de via ( timpul n care variabilei i se aloc o zon de memorie). - domeniul de vizibilitate ( zone ale programului care vd variabile, deci o pot utiliza. Variabile globale Sunt declarate n exteriorul oricrei funcii Zon de memorie: n segmentul de date al programului. Memoria Zon de memorie: pe stiv alocat fiind automat iniializat cu 0. Memoria rmne alocat Memoria rmne alocat pn la pn la sfritul execuiei sfritul execuiei programului. blocului n care a fost declarat variabila. Sunt vizibile din momentul declarrii pn la sfritul Sunt vizibile numai n blocul programului n toate funciile n care au fost declarate. acestuia, chiar i n alte fiiere surs, cu excepia cazurilor de omonimie1. Variabile locale Sunt declarate n blocul unei funcii a) b) c) d) e) 1 2 3 4 nici una
Durata de via
Domeniul de vizibilitate
Cazurile de omonimie i regula de omonimie nu sunt obiect de studiu n cadrul acestui manual. Omonimia poate fi studiat din alte cri de specialiate npreun cu operatorul de rezoluie ::. Proiectul pentru nvmntul Rural
141
Funcii
Exemplul 8.8 int n, x[50]; void citire (int n, int x[50]) { int i; for(i=1;i<=n;i++) cin>>x[i];} // x si n sunt variabile globale
Test de autoevaluare 8.3 Alege, prin ncercuire, varianta corect de rspuns pentru urmtoarele teste. Rspunsul pentru fiecare cerin valoreaz 20 de puncte. Punctaj minim: 80. 1. Stabilete care dintre urmtoarele funcii ntorc poziia primei valori strict pozitive din tabloul unidimensional v, care conine numere ntregi, sau 0 dac nu conine nici un numr pozitiv. a) c) int p(int v[11], int n) int p(int v[11], int n) { int i,x; { int x; x=0; x=0; for(i=1;i<=n;i++) if (v[i]>0)x=i; while ((v[x+1]<=0)&&(x<=n-1)) x++; return x; return x+1; } } b) d) int p(int v[11], int n) int p(int v[11], int n) { int x; { int i; x=0; for(i=1;i<=n;i++) if (v[i]>0) return i; while (v[x]<=0) x++; return 0; return x; } } 2. Se consider urmtoarea funcie: int testare( char &s) { int i,j,p; i=0; j=strlen(s)-1;p=1; while () { if(s[i]!=s[j]) p=0; i++; j--; } return p; }
Stabilete cu care dintre expresiile de mai jos trebuie nlocuite spaiile punctate astfel nct funcia s ntoarc 1, dac irul s este palindrom, sau 0 dac irul s nu este palindrom. 142
Proiectul pentru nvmntul Rural
Funcii
a) b) c) d)
3.Ce se afieaz n urma executrii urmtorului program? #include<iostream.h> int a,b; void calcul (int &x, int &y) {int a; a=x+y; y+=a; x+=b; } void main() {a=10; b=100; calcul(a,b); cout<<a<< <<b;}
4. Consider x o variabil ntreag a crei valoare este 2. Ce valoare va avea x dup apelul f(x,x)? void f(int x, int &y) { y+=x; x+=y;} a) 2 b)6 c) 8 d)4
5. Care dintre urmtoarele funcii returneaz cel mai mare numr natural p cu proprietatea c 2p<=n. a) int f(int n) {int p=0; a=1; while(e<=n) { p++;a*=2;} return p;} b) int f(int n) {int p=0; a=1; while(e<=n) { p++;a*=2;} return p-1;} Rspunsurile corecte se gsesc la pag. 153. c) int f(int n) { int p=0; a=1; while(e<n) { p++;a*=2;} return p; }
143
Funcii
Considerm un vector cu n (n<101) componente numere naturale mai mici sau egale cu 30000. Scrie un program care calculeaz i afieaz suma componentelor prime. Folosete pentru acesta o funcie pentru citirea vectorului i o funcie care verific dac un numr e prim. Ex: Pentru n=5 i numerele 1 4 7 33 5 se afieaz 13. Barem: declaraii corecte de variabile funciei pentru citirea vectorului funciei pentru verificarea numerelor prime calcularea sumei afiarea corect a rezultatului total 15 puncte 25 puncte 25 puncte 20 puncte 15 puncte 100 puncte
Sarcin de lucru 8.2 Considerm un vector a=( a[1],a[2], a[3],...a[n]) cu n (n<21) componente numere naturale cu cel mult 9 cifre. Scrie un program care calculeaz i afieaz suma: 3a[1]+3a[2] ++3a[n] . Vei folosi pentru aceasta: - o funcie pentru citirea vectorului a; - o funcie pentru calcularea 3a[i] ; - o funcie pentru calculul sumei a dou numere naturale. Ex: Pentru n=3 si vectorul: 2 1 3 , se va afisa 39. Barem:
declaraii corecte de variabile 15 puncte funcie pentru citirea vectorului a 20 puncte funcie pentru calcularea 3a[i] ; 25 puncte funcie pentru calculul sumei a dou numere 30 puncte naturale afiarea corect a rezultatului 10 puncte total 100 puncte Soluia se gsete la pag. 153. Exemplul 8. 11 Consider un vector cu n (n<50) componente ntregi. Voi verifica, printr-un program, dac acest vector reprezint o mulime. Ex: 144
Proiectul pentru nvmntul Rural
Funcii
Pentru n=5 si vectorul: 3 2 1 3, se va afisa Nu este multime! Pentru a verifica dac un vector este mulime trebuie s testez dac exist elemente care se repet. Pentru a verifica mai uor acest lucru, voi ordona vectorul prin metoda bulelor. Voi folosi o funie pentru citirea componentelor vectorului i o alta pentru testarea propriu-zis. #include<iostream.h> int n, x[50]; void citire (int n, int x[50]) { int i; for(i=1;i<=n;i++) cin>>x[i];} void testare(int n, int x[50]) { int sem,I,aux; //aplic bubblesort pentru sortarea componentelor vectorului do {sem =1; for (i=1;i<n;i++) if(x[i]<x[i+1]) { aux=x[i];x[i]=x[i+1];x[i+1]=aux; sem=0;} } while (!sem); /* testez dac exist elemente care se repet; pentru aceasta compar dou cte dou componente ale vectorului*/ sem=1; for (i=1;i<n;i++) if(x[i]==x[i+1]) sem=0; if(sem)cout<<Este multime!; else cout<<Nu este multime!; } void main() { cout<<n=;cin>>n; citire(n,x); testare(n,x);
Sarcin de lucru 8.3 Se dau dou mulimi A i B, ale cror elemente sunt literele mici ale alfabetului englez. Scrie un program care determin numrul de elemente ale mulimilor AUB i AB, folosind o funie perntru citirea elementelor unei mulimi i cte o funcie care returneaz cardinalul unei mulimi pentru fiecare din operaii ( U , ). Ex: pentru mulimea A={ c, m, p, r, z} i mulimea B={ a, b, c, d, p ,z} se va afia: 8 3. 145
Funcii
Barem:
declaraii corecte de variabile funcie pentru citirea vectorului funcie pentru determinarea cardinalului reuniunii ; funcie pentru determinarea cardinalul interseciei ; apelul corect al funciilor afiarea corect a rezultatului total Soluia se gsete la pag. 153.
8.2
Funcii recursive
O funcie este recursiv dac ea se autoapeleaz. Adic dac apelul su apare cnd subprogramul este activ. Ea se poate apela fie direct, n blocul propriu de instruciuni, fie indirect prin apelul n cadrul altor funcii. Voi analiza nti recursivitatea direct. Orice autoapelul genereaz o nou activare a aceleiai funcii, care presupune execuia instruciunilor, ncepnd cu prima instruciune a funciei i pn la autoapel, cnd se activeaz din nou funcia .a.m.d. Se poate observa c exist posibilitatea ca partea de nceput a funciei s se execute de o infinitate de ori. Pentru evitarea acestei situaii este obligatoriu ca autoapelul s fie legat de ndeplinirea unei condiii. Cnd condiia de autoapel nu se mai ndeplinete , irul activrilor funciei se ntrerupe i se vor executa secvenele rmase de efectuat din funciile activate anterior, n ordine invers. Propun spre studiu un exemplu matematic simplu: produsul a dou numere naturale. Dac doresc s construiesc o funcie care s se autoapeleze, trebuie s-i gasesc un mod recursiv de definire a operaiei de nmulire a dou numere. b daca a=1 produs(a,b)=a*b=a+a+a++a=(a-1)*b+b= b+produs(a-1,b),daca a>1 b ori Cum pot scrie funcia recursiv care implementeaz acest algoritm? Consider declaraiile de variabile: int a,b; long produs(int a, int b) { if(a==1) return b; else return b+produs( a-1,b) }
146
Funcii
Figura 8.1 Exemplul 8. 12 Voi scrie un program care citete de la tastatur un numr natural n i apeleaz o funcie recursiv care returneaz valoarea produsului: p(n)=1*3*5*(2n+1). Dac n=0, se va afia p(0)=1, adic 2*0+1, iar dac n=3, se va afisa p(3)=105, adic 1*3*5*7. #include<iostream.h> long p(long x) { if(x) return; else return 1; } void main() { long n; do{ cout<<n=;cin>>n;}while(n>=0); cout<<p(n); }
Proiectul pentru nvmntul Rural
147
Funcii
Observaii: 1. condiia de ieire din funcie este:x=0. Funcia returneaz valoarea 1 dac x=0. 2. definirea recursiv a funciei este dat de formula (2*x+1)*p(x-1), unde p(x-1) autoapelul. Atenie! Activarea unei funcii recursive presupune, la fel ca n cazul uneia iterative, alocarea pe stiv a variabilelor locale, a parametrilor i a adresei de revenire. Datorit acestui lucru, o soluie recursiv este eficient numai dac adncimea recursivitii un este mare.
Tem de reflecie 8.2 Analizeaz urmtorul algoritm i rspunde cerinelor de mai jos. Fiecare rspuns corect valoreaz 30 puncte. Punctaj minim: 70. Se acord 10 puncte din oficiu. #include<iostream.h> int s(int a,int b) { if(!b) return a; else return s(++a,--b);} void main() {int a,b; cin>>a>>b; cout<<s(a,b);} a) Ce realizeaz programul de mai sus? b) Justificai rspunsul de la punctul a) prin construirea unui tabel al evoluiei variabileor pe parcursul apelurilor. c) Scrie forma iterativ a algoritmului propus la punctul a).
Rspunsurile corecte se gsesc la pag. 153. Exemplul 8. 13 irul lui Fibonaci i-l aminteti? Este 1 , 1, 2, 3, 5, 8,13, 21, 34, 55, 89, ... 148
Proiectul pentru nvmntul Rural
Funcii
Voi construi o funcie recursiv care calculeaz i returneaz al n-lea element din acest ir. mi construiesc recurena: 1, daca n=1 si n=2 fib(n) = f(n-1)+f(n-2), daca n>2 Funcia recursiv este: int fib(int n) { if (n==1) return 1; else if(n==2) return 1; else return fib(n-1)+fib(n-2); } Pentru n=6 avem: fib(6)=fib(5)+fib(4)= fib(4)+fib(3)+fib(4)= . . . =1+1+1+1+1+1+1+1=8
Sarcin de lucru 8.4 Scrie un program prin care se citete numrul n natural de la tastatur. Programul trebuie s apeleze o funcie recursiv, care returneaz valoarea sumei: S(n)= 2+5+8++( 2+3*n). Ex: pentru n=3, se va afisa valoarea 26, adica s(3)=2+5+8+11. Barem:
definiia recursiv calculul sumei cerute corectitudine sintactic a funciei recursive apelul corect al funciei afiarea corect a rezultatului total
149
Funcii
Exemplul 8. 14 Consider funcia recursiv urmtoare: Int f(int a, int b) { if( a>=b) return f(a-b,b)+1; else return 0; } mi propun s scriu o funcie iterativ echivalent cu cea recursiv. Cum procedez? Pas 1. Pun n eviden calculul matematic recursiv al funciei date. 0 daca ab f(a,b)= 1+f(a-b,b) daca ab Pas 2. pentru a=4 si b=2, avem f(4,2)=1+f(2,2)=1+1+f(0,2)= 1+1+0=2 Pas 3. Observ c algoritmul calculeaz ctul mpririi lui a la b. Pas 4. Scriu funcia iterativ: int ff(int a, int b) { return a/b; } Consider funcia iterativ urmtoare: int fi(int &x) { int t=1; while (x>0) { x/=2; t++;} return t; } mi propun s scriu o funcie recursiv echivalent cu cea iterativ. S vedem cum procedez. Pas 1. pentru x=5, avem: t 1 2 3 4 x 5 2 1 0
Pas 2. Deduc de aici care este condiia de stopare: x=0. Observ c valoarea returnat este 4. 150
Proiectul pentru nvmntul Rural
Funcii
Pas 3. Scriu funcia recursiv care contorizeaz mpririle ntregi ale lui x transmis prin adres - la 2. int f (int &x) { if(x) { x/=2; return f(x)+1; } else return 1;} Exemplul 8. 15 Recursivitatea indirect este ilustrat prin urmtorul exemplu (irurile lui Gauss): Fie an= an-1+bn-1 2 bn= an-1 bn-1 , unde a0=a; b0=b
Figura 8.2 Pentru a, b i n numere naturale date, vreau s calculez termenul n al irului a i termenul n al irului b. #include<iostream.h> // variabile globale double a,b; int n; // declaratia functiei bb double bb(int n); // definirea functiei aa; calculeaz termenul n al irului a double aa(int n)
Proiectul pentru nvmntul Rural
151
Funcii
Figura 8.3 // definirea functiei bb; calculeaz termenul n al irului b double bb(int n) { if(!n) return b; else return sqrt(aa(n-1)*bb(n-1)); } void main() { cout<<a<<b<<n; cout<< aa(n); } Observaii: 1. declaraia funciei bb() trebuie s precead apelul su; 2. funcia principal main() apeleaz numai funcia aa(), cu care se pornete la efectuarea calculului termenilor irului.
152
Funcii
Atenie! Avantaje i dezavantaje ale recursivitii: - avantajul recursivitii este acela c reduce drastic lungimea textului surs al programului. De aceea soluiile recursive sunt mai clare dect cele iterative. - recursivitatea este o soluie avantajoas n cazul problemelor complexe, n acelea n care datele sunt definite recursiv, sau n probleme ale cror soluii pot fi definite n termeni recursivi. - utilizarea tehnicilor recursive nu conduce ntotdeauna la soluii optime. Trebuie aleas varianta (interativ - recursiv) avantajoas pentru cazul analizat. - folosirea recursivitii, mai ales a celei indirecte, poate genera dificulti deosebite n depanarea programelor.
else for(i=2;i<=sqrt(nr);i++) if(nr%i==0) p=0; return p;} void main() { int a[100],n; long sum; cin>>n; citire(n,a); sum=0; for(int i=1;i<=n;i++) if(prim(a[i]))sum+=a[i]; cout<<"suma este "<<sum; }
153
Funcii
Sarcin de lucru 8.2 Vezi U8.1.3 pag135 i U8.1.4 pag. 140 Indicaie: Pentru calculul 3a[i] poi folosi o funcie care determin cifrele acestei puteri ntr-un vector. Calculul sumei a dou numere naturale se va face pentru numerele date prin doi vectori, rezultatul fiind tot un vector. De menionat este faptul c, cifrele numerelor sunt reinute n vectori ncepnd cu cifra unitilor ctre prima cifr. Sarcin de lucru 8.3 Vezi U8.1.3 pag135 i U8.1.4 pag. 140 Soluie: #include<iostream.h> #include<conio.h> int n; char a[30],b[30]; void citire (int n, char v[30]) { int i; for(i=1;i<=n;i++) cin>>v[i];} int reuniune(int na, char a[30], int nb, char b[30]) {int i,sem, j,nc=na; for(i=1;i<=nb;i++) { sem=0; for(j=1;j<=na;j++) if(a[j]==b[i]) sem=1; if(sem==0) nc++;} return nc; } int intersectie (int na, char a[30], int nb, char b[30]) Sarcin de lucru 8.4 Vezi U 8.2 pag145 Soluie: Construiesc recurena: 2 daca n=0 S(n)= 3*n+2+S(n-1) daca n>0 #include<iostream.h> long s(int x) { if(x) return 3*x+2+s(x-1); else return 2; } void main() { long n; cout<<n=;cin>>n; cout<<s(n); }
{int i,j,nc=0; for(i=1;i<=na;i++) for(j=1;j<=nb;j++) if(a[i]==b[j]){nc++;break;} return nc; } void main() { int na, nb, nc; cout<<" cardinalul multimii A";cin>>na; citire(na,a); cout<<" cardinalul multimii B";cin>>nb; citire(nb,b); cout<<"cardinal reuniune:"<<reuniune(na,a,nb,b); cout<<"cardinal intersectie:"<<intersectie(na,a,nb,b); }
154
Funcii
Tem de reflecie 8.2 Vezi U 8.2 pag145 a)programul calculeaz a+b c) varianta 1: cout<<a=;cin>>a; cout<<b=;cin>>b; varianta 2 (corespunde cerinei recursive): int s(int a, int b) { int suma=a, i; for(i=1;i<=b;i++) suma++; return suma;}
Bibliografie
1. Herbert Schildt, C manual complet, Cap - Funcii C, Editura Teora, 2000 2. http://www. cs.umd.edu/users/cml/style/ - ghid privind stilul de programare in limbajele C si C++. 3. http://www.programmingtutorials.com tutoriale de programare pentru C, C++ precum si pentru alte limbaje. 4. http://www.snippets.org exemple de programe scrise in limbajul C.
155
Funcii
Aplicaia 6
5 puncte declaraii corecte 5 puncte funcia care determin numrul de numere din fiierul de intreare 5 puncte determinarea numrul de numere din fiierul numere.in care au exact 3 cifre 5 puncte - determinarea celui mai mare numr din fiierul numere.in 5 puncte - scrierea rezultatelor in fiierul de ieire 5 puncte declaraii corecte 10 puncte afieaz cifrele distincte din n 25 puncte 10 puncte afieaz cte numere se pot forma cu toate cifrele distincte din n 5 puncte a) 20 puncte 10 puncte b) 5 puncte c) 5 puncte corectitudinea antetultui, a listei de 10 puncte parametri 5 puncte scrierea corect a blocului funciei 100 puncte
Punctaj minim: 80 puncte. 1. Se consider programul: #include<iostream.h> int a,b,c; void expresie(int a, int b) {a+=c; b+=c; c=a+b;} void main() { a=1; b=2; c=3; expresie(a,b); cout<<a<<b<<c;} Dup executarea programului, ce se va afia? a) 129 b) 219 c) 126 d) 216 2. ncercuiete A sau F n funcie de corectitudinea declaraiilor urmtoare: 156
Proiectul pentru nvmntul Rural
Funcii
A A A A
/ / / /
F a) int maxim (int a,b,x,k); F b) float calcul(int x, int a[5], int b[5][5]); F c) int testare( int x, int x[10]); F d) produs( int n);
3. Ce va afia urmtorul program? #include<iostream.h> int expresie1(long n, int c) { if(n<10) return(c==0); else if (n%10==c) return 1; else return expresie1(n/10,c); } int expresie2(long n) { int i,m; m=0; for (i=1;i<=10;i++) if(expresie1(n,i)) m++; } void main() {cout<<expresie2(12129002);} a) 8 b)3 c)4 d)10
4. Consider funcia: int expresie(long k) { if (k==0) return 1; else if( k%10!=0) return expresie(k/10)*(k%10); else expresie(k/10); } Care va fi valoarea expresiei: expresie(192)+expresie(2005) ? a) 28 b)18 c)8 d)2
5. n fiierul numere.in se afl numere cu cel mult 10 cifre fiecare. Pe aceeai linie numerele sunt separate prin cte un spaiu. Scrie un program care creaz un fiier numere.out cu urmtorul coninut: - pe prima linie numrul de numere din fiierul numere.in; - pe a doua linie numrul de numere din fiierul numere.in care au exact 3 cifre; - pe a treia linie cel mai mare numr din fiierul numere.in. Ex: Fiierul numere.in conine: 12 34 567 1223456 89 789 90 89 13 56 7890 Fiierul numere.out conine: 11 2 1223456
157
Funcii
6. Considderm un numr cu cel mult 10 cifre. Scrie un progam care: - afieaz cifrele distincte din n. Vei folosi pentru aceasta o funcie care va construi un vector cu cifrele distincte din n. - afieaz cte numere se pot forma cu toate cifrele distincte din n. Ex: Pentru n=20055, se va afisa: 205 4 7. Considerm programul: #include<iostream.h> int x[11], y[11], dx,dy; void cit(int n, int x[11]) { cin>>n; for(int i=1;i<=n;i++) cin>>x[i];} int suma(int n, int x[11]) { int i,s; s=0; for(i=1;i<=n;i++) s+=x[i]; return s; } void main() { cit(dx,x);cit(dy,y); cout<<suma(dx,x)<<endl<<suma(dy,y); } a) Ce se va afia pe ecran dup executare dac dx=3, x=(1,2,3), dy=5, y=(1,2,3,4,5)? i) 0 0 ii) 6 6 iii) 15 15 iv)6 15 b) Transform funcia iterativ suma() ntr-o funcie recursiv. c) Cum se modific programul astfel nct s se afieze valorile 6 15. 8. Scrie o funcie recursiv care determin elementul maxim dintre componentele unui vector. Funcia va avea ca parametri vectorul i lungimea sa.
158
Anexe Laboratorul 1
ANEXE Laboratorul 1
n cadrul acestui laborator v vei familiariza cu calculatorul i cu mediul de lucru al limbajului C/C++; de asemenea, va trebui s efectuai un instructaj pentru protecia muncii n cadrul laboratorului. n continuare v este prezentat un exemplu de aplicaie din cadrul Capitolului 2, rezolvat prin reprezentarea algoritmului prin schem logic; reprezentarea prin pseodocod v revine vou. Avei posibilitatea s v verificai temele de autoevaluare 2, 3 i 4 din Capitolul 2
Exemplul 2.5
S se realizeze schema logic pentru evaluarea expresiei:
159
Anexe Laboratorul 1
START
CITESTE A,B,C
DA C<0
NU
NU E=A2-B C=0
DA
NU AFISEAZA E
Afiseaza Expesia nu are sens
A2-B>=0
E= A2 B
NU
A=0
DA
AFISEAZA E
E=
1 A2
B
Afiseaza Expesia nu are sens
AFISEAZA E
STOP
Testul de autoevaluare 2.2 1. Un melc se deplaseaz cu viteza v km/sptmn. De ct timp (n ore) are nevoie melcul pentru a strbate distana d dat n metri. 1km=1 000m; 1 sptmn = 7 zile = 7 . 24 ore = 168 ore; v km/sptmn = 1 000 / 168 m / or;
160
Anexe Laboratorul 1
2. Perimetrul unui ptrat este egal cu latura altui ptrat. tiind c suma perimetrelor este x, s se calculeze ariile celor dou ptrate. Perimetrul P1=4 L1 P1=L2 i P2=4 L2 4 L1 = L2 P1 + P2 = x 4 L1 + 4 L2 = x 5 L2 =x L2=x/5 i L1= L2/4. adic L1=x/20 Deci A1 = L12 = (x/20)2 i A2 = L22 = (x/5)2 n acest caz, algoritmul poate fi scris astfel:
real x, L1, L2, A1, A2 citete x L2=x/5 L1=L2/4 A1=L1*L1 A2=L2*L2 scrie A1, A2
sau aa:
real x, A1, A2 citete x A1=(x/20)*(x/20) A2=(x/5)*(x/5) scrie A1, A2
161
Anexe Laboratorul 1
Observaie: Modul de rezolvare al unei probleme nu este unic. 3. Fiind date trei numere ntregi a, b ,c, s se interschimbe valorile celor trei numere, astfel: b, c, a (a primete valoarea lui b, b pe a lui c i c ia valoarea lui a); c, a, b (a primete valoarea lui c, b pe a lui a i c ia valoarea lui b); c, b, a (se inverseaz ordinea variabilelor). Indicaie: se folosete o singur variabil auxiliar, aux, pentru a putea face interschimbrile necesare
ntregi a, b, c, aux citete a, b, c aux=a a=b b=c c=aux scrie a, b, c stop
a aux
Se procedeaz asemntor i n cazul celorlalte dou situaii 4. Se dau patru numere a, b, c, d reale. S se permute valorile acestor variabile astfel nct la tiprire ele s aib valorile rezultate din permutrile lor circulare , la stnga, respectiv la dreapta, cu o poziie: b, c, d, a d, a, b, c Problema este asemntoare cu cea anterioar; iat o secven din rezolvarea celui de-al doilea subpunct: ..........
aux=a a=d d=c c=b b=aux
Testul de autoevaluare 2.3 1. Se d sistemul de 2 ecuaii cu 2 necunoscute x i y, iar a, b, c, d, p i q sunt parametri reali (coeficienii necunoscutelor i termenii liberi):
ax + by = p cx + dy = q
S se scrie algoritmul de rezolvare a sistemului de ecuaii. Problema trebuie analizat i rezolvat din punct de vedere matematic:
x= y =
162
pd bq ad bc aq cp ad bc
daca ad bc 0
Anexe Laboratorul 1
n cazul n care numitorul fraciilor este egal cu zero, cele dou ecuaii reprezentate grafic vor fi dou drepte paralele sau confundate; primul caz are loc dac pd-bq0 i n aceast situaie sistemul nu are nici o soluie este incompatibil iar n caz contrar are o infinitate de soluii este nedeterminat iar soluiile vor fi mulimea punctelor situate pe cele dou drepte confundate.
2. S se scrie algoritmul de rezolvare a urmtoarei probleme: acum este ora h1, minutul m1 i secunda s1. Ct va fi ceasul peste h2 ore, m2 minute i s2 secunde? Rezultatul va fi reprezentat tot n ore, minute i secunde. Trebuie inut cont de faptul c 1min=60 secunde, 1h=60 min i o zi are 24 de ore. Astfel, dac suma secundelor depete valoarea 60, atunci nseamn c 60 secunde vor da 1 minut. La fel se ntmpl i n cazul minutelor, dac suma lor este mai mare dec 60, va fi o or n plus. De fiecare dat va trebui s scdem cele 60 de uniti care au fost transformate ntr-o unitate de rang superior. Reprezentarea m pseudocod a acestei secvene de algoritm poate fi:
dac s1+s2>=60 atunci s=s1+s2-60 m1=m1+1 altfel s=s1+s2 dac m1+m2>=60 atunci m=m1+m2-60 h1=h1+1 altfel m=m1+m2 dac h1+h2>=24 atunci h=h1+h2-24 altfel h=h1+h2
3. Dndu-se trei valori ntregi a, b i c, s se afieze valorile lor n ordine cresctoare. Trebuie s permutm valorile celor 3 variabile, astfel nct, la final, ele s fie ordonate cresctor. Valorile variabilelor se compar dou cte dou i, dac nu respect ordinea dorit, i interschimb valorile prin intermediul unei variabile auxiliare aux.
dac a>b atunci aux=a a=b Proiectul pentru nvmntul Rural
163
Anexe Laboratorul 1 b=aux dac b>c atunci aux=b b=c c=aux dac a>b atunci aux=a a=b b=aux
(2k 1)
k =1
n N
Problema seamn foarte mult cu cea referitoare la calcularea sumei primelor n numere naturale, cu deosebirea c pasul de incrementare al variabilei de tip contor este 2 (Ex. 2.8)
intregi n, k, s citete n k=1 s=0 repet s=s+i k=k+2 pn_cnd k>2n-1 scrie s stop
2. Se citete un ir de numere naturale pn la introducerea valorii zero. S se determine media aritmetic a numerelor pare introduse i produsul numerelor impare. Pentru rezolvarea problemei trebuie folosit o structur repetitiv cu test iniial, verificndu-se de fiecare dat dac numrul citit a fost zero. Pentru a calcula media aritmetic a unui ir de numere,
164
Anexe Laboratorul 1
trebuie calculat mai nti suma acestora i, n acelai timp, numrndu-se cte valori au fost introduse n sum. Media lor aritmetic va fi egal cu suma acestora mprit la numrul de valori introduse n sum. Atenie! Dac aceast valoare este zero, nu avem voie s facem mprirea! Pentru calcularea sumei, respectiv produsuului, se va proceda ca n exemplele prezentate. Pentru testarea paritii unui numr este folosit simbolul %, ce reprezint operatorul pentru determinarea restului la mprirea a dou numere ntregi.
real medie ntreg x, n, S, P citete x n=0 S=0 P=1 cat_timp x 0 execut daca x%2=0 atunci S=S+x n=n+1 altfel P =P * x citete x
x este par
dac n 0 atunci medie=S/n scrie medie altfel scrie Nu au fost introduse numere pare dac P 1 atunci scrie P altfel scrie Nu au fost introduse numere impare sau 1 stop
3. Se citete un ir de numere naturale pn la introducerea valorii zero. S se determine suma numerelor de pe poziiile pare (suma dintre al doilea, al patrulea, etc) i produsul numerelor de pe poziiile impare (produsul dintre primul, al treilea, al cincilea, etc). Diferena fa de problema anterioar const n selectarea elementelor care se introduc n sum, respectiv produs. De data aceasta, trebuie verificat paritatea sau imparitatea poziiilor n irul numerelor introduse
ntreg x, n, S, P citete x n=0 S=0 P=1 cat_timp x 0 execut n=n+1 daca n%2=0 atunci S=S+x altfel P =P * x citete x dac n 0 atunci scrie S, P Proiectul pentru nvmntul Rural
poziie par
165
Anexe Laboratorul 1 altfel stop scrie Nu au fost introduse numere diferite de zero
1 k { 1, n} , k (k + 1)
iar pentru cea de-a doua expresie este:
2k k { 1, n} (2k 1)(2k + 1)
k =1
n 1 i E 2 = k (k + 1) k =1
2k (2k 1)(2k + 1)
sau
E2=0
n 5. Dndu-se a, b i c, coeficienii unei ecuaii de gradul doi, s se calculeze: S n = x1n + x 2 , unde n * N este dat, fr a se rezolva ecuaia (innd cont de valorile lui P i S).
Pentru determinarea lui S n este necesar cunoaterea valorilor sumelor de ordin n-1 , respectiv n2. Asta nseamn c la nceput trebuie cunoscute valorile lui S1 = b / a i S 2 = S12 2 * c / a , din care se poate calcula valoarea lui S3, din sumele S2 i S3 se poate calcula S4 , i aa mai departe. n implementarea acestui algoritm sunt necesare trei variabile pentru sume, i anume S1, S2 i S; la un moment dat, din valorile lui S1 i S2, folosind relaia matematic de recuren pentru calculul lui Sn, se obine o nou valoare pentru S, se incrementeaz contorul ce ine evidena numrului de ordine al sumei calculate i se determin noile valori pentru S1 i S2: S1 preia valoarea lui S2, S2 pe a lui S, i se poate trece la un nou pas n determinarea sumei cerute
166
Anexe Laboratorul 1 real S1, S2, a, b, c intreg n,i citete a, b, c citete n S1=-b/a S2 = S1*S1-*c/a pentru i=3, n execut S= -c/a*S1 b/a*S2 S1= S2 S2= S scrie S stop
167
Anexe Laboratorul 2
Laboratorul 2
3.6.4 Operatori logici pe bii
Posibilitatea utilizrii operatorilor pe bii ofer limbajului C faciliti asemntoare cu cele ale limbajelor de asamblare. Operatorii de prelucrare la nivel de bit sunt: & I | SAU ^ SAU exclusiv ~ NEGARE >> Deplasare dreapta << Deplasare stnga Cu excepia operatorului ~ care este un operator unar, ceilali operatori sunt binari. Operanzii pot avea numai tipuri ntregi. Operatorul & I pe bii are sintaxa: expr1 & expr2 n urma folosirii acestui operator, biii pe poziii egale din cele dou expresii care au valoarea 1 vor determina aceeai valoare 1 pe bitul de pe aceeai poziie din rezultat; Pentru celelalte cazuri, biii rezultatului vor lua valoarea 0. Exemplul 3.20 Cel de-al optulea bit este n general bitul de paritate. Pentru ca acestuia s i se dea valoarea zero, se face I logic pe bii ntre acest octet i unul n care biii de la 1 la 7 sunt egali cu 1, iar al optulea este zero, adic numrul 127. Expresia ch & 127 semnific aplicarea unui I biilor din ch cu biii care alctuiesc numrul 127. Rezultatul este acela c al optulea bit din ch este stabilit la zero. Presupunem c ch a primit ca valoare caracterul A i avea stabilit bitul de paritate: Bit de paritate 11000001 01111111 & 01000001 A fr paritate Operatorul | SAU pe bii are sintaxa: expr1 | expr2 n urma folosirii acestui operator, biii pe poziii egale din cele dou expresii care au valoarea 0 vor determina aceeai valoare 0 pe bitul de pe aceeai poziie din rezultat; Pentru celelalte cazuri, biii rezultatului vor lua valoarea 1. ch conine A cu paritatea stabilit 127
168
Anexe Laboratorul 3
Exemplul 3.21 Operatorul SAU logic pe bii poate fi folosit pentru a stabili valoarea unui bit. Orice bit cu valoarea 1 dintr-unul din operanzi determin ca bitul corespunztor din rezultat s fie setat la 1. De exemplu, iat operaia 128 | 3: 10000000 128 n binar 00000011 3 n binar | 10000011 rezultatul lui SAU pe bii Operatorul ^ SAU EXCLUSIV pe bii are sintaxa: expr1 ^ expr2 n urma folosirii acestui operator, biii pe poziii egale din cele dou expresii care au valoari diferite vor determina valoarea 1 pe bitul de pe aceeai poziie din rezultat; Dac biii sunt egali, biii rezultatului vor lua valoarea 0. Exemplul 3.22 Operatorul SAU exclusiv, ntlnit i sub denumirea de XOR, acioneaz asupra unui bit dac i numai dac biii respectivi sunt diferii. De exemplu, 127^120 este: 01111111 127 n binar 01111000 120 n binar ^ 00000111 rezultatul lui XOR pe bii Operatorul ~ NEGAIE pe bii are sintaxa: ~a i face ca pe toate poziiile folosite la stocarea valorii expresiei a s aib loc complementarea biilor fa de 1. Exemplul 3.23 Fie numrul 120; s aplicm operatorul de negare pe bii pentru acest numr: 01111000 120 n binar ~ 10000111 rezultatul negrii pe bii 135 Se poate observa c suma dintre un numr i negatul su pe bii este ntotdeauna 255=28-1=111111112. Operatorii <<, respectiv >>, sunt numii operatori de deplasare la stnga, respectiv la dreapta. Ei au sintaxa: a<<n a>>n i sunt echivaleni nmulirii, respectiv mpririi ntregi cu 2n.
Proiectul pentru nvmntul Rural
169
Anexe Laboratorul 2
Fie biii b1 i b2. Conform celor spuse mai sus, rezultatele principalelor operaii pe bii sunt: Tabel ul 3.4 Exemplul 3.24 b1 0 0 1 1 b2 0 1 0 1 b1&b2 0 0 0 1 b1^b2 0 1 1 0 b1|b2 0 1 1 1 ~b1 1 1 0 0
nmulirea i mprirea folosind operatorii de deplasare unsigned char x valoarea binar a lui x valoarea rezultat pentru x x=7; 00000111 7 x=x<<1; 00001110 14 x=x<<3; 01110000 112 x=x<<2; 11000000 192 x=x>>1; 01100000 96 x=x>>2; 00011000 24 Tabelul 3.5 Fiecare deplasare la stnga determin o nmulire cu 2. Remarcai c s-a pierdut informaia dup x<<2, deoarece un bit a depit marginea din partea stng. Fiecare deplasare la dreapta determin o mprire ntreag cu 2. Remarcai c mpririle ulterioare nu readuc biii pierdui.
170
Anexe Laboratorul 3
Laboratorul 3
4. 4 Funcii de citire/scriere caractere
Funcia getchar() are forma general int getchar(void); i are rolul de a citi din stdin un caracter, citirea terminndu-se la apsarea tastei enter. Cuvntul cheie void are semnificaia c lista parametrilor de apel este vid. Pentru scrierea unui caracter se folosete funcia putchar(). Sintaxa acestei funcii este: int putchar(int); Dei sunt tratate caractere, se poate observa c parametrul de intrare al acestei funcii este de tip int, avnd loc o conversie implicit a caracterului n ntreg (valoarea codului ASCII al caracterului respectiv). Exemplul 4.8 Se citete un caracter de la tastatur, care apoi se va tipri char a; a=getchar(); putchar(a); Aceast secven este echivalent cu urmtoarea: putchar(getchar()); Trecerea cursorului pe un rnd nou se poate face i astfel: putchar(\n); de fapt se afieaz secvena escape \ncorespunztoare pentru new line. O alt funcie de intrare este getche() (get character with echo) care permite preluarea caracterelor imediat ce au fost tastate, fr a mai apsa tasta enter. Caracterul tastat este afiat pe ecran n ecou. O funcie asemntoare este getch(), care nu mai afieaz caracterul tastat (fr ecou). Aceste dou funcii aparin bibliotecii de funcii conio.h (console input/output). Exemplul 4.9 main() { char ch; printf(Tasteaza un caracter: ); ch=getche();
Proiectul pentru nvmntul Rural
171
Anexe Laboratorul 3
printf(\nCaracterul tastat a fost %c.,ch); } n urma execuiei programului, are loc urmtoarea interaciune cu operatorul: Tasteaza un caracter: A Caracterul tastat a fost A n cazul tastrii caracterului A. Nu mai este necesar apsarea tastei enter dup ce a fost tastat caracterul cerut. Funcia gets() citete un ir de caractere din fiierul standard de intrare. Sintaxa acestei funcii este: char *gets(char *s); n acest caz, spre eosebire de funcia scanf(), se pot introduce spaii i tab-uri n componena irului de caractere. Citirea se termin la apsarea tastei Enter, cnd se nlocuiete caracterul \n cu terminatorul de ir \0. Dac s-a citit corect irul, se ntoarce valoarea lui s, n caz de eroare sau de sfrit de fiier, se ntoarce pointerul NULL. Funcia puts() scrie un ir de caractere specificat ca parmetru n fiierul standard de ieire. Sintaxa acestei funcii este: int puts(char *s); Dup afiarea irului se trece la linia urmtoare. Exemplul 4.10 Programul urmtor citete numele i prenumele unei persoane, dup care face afiarea acestora: #include <stdio.h> main() { char nume[20], pren[30]; printf(Tasteaza numele: ); gets(nume); printf(Tasteaza prenumele: ); gets(prenume); puts(nume); puts(prenume); }
Anexe Laboratorul 3
cin console input dispozitiv de introducere de la tastatur echivalent cu stdin din C. Pentru a putea realiza operaii de intrare/ieire trebuie folosit biblioteca iostream.h. Modul de utilizare este urmtorul: cout<<expresie1<<expresie2.<<expresien; cin>>expresie1>>expresie2.>>expresien; Tipurile datelor citite/scrise sunt toate tipurile aritmetice i irurile de caractere; aceste operaii nu necesit un anumit format pentru executarea lor. Exemplul 4.11 Aplicaia din Exemplul 4.5 poate fi rescris cu ajutorul lui cin i cout astfel: #include <iostream.h> main() { int ev; float timp; char poz; cout<<Introduceti poz, ev,timp: cin>>poz>> ev>> timp; cout<<Evenimentul <<poz<< are numarul <<ev; cout<< si a avut loc la <<timp<<timp.; } Executarea acestui program va avea acelai efect cu cel din exemplul amintit. n cazul citirii irurilor de caractere, caracterul nul (\0)este adugat automat, dar nu poate fi citit un ir care conine mai multe cuvinte separate prin spaii sau tab-uri; citirea se oprete la ntlnirea unui astfel de caracter. Din acest motiv, pentru citirea irurilor de caractere se folosete o funcie de un tip special, i anume funcia: cin.get(sir_de_caractere, int nr, char=\n); citete un ir de caractere pn cnd este ndeplinit una din condiiile de mai jos: au fost citite n-1 caractere; a fost citit caracterul transmis ca ultim parametru (implicit \n); Observaii: sunt citite i caracterele albe spaii, tab-uri; este inserat caracterul nul - \0 la sfritul irului de caractere; caracterul transmis ca ultim parametru nu este inserat n ir; al treilea parametru este trecut n mod facultativ, dac nu este precizat se presupune c este \n.
173
Anexe Laboratorul 3
Exemplul 4.12 a) S se citeasc un ir de maxim 5 caractere. char s[10]; cin.get(s,6); cout<<s; De exemplu, dac se tasteaz cuvntul calculator i apoi se apas tasta Enter, va fi afiat calcu. b) S se citeasc un ir de maxim 10 caractere, cu oprirea citirii la ntlnirea caracterului t, char s[11]; cin.get(s,11,t); cout<<s; n acest caz, programul va afia cuvntul calcula. Atenie! Dac se utilizeaz de mai multe ori funcia cin.get() cu trei parametri, citirea nu se efectueaz corect datorit interpretrii caracterului corespunztor tastei Enter, care rmne n memoria tampon a calculatorului drept terminare de ir,i, prin urmare al doilea ir de caractere nu mai este citit. Aceast problem se poate soluiona prin folosirea unei funcii cin.get() fr parametri, dup una cu parametri, pentru a se goli memoria tampon. Exemplul 4.13 S se citeasc numele i prenumele unei persoane, folosindu-se pentru fiecare din ele cte un ir de caractere. #include <iostream.h> #include <string.h> main() { char nume[20], pren[30]; cout<<Dati numele: ; cin.get(nume,20); cin.get(); cout<<Dati prenumele: ; cin.get(pren,30); cout<<nume<< <<pren; } Pentru a v convinge de cele artate mai sus, executai programul de mai sus i n situaia n care lipsete instruciunea de citire fr parametri i comparai cele dou soluii.
174
Anexe Laboratorul 3
175
Anexe Laboratorul 4
Laboratorul 4
Exemplul 5.5 Se citesc a,b,c coeficienii reali ai ecuaiei de gradul II ax2+ bx+c=0. Se cere s se scrie un program care s rezolve ecuaia. Varianta 2: # include<iostream.h> # include<math.h> void main() { float a,b,c,d; cout<<"a=";cin>>a; cout<<"b=";cin>>b; cout<<"c=";cin>>c; a?d=b*b-4*a*c, d>=0?cout<<"x1="<<(-b+sqrt(d))/(2*a)<<"\n"<<"x2="<<(-b-sqrt(d))/(2*a): cout<<" nu are solutii reale": b?cout<<"x="<<(-c/b): c?cout<<"ecuatia nu are solutii": cout<<"infinitate de solutii"; } Observaii: Pentru a rula programul implementat in mediul limbajului C / C++ se tasteaz CTRL+F9. Dac sunt erori de sintax, apare un mesaj de eroare, iar cursorul este poziionat n zona n care se presupune c exist eroarea. n acest caz, se efectueaz corecia necesar i se ncearc, din nou, rularea programului (CTRL+F9). n cazul n care nu avem erori se execut programul. Rezultatele apar scrise in fereastra utilizator (user screen). Dac se lucreaz sub DOS, pentru vizualizarea rezultatelor se tasteaz ALT+F5. n acest caz, revenirea n fereastra textului surs se face prin apasarea tastei Enter sau ALT+F5.
176
Anexe Laboratorul 4
177
Anexe Laboratorul 4
Doi copii vopsesc un gard alctuit din n scnduri (numerotate de la 1 la n, n< 100000) astfel: primul ia o cutie de vopsea roie cu care vopsete scndurile cu numrul p, 2p, 3p, etc. Al doilea procedeaz la fel, ncepe de la acelai capt al gardului, dar folosete o cutie de vopsea albastr i vopsete din q n q snduri. Astfel, cnd vor termina de vopsit, gardul va avea multe scnduri nevopsite, unele scnduri vopsite n rou, altele n albastru, iar altele n violet ( albastru i rou). Cunoscnd numerele n, p, q, scriei un program care s afieze: - cte scnduri rmn nevopsite - cte scnduri sunt vopsite n rou - cte scnduri sunt vopsite n albastru - cte scnduri sunt vopsite n violet Exemplu: n=25, p=4, q=6 se vor afia valorile 17 4 2 2. Dei algoritmul nu este eficient, voi parcurge succesiv toate scndurile i voi verifica pentru fiecare scndur toate cazurile. Ilustrez astfel instruciunea for. #include<iostream.h> void main() { long int n, i, p,q, nec,rosu, albastru, violet; cout<<"nr. de scanduri n="; cin>>n; cout<<"p si q: ";cin>>p>>q; nec=rosu=violet=albastru=0; for(i=1;i<=n;i++) if(i%p==0 && i%q==0)violet++; else if(i%p==0) rosu++; else if (i%q==0)albastru++; else nec++; cout<<nec<<" "<<rosu<<" "<<albastru<<" "<<violet; }
178
Anexe Laboratorul 4
Tem de reflecie 5.1 Analizeaz algoritmul Exemplului 5.11 i rspunde cerinelor de mai jos. Fiecare rspuns corect valoreaz 30 puncte. Punctaj minim: 70. Se acord 10 puncte din oficiu. 1. Urmrete pas cu pas execuia programului din Exemplul 5.11 pentru n=7; 2. Modific algoritmul din Exemplul 5.11 astfel nct s calculeze suma primilor n termeni din irul Fibonacci. 3. Modific algoritmul din Exemplul 5.11 astfel nct s calculeze cel mai mare termen din irul Fibonacci mai mic sau egal cu n.
179
Anexe Laboratorul 4
Lucrare practic 5.1 ( n laboratorulul de informatic) Scrie i implementeaz programe C / C++ pentru rezolvarea urmtoarelor aplicaii. Fiecare cerin se noteaz cu 20 de puncte. Punctaj minim: 80 puncte. 1.S se determine cel mai mare numr care se poate forma cu ajutorul cifrelor unui numr natural citit de la tastatur. Ex: fie 2781 numrul dat; cu cifrele sale se poate forma numrul 8721 cu proprietatea dat. 2. Se dau n numere naturale nenule (n<40). Se cere s se afieze cel mai mare divizor comun. Ex: fie n=4 i numerele 16 40 36 8, se va afia 4. 3. Se consider un ir de n (n<10) numere naturale. S se verifice dac numrul format din primele cifre ale acestora este un palindrom. Un numr este palindrom dac citit de la sfrit la nceput este aceelai numr. Ex: fie n=5 i numerele 123, 435, 92, 4762, 10000 se obine numrul 14941 care este un palindrom. 4. Un mare bogta are un seif cu cifru. Pentru a nu uita cifrul, bogtaul vrea s-l scrie pe o foaie, dar codificat: fiecare cifr s fie nlocuit cu diferena dintre cifra 9 i cifra respectiv. Scrie un program care preia cifrul de la tastatur (prima cifr este diferit de 0), l codific dup metoda tiut i afieaz cifrul codificat. Ex: cifrul 43746521 se codific n 56253478. 5. Se extrag dintr-o urn bile pe care sunt scrise numere naturale. Extragerea se face pn la ntlnirea bilei cu numrul 1. Scrie un program care simuleaz aceasta i afieaz numrul cifrelor 0 n care se termin numrul produs al numerelor citite. Ex: se extrag bile cu numerele 15 20 4 12 1; numrul cifrelor 0 este 2.
Sarcin de lucru 5.1 Variant corect: # include <iostream.h> void main() { int n,i; float x,p=1; cin>>n; cin>>x; i=1; while (i<=n) {p*=x; i++;} cout<<p=p; } Sarcin de lucru 5.2 Variante corecte: e) 2
Proiectul pentru nvmntul Rural
180
Anexe Laboratorul 4
b) #include< iostream.h> void main() { int a,b, nr=0, i; cout<< a=;cin>>a; cout<< b=;cin>>b; i=a; nr=0; if (i<=b) do{ if (i%2==0) nr++; i++; } while (i<=b); cout<<nr=<<nr; } c) n variabila nr numrm valorile pare din intervalul [a,b]. Lucrare practic 5.1 1. Soluie: algoritmul realizeaz numrarea apariiilor fiecrei cifre n ordine descresctoare de la 9 la 0 i afiarea succesiv a acestora. # include <iostream.h> main() { long nr, a, I, aparitie, j; cin>>nr; for(j=9;j>=0;j--) { a=nr; aparitie=0; do{ if(a%10==j aparitie++; a/=10; }while (a>0); for (i=1;i<=aparitie;i++) cout<<j; } } 2. Soluie: voi determina cel mai mare divizor comun dintre primul numr i al doilea, apoi cel mai mare divizor dintre numrul obinut i al treilea, .a.m.d. #include<iostream.h> void main() {long n,x,a,b,d,i; cout<<n=; cin>>n; cin>>x; d=x; for(i=2;i<=n;i++) { cin>>x; a=d; b=x; while(a!=b) if(a>b) a-=b; else b-=a; d=a; } cout<<c.m.m.d.c=<<d; }
181
Anexe Laboratorul 4
3. Soluie: voi determina succesiv cifrele cele mai semnificative ale numerelor din ir, prin mprirea la 10, pn cnd se ajunge la valori mai mici sau egale cu 9. Cu aceste cifre voi forma un numr nou i apoi voi verifica dac este palindrom. #include< iostream.h> void main() { long a,b,c,n,x,i; cin>>n; a=0; for(i=1;i<=n;i++) { cin>>x; while (x>9) x/=10; a=a*10+x; } b=a; c=0; while( b!=0) { c=c*10+b%10; b/=10; } if(c==a) cout<<a<< este palindrom; else cout<<a<< nu este palindrom; }
182
Anexe Laboratorul 5
Laboratorul 5
Exemplul 6.4 Se consider un vector cu n componente numere ntregi, ordonate cresctor i un numr ntreg x. S se determine dac acest numr se afl printre componentele vectorului, iar n caz afirmativ, poziia sa n vector. Pentru acest exemplu s-ar putea folosi ca metod de rezolvare algoritmul prezentat n cazul exemplului 6.2, dar nu ar fi o metod eficient, deoarece nu se ine cont de faptul c vectorul este deja ordonat cresctor; prin urmare, cnd numrul x este comparat cu un element din vector a[i], se pot lua mai multe decizii; dac numrul x este egal cu a[i], atunci se poate spune c numrul se afl n vector pe poziia i; dac x este mai mic dect a[i], se poate deduce c acesta se poate afla pe poziiile mai mici dect i, respectiv pe poziiile mai mari dect i, n caz contrar. n continuare este prezentat algoritmul cutrii binare, care rspunde cerinelor acestei probleme. main() {int a[20], n, i, x, gata=0, li, ls, m; .................................... li=0; ls=n-1; while (!gata && li<=ls) { m=(li+ls)/2; if (x==a[m]) gata=1; else if(x<a[m]) ls=m-1]; else li=m+1; } if (gata) printf(%d se afla pe pozitia %d in vector.\n,x,m); else printf(%d nu se afla in vector.\n,x); } n rezolvarea acestei probleme au fost folosite urmtoarele variabile de lucru: li i ls, reprezentnd limita inferioar, respectiv superioar ntre care se efectueaz cutarea la un moment dat n vector; m reprezint mijlocul intervalului de cutare, fiind egal cu media aritmetic a capetelor acestuia; gata este o variabil necesar sesizrii momentului n care a fost gsit valoarea cutat n vector i opririi acestei cutri. Pentru nceput, valorile limitelor inferioare i superioare sunt iniializate cu zero, respectiv n-1, capetele vectorului, iar gata este iniializat cu zero. 183
Anexe Laboratorul 5
S presupunem c elementele vectorului sunt: 2, 5, 8, 9, 11, 14 (n=6) iar numrul cutat este x=11; li=0, ls=5, gata=0; este gata=0 i li<=ls? da //0<=5 m=2 //(0+5)/2 este 11=8? nu este11<8? nu li=3 este gata=0 i li<=ls? da //3<=5 m=4 //(3+5)/2 este 11=11? da gata=1 este gata=0 i li<=ls? nu este gata=1? da scrie 11 se afla pe pozitia 4 in vector. Pentru aceleai elemente ale vectorului, dar x=4, algoritmul va funciona astfel: li=0, ls=5, gata=0; este gata=0 i li<=ls? da //0<=5 m=2 //(0+5)/2 este 4=8? nu este 4<8? da ls=1 este gata=0 i li<=ls? da //0<=1 m=0 //(0+1)/2 este 4=2? nu este 4<2? nu li=1 este gata=0 i li<=ls? da //1<=1 m=1 //(1+1)/2 este 4=5? nu este 4<5? da ls=0 este gata=0 i li<=ls? nu //1<=0 este gata=1? nu scrie 4 nu se afla in vector. n cazul n care numrul cutat nu se afl n vector, cutarea se oprete n momentul n care limita inferioar nu mai este mai mic sau egal dect cea superioar. Indicaii pentru rezolvarea testului de autevaluare 6.5 1. Se iniializeaz valorile variabilelor min_poz = MAXINT i max_neg = - MAXINT. Se parcurge vectorul, comparndu-se valorile pozitive cu min_poz, respectiv cele negative cu min_neg. n final, dac una dintre aceste valori rmne neschimbate, nseamn c nu au fost gsite astfel de valori n vector. Se folosesc doi vectori, mpreun cu 2 variabile de tip contor, reprezentnd poziiile din vectori pe care vor fi puse noile valori citite,
2.
184
Anexe Laboratorul 5
3.
n funcie de paritatea numerelor citite. Citirea se termin la introducerea valorii 0. Pentru un numr dat, se mparte acesta la 10, pn cnd numrul devine 0. La fiecare mprire, restul se depune n vector, iar numrul se micoreaz de 10 ori.
Aritmetica pointerilor
Operaiile aritmetice permise asupra pointerilor sunt: adunarea/scderea unei constante, incrementarea/decrementarea i scderea a doi pointeri de acelai tip. De asemenea, acestora li se pot aplica operatorii relaionali (pot fi comparate adrese de variabile chiar de tip diferit). Prin definiie, adunarea lui 1 la un pointer face ca el s indice urmtorul obiect de acelai tip, aflat n memorie la adrese succesive. Scderea lui 1 dintr-un pointer face ca el s indice obiectul imediat anterior n spaiul de memorie. Aceleai reguli se aplic la operatorii ++ i --. De exemplu, avnd declaraiile: int *pi; float *pf; *(pi+1) este urmtorul ntreg de dup *pi, iar *(pf-1) este numrul real aflat imediat naintea lui *pf. Similar *(pi+i) va reprezenta al i-lea ntreg succesiv din memorie, de dup adresa pi. De remarcat c ceea ce se adun efectiv este sizeof(int), respectiv sizeof(float). Semnificaia pointerilor poate fi alterat prin conversia explicit de tip (cast). Astfel, n exemplul de mai sus, expresiile: *((char*)pf) i *(((char*)pf)+1) vor furniza primul i, respectiv al doilea octet din reprezentarea unei variabile de tip float. Tipul expresiei (char*)pf este char* i adunarea lui 1 la aceast expresie va avansa pe pf cu un octet. Atribuirile de pointeri trebuie s se fac ntre pointeri (sau expresii) de acelai tip. Se poate folosi conversia explicit de tip, n cazul unor pointeri de tip diferit. Acest lucru trebuie evitat pentru a nu se realiza atribuiri defectuoase. Aritmetica unui pointer (adunri/scderi de constante) este garantat n standardul ANSI C a funciona corect numai dac pointerul se menine ntre limitele unui tablou declarat de variabile. n ceea ce privete scderea a doi pointeri, standardul ANSI C permite aceast operaie numai ntre pointeri de acelai tip, care s indice elemente ale aceluiai tablou. Dac p i q sunt doi pointeri de tip T*, respectnd aceste condiii i p indic un element al tabloului aflat n memorie dup q (adic la o adres mai mare), atunci diferena p-q reprezint numrul de obiecte de tip T aflate ntre p i q. n aceleai condiii ca la scdere, se pot face comparaii cu operatorii: ==, !=, <, <=, >, >=. Prin definiie, p>q este 1, dac se poate face diferena p-q (conform restriciilor de mai sus) i aceast diferen este pozitiv. Este
Proiectul pentru nvmntul Rural
185
Anexe Laboratorul 5
permis comparaia oricrui tip de pointer cu pointerul NULL. Doi pointeri nu se pot niciodat aduna. Exemplul 6.7 Studiai ce tiprete programul urmtor:
Figura 6.2 Comparai bucla for din acest exerciiu cu bucla for obinuit de tiprire a elementelor tabloului a, mpreun cu adresele acestor elemente: long a[10]={10, 11, 12, 13, 14, 15, 16, 17, 18, 19}; long i; for (i=0;i<10;i++) printf("Adresa: %p Elementul: %ld\n",&a[i], a[i]);
Anexe Laboratorul 5
D. *pi= 1; E. pi++; 2. Ce se tiprete n urma executrii secvenei de mai jos? int a=5; *&a=7; printf(%d,a); B. 5 C. eroare de sintax D. 7 3. Ce se tiprete n urma executrii secvenei de mai jos? int a=0x120f; printf(%d,*((char*)&a+1)); A. 18 B. 12 C. 15 4. Ce se tiprete n urma executrii secvenei de mai jos? int a=0x120f; printf(%d,*((char*)&a)+1); A. 16 B. 0x C. 19
5. Tiprii coninutul n hexazecimal al octetului cel mai semnificativ al unei variabile de tip long int.
Lucrare practic 6.1 ( n laboratorulul de informatic) Scriei algoritmul de rezolvare a urmtoarelor probleme. Rezolvarea fiecrei probleme valoreaz 20 de puncte. Punctaj minim: 80 1. Se citete de la tastatur un ir de caractere i un caracter. S se spun dac acest caracter exist n ir, iar n caz afirmativ s se indice poziia primei sale apariii..
2. Se citete de la tastatur un ir de caractere i un caracter. S se spun dac acest caracter exist n ir, iar n caz afirmativ s se indice poziiile tuturor apariiilor acestuia n ir i numrul total de apariii.
Proiectul pentru nvmntul Rural
187
Anexe Laboratorul 5
4. Dndu-se un ir de caractere s i un subir a, s se elimine din irul dat toate apariiile subirului:
5. S se nlocuiasc toate apariiile unui subir a cu un subir b dintr-un ir s. Datele de intrare se preiau de la tastatur.
188
Anexe Laboratorul 6
Laboratorul 6
Exemplul 7.13 S considerm urmtorul program: #include<fstream.h> #include<string.h> void main() {fstream f; char s[15], t[15]; f.open("test.txt",ios::in); // f este deschis pentru citire while(f.getline(s,15)) //se citeste cte o linie din fisier si se retine in s strcpy(t,s); // sirul s se copiaza in t cout<<t; f.close(); } tiind c lungimea maxim a unei linii din fiierului test.txt este 15, s verificm ce afieaz programul de mai sus.
Figura 7.1 Observaii: 1. Fiierul surs nu este denumit! Fiierul test.txt a fost construit naintea rulrii fiierului surs, prin deschiderea unei ferestre noi, scrierea coninutului fiierului i salvarea acestuia n directorul curent, cu extensia txt.
Proiectul pentru nvmntul Rural
189
Anexe Laboratorul 6
2. n figura 7.1 se observ c s-a afiat ultima linie din fiier. n realitate programul afieaz caracterul de sfrit de fiier care, n aceast situaie este dup cuvntul fiiere.
Tem de reflecie 7.1 Analizeaz algoritmul Exemplului 7.13 i rspunde cerinei de mai jos. Rspunsul corect valoreaz 20 puncte. Modific fiierul test.txt astfel nct rezultatul s fie afiarea caracterului de sfrit de fiier.
Exemplul 7.14 Se dau dou fiiere f1 i f2. S se concateneze cele dou fiiere date, iar rezultatul s fie fiierul f3. #include<fstream.h> void main() { char c; ifstream f1("fis1.txt"); ifstream f2("fis2.txt"); ofstream f3("fis3.txt"); while (!f1.eof()) {f1.get(c); f3<<c;} f1.close(); while (!f2.eof()) {f2.get(c); f3<<c;} /* se citeste un caracter din f2 si se scrie in f3 */
190
Anexe Laboratorul 6
f2.close(); f3.close(); } Observaii: 1. Programul este pur didactic. Sunt evideniate modurile de: deschiderea fiierelor; detectarea sfritului de fiier pentru fiecare fiier n parte; citirea cte unui caracter dintr-un fiier i scrierea lui n alt fiier, operaie repetat pn la ntlnirea caracterului de sfrit de fiier pentru fiierul de intrare; inchiderea fiierelor. 2. Programul se poate modifica cu uurin prin adaugarea coninutului fiierului f2 la sfritul fiierului f1, dac dorim concatenarea lui f2 la f1, sau invers. 3. n figura 1.2 se observ n fiierul fis3.txt existena unor caractere cu rou, care reprezint sfritul fiierelor f1 i f2.
Figura 7.2
Lucrare practic 7.1 ( n laboratorulul de informatic) Scrie i implementeaz programe C / C++ pentru rezolvarea urmtoarelor aplicaii. Fiecare cerin se noteaz cu 25 de puncte. Punctaj minim: 75 puncte.
191
Anexe Laboratorul 6
1. S se scrie un program care creaz fiierul numere.out, care s conin 1000 de numere aleatoare divizibile cu 5 din intervalul [1, 25000].
2. Profesorul a dat celor n (n natural) elevi ai si s realizeze cte un fiier text care s conin informaii despre modul de via al vieuitoarelor i le-a spus s salveze lucrrile cu numele: capitolul1.txt, capitolul2.txt, ..., capitoluln.txt. Scrie o aplicaie care s concateneze aceste fiiere n stream-ul ecosisteme.txt.
3. La petrecerea organizat cu ocazia srbtoririi a 10 ani de fiinare a firmei X sunt invitate s participe persoane al cror nume se afl n dou fiiere text (pe fiecare linie este trecut numele unei persoane). Alctuiete o list final astfel nct o persoan s nu fie onvitat de dou ori.
4. Se citete din fiierul elevi.in situaia la nvtur a fiecrui elev. Pe liniile impare se gsesc numele i prenumele elevilor. Pe cele pare se gsesc numere separate prin spaii, astfel: primul numr reprezint clasa (ex: 5 sau 8), apoi se regsesc mediile pe discipline. S se calculeze i s se afieze media general a fiecrui elev; n cazul n care elevul este corigent se va afia numrul disciplinelor cu corigent.
Lucrare practic 7.1 1. Pentru generarea numerelor aleatoare se va folosi funcia standard random() al crei prototip este int random (int x); se afl n stdlib.h i returneaz un ntreg cuprins ntre 0 i ( x-1). Apelul funciei random() trebuie s fie precedat de apelul funciei randomize(). 2. Parcurg ntr-un ciclu toate fiierele de la 1 la n. La fiecare pas n ciclu, deschid fiierul, adaug coninutul lui n stream-ul ecosisteme.txt i trec mai departe la urmtorul fiier. 3. Fie w vectorul n care voi obine lista final. Elementele acestui vector reprezint reuniunea celor dou liste din fiierele date. Pentru nceput voi copia n w toate numele din primul fiier, apoi parcurg al doilea fiier i adaug n w doar acele nume care nu se afl deja n w. 4. Pentru fiecare elev din fiier citesc numele i prenumele ntr-o variabil de tip string. De pe linia urmtoare citesc apoi clasa i mediile elevului (ntr+un ciclu pn la sfritul liniei), calculez media general. Totodat numr ntr-o variabil mediile sub 5 i dac la sfritul ciclului acest variabil e diferit de 0, atunci elevul este corigent i voi putea afia numrul disciplinelor la care este corigent. nainte de a trece la un alt elev se afieaz media general calculat.
192
Anexe Laboratorul 7
Laboratorul 7
Exemplul 8.9 Consider un vector a cu n componente (a[1], a[2], a[3], , a[n]). mi propun s calculez suma a[1]! + a[2]! + +a[n], folosind: - o funie pentru citirea vectorului a; - o funcie pentru calculul k! , unde k! = 1*2*3**K; - o funcie pentru calculul sumei componentelor unui vector. Ex: Pentru n=4, vectorul: 4, 1, 3, 2, se va afisa 33. Numerele a[1], a[2], a[n] i suma factorialelor nu depesc tipul long. De aceea funciile corespunztoare factorial, respectiv suma vor fi de acest tip. #include <iostream.h> int n; /* n este o variabil global, recunoscut n toate funciile programului*/ void citire (int n, long a[100]) { int i; for(i=1;i<=n;i++) cin>>a[i];} /* pentru calculul sumei componentelor vectorului, se parcurg elementele pe rnd i se introduc n sum.*/ long suma (int n, long a[100]) { int i; long s=0; for(i=1;i<=n;i++) s+=a[i]; return s; } /* pentru calculul factorialului, voi iniializa variabila f cu valoarea 1 (elementul neutru la nmulire) i voi calcula n f produsul 1*2*3**k */ long factorial (int k) { int i; long f=1; for(i=1;i<=k;i++) f*=i; return i; }
193
Anexe Laboratorul 7
/* funcia principal apeleaz funciile: citire(), factorial() i suma(); este interesant de urmrit modul n care aceste funcii sunt apelate: - apelul funciei citire() este unul caracteristic funciilor de tip void; - apelul funciei factorial() este membru drept ntr-o expresie; - apelul funciei suma() apare n funcia de scriere cout */ void main() { long a[100], b[100]; cin>>n; citire(n,a); for( int i; i<=n;i++) b[i]=factorial(a[i]); cout<<suma este<< suma(n,b); }
Exemplul 8.10 Consider un numr natural nenul n (n<21). Vreau s construiesc o matrice ptratic a=(aij)i,j=1,,n , unde aij este al i+j lea numr prim, apoi, pentru un x cifr citit de la tastatur s afiez toate elementele matricei care au k cifre distincte. Voi folosi: - o funcie care verific dac un numr este prim; - o funcie care returneaz al k-lea numr prim; - o funcie care returneaz numrul de cifre distincte ale unui numr natural. Ex: Pentru n=3 si k=2 se va afisa: 3 5 7 5 7 11 7 11 13 13
194
Anexe Laboratorul 7
#include<iostream.h> #include<math.h> int a[21] [21],n,x,k; /* functia prim verifica daca parametru sau este prim si returneaza 1 daca este prim, 0 altfel*/ int prim (int k) { int i; for(i=2;i<=k/2;i++) if(k%i==0) return 0; return 1; } /* functia n_prim returneaza a x-lea numar prim; pentru aceasta apeleaza functia prim() */ int n_prim(int k) {int p,nr; p=2; nr=0; while(nr<k){ if(prim(p))nr++; p++; } return p-1; }
Proiectul pentru nvmntul Rural
195
Anexe Laboratorul 7
/* functia construct are tipul void, lista parametrilor vida si va construi matricea patratica */ void construct() { int i,j; for(i=1;i<=n;i++) for(j=1;j<=n;j++) a[i][j]=n_prim(i+j); } int cifre_dist(int k) { int i,j,nr,b[20],m=0; while(k!=0){ i=k%10; m++; b[m]=i;k=k/10;} nr=0; for(i=0; i<=9;i++) for (j=1;j<=m;j++)if(i==b[j]){ nr++; break;} return nr; } /* functia principala apeleaza functiile construct, afiseaza matricea construita si elementele cu proprietaea ca au k cifre disticte */ void main() { int i,j,x; cout<<"n=";cin>>n; construct(); cout<<" matricea:"<<endl; for(i=1;i<=n;i++) {for(j=1;j<=n;j++) cout<<a[i][j]<<" "; cout<<"\n";} cout<<"x=";cin>>x; for(i=1;i<=n;i++) for(j=1;j<=n;j++)if(cifre_dist(a[i][j])==x) cout<<a[i][j]<<" "; }
196
Anexe Laboratorul 7
Scrie i implementeaz programe C / C++ pentru rezolvarea urmtoarelor aplicaii. Fiecare cerin se noteaz cu 25 de puncte. Punctaj minim: 75 puncte. 1. S considerm un vector cu n (n<101) componente numere naturale mai mici sau egale cu 30000. Afieaz numerele din vector care au cele mai multe cifre de 1 n repreyentare binar. Vei folosi: - o funcie pentru citirea vectorului; - o funcie pentru determinarea numrului de cifre 1 din reprezentarea binar a unui numr; - o funcie care returmeaz elementul maxim dintre componente unui vector. Ex: pentru n=3 si elementele vectorului 13, 9, 7, se va afisa 13 7 2. S considerm un vector cu n (n<101) componente numere naturale mai mici sau egale cu 30000. Determin componentele vectorului care au cei mai muli divizori. Pentru aceasta vei folosi: - o funcie pentru citirea vectorului; - o funcie pentru calculul numrului de divizori ai unui numr. Ex: pentru n=5 si elementele 10 29 6 2 11, se va afisa 10 6 3. Considerm un vector V cu n (n<51) componente ntregi. Pentru un k dat (0<kn), ordoneaz cresctor primle k elemente i descresctor celelalte componenteale lui V. Pentru aceasta vei folosi: - o funcie pentru citirea lui V; - o funcie pentru a ordona, la alegere, cresctor sau descresctor o parte din componentele unui vector. Ex: pentru n=9, k=3 si V ( 72 15 33 45 58 23 2 5 20), se va afisa 15 33 72 58 45 23 20 5 2 4. Considerm dou numere nenule n i k (n,k<1000). Determin numerele naturale x1, x2, ..., xk cu proprietile: - 0<x1<x2<...<xk - x1 + x2 +... +xk = n - numerele sunt cuburi perfecte. Folosete la scrierea programului o funcie pentru determinarea numerelor care ndeplinesc toate cerinele. Ex: pentru n=100 si k=5, se va afisa 1 8 27 64 100.
197
Anexe Laboratorul 7
Lucrare practic 8.2 ( n laboratorulul de informatic) Scrie i implementeaz programe C / C++ pentru rezolvarea urmtoarelor aplicaii. Problemele se noteaz, n ordine, cu 20 puncte, 40 puncte, respectiv 40 de puncte. Punctaj minim: 80. 1. Scrie un program care conine o funcii recursiv care permite citirea unei matrice cu n linii i m coloane. 2. Consider date de la tastatur n (1n10) numere naturale nenule x1, x2, ..., xn. S se calculeze suma p(x1)!+p(x2)!++p(xn)!, unde prin p(k) am notat prima cifr a numrului k, iar prin k! produsul 1*2*3*n. Se va folosi: - o funcie pentru citirea irului de numere; - o funcie recursiv pentru gsirea primei cifre dintr+un numr natural; - o funcie recursiv pentru calculul factorialului; - o funcie recursiv pentru calculul sumei elementelor unui vector. Ex: pentru n=3, x1=15, x2=321, x3=41, se va afisa valoarea 31. 3. Consider c se d un numr natural n(n<100). S se afieze a n-a pereche de numere gemene. O pereche de numere naturale (a,b), a<b se numete pereche de numere gemene dac a i b sunt prime i |a-b|=2. Perechile sunt ordonate dup primul numr din pereche. Se va folosi: - o funcie recursiv pentru a verifica dac un numr este prim; - o funcie recursiv pentru gsirea celei de-a n-a perece de numere gemene. Ex: pentru n=2 se va afisa 5 7
198
Anexe Laboratorul 7
Lucrare practic 8.1 ( n laboratorulul de informatic) 1. Soluie: int cifra_1(int x) { int num=0; while (x) { num+=x%2; x/=2;} return num; } int max(int n, int a[ ]) { int i,max=a[1]; for(i=2;i<=n;i++) if( max<a[i]) max=a[i]; return max; } 2. Soluie: int numar_divizori(int x) { int nr=1, i; for(i=2;i<=x/2;i++) if(x%i==0) nr++; if(x>1) nr++; return nr; } 3. Soluie: void ordonare( intp, int u, int v[ ], int t) { int i, aux, sem=1; while(sem) {sem=0; for(i=p;i<u;i++) if(v[i]*t>v[i+1]*t) { aux=v[i]; v[i]=v[i+1]; v[i+1]=aux; sem=1;} } 4. Indicaie: Calculez valoarea sumei primelor k-1 numele cuburi perfecte nenule i o rein n variabila s. Apoi verific dac diferena dintre n i sum este mai mare dect ultimul cub perfect al sumei. n caz afirmativ exist soluie. Lucrare practic 8.2 ( n laboratorulul de informatic) 1. Soluie: #include<iostream.h> void citiremat(int a[10][10], int i, int j, int n, int m) { if(i<n) if(j<m) { cin>>a[i][j]; citiremat(a,i,j+1,n, m);} else citiremat(a,i+1,0,n,m); } void main()
Proiectul pentru nvmntul Rural
199
Anexe Laboratorul 7
{ int a[10][10],n,m; cin>>n>>m; citiremat(a,0,0,n,m);} 2. Soluie: # include<iostream.h> long x[10], z[10]; int i,n; int citire(long x[10]) { int i,d; cin>>d; for(i=1;i<=d;i++) cin>>x[i]; return d; } int pcifre(long a) { if(a<10) return a; else return pcifre(a/10); } long factorial(int n) { if(n==1) return 1;else return n*factorial(n-1); } long suma(long z[10], int n) { if( n==1) return z[1];else return suma(z,n-1)+z[n]; } void main() { n=citire(x); for(i=1;i<=n;i++) z[i]=factorial(pcifre(x[i])); cout<<suma(z,n); } 3. Soluie: #include<iostream.h> #include<math.h> int n; int prim(long a,long i) { if((a==0)||(a==1)) return 0; else if(i<=sqrt(a)) if(a%i==0) return 0; else return prim(a,i+1); else return 1; } int generare(int n, int i) { if(n>0) if(prim(i,2)&&prim(i+2,2)) generare(n1,i+1); else generare (n,i+1); else{ cout<<i-1<< <<i+1; return 0;} } void main() {cin>>n; generare(n,3); }
200
Bibliografie
BIBLIOGRAFIE
1. Dorin Stoilescu, Manual de C/C++, Editura Radial, Galati, 1998. 2. Florin. Munteanu, Traian C. Ionescu, Daniela Saru, Gheorghe Musca, Sergiu Mihai Dascalu, Programarea calculatoarelor - manual pentru liceele de informatic, Editura Didactic i Pedagogic, Bucureti, 1995. 3. Valeriu Iorga si colectiv, Programare in C/C++. Culegere de probleme, Editura Niculescu, Bucureti, 2003. 4. Programe de specialitate elaborate de ctre Ministerul Educaiei i Cercetrii pentru nvmntul preuniversitar 5. Herbert Schildt, C manual complet, Editura Teora, 2000 6. http://www. cs.umd.edu/users/cml/style/ - ghid privind stilul de programare in limbajele C si C++. 7. http://www.programmingtutorials.com tutoriale de programare pentru C, C++ precum si pentru alte limbaje. 8. http://www.snippets.org exemple de programe scrise in limbajul C. 9. Cerchez, Emanuela, Informatic. Culegere de probleme pentru liceu, Editura Polirom, Iai, 2002. 10. Cerchez, Emanuela, erban, Marinel, Programarea n limbajul C-C++ pentru liceu, , Editura Polirom, Iai, 2005 11. Cormen, Thomas, Introduction in Algorithms, The Massachussets Institute of Technology, 1990.
201