De ce contează?
O expresie e ca o rețetă citită de un robot foarte literal: el nu calculează „de la stânga la dreapta” cum ai face tu în grabă, ci urmează niște reguli stricte de prioritate — întâi înmulțirile, apoi adunările, exact ca la matematică. Dacă nu cunoști aceste reguli, robotul îți dă un rezultat corect... dar nu cel pe care îl aveai în minte. În plus, are o ciudățenie pe care matematica n-o are: pe numere întregi, împărțirea „uită” partea de după virgulă.
Intuiția
O expresie este o combinație de valori, variabile și operatori pe care calculatorul o reduce la o singură valoare. Când scrii 2 + 3 * 4, calculatorul nu citește pur și simplu de la stânga la dreapta; el aplică aceleași reguli de prioritate pe care le-ai învățat la matematică. Surpriza vine din faptul că unii operatori (mai ales împărțirea) se comportă altfel decât te aștepți: pe numere întregi, 7/2 nu dă 3.5, ci 3.
Ce este
Un operator este un simbol care îi spune calculatorului ce operație să facă. În C++ avem mai multe familii:
- Aritmetici:
+(adunare),-(scădere),*(înmulțire),/(împărțire),%(rest, modulo) - Relaționali:
<(mai mic decât),>(mai mare decât),<=,>=,==(egal),!=(diferit) — productruesaufalse - Logici:
&&(ȘI),||(SAU),!(NU) — combină condiții
Cel mai înșelător este /. Comportamentul lui depinde de tipul operanzilor:
- Dacă AMBII operanzi sunt întregi,
/face împărțire întreagă: păstrează doar câtul, aruncă restul. Deci7 / 2dă3, nu3.5. - Dacă măcar unul este real (
double),/face împărțire reală:7.0 / 2dă3.5.
Operatorul % (modulo) îți dă restul împărțirii întregi: 7 % 2 dă 1. Împreună, / și % îți spun tot: 7 = 2 * 3 + 1, adică 7/2 este câtul 3 și 7%2 este restul 1.
Regula de aur: pe numere întregi, a / b aruncă partea fracționară, iar a % b îți dă exact ce s-a aruncat (restul). De aceea % e unealta ta pentru paritate (n % 2 == 0 înseamnă număr par), pentru ultima cifră (n % 10) și pentru divizibilitate (n % d == 0 înseamnă că d divide pe n).
Cum arată
Hai să evaluăm pas cu pas expresia 2 + 3 * 4 - 10 / 2. Calculatorul nu merge de la stânga la dreapta; aplică precedența: întâi * și / (împreună, de la stânga la dreapta), apoi + și -.
2 | + | 3 | * | 4 | - | 10 | / | 2 |
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
2 | + | 12 | - | 10 | / | 2 |
0 | 1 | 2 | 3 | 4 | 5 | 6 |
2 | + | 12 | - | 5 |
0 | 1 | 2 | 3 | 4 |
14 | - | 5 |
0 | 1 | 2 |
Dacă voiai ca adunarea să se facă prima, foloseai paranteze: (2 + 3) * 4 dă 20, nu 14. Parantezele au prioritate peste tot — ele sunt modul tău de a forța ordinea pe care o vrei.
Când nu ești sigur de precedență, pune paranteze. Nu costă nimic la execuție și fac codul lizibil. (a + b) / 2 spune clar „media”, pe când a + b / 2 calculează de fapt a + (b/2) — cu totul altceva.
La operatorii logici precedența este: ! întâi, apoi &&, apoi ||. Astfel a || b && c înseamnă a || (b && c). Operatorii relaționali se evaluează înaintea celor logici, deci x > 0 && x < 10 se citește natural ca (x > 0) && (x < 10).
Implementare C++
#include <iostream>
using namespace std;
int main() {
int a = 7, b = 2;
// impartire intreaga: ambii operanzi sunt int
int cat = a / b; // 3 (nu 3.5)
int rest = a % b; // 1
cout << a << " / " << b << " = " << cat << endl; // 7 / 2 = 3
cout << a << " % " << b << " = " << rest << endl; // 7 % 2 = 1
// verificarea: a = b * cat + rest
cout << b * cat + rest << endl; // 7
// impartire reala: macar un operand este double
double real = (double)a / b; // 3.5
cout << real << endl; // 3.5
// precedenta: * si / inainte de + si -
int expr = 2 + 3 * 4 - 10 / 2; // 2 + 12 - 5 = 9
cout << expr << endl; // 9
// paranteze forteaza ordinea
int cu_paranteze = (2 + 3) * 4; // 20
cout << cu_paranteze << endl; // 20
// relationali + logici: par SI in intervalul [0, 100]
int n = 42;
bool ok = (n % 2 == 0) && (n >= 0 && n <= 100);
cout << ok << endl; // 1 (adica true)
return 0;
}Observă conversia (double)a din cod: prin ea forțezi împărțirea reală. Fără ea, a / b rămâne pe întregi și rezultatul 3 ar fi pus apoi într-un double ca 3.0 — prea târziu, partea fracționară s-a pierdut deja.
Capcana numărul unu la concurs: calculul mediei. Scrii double m = (a + b) / 2; cu a și b întregi și te miri de ce media lui 5 și 2 îți iese 3 în loc de 3.5. Cauza: (a + b) / 2 se evaluează ÎNTÂI pe întregi (7 / 2 dă 3), iar abia rezultatul 3 ajunge în double. Corect: double m = (a + b) / 2.0; — un singur .0 schimbă tot, fiindcă forțează împărțirea reală.
Capcana numărul doi: precedența. a + b / 2 NU este media — înseamnă a + (b / 2), pentru că / are prioritate peste +. Când vrei media, pune paranteze: (a + b) / 2.0.