S-a discutat pn acum despre structuri de control care permit alegerea condiionat ntre execuia mai multor seturi de instruciuni. Sistemele de calcul au avantajul c pot repeta, o dat 'instruite ce si ct (programate), un numr de operaiuni de cte ori este nevoie. Orice limbaj de programare este are implementat aceast posibilitate. Exist dou clase de instruciuni de ciclare (repetare). O prim categorie se reIer la instruciunile care repet un bloc de instruciuni pn cnd este ndeplinit o condiie (prin condiie putem nelege o expresie multipl ce va Ii evaluat de ctre compilator). De obicei este Iolosit pentru interaciuni repetitive cu utilizatorul sau n calculul numeric prin aproximaii si de aceea instruciunile respective se numesc instruciuni cu numr necunoscut de pasi. O a doua categorie de instruciuni repetitive este aceea a instruciunilor cu numr cunoscut de pasi. Din punct de vedere al limbajului nu ar Ii strict nevoie de acest tip de instruciuni, pentru c se poate realiza acest lucru cu instruciunile din prima clas. Totusi, dup cum se va observa mai jos implementarea (cu instruciuni cu numr necunoscut de pasi ) pentru aceast a doua clas presupune un cod care va Ii identic la absolut toate interpretrile. Pentru a usura scrierea codului si a-l Iace mai clar s-a implementat o instruciune nou Ior... . 7.1. Instruciuni cu numr necunoscut de payi 7.1.1. Instruciunea while Este o instruciune care permite repetarea sau nu a execuiei unei buci de cod Iuncie de valoarea de adevr a unei expresii. Un exemplu n care ar Ii necesar acest tip de instruciuni ar Ii restricia domeniului de valori n cazul datelor care le poate introduce un utilizator. Acest lucru este necesar pentru c de obicei utilizatorul nu ine cont de toate restriciile relativ la intervalul n care poate da o valoare de intrare,sau poate da din greseal o valoare incorect. Totusi modelul matematic speciIic clar c algoritmul lucreaz corect numai n intervalul |a,b]. Pentru utilizator Iaptul c programul d un rezultat eronat datorit unei valori de intrare introdus gresit nseamn c programul nu Iuncioneaz corect. Este necesar ca programatorul s nu permit introducerea altor date dect cele speciIicate de modelul matematic. Observaie: limbajul C spre deosebire de limbajul Pascal nu genereaz un mesaj de eroare dac tipul de dat introdus nu coincide cu speciIicatorul dat Iunciei scanf. Din acest motiv n momentul n care se pregteste o versiune beta (prima versiune a aplicaiei care va Ii Iolosit de ctre utilizator) trebuiesc introduse toate restriciile de tipul menionat mai sus. La nivel de pseudocod metoda poate Ii descris ca mai jos: citete valoarea de intrare atta timp cat valoarea de intrare nu se afl in intervalul [a,b] emite un mesaf de atenionare ctre utili:ator recitete valoarea Pentru aceasta se poate Iolosi instruciunea while. a crei sintax este prezentat mai jos: while(conditie)// atata timp cat condiia este adevrat execut { bloc de instruciuni } n Iigura 7.1. este prezentat schema logic corespunztoare instruciunii while. Fig. 7.1. Schema logic a instruciunii while n exemplul de mai jos este vorba de citirea unei valori ntregi care trebuie s aparin intervalului [0,255]. #include <stdio.h> #include <conio.h> void main(void) { unsigned char value; clrscr(); printf(Nr1:); scanf(%d,&op1); while((value>255)&&(value<0)) { printf(Eroare ! Numarul trebuie sa fie intre 0 si 255 ); printf(Nr1:); scanf(%d,&op1); } // urmea: restul programului } 7.1.2. Instruciunea do. while Dup cum s-a menionat anterior instruciunea while. testeaz mai nti valoarea de adevr a expresiei de evaluat si apoi, Iuncie de aceasta, execut sau nu blocul de instruciuni. De aceea i se mai spune instruciune de ciclare cu test anterior. Dac se analizeaz exemplul de mai sus din punct de vedere al simplitii codului se observ c blocul de instruciuni pentru citirea variabilei a Iost scris de dou ori. Pentru a evita scriere de cod inutil n aceast situaie pseudocodul trebuie s Iie ca mai jos: citete valoarea verific dac se afl in intervalul dorit dac da continu programul dac nu reia de la citirea variabilei Pentru a putea rezolva elegant situaiile de acest gen s-a mai introdus o instruciune si anume dowhile a crei sintax este prezentat mai jos: do //execut { bloc de instruciuni }while(condiie)// atata timp cat condiia este adevrat n Iigura 7.2. avem prezentat schema logic pentru instruciunea do.while. Fig. 7.2. Schema logic a instruciunii do.while Folosind aceast instruciune codul prezentat mai sus devine: #include <stdio.h> #include <conio.h> void main(void) { unsigned char value; clrscr(); do { printf(Nr1:); scanf(%d,&op1); if( value>255)&&(value<0)) printf(Eroare ! Numarul trebuie sa fie intre 0 si 255 ); } while((value>255)&&(value<0)); // urmea: restul programului } Deci se citeste numrul si, dac acesta nu este corect, se reia citirea. Pentru validarea aIisrii mesajului de eroare s-a prevzut veriIicarea condiiei pentru c dac utilizatorul introduce corect valoarea de prima oar, nu este permis aIisarea mesajului de eroare. Aceast instruciune execut mcar o dat blocul de instruciuni si de-abia apoi Iace evaluarea expresiei pentru a putea vedea dac acesta se mai repet sau nu. De aceea i se mai spune si instruciune de ciclare cu test posterior. 7.2. Instruciuni cu numr cunoscut de payi. Instruciunea for. Din cele prezentate pn acum rezult c se poate repeta un bloc de instruciuni pn cnd este ndeplinit o condiie. Exist cazuri cnd se cunoaste de la nceput cte valori se doresc a Ii prelucrate, Iie prin speciIicarea direct a utilizatorului, Iie ca rezultat a unor calcule anterioare. De obicei acest lucru se aplic la calculul vectorial sau matricial dar nu numai. ntruct nu s-a discutat nc despre acest tip de date se va lua n discuie un exemplu mai simplu, cum ar Ii realizarea unui program ce va ridica un numr la o putere. Pseudocodul si apoi programul sunt prezentate mai jos: citete numrul (nr) citete puterea la care va fi ridicat (pw) iniiali:ea: variabila re:ultat, ce va pstra nr la putere, cu 1 (rez=1) atata timp cat variabila ce a primit puterea ~0 f rez=rez*nr; pw=pw-1; repet afiea: re:ultatul Codul surs corespunztor . #include <stdio.h> #include <conio.h> void main(void) { int nr, pw; float rez; clrscr(); printf(Numarul); scanf(%d,&nr); printf(\nPuterea); scanf(%d,&op2); rez=1; //**** while(pw>0)//***** { rez=rez*nr; pw=pw-1;//***** } printf(Numarul %d la puterea %d este %f,nr,pw,rez); getch(); } Instruciunile marcate cu asterix se repet n Ioarte multe situaii cnd numrul de pasi este cunoscut. De aceea s-a implementat instruciunea Ior. avnd urmtoarea sintax for(contorvaloareiniial,contorsau~valoarefinal, contor=contor+sau -pas) { bloc de instruciuni } La nivel de schema logic execuia instruciunii for este prezentat n Iigura 7.3. Fig. 7.3. Schema logic instruciunii for Acum se observ c aceast instruciune scuteste programatorul de a scrie cod suplimentar. Programul anterior rescris Iolosind aceast instruciune este dat mai jos. #include <stdio.h> #include <conio.h> void main(void) { int nr, pw,i; float rez; clrscr(); printf(Numarul); scanf(%d,&nr); printf(\nPuterea); scanf(%d,&op2); for(i=0;i<pw;i=i+1) rez=rez*nr; //codul mai poate fi scris i ca in :ona comentata ce urmea: // for(i=pw;i>0;i=i-1) // rez=rez*nr; printf(Numarul %d la puterea %d este %f,nr,pw,rez); getch(); } Exist un control total asupra desIsurrii buclei exact ca si n cazul while dar codul scris este mult mai succint. Observaia 1: Dac blocul de instruciuni const ntr-o singur instruciune parantezele nu mai sunt necesare Observaia 2: Dac se pune '; dup Ior acesta va considera c are o bucl vid, compilatorul nu va raporta eroare sintactic, dar ceea ce este scris n blocul de instruciuni va Ii doar o singur dat executat. 7.3. Alte instruciuni 7.3.1. Instruciunea break EIectul instruciunii break const n prsirea imediat a celei mai apropiate (textual) instruciuni switch, while, do, Ior nconjurtoare. 7.3.2. Instruciunea continue Instruciunea continue nu se poate utiliza dect ntr-un ciclu while, do sau for. EIectul instruciunii continue const : - ntr-un salt la evaluarea condiiei de ciclare, dac cea mai apropiat (textual) instruciune de ciclare nconjurtoare este while sau do. - ntr-un salt la evaluarea expresiei din a treia poziie , dac cea mai apropiat (textual) instruciune de ciclare nconjurtoare este Ior. Prezentm mai jos un exemplu simplu de Iolosire a instruciunii break si continue: void main(void) { int xx; for(xx = 5;xx < 15;xx = xx + 1){ if (xx == 8) break; printf("In bucla oprita fortat , xx are valoarea %d\n",xx); } for(xx = 5;xx < 15;xx = xx + 1){ if (xx == 8) continue; printf("Prin aplicarea continue in bucla, xx devine %d\n",xx); } } 7.3.3. Instruciunea goto nume_etichet EIectul instruciunii goto const ntr-un salt necondiionat la instruciunea cu eticheta citat n instruciunea de salt, care trebuie s se aIle n aceeasi Iuncie. 7.3.4. Instruciunea return EIectul instruciunii return conduce la terminarea imediat a execuiei Iunciei curente si la revenirea la Iuncia apelant. Dac expresia este prezent, ea trebuie s Iie de un tip care poate Ii convertit la tipul Iunciei n care apare instruciunea return. Valoarea expresiei este valoarea ntoars de Iuncie. 7.3.5. Constante simbolice Cu ajutorul directivei "#define" se pot defini la nceputul programului nume sau constante simbolice care sunt un sir particular de caractere. Dup aceea, compilatorul va nlocui toate apariiile, nepuse ntre ghilimele, ale numelui, prin sirul corespunztor. nlocuirea eIectiv a numelui poate Ii orice text ea nu se limiteaz la numere. #define MIN 0 //valoarea minim admis #define MAX 300 //valoarea maxim admis # define AND && void main(void) { int x; printf(Dati un numar); scanf(%d,&x) if((x>=MIN)AND(x<=MAX))printf(\nNumarul este in interval); else printf(Numarul nu este in interval); getch(); } Cantitile MIN si MAX sunt constante, asa nct ele nu apar n declaraii. Numele simbolice se scriu n mod normal cu litere mari, asa c pot Ii usor distinse de numele de variabile care se scriu cu litere mici. La sIrsitul unei deIiniii NU se pune punct si virgul.