7 POKAZIVAI Sadraj tip pokazivaa korienje pokazivaa adresna

  • Slides: 30
Download presentation
7 POKAZIVAČI

7 POKAZIVAČI

Sadržaj • • • tip pokazivača korišćenje pokazivača adresna aritmetika dinamička alokacija memorije korišćenje

Sadržaj • • • tip pokazivača korišćenje pokazivača adresna aritmetika dinamička alokacija memorije korišćenje nizova u dinamičkoj zoni pokazivači na strukture 2

 • Pokazivači služe za pristup podacima putem adrese (uočiti da je adresa element

• Pokazivači služe za pristup podacima putem adrese (uočiti da je adresa element programa koji je dostupan i u fazi prevođenja i u fazi izvršenja!) • Vrednosti samog pokazivača su adrese, tj. skalari • Memorijska lokacija čiju adresu sadrži pokazivač nosi naziv pokazivana lokacija • Da bi se moglo pristupiti podatku na pokazivanoj lokaciji mora se znati tip tog podatka, te se tip pokazivača izvodi iz tipa pokazivane lokacije 3

Definisanje pokazivača • pokazivač se definiše iskazom tip *ime. Pokazivaca; gde tip označava tip

Definisanje pokazivača • pokazivač se definiše iskazom tip *ime. Pokazivaca; gde tip označava tip pokazivane lokacije. int *p. I, *p. J, x, a[100]; //tip p. I i p. J je int *! p. I i p. J su pokazivači na int lokaciju; x je obična int promenljiva, a je int niz. 4

Elementarno korišćenje pokazivača • osnovna operacija nad pokazivačima je pristup pokazivanoj lokaciji; nosi naziv

Elementarno korišćenje pokazivača • osnovna operacija nad pokazivačima je pristup pokazivanoj lokaciji; nosi naziv dereferenciranje i realizuje se unarnim operatorom * operator dereferenciranja *ime. Pokazivaca • na primer, *p. K //pristup lokaciji ciju adresu sadrzi p. K • konverziona specifikacija za prikaz pokazivača pomoću printf je %p. Vrednost se prikazuje heksadecimalno. 5

Adresni operator • u određenoj vezi sa pokazivačima je i tzv. adresni operator: unarni

Adresni operator • u određenoj vezi sa pokazivačima je i tzv. adresni operator: unarni operator & koji primenjen na promenljivu daje njenu adresu x //obezbedjuje vrednost promenljive x &x //obezbedjuje adresu promenljive x 6

ilustracija ponašanja pokazivača int *p. I, *p. J, x; x = 10; p. I

ilustracija ponašanja pokazivača int *p. I, *p. J, x; x = 10; p. I = &x; //koliko je p. I? //koliko je *p. I? p. J = p. I; //koliko je *p. J? *p. I = -5; //koliko je x? p. I p. J A A A x 10 7

Generički pokazivači • Generički pokazivači su pokazivači kod kojih nije definisan tip pokazivane lokacije;

Generički pokazivači • Generički pokazivači su pokazivači kod kojih nije definisan tip pokazivane lokacije; realizuju se kao tip void* void *p. G; • generički pokazivači se ne mogu dereferencirati (jer se ne zna tip pokazivane lokacije) *p. G 8

Osnovni operator dodele • Osnovni operator dodele pokazivača pokazivaču p 2 = p 1

Osnovni operator dodele • Osnovni operator dodele pokazivača pokazivaču p 2 = p 1 može da se izvrši – ako su p 1 i p 2 istog tipa – ako je bar jedan od njih void pokazivač 9

int *p. J, *p. K; double *p. D; void *p. G; p. J =

int *p. J, *p. K; double *p. D; void *p. G; p. J = p. K; //moze p. G = p. J; //moze p. G = p. D; //moze p. D = p. G; //moze p. G = p. K; //moze p. J = p. D; //ne moze! p. D = p. K; //ne moze! 10

 • razlog zašto pokazivači koji nisu istog tipa ne mogu da se dodele

• razlog zašto pokazivači koji nisu istog tipa ne mogu da se dodele je dereferenciranje p. K *p. K p. D *p. D = p. K -25 ? • posle dodele p. D=p. K, rezultat *p. D je slučajan! • dodela generičkom pokazivaču dozvoljena je, jer se on ne može dereferencirati 11

Sabiranje i oduzimanje • operacije: + ++ += - -- -= • jedan operand

Sabiranje i oduzimanje • operacije: + ++ += - -- -= • jedan operand je pokazivač, a drugi celobrojni podatak; jedinica mere za celobrojni podatak je veličina pokazivane lokacije (1 bajt za void pokazivač) int *p. K, i; double *p. D; void *p. V; p. K + i izvodi se kao p. K+i*sizeof(int) p. D - i izvodi se kao p. D-i*sizeof(double) p. V + i izvodi se kao p. V+i p. K++ na p. K se dodaje sizeof(int) 12

Pokazivači i nizovi • jedinstvena osobina C-a: ime niza je pokazivač na njegov nulti

Pokazivači i nizovi • jedinstvena osobina C-a: ime niza je pokazivač na njegov nulti element int a[100], j; *a a *(a+j) *(a+1) a[0] a[1] . . . a[j] . . . a[99] *(a+j) a[j] a+j &a[j] 13

još neke operacije • nad pokazivačima definisani su još i – relacioni operatori ==

još neke operacije • nad pokazivačima definisani su još i – relacioni operatori == != > >= < <= – oduzimanje pokazivača od pokazivača (koje ima smisla samo ako pokazivači pokazuju na elemente istog niza) 14

NULL vrednost pokazivača • konkretne vrednosti pokazivača su adrese i nisu od interesa (čak

NULL vrednost pokazivača • konkretne vrednosti pokazivača su adrese i nisu od interesa (čak se mogu menjati od slučaja do slučaja) • uopšte, pokazivačima se ne mogu dodeljivati konstantne vrednosti • izuzetak je simbolička konstanta NULL (definisana u zaglavljima stdio. h i stdlib. h) • kada ne postoji pokazivana lokacija pokazivač treba da ima vrednost NULL (u suprotnom se dereferencira slučajna lokacija) 15

Dinamička dodela memorije • izuzetno moćan mehanizam koji omogućuje da se tokom izvršenja, programu

Dinamička dodela memorije • izuzetno moćan mehanizam koji omogućuje da se tokom izvršenja, programu dodeli dodatna memorija, odnosno da se ona oslobodi • dodela memorije zove se alokacija, a oslobađanje dealokacija • zona operativne memorije u kojoj se vrši alokacijadealokacija zove se hip (heap) • rukovalac hipom (heap manager) je C-ov podsistem za upravljanje hipom • iz programa, hipom se rukuje preko odgovarajućih funkcija 16

 • u toku izvršenja programa, identifikatori više ne postoje (koristio ih je kompajler);

• u toku izvršenja programa, identifikatori više ne postoje (koristio ih je kompajler); shodno tome, jedini način da se rukuje memorijom na hipu jesu adrese, • što znači da je osnovni mehanizam za rukovanje hipom u toku izvršenja programa pokazivač • osnovne funkcije za korišćenje hipa su malloc (za alokaciju) i free (za dealokaciju) 17

alokacija pokazivač statička memorija p A malloc *p (otvara blok, uspostavlja vezu) A hip

alokacija pokazivač statička memorija p A malloc *p (otvara blok, uspostavlja vezu) A hip 18

dealokacija statička memorija p A free (oslobadja blok, raskida NULL vezu, upisuje NULL u

dealokacija statička memorija p A free (oslobadja blok, raskida NULL vezu, upisuje NULL u p) *p A hip 19

funkcije za rad sa hipom • osnovne funkcije za korišćenje hipa su: malloc(no_bytes) Zauzima

funkcije za rad sa hipom • osnovne funkcije za korišćenje hipa su: malloc(no_bytes) Zauzima blok od no_bytes bajtova na hipu i vraca pokazivac na taj blok; ako ne uspe vraća NULL. free(pokazivac) Oslobadja blok na koji pokazuje pokazivač i upisuje u pokazivač vrednost NULL 20

dodatne funkcije calloc(n, no_bytes) Zauzima blok od n*no_bytes bajtova na hipu i vraca pokazivac

dodatne funkcije calloc(n, no_bytes) Zauzima blok od n*no_bytes bajtova na hipu i vraca pokazivac na taj blok; ako ne uspe vraća NULL; blok se popunjava nulama. Smatra se zastarelom (engl. deprecate) realloc(pokazivac, new_bytes) Efektivno proširuje ili skraćuje blok na koji pokazuje pokazivac na veličinu new_bytes. 21

primer long double *p. LD; //zauzimanje memorije za long double podatak p. LD =

primer long double *p. LD; //zauzimanje memorije za long double podatak p. LD = malloc(sizeof(long double)); . . . . podatku se pristupa preko *p. LD. . //oslobadjanje memorije free(p. LD); 22

Curenje memorije • curenje memorije (memory leak) je situacija u kojoj je nedostupni blok

Curenje memorije • curenje memorije (memory leak) je situacija u kojoj je nedostupni blok na hipu označen kao zauzet • tipičan slučaj: pokazivač koji pokazuje na blok A na hipu preusmeri se na blok B, a da blok A nije prethodno oslobođen; time se efektivno smanjuje hip • curenje memorije se ne sme tolerisati ni pod kakvim uslovima! 23

blok A je nedostupan! A p B p = malloc(sizeof(Neki. Tip)); //preusmeravanje na blok

blok A je nedostupan! A p B p = malloc(sizeof(Neki. Tip)); //preusmeravanje na blok B 24

 • postulat za korišćenje hipa jeste sve što se alocira pomoću malloc, calloc

• postulat za korišćenje hipa jeste sve što se alocira pomoću malloc, calloc ili realloc mora se eksplicitno osloboditi pomoću free 25

Nizovi na hipu • korišćenjem pokazivača nizovi se realizuju na hipu, što je znatno

Nizovi na hipu • korišćenjem pokazivača nizovi se realizuju na hipu, što je znatno bolji način jer više ne predstavljaju rezervisani memorijski prostor • zauzimaju tačno onoliko memorije koliko imaju aktuelnih elemenata • broj elemenata (dužina) ne zadaje se u toku prevođenja, pa se u tu svrhu mogu koristiti i promenljive 26

int *a, i, n; //pokazivac a ponasace se kao niz!. . . . .

int *a, i, n; //pokazivac a ponasace se kao niz!. . . . . //na hipu se zauzima prostor potreban za int niz //sa n elemenata a = malloc(n*sizeof(int)); . . i-tom elementu "niza" a pristupa se sa a[i]. . . . zato sto je a[i] isto i *(a+i). . free(a): //obavezna dealokacija 27

 • napomena: isto se radi i sa matricom, uz korišćenje dvostrukog pokazivača **

• napomena: isto se radi i sa matricom, uz korišćenje dvostrukog pokazivača ** double **mtr; int m, n, i, j; //alokacija mtr = malloc(m*sizeof(double*)); for(i=0; i<m; i++) mtr[i] = malloc(n*sizeof(double)); . . . elementima "matrice" pristupa se sa mtr[i][j]. . . //dealokacija for(i=0; i<m; i++) free(mtr[i]); //oslobadjanje vrsta free(mtr); 28

Pokazivači na strukture • vrlo čest slučaj: strukture na hipu • neka je p.

Pokazivači na strukture • vrlo čest slučaj: strukture na hipu • neka je p. S pokazivač na strukturu i neka struktura ima polje x. Pristup polju x preko pokazivača p. S izvodi se operacijom (*p. S). x • pošto je ovo vrlo često, uveden je poseban nikad se ne koristi operator -> (*p. S). x p. S->x 29

Rezime • tip pokazivača je tip* gde je tip pokazivane lokacije • korišćenje pokazivača:

Rezime • tip pokazivača je tip* gde je tip pokazivane lokacije • korišćenje pokazivača: najvažniji operator je dereferenciranje * • dodela, sabiranje, oduzimanje i relacioni operatori mogući su pod određenim uslovima • dinamička alokacija memorije: zauzimanje i oslobađanje memorije u toku izvršenja programa • korišćenje nizova na hipu je, u stvari, normalan način za njihovu upotrebu 30