Date in limbajul C++


    Asa cum s-a vazut în lectiile anterioare un program realizeaza o prelucrare de informatie. Termenul de prelucrare trebuie sa fie considerat într-un sens foarte general (de exemplu prelucrarea sepoate  referi la un text si consta în afisarea lui). În program datele apar fie sub forma unor constante (valori cunoscute anticipat, care nu se modific?), fie sub forma de variabile. Constantele si variabilele sunt obiectele informationale de baza manipulate într-un program.

    Fiecare categorie de date este caracterizata de atributele:

  • Nume;
  • Valoare;
  • Tip;
  • Clasa de memorare.

    De primele trei tipuri de atribute ne vom ocupa în continuare, urmând ca de atributul clasa de memorare sa ne ocupam mai tarziu.

    Numele unei date
    Numele unei date este un identificator si, ca urmare, trebuie sa respecte regulile specifice identificatorilor. Deasemenea, numarul de caractere care intra în compunerea unui identificator este nelimitat, însa, implicit, numai primele 32 de caractere sunt luate în considerare. Aceasta înseamna ca doi identificatori care au primele 32 de caractere identice, diferentiindu-se prin caracterul 33, vor fi considerati identici.
 

    Tipul unei date
    Tipul unei date consta într-o multime de valori pentru care s-a adoptat un anumit mod de reprezentare în memoria calculatorului si o multime de operatori care pot fi aplicati acestor valori. Tipul unei date determina lungimea zonei de memorie ocupata de acea data. În general, lungimea zonei de memorare este dependenta de calculatorul pe care s-a implementat compilatorul.

    Tipurile de baza sunt:  intregi si reale

Intregi:

reale

    In completare exista un numar de calificatori, care se pot aplica tipurilor de baza char, int, float sau double: short, long, signed si unsigned. Astfel, se obtin tipurile derivate de date. Short si long se refera la marimea diferita a intregilor, iar datele de tip unsigned int sunt intotdeauna pozitive. S-a intentionat ca short si long sa furnizeze diferite lungimi de intregi, int reflectand marimea cea mai "naturala" pentru un anumit calculator. Fiecare compilator este liber sa interpreteze short si long in mod adecvat propriului hardware; in nici un caz, insa, short nu este mai lung decat long. Toti acesti calificatori pot aplicati tipului int. Calificatorii signed (cel implicit) si unsigned se aplica tipului char. Calificatorul long se aplica tipului double. Daca intr-o declaratie se omite tipul de baza, implicit, acesta va fi int.Tabelul urmator prezinta lungimea zonei de memorie ocupata de fiecare tip de data.

1. TIPURILE INTREGI
 

NUME TIP

DIMENSIUNE IN BITI

DOMENIU

unsigned char

8

0..255

char

8

-128..127

unsigned int

16

0..65535

short int

16

-32768..32767

int

16

-32768..32767

unsigned long

32

0..4294967295

long

32

-2147483648..2147483647

Obs:
a) In C++ nu exista tipul boolean. In acest caz, orice valoare diferita de 0 este considerata ca fiind TRUE si orice valoare 0 este considerata ca fiind FALSE.
b) Tipul caracter este asimilat tipurilor intregi. Memorarea unui caracter se face folosind codul ASCII al acestuia. In operatiile referitoare la caractere ne putem referi atat la caracter cat si la codul sau ASCII (conversia se face automat, in functie de context).
De ex:
    char a='c',b=99;
    cout<<a<<"   "<<b;  //Se tipareste de 2 ori caracterul 'c' (care are codul ASCII 99)
    cout<<a+101;          //Se tipareste 200 (a fost adunat codul ASCII al caracterului 'c' cu 101)

2. TIPURILE REALE
 

NUME TIP

DIMENSIUNE IN BITI

MAXIMA (in valoare absoluta)

float

32

3.4*pow(10,38)

double

64

1.7*pow(10.308)

long double

80

1.1*pow(10,4932)

    In header-ul <values.h> sunt definite constantele simbolice (cum ar fi: MAXINT, MAXSHORT, MAXLONG, MINDOUBLE, MINFLOAT, etc.) care au ca valoare limitele inferioara si superioara ale intervalului de valori pentru tipurile de date enumerate.  (de exemplu MAXINT reprezinta valoarea intregului maxim care se poate memora, etc. )
 
    Fara a detalia foarte mult modul de reprezentare a datelor reale (de tip float sau double), vom sublinia faptul ca, pentru acestea, este importanta si precizia de reprezentare. Deoarece calculatorul poate reprezenta doar o submultime finita de valori reale, in anumite cazuri, pot apare erori importante.
    Numerele reale pot fi scrise sub forma:   N = mantisa   baza unde:baza reprezinta baza sistemului de numeratie; mantisa (coeficientul) este un numar fractionar normalizat ( in fata virgulei se afla 0, iar prima cifra de dupa virgula este diferita de zero); exponentul este un numar intreg. Deoarece forma interna de reprezentare este binara, baza=2. In memorie vor fi reprezentate doar mantisa si exponentul. Numarul de cifre de dupa virgula determina precizia de exprimare a numarului. Ce alte cuvinte, pe un calculator cu o precizie de 6 cifre semnificative, doua valori reale care difera la a 7-a cifra zecimala, vor avea aceeasi reprezentare. Pentru datele de tip float, precizia de reprezentare este 6; pentru cele de tip double, precizia este 14, iar pentru cele de tip long double, precizia este 20.
Lungimea zonei de memorie ocupate de o data de un anumit tip (pe cati octeti este memorata data) poate fi aflata cu ajutorul operatorului sizeof.
Exemplu:
cout<<"Un int este memorat pe "<<sizeof(int)<<"octeti.\n";
Instructiunea are ca efect afisarea pe monitor a mesajului: Un int este memorat pe 2 octeti.

 

 

Tabelul 2.1.

 

 

Tip

Lungimea zonei de memorie ocupate (în biţi)

Descriere

 

MS-DOS

UNIX

LINUX

 

char

8

8

Valoarea unui singur caracter; poate fi întâlnit în expresii cu extensie de semn

unsigned char

8

8

Aceeaşi ca la char, fară extensie de semn

signed char

8

8

Aceeaşi ca la char, cu extensie de semn obligatorie

int

16

32

Valoare întreagă

long

32

64

Valoare întreagă cu precizie mare

(long int)

 

 

 

long long int

32

64

Valoare întreagă cu precizie mare

short int

16

32

Valoare întreagă cu precizie mică

unsigned int

16

32

Valoare întreagă, fără semn

unsigned long int

32

64

Valoare întreagă, fără semn

float

32

32

Valoare numerică cu zecimale, simplă precizie (6 )

double

64

64

Valoare numerică cu zecimale, dublă precizie (10 )

long double

80

128

Valoare numerică cu zecimale, dublă precizie

 

 

    Constante
    O constanta este un literal (o forma externa de reprezentare) numeric, caracter sau sir de caractere. Numele si valoarea unei constante sunt identice. Valoarea unei constante nu poate fi schimbata in timpul executiei programului in care a fost utilizata. Tipul si valoarea ei sunt determinate in mod automat, de catre compilator, pe baza caracterelor care compun literalul.

    Constante intregi

Constantele intregi sunt literali numerici (compusi din cifre), fara punct zecimal.

Exemple:
  45
 -78 // constante intregi decimale (in baza 10), tip int
 Constante intregi octale
Daca in fata numarului apare cifra zero (0), acest lucru indica faptul ca acea constanta este de tipul int, in baza opt (constanta octala).
Exemple:
056
 077 // constante intregi octale, tip int
 Constante intregi hexagesimale
Daca in fata numarului apar caracterele zero (0) si x (sau X), acest lucru indica faptul ca acea constanta este de tipul int, in baza 16 (constanta hexagesimala). Amintim ca in baza 16 cifrele sunt: 0-9, A (sau a) cu valoare 10, B (sau b) cu valoare 11, C (sau c) cu valoare 12, D (sau d) cu valoare 13, E (sau e) cu valoare 14, F (sau f) cu valoare 15.
Exemple:
0x45
 0x3A
 0Xbc // constante intregi hexagesimale, tip int
 Constante intregi, de tipuri derivate
 Daca secventa de cifre este urmata de L sau l, tipul constantei este long int.
Exemple:
145677L
 897655l // tip decimal long int
Daca secventa de cifre este urmata de U sau u, tipul constantei este unsigned int.
Exemple:
65555u
Daca secventa de cifre este urmata de U (u) si L (l), tipul constantei este unsigned long int.
Exemple: 7899UL //tip decimal unsigned long int

    Constante numerice, reale

Daca o constanta numerica contine punctul zecimal, ea este de tipul double.
Exemplu:
3.1459  //tip double
Daca numarul este urmat de F sau f, constante este de tip float.
Daca numarul este urmat de L sau l, este de tip long double.
Exemplu:
0.45f  //tip float
 9.788L //tip long double
Constante reale in format stiintific
Numarul poate fi urmat de caracterul e sau E si de un numar intreg, cu sau fara semn. In acest caz, constanta este in notatie stiintifica. In aceasta forma externa de reprezentare, numarul din fata literei E reprezinta mantisa, iar numarul intreg care urmeaza caracterului E reprezinta exponentul. In forma externa de reprezentare, baza de numeratie este 10, deci valoarea constantei va fi data de mantisa 10 .
Exemplu:
1.5e-2 //tip double, in notatie stiintifica, valoare 1.5*10-2

Exercitiu:  Sa se scrie urmatorul program si sa se urmareasca rezultatele executiei acestuia.
#include <iostream.h>
#include <values.h>
#define PI  3.14359
int main()
{
cout<<"Tipul int memorat pe: "<<sizeof(int)<<" octeti\n";
cout<<"Tipul int memorat pe: "<<sizeof(23)<<" octeti\n"; //23-const. zecimala int
cout<<"Int maxim="<<MAXINT<<’\n’;
//const. simbolice MAXINT, MAXLONG, etc. - definite in <values.h>
cout<<"Const. octala 077 are val decimala:"<<077<<’\n;
cout<<"Const. hexagesimala d3 are val decimala:"<<0xd3<<’\n’;
cout<<"Tipul unsigned int memorat pe:"<<sizeof(unsigned int)<<" octeti\n";
cout<<"Tipul unsigned int memorat pe: "<<sizeof(23U)<<" octeti\n";
cout<<"Tipul unsigned int memorat pe: "<<sizeof(23u)<<" octeti\n";
cout<<"Tipul long int memorat pe: "<<sizeof(long int)<<" octeti\n";
cout<<"Tipul long int memorat pe: "<<sizeof(23L)<<" octeti\n";
cout<<"Tipul long int memorat pe: "<<sizeof(23l)<<" octeti\n";
//23L sau 23l-const. decimala long int
cout<<"Long int maxim="<<MAXLONG<<’\n’;
cout<<"Tipul unsigned long memorat pe:";
cout<<sizeof(unsigned long int)<<" octeti\n";
cout<<"Tipul unsigned long memorat pe: "<<sizeof(23UL)<<" octeti\n";
cout<<"Tipul unsigned long memorat pe: "<<sizeof(23ul)<<" octeti\n";
//23UL sau 23ul-const. decimala unsigned long int
cout<<"Tipul long long int memorat pe: ";
cout<<sizeof(long long int)<<" octeti\n";
cout<<"Tipul long long int memorat pe: "<<sizeof(d)<<" octeti\n";
cout<<"Tipul short int memorat pe: "<<sizeof(short int)<<" octeti\n";
cout<<"Short int maxim="<<MAXSHORT<<’\n’;
cout<<"Tipul float memorat pe: "<<sizeof(float)<<" octeti\n";
cout<<"Tipul float memorat pe: "<<sizeof(23.7f)<<" octeti\n";
//23.7f-const. decimala float
cout<<"Float maxim="<<MAXFLOAT<<’\n’;
cout<<"Float minim="<<MINFLOAT<<’\n’;
cout<<"Tipul double memorat pe: "<<sizeof(double)<<" octeti\n";
cout<<"Tipul double memorat pe: "<<sizeof(23.7)<<" octeti\n";
//23.7-const. decimala double
cout<<"Const. decim. doubla in notatie stiintifica:"<<23.7e-5<<’\n’;
cout<<”Const. PI este:”<<PI<<’\n’;
cout<<”Constanta PI este memorata pe:”<<sizeof(PI)<<”octeti\n”:
cout<<"Double maxim="<<MAXDOUBLE<<’\n’<<"Double minim="<<MINDOUBLE<<’\n’;
cout<<"Tipul long double memorat pe: "<<sizeof(long double)<<" octeti\n";
cout<<"Tipul long double memorat pe: "<<sizeof(23.7L)<<" octeti\n";
//23.7L-const. decimala long double
cout<<"Cifra A din HEXA are val.:"<<0xA<<"\n";
cout<<"Cifra B din HEXA are val.:"<<0XB<<"\n";
cout<<"Cifra C din HEXA are val.:"<<0xc<<"\n";
cout<<" Cifra D din HEXA are val.:"<<0xD<<"\n";
cout<<" Cifra E din HEXA are val.:"<<0XE<<"\n";
cout<<" Cifra F din HEXA are val.:"<<0xf<<"\n";
cout<<"Val. const. hexa 0x7ac1e este: "<<0x7ac1e<<'\n';
cout<<"Val. const. octale 171 este: "<<0171<<'\n';
cout<<"O const. octala se memoreaza pe "<<sizeof(011)<<" octeti\n";
cout<<"O const.oct.long se mem pe ";cout<<sizeof(011L)<<" octeti\n";}

Constante caracter

Constantele caracter sunt incadrate intre apostroafe.
Exemplu:
'a'  //tip char
O constanta caracter are ca valoare codul ASCII al caracterului pe care il reprezinta.
Acest set de caractere are urmatoarele proprietati:
Fiecarui caracter ii corespunde o valoare intreaga distincta (ordinala);
Valorile ordinale ale literelor mari sunt ordonate si consecutive ('A' are codul ASCII 65, 'B' - codul 66, 'C' - codul 67, etc.);
Valorile ordinale ale literelor mici sunt ordonate si consecutive ('a' are codul ASCII 97, 'b' - codul 98, 'c' - codul 99, etc.);
Valorile ordinale ale cifrelor sunt ordonate si consecutive ('0' are codul ASCII 48, '1' - codul 49, '2' - codul 50, etc.).
 Constante caracter corespunzatoare caracterelor imprimabile
O constanta caracter corespunzatoare unui caracter imprimabil se reprezinta prin caracterul respectiv inclus intre apostroafe.
Exemplu:
Constanta caracter  Valoare
  ‘A’   65
  ‘a’   97
  ‘0’   48
  ‘*’   42
Exceptii de la regula de mai sus le constituie caracterele imprimabile apostrof (') si backslash (\).
Caracterul backslash se reprezinta: '\\'. Caracterul apostrof se reprezinta: '\''.

 Constante caracter corespunzatoare caracterelor neimprimabile
Pentru caracterele neimprimabile, se folosesc secvente escape. O secventa escape furnizeaza un mecanism general si extensibil pentru  reprezentarea caracterelor invizibile sau greu de obtinut.  In continuoare sunt prezentate cateva caractere escape utilizate frecvent:

‘\n’ 10 LF rand nou (Line Feed)
‘\t’ 9 HT tabulator orizontal
‘\r’ 13 CR pozitioneaza cursorul in coloana 1 din randul curent
‘\f’ 12 FF salt de pagina la imprimanta (Form Feed)
‘\a’ 7 BEL activare sunet
O constanta caracter pentru o secventa escape poate apare insa, si sub o forma in care se indica codul ASCII, in octal, al caracterului dorit:
  ’\ddd’  unde d este o cifra octala.
Exemple:
 ’\11’ (pentru ’\t’)
reprezinta constanta caracter backspace, cu codul 9 in baza 10, deci codul 11 in baza 8.
 ’\15’ (pentru ’\r’)
reprezinta constanta caracter CR, cu codul 13 in baza 10, deci codul 11 in baza 8.

Exercitiu:  Sa se scrie urmatorul program si sa se urmareasca rezultatele executiei acestuia.
#include <iostream.h>
void main(void)
{
cout<<"Un caracter este memorat pe "<<sizeof(char)<<" octet\n";
cout<<"Caracterul escape \\n este memorat pe ";
cout<<sizeof('\n')<<" octet\n";
cout<<"Caracterul escape '\\n\' este memorat pe "<<sizeof('\n');
cout<<" octet\n";
cout<<"Caracterul '9' este memorat pe "<<sizeof('9')<<" octet\n";
cout<<'B';cout<<' ';cout<<'c';cout<<'\t';
cout<<'\t';cout<<'9';cout<<'\b';cout<<'\a';
cout<<'L';cout<<'\v';cout<<'L';
cout<<'\'';cout<<'\t';cout<<'\"';cout<<'\\';cout<<'\n';
cout<<'\a';cout<<'\7';
}

     Constante sir de caractere

    Constanta sir este o succesiune de zero sau mai multe caractere, incadrate de ghilimele. In componenta unui sir de caractere, poate intra orice caracter, deci si caracterele escape. Lungimea unui sir este practic nelimitata. Daca se doreste continuarea unui sir pe randul urmator, se foloseste caracterul backslash.

    Caracterele componente ale unui sir sunt memorate intr-o zona continua de memorie (la adrese succesive). Pentru fiecare caracter se memoreaza codul ASCII al acestuia. Dupa ultimul caracter al sirului, compilatorul plaseaza automat caracterul NULL (\0), caracter care reprezinta marcatorul sfarsitului de sir. Numarul de octeti pe care este memorat un sir va fi, deci, mai mare cu 1 decat numarul de caractere din sir.
Exemple:
”Acesta este un sir de caractere” //constanta sir memorata pe 32 octeti
”Sir de caractere continuat\”
 pe randul urmator!”   //constanta sir memorata pe 45 octeti
 ”Sir \t cu secvente escape\n”  //constanta sir memorata pe 26 octeti
 ’\n’      //constanta caracter memorata pe un octet
 ”\n” //constanta sir memorata pe 2 octeti (codul caracterului escape si terminatorul de sir)
 ”a\a4”  /*Sir memorat pe 4 octeti:
      Pe  primul  octet: codul  ASCII al  caracterului a
      Pe  al doilea  octet: codul  ASCII al  caracterului escape \a
      Pe al treilea octet: codul ASCII al caracterului 4
      Pe al  patrulea octet:  terminatorul de sir NULL, cod ASCII 0 */
 ”\\ASCII\\”  /*Sir memorat pe 8 octeti:
Pe primul octet: codul  ASCII al  caracterului backslah
Pe  al doilea   octet:  codul   ASCII   al   caracterului A
Pe  al  treilea  octet:  codul  ASCII    al   caracterului S
Pe al   patrulea octet: codul ASCII al caracterului S
Pe al  6-lea  octet:  codul  ASCII  al  caracterului  I
Pe al  7-lea  octet:  codul  ASCII  al  caracterului  I
Pe  al  8-lea  octet:  codul   ASCII   al  caracterului backslah
Pe al 9-ea octet: terminatorul de sir NULL, de cod ASCII 0 */
 ”1\175a”  /*Sir memorat pe 4 octeti:
Primul octet: Codul ASCII al caracterul 1
Al 2-lea  octet:  codul  ASCII 125 (175 in octal) al caracterului }
Al  3-lea  octet:  codul  ASCII  al caracterului a
Al 4-lea  octet: codul ASCII 0 pentru terminatorul sirului */
Exercitiu:  Sa se scrie urmatorul program si sa se urmareasca rezultatele executiei acestuia.
#include <iostream.h>
void main()
{ cout<<"Sirul \"Ab9d\" este memorat pe:"<<sizeof("Ab9d")<<" octeti\n";
cout<<"Sirul \"Abcd\\t\" este memorat pe:"<<sizeof("Abcd\t")<<" octeti\n";
cout<<"Sirul \"\n\" este memorat pe "<<sizeof("\n")<<" octeti\n";
cout<<"Sirul \"\\n\" este memorat pe "<<sizeof("\n")<<" octeti\n";
cout<<"Sirul \"ABCDE\" se memoreaza pe "<<sizeof("ABCDE")<<" octeti\n";}

    Variabile

    Spre deosebire de constante, variabilele sunt date (obiecte informationale) ale caror valori se pot modifica in timpul executiei programului. Si variabilele sunt caracterizate de atributele nume, tip, valoare si clasa de memorare. Variabilele sunt nume simbolice utilizate pentru memorarea valorilor introduse pentru datele de intrare sau a rezultatelor. Daca la o constanta ne puteam referi folosind caracterele componente, la o variabila ne vom referi prin numele ei. Numele unei variabile ne permite accesul la valoarea ei, sau schimbarea valorii sale, daca este necesar acest lucru. Numele unei variabile este un identificator ales de programator. Ca urmare, trebuie respectate regulile enumerate in sectiunea identificatori.

Daca o data nu are legaturi cu alte date (de exemplu, relatia de ordine), vom spune ca este o data izolata. O data izolata este o variabila simpla. Daca datele se grupeaza intr-un anumit mod (in  tablouri - vectori, matrici - sau structuri), variabilele sunt compuse (structurate).

In cazul constantelor, in functie de componenta literalului, compilatorul stabilea, automat, tipul constantei. In cazul variabilelor este necesara specificarea tipului fiecareia, la declararea acesteia. Toate variabilele care vor fi folosite in program, trebuie declarate inainte de utilizare.

    Declararea variabilelor

Modul general de declarare a variabilelor este:

     tip_variabile lista_nume_variabile;

    Se specifica tipul variabilei(lor) si o lista formata din unul sau mai multi identificatori ai variabilelor de tipul respectiv. Intr-un program in limbajul C++, declaratiile de variabile pot apare in orice loc in programul sursa. La declararea variabilelor, se rezerva in memorie un numar de octeti corespunzator tipului variabilei, urmand ca ulterior, in acea zona de memorie, sa fie depusa (memorata, inregistrata) o anumita valoare.
Exemple:
 int i, j;/*declararea var. simple i,  j, de tip int. Se rezerva pentru i si j cate 16 biti (2octeti)*/
 char c;  /* declararea variabilei simple c, de tip char. Se rezerva un octet. */
 float lungime;  /* declararea variabilei simple lungime; se rezerva 4 octeti */

    Initializarea variabilelor in declaratii

    In momentul declararii unei variabile, acesteia i se poate da (asigna, atribui) o anumita valoare. In acest caz, in memorie se rezerva numarul de locatii corespunzator tipului variabilei respective, iar valoarea va fi depusa (memorata) in acele locatii.

    Forma unei declaratii de variabile cu atribuire este:

     tip_variabila  nume_variabila=expresie;

    Se evalueaza expresia, iar rezultatul acesteia este asignat variabilei specificate.
Exemple:
char backslash=’\\’; //declararea si initializarea variabilei simple backslash
 int a=7*9+2; /* declararea variabilei simple a, de tip int si initializarea ei cu valoarea 65*/
 float radiani, pi=3.14;/*declararea variabilei radiani;declararea si initializarea var. pi*/
 short int z=3;   //declararea si initializarea variabilei simple z
 char d=’\011’;
 char LinieNoua=’\n’;
 double x=9.8, y=0;