Sunteți pe pagina 1din 7

Algoritmic && programare. Limbajul C.

Instruciuni C\C++ (partea a II-a)

III. Instruciuni de ciclare


Instruciunile de ciclare (repetitive, iterative, etc) sunt utilizate n situaia n care o anumit secven de cod trebuie executat de mai multe ori n mod consecutiv, numrul de repetiii fiind fix, stabilit iniial, sau variabil, depinznd de rezultatul aciunii repetate. Limbajul C pune la dispoziia programatorilor trei instruciuni de ciclare: while, do-while i for, toate trei utiliznd pentru continuarea ciclrii o condiie de tip att timp ct este adevrat c , diferena dintre ele fiind dat, n principal, de momentul testrii condiiei de ciclare: n cazul instruciunii while testarea se face naintea fiecarei execuii a aciunii repetate (testare anterioara), n cazul do-while testarea se face la reluare, dup fiecare execuie a instruciunii corp (testare posterioara), iar n cazul instruciunii for testarea se face analog cazului while, instruciunea for avnd ns prevazut i executarea unei anumite secvene de cod nainte de fiecare reluare, precum i o secven iniial, executat naintea intrrii n ciclare. Instruciunile repetitive pstreaz controlul fluxului de execuie al programului pn cnd are loc ieirea din ciclare. O ieire din ciclare poate fi normal, atunci cnd controlul este preluat de urmtoarea instruciune din textul surs n urma evalurii condiiei de repetare a ciclrii, sau poate fi forat, prin executarea unei instruciuni de salt aflate n corpul instruciunii repetitive. In continuare vom descrie cele trei instruciuni iterative ale limbajului C n situaia n care ieirile sunt normale, urmnd ca ieirile forate din ciclare s fie tratate o dat cu instruciunile de salt.

7. Instruciunea while
Sintaxa: while (expresie-test) instruciune-corp Instruciunea while insereaz n mod repetat n fluxul de execuie instruciunea sa corp, att timp ct expresia-test este adevarat (are o valoare nenul). Este asemntoare cu instruciunea if, cu diferena esential c, dup executarea instruciunii corp, controlul este pstrat de while i se reia evaluarea expresiei-test. Controlul execuiei trece la urm-toarea instruciune din textul sursa al programului (daca n corp nu sunt prevazute salturi) numai atunci cand expresia test devine fals (egala cu zero). Dac expresia test este fals de la bun nceput, instruciunea corp nu este executat niciodat. Tipul expresiei-test trebuie sa fie scalar (numeric sau pointer) i la evaluare sunt completate toate efectele ei secundare naintea luarii deciziei de contiunare sau de terminare a ciclrii. Instruciunea-corp poate fi de orice tip (inclusiv o instruciune while), dar ca s aibe sens utilizarea ei trebuie sa fie o instruciune efectiv i nu o declaraie, de exemplu. De regul, instruciunea corp

este o instruciune compus, coninnd o secven de cod care descrie aciunea care trebuie repetat. De exemplu, pentru a tipri codurile ASCII ale caracterelor stringului text, se poate utiliza urmatorul sir de instruciuni:
int i=0; while(text[i]!='\0'){ cout<<(int)text[i]<<" "; i++; }

Dac irul de caractere este vid (adic text[0]== '\0'), nu este tiparit nici un cod ASCII. Secventa de mai sus poate fi compactat astfel:
int i=0; while(text[i]!='\0') cout<<(int)text[i++]<<" "; cout<<endl;

sau
int ch,i=0; while((ch=text[i++])!='\0') cout<<ch<<" "; cout<<endl;

Primele dou variante sunt complet echivalente, a treia, dei execut acelai lucru, difer de primele prin valoarea indexului i la ieirea din ciclare: deoarece n ultima variant incrementarea indexului are loc la evaluarea condiiei de continuare, i este incrementat i n cazul n care se decide ieirea din ciclare, astfel c n final valoarea indexului depete cu o unitate locul terminatorului de ir (caracterul nul).

8. Instruciunea do-while
Sintaxa: do instruciune-corp while (expresie-test); Instruciunile while i do-while sunt foarte asemntoare, singura diferen aprnd doar la iniierea ciclrii: la start, do-while execut o dat, n mod necondiionat, instruciunea sa corp i dup aceasta intr n ciclul evaluare test repetare execuie, spre deosebire de while care ncepe direct cu evaluarea expresiei test. In concluzie, instruc-tiunea do-while este echivalent cu urmtoarea secven de instruciuni: instruciune-corp while (expresie-test) instruciune-corp De remarcat c sintaxa instruciunii do-while prevede existena terminatorului ;care nu poate fi nlocuit cu nimic altceva (aici nu are sensul de instruciune nul). Instruciunea do-while este de preferat n locul instruciunii while n situaia n care aciunea iterat trebuie executat cel puin o dat. Exemplu: pentru a tipri toate codurile ASCII ale caracterelor stringului text, inclusiv codul terminatorului de ir (caracterul nul), este de preferat utilizarea instruciunii do-while:

int ch, i=0; do { ch=text[i]; cout<<ch<<" "; i++; } while (ch!='\0'); cout<<endl;

Dac irul de caractere text este vid, este imprimat numai codul caracterului nul (zero). Evident c i aceast secven poate fi scris ntr-un mod mai compact:
int ch, i=0; do cout<<(ch=text[i++])<<" "; while (ch!='\0'); cout<<endl;

Instruciunile while i do-while sunt preferate atunci cand expresia-test nu depinde direct de variabila indexat.

9. Instruciunea for
Sintaxa: for ( expresie-inial; expresie-test; expresie-reluare) instruciune-corp Instruciunea for, cu o sintaxa mult mai complex decat celelalte instruciuni de ciclare, furnizeaz o scriere compactat a etapelor standard de execuie a unui proces iterativ: iniializarea variabilelor naintea startului, evaluarea testului de ciclare, execuia aciunilor din corpul ciclului, actualizarea variabilelor implicate n expresia-test, reluarea testrii. In general (cu cteva excepii care vor fi precizate ulterior) instruciunea for este echivalent cu urmatoarea secven de instruciuni: expresie-inial; while ( expresie-test) { instruciune-corp expresie-reluare; } De exemplu, iniializarea cu zero a componentelor tabloului tab[100], executat de secvena de instruciuni:
i=0; while (i<100){ tab[i]=0; i++; }

poate fi efectuat de o singur instruciune for:


for ( i=0; i<100; i++) tab[i]=0;

Execuia instruciunii for ncepe cu evaluarea expresie-iniiale i completarea tuturor efectelor sale secundare. Expresia iniial poate fi de orice tip, scopul ei este de iniializare a valorilor variabilelor implicate n ciclare (dac trebuie facute mai multe atribuiri se poate folosi operatorul virgul, desigur). Ea este evaluat o singur dat, imediat nainte de intrarea n ciclarea propriu-zis. Dup evaluarea expresiei de iniializare se trece la evaluarea expresiei-test (i

completarea efectelor ei secundare). Expresia test trebuie s fie de tip scalar. Dac rezultatul evaluarii e fals execuia instruciunii for se ncheie aici, iar controlul este preluat de urmatoarea instruciune din textul surs. Dac expresia-test este adevarat se continu cu execuia instruciuniicorp. Dup finalizarea aciunilor descrise de corpul ciclui for (instruciunea-corp) i imediat nainte de reluarea testrii este evaluat expresia-reluare. Expresia-reluare poate avea orice tip, ea este utilizat mai ales pentru actualizarea valorii variabilei index. Dup completarea efectelor secundare a expresiei-reluare se reia procesul iterativ prin re-evaluarea expresiei test. Oricare dintre cele trei expresii din antetul instruciunii for poate lipsi, doar prezena celor doua simboluri punct i virgul este obligatorie. In cazul n care lipsete expresia-test ( fapt interzis pentru if sau pentru while) se consider ca testul de reluare a iteraiei este n mod implicit satisfcut. In acest caz, dac nu este prevzut ieirea forat (prin salt) din ciclare, execuia instruciunii for continu la nesfarit i, n consecin, blocheaza execuia programului. De reinut: urmatoarea form a instruciunei for: for ( ; expresie-test; ) instruciune-corp este echivalent cu while ( expresie-test ) instruciune-corp n timp ce forma: for ( ; ; ) instruciune-corp este echivalent cu while ( 1 ) instruciune-corp. Urmatoarele exemple ilustreaz modul uzual de utilizare al instruciunii for. Exemplul 1. Sumarea din trei n trei a elementelor unui tablou uni-dimensional, tab[], ncepand cu tab[2]:
for( suma=0,i=2; i<n; i+=3) suma+=tab[i];

Exemplul 2. Inversarea ordinei elementelor tabloului tab[]:


for( i=0,j=n-1; i<j; i++,j--){ aux=tab[i]; tab[i]=tab[j]; tab[j]=aux; }

Exemplul 3. Determinarea valorii maxime a elementelor matricei matr[][]:


for(valMax=matr[0][0],i=0; i<n; i++) for (j=0; j<m; j++) if (valMax < matr[i][j]) valMax=matr[i][j]; cout<<"valoarea maxima="<<valMax<<endl;

IV. Instruciuni de salt


10. Instruciunea break
Instruciunea break are sintaxa break; i este este folosit pentru a iei imediat dintr-o instruciune de ciclare sau dintr-un switch. Ea transfer controlul instruciunii imediat urmtoare celei prsite. Instruciunea break poate fi folosit numai n aceste dou situaii, dac ea apare fr s fie n corpul unei ciclri sau al unui switch avem o eroare la compilare. In cazul instruciunilor imbricate (for n for, etc) break ncheie numai execuia instruciunii n care este direct inclus. Exemplu:
#include<iostream> using namespace std; int main(void){ int i,j; for(i=0;i<5;i++){ cout<<"i="<<i; for(j=0;j<100;j++){ if (i==j) { cout<<" pauza"<<endl; break; } cout<<" j="<<j; } } return 0; } /* REZULTAT i=0 pauza i=1 j=0 pauza i=2 j=0 j=1 pauza i=3 j=0 j=1 j=2 pauza i=4 j=0 j=1 j=2 j=3 pauza Press any key to continue*/

11. Instruciunea continue


Instruciunea continue are sintaxa continue; i este este folosit n instruciuni de ciclare (i numai acolo) pentru a ncheia n mod forat execuia iteraiei curente i a trece la urmtoarea iteraie. In interiorul unei bucle while sau do-while, la ntlnirea instruciunii continue are loc un salt direct la re-evaluarea expresiei test, n cazul instruciunii for se trece mai ntai la evaluarea expresiei de reluare i apoi la evaluarea expresiei test. Exemplu:

#include<iostream> using namespace std; int main(void){ int i;

for(i=0; i<20; i++){ if (i%3==0) continue; cout<<i<<" "; } cout<<endl; return 0; } /* REZULTAT 1 2 4 5 7 8 10 11 13 14 16 17 19 Press any key to continue */

12. Instruciunea return


Instruciunea return permite unei funcii s transfere controlul napoi funciei apelante, (sau, n cazul funciei main, returnarea controlului ctre sistemul de operare). Execuia unei funcii care trebuie s returneze o valoare se ncheie atunci cnd controlul ntlnete o instruciune return cu sintaxa: return expresie-rezultat; caz n care se evalueaz expresia-rezultat iar rezultatul obinut este transferat funciei apelante. Funciile care nu trebuie s returneze nimic (cele a cror declaraie ncepe cu cuvntul cheie void) i ncheie execuia atunci cnd controlul ntlnete o instruciune return fr expresie rezultat, sau la ntlnirea acoladei care nchide corpul funciei. Exemplu:
#include<iostream> using namespace std; int dist(int a, int b){ if(a>b) return a-b; return b-a; } void panaLaPrimulZero( int tab[], int dim){ int i=0; for(i=0;i<dim;i++){ cout<<tab[i]<<" "; if(tab[i]==0) return; } } int main(void){ const int dim=6; int v[]={1,2,3,0,4,5}; int i; for(i=0;i<dim;i++){ v[i]=dist(i,v[i]); } panaLaPrimulZero(v,6); cout<<endl; return 0; } /* REZULTAT 1 1 1 3 0 Press any key to continue */

13. Instruciunea goto


Instruciunea goto transfer controlul unei etichete aflate n interiorul aceleiai funcii. Sintaxa instruciunii goto este urmtoarea: goto etichet; O etichet este format dintr-un identificator urmat de simbolul dou puncte : i poate apare cel mult odat n faa unei instruciuni din corpul unei funcii. Aceste etichete sunt utilizate numai de instruciunea goto, n orice alt context o instruciune etichetat este executat fr s se in seama de prezena etichetei. Deoarece urmrirea salturilor ctre etichete reduce claritatea programului, este recomandat utilizarea salturilor date de break, continue sau return n locul instruciunii goto. Un exemplu de utilizare justificat: ieirea forat din bucle imbricate:
int main(void){ const int dim=10; int mat[dim][dim]; int i,j; citeste(mat,dim); for(i=0;i<dim;i++){ for(j=0;j<dim;j++){ if(mat[i][j]==0) goto stop; cout<<1.0/mat[i][j]<<endl; } } stop: cout<<"GATA"<<endl; return 0; }

Dac n matricea mat nu exist elemente nule sunt afiate toate inversele elementelor i apoi apare textul "GATA", altfel afiarea se ncheie la prima apariie a lui zero. Se poate nlocui goto cu return dac afiarea se efectueaz ntr-o funcie adecvat.