Pointerii în C
Pointerii în C
Ce sunt pointerii?
Un pointer este o variabilă care stochează adresa unei alte variabile. În loc să conțină o valoare directă, un pointer conține locația în memorie a unei valori.
Notă pentru partea practică
Dacă doriți să urmați acest tutorial în mod interactiv și să executați
codul prezentat într-un editor de cod, direct în cloud,
lansați următorul sandbox - C/C++
Când accesați sandbox-ul, se va deschide o fereastră cu editorul VSCode.
Creați un fișier nou numit main.c
(sau orice alt nume preferați) și
introduceți codul din acest tutorial în editor.
Pentru a compila codul, deschideți un terminal și introduceți:
gcc main.c -o main
Această comandă va compila codul și va genera un fișier executabil numit main,
dacă nu există erori de compilare.
Pentru a rula acest executabil, introduceți:
./main
*****
Declarația și Inițializarea Pointerilor
Declarația unui pointer se face folosind simbolul *
De exemplu, pentru a declara un pointer la un întreg, vom scrie:
int *ptr;
Inițializarea unui pointer se face de obicei atribuindu-i adresa unei alte variabile folosind operatorul &.
De exemplu:
int var = 10;
int *ptr = &var;
Dereferențierea Pointerilor
Dereferențierea unui pointer înseamnă accesarea valorii la care pointează pointerul.
Aceasta se face tot folosind simbolul *
int var = 10;
int *ptr = &var;
printf("Valoarea lui var: %d\n", *ptr); // Va afișa 10
Aritmetica Pointerilor
Pointerii pot fi incrementați și decrementați. Aritmetica pointerilor se bazează pe dimensiunea tipului de date la care pointează pointerul.
int arr[] = {10, 20, 30, 40, 50};
int *ptr = arr;
printf("Prima valoare: %d\n", *ptr); // 10
ptr++;
printf("A doua valoare: %d\n", *ptr); // 20
ptr += 2;
printf("A patra valoare: %d\n", *ptr); // 40
Pointeri la Pointeri
Un pointer la un pointer este o variabilă care stochează adresa unui pointer. Aceștia sunt folosiți pentru a manipula pointeri la diferite nivele.
int var = 10;
int *ptr = &var;
int **pptr = &ptr;
printf("Valoarea lui var: %d\n", **pptr); // Afișează 10
Pointeri și Funcții
Pointerii pot fi folosiți pentru a trece adresele variabilelor în funcții, permițând funcțiilor să modifice variabilele originale.
#include <stdio.h>
void increment(int *num) {
(*num)++;
}
int main() {
int var = 10;
printf("Înainte de incrementare: %d\n", var); // 10
increment(&var);
printf("După incrementare: %d\n", var); // 11
return 0;
}
Pointeri la Funcții
Pointerii la funcții permit stocarea adresei unei funcții și apelarea acesteia prin intermediul pointerului. Aceasta este utilă pentru implementarea callback-urilor și funcțiilor de tip "plug-in".
#include <stdio.h>
void salut() {
printf("Salut, lume!\n");
}
int adunare(int a, int b) {
return a + b;
}
int main() {
void (*functie_salut)() = salut;
int (*functie_adunare)(int, int) = adunare;
// Apelarea funcțiilor prin intermediul pointerilor
functie_salut();
printf("Suma: %d\n", functie_adunare(5, 3));
return 0;
}
Gestionarea Memoriei cu malloc
și free
Pointerii sunt esențiali pentru gestionarea memoriei dinamice în C,
folosind funcțiile malloc
, calloc
, realloc
și free
.
#include <stdio.h>
#include <stdlib.h>
int main() {
int *ptr;
ptr = (int *)malloc(sizeof(int) * 5); // Alocare dinamică pentru 5 întregi
if (ptr == NULL) {
printf("Alocarea memoriei a eșuat\n");
return 1;
}
// Inițializarea memoriei alocate
for (int i = 0; i < 5; i++) {
ptr[i] = i + 1;
}
// Afișarea valorilor
for (int i = 0; i < 5; i++) {
printf("%d ", ptr[i]);
}
printf("\n");
// Eliberarea memoriei
free(ptr);
return 0;
}
Exemple Complete
Haideți să creăm câteva programe complete pentru a ilustra utilizarea avansată a pointerilor
1 - Utilizarea Pointerilor cu Matrici
#include <stdio.h>
int main() {
int mat[3][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
int (*ptr)[3] = mat; // Pointer la un array de 3 int-uri
// Accesarea elementelor matricei folosind pointerul
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
printf("Element at mat[%d][%d] = %d\n", i, j, *(*(ptr + i) + j));
}
}
return 0;
}
2 - Pointeri și Structuri
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Student {
char name[50];
int age;
float gpa;
};
int main() {
struct Student *student1 = (struct Student *)malloc(sizeof(struct Student));
if (student1 == NULL) {
printf("Alocarea memoriei a eșuat\n");
return 1;
}
strcpy(student1->name, "John Doe");
student1->age = 20;
student1->gpa = 3.5;
printf("Nume: %s\n", student1->name);
printf("Vârstă: %d\n", student1->age);
printf("GPA: %.2f\n", student1->gpa);
free(student1);
return 0;
}
Pointerii sunt un concept avansat și esențial în limbajul C. Ei oferă o mare flexibilitate și putere, permițând accesarea directă și manipularea memoriei. Prin înțelegerea și utilizarea corectă a pointerilor, puteți scrie programe eficiente și flexibile. Exersați cu diferite tipuri de pointeri și scenarii pentru a vă familiariza cu această caracteristică esențială a limbajului C.