Sunteți pe pagina 1din 0

Pointeri.

Alocarea dinamic a memoriei


Un pointer este o variabil care conine adresa unui
Obiect (alt variabil sau funcie).
Orice variabil are dou elemente caracteristice:
valoarea coninut n variabil;
valoarea adresei locaiei de memorie.
Adresa locaiei de memorie n care este stocat o variabil
se poate obine aplicnd operatorul de adres (operatorul
&) naintea numelui variabilei (operaie ntlnit frecvent
n cazul apelrii funciei scanf).
Operatorul de adres poate fi utilizat pentru
obinerea valorii adresei oricrei variabile.
int a=18;
printf("valoarea lui a este %d \n",a);
printf("adresa lui a este %p \n", &a);
Un pointer este o variabil care are ca valoare o
adres de memorie.
Spunem c variabila pointer indic locaia de
memorie de la adresa pe care o conine.
n C, pointerii se refer la un anumit tip: tipul
datelor coninute n locaia de memorie indicat de
variabila pointer.

=>O variabil pointer n C este de regul
pointer la un anumit tip.
Declararea variabilelor pointer se face n felul urmtor:
tip * nume_variabila_pointer;
variabila nume_variabila_pointer conine adrese de
zone de memorie alocate datelor de tipul tip.
* semnific faptul c variabila este de tip pointer la
tipul respectiv. De exemplu,
int *p;
defineste o variabil p pointer la ntreg. Variabila p poate
conine adrese de locaii n care se memoreaz valori
ntregi.
Se pot declara si pointeri generici, de tip void * ( tipul
datelor indicate de ei nu este cunoscut).
Un pointer de tip void reprezint doar o adres
de memorie a unui obiect oarecare:

- dimensiunea zonei de memorie indicate si
interpretarea informaiei nu sunt definite;
- poate aprea n atribuiri, n ambele sensuri,
cu pointeri de orice alt tip;
- folosind o conversie explicit de tip cu
operatorul cast : (tip *), el poate fi convertit la orice alt
tip de pointer(pe acelai calculator, toate adresele au
aceeai lungime).
Ca i n cazul variabilelor de orice tip, si variabilele pointer
declarate si neiniializate conin valori aleatoare.
Pentru a atribui variabilei p valoarea adresei variabilei x, se foloseste
operatorul de adres ntr-o expresie de atribuire de forma:
p=&x;
n urma acestei operaii, se poate spune c pointerul p indic spre variabila x.
Pentru a obine valoarea obiectului indicat de un pointer se
utilizeaz operatorul de derefereniere (indirectare) (operatorul *):
Dac p este o variabil de tip pointer care are ca valoare adresa
locaiei de memorie a variabilei ntregi x (p indic spre x) atunci expresia *p
reprezint o valoare ntreag (valoarea variabilei x).
int x, *p;
x=3; p=&x;
pr i nt f ( " %d" , *p) ;
*p=5;
pr i nt f ( " %d" , x) ;
Pentru a indica adres inexistent, se utilizeaz ca valoare a unui
pointer, constanta NULL.
Variabilele pointer pot fi utilizate n expresii si direct, fr indirectare.
int x, *p1, *p2;
x=3; p1=&x; p2=p1; / / at r i bui r e de poi nt er i
Atribuirea p2=p1; copiaz coninutul lui p1 n p2, deci p2 va fi fcut s
indice spre acelai obiect ca i p1. n contextul secvenei, p2 va indica tot
spre x. Exemple:
int x = 1, y = 2, z[ 10] ;
int *i p; / * i p est e un poi nt er l a i nt */
i p = &x; / * i p i ndi ca acumspr e x */
y = *i p; / * y est e acum1 */
*i p = 0; / * x est e acum0 */
i p = &z[ 0] ; / * i p i ndi ca acumspr e z[ 0] */
Dac ip indic spre ntregul x, atunci *ip poate aprea n orice context n care
ar putea aprea x, deci *i p = *i p + 10;
l incrementeaz pe x cu 10.
Operatorii unari * si & au o preceden mai mare dect operatorii aritmetici,
n consecin:
y =*ip +1
preia obiectul spre care indic ip, l adun cu 1 si atribuie rezultatul lui y, iar
*ip +=1
incrementeaz obiectul spre care indic ip, ca i ++*ip i
(*ip )++
Operatorii unari precum * si ++ se asociaz de la dreapta la stnga.
Pointerii fiind variabile, pot fi folosii fr a fi derefereniai.
Dac iq este un alt pointer spre tipul int,
iq =ip
copiaz coninutul lui ip n iq, fcnd astfel ca iq s indice spre ceea ce indic
ip.
Operatorul de adres (&) se aplic numai obiectelor din memorie: variabile i
elemente de tablou.
Orice operaie care poate fi realizat cu ajutorul tablourilor cu indici poate fi
de asemenea efectuat cu ajutorul pointerilor.
Declaraia
int a[ 10] ;
definete un tablou de dimensiune 10, adic un bloc de 10 elemente
consecutive notate a[0], a[1], ..., a[9].
Dac pa este un pointer spre un ntreg,
declarat ca
int *pa;
atunci atribuirea
pa = &a[ 0] ;
l seteaz pe pa s indice spre elementul zero al lui a; mai precis, pa conine
adresa lui a[0].


Instruciunea x = *pa; va copia coninutul lui a[0] n x.
Dac pa indic spre un anumit element de
tablou, atunci, prin definiie, pa + 1 indic
spre urmtorul element, pa + i indic
Spre o locaie aflat la i elemente dup pa,
iar pa i indic spre o locaie aflat cu
i elemente nainte.
Prin definiie, valoarea unei variabile sau expresii de tip tablou este
adresa elementului zero al tabloului.
pa = &a[ 0] ; poate fi scris pa = a;
Fie urmtoarele declaraii: tab un tablou de elemente de tip T si p un pointer
la tipul T: T tab[N]; T * p;
Cele 3 atribuiri urmtoare sunt echivalente, si au ca efect faptul c
p va indica adresa primului element al tabloului tab:
p=tab; p=&tab; p=&tab[0];
Atribuirea tab=p; nu este permis.
Toate operaiile de manipulare a pointerilor iau n considerare n mod
automat dimensiunea obiectului spre care se indic.
Operaiile permise cu pointeri sunt:
- atribuirea pointerilor de acelasi tip;
- adunarea unui pointer cu un ntreg, scderea unui ntreg, compararea a doi
pointeri care indic spre elemente ale aceluiasi tablou;
- atribuirea valorii zero(NULL) sau compararea cu aceasta.
Operatorii unari de incrementare si decrementare se pot aplica asupra
variabilelor de tip pointer, n format prefix si postfix.
T * p; p++; p--; ++p; --p;
Operatorul de incrementare aplicat asupra unui operand de tip
pointer la tipul T mreste adresa coninut de operand cu numrul de octei
necesar pentru a pstra o dat de tipul T (se adun sizeof(T)):
T tab[N], * p; int i;
p=&tab[i]; p++;
p va contine adresa elementului tab[i+1];
n general, un pointer poate fi iniializat ca orice alt variabil, desi n mod
normal singurele valori care au sens sunt zero sau o expresie care implic
adresele unor date definite anterior.
Constanta zero poate fi atribuit unui pointer si, de asemenea, un pointer
poate fi comparat cu constanta zero. Constanta simbolic NULL (definit n
<stdio.h>) este folosit de obicei n locul lui zero, ca o modalitate de a indica
mai clar c aceasta este o valoare special pentru un pointer.
Compararea a doi pointeri
Doi pointeri care indic spre elementele aceluiasi tablou pot fi
comparai, folosind operatorii de relaie si de egalitate.
Dac p si q sunt doi pointeri spre elementele tab[i] respectiv tab[j]
ale unui tablou, comparaia p<q este adevarat dac i<j.
Diferena a doi pointeri
Doi pointeri care indic spre elementele aceluiasi tablou pot fi
sczui. Dac p si q sunt doi pointeri spre elementele tab[i] si respectiv
tab[i+n], diferena q-p are valoarea egal cu n.
Se considera urmatoarele declaratii:
int t ab[ 100] , N, *pt r , i ;
Urmatoarele instructiuni afiseaza la ecran elemenetele tabloului
for(i =0; i <N; i ++) pr i nt f ( " %d " , t ab[ i ] ) ;
pt r =&t ab[ 0] ;
for( i =0; i <N; i ++) pr i nt f ( " %d " , *( pt r +i ) ) ;
for( pt r =t ab; pt r <t ab+N; pt r ++) pr i nt f ( " %d " , *pt r ) ;
Instructiunea
pr i nt f ( " adr esa val oar ea de pe adr esa\ n" ) ;
for( pt r =t ab; pt r <t ab+N; pt r ++)
pr i nt f ( " %p %d \ n" , pt r , *pt r ) ;
Va afisa adresa de memorie a fiecarui element din tablou urmata de
valoare de pe adresa
char *pmesaj ;
atunci instruciunea
pmesaj =acum este timpul;
i atribuie lui pmesaj un
pointer ctre tabloul de caractere.
Exist o deosebire important ntre urmtoarele definiii:
char t mesaj [ ] = acumest e t i mpul ; /* un tablou */
char *pmesaj = acumest e t i mpul ; /* un pointer */



- Caracterele din cadrul tabloului pot fi modificate individual, dar t mesaj
va indica ntotdeauna ctre acelasi spaiu de stocare.
- pmesaj este un pointer iniializat s indice ctre o constant sir; poate fi
modificat ulterior astfel nct s indice alt locaie, dar rezultatul este
nedefinit dac se modific coninutul sirului.

S-ar putea să vă placă și