De ce contează?
Mergi pe un drum și ajungi la o bifurcație: un indicator spune „dacă plouă, ia-o la stânga; altfel, mergi drept". Nu poți alege ambele drumuri — citești condiția, te uiți pe cer, și un singur traseu se deschide. Structura alternativă este exact acel indicator pus în cod: pune o întrebare cu răspuns DA sau NU și, în funcție de răspuns, programul o ia pe un singur drum.
Intuiția
Până acum programul tău mergea drept înainte, instrucțiune după instrucțiune. Dar viața nu e o linie dreaptă: uneori trebuie să faci una sau alta. Structura alternativă este momentul în care programul se oprește, evaluează o condiție și decide pe care ramură să continue. Frumusețea ei stă într-o regulă simplă: indiferent cât de multe ramuri scrii, se execută exact una singură.
Ce este
Structura alternativă (sau decizională) este o instrucțiune care alege ce cod să ruleze în funcție de o condiție. Forma de bază în C++ este:
if (conditie) {
// se executa daca conditia e adevarata
} else {
// se executa daca conditia e falsa
}Inima ei este condiția — o expresie care, evaluată, dă una din doar două valori: adevărat sau fals. În C++ orice valoare diferită de 0 înseamnă adevărat, iar 0 înseamnă fals. O scrii de obicei cu operatori de comparație în cod: == (egal), != (diferit), <, >, <=, >=.
Ai trei forme, de la simplu la complet:
- if singur — fac ceva doar dacă merită, altfel nu fac nimic.
- if / else — una din două: ori ramura de DA, ori ramura de NU.
- if / else if / else — un lanț de întrebări; prima care e adevărată câștigă, restul sunt ignorate.
Condiția nu „conține" adevărul — ea se evaluează la o valoare. Când scrii if (x > 0), C++ calculează mai întâi dacă x > 0 este adevărat sau fals, exact ca un calcul aritmetic care dă un rezultat. Apoi alege ramura. De aceea contează ce pui în paranteză: paranteza este întrebarea, nu răspunsul.
Cum arată
Să clasificăm un număr: este negativ, zero sau pozitiv? Avem trei cazuri, deci un lanț if / else if / else. Programul verifică întrebările în ordine și se oprește la prima cu răspuns DA.
if (n < 0) {
cout << "negativ";
} else if (n == 0) {
cout << "zero";
} else {
cout << "pozitiv";
}Hai să urmărim ce ramură rulează pentru n = -4. Programul intră în lanț de sus și pune întrebările pe rând.
n<0 | ? | n==0 | ? | altfel |
if | elseif | else |
Pentru că prima întrebare a fost DA, ramura „negativ" rulează și restul lanțului este sărit complet. Acum urmărește n = 5: prima întrebare e NU, a doua e NU, deci ajungem la else.
n<0 | ? | n==0 | ? | altfel |
if | elseif | else |
Observă cheia lanțului: else if este o întrebare nouă pusă doar dacă toate cele de dinaintea ei au fost NU. Iar else final este plasa de siguranță — prinde tot ce nu s-a potrivit mai sus, fără să mai pună vreo întrebare.
Implementare C++
Să rezolvăm o problemă clasică: maximul a trei numere. Comparăm pe rând și ținem minte cel mai mare găsit până acum.
#include <iostream>
using namespace std;
int main() {
int a, b, c;
cin >> a >> b >> c;
// presupunem ca primul e cel mai mare
int maxim = a;
// daca b e mai mare, el devine noul maxim
if (b > maxim) {
maxim = b;
}
// daca c e mai mare decat ce avem acum, el devine maxim
if (c > maxim) {
maxim = c;
}
cout << maxim << endl;
// pentru a = 7, b = 12, c = 4 afiseaza 12
return 0;
}Aici cele două if-uri sunt independente: fiecare se verifică oricum, pentru că orice număr ar putea fi cel mai mare. Nu folosim else între ele, fiindcă nu sunt cazuri care se exclud — sunt două verificări separate față de același maxim.
Compară cu varianta inlănțuită, când cazurile chiar se exclud (un număr e ori negativ, ori zero, ori pozitiv — niciodată două deodată):
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
if (n < 0) {
cout << "negativ" << endl;
} else if (n == 0) {
cout << "zero" << endl;
} else {
cout << "pozitiv" << endl;
}
// pentru n = -4 afiseaza negativ
return 0;
}Când cazurile se exclud, folosești else if — astfel programul nu mai pune întrebări inutile după ce a găsit răspunsul. Pentru un set închis de cazuri pe o singură valoare întreagă, C++ oferă și switch, o formă mai compactă de lanț pe egalități:
switch (nota) {
case 10: cout << "excelent"; break;
case 9: cout << "foarte bine"; break;
default: cout << "alta nota"; // prinde restul, ca else
}break oprește căutarea după ce s-a potrivit un case; default joacă rolul lui else.
Trei capcane care strică tăcut o ramificare:
-
=în loc de==.if (x = 5)nu compară — îl atribuie luixvaloarea5, iar rezultatul atribuirii (5, diferit de zero) este mereu adevărat. Ramura rulează întotdeauna, indiferent dex. Pentru comparație folosești mereu==. -
elseuitat la cazuri care se exclud. Dacă scrii douăif-uri separate în loc deif / else, ambele se pot executa. La clasificare asta poate afișa două răspunsuri pentru același număr: dacă o ramură schimbă variabila testată, a doua întrebare devine adevărată „din greșeală" și se execută și ea. Când cazurile se exclud reciproc, leagă-le cuelse. -
Condiții suprapuse, în ordine greșită. Într-un lanț, prima întrebare adevărată câștigă. Dacă pui întrebarea generală înaintea celei specifice (de exemplu testezi „nota peste 5" înainte de „nota egală cu 10"), ramura specifică nu mai e atinsă niciodată. Ordonează condițiile de la cea mai îngustă la cea mai largă.