Skip to content

Instructiunea while

Pana acum, cu if, un bloc de cod se executa o singura data daca o conditie e adevarata. Cu while, blocul se executa repetat, cat timp conditia ramane adevarata.

Sintaxa

cpp
while (conditie)
{
    Instr1; 
    Instr2;
    // ...
    InstrK;
}

iteratie = 1 singura executie a instructiunilor dintre { si }

Observatie

La fiecare iteratie, conditia se evalueaza din nou. De indata ce devine falsa, executia continua dupa }.

Exemplu pas cu pas: Afisarea numerelor de la 3 la 7

cpp
#include <iostream>
using namespace std;

int i;

int main()
{
    i = 3;
    while (i <= 7)
    {
        cout << i << " ";
        i++;
    }
    cout << "gata!" << endl;
    cout << "i este: " << i;
    return 0;
}

Afisare:

3 4 5 6 7 gata!
i este 8

Evolutia variabilelor:

Iteratieii <= 7
13adevarat
24adevarat
35adevarat
46adevarat
57adevarat
8fals

In acest exemplu s-au executat 5 iteratii (la inceputul fiecarei iteratii, i a avut valorile 3, 4, 5, 6, 7).


De la "pana cand" la "cat timp"

Cand rezolvi o problema, e natural sa gandesti in termeni de oprire:

"Fac X pana cand conditia de stop devine adevarata."

while insa lucreaza cu continuare:

"Fac X cat timp conditia de continuare este adevarata."

Transformarea e simpla — neghezi conditia de oprire:

Gandire naturalaConditia de oprireConditia while
"pana cand i > n"i > nwhile (i <= n)
"pana cand p > n"p > nwhile (p <= n)
"pana cand a > n"a > nwhile (a <= n)

Exemplu introductiv: numerele de la 1 la n

Rationament: "Afiseaza i, pana cand i depaseste n."
→ Conditia de oprire: i > n → Conditia while: i <= n

Inainte de bucla: initializam i = 1. In bucla: afisam i, apoi incrementam.

cpp
#include <iostream>
using namespace std;

int n, i;

int main()
{
    cin >> n;
    i = 1;
    while (i <= n)
    {
        cout << i << " ";
        i++;
    }
    cout << endl;
    return 0;
}

Rulare cu n = 5:

5
1 2 3 4 5

Atentie

i++ este esential — fara el, i ramane 1 si while-ul nu se opreste niciodata.


Suma primelor n numere

Problema: Citeste un numar n. Calculeaza suma 1 + 2 + ... + n.

Rationament: "Adauga i la suma, pana cand i depaseste n."
→ Conditia while: i <= n

cpp
#include <iostream>
using namespace std;

int n, i, suma;

int main()
{
    cin >> n;
    suma = 0;
    i = 1;
    while (i <= n)
    {
        suma = suma + i;
        i++;
    }
    cout << suma << endl;
    return 0;
}

Rulare cu n = 5:

5
15

Puteri ale lui 2

Problema: Citeste un numar n. Afiseaza toate puterile lui 2 mai mici sau egale cu n.

Rationament: "Afiseaza p, pana cand p depaseste n."
→ Conditia de oprire: p > n → Conditia while: p <= n

Inainte de while: p = 1 (prima putere: 2⁰ = 1). In while: afisam p, apoi p = p * 2.

cpp
#include <iostream>
using namespace std;

int n, p;

int main()
{
    cin >> n;
    p = 1;
    while (p <= n)
    {
        cout << p << " ";
        p = p * 2;
    }
    cout << endl;
    return 0;
}

Rulare cu n = 100:

100
1 2 4 8 16 32 64

Evolutia lui p pentru n = 100:

Iteratiepp <= 100Afisarep dupa executie
11adevarat12
22adevarat24
34adevarat48
48adevarat816
516adevarat1632
632adevarat3264
764adevarat64128
128fals

Sirul Fibonacci

Problema: Citeste un numar n. Afiseaza toti termenii sirului Fibonacci mai mici sau egali cu n.

Sirul Fibonacci: 1, 1, 2, 3, 5, 8, 13, 21, 34, ...
Fiecare termen e suma celor doi anteriori.

Rationament: "Afiseaza termenul curent a, pana cand a depaseste n."
→ Conditia while: a <= n

Avem doua variabile consecutive: a (termenul afisat) si b (urmatorul). La fiecare pas:

  1. Afisam a
  2. Calculam urmatoarea pereche: t = a + b, a = b, b = t
cpp
#include <iostream>
using namespace std;

int n, a, b, t;

int main()
{
    cin >> n;
    a = 1;
    b = 1;
    while (a <= n)
    {
        cout << a << " ";
        t = a + b;
        a = b;
        b = t;
    }
    cout << endl;
    return 0;
}

Rulare cu n = 20:

20
1 1 2 3 5 8 13

Evolutia variabilelor pentru n = 20:

Iteratieaba <= 20Afisarea dupab dupa
111adevarat112
212adevarat123
323adevarat235
435adevarat358
558adevarat5813
6813adevarat81321
71321adevarat132134
2134fals

Observatie

Variabila temporara t e necesara deoarece la pasul a = b pierdem valoarea veche a lui a, care e necesara pentru b = a + b. t o salveaza inainte sa fie suprascris.


Cautarea primului numar care satisface o conditie

Problema: Gaseste primul numar din intervalul [100, 200] care este impar si a carui suma a cifrelor e divizibila cu 7.

Rationament: "Inainteaza cat timp nu am gasit inca numarul si nu am depasit 200."
→ Conditia while: i <= 200 && gasit == 0

Cand numarul e gasit, setam gasit = 1 si salvam i in rezultat. i++ se executa oricum la finalul fiecarei iteratii. La urmatoarea evaluare a conditiei, gasit == 0 devine falsa si bucla se opreste.

cpp
#include <iostream>
using namespace std;

int i, sumaCif, gasit, rezultat;
int u, z, s;
int main()
{
    i = 100;
    gasit = 0;
    while (i <= 200 && gasit == 0)
    {
        u = i % 10;
        z = (i / 10) % 10;
        s = i / 100;
        sumaCif = u + z + s;
        if (sumaCif % 7 == 0 && i % 2 != 0)
        {
            gasit = 1;
            rezultat = i;
        }
        i++;
    }
    if (gasit == 0)
    {
        cout << "Nu exista" << endl;
        return 0;
    }
    cout << rezultat << endl;
    return 0;
}

Afisare:

115

Evolutia variabilelor (iteratii relevante):

Iteratieiss % 7 == 0 && impargasitrezultati dupa
11001nu0101
21012nu0102
.....................
71067s%7=0, dar 106 e par0107
.....................
161157da1115116

Observatie

La iteratia 16: s = 1+1+5 = 7, 7 % 7 == 0 si 115 e impar — conditia e indeplinita. rezultat = 115, gasit = 1, apoi i creste la 116. La urmatoarea verificare a conditiei, gasit == 0 e falsa si bucla se opreste.


Capcane frecvente

1. Bucla infinita (en. infinite loop)

Bucla infinita = o instructiune repetitiva pentru care conditia nu va fi NICIODATA falsa (de-a lungul executiei)

In exemplul de mai jos, elevul voia sa afiseze numerele de la 1 la n (unde n e un nr >= 1).

Dar, a uitat sa mai creasca i-ul. Deci, conditia 1 <= n ramane mereu ADEVARATA.

cpp
// GRESIT — i nu se modifica niciodata
i = 1;
while (i <= n)
{
    cout << i << " ";
}
cpp
// CORECT
i = 1;
while (i <= n)
{
    cout << i << " ";
    i++;
}

2. Conditie falsa de la inceput

Daca conditia este falsa, inca de prima data cand este evaluata, atunci nu se va executa nicio iteratie.

cpp
// Daca n = 0: conditia 1 <= 0 e falsa de la inceput
// Nu se afiseaza nimic
i = 1;
while (i <= n)
{
    cout << i << " ";
    i++;
}