Tipuri simple de date

Bază~14 min10 pași

De ce contează?

Când împachetezi obiecte, alegi cutia după mărime: o cană nu intră într-o cutie de chibrituri, dar nici n-ai pune un inel într-un dulap. La fel alegi tipul unei variabile: destul de mare cât să încapă valoarea, dar fără să irosești spațiu.

Ce este un tip de date

Un tip spune două lucruri: ce fel de valori poate ține o variabilă și cât spațiu ocupă în memorie. Spațiul fixat înseamnă și o limită: dacă depășești limita, valoarea „se sparge" (overflow).

Cele mai folosite tipuri la concursuri:

TipCe țineInterval aproximativSpațiu
intîntregi−2,1 mld … +2,1 mld4 octeți
long longîntregi mari±9,2 · 10¹⁸8 octeți
charun caracter / întreg mic−128 … 1271 octet
booladevărat/falstrue / false1 octet
doublenumere reale~15 cifre exacte8 octeți
Observația-cheie

Regula de aur la concurs: dacă rezultatul poate trece de 2 miliarde, folosește long long. Sumele și produsele cresc rapid — un produs de doar câteva numere de ordinul miilor depășește deja int.

Cum „arată" un interval

Un int cu semn acoperă valori în jurul lui zero, simetric. Dincolo de capete, urmează overflow — valoarea sare la celălalt capăt:

-2.1mld
...
-1
0
1
...
2.1mld
Capetele intervalului unui int. Adunând 1 la maximul din dreapta, valoarea „se rostogolește” la minimul din stânga.

Algoritm pas cu pas: când se sparge un int

Calculăm n * (n + 1) / 2 (suma primelor n numere) pentru n = 100000:

  1. n + 1 = 100001
  2. n * (n + 1) = 10.000.100.000peste 2,1 miliarde!
  3. Dacă n și produsul sunt int, rezultatul e deja greșit înainte de împărțire.

Soluția: facem calculul în long long.

Implementare C++

#include <iostream>
using namespace std;

int main() {
    long long n = 100000;
    long long suma = n * (n + 1) / 2;   // 5000050000, corect
    cout << suma << "\n";

    int mic = 200;
    char litera = 'A';
    bool esteImpar = (n % 2 == 1);      // false, fiindca 100000 e par

    cout << mic << " " << litera << " " << esteImpar << "\n";  // 200 A 0
    return 0;
}
Observația-cheie

char litera = 'A'; ține de fapt codul numeric al literei (65 pentru 'A'). De aceea char e și „număr mic": poți face litera + 1 și obții codul lui 'B'.

Complexitate

Alegerea tipului nu schimbă viteza algoritmului, dar long long ocupă dublu față de int. La vectori foarte mari (milioane de elemente) asta contează la memorie — folosește long long doar unde chiar ai nevoie.

Greșeli frecvente

Greșeli reale de concurs legate de tipuri:

  • Overflow tăcut: calculezi un produs în int, primești un rezultat „plauzibil" dar greșit, fără niciun mesaj de eroare. Verdict: rezultat parțial.
  • Conversie prea târzie: scrii long long s = a * b; cu a, b de tip int → înmulțirea se face tot în int și se sparge înainte de atribuire. Scrie (long long)a * b.
  • double pentru numărători: rotunjirile dau 4.999999 în loc de 5 și pierzi un caz. Pentru întregi folosește tipuri întregi.
  • Risipă de memorie: un vector de long long când valorile încap în int poate depăși limita de memorie a problemei.

De reținut

  • Tipul fixează atât felul valorilor, cât și limita lor — depășirea înseamnă overflow.
  • Peste 2 miliarde → long long; pentru întregi nu folosi niciodată double.
  • Convertește la long long înainte de înmulțire, nu după.

Întrebarea 1 / 3

Vrei să stochezi `12!` = 479001600. Ce tip alegi sigur?