You are on page 1of 5

Strukture podataka i algoritmi 2

dr Boban Stojanovi

Pokazivai i nizovi
Pokaziva (pointer) je promenljiva koja sadri adresu neke druge promenljive. Pokazivai i nizovi su u
programskom jeziku C veoma bliski, pa se iz tog razloga u ovom poglavlju opisuju zajedno.
Prilikom programiranja pokazivai mogu biti veoma moan alat, koji omoguava pisanje kompaktnijeg i
efikasnijeg koda. Meutim, njihovo nepravilno korienje moe ozbiljno naruiti itljivost i funkcionalnost
programa.

Pokazivai i adrese
Memoriju raunara moemo posmatrati kao niz numerisanih (adresiranih) memorijskih elija, kojima se
moe pristupati pojedinano ili u povezanim grupama. Najmanja memorijska jedinica (elija) kojoj se moe
pritupiti je bajt. Jedan bajt memorije je dovoljan za uvanje jednog char podatka, dva bajta mogu uvati
short celobrojni tip podatka, a etiri uzastopna bajta mogu da formiraju long. Slino, za smetanje
pokazivaa se najee koriste grupe od dve ili etiri uzastopne elija (bajta).
Na sledeoj slici je shematski prikazana situacija u memoriji kada pokaziva pokazuje na promenljivu tipa
char.

Slika ### Pokaziva pokazuje na promenljivu tipa char

Da bismo dobili adresu neke promenljive u memoriji, koristimo operator &. Tako izraz
p=&c;

pokazivau p dodeljuje adresu promenljive c i tada kaemo da p pokazuje na c.


Ukoliko imamo pokaziva na neku promenljivu, toj promenljivoj moemo pristupiti korienjem operatora
*, koji se jo naziva i operator dereferenciranja. Na sledeem primeru moemo videti kako se deklarie
pointer i kako se koriste operatori & i *.
intx=5,y=1,z[20];
int*p; /*pjepokazivacnaint*/

p=&x; /*psadapokazujenax*/
y=*p; /*ysadaimavrednost5*/
*p=0; /*xsadaimavrednost0*/
p=&z[0] /*psadapokazujenaz[0]*/

U prethodnom primeru smo videli da se pokaziva p deklarie pomou


int*p;

to bi moglo da se ita kao p pokazuje na int, ili *p je int. Iz ovoga zakljuujemo da se pokaziva
deklarie kao pokaziva na tano odreeni tip podatka i ne moe se koristiti za pokazivanje na neki drugi
tip.
Ukoliko pokaziva pokazuje na celobrojnu promenljivu x, *p se moe pojaviti u bilo kom kontekstu gde bi
se moglo pojaviti i x. Na primer:
*p=*p+12;

uveava *p za 12, a samim tim uveava i x za 12.


Unarni operatori & i * imaju vei prioritet od aritmetikih operatora, tako da
1

Strukture podataka i algoritmi 2

dr Boban Stojanovi

y=*p+5;

prvo uzima vrednost na koju pokazuje p, uveava je za 5 i dodeljuje promenljivoj y, dok svaka od linija
*p+=1;
++*p;
(*p)++;

uveava *p za jedan.
S obzirom da su pokazivai promenljive kao i sve druge, mogue je njihovo korienje i bez
dereferenciranja. Jedan od primera je i dodeljivanje vrednosti jednog pokazivaa drugom:
q=p;

ime se vri kopiranje sadraja pokazivaa p u pokaziva q, tako da sada pokaziva q pokazuje na istu
memorijsku lokaciju, na koju pokazuje i pokaziva p.

Pokazivai kao argumenti funkcija


Imajui u vidu da C funkcijama alje argumente preko vrednosti, ne postoji direktan nain da funkcija koja
je pozvana promeni promenljive u funkciji koja ju je pozvala. Na primer, funkcija za sortiranje treba da
meusobno zameni vrednosti dvema promenljivama korienjem funkcije zameni, koja je definisana kao
voidzameni(inta,intb)
{
intpom;

pom=a;
a=b;
b=pom;
}

/*POGRESNO*/

pri emu bi poziv funkcije bio


zameni(x,y);

Ovako definisana funkcija kopira vrednosti koje su joj poslate u svoje privremene lokalne promenljive a i b.
Iako funkcija vri promenu podataka u promenljivim a i b, ta promena ne utie na prosleene promenljive
x i y, s obzirom da se funkciji argumenti prosledjuju preko njihovih vrednosti.
Na sreu, ovaj problem je mogue reiti korienjem pokazivaa. Umesto slanja vrednosti odreenih
promenljivih, funkciji se alju adrese, odnosno pokazivai na te promenljive. Na ovaj nain pozvana funkcija
moe korienjem prosledjenih pokazivaa posredno da pristupi ovim promenljivim i da promeni njihove
vrednosti. U tom sluaju funkcija zameni bi izgledala ovako:
voidzameni(int*pa,int*pb)
{
intpom;

pom=*pa;
*pa=*pb;
*pb=pom;
}

/*ISPRAVNO*/

pri emu bi poziv funkcije bio


zameni(&x,&y);

Strukture podataka i algoritmi 2

dr Boban Stojanovi

Slika ### Shematski prikaz prosleivanja pokazivaa funkciji

Pokazivai i nizovi
U programskom jeziku C postoji vrsta veza izmeu pokazivaa i nizova, tako da se o njima moe govoriti
istovremeno. Svaka operacija koja se moe obaviti korienjem nizova, moe se obaviti i pomou
pokazivaa. Varijanta koja koristi pokazivae je bra, ali tea za razumevanje.
Deklaracija
inta[10];

definie niz a veliine 10, odnosno niz od 10 uzastopnih celih brojeva [0], a[1], ..., a[9].

Slika ### Shematski prikaz niza a u memoriji raunara.

Notacija a[i] ukazuje na i-ti element niza.


Ukoliko je p pokaziva na ceo broj, deklarisan kao
int*p;

onda linija
p=&a[0];

postavlja pokaziva p da pokazuje na nulti element niza a (indeksi nizova u C-u poinju od nule), ili
drugaije reeno pokaziva p sadri adresu elementa a[0].

Slika ### Pokaziva p pokazuje na nulti element niza a

Sada linija
x=*p;

dodeljuje promenljivoj x vrednost elementa a[0].


Ukoliko pokaziva p pokazuje na odreeni element niza, po definiciji p+1 pokazuje na sledei element, p+i
pokazuje na i-ti element iza p, a p-i pokazuje na i-ti element ispred p. Tako, ukoliko p pokazuje na a[0], onda
3

Strukture podataka i algoritmi 2

dr Boban Stojanovi

*(p+1)

predstavlja sadraj elementa a[1], a


*(p+i)

sadraj elementa a[i].

Slika ### Pristupanje elementima niza pomou pokazivaa

Ovakav nain pristupanja elementima niza moe se koristiti bez obzira na tip elemenata niza, tako da
notacija p+1 uvek predstavlja sledei element niza, a p+i predstavlja i-ti element iza p, bilo da se radi o nizu
celih brojeva ili nekom drugom nizu.
Indeksiranje nizova i aritmetika pointera su veoma bliski. Po definiciji, vrednost promenljive kojom se
oznaava niz je upravo adresa nultog elementa niza. Zbog toga nakon izvrenja linije
p=&a[0];

p i a imaju jednake vrednosti, tako da prethodna linija moe biti napisana i kao
p=a;

Imajui ovo u vidu, ne iznenauje injenica da se a[i] moe napisati kao *(a+i). Ukoliko primenimo operator
& na oba ova oblika, dobijamo da je &a[i] isto to i a+i, tj. adresa i-tog elementa niza. Slino vai i za
pokaziva p, pa je p[i] isto to i *(p+i).
Iako na prvi pogled izgleda da su pokazivai i nizovi jedno te isto i da imaju potpuno iste osobine, postoji
jedan detalj koji ih razlikuje. Naime, kao to je ranije pomenuto, pokazivai su promenljive, pa su i izrazi
p=a i p++ dozvoljeni. Meutim, sam naziv niza nije promenljiva i na njega se ne mogu primeniti izrazi tipa
a=p i a++.
Kada se funkciji prosleuje naziv niza, ono to se zapravo alje je adresa nultog elementa. Unutar pozvane
funkcije ovaj argument je lokalna promenljiva, a parametar koji predstavlja niz je pokaziva, odnosno
promenljiva koja sadri adresu nultog elementa niza. Posmatrajmo funkciju za odreivanje duine stringa
(niza karaktera):
/*duzina:vracaduzinustringas*/
intduzina(char*s)
{
intn;

for(n=0;*s!='\0';s++) n++;

returnn;
}

Imajui u vidu da je s pokaziva, njegovo poveavanje korienjem s++ je doputeno. Poto je s lokalna
promenljiva funkcije duzina, njegova promena ne utie na string koji je prosleen iz funkcije koja je pozvala
funkciju duzina. Zahvaljujui tome mogui su sledei pozivi funkcije duzina:
duzina("Zdravo,drugari!");
duzina(niz);

duzina(pok);

/*konstantanstring*/
/*charniz[100];*/
/*char*pok*/

Strukture podataka i algoritmi 2

dr Boban Stojanovi

U definiciji funkcija dozvoljeno je deklarisanje formalnih parametara na oba naina; i kao niza i kao
pokazivaa. Deklaracije
chars[]

i
char*s

su ekvivalentne.
Funkciji je mogue proslediti i deo nekog niza tako to bi joj se prosledio pokaziva na podniz. Tako,
ukoliko je a niz, pozivi
fun(&a[5]);

i
fun(a+5);

prosleuju funkciji fun podniz koji poinje od petog elementa niza a.

You might also like