Aritmetica de adrese
Daca p este un pointer, atunci p += i incrementeaza pe p pentru a indica cu i elemente dupa elementul pe care il indica in prealabil p. Aceasta constructie si altele similare sint cele mai simple si comune formule ale aritmeticii de adrese, care constituie o caracteristica puternica a limbajului C. Sa ilustram citeva din proprietatile aritmeticii de adrese scr 151i83b iind un alocator rudimentar de memorie. Fie rutina alloc(n) care returneaza un pointer p la o zona de n caractere consecutive care vor fi folosite de rutina apelanta pentru memorarea unui sir de caractere. Fie rutina free(p) care elibereaza o zona incepind cu adresa indicata de pointerul p pentru a putea fi refolosita mai tirziu. Zona de memorie folosita de rutinele alloc si free este o stiva functionind pe principiul ultimul intrat primul iesit, iar apelul la free trebuie facut in ordine inversa cu apelul la alloc. Sa consideram ca functia alloc va gestiona stiva ca pe elementele unui masiv pe care il vom numi allocbuf. Vom mai folosi un pointer la urmatorul element liber din masiv, pe care-l vom numi allocp. Cind se apeleaza rutina alloc pentru n caractere, se verifica daca exista suficient spatiu liber in masivul allocbuf. Daca da, alloc va returna valoarea curenta a lui allocp, adica adresa de inceput a blocului cerut, dupa care va incrementa pe allocp cu n pentru a indica urmatoarea zona libera. free(p) actualizeaza allocp cu valoarea p, daca p indica in interiorul lui allocbuf
#define NULL 0
/* valoarea pointerului pentru semnalizarea erorii */
#define ALLOCSIZE 1000
/* dimensiunea spatiului disponibil */
static char allocbuf [ALLOCSIZE];
/* memoria pentru alloc */
static char *allocp = allocbuf;
/* urmatoarea pozitie libera */
char *alloc(int n)
else
return NULL; /* nu este spatiu suficient */
}
free(char *p)
Testul if (allocp+n<=allocbuf+ALLOCSIZE)
verifica daca exista spatiu suficient pentru satisfacerea cererii de alocare a n caractere. Daca cererea poate fi satisfacuta, alloc revine cu un pointer la zona de n caractere consecutive. Daca nu, alloc trebuie sa semnaleze lipsa de spatiu pe care o face returnind valoarea constantei simbolice NULL. Limbajul C garanteaza ca nici un pointer care indica corect o data nu va contine zero, prin urmare o revenire cu valoarea zero poate fi folosita pentru semnalarea unui eveniment anormal (in cazul nostru, lipsa de spatiu). Atribuirea valorii zero unui pointer este deci un caz special.
Observam de asemenea ca variabilele allocbuf si allocp sint declarate static cu scopul ca ele sa fie locale numai fisierului sursa care contine functiile alloc si free
Exemplul de mai sus demonstreaza citeva din facilitatile aritmeticii de adrese (pointeri). In primul rind, pointerii pot fi comparati in anumite situatii. Daca p si q sint pointeri la membri unui acelasi masiv, atunci relatiile < <= > >= sint valide. Relatia p<q, de exemplu, este adevarata daca p indica un element mai apropiat de inceputul masivului decit elementul indicat de pointerul q. Compararile intre pointeri pot duce insa la rezultate imprevizibile, daca ei se refera la elemente apartinind la masive diferite.
Se observa ca pointerii si intregii pot fi adunati sau scazuti. Constructia de forma:
p+n
inseamna adresa celui de-al n-lea element dupa cel indicat de p, indiferent de tipul elementului pe care il indica p. Compilatorul C aliniaza valoarea lui n conform dimensiunii elementelor pe care le indica p, dimensiunea fiind determinata din declaratia lui p (scara de aliniere este 1 pentru char, 2 pentru int etc).
Daca p si q indica elemente ale aceluiasi masiv, p-q este numarul elementelor dintre cele pe care le indica p si q. Sa scriem o alta versiune a functiei strlen folosind aceasta ultima observatie:
strlen(char *s)
In acest exemplu s ramine constant cu adresa de inceput a sirului, in timp ce p avanseaza la urmatorul caracter de fiecare data. Diferenta p-s dintre adresa ultimului element al sirului si adresa primului element al sirului indica numarul de elemente.
In afara de operatiile binare mentionate (adunarea sau scaderea pointerilor cu intregi si scaderea sau compararea a doi pointeri), celelalte operatii cu pointeri sint ilegale. Nu este permisa adunarea, inmultirea, impartirea sau deplasarea pointerilor, dupa cum nici adunarea lor cu constante de tip double sau float
|