Documente online.
Zona de administrare documente. Fisierele tale
Am uitat parola x Creaza cont nou
 HomeExploreaza
upload
Upload




Pointeri

c


Pointeri

Adrese

Prin locatie de memorie vom intelege, in continuare, cea mai mica unitate de memorie adresabila. De obicei, unitatea minima de memorie adresabila este byte-ul. De obicei un byte este format din 8 biti (un bit este unitatea minima de reprezentare a datelor), caz in care se vorbeste despre octet.



Locatiile de memorie sunt consecutive si numarul lor de ordine (numar intreg pozitiv!) reprezinta adresa lor . Exista o stransa legatura intre dimensiunea memoriei adresabile si numaru 333c25d l de biti pe care se reprezinta adresele locatiilor de memorie. De ex. cu adrese pe 2 octeti (16 biti) se poate adresa un spatiu de memorie de maximum 216=65536 locatii (64KB). Cu adrese pe 4 octeti se poate adresa un spatiu de memorie de 232=4294967296 locatii (4GB).

Informatiile memorate de un calculator (fie ele date sau coduri de instructiuni sau chiar adrese) pot ocupa una sau mai multe locatii succesive de memorie. Indiferent insa cate locatii de memorie ocupa o informatie ce trebuie stocata, adresa de inceput a grupului de locatii ocupate este.o adresa. Altfel spus, informatiile de tip adresa ocupa acelasi numar de octeti, indiferent de tipul informatiei stocate incepand cu acea adresa. De obicei adresele se reprezinta pe doi sau patru octeti. Adresele reprezentate pe doi octeti sunt adrese relative in cadrul unor segmente de memorie de 64KB, si sunt utilizate de obicei la calculatoare cu registri pe 16 biti, necesitand o schema de prelucrare care sa permita accesarea unui spatiu de memorie mai mare decat 64KB.

In exemplul de mai jos, adresele (de inceput ale) celor trei date sunt cele cu font ingrosat. Data de tip long int ocupa 4 bytes (de la 0100 la 0103, inclusiv), data de tip char ocupa un byte (la adresa 0106) iar data de tip int ocupa 2 bytes (de la adresa 010A la 010B, inclusiv).

0100 0101

010A

010B

}long int (4 bytes)

} char (1 byte)

}int (2 bytes)

Pointerii sunt variabile. Declararea variabilelor pointer

Definitie1. Pointerii sunt variabile a caror valoare este interpretata ca adresa a unei locatii de memorie.

Spatiul ocupat de o variabila pointer este raportat corect de operatorul sizeof

Sintaxa declaratiei unei variabile pointer este:

TIP *nume_variabila;

unde TIP este orice tip de data fundamental sau definit de catre programator.

Definitie2. Pointerii sunt variabile a caror valoare este interpretata ca adresa a unei locatii de memorie unde poate fi accesata o valoare de tipul declarat al pointerului.

La fel ca in cazul oricaror variabile, variabilele pointer globale sau cele locale declarate static se initializeaza automat, cu valoarea NULL. NULL, ca valoare a unui pointer, este o adresa invalida! Ea se foloseste doar pentru a indica faptul ca pointerul care are valoarea respectiva nu poate fi utilizat intr-o operatie de dereferentiere.

Operatorul &. Initializarea pointerilor. De ce?

Operatorul unar & se uilizeaza in expresii a caror valoare reprezinta adresa variabilei operand.

Ex.

TIP var, *pvar; /* var - variabila de tipul TIP pvar - variabila "pointer la variabile de tipul TIP

pvar = &var; valoarea lui pvar reprezinta adresa variabilei var

OBS. TIP poate fi oricare din tipurile fundamentale sau definite de catre utilizator (inclusiv pointer!)

Dereferentierea pointerilor. Operatorul *.

Operatorul unar se utilizeaza in expresii a caror valoare reprezinta valoarea memorata la adresa indicata de operand (variabila pointer).

Ex:

TIP var=expresie,*pvar; /* var - variabila de tipul TIP; pvar - variabila "pointer la variabile de tipul TIP" */

pvar = &var; valoarea lui pvar reprezinta adresa varibilei var */

*pvar /* *pvar este o valoare de tipul TIP egala cu valoarea espresiei expresie

Pointeri (void *)

Daca tipul declarat al unui pointer este void *, aceasta semnifica absenta oricarei informatii despre tipul valorii memorate incepand cu adresa care reprezinta valoarea pointerului. Astfel de pointeri nu pot fi folositi decat pentru memorarea unor adrese nu si pentreu accesul la datele de la adresele respective!

Asupra pointerilor de tip void * nu se pot face nici un fel de operatii (din cele admise asupra pointerilor) cu exceptia asignarii unui astfel de pointer la alt pointer sau al asignarii unui pointer la un astfel de pointer.

Ex:

int v, *pi=&v;

char *pc;

void *p;

p=pi; /*corect! p contine adresa variabilei v */

*p. /* eronat! p nu poate fi dereferenetiat pt ca nu se cunoaste tipul datei de al adresa p

pc=p: /* corect! pc contine adresa primului octet (un char) de la adresa din p=pi deci

primul octet al lui v

Pointeri ca argumente de functii

Argumentele formale declarate ca tablouri sunt pointeri! Intr-adevar, daca un argument formal al unei functii este un tablou, la apelul functiei respective ceea ce se transmite este adresa tabloului. In functia apelata, argumentul respectiv este insa o variabila al carei continut este o adresa. Dar, variabilele al caror continut (valoare) reperzinta o adresa sunt (se numesc).pointeri!

OBS. De altfel, la apelul unei astfel de functii, argumentul actual corespunzator argumentului formal declarat ca tablou este, de obicei, numele unui tablou. Numele unui tablou este sinonim cu adresa de inceput a tabloului, Q.E.D.!

Operatii cu pointeri. Pointeri si tablouri. Indexarea si dereferentierea - notatii echivalente.

Operatii legale asupra pointerilor:

Asignarea unei adrese la un pointer

Atribuirea unui pointer la alt pointer

Dereferentierea unui pointer (daca e de alt tip decat void *!)

Adunarea/scaderea unei constante la/dintr- un pointer (atunci cand pointerul indica spre un element al unui tablou)

Incrementarea/decrementarea unui pointer (atunci cand pointerul indica spre un element al unui tablou)

Scaderea unui pointer din alt pointer (atunci cand ambii indica spre elemente ale aceluiasi tablou)

Compararea a doi pointeri care indica spre elemente ale aceluiasi tablou

Operatii ilegale

Oricare din operatiile care nu sunt legale! ;-)

Pointeri si siruri de caractere.

Exista o stransa legatura intre pointeri si tablouri. De obicei (desi nu in exclusivitate!), pointerii se utilizeaza in conjunctie cu tablourile (pentru a accesa elemente ale unui tablou). Cu o frecventa si mai mare se utilizeaza pointerii pentru prelucrarea sirurilor de caractere (tablouri - declarate ca atare sau nu! - al caror continut este o succesiune de caractere din care ultimul are valoarea '\0' , asa numitul caracter terminator de sir). Toate functiile de tratare a sirurilor de caractere (care au prototipul in headerul string,h) reprezinta exemple de prelucrare prin intermediul pointerilor.

Pointeri vs. tablouri

Tinand cont de faptul ca numele unui tablou reprezinta un sinonim pentru adresa unui tablou, se poate utiliza numele unui tablou ca pointer.

Ex.

TIP t[DIM], *p=t;

t[i este tot una cu *(t+i) /* t+i reprezinta adresa celui de-al i+1 -lea element al tabloului t */

Pe de alta parte, intrucat evaluarea oricarei expresii reprezentand un element de tablou presupune un calcul de adresa, un pointer poate fi utilizat ca nume de tablou.

Ex.

t[i] este totuna cu *(t + i*sizeof(TIP)) care este totuna cu *(p+i) si ca atare cu p[i]

OBS. Echivalenta dintre numele de tablouri si pointeri se opreste insa acolo unde e vorba de operatii care ar avea ca urmare modificarea adresei.

Ex.

p++;

p=p+i;

sunt ambele expresii corecte, pe cand

t++;

t=t+i;

sunt ambele eronate, intrucat presupun modificarea lui t care este o constanta (adresa de memorie de la care incepand sunt memorate elementele tabloului!

Eficienta utilizarii pointerilor.

Pointerii, desi contribuie la scaderea lizibilitatii programelor C reprezinta in anumite situatii o alternativa mult mai eficienta decat utilizarea tablourilor. Pe de o parte utilizarea pointerilor poate micsora semnificativ timpul de acces la elementele unui tablou iar pe de alta parte, utilizarea pointerilor reprezinta singura modalitate de acces la zone de memorie alocate dinamic (in timpul executiei).

Ex.

for(i=0; i < DIM ; i++) /* la fiecare iteratie: o comparatie si o incrementare */

t[i]=expresie; /*o inmultire, o adunare si o asignare (in afara de operatiile presupuse de evaluarea expresiei)*/

for(p=t,i=0;i<DIM;i++,p++) /* la fiecare iteratie: o comparatie si doua incrementari */

*p=expresie; / * o asignare (in afara de operatiile presupuse de evaluarea expresiei)*/

OBS. Diferenta: o inmultire si o adunare la varianta cu tablou fata de o incrementare la varianta cu pointer. Chiar daca presupunem ca incrementarea este echivalenta ca timp de executie cu adunarea (in nici un caz nu este mai lunga !) in versiunea in care se foloseste pointerl se economiseste timpul necesar unei inmultiri la fiecare ciclu !     Daca in expresie mai apar si alte referiri la elemente ale tabloului diferenta creste.

Pointeri la functii

Desi functiile nu sunt variabile, ele ocupa totusi o zona de memorie, cu alte cuvinte, incep de la o anumita adresa! De aceea, in C se pot declara pointeri la functii, prin intermediul carora se pot apela functiile a caror adresa o contin. In mod similar numelor de tablouri, numele unei functii este sinonim cu adresa tabloului.

Ex.

int (*pf)(char *); /*pointer la functie care asteapta ca argument un char * si care intoarce un int

pf=strlen; /* initializarea pointerului cu adresa unei functii de tipul declarat al pointerului */

n=(*pf)("Timisoara"); /* apelul functiei strlen prin intermediul pointerului pf */

Tablouri multidimensionale. Tablouri de pointeri

Spre deosebire de alte limbaje, in C un tablou multidimensional este un tablou .unidimensional ale carui elemente sunt .tablouri!

Ex.

TIP t[N][M];

In exemplul anterior, t este un tablou de N elemente, fiecare element fiind un tablou de M elemente de tipul TIP! Aceasta inseamna ca t[i] este un tablou de M elemente de tipul TIP.

La fel ca si in cazul tablourilor unidimensionale, dimensiunile (precizate in declaratia) tablourilor multidimensionale trebuie sa fie expresii constante.

In cazul in care un tablou multidimensional este transmis ca argument unei functii, prima dimensiune nu trebuie precizata in declaratia functiei, in schimb toate celelalte dimensiuni sunt obligatorii, pentru a permite compilatorului sa calculeze corect adresa unui element atunci cand se foloseste indexarea

TIP fct( TIP t[ ][N2][N3]);

Aceasta necesitate rezulta clar din modul in care o expresie desemnand un element de tablou este folosita pentru a calcula adresa acestuia:

Elementul t[i][j][k] se afla la adresa t + ( i - 1)*N2*N3 + j.

Pointerii fiind variabile, se pot agrega (grupa) in tablouri.

Declaratia unui tablou de pointeri arata ca mai jos:

TIP *ptr_tab[N];

Tablourile de pointeri reprezinta alternativa (economica) la utilizarea tablourilor bidin\mensionale, mai ales a tablourilor bidimensionale de caractere.

Ex (reprez. Grafica).

Transmiterea argumentelor pe linia de comanda

Un ui program C I se pot transmite anumite argumente (siruri de caractere) la lansarea in executie. Pentru aceasta, functia main trebuie declarata ca asteptand doua argumente:

argc - un intreg care are ca valoare numarul de argumente cu care a fost lansat in executie programul (inclusiv numele acestuia)

argv - un tablou de pointeri catre sirurile de caractere care reprezinta argumentele

Ex.

main( int argc, char *argv[ ])



Document Info


Accesari: 1909
Apreciat: hand-up

Comenteaza documentul:

Nu esti inregistrat
Trebuie sa fii utilizator inregistrat pentru a putea comenta


Creaza cont nou

A fost util?

Daca documentul a fost util si crezi ca merita
sa adaugi un link catre el la tine in site


in pagina web a site-ului tau.




eCoduri.com - coduri postale, contabile, CAEN sau bancare

Politica de confidentialitate | Termenii si conditii de utilizare




Copyright © Contact (SCRIGROUP Int. 2024 )