Sunteți pe pagina 1din 6

Lucrarea nr.

Notiuni despre pointeri

Un pointer este o variabilă care are ca valori adrese. Pentru modificarea unui parametru
în cadrul unei funcţii este necesar ca programul să transmită funcţiei adresa respectivului
parametru (un pointer). Funcţia, la rândul ei, utilizează apoi o variabilă pointer pentru a
accesa locaţia de memorie corespunzătoare.
• Pentru simplitate (pentru reducerea codului), multe programe tratează un şir de
caractere ca un pointer şi manipulează conţinutul şirului cu ajutorul operaţiilor cu
pointeri.
• La incrementarea unei variabile pointer, C++ incrementează automat adresa cu o
valoare adecvată (1 octet pentru char, 2 octeţi pentru int, patru octeţi pentru
float,etc.), astfel încât pointerul să indice următoarea valoare pe care o are tipul
pointerului.
• Programele pot utiliza pointeri pentru a lucra cu vectori întregi sau în virgulă mobilă.

Fie de exemplu:
int x,y;
atunci, dacă p are ca valoare adresa lui x, atribuirea
y=x+100
este identică cu:
y=*p+100
În mod analog, atribuirea:
*p=3
este identică cu:
x=3.

În construcţia *p utilizată mai sus, caracterul * se consideră ca fiind un operator


unar care furnizează valoarea din zona de memorie a cărei adresă este conţinută în p. Dacă
p conţine adresa zonei de memorie alocată lui x, vom spune că p pointează spre x.
Pentru a atribui o adresă unei variabile de tip pointer se poate folosi operatorul unar
&. Astfel, dacă dorim ca p să pointeze spre x putem utiliza atribuirea:
p=&x.
Operatorul unar & este numit operator adresă sau de referenţiere. Operatorul unar *
îl vom numi operator de indirectare sau dereferenţiere.

Utilizarea unui pointer la un şir de caractere

Atunci când programele transmit vectori (un şir de caractere, de pildă) către funcţii,
C++ transmite ca parametru adresa primului element al vectorului. Prin urmare este uzual
ca funcţiile să folosească pointeri la şiruri de caractere

void o_functie(char *sir)


Programul următor foloseşte în cadrul funcţiei afiseaza_şir un pointer la un şir de
caractere pentru a afişa conţinutul şirului caracter cu caracter :

#include <iostream.h>
#include <stdlib.h>
void afiseaza_sir(char *string)
{
while (*string != '\0')
{
cout << *string<<endl;
string++;
}
}

void main (void)


{
afiseaza_sir("Laborator C++");

system ("pause");
}

După cum s-a văzut, funcţiile pot parcurge caracterele unui şir prin intermediul
unui pointer până la întîlnirea caracterului NULL. Programul următor utilizează în funcţia
lungime_sir un pointer la un şir de caractere pentru a determina numărul de caractere din
şir :

#include <iostream.h>
#include <stdlib.h>
int lungime_sir (char *sir)
{
int lungime =0;
while (*sir != '\0')
{
lungime++;
sir++;
}
return(lungime);
}

void main (void)


{
char titlu[] = "Laborator de C++";
cout << titlu << "Contine" << lungime_sir(titlu)<<"caractere"<<endl;

system ("pause");
}

Deşi pointerii sînt cel mai uzual utilizaţi în cazul şirurilor de caractere, aceştia pot fi
folosiţi şi pentru alte tipuri de vectori. Spre exemplu, programul care urmează, foloseşte un
pointer la un vector de tip float pentru a afişa valorile în virgulă mobilă conţinute :
#include <iostream.h>
#include <stdlib.h>

void afiseaza_float(float *vector, int numar_elemente)


{
int i;
for (i=0;i<numar_elemente;i++)
cout << *vector++ <<endl;
}
void main (void)
{
float valori [5] = {2.75, 3.56, 4.56, 5.68, 10.21};
afiseaza_float(valori,5);

system ("pause");
}

Un alias este un alt nume dat unei variabile. În C, programele pot crea un alias
utilizând pointerii. C++ simplifică crearea de aliasuri utilizând referinţele. Pentru a crea o
referinţă, se utilizează operatorul de referenţiere (&):

int variabilă;
int& alias_variabilă;

Operatorul de referenţiere urmează imediat unui tip. Fiecare alias poate corespunde
numai unei singure variabile de-a lungul existenţei sale. Următorul program creează două
aliasuri şi le utilizează pentru a afişa adresele variabilelor specificate:

#include <iostream.h>
#include <stdlib.h>

void main(void)
{
int a=1001;
int& a_alias=a;
float pret=39.35;
float& pret_alias=pret;
cout<<"Valoarea lui a: "<<a<<'\n'<<"aliasul:"<<a_alias<<'\n';
cout<<"Pretul : "<<pret<<'\n'<<"aliasul: "<<pret_alias<<'\n';
a_alias++;
pret_alias++;
cout<<"Valoarea lui a : "<<a<<'\n'<<"aliasul :"<<a_alias<<'\n';
cout<<"Pretul : "<<pret<<'\n'<<"aliasul: "<<pret_alias<<'\n'<<endl;
system ("pause");
}

Pentru a modifica o variabilă în cadrul unei funcţii, programele trebuie să transmită


un pointer către variabilă. În C++, se poate simplifica modificarea unei variabile în cadrul
unei funcţii, folosind o referinţă. Următorul program transmite o referinţă la variabila
valoare către funcţia modif_val, care atribuie variabilei valoarea 1500:

#include <iostream.h>
#include <stdlib.h>

void modif_val(int& val_referinta)


{
val_referinta=1500;
}
void main(void)
{
int valoare=10;
int& alias=valoare;
cout<<"Valoarea inaintea functiei: "<<valoare<<'\n';
modif_val(alias);
cout<<"Valoare dupa functie: "<<valoare<<endl;

system ("pause");
}

În C, programele pot transmite parametri către funcţii utilizând apelarea prin valoare
şi apelarea prin pointer de referinţă. În C++, programele pot utiliza o a treia tehnică,
apelarea prin referinţă. Următorul program ilustrează modul în care se utilizează toate cele
trei tehnici:

#include <iostream.h>
#include <stdlib.h>
#include <iomanip.h>

void apel_prin_valoare(int a,int b,int c)


{
a=3;b=2;c=1;
}
void apel_prin_pointer_referinta(int *a,int *b,int *c)
{
*a=3;*b=2;*c=1;
}
void apel_prin_referinta(int& a,int& b,int& c)
{
a=3;b=2;c=1;
}

void main(void)
{
int a=1,b=2,c=3;
int& a_alias=a;
int& b_alias=b;
int& c_alias=c;
apel_prin_valoare(a,b,c);
cout<<"Prin valoare: "<<a<<b<<c<<endl;
apel_prin_pointer_referinta(&a,&b,&c);
cout<<"Prin pointer: "<<a<<b<<c<<endl;
apel_prin_referinta(a_alias,b_alias,c_alias);
cout<<"Prin referinta: "<<a<<b<<c<<endl;

system ("pause");
}

Când se utilizează referinţe, trebuie respectate următoarele reguli:


1. După iniţializare, programul nu poate modifica valoarea referinţă.
2. Tipul referinţei şi tipul variabilei trebuie să fie acelaşi.
3. Nu se poate crea un pointer la o referinţă.
4. Nu se pot compara valorile a două referinţe – comparaţiile ar compara valorile
variabilelor referenţiate.
5. Nu poate fi incrementată, decrementată sau modificată valoarea referinţei – operaţiile
se vor aplica valorii variabilelor referenţiate.

Modul de lucru

1. Se vor edita şi rula toate programele din cuprinsul lucrării.


2. Să se realizeze un program ce ordonează crescător elementele unui vector de numere
reale şi apoi se afişează elementele şi adresele la care acestea se află în memorie.
3. Să se realizeze un program care foloseşte o funcţie ce primeşte ca argumente un
pointer la un vector de numere reale şi un pointer la o funcţie şi returnează cel mai
mic, respectiv cel mai mare element al vectorului prin apelarea unei funcţii de calcul
a minimului respectiv a maximului.
4. Să se scrie un program care citeşte o dată sub forma zz ll aaaa (de ex. 20 11 2001) şi
o afişează sub forma yy luna aaaa (20 noiembrie 2001) folosind o funcţie ce
returnează un pointer spre denumirea lunii calendaristice respective.
5. Să se scrie un program care determină rădăcina ecuaţiei f(x)=0 din intervalul [a,b] cu
o eroare mai mică decât EPS=1e-8, ştiind că ecuaţia are o singură rădăcină în
intervalul respectiv şi f(x) este o funcţie continuă pe acest interval. Se va utiliza o
funcţie ce apelează ca parametru funcţia f căreia i se calculează rădăcina.
(Indicaţie:
Una din cele mai simple metode de calcul este metoda înjumătăţirii al cărei algoritm
este următorul:

1) c=(a+b)/2
2) Dacă f(c)=0, atunci c este soluţia căutată şi se întrerupe procesul de calcul.
3) Dacă f(a)*f(c)<0, atunci se pune b=c, altfel a=c
4) Dacă b-a<EPS, atunci procesul de calcul se întrerupe şi rădăcina se ia media
dintre a şi b.
Altfel algoritmul se reia de la pasul 1).
Se va aplica programul de mai sus la calculul rădăcinii ecuaţiei:
x-sin(x+1)=0
în intervalul [0.5 , 1], cu o eroare mai mică de 1e-8.
6. Să se realizeze un program ce creează o listă simplă înlănţuită ale cărei noduri sunt
structuri ce au următoarele câmpuri:
cheie, nume, prenume, vârstă, salariu.
Se va ordona lista crescător după nume şi după vârstă.
7. Să se realizeze un program pentru calculul rădăcinilor ecuaţiei de gradul II folosind o
funcţie ai carei parametrii (coeficienţii ecuaţiei) vor fi apelaţi prin pointer şi prin referinţă.

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