De ce contează?
Calculatorul tău nu „înțelege” codul — îl execută, orbește și foarte repede, fără să se întrebe vreodată ce vrei tu de fapt. Când rezultatul iese altfel decât te așteptai, nu poți întreba mașina „de ce?”. Singura cale e să faci tu, încet și pe hârtie, exact ce face ea în milisecunde: să devii tu calculatorul. Asta se numește urmărire manuală (sau dry-run).
Ideea-cheie
A urmări manual un algoritm înseamnă să execuți tu însuți instrucțiunile, una câte una, în ordinea în care le-ar executa calculatorul, și să scrii valoarea fiecărei variabile după fiecare pas într-un tabel.
De ce un tabel și nu „în cap”? Pentru că mintea ta sare peste pași, presupune rezultate și uită ce s-a schimbat — exact unde se ascunde bug-ul. Calculatorul nu sare niciun pas. Ca să-l imiți cinstit, trebuie să fii la fel de răbdător: o linie de tabel pentru fiecare schimbare reală a unei variabile.
Calculatorul nu prezice, execută. Tu, ca să prezici ce va afișa un cod (sau să găsești de ce afișează altceva), faci pe dos: execuți tu pașii încet și notezi totul. Tabelul de urmărire e „creierul de hârtie” care ține minte starea în locul tău.
Cum alegi: când merită urmărirea manuală
Nu urmărești manual orice. Ai nevoie de ea mai ales în trei momente:
- Când rezultatul te surprinde — codul rulează, dar afișează altceva decât credeai. În loc să schimbi cod la întâmplare, urmărești pas cu pas până vezi exact unde realitatea se desparte de așteptarea ta.
- La bucle — într-o buclă, aceleași linii se execută de mai multe ori, iar o variabilă își schimbă valoarea la fiecare rotație. E ușor să greșești cu un pas în plus sau în minus. Tabelul îți arată fiecare rotație separat.
- Înainte să apeși „Rulează” — la concurs sau pe hârtie, când vrei să fii sigur că logica e bună fără să ai un calculator la îndemână.
Un exemplu concret
Hai să urmărim acest fragment, care adună numerele de la 1 la 3:
int s = 0;
for (int i = 1; i <= 3; i++) {
s = s + i;
}
// ce valoare are s la final?Ne facem un tabel. O coloană pentru pas (a câta rotație a buclei), una pentru i (contorul) și una pentru s (suma de până acum). Completăm rând cu rând, exact în ordinea în care rulează codul:
| Pas | i | s = s + i | s după pas |
|---|---|---|---|
| start | — | s = 0 | 0 |
| 1 | 1 | 0 + 1 | 1 |
| 2 | 2 | 1 + 2 | 3 |
| 3 | 3 | 3 + 3 | 6 |
Citește tabelul de sus în jos, ca un film cu încetinitorul:
0 | 1 | 3 | 6 |
start | pas-1 | pas-2 | pas-3 |
s=0 | i=1 | i=2 | i=3 |
La fiecare rotație faci trei lucruri în ordine: iei i-ul curent, îl aduni la s-ul vechi și scrii noul s pe un rând nou. Când i ajunge la 4, condiția i <= 3 devine falsă, bucla se oprește, iar răspunsul e ultimul s din tabel: 6.
Observă puterea metodei: nu ai ghicit „cred că dă 6”. Ai demonstrat că dă 6, pas cu pas, exact cum ar fi făcut calculatorul. Dacă în loc de 6 te așteptai la altceva, tabelul îți arată negru pe alb la care rotație se rupe logica.
Cea mai costisitoare greșeală e urmărirea „în cap”, sărind peste pași: „start zero, apoi… cam trei, deci pe la șase”. Tocmai pasul peste care sari e cel în care se ascunde bug-ul. Calculatorul nu sare niciodată un pas — dacă vrei să-l imiți, nici tu nu ai voie. Scrie fiecare actualizare pe un rând nou, chiar dacă pare evidentă. O urmărire făcută corect e plictisitoare; o urmărire plictisitoare e una care prinde bug-ul.
Pe scurt: calculatorul execută orbește, nu înțelege — așa că tu prezici și depanezi devenind calculatorul: rulezi pașii pe hârtie și ții un tabel cu fiecare variabilă. Folosește urmărirea manuală la bucle, când rezultatul te surprinde sau înainte să rulezi — și scrie fiecare actualizare, niciodată „în cap”.