De ce contează?
Gândește-te la o rețetă de clătite: spargi ouăle, adaugi făina, torni laptele, amesteci, prăjești. Pașii se fac unul după altul, în ordine. Dacă prăjești înainte să amesteci, strici totul — chiar dacă pașii sunt aceiași. Un program simplu funcționează la fel: instrucțiunile se execută de sus în jos, una câte una, iar ordinea lor decide rezultatul.
Intuiția
Calculatorul nu se uită la tot programul deodată. Citește prima linie, o execută, trece la a doua, o execută, și tot așa până jos. E ca o listă de comenzi pe care le bifezi pe rând. Această execuție „în linie", de sus în jos, se numește structură liniară (sau secvențială). Și, ca la rețetă, ordinea contează: aceleași instrucțiuni puse în altă ordine pot da alt rezultat.
Ce este
O structură liniară este o secvență de instrucțiuni care se execută o singură dată fiecare, în ordinea în care sunt scrise, de la prima la ultima. Nicio instrucțiune nu se sare, nu se repetă, nu se reia — fluxul merge drept înainte.
Cel mai bun loc unde vezi de ce contează ordinea este interschimbarea a două variabile: ai a = 5 și b = 8 și vrei ca la final a să fie 8, iar b să fie 5. Pare simplu, dar ai un obstacol: o atribuire precum a = b suprascrie vechea valoare a lui a — și o pierzi pentru totdeauna.
O atribuire (a = b) nu „mută" valori, ci copiază valoarea din dreapta peste cea din stânga. Vechea valoare a lui a este ștearsă în acel moment. De aceea, înainte s-o ștergi, trebuie s-o pui la păstrare într-o a treia variabilă — aux. Asta e tot rolul lui aux: o cutie temporară care ține valoarea cât timp o muți.
Cum arată
Ai trei cutii: a, b și aux (la început goală, o notăm cu -). Vrem să schimbăm între ele valorile lui a și b. Executăm trei instrucțiuni, în ordine, și urmărim ce conține fiecare cutie după fiecare pas.
Instrucțiunile sunt:
aux = a;a = b;b = aux;
Starea de start — a are 5, b are 8, aux e goală.
5 | 8 | - |
a | b | aux |
a=5 | b=8 | aux=gol |
Pasul 1 — aux = a; copiem valoarea lui a în aux. Acum avem o copie de siguranță a lui 5.
5 | 8 | 5 |
a | b | aux |
a=5 | b=8 | aux=5 |
Pasul 2 — a = b; copiem b peste a. Vechiul 5 din a dispare, dar nu ne pasă: îl avem în aux.
8 | 8 | 5 |
a | b | aux |
a=8 | b=8 | aux=5 |
Pasul 3 — b = aux; punem în b valoarea salvată în aux (adică 5). Gata: schimbul e complet.
8 | 5 | 5 |
a | b | aux |
a=8 | b=5 | aux=5 |
Observă că la pasul 2 cele două variabile ajung temporar egale (8 și 8). Asta e normal și nu strică nimic — pentru că valoarea de care aveam nevoie (5) era deja la adăpost în aux. Tocmai de aici vine întreaga idee.
Implementare C++
#include <iostream>
using namespace std;
int main() {
int a = 5, b = 8;
// pas 1: salvam valoarea lui a inainte sa fie suprascrisa
int aux = a;
// pas 2: copiem b peste a
a = b;
// pas 3: punem in b valoarea veche a lui a, salvata in aux
b = aux;
cout << "a = " << a << endl; // a = 8
cout << "b = " << b << endl; // b = 5
return 0;
}Cele trei atribuiri se execută strict în ordinea în care le-ai scris — asta e structura liniară la lucru. Schimbă ordinea și rezultatul se strică: dacă pui a = b; înaintea lui aux = a;, atunci aux va salva un a care deja e 8, nu 5.
Capcana clasică: să încerci interschimbarea fără aux, scriind direct:
a = b; // a devine 8 — vechiul 5 s-a pierdut chiar aici
b = a; // a este deja 8, deci b devine tot 8Urmărește pas cu pas, ca în diagramă, cu a=5 și b=8:
- după
a = b;aia=8,b=8(valoarea5a dispărut pentru totdeauna); - după
b = a;aia=8,b=8— pentru căaera deja8.
Ambele variabile ajung egale și vechiul 5 nu mai există nicăieri. De asta ai nevoie de aux: el ține valoarea lui a la adăpost exact cât timp o suprascrii.