break, continue și goto în C

break iese din buclă, continue trece la repetarea următoare, iar goto sare la o etichetă, folosit în C mai ales pentru curățenie la erori.

Sintaxă
break;      // iese din bucla sau din switch-ul curent
continue;   // sare la următoarea repetare
goto eticheta;
eticheta:

Ce face break, continue și goto

break oprește imediat bucla (sau switch-ul) în care se află și continuă cu codul de după ea. Într-o buclă în altă buclă, iese doar din cea interioară.

continue sare peste restul corpului și trece la repetarea următoare. Într-un for, pasul (i++) se execută în continuare.

goto eticheta; sare la o etichetă din aceeași funcție. În cod obișnuit se evită, pentru că face programul greu de urmărit. În C are totuși o utilizare acceptată: ieșirea dintr-o funcție cu eliberarea resurselor (fișiere, memorie) dintr-un singur loc, sau ieșirea din mai multe bucle deodată.

Exemple

Exemplul 1: break: primul elev cu nota 10

#include <stdio.h>

int main(void) {
    const char *elevi[] = {"Ana", "Mihai", "Ioana", "Radu"};
    int note[] = {9, 8, 10, 10};
    for (int i = 0; i < 4; i++) {
        if (note[i] == 10) {
            printf("Primul cu 10: %s\n", elevi[i]);
            break;
        }
    }
    return 0;
}

Rezultat

Primul cu 10: Ioana

Exemplul 2: continue: sare peste produsele fără stoc

#include <stdio.h>

int main(void) {
    const char *produse[] = {"mere", "pere", "prune", "nuci"};
    int stoc[] = {12, 0, 5, 0};
    for (int i = 0; i < 4; i++) {
        if (stoc[i] == 0) {
            continue;
        }
        printf("%s: %d kg\n", produse[i], stoc[i]);
    }
    return 0;
}

Rezultat

mere: 12 kg
prune: 5 kg

Exemplul 3: goto pentru curățenie la eroare

Dacă a doua alocare eșuează, codul sare la eticheta care eliberează ce s-a alocat deja. Așa eliberarea stă într-un singur loc. Aici ambele alocări reușesc.

#include <stdio.h>
#include <stdlib.h>

int proceseaza(void) {
    int rezultat = -1;
    int *note = malloc(100 * sizeof *note);
    if (!note) goto final;
    double *medii = malloc(100 * sizeof *medii);
    if (!medii) goto elibereaza_note;

    note[0] = 9;
    medii[0] = 9.5;
    printf("Date procesate: %d, %.1f\n", note[0], medii[0]);
    rezultat = 0;

    free(medii);
elibereaza_note:
    free(note);
final:
    return rezultat;
}

int main(void) {
    printf("cod: %d\n", proceseaza());
    return 0;
}

Rezultat

Date procesate: 9, 9.5
cod: 0

Greșeli frecvente

  • Te aștepți ca break să iasă din două bucle deodată. Iese doar din cea interioară; folosește un steag, o funcție cu return sau goto.
  • Pui continue într-un while înainte de linia care crește contorul. Contorul nu mai crește și bucla nu se oprește.
  • Sari cu goto peste declarația unui tablou de lungime variabilă sau în interiorul unui bloc. Compilatorul refuză saltul în domeniul unui VLA; ține goto doar pentru salturi înainte, spre final.

Comenzi înrudite

  • for: Bucla cu contor: inițializare, condiție verificată înainte de fiecare pas și actualizare, toate pe un singur rând.
  • while și do-while: Repetă un bloc cât timp o condiție este adevărată; do-while rulează blocul cel puțin o dată, apoi verifică.
  • switch: Alege una din mai multe ramuri după valoarea unui întreg, cu etichete case; fără break, execuția continuă în ramura următoare.
  • free: Eliberează un bloc alocat cu malloc, calloc sau realloc, ca memoria să poată fi refolosită.