C++ Pokazivac2
-
Upload
bojan-jevtic -
Category
Documents
-
view
218 -
download
0
description
Transcript of C++ Pokazivac2
1
Pokazivač Pokazivač (pointer) je varijabla koja sadrži adresu druge varijable. Pošto pokazivač nema izravno vezu s podacima (ne sadrži podatke) govori se o indirekciji ili referenciranju. Sintaksa: tip_podataka_na koji _pokazuje *naziv_pokazivača Primjer: int *ptr Pokazivač ptr pokazuje na cjelobrojni tip podataka (int). Pokazivači se mogu deklarirati na sve jednostavne tipove podataka (int, short, long, char itd.) kao i na objekte.(polja ili klase). Može se slikovito usporediti s karticom na kojoj je pohranjen broj žiro računa.
Slika 18. Primjer pokazivača Broj kartice 22233344 je pokazivač na stanje žiro računa. Adresa pokazivača je slična broju žiro računa, a stanje žiro računa je varijabla na koju pokazuje broj računa (pokazivač). Dereferenziranje pokazivača Dereferenciranje pokazivača znači prikazati sadržaj na koji pokazuje pokazivač (pointer). Pokazivač u nekoj memorijskoj lokaciji čuva adresu druge memorijske lokacije na kojoj je upisan određeni sadržaj. Primjer dereferenciranja pokazivača
int A = 44; int *p = &A; // Pokazivaču se pridružuje adresa varijable A // kasnije... int B = *p; // Varijabli B se pridružuje vrijednost varijable na koju ukazuje pokazivač p ( tj. vrijednost varijable A).
Prvo se deklarira varijabla A tipa integer. U drugom retku programa deklarira se pokazivač na cjelobrojnu vrijednost, a pokazivaču se pridružuje adresa varijable A. Operator referenciranja & znači da se pokazivaču pridružuje adresa (vrijednost u heksadekadnom brojevnom sustavu), a ne vrijednost koja je pohranjena na toj adresi (vrijednost pohranjena na toj adresi je 44 tj. A=44). Pomoću pokazivača se može dobiti i vrijednost pohranjena na adresi pridruženoj pokazivaču. Intuitivno bi se najvjerojatnije napravila sljedeća pogreška:
int B = p; // pogrešan kod!!!!
Pokazivač
Adresa
Broj računa
22233344
100.000,00
Kartica Marina
8888
22233344
2
Prilikom prevođenja takvog koda kompajler bi prijavio sljedeću pogrešku: ne može konvertirati int* to int. Takva pogreška je razumljiva jer su B i p dva različita tipa podataka. Naime B je varijabla tipa integer, a p je adresa varijable A (u heksadekadnom brojevnom sustavu). Zato se za pridruživanje varijabli B vrijednosti na koju pokazuje pokazivač potrebno poslužiti operatorom dereferenciranja (*): int B = *p; Operator dereferenciranja priopćava kompajleru da se varijabli B pridruži vrijednost objekta na koji pokazuje pokazivač p, a ne vrijednost pohranjena u p.
Slika 19. Koncept pokazivača
Važno je uočiti da operator dereferenciranja služi za deklariranje pokazivača (int *p) i za derefernciranje (int B=*p). Neinicijalizirani pokazivač sadrži slučajnu (neodređenu) vrijednost ( slično neinicijaliziranoj varijabli). Zato je korisno i potrebno inicijalizirati pokazivač prilikom njegove deklaracije. Slijede primjeri pristupa vrijednostima varijabli pomoću pokazivača: int X=3, *p; //Deklaracija varijable X i pokazivača p na cjelobrojni tip podataka p=&X; //Pokazivaču p se pridružuje memorijska adresa varijable X Pristup vrijednostima varijabli pomoću operatora dereferenciranja (*) Primjer
Slika 20. Pristup vrijednostima varijabli pomoću pokazivača
p=0xFF1
B=44
*p=44 Memorijske adrese 0xFF0 0xFF1 ………. ……….
3
Pokazivači na polja Naziv polja (array) bez indeksa polja označava adresu prvog elementa polja. Naziv polja je pokazivač na početak polja pa se polju može pridružiti pokazivač. Primjer
#include <vcl.h> #pragma hdrstop #include <iostream.h> void main() { int polje[]={2,4,6,8,10}; cout<<"Adresa prvog elementa polja je: "<<polje<<endl; cout<<"Vrijednost prvog elementa polja je: "<<*polje<<endl; getchar(); }
Program 3: Pokazivači na polja
Pojedinačnom elementu polja se može pristupiti pomoću odgovarajućeg indeksa polja. Dano je polje podataka čiji su elementi: int polje[] = {2,4,6,8,10}; Varijabli a se pridružuje vrijednost drugog elementa polja: int a = polje[1]; // a ima vrijednost drugog elementa polja jer indeks počinje od 0, a ne 1). Sličan program se može zapisati primjenom pokazivača. Prvo se definira polje i incijaliziraju odgovarajući indeksi, a zatim pokazivaču pridruži ime polja (ime polja bez indeksa je adresa prvog elementa – člana polja). Primjer int polje[] = {2,4,6,8,10};
int* p = polje; // Deklaracija pokazivača p i pridruživanje adrese prvog člana polja. int b = p[2]; //Varijabli b se dodjeljuje treći element polja – vrijednost 6.
Slika 21. Pristup elementima polja pomoću pokazivača
4
Nakon prevođenja programa dobiva se rezultat koji se lako može razumjeti na temelju prethodnih objašnjenja.
Pokazivači na funkcije Pokazivačima se mogu pridruživati i adrese funkcija. To svojstvo pokazivača se često primjenjuje u objektno orijentiranom programiranju. Naziv funkcije zamjenjuje se pokazivačem dok ostali dijelovi zaglavlja funkcije se ne mijenjaju (tip povratka i argumenti funkcije). Pokazivač na funkciju se definira na slijedeći način: <tip povratka> (*naziv)( <tip> p1, <tip> p2,.., <tip> pn) Objašnjenja: (*naziv) je naziv pokazivača, a on pokazuje na funkciju. <tip povratka> je tip podataka koji funkcija vraća. (<tip> p1,...) su parametri funkcije. Porebno je ponovno navesti primjer kako bi se razumjela uporaba pokazivača na funkcije u programima. Primjer #include <vcl.h> #include <iostream.h> void izlaz() //Definicija funkcije izlaz { cout<<"Upisati neki broj:" <<endl; } int zbroj(int x, int y) //Definicija funkcije zbroj. { return(x+y); } void main() { int a,b; void (*pNaFunkciju1)(void); //Definicija pokazivača na funkciju pokazivacNaFunkciju1 // i on nema povratne vrijednosti ni nema ulaznih parametara. int (*pNaFunkciju2)(int, int); // Definicija pokazivača na funkciju pokazivacNaFunkciju2 // povratna vrijednosti tipa int i ulazni parametri tipa int. pNaFunkciju1=izlaz; //Pokazivaču pNaFunkciju1 se pridružuje adresa funkcije izlaz,a
// adresa je naziv funkcije bez malih zagrada!) pNaFunkciju2=zbroj; // Pokazivaču pNaFunkciju2 se pridružuje adresa funkcije zbroj pNaFunkciju1(); //Poziv funkcije preko pokazivača pNaFunkciju1, dakle funkcija izlaz. cin>> a; pNaFunkciju1(); //Poziv funkcije preko pokazivača pNaFunkciju1, ponovno funkcija izlaz cin>>b; cout<<"Zbroj varijabli a i b je "<<pNaFunkciju2(a,b)<<endl;// Poziv funkcije pomoću pokazivača, pNaFunkciju2, dakle funkcija zbroj. getchar(); }
5
Program 4: Primjena pokazivača na funkcije Bitno je uočiti da je naziv funkcije (bez malih zagrada) njezina adresa u memoriji računala. Slično svojstvo primjenjuje se i za polje. Kao što je pokazano, naziv polja je memorijska adresa prvog člana polja.
Pokazivač na pokazivač Osim pokazivača na varijable i funkcije može se deklarirati i pokazivač na pokazivač. Pokazivač na pokazivač ima slijedeću sintaksu: <tip> **naziv_pokazivača; Pojašnjenje: Pokazivač **naziv_pokazivača pokazuje na pokazivač koji pokazuje na tip varijable tip. Mnogo je složenije napisati što pokazuje pokazivač na pokazivač, nego razumjeti i primijeniti u programima. Zato ponovno slijedi primjer.
#include <iostream.h> void main() { int x, y, *xptr, **ptrptr; //Deklaracija varijabli x,y, pokazivača xptr i pokazivača na //pokazivač ptrptr. x=10; y=10; cout<<"x = "<<x<<endl; xptr=&x; //Pokazivaču xptr se pridružuje adresa varijable x . *xptr=20; //Vrijednost varijable na koju pokazuje xptr postavlja se na 20. cout<<"x = "<<x<<" i *xptr = " <<*xptr<<endl; ptrptr=&xptr; //Pokazivaču ptrptr se pridružuje adresa pokazivača xptr. **ptrptr=30; //Varijabli x se preko pokazivača **ptrptr pridružuje vrijednost 30. cout<<"x = "<<x<<" *xptr = "<<*xptr<<" i **ptrptr = "<<**ptrptr<<endl; *ptrptr=&y; //Pokazivač sada pokazuje na varijablu y. **ptrptr=40;//Varijabli y se pridružuje 40, jer ptrptr pokazuje na ptr, a ptr sada na y. cout<<"x = "<<x<<", y= "<<y<<", *xptr = "<<*xptr<<" i **ptrptr ="<<**ptrptr<<endl;getchar() ; }
Program 5. Program za koncept „pokazivač na pokazivač“
Pojašnjenja bitnih dijelova programa: Deklaracije varijable: x i y tipa int, pokazivača: xptr, koji pokazuje na varijablu tipa int,
pokazivača: ptrptr, koji pokazuje na pokazivač, a on sadrži adresu jedne varijable tipa int,
Pridruživanje pokazivaču xptr se pridružuje adresa varijable x, xptr pokazuje prvo na x, varijabli x se pridružuje 20 preko pokazivača xptr dereferenciranjem, pokazivač ptrptr se pridružuje adresa pokazivača xptr, tj. ptrptr pokazuje na xptr, pokazivaču xptr se pridružuje 30 preko pokazivača ptrptr dereferenciranjem, a to je implicitno pridruživanje vrijednosti varijabli x preko pokazivača xptr
Pridruživanje pokazivaču xptr se pridružuje adresa varijable y, xptr sada pokazuje na y,
6
varijabli y se pridružuje 40 preko pokazivača xptr dereferenciranjem, a to je implicitno pridruživanje vrijednosti varijabli y preko pokazivača xptr. Referenciranje varijable x preko pokazivača *xptr će time biti završeno, tj. pokazivač *xptr ne pokazuje više na varijablu x !
Cijeli program je moguće komprimirati u zaključak da je moguće je pristupiti bilo kojoj varijabli preko pokazivača na tu varijablu. To je smisao primjene pokazivača na pokazivač.