Invatare Atomica

Expresii, tipuri si operatori — Recap BAC

Progres lectie:
0%
🎯

Obiectivul lectiei

Recapitulezi tot ce trebuie sa stii despre tipuri de date, operatori si evaluarea expresiilor pentru Bacalaureat E(d). Vei rezolva grilele clasice de la Subiectul I fara sa faci greseli de precedenta sau conversie.

Dupa aceasta lectie vei putea:

  • Sa enumeri tipurile de date fundamentale C++ cu dimensiunile si rangurile lor
  • Sa aplici corect regulile de precedenta si asociativitate a operatorilor
  • Sa identifici conversiile implicite (widening) si explicite (cast) dintr-o expresie
  • Sa urmarest executia pas cu pas a unei expresii compuse (tip grila BAC)
  • Sa eviti capcanele clasice: impartire intreaga, overflow, = vs ==
  • Sa explici operatorii pe biti (EXCLUSIV intensiv): &, |, ^, ~, <<, >>

Incearca singur!

Provocare de incalzire:

Ce afiseaza urmatorul cod C++? Calculeaza in cap inainte sa citesti lectia.

int a = 7, b = 3;
double x = a / b;
double y = (double)a / b;
cout << x << " " << y;
💡 Ai nevoie de un indiciu?

Atentie la tipul rezultatului lui a / b: daca ambii operanzi sunt int, rezultatul e int (trunchiat), iar abia apoi se face conversia la double. In cazul (double)a / b, cast-ul se aplica inainte de impartire.

Raspuns: x = 2, y = 2.33333

1

1. Tipuri de date fundamentale in C++

In C++, fiecare variabila are un tip care determina: cat spatiu ocupa in memorie, ce valori poate retine si ce operatii sunt permise. Tipurile fundamentale sunt:
Tipuri intregi (verificat cu sizeof si climits):
// Intregi — dimensiune si rang (pe arhitectura x86-64)
short      // 2 bytes:  -32768 la 32767
int        // 4 bytes:  -2147483648 la 2147483647
long long  // 8 bytes:  -9223372036854775808 la 9223372036854775807
unsigned int // 4 bytes: 0 la 4294967295
char       // 1 byte:  -128 la 127 (signed) sau 0 la 255 (unsigned)
bool       // 1 byte:  false (0) sau true (1)
Tipuri reale (virgula mobila):
float   // 4 bytes: ~7 cifre semnificative (precizie simpla)
double  // 8 bytes: ~15-16 cifre semnificative (precizie dubla)
Cod C++ rulat (g++ -std=c++17) — output real:
#include <iostream>
#include <climits>
using namespace std;
int main() {
    cout << "sizeof(int)       = " << sizeof(int) << " bytes" << endl;
    cout << "sizeof(long long) = " << sizeof(long long) << " bytes" << endl;
    cout << "sizeof(double)    = " << sizeof(double) << " bytes" << endl;
    cout << "INT_MAX  = " << INT_MAX << endl;
    cout << "INT_MIN  = " << INT_MIN << endl;
    return 0;
}
sizeof(int)       = 4 bytes
sizeof(long long) = 8 bytes
sizeof(double)    = 8 bytes
INT_MAX  = 2147483647
INT_MIN  = -2147483648
Regula de memorat (BAC): int = 4 bytes = 2 miliarde. Daca rezultatul depaseste 2 miliarde, foloseste long long. Daca ai nevoie de virgula, foloseste double (nu float — precizia e mai mica).
2

2. Operatori aritmetici si precedenta

Tabel de precedenta (de la cea mai mare la cea mai mica):
  1. ( ) — Paranteze (prioritate maxima)
  2. ! — Negatie logica (unar, dreapta la stanga)
  3. * / % — Inmultire, impartire, modulo
  4. + - — Adunare, scadere
  5. < <= > >= — Operatori relationali
  6. == != — Egalitate / inegalitate
  7. && — SI logic
  8. || — SAU logic
  9. = += -= *= — Atribuire (prioritate minima, dreapta la stanga)
Asociativitate: operatorii de pe acelasi nivel se evalueaza stanga la dreapta (exceptie: ! si atribuirea, de dreapta la stanga).
Evaluare pas cu pas (output real, python verificare):
# a=3, b=4, c=2
a = 3; b = 4; c = 2

# Exemplul 1: precedenta * > +
expr1 = a + b * c   # 3 + (4*2) = 3 + 8 = 11
print(expr1)        # -> 11

# Exemplul 2: parantezele schimba ordinea
expr2 = (a + b) * c # (3+4)*2 = 7*2 = 14
print(expr2)        # -> 14

# Exemplul 3: asociativitate stanga la dreapta
expr3 = 10 - 3 - 2  # (10-3)-2 = 5, NU 10-(3-2)=9
print(expr3)        # -> 5
11
14
5
Operatorul modulo % — esential la BAC:
// 17 % 5 = 2 (restul impartirii 17 la 5)
int r = 17 % 5;  // r = 2
int cifra_unitati = 1234 % 10; // = 4
int par = 8 % 2;   // = 0 (par)
int impar = 7 % 2; // = 1 (impar)
3

3. Impartire intreaga, conversii implicite si cast

Regula de aur in C++: daca ambii operanzi ai / sunt intregi (int), rezultatul e tot int — trunchiat spre zero, NU rotunjit. Aceasta este una dintre cele mai frecvente capcane la BAC.
Cod C++ rulat (g++ -std=c++17) — output real:
#include <iostream>
using namespace std;
int main() {
    int a = 7, b = 3;

    // Impartire intreaga (trunchiere spre zero)
    cout << "7 / 3 (int)     = " << a/b << endl;   // -> 2

    // Impartire reala cu cast explicit
    cout << "(double)7 / 3   = " << (double)a/b << endl; // -> 2.33333

    // Capcana: atribuire inainte de cast
    double x = a/b;        // int/int=2, apoi 2->2.0
    double y = (double)a/b; // (double)7/3 = 2.33333
    cout << "x (gresit) = " << x << endl;
    cout << "y (corect)  = " << y << endl;

    // Cast explicit: trunchiere, NU rotunjire
    double pi = 3.14159;
    cout << "(int)3.14159 = " << (int)pi << endl;  // -> 3
    return 0;
}
7 / 3 (int)     = 2
(double)7 / 3   = 2.33333
x (gresit) = 2
y (corect)  = 2.33333
(int)3.14159 = 3
Conversii implicite (widening) — fara pierdere de date: charintlong longfloatdouble. Daca intr-o expresie aritmetica apare un double, toti ceilalti operanzi sunt convertiti automat la double inainte de calcul.
4

4. Operatori relationali si logici

Operatori relationali — rezultatul e bool (1 sau 0 in cout): < <= > >= == !=
Operatori logici si precedenta lor (de la mare la mica):
  1. ! — NOT (prioritate maxima, unar)
  2. && — AND
  3. || — OR (prioritate minima)
Cod C++ rulat (g++ -std=c++17) — output real:
#include <iostream>
using namespace std;
int main() {
    int x = 5, y = 10;
    cout << (x < y) << endl;    // -> 1 (true)
    cout << (x == y) << endl;   // -> 0 (false)
    cout << (x != y) << endl;   // -> 1 (true)

    bool a = true, b = false;
    cout << (a && b) << endl;   // -> 0
    cout << (a || b) << endl;   // -> 1
    cout << (!a) << endl;       // -> 0

    // Expresie tip BAC: (n%3==0) && (n%5==0)
    int n = 15;
    cout << ((n%3==0) && (n%5==0)) << endl; // -> 1

    // Precedenta && > ||
    cout << (false || true && false) << endl; // false||(true&&false)=0
    cout << (false || true && true) << endl;  // false||(true&&true)=1
    return 0;
}
1
0
1
0
1
0
1
0
1
Short-circuit evaluation: in A && B, daca A e false, B nu mai e evaluat. In A || B, daca A e true, B nu mai e evaluat. Important daca B are efecte secundare (ex: apel de functie).
5

5. Operatori pe biti — EXCLUSIV INTENSIV

⚡ Sectiune doar pentru profilul intensiv informatica

Operatorii pe biti lucreaza direct pe reprezentarea binara a intregilor. Apar rar la BAC standard, dar frecvent la olimpiade si concursuri. La intensiv sunt materie obligatorie.

Cod C++ rulat (g++ -std=c++17) — output real:
#include <iostream>
using namespace std;
int main() {
    int p = 12; // binar: 1100
    int q = 10; // binar: 1010

    cout << (p & q) << endl;   // AND biti: 1000 = 8
    cout << (p | q) << endl;   // OR biti:  1110 = 14
    cout << (p ^ q) << endl;   // XOR biti: 0110 = 6
    cout << (~p) << endl;      // NOT biti: complement 2 = -13
    cout << (p << 1) << endl;  // shift stanga 1: *2 = 24
    cout << (p >> 1) << endl;  // shift dreapta 1: /2 = 6
    return 0;
}
8
14
6
-13
24
6
Utilitate practica:
  • n & 1 — testeaza daca n e impar (ultimul bit)
  • n << k — echivalent cu n * 2^k (mult mai rapid)
  • n >> k — echivalent cu n / 2^k (trunchiat)
  • n ^ n — rezulta 0 (proprietate XOR)
6

6. Urmarire executie si capcane clasice BAC

La Subiectul I apar frecvent exercitii de tip „ce afiseaza programul”. Strategia corecta: evalueaza pas cu pas, respectand precedenta.
Exercitiu rezolvat complet (output verificat):
# a=3, b=5, c=2
# x = a + b*c - (a-c)*b/2
#
# Pas 1: b*c = 5*2 = 10  (inmultire)
# Pas 2: a-c = 3-2 = 1   (paranteze prioritate maxima)
# Pas 3: (a-c)*b = 1*5 = 5
# Pas 4: (a-c)*b/2 = 5//2 = 2  (IMPARTIRE INTREAGA!)
# Pas 5: a + b*c = 3 + 10 = 13
# Pas 6: 13 - 2 = 11
a, b, c = 3, 5, 2
x = a + b*c - (a-c)*b//2  # // = impartire intreaga (ca C++)
print(x)
11
Capcane clasice verificate in C++ (output real):
#include <iostream>
#include <climits>
using namespace std;
int main() {
    // Capcana 1: Overflow
    int maxInt = INT_MAX;
    cout << maxInt + 1 << endl;  // -> -2147483648 (overflow!)

    // Capcana 2: Impartire intreaga atribuita la double
    double x = 5/2;      // int/int=2, dupa double -> 2
    double y = 5.0/2;    // double/int -> 2.5
    cout << x << endl;   // -> 2
    cout << y << endl;   // -> 2.5

    // Capcana 3: = (atribuire) vs == (comparatie)
    int n = 0;
    cout << (n = 5) << endl;   // -> 5 (atribuire, NU comparatie!)
    cout << (n == 5) << endl;  // -> 1 (comparatie)
    return 0;
}
-2147483648
2
2.5
5
1
Checklist anti-capcana BAC:
  • ⚠ Ambii operanzi int la / ⇒ rezultat int (trunchiat!)
  • ⚠ Cast (int) ⇒ trunchiere spre zero, NU rotunjire
  • = atribuie, == compara — confuzia da erori logice greu de depistat
  • INT_MAX + 1 ⇒ overflow (undefined behavior, practic wrap-around)
  • ! are precedenta mai mare decat && care are precedenta mai mare decat ||

Exercitii practice

Exercitiul 1 (Nivel minim) — Tipuri si conversii

Completeaza tipul corect (int, double sau long long) pentru fiecare variabila:

___ nr_studenti = 1500;   ___ medie = 8.75;   ___ populatie_China = 1400000000LL;

Explica de ce int populatie = 1400000000 este potential problematic.

Exercitiul 2 (Nivel standard) — Urmarire executie

Ce afiseaza urmatorul fragment? Calculeaza manual, pas cu pas:

int a=10, b=3, c=4;
int x = a/b + (a-b*c) % (b+1);
cout << x;

Indica exact unde intervine impartirea intreaga si ce efect are.

Exercitiul 3 (Nivel performanta) — EXCLUSIV INTENSIV

Scrie o expresie C++ pe o singura linie care, folosind numai operatori pe biti, calculeaza:

  • Daca un intreg pozitiv n este o putere a lui 2 (returneaza true daca da).
  • Indiciu: o putere a lui 2 are exact un bit 1 in reprezentarea binara.

Verifica pentru n=8 (1000 binar ⇒ true) si n=6 (0110 binar ⇒ false).

Ce ai consolidat astazi

  • Tipuri de date fundamentale C++: int, long long, double, char, bool — dimensiuni si ranguri
  • Precedenta operatorilor: ! > * / % > + - > < <= > == != > && > || > =
  • Impartire intreaga: int/int ⇒ trunchiere spre zero (nu rotunjire)
  • Conversii: widening automat (int → double) vs cast explicit cu trunchiere
  • Capcane BAC: overflow, = vs ==, atribuire inainte de cast
  • Operatori pe biti (intensiv): &, |, ^, ~, <<, >>

Urmatoarea lectie

Continua cu Structuri de control — Master: IF, FOR, WHILE — toate variantele si capcanele pentru Subiectul I si II.

Continua →