1. Tipuri de date fundamentale in C++
// 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)
float // 4 bytes: ~7 cifre semnificative (precizie simpla) double // 8 bytes: ~15-16 cifre semnificative (precizie dubla)
#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
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. Operatori aritmetici si precedenta
( )— Paranteze (prioritate maxima)!— Negatie logica (unar, dreapta la stanga)* / %— Inmultire, impartire, modulo+ -— Adunare, scadere< <= > >=— Operatori relationali== !=— Egalitate / inegalitate&&— SI logic||— SAU logic= += -= *=— Atribuire (prioritate minima, dreapta la stanga)
! si atribuirea, de dreapta la stanga).
# 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
// 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. Impartire intreaga, conversii implicite si cast
/ sunt intregi (int), rezultatul e tot int — trunchiat spre zero, NU rotunjit. Aceasta este una dintre cele mai frecvente capcane la BAC.
#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
char → int → long long → float → double. Daca intr-o expresie aritmetica apare un double, toti ceilalti operanzi sunt convertiti automat la double inainte de calcul.
4. Operatori relationali si logici
bool (1 sau 0 in cout):
< <= > >= == !=
!— NOT (prioritate maxima, unar)&&— AND||— OR (prioritate minima)
#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
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. Operatori pe biti — EXCLUSIV INTENSIV
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.
#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
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. Urmarire executie si capcane clasice BAC
# 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
#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
- ⚠ Ambii operanzi
intla/⇒ rezultatint(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||