Strukture podataka i algoritmi |
2.8 Funkcije kao tip podataka u C-u |
C dozvoljava da se funkcija koristi kao podatak, sto daje mogucnost i da se funkcija prosledi kao argument druge funkcije - vazna osobina koje omogucava kreiranje fleksibilnih opstih apstraktnih tipova podataka u ANSI C-u. Ova mogucnost je, iako se ne koristi cesto, ekstremno korisna u odgovarajucim situacijama. Na primer, dok smo inicijalno definisali skupove, iako smo bili pazljivi da dizajniramo nase skupove tako da mogu da obrade bilo koji tip podataka, mi smo se u svakom programu ogranicavali na skupove koji sadrze samo jedan odredjeni tip podataka. Ovo je bila posledica potrebe za definisanjem spoljasnje funkcije za poredjenje objekata. Idealno, hteli bismo da specificiramo opstu funkciju za poredjenje objekata u skupu jos prilikom konstrukcije apstraktnog tipa skupa. U C-u, ovo je veoma lako (iako sintaksa definitivno nije intuitivna!). Zelimo da imamo opstu funkciju za poredjenje koja nam kaze kako treba poredjati objekte koje stavljamo u skup, tj. treba nam funkcija:
int ItemCmp( void *a, void *b );
koja vraca -1, 0 ili +1 u zavisnosti od toga da li je a manje, jednako ili vece od b. (Obratimo paznju da dozvoljavamo veoma opsti pojam relacije 'manje od': ItemCmp funkcija moze da poredi objekte po bilo kom pravilu koje moze biti odgovarajuce za odredjenu vrstu objekata.)
Znaci, u strukturu naseg skupa smo dodali i funkciju za poredjenje:
struct t_collection { int item_cnt; int (*ItemCmp)( void *, void * ); .... };
ItemCmp je pointer na funkciju ciji je prototip (definicija):
int ItemCmp( void *, void * );Zagrade su neophodne da bi razlikovali ovu deklaraciju od prototipa funkcije i samog poziva funkcije! Konstruktor ConsCollection sada postaje:
collection ConsCollection( int max_items, int (*ItemCmp)( void *, void * ) );
A koriscenje skupa sada izgleda ovako:
#include "objekat.h" /* ucitaj apstraktni tip podataka za objekte */ int PorediObjekte( objekat, objekat ); collection MnogoObjekata; MnogoObjekata = ConsCollection( veliki_broj, PorediObjekte );
U implementaciji apstraktnog tipa podataka, ItemCmp funkcija se koristi de-referenciranjem pointera na funkciju i normalnim koriscenjem: u FindInCollection funkciji, mogli bismo da imamo:
int FindInCollection( collection c, void *a ) { ..... if ( (*(c->ItemCmp))( c->items[i], a ) == 0 ) { /* Pronasli smo iste ... */ .... }
U gornjem primeru koristili smo veci broj zagrada, zato sto ne zelimo da se zamaramo pravilima sta se prvo racuna: zasto rizikovati glupu gresku, kad nekoliko dodatnih zagrada osigurava da kompajler tretira kod onako kako zelimo?
Ipak, C dozvoljava 'precicu' - koja ne zahteva de-referenciranje pointera na funkciju: u primerima izvornog koda, funkcija ItemCmp je dodata u implementaciju skupa pomocu binarnih stabala.
Nova implementacija skupa pomocu binarnih stabala
Kljucni pojmovi |
Dalje na Nizove Nazad na Sadrzaj |