Cicluri
Ciclurile sunt construcții de control care permit, în funcție de anumite condiții, executarea unei acțiuni de mai multe ori. În C# există următoarele tipuri de cicluri:
- for
- foreach
- while
- do...while
Ciclu for
Ciclul for are următoarea definiție formală:
for ([acțiuni înainte de execuția ciclului]; [condiție]; [acțiuni după execuție])
{
// acțiuni
}
Declarația ciclului for constă din trei părți. Prima parte a declarației ciclului - unele acțiuni care se execută o singură dată înainte de execuția ciclului. De obicei, aici se definesc variabilele care vor fi utilizate în ciclu.
A doua parte - condiția la care va rula ciclul. Atâta timp cât condiția este adevărată, ciclul va rula.
Și a treia parte - unele acțiuni care se execută după terminarea blocului ciclului. Aceste acțiuni se execută de fiecare dată la terminarea blocului ciclului.
După declarația ciclului, în acolade se plasează acțiunile ciclului.
Să luăm în considerare un ciclu for standard:
for (int i = 1; i < 4; i++)
{
Console.WriteLine(i);
}
Aici prima parte a declarației ciclului - int i = 1 - creează și inițializează variabila i.
A doua parte - condiția i < 4. Adică, atâta timp cât variabila i este mai mică decât 4, ciclul se va executa.
Și a treia parte - acțiunile care se execută după terminarea acțiunilor din blocul ciclului - incrementarea variabilei i cu o unitate.
Întregul proces al ciclului poate fi prezentat astfel:
- Se definește variabila int i = 1
- Se verifică condiția i < 4. Este adevărată (deoarece 1 este mai mic decât 4), deci se execută blocul ciclului, și anume instrucțiunea Console.WriteLine(i), care afișează pe consolă valoarea variabilei i
- Blocul ciclului a terminat execuția, deci se execută a treia parte a declarației ciclului - i++. După aceasta, variabila i va fi egală cu 2
- Se verifică din nou condiția i < 4. Este adevărată (deoarece 2 este mai mic decât 4), deci se execută din nou blocul ciclului - Console.WriteLine(i)
- Blocul ciclului a terminat execuția, deci se execută din nou expresia i++. După aceasta, variabila i va fi egală cu 3
- Se verifică din nou condiția i < 4. Este adevărată (deoarece 3 este mai mic decât 4), deci se execută din nou blocul ciclului - Console.WriteLine(i)
- Blocul ciclului a terminat execuția, deci se execută din nou expresia i++. După aceasta, variabila i va fi egală cu 4
- Se verifică din nou condiția i < 4. Acum returnează false, deoarece valoarea variabilei i NU este mai mică decât 4, deci ciclul se încheie. Se execută restul programului, care urmează după ciclu
În final, blocul ciclului se va executa de 3 ori, până când valoarea i devine egală cu 4. Și de fiecare dată această valoare va fi incrementată cu 1. O singură execuție a blocului ciclului se numește iterație. Astfel, aici ciclul va efectua trei iterații. Rezultatul programului:
1
2
3
Dacă blocul ciclului for conține o singură instrucțiune, atunci putem să-l scurtăm, eliminând acoladele:
for (int i = 1; i < 4; i++)
Console.WriteLine(i);
// sau așa
for (int i = 1; i < 4; i++) Console.WriteLine(i);
Nu este obligatoriu ca în prima parte a ciclului să declarăm variabila, iar în a treia parte să îi schimbăm valoarea - acestea pot fi orice acțiuni. De exemplu:
var i = 1;
for (Console.WriteLine("Începutul execuției ciclului"); i < 4; Console.WriteLine($"i = {i}"))
{
i++;
}
Aici din nou ciclul se execută atâta timp cât variabila i este mai mică de 4, doar că incrementarea variabilei i are loc în blocul ciclului. Ieșirea pe consolă a acestui program:
Începutul execuției ciclului
i = 2
i = 3
i = 4
Nu este obligatoriu să specificăm toate condițiile în declarația ciclului. De exemplu, putem scrie astfel:
int i = 1;
for (; ;)
{
Console.WriteLine($"i = {i}");
i++;
}
Declarația formală a ciclului a rămas aceeași, doar că acum blocurile din declarație sunt goale: for (; ;). Nu avem o variabilă inițializată, nu avem o condiție, deci ciclul va rula la infinit - ciclu infinit.
Putem de asemenea să omitem unele blocuri:
int i = 1;
for (; i < 4;)
{
Console.WriteLine($"i = {i}");
i++;
}
Acest exemplu este echivalent cu primul exemplu: avem de asemenea o variabilă contor, doar că este definită în afara ciclului. Avem o condiție de execuție a ciclului. Și avem incrementarea variabilei deja în blocul for.
De asemenea, putem defini mai multe variabile în declarația ciclului:
for (int i = 1, j = 1; i < 10; i++, j++)
Console.WriteLine($"{i * j}");
Aici, în prima parte a declarației ciclului, sunt definite două variabile: i și j. Ciclul se execută până când i va fi egală cu 10. După fiecare iterație, variabilele i și j sunt incrementate cu o unitate. Ieșirea pe consolă a programului:
1
4
9
16
25
36
49
64
81
Ciclu do..while
În ciclul do, mai întâi se execută codul ciclului, apoi se verifică condiția în instrucțiunea while. Și atâta timp cât această condiție este adevărată, ciclul se repetă.
do
{
acțiuni ale ciclului
}
while (condiție)
De exemplu:
int i = 6;
do
{
Console.WriteLine(i);
i--;
}
while (i > 0);
Aici codul ciclului se va executa de 6 ori, până când i devine egal cu zero. Dar este important de menționat că ciclul do garantează cel puțin o execuție a acțiunilor, chiar dacă condiția din instrucțiunea while nu este adevărată. Adică putem scrie:
int i = -1;
do
{
Console.WriteLine(i);
i--;
}
while (i > 0);
Deși variabila i este mai mică decât 0, ciclul se va executa totuși o dată.
Ciclu while
Spre deosebire de ciclul do, ciclul while verifică imediat veridicitatea unei condiții și, dacă condiția este adevărată, codul ciclului se execută:
while (condiție)
{
acțiuni ale ciclului
}
De exemplu:
int i = 6;
while (i > 0)
{
Console.WriteLine(i);
i--;
}
Ciclu foreach
Ciclul foreach este destinat pentru parcurgerea unui set sau colecții de elemente. Definiția sa generală:
foreach (tip_date variabilă in colecție)
{
// acțiuni ale ciclului
}
După operatorul foreach, în paranteze, mai întâi se face definiția variabilei. Apoi cuvântul cheie in și ulterior colecția, ale cărei elemente trebuie parcurse.
La execuție, ciclul parcurge secvențial elementele colecției și le plasează în variabilă, și astfel, în blocul ciclului putem efectua unele acțiuni cu ele.
De exemplu, să luăm un șir. Un șir, în esență, este o colecție de caractere. Și .NET permite parcurgerea tuturor elementelor șirului - a caracterelor sale, folosind ciclul foreach.
foreach (char c in "Tom")
{
Console.WriteLine(c);
}
Aici ciclul foreach parcurge toate caracterele șirului "Tom" și plasează fiecare caracter în variabila de tip char c. În blocul ciclului, valoarea variabilei c este afișată pe consolă. Deoarece șirul "Tom" are trei caractere, ciclul se va executa de trei ori. Ieșirea pe consolă a programului:
T
o
m
Este important de menționat că variabila definită în declarația ciclului trebuie să corespundă tipului de date al elementelor colecției parcurse. Astfel, elementele șirului - sunt valori de tip char - caractere. De aceea, variabila c este de tip char. Totuși, în realitate, nu este întotdeauna evident ce tip reprezintă elementele colecției. În acest caz, putem defini variabila folosind operatorul var:
foreach (var c in "Tom")
{
Console.WriteLine(c);
}
În continuare, vom analiza mai detaliat ce sunt colecțiile în .NET și ce colecții pot fi parcurse folosind ciclul foreach.
Operatorii continue și break
Uneori apare situația în care trebuie să ieșim din ciclu fără a aștepta terminarea acestuia. În acest caz, putem folosi operatorul break.
De exemplu:
for (int i = 0; i < 9; i++)
{
if (i == 5)
break;
Console.WriteLine(i);
}
Deși în condiția ciclului se spune că ciclul va rula până când contorul i va atinge valoarea 9, în realitate ciclul se va executa de 5 ori. Deoarece când contorul i atinge valoarea 5, se va executa operatorul break și ciclul se va încheia.
0
1
2
3
4
Acum să ne propunem altă sarcină. Ce se întâmplă dacă dorim ca la verificare ciclul să nu se încheie, ci doar să sară peste iterația curentă. Pentru aceasta putem folosi operatorul continue:
for (int i = 0; i < 9; i++)
{
if (i == 5)
continue;
Console.WriteLine(i);
}
În acest caz, ciclul, când ajunge la numărul 5, care nu satisface condiția de verificare, doar va sări peste acest număr și va trece la iterația următoare:
0
1
2
3
4
6
7
8
Este important de menționat că operatorii break și continue pot fi aplicați în orice tip de ciclu.
Cicluri imbricate
Un ciclu poate fi imbricat într-alt ciclu. De exemplu:
for (int i = 1; i < 10; i++)
{
for (int j = 1; j < 10; j++)
{
Console.Write($"{i * j} \t");
}
Console.WriteLine();
}
În acest caz, ciclul for (int i = 1; i < 10; i++) se execută de 9 ori, adică are 9 iterații. Dar în cadrul fiecărei iterații se execută de 9 ori ciclul imbricat for (int j = 1; j < 10; j++). În final, acest program va afișa tabla înmulțirii.