pointer i

45
POINTERI

Upload: gabryel2907

Post on 27-Jan-2016

213 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Pointer i

POINTERI

Page 2: Pointer i

Pointerul este o variabilă de memorie în care se memorează o adresă de memorie 

Un pointer se asociază întotdeauna unui tip de dată (int, float, chr, etc) numit tip de bază. Se spune că un pointer indică o zonă de memorie care conţine o dată care are tipul de bază.

 

Declararea variabilelor de tip pointer. 

Declararea unei variabile de tip pointer se poate face printr-o instrucţiune declarativă de forma:

 

tip_dată *nume_variabilă ; 

unde :tip_dată – reprezintă tipul datei stocate la adresa memorată în pointer (tipul de bază)* – reprezintă operatorul de referinţănume_variabilă – reprezintă numele variabilei de tip pointer în care se memorează adresa unei variabile de memorie care are tipul de bază

Page 3: Pointer i

Exemple :

 

char *p ;

int *q ;

float *r ;

 

S-au definit trei variabile de tip adresă (pointer) : p către tipul char, q către tipul int şi r către tipul float.

 

Dimensiunea zonei de memorie alocate unei variabile de tip pointer depinde de mai mulţi factori : tipul de calculator pe care rulează programul, modelul de memorie în care este compilat programul, compilator, etc. Pentru a afla dimensiunea zonei de memorie alocate unui pointer se poate folosi operatorul sizeof() ca în exemplul următor :

 

int *p, *q, *r, i, j ;

cout<<sizeof(p) ;

Page 4: Pointer i

Categorii de pointeri: 

1. Pointeri fără tip.  

Aceşti pointeri se asociază tipului de dată void. Ei sunt pointeri universali, putând fi asociaţi oricărui tip de dată. Sunt utilizaţi pentru a putea referi, la momente diferite, tipuri de bază diferite.

 void *p ;

 2. Pointerul zero

 Acest pointer are valoarea 0 şi el indică zona de memorie de la adresa

0. Pentru C++ această adresă este inexistentă. Pointerul zero nu indică nimic. Acest tip de pointer este folosit de obicei ca terminator în diverse structuri de date. În locul constantei numerice literale 0, se poate folosi constanta simbolică predefinită NULL, care are valoarea « adresă nulă ». Constanta NULL este definită în fişierele antet <stdio.h> şi <stdlib.h>. Ea este utilă în unele cazuri pentru iniţializarea valorii unui pointer.

Page 5: Pointer i

Constante de tip adresă

 

O constantă simbolică de tip adresă este un pointer al cărui conţinut nu poate fi modificat. Ea poate fi definită prin instrucţiunea decalarativă :

 

tip_dată *const nume=adresă ;

 

unde :

tip_dată – este tipul de bază ;

nume – este numele constantei

adresă – este valoarea constantă a adresei de memorie.

 

Exemplu :

 

int *const zero=0 ;

Page 6: Pointer i

Tablourile de memorie şi adresele 

La declararea unui tablou de memorie, acestuia i se alocă o zonă de memorie de dimensiune fixă, începând de la o anumită adresă de memorie. Adresa de la care se alocă zona de memorie este o constantă (nu se poate modifica) şi ea este asociată cu numele tabloului de memorie.

 

Numele tabloului de memorie este folosit de compilatorul C++ ca o constantă simbolică de tip adresă, ce reprezintă adresa de la care începe zona de memorie internă alocată tabloului. Din această cauză, nu se poate folosi operatorul de atribuire între două variabile de tip tablou de memorie.

 

Exemplu :

 

int a[10], b[10] ;

a=b ; // Eroare !

Page 7: Pointer i

În schimb, se poate atribui unui pointer o variabilă de tip tablou de memorie.

 Exemplu :

 int a[10], *p ;p=a ; // Corect !

 Fiecare element al unui tablou de memorie ocupă acelaşi număr de

octeţi. Acest mod de memorare permite determinarea adresei fiecărui element pornind de la adresa simbolică a tabloului, care va reprezenta şi adresa primului element. Identificarea unui element de tablou se face folosind pentru fiecare element un grup de indici (numărul de indici fiind egal cu dimensiunea tabloului), adresa elementului calculându-se faţă de un element de referinţă care este adresa tabloului.

 

Page 8: Pointer i

Exemplu:

 

int a[5] ;

 

Zona de memorie alocată vectorului are dimensiunea n x sizeof(tip_bază). În exemplu, vectorului a i se va aloca o zonă de memorie de 5 x sizeof(int) = 5 x 2 = 10 octeţi.

 

Deoarece adresa vectorului a este şi adresa primului element, în C++ numerotarea indicilor se face pornind de la 0, indicele reprezentând deplasarea elementului faţă de adresa vectorului. Dacă adresa vectorului a este adr, ea este şi adresa elementului a[0], iar adresa elementului a[i] va fi

adr + i x sizeof(tip_bază).

 

Pentru exemplul de mai sus adresa elementului a[2] va fi

 

adr + 2 x sizeof(int) = adr + 2 x 2 = adr + 4

Page 9: Pointer i

Operatori pentru variabile de tip pointeri 

Pe variabilele de tip pointeri se pot aplica următorii operatori :

  operatori specifici,

operatorul de atribuire,

operatori aritmetici,

operatori relaţionali.

Page 10: Pointer i

Operatori specifici 

Operatorul & - operatorul de adresare.

 

Acest operator se aplică pe o variabilă de memorie sau un element de tablou de memorie şi furnizează adresa variabilei de memorie, respectiv a elementului de tablou. Nu se poate aplica pe o expresie, o constantă sau o variabilă de tip registru. Rezultatul obţinut prin aplicarea acestui operator este de tip pointer. Operaţia se numeşte referenţierea unei variabile de memorie.

 

Operatorul * - operatorul de redirectare

 

Acest operator se aplică pe o variabilă de tip pointer şi furnizează valoarea variabilei de memorie care se găseşte la adresa memorată în pointer. Rezultatul obţinut prin aplicarea acestui operator este de tipul datei asociate pointerului. Operaţia se numeşte dereferenţierea unui pointer.

Page 11: Pointer i

Aşadar, localizarea unei date memorată într-o variabilă de memorie se poate face prin :

  adresare directă – folosind numele variabilei de memorie ; adresare indirectă – folosind o variabilă de tip pointer în care este

memorată adresa zonei de memorie în care este stocată data. 

Exemplu : 

int a=10, *p=&a ;cout<<*p<<endl ; // se afişează 10cout<<a<<endl ; // se afişează 10cout<<p<<endl ; // se afişează adresa lui acout<<&a<<endl ; // se afişează adresa lui a

 Exemplu :

 int a=200 ;*(&a)=100 ;cout<<a ; // se afişează 100

Page 12: Pointer i

Observaţii : 

1. Operatorul * se poate folosi în ambii membrii ai unei operaţii de atribuire :

 

int a=10, b=20, *p=&a, *q=&b ;

*q=*p ;

cout<<a<<” ”<<b; // se afişează 10 10

 

2. Construcţia *p (p fiind un pointer către un tip de dată) poate apărea în orice expresie, în locul unei variabile de memorie care are acelaşi tip ca şi cel asociat pointerului :

 

int a=10, *p=&a ;

*p=*p+5 ;

cout<<a<<” ”<<*p; // se afişează 15 15

Page 13: Pointer i

3. Operatorii * şi & sunt operatori unari şi au prioritate mai mare decât operatorii aritmetici, relaţionali, logici şi de atribuire.

 

int a=10, *p=&a ;

*p+=1 ; // echivalent cu *p=*p+1

cout<<a ; // se afişează 11

 

4. Asociativitatea operatorilor unari este de la dreapta la stânga. Astfel, *p++ incrementează cu 1 adresa memorată în variabila p, şi nu valoarea de la adresa memorată în p :

 

int a=10, *p=&a ;

++*p ;

cout<<a ; // se afişează 11

(*p)++ ;

cout<<a ; // se afişează 12

Page 14: Pointer i

5. Pe pointerii fără tip nu poate fi aplicat operatorul de redirectare, deoarece pentru a putea furniza conţinutul unei zone de memorie nu este suficient să fie cunoscută adresa de la care începe acea zonă de memorie, ci şi lungimea sa şi modul în care poate fi interpretat şirul de biţi din acea zonă de memorie, informaţii pe care un pointer fără tip nu le poate furniza.

 int a=1 ;void *p=&a ;cout<<p ; // se afişează adresa memorată în pcout<<*p ; // Eroare !

 6. Pe un pointer fără tip se poate aplica operatorul de redirectare numai dacă este

convertit într-un pointer cu tip prin aplicarea unui operator de conversie explicită de tip.

 int a=10 ;void *p ;p=&a ;cout<<*(int*)p<<endl; // se afişează 10cout<<*(float*)p<<endl ; // se afişează 1.401298e-44 un număr real în notaţie ştiinţifică.

Page 15: Pointer i

7. Deoarece în C++ caracterul * este folosit şi ca operator de redirectare (operator unar) şi ca operator de multiplicare (operator aritmetic), pentru a înmulţi valorile memorate la două adrese de memorie indicate de doi pointeri p şi q este obligatoriu să se folosească parantezele :

 

int a, b=10, c=20, *p=&b, *q=&c;

a=(*p)*(*q);

cout<<a; // se afişează 200

 

O constantă poate fi modificată indirect prin intermediul unui pointer.

 

const int x=100 ;

*(int*)&x=200 ;

cout<<x<<” ”<< *(int*)&x ; // se afişează 100 200

Page 16: Pointer i

Operatorul de atribuire 

Folosind operatorul de atribuire = unei variabile de tip pointer i se poate atribui numai o valoare care reprezintă o adresă de memorie. Ea poate fi exprimată prin :

  O adresă de memorie care poate fi obţinută prin aplicarea operatorului

de adresare (&) pe o variabilă de memorie definită anterior, de acelaşi tip cu tipul de bază al pointerului, sau furnizată de numele unui tablou de memorie.

O altă variabilă de tip pointer care se referă la acelaşi tip de bază. După operaţia de atribuire, cele două variabile de tip pointer vor adresa aceiaşi zonă de memorie.

Rezultatul unei expresii construite cu operanzi de tip adresă a unor date definite anterior şi care aparţin tipului de bază al pointerului.

Constanta 0 sau constanta predefinită NULL. Poate fi atribuită oricărui tip de pointer.

Page 17: Pointer i

Exemplul 1 : 

char c=’A’, *p ;p=&c ;cout<<c<<” ”<<*p; // se afişează A A

 

Exemplul 2: 

int a=10, *p, *q;p=&a;q=p;cout<<*p<<” ”<<*q // se afişează 10 10

 

Exemplul 3: 

int a=10, b=20, *p;p=&a;b=*p;cout<<a<<” ”<<b; // se afişează 10 10*p=100;

cout<<a<<” ”<<b; // se afişează 100 10

Page 18: Pointer i

Exemplul 4: 

int a=10, *p=&a, *q;

q=0;

cout<<*p; // se afişează 10

cout<<*q; // nu afişează nimic

q=NULL;

cout<<*q; // nu afişează nimic

 

Exemplul 5: 

int a=1, b=2, *p=&a;

(*(p=&b))++;

cout<<a<<” ”<<b; // se afişează 1 3

 

Exemplul 6: 

int a[10], i, k=0, *p;

for(i=0;i<10;i++)

a[i]=k++;

p=a;

cout<<*p<<<<” ”<<a[0]; // se afişează 0 0

Page 19: Pointer i

Observaţii:

 

Singurele excepţii permise de a atribui unui pointer o variabilă de tip pointer de alt tip decât tipul său de bază sunt:

 

1. Unui pointer fără tip i se poate atribui orice alt tip de pointer. Reciproca nu este însă posibilă.

2. Unui pointer i se poate atribui un pointer de alt tip decât tipul său de bază numai dacă se aplică operatorul de conversie explicită de tip.

Page 20: Pointer i

Operatori aritmetici 

Operaţiile aritmetice permise asupra pointerilor sunt:

  Adunarea şi scăderea unei constante – operatorii + şi – Incrementarea şi decrementarea unui pointer – operatorii ++

şi -- Scăderea a doi pointeri de acelaşi tip – operatorul –

 

Observaţie:

 

Operaţiile aritmetice cu pointeri au sens şi se execută corect, numai dacă adresele indicate de pointerii operanzi şi de pointerul rezultatului expresiei se păstrează în spaţiul de adrese ale unui tablou de memorie. Singura excepţie acceptată este cea a pointerului care indică adresa unui element situat imediat după ultimul element al tabloului.

Page 21: Pointer i

Operatorul pentru adunarea sau scăderea unei constante este:

 p+k sau p-k

 

unde p este un pointer cu tip care memorează o adresă adr, iar k o constantă. Rezultatul este o adresă care se calculează astfel: adr + k x sizeof(tip_bază), respectiv adr – k x sizeof(tip_bază).

 

Observatie:

Operaţia de adunare a unei constante la un pointer este comutativă: p+k = k+p.

Page 22: Pointer i

Operatorul pentru incrementarea şi decrementarea unui pointer este:

p++ sau p-- 

unde p este un pointer cu tip care memorează o adresă adr. Rezultatul este o adresă care se calculează astfel:

adr + sizeof(tip_bază), respectiv adr – sizeof(tip_bază).

Page 23: Pointer i

Operatorul pentru scăderea a doi pointeri este:

 

p – q

unde p şi q sunt pointeri către acelaşi tip de bază, care indică elementele aceluiaşi tablou de memorie, adresa memorată de p fiind mai mare decât cea memorată de q (p indică un element de tablou situat în memorie după elementul indicat de pointerul q). Rezultatul este un număr întreg care reprezintă numărul de elemente între p şi q.

Page 24: Pointer i

Exemplu:

int a=10, *p=&a, *q=p;

cout<<p<<” ”<<*p<<endl;

p++;

cout<<p<<” ”<<*p<<endl;

p++;

cout<<p<<” ”<<*p<<endl;

cout<<p-q; //se afişează 2

Page 25: Pointer i

Observaţii: 

1. Doi pointeri nu se pot aduna.

2. Asupra pointerului fără tip nu se pot aplica operatori aritmetici.

3. Pointerii pot fi folosiţi pentru a indica elementele tablourilor de memorie. Referirea la elementele unui tablou se poate face folosind pointeri în locul indicilor, iar operaţiile aritmetice cu pointeri sunt foarte utile pentru accesarea elementelor tabloului în vederea prelucrării valorii lor.

 

Exemplu: 

Să se afişeze elementele unui vector folosind indici cât şi ponteri

 

int i, a[10]={0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, *p=a;

for(i=0;i<10;i++)

cout<<a[i]<<” ”;

for(i=0;i<10;i++)

cout<<*p++<<” ”;

for(p=a;*p;p++)

cout<<*p<<” ”;

Page 26: Pointer i

Operatori relaţionali

Operatorii relaţionali care pot fi aplicaţi asupra pointerilor sunt:

  Operatorii de inegalitate: <, >, <=, >= Operatorii de egalitate: == şi !=

 

Evaluarea unui operator relaţional aplicat pe doi pointeri p şi q se face prin analiza diferenţei p-q.

 

Observaţii:

1. Asupra pointerului fără tip nu se pot aplica operatori relaţionali.

2. Asupra pointerului zero se pot aplica operatori relaţionali.

Page 27: Pointer i

Exemplu: 

Să se afişeze ordinea în care apar două valori x şi y într-un vector cu numere întregi.

int x, y, a[100], *p=a, *q=a;cout<<”n=”;cin>>n;for(i=1;i<=n;i++)

{ cout<<”elementul ”<<i<<” = ”; cin>>*p++;

}cout<<”x=”;cin>>x;cout<<”y=”;cin>>y;p=a;while (*p!=x) p++;while (*q!=y) q++;if (p>q)

cout<<”valoarea ”<<y<<” apare înintea valorr ”<<x;else

cout<<”valoarea ”<<x<<” apare înintea valorr ”<<y;

Page 28: Pointer i

Pointeri către pointeri 

Pointerii sunt şi ei tot variabile de memorie şi deci ocupă şi ei un spaţiu de memorie, iar pentru memorarea adresei unui pointer se poate folosi o variabilă de tip pointer.

 

În exemplul următor, pointerul p este un pointer către întreg, iar pointerul pp este un pointer către un pointer către întreg.

 

int *p, **pp;

Page 29: Pointer i

Exemplu:

int a=10, *p=&a, **pp=&p;

cout<<a<<” ”<<*p<<” ”<<**pp; // se afişează 10 10 10

 

Observaţie:

 

Nu există limite în numărul de redirectări (pointer către pointer).

Page 30: Pointer i

Tablouri de memorie şi pointeri

Deoarece numele unui tablou de memorie este o constantă de tip adresă, în manipularea elementelor unui tablou de memorie, numele tabloului poate fi tratat ca un pointer.

 

Vectori 

Numele vectorului poate fi considerat ca un pointer, cu tipul de bază al elementelor vectorului, care indică primul element al vectorului, iar numele vectorului poate fi atribuit ca valoare unui pointer:

 Exemplu:

 int a[20], *p;p=a; // Corect !a=p // Incorect ! valoarea unei constante nu poate fi modificată

Page 31: Pointer i

Următoarele operaţii de atribuire sunt echivalente:

p=a p=&a p=&a[0]

 

şi

 

*p a[0]

 

Aşadar, pointerului p i se poate atribui adresa vectorului a exprimată prin:

 o constanta simbolică de tip adresă a;o operatorul de adresare & aplicat pe numele variabilei a;o operatorul de adresare & aplicat pe numele primului element

al vectorului – a[0].

Page 32: Pointer i

Prin definiţie, operatorul indice al tabloului ([ ]:

  se aplică pe doi operanzi x şi y (x[y] sau y[x]), x fiind un pointer

şi y un întreg; realizează adunarea dintre pointerul x şi constanta y, obţinând

adresa elementului y al vectorului de la adresa x; rezultatul furnizat este valoarea indicată de pointerul obţinut,

adică valoarea elementului y al vectorului de la adresa x; expresiile următoare sunt echivalente: x[y] y[x] *(x+y)

 

Deoarece operaţia de adunare dintre un pointer şi o constantă este comutativă, următoarele expresii sunt echivalente şi se pot folosi pentru identificarea elementului i al vectorului:

 

a[i] *(a+i) *(i+a) i[a]

Page 33: Pointer i

Exemplu:

 

int a[10], i, k=0, *p;

for(i=0;i<10;i++)

a[i]=k++;

p=a;

cout<<*(a+5)<<” ”<<a[5]<<” ”<<5[a]<<endl; // se afişează 5 5 5

cout<<*(p+5); // se afişează 5

 

La definirea unui pointer trebuie precizat tipul de bază. Tipul de bază al unui pointer poate fi şi un vector, astfel încât definiţia următoare este corectă:

 

int a[20], *p=a, (*q)[20]=a;

Page 34: Pointer i

Matrice

O matrice cu m linii şi n coloane poate fi considerată un vector cu m elemente de tip vector cu n elemente care au tipul de bază. Numele tabloului de memorie poate fi considerat ca un pointer cu tipul de bază al elementelor matricei care indică primul element al matricei, iar numele tabloului poate fi atribuit ca valoare unui pointer. Următoarele operaţii de atribuire sunt echivalente:

 

p=a p=&a p=a[0] p=&a[0][0]

Page 35: Pointer i

Deoarece matricea poate fi considerată ca un vector cu m elemente de tip vectori cu n elemente care au tipul de bază, se poate defini şi un pointer către elementul vectorului, adică un pointer care va avea ca tip un vector cu n elemente cu tipul de bază al matricei. În acest mod se poate considera că a[i] este un vector cu n elmente cu tipul de bază al matricei:

a[i][0] a[i][1] a[i][2] .. a[i][n-1]

 

şi a[i] este adresa acestui vector. Elemntul a[i] poate fi scris şi ca un pointer: *(a+i)

Page 36: Pointer i

Aşadar matricea poate fi văzută ca un vector de m pointeri, aceşti pointeri indicând fiecare câte un vector cu n elemente. Numele matricei a este la rândul său un pointer. În acest mod se poate vedea matricea ca pe un pointer către un alt pointer, unitatea folosită în operaţiile aritmetice fiind n x sizeof(tip_bază) octeţi.

 

Un element al matricei a poate fi indicat, folosind cei doi indici i şi j, prin a[i][j]. Asociativitatea operatorului indice al tabloului este de la stânga la dreapta şi prioritatea sa este mai mare decât a operatorului de indirectare *. Calcularea adresei elementului se va face astfel: mai întâi se execută suma dintre pointerul a şi constanta i şi apoi suma dintre rezultatul obţinut anterior şi constanta j.

Page 37: Pointer i

Următoarele operaţii sunt echivalente:

a[i][j] *(a[i]+j) (*(a+i))[j] *(*(a+i)+j) *(&a[0][0]+n*i+j)

 

Exemplu:

 

int a[10][10], i, j, k=1, *p;

for(i=0;i<10;i++)

for(j=0;j<10;j++)

a[i][j]=k++;

p=a[0];

cout<<a[5][4]<<” ”<<*(a[5]+4)<<” ”<<*(*(a+5)+4)<<endl; // se afişează 55 55 55

cout<<*(p+5*10+4); // se afişează 55

Page 38: Pointer i

Tipul de dată referinţă  

Acest tip de dată permite folosirea mai multor identificatori pentru aceiaşi variabilă de memorie. Declararea unei variabile de tip referinţăm se poate face prin instrucţiunea decalarativă:

 

tip_dată &nume_variabilă = nume_variabilă_referită;

unde:

  tip_dată – este tipul datei la care se referă variabila de memorie definită; & – este operatorul de referenţiere; nume_variabilă – este numele variabilei de memorie care se defineşte prin

referinţă la o altă variabilă de memorie; nume_variabilă_referită – este numele variabilei de memorie la care se

referă variabila de memorie definită. 

Page 39: Pointer i

Exemplu:

int a=10;

int &b=a;

sau

 

int a=10, &b=a;

 

Variabila de memorie b este o referinţă către variabila de memorie a. Aceasta înseamnă că, prin referinţă, variabilei de memorie a i s-a mai dat un nume b. Cele două variabile de memorie (a şi b) au aceleaşi atribute (adresă de memorie, lungime, valoare, tip etc), cu excepţia numelui. Chiar dacă în program s-au declarat două variabile de memorie (a şi b), el de fapt lucrează cu o singură zonă de memorie care poate fi identificată cu două nume diferite, iar următoarele două instrucţiuni vor afişa aceleaşi valori:

 

cout<<”a=”<<a<<” adresa lui a =”<<&a<<endl;

cout<<”b=”<<b<<” adresa lui b =”<<&b;

Page 40: Pointer i

Orice operaţie de modificare a valorii variabilei referite prin numele b, va modifica valoarea variabilei identificate prin numele a, deoarece ambele nume de variabile se referă la conţinutul aceleiaşi zone de memorie. Următoarele două instrucţiuni vor afişa aceleaşi valori:

b=15;

cout<<”a=”<<a<<” adresa lui a =”<<&a<<endl;

cout<<”b=”<<b<<” adresa lui b =”<<&b;

Page 41: Pointer i

Observaţii:

1. Tipul referinţei şi tipul variabilei la care se referă trebuie să fie acelaşi.

2. Referinţa şi obiectul la care se face referirea trebuie să fie de acelaşi tip. Astfel, referinţa este o variabilă de memorie, referirea trebuie să se facă tot la o variabilă de memorie, şi nu, de exemplu, la o constantă, chiar dacă aceasta este de acelaşi tip cu referinţa,

3. Referinţa trebuie iniţializată chiar în momentul declarării ei.

int a, &b; //Eroare !

Page 42: Pointer i

4. Tipul de dată referinţă, la fel caşi tipul de dată pointer, conţine o adresă. Pentru a avea acces prin referinţă la o variabilă de memorie nu mai este nevoie însă să se folosească adresa de memorie, ci numele variabilei referinţă.

 

int a=10, b=200;

int &x=a;

int *p=&a;

int *q=&x;

cout<<a<<” ”<<x<<” ”<<*p<<” ”<<*q<<endl; // afişează 10 10 10 10

*p=20;

cout<<a<<” ”<<x<<” ”<<*p<<” ”<<*q<<endl; // afişează 20 20 20 20

x=30;

cout<<a<<” ”<<x<<” ”<<*p<<” ”<<*q<<endl; // afişează 30 30 30 30

p=&b;

cout<<b<<” ”<<*p<<endl; // afişează 200 200

p=&x;

cout<<b<<” ”<<*p<<endl; // afişează 200 30

Page 43: Pointer i

5. După ce a fost iniţializată, referinţa nu mai poate fi modificată (nu i se mai poate schimba adresa de memorie la care se referă).

int a=10, b=100, &x=a;

cout<<a<<” ”<<x<<endl; // afişează 10 10

x=&b // Eroare !

x=b // Corect !

cout<<a<<” ”<<x<<endl; // afişează 100 100

 

6. Nu se poate crea un pointer la o referinţă

 

int a=10, &x=a;

int *p=x; // Eroare !

int *p=&x; // Corect !

Page 44: Pointer i

7. Nu este permisă declararea unei referinţe la o adresă exprimată printr-o referinţă sau printr-un pointer.

 

int a=10, b=100, *p=&a, *q=&b, &x=a;

int &y=&x; // Eroare !

int &y=x; // Corect ! variabila y se referă la variabila a

int &z=q; // Eroare!

int &z=*q // Corect !

cout<<a<<” ”<<*p<<” ”<<x<<” ”<<y<<endl; // afişează 10 10 10 10

cout<<b<<” ”<<*q<<” ”<<z<<endl; // afişează 100 100 100*p=20;

cout<<a<<” ”<<*p<<” ”<<x<<” ”<<y<<endl; // afişează 20 20 20 20

x=30;

cout<<a<<” ”<<*p<<” ”<<x<<” ”<<y<<endl; // afişează 30 30 30 30

p=&z;

b=200;

cout<<a<<” ”<<*p<<” ”<<x<<” ”<<y<<” ”<<*q<<” ”<<z<<endl;

// afişează 30 200 30 30 200 200

Page 45: Pointer i

8. Operatorii aritmetici aplicaţi pe variabile referinţă nu modifică valoarea adresei referite, ci valoarea memorată la adresa variabile referite. Operatorii relaţionali aplicaţi pe variabile referinţă nu compară valorile adreselor referite, ci valorile memorate la adresele variabilelor referite.

int a=10, b=20, &x=a, &y=b;

x=30;

cout<<a<<” ”<<x<<endl; // afişează 30 30

x++;

cout<<a<<” ”<<x<<endl; // afişează 31 31

x=--x;

x+=x*2;

cout<<a<<” ”<<x<<endl; // afişează 90 90

if (x!=y)

cout<<”adevărat”<<endl; // afisează adevărat

x=++y;

cout<<a<<” ”<<x<<endl; // afişează 21 21

cout<<b<<” ”<<y<<endl; // afişează 21 21

if (x==y)

cout<<”adevărat”<<endl; // afisează adevărat