Professional Documents
Culture Documents
Pointeri
POINTERI
5.1.Variabile pointer 5.1.1. Declararea variabilelor pointer 5.1.2. Ini!iali"area variabilelor pointer 5.1.3. Pointeri $enerici 5.2. Opera!ii cu pointeri 5.3. Pointeri i tablouri
5.3.1. Pointeri i iruri de caractere 5.3.2. Pointeri i tablouri bidimen ionale 5.#. Tablouri de pointeri 5.5. Pointeri la pointeri 5.%. &odi'icatorul con t (n declararea pointerilor
*./0 *./2
Aceasta permite declararea unui pointer eneric& care nu are asociat un tip de date precis. %in acest motiv& #n cazul unui pointer vid& dimensiunea zonei de memorie adresate 1i interpretarea in,orma!iei nu sunt de,inite& iar propriet"!ile di,er" de ale pointerilor de date.
)*
m;
CAPITOLUL 5
Pointeri
55 ptr$ variabil" pointer c"tre un int( +&;$variabile prede,inite& simple& de tip int
x=5; cout<<Adresa variabilei x este:<< x<<!"n!; cout<<#aloarea lui x:<<x<<!"n!; ptr= x; 55 atribuire' variabila ptr con!ine adresa variabilei + cout<<#ariabila pointer ptr are valoarea:<<ptr; cout<< si adresea$a obiectul:<< ptr<<!"n!; y= ptr; cout<<y=<<y<<!"n!; 55 ;<5 x=%; cout<<x=<<x<<!"n!; cout<< ptr=<< ptr<<!"n!;
ptr;
ptr reprezinta acelasi obiect& un intre cu valoarea 0 x=&'; 55 ec3ivalenta cu ptr<=.( y=x(1'; 55 ec3ivalenta cu ;< ptr>*.
55 + si
-n e+emplul anterior& atribuirea ptr=&x se e+ecut" ast,el' operatorul ,urnizeaz" adresa lui x( operatorul = atribuie valoarea (care este o adres") variabilei pointer ptr. Atribuirea y= ptr se realizeaz" ast,el' operatorul acceseaz" con!inutul loca!iei a c"rei adres" este con!inut" #n variabila ptr( operatorul = atribuie valoarea variabilei y. %eclara!ia int ptr; poate ,i& deci& interpretat" #n dou" moduri& ambele corecte' ptr este de tipul int ( ptr este de tip pointer spre int) ptr este de tipul int (con!inutul loca!iei spre care pointeaz" variabila ptr este de tipul int) Construc!ia tip este de tipul pointer c"tre int. Atribuirea x=8;este ec3ivalent" cu ptr=&x; p=x; Variabilele pointer& al"turi de operatorii de re,eren!iere 1i de de,eren!iere& pot apare #n e+presii. Exemple:
int x, y, q; q= x; 55 ec3ivalent" cu +<2( q=); q= 5; 55 invalid" $ constantele nu au adres" 55 invalid" $ + nu este variabil" pointer x=*; x= y; 55invalid"' + nu este variabil" pointer& deci nu poate ,i ,olosit" cu operatorul de indirectare y= q ( +; 55 ec3ivalent" cu ;<+>?( q = '; 55 seteaz" + pe . q (= 1; 55 ec3ivalent" cu ( 6)>> sau cu +>> int r; r = q;
5@ copiaz" con!inutul lui 6 (adresa lui +) #n r& deci r va pointa tot c"tre + (va con!ine tot adresa lui +)@5
double ,, r = ,, r1, r-; r1= ,; r-=r1; cout<<r1=<<r1<<!"n!; 55a,i1eaz" valoarea pointerului r* (adresa lui A) cout<< r1=<< r1<<!"n!; 55 a,i1eaz" adresa variabilei r* cout<< r1= << r1<<!"n!; double $= r1; 55 ec3ivalent" cu z<A
)/
CAPITOLUL 5 cout<<$=<<$<<!"n!;
Pointeri
interpretat" ca ,iind adresa zonei de memorie care con!ine o data de tip c3ar. @5 Pe baza e+emplului anterior& se pot ,ace observa!iile' *. Conversia tipului pointer eneric spre un tip concret #nseamn"& de ,apt& precizarea tipului de pointer pe care #l are valoarea pointerului la care se aplic" conversia respectiv". /. Conversia tipului pointer eneric asi ur" o ,le+ibilitate mai mare #n utilizarea pointerilor. ?. Utilizarea #n mod abuziv a pointerilor enerici poate constitui o surs" de erori.
Compararea valorilor variabilelor pointer Valorile a doi pointeri pot ,i comparate& ,olosind operatorii relaionali& ca #n e+emplul' Exemplu:
int p1, p-; if .p1<p-/ cout<<p1=<<p1<<<<<p-=<<p-<<!"n!; else cout<<p1=<<p1<<2=<<p-=<<p-<<!"n!;
O opera!ie uzual" este compararea unui pointer cu valoarea nul& pentru a veri,ica dac acesta adreseaz un obiect. Compararea se ,ace cu constanta simbolic" 3455 (de,init" #n 3eader$ul stdio60) sau cu valoarea .. Exemplu:
if .7p1/ 6 6 6 6 6 ; else 6 6 6 6 ;
Adunarea sau sc"derea 4unt permise opera!ii de adunare sau scdere ntre un pointer de obiecte i un ntreg' Ast,el& dac" ptr este un pointer c"tre tipul tip (tip ptr;)& iar n este un #ntre & e+presiile ptr + n 8i ptr - n au ca valoare& valoarea lui ptr la care se adau "& respectiv& se scade n sizeof(tip).
)?
CAPITOLUL 5
Pointeri
Un caz particular al adun"rii sau sc"derii dintre un pointer de date 1i un #ntre ( n=1) #l reprezint" incrementarea 1i decrementarea unui pointer de date. -n e+presiile ptr((& respectiv ptr99& valoarea variabilei ptr devine ptr+sizeof(tip)& respectiv& ptr-sizeof(tip). 9ste permis" scderea a doi pointeri de obiecte de acelai tip & rezultatul ,iind o valoare #ntrea " care reprezint" di,eren!a de adrese divizat" prin dimensiunea tipului de baz". Exemplu:
int a, pa, pb; cout<< a=<< a<<!"n!; pa= a; cout<<pa=<<pa<<!"n!; cout<<pa(-<<pa(-<<!"n!; pb=pa((; cout<<pb=<<pb<<!"n!; int i=pa9pb; cout<<i=<<i<<!"n!;
ptr;
int x = a:';;
55 a este de,init ca DaE.F( a este pointer constant 55 ile al 55 le al' ptr are aceea1i valoare ca 1i a& respectiv adresa elementului aE.F 55 ptr este variabil pointer& a este constant pointer. 55 ec3ivalent cu + < ptr( se atribuie lui + valoarea lui aE.F
%eoarece numele tabloului a este sinonim pentru adresa elementului de indice zero din tablou& asi narea ptr= a:'; poate ,i #nlocuit"& ca #n e+emplul anterior& cu ptr=a.
<< ile=al << le=al Opera!ia de inde+are a elementelor unui tablou poate ,i realizat" cu aCutorul variabilelor pointer. Exemplu:
int a:1';, ptr = a;
psir;
55 a este pointer constant( ptr este variabil" pointer 55 ptr este adresa lui aE.F ptr(i #nseamn" ptr(.i si$eof.int//& deci' ptr ( i %eoarece numele unui tablou este un pointer (constant)& putem concluziona (,i ura 5./)'
)0
ptr;
a:i;
CAPITOLUL 5
Pointeri
6 6 6
ptr
Exerciiu: 4" se scrie urm"torul pro ram (care ilustreaz" le "tura dintre pointeri 1i vectori) 1i s" se urm"reasc" rezultatele e+ecu!iei acestuia.
>include <iostream602 void main.void/ ?int a:1'; = ? ', 1, -, +, %, 5, @, &, ), * A; int int pi- = a:';; int pi+; cout<<a=<<a<< a=<< a<< a=<< a<<!"n!; cout<<a(1=<<.a(1/<< a:1;=<< a:1;<<!"n!; cout<<a:1;=<<a:1;<< .a(1/=<< .a(1/<<!"n!; cout<<pi1=<<pi1<<pi-=<<pi-<<!"n!; int x= pi1;
pi1
= a ;
5@ + prime1te valoarea loca!iei a carei adres" se a,l" #n variabila pointer pi*& deci valoarea lui aE.F @5 cout<<x=<<x<<!"n!; x= pi1((; 55 ec3ivalent cu (pi*>>) +<*
cout<<x=<<x<<!"n!; x=. pi1/((;
5@ +<.' #nt:i atribuirea& apoi incrementarea valorii spre care pointeaz" pi*. -n urma increment"rii& valoarea lui aE.F devine * @5 cout<<x=<<x<<!"n!; cout<< pi1<<!"n!;x= ((pi1; 55ec3ivalent cu (>>pi*)
cout<<x=<<x<<!"n!; x=((. pi1/; cout<<x=<<x<<!"n!; pi1=a; pi+=pi1(+; cout<<pi1=<<pi1<< pi1=<< pi1<< pi1=<< pi1<<!"n!; cout<<pi+=<<pi+<< pi+=<< pi+<< pi+=<< pi+<<!"n!; cout<<pi+9pi1=<<.pi+9pi1/<<!"n!; 55pi?$pi*<? A
Exerciiu: 4" se scrie urm"torul pro ram (le "tura pointeri$1iruri de caractere) 1i s" se urm"reasc" rezultatele e+ecu!iei acestuia.
>include <iostream602 void main.void/ ?int a=95, b=1-, pi= a; double u=&61+, v=9-6-%, pd= v; c0ar sir1:;=sirul 1, sir-:;=sirul -, psir=sir1; cout<<a=<<a<< a=<< a<< b=<<b<< b=<< b<<!"n!; cout<< pi=<< pi<<pi=<<pi<< pi=<< pi<<!"n!; cout<< pd=<< pd<<pd=<<pd<< pd=<< pd<<!"n!; cout<< sir1=<< sir1<< sir1=<<sir1<< sir1=<< sir1<<!"n!;
55 @sir*<s sir*<sirul * Dsir*<.+,,d) 55 @sir/<s sir/<sirul / Dsir*<.+,,ce 55 @psir<s psir<sirul * Dsir*<.+,,cc 55 sir*>/<rul * psir>/<rul *
cout<< .sir1(-/=<<
cout<<sir1(-=<<.sir1(-/<< psir(-=<<.psir(-/<<!"n!;
.sir1(-/<<!"n!;
)5
CAPITOLUL 5
Pointeri
void pv1, pv-; pv1=psir; pv-=sir1; cout<<pv1=<<pv1<< pv1=<< pv1<<!"n!; cout<<pv-=<<pv-<< pv-=<< pv-<<!"n!; pi= b; pd= v; psir=sir-; cout<< pi=<< pi<<pi=<<pi<< pi=<< pi<<!"n!; cout<< pd=<< pd<<pd=<<pd<< pd=<< pd<<!"n!; cout<< psir=<< psir<<psir=<<psir<< psir=<< psir<<!"n!; A
Exerciiu: 4" se scrie un pro ram care cite1te elementele unui vector de #ntre i& cu ma+im /. elemente 1i #nlocuie1te elementul ma+im din vector cu o valoare introdus" de la tastatur". 4e va ,olosi aritmetica pointerilor.
>include <iostream602 void main./ ? int a:-';; int n, max, indice; cout<<3r6 elemente:; cin22n; for .i='; i<n; i((/ ? cout<<a:B<<i<<;=; cin22 .a(i/;A
max= a; indice='; for .i='; i<n; i((/ if .max<= .a(i// ? max= .a(i/; indice=i;A
55 a,i1area noului vector 5@ #n acest mod de implementare& #n situa!ia #n care #n vector e+ist" mai multe elemente a c"ror valoare este e al" cu valoarea elementului ma+im& va ,i #nlocuit doar ultimul dintre acestea (cel de indice ma+im).@5
A
Compilatorul trateaz" at:t G& c:t 1i GE.F& ca tablouri de m"rimi di,erite. Ast,el' cout<<Carime C:<<si$eof.C/<<!"n!; 55 /0 < /octe!i */elemente cout<<Carime C:';<<si$eof.C:';/<<!"n!; 55 ) < /octe!i ?elemente cout<<Carime C:';:';<<si$eof.C:';:';/<<!"n!; 55 0 octe!i (sizeo,(int)) Gatricea M
M[0] M[1] M[2] M[3] *. H ?/ $* 5 *2 /. . $? . * 2
Gatricea C are 0 linii 1i ? coloane. 7umele tabloului bidimensional& G& re,er" #ntre ul tablou( C:'; re,er" prima linie din tablou( C:';:'; re,er" primul element al tabloului.
))
CAPITOLUL 5
Pointeri
A1a cum compilatorul evalueaz" re,erin!a c"tre un tablou unidimensional ca un pointer& un tablou bidimensional este re,erit #ntr$o manier" similar". 7umele tabloului bidimensional& C& reprezint" adresa (pointer) c"tre primul element din tabloul bidimensional& acesta ,iind prima linie& GE.F (tablou unidimensional). C:'; este adresa primului element (GE.FE.F) din linie (tablou unidimensional)& deci GE.F este un pointer c"tre int' C = C:'; = C:';:';. Ast,el& C 1i C:linie; sunt pointeri constan!i. Putem concluziona' M este un pointer ctre un tablou unidimensional (de #ntre i& #n e+emplul anterior). M este pointer ctre int (pentru c" GE.F este pointer c"tre int)& 1i M = (M + 0) M[0]. M este ntreg( deoarece M[0][0] este int& M= ( M) (M[0])= (M[0]+0) M[0][0]. Exerciiu: 4" se testeze pro ramul urm"tor& urm"rind cu aten!ie rezultatele ob!inute.
>include <iostream602 >include <conio602 void main./ ?int a:+;:+;=??5,@,&A, ?55,@@,&&A, ?555,@@@,&&&AA; clrscr./; cout<<Da=D<<a<<D a=D<< a<<D a:';=D<< a:';<<1"n1; cout<<DEointeri catre vectorii linii"nD; for .int i='; i<+; i((/? cout<<D F.a(D<<i<<D/=D<<F.a(i/; cout<<D a:D<<i<<D;=D<<a:i;<<1"n1; A
55 a,i1area matricii
for .i='; i<+; i((/? for .int G='; G<+; G((/ cout<<F.F.a(i/(G/<<1"t1; 55sau' cout<<F.a:i;(G/<<1"t1; cout<<1"n1; A A
%eoarece operatorul de inde+are : ; are prioritate mai mare dec:t operatorul de de,eren!iere & declara!ia c0arstr_ptr:+; este ec3ivalent" cu c0ar.str_ptr:+;/& care precizeaz" c" str_ptr este un vector de trei elemente& ,iecare element este pointer c"tre caracter.
CAPITOLUL 5
Pointeri
-n ceea ce prive1te declara!ia' c0ar .str_ptr:+;/& se poate observa' *. str_ptr[3] este de tipul char (,iecare dintre cele trei elemente ale vectorului str_ptr:+; este de tipul pointer c"tre c3ar)( /. (str_ptr[3]) este de tip char (con!inutul loca!iei adresate de un element din str_ptr:+; este de tip char). 8iecare element (pointer) din str_ptr este ini!ializat s" pointeze c"tre un 1ir de caractere constant. 8iecare dintre aceste 1iruri de caractere se "sesc #n memorie la adresele memorate #n elementele vectorului str_ptr' str_ptr:';, str_ptr:1;& etc. 4" ne amintim de la pointeri c"tre 1iruri de caractere' -n mod analo '
c0ar p=0e55I; . p(1/ = !e!
p:1; = !e!;
str_ptr:1;:1;=!s!;
Putem conculziona' str_ptr este un pointer ctre un pointer de caractere . str_ptr este pointer ctre char. 9ste evident& deoarece str_ptr:'; este pointer ctre char& iar
str_ptr[0]. str_ptr este un de tip char. 9ste evident& deoarece str_ptr:';:'; este de tip char& iar str_ptr= ( str_ptr) (str_ptr[0])= (str_ptr[0]+0) str_ptr[0][0].
str_ptr
(str_ptr
[0] + 0 )
%e aceea& putem declara o variabil" pointer ptr_ptr, care s" pointeze c"tre primul element din strJptr. Variabila ptr_ptr este pointer ctre pointer 1i se declar" ast,el' c0ar ptr_ptr; -n e+emplul urm"tor este prezentat modul de utilizare a pointerului la pointer ptrJptr (,i ura 5.5). Exemplu:
c0ar ptr_ptr; c0ar str_ptr:+; = ? Ero=ramarea, este, frumoasH7 A; c0ar ptr_ptr; ptr_ptr = str_ptr;
ptr_ptr
str_ptr
%up" atribuire& 1i str_ptr 1i ptr_ptr pointeaz" c"tre aceea1i loca!ie de memorie (primul element al tabloului str_str). -n timp ce ,iecare element al lui strJstr este un pointer& ptrJptr este un pointer ctre pointer. %eoarece ptrJptr este un pointer variabil& valoarea lui poate ,i sc3imbat"' for .i=';i<+;i((/ cout<<ptr_ptr(( ;
CAPITOLUL 5
Pointeri
Le,eritor la declara!ia char ptr_ptr& putem concluziona' ptr_ptr este de tipul char (ptr_ptr este pointer la pointer ctre char )( ptr_ptr este de tipul char (coninutul locaiei ptr_ptr este de tipul pointer ctre char)( ptr_ptr este de tipul char . ptr_ptr ( ptr_ptr)( coninutul locaiei ptr_ptr este de tipul char).
Exemplu: 55variabila sirul este pointer spre un 1ir constant de caractere Atribuirile de ,orma'
Fsirul=coco; F.sirul(-/=!A!;
nu sunt acceptate& deoarece pointerul sirul pointeaz" c"tre o dat" constant" (1ir constant).
%eclararea unui pointer constant c"tre o dat care nu este constant tip F const nume_pointer=datH_neconst;
c0ar F const psir=abcd; const c0ar Fsir=un text; sir=alt sir; 55incorect& sir pointeaz" c"tre dat" constant" psir=sir; 55incorect& deoarece psir este pointer constant
Exemplu:
%eclararea unui pointer constant c"tre o dat constant const tip F const nume_pointer=datH_constantH;
const c0ar F const psir1=DmnED; F.psir1(-/=1J1; 55 incorect& data spre care pointez" psir* este constant" psir1((; 55 incorect& psir* este pointer constant
Exemplu:
). Ce ,el de variabile pot constitui operandul operatorului de de,eren!iereM =. Operatorul de re,eren!iere. 2. Unui pointer eneric i se poate atribui valoarea unui pointer cu tipM H. Care este le "tura #ntre tablouri 1i pointeriM *.. %e ce numele unui tablou este rvalueM
CAPITOLUL 5
Pointeri
*. 4" se implementeze pro ramele cu e+emplele prezentate. /. 4" se scrie pro ramele pentru e+erci!iile rezolvate care au ,ost prezentate. ?. Analiza!i urm"toarele secven!e de instruc!iuni. Identi,ica!i secven!ele incorecte (acolo unde este cazul) 1i sursele erorilor'
int a,b,Fc; a=&; b=*'; c=a; double y, $, Fx= $; $= y; c0ar x, FFp, Fq; x = 1A1; q = x; p = q; cout<<x=<<x<<!"n!; cout<<FFp=<<FFp<<!"n!; cout<<Fq=<<Fq<<!"n!; cout<<p=<<p<< q=<<q<<Fp=<<Fp<<!"n!; c0ar Fp, x:+; = ?1a1, 1b1, 1c1A; int i, Fq, y:+; = ?1', -', +'A; p = x:';; for .i = '; i < +; i((/ ? cout<<Fp=<<Fp<< p=<<p<<!"n!; p((; A q = y:';; for .i = '; i < +; i((/ ? cout<<Fq=<<Fq<<q=<<q<<!"n!; q((; A const c0ar Fsirul=sH pro=ramHm; F.sirul/((; double a, Fs; s= .a()*/; cout<<s=s<<!"n!; double a1, Fa-, Fa+; a-= a1; a-(=&6); a+=a-; a+((; int m:1';, *p;p=m; for .int i='; i<1'; i((/ cout<<Fm((; void Fp1; int Fp-; int x; p-= x; p-=p1; c0ar c=!A!; c0ar Fcc= c; cout<<.Fcc/((<<!"n!;
0. Lescrie!i pro ramele pentru problemele din capitolul 0 (?.a.$?. .& 0.a.$0.i.& 5.a.$5.3.)& utiliz:nd aritmetica pointerilor.
=.