Ce vei învăța astăzi?
După această lecție, vei stăpâni complet ambele tipuri de bucle cu număr necunoscut de pași și vei ști când să alegi fiecare dintre ele.
Bucla CÂT TIMP (while)
Test INIȚIAL: verifică condiția înainte de a intra în buclă
- Bucla poate să NU se execute deloc
- Potrivită pentru validări și citiri controlate
- Folosită când nu știi dacă trebuie să execuți
Sintaxa: ┌ cât timp (condiție) execută ... └■
Bucla REPETĂ...PÂNĂ CÂND (do...while)
Test FINAL: verifică condiția după ce a executat bucla
- Bucla se execută CEL PUȚIN o dată
- Potrivită pentru meniuri și procesări inițiale
- Folosită când știi că trebuie să execuți cel puțin o dată
Sintaxa: ┌ repetă ... └■ până când (condiție)
1. Bucla CÂT TIMP (while) - Test Inițial
Verifică ÎNAINTE de executare
Doar dacă condiția e adevărată
Definiție: Instrucțiunea while este o structură repetitivă cu număr necunoscut de pași și test inițial.
Mod de execuție:
Adevărat sau Fals?
Exemplu practic: Suma primelor n numere
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
int S = 0;
int i = 1;
while(i <= n) {
S += i;
i++;
}
cout << S << endl;
return 0;
}
Rulați programul analizând rezultatul pentru diverse valori ale lui n, inclusiv 0.
Dacă condiția este falsă din start, instrucțiunea NU se execută deloc.
Instrucțiunea poate fi orice fel de instrucțiune, dar una singură. Pentru mai multe instrucțiuni, folosește instrucțiunea compusă (bloc cu { }).
Este necesar ca cel puțin o variabilă care apare în condiție să-și modifice valoarea în instrucțiune. Altfel se obține o buclă infinită.
Exercițiu: Completează bucla while pentru validare
Bancă de cuvinte:
2. Bucla REPETĂ...PÂNĂ CÂND (do...while) - Test Final
Mai întâi execută
Verifică DUPĂ executare
Definiție: Instrucțiunea do...while este o structură repetitivă cu număr necunoscut de pași și test final.
Mod de execuție:
Adevărat sau Fals?
Exemplu practic: Suma primelor n numere (varianta)
Diferență esențială: Bucla se execută cel puțin o dată, chiar și pentru n=0!
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
int S = 0;
int i = 1;
do {
S += i;
i++;
}
while(i <= n);
cout << S << endl;
return 0;
}
Rulați programul analizând rezultatul pentru diverse valori ale lui n, inclusiv 0. Observați diferența față de while!
Chiar dacă condiția este falsă din start, instrucțiunea se execută exact o dată.
La fel ca while, instrucțiunea poate fi orice fel de instrucțiune, dar una singură. Pentru mai multe instrucțiuni, folosește blocul.
La fel ca while, este necesar ca cel puțin o variabilă din condiție să se modifice în corpul buclei.
În do...while continuăm atâta timp cât condiția este adevărată. Atenție la inversarea logicii!
Exercițiu: Completează bucla do...while pentru meniu
Bancă de cuvinte:
Comparație detaliată: CÂT TIMP vs REPETĂ...PÂNĂ CÂND
| Caracteristică | CÂT TIMP (while) | REPETĂ...PÂNĂ CÂND (do...while) |
|---|---|---|
| Tip test | Test INIȚIAL | Test FINAL |
| Execuție minimă | 0 ori (poate să nu se execute deloc) | 1 dată (se execută întotdeauna cel puțin o dată) |
| Când să folosești | Validări, citiri până la marker, când nu ești sigur că trebuie să execuți | Meniuri, procesări care trebuie să înceapă cel puțin o dată |
| Sintaxă Pseudocod | ┌ cât timp (cond) execută ... └■ |
┌ repetă ... └■ până când (cond) |
| Sintaxă C++ | while(cond) { ... } |
do { ... } while(cond); |
| Logică condiție | Continuă CÂT TIMP condiția este adevărată | Repetă PÂNĂ CÂND condiția devine adevărată (oprește când e adevărată!) |
Test de înțelegere: Care tip de buclă?
Pentru fiecare situație, alege tipul de buclă mai potrivit:
Atenție la erorile comune!
1. Bucle infinite - uitarea de actualizare
Problemă: i rămâne întotdeauna 1, condiția i ≤ 5 este întotdeauna adevărată!
2. Confuzia logicii condiției
| While | Do...While |
|---|---|
while(x != 0) { ... } |
do { ... } while(x == 0); |
| Continuă cât timp x ≠ 0 | Repetă până când x ≠ 0 (oprește când x ≠ 0) |
Regulă: În do...while condiția este inversată față de while pentru același efect!
Best Practices pentru ambele bucle:
PbInfo #1220 - Suma cifrelor
Problemă perfectă pentru bucla while
Enunț:
Cerință: Să se scrie un program care citește un număr natural n și afișează suma cifrelor sale.
Date de intrare:
Programul citește de la tastatură numărul n.
Date de ieșire:
Programul va afișa pe ecran suma cifrelor lui n.
Exemplu:
Intrare:
12345
Ieșire:
15
Explicație: 1 + 2 + 3 + 4 + 5 = 15
Cum gândim soluția:
- Citim numărul n
- Pregătim o variabilă
suma ← 0 - Cât timp
n > 0(test inițial - perfect pentru while):- Extragem ultima cifră:
cifra ← n % 10 - Adăugăm cifra la suma
- Eliminăm ultima cifră:
n ← n / 10(actualizare importantă!)
- Extragem ultima cifră:
- Afișăm suma
Urmărește pentru n=12345:
De ce while și nu do...while?
Pentru n=0 (număr cu o singură cifră, cifra 0):
- While: condiția
0 > 0este falsă → bucla nu se execută → suma=0 (corect!) - Do...while: s-ar executa cel puțin o dată → ar calcula greșit!
Scrie soluția în C++:
Soluție corectă:
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
int suma = 0;
while (n > 0) {
suma = suma + (n % 10); // adaugă ultima cifră
n = n / 10; // elimină ultima cifră (ACTUALIZARE!)
}
cout << suma;
return 0;
}
Ce am învățat din această problemă:
- CÂT TIMP perfect pentru număr necunoscut de cifre
- Actualizare obligatorie:
n = n / 10modifică variabila din condiție - Condiția corectă:
n > 0- când n devine 0, am terminat - Test inițial important: pentru n=0, bucla nu se execută (corect!)
Problemă cu do...while - Meniu interactiv
Exemplu perfect pentru do...while
Enunț:
Cerință: Să se scrie un program care afișează un meniu și execută operații până când utilizatorul alege să iasă.
Date de intrare:
Programul citește opțiuni de la tastatură până când se introduce 3.
Date de ieșire:
Programul afișează rezultatele operațiilor alese.
Exemplu de rulare:
Meniu: 1. Salut 2. La revedere 3. Ieșire Alege: 1 Salut! Meniu: 1. Salut 2. La revedere 3. Ieșire Alege: 2 La revedere! Meniu: 1. Salut 2. La revedere 3. Ieșire Alege: 3 Program terminat.
Cum gândim soluția:
- Pregătim o variabilă
optiune ← 0 - Folosim do...while (test final - perfect pentru meniu):
- Afișăm meniul (trebuie afișat cel puțin o dată)
- Citim opțiunea
- Executăm operația corespunzătoare
- Continuăm până când
optiune = 3
De ce do...while și nu while?
Pentru că întotdeauna vrem să afișăm meniul cel puțin o dată, înainte de a întreba utilizatorul ce vrea să facă!
Scrie soluția în C++:
Soluție corectă:
#include <iostream>
using namespace std;
int main() {
int optiune;
do {
// Afișăm meniul (se execută CEL PUȚIN o dată)
cout << "Meniu:" << endl;
cout << "1. Salut" << endl;
cout << "2. La revedere" << endl;
cout << "3. Ieșire" << endl;
cout << "Alege: ";
cin >> optiune;
// Executăm operația corespunzătoare
if (optiune == 1) {
cout << "Salut!" << endl;
} else if (optiune == 2) {
cout << "La revedere!" << endl;
} else if (optiune == 3) {
cout << "Program terminat." << endl;
} else {
cout << "Opțiune invalidă!" << endl;
}
cout << endl; // linie goală pentru claritate
} while (optiune != 3); // TEST FINAL: continuă până când optiunea este 3
return 0;
}
Puncte cheie importante:
- do...while perfect pentru meniuri - afișează întotdeauna meniul cel puțin o dată
- Condiția inversată:
while(optiune != 3)- continuă atâta timp cât nu am ales ieșirea - Actualizare în buclă: citirea opțiunii modifică variabila din condiție
- Validare input: tratăm și cazul opțiunii invalide
Transformare Pseudocod → C++
Exercițiu de traducere pentru fixare
Pseudocod dat (numara cifrele pare ale lui n):
Ce face acest algoritm? Numără câte cifre pare are un număr.
Exemplu pentru n=246813: 2, 4, 6, 8 → 4 cifre pare
Transformă în C++ folosind while:
Soluție corectă:
#include <iostream>
using namespace std;
int main() {
int n, numarPare = 0, cifra;
cin >> n;
while (n > 0) {
cifra = n % 10; // extragem ultima cifră
if (cifra % 2 == 0) { // verificăm dacă este pară
numarPare++; // incrementăm contorul
}
n = n / 10; // eliminăm ultima cifră (ACTUALIZARE!)
}
cout << numarPare;
return 0;
}
Observații importante pentru transformări Pseudocod → C++:
| Pseudocod | C++ |
|---|---|
┌ cât timp ... execută |
while (...) { |
└■ |
} |
← |
= |
% (rest) |
% (la fel) |
scrie |
cout << |
citește |
cin >> |
Exercițiul Practic: Comparație între while și do...while
Sarcini de lucru
Completează următoarele sarcini pentru a-ți consolida înțelegerea diferențelor dintre cele două tipuri de bucle
Sarcina 1: Analiză comportament pentru n=0
Avem două algoritmi identici, unul cu while și unul cu do...while:
Algoritmul A (while):
Algoritmul B (do...while):
Soluție pentru Sarcina 1:
Analiza pentru n=0:
- Algoritmul A (while):
• Condiția:i ≤ n→1 ≤ 0→ FALS
• Bucla nu se execută deloc
• S rămâne 0 → afișează 0 (corect!) - Algoritmul B (do...while):
• Bucla se execută cel puțin o dată
• Adaugă 1 la S → S devine 1
• Incrementează i → i devine 2
• Verifică condiția:i > n→2 > 0→ ADEVĂRAT
• Afișează 1 (greșit! suma primelor 0 numere este 0) - Concluzie: Algoritmul A (while) este corect pentru această problemă!
Sarcina 2: Scriere algoritm cu do...while
Cerință: "Scrieți un algoritm care cere utilizatorului să ghicească un număr secret (7). Utilizatorul introduce numere până când ghicește corect. Afișează de câte încercări a avut nevoie."
Exemplu de execuție:
Ghicește numărul secret: 3 Mai încearcă! Ghicește numărul secret: 10 Mai încearcă! Ghicește numărul secret: 7 Corect! Ai ghicit din 3 încercări.
Soluție pentru Sarcina 2:
ALGORITMUL GhicesteNumar
VARIABILE
numarSecret, incercare, contor: întreg
ÎNCEPUT
numarSecret ← 7
contor ← 0
REPETĂ
contor ← contor + 1
SCRIE "Ghicește numărul secret: "
CITESTE incercare
DACĂ incercare ≠ numarSecret ATUNCI
SCRIE "Mai încearcă!"
SFÂRȘIT DACĂ
PÂNĂ CÂND incercare = numarSecret
SCRIE "Corect! Ai ghicit din ", contor, " încercări."
SFÂRȘIT
De ce do...while este perfect aici:
- Trebuie să cerem cel puțin o încercare (chiar dacă ar ghici din prima)
- Contorul începe de la 0 și crește în buclă
- Condiția inversată: continuă până când încercarea = numărul secret
- Perfect pentru jocuri și meniuri interactive
Sarcina 3: Conversie while ↔ do...while
Cerință: Transformă următorul algoritm while în echivalentul său do...while:
Soluție pentru Sarcina 3:
Reguli de conversie while ↔ do...while:
| While | Do...While | Explicație |
|---|---|---|
while(x != 0) |
do ... while(x == 0) |
Condiția se inversează! |
| Continuă cât timp condiția e adevărată | Repetă până când condiția devine adevărată | Logică diferită |
| Poate să nu se execute deloc | Se execută cel puțin o dată | Comportament diferit pentru x=0 inițial |