break, continue și ieșirea din bucle
Cum ieși dintr-o buclă mai devreme, ce face break într-o buclă imbricată și când e mai bine să nu le folosești deloc.
break
break oprește bucla imediat și trece la instrucțiunea de după ea.
for (int i = 1; i <= n; i++) {
if (v[i] == x) {
cout << "găsit pe poziția " << i;
break;
}
}Fără break, bucla ar continua degeaba până la n. Iar dacă x apare de mai multe ori, ar afișa fiecare apariție.
continue
continue sare peste restul corpului și trece direct la pasul următor al buclei.
for (int i = 1; i <= n; i++) {
if (v[i] < 0) continue; // sar peste negative
suma += v[i];
}Același efect îl obții scriind condiția inversă:
for (int i = 1; i <= n; i++)
if (v[i] >= 0)
suma += v[i];A doua variantă este mai scurtă și mai limpede. continue e util când ai mai multe condiții de eliminat la început și nu vrei să indentezi tot corpul de trei ori.
Atenție la continue într-un while: dacă modificarea contorului este la sfârșitul corpului, continue sare peste ea și bucla devine infinită.
int i = 0;
while (i < n) {
if (v[i] < 0) continue; // i nu se mai incrementează niciodată
suma += v[i];
i++;
}Într-un for, pasul se execută oricum, deci problema nu apare.
break în bucle imbricate
break iese numai din bucla în care se află, nu din toate.
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if (a[i][j] == x) {
gasit = true;
break; // iese doar din bucla lui j
}
}
}Bucla exterioară continuă. Dacă vrei să te oprești de tot, ai nevoie de un indicator testat și în condiția exterioară:
bool gasit = false;
for (int i = 1; i <= n && !gasit; i++)
for (int j = 1; j <= m && !gasit; j++)
if (a[i][j] == x) {
gasit = true;
linia = i;
coloana = j;
}Aici nu mai e nevoie de niciun break, pentru că oprirea o fac condițiile buclelor. Majoritatea profesorilor preferă varianta aceasta, fiindcă vezi din antet când se oprește bucla, fără să cauți prin corp.
Când merită și când nu
break e potrivit când ai găsit ce căutai și restul buclei nu mai are rost.
break devine o problemă când îl folosești ca să ieși din mijlocul unui corp lung, de la mai multe niveluri de indentare. Atunci nu se mai vede din antet unde se termină bucla, iar la corectare asta contează.
La bac, pe hârtie, un algoritm cu condiție compusă în antet se urmărește mai ușor decât unul cu break-uri împrăștiate. În pseudocod nici nu există break. Așa că, dacă transcrii un algoritm din C++ în pseudocod, trebuie oricum să-l rescrii cu indicator.
Un exemplu complet
Se citește un număr natural n > 1. Să se afișeze cel mai mic divizor al său mai mare decât 1.
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
int d = 2;
while (n % d != 0)
d++;
cout << d;
return 0;
}Nu are nevoie nici de break, nici de o limită superioară. Bucla se oprește sigur, pentru că în cel mai rău caz d ajunge la n, iar n % n este 0. Dacă răspunsul este chiar n, atunci n este prim.
Exemplul arată că de multe ori break nu e necesar. Dacă poți scrie condiția de oprire în antet, scrie-o acolo.
De reținut
breakoprește bucla,continuesare la pasul următor.breakiese dintr-un singur nivel de imbricare.continueîntr-unwhilepoate sări peste incrementare, iar bucla devine infinită.- Condiția compusă în antet este de obicei mai limpede decât
breakîn corp. - În pseudocod nu există
break; algoritmul se scrie cu indicator.