</>
InfoPrep

Lecție

Tipuri de date

Alege tipul potrivit pentru valorile folosite în program.

Tipuri de date în C++

În lecția anterioară am văzut că fiecare variabilă are un tip.

Tipul stabilește ce fel de valoare poate memora variabila.

De exemplu:

int varsta = 18;
double medie = 9.75;
char litera = 'A';
bool admis = true;

Valorile memorate sunt diferite:

18      → număr întreg
9.75    → număr real
'A'     → caracter
true    → valoare logică

De aceea avem nevoie de tipuri de date diferite.

În probleme vom folosi în principal:

int        → numere întregi
long long  → numere întregi foarte mari
double     → numere reale
char       → caractere
bool       → adevărat / fals

De reținut: Alegem tipul unei variabile în funcție de valorile pe care trebuie să le memoreze.


int — numere întregi

Tipul int este folosit pentru memorarea numerelor întregi.

int varsta = 18;
int temperatura = -5;
int x = 0;

Un int poate memora valori precum:

-100
-5
0
17
1000

dar nu este potrivit pentru valori cu parte zecimală precum:

3.14
9.75
2.5

int va fi unul dintre cele mai folosite tipuri în problemele pe care le vom rezolva.


Cât de mare poate fi un int?

În mediile întâlnite în mod obișnuit la problemele de liceu, un int are limita aproximativă:

-2 × 10⁹ ... 2 × 10⁹

Mai exact, pentru un int pe 32 de biți:

-2 147 483 648
...
 2 147 483 647

Nu este necesar să memorezi valorile exacte.

Este suficient să reții:

int → aproximativ ±2 × 10⁹

De exemplu:

100 000          → încape
1 000 000 000    → încape
1 000 000 000 000 → nu încape

long long — numere întregi mai mari

Dacă avem nevoie să memorăm numere întregi care depășesc limita lui int, putem folosi:

long long

De exemplu:

long long n = 5000000000;

Numărul:

5 000 000 000

este mai mare decât limita unui int, dar poate fi memorat într-un long long.

Pentru problemele noastre putem reține aproximativ:

int        → până în zona lui 10⁹
long long  → până în zona lui 10¹⁸

Mai precis, un long long pe 64 de biți poate ajunge aproximativ până la:

±9 × 10¹⁸

Cum alegem între int și long long?

Ne uităm la valorile maxime care pot apărea.

Dacă enunțul spune:

n ≤ 100 000

putem folosi:

int n;

Dacă avem:

n ≤ 10⁹

valoarea încă încape într-un int.

Dar dacă avem:

n ≤ 10¹²

int nu mai este suficient.

Vom folosi:

long long n;

pentru că:

10¹² > 2 × 10⁹

Atenție și la rezultatul calculelor

Nu trebuie să verificăm doar dacă valorile inițiale încap într-un anumit tip.

Trebuie să ne gândim și la valorile care pot apărea în timpul calculelor.

Să presupunem că avem:

int a = 100000;
int b = 100000;

Atât a, cât și b încap fără probleme într-un int.

Dar produsul lor este:

100 000 × 100 000 = 10 000 000 000

adică:

10¹⁰

Această valoare depășește limita unui int.

Într-o astfel de situație avem nevoie de un tip suficient de mare pentru rezultat, de exemplu long long.

Important: Atunci când alegi tipul unei variabile, gândește-te și la cât de mari pot deveni rezultatele calculelor.

Dacă o valoare depășește intervalul pe care tipul respectiv îl poate reprezenta, apare o problemă numită overflow.

Pentru moment este suficient să reții ideea:

valoarea devine prea mare pentru tipul ales
→ tipul respectiv nu mai este potrivit

double — numere reale

Pentru valori care pot avea parte zecimală folosim, în general:

double

De exemplu:

double medie = 9.75;
double temperatura = 23.5;
double x = 2.5;

Compară:

int a = 5;
double b = 5.5;

a memorează un număr întreg, iar b poate memora o valoare cu parte zecimală.

Există și tipul float pentru numere reale, însă double oferă o precizie mai mare și va fi alegerea noastră obișnuită atunci când avem nevoie de valori reale.


int vs. double la împărțire

Aici apare una dintre cele mai importante diferențe dintre cele două tipuri.

Să avem:

int a = 5;
int b = 2;

Dacă efectuăm:

a / b

rezultatul este:

2

nu:

2.5

De ce?

Pentru că ambii operanzi sunt de tip int:

int / int
     ↓
împărțire întreagă
     ↓
     2

Partea zecimală este eliminată.


Dacă apare un double

Să schimbăm tipul uneia dintre valori:

double a = 5;
int b = 2;

Acum:

a / b

produce:

2.5

Putem reține regula astfel:

int / int
→ împărțire întreagă

int / double
double / int
double / double
→ împărțire reală

De reținut: Dacă ambii operanzi sunt int, împărțirea este întreagă. Dacă cel puțin unul este double, împărțirea este reală.


Atenție la tipul expresiei

Să analizăm:

int a = 5;
int b = 2;

double rezultat = a / b;

Am putea crede că:

rezultat = 2.5

deoarece rezultat este double.

Dar nu se întâmplă așa.

Mai întâi este calculată expresia:

a / b

Cum a și b sunt int:

5 / 2
  ↓
  2

Abia apoi rezultatul este memorat în variabila rezultat:

2 → 2.0

Prin urmare:

rezultat = 2.0

Important: Tipul variabilei în care memorăm rezultatul nu schimbă modul în care expresia a fost deja calculată.


Cum obținem rezultatul real?

Putem transforma unul dintre operanzi în double:

int a = 5;
int b = 2;

double rezultat = (double)a / b;

Acum avem:

(double)a / b
     ↓
   5.0 / 2
     ↓
     2.5

Această transformare se numește conversie de tip.

Pentru moment este suficient să recunoști forma:

(double)a

și să știi că valoarea lui a este tratată ca double în expresia respectivă.


char — un singur caracter

Tipul char este folosit pentru memorarea unui singur caracter.

De exemplu:

char litera = 'A';
char cifra = '7';
char semn = '+';

Valorile de tip char se scriu între apostrofuri:

'A'
'7'
'+'

Caracterul '7' nu este numărul 7

Este foarte important să facem diferența dintre:

char c = '7';

și:

int x = 7;

În primul caz avem:

'7' → caracter

În al doilea:

7 → număr întreg

Așadar:

'7' și 7 nu reprezintă același lucru

Calculatorul reprezintă intern caracterele prin coduri numerice. Vom folosi această proprietate mai târziu, când vom lucra cu șiruri de caractere.

Pentru moment este suficient să reții:

'A' → caracter
'7' → caracter
7   → număr

bool — adevărat sau fals

Uneori vrem să memorăm dacă o anumită situație este adevărată sau falsă.

Pentru aceasta putem folosi tipul:

bool

Acesta are două valori:

true
false

De exemplu:

bool gasit = false;

Mai târziu valoarea poate deveni:

gasit = true;

Putem privi o variabilă bool ca pe un indicator:

true  → DA
false → NU

De exemplu, nume precum:

bool gasit;
bool prim;
bool exista;

sugerează că vrem să memorăm dacă o anumită proprietate este adevărată sau falsă.

Vom vedea cum folosim astfel de variabile după ce învățăm condițiile și structurile de control.


Cum alegem tipul potrivit?

Putem porni de la două întrebări:

1. Ce fel de valoare trebuie să memorez?

număr întreg      → int / long long
număr real        → double
caracter           → char
adevărat / fals   → bool

2. Cât de mare poate deveni valoarea?

Pentru numerele întregi:

până în zona lui 10⁹
→ int

mai mare decât limita lui int,
dar în zona lui 10¹⁸
→ long long

De exemplu:

n ≤ 100 000

→

int n;

Dar:

n ≤ 10¹²

→

long long n;

Dacă avem o valoare reală:

double medie;

Un caracter:

char litera;

O situație adevărat/fals:

bool gasit;

Alegerea tipului pornește de la ce vrem să memorăm și ce valori pot apărea în program.


Recapitulare

Din această lecție trebuie să reții în primul rând:

int        → numere întregi
long long  → numere întregi mai mari
double     → numere reale
char       → un caracter
bool       → true / false

Pentru numere întregi, limitele utile de reținut sunt aproximativ:

int        → ±2 × 10⁹
long long  → ±9 × 10¹⁸

Nu te uita doar la valoarea citită. Verifică și cât de mari pot deveni rezultatele calculelor.

Foarte important

La împărțire:

int / int
→ împărțire întreagă

cel puțin un operand double
→ împărțire reală

De exemplu:

5 / 2

produce:

2

iar:

(double)5 / 2

produce:

2.5

De asemenea:

double rezultat = 5 / 2;

nu produce 2.5.

Expresia 5 / 2 este calculată mai întâi ca împărțire întreagă, deci în rezultat ajunge valoarea 2.0.

Alte diferențe de recunoscut

'7' → caracter
7   → număr

true / false → valori de tip bool

Pentru bacul la info: alegerea corectă între int și long long și înțelegerea împărțirii dintre valori int sunt mult mai importante decât memorarea tuturor tipurilor existente în C++. Urmărește întotdeauna tipurile valorilor și rezultatul pe care îl poate produce o expresie.