goto în C++

Sare direct la o etichetă din aceeași funcție; folosit foarte rar, de obicei doar pentru ieșirea din mai multe bucle imbricate.

Sintaxă
goto eticheta;
...
eticheta:
    instructiune;

Ce face goto

goto eticheta; mută execuția la linia marcată cu eticheta:, oriunde în aceeași funcție. Este cea mai veche formă de control al execuției și cea mai ușor de folosit greșit: un program cu multe goto devine greu de urmărit („cod spaghetti”).

Singura folosire acceptată în general în C++ este ieșirea din mai multe bucle imbricate deodată, unde break nu ajunge. Chiar și atunci, mutarea buclelor într-o funcție separată cu return este de obicei mai clară.

goto nu poate sări peste inițializarea unei variabile în același bloc și nu poate ieși din funcție.

Exemple

Exemplul 1: Ieșire din două bucle imbricate

#include <print>

int main() {
    int harta[3][4] = {{0, 0, 0, 0}, {0, 0, 7, 0}, {0, 0, 0, 0}};
    for (int r = 0; r < 3; ++r) {
        for (int c = 0; c < 4; ++c) {
            if (harta[r][c] != 0) {
                std::println("Comoara este la rândul {}, coloana {}", r, c);
                goto gasit;
            }
        }
    }
    std::println("Nicio comoară");
gasit:
    std::println("Căutare încheiată");
}

Rezultat

Comoara este la rândul 1, coloana 2
Căutare încheiată

Exemplul 2: Aceeași idee fără goto

Buclele mutate într-o funcție: return iese din ambele deodată. Varianta aceasta este de obicei preferată.

#include <print>

bool cauta(const int (&harta)[3][4]) {
    for (int r = 0; r < 3; ++r) {
        for (int c = 0; c < 4; ++c) {
            if (harta[r][c] != 0) {
                std::println("Comoara este la rândul {}, coloana {}", r, c);
                return true;
            }
        }
    }
    return false;
}

int main() {
    int harta[3][4] = {{0, 0, 0, 0}, {0, 0, 7, 0}, {0, 0, 0, 0}};
    if (!cauta(harta)) std::println("Nicio comoară");
    std::println("Căutare încheiată");
}

Rezultat

Comoara este la rândul 1, coloana 2
Căutare încheiată

Greșeli frecvente

  • Sari cu goto peste o declarație cu inițializare (goto final; int x = 5; final: ...). Compilatorul refuză: x ar exista fără să fi fost inițializat.
  • Folosești goto pentru a face bucle (sari înapoi la o etichetă). Folosește for sau while; sunt mai clare și mai greu de greșit.

Comenzi înrudite

  • break, continue: break oprește imediat bucla sau switch-ul curent; continue sare peste restul pasului curent și trece la următorul.
  • return: Încheie funcția curentă și trimite, opțional, o valoare înapoi celui care a apelat-o.
  • for: Bucla cu contor: repetă un bloc de cod cât timp condiția este adevărată, cu inițializare și pas scrise pe același rând.