Arhitectura Expresiilor și Magia Cifrelor
Disecția numerelor cu / și %, logica booleană avansată și legile lui De Morgan.
Adevărul numeric și evaluarea pe scurtcircuit
În C++, orice valoare nenulă este considerată adevărată. Singura valoare falsă este 0.
int x = 10;
if (x) {
// true! x este 10, diferit de 0
}
int y = -5;
if (y) {
// tot true! orice număr != 0 e adevărat
}Notă: Sfat BAC: Chiar dacăif(x)funcționează, scrie mereuif(x != 0)ca să fii explicit și să nu pierzi puncte.
Evaluarea pe scurtcircuit
La &&: dacă prima parte e falsă, a doua nu mai este verificată deloc.
La ||: dacă prima parte e adevărată, a doua nu mai este verificată deloc.
// SIGUR: dacă b==0, împărțirea nu se mai execută
if (b != 0 && a / b > 2) { ... }
// PERICULOS: încearcă a/b chiar dacă b==0 → crash!
if (a / b > 2 && b != 0) { ... }Notă: Atenție la BAC: ordinea condițiilor în&&contează! Pune întâi verificarea de siguranță (ex:b != 0), abia după operația care poate crăpa.
Disecția numerelor cu / și %
La BAC, majoritatea problemelor implică cifrele unui număr. Operatorii / și % sunt instrumentele tale principale. Trebuie să le stăpânești perfect.
Cum funcționează pe numărul 1234
int n = 1234;
n % 10 // → 4 (ultima cifră)
n / 10 // → 123 (taie ultima cifră)
(n / 10) % 10 // → 3 (cifra zecilor)
(n / 100) % 10 // → 2 (cifra sutelor)
n % 100 // → 34 (ultimele 2 cifre)Tabel rezumativ: de memorat
| Expresie | Ce face | Exemplu (n=1234) |
|---|---|---|
| n % 10 | Ultima cifră | 4 |
| n / 10 | Taie ultima cifră | 123 |
| (n/10) % 10 | Cifra zecilor | 3 |
| (n/100) % 10 | Cifra sutelor | 2 |
| n % 100 | Ultimele 2 cifre | 34 |
| n % 1000 | Ultimele 3 cifre | 234 |
| a*10 + b | Lipește 2 cifre | a=7, b=3 → 73 |
Notă: Atenție la BAC: expresiax/10%10extrage cifra zecilor. Echivalentă cu(x/10)%10: apare des la Subiectul I grilă.
Legile lui De Morgan
Legile lui De Morgan descriu cum se distribuie negarea ! peste operatorii logici. Apar frecvent la Subiectul I la BAC.
Cele doua legi
| Expresie originala | Echivalent negat | Ce se schimba |
|---|---|---|
| !(A && B) | !A || !B | && devine || |
| !(A || B) | !A && !B | || devine && |
Notă: Regula simpla de memorat: când negezi, operatorul se inversează (&&devine||si invers) si fiecare condiție se neagă individual.
Exemplu concret: interval
// x este in intervalul [1, 10]
x >= 1 && x <= 10
// Negarea: x NU este in [1, 10]
!(x >= 1 && x <= 10)
// echivalent cu:
x < 1 || x > 10Negarea comparatorilor
| Original | Negat cu ! |
|---|---|
| a > b | a <= b |
| a < b | a >= b |
| a == b | a != b |
| a >= b | a < b |
| a <= b | a > b |
Notă: La BAC apare des intrebarea "Care expresie este echivalenta cu !(x >= 1 && x <= 10)?". Raspuns: x < 1 || x > 10.Conversii de tip (cast)
O conversie de tip schimbă valoarea dintr-un tip de date în altul. Apare constant la grilele de BAC și este sursa unor greșeli clasice.
Conversia implicită: se întâmplă automat
int a = 10, b = 4;
double c = a / b; // c = 2.0 (NU 2.5!)
// a/b se calculează ca împărțire întreagă: 10/4 = 2
// abia după se convertește 2 → 2.0 și se pune în cNotă: Greșeala clasică la BAC! Variabila double c nu garantează că împărțirea va fi reală. Tipul împărțirii depinde de operanzi, nu de unde se stochează rezultatul.Conversia explicită: cast
int a = 10, b = 4;
double c = (double)a / b; // c = 2.5
// (double)a convertește a în 10.0 ÎNAINTE de împărțire
// 10.0 / 4 = 2.5
double x = 3.9;
int y = (int)x; // y = 3 (se taie zecimalele, nu rotunjește!)
int z = (int)3.1; // z = 3Tabel rezumativ
| Expresie | Rezultat | De ce |
|---|---|---|
| 10 / 4 | 2 | int / int = int |
| (double)10 / 4 | 2.5 | double / int = double |
| 10 / 4.0 | 2.5 | int / double = double |
| (int)3.9 | 3 | taie zecimalele |
| (int)3.1 | 3 | taie zecimalele (nu rotunjește) |
Notă: Sfat BAC: Dacă vrei împărțire reală, cel mai simplu e să scrii(double)a / bsaua / (double)bsaua * 1.0 / b.
Test de atenție: Expresii și cifre
Analizează bucățile de cod de mai jos și gândește-te ce s-ar afișa în consolă. Unele sunt scrise intenționat să te păcălească!
1. Matematica resturilor
Ce se afișează pentru n = 1234?
int n = 1234;
int x = (n / 10) % 100;
cout << x;Răspuns: [23: n/10 dă 123, apoi 123%100 izolează ultimele două cifre]
2. Capcana lui "Adevărat"
Ce se va afișa pe ecran?
int x = -5;
if (x) {
cout << "Este adevarat";
} else {
cout << "Este fals";
}Răspuns: [Este adevarat: orice număr diferit de 0 este true, chiar și negativ!]
3. Negare și interval
Avem x = 5. Ce afișează codul?
int x = 5;
if (!(x > 1 && x < 10)) {
cout << "In afara";
} else {
cout << "In interior";
}Răspuns: [In interior: x>1 && x<10 este true (5 e între 1 și 10), negarea o face false, deci merge pe else]
4. Capcana împărțirii
Ce valoare afișează codul?
int a = 10, b = 4;
double c = a / b;
cout << c;Răspuns: [2: deși c e double, a/b se calculează ca int/int = 2, abia după se convertește în 2.0]
5. Scurtcircuit logic
Ce afișează codul?
int x = 10;
if (x > 5 || x / 0 == 1)
cout << "Succes";
else
cout << "Eroare";Răspuns: [Succes: x>5 este true, deci || nu mai verifică a doua parte, nu ajunge la împărțirea la zero]
6. Construcția unui număr
Ce valoare va avea rezultat?
int a = 7, b = 3;
int rezultat = a * 10 + b;
cout << rezultat;Răspuns: [73: metoda standard de a lipi două cifre: a*10 mută prima cifră pe poziția zecilor]