Documente Academic
Documente Profesional
Documente Cultură
3 VARIABILE
CUPRINS
3 Variabile......................................................................................................................................................2
3.1 Dimensiunea variabilelor....................................................................................................................2
3.1.1Biti si octeti...................................................................................................................................2
3.1.2Determinarea numarului de octeti pentru variabile - operatorul sizeof........................................2
3.1.3 Reprezentarea numerelor in baza 2 (binar)..................................................................................3
3.1.4Reprezentarea numerelor in baza 16 (hexazecimala)...................................................................3
3.1.4.1 Initializarea variabilelor intregi cu valori hexazecimale......................................................4
3.1.4.2 Unde se foloseste reprezentarea hexazecimala....................................................................4
3.1.5Reprezentarea numerelor in baza 8 (octal)...................................................................................5
3.2 Domeniul de viata al variabilelor........................................................................................................5
3.2.1Locul declararii variabilelor si influenta acestuia asupra domeniului de viata............................5
3.2.1.1 Mascarea variabilelor...........................................................................................................6
3.2.1.2 Domeniul de viata al variabilelor si apelul functiilor..........................................................7
3.2.2Calificatorii de context.................................................................................................................8
3.2.2.1 Calificatorul auto.................................................................................................................8
3.2.2.2 Calificatorul register............................................................................................................8
3.2.2.3 Calificatorul extern..............................................................................................................8
3.2.2.4 Calificatorul static................................................................................................................8
3.3 Variabile numerice...............................................................................................................................9
3.3.1Variabile intregi..........................................................................................................................10
3.3.1.1 Calculul dimensiunii necesare pentru stocarea variabilelor intregi pozitive.....................10
3.3.1.2 Procesarea semnului..........................................................................................................10
3.3.1.3 Calificatori de semn...........................................................................................................11
3.3.1.4 Calificatori de marime.......................................................................................................11
3.3.1.5 Limitele variabilelor intregi...............................................................................................11
3.3.1.6 Depasirea limitelor.............................................................................................................13
3.3.2Variabile reale.............................................................................................................................13
3.3.2.1 Tipuri de variabile reale suportate de C++.........................................................................14
3.3.2.2 Moduri de scriere a numerelor reale..................................................................................14
3.3.2.3 Intializarea variabilelor reale.............................................................................................14
3.3.2.4 Testarea egalitatii pentru variabilele reale.........................................................................15
3.3.2.5 Limitele variabilelor reale..................................................................................................16
3.4 Variabile de tip caracter.....................................................................................................................17
3.4.1.1 Afisarea codurilor ASCII pe ecran.....................................................................................17
3.4.1.2 Citirea valorilor tip caracter de la tastatura........................................................................18
3.4.1.3 Categorii de coduri ASCII.................................................................................................18
3.5 Aliasuri de tipuri................................................................................................................................20
3.6 Sumar................................................................................................................................................20
3.7 Intrebari si exercitii...........................................................................................................................21
3.8 Bibliografie.......................................................................................................................................23
1
Adonis Butufei
3 VARIABILE
In acest capitol vom discuta despre:
• Dimensiunea variabilelor: cum se determina dimensiunea variabilelor folosind operatorul sizeof, ce
legatura este intre dimensiunea variabilelor si intervalul de valori cu care lucreaza acea variabila, baze
de numeratie.
• Variabile de tip caracter, codurile ASCII, categorii de caractere si secvente escape.
• Variabile de tip numeric, procesarea semnului, limitele intervalelor de valori pentru fiecare tip de date
standard folosite in C++ si conversia tipurilor de date.
• Domeniul de viata al variabilelor.
#include <iostream>
using namespace std;
int main()
{
cout << sizeof(int) << "\n";
}
2
InfoAcademy Adonis Butufei
3 2 1 0
abcd 10 =a∗10 + b∗10 + c∗10 + d∗10
Exemple:
(0)10=0∗2 1+ 0∗2 0=(00)2
(1)10=0∗21+ 1∗20 =( 01)2
(2)10=1∗21+ 0∗20=(10)2
(3)10=1∗21+ 1∗20=(11)2
1 In literatura de specialitate il putem intalni sub acronimul MSB most significant bit.
2 In literatura de specialitate il putem intalni sub acronimul LSB least significant bit.
3
Adonis Butufei
Exemple:
Zecimal Binar Hexazecimal
74 01001010 4A = 4∗16110∗16 0
Se observa ca plecand de la codurile hexazecimale se poate verifica foarte usor reprezentarea binara.
4
InfoAcademy Adonis Butufei
int main()
{
int total = 0; // Aceasta variabila este accesibila
// in interiorul functiei main.
5
Adonis Butufei
return 0;
}
Daca incercam sa folosim o variabila in afara domeniului ei obtinem o eroare de compilare ca in exemplul
de mai jos:
int main()
{
int total;
for(int i = total; i < 10; i = i + 1)
{
total = total + i;
}
return 0;
}
Recomandare
Pentru reducerea defectelor programelor este bine ca variabilele sa aiba cel mai mic domeniu de viata.
Acesta este un mod defensiv care asigura eliberarea memoriei nefolosite si reduce cuplajul prin date3
care poate crea defecte greu de depistat.
3 Cuplajul prin date apare atunci cand mai multe functii folosesc aceleasi variabile globale.
6
InfoAcademy Adonis Butufei
In linia 6 am declarat o variabila total care are domeniul de viata functia main. Pe linia 9 am definit o alta
variabila total care are ca domeniu de viata acest bloc si blocurile descendente si care mascheaza variabila
total definita in linia 6.
Bucla dintre liniile 11 – 14 lucreaza cu aceasta variabila, Atunci cand se termina executia blocului,
memoria pentru variabila declarata aici este eliberata si rezultatul se pierde.
Mascarea variabilelor poate genera defecte foarte greu de depanat si trebuie evitata. Folosind variabile
cu domenii de viata cat mai mici este usor de identificat acest fenomen.
7
Adonis Butufei
In prima linie am declarat o variabila globala total. Functia sum calculeaza suma parametrilor a si b si
returneaza rezultatul. Functia badsum atribuie rezultatul sumei variabilei globale creand un cuplaj prin
date.
Daca o alta functie schimba valoarea acestei variabile intre punctul de apel si cel in care se foloseste
rezultatul, executia este incorecta.
Parametri transmisi unei functii sunt considerati variabile locale si pot fi folositi ca si cum ar fi fost
declarati in corpul functiei.
4 Se recomanda masurarea precisa a performantei si identificarea portiunilor care necesita optimizarea performantei.
Optimizarea prematura a performantei este o sursa de probleme si poate genera un cod greu de mentiut.
8
InfoAcademy Adonis Butufei
codului.
Variabila globala definita in acest fisier are domeniul de viata in acest fisier, Daca se incearca accesarea ei
din alt fisier folosind o declaratie: extern int variabilaGlobala; se obtine o eroare de compilare.
1: #include <iostream>
2: using namespace std;
3:
4: void ExempluVariabilaStatica()
5: {
6: static int nrApeluri = 1; // Se executa doar la primul apel.
7:
8: cout << "Numarul apelurilor functiei:"
9: << nrApeluri << "\n";
10:
11: nrApeluri = nrApeluri + 1;
12: }
13:
14: int main()
15: {
16: ExempluVariabilaStatica();
17: ExempluVariabilaStatica();
18:
19: return 0;
20: }
In acest exemplu linia 6 se executa doar la prima rulare. Apelurile succesive ale functiei incrementeaza
variabila si, in acest caz, putem calcula numarul apelurilor.
lor de viata. Acum vom examina in detaliu tipurile de variabile intregi si reale, intervalele de valori si
dimensiunea zonei de memorie in octeti necesara pentru aceste variabile.
Exemplu:
In cazul unui octet putem stoca numere pozitive cuprinse intre 0 si 2 8−1 adica in intervalul [0, 255].
Important
• Atunci cand una dintre limitele intervalului este depasita cu o unitate prin incrementare sau
decrementare urmatoarea valoare va fi cealalta limita a intervalului.
• Putem gandi valorile unui interval dispuse pe un cerc. Dupa o rotatie completa in oricare sens valorile
se repeta.
• Acest aspect este foarte important la bucle: daca valoarea din conditia de oprire a buclei nu este in
intervalul variabilei utilizate pentru testul buclei, vom avea fie o bucla infinita, fie secventa buclei nu
se va executa niciodata.
Exemplu:
Pentru un octet am avea limita maxima pozitiva de 2 7−1 adica 127, iar limita inferioara va fi de
−27 adica -128. Pe un octet putem stoca numere cuprinse in intervalul [-128, 127].
Important
Sa presupunem ca avem o variabila de marimea unui octet care are valoarea 127 si o incrementam. Si in
aceasta situatie se aplica observatiile anterioare. Noua valoare va fi -128. Iar daca variabila are valoarea
-128 si o decrementam noua valoare va fi 127.
10
InfoAcademy Adonis Butufei
11
Adonis Butufei
int main()
{
cout << "Valoarea minima pentru int: " << INT_MIN << "\n";
cout << "Valoarea minima pentru int: " << INT_MAX << "\n";
cout << "Valoarea maxima pentru unsigned int: " << UINT_MAX << "\n";
return 0;
}
12
InfoAcademy Adonis Butufei
Exemplu:
1: unsigned short v1;
2: // ...
3: short v2 = v1;
Atribuirea din linia 3 necesita multa atentie. Daca valoarea variabilei v1 depaseste limita SHRT_MAX,
atunci este posibil ca functionarea sa fie defectuoasa.
Acest fenomen poate apare atunci cand se face atribuirea intre doua variabile de tip diferit sau cand o
variabila este folosita pentru a calcula suma sau produsul unei secvente de valori.
Cunoasterea acestui aspect este esentiala pentru alegerea tipurilor de variabile si scrierea codului
de calitate.
Pe de alta parte, daca am folosi numai variabile reale pentru efectuarea calculelor este ca si cum am
incerca sa construim un cub din plastilina. Oricat de mult ne-am stradui nu am obtine muchiile drepte si
precise.
Pentru efectuarea calculelor cu numere reale au trebuit rezolvate doua probleme importante: posibilitatea
de a lucra cu intervale foarte mari de valori si reprezentarea acestor valori intr-o dimensiune predefinita
de memorie.
Pentru adresarea acestor necesitati nu se putea folosi o reprezentare exacta ca in cazul variabilelor intregi
ci s-a folosit o reprezentare aproximativa suficient de precisa a numerelor reale folosind un numar
standard de octeti7.
Deoarece analiza reprezentarii in memorie a variabilelor reale depaseste scopul cursului, in continuare
vom schita aspectele necesare intelegerii principiilor de functionare a numerelor reale.
Variabilele reale au trei elemente: semnul, o fractie zecimala si un exponent:
y=± f . f 1 f 2 … f n x 2exponent
Unde f.f 1 f 2 … f n este fractia zecimala.
Pentru a separa partea intreaga de partea zecimala, in C++ folosim caracterul punct . in loc de virgula ,.
Exemple:
3.54
0.37
-42.8
Modul stiintific foloseste forma ±abE±cd care este echivalenta cu ±ab x 10±cd . In aceasta notatie
putem folosi ambele litere (E) sau (e).
Exemple:
3e+2 = 3x102 = 300
3.24e-3= 3.24x10−3
De retinut
Nu trebuie sa existe spatii intre caractere atunci cand se foloseste aceasta notatie. Urmatoarele valori sunt
incorecte:
3 e+4
-4.5 e-2
Exemple:
14
InfoAcademy Adonis Butufei
int main()
{
double sum = 0.0;
for(int i =0; i < 10; i = i + 1)
{
sum = sum + 0.1;
}
if(1.0 == sum)
{
cout << "suma este 1.0\n";
}
else
{
cout << "suma nu este 1.0\n";
}
return 0;
}
Pentru a compara variabilele reale este necesar sa calculam diferenta absoluta a valorii celor doua
variabile si daca aceasta diferenta este mai mica decat un nivel de eroare considerat acceptabil atunci
numerele sunt considerate egale. Programul urmator exemplifica aceasta idee:
#include <iostream>
#include <cmath>
15
Adonis Butufei
int main()
{
double sum = 0.0;
for(int i =0; i < 10; i = i + 1)
{
sum = sum + 0.1;
}
if(AreEqual(1.0, sum))
{
cout << "suma este 1.0\n";
}
else
{
cout << "suma nu este 1.0\n";
}
}
16
InfoAcademy Adonis Butufei
Este important de facut diferenta intre valoarea numerica si codul ASCII corespunzator unei cifre.
Urmatoarele doua variabile au valori diferite. In primul caz variabila are valoarea 5 in al doilea caz
variabila are valoarea codului asociat pentru caracterul 5 care este 53.
char x = 5; // x are valoarea 5
char y = '5'; // y are valoarea codului ASCII pentru '5' este 53.
17
Adonis Butufei
5: {
6: for(int i =0; i < 256; i = i + 1)
7: {
8: cout << (char) i << " " << i << "\n";
9: }
10: return 0;
11: }
Ca si contor al buclei am folosit o variabila de tip int. Pentru a putea tipari ultima valoare a intervalului
trebuia sa fixez limita la 256. Daca foloseam o variabila unsigned char intervalul posibil de valori era [0 –
255]. Atunci cand i lua valoarea 255 se executa codul buclei apoi se incrementa valoarea care in acest caz
ar fi devenit 0. In acest moment totul se repeta si obtineam o bucla infinita.
Pe linia 8 observam expresia (char)i aceasta converteste tipul variabilei i de la intreg la caracter si se
numeste castare. Vom analiza conversiile in detaliu in capitolul urmator cand vom discuta despre
operatori.
int main()
{
char c;
cout << "Introduceti un caracter\n";
cin >> c;
Exista o categorie speciala de valori care este utilizata pentru formatarea textului. Fiecare valoare din
aceasta categorie incepe cu caracterul (\) pentru a preveni procesarea implicita a caracterului care
urmeaza. Acest grup de doua caractere se numeste secventa escape .
18
InfoAcademy Adonis Butufei
Valoare Explicatie
'\0' marcheaza sfarsitul unui sir de carcatere
'\t' insereaza un tab orizontal
'\n' muta cursorul pe linia urmatoare
'\r' muta cursorul la inceputul linei
'\"' afiseaza caracterul (")
'\\' afiseaza caracterul (\)
Valorile mai pot fi impartite logic si in alte categorii: caracterele care reprezinta cifre ('0' - '9'), litere
(majuscule, minuscule) etc. Pentru a testa apartenenta unui caracter la o categorie se folosesc functiile
declarate in fisierul <cctype>.
Tabelul de mai jos contine o scurta prezentare a acestor functii:
Functie Explicatie
isalpha(c) returneaza 1 daca c este litera mare sau mica A-Z, a-z
isupper(c) returneaza 1 daca c este litera mare A-Z
islower(c) returneaza 1 daca c este litera mica a-z
isdigit(c) returneaza 1 daca c este cifra 0-9
isxdigit(c) returneaza 1 daca c este cifra hexa 0-9,a-f,A-F
isspace(c) returneaza 1 daca c este spatiu ' ','\t','\n','\r','\f' sau '\v'
ispunct(c) returneaza 1 daca c este character de punctuatie
isalnum(c) returneaza 1 daca c este litera sau cifra
isprint(c) returneaza 1 daca c este afisabil cu spatiu
isgraph(c) returneaza 1 daca c este afisabil fara spatiu
iscntrl(c) returneaza 1 daca c este caracter de control
tolower(c) converteste caracterul c la litera mica
toupper(c) converteste caracterul c la litera mare
19
Adonis Butufei
2: #include <cctype>
3: using namespace std;
4:
5: int main()
6: {
7: for(int c = 0; c < 256; c = c + 1)
8: {
9: if(ispunct(c))
10: {
11: cout << c << " " << (char)c << "\n";
12: }
13: }
14:
15: return 0;
16: }
3.6 Sumar
• Cea mai mica unitate de informatie este bitul.
• Un grup de 8 biti formeaza un octet.
• Variabilele se masoara in octeti.
• Pentru a determina numarul de octeti ocupati de o variabila se foloseste operatorul sizeof.
• Pe langa reprezentarea zecimala, variabiele intregi mai pot fi reprezentate in baza 8, reprezentare
octala, sau baza 16, reprezentare hexazecimala.
• Domeniul de viata al variabilelor reprezinta zona de cod in care acestea pot fi utilizate in cadrul
programului. Dupa ce sunt executate instructiunile din domeniul de viata al unei variabile, acea
variabila nu mai poate fi accesata si memoria aferenta este eliberata. Exceptie in cazul variabilelor
statice!
• Pentru a reduce cuplajul prin date este recomandabil ca variabilele sa aiba un domeniu de viata cat mai
redus.
• Calificatorul de context este utilizat pentru a accesa variabile declarate in alt fisier.
• Calificatorul de context static are doua caracteristici:
- variabilele globale statice pot fi accesate doar din fisierul curent
- variabilele locale statice sunt alocate in memorie la prima executie si valoarea lor se pastreaza pe
toata perioada rularii programului.
20
InfoAcademy Adonis Butufei
• In C++ sunt definite urmatoarele tipuri de variabile intregi: int, long si short. Primele doua tipuri ocupa
4 octeti, ultimul tip ocupa 2 octeti.
• Variabilele intregi pot avea semn sau nu. In cazul celor fara semn toate valorile sunt pozitive.
• Limitele pentru variabilele intregi sunt definite in fisierul <climits>
• Variabilele reale pot lua valori in intervale largi. Ele folosesc o reprezentare aproximativa a numerelor
datorita faptului ca au un numar finit de cifre.
• Dimensiunea variabilelor reale este de 4 sau 8 octeti.
• Pentru variabilele reale se folosesc doua notatii: zecimala si stiintifica. Cea zecimala este de forma
24.5 iar cea stiintifia este de forma 2.45 * 101 .
• Pentru testarea egalitatii variabilelor reale, datorita aproximarii, nu se poate folosi operatorul == . Se
defineste cea mai mica diferenta acceptabila. Daca diferenta celor doua numere este mai mica in
valoare absoluta decat diferenta acceptabila atunci sunt considerate egale.
• Limitele variabilelor reale sunt definite in fisierul <cfloat>.
• Tipul char foloseste codurile ASCII pentru reprezentarea informatiei ca si text.
#include <iostream>
using namespace std;
int main()
{
21
Adonis Butufei
for(int i = 0; i < 3; i = i + 1)
{
static int a = 1;
int b = 1;
cout << "a= " << a << " b= " << b << "\n";
a = a + 1;
b = b + 1;
}
return 0;
}
16. Care este diferenta dintre o variabila de tip int si una de tip short?
17. Care este diferenta dintre o variabila cu semn si una fara semn?
18. Cum se declara o variabila fara semn de tip long long?
19. Care este valoarea variabilei dupa executarea codului:
int x = INT_MIN;
x--;
21. Ce fisier trebuie inclus pentru a putea lucra cu limitele variabilelor de tip intreg?
22. Extindeti programul de afisare a dimensiunii variabilelor pentru toate tipurile de variabile discutate
pana acum.
23. Extindeti programul de afisare a limitelor pentru toate valorile intregi.
24. Scrieti reprezentarea zecimala pentru urmatoarele valori:
1.345e-2
45.89e-1
1234.789E-3
-324.758e-2
25. Scrieti reprezentarea stiintifica pentru urmatoarele valori astfel incat partea intreaga sa aiba 2 cifre:
234.78
0.756
-2.546
22
InfoAcademy Adonis Butufei
-2459.576
26. Modificati exemplul initial pentru compararea numerelor reale astfel incat sa foloseasca variabile de
tip float. Apar si in acest caz erorile de aproximare?
27. Ce fisier trebuie inclus pentru a folosi limitele variabilelor reale?
28. Scrieti un program care afiseaza valorile limitelor pentru variabilele de tip float si double.
29. Implementati un program care afiseaza codul ASCII si valoarea pentru toate literele si cifrele.
30. Programul urmator ruleaza in bucla infinita. Care este eroarea?
17: #include <iostream>
18: using namespace std;
19: int main()
20: {
21: for(unsigned char c = 0; c < 256; c = c + 1)
22: {
23: cout << c << " " << (int)c << "\n";
24: }
25:
26: return 0;
27: }
31. Modificati codul anterior pastrand tipul datelor, dar folosind o bucla do /while
32. Implementati o functie care primeste un caracter si daca acesta este litera o transforma in majuscula
folosind tabelul codurilor ASCII prezentat in bibliografie.
3.8 Bibliografie
• Practical C++ Programming, second edition, O'Reily, Steve Oualline, Cap 5, Cap 9.
• C++ Primer, sixth edition, Addison-Wesley Professional, Stephen Prata, Cap3.
• Reprezentarea numerelor reale http://steve.hollasch.net/cgindex/coding/ieeefloat.html
• Acuratete vs. precizie:
http://www.cprogramming.com/tutorial/floating_point/understanding_floating_point.html
• Reprezentarea double pe 64 biti: http://en.wikipedia.org/wiki/Double_precision_floating-point_format
• Codurile ASCII http://www.asciitable.com/
23