collection of c++ lessons
Post on 10-Feb-2018
297 Views
Preview:
TRANSCRIPT
-
7/22/2019 Collection of C++ lessons
1/136
ProgramiranjeI_sylabus.doc
Programiranje I:: Vjebehttp://dl.fit.ba/
1
Fakultet informacijskih tehnologija
denis@fit.ba
Datum:03.03.2011
Vjebe 1
Rekurzivne funkcije - rekurzija
Zaista se nadam da ste dovoljno dobro savladali gradivo koje je obraivano u okvirupredmeta Uvod u programiranje jer je ono kljunoza uspjeno praenje tema koje nasoekuju.
Materijal koji trenutno itate ima za cilj da predstavi osnovne koncepte koji se odnose napojam rekurzije. Naime, rekurzija predstavlja sposobnost odreene funkcije da pozivasamu sebe. Znaaj i primjena rekurzivnih funkcija posebno je naglaena u odreenimpodrujima programiranja kao to je Umjetna inteligencija. Pored toga, primjena
rekurzivnih funkcija nije ba rijetka ni u svakodnevnom radu. Pred programere seponekad postavljaju zadaci koji zbog svoje veliine zahtijevaju kompleksna rjeenja.Kompleksni zadaci se u veini sluajeva mogu podijeliti na vie manjih cjelina, te na tajnain postii mnogo efikasnija rjeenja. Ideja rekurzije lei upravo u tome: koristeirekurzivne algoritme podijeliti problem na manje dijelove koje je jednostavnije rijeiti.
Da biste dobili neto jasniju sliku o nainu na koji moete implementirati rekurziju,pogledajte sljedei primjer:
voidimeFunkcije(argument) //definicija funkcije koja ne vraa vrijednost
{
Iskaz1; //iskaz koji e se izvriti pri svakom pozivu funkcije uzlazni tok
if(nekiUslov){ //provjera nekog uslova
argument--; //dekrementiranje vrijednosti
imeFunkcije(argument); //ponovni poziv funkcije -- REKURZIJA
} //kraj if-a
Iskaz2; //iskaz koji e se izvriti kada uslov ne bude ispunjensilazni tok
} //kraj funkcije
Bitno je pomenuti da rekurzivne funkcije posjeduju nekoliko osobina o kojima treba voditi
rauna. Jedna od osobina rekurzivnih funkcija se odnosi na mogunost da nepanjomdobijemo nekontrolisanu ili beskonanu petlju. Najei uzrok beskonane petlje je
nepostojanje ili nepravilno definisanje tzv. baznog sluaja. Koristei bazni sluajmi smou stanju da, u zavisnosti od toga ta elimo postii rekurzijom, u odreenom momentuonemoguimo ponovno pozivanje funkcije tj. prekid rekurzije. Za efikasno funkcionisanje,svaka rekurzivna funkcija zahtijeva postojanje najmanje jednog baznog sluaja.
Poto ste se upoznali sa osnovnim pojmovima rekurzije, vrijeme je da vidimo i njihovupraktinu primjenu.
Zadatak 1.Koristei rekurziju, napisatiprogram koji od korisnika trai da unese broj ijavrijednost mora biti u opsegu od 1 do 10. Unesenu vrijednost predati funkciji, koja treba
da se izvrava onoliko puta kolika je vrijednost predanog argumenta (ako korisnik unese
broj 5, funkcija treba da 5 puta pozove sama sebe). Pri svakom pozivu, funkcija treba daispie trenutnu vrijednost predanog argumenta.
-
7/22/2019 Collection of C++ lessons
2/136
ProgramiranjeI_sylabus.doc
Programiranje I:: Vjebehttp://dl.fit.ba/
2
Fakultet informacijskih tehnologija
denis@fit.ba
#includeusingnamespacestd;
voidrekFunkcija(intbroj) //zaglavlje rekurzivne funkcije{
if(broj>0){ //provjera uslova da li je broj veci od 0cout
-
7/22/2019 Collection of C++ lessons
3/136
ProgramiranjeI_sylabus.doc
Programiranje I:: Vjebehttp://dl.fit.ba/
3
Fakultet informacijskih tehnologija
denis@fit.baUmanjivanje vrijednosti argumenta pri samom pozivu funkcije se ba ne preporuuje, alizbog demonstracije razliitih naina rjeavanja istog problemato smo ipak uradili.
ta bi se desilo da smo kojim sluajem umjesto pre-dekrementiranja (--broj) koristilipost-dekrementiranje (broj--)? Naravno, dobili bismo beskonanu rekurziju. Glavnirazlog tome je injenica da bi se pri svakom narednom pozivu funkcije predavala
identina vrijednost argumenta (vrijednost argumenta se post-dekrementira tek nakonpoziva funkcije).
Za potpuno razumijevanje naina na koji funkcionie rekurzija bitno je znati da seprilikom svakog ponovnog poziva funkcije (rekurzije) izvrava druga verzija (kopija)funkcije, a ne originalna funkcija. Analogno tome, lokalne varijable u drugoj verziji
(kopiji) funkcije su apsolutno nezavisne od lokalnih varijabli originalne funkcije.
U sluaju da vas je malo zbunila prethodna konstatacija, nema potrebe da se brinete. Dabismo pojasnili izneseno koristit emo definiciju prethodne funkcije. Dakle, mainfunkcijaostaje ista kao i u prethodnom primjeru, samo napravite sljedee korekcije u definiciji
funkcije rekFunkcija.
voidrekFunkcija(intbroj){
if(broj>0){cout
-
7/22/2019 Collection of C++ lessons
4/136
ProgramiranjeI_sylabus.doc
Programiranje I:: Vjebehttp://dl.fit.ba/
4
Fakultet informacijskih tehnologija
denis@fit.ba
U nastavku emo dati neto detaljnije objanjenje o nainu izvravanja programa, pakrenimo redom:
1. Unutar main funkcije korisniku je omogueno da unese neki broj. Zbog veliineprethodnog dijagrama pretpostavljamo da je korisnik unio vrijednost 3. Nakon
unosa vrijednosti uslijedio jeprvi pozivfunkcije rekFunkcija. Samim pozivom, na
steku je rezervisan prostor dovoljan za izvrenje nove funkcije1.2. Na samom poetku izvrenja funkcije slijedi provjera vrijednosti primljenog
parametra (u naem sluaju vrijednost je 3), tanije provjerava se da li jevrijednost parametra vea od nule (3>0). Poto je uslov zadovoljen, slijedi ispisvrijednosti (Broj je: 3), te ponovni (drugi) poziv funkcije sa pre-
dekrementiranom vrijednou parametra (nakon dekrementiranja vrijednost je 2).3. Drugi poziv funkcije uzrokuje rezervisanje novog prostora na steku, te poetak
izvrenja funkcije. Poto je vrijednost primljenog parametra (2) vea od nula,
1Pokretanjem programa na steku je rezervisan prostor za izvrenje mainfunkcije
rekFunkcija(3);
main
voidrekFunkcija(intbr){if(br>0){
cout
-
7/22/2019 Collection of C++ lessons
5/136
ProgramiranjeI_sylabus.doc
Programiranje I:: Vjebehttp://dl.fit.ba/
5
Fakultet informacijskih tehnologija
denis@fit.baslijedi njen ispis (Broj je: 2), te ponovni (trei) poziv funkcije sapredekrementiranom vrijednouparametra (vrijednost parametra je sada 1).
4. Nakon rezervisanja prostora za izvrenje nove funkcije slijedi provjera uslova.Poto je uslov ponovo zadovoljen (1>0), funkcija ispisuje poruku (Broj je: 1) teponovo poziva funkciju sa predekrementiranom vrijednou parametra (ovogaputa 0).
5. etvrtimpozivomvrijednost predanog parametra je 0. Poto uslov nije ispunjen(0>0), nee doi do novog poziva funkcije, te funkcija ispisuje drugu porukuBroj_K je: 0.
6. Nakon ispisivanja prethodne poruke (Broj_K je: 0), posljednje pozvana funkcija(funkcija pozvana etvrtim pozivom) se zavrava i oslobaa prostor koji je bioalociran za potrebe njenog izvrenja.
7. Poto je posljednja funkcija zavrila svoj ivotni ciklus, izvrenje programa senastavlja na mjestu odakle je ona pozvana tj. na mjestu odakle je uslijedio etvrtipoziv. Nakon linije koda koja je uzrokovala posljednji poziv slijedi ponovni ispis
vrijednosti parametra. U trenutku poziva vrijednost parametra je bila 0, pa efunkcija ponovo ispisati poruku
Broj_K je: 0. Treba napomenuti injenicu da je
funkcija (iz koje je uslijedio etvrti poziv) primila vrijednost parametra 1, ali jeprilikom poziva funkcije (etvrtog poziva) izvreno njegovo dekrementiranje.Nakon ispisa poruke, funkcija se zavrava i time oslobaa alocirani prostor.
8. Po zavretku funkcije iz koje je uslijedio etvrti poziv, izvrenje programa senastavlja na mjestu treeg poziva. Identino prethodnom scenariju, funkcijaispisuje vrijednost parametra Broj_K je: 1 i time zavrava svoje postojanje.Slijedi oslobaanje alociranog prostora i povratak na mjesto odakle je funkcijapozvana.
9. Prethodna funkcija je pozvana koristei drugi poziv, te se izvrenje programanastavlja neposredno ispod te linije. Funkcija ispisuje poruku Broj_K je: 2nakon
ega slijedi dealokacija memorijskog prostora i povratak u mainfunkciju odakle jeuslijedioprvi pozivfunkcije.
10.Po povratku u main funkciju slijedi ispisivanje poruke MAIN::poslije pozivarekurzivne funkcije! i time program zavrava.
Prethodni primjer oslikava princip funkcionisanja rekurzije, te je njegovo razumijevanje
temelj za uspjeno praenje ostatka materijala. Ukoliko niste shvatili nain izvrenjaprethodnog programa svakako vam preporuujem da nekoliko puta preradite zadatak uzpomo navedenih pojanjenja.Ukoliko elite provjeriti da li ste shvatili prethodni primjer,pokuajte predvidjeti ispis sljedee funkcije:
voidrekFunkcija(intbroj){if(broj>0){
cout
-
7/22/2019 Collection of C++ lessons
6/136
ProgramiranjeI_sylabus.doc
Programiranje I:: Vjebehttp://dl.fit.ba/
6
Fakultet informacijskih tehnologija
denis@fit.bavoidrekFunkcija(intbroj) {
if(broj==0)//bazni slucajreturn;
cout
-
7/22/2019 Collection of C++ lessons
7/136
ProgramiranjeI_sylabus.doc
Programiranje I:: Vjebehttp://dl.fit.ba/
7
Fakultet informacijskih tehnologija
denis@fit.ba
Kada korisnik pritisne tipku enter, komanda cin>>(govorimo o prvom izvrenju funkcijeprikaziUnazad) e iz buffera preuzeti prvi karakter (u naem sluaju slovo F jer se uvarijablu tipa charmoe pohraniti samo jedan znak) i pohraniti ga u varijablu znak.Odmah nakon toga vri se provjera uslova tj. da li je znak(ne)jednak znaku taka (.).Ako je uslov ispunjen (ako znak nije jednak znaku taka) funkcija se poziva ponovo.Prilikom sljedeeg poziva funkcije sadraj input buffera je sljedei (poto je prethodnafunkcija iskoristila slovo F):
Na poetku izvrenja sljedee funkcije, komanda cine preuzeti naredni karakter (slovoI) i pohraniti ga u varijablu znak. Ovdje se namee pitanje: zato komanda cin, prilikom
sljedeeg izvrenja funkcije, nije traila ponovni unos sa tastature? Odgovor naprethodno pitanje lei u injenici da komanda cin nee zahtijevati interakciju sakorisnikom (misli se na unos) sve dok u input bufferu postoji bilo kakav sadraj. Poto jeu naem sluaju sadraj input buffera IT., komanda cin preuzima sljedei znak tj.slovo I.
Izvrenje programa se na taj nain nastavlja sve do momenta dok varijabla znakne budeinicijalizovana vrijednou karaktera taka. U tom momentu, ponovni poziv funkcije jeonemoguen i rekurzija se zavrava. Na osnovu iznesenog, moemo postaviti nekolikopitanja:
1. ta e se desiti u sluaju kada unesete neki tekst bez take i pritisnete tipkuenter?
2. Zato se poruka:Obrnutim redoslijedom ste unijeli sljedece znakove:, koja senalazi unutar else bloka, prikazuje prije teksta (obrnutog redoslijeda) kojeg je
unio korisnik?
Zaista se nadam da ete biti u stanju samostalno odgovoriti na postavljena pitanja.
Za prethodni program je karakteristino da ispisuje samo one znakove koji su uneseni doprvog znaka take. Svi znakovi uneseni poslije znaka take se ignoriu. Takoer,program ignorie sve razmake meu znakovima, to moemorijeiti koritenjem funkcije
cin.get(). Ova funkcija uitava sadraj buffera znak po znak (ak i ako se radi orazmaku) i njihovu vrijednost dodjeljuje nekoj varijabli (u naem sluaju varijabli znak).Kao ilustraciju napravite sljedee izmjene u definiciji funkcije prikaziUnazad:
//..charznak;cin.get(znak);//
-
7/22/2019 Collection of C++ lessons
8/136
ProgramiranjeI_sylabus.doc
Programiranje I:: Vjebehttp://dl.fit.ba/
8
Fakultet informacijskih tehnologija
denis@fit.baZadatak 3. Koristei rekurziju, napisati program koji od korisnika trai da unese nekoslovo. Nakon unosa, program treba da ispie sva slova koja se nalaze izmeu unesenog islova 'A'. Pored oznake slova, program treba da ispie i njima pripadajui ASCII kod.Takoer, potrebno je ispisati odgovarajuu poruku usluaju da korisnik unese znakkojiima ASCIIvrijednost manju od slova 'A' ili program u svom izvrenju ispie sve znakovedo slova 'A'.
Napomena:
Kada se kae manje ili vee slovo, naravno, misli se na vrijednost ASCIIkoda kojije asociran sa odreenimslovom.
ASCIIkod za malo slovo aje 97, a za veliko slovo Aje65.#includeusingnamespacestd;
voidprikaziSlovo(charslovo){
if(slovo>='A')
{ cout
-
7/22/2019 Collection of C++ lessons
9/136
ProgramiranjeI_sylabus.doc
Programiranje I:: Vjebehttp://dl.fit.ba/
9
Fakultet informacijskih tehnologija
denis@fit.baintkraj=0;do{
system("cls");//cisti sadrzaj komandnog prozoracoutpoc;coutkraj;
}while(poc>=kraj);cout
-
7/22/2019 Collection of C++ lessons
10/136
ProgramiranjeI_sylabus.doc
Programiranje I:: Vjebehttp://dl.fit.ba/
10
Fakultet informacijskih tehnologija
denis@fit.baAko niste sigurni u nain izvrenja prethodnog programa, pokuajte samostalnokonstruisati sliku o tome kako se program izvrava na steku. Ukoliko ne uspijete,posluite se sljedeom slikom.
Zbog veliine, prethodni dijagram je kreiran pod pretpostavkom da e korisnik unijetibroj koji je manji od broja 100. Upravo zbog toga, kod koji je prikazan u dijagramu,
manipulie samo brojevima koji su manji od 100. Takoer, u prethodnom programu,parne vrijednosti su uveavane/umanjivane za dva ime se dvostruko smanjio brojrekurzivnih poziva. To smo mogli uiniti prvenstveno zbog injenice da je bazni sluajparan broj. Iznesenu konstataciju moemo dokazati beskonanom petljom koju dobijemosljedeom definicijom funkcije.
intsumParne(intbroj){if(broj==101)//bazni slucaj neparan
return0;if(broj
-
7/22/2019 Collection of C++ lessons
11/136
ProgramiranjeI_sylabus.doc
Programiranje I:: Vjebehttp://dl.fit.ba/
11
Fakultet informacijskih tehnologija
denis@fit.baif(broj%2==0)//ako je paran
returnbroj + sumParne(broj+2);else//ako je neparan
returnsumParne(broj+1);}else{//ako je broj veci od 100
if(broj%2==0)//ako je paranreturnbroj + sumParne(broj-2);
else//ako je neparanreturnsumParne(broj-1);}
}
Pokuajte nacrtati izvrenje funkcije na steku ili poslije baznog sluaja dodajte liniju kodakoja e ispisivati vrijednost parametra broj.
intsumParne(intbroj){if(broj==101)
return0;cout
-
7/22/2019 Collection of C++ lessons
12/136
ProgramiranjeI_sylabus.doc
Programiranje I:: Vjebehttp://dl.fit.ba/
12
Fakultet informacijskih tehnologija
denis@fit.baif(niz[max]%2==0)
returnniz[max] + sumirajParne(niz,max-1);else
returnsumirajParne(niz,max-1);}voidmain(){
constintmax = 5;intniz[max];
for(inti=0;i
-
7/22/2019 Collection of C++ lessons
13/136
ProgramiranjeI_sylabus.doc
Programiranje 1::Vjebehttp://dl.fit.ba/
1
Fakultet informacijskih tehnologija
indira@fit.ba
Datum 09.03.2011.
STATIKINIZOVI
O statikim nizovima, jednodimenzionalnim i dvodimenzionalnim, je ve bilo rijei napredmetu Uvod u programiranje. Na predmetu Programiranje 1 bi ste se samo trebali
podsjetiti ve nauenog.Niz je kontinuirani blok memorijskih lokacija koje se nazivaju jednim imenom i sve mogu
pohraniti podatke istog tipa. Kako bi se jednoznano odredilo o kojoj je memorijskoj
lokaciji rije, odnosno o kojem elementu niza, koriste se indeksi.
Veliina statikog niza mora biti konstantna vrijednost. Prvi element niza ima indeks 0.
Kako vam je gradivo o statikim nizovima ve poznato, u zadacima koji slijede
kombinirat emo ga s novonauenim sadrajem - rekurzivnim funkcijama.
Zadatak
Napiite program koji e omoguiti kreiranje niza od 7 cijelih brojeva, te uz pomo
rekurzivnih funkcija omoguiti unos elemenata, ispis elemenata i izraunati sumu
elemenata niza.
Funkcija main
start
kraj
Unos(niz,velicina)
s=suma(niz,velicina);
Ispis(niz,velicina)
s
velicina=7
s=0
Funkcija unos
PP
PUP
Unos(niz, v-1)
Niz[v]
v==0
Niz[v]
da
ne
-
7/22/2019 Collection of C++ lessons
14/136
ProgramiranjeI_sylabus.doc
Programiranje 1::Vjebehttp://dl.fit.ba/
2
Fakultet informacijskih tehnologija
indira@fit.ba
#include
usingnamespacestd;
voidunos (intn[], intv)
{
if(v==0)
cin>>n[v];
else
{
cin>>n[v];
unos(n,v-1);
}
}
voidispis (intn[], intv)
{
if(v==0)
cout
-
7/22/2019 Collection of C++ lessons
15/136
ProgramiranjeI_sylabus.doc
Programiranje 1::Vjebehttp://dl.fit.ba/
3
Fakultet informacijskih tehnologija
indira@fit.baZadatak
Napiite program koji e omoguiti kreiranje matrice 5x5. Uz pomo rekurzivnih funkcija
pronai najveu vrijednost u svakom od redaka, svakoj od kolona, te sumu elemenata
na glavnoj i sporednoj dijagonali.
Funkcija main
start
kraj
velicina=5
unos(niz,velicina)
ispis(niz,velicina)
i=0, velicina
M=maxreda(niz,velicina-1,i,max)
max=niz[0][i]
M
i=0, velicina
N=maxkolone(niz,velicina-1,i,max)
max=niz[i][0]
N
SG=sumaglavnedijagonale(niz,velicina-1)
SG,SS
SS=sumasporednedijagonale(niz,,0, velicina-1)
da
ne
da
ne
Funkcija maxred
PP
PUP
kmax
MR=maxred(n,k-1,trenutni,max)
MR=max
da
ne
max=n[trenutni][k]
da
MR=maxred(n,k-1,trenutni,max)
ne
Funkcija maxkolona
PP
PUP
rmax
MK=maxkolona(nr-1,trenutni,max)
MK=max
da
ne
max=n[ri][trenutni]
da
MK=maxkolona(n,r-1,trenutni,max)
ne
-
7/22/2019 Collection of C++ lessons
16/136
ProgramiranjeI_sylabus.doc
Programiranje 1::Vjebehttp://dl.fit.ba/
4
Fakultet informacijskih tehnologija
indira@fit.baFunkcija sumaglavnedijagonale
PP
PUP
Suma=n[r][r]
r==0
Suma=n[r][r]+sumaglavnedijagonale (n, r-1)da
ne
Funkcija sumasporednedijagonale
PP
PUP
Suma=n[r][k]
r==4&& k==0
Suma=n[r][k]+sumasporednedijagonale (n, r+1,k-1)
da
ne
r+k==4
da Suma=sumasporednedijagonale (n, r+1,k-1)
-
7/22/2019 Collection of C++ lessons
17/136
ProgramiranjeI_sylabus.doc
Programiranje 1::Vjebehttp://dl.fit.ba/
5
Fakultet informacijskih tehnologija
indira@fit.ba#include
#include
usingnamespacestd;
voidunos (int[][5], int);
voidispis (int[][5], int);
intmaxred(int[][5], int, int, int);
intmaxkolona(int[][5], int, int, int);
intsumaglavnedijagonale (int[][5], int);
intsumasporednedijagonale (int[][5], int, int);
voidmain()
{
constintvelicina=5;
intniz[velicina][velicina], max;
cout
-
7/22/2019 Collection of C++ lessons
18/136
ProgramiranjeI_sylabus.doc
Programiranje 1::Vjebehttp://dl.fit.ba/
6
Fakultet informacijskih tehnologija
indira@fit.baintmaxred(intn[][5], intk, inttrenutni, intmax)
{
if(kmax)
{
max=n[trenutni][k];
returnmaxred(n,k-1,trenutni, max);
}
else
returnmaxred(n, k-1, trenutni,max);
}
intmaxkolona(intn[][5], intr, inttrenutna, intmax)
{
if(rmax)
{
max=n[r][trenutna];returnmaxkolona(n, r-1, trenutna,max);
}
else
returnmaxkolona(n, r-1, trenutna,max);
}
intsumaglavnedijagonale (intn[][5], intr)
{
if(r==0)
returnn[r][r];
else
returnn[r][r] + sumaglavnedijagonale(n, r-1);
}
intsumasporednedijagonale (intn[][5], intr, intk)
{
if((r==4)&&(k==0))
return n[r][k];
if(r+k==4)
return n[r][k]+ sumasporednedijagonale(n, r+1,k-1);
else
returnsumasporednedijagonale(n, r+1,k-1);
}
-
7/22/2019 Collection of C++ lessons
19/136
ProgramiranjeI_sylabus.doc
Programiranje 1::Vjebehttp://dl.fit.ba/
7
Fakultet informacijskih tehnologija
indira@fit.ba
Napomena: Predstavljena rjeenja nisu jedina mogua rekurzivna rjeenja niti
su osobito efikasna - slue samo za uvjebavanje rekurzije.
-
7/22/2019 Collection of C++ lessons
20/136
ProgramiranjeI_sylabus.doc
Programiranje I:: Vjebehttp://dl.fit.ba/
1
Fakultet informacijskih tehnologija
denis@fit.ba
Datum:15.03.2011.
Vjebe 3
Strukture
U ovom materijalu emo detaljnije predstaviti pojam, te nain kreiranja i koritenja
struktura koje nam omoguavaju kreiranje novih - vlastitih tipova podatka. S druge
strane, za strukture kaemo da predstavljaju kolekciju varijabli koje mogu biti razliitog
tipa.
Pod konstatacijom da strukture predstavljaju kolekciju varijabli razliitog tipa,
podrazumijevamo da su strukture pogodne za uvanje vie razliitih informacija o nekom
entitetu npr. informacija o igrau nekog tima: ime, prezime, visina, teina, plata, broj
pogodaka, broj asistencija itd. Na prvi pogled je jasno da pobrojane informacije ne
moemo smjestiti u jedan niz (koji je tipa charili int). Razlog tome je injenica da
nizovi mogu sadravati vie elemenata, ali ti elementi moraju biti istog tipa. Idealan
nain za rjeavanje problema koji zahtijevaju uvanje vee koliine podataka razliitog
tipa predstavlja upravo koritenjestruktura.
Dakle, za strukture moemo rei da predstavljaju korisniki-definisane tipove
podataka. Svima nam je poznato da postoje ugraeni tipovi podataka kao to su: int,
float, doubleitd. Pri deklaraciji varijable nekog od ugraenih tipova prvo navedemo tip
podatka pa onda ime varijable:
//tipPodatka imeVarijable;
int mojaVarijabla;
U prethodnom primjeru smo deklarisali varijablu koja se zove mojaVarijabla, au koju
moemo pohraniti neku cjelobrojnu vrijednost. Slino je isa strukturama, ali ipak postoje
odreene razlike. Razlike najbolje moemo uoiti na nekom primjeru pa emo za poetak
kreirati strukturu ija varijabla (za sada je nazivamo varijabla) moe uvati informacije
o igrau nekog tima.
structigracTima{
charime[30];
charprezime[30];
floatvisina;
floattezina;
floatplata;
intbrojPogodaka;
intbrojAsistencija;
};
Prije svega, vidimo da se pri deklarisanju strukture koristi kljuna rije structnakon
ega slijedi naziv strukture (u ovom sluaju igracTima). Naziv strukture moemo
posmatrati kao novi tip podatka. Takoer, vidimo da se tijelo strukture nalazi unutar
vitiastih zagrada koje zavravaju znakom takazarez(;). Unutar tijela strukture se
nalaze njeni elementi koji se najee nazivaju obiljeja ili atributi. Kao to vidimo iz
-
7/22/2019 Collection of C++ lessons
21/136
ProgramiranjeI_sylabus.doc
Programiranje I:: Vjebehttp://dl.fit.ba/
2
Fakultet informacijskih tehnologija
denis@fit.baprethodnog primjera, struktura igracTima ima sljedea obiljeja (navesti emo samo
neka od njih):
charime[30] niz u koji moemo pohraniti 30 karaktera (ime igraa) floatvisina varijabla u koju emo pohraniti visinu igraa floatplata varijabla koja e uvati podatke o iznosu plate igraa int brojPogodaka - varijabla u koju emo pohraniti broj pogodaka svakog
igraa (bilo da se radi o golovima, koevima....)
U prethodnom primjeru smo vidjeli deklarisanje jedne strukture sa svim njenim
obiljejima. Mogli smo primijetiti da se pri deklaraciji obiljeja koriste ugraeni tipovi
podataka (kao tipovi podataka obiljeja mogu se koristiti i drugi korisniki definisani
tipovi, ali o tome emo govoriti nesto kasnije), te da su deklarisana obiljeja razliitog
tipa. Ovo nismo mogli postii sa nizovima, jer svi lanovi niza moraju biti istog tipa.
Dakle, moemo zakljuiti da nam strukture pomau pri manipulaciji veom koliinompodataka koji su razliitog tipa. Kada kreiramo neku strukturu, tek onda moemo kreirati
varijable koji su tipa te strukture. Varijable koje umjesto ugraenih tipova podataka
(int, float) koriste naziv neke strukture (igracTima), najee nazivamo objektomili
instancomte strukture. Da bi ovo bilo malo jasnije, kreirat emo objekt Igrac1 koji je
tipa prethodno kreirane strukture igracTima:
//nazivStrukture imeObjekta;
igracTima Igrac1;
Vidimo da objekte odreene strukture deklariemo na isti nain na koji deklariemo
varijable sa ugraenim tipovima podataka. Znai, prvo navedemo naziv strukture (tippodatka), pa onda naziv objekta (varijable). U prethodnom dijelu teksta smo kreirali
strukturu koja se naziva igracTima, a nakon toga smo kreirali objekt spomenute
strukture koji se naziva Igrac1. Radi lakeg razumijevanja, moemo rei da smo kreirali
varijabluIgrac1 koja je tipa igracTima. Sve to smo do sada nauili, prikazano je u
sljedeemprimjeru:
#include
usingnamespacestd;
//kreiramo novi tip podatka koji se naziva igracTima
structigracTima{
//obiljeja- atributi sturkture
charime[30];
charprezime[30];
floatvisina;
floattezina;
floatplata;
intbrojPogodaka;
intbrojAsistencija;
};//kompajler ce prijaviti gresku ukoliko izostavite taku-zarez(;)
voidmain(){
//kreiranje objekta tipa igracTima
igracTima Igrac1;
system("pause");
}
Prethodni program ne radi ba nita korisno, ali iz njega moemo vidjeti na koji nain sekreira struktura (igracTima) i objekat (Igrac1) te strukture. Sada se postavlja
pitanje na koji nain inicijalizirati obiljeja strukture, te kako ih koristiti? Za
-
7/22/2019 Collection of C++ lessons
22/136
ProgramiranjeI_sylabus.doc
Programiranje I:: Vjebehttp://dl.fit.ba/
3
Fakultet informacijskih tehnologija
denis@fit.bainicijalizaciju vrijednost obiljeja nekog objekta prvo navodimo ime objekta, zatim znak
taku (.), te ime obiljeja:
//imeObjekta.imeObiljezja = vrijednost;
Igrac1.plata = 670;
Ukoliko smo pravilno deklarisali strukturu i kreirali objekt, pri inicijalizaciji obiljeja
dobijamo malu pomo(barem kada je rije o Visual Studio razvojnom okruenju). Naime,odmah nakon navoenja imena objekta i znaka take, dobijemo listu svih obiljeja koj i se
nalaze u naoj strukturi (to se vidi na sljedeojslici).
Dakle, sva obiljeja naeg objekta smo mogli inicijalizovati na sljedei nain(prikazujemo
samo mainfunkciju):
voidmain(){
//kreiranje objekta tipa igracTima
igracTima Igrac1;
//inicijalizacija obiljezja
strcpy(Igrac1.ime,"Refet");
strcpy(Igrac1.prezime,"Gojak");Igrac1.visina = 1.98;
Igrac1.tezina = 99;
Igrac1.plata = 940;
Igrac1.brojPogodaka = 50;
Igrac1.brojAsistencija = 38;
system("pause");
}
Bitno je napomenuti da obiljeja koja su tipa char (niz karaktera) inicijalizujemo
koristei funkciju strcpy(). Prvi dio naziva funkcijestrse odnosi na string, a drugi dio
cpy predstavlja skraenicu rijei copy. Da smo kojim sluajem pokuali direktno
inicijalizovati obiljeje ime, kompajler bi prijavio greku:
Igrac1.ime = "Refet";
//Error1 error C2440:'=': cannot convert from 'const char [6]' to 'char [30]'
Detaljnije informacije o strcpy() funkciji moi ete pronai u nekom od narednih
materijala koji e detaljnije obraivati podruje manipulisanja nizovima karaktera. Za
sada je dovoljno da znate da pomenuta funkcija prihvata dva argumenta; prvi kojim
definiemo gdje emo neto kopirati (destinaciju) i drugi kojim definiemo ta emo
kopirati (izvor).
// :destinacija: :izvor:
strcpy(Igrac1.ime, "Refet");
Nakon inicijalizacije vrijednosti svih njegovih atributa, objekta Igrac1 moemo
predstaviti sljedeom slikom:
Igrac1ime[30] R e f e tprezime[30] G o j a kvisina 1.98
tezina 99plata 940
brojPogodaka 50brojAsistencija 38
-
7/22/2019 Collection of C++ lessons
23/136
ProgramiranjeI_sylabus.doc
Programiranje I:: Vjebehttp://dl.fit.ba/
4
Fakultet informacijskih tehnologija
denis@fit.ba
Treba pomenuti injenicu da inicijalizaciju obiljeja nekog objektamoemo izvriti na vie
naina, a jedan od njih je da odmah pri deklaraciji objekta, unutar vitiastih zagrada,
navedemo vrijednosti obiljeja.
Nakon inicijalizacije, vrijednosti obiljeja ispisujemo jednostavnim navoenjem imena
objekta, znaka take (.), te imena obiljeja.
//cout
-
7/22/2019 Collection of C++ lessons
24/136
ProgramiranjeI_sylabus.doc
Programiranje I:: Vjebehttp://dl.fit.ba/
5
Fakultet informacijskih tehnologija
denis@fit.bacout
-
7/22/2019 Collection of C++ lessons
25/136
ProgramiranjeI_sylabus.doc
Programiranje I:: Vjebehttp://dl.fit.ba/
6
Fakultet informacijskih tehnologija
denis@fit.baStrukturu igracTima smo mogli deklarisati unutar main funkcije, to apsolutno ne bi
utjecalo na izvrenje naeg programa. Meutim, niti jedna druga funkcija osim mainne bi
mogla koristiti tu strukturu. Znai, kada se struktura deklarie unutar funkcije, ona je
dostupne samo toj funkciji, te je niti jedna druga funkcija ili struktura ne moe koristiti.
U jeziku C++, korisniki definisanim tipovima se moe manipulisati na gotovo identian
nain kao i sa ugraenim tipovima podataka. Zahvaljujui tome, strukture (objekte)moemo kao argumente prosljeivati funkcijama, a funkcije mogu imati povratnu
vrijednost tipa neke strukture. Takoer, koritenjem operatora dodjele (=) vrijednosti
obiljeja jednog objekta moemo dodijeliti drugom objektu. Da biste vidjeli na koji nain
se vri dodjele vrijednosti, na prethodnom programu izvrite sljedee izmjene:
voidmain()
{
//prethodni dio koda ostaje isti
//inicijalizujemo obiljeja samo jednog objekta
igracTima Igrac1={"Emir Sefic",30,120000};
igracTima Igrac2;//={"Amer Gojak",42,142000};
igracTima Igrac3;//={"Sanjin Gerin",25,109500};
Igrac2=Igrac1; //
-
7/22/2019 Collection of C++ lessons
26/136
ProgramiranjeI_sylabus.doc
Programiranje I:: Vjebehttp://dl.fit.ba/
7
Fakultet informacijskih tehnologija
denis@fit.ba//kreiramo dva objekta-instance tipa igracTima
igracTima Igrac1={"Emir Sefic",30,120000};
igracTima Igrac2={"Amer Gojak",42,142000};
//pozivamo funkciju i predajemo kreirane objekte
igracInfo(Igrac1,Igrac2);
system("pause");
}
U prethodnom programu treba da primijetite nain definicije funkcijeigracInfo. Vidimo
da funkcija prima dva parametra koja su tipa igracTima. Nakon toga, funkcija vri
neophodne kalkulacije i ispis vrijednosti obiljejaprimljenih objekata. Takoer, bitno je
da uoite nain pozivanja funkcije tj. samu predaju argumenata(gdje je dovoljno navesti
samo ime objekta). Ovaj program radi isto kao i prethodni, samo to se vei dio
aktivnosti ne obavlja u mainve u funkciji igracInfo.
Na poetku teksta smo pomenuli da obiljeja strukture, pored ugraenih tipova
podataka, mogu biti nekog drugog korisniki-definisanog tipa. To znai da u sluajevima
kada imamo dvije ili vie struktura, obiljeja jedne strukture mogu biti tipa neke druge
strukture. Za potrebe ovog programa kreirat emo jo jednu strukturu koja se naziva
Datum. Nakon toga emo strukturi igracTimadodati novo obiljeje koje je tipa Datum.
Pogledajte sljedei program:
#include
usingnamespacestd;
charcrt[]="\n--------------------------------------------------------------------
\n";
structDatum{
intdan;
intmjesec;
intgodina;
};
structigracTima {
charimePrezime[40];intbrojPogodaka;
doublecijena;
//objekat tipa Datum; obiljezja:dan,mjesec,godina
Datum datumTransfera;
};
voidmain()
{
//kreiramo objekat-instancu tipa igracTima
igracTima Igrac1;
//inicijalizujemo obilljeja objekta
strcpy(Igrac1.imePrezime,"Emir Sefic");
Igrac1.brojPogodaka=30;
Igrac1.cijena=120000;
//primjetite nacin na koji inicijalizujemo obiljeja//objekta datumTransferakoji je tipa Datum
Igrac1.datumTransfera.dan=12;
Igrac1.datumTransfera.mjesec=10;
Igrac1.datumTransfera.godina=2010;
cout
-
7/22/2019 Collection of C++ lessons
27/136
ProgramiranjeI_sylabus.doc
Programiranje I:: Vjebehttp://dl.fit.ba/
8
Fakultet informacijskih tehnologija
denis@fit.baDakle, jedna od novina u ovom programu je u tome to se unutar strukture igracTima
koristi obiljejekoji je tipa Datum.
ObiljejedatumTransferapripada strukturi igracTima, ali je tipa druge strukture te zbog
toga posjeduje sva njihova obiljeja (obiljeja strukture Datum). To moemo vidjeti u
sluajevima kada pokuamo inicijalizovati jedno od obiljeja koje pripada objektu
datumTransfera, npr:
//kompajler e prijaviti greku
Igrac1.datumTransfera = 12;
U prethodnom primjeru kompajler e prijaviti greku iz
razloga to nismo naveli koje obiljeje inicijalizujemo,
poto znamo da struktura Datum (tj. objekt
datumTransfera) ima tri obiljeja: dan, mjesec,
godina. Upravo iz tog razloga, kod obiljeja koja su tipa drugih struktura, odmah nakon
znaka take, prikazuje se lista obiljeja koja su definisana u toj strukturi (to se moe
vidjeti na slici).
U sluajevima kada unutarjednog objekta imamo obiljejakoji su tipa druge strukture,
inicijalizaciju njihovih vrijednosti moemo vriti neposredno pri kreiranju objektanpr:
igracTima Igrac1={"Emir Sefic",30,120000,20,10,2010};
Za kraj emo uraditi jedan primjer u kojem korisniku omoguavamo da inicijalizujevrijednosti obiljeja jednog od objekata.
#include
usingnamespacestd;
charcrt[]="\n--------------------------------------------------------------------
\n";
structDatum{
intdan;
intmjesec;
intgodina;
};
structigracTima {
charimePrezime[40];intbrojPogodaka;
doublecijena;
Datum datumTransfera;
};
voidispis(igracTima Igrac){
cout
-
7/22/2019 Collection of C++ lessons
28/136
ProgramiranjeI_sylabus.doc
Programiranje I:: Vjebehttp://dl.fit.ba/
9
Fakultet informacijskih tehnologija
denis@fit.ba//funkciju cin.getline() koristimo u slucajevima kada korisniku zelimo
//omoguciti da inicijalizuje neki niz karaktera.Upravo zbog toga, prvi
//argument funkcije oznacava destinaciju na koju se pohranjuje uneseni tekst,
//nakon cega slijedi maksimalan broj karaktera koji se mogu prihvatiti
cin.getline(Igrac2.imePrezime,39);
coutIgrac2.brojPogodaka;
coutIgrac2.cijena;coutIgrac2.datumTransfera.dan;
cin>>Igrac2.datumTransfera.mjesec;
cin>>Igrac2.datumTransfera.godina;
//ispisujemo vrijednosti obiljeja za oba objekta
cout
-
7/22/2019 Collection of C++ lessons
29/136
ProgramiranjeI_sylabus.doc
Programiranje I:: Vjebehttp://dl.fit.ba/
1
Fakultet informacijskih tehnologija
denis@fit.ba, irah@fit.ba
Datum: 18.03.2011
Vjebe 3
Dvodimenzionalni statiki nizoviSa jednodimenzionalnim i dvodimenzionalnim statikim nizovima ste se ve imali priliku
upoznati u okviru predmeta Uvod u programiranje. Na predmetu Programiranje 1 biste se
samo trebali podsjetiti ve nauenog te proiriti postojee znanje. Upravo zbog toga, u
zadatku koji slijedi, znanje o dvodimenzionalnim statikim nizovima e biti kombinovano
sa novonauenim sadrajima tj. strukturama i objektima.
Iako se sljedei zadatak moe jednostavnije i efikasnije rijeiti s funkcijama lanicama
strukture, posluit e za demonstraciju injenice da se dvodimenzionalni statiki niz moe
kreirati od podatkovnih objekata bilo kojeg validnog tipa podatka, pa tako i od objekata
tipa strukture.
Zadatak: Napiite program u kojem ete omoguiti unos podataka za 16 studenata
(matrica 4x4). Podaci koje treba unijeti su: broj indeksa, ime, prezime, ocjene za 4
predmeta. Na osnovu unesenih ocjena potrebno je izraunati prosjenu ocjenu svakog
studenta. Nakon unosa, pronaite i ispiite podatke studenta koji ima najveu prosjenu
ocjenu, te omoguite pretragu studenata po broju indeksa. Kreirajte zasebne funkcije za:
unos podataka, ispis podataka, pronalaenje studenta s najveom prosjenom ocjenom i
pretragu po broju indeksa.
Pomo: Matrica objekata tipa student veliine 4 x 4 se moe predstaviti na sljedei nain:
Kolona 0 Kolona 1 Kolona 2 Kolona 3Red 0 Broj indeksa:
Ime:
Prezime:
Ocjena1:
Ocjena2:
Ocjena3:
Ocjena4:
Prosjecna ocjena:
Broj indeksa:
Ime:
Prezime:
Ocjena1:
Ocjena2:
Ocjena3:
Ocjena4:
Prosjecna ocjena:
Broj indeksa:
Ime:
Prezime:
Ocjena1:
Ocjena2:
Ocjena3:
Ocjena4:
Prosjecna ocjena:
Broj indeksa:
Ime:
Prezime:
Ocjena1:
Ocjena2:
Ocjena3:
Ocjena4:
Prosjecna ocjena:Red 1 Broj indeksa:
Ime:
Prezime:
Ocjena1:
Ocjena2:
Ocjena3:
Ocjena4:
Prosjecna ocjena:
Broj indeksa:
Ime:
Prezime:
Ocjena1:
Ocjena2:
Ocjena3:
Ocjena4:
Prosjecna ocjena:
Broj indeksa:
Ime:
Prezime:
Ocjena1:
Ocjena2:
Ocjena3:
Ocjena4:
Prosjecna ocjena:
Broj indeksa:
Ime:
Prezime:
Ocjena1:
Ocjena2:
Ocjena3:
Ocjena4:
Prosjecna ocjena:Red 2 Broj indeksa:
Ime:Prezime:
Ocjena1:
Ocjena2:
Ocjena3:
Ocjena4:
Prosjecna ocjena:
Broj indeksa:
Ime:Prezime:
Ocjena1:
Ocjena2:
Ocjena3:
Ocjena4:
Prosjecna ocjena:
Broj indeksa:
Ime:Prezime:
Ocjena1:
Ocjena2:
Ocjena3:
Ocjena4:
Prosjecna ocjena:
Broj indeksa:
Ime:Prezime:
Ocjena1:
Ocjena2:
Ocjena3:
Ocjena4:
Prosjecna ocjena:Red 3 Broj indeksa:
Ime:
Prezime:
Ocjena1:
Ocjena2:
Ocjena3:
Ocjena4:
Prosjecna ocjena:
Broj indeksa:
Ime:
Prezime:
Ocjena1:
Ocjena2:
Ocjena3:
Ocjena4:
Prosjecna ocjena:
Broj indeksa:
Ime:
Prezime:
Ocjena1:
Ocjena2:
Ocjena3:
Ocjena4:
Prosjecna ocjena:
Broj indeksa:
Ime:
Prezime:
Ocjena1:
Ocjena2:
Ocjena3:
Ocjena4:
Prosjecna ocjena:
-
7/22/2019 Collection of C++ lessons
30/136
ProgramiranjeI_sylabus.doc
Programiranje I:: Vjebehttp://dl.fit.ba/
2
Fakultet informacijskih tehnologija
denis@fit.ba, irah@fit.ba
#include#includeusingnamespacestd;constintvelicina=4;structstudent{
charIme[10];charPrezime[15];intbr_indeksa;intOcjene[velicina];floatprosjek;
};
voidunos(student &);voidispis(student );student PronadjiNajboljeg (student [][velicina]);boolPretragaPoBrojuIndeksa(student [][velicina]);
voidmain(){
student matrica [velicina][velicina];//deklaracija dvodimenzionalnog niza objekata tipa student
student NajveciProsjek; //deklaracija objekta tipa student u koji emo//pohraniti ono to vrati funkcija PronadjiNajboljeg
charodgovor='d';for(inti=0; i
-
7/22/2019 Collection of C++ lessons
31/136
ProgramiranjeI_sylabus.doc
Programiranje I:: Vjebehttp://dl.fit.ba/
3
Fakultet informacijskih tehnologija
denis@fit.ba, irah@fit.ba
cin>>STUDENT.br_indeksa;}while(STUDENT.br_indeksa
-
7/22/2019 Collection of C++ lessons
32/136
ProgramiranjeI_sylabus.doc
Programiranje I:: Vjebehttp://dl.fit.ba/
4
Fakultet informacijskih tehnologija
denis@fit.ba, irah@fit.ba
if(matrica[i][j].br_indeksa==BRI){
indikator=true;ispis (matrica[i][j]);
}returnindikator;
}
Na kraju ovog materijala e biti dat primjer programa koji simulira rad XO igrice. Programski
kod koji slijedi je uraen bez koritenja objekata, te va zadatak ostaje da za vjebu kreirate
strukturu sa nazivom Polje. Pomenuta struktura treba zadravati sva obiljeja potrebna za
efikasno funkcionisanje XO igrice (npr:zauzeto, odigrao_igraci sl...).
#include#includeusingnamespacestd;//mada se radi o istim vrijednostima,a kako bismo izbjegli zabune,//odlucili smo koristiti dvije konstante
constintred = 3;constintkolona = 3;
voidIspis(charXO[][kolona]){cout
-
7/22/2019 Collection of C++ lessons
33/136
ProgramiranjeI_sylabus.doc
Programiranje I:: Vjebehttp://dl.fit.ba/
5
Fakultet informacijskih tehnologija
denis@fit.ba, irah@fit.ba
cout
-
7/22/2019 Collection of C++ lessons
34/136
ProgramiranjeI_sylabus.doc
Programiranje I:: Vjebehttp://dl.fit.ba/
6
Fakultet informacijskih tehnologija
denis@fit.ba, irah@fit.ba
intbrojac=0;for(inti=0;i
-
7/22/2019 Collection of C++ lessons
35/136
ProgramiranjeI_sylabus.doc
Programiranje I:: Vjebehttp://dl.fit.ba/
7
Fakultet informacijskih tehnologija
denis@fit.ba, irah@fit.ba
implementirati funkciju koja e provjeriti da kojim sluajem nije dolo do nerijeenogrezultata.
-
7/22/2019 Collection of C++ lessons
36/136
Fakultet informacijskih tehnologija
indira@fit.ba
Programiranje 1::VjebeCopyright by: FIT
1
Datum: 21.03.2011.
POKAZIVAI
Pokaziva je podatkovni objekt koja uva memorijsku adresu. Pokaziva deklariramo nasljedei nain:
tip * identifikator;
gdje je:
tip- tip podatka na kojeg upuuje pokaziva;
* - operator dereferenciranja. Kada se pokaziva dereferencira, dobije se vrijednost
pohranjena na adresi koja je zapisana u pokazivau.identifikator- bilo koji validan identifikator u C++.
Na primjer:
int *p;
Poeljno je odmah pri deklaraciji inicijalizirati pokaziva ili s NULL ili na adresu nekog
objekta.
ili
Ukoliko je prethodno deklariran pokaziva p vrijednost pokazivaa se inicijalizira na sljedei
nain:
p = &objekt;
gdje je:
pidentifikator (ime) pokazivaa&- operator reference (ampersand) koji vraa adresu objekta
objektobjekt na koji pokaziva upuuje.
int *p = NULL; int*p = 0;
int *p = &objekt;
-
7/22/2019 Collection of C++ lessons
37/136
Fakultet informacijskih tehnologija
indira@fit.ba
Programiranje 1::VjebeCopyright by: FIT
2
Operator adrese&i operator derefenciranja *su inverzni operatorito pokazuje sljedei primjer:
// koritenje & i * operatora
#includeusingnamespacestd;
intmain(){
inta;
int*aPtr; // aPtr je pointer na integer-cjelobrojnu vrijednost
a = 7;aPtr = &a; // aPtr postavljen na adresu varijable a
cout
-
7/22/2019 Collection of C++ lessons
38/136
Fakultet informacijskih tehnologija
indira@fit.ba
Programiranje 1::VjebeCopyright by: FIT
3
Nije dozvoljeno dereferncirati pokaziva koji nigdje ne pokazuje!
Na primjer:
Pokuajte uraditi sljedei zadatak:
Zadatak 1
Napiite program u kojem ete:
a) Deklarirati dvije varijable tipa float (broj1 i broj2).b) Inicijalizirati varijablu broj1 vrijednou 7.3.c) Deklarirati pokaziva na tip podatka float.d) Inicijalizirati pokaziva na adresu varijable broj1.e) Ispisati vrijednost varijable na koju upuuje pokaziva koristei dereferenciranje
pokazivaa.f) Inicijalizirati vrijednost varijable broj2 na istu vrijednost na koju upuuje pokaziva,
te ju ispisati.g) Ispisati adresu varijable broj1.
(Rjeenje zadatka se nalazi na kraju dokumenta.)
POKAZIVAI TIPA VOID
Pokazivai tipa void su posebna vrsta pokazivaa. U C++ rezervirana rije void ukazuje na
odsustvo tipa, tako da moemo rei:
Void pokazivai, su pokazivai koji pokazuju na vrijednost koja nema tipa (odnosno na
vrijednost koja ima neodreena svojstva dereferenciranja i ija duina nije odreena).
Ovo omoguava void pokazivaima da pokazuju na bilo koji tip podatka (cjelobrojni, realni,
karakter ). No, void pokazivai imaju i ogranienje: vrijednosti na koje pokazuju void
pokazivai ne mogu se direktno dereferencirati. Budui da nema vrijednosti koja se
dereferencira, nuno je promijeniti void pokaziva u neki drugitip pokazivaa prije nego ga
dereferenciramo. To se postie upotrebom type-casting operatora kao u sljedeem
primjeru:
voidmain( )
{
float*pointer;
floatx;
*pointer = 3 /* Greska */
x = *pointer;
}
ta nedostaje?
pointer = &x;
-
7/22/2019 Collection of C++ lessons
39/136
Fakultet informacijskih tehnologija
indira@fit.ba
Programiranje 1::VjebeCopyright by: FIT
4
#include
usingnamespacestd;
voidpovecaj(void* podatak, intvelicina)
{switch(velicina)
{
casesizeof(char) : (*((char*)podatak))++; break;
casesizeof(int) : (*((int*)podatak))++; break;
}
}
intmain ()
{
chara = 'x';
intb = 1602;
cout
-
7/22/2019 Collection of C++ lessons
40/136
Fakultet informacijskih tehnologija
indira@fit.ba
Programiranje 1::VjebeCopyright by: FIT
5
o konstantan pokaziva na konstantu vrijednostPrimjer:
constint* constpZ; // konstantan pokazivac na konstantan int
*pZ = 5; // nije dozvoljeno - ne mozete koristiti pZ za modifikaciju int
vrijednosti
pZ = &someOtherIntVar; // nije dozovoljeno - ne mozete usmjeriti pokazivac pZ na nesto drugo
OPERACIJE NAD POKAZIVAIMA
Pokazivai su validni operandi u aritmetikim izrazima, izrazima dodjeljivanja i izrazima
usporedbe. No, na pokazivae je mogue primijeniti ogranien skup aritmetikih operacija.
Pokazivai se mogu:
dekrementirati (++), inkremnetirati (--), zbrajati (+ ili +=) i oduzimati (- ili -=) s
cjelobrojnim vrijednostima, i oduzimati od drugih pokazivaa.
Pretpostavimo da smo deklarirali niz int v[5] i da se prvi element niza nalazi na
memorijskoj lokaciji 3000. Inicijalizirajmo pokaziva P na adresu 3000.
Pokaziva P jemogue inicijalizirati na adresu prvog elementa niza na dva naina:
P=v;// ime niza upuuje na adresu prvog elementa niza
P=&v[0];
U konvencionalnoj aritmetici zbrajanje vrijednosti 3000 + 2 za rezultat ima vrijednost
3002. No, kad su u pitanju pokazivai sljedei izraz:
P+=2;
e imati ovakav rezultat: 3008 (3000 + 2*4), pod pretpostavkom da je za pohranu
cjelobrojnog tipa podatka potrebno 4 bajta (upotrebom operatora sizeof provjerite koliko je
potrebno bajta za pohranu odreenog tipa podatka).
U naem primjeru pokaziva P e upuivati na trei element niza, tj v[2].
lokacija
-
7/22/2019 Collection of C++ lessons
41/136
Fakultet informacijskih tehnologija
indira@fit.ba
Programiranje 1::VjebeCopyright by: FIT
6
Ukoliko pokaziva Pdekrementiramo za 2:
P-=2;
Pokaziva e opet upuivati na memorijsku lokaciju 3000, tj na prvi element niza.
Izrazi poput P++ i ++P, kao i izrazi -P i Pinkrementiraju, tj dekrementiraju vrijednost
pokazivaa na sljedei, odnosno prethodni element niza.
Mogue je vriti i oduzimanje dva pokazivaa. Na primjer, ako P1 sadri lokaciju 3000, a P2
lokaciju 3008, izraz:
X= P2-P1;
e dodijeliti varijabli X broj elemenata niza koji se nalaze izmeu ove dvije lokacije, tj. 2.
Primjena aritmetikih operacija na pokazivaima ima smisla ukoliko je rije onizovima.
Ukoliko nije rije o nizu, ne moemo tvrditi da e dvije varijable istog tipa biti pohranjene umemoriji jedna iza druge.
Kad primjenjujete navedene aritmetike operacije na nizove karaktera rezultat e biti u
skladu s konvencionalnom aritmetikom, jer je za pohranjivanje karaktera u memoriju
potreban jedan bajt.
Zadatak 2
Napiite program u kojem ete:
a) deklarirati niz tipa double koji ima 10 elemenata:double niz [10]={0.0, 1.1, 2.2, 3.3., 4.4, 5.5, 6.6, 7.7, 8.8, 9.9}b) provjeriti koliko prostora u memoriji zauzima tip podatka double i koliko prostora u
memoriji zauzima cijeli niz(upotrijebite operator sizeof)
c) deklarirati pokaziva koji pokazuje na objekt tipa doubled) inicijalizirate pokaziva na adresu prvog elementa niza
(pokuajte ovu inicijalizaciju napraviti na dva naina)
e) ispiite 4 element niza na barem 3 razliita naina(koristite indeksaciju elemenata niza, dereferenciranje pokazivaa i operacije nad pokazivaem)
f) ispiite adrese svih elemenata niza koristei operator inkrementa na pokaziva(vodite rauna da ukoliko dekrementirate pokaziva rezultat je adresa pomaknuta za onoliko bajta
koliko zauzima tip podatka na koji upuuje pokaziva)
g) ispiite elemente niza koristei dereferenciranje pokazivaa.(Rjeenje zadatka se nalazi na kraju dokumenta.)
pokaziva P
lokacija
-
7/22/2019 Collection of C++ lessons
42/136
Fakultet informacijskih tehnologija
indira@fit.ba
Programiranje 1::VjebeCopyright by: FIT
7
UPOTREBA POKAZIVAA
U dosadanjim primjerima dodjeljivali smo adrese varijabli pokazivau i koristili vrijednostina koje pokaziva upuuje koritenjem operatora dereferenciranja. U praksi ete ovako
neto raditi rijetko. Razlog za ovu vrstu manipulacije pokazivaima je demonstracija nainana koji pokazivai funkcioniraju.
Pokazivae ete najee upotrebljavati za:o za upravljanje podacima na slobodnom skladitu (free store) tj. dinamikoj memoriji,o za pristupanje podacima lanovima i funkcijama lanicama struktura io za prosljeivanje parametara funkcijama.
POZIV FUNKCIJE PO REFERENCI KORITENJEM POKAZIVAKIH PARAMETARA
U C++ funkciji moemo proslijediti parametre (argumente) na tri naina: pozivom funkcijepo vrijednosti (call bay value), pozivom funkcije koritenjem referentnih parametara (call
bay reference with refrence arguments) i pozivom funkcije po referenci koritenjem
pokazivakih parametara (call bay reference with pointer arguments). Prva dva naina ve
su vam poznata. Pozabavimo se s pozivom funkcije po referenci koritenjem pokazivakih
parametara. Pri pozivu funkcije s parametrima koje je potrebno modificirati, ne
prosljeujete vrijednosti parametara, ve njihove adrese. Prosljeivanje adrese kao
parametra funkcije se postie upotrebom adresnog operatora (&) prije imena varijable iju
vrijednost elimo modificirati u funkciji, a u zaglavlje funkcije kao parametar se stavlja
pokaziva.
Zadatak 3
Napiite program koji e vrijednost unesenogcijelog broja mijenjati u trostruko veu kub
unesenog broja. Neka funkcija za raunanje kuba ima jedan argument i neka njeno
zaglavlje izgleda ovako:
void cube ( int * );
(Rjeenje zadatka se nalazi na kraju dokumenta.)
Zadatak 4
Napiite program u kojem ete deklarirari niz od 5 cijelobrojnih elemenata te uz pomo:
funkcije: void unos (int *, int); omoguiti unoselemenata niza funkcije: void ispis(int *, int); omoguiti ispis elemenata niza funkcije: int * najveci (int *, int); vratiti adresu najveeg elementa u nizu;
obavezno provjerite je li funkcija vratila korektnu adresu.
(Rjeenje zadatka se nalazi na kraju dokumenta.)
-
7/22/2019 Collection of C++ lessons
43/136
Fakultet informacijskih tehnologija
indira@fit.ba
Programiranje 1::VjebeCopyright by: FIT
8
Rjeenja:
Zadatak 1
#include
usingnamespacestd;
voidmain()
{
floatbroj1, broj2;
broj1=7.3;//inicijalizacija vrijednosti varaijble broj1
float*pokazivac; //deklaracija pokazivaca
pokazivac=&broj1; //inicijalizacija pokazivaca adresom varijable broj1
cout
-
7/22/2019 Collection of C++ lessons
44/136
ProgramiranjeI_sylabus.doc
Programiranje 1::Vjebehttp://dl.fit.ba/
Fakultet informacijskih tehnologija
indira@fit.ba
Zadatak 2
#include
usingnamespacestd;
voidmain()
{
doubleniz[10]={0.0, 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9};
cout
-
7/22/2019 Collection of C++ lessons
45/136
ProgramiranjeI_sylabus.doc
Programiranje 1::Vjebehttp://dl.fit.ba/
Fakultet informacijskih tehnologija
indira@fit.ba
-
7/22/2019 Collection of C++ lessons
46/136
ProgramiranjeI_sylabus.doc
Programiranje 1::Vjebehttp://dl.fit.ba/
11
Fakultet informacijskih tehnologija
indira@fit.ba
Zadatak 3
#include
usingnamespacestd;
voidcube ( int* ); // prototip funkcije
intmain()
{
intbroj = 5;
cout
-
7/22/2019 Collection of C++ lessons
47/136
ProgramiranjeI_sylabus.doc
Programiranje 1::Vjebehttp://dl.fit.ba/
12
Fakultet informacijskih tehnologija
indira@fit.bavoidunos (int* pok, intvel)// buduci da je ime niza adresa provog elementa -
koristimo pokazivac da pohranimo navedenu adresu
{
for(inti =0; i>*(pok+i); //dereferenciramo pokazivac da bi smo mogli unijeti vrijednost na
zeljenu adresu
}
voidispis (int* pok, intvel){
for(inti =0; i
-
7/22/2019 Collection of C++ lessons
48/136
ProgramiranjeI_sylabus.doc
Programiranje I:: Vjebehttp://dl.fit.ba/
1
Fakultet informacijskih tehnologija
denis@fit.ba
Datum: 28.03.2011
Vjebe 5
Funkcije i pokazivaiU prolom materijalu ste se upoznali sa pojmom pokazivaa (pointera) tj. varijabli kojeuvaju memorijsku adresu neke druge varijable. Ukoliko niste itali prethodni materijal,bilo bi dobro da to uinite prije nego to nastavite dalje.
Ovaj materijal ima za cilj da vam malo detaljnije predstavi pokazivae, te nain njihovogkoritenja pri radu sa funkcijama. Za one koji su zaboravili, na samom poetku emo sepodsjetiti naina na koji se argumenti predaju funkciji. U narednom primjeru funkcija imazadatak da uvea(inkrementira), te ispie vrijednosti primljenih parametara.
#includeusingnamespacestd;
voidUvecaj(inta,intb){
//poto se varijable a i b predaju po vrijednostia++; //ovaj inkrement nece utjecati na varijablu 'a' u main-u
b++; //ovaj inkrement nece utjecati na varijablu 'b' u main-u
cout
-
7/22/2019 Collection of C++ lessons
49/136
ProgramiranjeI_sylabus.doc
Programiranje I:: Vjebehttp://dl.fit.ba/
2
Fakultet informacijskih tehnologija
denis@fit.bavarijable), ali nam jo ostaje zadatak da u zaglavlju funkcije naznaimo da se kaoparametri primaju adrese varijabli. Primljene adrese smjetamo u pokaziva, imedobijamo mogunost manipulisanja originalnim vrijednostima varijable.Pogledajmo sadaprimjer koji je identian prethodnom, samo uz koritenje pokazivaa:
#include
usingnamespacestd;
voidUvecaj(int* a,int* b){
(*a)++; //inkrementira vrijednost varijable 'a' u main-u
(*b)++; //inkrementira vrijednost varijable 'b' u main-u
cout
-
7/22/2019 Collection of C++ lessons
50/136
ProgramiranjeI_sylabus.doc
Programiranje I:: Vjebehttp://dl.fit.ba/
3
Fakultet informacijskih tehnologija
denis@fit.bainta = 0;
int& refA = a;
Nakon deklaracije, referenca 'refA' se ponaa apsolutno identino varijabli 'a', te se svemodifikacije reference 'refA' reflektuju na varijablu 'a'. U sljedeem primjeru jasnijemoemo vidjeti primjenu referenci.
#include
usingnamespacestd;
voidmain(){
inta = 15;
int& refA = a;
cout
-
7/22/2019 Collection of C++ lessons
51/136
ProgramiranjeI_sylabus.doc
Programiranje I:: Vjebehttp://dl.fit.ba/
4
Fakultet informacijskih tehnologija
denis@fit.ba
#include
usingnamespacestd;
//funkcija prima parametre po referenci
//i manipulise originalnim vrijednostima
voidUvecaj(int& ref){
cout
-
7/22/2019 Collection of C++ lessons
52/136
ProgramiranjeI_sylabus.doc
Programiranje I:: Vjebehttp://dl.fit.ba/
5
Fakultet informacijskih tehnologija
denis@fit.baU dosadanjim materijalima smo spominjali primjere u kojima pokazivaiuvaju adresenekih drugih varijabli. Meutim, diskusija o pokazivaima ne bi bila potpuna kada nebismo spomenuli pokazivae na funkcije. Kreiranje pokazivaa na funkciju mogue jeostvariti zahvaljujui injenici da funkcije, kao i sve varijable, imaju odgovarajuememorijske adrese.
#includeusingnamespacestd;
intsaberi(inta, intb){
returna + b;
}
voidmain()
{
//obe linije ispisuju adresu funkcije saberi
cout
-
7/22/2019 Collection of C++ lessons
53/136
-
7/22/2019 Collection of C++ lessons
54/136
ProgramiranjeI_sylabus.doc
Programiranje I:: Vjebehttp://dl.fit.ba/
7
Fakultet informacijskih tehnologija
denis@fit.bausingnamespacestd;
intsaberi(inta, intb){
returna + b;
}
voidmain(){
inta = 6, b = 7;
//kreiramo pokaziva na funkciju koja vraa cjelobrojnu vrijednost
//i prima dva cjelobrojna parametraint(* pFunkcija)(int, int) = &saberi;
//mogue je provjeriti da li pokaziva zaista pokazuje na funkciju saberiif(pFunkcija == &saberi)
//pozivamo funkciju koristei pokaziva i ispisujemo povratnu vrijednostcout
-
7/22/2019 Collection of C++ lessons
55/136
-
7/22/2019 Collection of C++ lessons
56/136
ProgramiranjeI_sylabus.doc
Programiranje I:: Vjebehttp://dl.fit.ba/
9
Fakultet informacijskih tehnologija
denis@fit.baDa biste bili sigurni da u potpunosti razumijete nain rada pokazivaa na funkcije,prethodnom primjeru dodajte pokaziva na funkciju centralna, te pomou njegapozovite funkciju.
U nastavku je prikazan jedan malo dui primjer u kojem je objedinjeno sve do sadanaueno gradivo o pokazivaima. Primjer je kreiran sa namjerom da simulira rad
bankomata. Bitno je pomenuti da postoji mnogo efikasnijih naina da se napie ovajprogram, ali za sada je neophodno da shvatite nain koritenja pokazivaana funkcije.
#include
usingnamespacestd;
intprikaziMeni(){
intizbor=0;
do{
cout
-
7/22/2019 Collection of C++ lessons
57/136
-
7/22/2019 Collection of C++ lessons
58/136
ProgramiranjeI_sylabus.doc
Programiranje I:: Vjebehttp://dl.fit.ba/
11
Fakultet informacijskih tehnologija
denis@fit.ba}
Iskreno se nadam da u prethodnom programu nema mnogo nepoznatih stvari? Jedino
bismo mogli pojasniti nain poziva funkcija koje primaju ili vraaju pokazivae. Uzetiemo primjer funkcije isplata, koja se poziva dereferenciranjem pokazivaa pIsplata.
//..voidisplata(float* stanje){
//..
}
voidmain() { float* stanje = &stanje;
//..
(* pIsplata)(&stanje);
//..
}
Funkcije imaju mogunost da vrate pokaziva na neku memorijsku lokaciju. Prototipfunkcije koja vraa pokaziva na neku cjelobrojnu vrijednost moemo napisati na sljedeinain:
int* getPokazivac();
Prije nego to krenemo sa primjerom, bitno je da uoite razliku izmeu deklaracijepokazivaa na odreenu funkciju i deklaracije funkcije koja vraa pokaziva na odreenitip podatka. Dobro razmotrite sljedea dva primjera.
U nastavku emo kreirati program koji korisniku omoguava da inicijalizuje statiki nizod 5 lanova. Nakon toga, koristei funkciju getPokazivac, program omoguavakorisniku da odabere lan niza na koji eli kreirati pokaziva.
#include
usingnamespacestd;
voidunos(int* niz, intmax){
for(inti=0;i
-
7/22/2019 Collection of C++ lessons
59/136
ProgramiranjeI_sylabus.doc
Programiranje I:: Vjebehttp://dl.fit.ba/
12
Fakultet informacijskih tehnologija
denis@fit.baispis(niz,max);
coutindeks;
//korisnika onemoguavamo da unese vrijednost koja nije u opsegu nizaif(indeks0){
//kreira se pokaziva na element niza koji je odabrao korisnikint* pok = &niz[indeks-1];
//funkcija vraa pokaziva
returnpok;}
//ako korisnik unese indeks koji je ve od 5 lii manji (ili jednak)//od 0, funkcija treba da vrati NULL
returnNULL;
}
voidmain ()
{
constintmax = 5;
intniz[max];
unos(niz, max);
//pokaziva pok e biti inicijalizovan adresom koju vrati funkcija//getPokazivac.To moe biti adresa nekog lana niza ili NULLint* pok = getPokazivac(niz,max);
//provjerom da li je pokaziva inicijalizovan na NULL onemoguavamo//greku pri izvrenju programa. Nije mogue dereferencirati pokaziva//koji ne pokazuje nigdje tj. NULL pokazivaif(pok!=NULL){
cout
-
7/22/2019 Collection of C++ lessons
60/136
ProgramiranjeI_sylabus.doc
Programiranje I:: Vjebehttp://dl.fit.ba/
13
Fakultet informacijskih tehnologija
denis@fit.ba//prvi pokazivac u nizu pokazuje na funkciju ProvjeriPrivilegije
nizPokazivacaNaFunkcije[0] = &ProvjeriPrivilegije;
//...
nizPokazivacaNaFunkcije[1] = &ProvjeriPostojanjeViriusa;
nizPokazivacaNaFunkcije[2] = &SacuvajFajl;
for(inti=0;i
-
7/22/2019 Collection of C++ lessons
61/136
ProgramiranjeI_sylabus.doc
Programiranje I:: Vjebehttp://dl.fit.ba/
14
Fakultet informacijskih tehnologija
denis@fit.ba#include
usingnamespacestd;
boolProvjeriPrivilegije(){
cout
-
7/22/2019 Collection of C++ lessons
62/136
ProgramiranjeI_sylabus.doc
Programiranje 1::Vjebehttp://dl.fit.ba/
1
Fakultet informacijskih tehnologija
indira@fit.ba
Datum: 06.04.2011.
DINAMIKI NIZOVI
RUN
TIME ALOKACIJA:OPERACIJE NEW I DELETE
Deklaracija varijable u obliku:
Tip ImeVarijable;
"govori" kompajleru da
1. alocira blok memorije dovoljno velik da pohrani vrijednost specificiranu tipompodatka,
2. povezuje identifikator ImeVarijable s adresom tog bloka u memoriji.
Kao to znate, vrijednost izraza:
&ImeVarijable
je adresa spomenutog bloka u memoriji. Memorijski blok povezan s imenom varijable se
alocira u trenutku kompajliranja programa i ne moe se mijenjati bez editiranja i
rekompajliranja programa.
Slino je i s deklaracijom statikih nizova.
Deklaracija:
constintduzina=10;doubleNiz[duzina];
rezultira alokacijom memorijskog bloka dovoljno velikog da pohrani deset vrijednosti tipa
double i povee ih s imenom niza (Niz). Veliina memorijskog bloka se ne moe
promijeniti bez editiranja i rekompajliranja programa. Moemo zakljuiti, statiki
definirani nizovi imaju sljedee slabosti:
o ukoliko imate manje elemenata od deklarirane veliine niza imate nepotrebnorasipanje memorije;
o ukoliko je veliina niza premala da pohrani sve vrijednosti pojavit e se greka array overflow.
Oba navedena problema bi bilo mogue rijeiti alokacijom memorije za vrijeme
izvravanja programa (tzv. run-timealokacija). Ovakav mehanizam bi morao ukljuivati
sljedee operacije:
1. dodjeljivanje dodatne memorije nekom objektu ako se za tim pokae potreba,2. "oslobaanje" memorije u trenutku kad vie nije potrebna.
C++ nudi dvije predefinirane operacije newi deleteza izvoenje ovih dviju operacija.
-
7/22/2019 Collection of C++ lessons
63/136
ProgramiranjeI_sylabus.doc
Programiranje 1::Vjebehttp://dl.fit.ba/
2
Fakultet informacijskih tehnologija
indira@fit.ba
OPERACIJA NEW
Operacija new upuuje zahtjev operativnom sistemu za jo memorijskog prostora za
vrijeme izvoenja programa. Opa sintaksa izgleda ovako:
newtip;
ovakav izraz rezultira zahtjevom za memorijskim blokom (tokom run-time) dovoljno
velikim da pohrani podatkovni objekt specificiran tipom. Ukoliko je operativni sistem na
zahtjev odgovori pozitivno, new vraa adresu memorijskog bloka, u suprotnom vraa
NULL.
Budui da newvraa adresu, a adresa se moe pohraniti u pokaziva, operacija newse
uvijek izvodi u kombinaciji s pokazivaem.
Npr. ako imamo:
int*Pokazivac;
Pokazivac=newint;
Izvravanje izraza new int e rezultirati zahtjevom operativnom sistemu za
memorijskim blokom dovoljno velikim da pohrani cjelobrojnu vrijednost. Ukoliko je
operativni sistem u mogunosti da odgovori na ovaj zahtjev varijabli Pokazivac e biti
dodijeljena adresa memorijskog bloka. U protivnom, ako nema slobodnih memorijskih
blokova pokazivau e biti dodijeljena vrijednost 0. Stoga je poeljno provjeriti vrijednost
koju vraa operacija new:
assert(Pokazivac!=0);
tj. upotrijebite assert mehanizam koji nudi C++. Ovaj mehanizam omoguava nastavak
izvravanja programa samo u sluaju ukoliko je rezultat navedenog izraza true (istina).
Da bi ste mogli koristiti navedeni mehanizam potrebno je ukljuiti datoteku zaglavlja
(ili ).
Kad smo utvrdili da vrijednost pokazivaa nije 0 (dodijeljena mu je adresa nekog
memorijskog bloka) zapravo smo dobili tzv. anonimnu varijablu, odnosno s
novoalociranom memorijom nije povezano nikakvo ime.
Pokazivac
0x020 0x020
Budui da novoalociranoj memoriji nije dodijeljeno nikakvo ime nije joj mogue pristupiti
direktno. Meutim, adresa tog memorijskog bloka je pohranjena u pokaziva, te
vrijednostima pohranjenim u taj blok moemo pristupati indirektno dereferenciranjem
pokazivaa.
*Pokazivac
Pokazivac
0x020 0x020
-
7/22/2019 Collection of C++ lessons
64/136
-
7/22/2019 Collection of C++ lessons
65/136
ProgramiranjeI_sylabus.doc
Programiranje 1::Vjebehttp://dl.fit.ba/
4
Fakultet informacijskih tehnologija
indira@fit.baPrvom elementu niza moemo pristupiti koristeinotaciju:
Pokazivac_na_niz[0]
drugom elementu:
Pokazivac_na_niz[1]
Pokazivac_na_niz
0x032
[0] [1] [2] [3] [4]
0x032
Vrijednost pokazivaa je adresa prvog elementa niza, a za dani indeks i
Pokazivac_na_niz[i]
jednostavno se pristupa memorijskoj lokaciji Pokazivac_na_niz + i.
Prednost dinamikog alociranja niza lei u injenici da ne morate unaprijed
znati veliinu niza.
Na primjer:
coutbroj_elemenata;
double*Pokazivac=newdouble[broj_elemenata];
for(inti=0; i < broj_elemenata; i++)cin>>Pokazivac [i];
......
Za razliku od statiki alociranih nizova, dinamiki alocirani nizovi ne prouzrokuju
probleme kao to su rasipanje memorije ili prekoraenje opsega niza (overflow).
Efekt upotrebe operacije newje zahtjev operativnom sistemu za:
o uklanjanje memorijskog bloka iz slobodnog skladita (free store ili heap) io alociranje tog bloka programu koji se izvrava.
Memorijskom bloku se moe pristupiti za vrijeme izvravanja programa ukoliko se
spomenuta adresa (dobivene upotrebom operatora new) pohrani u pokaziva. Budui daje veliina nealocirane memorije ograniena, svako izvravanje operacije newrezultira
-
7/22/2019 Collection of C++ lessons
66/136
ProgramiranjeI_sylabus.doc
Programiranje 1::Vjebehttp://dl.fit.ba/
5
Fakultet informacijskih tehnologija
indira@fit.basmanjenjem raspoloive memorije. Stoga se memorijski blokovi koji vie nisu potrebni
mogu "osloboditi" upotrebom operacije delete. "Osloboena" memorija se zatim moe
ponovno dodijeliti pri sljedeem new zahtjevu. Operacije new i delete su
komplementarne operacije.
Opi oblik operacije delete izgleda ovako:
deletePokazivac;
ili
delete[] Pokazivac_na_niz;
Na primjer, ako smo pokaziva ima sljedeu vrijednost:
int*Pokazivac=newint;
iskazom
deletePokazivac;
e te "osloboditi" memorijski blok i omoguiti da bude kasnije ponovno upotrijebljen.
Nakon toga vrijednost pokazivaa e biti nedefinirana, te e dereferenciranje pokazivaa
*Pokazivac
rezultirati nepredvidljivim rezultatima. Da bi se izbjegli ovakvi problemi poeljno je
postaviti vrijednost pokazivaa nanulu.
deletePokazivac;Pokazivac=0;
Slino tome, ako je vrijednost varijable Pokazivac_na_niz adresa prvog elementa
dinamiki kreiranog niza
double*Pokazivac_na_niz= newdouble[n];
memoriju moete "osloboditi" na sljedei nain:
delete[] Pokazivac_na_niz;
Pokazivac_na_niz=0;
Zadatak 1:
Napiite program u kojem ete:
o Omoguiti korisniku da unese vrijednost N (broj lanova niza);o Alocirati niz operacijom new (lanovi niza su tipa double);o Omoguiti inicijalizaciju lanova niza unosom vrijednosti s tastature (koristiti
funkciju);o Izraunati i ispisati prosjenu vrijednost elemenata niza(koristiti funkciju);o Dealocirati memorijski blok upotrijebljen za kreiranje niza.
-
7/22/2019 Collection of C++ lessons
67/136
ProgramiranjeI_sylabus.doc
Programiranje 1::Vjebehttp://dl.fit.ba/
Fakultet informacijskih tehnologija
indira@fit.ba
#include#includeusingnamespacestd;
voidunos (int*, intn);floatprosjek (int*, int);voidispis (int*, int);
voidmain (){intN, suma=0;int*Pokazivac=NULL;
cout
-
7/22/2019 Collection of C++ lessons
68/136
ProgramiranjeI_sylabus.doc
Programiranje 1::Vjebehttp://dl.fit.ba/
Fakultet informacijskih tehnologija
indira@fit.ba
Zadatak 2:
Napiite program u kojem ete:
o Kreirati dinamiki niz od onoliko cjelobrojnih elemenata koliko eli korisnik;o Omoguiti inicijalizaciju lanova niza unosom s tastature;o Utvrditi koliko elemenata niza je manje od 0;o Kreirati novi niz iji e elementi biti elementi prvog niza koji zadovoljavaju prethodni uvjet (manji su od 0);o Koristite funkcije.
#include#includeusingnamespacestd;intunos(int*, int);//funkcija vraca vrijednost jer ce osim unosa elemenata i prebrojati koliko elemenata je manje od 0voidinicijalizacija_niza(int*, int*, int);//funkcija smjesta negativne elemente iz prvog niza u drugivoidispis (int*, int);
voidmain(){
intvelicina1, velicina2;
cout
-
7/22/2019 Collection of C++ lessons
69/136
ProgramiranjeI_sylabus.doc
Programiranje 1::Vjebehttp://dl.fit.ba/
Fakultet informacijskih tehnologija
indira@fit.ba
delete[]Pokazivac1; //obavezno dealocirajte memorijudelete[]Pokazivac2;
Pokazivac1=NULL;Pokazivac2=NULL;
}intunos(int*pok, intvel)//funkciju za unos elemenata prvog niza smo iskoristili da prebrojimo koliko elemenatazadovoljava trazeni uvjet (manji od 0){intbrojac=0;
for(inti=0; i>pok[i];if(pok[i]
-
7/22/2019 Collection of C++ lessons
70/136
ProgramiranjeI_sylabus.doc
Programiranje 1::Vjebehttp://dl.fit.ba/
9
Fakultet informacijskih tehnologija
indira@fit.baNIZ POKAZIVAA
Do sada smo kreirali nizove iji su elementi bili nekog od ugraenih tipova (int, double,
float, char ...) ili nekog tipa kojeg smo sami kreirali (strukture). No mogue je kreirati i
niz pokazivaa. Nizovi pokazivaa e nam biti neophodni za dinamiko kreiranjematrica,
stoga je nuno da se prije dvodimenzionalnih dinamikih nizova na jednostavnom
primjeru upoznamo sa nizovima pokazivaa.
Niz pokazivaa moemo deklarirati na sljedei nain:
int**Pokazivac= newint*[vel];
ovom naredbom smo deklarirali pokaziva koji e pokazivati na dinamiki kreiran niz
pokazivaaveliine vel, a svaki pokaziva u nizue pokazivati na cjelobrojni tip podatka.
Zadatak 3:
Napiite program u kojem ete:
Kreirati statiki niz od pet (5) cjelobrojnih vrijednosti;
Kreirati dinamiki niz od dva pokazivaa;
Inicijaliziratijedan od pokazivaa da pokazuje na najmanji element u statikom
nizu;
Inicijalizirati drugi pokaziva da pokazuje na najvei element u statikom nizu;
Koristite funkcije.
-
7/22/2019 Collection of C++ lessons
71/136
ProgramiranjeI_sylabus.doc
Programiranje 1::Vjebehttp://dl.fit.ba/
Fakultet informacijskih tehnologija
indira@fit.ba
#include#includeusingnamespacestd;
voidunos(int[], int);voidinicijaliziraj_pokazivace(int[], int**, int, int);
intmain(){
constintvelicina =5;intNiz [velicina];//staticki deklarinan niz od 5 cjelobrojnih vrijednosti
int**Pokazivac = newint*[2];//dinamicko kreiranje niza pokazivacacout
-
7/22/2019 Collection of C++ lessons
72/136
ProgramiranjeI_sylabus.doc
Programiranje 1::Vjebehttp://dl.fit.ba/
Fakultet informacijskih tehnologija
indira@fit.ba
niz_pokazivaca[0]=&s_niz[i];//inicijaliziramo pokazivac da pokazuje na najmanji element
}
if(s_niz[i]>najveci)//trazimo najveci element u nizu{
najveci=s_niz[i];niz_pokazivaca[1]=&s_niz[i];//inicijaliziramo pokazivac da pokazuje na najveci element
}}
}
-
7/22/2019 Collection of C++ lessons
73/136
-
7/22/2019 Collection of C++ lessons
74/136
-
7/22/2019 Collection of C++ lessons
75/136
ProgramiranjeI_sylabus.doc
Programiranje 1::Vjebehttp://dl.fit.ba/
14
Fakultet informacijskih tehnologija
indira@fit.ba
Izraz niz[1] vraa vrijednost na adresi "niz" + 1, ekvivalentno je *(niz + 1). Vrijednost
na toj adresi je opet adresa (i to adresa prvog elementa niza u drugoj dimenziji).
Slijedeim izrazom dobijemo adresu treeg elementa (sa indeksom 2):
*(niz+1)+2
Ako treba upisati ili iitati vrijednost sa te adrese moramo dereferencirati pokaziva pa
dobijemo:
*(*(niz+1)+2)
Poto znamo da operator "[]" radi automatski sabiranje i dereferenciranje to
jednostavnije moemo pisati:
niz[1][2]
Kada zavrimo rad sa viedimenzionalnim nizom u dinamikoj memoriji neophodno je
reciklirati memoriju koju je on zauzimao. Potrebno je voditi rauna pri pozivanju
operatora "delete" za viedimenzionalne nizove. Nije dovoljno samo pozvati:
delete []niz;
Prethodni red bi rezultirao "curenjem" memorije, jer bi se reciklirao niz pokazivaa, a tri
niza sa elementima tipa double bi ostali alocirani i nedostupni naem programu, to
ilustrira slijedea slika:
Prije recikliranja niza pokazivaa neophodno je reciklirati nizove sa elementima tipadouble.Slijedei dio koda pravilno reciklira dvodimenzionalni niz u dinamikoj memoriji:
-
7/22/2019 Collection of C++ lessons
76/136
ProgramiranjeI_sylabus.doc
Programiranje 1::Vjebehttp://dl.fit.ba/
15
Fakultet informacijskih tehnologija
indira@fit.bafor(inti = 0; i < redova; i++)delete[] niz[i];delete[] niz;niz = NULL; //nije neophodno ali je pozeljno,
//jer se poslije moze provjeriti//validnost adrese (niz != NULL)
Slijedea ilustracija prikazuje korake pri dealociranju dvodimenzionalnog niza.
Zadatak 4:
Napiite program za zbrajanje dviju matrica (matrice A i matrice B)koji e:
omoguiti unos eljene veliine matrica (broj redova i kolona), omoguiti unos vrijednosti elemenata matrica s tastature, kreirati treu matricu iji e elementi biti suma elemenata matrice A i B , koristite funkcije.
-
7/22/2019 Collection of C++ lessons
77/136
ProgramiranjeI_sylabus.doc
Programiranje 1::Vjebehttp://dl.fit.ba/
Fakultet informacijskih tehnologija
indira@fit.ba
#include#includeusingnamespacestd;
voidunos(double**, int, int);voidispis(double**, int, int);voidIncijalizacija_matrice_C(double**, double**,double**, int, int);intmain(){intredova, kolona;cout > redova;
cout > kolona;
double**A = newdouble*[redova];//alokacija prve matricefor(inti = 0; i < redova; i++)
A[i] = newdouble[kolona];
double**B = newdouble*[redova];//alokacija druge matricefor(inti = 0; i < redova; i++)
B[i] = newdouble[kolona];
double**C = newdouble*[redova];//alokacija druge matricefor(inti = 0; i < redova; i++)
C[i] = newdouble[kolona];
cout
-
7/22/2019 Collection of C++ lessons
78/136
ProgramiranjeI_sylabus.doc
Programiranje 1::Vjebehttp://dl.fit.ba/
Fakultet informacijskih tehnologija
indira@fit.ba
for(inti = 0; i < redova; i++){
delete[] A[i];delete[] B[i];delete[] C[i];
}delete[] A;delete[] B;delete[] C;
A=NULL;B=NULL;
C=NULL;
return0;}
voidunos(double** matrica, intr, intk){for(inti = 0; i < r; i++)
{cout
-
7/22/2019 Collection of C++ lessons
79/136
-
7/22/2019 Collection of C++ lessons
80/136
-
7/22/2019 Collection of C++ lessons
81/136
ProgramiranjeI_sylabus.doc
Programiranje I:: Vjebehttp://dl.fit.ba/
2
Fakultet informacijskih tehnologija
denis@fit.bajednog karaktera. Zahvaljujui funkcijiget()imamo mogunost itanja bilo kojeg unosasa tastature, pa ak i znaka za prelazak u novi red (pritisak na tipku ENTER). Naredna dvaprimjera se ponaaju gotovo identino, osim u sluaju kada umjesto nekog znakapritisnemo tipku ENTER.
//prihvata sve zankove kao i znak za novi red (ENTER - \n)cout
-
7/22/2019 Collection of C++ lessons
82/136
-
7/22/2019 Collection of C++ lessons
83/136
-
7/22/2019 Collection of C++ lessons
84/136
ProgramiranjeI_sylabus.doc
Programiranje I:: Vjebehttp://dl.fit.ba/
5
Fakultet informacijskih tehnologija
denis@fit.baBitno je napomenuti da drugi argument funkcije odreuje maksimalan broj karakterakoje funkcija prihvata. Funkcija getline()je slina funkciji get(), te je nema potrebedetaljno opisivati. Pogledajte primjer:
#includeusingnamespacestd;voidmain(){
charcrt[]="\n--------------------------------\n";constintmax=40;intgodStudija;charfakultet[max];//niz od 40 karakteracharimePrezime[max];//niz od 40 karaktera
cout
-
7/22/2019 Collection of C++ lessons
85/136
-
7/22/2019 Collection of C++ lessons
86/136
ProgramiranjeI_sylabus.doc
Programiranje I:: Vjebehttp://dl.fit.ba/
7
Fakultet informacijskih tehnologija
denis@fit.baPrethodni program provjerava uneseni karakter, te na osnovu toga ispisuje odgovarajueporuke. Unutar funkcije ProvjeriZnak() nalaze se funkcije iz biblioteke cctype koje
provjeravaju vrijednost primljenog parametra.
Kada pokrenete program pokuajte unijeti razliita slova i znakove, te pratite ispis.Takoer, unutar main funkcije stavite komentar na linije koda u kojima se koristi
ignore() funkcija i ponovo pokrenite program. Da li je funkcija ignore() uoptepotrebna u prethodnom programu?
Do sada smo uglavnom govorili o cctypebiblioteci koja sadri funkcije za manipulisanjejednim karakterom. U C++ jeziku postoji biblioteka koja se naziva cstring, a sadrifunkcije za manipulisanje nizovima karaktera.
Funkcija strlen()
Funkcija strlen() nam omoguava da odredimo duinu niza karaktera. Prilikom poziva,funkciji se predaje jedan argument koji je najee niz ili pokaziva na nizkaraktera.Funkcija vraa cjelobrojnu vrijednost koja predstavlja broj karaktera u predatomargumentu tj. nizu. Kao ilustraciju koritenja ove funkcije u nastavku je prikazan primjerkoji od korisnika trai da unese neki tekst. Nakon unosa, program treba da ispiebrojunesenih znakova.
#include#includeusingnamespacestd;voidmain(){
charcrt[]="\n-------------------------------------------\n";charniz[100];cout
-
7/22/2019 Collection of C++ lessons
87/136
-
7/22/2019 Collection of C++ lessons
88/136
-
7/22/2019 Collection of C++ lessons
89/136
-
7/22/2019 Collection of C++ lessons
90/136
ProgramiranjeI_sylabus.doc
Programiranje I:: Vjebehttp://dl.fit.ba/
11
Fakultet informacijskih tehnologija
denis@fit.bavraa pokaziva na prvi karakter traene rijei. U sluaju da traena rije ne postojifunkcija vraa NULL. U nastavku je prikazan program koji korisniku omoguava da uneseodreeni tekst te izvri njegovu pretragu.
#include#includeusingnamespacestd;
intmain(){char* crt="\n------------------------------------------------\n";chartekst[200];charpretraga[20];cout
-
7/22/2019 Collection of C++ lessons
91/136
-
7/22/2019 Collection of C++ lessons
92/136
-
7/22/2019 Collection of C++ lessons
93/136
-
7/22/2019 Collection of C++ lessons
94/136
-
7/22/2019 Collection of C++ lessons
95/136
-
7/22/2019 Collection of C++ lessons
96/136
-
7/22/2019 Collection of C++ lessons
97/136
-
7/22/2019 Collection of C++ lessons
98/136
ProgramiranjeI_sylabus.doc
Programiranje I:: Vjebehttp://dl.fit.ba/
4
Fakultet informacijskih tehnologija
denis@fit.ba#include#includeusingnamespacestd;voidmain() {
//kreiramo objekat tipa ifstreamkoji se naziva ispisifstream ispis;ispis.open("mojFajl.txt");//ako fajl iz bilo kojih razloga nije mogue otvoriti
//vrijednost objekta e bitiNULLif(ispis==NULL)cout
-
7/22/2019 Collection of C++ lessons
99/136
-
7/22/2019 Collection of C++ lessons
100/136
-
7/22/2019 Collection of C++ lessons
101/136
-
7/22/2019 Collection of C++ lessons
102/136
ProgramiranjeI_sylabus.doc
Programiranje I:: Vjebehttp://dl.fit.ba/
8
Fakultet informacijskih tehnologija
denis@fit.baBitno je znati da su neki od pomenutih modova podrazumijevani tj. defaultni. Za
ofstreamobjekte defaultni mod je iso::out, dok je za ifstreamobjekte defaultni mod
ios::in.
ofstream upis;//zato to ofstream objekti imaju defaultni mod ios::out//naredne dvije linije imaju isto znaenje
upis.open(nazivFajla);upis.open(nazivFajla, ios::out);
Prilikom otvaranja fajla moemo koristiti vie modova koje moramo razdvojiti koristei
znak pipe (|). Pogledajte sljedei primjer:
//izmedju modova koristimo znak pipe (|)upis.open(nazivFajla, ios::out | ios::app);
Pored navedenih, postoji i fstreamklasa iji objekti imaju dva defaultna moda: ios::ini
ios::out. Na osnovu toga moemo zakljuiti da se pomenuti objekt i mogu koristiti za
upisivanje i za itanje sadraja fajla. Pokuajte jedan od prethodnih primjera napraviti
koristeiobjekat tipa fstream.
Kretanje kroz sadraj fajla nam omoguava ulazni (pri upisu sadraja) i izlazni(pri ispisu
sadraja) pokaziva. Kada otvorimo fajl, pokaziva se nalazi na samom poetku fajla
na prvom karakteru (ukoliko drugaije ne zahtijevamo). Upravo zbog toga mi smo u
mogunosti da itamo sadraj fajla od poetka do kraja. U tabeli modova smo naveli da
mod ios::ateomoguava pomijeranje pokazivaa na kraj fajla. Upravo to predstavlja
glavni razlog zato naredni primjer nee prikazati sadraj fajla.
#include#include
usingnamespacestd;voidmain(){char* nazivFajla = "mojFajl.txt";
ofstream upis(nazivFajla);if(upis.fail())
cout
-
7/22/2019 Collection of C++ lessons
103/136
-
7/22/2019 Collection of C++ lessons
104/136
-
7/22/2019 Collection of C++ lessons
105/136
ProgramiranjeI_sylabus.doc
Programiranje I:: Vjebehttp://dl.fit.ba/
11
Fakultet informacijskih tehnologija
denis@fit.bacout
-
7/22/2019 Collection of C++ lessons
106/136
ProgramiranjeI_sylabus.doc
Programiranje I:: Vjebehttp://dl.fit.ba/
12
Fakultet informacijskih tehnologija
denis@fit.bacin.getline(nazivFajla,max);
//otvaramo fajl za upis u binarnom formatu - ios::binary modofstream objekatUnos(nazivFajla,ios::out | ios::binary);cout
-
7/22/2019 Collection of C++ lessons
107/136
ProgramiranjeI_sylabus.doc
Programiranje I:: Vjebehttp://dl.fit.ba/
13
Fakultet informacijskih tehnologija
denis@fit.bausingnamespacestd;
char* crt="\n==========================================================\n";char* poruka_o_gresci = "Greska prilikom otvaranja fajla!";
voidUnosSadrzaja(constchar* nazivFajla){cout
-
7/22/2019 Collection of C++ lessons
108/136
-
7/22/2019 Collection of C++ lessons
109/136
-
7/22/2019 Collection of C++ lessons
110/136
-
7/22/2019 Collection of C++ lessons
111/136
ProgramiranjeI_sylabus.doc
Programiranje I:: Vjebehttp://dl.fit.ba/
2
Fakultet informacijskih tehnologija
denis@fit.ba};voidmain(){
Struktura s;Unija u;cout
-
7/22/2019 Collection of C++ lessons
112/136
-
7/22/2019 Collection of C++ lessons
113/136
ProgramiranjeI_sylabus.doc
Programiranje I:: Vjebehttp://dl.fit.ba/
4
Fakultet informacijskih tehnologija
denis@fit.baenumGodinaStudija{prva=1,druga,treca,cetvrta};enumOdgovori{TACNO,NETACNO};
constintbrojPitanja = 5;
structStudent{int_brojIndeksa;char_imePrezime[30];
bool_radioTest;NacinStudiranja _nacin;GodinaStudija _godina;Odgovori _odgovori[brojPitanja];
};
voidPrikaziPitanje(intrbPitanja){if(rbPitanja==1)
cout
-
7/22/2019 Collection of C++ lessons
114/136
ProgramiranjeI_sylabus.doc
Programiranje I:: Vjebehttp://dl.fit.ba/
5
Fakultet informacijskih tehnologija
denis@fit.bacin.getline(niz[i]._imePrezime,30);coutniz[i]._brojIndeksa;coutunos;niz[i]._nacin = (NacinStudiranja)--unos;coutunos;
niz[i]._godina = (GodinaStudija)--unos;cin.ignore();niz[i]._radioTest = false;//tek smo kreirali studenta//tako da je sigurno da test nije radjen
}}
voidPretraga(Student * niz, intmax){//definisati funkciju(e) koja(e) ce omoguciti pretragu po://1. godini studija//2. nacinu studiranja//3. rezultatima ostvarenim na testu//Nove funkcionalnosti dodati u funkciju PrikaziMeni
}intPrikaziMeni(){
intizbor;do{
cout
-
7/22/2019 Collection of C++ lessons
115/136
ProgramiranjeI_sylabus.doc
Programiranje I:: Vjebehttp://dl.fit.ba/
6
Fakultet informacijskih tehnologija
denis@fit.ba//3.uvesti username/password na osnovu koga ce se studenti logirati//4.odvojiti administratorske funkcije (meni) od korisnickih
voidmain(){intmax, izbor, student;coutmax;cin.ignore();
Student * niz = newStudent[max];UnosPodataka(niz,max);system("cls");
do{izbor=PrikaziMeni();if(izbor==3)
break;
student=PrikaziStudente(niz, max, izbor);//pokusajte pojednostaviti naredni dio koda, te smanjiti broj nepotrebnih provjera
if(student!=-1){if(izbor==1){
if(niz[student]._radioTest == false)PokreniTest(niz[student]);
elsecout
-
7/22/2019 Collection of C++ lessons
116/136
-
7/22/2019 Collection of C++ lessons
117/136
-
7/22/2019 Collection of C++ lessons
118/136
ProgramiranjeI_sylabus.doc
Programiranje I:: Vjebehttp://dl.fit.ba/
3
Fakultet informacijskih tehnologija
denis@fit.bacout
-
7/22/2019 Collection of C++ lessons
119/136
ProgramiranjeI_sylabus.doc
Programiranje I:: Vjebehttp://dl.fit.ba/
4
Fakultet informacijskih tehnologija
denis@fit.bacoutsnagaMotora;
system("cls");cout
-
7/22/2019 Collection of C++ lessons
120/136
-
7/22/2019 Collection of C++ lessons
121/136
-
7/22/2019 Collection of C++ lessons
122/136
-
7/22/2019 Collection of C++ lessons
123/136
-
7/22/2019 Collection of C++ lessons
124/136
-
7/
top related