Sunteți pe pagina 1din 24

UNIVERSITATEA DE STAT B.P.

HASDEU DIN CAHUL


FACULTATEA ECONOMIE, INFORMATIC I MATEMATICA
CATEDRA INGINERIE I TIINE APLICATE


GRECU VALERI
Pointerii n C++

TEZ DE AN
Domeniu:TIINE EXACTE
Specialitatea:INFORMATIC





Conductor:___________________
(Semntura)


Autor:___________________
(Semntura)





Cahul-2014

2

Cuprins
INTRODUCERE ......................................................................................................................................... 3
I.Pointerii ..................................................................................................................................................... 4
Variabilele de tip pointer: ..................................................................................................................... 4
Operatori pentru pointeri.......................................................................................................................... 2
Operatori specifici pointerilor ................................................................................................................. 5
1. Operatorul de adresare &, este un operator unar care returneaza adresa de memorie a operandului
specificat si are sintaxa: ....................................................................................................................... 5
2. Operatorul de indirectare *, este un operator unar, complementul operatorului &, care returneaza
valoarea variabilei aflata la adresa de memorie a operandului specificat si are sintaxa: ..................... 5
Operatii cu pointeri .................................................................................................................................. 7
1. Operatia de atribuire a unui pointer se realizeaza dupa sintaxa:...................................................... 7
Operatiile de incrementare si decrementare ale pointerilor se realizeaza dupa sintaxa: nume_pointer++;
si nume_pointer--;unde - nume_pointer este o variabila te tip pointer declarata corespunzator care
adreseaza alte variabile de tipul de baza al pointerului. .......................................................................... 8
Adunarea si scaderea unei date de tip intreg , la un pointer se realizeaza dupa sintaxa: nume_pointer =
nume_pointer +/- expresie_intreaga ........................................................................................................ 8
Scaderea a doi pinteri de acelasi tuip de baza se realizeaza cu sintaxa: .................................................. 8
Compararea pointerilor se realizeaza prin relatia: ................................................................................... 9
II. Pointeri si tablouri in LC ........................................................................................................................ 9
Tablouri de pointeri in LC ..................................................................................................................... 10
Adresarea indirecta ................................................................................................................................ 11
Initializarea pointerilor .......................................................................................................................... 12
Functii de alocare dinamica de memorie in LC ..................................................................................... 14
Tablouri alocate dinamic ....................................................................................................................... 15
Operatii cu pointeri ................................................................................................................................ 16
1. Operatia de atribuire a unui pointer se realizeaza dupa sintaxa:.................................................... 16
Operatiile de incrementare si decrementare ale pointerilor se realizeaza dupa sintaxa:.................... 17
Adunarea si scaderea unei date de tip intreg , la un pointer se realizeaza dupa sintaxa: ................... 17
Scaderea a doi pinteri de acelasi tuip de baza se realizeaza cu sintaxa: ............................................ 18
Compararea pointerilor se realizeaza prin relatia: ................................................................................. 18
Concluzie..19
Bibriografie: .............................................................................................................................................. 20


3



INTRODUCERE
Limbajul C++ este un limbaj de programare universal, caracterizat printr-o exprimare
concisa, un control modern al fluxului executiei, structuri de date, si un bogat set de operatori.
Limbajul C++ nu este un limbaj de nivel foarte inalt si nu este specializat pentru un
anumit domeniu de aplicatii. Absenta restrictiilor si generalitatea sa il fac un limbaj mai
convenabil si mai eficient decit multe alte limbaje mai puternice. Limbajul C++ permite scrierea
de programe bine structurate, datorita constructiilor sale de control al fluxului: grupari de
instructiuni, luari de decizii (if), cicluri cu testul de terminare inaintea ciclului (while, for) sau
dupa ciclu (do) si selectia unui caz dintr-o multime de cazuri (switch). Limbajul C++ permite
lucrul cu pointeri si are o aritmetica de adrese puternica.
Limbajul C++ nu are operatii care prelucreaza direct obiectele compuse cum sint sirurile
de caractere, multimile, listele sau masivele, considerate fiecare ca o entitate. Limbajul C++ nu
prezinta facilitati de alocare a memoriei altele decit definitia statica sau disciplina de stiva
relativa la variabilele locale ale functiilor. In sfirsit, Limbajul C++ nu are facilitati de intrare-
iesire si nici metode directe de acces la fisiere. Toate aceste mecanisme de nivel inalt sint
realizate prin functii explicite.
Desi Limbajul C++ este, asadar, un limbaj de nivel relativ scazut, el este un limbaj
agreabil, expresiv si elastic, care se preteaza la o gama larga de programe. C este un limbaj
restrins si se invata relativ usor, iar subtilitatile se retin pe masura ce experienta in programare
creste.









4

I.Pointerii
Pointerii reprezint caracteristica cea mai puternic a limbajului de programare C++. n
capitolele precedente am vzut cum se pot scrie funcii ale cror parametri sunt transmii prin
referin. Mecanismul transmiterii parametrilor prin intermediul pointerilor este o extensie a
transmiterii prin referin. Am vzut, de asemenea, c tablourile sunt colecii de elemente de
acelai tip care sunt stocate n locaii succesive de memorie. Vom arta n acest capitol c
exist o strns relaie ntre pointeri i tablouri i vom studia modul n care se pot manipula
tablourile prin intermediul pointerilor.

Variabilele de tip pointer:
Variabilele de tip pointer stocheaz adrese de memorie. Pot, de exemplu, s pstreze
adrese de memorie ale altor variabile care, la rndul lor, conin alte valori. n acest sens, un
nume de variabil refer direct o valoare, iar un pointer refer indirect o valoare. Referirea
unei valori printr-un pointer se numete indirectare.

count


7



count refer direct o
variabil a crei
valoare este 7


countPtr


count


7


countPtr r indirect este
o variabil a crei
valoare este 7
2

Pointerii, ca orice alt variabil, trebuie declarai nainte de a fi folosii.
Exemplu
int *countPtr, count;
Prin aceste declaraii, variabila countPtr este de tip int*, adic este pointer ctre o
valoare ntreag. Variabila count este de tip ntreg i nu pointer la ntreg. Fiecare variabil
declarat ca pointer este precedat de un asterisc *.
Exemplu
double *x, *y;
Att x ct i y sunt pointeri ctre valori de tip double. Aceste variabile pot pstra
adrese de memorie ale unor valori de tip double. Pot fi declarai pointeri ca s pointeze ctre
variabile de orice tip de dat.
Este indicat ca pointerii s fie iniializai fie odat cu declaraia acestora, fie printr-o instruciune
de asignare. Un pointer poate fi iniializat cu 0, NULL sau cu o adres de memorie. Un
pointer cu valoarea 0 sau NULL nu pointeaz ctre nicio zon de memorie. Constanta NULL
este declarat n fiierul header <iostream> i n alte cteva fiiere din biblioteca standard.
Iniializarea prin valoarea NULL este echivalent cu iniializarea prin valoarea 0, dar n C++ se
prefer cea de-a doua variant. ntregul 0 este convertit automat ctre o dres de tipul
pointerului.
Valoarea 0 este singurul ntreg care poate fi asignat direct unei variabile pointer fr
o conversie prealabil.
Pointerii constani sunt cei al cror coninut nu se poate modifica. Un astfel de pointer
trebuie iniializat n instruciunea de declarare.
Exempl
u
int x;
const int *xPtr = &x;

Operatori pentru pointeri
Operatorul adres & este unar i returneaz adresa operandului su.
Exemplu
3

int y = 5; int
*yPtr; yPtr =
&y;
Prin ultima instruciune, adresa de memorie a variabilei y este ncrcat n
variabila pointer yPtr

yPtr y


5



Exemplu
#include <iostream> using
std::cout; using std::endl;

int main()
{
int a; int
*aP; a = 7;
aP = &a;
cout << "Adresa lui a este " << &a
<< "\nValoarea lui aP este " << aP;
cout << "\n\nAdresa lui a este " << a
<< "\nValoarea lui *aP este " << *aP;
out << "\n\nOperatorii * si & sunt inversi unul altuia. "
<< "\n&*aP = " << &*aP
<< "\n*&aP = " << *&aP << endl;
cout << "\n\nAdresa lui aP este " << &aP << endl;

return 0;
4

}
Acest program afieaz pe ecran urmtorul rezultat:
Adresa lui a este 0x22ff74
Valoarea lui aP este 0x22ff7
Operandul operatorului adres trebuie s fie un lvalue (left value), adic o entitate
cruia i poate fi asignat o valoare, de exemplu valoarea unei variabile. Operatorul adres
nu poate fi aplicat constantelor sau expresiilor al cror rezultat nu poate fi referit.
Operatorul * numit operator de indirectare sau de derefereniere returneaz un
sinonim sau un alias pentru obiectul asupra pointeaz operandul su.
Instruciunea
cout << *aP << endl;
tiprete valoarea variabilei a care este 7, n acelai fel n care o face instruciunea
cout << a << endl;
Un pointer derefereniat poate fi folosit n partea stng a unei instruciuni de
asignare:*aP = 5;
Prin aceast operaie, valoarea 5 este asignat variabilei a.
Un pointer derefereniat poate fi folosit n diverse operaii:
cin >> *aP;
Un pointer este o variabila care contine o adresa de memorie la care se gaseste un alt obiect din
memorie (de regula o alta variabila). O variabila (pointer) care contine adresa altei variabile se
spune ca indica (pointeaza) catre cealalta variabila. Intelegerea si utilizarea corecta a pointerilor
este fundamentala pentru programarea in Limbajul C (LC). Declararea si utilizarea pointerilor
sunt importante in urmatoatrele trei ipostaze in definirea, declararea si apelul functiilor pointerii
asigura mijloacele prin care functiile apelate si executate pot modifica parametrii efectivi
transmisi de functiile aplelante tocmai prin furnizarea adreselor acestor parametri.
- in alocarea dinamica a memoriei pointerii accepta subrutinele Limbajului C (LC) de
alocare dinamica (alloc, malloc, etc.)
- in optimizarea programarii pointerii pot imbunatati eficienta unor subrutine
Declararea unor variabile de tip pointer se face utilizand sintaxa generala:
tip_pointer *nume_pointer;
unde:
5

- tip_pointer este tipul de baza al pointerului care precizeaza in esenta tipul variabilelor
indicate (adresate, pointate) de pointer si poate fi orice tip de variabila a LC
- nume_pointer este un identificator care denumeste variabila de tip pointer

- Pointerii reprezinta una din caracteristicile cele mai puternice ale LC dar si un mijloc de
generare a unor erori fatale atunci cand nu sunt folositi corespunzator. Ca exemplu se poate da
initializarea incorecta a unor pointeri care poate determina chiar caderea sistemului de operare
gazda
-Toate operatiile cu pointeri se refera, de fapt, la operatiile definite pe multimea tipurilor
referite de catre pointeri.
Operatori specifici pointerilor
1. Operatorul de adresare &, este un operator unar care returneaza adresa de
memorie a operandului specificat si are sintaxa:
adresa_de_memorie=&variabila;
unde:
-variabila este identificatorul unei variabile de un anumit tip declarata corespunzator
- adresa_de_memorie este o variabila de tip pointer care dupa executia atribuirii de mai
sus primeste ca valoare adresa de memorie a variabilei specificata.
Obsevatie:
Tipul de baza al variabilei pointer trebuie sa fie acelasi cu tipul variabilei indicate
(pointate, adresate).
Exemplu:
/* se declara variabila reala vr cu valoarea initiala 125.75, si variabila p de tip pointer
care va memora o adresa de memorie a unei variabile reale */
float vr=100, *p;
/* se memoreaza in p adresa de memorie a variabilei reale vr */
p=&vr;
2. Operatorul de indirectare *, este un operator unar, complementul
operatorului &, care returneaza valoarea variabilei aflata la adresa de memorie a
operandului specificat si are sintaxa:
variabila=*adresa_de_memorie;
6

unde:
- adresa_de_memorie este o variabila de tip pointer care contine adresa de memorie a
unei variabile de un anumit tip.
- variabila este identificatorul unei variabile de acelasi tip cu tipul variabilei a carei
adresa de memorie este memorata in adresa_de_memorie.
In urma executarii acestei operatii de atribuire variabila specificata prin variabila va
primi valoarea variabilei a carei adresa de memorie se afla in adresa_de_memorie.
Variabilele care memoreaza adrese de memorie, adica pointeri, trebuie declarate ca atare,
precizandu-se tipul variabilelor ale caror adrese le memoreaza si inserand simbolul * inaintea
numelor variabilelor de tip pointer cu sintaxa de mai jos.
[specificator_clasa_de_memorie] specificator_de_tip *p1[,*p2] ;
unde:
specificator_clasa_de_memorie este optional si precizeaza clasa de memorie a
variabilelor ale caror adrese de memorie urmeaza sa se memoreze in variabilele de tip pointer
p1.p2
specificator_de_tip precizeaza tipul variabilelor ale caror adrese de memorie urmeaza sa
se memoreze in variabilele de tip pointer p1,p2
p1, p2, sunt variabilele de tip pointer declarate, recunoscute prin simbolul * plasat
inaintea acestora.
Exemplu:
Sa se scrie un program in C care sa atribuie unei variabile intregi valoarea 125 si unei
variabile reale valoarea 1234.321 Apoi sa se determine adresele de memorie ale acestor
variabile si sa se atribuie apoi, prin intermediul pointerilor, valorile variabilelor de mai sus altor
doua variabile de acelasi tip afisandu-se pe ecran valorile acestor variabile.
#include <stdio.h>
void main(void)
{
int x=125,*px,y;
float a=-1234.321,*pa,b;
7

/* se declara variabila intreaga x cu valoarea initiala 125, variabila px de
tip pointer care va memora adresa de memorie a variabile intregi x si variabila
intreaga y */
int x=125, *px,y;
/* se declara variabila reala a cu valoarea initiala 1234.321, variabila pa
de tip pointer care va memora adresa de memorie a variabile reale a si variabila reala b
*/
float a=-1234.321, *pa,b;
printf(\n valorile variabilelor date:x=%d,a=%f,x,a);
/* se memoreaza in px adresa de memorie a variabilei intregi x */
px=&x;
/* se memoreaza in pa adresa de memorie a variabilei reale a */
pa=&a;
/* se atribuie variabilei intregi y valoarea variabilei a carei adresa se afla in px, adica
valoarea variabilei x=125 */
y=*px;
/* se atribuie variabilei reale b valoarea variabilei a carei adresa se afla in pa, adica
valoarea variabilei a=-1234.321 */
b=*pa;
printf(\n valorile variabilelor obtinute:y=%d,b=%f,y,b);
}
Operatii cu pointeri
1. Operatia de atribuire a unui pointer se realizeaza dupa sintaxa:
nume_pointer = expresie;unde:- nume_pointer este o variabila te tip pointer declarata
corespunzator.- expresie poate fi o alta variabila de tip pointer sau adresa unei variabile de
acelasi tip cu tipul de baza (&variabila)
Exemplu:
#include <stdio.h>
void main(void)
{
float a,b,*pa,*pb,*psab
8

printf(\n dati valorile reale a,b=);
scanf(%f%f,&a,&b);
pa = &a; /* pa va memora adresa variabilei reale a */
pb = &b; /* pb va memora adresa variabilei reale b */
psab = pa; /* psab va avea aceeasi val. ca pa, deci va avea adresa variabilei a */
*psab = *psab + *pb; /* sau *psab = *psab + b; */
printf(\n %f + %f = %f,*pa,*pb,*psab);
}
Operatiile de incrementare si decrementare ale pointerilor se realizeaza dupa sintaxa:
nume_pointer++; si nume_pointer--;unde - nume_pointer este o variabila te tip pointer
declarata corespunzator care adreseaza alte variabile de tipul de baza al pointerului.
Incrementarea si decrementarea unui pointer inseamna incrementarea si decrementarea
unei adrese si nu se face cu o unitate (1) ci cu o lungime egala cu lungimea tipului de baza al
poiterului exprimata in bytes
Daca tipul de baza este int (reprezentat pe 2 bytes) atunci incrementarea si decrementarea
se face cu 2 bytes, iar daca tipul de baza este float (reprezentat pe 4 bytes) atunci incrementarea
si decrementarea se face cu 4 bytes, s.a.m.d.
Exemplu: Daca in pointerul p, de tip float se afla adresa de memorie 3000 atunci, dupa
incrementarea p++, in p se va gasi adresa 3004 iar dupa decrementarea p--, in p se va gasi adresa
2996.
Adunarea si scaderea unei date de tip intreg , la un pointer se realizeaza dupa
sintaxa: nume_pointer = nume_pointer +/- expresie_intreaga
unde: - nume_pointer este o variabila te tip pointer declarata corespunzator care adreseaza alte
variabile de tipul de baza al pointerului.- expresie_intreaga este o expresie de tip intreg, pozitiva
sau negativa, care poate fi un literal, constanta, variabila, functie sau expresie intreaga.
In urma executarii acestor operatii variabila de tip pointer va contine adresa care se obtine
prin adunarea sau scaderea algebrica, la adresa continuta anterior de aceasta a valorii intregi a
expresiei intregi precizata.
Scaderea a doi pinteri de acelasi tuip de baza se realizeaza cu sintaxa:
n = nume_pointer1 nume_pointer2 unde- nume_pointer1 si nume_pointer2 sunt 2
variabile de tip pointer declarate corespunzator care adreseaza alte variabile de tipul de baza
9

comun al pointerilor n va contine, dupa efectuarea scaderii pointerilor, numarul obiectelor de
tipul de baza al pointerilor, aflate intre cele doua adrese de memorie.
Toate celelalte operatii aritmetice cunoscute (inmultirea, impartirea, operatiile pe biti)
sunt interzise iar operatiile de mai sus, permise cu intregi, sunt interzise pentru tipurile float si
double.
Compararea pointerilor se realizeaza prin relatia:
nume_pointer1 operator_relatie nume_pointer2 unde nume_pointer1 si nume_pointer2
sunt 2 variabile de tip pointer declarate corespunzator care adreseaza alte variabile de tipul de
baza comun al pointerilor operator_relatie este un operator de comparatie al LC (<, <=, >, >=,
==, !=)
Compararea pointerilor se rezuma la compararea adreselor continute in variabilele de tip pointer
iar rezultatul poate fi adevarat (o valoare diferita de zero) daca relatia de comparare este
adevarata si fals (o valoare egala cu zero) daca relatia de comparare este falsa.
II. Pointeri si tablouri in LC
Intre pointeri si tabluri, in LC, exista legaturi foarte stranse.In cazul general putem avea
urmatoarele declaratii de variabile:tip_de_baza nume_tablou [dim1][dim2] . [dimn],
*ptrtablou unde nume_tablou [dim1][dim2] . [dimn] este un tablou multidimensional
dim1,dim2, . ,dimn sunt dimensiunile maxime ale tabloului.
ptrtablou este un pointer care adreseaza date de acelasi tip cu elementele tabloului.
Instructiunea:
ptrtablou = nume_tablou;
va determina memorarea in ptrtablou a adresei primului element al tabloului, numele tabloului
fara indecsi reprezentand de fapt un pointer la primul element al tabloului.Iar referirile urmatoare
nume_tablou[n] si *(ptrtablou+n) unde n>=0 si n<=numarul total de elemente ale tabloului sunt
echivalente referinduse la acelasi element al tabloului.Prin urmare elementele unui tablou pot fi
referite prin indecsi (coordonatele tabloului) sau aritmetica pointerilor. Aritmetica pointerilor,
pentru referirea elementelor tablourilorm conduce la operatii mai rapide.
Exemplu:
Sa se citeasca un sir de la tastatura si apoi sa se afiseze pe ecran caracter cu caracter utilizandu-
se accesarea elementelor sirului prin indecsi si prin aritmetica pointerilor.
10

#include<stdio.h>
void afiseaza_prin_indici(char *sir)
{
int k;
printf(\n sirul afisat utilizandu-se tablou ci indice: );
for(k=0; sir[k]; ++k) putchar(sir[k]);
}
void afiseaza_prin_pointer(char *s)
{
printf(\n sirul afisat utilizandu-se pointeri: );
while(*s) puchar(*s++);
}
void main(void)
{
char sirdat[20];
printf(\n dati un sir de max 20 caractere:);
gets(sirdat);
/* apelarea celor doua functii pentru afisarea folosind indici si pointeri */
afiseaza_prin_indici(sirdat);
afiseaza_prin_pointer(sirdat);
}
Tablouri de pointeri in LC
Pointerii pot fi memorati in tablouri ca orice alt tip de date valid in LC care se pot declara
asfel int *nume_tablou[dim1][dim2] . ;
Unde nume_tablou este numele unui tablou multidimensional ale carui elemente sunt adrese de
variabile, deci valori intregi dim1, dim2, sunt dimensiunile maxime ale tabloului iar atribuirea
de valori (adrese de variabile) elementelor tabloului se face astfel:
nume_tablou[i1][i2][i3] . = &variabila;
unde nume_tablou este numele tablou multidimensional in care se memoreaza adrese de
variabile (deci valori intregi) - i1, i2, sunt indicii (coordonatele) unui element oarecare al
11

tabloului variabila este o variabila de un anumit tip a carei adresa se atribuie elementului de
tablou referit.
Mod de executie:
- se determina adresa de memorie a variabilei precizate (&variabila).
- se atribuie elementului de tablou referit prin indicii i1, i2, i3, valoarea adresei
variabilei determinate anterior.
iar atribuirea de valori (adrese de variabile) elementelor tabloului se face astfel:
Adresarea indirecta
Adresarea indirecta se aplica pointerilor care nu memoreaza adresele unor variabile ci
adresele unor alti pointeri care adreseaza niste variabile. Adresarea indirecta mai este cunoscuta
sub numele pointer de pointer. Adresarea indirecta poate fi extinsa la adresari indirecte multiple
dar nu este recomandata din cauza erorilor inerente care pot sa apara in timpul executiei
programelor.
Pentru adresarea indirecta simpla este nevoie de urmatoarea declaratie:
tip_de_baza **nume_pointer;
unde nume_pointer este numele unei variabile de tip pointer care memoreaza adresa unui alt
pointer care adreseaza o variabila de tipul precizat prin tip_de_baza.
Referirea sau accesarea variabilei adresate de pointerul a carui adresa se gaseste intr-un
pointer cunoscut se aplica de doua ori operatorul de indirectare (*)
Exemplu:
Sa se citeasca 10 numere reale oarecare de la tastatura si sa se calculeze media lor utilizandu-se
adresarea indirecta cu utilizarea pointerilor de pointeri.
#include <stdio.h>
void main(void)
{
float a,s=0,*pa,**ppa;
int i;
i=1;
while(i<=10)
{
printf(\n a=); scanf(%f,&a);
12

pa=&a; ppa=&pa;
s=s + **ppa; i++
}
printf(\n media=%f,s/(i-1));
}

Initializarea pointerilor
Dupa declararea unui pointer acesta poate contine o valoare necunoscuta. Incercarea de folosire a
unui pointer inainte de a i se atribui o valoare valida va determina o abandonare a executiei
programului cu o eroare fatala. Pentru a se evita acest neajuns unui pointer care nu contine nici o
adresa i se va atribui valoarea nula (care este zero) si ca atare nu trebuie folosit. Utilizarea valorii
nule pentru un pointer care nu contine nici o adresa nu este decat o conventie pentru
programatori neavand nici-o relevanta pentru compilatorul C. Folosirea unui pointer nul in
membrul stang al unei instructiuni de atribuire poate distruge programul sau chiar sistemul de
operare gazda. Si totusi un pointer nul poate fi folosit pentru a marca sfarsitul unui tablou de
pointeri sau unei liste de pointeri, ca in exemplul de mai jos:
Exemplu:
Functia cauta_nume cauta intr-un tablou de nume ale caror adrese sunt memorate intr-un
tablou de pointeri un nume bine precizat pana se detecteaza valoarea nula a ultimului pointer din
tablou:
#include <stdio.h>
#include <string.h>
/* cauta intr-o multime de nume un nume dat */
int cauta_nume(char *ptrnume[], *numedat)
{
int k;
for(k=0; ptrnume[k]; ++k)
if(!strcmp(ptrnume[k],numedat) return k;
return 1; /* nume negasit */
}
void main(void)
13

{
char a[10][10],wnume[10]; int *ptra[10];
for(i=0;i<10;i++)
{
printf(\n sirul(%d)=,i);
gets(a[i]); /* citirea unui nume oarecare in tabloul de nume */
ptra[i]=&a[i]; /* memorarea adresei sirului in tabloul de pointeri */
}
ptra[i]=0; /* plasarea valorii nule in ultimul element al tabloului de pointeri */
printf(\n dati numele de cautat:);
gets(wnume);
if (cauta_nume(ptra,wnume) == -1)
printf(\n numele %s nu se gaseste in textul introdus,wnume);
else
printf(\n numele %s se gaseste in textul introdus,wnume);
}
Initializarea sirurilor de caractere se poate face utilizand sintaxa urmatoare:
char *ptrsir = sir de caractere;
unde ptrsir nu este in acceptiunea LC un tablou ci este un pointer care adreseaza un sir de
caractere sir de caractere este un sir de caractere ASCII oarecare.
Desi o functie nu este o variabila, aceasta are o adresa fizica precisa de lansare in
executie, numita si punct de intrare in functie. Aceasta adresa poate, deci, fi atribuita unei
variabile de tip pointer, ceea ce poate duce la posibilitatea apelarii functiei folosind un pointer
catre functie. In orice limbaj de programare, deci si in LC, apelarea pentru executie a unei functii
presupune lansarea executiei programului in cod masina, obtinut dupa compilare si linkeditare,
de la adresa punctului de intrare in functie. Acest lucru permite ca apelarea si lansarea in
executie a unei functii sa se faca prin intermediul unui pointer catre functia respectiva. Ca si in
cazul obtinerii adreselor tablourilor (prin folosirea numelor acestora fara utilizarea indicilor)
adresele functiilor se obtin prin folosirea numelor acestora fara paranteze si argumente.


14



Functii de alocare dinamica de memorie in LC
Alocarea dinamica este un mijloc folosit, in programarea in LC, pentru alocarea de
memorie pentru diversele variabile pe parcursul executarii programului. Alocarea dinamica de
memorie se face cu ajutorul unor functii speciale numite functii de alocare dinamica. Prin aceste
functii pot fi alocate zone de memorie dinamice in zona speciala de memorie heap care se afla
intotdeauna intercalata intre programul utilizatorului impreuna cu zona de memorare permanenta
si memoria stiva. Dimensiunea zonei heap este necunoscuta utilizatorului dar dispune de o
cantitate relativ mare de memorie.
Pentru alocarea dinamica in LC se folosesc, in mod uzual, functiile malloc() si free(),
prima pentru alocarea dinamica propriu-zisa si cea de-a doua pentru eliberarea zonei de memorie
ocupata prin functia malloc(). Aceste functii se gasesc in fisierul antet (header) stdlib.h.
Alocarea dinamica de memorie se face cu sintaxa:
*malloc (size_t numar_de_bytes)
unde:
- size_t este un tip definit in fisierul stdlib.h ca un intreg fara semn
- numar_de_octeti reprezinta numarul de bytes (octeti) pe care programatorul doreste sa-i
aloce prin functia malloc
Dupa o alocare reusita functia malloc returneaza un pointer de tip void, (ceea ce precizeaza ca
poate fi atribuit oricarui tip de pointer), al primului octet liber din zona de memorie heap, iar
daca alocarea esueaza ca urmare a inexistentei lungimii de memorie ceruta din zona heap atunci
functia malloc returneaza valoarea zero.
Exemple:
- secventa de program:
char *ptrsir;
ptrsir = malloc(200); /* se aloca 200 octeti */
aloca 200 de octeti , iar adresa primului octet se va gasi in pointerul ptrsir
- secventa de program:
int *ptrint;
ptrint = malloc(75*sizeof(int); /* se aloca memorie pentru 75 nr. intregi */
15

aloca memorie pentru 75 de numere intregi (75*ziseof(int)=75*2 octeti), iar adresa primului
numar se va gasi in pointerul ptrint.
Deoarece zona heap de memorie nu este infinita (ci limitata), la fiecare alocare dinamica
de memorie, trebuie sa se verifice valoarea returnata de functia malloc pentru a fi siguri ca
alocarea s-a facut cu succes, ca in exemplul de mai jos:
int *ptrint;
ptrint = malloc(75*sizeof(int); /* se aloca memorie pentru 75 nr. intregi */
if(ptrint)
{
printf(\n memorie insuficienta, eroare de alocare);
exit(1);
}
Eliberarea zonei memorie alocata printr-o functie malloc se face cu functia free() avand
sintaxa urmatoare:
free(nume_pointer);
unde nume_pointer este variabila de tip pointer care contine adresa de memorie a zonei alocate si
utilizate anterior si care urmeaza sa fie disponibilizata pentru alte alocari dinamice viitoare.
Tehnica alocarii dinamice in LC este folosita alaturi de pointeri pentru crearea,
actualizarea si exploatarea unor structuri de date importante cum ar fi:listele simplu si dublu
inlantuite, arborii binari si tablourile alocate dinamic.
Tablouri alocate dinamic
Deoarece oricarui pointer i se poate aplica un indice, asemanator unui tablou unidimensional,
atunci se poate lucra cu zona de memorie indicata de un pointer ca si cum ar fi un tablou
unidimensional. Acest lucru permite crearea de tablouri alocate dinamic, ca in exemplul de mai
jos:
Se da un sir oarecare de la tastatura, de lungime maxima 60 caractere. Sa se afiseze acest
sir in sens direct cat si in sens invers utilizandu-se un tablou unidimensional alocat dinamic.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void main(void)
16

{
char *sir; int i;
sir = malloc(60); /* alocarea de memorie ptr sir */
if(!sir)
{
printf(\n cerere de memorie nesatisfacuta);
exit(1);
}
gets(sir);
printf(\n sirul in sens direct:);
for(i=0; i<strlen(sir);i++) putchar (sir[i]);
printf(\n sirul in sens invers:);
for(i=strlen(sir)-1; i>=0;i--) putchar (sir[i]);
}

Operatii cu pointeri
1. Operatia de atribuire a unui pointer se realizeaza dupa sintaxa:
nume_pointer = expresie;
unde nume pointer este o variabila te tip pointer declarata corespunzator expresie poate fi o alta
variabila de tip pointer sau adresa unei variabile de acelasi tip cu tipul de baza (&variabila)




Exemplu:
#include <stdio.h>
void main(void)
{
float a,b,*pa,*pb,*psab
printf(\n dati valorile reale a,b=);
scanf(%f%f,&a,&b);
17

pa = &a; /* pa va memora adresa variabilei reale a */
pb = &b; /* pb va memora adresa variabilei reale b */
psab = pa; /* psab va avea aceeasi val. ca pa, deci va avea adresa variabilei a */
*psab = *psab + *pb; /* sau *psab = *psab + b; */
printf(\n %f + %f = %f,*pa,*pb,*psab);
}
Operatiile de incrementare si decrementare ale pointerilor se realizeaza dupa sintaxa:
nume_pointer++; si nume_pointer--;
unde
- nume_pointer este o variabila te tip pointer declarata corespunzator care adreseaza alte
variabile de tipul de baza al pointerului.
Incrementarea si decrementarea unui pointer inseamna incrementarea si decrementarea
unei adrese si nu se face cu o unitate (1) ci cu o lungime egala cu lungimea tipului de baza al
poiterului exprimata in bytes
Daca tipul de baza este int (reprezentat pe 2 bytes) atunci incrementarea si decrementarea
se face cu 2 bytes, iar daca tipul de baza este float (reprezentat pe 4 bytes) atunci incrementarea
si decrementarea se face cu 4 bytes, s.a.m.d.
Exemplu: Daca in pointerul p, de tip float se afla adresa de memorie 3000 atunci, dupa
incrementarea p++, in p se va gasi adresa 3004 iar dupa decrementarea p--, in p se va gasi adresa
2996.
Adunarea si scaderea unei date de tip intreg , la un pointer se realizeaza dupa sintaxa:
nume_pointer = nume_pointer +/- expresie_intreaga
unde nume_pointer este o variabila te tip pointer declarata corespunzator care adreseaza alte
variabile de tipul de baza al pointerului.
- expresie_intreaga este o expresie de tip intreg, pozitiva sau negativa, care poate fi un
literal, constanta, variabila, functie sau expresie intreaga.
In urma executarii acestor operatii variabila de tip pointer va contine adresa care se obtine
prin adunarea sau scaderea algebrica, la adresa continuta anterior de aceasta a valorii intregi a
expresiei intregi precizata.
18

Scaderea a doi pinteri de acelasi tuip de baza se realizeaza cu sintaxa:
n = nume_pointer1 nume_pointer2;
unde nume_pointer1 si nume_pointer2 sunt 2 variabile de tip pointer declarate corespunzator
care adreseaza alte variabile de tipul de baza comun al pointerilor n va contine, dupa efectuarea
scaderii pointerilor, numarul obiectelor de tipul de baza al pointerilor, aflate intre cele doua
adrese de memorie.
Toate celelalte operatii aritmetice cunoscute (inmultirea, impartirea, operatiile pe biti)
sunt interzise iar operatiile de mai sus, permise cu intregi, sunt interzise pentru tipurile float si
double.
Compararea pointerilor se realizeaza prin relatia:
nume_pointer1 operator_relatie nume_pointer2 unde nume_pointer1 si nume_pointer2
sunt 2 variabile de tip pointer declarate corespunzator care adreseaza alte variabile de tipul de
baza comun al pointerilor operator_relatie este un operator de comparatie al LC (<, <=, >, >=,
==, !=)
Compararea pointerilor se rezuma la compararea adreselor continute in variabilele de tip pointer
iar rezultatul poate fi adevarat (o valoare diferita de zero) daca relatia de comparare este
adevarata si fals (o valoare egala cu zero) daca relatia de comparare este falsa.













19

Concluzie:
Pointerii permit:
s realizm modificarea unor valori trimise ca parametrii unei funcii
s accesm mult mai eficient tablourile.
ofer mijlocul de a accesa indirect o valoare a ununi tip de dat.
s lucrm cu zone de memorie alocate dynamic
Intre pointeri si tabluri, in LC, exista legaturi foarte stranse.
In cazul general putem avea urmatoarele declaratii de variabile tip_de_baza nume_tablou
[dim1][dim2] . [dimn], *ptrtablou;
Unde nume_tablou [dim1][dim2] . [dimn] este un tablou multidimensional dim1,dim2, .
,dimn sunt dimensiunile maxime ale tabloului ptrtablou este un pointer care adreseaza date de
acelasi tip cu elementele tabloului.
Instructiunea:
ptrtablou = nume_tablou;
va determina memorarea in ptrtablou a adresei primului element al tabloului, numele tabloului
fara indecsi reprezentand de fapt un pointer la primul element al tabloului.
Iar referirile urmatoare:
nume_tablou[n] si *(ptrtablou+n) unde n>=0 si n<=numarul total de elemente ale
tabloului sunt echivalente referinduse la acelasi element al tabloului.
Prin urmare elementele unui tablou pot fi referite prin indecsi (coordonatele tabloului)
sau aritmetica pointerilor. Aritmetica pointerilor, pentru referirea elementelor tablourilorm
conduce la operatii mai rapide.

20






Bibriografie:


http://vega.unitbv.ro/~cataron/Courses/PCLPI/PCLP1_Capitolul11.pdf

http://www.math.uaic.ro/~eduard/Laborator%2014%20-%20Referinte%20si%20Pointeri.pdf

http://www.bitcell.info/nu-inteleg-pointerii-din-c-c-t524.html

http://tutorialeplusplus.blogspot.com/2013/06/tutoriale-c-pointeri-memorie-dinamica.html

http://www.cplusplus.com/doc/tutorial/pointers/

http://infoscience.3x.ro/c++/pointeri.html

http://193.226.6.120/Miclea/Prg/curs/PDF/B05_Pointeri.pdf

http://bigfoot.cs.upt.ro/~gabia/TP/2008/L03-Pfunct_arg.htm
http://www.scritub.com/stiinta/informatica/c/Pointeri-catre-functii94248.php
http://subprogrameatestat.wikispaces.com/Pointeri+c%C4%83tre+o+func%C5%A


21

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