💻

Capcane frecvente

Proba E.d) | Matematică-Informatică

Capitole Simulator Vizualizator Pseudocod ↔ C++ Capcane frecvente

Greșelile de mai jos apar cel mai des la examen. Citește-le o dată — e suficient ca să nu le mai faci.

Operatori

= în loc de == în condiție

Greșit
if (n = 0)    // atribuire, nu comparație!
Corect
if (n == 0)   // comparație
În C++, = face atribuire și returnează valoarea atribuită. if (n = 0) va fi mereu fals (0 = fals). Compilatorul avertizează, dar nu dă eroare.
Variabile

Variabilă neinițializată

Greșit
int s;
while (...) s = s + v[i];  // s are valoare nedefinită!
Corect
int s = 0;
while (...) s = s + v[i];
Variabilele locale în C++ nu se inițializează automat. Valoarea lor inițială este nedefinită (garbage). Mereu inițializează: s = 0, max = v[1], prim = true etc.
Tipuri de date

Împărțire întreagă când vrei zecimale

Greșit
float medie = suma / n;  // dacă suma și n sunt int, rezultat int!
Corect
float medie = (float)suma / n;
Dacă ambii operanzi sunt int, C++ face împărțire întreagă chiar dacă variabila rezultat e float. Convertește explicit cel puțin un operand: (float)suma sau suma * 1.0.
Tipuri de date

Overflow la produse mari

Greșit
int a = 100000, b = 100000;
int p = a * b;  // overflow! depășește 2^31
Corect
long long p = (long long)a * b;
int stochează maxim ~2 miliarde (2^31 - 1). Produsul a * b = 10^10 depășește asta. Dacă folosești CMMMC(a,b) = a*b/cmmdc(a,b), fă conversia înainte de înmulțire.
Vectori

Confuzie cu indexarea 0 vs 1

Greșit
// citești n elemente în v[0..n-1], dar cauți în v[1..n]
for (int i = 1; i <= n; i++) cin >> v[i];  // v[0] nefolosit
for (int i = 0; i < n; i++) cout << v[i];  // afișezi v[0] = 0
Corect
// alege un singur stil și respectă-l
for (int i = 1; i <= n; i++) cin >> v[i];
for (int i = 1; i <= n; i++) cout << v[i];
La BAC, vectorii se indexează de obicei de la 1. Declară v[101] și lucrează cu i de la 1 la n. Amestecarea stilurilor produce rezultate greșite sau acces în afara vectorului.
Vectori

Limita greșită în for (≤ vs <)

Greșit
for (int i = 1; i < n; i++)   // ratezi ultimul element!
Corect
for (int i = 1; i <= n; i++)  // dacă indexezi de la 1
for (int i = 0; i < n; i++)  // dacă indexezi de la 0
Eroare clasică. Dacă indexezi de la 1, condiția e i <= n. Dacă indexezi de la 0, condiția e i < n. Verifică mereu cu n = 1: intri în buclă?
Bucle

Buclă infinită în while

Greșit
int d = 2;
while (d * d <= n) {
    if (n % d == 0) prim = false;
    // uitat d++!
}
Corect
int d = 2;
while (d * d <= n) {
    if (n % d == 0) { prim = false; break; }
    d++;
}
Dacă variabila din condiția while nu se modifică în buclă, bucla rulează la infinit. Verifică că contorul sau valoarea din condiție se actualizează la fiecare iterație.
Fișiere

Citire/scriere din fișier — pași obligatorii

Greșit
cin >> n;  // citești de la tastatură, nu din fișier
Corect
#include <fstream>
ifstream f("date.in");
ofstream g("date.out");
f >> n;
g << rezultat;
f.close(); g.close();
La subiectele cu fișiere (clasic la BAC), trebuie declarat ifstream/ofstream, deschis fișierul, citit/scris prin el, și închis. Nu folosi cin/cout în loc de f/g.
Funcții

Uitat return în funcție recursivă

Greșit
int factorial(int n) {
    if (n == 0) return 1;
    factorial(n - 1) * n;  // calculează dar nu returnează!
}
Corect
int factorial(int n) {
    if (n == 0) return 1;
    return factorial(n - 1) * n;
}
Fără return, funcția calculează valoarea dar o aruncă. În unele compilatoare se compilează fără eroare dar returnează garbage. Verifică că fiecare ramură returnează ceva.
Variabile

Inițializarea greșită a maximului/minimului

Greșit
int max = 0;  // greșit dacă toate elementele sunt negative!
for (int i = 1; i <= n; i++)
    if (v[i] > max) max = v[i];
Corect
int max = v[1];  // inițializează cu primul element
for (int i = 2; i <= n; i++)
    if (v[i] > max) max = v[i];
Inițializând max = 0, dacă vectorul conține doar numere negative, max va rămâne 0 (greșit). Mereu inițializează cu primul element al vectorului și parcurge de la al doilea.
Afișare

Spații și newline în afișare

Greșit
for (int i = 1; i <= n; i++)
    cout << v[i] << " ";  // spațiu în plus la final
Corect
for (int i = 1; i <= n; i++) {
    if (i > 1) cout << " ";
    cout << v[i];
}
cout << "\n";
La BAC formatul contează. Dacă cerința zice "elementele separate prin spațiu", nu pune spațiu după ultimul. Folosește "\n" sau endl pentru linie nouă la final.
C++ syntax

Declararea variabilei în interiorul for

Greșit
// în C++ clasic (nu C++11+), unele compilatoare refuză:
for (int i = 1; ...)
Corect
// funcționează sigur în C++11 și mai nou:
for (int i = 1; i <= n; i++)
La BAC se folosește de obicei GCC cu C++11 sau mai nou, deci declararea în for e OK. Dacă primești eroare de compilare pe platformele de evaluare, declară variabila înainte de for.