Documente Academic
Documente Profesional
Documente Cultură
Laborator VII
Adrian Liţă / Ovidiu Grigore / Anamaria Rădoi
2015
1 Scopul laboratorului
Laboratorul VI al materiei Programarea Calculatoarelor are ca scop introduce-
rea tablourilor (vectorilor) şi a pointer-ilor.
În acest laborator se parcurg următoarele puncte:
• tablouri unidimensionale
• tablouri N-dimensionale
2 Desfăşurarea lucrării
Folosirea variabilelor reprezintă un lucru extrem de util în programare. Una din
principalele limitări ale variabilei este aceea că poate ţine minte doar o singură
valoare. Pentru cazurile în care este necesară memorarea mai multor valori a
fost introdus elementul numit tablou (sau array).
Un array reprezintă o colecţie de variabile de un anumit tip, plasate conti-
nuu (una după cealaltă) şi liniar în memorie. Cu ajutorul array-urilor putem
defini tipuri de date cum ar fi vectori sau matrice. Tabloul se declară în felul
următor:
1 t i p _ d a t e nume_tablou [ d i m e n s i u n e 1 ] [ d i m e n s i u n e 2 ] . . . [ dimensiuneN ] ;
Dacă tabloul are o singura dimensiune, acesta este se mai numeşte vector.
1
2.1 Pointeri
Pointerii sunt unul dintre cele mai folositoare tipuri de date într-un limbaj de
programare. Pointerii sunt variabile cu o singură particularitate: un pointer
poate ţine mine DOAR adresa unei variabile. Prin urmare, valoarea unui
pointer reprezintă o adresă şi nu ar trebui luată în considerare altfel!
1 char c ; // d e c l a r a r e a v a r i a b i l e i c
2 c h a r ∗ cp ; // d e c l a r a r e a p o i n t e r u l u i cp
3
4 c = ’a ’ ; // v a l o a r e a v a r i a b i l e i c d e v i n e c a r a c t e r u l ’ a ’
5 cp = &c ; // v a l o a r e a p o i n t e r u l u i cp d e v i n e a d r e s a v a r i a b i l e i c
*cp = ’b’ se traduce prin "valoarea de la adresa din cp devine ’b’". În ge-
neral, cu excepţia declarării pointerului (linia 2), *cp se traduce prin "valoarea
de la adresa din cp". În acest caz, când cp = &c (cp ia valoarea adresei lui c),
*cp reprezintă, pentru operaţii de citire şi/sau scriere acelaşi lucru ca şi c. Fie
că executăm *cp = ’a’ sau c = ’a’, rezultatul este acelaşi.
Notă. ’a’, ’b’, etc sunt ceea ce noi numim caractere. De fapt ele sunt numere
întregi, corelate cu codul ASCII: ’a’ = 97, ’b’ = 98, ’A’ = 65, etc. În exemplul
de mai sus, scrierea c = ’a’ este perfect identică cu c = 97. Amintiţi-vă codul
ASCII.
2
2.1.1 Alocarea dinamică
Alocarea dinamică, spre deosebire de cea statică, presupune că programatorul
nu ştie dinainte exact câtă memorie are nevoie pentru a-şi putea executa pro-
gramul. Un bun exemplu pentru un astfel de caz constituie memorarea unui
nume sub formă de vector de caractere. Lungimea unui nume poate varia de la
câteva caractere până la câteva zeci dacă persoana în cauză are mai multe pre-
nume. Dacă declarăm static un vector de 100 de caractere (presupunând totuşi
că 100 ar fi lungimea maximă), atunci pentru orice nume ţinut minte, ocupăm
100 de octeţi. Acest lucru este foarte ineficient pentru lungimi de nume mici.
În momentul în care memoria disponibilă nu este foarte mare, sau în momentul
în care numărul de nume care trebuiesc memorate este foarte mare, acest lucru
nu mai este fezabil.
3
Notă. Atenţie: în momentul alocării, s ţine minte adresa noului spaţiu de
memorie alocat. Dacă cumva s va pierde acea valoare (a adresei spaţiului)
atunci memoria respectivă va fi pierdută dar NU va fi dezalocată automat.
Trebuie avută foarte mare grijă ca să nu fie pierdută adresa spaţiului de memorie
alocat dinamic.
1 char ∗ s ;
2 int n = 4;
3 s = new c h a r [ n ] ;
4 i f ( s == NULL)
5 {
6 c o u t << " E r o a r e de a l o c a r e ! \ n" ;
7 exit (1) ;
8 }
9
10 s [ 0 ] = ’P ’ ;
11 s [ 1 ] = ’C ’ ;
12 s [2] = ’7 ’ ;
13 s [ 3 ] = 0;
14 p r i n t f ( "%s \n" , s ) ; // va a f i s a "PC7"
15
16 s = NULL;
17
18 p r i n t f ( "%s \n" , s ) ; // e r o a r e
1. Alocare
2. Verificarea dacă s-a alocat
3. Folosirea acelui spaţiu de memorie
4. Eliberarea (sau dezalocarea) spaţiului de memorie când nu mai este folosit
1 char ∗ s ;
2 int n = 4;
3 s = new c h a r [ n ] ;
4 i f ( s == NULL)
5 {
6 c o u t << " E r o a r e de a l o c a r e ! \ n" ;
7 exit (1) ;
8 }
4
9
10 s [0] = ’P ’ ; // sau ∗ s = ’P ’ ;
11 s [1] = ’C ’ ; // sau ∗ ( s +1) = ’C ’
12 s [2] = ’7 ’ ; // sau ∗ ( s +2) = ’ 7 ’
13 s [3] = 0; // sau ∗ ( s +3) = 0
14
15 p r i n t f ( "%s \n" , s ) ; // va a f i s a "PC7"
16
17 delete [ ] s ;
18 s = NULL;
Notă. Liniile 10-13 prezintă folosirea memoriei dinamice prin pointer ca vector.
Această scriere este mai uşoară şi mai simplu de urmărit. Totuşi, scrierea
perfect corectă este dată la comentariu. *s înseamnă "valoarea de la adresa din
pointerul s", *(s+1) înseamnă "valoarea de la (adresa din pointerul s, plus o
unitate de adresă)". Această unitate nu reprezintă neapărat un octet, ci exact
numărul de octeţi ai tipului de date pe care-l reprezinta pointerul.