Operații cu pointeri
Pointerii suportă o serie de operații: atribuire, obținerea adresei, dereferențiere (obținerea valorii), unele operații aritmetice și operații de comparație.
Atribuirea unei adrese
Unui pointer i se poate atribui adresa unui obiect de același tip sau valoarea altui pointer. Pentru a obține adresa unui obiect se folosește operatorul &:
int a {10};
int *pa {&a}; // pointerul pa stochează adresa variabilei a
Pointerul și variabila trebuie să aibă același tip – în acest caz, int.
Dereferențierea unui pointer
Operația de dereferențiere a unui pointer este scrisă sub forma *nume_pointer. Această operație returnează obiectul aflat la adresa stocată în pointer.
#include <iostream>
int main()
{
int a {10};
int *pa {&a}; // stochează adresa variabilei a
std::cout << "*pa = " << *pa << std::endl; // *pa = 10
std::cout << "a = " << a << std::endl; // a = 10
*pa = 25; // modificăm valoarea de la adresa din pointer
std::cout << "*pa = " << *pa << std::endl; // *pa = 25
std::cout << "a = " << a << std::endl; // a = 25
}
Prin expresia *pa obținem valoarea stocată la adresa indicată de pa, iar prin *pa = valoare putem modifica acea valoare. Deoarece pa pointează către a, modificarea afectează și variabila a.
Atribuirea unui alt pointer
#include <iostream>
int main()
{
int a {10};
int b {2};
int *pa {&a}; // pointer către a
int *pb {&b}; // pointer către b
std::cout << "pa: address=" << pa << "\t value=" << *pa << std::endl;
std::cout << "pb: address=" << pb << "\t value=" << *pb << std::endl;
pa = pb; // acum pa stochează adresa lui b
std::cout << "pa: address=" << pa << "\t value=" << *pa << std::endl;
*pa = 125; // modificăm valoarea de la adresa lui b
std::cout << "b value=" << b << std::endl;
}
Când unui pointer i se atribuie alt pointer, acesta începe să indice aceeași adresă:
pa: address=0x56347ffc5c value=10
pb: address=0x56347ffc58 value=2
pa: address=0x56347ffc58 value=2
b value=125
Pointeri nul (null pointers)
Un pointer nul nu indică niciun obiect. Dacă nu dorim ca pointerul să indice către o locație validă, îi putem atribui valoarea nulă:
int *p1{nullptr};
int *p2{};
Referințe la pointeri
Deoarece o referință nu este un obiect, nu putem crea un pointer la o referință, dar putem crea o referință la un pointer. Printr-o astfel de referință putem modifica adresa pe care o stochează pointerul sau valoarea stocată la acea adresă:
#include <iostream>
int main()
{
int a {10};
int b {6};
int *p{}; // pointer
int *&pRef {p}; // referință la pointer
pRef = &a; // prin referință atribuim adresa lui a pointerului p
std::cout << "p value=" << *p << std::endl; // 10
*pRef = 70; // modificăm valoarea la care pointează p
std::cout << "a value=" << a << std::endl; // 70
pRef = &b; // schimbăm adresa către care pointează p
std::cout << "p value=" << *p << std::endl; // 6
}
Adresa unui pointer
Un pointer stochează adresa unei variabile, dar el însuși are o adresă proprie în memorie. Această adresă se obține cu &:
int a {10};
int *pa {&a};
std::cout << "address of pointer=" << &pa << std::endl; // adresa pointerului
std::cout << "address stored in pointer=" << pa << std::endl; // adresa stocată (adresa lui a)
std::cout << "value on pointer=" << *pa << std::endl; // valoarea de la acea adresă (valoarea lui a)
Operații de comparație
Pointerii pot fi comparați folosind operatorii >, >=, <, <=, ==, !=, dar doar între pointeri de același tip. Compararea se face după valorile adreselor:
#include <iostream>
int main()
{
int a {10};
int b {20};
int *pa {&a};
int *pb {&b};
if(pa > pb)
std::cout << "pa (" << pa << ") is greater than pb ("<< pb << ")" << std::endl;
else
std::cout << "pa (" << pa << ") is less or equal pb ("<< pb << ")" << std::endl;
}
Ieșire posibilă:
pa (0xa9da5ffdac) is greater than pb (0xa9da5ffda8)
Conversia tipurilor
Uneori este necesar să atribuim unui pointer valoarea altui pointer de alt tip. În acest caz, se folosește conversia explicită:
#include <iostream>
int main()
{
char c {'N'};
char *pc {&c}; // pointer la char
int *pd {(int *)pc}; // conversie la pointer la int
void *pv {(void*)pc}; // pointer la void
std::cout << "pv=" << pv << std::endl;
std::cout << "pd=" << pd << std::endl;
}
Pentru conversie, se pune tipul dorit între paranteze înaintea pointerului. Deși nu putem crea o variabilă de tip void, putem crea un pointer void*.
De asemenea, pointerul de tip char* este interpretat ca un șir la afișare:
std::cout << "pc=" << pc << std::endl;
Dacă dorim să afișăm adresa stocată în pointerul char*, trebuie să o convertim la alt tip, de exemplu void* sau int*.