Sunteți pe pagina 1din 14

Curs: Core Java Programming

Modul: Controlul fluxului


Unitate: Bucla For

În programare, adesea este necesar să se repete de câteva ori acelaşi


bloc de comenzi. Această repetare se face prin folosirea buclelor. Java
are câteva tipuri de bucle, dar dacă nu numărăm toate variaţiile,
numărul buclelor se reduce la două. Buclele for şi while. În lecţia
aceasta vom vorbi mai mult despre bucla for.

Bucla for se foloseşte atunci când ştim în prealabil exact de câte ori
trebuie să se execute un bloc de comenzi. Bucla aceasta are
următoarea sintaxă:

for (ini?ializare; condi?ie; m?rire) {


bloc de comenzi;
}

Primul parametru se foloseşte pentru a crea şi pentru a seta valoarea


iniţială a numărătorului. Al doilea parametru conţine condiţia pentru
numărător, iar al treilea determină în ce fel creşte numărătorul.
Următorul exemplu de cod scrie mesajul de bun venit de 4 ori:

for (int num?r?tor=1;num?r?tor<5;num?r?tor++) {


System.out.println("Bine a?i venit!");

Întâi, valoarea variabilei numărător (counter) se iniţializează şi se


setează la 1 (int numărător=1). Al doilea parametru conţine condiţia
(numărător<5). Blocul de comenzi se va executa atâta timp cât
condiţia aceasta este adevărată, iar condiţia va fi corectă atâta timp
cât variabila numărător este mai mică decât 5. Al treilea parametru
măreşte variabila numărător cu unu (numărător++).

Numărătorul din buclă are o semnificaţie multiplă. Aceaasta este, în


primul rând, unicul mod în care controlăm numărul de executări ale
unui bloc în buclă. Însă, pe lângă aceasta, numărătorul, în fiecare
iteraţie a buclei, ne expune valoarea sa pe care o putem folosi. După
terminarea buclei, se opreşte existenţa variabilei definite ca
numărător (dacă am declarat-o în interiorul definiţiei buclei).

Următorul exemplu va afişa numerele de la 0 la 4.

© Copyright Link group 1 / 14


Curs: Core Java Programming
Modul: Controlul fluxului
Unitate: Bucla For

for (int counter=0;counter<5;counter++) {


System.out.println(counter);
}

Însă, dacă după acest bloc mai adăugăm o linie în care prezentăm
valoarea variabilei numărător (counter), se va produce o eroare pentru
că variabila counter a fost declarată şi iniţializată în interiorul buclei.

for (int counter=0;counter<5;counter++) {


System.out.println(counter);
}
System.out.println(counter);

Dacă dorim să avem un numărător (counter) disponibil pentru altă


folosire şi după executarea buclei, acest lucru trebuie declarat mai
devreme, în afara definiţiei buclei:

int counter;
for (counter=0;counter<5;counter++) {
System.out.println(counter);
}
System.out.println(counter);

Acest exemplu nu va semnala nicio eroare şi va afişa numerele de la 0


la 5. Poate părea ciudat faptul că, la sfârşit, valoarea variabilei
numărător va fi 5, dar este în totalitate logic. Corpul buclei se execută
atâta timp cât valoarea variabilei numărător este mai mică decât 5.
Dacă am merge iteraţie cu iteraţie prin buclă, valoarea numărătorului,
bucla şi programul însuşi ar avea următoarea viaţă: bucla s-ar executa
de 5 ori, de atâtea ori cât se va îndeplini condiţie. La final, valoarea se
va mări cu unu (şi vom obţine valoarea 5), prin care condiţia nu se va
mai îndeplini. Ca rezultat, se va anunţa că bucla va fi părăsită, dar
valoarea numărătorului va rămâne în continuare 5. De aceea, după
bucla executată astfel, obţinem valoarea numărătorului 5.

Buclele for se folosesc frecvent pentru trecere prin şiruri.

De exemplu:

© Copyright Link group 2 / 14


Curs: Core Java Programming
Modul: Controlul fluxului
Unitate: Bucla For

//se creeaz? un nou ?ir de cinci elemente


String[] colors = {"ro?u" , "verde" , "albastru" , "galben"
, "alb"};
//se folose?te bucla for pentru trecerea prin ?ir ?i pentru
scrierea elementelor lui
for (int i = 0; i < colors.length; i++)
{
System.out.println("Valoarea elementului " + i + " este " +
colors[i] + ".");
}

Şirul creat mai sus are cinci elemente; indexurile elementelor sunt de
la 0 la 4. De aceea, în condiţie se foloseşte inegalitate strictă, pentru
ca programul să nu încerce să acceseze elementul cu indexul 5, care
nu există.

Ştim că există trei părţi la iniţializarea buclei for. În exemplele


precedente, fiecare parte a avut câte un parametru, dar aceasta nu
este structura obligatorie. Uneori, la o singură iniţializare, putem defini
mai mulţi parametri.

Bucla următoare va iniţializa variabilele i şi a, şi le va atribui valori


diferite. Apoi, se pune o condiţie (ca i să fie mai mic decât 10), iar
apoi, se intervine la ambele valori, mărindu-le cu unu:

int i;
int a;
for(i=0,a=5;i<10;i++,a++)
System.out.println(i + ":" + a);

Însă, precondiţia sintactică nu subînţelege introducerea tuturor celor


trei parametrii. Următorul exemplu va fi, de asemenea, valabil:

for(i=0;i<10;) System.out.println(i++);

În acest exemplu, cel de-al treilea parametru a fost omis. De fapt, nu


este omis, ci rămâne complet vid, ceea ce desemnează marcajul ;
după numărul 10.

© Copyright Link group 3 / 14


Curs: Core Java Programming
Modul: Controlul fluxului
Unitate: Bucla For

După o astfel de iniţializare, am făcut incrementarea în blocul însuşi,


ceea ce poate fi foarte periculos. Dacă lipseşte increment, putem
cădea într-o aşa-numită bucla moartă (bucla care se execută la infinit)
şi care, în cel mai bun caz, va bloca tot mediul.

Trebuie, în general, să ne ferim de bucla moartă, pentru că există


diverse feluri în care o putem produce. Pur şi simplu, aveţi grija ca
bucla dvs. să nu arate astfel încât condiţiile executării ei să se poată
îndeplini întotdeauna.

De exemplu:

for(i=1;i>0;) System.out.println(i++);

Observăm că cele două exemple precedente au fost scrie într-un


singur rând. Aceasta datorită aceleiaşi reguli care este valabilă şi
pentru toate celelalte structuri pentru control de flux. După condiţie se
poate scrie doar o singură linie de cod fără paranteze. Dacă doriţi să
scrieţi un bloc (două sau mai multe linii), trebuie să puneţi blocul
întreg între paranteze acolade.

Fiţi atenţi, fiindcă valorile buclei vor rămâne şi după executarea buclei.
Astfel, dacă scrieţi:

for(i=0;i<10;i++)
System.out.println(i);

valoarea i, după executarea buclei, va fi 10. De aceea, trebuie să


respectăm numele variabilelor standard, care se vor folosi doar cu
acest scop. De exemplu, chiar litera i. Astfel vom ştii întotdeauna că
litera respectivă este rezervată pentru buclă şi nu o vom folosi pentru
variabilele actuale. Bineînţeles că acesta este doar un sfat. Pentru
numele variabilelor în bucle sunt valabile aceleaşi reguli ca şi pentru
numele tuturor celorlalte variabile din Java.

Buclele for pot fi încuibate una în alta. În practică, veţi vedea că


programele mai mari sunt formate tocmai din bucle aflate în nişte
bucle mai mari şi care, iarăşi, se află în bucle şi mai mari. Când

© Copyright Link group 4 / 14


Curs: Core Java Programming
Modul: Controlul fluxului
Unitate: Bucla For

începeţi să creaţi singuri nişte structuri mai complexe (cu bucle


încuibate), aveţi grijă la ordinea executării lor. Nu uitaţi că programul
dvs., oricât de complex ar fi, se execută secvenţial. Dacă, în orice
moment, iniţiaţi un proces, toate celelalte procese se vor opri până
când procesul respectiv se va termina (fireşte, regula aceasta nu este
valabilă pentru programarea în timp real şi pentru programarea
multitasking):

for(int i=0;i<10;i++)
for(int u=0;u<10;u++)
System.out.println(u);

Acest exemplu, în mod clar, va scrie variabila de 100 de ori. Însă, cât
va fi variabila i în fiecare moment de executare?

Deoarece bucla i este bucla externă, iar bucla u se execută în


interiorul ei, de fiecare dată când se face o iteraţie a buclei i, se va
face şi ciclul complet al buclei u:

prima iteraţie a buclei i


prima iteraţie a buclei u
a doua iteraţie a buclei u
...
a zecea iteraţie a buclei u
a doua iteraţie a buclei i
....

şi aşa mai departe, până la ultima iteraţie a buclei i, când întregul său
ciclu se va termina.

La începutul buclei am menţionat că numărătorul buclei se "măreşte".


Aceasta nu este o regulă obligatorie. Numărătorul se poate şi micşora
sau chiar (cum am văzut în unul dintre exemplele precedente) poate
să nu existe neapărat.

for(i=10;i>0;i--) System.out.println(i);

© Copyright Link group 5 / 14


Curs: Core Java Programming
Modul: Controlul fluxului
Unitate: Bucla For

Bucla foreach

Bucla aceasta este o variaţie a buclei for, menită exlusiv lucrului cu


şiruri. Se foloseşte, în special, în listele de obiecte.

Foreach funcţionează foarte simplu (din partea utilizatorului) deoarece,


practic, nu este necesar să ştim nimic despre şirul prin care dorim să
trecem, în afară de numele lui. La iniţializare, introducem numele
şirului şi numele variabilei pentru care dorim să preia valoarea actuală
a şirului la fiecare iteraţie:

int[] arr = {1,2,3,4,5};


for(int val: arr )
System.out.println(val);

În acest exemplu, se trece prin şir şi, la fiecare iteraţie, valoarea


elementului curent se stochează în variabila val (-oare). În blocul de
comenzi se poate folosi variabila aceasta, fără a se schimba valoarea
originală conţinută în elementul curent al şirului.

Uitaţi-vă la exemplul următor:

String[] arr = {"ro?u","verde","albastru"};


System.out.println("Culorile con?inute în ?ir sunt: ");
String culori = "";
for(String culoare: arr)
{
culori += culoare + " ";
}
System.out.println(culori);

La fiecare trecere prin buclă, valoarea elementului curent se atribuie


variabilei culoare. Apoi, valoarea aceasta se adaugă la variabila culori,
împreună cu un caracter vid. La sfârşit, rezultatul va fi:

Culorile con?inute în ?ir sunt: ro?u verde albastru

După cum vedeţi, foreach operează destul de automatizat. Aceasta

© Copyright Link group 6 / 14


Curs: Core Java Programming
Modul: Controlul fluxului
Unitate: Bucla For

este bine uneori, dar uneori nu este bine, fiindcă atunci când lucrăm
cu foreach, nu gestionăm membrii şirului explicit prin indexurile lor, ci
obţinem doar valorile lor. Astfel, putem spune că foreach este bună
atunci când dorim o citire rapidă şi simplă a unui şir, dar nu şi pentru
orice intervenţii mai serioase asupra şirului.

Deşi, în exemplele de până acum, fiecare buclă foreach precedă blocul


cu paranteze acolade, şi aici este valabilă regula conform căreia nu
trebuie neapărat să existe paranteze acolade pentru o singură linie de
cod:

for(String color: arr) colors += color + " ";

Controlul de flux al buclei

Controlul de flux al buclei se poate face în câteva moduri. Primul mod


este, desigur, prin modificarea manuală a variabilei de control
(numărător).

for(int i=0;i<10;i++)
{
if(i>5) i=10;
System.out.println(i);
}

În acest exemplu, am "spus" buclei să se execute atâta timp cât


variabila i este mai mică decât 10, cu increment 1. Apoi, în bloc, ne-am
"răzgândit" şi am spus că, dacă numărătorul este mai mare decât 5
(deci, 6), numărătorul obţine valoarea 10. Fiindcă numărătorul a
obţinut valoarea prin care bucla nu mai îndeplineşte condiţii de
executare, bucla este părăsită. Soluţia aceasta va funcţiona, dar este
neîndemânatică, pentru că trebuie să cunoaştem valoarea ţintită a
numărătorului, ceea ce adesea nu va fi posibil (De ex. for(int
i=0;i<u;i++)).

Celălalt mod (modul corect) este prin folosirea cuvântului cheie Break.

© Copyright Link group 7 / 14


Curs: Core Java Programming
Modul: Controlul fluxului
Unitate: Bucla For

Am cunoscut acest cuvânt în lecţia precedentă, când am spus că


acesta opreşte necondiţionat blocul de cod:

for(int i=0;i<10;i++)
{
if(i>5) break;
System.out.println(i);
}

Prin folosirea acestui cuvânt cheie, bucla noastră nu a pierdut prea


mult din dimensiuni, dar totuşi obţine mult la dinamică, pentru că
acum nu mai trebuie să ştim valoarea finală a buclei.

for(int i=0;i<10;i++)
{
System.out.print("\n" + i + ":");
for(int u=0;u<10;u++)
{
System.out.print(u);
if(u==5)
break;
}
}

Dacă iniţiăm acest exemplu, se vor scrie zece rânduri, în care fiecare
dintre ele va conţine cifrele de la 1 la 5. Logic, pentru că de fiecare
dată când numărătorul iteraţiei buclei interioare ajunge la cinci,
aceasta se opreşte. În plus, bucla exterioară continuă să lucreze.

Însă, uneori se va întâmpla să dorim să setăm o condiţie în cursul


executării buclei şi pentru care, când se îndeplineşte, nu vom dori să
facem nici o iteraţie a buclei (fără a părăsi buclă). De exemplu, să ne
închipuim o imensă listă de oameni (câteva milioane). Toţi aceşti
oameni se află în baza de date şi noi dorim să separăm doar o anumită
grupare în care sunt doar profesori.

Să presupunem că citirea datelor despre profesia fiecărui membru al


listei durează 1 secundă, şi citirea datelor complete despre membru

© Copyright Link group 8 / 14


Curs: Core Java Programming
Modul: Controlul fluxului
Unitate: Bucla For

durează 5 secunde.

Acum să presupunem că procedura citirii subînţelege: citirea datelor


despre profesie, locuinţă, citirea numelui, citirea prenumelui... (ceea
ce, în total, durează 5 secunde). Dacă trecem prin întreaga procedură
pentru fiecare membru, vom pierde câte 5 secunde pe membru şi
aceasta înseamnă foarte multe secunde pentru toţi membrii împreună.
Pe de altă parte, ne putem uita imediat, la început, dacă membrul este
profesor (ceea ce necesită doar o secundă) şi, dacă nu este, să
preluăm imediat datele următorului membru din listă. Astfel vom
economisi 4 secunde. La o cifră de câteva milioane de membri,
aceasta reprezintă un număr imens de secunde.

Acest exemplu simplu funcţionează automat în gândirea omenească,


dar programul trebuie să aibă acest lucru accentuat explicit pentru a
gândi astfel. Această accentuare se face prin cuvântul cheie Continue
.

Aşa ar arăta pseudo-codul exemplului menţionat, cu folosirea


cuvântului cheie continue:

for(member=0;member<1000000;member++)
{
if(member!="profesor")
continue;
//CODUL IMENS CARE CITE?TE TOATE CELELALTE DATE DESPRE
MEMBRUL LISTEI
//......
}

Exemplul următor va afişa toate numerele în afara numărului cinci,


pentru că am accentuat explicit că, o dată ce apare numărul 5,
executăm comanda continue, respectiv, sărim peste această iteraţie a
buclei.

for(int i=0;i<10;i++)
{
if(i==5)

© Copyright Link group 9 / 14


Curs: Core Java Programming
Modul: Controlul fluxului
Unitate: Bucla For

continue;
System.out.print(i);
}

Exerciţiu 1

Problemă:

Avem şirul următor:

int[] arr = {1,2,-1,4,5,-1};

Cu ajutorul buclei for, trebuie să copiem acest şir în şirul şir1, unde toţi
membrii cu valoarea -1 trebuie înlocuiţi prin membrii cu valoarea zero.
Şir1 trebuie afişat apoi la ieşire.

Rezolvare:

int[] arr = {1,2,-1,4,5,-1};


int[] arr1 = new int[arr.length];
for(int i=0;i<arr.length;i++)
{
if(arr[i]==-1)
arr1[i]=0;
else
arr1[i]=arr[i];
}
System.out.println(java.util.Arrays.toString(arr1));

Exerciţiu 2

Problemă:

În aplicaţie intră şirul următor:

© Copyright Link group 10 / 14


Curs: Core Java Programming
Modul: Controlul fluxului
Unitate: Bucla For

String[][] users = { { "petru" , "petrescu" , "1111" },


{"ion","ionescu","2222"} , {"stan","ivanescu","3333"} };

Trebuie să separăm doar numele utilizatorilor şi să le stocăm într-un


şir aparte. Acest şir trebuie emis la ieşire.

Rezolvare:

String[][] users = { { "petru" , "petrescu" , "1111" },


{"ion","ionescu","2222"} , {"stan","ivanescu","3333"} };
String[] names = new String[users.length];
for(int i=0;i<users.length;i++)
names[i]=users[i][0];
System.out.println(java.util.Arrays.toString(names));

© Copyright Link group 11 / 14


Curs: Core Java Programming
Modul: Controlul fluxului
Unitate: Bucla For

CJPro_10 - Core Java Programming


1. Când folosim bucla for?
a) atunci când dorim să executăm un bloc de cod de un
anumit număr de ori
b) numai atunci când dorim să măsurăm lungimea şirului
c) numai atunci când dorim să introducem în şir un număr
predefinit de membrii
d) numai atunci când dorim să afişăm toţi membrii unui şir
2. Oare bucla for poate fi oprită, şi cum?
a) da, prin comanda break
b) nu
c) da, prin comanda continue
d) da, prin comanda switch
3. Dacă dorim să sărim peste o iteraţie a buclei for, care
cuvânt cheie folosim?
a) continue
b) break
c) repeat
d) stop
4. Corpul buclei trebuie neapărat să se afle în blocul mărginit
cu paranteze acolade?
a) Da, dacă corpul buclei are mai multe linii
b) da, în orice caz
c) corpul buclei nu trebuie să fie în blocul mărginit cu
paranteze acolade
5. Care vor fi valorile variabilelor i şi u în codul următor?
   for(int i=0;i<10;i++)
      for(int u=0;u<10;u++)
         System.out.println(u);

© Copyright Link group 12 / 14


Curs: Core Java Programming
Modul: Controlul fluxului
Unitate: Bucla For

a) niciodată nu sunt mai mari ca 10


b) uneori sunt mai mari ca 10
c) întotdeauna sunt mai mari ca 10
d) codul este greşit
6. De câte ori se va scrie valoarea u, la ieşire, după codul
următor?
  for(int i=0;i<10;i++)
      for(int u=0;u<10;u++)
         System.out.println(u);
a) 100 de ori
b) 10 ori
c) 50 de ori
d) Nici o oară
7. Dacă corpul buclei nu este mărginit prin paranteze acolade?
a) se execută doar prima linie de sub definiţia buclei
b) se execută toate liniile de sub definiţia buclei, până ce nu
se accentuează explicit că bucla se termină
c) nu se execută nicio linie a buclei
d) programul nu se interpretează, pentru că este o eroare
sintactică

© Copyright Link group 13 / 14


Curs: Core Java Programming
Modul: Controlul fluxului
Unitate: Bucla For

1. Când folosim bucla for?


a
2. Oare bucla for poate fi oprită, şi cum?
a
3. Dacă dorim să sărim peste o iteraţie a buclei for, care
cuvânt cheie folosim?
a
4. Corpul buclei trebuie neapărat să se afle în blocul mărginit
cu paranteze acolade?
a
5. Care vor fi valorile variabilelor i şi u în codul următor?
   for(int i=0;i<10;i++)
      for(int u=0;u<10;u++)
         System.out.println(u);
a
6. De câte ori se va scrie valoarea u, la ieşire, după codul
următor?
  for(int i=0;i<10;i++)
      for(int u=0;u<10;u++)
         System.out.println(u);
a
7. Dacă corpul buclei nu este mărginit prin paranteze acolade?
a

© Copyright Link group 14 / 14

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