You are on page 1of 53
146 Buzele programarii calcutatoarelor Open Exempl sir de sce co citie carac mem: fost d Observatie: la citirea cu specificatorul de format +2, sirul introdus se incheie prin tastele sau spariw (chiar daca se precizeaz’ Iungimea campului. cemple: Daca de ta tastaturd se introduce sirul Limbaje evaluate, atunci cele dows variabile vor confine: s valoares ..Limbaje” si s2 valoarea .evoluate’ ammato Introducénd de le tastaturd sirul de la exemplul 1. cele doua variabile vor confine CRLF sJ valoarea ..Li", deoarece se citesc maxim dova caractere si s2 valoarea .mbaje deoarece cdmpul se termina la intalnirea caracterului spatiu Se observa ca se pot preciza lungimile cdmpurilor externe din care se citese datele prin insasi sintaxa functiilor. Folosind valoarea returnata de funetie se pot face validiri asupra citirii corecte a datelor. 8.3. Funcfii de intrare/iesire fara format Limbajul C are functii de intrare/iesire dedicate lucrului cu siruri de caractere, definite in biblioteca sidio.h. Acestea sunt gets si puts. @ Functia gets se apeleazi astfel: gets (nasiv_de unde masiv_de_caractere este adresa unde se va depune sirul de caracter citit (numele vectorului de caractere). gramari caleulatoarelor Qperaratii de intrareAesire 7 tastfel s. sirul introdus se precizeaz& lungimea unei cele dows variabile 48 variabile vor confine: si s2 valoarea .mbaje lor externe din care se valoarea retumaté de or, rmat ¢ lucrului cu siruri de ets gi puts, vune sirul de caractere Functia gets este folosita pentru introducerea de la tastatura a unui sir de caractere. Spre deosebire de citirea cu scanf (cu descriptorul %s), sirul citit poate conjine si spayii, deoarece girul extern se termina la intalnirea caracterului CR/LF sau CTRL/Z (terminator de fisier). Valoarea cititd se memoreazi in masivul masiv_de_caractere $i se returneazi adresa unde fost depus acest sir (adresa primita ca parametru). Daca se introduce CRLF memorie, la caracterul ‘\0"), Daca se introduce numai CTRUZ nu se citeste nici un sir si se retumeazi zero (pointer neinitializat). Caracterul CR/LF nu se pastreaza in sirul citit, fiind inlocuit eu 0’ fard a se introduce alte caractere se considera siral vid (in adresa sirului se va g unctia puts se apeleaza astfel pu unde sir este o expresie de tip pointer spre caracter. Funcjia puts este folosita pentru afisarea unui sir de caractere pe ccran, retumand codul ASCII al ultimului caracter afigat in caz de succes. sau —1 in caz de eroare. Dupa afisarea ultimului caracter. cursorul trece la inceputul randului urmator. Caracterul NULL (0°) nu este afigat, find intocuit eu seeventa CRILF. Funetia afisea caracterele pana a, incepaind de la adresa primita ca parametru. toate la Intdlnirea caracterului NULL (10°). Daca la adresa primiti ca parametru nu se af li un sit terminat cu caracterul NULL rezultatele sunt imprevizibile. Exemple: + Functiile getch si gerche Ambele functii sunt destinate citirii unui caracter de la tastatura si sunt definite in biblioteca standard conio.h. Ele nu au parametri. si in returneazi codul ASCII al caracterului citit. Deosebirea dintre ele cons faptul cA citirea cu getch se realizeaza firs ecou pe ecran (caracterul corespunzator tastei apisate nu este afigat pe ecran), La apelul functiei getche, pe ecran apare caracterul corespunziitor tastei apasate. 148 Bazele programariicalculatoarelor ii centrale, cele in cazul apisirii unei teste corespunzitoare tast doua funciii returneaza codul ASCII asociat caracterelor direct afigabile. In cazul apasarii unei taste functionale sau a combinatiilor cu tasta CTRL, care relurneaZi o secventa de doua caractere ASCII, functiile trebuie apelate de doua ori: prima data se returneazi codul null, iar a doua oar’ se returneazi ; codul ASCII al tastei apasate. La apisarea tastei Ener se returneaz’ valoarea 13 Exemplu: mul urmator afigeaza codurile tastelor apasate, pand cand se apasé tasta Rezultatul apasarii sirului de t speas este urmatorul (pe fiecare rind a fost afigaid seeventa codurilor corespunzatoare combinatiei de taste) + Funegia purch Funetia putch este defi ca parametru 0 valoare intre biblioteca standard covio.h. Functia are erului ASCII nita si are ca efect afigarea cars corespunzator grafice excepti care va care pn care va valori i centrale in inter afigeazz aritmeti tipului interna prevede simplu: Exempl * pe © pe in virgul virgula fi © pe bina in = punctul parte din n virgul + per binara in 1001111 separa oc este 1100 egate de un rind ramarii calculatoarelor Qperarafi de intrurefeyire 149 aturii centrale, cele Daca parametrul are valori in intervalul 031. se vor afiga caractere direct afigabile. in grafice nestandard, corespunzatoare caracterelor ASCII de control (cu zu tasta CTRL, care exceptia caracterclor nul si bell, pentru care nu se afiseaza nimic, backspace 2 trebuie apelate de care va produce revenirea cu 0 pozitie inapoi pe randul curent, LF (cod 10) a oar se returneazit care produce trecerea pe randul urmator in aceeasi coloana si CR (cod 13) ter se returneazi care va produce revenirea la inceputul randului curent), Dac& parametrul are valori in intervalul 27 se vor afiga caracterele corespunzatoare tastaturii centrale (caractere direct afigabile/ imprimabile). Daca parametrul are valori céind se apasé tasta in intervalul 128+: vor af a caracterele grafice standard. Daca parametrul are valoare in afara domeniului 0255, atunci se alige la fixa caracterul corespunzator interpretarii ca valoare in v ve (conform 1 cel mai pujin semnificativ, deoarece in reprezentarea aritmetica a primului octet din reprezentarea valorii resp. tipului ci) — octet interna ordinea octetilor este inversars. Se poate face caleulul pentru a prevedea ce taracter va fi afisat. Pentru valori peste 255. calculul este simplu: daca v este valoarea primitd, se afigeaz caracterul cu codul v%256. Exemple: Sis 2 * pentru valoarea 2561 se va afiga caracterul cu codul ! (2561%256=1)}: ° dow * pentru valoarea ~45 se afigeaza caracterul cu codul 211 (reprezentarea binard 14 secventa codurilor in virgula fix algebric’ a lui —45 este 11010011. pe un octet: interpretarea in virgula fixa aritmetica este 211} © pentru, valoarea 1234 binara in vi caracterul cu codul 46 (reprezentarea 18 fixa algebrica a lui -1234 este 11111011, 00101110. pe doi octeti — punetul a fost pus din motive de lizibilitate. pentru a separa octetii ~ el nu face parte din reprezentare: octetul cel n in virguta fixa arftmetica este 46). tiv este 00101110: interpretarea © pentru valoarea 54321 se afigeaz caracterul cu codul 207 (reprezentare binard in virgul8fixd algebricd a lui $4321 este JHITN11,11111111,00101011 11001111, pe patru octeti ~ punctele au fost puse din motive de lizbilitae, pentru a separa octe{ii ~ ele nu fac parte din reprezentare: octetul cel mai nesemnificativ este 110011115 interpretarea in virgula fixa aritmetie’ este 207). + programul urmétor afigeazd caracterele ASCII (sau corespondentele lor fice, pentru caracterele de control si neimprimabile) si coducile lor. Din motive d conio.h. Functia are fe de agezarea rezultatului in pagina, s-au afigat cite 8 perechi cod/caracter pe ‘a caracterului ASCII cee 150 Bazele program calculatoarelor Operarasii void main() si {unsigned cher ci «= pe rind: int 3: avem 0 elrscrt) for ($0; 16327444) caracter {for (}=075<8:3+ = si trece print(” 83d" caracter poten (7845 “ peinte(*"\n")7) * sevens getch()7} (CR, co si15) Rezutiatele executiei programului sunt: 4 ° 20 20 34 46% se 68 7 7 @ 90 20 op ise 1 ca si fun: 16 > s - 3G ? as 1 a + 4 tastatura x0 ) j ay afigabile 4a 0 d 4 face dir 56 8 9 : < 2 se 6b aw c 6 D tampon 2 Bt K 76 L tampon so P elo s ut caracten Ga it 4. Ce 3 returnea 96 Ta © 100 £ ¢ 30a h 105 i e108 3 non ino lui getel uz p 113 q s ne = ie v us w ious | x i y (124 126 ~ 127 0 ve ¢ a a as2 8 13a 8 ¢ | 136 ¢ e138 x 190 4 A x A EOF, di 1a 8 = 16 R76 UB 6 © 180 8 8 1 y Q is¢ 0 155 ¢ 156 £ e158 & 5 a 4 162 6 163 G 164 A 165 N 165 * 167 ° reprezin 2 169 e170 4 17% 172 W173 | « » returnes ae 3 177 § we M179 | 150 4 181 4 ez 4 x res y 185 4 186 J 187 g 188 4 1e9 4 190 J ‘ too Liss 4 isa 7 195 $ 196 — 197 $+ 198 f 199 Exemp! 200 &§ 201 202 4 203 205 = 206 $ 207 + 208 4 209 210 y 211 tas p ae ¢ 215 F zis $ 27 J 218 5 = 222 J 222 f 223 224 a 225 8 226 T 227 E229 ¢ 230 p 231 x 232 @ 233 © 234 2 3 236 = 237 9 238 © 239 A 240 = 241 + 242 2 243 < 24a [ 205 | 246 + 247 = 248° 249 251 VY 252 * 253 # 254 m 255 Program afigabile amitri catcutatoarelor i i i i Operarati de intrarchesire ist Se observa: ~ pe randul al doilea al rezultatului deplasarea cu o pozifie inapoi (practic pe ecran avem o deplasare aparenta de 2 pozitii: una prin revenire si una prin neafigarea caracterului curent) prin afigarea caracterului backspace (cod 8); si trecerea pe randul urmator, ffiri a schimba coloana curenté ta afigarea caracterului line feed (LF, cod 10); ~ revenirea la inceputul réndului curent la afigarea caracterului carriage return (CR, cod 13) si afigarea acolo a cel si 15). te caractere din randul curent (codurile 14 % Macro-urile getchar si putchar Cele dot in biblioteca stdio.h si se apeleazi ca si flnctiile getch si purch. Diferenta const in modul de execui}e. Magroul gerchar permite citirea cu ecou pe ecran a caracterelor de la tastaturd. Se pot citi numai caractere asociate codurilor ASCII direct afigabile, nu si caracterele corespunzatoare tastelor speciale. Citirea nu se face direct de la tastatur’. Toate caracterele tastate se introduc intr-o zona tampon pana la apasarea tastei Enter. in acest moment se introduce in zona tampon caracterul newline *\n" si macro-ul returneaza codul ASCII al caracterului curent din zona tampon. La urmatorul apel al ui gefchar se returneaz codul urmatorului caracter din zona tampon. Dacd la un apel al lui getchar nu mai sunt caraetere disponibile in zona tampon se introduc din nou de la tastaturd caractere pana la aplisarea tastei Enter. La intdlnirea caracterului CTRL-Z, macro-ul returneazi valoarea EOF, definitt in stdio.h, Macroul putchar are ca parametru o expresie al cirei rezultat Teprezinta codul ASCII al caracterului care se doreste s& fie afigat. Se returneaza codul ASCII al caracterului afisat sau -1 in caz de croare. macro-uri sunt defi Exemple: #inctudecstaio.h> #include void main() { putchar (getenar()); putchar('\a" 2) Programul asteapta introducerea de la tastaturd a unui sir de caractere ASCII direct afigabile (orice altceva este ignorat) terminat cu Ener. Primul caracter din giral 152 ramariicalculatoarelor introdus va fi preluat de macroul getchar care retumeaz4 codul ASCII al caracterului respectiv. Macroul puichar primeste ca parametru codul ASCII returnat de geichar si afiyeaza caracterul corespunzator. Ca urmare, pe ecran se va primul caracter introdus de Ia tastaturd, La primul a tastaturd a unui sir de caractere ASCII direct afisabile (orice altceva este ignorat) al lui getchar, programul asteapté introducerea de ta terminat cu Enter. La fel ca inainte. primul caracter va fi afiset. La urmatoarele un caracter din cele introduse anterior si se afigeaza. Daca in butler nu mai sunt caractere, se asteapta din nou introducerea unui sir terminat eu Emer. apeluri, se preia cat in aplicatiile prac furnizate de la dispozitival standard de intrare — tastatura. Cand numdrul . pentru multi algoritmi, datele de intrare sunt acestor date de intrare nu este cunoscut, programatorul trebuie s& stabileast modalitati de finalizare a procesului de introducere a datelor. Astfel. exist doud forme generale de a incheia procesul de introducere: sfairsit conventional si sfarsit standard, Prin sfargit conventional ingelegem situatia in care programatorul isi stabileste un criteriu (conditie) de incheiere a procesului de introducere a ura cu tipul datelor de intrare. De exemplu, dacd datele de intrare sunt de tip numeric se poate stabili 0 valoate a datelor care in mod normal este imposibila” (zero. negativ, mult prea mare, mult prea mica ete Prin sfargit standard ingelegem bl dispozitiv standard de intrare, Tastatura are asociaté o component logic’. care in limbajul C este figierul ASCII sidin, ..Blocares logica” a tastaturii coincide cu operajia de inchidere a fisierului stdin. Acest lucru se realizeaza prin combinatia de taste CTRL-Z. datelor. Conventia astfel stabilita este in stransa leg ea logica” a tastaturii ca Qperaras i realizea: are urmi F care este fost cu s citit sry valoarea Exemple 1. Citirea pana la ap #inctude: void mai wnie(s xtl scant ' printt( for (in print geteht) 2. Citirea ¢ acestora, px realizeaz’ a ncludecs udece oid main( eet ii caleulatoarelor odul ASCII al 1 codul ASCH roducerea de la a este ignorat) La urmitoarele afigeazii, Daca in i sir terminat cu de intrare sunt Cand numarul € sd stabileas r. Astfel, exist ducere: rit ogramatorul igi introducere a tipul datelor de meric se poate (zero, posibila 2 tastaturii ca ponent Logica, ica” @ tastaturii su se realizeazi Qperaratii de intrarehesire 153 in limbajul C, detectarea sfarsitului standard de prelucrare se realizeazA prin apelarea functiei feof, predefinita in biblioteca stdio.h si care are urmiitoarea sintaxa: [Kernighan et al., 1988] int feof (FILS *numefisier) /* peni u tastatura, efisier va fi stdin*/ Functia feof furnizeaza valoarea indicatorului de sfarsit de fisier, care este setat de ultima operatie de citire. Astfel, daca operatia de citire a fost cu succes (fra eroare), feof va returna o valoare nenuli, iar dacd s-a citit sfarsit de fisier (CTRL-Z, in cazul sfargitului standard), feof va returna valoarea zero, Exemple: 1. Citirea caracter cu caracter a elementelor unui sir de maxim 100 de caractere pénd la apaisarea combinatiei CTRL-Z (sfargit standard). #incledecstdio.n> #incledecconie. void main() (char text{100], © no; while(! feo (stain) ) { text in} = ¢! scent (mse, geten(); 2. Citirea elementelor unui vector de maxim 200 de valori reale si contorizarea acestora, pnd la apasarea combinajiei CTRL-Z (sfsit standard). La final se realizeaza afisarea elementelor. #includecstdio.n> Hineludecconio.h> { Eloat x[200}, neoz Print? ("Introduce i elementele vectorului:\n"); Bazele programiirii calculatoarelor Realizarea st 154 —_ scanf("£", 6xIn]17 white 1fe0¢ (otha) epee ‘ Fan at”, cx[n]); /* echivalente cu scanf("8i", ax{+4nl) 7*/ , printé ("Vectorul picnritt) 43.26 "xLL1e Une 7A nativ co Altele (incl Instructiuni rezultatelor tat este:\n")s getch i) instructiunil teoria progr: Instr vederea obt rezultat dup instructiuni configuratii Instrucjiunite de acolade care este te sfargitul fieci Un pi limita, aceast unei funcfii r Dupa actiuni descri fi create bloct eo structurate s implementeaz ‘graméritcalculatoarelor Realizarea structurilor fundamentale de control 158 amit colentosoarelor, ee cS 9. REALIZAREA STRUCTURILOR FUNDAMENTALE Be", ex[ten}) 9*/ DE CONTROL Unele limbaje de programare cuprind instrucjiuni care implementea- ZA nativ conceptele proiectirii structurate si modularizate a programelor. Altele (inclusiv C) implementeaza parfial sau simuleaza aceste concepte. Instructiunile desemneazi actiuni care se aplica datelor in vederea obtinerii rezultatelor scontate printr-un algoritm, Este recomandat ca studiul instructiunilor s& se faci pornind de la structurile fundamentale definite de teoria programarii structurate. 9.1. Tipurile de instruciuni Instructiunile specifica operajiile (actiunile) care se aplica datelor in vederea objinerii rezultatelor scontate prin algoritm. In programul obiect rezultat dupa compilare, ele se regisesc sub forma unor secvente de apeluti si instrucjiuni cod magin&, Aceiasi instructiune sursi poate avea diverse configuratii cod masina, depinzand de tipul operan: Instructiunile unui program C se grupeaza intr-un bloc delimitat de o pereche de acolade (}. Instructiunile se incheie cu caracterul ; (punct si virgula), care este terminator de instructiune si este obligatoriu pentru a marca sfarsitul fiecdreia. Un program trebuie si execute cel putin o instructiune, chiar dact, la limita, aceasta este vida. in limbajul C, un program se regiseste sub forma unei functii rédacind, care, la limi, poate avea un corp vid: void maint) { Dupa modul de realizare a constructiilor sintactice si al numarului de acfiuni descrise, se disting instructiuni simple si structurate, De asemenea, pot fi create blocuri de instrucyiuni executabile, denumite instructiuni compuse. © 0 instructiune compusa este o secvenfa de instruciuni (simple, structurate sau compuse) delimitatt de perechea de acolade {). Ea implementeaz& natural structura secventiali din programarea structuratd, F pe care Ti referd 156 Bazele programiri calculatoarelor a Muljimea instructiunilor executabile ale unui program este, la limit, 0 instrucfiune compus’. Orice instructiune (simpli sau structuratf) poate fi transformatd in instructiune compusd © 0 instructiune este simpli daci descrie o singura acjiune, unic determinata si care nu provoac’ conditionari. Din categoria instructiunilor simple fac parte, de exemplu: instructiunea vida, instrueyiunea de evaluare a unei expresii, goto, break, continue, return. @ Instructiunile structurate sunt constructii care contin alte instructiuni (simple, compuse sau structurate) care vor fi executate altemativ sau repetitiv. Corespunzator, prin instructiunile structurate se codific& structurile fundamentale alternative sau repetitive din algoritm. Pe Kanga instrucfiunile care implementeaz’ conceptele programatii structurate, C confine si instructiuni care contravin acestora, datoriti orientarii timbajului spre compactarea textului surst si spre neconformism in stilul de programare impus de autor 9.2. Instructiunile simple @ Instructiunea vida descrie actiunea vida. In C nu are o mnemonica explicité, fiind dedusd din contextul unor constructii sintactice. Ea se foloseste acolo unde trebuie si apard o instructiune, dar care nu trebuie si execute nimic. Situagia este intélnitd de ol structurate ei in cazul instructiunilor Exempl instruciune vida T instruciuni vide 7 a instructiune vida 7 ®@ Instructiunea de tip expresie evalueazi o expresie care, in cele mai dese cazuri, este de atribuire sau de apel al unei functii (vezi si capitolul Operatori si expresii). Instructiunea de tip expresie se obfine seriind termine © instru Exemp dectarat fie plase Exempl Variabila afara ei 1 execute instruct instructit while, de 4riicatentatoarelor te, la limita, 0 ‘turaté) poate 14 acfiune, unic a instructiunilor ea de evaluare a re contin alte ccutate altemativ vate se codifica tele programarii cestora, datorita ce neconformism are 0 mnemonica simactice. Ea se are nu trebuie sa ul_instrucfiunilor 2 care, in cele mai (vezi si capitolul se obfine seriind Realizarea structuritor fundamentale de control tem torul de instructiune dupa o expresie (acolo unde este legal si apart © instructiune in program). Forma generala este: Exemple: 9.3. Instruefiunea compusi Instructiunea compusa este o succesiunea de insiruejiuni si declaratii, cuprinse intre © pereche de acolade. Se prefera ca declaratiile si fie plasate inaintea instruc{iunilor. Forma generali este: Declarafiile sunt valabile in interiorul instructiunii compuse. Exemplu: Variabila # este definita in cadrul instruc afara luni compuse si nu mai este definivs in Instructiunea compusi se utilizeazi acolo unde este nevoie si se execute mai multe aciuni, dar sintaxa impune prezenja unei singure instrucjiuni: mai multe instructiuni sunt .transformate” intr-o singuré instructiune (compusd). Situatia este intdlnit& in cadrul instructiunilor if while, do, for, care precizeazi, in sintaxa lor o singurd instructiune. Bi le prograntirit calculatvarelor 9.4, Instructiunile structurate in continuare, prin instructiune se injelege o instrucyiune simpla, ‘compusi sau structuratd, 9.4.1. Realizarea structurilor alternative ura 9.1) permite realizarea unei a) Structura alternativa simpla ramifieari logice binare, in funetie de valoarea nei conditii (expresie cu rezultat logic). Instrucjiunea care realizeaza aceasta structurd este if ond > — [structione 2 “y" Fig. 9.1. Structura alternativa simpla Expresia poate fide orice tip. Daca valoarea expresiei este diferita de zero (valoare asociaté din punct de vedere logic cu adevdirat) se executi instrucfiune_]; in caz. contrat se exeeuta insiructiune_2 sau se iese din structuré (cand construofia else lipseste. caz in care instructiunea if realizeazi structura pseudoalternativa) Exemple: 1) SE te>b) arc) else arbi 2 iftane3) LElbe=4) om Rolul | (ali acest It condigi expres Exemy 1. Dete 2. Reze un gra limbaj este: unde: de tip insirw compt este nc cauta i amdrié caleutatoaretor trucyiune simp! ite realizarea unei aditii (expresie cu ri este if lei este diferita de devdiral) se executi 2 sau se iese din re instrucjiunea if Realizarea structurilor fundamentale de control 159 Observatii © Terminatorul de instrucyiuni ; se serie obligatoriu inainte de else. Rolul lui este de a termina instructiunes de pe ramura direct a instructiunii if (la limita aceasta poate fi instructiunea vida); © Expresia instr cliunii if este intotdeauna inclusd intre paranteze. acest lucru flind valabil pentru toate instrucjiunile conditionale din C. In locul unei structuri if-then-else poate utiliza operatorul conditional expresie. + atunci cand instructiune_1 si insiructiume_2 sunt de tip Exemple: 1, Determinarea maximului dintre 2, Rezolvarea ecuatiei de gradul I, ax+b=0: 1 numere: b) Structura alternative multipla permite alegerca unei actiuni dintr- un grup, in functie de valorile pe care le poate lua un selector (figura 9.2). In limbajul C structura se simuleazd cu instructiunea switch. a cirei sintaxé este: [defavit: instruc: unde: expresie este de tip intreg; c 1, ¢ 2, .... em sunt expresii constante, de tip int, unice (o valoare nu poate s& apari de dowd sau mai multe ori) instructiuni_I, instruefiuni_2, .... instructiuni_n, instructiuni sunt simple, compuse sau structurate. Daca pe o ramurd sunt mai multe instructiuni. nu este nevoie si fie incluse intre acolade (si fie instructiune compu: Instructiunea sivitch evalueaz expresia dintre paranteze, dupa care cauti in lista de expresii constanta cu valoarea obtinuta. Daca este gis 160 programiril catculatoarelor executi instruc{iunile asociate valorii respective si, seevential, toate instrucfiunile care urmeazé, pan& la terminarea structurii de selectie Daca valoarea cfutata nu este gAsitd in list si ramura default este prezenti, se executl instrucfiumile asociate acesteia. Daci ramura default lipseste nu se executi nimic. Pentru a limita acjiunea strict Ia executia instructiunilor asociate unei valori, trebuie inclus’ instructiunea break, care determina iesirea din struetura switeh Pentru a simula structura din figura 9, Fminuejanen | { Tastractione Fig. 9.2. Structura alternativa multipla Exemplu: + Dac’ intr-un program C este prezentd o instructiune switch de forma suiteh lexpresie) ci: dnstrveriuns tune} ca se exceuti astfel = ach valoarea expresiei este ¢ J. se executll insiructiuni_1 si apol instructitni_2, dacd instructiuni_I nu defineste ea insisi o alté seeventi de continuare; - daci valoarea expresiei este c_2, se executd instructint = dacd valoarea expresiei diferd de c_1 si c_2, nu se executd nimic. # Selecjie in functie de tasta apisata instr. este « sau s ‘objin while valoa sgraméri cateulaoureior seovenfial, toate xii de selectie, Daca mult este prezentd, se default lipseste nu se ccutia instructiunilor eak, care determina 2 switch de forma: instructiuni_l si apoi rsisi 0 alts seevenys de Realizarea structurilor fundamentate de control 161 char litera printf("\ntastati o Litera intre @ si eM): scanf "8c", elitera); switch (Litera) case 'A': printf ("litera a sau case "8": printf ("litera b sau 8") ;break: case 'C': printe(*iitera default: printf ("alta litera"):) ay C*} rbreak; Se observa cA instructiunea switch nu realizeazi natural structura CASE-OF (iesirea unica trebuie si fie asigurata prin instructiunea break) Pentru a executa aceeasi instructiune pentru mai multe valori se procedeazé ca in exemplul de mai sus: valorile respective se inscriu pe ramuri succesive, asociind instructiunea doritd ultimei ramuri; restul ramurilor nu vor avea instructiuni asociate. Pentru a simula in C structura fundamental. CASE-OF, fiecare ramura trebuie sd se incheie cu break. 9.4.2, Realizarea structurilor repetitive a) Structura repetitive conditionata amerior este implementata prin instructiunea while cu forma generala: while (expresie) instructiune; Instructiunea while se executi astfel: se evalueazi expresia si daca este diferita de zero (adevaratt) se execut instructiunea (simpli, compusd sau structurata), apoi se reia procesul pana cénd la evaluarea expresiei se ‘obtine valoarea zero. in acest moment se incheie execufia instructiunii while. Pentru a asigura iesirea din ciclu, instructiunea trebuie s& modifice valoarea expresiei Daci la prima evaluare a expresiei se obfine valoarea zero, atunci nu se executd nimic. Instructiunea while implementeazi natural structura corespunzétoare din teoria programarii structurate. Mecanismul de executie este redat in figura 9.3, 162 Bazele programiiri calculatoarelor #0 (adevarat) instructiune Fig. 9.3. Mecanismul de executie a instructiunii while Exemple: Lwnite (a>) Li float x,v{20)7 unsigned a peint# "Valo: for (i=0;icn, Af (i>en) printe (Ne ext oarea 14.26", ); else printf ("Valoares 84.2F spare prima data pe a ura pozitie’, xiths] b) Structura repetitive conditionata posterior este implementata (cu uncle deosebiri fati de teoria programarii structurate), prin intermediul instructiunii do-while. Forma generala este: do instru se pr fig prc str Inst poate pe ce partic aprop formz ramiriicaleulatoarelor inii while ze implementata (cu 2), prin intermediul Realizarea structurilor fundamentale de control 1683 Instructiunea do-while se executd astfel: se executd instrucfiune apoi se evalueazi expresia; dact expresia este nenuli (adevarata), se repetii procesul, altfel se incheie executia. Mecanismul de executie este redat in figura 9.4. Se observa c& instructiunea do-while se abate de la teoria programiii structurate, realiznd repetitia pe conditia adevdrar, in timp ce structura fundamental’ o realizeaza pe conditia fal jt instructiune #0 (adevarat) expresio > = 0(fals) Fig. 9.4. Mecanismul de executie a instructiunii do-while Instrucjiunea do-while este echivalent instructiune; cu seeventa: while(expresie) instructiunes while (ac=100) 7 clude expresie_I va fi expresia de initi + expresie_2 controleaza terminatea ciclului: contor voia main() (Se0;4c10; print#("\n mezge") jn urma executiei programului, cuvantul merge se va afiga de sapte ori ([(10- Oy. s}+1=64 5) Re ol for cel _programiril cateutatoarelor instruct iune; alueazA expresie_I; se acheie executia lui for, xpresie_3. Se revine la or realizeazi structura ata: ructiunii for itor (do-for) se folosese ntor=valoare initial; contor —_legitura dintre pointeri si masivele de date. in limbajul C %* — alocarea dinamicd a datelor: > tratarea parametrilor primiti in Tinia de comand, 10.1. Tipuri de date dinamice Pointerul este un tip de data predefinit, care are ca valoare adresa unei zone de memorie (figura 10.1) Memorie intern Hee power Zona de memorieindieta de palmer ig. 10.1. Un pointer este adresa unei alte zone de memorie Folosirea pointerilor prezinté urmatoarele avantaje: plocuirea expresiilor cu indici ~ inmuljirile din formula de calcul al rangului se transforma in adunari si deplasiris * posibilitatea alocérii dinamice a memoriei;, © folosirea tipurilor procedurale de date; © calculul adreselor. 168 Bazele programirii cateutatoarelor Fipuri dina folosese {in operafiile cu pointe urmatorii operatori specifici: Pe [____ Operatori Simbol | ___ Utilizare | principal |\—ooemordergéreniere adress Operator de refereniere Up adres. Op re Cin ‘Operator de referenjiere Operator de dereferentiere | implicit v variabile 1 * => defineste un nou tip de data (pointer la tip): & — >extrage adresa unei variabile (creeaz o referinya): adresa oric * = acceseuzii confinutul zonei de memorie indicate de pointer. Exemple Cei doi operatori au efect invers: +érame @ sane 5. int variabilei a Exemplu 1. rsmune reprezinta valoarea de la adresa variabilei_nume (valoare: in variabilei mune). valoare doz 10.2, Declararea si initializarea pointerilor Fie sre un tip de dati oarecare in limbajul C (inclusiv void). Declarareatie+ nume; este o declaratie de pointer data denumit pointer spre +1, iar nume este o variabila de tipul pointer spre valoare adr p+ este un nou tip de falcane, adh a Initi. sau, ca si pe Exemple 2. int* nz =p meste o variabild de tip pointer spre intreg: em 3. seever coupion la,berealy!* x; =x este 0 variebila de tip pointer spre Sad 6 structuré de tipul complex: referinta cat 4. void® ps => peste 0 variabilii de sip pointer spre void: p poate primi ca alti metoda valoare adresa unei zone de memorie de orice tip. utilizeazs at de la adresa Daca rip este un tip oarecare (mai putin void) atunci tipul 7 adresa unei zone de memorie de un tip cunoscut. Operatille care se pot Exempla efectua asupra zonei respective de memorie sunt definite de tipul acesteia. ine Dacd vrv este void, atunci 11e+ este adresa unei zone de memorie de tip void necunoscut. Deoarece nu se cunoaste tipul zonei de memorie, nu sunt definite operatiile care se pot efectua asupra ei amit calcularoaretor ratori specific ‘ilizare 18): te de pointer. ilei_ mune (valoarea rilor 1 C (inclusiv void). + este un now tip de de tipul poimer spre ntreg: de tip pointer spre i p poate primi ca atunci tipul sre este Yperatiile care se pot aite de tipul acesteia. © de memorie de tip © memorie, mu sunt Tipuri dinamice de date 169 Pentru pointerii din exemplele anterioare se rezerv in memoria principala (in segmentul de date) cite © zon& de 4B in care se va memora 0 adres Cind variabila sume nu este inijializata prin declarare, ea primeste implicit valoarea wu. La executie. poate primi ca valoare adresa unei Variabile numai de tipul 222, Dac& z2r este atunei nume poate primi adresa oricirei variabile, de orice tip, Exemple 5. int? numer une = G2; => este o atribuire corectd; mime are variabilei a. valoare adresa pune = éb; => este o atribuire incorecté; mune poate primi ca valoare doar adresa unei variabile intregi. 6 void numer => pointer fara tip test = variabile de tip intreg, respectiv real tay = atribuire corecta oo: = alribuire corect’s mume poate primi ca valoare adresa oricarei variabile, de orice tip. Initializarea pointerilor se poate realiza ca in exemplul precedent sau, ca si pentru celelalte variabile, la declarare, astfel Se observa folosirea operatorului de referengicre & pentru a crea 0 referina cdtre variabila a. La alocarea dinamica a memoriei se foloseste 0 alt metoda pentru initializarea unui pointer. Operatorul de dereferengiere se utilizeaza atit pentru definirea tipului pointer, cit si pentru referirea datelor de la adresa indicat de pointer Exemplu 7. int a,b,c; int* nume; 170 _ Bazete programéit caleulatoarelor Tipu Se observii folosirea conversiei de tip (¢ypecasting). atunci cind se lucreazi cu pointeri spre tipul void (fra tip). Chiar daci un pointer spre tipul voia poate primi ca valoare adresa unei variabile de orice tip. pentru a Exen putea lucra cu ea este necesata gestionarea corecté a tipului operanzilor, 8. ‘ea pointerilor in urn octeti 10.3.1. Operasii cu pointeri Adune Asupra pointerilor se pot efectua operatii aritmetice, Fie seeventa: int ‘nune, *nune2, mena: aduna Incrementare/decrementare a 5 e ca Daca nume este pointer spre un tip v1», prin incrementare! ‘a octeti decrementare, valoarea lui mume se inerementeazil decrementeazi cu ia em numirul de octefi necesari pentru a memora o data de tip 71P, adied cu sizeof (TIP) rono++ mume are ca valoare o adresd care este incrementata gi primeste valoatea auines ty (care este adresa lui b); nume are ca valoare 0 adresa care este decrementat& $i primeste valoarea nune-sizeos (int) (care este adresa lui o: Situayia inigialé este urmétoarea: [oy Je |e nume ~Trumea 4B 4B 2B 2B 2B Exemy % inigialis valoare primest Operati Compa folosin: ramirit caleulatouretor Tipuri dinamice de date m1 ). atunci cind se un pointer spre c orice tip. pentru a lui operanzilor ice. Fie seeventa: prin inerementare/ decrementeazi. cu tip s1e, adic cu este incrementati gi (care este adresa lui este decrementata si (care este adresa lui Dupa cele dowd operayit | yoo fume! Joke? — [ea 3B 48 2B 2B 2B Analog se executd operatiile -=nure gi --un Exemplu 8. float v{20}: lost* svlil: unde / poate avea valori intre 0 si 19 in uma atribui ica adresa lui vfit] +P va avea ca valoare adresa lui v{i) plus 4 octepi, Adunarea/sciiderea unui intreg in general, dac& p este un pointer spre un tip vre, atunci cind se aduna un intreg 1 la pointerul p, rezultatul va fi tot un pointer spre 7:2, care are ca valoare adresa memorati in p, la care se adund de 1 ori numirul de octeti necesari pentru a memora o dati de tip rie, adied o*siseos (122 Asemanator se executi scdderea unui intreg dintr-un pointer. mune > mume primeste valoarea sunesn-sizeo! jin ne © mume primeste valoarea nune-*sizeof (én Exemplu 9. Fie p sig pointer spre tipul float (si0s:* p, a). Presupunind e& p a fost inigializat cu valoarea OxOfff'0x3450, in urma operatici g-p+3, ¢ primeste valoarea Oxfff:0x345e (se adun& 3*4 octeti). In urma operatiei g-p-2, g primeste valoarea Oxfff:0x3-14a (se scad 2°4 octeji). Operatiile descrise anterior se folosese freevent in lucrul cu masive Compararea a doi pointeri Limbajul C permite compararea a doi pointeri intr-o expresie folosind oricare din operatorii relationali (==, | Rezultatul expresiei rune op <>, <=, 35). (unde op este unul din operatorii Bazete programetitcaleulatoarelor Tp precizati anterior) este adevarat (nenul) sau fals (zero) dupa eum mume este Diy J, mei mate sau mai mic decit mume2, Doi pointeri sunt egali daca adresele care constituie valorile lor sunt egale, Privind memoria intern’ liniar, incepind de la adresa 0 (zero), un pointer p este mai mare decit altul g. daca adresa pe care o contine p este mai indepartataé de inceputul une, memoriei decit adresa continutd de g ints Este permisd si compararea unui pointer cu o valoare constanta del Uzual se foloseste comparatia cu valoarea NULL pentru a verifiea dat pointerul a fost inijializat (un pointer neinifializat are valoarea NULL), dik folosind unul din operatorii == sau /=. Valoarea NULL este detinita in pe stdio.h astfel: Yaetine wee. ¢ “wee De multe ori se prefera comparatia directa cu zero (nume--0 sau wet mme!=0). In loc de nunes=e se poate folosi expresia name. Aceasta se ull interpreteaz astfel: daci mume nu a fost initializat, atunci are valoarea NULL (adic& 0), deci expresia este falsi, In caz contrar valoarea expresiei este nenula, deci adevarata nator se folos Exemplu é 10. float pga float abs if(e) print prints ("Poi Ant iferiri\at) Pe ecran se va afiga: Pointeri egali deoarece fare valoarea NULL, variabilele p si r au ca valoare adresa lui a, iar q contine adresa lui b, care este mai mare decit a lui a (datorit& faptului cia a fost alocat primul). elen Pen me deel Prog adre gramérlicaleulatoarelor dupa cum mume este veri sunt egali dac nd memoria interna mai mare decit altul rlatd de inceputul © valoare constant tru a verifica daca NULL), ULL este definita in re valoarea uw zero (nune-0 sau ja sume, Aceasta se atunci are valoarea ar valoarea expresiei presia tnome aloare adresa lui a, @ datorita faptului Tipuri dinamice de date 173 Diferenta dintre doi pointeri Fie secvenja: int (501, a, + be aeam{i}: b-6m(3) unde i si f sunt intregi in intervalul [0.49]. Expresia a-p are valoarea i-j, interpretata ca distant intre adresele a si 6, exprimat de lungime sizeof (iat). Valoarea unei expresii difereni se calculeazd astfel: se face diferenja intre cele doua adrese (in octeti), apoi se imparte la dimensiunea tipului de data referita de cei doi pointeri (tipul amt in exemplul de mai sus ~ vezi figura 10.2). Cei doi pointeri trebuie si refere acelasi tip de dati, altfel rezultatul nu are semnificatie (trebuie s8 aiba tipuri identice). Operatia este utila in luerul cu masive. in zone de memorie Fig.10.2, Reprezentarea semnificatiei variabilelor din exemplul anterior Atentie: vorbim despre diferenja dintre doi pointeri (injelegind distanta dintre cele dou adrese), nu despre sciderea a doi pointer 10.3.2. Legatura intre pointeri $i masive fn limbajul C numele unui masiv este un pointer citre tipul de data al elementele masivului. Pentru masivele unidimensionale: int (50); mare tipul int* int* ps pare tipul int~ Diferenja consta in faptul c& zona de memorie catre care puncteaz ‘m este rezervata la compilare (ceea ce nu se intimpla in cazul pointerilor declarati ca atare). De aceea m nici nu poate primi valori in timpul executici programului (nu se poate schimba adresa memoraté in m). El memoreaza adresa primului element din masiv. Referirea unui element mfij este 174 Bazele programériicaleulatoarelor ame programntrl caleba ctor echivalent cu + (nti) —continutul de fa adresa m+i. Limbajul C nu face nici un fel de verificari in privinta depasirii limitelor indicilor masivului, de aceea expresiile m(s00) sau m(-7) vor fi considerate corecte de compilator, existind riscul unor erori logice. Este sarcina programatorului s& se asigure A indicii nu vor depasi limitele. Pentru masivele bidimensionale: int {501150}: mare semnificafia urmatoare: mii) i} +c ¢m4i345), reprezinta ,,confinutul de la adresa j plus confinutul de la adresa memorata in m plus 7”. Aceasta poate fi interpretatd astfel: m este un poiitter spre un vector de pointeri, fiecare element al vectorului fiind la rindul lui un pointer spre o linie a matricei (un vector de elemente de tip floct), Figura 10.3. poate fi utilizata pentru a injelege mai bine cum se acceseazii elementele unui masiv bidimensional. Aten{ie: aceas unei matrice statice! Doar pentru matricele alocate dinamic zonele de memorie sunt alocat acest fel, I mi. 01 Tai. [iaaay) [0.0 mf0.49) mf2.0) [ mf2.01 mis.0) Twist | Ta 8 Leni. 13.491] maf) -——+ mls. 0] | mis] [Tm 491) mo CT TT] mala] mnfs9,0}[mfa9.7]].. Tm[49.49] Fig.10.3. Reprezentarea modului de alocare dinamic’ a spatiului necesar pentru memorarea unei matrice 50x50 figura NU reprezinta modul de alocare in memorie Analog pot fi interpretate masivele cu mai multe dimensiuni Exempla 11. Un masiv cu trei dimensiuni float m{10]{10][10} poate fi interpretat ca Un pointer spre un vector de pointeri spre matrice; ‘Un masiy cu dimensiuni este tratat ca un pointer spre un vector de pointeri Tipn cate adre adre pent adre inter Exe! 12: Dup. folos refer decle nece: acest conv: valoa functi zona. pentre ‘gramariicalculatoarelor imbajul C nu face nici adicilor masivului, de corecte de compilator, e torului si se asigure rméatoare: mij {i] © plus contimutul de ta retata astfel: m este un al vectorului fiind la jor de elemente de tip ege mai bine cum se de alocare in memorie locate dinamic zonele EO Ta] 229] a spatiului necesar x50 dimensiuni, soate fi interpretat ca un vector de pointeri Tipuri dinamice de date 175 cdtre masive cu n-/ dimensiuni, Pentru a lucra cu elementele unui masiv static se poate folosi adresarea indexatd (m{i) pentru vectori sau 131131 pentru matrice) sau adresarea elementelor prin pointeri (+ (+i) pentru vectori sau + (+(mei)+)) pentru matrice etc). Mai mult, pentru vectori se poate declara un pointer initializat cu adresa de inceput a masivului, iar elementele masivului s8 fie referite prin intermediul acestui pointer. Exemplu 12, eroae* vii01 at ps Dupi atribuire, pointerul p contine adresa de inceput a masivului si poate fi folosit pentru refer "a elementelor masivului. De exemplu, vis) si (2) referd aceeasi zona de memorie. 10.4. Alocarea dinamic& a memoriei Pentru a memora o data de un anumit tip in heap este necesar s& se declare un pointer cdtre acel tip de data, apoi sA se rezerve memoria necesar’. Pentru a rezerva spatiu in heap se foloseste functia standard: void* malloc (unsigned n)1 Functia rezerva o zon& de n octeti in heap si returneaz’ adresa acesteia. Deoarece funcjia returneazi pointer spre void este neceserd conversia rezultatului spre tipul dorit, astfel: umes (int *} malloc (size0$ valoare de tip intreg. iberarea unei zone de memorie rezervate anter funcfia standard void free (void™ p)s Funejia primeste ca parametru un pointer (indiferent de tip) spre zona de memorie pe care trebuie si 0 elibereze. Limbajul C ofera posibilitatea de a aloca contiguu zone de memorie pentru mai multe date de acelasi tip, prin functia standard void* callociunsigned az elem, snsign 1); <> rezerv in heap spatiu pentru o © se face prin 176 Bazele programiriicalculatoarelor Funofia calloc rezerva o zona contigua de memorie pentru mai multe elemente de acelasi tip, intorcind un pointer spre zona respectiva. Exist& gi o varianta a lui malloc care retumeazi in mod explicit un pointer ,,indepartat” (far): void? farmalloe (unsigned Long 9) Pentru cliberarca unei zone de memorie rezervate prin farmalloc se foloseste funcfia standard: woid* ph; void far! Exemple 13. int* masiv; masiv=(int*calloc(50,sizeof(int)); <=> rezerva spatiu de memorie pentru un vector cu 50 de elemente intregi. 14, Alocarea de spatiu in heap pentru o matrice se face conform figurii 10.3 pentru a putea accesa elementele la fel ca in cazul unei matrice statice, prin dubla indexare. 7* ae alock spate pente ale nat +)mallec ints /*3e alocé spetiu pe cite p elenente*/ ii]= (int im 15. Sa se sctie 0 functie care si citeascd cel mult numere intregi si le piistreze in zona de memorie a cirei adres& de inceput este dat printr-un pointer, Functia returneaz& numarul valorilor sizeof (int): int cit_ne (int n, intt pp (int ar, 4 int? q-penz “Wa adresa unde se // reservata pentze cele 9 (ea Hf cit timp aw sai ( printé("wumarul td= ", i); scant("8d", gnz) !=1) break? JJ in caz de exoare // se termina ciclul return(i); ) Tipuri a preproc initializ acesteis Uurmato; a) permite Fata de care sei b) 1 constant Poate ce unde p memoric pointer: °) © formali, cazul in in argument poate ac: gramitri calculatoaretor Tipurt dinamice de date 177 wie pentru mai multe espectiva. 'n mod explicit un prin farmalloc se rezerva spajiu de conform figurii 10.3, natrice statice, prin atricei, cite p sumere intregi si le este data printr-un 2 scau citit n 10.5. Modificatorul const h preprocesare #define. O alta posibilitate de lucru cu constante este initial acesteia. In acest scop se foloseste modificatorul const, Sunt permise urmatoarele forme de utilizare: limbajul C constantele simbolice se declara prin directiva de area unei variabile cu. o valoare si interzicerea modificarii valorii a) tip const name - valoare; sau Declaratia este echivalenté cu tip nune-valoare dar, in plus, permite modificarea valorii lui nume printr-o expresie de atribuire une = valoare_nova: Fafa de 0 constant& simboliea, in acest caz se rezerv spafiu de memorie i care se inscrie valoarea constantei (constant obiect), Prin aceasti declarare se defineste un pointer spre 0 zona cu valoare constant. Nu este permis atribuirea de genul -nuno-va . dar poate ca variabilei smme sé i se atribuie o adres (de exemplu, 1 unde p este un pointer spre éip). Pentru a modifica valoarea insc memorie la adresa memor pointer © in ©) const tip? nunes Constructia de mai sus se foloseste Ia declararea parametrilor formali, pentru a impiedica modificarea lor in corpul subprogramelor, in cazul in.care apelatorul are nevoie de valorile initiale. 10.6. Tratarea parametrilor din linia de comanda In linia de comand& a unui program pot s& apard parametri (sau argumente). Acestia sunt siruri de caractere despartite prin spatii. Programul poate accesa argumentele prin intermediul parametrilor predefiniti. ai Bazele programiirit caleulatoarelor funefiei main unde arge confine numérul de parametti ai programului, inerementat cu 1 Exemplu 16, Dac& programul nu are ni programul are doi parametti, arge are valoarea 3 etc. un parametra, arge are valoares 1, dacd Variabila argv este un vector de pointeti care conjine adresele de wie parametrii programului, Primul sir (cu adresa aegvi01) confine identificatorul fisierului memorie unde s-au stocat sirurile de caractere care const (inclusiv calea completa) care memoreazi programul executabil. Urmitoarele siruri contin parametrii in ordinea in care au aparut in linia de comanda (parametrii in linia de comanda sunt siruri de caractere separate prin spatii) Interpretarea acestor parametti cade in sarcina programului. Exemplu 17. Sa se scrie un program care afigeaz parameitii din linia de comand. geamarii caleulatoaretor Subprograme 179 11. SUBPROGRAME inerementat cu | Dupai studierea acestui capitol, studentii vor avea cunostinfe teoretice B viioarca Tue si abilitati practice necesare pentru lucrul eu subprograme. Ei vor putea analiza problemele si construi subprogramele care le rezolva corect. Conctet, se vor asimila cunostinge si abilitayi de lueru privind tipurile de su structura si apelul subprogramelor: transferul parametrilor intre apelator si apelat: confine adresele de bprogtane; constituie parametri ntificatorul figierului emul exetitebil luerul cu paremetri de tip simplu, masiv, subprogram: aru h lucrul cu liste de parametri cu lungime variabils au aparut in linia de \ P 4 lungime variabil V¥Y¥VYY¥ Jucrul cu sul 21 cursive de caractere separate "u subprograme recursive, nna programului. 11.1. Construirea si apelul subprogramelor linia de eomanda, Conform teoriei programarii, subprogramele sunt clasificate in functii, care returneazi un singur rezultat prin .numele” functiei si oricite prin parametri de iesire si proceduri, care retumneaza oricite rezultate, toate prin intermediul parametritor de iesire. Un program C este un ansamblu de funcfii care realizeaza activitayi bine definite. Exista o functie, numita main(), care este apelata la lansarea in executie a programului, Subprogramele C sunt, in mod nativ, funcfil. Pot fi construite subprograme care nu return comportindu-se ca o procedura (conform definitiei din teorie). Sistemele C au colectii de biblioteci care contin functii standard. ‘Textul sursi al unui program C poate fi partitionat in mai multe fisiere. Fiecare fisier consti dintr-un set de functii si declaratii globale. Fisierele care constituie partitia pot fi compilate numai unul va confine functia main(). Funcfile C sunt formate din antet si un corp. Ametul are forma: ip pune ([iste-paranetri-fornali nici un rezultat prin numele lor, , eventual, testate separat, dar unde: tip poate fi un tip simplu de data. Dacé lipseste, este considerat tipul 180 Bazele programérii calculatoarelor implicit (int pentru unele compilatoare, void pentru altele); ume este un identificator care reprezintt numele functiei; lista-parametrilor-formali contine parametrii formali sub forma: vv Parametrii sunt separa{i prin virgula, La limita, lista poate fi vida. Pentru fiecare parametru trebuie specificat tipul. chiar daca mai’ multi il parametri sunt de acelasi tip (nu este pos cu acelasi tip) Pentru funcjiile care nu intore o valoare prin numele lor. tipul definirea de liste de parametri functiei va fi void sau va fi om Corpul este o instructiune compusa: conine declaratiile locale gi instructiunile executabile care implementeaza algoritmul, Coxpul functiei se executd pind la executarea ultimei instructiuni sau pind la executa instrue{iunii return, Forma ei general este: 1 $i a doua forma sunt folosite in cazul funcyiilor care returneazi 6 valoarea prin numele lor. Prin ‘executarea acestei instructiuni se evalueaz: expresia, valoarea sa este atribuitd funetiei gi se incheie execujia functiei. A treia forma este folosité in cazul functiilor care nu returnee: prin numele lor (poate chiat s8 lipseasea). Dac& este prezenti, efectul ei este o valoare ni incheierea executiei functiei. Tipul expresiei din instructiunea refurn trebuie i coincida cu tipul functie. Atenfie: corect este tipul recudtatului intors de functie prin rumele su. Vom vedea mai tirziu c& sintagma sipul funcsiei are un alt ‘nfeles, mai complex. in limbajul C nu este admisi imbricarea, adicé definirea unui subprogram in cadrul altui subprogram si nu sunt permise salturi cu instructiunea goto (instrucjiune de salt necondifionat) in afara subprogramului curent. Declararea unui subprograin apare, in cadrul fisierului sus, inaintea primului apel. Exist cazuri particulare in care, fie functiile se apeleaza Subpr uunele afl t verifi subpr decla Sinta carac sufici inaint subpr meV soci: prinn apetul instru pierde Exem 1. doua pentru unit calculatoarelor ‘Subprogran 181 waltele); functieis ali sub forma: ta poate fi vida. dacd mai’ multi 2 liste de parametri numele lor, tipul sclaraile locale si Corpul funetiei se vind la executarea lor care returneazd ctiuni se evalueazd executia finctiei. A az nici o valoare enti, efectul ei este unea return trebuie inetie prim manele functiei are un alt jc& definirea unui permise salturi cu tionat) in afara rului sus’, fnaintea fille se apeleaza uncle pe altele (de exemplu, cazul recursivitatii mutuale), fie definitia nu se afla in fisierul sursi. Pentru a oferi compilatorului posibilitatea sé efectueze verificarea validititii apelurilor, sunt prevazute — declarat subprogramelor fara definirea corpului lor (declarayii anticipate). Aceste tic. declaratii se numese protoripuri si apar in afara oricarui corp de fun Simaxa generald este 1 Prototipul este de fapt un antet de funciie dupa care se scrie caracterul ; (punet si virguli). Numele parametrilor pot lipsi, flind suficienta specificarea tipurilor lor. Prototipul trebuie inserat in program inaintea primului apel al functiei. Domeniul de valabilitate a declarajiei unui subprogram este limitat la partea care urmeazé declaratiei din fisierul sus Prototipurile functiilor standard se afld in fisiere header (cu extensia 4). Utilizarea unei funetii din biblio: figierului asociat, cu directiva #include 4 impune ineluderea Fiind funefii, subprogramele C se apeleazi ca operanzi in expresii. prin numele functiei urmate de lista parametrilor reali. Expresia care conti ne apelul poate la limit si contina un singur operand si chiar si fie 0 instructiune de tip expresie. in aceste cazuri valoarea returnata de functie se pierde. nefiind folosit8 in niei un fel Exemple 1, S& se scrie o functic care calculeaza cel mai mare divizor comun dintre doua numere intregi nenule, utilizind algoritmul lui Euclid si un apelator pentru testare, 182 Bazele programérii ealeulatoarelor 11.2. Transferul datelor intre apelator si apelat in practica programarii. s-au conturat doug posibilitati de transfer al datelor intre apelator si apelat: prin parametti gi prin variabile globale. Prin utilizar variabilelor globale nu se face un transfer propriu-zis, ci se folosesc in comun anumite zone de memorie, Aceast practic este nerecomandata, 11.2.1. Transferul prin parametri Principial, transferul parametrilor se poate face prin valoare sau prin adres. in limbajul C este implementat numai transferul prin valoare (valoarea parametrului real este copiaté tn stiva iar subprogramul lucreazi numai cu aceasti copie). Operajiile efectuate asupra unui parametru formal scalar (care nu este masiv) nu modifica, la iesirea din subprogram, par sit pe (tip exi vale face num mas (ver Exe: 5.5, prin gramiriicateutatoarelor mnde: apelat >ilitayi de transfer at riabile globale. Prin propriu-zis. ci se easta pra rin Valoare sau prin ferul prin valoare programul lucre 1i parametru formal 2 din subprogram, Subprograme_ 183 parametrul real corespunzator. Dezvoltirile ulterioare (C+) au implementat si transferul prin adresa, Transferul valorii este insoyit de eventuale conversii de tip realizate pe baza informatiilor de care dispune compilatorul despre subpt gram (tipucile parametrilor). Dac’ prototipul precede apelul subprogramului si nu existd o sublista variabila de parametri, conversiile se fae similar atribu Exemphu 3 ecru p)s ® peste transferat prin valoare Folosind transferul prin valoare se pot transmite numai parametri de intrare in subprogram, Pentru a putea folosi parametri de iesire trebuie simulat transferul prin adresit. In acest scop. se vor efectua explicit operatiile care se fac automat la transferul prin adres din alte limbaje: se transmite ca parametru adresa parametrului real iar in subprogram se lucreaz& cu indirectare (pentru a accesa valoarea parametrului. se dereferenjiaza adresa primita), Exemplu 4. tip ret e(tp_para valoare, fiind adresa parametrului real ‘ peste transferat prin Pentru parametrii de tip masiv, simularea transferului prin adrest se face in mod implicit, datorita modului de construire a masivelor in C: numele masivului este un pointer. La apel, in stiva se va transfera adresa masivului iar referirea elementelor se face automat prin calcul de adrese (vezi capitolul Tipuri dinamice de date). Urmatoatele prototipuri sunt echivalente: Exemple 5. Sa se calculeze produsul scalar dintre doi vectori. Rezultatul se intoarce prin numele functei Iss ele programiril caleulatoarelor in a doua variant de rezolvare, rezultatul se intoarce prin parametru, simulind transferul prin adresa: 6, Sa se calculeze clementul maxim dintr-un_v si pozitiile tuturor aparifiilor acestuia (v. n sunt parametri de intrare: max, rap, poz sunt parametri de iesire), xim(a,dinensivne, énax,anz_aparitii,pozitii) ; Antetul subprogramului este echivalent cu constructia pentru care corpul subprogramutui este acelagi 7. Sa se caleuleze produsul a dou’ matrice statice cous (eta ITT su me nu Ex 8. Ap. a) cu ind b) Se pref amiiril caleulatoarelor 185 nett, Observatie: Desi un tablou (masiv) nu poate fi returnat ca tip masiv prin numele unei funeti i, se pot serie functii ¢ retumeazi prin nume un tablou ca pointer — deoarece numele tabloului este echivalent in C cu adresa sa (pointer la inceputul masivului). Unui astfel de care il calculeaza masiv i se alocd memorie in func} Rezultatul intors prin numele funcfiei este adresa spatiului de memorie alocat pentru masiv Exemple 8, S& se calculeze produsul dintre o matrice $i un vector. si Apelul se realizeaza astfel: a) float 2120) 1301, bi30), ~er Cu vectorul ¢ se lucreazi in modul obignuit: elementele se refer prin indexare (c[i], i=0..m ). b) oat 2 Se lucreazi cu ,vectorul” prod(a.b,m.n) ~ elementele sale se refer’ ca prod(a,bemyn) [i], 10. Observati functia, ceea ce duce Ia consum mare si inutil de resurse. Este preferabild prima varianta, la fiecare referire de element se apeleazii gi se executi 186 Bazele programiriiealewlatoarelor Subp nbajul C permite transmiterea parametrilor numai prin valoare (la apelul subprogramelor se copiazi in stiva valoarea parametrului real si subprogramul luereazé cu aceasta copie). Subprogramul nu poate modifica valoarea parametrului din apelator Daca parametrul formal este un masiv, el este de fapt un pointer (adresa de inceput a masivului). Folosind aceasta proprietate, se pot modifica valorile elementelor masivului, iar modificzrile se vor prop: blocul apelator, deoarece valoarea care se copiazi a th stiva este adresa de \eeput a masivului, Masivul rimine in memoria principala si poate fi modificat prin intermediul adresei sale de inceput. Astfel se poate simula transmiterea parametrilor prin adres folosind pointerii. Subprogramul poate modifica valori care s& se propage in apelator. In acest scop se transmite ca parametru un pointer spre variabila cu care trebuie s@ lucreze subprogramul apelat. Subprogramul va folosi explicit acest pointer. Un exemplu in acest sens este functia de citire a datelor de la tastaturd, Paramettii acestei functii sunt adresele variabilelor ale ctor valori trebuie citite (altfel spus: adresele zonelor de memorie unde trebuie depuse valorile citite de la tastatura). Exemple 9. Fie un subprogram care calculeazd suma elementelor unui vector v de lungime m, stv la; Subprogramul suma calculeazi suma elementelor vectorului_ dar aceasta nu poate fi folositi de apelator, deoarece valoarea sumei este cunoscut numai in interiorul funetiei (parametrul a fost transmis. prin valoare). fn apelator valoarea variabilei corespunzitoare parametrului formal s nu va fi modificata. Pentru ca subprogramul sa fie utilizabi ca parametrul s si fie un pointer spre variabila in care se va memora suma elementelor vectorului: sume ( trebuie t vl, ant al Laa mem dino se pe num espe (func Exen 1. sramiri calcututoarelor Subprograme 187 rin adres mai prin valoare (la sarametrului real. si | nu poate modifica de fapt un pointer proprietate, se pot fe se vor propaga in stiva este adresa de incipalé si poate fi fel se poate simula Subprogr mul poate ter spre variabila cu aul va folosi explicit citire a datelor de la elor ale ciror valori unde trebuie depuse r unui vector v de elor vectorului dar aloarea sumei este Hoare parametrului fie utilizabil, trebuie va memora suma La apelul fune memoreaz suma: 10. S& se realizeze un subprogram care citeste de la tastatura o valoare ntreaga care apartine unui interval dat. 11.2.3. Comunicatia prin variabile globale abilele globale se declara in afara functiilor. Ele pot fi r din orice alte functii. De aceea, comunicarea valorilor intre apelator i apelat se poate realiza prin intermediul lor. Variabilele declarate intr-o Funct numese Jocale (din clasa awomatic) si pot fi referite numai din functia respectiv: (functia sau instructiuni ul de valabilitate a unei variabile locale este blocul a compusd) in care a fost definita - Domeni Exempla 1. 188 le programirit caleulatoarelor Subs Domeniile de valabilitate a referiilor variabilelor declarate sunt urmétoarele: » poate fi refe it doar in functia ¢ poate fi referit doar in functia main > > > — dpoate fi referit doar in instructiunea compu: > aeste globalai si poate fi referité de oriunde. Atenfie: este impropriu spus éransfer prin variabile globale. deoarece nu se realizeazi un transfer propriu-zis. De fapt o zond de memorie este accesatai de mai multe entit’yi (subprograme), toate avind posibilitatea utilizirii si modificarii valorii din acea zona. Datorit controlului asupra modificarilor, acest mod de transmitere a datelor nu este recomandat. Se prefera utilizarea acestei metode doar atunci cind este vorba de valori comune, general valabile intr-o aplicatie si care se modificd relativ rar (de exemplu calea ciitre figierul de date cu care se lucreaza). lipsei 11.3. Pointeri spre funefii in limbajul C, numele unei functii este un pointer care indica adresa de memorie unde incepe codul executabil al funcyiei. Aceasta permite transmiterea functiilor ca parametri in subprograme precum si luerul cu tabele de functii. in acest scop trebuie parcurse urmatoarele etape: a. Declararea unei variabile de tip procedural (pointer spre functie) unc fun tip une un: Ex 12, cur pri dif 190 _ Bazele programa ealculatoarelor Subp Apelul se realizeazd prin transmiterea ca parametru real a functiei potrivite prelucrarii dorite. Limbajul C permite Iucrul cu variabile de tip pointer, care contin adresa de Inceput a unei functii (a codului sau executabil). Aceste variabile permit transferul adresei funcjiei asociate ca parametru, precum si apelul funetiei prin intermediul pointerului séu. Urmatoarea declaratie defineste pointer_fca .pointer spre functia cu rezultatul /ip_returnat si paramett parametri™ nter_f) ((paranetr Observatie: Nu trebuie sa se confuunde un pointer la 0 funetie cu 0 c \ funotie care are ca rezultat un pointer, cu sintaxa de forma ip_ceturnat “pointer_f{{paranetri Adresa unei funcii se objine prin simpla specificare a iden poat com tran: para Exe 13, bise: gramériicaleulatoarelor ala functiei potrivite pointer, care contin bil). Aceste variabile “u, precum si apelul >inter spre functia cu ter lao funcjie cu o de forma pla specificare a Subprograme __ 191 identificatorului acesteia (fara specificarea parametrilor sau parantezelor) si poate compatibili. Pointerul poate fi folosit ulterior pentru apelul functiei transmi atribuitt unui pointer spre functie cu rezultat si parametri au ca parametru real in apelul unui subprogram care confine, in lista parametrilor formali, un pointer la un prototip de functie compatibila, Exempla 13. Sa se aproximeze solujia unei ecuafii de forma f(x)=0 prin metoda bisectiei 192 le programarii calculatoarelor Exemplu ai se sorteze at, dar pe care se poate in sir cu elemente de un tip nepre io relagie de ordine (de exemplu numeric, sir de caractere, caracter), Metoda aleas spre exemplificare este sortarea prin selectie directa. Un subprogram de sortare care sa nu depinda de tipul elementelor si de aiba ca parametti formali criteriul de sortare considerat trebuie sé > veetorul de sorta’, ca pointer la tipul void, asigurindu-se astfel posibilitatea realizirii operajiei de schimbare a tipului (..cast”) in functie de necesitatile ulterioare (la momentul apelului se poate realiza modificarea tipului in enc*, unde tip element reprezinté tipul elementelor vectorului de sortat); > —— dimensiunea vectorului de sortat si numarul de octeti din reprezentarea tipului eler > pointerul la 0 functie de comparare, cu argumente de tip void *, care ‘4 la apel atit schimbarea de tip, cit si descrierea efectiva a relajiei de ordine. elor vectorului: sf perm Deoarece tipul elementelor vectorului nu este cunoscut Ja momentul descrierii procedurii de sortare, operatia de atribuire nu poate fi folosita, ea find inlocuitd de o functie de copiere a unui numér prestabilit de octeti, lao adresa sursa la una destinatie. O astfel de functie exista in biblioteca 8 nari caleuletoarelor Subprograme 193 ‘mem.h, sintaxa ei fiind: Pentru accesarea adresei clementului de rang i din vector se foloseste formula Fisierul surs care confine funcjia de sortare descrisa anterior este urmatorul: rT pe care se poate tere, caracter) n selectie directa. elementelor si de ormali findu-se_astfel ipului (.cast") in apelului se poate unde tip_elemem ti din de tip void *, care serierea efectiva a sscut la momentul printf ("Dinensiunea ve scant ("#d", én) date fi folosita, ea wbilit de octeti, de sista in biblioteca 194 Bazele programérii caleulatoaretor Sut (int isQriensitey meant tiarscy sort (vect. printé ("\ni 11.4, Funefii cu numar variabil de parametri Bibliotecile limbajului C conjin subprograme standard cu numar variabil de parametri. Limbajul C permite definirea func{iilor utilizator cu numar variabil de parametti, prin utilizarea unui set de macrodefiniti, declarate in biblioteca sidarg.h, care permit accesul la lista de parametti Figierul sidarg.h declara tipul va_tist si func va_end, in care: va_start, va_arg si va_list este un pointer catre lista de parametri. in functia utilizator corespunzatoare trebuie declaraté o variabilé (numita in continuare pilisi) de acest tip, care va permite adresarea parametrilor. > sub unc une var Pro unc ape um ~» ape pro. Ex 15. nun smiirit ealeutatoarelor Subprograme _ 198 >>va_start initializeaza variabila pilist cu advesa primului para sublista variabild, Prototipul acestei functii este: unde wtim reprezinta numele ultimului parametru din sublista variabila. in unele situafii (vezi exemplele) se transferd in acest parametru numairul de variabile trimise. >va_arg intoarce valoarea parametrului urmator din sublista variabila. Prototipul acestei functii este: unde ‘ip_element este tipul elementului wansferat din lis 18. Dupa fiecare arg, variabila pilist este modificatd astfel tneit s& indice urmétorul parametru. apel al funetiei va >va_end incheie operatia de extrag, re a valorilor paramettilor si trebuie apelata inainte de revenirea din funefie, Prototipul functiei este: Problema numarului de parametri si ipurilor lor este tratat’i de programator. Exemplu . 15. Sa se calculeze cel mai mare divizor comun al unui numéar oarecare de umetti i numere intr; standard cu numar netiilor utilizator cu 1 de macrodefiniti, sta de parametr. ra_start, va_arg si in funcyia utilizator continuare pilist) de prine# ("\ncnme e 196 Bazele programiarit calculatoaretor £(\aCand! 2 x Exemplu 16. Sa se interclaseze un numa oarecare de vectori Spre deosebire de exemplul anterior, in care in lista de parametri a functiei cu num oarecare de parametri figurau elemente de acelagi tip (int) acest exemplu ilustreaz& modul de transfer si acces Ja elemente de tipuri diferite. Funcfiei inrer_var i se transmit la apel vectorul rezultat, iar pentru fiecare vector de interclasat, adresa de inceput (pointer la tipul double) si numarul de elemente (int). Numarul parametrilor din lista variabil& este, in acest, caz2 x numérul de vectori de interclasat. Sub aril calculatoarelor n lista de parametri a ate de acelasi tip (int), la elemente de tipuri ul rezultat, iar pentru er Ja tipul double) si lista variabil& este, in Subprograme 198 Bazele programérii calculatoarelor Bibliog [Ros Rosca Batag aplica pleva_argiptliat, inti [Rose Rog cale meiguaniien2s aplice [Rose Rogea in Pas [Rose Rosca progr romar [Rose Rosca in Pas [Kem Keri In {Dode Dodes Bucur caleulatoarelor Bibliograpie 199 BIBLIOGRAFIE [Rosca et al., 2006} Rosca |. Gh. Ghilie-Micu B.. Cocianu C., Stoica M. sircea M., Silvestru C.. Bacele programarii cateulatoarelor. Teorie si aplicatit in C. Ed, ASE. Bucuresti 2006, ISBN 973-594-591-6 Uscatu C.. {Rosca et al.. 2003] Rogca 1. Gh., Ghilie- caleulaioarelor. Siina inviqarit unui limbaj de programare. Teorie si aplicatii. Ed, ASE, Bucuresti 2003. ISBN 973-594-243-7 u B., Stoica M., Cocianu C., Uscatu C.. Programarea [Rogca et al.. 1998] Rosca 1. Gh.. Apostol C., Ghilic-Micu B., Rogea V.. Programare sisten in Pascal. Ed, Didactiea si Peds esti 1998. ISBN 97 30-3341-3 ogica. Bucur [Rogea et al.. 1996] Rosca I. Gh. Apostol C.. Ghilie-Mieu B.. Rosca V.. Introducere programare. Teorie si practiced Pascal. Casa de editura si pr roméneasca, Bucuresti, 1996 [Rosca et al.. 1994] Rosca, 1. Gh. Apostol C., Ghilic-Micu B., Rosca V.. Prefucrarea fisierelor in Pascal, Bd. Tehnica, Bucuresti, 1994 [Kemighan et al., 1988] Kernighan B.. Richie D.. The C Programming Language, Prentice Hal Inc., 1988, ISBN 0-13-1103 [Dodescu et al. 1987] Dodeseu Gh. si colectiv, Informatica, Ed. § Bucuresti, 1987 4 si Enciclopedica,

You might also like