Prima pagină > Tutoriale C++ > Capitolul 6: Tipuri fundamentale de date

Capitolul 6: Tipuri fundamentale de date


Tipuri fundamentale de date

6.1 Declaratii si expresii

Variabilele si constantele sunt obiecte cu care se lucreaza intr-un program. In C, toate variabilele trebuie declarate inainte de a fi folosite. Declaratiile au doua scopuri:
1. spun compilatorului cat spatiu de memorie trebuie rezervat pentru memorarea acelor variabile;
2. permit compilatorului sa instruiasca masina pentru a face operatiile specifice corect.

De exemplu, in expresia a + b, operatorul + este aplicat pentru doua variabile. Masina executa in mod diferit adunarea pentru variabile de tip „int” si pentru variabile de tip „float”. Bineinteles, pentru programator aceste conventii sunt transparente (se mai spune ca „+” este operator de supraincarcare). Expresiile sunt combinatii (cu inteles) de constante, variabile si apeluri de functii. Majoritatea expresiilor (cum ar fi, de exemplu, variabilele) au si valoare si tip. In multe situatii, valoarea returnata depinde in principal de tipul expresiei.

6.2 Tipuri fundamentale de date

Avem urmatoarele tipuri fundamentale de date (scriere intreaga – lunga):

char |signed char |unsigned char

signed short int | signed int |signed long int

unsigned short int |unsigned int |unsigned long int

float double | long double
Toate acestea sunt cuvinte rezervate, deci nu se pot folosi ca nume de variabile. Alte tipuri de date, cum ar fi vectorii si pointerii, sunt derivate din tipurile fundamentale.
De obicei, cuvantul rezervat „signed” nu se mai scrie. De exemplu, „signed int” este echivalent cu „int”. De asemenea, cuvintele „short int”, „long int” si „unsigned int” pot fi prescurtate, de obicei, ca „short”, „long” si „unsigned”. Cu aceste conventii, tabelul de mai sus se mai poate scrie:
char signed | char unsigned char short |int long |unsigned short | unsigned unsigned long |float double |long double
Tipurile fundamentale se pot grupa dupa functionalitate:
1. tipurile integrale sunt cele care sunt folosite pentru reprezentarea valorilor intregi;
2. tipurile reale sunt cele care sunt folosite pentru reprezentarea valorilor reale;
3. tipurile aritmetice sunt tipuri integrale sau reale.

Acestea sunt:
Tipuri integrale:
– char signed char unsigned char
– short int long
– unsigned short unsigned unsigned long
Tipuri reale:
-float double,
long double

6.3 Caractere si tipul „char”

In C, variabilele de orice tip integral pot fi folosite pentru reprezentarea caracterelor. In particular, variabilele de tip „char” si „int” se folosesc pentru acest scop. Am vazut in capitolul precedent ca atunci cand dorim sa comparam o variabila cu EOF, atunci trebuie sa declaram acea variabila de tip „int”, si nu de tip „char”. Constante cum ar fi ‘a’, ‘+’ pe care le gandim ca fiind caractere sunt de tip „int”, si nu de tip „char”. Retineti ca nu exista constante de tip „char” !!!
Reamintim ca toate caracterele sunt tratate ca „intregi mici”, si reciproc, intregii mici sunt tratati ca niste caractere. In particular, orice expresie integrala poate fi afisata in format intreg sau caracter.

Exemplu: Presupunem ca avem o „bucata” de cod C:

char c = ‘a’; /* ‘a’ are codul ASCII 97 */
int i = 65; /* 65 este codul ASCII pentru ‘A’ */

printf(„%c”, c + 1); /* este afisat b */
printf(„%d”, c + 2); /* este afisat 99 */
printf(„%c”, i + 3); /* este afisat D */
In C, fiecare caracter este memorat pe un octet de memorie. Pe aproape toate masinile, un octet este compus din 8 biti. Fie declaratia char c = ‘a’;
Putem gandi ca „c” este memorat pe un octet astfel

| 0 | 1 | 1 | 0 | 0 | 0 | 0 | 1 |
7 6 5 4 3 2 1 0

Fiecare celula reprezinta un bit si fiecare bit este numerotat (incepand cu cel mai putin semnificativ). Bitii care formeaza un octet sunt fie „on”, fie „off”, aceste stari fiind reprezentate prin 1 si 0 respectiv. Acesta ne conduce sa gandim fiecare octet din memorie ca un sir de 8 cifre binare (se mai numesc siruri de biti).
Astfel variabila „c” poate fi gandita ca sirul de biti 01100001.
Mai general, fiecare cuvant masina poate fi gandit ca un sir de cifre binare grupate in octeti.
Un sir de cifre binare poate fi deci gandit ca un numar binar (adica in baza 2). Fara a intra in detalii matematice (teorema bazei de numeratie) vom face doar un exemplu:

Exemplu:

Valoarea lui „c” este numarul 01100001 (in baza 2)= 1 x 2^6 + 1 x 2^5 + 0 x 2^4 + 0 x 2^3 + 0 x 2^2 + 0 x 2^1 + 1 x 2^0 care inseamna 64 + 32 + 1 = 97 in notatia zecimala (in baza 10). ANSI C pune la dispozitie trei tipuri referitoare la caractere:
char signed char unsigned char.
De obicei, tipul „char” este echivalent cu „signed char” sau „unsigned char”, depinzand de compilator. Fiecare din aceste trei tipuri se memoreaza pe un octet (deci poate „tine” 256 valori distincte). Pentru „signed char”, valorile sunt intre -128 si 127, iar pentru „unsigned char” intre 0 si 255.

6.4 Tipul de date „int”

Tipul de date „int” este cel mai folosit tip din limbajul C. Acest tip, impreuna cu alte tipuri integrale (cum ar fi: „char”, „short” si „long”) este desemnat pentru lucrul cu valori intregi reprezentabile pe o masina.
In matematica, numerele naturale sunt 0, 1, 2, 3, …, care impreuna cu cele negative (corespunzatoare) formeaza numerele intregi. Pe o masina, se pot reprezenta (folosind un tip integral) numai o submultime finita a acestor numere.
De obicei, un cuvant se memoreaza pe un cuvant masina. Anumite calculatoare folosesc cuvante de 2 octeti (=16 biti), altele 4 octeti (=32 biti).

Exemple:

1. Masini ce folosesc cuvinte memorate pe 2 octeti: PC
2. Masini ce folosesc cuvinte memorate pe 4 octeti: Apollo, Hewlett-Packard, Next, Silicon Graphics, Sun, etc.

Presupunem ca lucram pe un calculator care lucreaza pe 4 octeti. Aceasta implica ca un cuvant are 32 biti, deci poate „tine” 2^{32} valori distincte. Jumatate sunt folosite pentru reprezentarea numerelor negative si cealalta jumatate pentru pozitive:
– 2^{31}, -2^{31}+1,…, -2, -1, 0, 1, 2, …, 2^{31}-1
Daca lucram pe un calculator unde memorarea unui cuvant se face pe 2 octeti, atunci putem memora 2^{16} valori distincte.
Valoarea cea mai mare, a tipului „int” este data de constanta MAXINT. Evident cea mai mica valoare va fi -MAXINT-1.
Daca se incearca, de exemplu, adunarea a doua numere (si se depaseste aceasta valoare), atunci se va primi un mesaj „integer overflow”.

6.5 Tipurile integrale „short”, „long” si „unsigned”

De obicei, tipul „short” se memoreaza pe doi octeti si tipul „long” pe patru octeti. Astfel, pe masinile in care cuvintele au patru octeti, lungimea tipului „int” este aceeasi cu lungimea tipului „long”, iar pe masinile in care cuvintele au doi octeti, lungimea tipului „int” este egala cu lungimea tipului „short”. Constantele predefinite MAXSHORT si MAXLONG (in unele implementari LONG_MAX) caracterizeaza lungimea acestor tipuri. De obicei, MAXSHORT=2^{15} si MAXLONG=2^{31}. Astfel, daca „s” este o variabila de tip „short”, atunci – MAXSHORT <= s <= MAXSHORT-1.
Daca „l” este o variabila de tip „long”, atunci – MAXLONG <= s <= MAXLONG-1.
In ceea ce priveste tipul „unsigned”, acesta este memorat pe acelasi numar de octeti ca si tipul „int”. Daca „u” este o variabila de tip „unsigned”, atunci 0 <= u <= 2*MAXINT-1

6.6 Tipuri reale

ANSI C contine trei tipuri reale: „float”, „double” si „long double”. Variabilele de acest tip vor putea tine valori reale, cum ar fi: 0.001 2.0 3.14159.
Aceasta notatie se numeste notatie zecimala, deoarece contine punctul zecimal. Mai exista si notatia exponentiala. De exemplu, 1.234567e5 corespunde cu 1.234567 x 10^5=123456.7
Pe majoritatea masinilor, tipul „float” se memoreaza pe 4 octeti, iar tipul „double” pe 8 octeti. Asta inseamna ca o variabila de tipul „float” poate avea 6 zecimale, iar o variabila de tipul „double” poate avea 15 zecimale. Astfel, o variabila de tipul „float” are forma:
0,d_1 d_2 d_3 d_4 d_5 d_6 x 10^{n} unde -38 <= n <= 38.
Asemanator, o variabila de tipul „double” are forma
0,d_1 d_2 … d_{15} x 10^{n} unde -308 <= n <= 308.
Astfel, instructiunea
x = 123.45123451234512345; /* 20 cifre semnificative */
va implica atribuirea lui x a valorii
0.123451234512345 x 10^3 (15 cifre semnificative)
In ANSI C, pentru varibilele de tip „long double” se aloca mai multa memorie. Insa sunt compilatoare care trateaza acest exact tip exact ca si „double”.

6.7 Operatorul „sizeof()”

C pune la dispozitie operatorul „sizeof()” pentru determinarea numarului de octeti necesari memorarii unui obiect. Acesta are aceeasi prioritate si asociativitate ca si ceilalti operatori unari. O expresie de forma sizeof(obiect) returneaza un intreg car reprezinta numarul de octeti necesari pentru memorarea obiectului in memorie. Un obiect poate fi un tip, cum ar fi „int” sau „float”, sau poate fi o expresie, cum ar fi a + b, sau poate fi un sir sau o structura.

Exemplu: Calculul numarului de octeti pentru cateva tipuri

#include
main()
{
printf(„Lungimea catorva tipuri fundamentale.\n\n”);
printf(” char:%3d octeti \n”, sizeof(char));
printf(” short:%3d octeti \n”, sizeof(short));
printf(” int:%3d octeti \n”, sizeof(int));
printf(” long:%3d octeti \n”, sizeof(long));
printf(” unsigned:%3d octeti \n”, sizeof(unsigned));
printf(” float:%3d octeti \n”, sizeof(float));
printf(” double:%3d octeti \n”, sizeof(double));
printf(„long double:%3d octeti \n”, sizeof(long double));
}

Din moment ce limbajul C este flexibil in ceea ce priveste necesarul de memorie pentru tipurile fundamentale, situatiile pot sa difere de la o masina la alta. Totusi, aceasta garanteaza ca:
– sizeof(char) = 1
– sizeof(short) <= sizeof(int) <= sizeof(long)
– sizeof(signed) <= sizeof(unsigned) <= sizeof(int)
– sizeof(float) <= sizeof(double) <= sizeof(long double)
„sizeof()” nu este o functie (chiar daca contine paranteze atunci cand ne referim la tipuri), ci este un operator. De
Exemplu:
sizeof(a + b + 7.7) este echivalent cu sizeof a + b + 7.7

6.8 Functii matematice

Nu exista functii matematice implicite (in compilatorul C), ci acestea sunt descrise in biblioteci. De exemplu, functiile sqrt() pow() exp() log() sin() cos() tan() sunt definite in biblioteca . Toate aceste functii, cu exceptia lui „power()” au un argument de tip „double” si returneaza o valoare de tip „double”. Functia „power()” are doua argumente de tip „double” si returneaza o valoare de tip „double”.

6.9 Conversii implicite si explicite

O expresie aritmetica, cum ar fi „x + y”, are si valoare si tip. De exemplu, daca „x” si „y” au tipul „int”, atunci expresia „x + y” are tipul „int”. Dar, daca „x” si „y” au ambele tipul „short”, atunci „x + y” este de tip „int”, si nu „short”. Aceasta se intampla deoarece in orice expresie, „short” se converteste la „int”.

6.10 Conversia la intreg

Un „char” sau „short”, ori „signed” sau „unsigned”, ori un tip enumerare (vom reveni) poate fi folosit in orice expresie unde poate fi folosit „int” sau „unsigned int”. Daca toate valorile tipului original pot fi reprezentate de un „int”, atunci valoarea acesteia se va converti la „int”; altfel se va converti la „unsigned int”. Aceasta se numeste „conversie la intreg”.

Exemplu:

char c = ‘A’;
printf(„%c\n”, c);

Variabila „c” apare ca argument al functiei „printf()”. Cu toate acestea, deoarece are loc conversia la intreg, tipul expresiei „c” este „int”, si nu „char”.

6.11 Conversiile aritmetice uzuale

Conversiile aritmetice pot apare cand sunt evaluati operanzii unui operator binar.

Exemplu:

Presupunem ca „i” este „int” si „f” este un „float”. In expresia „i + f”, operandul „i” se converteste la „float” si deci expresia „i + f” va intoarce tipul „float”.
Aceste reguli se numesc „conversii aritmetice uzuale”. Iata urmatorul „algoritm”:
– daca un operand este de tip „long double” atunci si celalalt operand va fi convertit la tipul „long double” altfel daca un operand este de tip „double” atunci si celalalt operand va fi convertit la tipul „double” altfel daca un operand este de tip „float” atunci si celalalt operand va fi convertit la tipul „float” altfel
/***** au loc conversiile la intreg *****/
– daca un operand este de tip „unsigned long” atunci si celalalt operand va fi convertit la tipul „unsigned long” altfel daca un operand are tipul „long” si celalalt „unsigned” atunci:
– daca un „long” poate reprezenta toate valorile „unsigned” atunci operandul de tip „unsigned” se va converti la „long”
– daca un „long” nu poate reprezenta toate valorile „unsigned” atunci ambii operanzi se vor converti la „unsigned long” altfel
– daca un operand are tipul „long” atunci celalalt operand se converteste la „long” altfel daca un operator are tipul „unsigned” atunci celalalt operand va fi convertit la „unsigned” altfel ambii operanzi vor avea tipul „int”.

Exemplu: Presupunem ca avem declaratiile:

– char c;
– short s;
– int i;
– unsigned u;
– unsigned long ul;
– float f;
– double d;
– long double ld;

Atunci avem urmatoarele valori pentru tipurile expresiilor de mai jos:

Expresie
Tip
Expresie
Tip
c – s / i
int
u * 7 – i
unsigned
u * 2.0 – i
double
f * 7 – i
float
c + 3
int
7 * s * ul
unsigned long
c + 5.0
double
ld + c
long double
d + s
double
u – ul
unsigned long
2 * i / l
long
u – l
dependent de sistem

6.12 Conversii explicite

Daca „i” este de tip „int”, atunci (double) i va converti valoarea lui „i” astfel incat expresia sa aiba tipul „double”. Variabila „i” ramane neschimbata. Conversiile se pot aplica si expresiilor.

Exemple:

(long) (‘A’ + 1.0)
x = (float) ((int) y + 1)
(double) (x = 77)

Operatorul de conversie de tip (cast) este un operator unar care are aceeasi prioritate si asociativitate (de la dreapta la stanga) ca alti operatori unari.

Exemplu:

Expresia (float) i + 3 este echivalenta cu ((float) i) + 3 pentru ca operatorul „cast” are prioritate mai mare decat „+”.

6.13 Erori de programare frecvente

Presupunem ca suntem pe o masina care lucreaza folosind cuvinte memorate pe doi octeti. Consideram urmatorul exemplu:

Exemplu:

int a = 1, b = 1776, c = 32000;
printf(„%d\n”, a + b + c); /* eroare: va fi afisat -31759 */
Un mod de a repara aceasta greseala este inlocuirea instructiunii „printf()” cu:
printf(„%d\n”, (long) a + b + c); /* va fi afisat 33777 */

Categorii:Tutoriale C++
  1. Niciun comentariu până acum.
  1. No trackbacks yet.

Lasă un răspuns

Completează mai jos detaliile despre tine sau dă clic pe un icon pentru autentificare:

Logo WordPress.com

Comentezi folosind contul tău WordPress.com. Dezautentificare / Schimbă )

Poză Twitter

Comentezi folosind contul tău Twitter. Dezautentificare / Schimbă )

Fotografie Facebook

Comentezi folosind contul tău Facebook. Dezautentificare / Schimbă )

Fotografie Google+

Comentezi folosind contul tău Google+. Dezautentificare / Schimbă )

Conectare la %s

%d blogeri au apreciat asta: