Limbajul de programare Pascal sau C++
Elevii utilizează un limbaj de programare pentru implementarea algoritmilor și rezolvarea problemelor.
Evaluarea Națională
Structura unui program și tipurile de date
Un program C++ are un schelet fix: directiva #include <iostream> (aduce instrumentele de citire/scriere), using namespace std; și funcția main() — punctul din care începe execuția. Orice instrucțiune se termină cu punct și virgulă; uitarea lui e cea mai frecventă eroare de compilare. În Pascal, echivalentul e blocul program ... begin ... end. — cu punct la final.
Tipurile de date simple pe care trebuie să le stăpânești:
- int (Pascal: integer) — numere întregi: −5, 0, 172;
- float / double (Pascal: real) — numere cu virgulă: 3.14, −0.5;
- char — un singur caracter, scris între apostrofuri: 'a', '7';
- bool (Pascal: boolean) — doar valorile true și false.
Alegerea tipului contează la punctaj: dacă împarți doi întregi în C++, rezultatul e tot întreg! Expresia 7 / 2 dă 3, nu 3.5 — se păstrează doar câtul împărțirii întregi. Pentru rest există operatorul % (modulo): 7 % 2 dă 1. În Pascal aceleași operații se numesc div și mod.
O variabilă e o zonă de memorie cu nume și tip, a cărei valoare se poate schimba; o constantă primește o valoare la declarare și nu mai poate fi modificată. Numele lor trebuie să înceapă cu literă sau liniuță de subliniere, fără spații și fără a folosi cuvintele rezervate ale limbajului.
Citirea, scrierea și atribuirea
Comunicarea programului cu utilizatorul se face prin citire (datele intră de la tastatură) și scriere (rezultatele apar pe ecran).
În C++: cin >> n; citește valoarea variabilei n, iar cout << n; o afișează. Săgețile arată sensul datelor: spre variabilă la citire (>>), dinspre variabilă spre ecran la scriere (<<). Inversarea lor e o greșeală de sintaxă tipică. În Pascal folosim read(n) / readln(n) și write(n) / writeln(n).
Atribuirea este instrucțiunea fundamentală: v = expresie; (Pascal: v := expresie). Se evaluează ÎNTÂI expresia din dreapta, apoi rezultatul se depune în variabila din stânga, ștergând vechea valoare. De aceea x = x + 1; este perfect corectă: ia valoarea curentă a lui x, adună 1 și pune rezultatul înapoi.
Atenție la confuzia cu cel mai mare cost la punctaj în C++: = este atribuire, == este comparație. Condiția if (x = 5) NU verifică dacă x este 5 — îi atribuie lui x valoarea 5 și condiția devine adevărată aproape mereu. Verificarea corectă este if (x == 5).
Un șablon celebru care apare la subiecte: interschimbarea valorilor a două variabile a și b cere o a treia variabilă auxiliară: aux = a; a = b; b = aux;. Dacă scrii direct a = b; b = a; ambele variabile ajung cu aceeași valoare — valoarea inițială a lui a se pierde la primul pas.
Structura alternativă (decizia)
Structura alternativă alege între două drumuri pe baza unei condiții:
if (conditie) { instructiuni1 } else { instructiuni2 }
Dacă condiția e adevărată se execută prima ramură, altfel a doua. Ramura else este opțională.
Condițiile se construiesc cu operatorii relaționali: < , > , <= , >= , == (egal), != (diferit) și se combină cu operatorii logici:
- && (și) — adevărat doar când AMBELE condiții sunt adevărate;
- || (sau) — adevărat când CEL PUȚIN una e adevărată;
- ! (negație) — inversează valoarea de adevăr.
Capcana matematică: condiția „x este între 1 și 10” NU se scrie 1 <= x <= 10 (în C++ expresia asta se evaluează greșit, de la stânga la dreapta), ci x >= 1 && x <= 10.
Altă capcană: la numere pare condiția este n % 2 == 0. Pentru impare poți scrie n % 2 != 0 — dar atenție la numerele negative în C++, unde restul poate fi negativ, motiv pentru care n % 2 == 1 nu prinde toate cazurile impare.
Instrucțiunile if se pot imbrica (un if în interiorul altuia). Regula de citire: un else se leagă de cel mai apropiat if fără else de deasupra lui. La urmărirea execuției pe hârtie, marchează cu acolade de cine aparține fiecare else — aici se pierd cele mai multe puncte la exercițiile de tip „ce afișează programul”.
Structurile repetitive
Trei instrucțiuni repetă un bloc de cod, fiecare cu specificul ei:
- for — repetiție cu număr cunoscut de pași: for (i = 1; i <= n; i++) { ... }. Cele trei zone: inițializarea contorului, condiția de continuare (verificată ÎNAINTE de fiecare pas) și pasul de modificare.
- while — repetiție cu test inițial: condiția se verifică înainte de fiecare execuție; dacă e falsă de la început, corpul nu se execută niciodată (zero execuții posibile).
- do...while — repetiție cu test final: corpul se execută o dată, APOI se verifică condiția; garantează cel puțin o execuție. Echivalentul Pascal, repeat...until, are o diferență vicleană: repeat se repetă cât timp condiția e falsă (până devine adevărată), pe când do...while se repetă cât timp condiția e adevărată.
Diferența while / do...while este întrebare-standard: pentru aceleași date, cele două pot produce rezultate diferite exact când condiția e falsă de la început.
Șablonul de prelucrare a cifrelor unui număr apare aproape an de an: cât timp n este diferit de 0, extragem ultima cifră cu n % 10 și o eliminăm cu n = n / 10 (împărțire întreagă). Astfel numărăm cifrele, le adunăm sau construim inversul (oglinditul) numărului: inv = inv * 10 + n % 10.
Buclele se pot imbrica — o buclă în interiorul alteia. Numărul total de execuții ale corpului interior este produsul numerelor de pași, de aceea urmărirea pe hârtie cere un tabel cu valorile ambilor contori.
Subprograme și tablouri în cod
O funcție C++ se definește cu tipul rezultatului, nume și parametri: int maxim(int a, int b) { if (a > b) return a; return b; }. Instrucțiunea return încheie imediat funcția și trimite rezultatul la locul apelului. O funcție void (procedură) doar execută acțiuni, fără a returna o valoare.
Regulă care se punctează: parametrii transmiși prin valoare sunt copii — modificările din interiorul funcției NU afectează variabilele de la apel. Ca funcția să poată modifica variabila originală, parametrul se transmite prin referință (în C++ cu &: void dubleaza(int &x)).
Tablourile în cod: int v[100]; declară un vector cu maximum 100 de elemente, indexate de la 0 la 99. Citirea a n elemente: for (i = 0; i < n; i++) cin >> v[i];. Observă condiția i < n, nu i <= n — cu <= ai accesa un element în plus, în afara datelor citite.
Matricea se declară int a[20][20]; și se citește cu două bucle imbricate.
Erori tipice de cod care apar la subiectele de tip „depanare”:
- punct și virgulă pus imediat după for sau if — bucla/decizia rămâne cu corp vid, iar blocul de sub ea se execută o singură dată, necondiționat;
- folosirea lui = în loc de == în condiții;
- depășirea limitelor tabloului;
- lipsa acoladelor când corpul buclei are mai multe instrucțiuni — doar prima mai aparține buclei.
Când primești un program cu erori, caută-le exact în această ordine: sintaxă, limite, condiții.
De reținut
- variabilă
- zonă de memorie identificată prin nume, care păstrează o valoare de un anumit tip, valoare ce se poate modifica în timpul execuției
- constantă
- nume asociat unei valori fixate la declarare, care nu mai poate fi modificată pe parcursul programului
- atribuire
- instrucțiune care evaluează expresia din dreapta și depune rezultatul în variabila din stânga, ștergând valoarea anterioară
- operatorul %
- operatorul modulo din C++, care calculează restul împărțirii întregi a doi operanzi întregi (echivalentul lui mod din Pascal)
- structură alternativă
- structură de control care execută una dintre două secvențe de instrucțiuni, în funcție de valoarea de adevăr a unei condiții
- while
- structură repetitivă cu test inițial: condiția se verifică înaintea fiecărei execuții, deci corpul se poate executa de zero ori
- do...while
- structură repetitivă cu test final: corpul se execută o dată înainte de prima verificare, deci cel puțin o execuție este garantată
- for
- structură repetitivă cu contor, folosită când numărul de repetări este cunoscut: inițializare, condiție de continuare, pas
- transmitere prin valoare
- mecanism prin care subprogramul primește o copie a parametrului, astfel că modificările din interior nu afectează variabila de la apel
- transmitere prin referință
- mecanism prin care subprogramul lucrează direct pe variabila de la apel, putând să îi modifice valoarea
Greșeli frecvente
Greșit: Folosirea lui = în loc de == în condiții C++
Corect: = atribuie o valoare, == compară; if (x = 5) atribuie și condiția devine adevărată, verificarea corectă fiind if (x == 5)
Greșit: Așteptarea rezultatului 3.5 la expresia 7 / 2 cu operanzi întregi
Corect: Împărțirea a doi întregi în C++ este împărțire întreagă: 7 / 2 dă 3; pentru rezultat real, cel puțin un operand trebuie să fie real
Greșit: Scrierea condiției de interval ca 1 <= x <= 10
Corect: Intervalul se exprimă cu operator logic: x >= 1 && x <= 10; forma înlănțuită se evaluează greșit în C++
Greșit: Interschimbarea a două variabile prin a = b; b = a;
Corect: Este necesară o variabilă auxiliară: aux = a; a = b; b = aux; altfel valoarea inițială a lui a se pierde la primul pas
Greșit: Punct și virgulă pus imediat după antetul lui for sau if
Corect: Acel punct și virgulă creează un corp vid: bucla se execută în gol, iar blocul de dedesubt rulează o singură dată, necondiționat
Test — 6 întrebări ca la examen
1. Ce valoare are expresia C++ 17 % 5 + 17 / 5?
- 6.4
- 5
- 2
- 3
Vezi răspunsul
5. 17 % 5 = 2 (restul) și 17 / 5 = 3 (câtul întreg), deci 2 + 3 = 5. Varianta 6.4 e capcana celor care fac împărțirea reală 17/5 = 3.4 — dar cu operanzi întregi împărțirea este întreagă.
2. După executarea secvenței x = 3; y = x + 2; x = y * 2;, variabilele x și y au valorile:
- x = 10, y = 5
- x = 6, y = 5
- x = 10, y = 12
- x = 3, y = 5
Vezi răspunsul
x = 10, y = 5. y = 3 + 2 = 5, apoi x = 5 * 2 = 10. Varianta x = 6 apare dacă folosești vechea valoare a lui x în ultima atribuire; dar atribuirea a suprascris deja pe y cu 5, iar x se recalculează din y, nu invers.
3. Care condiție C++ verifică corect faptul că numărul întreg pozitiv n este par și are exact două cifre?
- n % 2 == 0 || n >= 10 && n <= 99
- n % 2 == 0 && n >= 10 && n <= 99
- n / 2 == 0 && n >= 10 && n <= 99
- n % 2 == 0 && 10 <= n <= 99
Vezi răspunsul
n % 2 == 0 && n >= 10 && n <= 99. Paritatea se testează cu n % 2 == 0, iar cele două cifre cu n >= 10 && n <= 99, legate toate prin ȘI logic. Prima variantă folosește SAU, deci ar accepta orice număr par, indiferent de cifre; ultima folosește înlănțuirea 10 <= n <= 99, care se evaluează greșit în C++.
4. Pentru n = 4, câte execuții are corpul buclei while (n > 4) { n = n - 1; } și câte are corpul buclei do { n = n - 1; } while (n > 4); ?
- 0 și 0
- 0 și 1
- 1 și 1
- 1 și 0
Vezi răspunsul
0 și 1. La while, condiția 4 > 4 este falsă de la început, deci corpul nu rulează deloc. La do...while, corpul se execută o dată OBLIGATORIU (n devine 3), abia apoi condiția falsă oprește bucla. Exact această diferență — test inițial versus test final — e vânată de întrebare.
5. Se execută secvența: s = 0; cât timp n != 0 execută s = s + n % 10; n = n / 10;. Pentru n = 205, valoarea finală a lui s este:
- 7
- 25
- 502
- 3
Vezi răspunsul
7. Se adună cifrele: 5 + 0 + 2 = 7. Varianta 502 este oglinditul numărului — șablonul înrudit, dar cu formula inv = inv * 10 + n % 10; iar 3 este numărul de cifre, alt șablon din aceeași familie. Recunoașterea exactă a șablonului e cheia.
6. Funcția void f(int x) { x = x + 10; } este apelată prin f(a); unde a = 5. Ce valoare are a după apel?
- 15
- 10
- 5
- 0
Vezi răspunsul
5. Parametrul x este transmis prin valoare, deci funcția modifică o copie, nu variabila a — care rămâne 5. Varianta 15 ar fi corectă doar la transmiterea prin referință, void f(int &x), capcana clasică a acestui tip de item.
Deschide varianta interactivă — cu AI care îți explică