Ce face Pointeri (& și *)
Fiecare variabilă stă la o adresă în memorie. Operatorul & îți dă această adresă, iar un pointer este o variabilă în care o păstrezi: int *p = &x; se citește „p este un pointer la int și arată spre x”.
Operatorul * aplicat unui pointer (dereferențiere) înseamnă „valoarea de la adresa asta”. *p = 5; schimbă chiar variabila x.
În C, argumentele sunt trimise funcțiilor prin valoare (ca o copie). Dacă vrei ca o funcție să modifice o variabilă a apelantului, îi trimiți adresa variabilei, iar funcția lucrează prin pointer. Un pointer care nu arată spre nimic primește valoarea NULL (sau nullptr în C23).
Exemple
Exemplul 1: Adresa și valoarea
După *p = 1500, variabila salariu are noua valoare, pentru că p arată spre ea. Adresele diferă la fiecare rulare, așa că aici comparăm doar că sunt egale.
#include <stdio.h>
int main(void) {
int salariu = 1200;
int *p = &salariu;
printf("salariu = %d, *p = %d\n", salariu, *p);
*p = 1500;
printf("după *p = 1500: salariu = %d\n", salariu);
printf("p arată spre salariu? %s\n", p == &salariu ? "da" : "nu");
return 0;
}
Rezultat
salariu = 1200, *p = 1200
după *p = 1500: salariu = 1500
p arată spre salariu? da
Exemplul 2: Funcția swap: modificare prin pointer
Funcția primește adresele, deci schimbă chiar variabilele din main. Cu parametri int a, int b ar fi schimbat doar copiile.
#include <stdio.h>
void schimba(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
int main(void) {
int x = 3, y = 8;
schimba(&x, &y);
printf("x = %d, y = %d\n", x, y);
return 0;
}
Rezultat
x = 8, y = 3
Exemplul 3: Mai multe rezultate dintr-o funcție
Funcția returnează un cod de succes și scrie rezultatele prin pointeri. Verifică NULL înainte să scrie, ca apelantul să poată sări peste un rezultat.
#include <stdio.h>
#include <stddef.h>
int min_max(const int *v, size_t n, int *min, int *max) {
if (n == 0) return 0;
int mic = v[0], mare = v[0];
for (size_t i = 1; i < n; i++) {
if (v[i] < mic) mic = v[i];
if (v[i] > mare) mare = v[i];
}
if (min != NULL) *min = mic;
if (max != NULL) *max = mare;
return 1;
}
int main(void) {
int temperaturi[] = {12, -3, 7, 21, 4};
int mic, mare;
if (min_max(temperaturi, 5, &mic, &mare)) {
printf("minim %d, maxim %d\n", mic, mare);
}
return 0;
}
Rezultat
minim -3, maxim 21
Greșeli frecvente
- Folosești un pointer neinițializat:
int *p; *p = 5;.pconține o adresă la întâmplare, iar scrierea acolo este comportament nedefinit. Inițializează-l cu o adresă validă sau cuNULL. - Dereferențiezi
NULL. Verifică pointerul înainte de*pdacă poate fi nul (de exemplu rezultatul luimallocsaufopen). - Scrii
int* a, b;crezând că ai doi pointeri. Doaraeste pointer;besteint. Scrieint *a, *b;. - Returnezi adresa unei variabile locale. Variabila dispare la ieșirea din funcție, iar pointerul rămâne „atârnat” (dangling).
Comenzi înrudite
Aritmetica pointerilor: Adunarea și scăderea pe pointeri se fac în elemente, nu în octeți: p + 1 arată spre următorul element din tablou.Pointer la pointer (**): Un pointer care păstrează adresa altui pointer: util când o funcție trebuie să schimbe un pointer sau pentru tablouri de șiruri.void * (pointer generic): Un pointer care poate păstra adresa oricărui tip de date, dar care trebuie convertit la un tip concret înainte de folosire.Funcții și prototipuri: Cum definești și declari funcții în C: tipul rezultatului, parametrii, prototipul și transmiterea argumentelor prin valoare.nullptr: Constanta C23 pentru pointerul nul, cu tip propriu (nullptr_t), mai sigură decât NULL sau 0.malloc: Cere sistemului un bloc de memorie de mărimea dată, în timpul rulării, și returnează adresa lui sau NULL dacă nu reușește.