Documente Academic
Documente Profesional
Documente Cultură
Manual Programare - Pointeri C++
Manual Programare - Pointeri C++
"
" # $
# $
%&
' ! "
%
% " % ()) %
()) *
int px, x, y; % %+ ,-
. ! . /#0 1$
px = &x; -
, % %,-
. , #0 1$
y=*px; -
, % % + %
%,-
2
" %
!
.
#$ 3
4
. , 5
2%
9 !
2%
%&'
2%
%&'(
3 ,! / %
: :: ! ;
-
. "
5 " %
int *p;
! 7))) " %
p++;
! ( + !
7))7
! !
3 !
p--;
<<=
" # > +
$ 7)))
float *p;
%
p++;
7))>
3 5 -
-
!
? - - " %
, -
.
6 !
@
3 ! !
(
!
. -
! '
" %
5 !
Pointeri
Simbolul precizeaz c identificator_pointer este numele unei variabile pointer de date, iar
tip este tipul obiectelor a cror adres o va conine.
Exemplu:
int u, v, p, q; // p, q sunt pointeri de date (ctre int)
double a, b, p1, q1; // p1, q1 sunt pointeri ctre date de tip double
void identificator_pointer;
Exemplu:
void m;
Aceasta permite declararea unui pointer generic, care nu are asociat un tip de date precis. Din acest motiv, n
cazul unui pointer vid, dimensiunea zonei de memorie adresate i interpretarea informaiei nu sunt definite,
iar proprietile difer de ale pointerilor de date.
5.1.2. INIIALIZAEA VARIABILELOR POINTER
& - operatorul adres (de refereniere) - pentru aflarea adresei din memorie a unei variabile;
- operatorul de indirectare (de defereniere) - care furnizeaz valoarea din zona de memorie spre
care pointeaz pointerul operand.
n exemplul prezentat n figura 5.1, pentru variabila ntreag x, expresia &x furnizeaz adresa
variabilei x. Pentru variabila pointer de obiecte int, numit ptr, expresia ptr nseamn coninutul locaiei
de memorie a crei adres este memorat n variabila ptr. Expresia ptr poate fi folosit att pentru aflarea
valorii obiectului spre care pointeaz ptr, ct i pentru modificarea acesteia (printr-o operaie de atribuire).
Exemplu:
int x, y, ptr;
// ptr- variabil pointer ctre un int; x,y-variabile predefinite, simple, de tip int
n exemplul anterior, atribuirea ptr=&x se execut astfel: operatorul & furnizeaz adresa lui x;
operatorul = atribuie valoarea (care este o adres) variabilei pointer ptr.
Atribuirea y= ptr se realizeaz astfel: operatorul acceseaz coninutul locaiei a crei adres este
coninut n variabila ptr; operatorul = atribuie valoarea variabilei y.
Declaraia int ptr; poate fi, deci, interpretat n dou moduri, ambele corecte:
ptr este de tipul int ( ptr este de tip pointer spre int)
ptr este de tipul int (coninutul locaiei spre care pointeaz variabila ptr este de tipul int)
Construcia tip este de tipul pointer ctre int.
Exemple:
int x, y, q; q=&x;
x=&y; //invalid: x nu este variabil pointer, deci nu poate fi folosit cu operatorul de indirectare
y= q + 3; // echivalent cu y=x+3;
q = 0; // seteaz x pe 0
int r; r = q;
/* copiaz coninutul lui q (adresa lui x) n r, deci r va pointa tot ctre x (va conine tot adresa lui
x)*/
Pointeri
double w, r = &w, r1, r2; r1= &w; r2=r1;
cout<<z=<<z<<\n;
La declararea pointerilor generici ( void nume; ) nu se specific un tip, deci unui pointer void i se pot
atribui adrese de memorie care pot conine date de diferite tipuri: int, float, char, etc. Aceti pointeri pot fi
folosii cu mai multe tipuri de date, de aceea este necesar folosirea conversiilor explicite prin expresii de
tip cast, pentru a preciza tipul datei spre care pointeaz la un moment dat pointerul generic.
Exemplu:
1. Conversia tipului pointer generic spre un tip concret nseamn, de fapt, precizarea tipului de pointer pe
care l are valoarea pointerului la care se aplic conversia respectiv.
2. Conversia tipului pointer generic asigur o flexibilitate mai mare n utilizarea pointerilor.
3. Utilizarea n mod abuziv a pointerilor generici poate constitui o surs de erori.
n afara operaiei de atribuire (prezentat n paragraful 5.1.2.), asupra variabilelor pointer se pot realiza
operaii de comparare, adunare i scdere (inclusiv incrementare i decrementare).
Pointeri
Exemplu:
if (p1<p2)
cout<<p1=<<p1<<<<<p2=<<p2<<\n;
else cout<<p1=<<p1<<>=<<p2=<<p2<<\n;
O operaie uzual este compararea unui pointer cu valoarea nul, pentru a verifica dac acesta
adreseaz un obiect. Compararea se face cu constanta simbolic NULL (definit n header-ul stdio.h)
sau cu valoarea 0.
Exemplu:
. . . . . ; // pointer nul
Astfel, dac ptr este un pointer ctre tipul tip (tip ptr;), iar n este un ntreg, expresiile
ptr + n i ptr - n
Un caz particular al adunrii sau scderii dintre un pointer de date i un ntreg (n=1) l reprezint
incrementarea i decrementarea unui pointer de date. n expresiile ptr++, respectiv ptr--, valoarea
variabilei ptr devine ptr+sizeof(tip), respectiv, ptr-sizeof(tip).
Este permis scderea a doi pointeri de obiecte de acelai tip, rezultatul fiind o valoare ntreag care
reprezint diferena de adrese divizat prin dimensiunea tipului de baz.
Exemplu: Pointeri
int a, pa, pb;
n limbajele C/C++ exist o strns legtur ntre pointeri i tablouri, deoarece numele unui tablou este un
pointer (constant!) care are ca valoare adresa primului element din tablou. Diferena dintre numele unui
tablou i o variabil pointer este aceea c unei variabile de tip pointer i se pot atribui valori la execuie,
lucru imposibil pentru numele unui tablou. Acesta are tot timpul, ca valoare, adresa primului su element.
De aceea, se spune c numele unui tablou este un pointer constant (valoarea lui nu poate fi schimbat).
Numele unui tablou este considerat ca fiind un rvalue (right value-valoare dreapta), deci nu poate apare
dect n partea dreapt a unei expresii de atribuire. Numele unui pointer (n exemplul urmtor, ptr) este
considerat ca fiind un lvalue (left value-valoare stnga), deci poate fi folosit att pentru a obine valoarea
obiectului, ct i pentru a o modifica printr-o operaie de atribuire.
Exemplu:
a = a + 1; // ilegal
ptr = a ; // legal: ptr are aceeai valoare ca i a, respectiv adresa elementului a[0]
Deoarece numele tabloului a este sinonim pentru adresa elementului de indice zero din tablou, asignarea
ptr=&a[0] poate fi nlocuit, ca n exemplul anterior, cu ptr=a.
Aa cum s-a artat n capitolul 4, un ir de caractere poate fi memorat ntr-un vector de caractere. Spre
deosebire de celelalte constante, constantele ir de caractere nu au o lungime fix, deci numrul de octei
alocai la compilare pentru memorarea irului, variaz. Deoarece valoarea variabilelor pointer poate fi
Pointeri
schimbat n orice moment, cu mult uurin, este preferabil utilizarea acestora, n locul tablourilor de
caractere (vezi exemplul urmtor).
Exemplu:
Operaia de indexare a elementelor unui tablou poate fi realizat cu ajutorul variabilelor pointer.
Exemplu:
int a[10], ptr; // a este pointer constant; ptr este variabil pointer
Deoarece numele unui tablou este un pointer (constant), putem concluziona (figura 5.2):
a+i & a[i]
a[i] (a+i)
68
CAPITOLUL 5 Pointeri
Exerciiu: S se scrie urmtorul program (care ilustreaz legtura dintre pointeri i vectori) i s se
urmreasc rezultatele execuiei acestuia.
#include <iostream.h>
void main(void)
/* x primete valoarea locaiei a carei adres se afl n variabila pointer pi1, deci valoarea lui a[0]
*/
/* x=0: nti atribuirea, apoi incrementarea valorii spre care pointeaz pi1. n urma incrementrii,
valoarea lui a[0] devine 1 */
pi3=pi1+3;
cout<<pi3-pi1=<<(pi3-pi1)<<\n; //pi3-pi1=3
#include <iostream.h>
void main(void)
cout<<sir1+2=<<(sir1+2)<< psir+2=<<(psir+2)<<\n;
// sir1+2=rul 1 psir+2=rul 1
pv1=psir; pv2=sir1;
cout<<pv1=<<pv1<<&pv1=<<&pv1<<\n;
cout<<pv2=<<pv2<<&pv2=<<&pv2<<\n;
Exerciiu: S se scrie un program care citete elementele unui vector de ntregi, cu maxim 20
elemente i nlocuiete elementul maxim din vector cu o valoare introdus de la tastatur. Se va folosi
aritmetica pointerilor.
#include <iostream.h>
void main()
{ int a[20];
if (max<= (a+i))
int val;
(a+indice)=val;
cout<< (a+i);<<'\t';
cout<<'\n';
/* n acest mod de implementare, n situaia n care n vector exist mai multe elemente a cror
valoare este egal cu valoarea elementului maxim, va fi nlocuit doar ultimul dintre acestea (cel de
indice maxim).*/
Elementele unui tablou bidimensional sunt pstrate tot ntr-o zon continu de memorie, dar
inconvenientul const n faptul c ne gndim la aceste elemente n termeni de rnduri (linii) i coloane
(figura 5.3). Un tablou bidimensional este tratat ca un tablou unidimensional ale crui elemente sunt
tablouri unidimensionale.
int M[4][3]={ {10, 5, -3}, {9, 18, 0}, {32, 20, 1}, {-1, 0, 8} };
Compilatorul trateaz att M, ct i M[0], ca tablouri de mrimi diferite. Astfel:
Matricea M
M[0] 10 5 -3 Matricea M are 4 linii i 3 coloane.
71
Numele tabloului bidimensional, M, refer ntregul tablou;
M[1] 9 18 0
M[0] refer prima linie din tablou;
Putem concluziona:
#include <iostream.h>
void main()
cout<<" *(a+"<<i<<")="<<*(a+i);
cout<<" a["<<i<<"]="<<a[i]<<'\n';
}
Pointeri
// afiarea matricii
cout<<*(*(a+i)+j)<<'\t'; //sau:
cout<<*(a[i]+j)<<'\t';
cout<<'\n';
Un tablou de pointeri este un tablou ale crui elemente sunt pointeri. Modul general de declarare a unui
tablou de pointeri:
tip nume_tablou[dim];
S considerm exemplul n care se declar i se iniializeaz tabloul de pointeri str_ptr (figura 5.4.):
str_ptr
Deoarece operatorul de indexare [ ] are
str_ptr[0] prioritate mai mare dect operatorul de
Programarea
defereniere , declaraia char str_ptr[3]
este echivalent cu char (str_ptr[3]), care
str_ptr[1] precizeaz c str_ptr este un vector de trei
este
elemente, fiecare element este pointer ctre
Figura 5.4. Tabloul de pointeri str_ptr caracter.
str_ptr[2]
frumoas!
Pointeri
n ceea ce privete declaraia: char (str_ptr[3]), se poate observa:
1. str_ptr[3] este de tipul char (fiecare dintre cele trei elemente ale vectorului str_ptr[3] este
de tipul pointer ctre char);
2. (str_ptr[3]) este de tip char (coninutul locaiei adresate de un element din str_ptr[3] este
de tip char).
Fiecare element (pointer) din str_ptr este iniializat s pointeze ctre un ir de caractere constant.
Fiecare dintre aceste iruri de caractere se gsesc n memorie la adresele memorate n elementele
vectorului str_ptr: str_ptr[0], str_ptr[1], etc.
char p=heLLO;
( p+1) = e p[1] = e;
n mod analog:
str_ptr[1] = este;
( str_ptr[1] + 1) = s; str_ptr[1][1]=s;
Putem conculziona:
str_ptr este un de tip char. Este evident, deoarece str_ptr[0][0] este de tip char, iar
str_ptr= ( str_ptr) (str_ptr[0])= (str_ptr[0]+0)
str_ptr[0][0].
S revedem exemplul cu tabloul de pointeri str_ptr. irurile spre care pointeaz elementele tabloului
pot fi accesate prin str_ptr[index], ns deoarece str_ptr este un pointer constant, acestuia nu i se
pot aplica operatorii de incrementare i decrementare. Este ilegal :
for (i=0;i<3;i++)
cout<<str_ptr++ ;
Pointeri
De aceea, putem declara o variabil pointer ptr_ptr, care s pointeze ctre primul element din str_ptr.
Variabila ptr_ptr este pointer ctre pointer i se declar astfel:
char ptr_ptr;
n exemplul urmtor este prezentat modul de utilizare a pointerului la pointer ptr_ptr (figura 5.5).
Exemplu:
char ptr_ptr;
char ptr_ptr;
ptr_ptr = str_ptr;
frumoas!
Exemplu:
Atribuirile de forma:
*sirul=coco;
*(sirul+2)=A;
nu sunt acceptate, deoarece pointerul sirul pointeaz ctre o dat constant (ir constant).
Exemplu:
Exemplu:
Sa se calculeze suma elementelor unui vector folosind o functie de tip int cu pointer la referinta