Curs C++ | Sectiunea 9 – Loops

 

Vom incepe aceasta sectiune cu analiza unui algoritm simplu. Acesta are ca scop gasirea maximului dintre 2 numere. Codul va fi explicat prin comentarii mai jos.

/* Gasirea maximului dintre 2 numere */

#include <iostream>
using namespace std;

int main() {
/* declaram 2 variabile de tip int */
int number1, number2;

/* declaram o variabila ce va stoca maximul */
int max;

/* citim cele 2 numere de la tastatura */
cin >> number1;
cin >> number2;

/* alegem unul din cele 2 numere si presupunem ca este maxim */
max = number1;

/* verificam daca este intr-adevar maximul */
if (number2 > max)
max = number2;

/* afisam rezulatul */
cout << "Maximul este " << max << endl;

/* terminam programul */
return 0;
}

Acum sa ne gandim, daca ne dorim sa gasim maximul dintre 3 numere. Sectiunea de cod corespunzatoare ar arata in felul urmator:

cin >> number1;
cin >> number2;
cin >> number3;

max = number1;

if (number2 > max)
max = number2;

if (number3 > max)
max = number3;

cout << "Maximul este " << max << endl;

❓ Inca putem spune ca nu este un pogram atat de complex. Am putea sa gasim maximul si dintre 4 numere, si dintre 5 dar ce am face daca am avea de cautat maximul dintre 100 de numere, sau dintre 1000?

  • am avea nevoie sa declaram sute de variabile de tip int si in acelasi timp sa si citim valori pentru ele
  • ar trebui sa folosim sute de instructiuni conditionate

 

Pseudo-cod

💡 Sa ignoram pentru moment limbajul C++ si sa incercam sa gasim o solutie. Altfel spus, sa incercam sa scriem un algoritm corespunzator problemei noastre.

❗ Scriem acest algoritm intr-un mod care nu este neaparat legat de un anumit limbaj de programare (nu poate fi compilat sau executat), dar este formal, concis si citibil. Acest mod de scriere poarta numele de pseudo-cod.

max = -999999999; 
read number
if(number == -1)
print max
next stop;
if(number > max) max = number
go to 2

Pentru inceput, setam variabila noastra max ca fiind un numar foarte mic, mai mic decat orice am introduce. Apoi, presupunem ca nu stim de la inceput cate numere va introduce utilizatorul de la tastatura.

Poate introduce si o infinitate de numere asa ca setam un punct de stop. Acel punct de stop de va realiza prin introducerea de catre utilizator a valorii -1. Bineinteles, puteam alege orice valoare. In cazul in care valoarea nu este -1, programul o compara cu maximul nostru anterior si trece la pasul initial,  de citire a altei valori.

Trucul, daca putem spune asa, consta in a presupune ca orice parte din cod este executata mai mult de o singura data, mai exact, de cate ori dorim.

💡 A executa o parte de cod mai mult de o singura data se numeste bucla (loop). In exemplul nostru pasii 2 – 7 reprezina o bucla. Acum ca stim acest lucru putem sa analizam si in cadrul C++ cum sa folosim aceste bucle.

 

While

Aceasta bucla s-ar traduce in felul urmator. Cat timp ceva este adevarat, atunci faci asta. Sintaxa generala este urmatoarea:

while(conditional_expression) 
statement;

Am putea spune ca intr-o oarecare masura seamana cu if, ceea ce este adevarat. In cazul in care conditia este indeplinita (true), se executa instructiunea. Diferenta este ca acea instructiune se va executa de o infinitate de ori sau pana cand conditia nu va mai fi indeplinita (false).

while(conditional_expression) {
statement_1;
statement_2;
:
:
statement_n;
}

Observam urmatoarele lucruri:

  • daca ne dorim sa executam mai mult de o instructiune, trebuie sa folosim un block – intre acolade
  • instructiunile din interiorul unei bucle se numesc corpul buclei (loop’s body)
  • daca inca de la inceput conditia este falsa, corpul nu este executat nici macar o data
  • corpul buclei trebuie sa fie capabil sa modifice valoarea conditiei, altfel bucla noastra va merge la infinit

Un exemplu de bucla infinita ar putea arata astfel:

while(1) {
cout << "Sunt blocat aici" << endl;
}

💡 Din moment ce am lamurit si acest aspect, sa ne intoarcem la problema noastra de la inceput 🙂 . O singura remarca inainte de asta. Putem combina 2 procese diferite, si anume: declararea unei variabile cu asignarea unei valorii in acelasi timp.

❗ Realizam acest lucru adaugand semnul egal=” urmat de expresia a carei valori este asignata variabilei. Acest proces poarta numele de initializare.

float PI = 3.1415;
int R = 10;
double surface = 2.0 * PI * R;

Odata lamurit si acest lucru, sa aruncam o privire pe codul nostru final, implementat conform celor discutate:

#include <iostream>

using namespace std;

int main() {
/* variabila ce stocheaza ultima valoare citita */
int number;
/* citim prima valoare */
cin >> number;
/* presupunem ca prima valoare citita este maxima */
int max = number;
/* daca variabila nu este egala cu -1 se executa corpul buclei */
while (number != -1) {
/* comparam valoarea citita cu maximul */
if (number > max)
/* in caz afiramitv rescriem max cu noua valoare */
max = number;
/* citim urmatorul numar de la tastatura */
cin >> number;
}
/* afisam rezultatul */
cout << "Cel mai mare numar este " << max << endl;
/* terminam programul */
return 0;
}

 

Do While

do
statement;

while(condition);

do {
statement_1;
statement_2;
:
:
statement_n;
} while(condition);

Este foarte asemanatoare cu bucla while discutata anterior, singurele diferente sunt urmatoarele:

  • conditia este verificata la finalul executiei corpului buclei
  • block-ul de cod este executat cel putin o data

Acelasi program al nostru de cautat maximul, folosind do while arata astfel:

#include <iostream>

using namespace std;

int main() {
int number;
int max = -100000;

do {
cin >> number;
if (number > max)
max = number;
} while (number != -1);

cout << "Maximul este " << max << endl;

return 0;
}

Avantajul in acest caz particular este ca citim macar o data un numar, ceea ce are sens pentru codul nostru.

 

For

💡 Ultima forma in care putem crea o bucla in C++ apare de la ideea ca uneori este mai important sa numaram iteratiile unei bucle decat sa verificam o conditie de repetitie.

Sa facem urmatorul exercitiu de imaginatie. Avem nevoie un block de instructiuni sa fie executat de 100 de ori. O solutie folosind while ar arata de felul urmator:

int i; 
i = 0;
while (i < 100) {
/* block de instructiuni */
i++;
}

Pe baza acestui exemplu observam 3 elemente distincte:

  • initializarea contorului
  • verificarea conditiei
  • modificarea contorului

Folosind aceste 3 elemente putem sa ne construim si noua noastra bucla, for:

for (initializare; verificare; modificare) {/*block de cod*/}

int i;
for(i = 0; i < 100; i++)
{
/*block de cod*/
}

//Putem declara i chiar in interior
for(int i = 0; i < 100; i++)
{
/*block de cod*/
}

Un caz mai special al acestei bucle este urmatorul:

for( ; ; ) {
/* block de cod */
}

In cazul in care omitem toate cele 3 componente, compilatorul presupune ca este 1 acolo. Ca rezultat, bucla va merge la infinit deoarece conditia este mereu adevarata si nu poate fi schimbata starea acesteia.

 

Break & Continue

Pana acum am tratat corpul unei bucle ca fiind o serie de instructiuni indivizibila si inseparabila ce se executa complet la fiecare iteratie. Cu toate acestea, pot aparea urmatoarele probleme:

  • exista posibilitatea sa nu fie nevoie sa executam bucla complet asa ca ar trebui sa o oprim
  • exista posibilitatea sa trebuiasca sa trecem la verificarea conditiei fara executarea completa a iteratiei curente

❗ C++ ne pune la dispozitie urmatoarele 2 instructiuni (keywords):

  • break – iese din bucla imediat fara verificarea conditiei iar programul sare la cea mai apropiata instructiune, dupa bucla
  • continue – se comporta ca si cum programul a ajuns la finalul corpului buclei iar conditia este verificata
//Break
for (;;) {
cin >> number;
if (number == -1)
break;
counter++;
}

//Continue
do {
cin >> number;
if(number == -1)
continue;
} while (number != -1);

De remarcat, singurul mod de a intrerupe bucla for (;;) este prin break, deoarece nu avem alta conditie de oprire.

Aici se termina si aceasta sectiune. Daca aveti intrebari suplimentare puteti folosi informatiile de aici 🙂 .

➡ Sectiunea anterioara:Curs C++ | Sectiunea 8 – Noi tipuri de date

➡ Sectiunea urmatoare:Curs C++ | Sectiunea 10 – Algebra Booleana

You may also like...