De ce contează?
Te muți într-un bloc nou și încurci etajul cu apartamentul: ajungi la ușa greșită. La matrice se întâmplă la fel — dacă inversezi linia cu coloana sau treci de ultima cu un pas, „bați la ușa” greșită. Vestea bună: aproape toate erorile de indici vin din câteva tipare pe care le poți recunoaște.
De ce sunt erorile de indici atât de frecvente
La matrice jonglezi cu doi indici simultan, fiecare cu propria limită. Două surse de bug domină:
- Inversarea liniei cu coloana (
a[j][i]în loc dea[i][j]). - Off-by-one: treci de
n-1sau pornești de la1când trebuia de la0(sau invers).
Regulă de aur pentru depistare: testează pe o matrice nepătratică mică (ex. 2×3). Dacă inversezi indicii, la n ≠ m codul fie iese din matrice, fie dă rezultate clar greșite — eroarea se vede imediat. Pe matrice pătratice se ascunde.
Cele trei verificări rapide
Înainte de a rula pe teste, verifică:
- Ordinea indicilor. Peste tot
a[linie][coloană]=a[i][j]. Linia mereu prima. - Limitele buclelor. Liniile
0..n-1, coloanele0..m-1. La parcurgere pe coloane, bucla interioară merge până lan(linii), num. - Dimensiunile la afișare. Dacă ai transpus sau ai schimbat forma, afișezi cu noile limite, nu cu cele vechi.
Exemplul care prinde bug-ul
Pe matricea 2×3:
| L0 | 1 | 2 | 3 |
0 | 1 | 2 |
| L1 | 4 | 5 | 6 |
0 | 1 | 2 |
Dacă din greșeală scrii a[j][i] cu j = 2, accesezi linia 2 într-o matrice cu doar 2 linii (0 și 1) → memorie în afara matricei, rezultat imprevizibil. Pe o matrice 3×3 aceeași greșeală ar fi „mers” și ai fi pierdut bug-ul.
Tipare de cod corecte
// parcurgere pe linii: i exterior, j interior
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
folosesc(a[i][j]); // linie-intai, mereu
// vecin cu verificare de margine
int ni = i + dx[k], nj = j + dy[k];
if (ni >= 0 && ni < n && nj >= 0 && nj < m) // OBLIGATORIU
folosesc(a[ni][nj]);Greșeli frecvente de concurs:
a[j][i]în loc dea[i][j]. Cea mai des întâlnită. Testează pen ≠ mca s-o prinzi; pe pătratice se ascunde.<= nîn loc de< n. Buclafor (i = 0; i <= n; i++)acceseazăa[n][...], care nu există. Limita corectă e< n.- Limita greșită în bucla interioară. La parcurgere pe coloane, interiorul merge pe linii (
i < n). Folosirea luimaici e clasică lan ≠ m. - Vecin fără verificare de margine. La bordură,
i-1sauj+1ies din matrice. Verifică limitele înainte de orice acces la vecin.
Recapitulare
- Cele două surse de bug: inversarea linie/coloană și off-by-one la limite.
- Testează pe o matrice mică, nepătratică (
2×3) — acolo erorile de indici ies imediat la suprafață. - Verifică mereu: linie-întâi (
a[i][j]), limite< n/< m, și margini înainte de a accesa vecini.