Documente Academic
Documente Profesional
Documente Cultură
Curs 3 – Pointeri
C
++{};
C++ Acest curs
› Definitie
› Initializare
› Tip de date
› Dereferentiere
› Pointeri si const
› Pointer nul
› Pointer la pointer
C++ C Pointers Explained
Laurentiu Petrea
Senior Software Architect
ACCESS - Browser Product Department
C++ Definitie
› Variabilă utilizată pentru a stoca adresa de memorie a unei
date sau functie.
.
.
.
0x00394768 x = 40
.
.
› Declaratie .
Datatype* variableName;
C++ Initializare
int x = 40;
int *ptr;
int *ptr;
ptr = (int *) malloc(sizeof(int) * count);
ptr = &x;
Memory from
0x00394768 x = 40 0x00394768 heap
int main()
{
char c_var; Dimensiune char pointer = 4 value = 4061659
int i_var; Dimensiune integer pointer = 4 value = 4061644
double d_var; Dimensiune double pointer = 4 value = 4061628
char *char_ptr;
int *int_ptr;
double *double_ptr;
char_ptr = &c_var;
int_ptr = &i_var;
double_ptr = &d_var;
printf(“Dimensiune char pointer = %d value = %u\n", sizeof(char_ptr), char_ptr);
printf(“Dimensiune integer pointer = %d value = %u\n", sizeof(int_ptr), int_ptr);
printf(“Dimensiune double pointer = %d value = %u\n",
sizeof(double_ptr),double_ptr);
}
C++ Dereferentiere
I
int x = 10; x = 10 0x12345678
II
int *ptr = 10; ptr = junk value 0x32142658
int main()
{
int num1 = 10;
int num2 = 20;
const int* const ptr1 = &num1;
*ptr1 = 20; //nu se poate - pointer catre const
num1 = 20; //se poate
ptr1 = &num2; //nu se poate - pointer constant
printf("Valoarea stocata la adresa = %d\n",*ptr1);
}
C++ Pointeri către un obiect de tip necunoscut
› Într-o secvenţă de cod low level este necesar a transmite
adresa unei locaţii de memorie fără a cunoaşte tipul
datei/datelor stocate în acea locaţie.
› Pentru asta se foloseşte pointerul către tipul de date
necunoscut void*
› Un pointer către orice tip de dată poate fi atribuit unei
variabile de tip void*.
› Un pointer pe funcţie sau la un membru al unei clase nu
poate fi atribuit unei variabile de tip void*.
› Un pointer de tip void* poate fi atribuit/comparat unui/cu alt
pointer de tip void*.
› Un pointer de tip void* poate fi convertit explicit la orice tip
de date.
C++ Pointeri către un obiect de tip necunoscut
int f(int *p)
{
void *pv = p;//conversie implicita
*pv;//eroare, un pointer pe void* nu poate fi dereferentiat
++pv;//eroare, un pointer pe void* nu poate fi incrementat
› Sfaturi:
– A nu se utiliza pointeri convertiţi explicit către un alt tip de date decât cel iniţial
– A se utiliza pointeri la void* doar pentru a fi:
› transmişi ca parametru funcţiilor iar tipul acestora nu este necesar a fi cunoscut;
› returnat de funcţii.
– A se converti explicit pointerii la void* atunci când sunt folosiţi;
C++ Pointeri către un obiect de tip necunoscut
› Având în vedere că pointerii la void* sunt folosiţi în
programarea low level, acolo unde resursele hardware sunt
manipulate, apariţia/utilizarea unor astfel de pointeri la nivel
high level trebuie privită cu suspiciune deoarece cu
siguranţă se datorează unor erori de proiectare.
Pointer nul
nullptr reprezintă un pointer nul literal, un pointer ce nu
pointează către ceva.
Poate fi atribuit oricărui tip de pointer
int ∗pi = nullptr;
double ∗pd = nullptr;
int i = nullptr; // eroare : i nu este un pointer
C++ Pointer nul
› Înainte de a fi introdus nullptr, era folosit zero (0) ca notaţie pentru
pointer nul. int *x = 0;
› Nici un obiect nu este alocat la adresa 0, iar zero (0) este cea mai
comună reprezentare a nullptr.
› Zero (0) este un int. Totuşi în conversiile standard 0 este folosit ca o
constantă a unui pointer sau pointer la membru.
› O altă reprezentare a unui pointer nul a fost macrodefiniţia NULL.
int *p = NULL;
return p; ...
}
... //apel
//apel Dealoca2D((void**)v);
v = (short int**)Alocare2D(n, m, sizeof(short int)); v = 0;
C++
C++
C++
C++
C++
C++
C++
C++ Alocare memorie pt. o matrice – un singur bloc
//alocare un singur bloc de memorie (C ANSI) // dealocare (C ANSI) -
void **Alocare2D(size_t n, size_t m, size_t dim) nu este nevoie de functie
{ de dealocare
void **p = nullptr;
p = malloc(n * sizeof(void *) + n * m * dim);
size_t i = 0;
const size_t dimvp = n * sizeof(void*);
return p;
}
... ...
//apel //apel
v = (short int**)Alocare2D(n, m, sizeof(short int)); free(v);
v = 0;
C++
C++
C++
C++
C++
C++
C++
C++ Struct/class layout
› O structură/clasă îşi păstrează membri în ordinea în care au fost
declaraţi: struct DataCalendaristica
{
char zi; // [1:31]
int an;
char luna; // [1:12]
};
› Optimizare:
struct Data
{
int an;
char zi; // [1:31]
char luna; // [1:12]
};
C++ Definiţia şi utilizarea unei structuri
› Un nume (identificator) devine accesibil imediat ce a fost scris şi nu după
declarare completă:
struct Link
{
Link∗ previous;
Link∗ successor;
};
› Totuşi nu se poate declara un obiect de un anumit tip dacă declaraţia tipului
respectiv nu este finalizată
struct Link
{
Link data;
};
struct Link
{
Link∗ prev;
Link∗ next;
List∗ member_of;
int data;
};
struct List
{
Link∗ head;
};