You are on page 1of 13

20.12.2015.

Pokazivači

Osnove programiranja © ZN 1

Uvod
• izvršenjem naredbe za deklaraciju varijable:
• za varijablu de biti rezervirana potrebna količina memorijskog prostora ovisno o
tipu varijable
• rezerviranom memorijskom prostoru bit de dodijeljeno ime
• deklaracijom varijable prevoditelj je povezao ime varijable sa adresom
prvog bajta prostora memorije rezerviranog za varijablu
• dodjeljivanjem imenâ varijablama:
• omogudava se jednostavnije zapisivanje naredbî programa
• povedava se čitljivost i razumljivost programa
• olakšava se pronalaženje i otklanjanje grešaka u programu
• olakšava se održavanje programa i mijenjanje njegovih karakteristikâ

2
Osnove programiranja © ZN

1
20.12.2015.

Uvod (nast.)
• za izvršavanje određenih zadataka nužno je poznavati i adrese varijablî
• za pohranjivanje adresâ varijablî, u naredbama programa koriste se
varijable posebnog tipa - pokazivači
• upotrebom pokazivača programski jezik C omoguduje:
• slanje pozivatelju više od jedne vrijednosti iz funkcije
• obrada nizova u funkcijama
• kreiranje složenih strukturâ podataka (npr. povezane liste, stabla, redovi, itd.)
• dinamičko dodjeljivanje memorije u skladu sa potrebama programa
• brže pristupanje elementima nizova, itd.

3
Osnove programiranja © ZN

Pokazivači
• Zadatak: Učitati dva prirodna broja i izračunati njihov količnik.

❶ deklaracija pokazivača #include<stdio.h>


int main() {
int djeljenik, djelitelj;
❷ inicijalizacija pokazivača
❶ int *pokDjeljenik, *pokDjelitelj;
float kolicnik;
❸ učitavanje podataka
upotrebom pokazivača pokDjeljenik = & djeljenik;

pokDjelitelj = & djelitelj;
❹ operacije nad podacima
upotrebom pokazivača printf("\nUpisi vrijednosti djeljenika i djelitelja:");
❸ scanf("%d %d", pokDjeljenik, pokDjelitelj);

❹ if (*pokDjelitelj == 0) {
printf("\nDjelitelj je jednak nuli!");
} else {
❹ kolicnik = (float)(*pokDjeljenik)/(*pokDjelitelj);
printf("\nKolicnik: %f\n", kolicnik);
}

return 0;
}

4
Osnove programiranja © ZN

2
20.12.2015.

Pokazivači
• pokazivači su varijable koje mogu sadržavati samo adrese drugih varijablî
• za upotrebu pokazivača potrebno je:
• deklarirati pokazivač
• inicijalizirati pokazivač adresom varijable
• izvršiti operacije nad vrijednošću varijable upotrebom adrese varijable
pohranjenje u pokazivaču

5
Osnove programiranja © ZN

Deklaracija pokazivača
• u naredbi za deklaraciju pokazivača zapisuje se:
• tip varijable čiju de adresu sadržavati pokazivač
• informacija procesoru koliko de byta pročitati počevši od adrese koja je u pokazivaču
• operator '*' koji označava da je varijabla čije je ime zapisano neposredno iza
operatora pokazivačka varijabla
• operator je potrebno zapisati prije svake pokazivačke varijable
• ime pokazivača

tipa varijable na koju


pokazuje pokazivač ime pokazivača

int djeljenik, djelitelj;


int *pokDjeljenik, *pokDjelitelj;

operator za deklaraciju pokazivača

Osnove programiranja © ZN

3
20.12.2015.

Inicijalizacija pokazivača
• vrijednost neinicijaliziranog pokazivača nije određena i kao takva je
neupotrebljiva
• run-time error zbog neinicijaliziranog pokazivača
• inicijalizacija pokazivača je postupak kojim se pokazivaču dodjeljuje adresa
varijable
• adresu varijable nalazi operator '&'
• varijabla čija se adresa nalazi zapisuje se neposredno iza operatora

int djeljenik, djelitelj;


int *pokDjeljenik, *pokDjelitelj;
pokDjeljenik = & djeljenik;

adresni operator varijabla čiju adresu nalazi operator &


7
Osnove programiranja © ZN

Inicijalizacija pokazivača (nast.)


• pokazivač je mogude inicijalizirati i za vrijeme deklaracije pokazivača
• u trenutku deklaracije pokazivača poznata je varijabla čiju de adresu sadržavati
pokazivač
• pokazivač se inicijalizira konstantom NULL ako u trenutku deklaracije
pokazivača nije poznata varijabla čiju de adresu pokazivač sadržavati
• konstanta NULL sprječava da sadržaj na adresi koja se slučajnim procesima
zatekla u neinicijaliziranom pokazivaču bude prebrisan
• ako se ispitivanjem naredbama programa, ustanovi da je vrijednosti pokazivača
jednaka vrijednosti NULL, sadržaj pokazivača nije valjan i ne smije biti upotrijebljen

int *pokX = NULL;

inicijalizacija pokazivača
adresom 0

8
Osnove programiranja © ZN

4
20.12.2015.

Ispis vrijednosti pokazivača


• za ispisivanje vrijednosti pokazivača, tj. vrijednosti adrese pohranjene u
pokazivač, u pozivu funkcije printf() potrebno je zapisati specifikator %p

int djeljenik;
int *pokDjeljenik = & djeljenik;
printf("\npokDjeljenik = %p\n", pokDjeljenik);

9
Osnove programiranja © ZN

Učitavanje podataka upotrebom pokazivača


• učitavanjem vrijednostî skalarnih varijablî u pozivu funkcije scanf() zapisuju
se adrese varijablî čije se vrijednosti učitavaju
• inicijalizacijom pokazivača adresom varijable, u pozivu funkcije scanf()
mogude je zapisati pokazivač umjesto operatora '&' i varijable

int djeljenik, djelitelj;


int *pokDjeljenik, *pokDjelitelj;
pokDjeljenik = & djeljenik; određivanje adrese varijable djeljenik
pokDjelitelj = & djelitelj;
printf("\nUpisi vrijednosti djeljenika i djelitelja:");
scanf("%d %d", pokDjeljenik, pokDjelitelj);

pokazivač sa adresom varijable djeljenik

10
Osnove programiranja © ZN

5
20.12.2015.

Operacije nad podacima upotrebom pokazivača


• na osnovu adrese varijable pohranjene u pokazivaču, do vrijednosti
varijable dolazi se upotrebom operatora '*'
• operator '*' nalazi vrijednost zapisanu na adresi pohranjenoj u pokazivaču
• tzv. dereferenciranje pokazivača

int djeljenik, djelitelj;


int *pokDjeljenik, *pokDjelitelj;
pokDjelitelj = & djelitelj;
...
scanf("%d", pokDjelitelj);
if (*pokDjelitelj == 0)
...

nalazi vrijednost pohranjenu u varijabli preko njezine adrese u pokazivaču

11
Osnove programiranja © ZN

Prioriteti operacijâ
• poredak operatorâ po prioritetu:
• zagrade
• operatori za rad sa pokazivačima
• operatori za prilagodbu tipova podataka
• predznaci
• povedavanje ili smanjivanje vrijednosti varijable za 1
• množenje, dijeljenje, ostatak cjelobrojnog dijeljenja
• zbrajanje i oduzimanje
• usporedba: manje, manje od ili jednako, vede i
vede od ili jednako
• usporedba: jednako, različito
• logička operacija I
• logička operacija ILI
• operator za dodjeljivanje
12
Osnove programiranja © ZN

6
20.12.2015.

Inicijalizacija pokazivača na niz


• ime niza predstavlja adresu prvog elementa niza
• prevoditelj povezuje ime varijable ili niza sa adresom prve memorijske lokacije u
grupi lokacija koje zauzima varijabla ili niz
• za inicijalizaciju pokazivača na niz dovoljno je iza operatora za dodjeljivanje
zapisati samo ime niza

int broj[UK_BROJEVA], i;
int *pokBroj;
pokBroj = broj;

adresa prvog elementa niza


13
Osnove programiranja © ZN

Učitavanje elemenata niza upotrebom pokazivača


• za pristupanje vrijednostima pojedinačnih elemenata niza upotrebom
pokazivača koristi se aritmetika pokazivača
• aritmetika pokazivača definira operacije koje mogu biti izvršene nad
vrijednostima pokazivačâ
• skup operacijâ nad pokazivačima ograničen je na zbrajanje i oduzimanje
pokazivača sa konstantnim vrijednostima
• vrijednosti pokazivačâ su adrese varijabli te množenje, dijeljenje i druge
operacije nad adresama nemaju smisla

14
Osnove programiranja © ZN

7
20.12.2015.

Aritmetika pokazivača
• dodavanjem vrijednosti i (0, 1, 2... ) adresi u pokazivaču, adresa de se
povedati za i*n, gdje je:
• n = broj byta koje zauzima varijabla čiju adresu sadrži pokazivač
• npr.:
• za nizove cjelobrojnog tipa, adresa u pokazivaču povećava se za 4
• za nizove znakovnog tipa, adresa u pokazivaču povećava se za 1
• itd.

#define UK_BROJEVA 5
...
int broj[UK_BROJEVA], i;
int *pokBroj = broj;

for(i = 0; i < UK_BROJEVA; i++) {


printf("\npokBroj + %d = %p", i, pokBroj + i);
}

adresa prvog elementa niza povećava se za i*4 byta

15
Osnove programiranja © ZN

Učitavanje elemenata niza upotrebom pokazivača


• pojedinačni znakovi ili numerički podaci učitavaju se funkcijom scanf()
jedan po jedan:
• pokazivaču se dodijeli adresa prvog elementa niza
• početna adresa povećava se za umnožak broja
bajta podatka i rednog broja elementa kojemu
se pristupa

#define UK_BROJEVA 5
...
int broj[UK_BROJEVA], i;
int *pokBroj = broj;

for(i = 0; i < UK_BROJEVA; i++) {


printf("\nUpisi %d. prirodan broj: ", i + 1);
scanf(" %d", pokBroj + i);
}

povećavanje adrese prvog elementa niza

16
Osnove programiranja © ZN

8
20.12.2015.

Operacije nad podacima upotrebom pokazivača


• na osnovu adrese elementa niza pohranjene u pokazivaču, do vrijednosti
elementa niza dolazi se upotrebom operatora '*'
• operator za određivanja vrijednosti elementa primjenjuje se na uvedanu
adresu prvog elementa
• operatori zagradâ osiguravaju ispravnost redoslijeda izvršavanja operacijâ -
najprije povedanje početne adrese a tek nakon toga određivanje vrijednosti

#define UK_BROJEVA 5
...
int broj[UK_BROJEVA], i;
int *pokBroj = broj;

for(i = 0; i < UK_BROJEVA; i++) {


if(*(pokBroj + i) % 2 == 0)
printf(" %d",*(pokBroj + i));
}

17
Osnove programiranja © ZN

Pokazivači i funkcije
• Zadatak: Učitati 5 znakova u niz i u funkciji ispisati elemente niza.
#include<stdio.h>
#define ZNAKOVA 5
void ispis (char * pokNizZnakovaf, int n);
int main() {
❶ deklaracija pokazivača char nizZnakova [ZNAKOVA];
na niz ❶ char * pokNizZnakova;
int i;
❷ inicijalizacija pokazivača ❷ pokNizZnakova = nizZnakova;
adresom niza for (i = 0; i < ZNAKOVA; i++) {
printf ("Upisi %d. znak: ", i + 1);
❸ učitavanje podataka u niz ❸ scanf (" %c", pokNizZnakova + i);
upotrebom pokazivača }
❹ ispis ( pokNizZnakova, ZNAKOVA ) ;
❹ poziv funkcije za obradu return 0;
}
elemenata niza
❺ void ispis (char * pokNizZnakovaf, int n) {
int j;
❺ zaglavlje funkcije za obradu printf ("\nUpisani su znakovi: ");
elemenata niza for (j = 0; j < n; j++) {
❻ printf ("%c ", * ( pokNizZnakovaf + j ) );
❻ ispsivanje elemenata niza u }
funkciji return;
}

18
Osnove programiranja © ZN

9
20.12.2015.

Parametri poziva funkcije


• stvarni parametri su podaci koji se pozivom funkcije šalju u funkciju na
obradu
• za slanje stvarnih parametara na obradu u funkciju koriste se dva
mehanizma:
• slanje stvarnih parametara po vrijednosti
• engl. by value
• slanje stvarnih parametara po adresi
• engl. by refefence

19
Osnove programiranja © ZN

Slanje stvarnih parametara po adresi


• slanjem stvarnih parametara po vrijednosti, u funkciju se šalju kopije
stvarnih parametara
• naredbama funkcije nije mogude mijenjati vrijednosti stvarnih parametara ved
samo njihovih kopijâ
• slanjem stvarnih parametara po adresi, u funkciju se šalju adrese stvarnih
parametara
• naredbama funkcije moguće je mijenjati vrijednosti stvarnih parametara

20
Osnove programiranja © ZN

10
20.12.2015.

Poziv funkcije za obradu elemenata niza


• za obradu elemenata nizova u funkciji koristi se mehanizam slanja stvarnih
parametara u funkciju po adresi
• u pozivu funkcije za obradu elemenata niza zapisuje se adresa prvog
elementa niza
• kopiranje velikog broja elemenata niza vremenski je i memorijski zahtjevno
• u pozivu funkcije za obradu elemenata niza potrebno je zapisati i broj
elemenata niza

#define ZNAKOVA 5
...
char nizZnakova [ZNAKOVA];
char * pokNizZnakova;
pokNizZnakova = nizZnakova;
...
ispis (pokNizZnakova, ZNAKOVA);

adresa prvog elementa niza broj elemenata niza

21
Osnove programiranja © ZN

Zaglavlje funkcije za obradu elemenata niza


• pozivom funkcije za obradu niza u funkciju se šalje adresa prvog elementa
niza koji de biti obrađivan u funkciji
• u zaglavlju funkcije koja prima adresu mora biti deklarirana varijabla koja
može pohraniti adresu
• adresu (početka) niza poslanu iz pozivatelja može u funkciji prihvatiti pokazivač

#define ZNAKOVA 4
...
char nizZnakova [ZNAKOVA];
char * pokNizZnakova;
pokNizZnakova = nizZnakova; deklaracija pokazivača
... za prihvat adrese iz
ispis (pokNizZnakova, ZNAKOVA); poziva funkcije
...
adresa prvog elementa niza
void ispis (char * pokNizZnakovaf, int n) {
...

22
Osnove programiranja © ZN

11
20.12.2015.

Operacije nad elementima niza u funkciji


4
• na osnovu adrese niza, u funkciji je mogude izvršavati operacije nad
elementima niza kao da se izvršavaju naredbama pozivatelja
• sve promjene izvršene u funkciji mijenjaju
originalne vrijednosti

...
ispis (pokNizZnakova, ZNAKOVA);
...
void ispis (char *pokNizZnakovaf, int n) {
int j;
printf ("\nUpisani su znakovi: ");
for (j = 0; j < n; j++) {
printf ("%c ", * (pokNizZnakovaf + j));
}
return;
}

23
Osnove programiranja © ZN

Greške pri upotrebi pokazivača


• u naredbama za deklaraciju:
• prije imena pokazivača nije zapisan operator '*'
• pokazivač nije istog tipa kao i varijabla čiju bi adresu trebao sadržavati
• u naredbama za inicijalizaciju:
• prije imena varijable čiju je adresu potrebno dodijeliti pokazivaču nije zapisan operator
'&'
• u naredbi za dodjeljivanje adrese varijable pokazivaču prije imena pokazivača zapisan je
operator '*'
• u naredbama za učitavanje podataka:
• prije imena pokazivača zapisan je operator '*'
• u naredbama za određivanje vrijednostî elemenata niza
• izostavljane okrugle zagrade oko izraza za izračunavanje adrese elementa čija se
vrijednost određuje
• u zaglavlju funkcije:
• varijabla za prihvat adrese nije deklarirana kao pokazivač

24
Osnove programiranja © ZN

12
20.12.2015.

PITANJA?

25

13

You might also like