You are on page 1of 218

..

, r~,:-_; . ,. ~- il~--
l -~
6. ( ~
. ·• . -~-
:,: .:_

. . ·.:
' ' . , ··~::_>·-= .. ·. . ..
;_,.·
.. .·. ~--. .-:, ·• .. :·
. J
..
···{ - ~-

n
·n - ~ .. ·. ·'". .. .: ..
. ' ..
..
1 ....., ·.
[ i' .
.. ,·

l ;

.t;- .. Ii
se·
t ... _·_ ~.·. ~~n,iQ- s:iil<.jt ~.,ryi.g.·a.:fil~o.ada[i~
: · · . · . ~
· ~--- --:--
. . fakio/iiiil mozem ;i~9W ~p·.~n j#).~sJl!taVilinom~o Re~ju. .
·;-··.R. . . '..·•
na
fT.
U ... ..•:··.·.· ·...o mo...en ..; a.l·i. i. ki>lppli\<:ovane PJ"Qgram.ecl.ke
l. I' .. . . ·. ·. o .iskaza
. tfliU
. iidecor..i:i formlilom: .
priliijeru. Poznato je da
. ··
tehnike;
inatell11rti~kU flirikciju .·
. . .· ·
. ) . ·
n!= 1· 2 ·.3 · ... · n
u
n - l
-~--
Na osnovu ove formule sasvim
argwnenta, koristeCi fo r pet
lju. Medutim, n! se mo re defini
'··

lllko je .napisati funkciju ujeziku


·C++ koja racuna faktorijel $Vag
rati ina drugaciji naeip, preko
,..... formille ,
iU. ~ . -1 )! za. n~ . O
~
{n
n! ·- . ·(n
; . -1 · za n=O
Q . Ov a formula definira funkci
defin!cii.§. PokaZimo, na p~je
ju faktorijel preko same sebe,
i predstavlja tipican prinijer rekurz
ru, kak.o teee postupak ivne
· formule: izraCUllllYanja faktorijela bro
Q ··
ja 4 pomo6U ove

4! =. 4 · 3! = 4 · (3 · 2!) = 4
n = ..
{3 . [2 •4: · [3 · (2 · I!)] = 4 · {3 · [2 ·(I
o . on
= 4 . £3 . (2 . 1)] = 4 . (3
· 0!)]} = .
. 2) = 4 . 6 = 24
U · lJkolikol1ismo ovu {ormull)neposredno prevel
i u C++, dobijmlio rekunivilu verziju
-_,_._·. ___ r__ac.unl!llje faktorijeJa: : · C++ funkcije za
.
_ · ~ong iri t f_~ktorij el
- - (.i. nt n) (
· .i.f (n ~ 0) re tu = .f;u
·, .i._l
J
[
al. se z-
} etu = n * fak t: (n ,- l);

u Upbtrei:JOm uvj~tnog temarn


,· ' . og operatora
.

~ong .i.n·t fa: kto rij el (.i.


· re tu rp (h. ==.. OJ .?
.

nt ~J {
ri., * fa kt (n - 1) ; f:
. .· "? : "funkcija :fak:torijel se mo re zapisati jo~ kompak

'
tnije:
.

Il· ) . . . ·, . .

Na sljede6oj slici pri kaz anj e


s!(ematski.tok izraeunavanj~ ove
. ~-· . . .

pratiti fu se zapravo d~va funkcije za n= 4, na kojem se


Q\ faktorijel~4)
prilikom ~vanja ov~ funkC
ije.
iijepo moite

. of;
[i,. 4* fa kt or ije l(3 )
.t6 .
]ro . . 3* fak tor ije l.( 2) ·
t .
2.
2* f.a kto rij el (1.)

]!J.':\o.-- t.. ..
· "l* fa kt or ije l(O )
\ .
-,_·
t.1 . . -:.
....
] . .

c~ ·.
~.~.·\;~·:.·
I ..

..
. "~, .
... ·:_.-.:, j
·,
I'

1
i
void bin(int n) {
int cifre[32], i = 0;
whUEi(n != 0) { r
r
cifre[i++] = n·% 2;
n /= 2;
}
while(--i >=.0) cout << cifre[i];

I
}
·. ' .' . IJ
NiZ cifre dimenzioniran je na 32 elementa uz r ostavku da fl:'areni binarni bro· neee imati viSe
f ·od 32 biniune cifre (§to je sv o ISpunjeno uz pretpostavku da tip ints zanzjroa ne viSe od 32 itlfl
Medutim, sljedeea rekurzivna realizacija isle /unkcije za•novana na istoi ideji ne samo da
nevjerovatno kratka, nego uopee ne koristi nikakav niZ:·
LJ
.
void bin(int n) {
i i:f(n > 1) bin(n I 2 l; £]
cout << n % 2;
r '
Na prvi pogled, nije lako ustanoviti §ta se zaista de§ava kada se pozove ova funkcija. Stvari postaju
jas~je ~on sto se razmotti · sljedeei dijagram, koji ilustJ:inl tok izvclavanja ove funkcije prilik1J
u
pOZ!Va b~n (19): · ·

n=19: n=9: n-2: ..


n~.,.

!:>in (19) ~~bin (9) ~~bin ( 4) ~~bin (2) ~~bin (1) ~·-- iapi§i 1
ispW 1 · ispiSi 1 ispisi o · ispiSi o
0
Moglo bi se u~initi da je prikazano rekurzivno lje§enje znatno efikaSnije od prethodnf J
nereiwrzivnog lje8enja, s obzirom da ne zahtijeva upotrebu niza za smj~e medurezultata. Med~
ovo je samo iluzija. Da bismo rasviie1tili misteriomi nestanak ootnibe za oomoenim nizom i shvatili ~ .
se zaistll de5ava, moramo se oodsietiti da se Iokelne oromienliive svake funkoije stvaraju svaki put kli
-~e funkcija nozove, i uniJtavajlt po zavriletKu fimkcije lstO vrijedi i za formalne oarametre funkciie. 11:
su oni zapravo vrsta. lokalnih proriljenljivih. U ovom primjeru, poziv funkcije bin ( 19) stvai-a u
memQriji niJV1J prQil\ienljivu li i inicijalizLraje na vrijcxi!IQ~ 19, NakQn tQgl!, kakQ je 19 vet:e l,!J·
w
se ponovni poziv funkcije bin sa stva'rnimparametrom n/2 koji iZnosi 9. Ovaj novi poziv funkcije -._
stvara novi prim;erak (instancu) promjenljive n koja l;e inicijalizira na vrijednost 9. Medutim, pret!wdna
promjenljiva n (cijaje vrijednost 19) ·e i dare risutna u mEltnoriji! Nairne, ona se uniStava tek -
I
i -,~
2 .
:JJ ' }
n·\

twi;i•~ iz s<elie"sarnr& P<iVUitllk ce se


. . ·.· . . .
.. . . n je sad
·.
.. . ·..
oblivlilaniia. ove naredbe, do a ona koja sadrZi vrijednost 2, . ins ~~
tekuCa instanca promjen!jiv
lazi do. novog povratka iz
fun
.
kcije u samu sebe, pr i &lnu
tan ca . Na kon
e D; a nova tekufu instanea se ponovo liDiStava
nastavlja na naein koji je postaje 011a cija je vrijedno
slikovito prikazan na pretho st
do lat i do lliiistavanja svih dnoj shemi. Te k na ko up eto 4, Proces SC taka
stvorenih instanci promjen g zavcletka funkoije
funkcija bi n zai sta hila prv ljive n i do povmtka iz fun
i ptrt pozvana (npr. u glavn kcije na mjesto odakle je
i progtam).
opisl\fii m~niU\iZi® 41~1\!i<i <l.<
ist!! kotilpu~ll'®i!. M()4f
vilnu primjenu rekmzije, veo 1tlill. kills9 J() ~u~y@j~ <lvog fut<'fl@iilii~
od kljuene vamosti za pra
budete sigurni da ste u potpu !D
nosti shvatili opisani mehan ll je bitno d<! ne citate t!lllJl tekst: prije nego ~
nioze biti slikoviti prikaz iZam. Za njegovo razja8qji
sa prethodile sheme. Radi mje od ve!lke pomoci
mo tet e shv11titi i da svaka lak:Seg IISVajanja mehaniz
funk~ija Gi'e 'e izvrSavan ina rekilrzivnih pqziva,
poZivom se 6 same nasta · e prekinute bilo po wo m
vlja da zivi" _sve do k ne neke _diugc ti•Dteije hil a
Ukoliko je fUDkclja pozvala · e do njenog regulamo
samu sebe, stvara se njena g zavcletka; Pr i tomei
i ooka da bude nastavljena. "nova instanca", dok "stara
instanca" i dalje "Zivi"
Tako, u nekom trenutku
jimkcije, pri oomu je sam mo
o jedna "aktivoa", dok su ost .ze da bude "Zivo" i po ne!roljko iostanoi iste
prethodnom primjeru do isp ale "uspavane" i ookaju svo
isa prve cifre dolll2!i tek na j red fuimiietimo da u
bi n, a da se zatim sv ak a kon sto se stvore sve neop
nar&lila cifra: ispiStlj(i tek na: hodne instance funkeije
kaii: uniStaVanja prethodiie ins
tance-.
K<iriC ~. U~t <ttWUI#ik¢/Jtt iri 1£ $
.,.,. ·"'u' «A ---ve_, u. m"......"' oro 9\U i!i\ 'i
'""''!!-~"'" K6!'16....~'-
'' . "'
, 1- a~ ·ii. :r fH:'rlliiii. eel "' -~ :lv~ ~ti.t l®.!i!
~)
-'"w
e o ...'""'
..ie·&11
'-<><..;;., ""' e if" . 'e~
"':
koje sadrZi sve lokalne pro a a' -''·· J«
~:.,;; .._, ..i' ·;;
'--'otilme odakle je funkcija mjen ljive i formalne pa ram we pos.m <,_!J .. ~--
~v
[-"·it
atrane funkcije, kilo 1 orm t::.rm
,.,,u
·u · ,.,.J....
1]; \...;
povratna adresa (engl. ret
pozvana, tj. gdje treba da
urn address). Okvir fimkc
zavrSetkai Svaki prtikid izvrSavanja
.se vrati nakon zavr5etka. Ova
ije ukJaiYa se iz memorije
il¢iju
infonnaclja naziva se
:funkdje ostavlja njen ok tek n.akon 1\ienog
funkci'e u memoriji :makje vir i dhlje u memoriji. Pri
o-..
'
Fri tome, izvrSavanJe
instance sebe same), ali nje
bude nastavljena. Tako,po
da je funkcija."Ziva" g, da
1
eye mo.ze tti prekinuto izv
n okviF jo§ postoji u memo
·e n·eno izvrSavan'e
r§avanjem neke druge fun
riji i bice iskoriSten onda
su8tva okvint
o a ·· "o§ zavr5eno •• -
koije (pa Cak i druge
stojanje vi~e "instanci" ist ka da funkcija ponovo ,
pEun~eraJiia: oii:Vira te fun e funkcije u memociji zapn
Q;- mo'Ze biti "aktivna" d&k su
k-eije U memcrnJI (lj. VISe iriS
tancJ o/iVzra). Prl tome: jednS
~vo znaei postojanje vis
e
' . sve ostale "na C<iklltiju". : i samaj.ed!ill WtafiCI!

l' l .
~~~~rekurzi~~'vnogpozivanjafunkcijebin
· pu t kori§tena isla promj nove
lr <'!'
bi n promjenljiva n . popri
vrijednollti (koje su zauvij
enljiva n, Ocigledno bi u
mila vrijednost 1, bez ika
ek izgubljene}. Stoga bi sv
tom slueaju nakon petog rek
kve mogu6nosti povratka
lirzivn og
n, ve ed aje sv ak i
pozivll funkcije
na njene pretb.odne
nakon 8vakog povrataka iz e naredbe oblika co ut «
t. "i ··is...ano p_
v. isP. ~et...
J'edin ica \
-- .. ') .
funkcije koristile tu vrijed
iibst promjen!Jive n, i ispis
n % 2 kqje ce se izvrSiti
ne bi bio ispravan (bilo

t\ 3
(
r·-~
L
'
i
i
t_.. .•{
[
1 ![
\.J.

.~r
I ~.
'
''...J' ' .

1[ -..1 .

prab~~IJ~/ff~~~~ih~~e=~~;m. I1..e.lrur.lij~ e,~)~~~b~.~v~~! O[


briijcva. aj, 221 u; a, (pri ~llili Se n takodtr prethodno i iiraeunati
vrijednost venmog razlomka
1
ispisati
O[
a,+-~-..,-1-

a~+----;1-
-~.+-
O[
.: '

a,;

Kako se rncllllanje verifnog razlomka Pbavlja od PosU!l®jeg Ulli:s~Pg brojeve ka prvoi)l, izgleda ®
j[
je jedmp rjellenje ui!ifl,lti 8Ve brojeve u niz, a:~ •irazmo.titti~ raz1'§ak kOrisi:Cei Vrijednosti sll\ielltene u

-·,~~r
niil paeev Gdp<islj¢njeg eleiriema ka prv<irti; MedUtiiiij sljedeee rj~enje ukajeiil se koriSti: mbit:iivna
f'unkdja verizni uo~ ne k<iristi inz.um.)~o fuga, brojsvi' uneSeni tastature 89 pamte u razliCitim : '
instfmcoitia iok8Ine promjmiljive a (k;9je su sadFzane u fliZiiiSitim Uistimoama okvim fuukoii!:)l
,: .
I ' •
-{[
#include <iostrealll)o.
-ing ~l'lli!.~" stdi
'
u ;
46~1~ if~fHIH. Cifa~ Ill 1
iut a; 'D[
cin·. >> a;
== 1) -~ a;

j
.i:f(n
eiti<(i itEiturtt a. + .1 I verizni (n ~ 1); ][
j,l\tJ 1\\i!!!!. () {
i6£ ni
cout << "Koliko zelite unijeti brojeva? ";
ein >> n;
J~
oout <i< "Uneaite ih .. -: .\n" 1
doubia rezuitat ~ verizni(n);
cout << wvrijednost veriznog razlomka je w << rezultat;
JD
IJD
sv g rekurzivnog poziva, mada nam qjihovo stvaranje nije potrebno, s obzirom da se vrijednost n
nigdje ne k"Oristi nakon JXlZI'I& funkcije, Naful~ stVarailje ovih instanci se ne mofe i2bjeei; <lime se
trepotrebng tio.§e memorijski resursL Ovu osebinu treba shvatiti kao ~lateralnt! §tetu" rekurzivnih
rjdcnja. Kasnije 6e usyeditl n~ detaljnifa diskusija eflkasnostl rekurzivnih rjeknja. ·
JD
"* Cesto je prilikom realizacije rekurzivnih Ijellenja potrebno ostvariti komunikaciju izmedu razlicitih rD
~

instlmci iste fimkcije. !ako svaka od instanci ima pristup samo onim instancamillokalnih prom)erujivih
KOJe 1e saroa styoti!i jedini naCin za ostvarivanje ove kmjmnikacij¢ je 'plltem preno8a parametara u
novostvorenu instancu .(dodu§e, komunikacija se more ostvariti i posredstvom globalnih ili statii!kih
- -1
....._
ptollijeilljivih, ali takVa rje~enjii rrisu preporo~ijiva osim u poseliiiiiii situacijliiila). Pretpostaviiilo, na

4 r~
r~
.i-.~;~:
~u
n
D :. !

~~
-....• J

''"'
o'·-·r
nc
Or '\.- ,<

oc
i
doUhl~ ve ri zn i( in t n,
in t br oj ac = 1)

Oc iP,l5 ... ;
cQJJ,1; <;< "Qne~li
ci n :J<> a;
if (n ,;;,;;; i) r< rt
t"' "
« R!;Qji!,<;: « • R<
{

;<;?j; ";
ur n i!i ;.
Pc al .a e !!eo~ a
+ 1 I veri~ni (n
1, br oj ao + 1) .}

tr
i
f
"""'...
. U ov om pr.imjeru,
~. odjedlliice. O
- j«+~ "~~''" ·iJui!iiifd
~~ ~'ll!'~ ~ !!H
V
fotmalni parmnetal'
irn je blil~!W~o da
«•.tffi ~"dlii .. ~tii :
hrroja~ ima poc;!raz
se ftilik(?ija veri:z:ni
d.~ ·.-. s ;~.;,;;:, ~i<l>i
I"! " •001-· i!~\!t't'>:l
umijevimu vl'ijednost
i daljli po.tivi it glavn
1, jet ' brojao m is
ta i
tll !\ __ , "'"""~ •\\m"'" <;~i<tiiJ "'"'tr"U
rrt pfuilj~ju¢i ka
nov_~ irts~ca prom
o stv!U'IIi par;un~
fustanei ov e promjenljiv
jenljive & io ja c p08t
vrij~o.st f<irm!im

e takoder "koiaterai
.,., \!>!"~ +lil!m'< "'" tr'
og PlU'II01¢U'a br oj..1\ttHY.IIl _e MW,, ~)f~
aj4 Zajedlm voolt od
pr eth
ac UV eC
oencii Primijcitirno
M
:tig program:a na
<~ Ax· ··v'·~~ -- -"'ti --·~-·
...~v• ·'u--t
~'
u z:a 1, cime sv<ll
~ p __ ,
a\
na lfteta", d i je gamilanje
i{ l
' ~,..
U ~irn do sa da _i zl
Nairne, m ad a pr ik az
om nm pr im je rim a
nismo .irnali ne ke pr
. . -
an a rekur.tivna :rjoo ev el ik e koristi od

u veei nap<»' rije~iti i be


re~~
z pom!Jei rektmlije.
enja djeluju ja ko ele
Nairne, sv ak 8
~
gmrtno, ist i
su
rekur.tivnih Ijooenja.
se mogli uz ne zn at no
Y

u instanc
$~
rcl~dVJilli Ij~e
nja. Nairne, u
u ok vi ra funkcije cirprirnje.ru
ne se rcl
.

0 nerekat:zivnoj ve rr
akumUiira produ!tt do
ve m ja za pam6enj
be
iji ist e funkeije sv i
sp .G
m
tre
tada: ob ra de ni h br oj ev
e meJturerulWa koris
bn o _tro8e m em ar ijs ki (e
litturezultati. m og u pa
a mra sp on a od 1 do
<:
m tit i u jOOIIoj jedim
n) . Za slu ea j funkci
um vn i p®
sursi, s obzirom da: se v stv m a nQvu
u odg~.~vmajuooj
'lj -promjenljivoj (k oj
a

D
·-·
, na p!Ni pos!ed ut r@
furmlllttih parmn:etar
yi§C ptq$t.Ora u mtfutir
sk memm;jje isti M
a pamte i pqvratrut
ad
ti nj z dok rekumiv
ed ut im , okviri ftmkc
re se, taK-6' da se ispo's
na Verzija koristi instanc
ije pu te d w:ijednosti
lo kl
je bi n pe re ku rz jv na
e okvim, takO da je
lln
iji n§lil sw b'i zauz mvi da tlmnirani olfv.j ih JllDll!ienliivib: i
.V-:<i... eb niz. Sl ic na je stvar ci :funkci:ja: zauzmu
0•• !r1F-
Zn'.

--' · brzine izvrsavan


'dl;l' ~I?. i! 'lC;Vii'lfiia
;L, g_~
,p!lfllllletara n i br oj_Q _. ·--·---- ____flk
ac taka da je
ja nerekurzivna tje
fu __ J<Ta
!L w""L
zauzeee
'e d_""
m
M Vf-..
iit. -.lil..,li i{dfi:Sa ~·'"'~
emorije ponava v * ne
i sa re'k.UtZiil'nim pr
, -· ---- .J?Q-'i - ~lf '-
_!lQ «i...
" iii..ite
, .
! wr
imjetb'til funkcije
~o
U ...st....i_. fif
JLiii....
ill,_-
iii...
fi

u l!e go da sm a ka ris tili


re ku rz iv no . 'v a tro8i se izvjes nj a su ta ka 4e r m an je efikasna.__, tm . Sa as pe kt a
st V w nj e i 1mi§tav iio vr ije m e na Nairne, pr ili ko m
auje okvira fil llW Je 'v fu nk ei 'e; na sv ak og
• . brzo, on e ip ak us po ra va ~ na ve de ne vratak iZ :fimlrei'e;
operacije raCunar ge kao i na '
ju iz vm lv an je pr og ra nernlno izvr§ava pr

a
m s, pogotOvo u slu~ ili o
ju ve lik og br oj a
relrurzivnih poziva.
·

1
1\
5
.. 1
..
•''

~
[
-[
i
._.''

1[....J
Za slu~ tri diska nije se diskovi prebace sa §tapa 1 na
1~2. 3~1. 3~2 i
§tap 2 postujuci pra:vila igre (na:jkraci re:dos!lijed poteza
.
1 4 2). Medutim, .
il
.....
[
ne
za
'1
....J
[
madaje ovim
. diskova sveden nli . 1 diSkova. Da:kle, broj
umanjen za 1. Sll.cnim rezonov'imjeril -1 diskova svode se ria
probleme prebacivanja N- 2 diskova, i¢. Ocigledno problemi kada br~j diskova' dostigne nulu,
je rek:Urzivan
'l[
:
...... I

jer tada nemamo sta prebacivati. Ovo rezonovanje dovodi nas do sljedeeeg algoritm a,)oji
. ·. ·
jer se poziva na samog sebe: ·
:·;r;
)> Prebaciv anje N diskava sa stapaX na stap Y koristef:i !tap Z kao pomocni
: '~
)> Ako N ni}e nula:
l> Prebaci N -.1 diskava sa Stapa X na stap Z karistef:i stap Y kao pomocni ;
)> Prebaci jedan disk sa !tapa X na Stap Y;
?'" __ .Erebaci N ~--t-diskova -sa stapq_?_ na !tap Y koristeei stap X kao pomocni.
___ ,..
JJ
Ovaj ~tl~ Ia:ko je pretoeiti u konkretan C-H- program, koji ispisuje re:doslijed poteza neophod
za rj~'iianJe problema Hanojskih kula:
an
j]

i
#includ e <iostre arn>
using namesp ape std; 1l
void J?reba ci(intN , int x, int Y, int Z)
j
! if(N != 0) ( .
Prebac i(N- l, X, Z, Y);
]
cout << "Preba ci disk ~a Stapu. " << X << "na· Stap " << Y <<
endl;

)
}
Prebac i(N - 1, Z, Y, X);

,.
·u-
int main(} {
int n;
Cout << ."Koliko ima diskova ? ";
·U
~-

cin·>> n;

)
Prebaci . (n, ·1; 2, 3);
D

6
D
- ·- -----
1
\U 1
D rez:ultujtici p1
1
rogt'8111 v!;loma
0 lcratak. To ll
· ~to ledutim ne zn
za aci da je · on
·· · ·
jClhlo•stavar.
1
,.... I
O'L 1
r"
0 ; ·-l h a n o i( 4 ,1
1
,2 ,3 )
0:[ t 1

1)1
ha_._ n___._"'"'_.-_<_3,1
. prebaci sa , 3 , 2)-<t;. _·
/. n o 2 h a i { 2 ,1
1., prenbGaci ;q~~hane. 1
0r
· , . hanoi , 2·,
sa 1 no 3
1
(3 , 3 ;2 ,
h a n o i (2 ,2 t.; p re b aici{sa
l ; 1_., 3 , 2)_.
1 no 2
.._,.. p re b.. aei&
!(....~ , 3,1)~.- h ·
.a 1no-'3
. . a n o i (1 , 3 , 2 , . 1
1 ) ,. _ p r e b
i, .. .. . · _ ,h a n o i{ 2 a c is a 3 n a 2
.prellac.i sa J,3 ,1 ,2 )
O
I
i. ~-
...
._ . h a n o i (2 ,
1141
1~ 2 , 3 )
lhan
. prelola·i>. i(1
hanoH1, 1
,2 ,1 ,3 ). -p r
~ll Zm1 J
.
e b a .c is a :Z
n a . 1.
1

oc !
h a n o i (1 , 3
; 3 , 2) . _
p re /l « fi ~a.(

pre.hl!(ii sa 3 M, 2 , 1 ) .. _ prebac.isa 3.
nq ;f 1

1
'r
o~.
h a n o i (1 , 2 .(

h a n o i (1 , 1
, 1, 3) . _
prellaqisa Zoo
I
na-2
·
1

~ Sa oye siike m
1 -- * 3 , 2--1-1
· dijagrama
oremo ustano
, 2--1-3, 1--1 vlti .da isprav
-3, 1--1-2, 3 an redtislijed
Ip re b a cl sa 1
h a n o i (1 , 3
, 3 , 2.) . _
na 2
,2 ,1 ) . _
prebttlfl sa i
.
p re b a ci sa 3
n11 J ·

TUJ 2 ·
1
I poput pretho -4 2 , 3--1-1, pofeza zilN-:'4
dnog i pra.Cen g!asi 1 -- * 3 , 1
I[ programa je
primjeru tako
prakti~ki neu
der moremo v
hvatljiv, bez
ja vrijednosti
obzira Mo sa
2 -+ 1 , 3--1-2

m
koje im!\iu fr
,-·l--1-3, 1--1
umalni param
-2 i 3 -4 2 .
1--*2, 3 -- * 2
,
B e z crll\Iljll
et
in st a n o a fun
koije P re b a o
idjeti d a je n
jegovo isprav program izjpeda veoma ri N , x, Y i z tok 1
· rek:tlFzivnom :i . koristi vla n p . funkoioniral jednolltavno. U
tr ob:tita §to smn
po

a funkcija Pr
~oaci dje!U
stite

ni raZ!ag zlmg
e
lje
u novmormir zivu dolazi do presipanja v insbmoe svojih lokahrih za8novano na mnjeniei da vom
ane iru!tauce. ri
T<djeste glav jed!iosti teku6ih instanoi plll'll1Iletara, pri l!emU pri
zadanih u vid
u. s sv
o
sv
ako
aka
m
1

je gatovo ooig e g a je tai'll!n wki programa tvamih pammetalia 1


D U nave den
Vrijednosti liet om primjeru funkcij~ P re
6, moremo iz
iri formalna p
arametra N, X
b a c i, svaka
llidi:ld.

instauca. qjen
ta1w teSk0 pm
ti
ti be2l
1

n P re b a c i ko
ia
bje
sto eemo njeg 6i potroou za formatnim p
ovu vrijednost
,
~ trooi manie memo
r!W un at
; Y i ~. Uko
arametrom z
i p o relaciji 6
liko primijlrtitn og akvil'a liuva pored po.\'I
(o dno sn o
o d a je zbir V
redhim broje
riiskih resursa: - X - Y. Ovilll dolazimo m pomoenog Stiipa) tako
,
atn
rijeenoSti X; Y !l adr~e
i Z uv.ijek 1

u v e id P r e b
.if{ N I= 0
)
a c i( in t N,
P E e b a < d (N
{
i
·
n t X, i n t
I
• . ,w-:
~)
'i;:-
do sljedeee v
erzije funkoij
e
1

u - 1 , ll: ; 6 1
cout << "P - ll : - Y,
re b a c i· d ¥ )' '; ,
P re b a c i (N is
- l , 6 - Xk s a s ta p a " < < X 1
l ·- . Y, Y, X < < " n a s ta p
} ); • "<< y < <
r· e n d l;

l NMtvM, ov
a
obzitoiri da se ko i? m ij ¢ j¢ q f\w.k<;ij~,t ~
1

krajnjeg Stiipa . te.diii broj pomotrtog §ta o i<; g!!\V!log p 1


e ne zadllje nerq~ po~iv<m ~"' i' te b
u .
·
pli vm
· go iiiai!Uimvli ac
li ri<!nog liroija(!'l, l , ~ l s
poc¢ttiog i 1

1 1
7
\ 1
------
--~~~-
·

.
••
r
""\-_, ~. 1

[
iu
~~

~\~f\~~~a· fa l< to rije,eltad a


bi
· = 1. Na irn J [

3! =3 ·2! 2! =2 ·1! 1! =1 ·0! 0! =0 '(- 1) ! (_:1)! =( -1 ). (-2)! [


4! =3 ·2 !
,.,....
koj1 I
...J [
1_..·[
J i[ i

][
Pro ble m Ila no jsk ih ku la
se ob ien o u 1it era tur i nav od i ka a tip icr uq nim jer pro ble ma za ko
naei mirekurzivno rji:mnjel Pri
ji p~i
rod no ][
vcioma jedn.oafm>no nik urz
ivn o rje kn je, a za
lro je nij e nimalo Jako
po e po sto ji• Od go vo r je
Ij ~j e ble ma Ha no jsk ih ku la uo
·je postaviti pitanje da ·rr ner
·po tw da n. StaviSe,u teo
~ku
riji alg ori
rzi
tam
vno
a se;
(po
do
d
~e
pro
da za sva ko rek urz ivn o rj~jli
iterativnim rje§enjem · se
po sto
sm atr a ne rek urz ivn
ji i
o
ite rat
rje
tvn
§en
o
je ][
e . efe ka t i pustuplli
rjelenje kojiin se · po stiZ ist i
vim fot ma lizi t:an i, mada: ae i posve jed ao sta vn
). Cak postO je i sas
d!lbijena nerektlmvna: lj~
ea:ja ebiOO:o ~,[
za8novano na pru nje ni petlji rje §en ja. Pc i tom e su: ,j
u n~vna lltio dobijemt
pr-eW'llilqja r-ekw;zivaih rekurzivn'lh rje §en jll. Po red to'glt, tsk o fotml
o8jetn0' komplikOVIlilija. od
jidlazilih
tiili tekiltiiVIU!i t:l~Ja, Jet&t za dotiijlilije bittto
icno tii!J u bit no efi kiil mi ja 04 po liii
bii ko iti· ~1._,-· e• -~ > ..m·
;t.;~~J
nt~te1d.lt:tiVba: t;l~etija: tib tte
-~r ifl
~~i11
>'~. 1fiP
li n:e
...
&' kit iiiv

till
. ··-
~~f1 ftt ·l~ IZmJf ~~ ,r,--;J
, . ,.,.
i§e
+~i...
i !J ifi..£ '·
,J!J \.\1·ijJ sltW
, ji# ·;~t:'

~ <~ hi li
""tJ'"
\l ~t i~
.
t1
i

~l
.,
dil:
'6
·
d'
.tiili
'tiin
~l
;:
:V·
i' f~
9'k
~l
ur<
t.it
"i5e
"J.P
"ds
fa~ i'rdai~
ii
ur.
.. ..v
\)1¥1 .• , .• ., ~-- ~~·
il"i~ .... ,, ..., •. !( ..'fK .·. i) u,611~H~ltab.P ~~'lt~!Jj;Ctf ,...; ~ IIJ H~\ r!Y <
1
6 ~Xttlm~'ifiii6~'~~4bl!
1

·2[ ~'Jiti

~64~.(prl1ob~K ntnu je, i nije mnp.go Jl(l.Wllto


,
pos.toje lem Ha nq jsk lh kul.a je upravo
pro ble m Ha no jsk ih ku la
takav). Medutim, interllSa ve om a jed na sta vn o iska'fflti u
im a iterativno (nerekurzivn
e ko je je
o) rj~enj J
pri md no m ga vo rno m. jez

»
iku :

»
pa X na §tap. Y koris.teci §ta p
Prebacivanj'e N disko:v.a sa Sti budu na stap.u Y.·
Sve do}{ S1!i diskc.vi ne
Z kaa parno.Cni:
r
> Ak o je N neparan: eroX ~ Y ~ Z: ~X;
.» Pl'ebcwinqjmaw"iciW;usmi D
lf. S.f!P.rQ(nQm; .r
u ~mi((I"ZJ,.;f' ~ Z ~ ~X; ·' '·''' '·'uiiik...
)'
> Pr~l!qgi IWJII!5Wii <lw.k
. . ..iln6 '" "· "i. P... ... !I. . u
·em nU.OHSii. !'@ma>!l. .
... u. TCJ
·'6l~i . ·. . . ..
r""i.1.·ett<'i" .i<'i.. fW
> p;..".~:A . . . W!J.gi!C
blem priWeSti ev.aj D
sta vn a,.vmtiti l'Ui!na, i i!twjelru nij e nik ak av pro pri
Ov aj alg ari tam je ve am a jed na 11 je re' kti ttiv ni alg ori tattl Zlldal> .vellkih problema
j N, be t ob tit a §W 11at
iiii lre tje sit i problem
algoritam za proizvtjljatt bro
pra een ju ve e za N=4{sW
gii, uk dlJ ktj se go
ov a
... .. - ...~
+<t avo
d l:itillet e
1 iil"otl"'"
.. ~- --
htje
~W "'·
-
1i pohViiliti preu iiekiiii dli
s... dti
.. l"e
!!g .. _...Sti ~,.e• ov
....'afi ...a·~ ru_!@·"f....
"' ··!e i!i
ifi J·e....dli....lek_o•.lid
itii.__
,..
..... .Q YYJ'i1H" '''H~h
JJ.: "'" "-"

'
0
.... Q· m!>
,j-"'
.ite. Yu
li:ii...
kdt... !'· !ilk
Ha noL_
....... ·skili....ku1
....a.... bw
rll... , ... ...
·m : ZQ .ff _., ''dd t lai C s~
·> ., ~-
.. · n\\¥ ."1 ;J.. 8r:
llJ'i 1!r n'll:
" ·.. l ~ ·· j" •"".,Q $".~"" .......Q Qn
'-' · ; n ...... _ ..Q iar. NcitWit<l. je
orlti u program .za tl\Mjem
··&;
o·~" ,""
..~r.' :<w.•Qg, . . _ ......Q "~. ivr io P.r etv
riij l\ po svl\ jl\drio Sil
Pored tciga, ov!ij .Ugo.ritam a ko ji glasi "Povuci jed ini trenutno mo gu ci potez u ko jij e to "jedini
se ne koristi D
. pro ble rna tic an ka tak alg
ori tm va ve om aje lak o uo cit i ko
Na irn e, cov jek ll ko ji im a isp red sebe sliku dis ko
na jm an ji disk".

8
n
r
IJ4

-0-----
--
{]
......

{]
{]
-{]
~

{]
-··
{]
,.
saMa jiu ·
-o
·-~
je io01. gu"un"
. ~k<iiii).

-o·-
.•-o
-o-·
{] )» Pr{kaz svih rastava broja N na K sabiraka:
~
)> Ako je K =d.•
)> lspiS iN

-B
·J
)> U suprotnom.'
)> Za sve Vl'ijednoati I od 1 do N--K+ 1.'
)> Prifr a# sve rasta ve broja N-1 na K-1
{J
,.
preth odno ispi3i sabir ak 1
sabiraka, ali ispre d svalre rastave
·
Ovim je fonni rana osno vna ideja za Ijooavwye
probl ema. Medutim, ostaj e da se rijooe joo neke

~ eesto
potOOkoee, na koje se nailazi pri rekw:zivnom rj008vanju iole teZih probl
problematican posljednji korak algoritma, odnosno ema. U ovom sluooju je
rijegov. dio kf!ii glasi "ali ispre d svalre rastave
" prethlidntJ ispis i sabit ak r', On nas s~va da
ov!U korak algoritma prt1Stt1 sv&lemo na rekurzivnd
poziv atlje iste funk tije za rl!Stlivu broja N-I na x--.:1

.D
sabit!lka. Naza lust, ovaj kotak se ne mo~ pmstc
~in M <Jv~ t!~Ylsfia t<.otiik!i koJi ~~ @Willi "f.f.Pi ;
l~ ~«W#k ,f' i "fft~i file r~t<tve l)fw« N-1 fl4
tom
sdo/Fak4", Niiiiiie, u slucaju Iii K~J
se s~liifilk-JlSfiiSiio sa.nioHd4i@.if.Pi'Ue liip!Sa avni liiStiiva liroJaN-I
na K-f ~if,llai, ta.Jcri ga Iii Sariio pr¥a t.~St4- v!i im~l~ 5ve ~aoffi(e, stoga, je ocigl~o {ioifebiia rie~
D
.
sabir ak I prosl ijedit i funkciji ~oja 6e ispisati rasta
Sada se posta vlja pitan je na kojem mjes(u ispisaji
ve
broja N-1 na K-1 sabir aka (zapr avo, samo j sebi)
taj prosl ijeile ni sabira"" lstim rezon ovan jem k9je smo
.
uprav o prim ijenil i moze mo Zakljueiti da gdje god
da ubac imo njego v ispis; on pono vo neee biti ispisa
n
D
'
dovo ljan broj puta; jet se pri svakom njego vom ispisu
poziv ima unuta r petlje (u kojin ia se taj sabir ak ne
geile rira rnatn o viSe novib rasta va u rekurzivnim
ispisu je). Slijed i da j"' jedin o rjeren je prikupljati
sve

0 9
i~)
l
[
.sabirke koji treba d:i se ispisu u Iiiz i odgoditi Iijiliov iSJ:\is 8ve do trenutkli IQid:i semi igpiS ~iibirkaN (g. ·
karla se problenuve4e na situaciju za K= 1. Ovim d.obit~o n~:~~ij'! y~j~ al$9fll!na za
Ijclavimjeproblema, u kojem se vee jasno uocava niogiicnostriejlos~()i:~~VD.Cigcpo~ja: . [
)> Prikaz sv~ rqstava broja N na K s_abirqka:
)> AkojeK=J:
· ,.: lspiSi sve do t(lfia prikupljene sab[r{(e (aka ih ima) ·
[
»- lspiSiN . .
"' . us_up··rtifiiam:
··"···------
);> Za sve vrijednosti I adJ. daN-/.(+.
1: [
·>·iii -irakL ·'-8'
Si.I!J' #I . ., lf.I!QP.~ ~Jf\·a~;a
. .
)'. PrG
. ' -·-·· . iVe. riiiiave
-· ··-·- . . ..flriifii:N'-'I
•.· .·- na. K-I s®ii«Ka
- - - ~ .
[
_[
_

[
[
r
[
void Rastavi(int N, int K,' iDt Indeks = 0) {
· st&ti.c int Niz [100); ·
[
i:f{K ,.- ll {
:r<;f(•l;;nti· J = 0; J <: Indeks; "+";
}
aGu't ·.,:;;: N << Qll'd1;
J++) oout <:<: Niz[J) <:<:
[
elae fo~(i~~ I = 1; I <= N + 1 - K; ~++) {
N:iz t:i:M~k!IJ = I; · ··
Rastavi(N ~I, K ~ 1, Indeks + 1); [
}

Prlmijethn(). da smo koristili I t'onnalni parametar Indeks. Njegova uloga je d:i vodi evidencij\1 o.
~
rednom broju (indelqn1) sabirlm koji se upmvo razmatra, sa cilje!ll njegovog smjcltanja na pmvo uyesto
u niz. Pri totne. smo ovf!i ~etar definirali d:i ima ~jevanu vrijednost 0, tako d:i ga ne.
momm() navoditi prilikom gla~g poziya funkcije (s obzirO!ll d:ije njegovo postojanje bitno samo za G
rekin-Zivne poZive). Bez obzira na krlrtkocu ii.ulkcije Rastavi~ iUett tokje v-eott1a te§ko pratiti. Najbblje
je dl! pokW!lte <Ia 11®rtate shett~mski piikai w~ ~IIlii~ I:JVt: 1\lnl!:<!ile za ttli#iJt: -vrijt$.1osti N i K
(lirejic!rul!iije
.. seN=
..
6 i K = 3 ill K
. = 4). Nlik<j!i toga ee Yam milclge
.~
!~Willi
.
:iWStiitl
. ftllii!&d. Ji!Sri\le. · u
Pre$odni primjer-je zaisia teZak i predstavlja, !lit izvjestan naCln, test zrel9sti koji Jl!lkazuje u kojoj
mjeri ste sposobni d:i savlad:ite naprednije tebnike programiianja. Ukoliko ne uspijere d:i u potpunosti m
rnzumijete ovo Ije§enje, vjerovatno nikada neCete moci biti u onoj kategoriji programera koji bi se mogli
nazvati "IjeS~ problema" (na =Gil; tom: mora svako da bulle). s druge strane; ukoliko ste uspjeli da
u potpunosti "svarite" ovo Ijclenje; mo~e biti sigurni da Vam nitijedna tehnika progmmiranja rteee biti D
10 D
II
u _·
.....~
·

{} L,.
~Jltiidjete ova IjeseQie, moc ite oiti sigu
mi da t'8z1Jiiiijete
[}
1,., ..
~c¢ell.ie~i):;j};au nizu, zbog eega je neop
hodn
~~y. ~l,l>~ !! ~!mir.!t<l J:nd eks. N a krajU; sami sebi
o da niz bude
odgovorite na
• definirrui kao siati~ki (pri tome je neophodD.o
[}
~

[}~

~
G
....
g
~..... l.on g.in t F(i. nt n)
· ii /D. ·< 3l ,;,.turn
elsa retu rn .F.(n -
(
1;
1) + F(n - 2);
•.·. . .
l
Q . NiJI;!. ~Y prijl:ii~lsproWti ~ fi!bk~ijiJ i ~tiyiti(!it
(;Ina 1"\@. Ip&k, tcistitafUi! gy~ ~~lje iii
rpll~itii _;vtU~d~~ #~etrtt .?o.t(l~i, ~~-· ~<iil~u~
n
QI '
~ezuliat piillalcno freliutiio. Medi.itliil, ·voo .za n"'40
sekun4iJ Pak i na priliCrio brziiii racunarlini Za
lh ~tl~& i.kii, _.?4 h <20 futlkciQ~ ¢e p~~uqltf
tta. rezuitat Cet:e cekati ptillroo duga (viSe
desetliiil
·-~ n,.; j() na iezultat tete eekati ~dok se
dO~ 4a za -fl = 100 nete te doeekati rez.iitat za V*g moZe lako
najbdim ri¢~ kOji u ovom ttenulku po~je na. Sv:ije.tlvota (!ak ni ukoliko :funkciju isprpbate na
D
.... obzirQm na Gin:jeniw d'a s_e F 1oo mom iztamuliiti por
pomo6u for petlje (a mogu6e je pos\>e Iilkd'\Jrad
tuJ OVci mo~ <lj~lOvati \'eGma !lokantno; s
n~ sveg a 98 Sabii-abja, ~ se mou obaviti npr•
iti iSak i rucno). Da bislnd vidjeli §taj e uzrok ovako
n~biiSnom poiiallai!jil, razinotrimo sljede6u
Q =
pbzO-ire za: n 7:
slikU koja prikazuje tok iivrnavailja funk dje F
kada se

Q F{7)

t 3

Q /(6)+F~

0
...... /
· F(4) +F(3 )
F(S) +F(4 )

~
F(4) -f:F( 3)

y"
F(3) +F(2 )
D t ~- ,zt 'I
F(3) +F(2 )

~
F(2 )+F (l)

- F(3) +F(2 ) F(2) +F(1 )

,, It 'I ¢ ,,
F(2) +F(1 ) 1 F(2} +F(1 )
\1 It 'I
1 1
9,.., 2~
F(2) +F(1 )
It ,,
1

t ,, 1 1 i 1 1· 1 1

9
-~
1 1

l 11

1
-·t

.. -
;;.

•f
~

lZ ovog dijagrama vidiffio da je prilikom ral\\lllanja vrijednosti .F (7) funkcija F pozvala samu sebe ·
25 puta, bez obzira ~to se F7 · ·
da se neki izrazi
F(3)+F(2)
·· ·
svega
· ··
· · ~ vidi

n
J
~

~f
-~r
~

~r
Ta)(o ee. za 1:!!£'!!1"!';\i~}'so = J25~~26!)()25 .~\lij.a.P?~a~ sama sebe 25172?3804') puta, ~to. zaista ~

tliora rut ftijj.~; I!M®o dt!go, Jo~ g(lre. ttlljlitij~ ~vilbja broja .F100 = 708449696358523830149
oviik6 #iJPisailofii fii#kcijom t,i'itj!ilo Iii il1«1224 itXttfiii l\ak uz tftefptiStAVki! dii c¥iiil~t Dioze otiii~Ijlill
bilion poziva u ~· (Sfu je Otprilike slul\aj sa illijmoCnijim ~ kojima d3nas iaspoi3Zemo).
Pre'ma tome, rekurzivna varjjanta .funkcije ·za ral\unanje Fibonal\ijevih brojeva je,· usprkos ·toine ~to
1
~

iz&leda lijepo i eleg'antno; powuno neupotrebljiva!


·[
Posij~dnji primjer posve ubjedljivo ukazuje dl! treba dobro profllisliti prije nego ~o se upotrijebi
~
·
neko rekuizivrio Ijooenje. Kao pravilo, mol!e ~ rem da svako rekurzivno rj~je u kojem :funkcija
poziva: ~·~be vi~e od je£«riput u ~ svog .£vota .i u kojet!t se 've)jSne.potproblema .koji se '[
rektitzivrio rj'OO(!Vaju sporo smaiijuju (npr. za koi:IStaiitim: iznos) obi&&n& vo'dfek:SponenbijaltiC:im tmjifujti
izVclavanja: (takVti sitilitcijii ioiariio u o~IjMtlja. tri ptin'ijem}. Talct;o rj~eD;je je prihva'tljivo jedido
ukoliko i.iiamo da problem koji se.rjooa!a sam sehl j:ii;i ii.Vrniivanja.
t.aJitijeva elcip'oiiendjliliici trajanje Na
ptiiner, .Pfu'blem Haiiojskih kiilii je upi-iiirci tiili:liV (j& je n&phodaii oroJ jiOteza ekSpon:endjliliia fiirikcija f
.~

broja kula), a more se pokazati da to vrijedi i za problem rastavljanja broja na sabirke. Me4utim,
i:al\unanje n-tog Fibonal\ijevog broja more se izvesti sa rf.-2 sabiranja, odnosno izral\unavanje se. more
g,vesti u vremenu koje liizearno oviSj 'od n. Kao posljedicu imamo da. je rekurzivno ral\unanje l
~

Fibonal\ij~vih brojeva katastrofaln~. $'t9ga su .~Jene brojne meiode za ubrzavanje rekurzivnih


rjOOenjii, koje se zasnivaju ila dopllllBkol!l .l~ll:D1o!franju yee izrafunatih rezultata i izbjegavanju
rekurziynih poziva za ~anje onog §toje vee ·i'ii-!Wumito. Na ovom mjestu se ne£ento zadi;mvati na
[
.....
ovlm meiodama; s obzirom ila one spadajiJ a ilomen t,iwrije algori~ Jo§ j8 bitno napomeniiti da s'irilko
·rekurzivno rjdenje u kojel!l funkcija rekurzivno Ji{lziva sama sebe vwe lid jedanput u toku 5Vog ~vota
(
ne mora nuZno biti spero. Nairne, takva IjeOOnjll' mogu biti i jiik~ bmt, pod uvjetom da se velicine
potproblema koji se rekuizivno Jjooav~u mpidno smanjuju, l'rili\jer jednog takvog brwg rek"drri~
Ijclerija bite naveden u poglavlju o ~Ortinlhjt:L
-
· Ni· kraju izlaganja o rekurzijama moramo rem da rekurzija iz dana u dan dObi.@ sve veCi znaCa.i. u
D
-
·modetnoiti progtilniiriUiJU. jet su mttogj. savtdileili koncepti u su§tini' rekiitzivne prlttide. Na pritlijer,
op~t!Wlj:ii tllid fuldetimli i rtteilijlttta ~ se izVtlde tekttril:Vilo s (lbzli't:im na !!injeilii:ir da ftilderl tnoit!J
sadffli.vilti tiodfuldere, fiienijl tlie!gU Slldff.avilti podiiiefiije Itit 1 to dO prtiiiVoljfte dtil5iiiC:. Tllktidef,
D
-
rekutzije predsiav!jaju osnovnu metodologiju ptogiliiiiifliiija u veciiii rteptocedllliiliiih jezika (kli6 sto su
npr. LISP, Pralog i ML), i nezamjenljive su za programiranje logiCkih igara (iloput ~)kao i metoda
k<ije spadaji.t u dbmen vjeStWke inteligencije. Razlog za to len u. ~iiljenici da su definicx}e mnogifl D
-
pojmova koji se susreGu u r~:ali!om Zivotu zapravo rekurzivne pruode (nil priinjer, defiilii:ija "Va§ predak
je osoba-koji! je iii va§ rodite!j, ili je p~ nekog od va§ih rodit!:>!Ja." predstavlja tipi&m primjer
rekurzivne defmicije). Mnogi kafu da je rekurzija "jednc oo najubojitijih programerskih oruija" kojim se
l\esto mogu savladati i najte£ problemi, alfkao i svako ofllZje, more ilanijeti neprocjenjivu ~tu dospije
u-
.li "u pogre5ile ruke". . - · · - · · - ·
D
-
D
-
12 D
~·I
lJ
-- •
-{] ,. . JE I
.,. >
~s.o·nT.-m "'·"""]>.
7' · -n..- -~.-,: -·
v . ..
n:n;t;<~.t.,.!7.n7AN·:."R' ;e--
· - E'".IXJ lJ'~;;~.J.:>v· . . · . -~:.1!1

-!J
~

-n
-~

-D
--0 . :~2~Y;i:mo cia iJA~q neJ<i niz
R'cl'""ll·tkii"e se rvo rili!iiece "e da rVO
od n ~~J:!lPJ}!Ita !c~J Z,e~o
_sq~ n,P~· _u ~~{!14.!pPre~k­
roilildemo'na.,na'lfi elemen(~
~~~i~~~m;iJi;):~~o~;~!~:~;~~~i~~jlfj~~~~~~odna~:-
''":(lji\,'a,dovedt o'na. rvo

....
eleizi.eiita ri!za IiiWalje, a zatirii ga dovedemo na drug(,lmjest{) uniz~. ~~,
uriekom, .k-tom kOI:aku
-0 Iirotml8zimo iiajm~i element p<irev ·oo k-tog el~~nta ·m.za Iiiidalje, a ?,a~·
nijesto u :nizii (na njegovo mjestO do:Vodimo eleirient koji Se do tada nalilzio gil dovedemo na. k-io
- Ocigledno; nakon n-i koraka, niz je sortiran. Na osnow ove id'<ill; morefuo 'lako
ria k~toin mjestu).

-0 (siwlonsku) furikciju Klasic niSort koja sortira niz Niz od n elenienata u raStuci
nai>raViti genericku
poredak:
- templ. ate <typen ame tip>

-0
~ .....
void. Klasi cniSo rt(tip Niz[], int nj f
for(in t k = 0; k < n - 1; k++) {
int gdje_j e_min ;
tip min= Niz[k] , porn= min;
rlJ
l.
for(in t i .= k + 1; i < n; i++)
' < min) {'--..
if (Niz [i] .
.
min= Niz[i] ; gdje:t e:min = i;

~
}
Niz[k] . =min; Niz[gd je_je_ min] porn;
}

~ Primijetimo da smo prilikom traUnja najmanjeg elementa zapamtili PO~ciju na kojoj


u promjenljivu gctje_j e_min da bismo kasnije mogli da element koji se .-do
je:On promiden
tada nalmo na k-tom

~
mjestu prebacimo na njegovo mjesto (porn je pomoena promjenljiva koja sluE
za razmjenu). 'Ukoliko

-
D
malo mzmislim(), primijeticemo da se furikcija Klasic niSort m9re skratiti tak<i
traz.enja minimuma cim primijetimo da je tekuci elem,ent manji od k-tog izmiti
k-tim elementom {tako ell na kraju sigmno najmanji element doei na k-tp
sljedeeu verziju furikcije za sortiranje:
st<i eenio U procesu
njegow raZinjenu sa
uyesto). Ovim dobijamo

""' templ. ate <typenall!e tip> :.


D void Klasic niSor t2(tip Niz[], int n)

- for(in t k = 0; k < n - 1; k++) {


for{in t i = k + 1; i < .n; i++)

0
~
if(Niz [i) < Niz[k] ) {

)
tip porn =· Niz.[i ]; Niz [i] = Niz [k]; Niz [k] = porn;.
}

~ . . .
Razmotrimo sada koliko su efikasne napj$ane fimkcije. U oba slueaja SPQljalinja petlja
(Sa brojaekom
.
~
promjenljivom k) izmav a se n-1 puta .(za k od 0 do n-:.2), dok se unutralinja PetJja
izvrSava n-k-1 put
]
i
(zavisno od k), tako da·urupan broj pro!azaka kroz unutralinju petlju iznosi (n-l)+
9dnosno n(n-1)12 puta. Za veliko n broj prolazaka iznosi pribliZno r1!2, takoda
(n-2}+ ... + 3 + 2 + 1
je vrijeme izvrSavanja
~
furikcije pribliZno proporcionalno kvadratu broja elemenata niza. St9ga se kare
da ove furikcije imaju
] kvadratnu s/oienost. Pri tome je furikcija Klasic niSort neznatno br.Za od furikcij
obzirom da se u ovoj drugoj furikciji tipieno vr8i veei broj premjeStpnja elemen
e Klasi~niSort2 s
ata niza. Kako se

I

I

r ) /
. l .

premjeStanje l:leinenata niza obavlj11 prilit!no brzo, raziika


[
u vremen11 izvclav~~Djll je gotovcrzanemariva. ·
· Ipak, Ukoliko ~ sliCnim postupkom so,-tiraju neke druge stiu
kturep~ !l; ~e nizOvi (npr. datot¢ke na
di~IJ: k~d !:';<;lji./1 se riiZinj~qa ~Cija dva eleineilta izVcidi [
varijanta more biti osjetno bda od drifge. osjeiifii'/sll\ln.l'ti riego ktid nizova, prva
- ·. . .

oJXl'~lPlca za sertiranje, ·
iw~va sortifQ_nje
[
""•·'-' - ~~iitm
iniliona [
wilitittio, 411 da.
;;o.,;••.,,,,_;...
nijlltije
li SU
[
'
N~ boiji postllpak sortiranja zasniva se na poredenju
svakog \llcm)ll!lta u nizu sa svojim susjedom i
njihovoj razmjeru u slut!aju da su u neispriMlom poretku. Nako
najveei element ee slgmno doei na kritj niza. Sliedeea
il ~~ ria taj nal:in prodemo kroz t!itav niz, [
slika J>rllciiuje ovaj postupak na jednom
konkretnom nizu ·od 8 brojeva. Elementi koji se llporedliju
oznareni ·su crticama, dok su elementi u
pop oni :Poietku (koji Ce hiti i-azmijenjeni) oznaeeni podeb
lji\Do: [
'
3 5 .. 1 8 6 9 5 7
3 ~'
3 1 5
l 8
8
6
6
9 5
9. 5
7
7
[
3
3
i 5
1 ·5
! 6
6" 8
9 5 7 '
9 5 7
3
3
1 5
1' 5
6
6 8
a 2 5
5 9
7
7
[
3 1 5 6 8 5 7 9
. Naravno,,· o~im niz jo~ nije sortiran; negoje samo najveci element doveden na svoje
Medutim, sada ·na ovako dopijeni niz nioiemi,1 popov o primijeniti pcinovo isti postupak,
mjesto. u~

elem entko ji je odmah po veiit!ini iS.Po<i wv~g dovesti t!ime eemo


postUpak ne moramo Pt9voditi do kraja niu vee ga moie mo
· eiementll; jerje najveei element vee doveden' na·, svoje
na pravo (pretposljednje) mjesto. Pri tome,
prekinuti kada dodemo do pretposljegnjeg
11\iesto. Tok ovog postupka prikazan je na
0~

sljedeeoj slici,.pri eemu radijednostavilosti necemoprikaziva


ti posljednji element kojij e vee doveden na
svoje m.jesto: .
5'
.• ·:
..
0
~ ! 6 8 5 7

1
1
1· 3
3
3
5 ,. 6
"5 6
5 6
~
8
8
5
5
5

7
7
0
1 3 5· 6 ! 5 7
1
1
3
3
5 6
5 6
5
5
8
7
7-
8 0-
Ot!igledno, ako ovako nastavimo, nakon najvme n-1 prola '·
prolazu dovodi.mo barem jedan element na s\roje mjest
ispitivanje moflmto prekinuti jedan korak prije nego u preth
za niz ee biti sortiran (jer u svakom
o). Pri tome, u svakom narednom prolazu 0-
niZ posti\De sortiran i p.rije nego ~to ~imo svih n-1 prolaodnon i prolazti. Medutim, mou se desiti da
zaNa primjer, ukoliko na niz iz prethodnog
primj
. era priinijenim o j~ jedan prolaz, dobijamo sljedeeu sit)Jaciju: D
.. .
~ ·
-
u
"1 3 5 6 5 7
:··.:1~ 3 5 6 '5 7
1 3 5 6 '·5 7
1 3 :5 6 ·5 7
1
1
3 5 5 •. 6
3 ,, __5 .5 6
7
7
u
2 ll
. I-
ij
_).
.
i

' . '
D
~·-'I

fl
......

~
'-·
n
·..,_,
~:i>ate <5ii!iii:o;a,a u >
~~d(atJ;bii.sd_if'(tip. Nlz [ ], int · n) {
int·. sarti ra'n =O;
:0!
~.
£Cii; (ilit;_ prola z =·1; prol; ;tz < n
sor~i;an = 1; 0- pro~
&&
!sor tiran ; prola z++) {
. .
for( int i = 0; i < p~_i&z_ J:; i++)

~
;i.f{N iz [i] > Niz [i-1-l li .{ ··
tip porn = Ni:i [i}; Niz [i] = Niz[ i+1] ; Niz
[i+l] = porn;
.,_~ sort iran = 0;
} .

@ }
"'V.
v r:J
-
50ft
.-~ -~- __ ....~
" ~ · · ~~ c• ~
.
.P :J
0
..,oR..,·~
1"'' -~ 0)'\<:> sdot: :\1"- "'-~- k '<!-;
· de; ·rte,., .,=, j><-<.n of'~
D
-
Priinijetpno da za raziiku od so~ja_izbo!:Om f.imkcija
prvoiil j;ri>IB,Zu uk<iliko joJ se ponudi '-\fee soifo'ani iiiz; ~ je Bubb leSo rt zavr8avaposttipak odma h u
sVakako veoma po'Voljno~ S drUge strane,
Ulcoiikil ~ flin!a:iji prol!lijedi I# liojij e sortirim u obl:nilt<)m: poretku od
(

Nij~_tclk:o Vid]eti ditJe u slu~Ju .<hi se ~ svi prolazi broj uljen og, Wcliee se svi prolazi.
{] izboroiii.DaJde, u nil orem slli~ilu, m"ehunisto 'saitlnmje Je podjednak:pioi32:8ka kioz pettju isti kao kod sortiranja
o s.Pofo kao 180rtirari" e izboroin,
~ u
ali nekim sl~·evuna mo ude miio o br:Ze. Sroga Je o postav:iti pitanje kakva je
r[) u
e . •.. . . <ist Ip.j(:~g sortiriinja p1"0sjeku. Odgovor
nizOve os·efuo trajlinje sortinm·a ovim · pkom je novo ro rciOnalno za
riije obeshr8bru.Ju6i: nasumimo odabrane .

·~
.e emenirtli, i tekje neznatno brZe od sortiranja izborom. ~ehlir kvadratu biOja
astO sortiranje je veoma dobar postupak u
s!u~~~ kada. ~jed Zllllm~ da je ~ skoro
{] prem Jdtan ja da b1 mz postao sortiran. U takviDi slu§luev~man, .ti- da nije P?tre?no ~iti mnogo
sornr
a mJehurastn sortiranJe radi veoma brzo.
Mcictutim, za slu~ prilimo "izmje8anih" nizova, ovaj postt ipakj e podjednako Ioo (tJ spor) kao i do sada
•·*.
opisarii postupci.
{] . Posrojijo~ mnogo postupaka kao §to j~npr. sortir_<m.je
-~

{1

imaju kvadratnu slof.enost. Sroga je prirodno postavitl pitan
sortirati br:Ze. Odgovor je potvrdan. Posroji cijeli riiz postti

veliki napredak (npr. za n=lOOOO imiun\) ,(-= 10000 0000


postu pci za sortiranje su Shel/avo s~engi.Qleli;c;r
bmr
;mzetcilyetn Gin sert ion sorti1Qji takoder
je da li Je uopee I;lloguCe. proizvoljan riiz
kojih je vrijeme pofrebno za sortinmje riiza odn elemenata paka nazvanih
proporcionaliFo n og n !iestn
dOkj e nlog n= ~- Na
sq~od

j~
je
l>J sortiranje spqj ·em en ~
-o
·~
sortiratife slaganjem na hrpu (engl.~i sortiranje razdva
jcm.jem (en partition sort
· Ve6ina brzih postupaka za sortinuije su dosta komplikov
{l sinje§tmije raznih medurezultata. Vjerovatno najbolji komp
ani i C!esto zahtijevaju .,Omoene nizove za

.. pri sprtiranju razdvl!ianjem. Ovaj posttipak otkrio je C. Hoar


postu pak za sortiranje•. Stoga se-on ~ naziva prosto. brziJ
romis ~edu brzine i slof.enosti ostvaren je
e 1972. godin e. I"a najPQznatiji brzi
sortirarif (engl. quick s_o Postoji mnogo
{j podvarijanti ovog pnstupka, a sve se zasnivaju na istoj ideji
da se riiz p na a pn"blimo jednaka
... dijela takva da je svaki element iz
uraditi tako §to se
dijeta od svakog elementa iz· drugog dijela To se more
·
ll

toga,

u
u 3

rl
... l-
r-
[
[
2 9 5 4 1 7 .6 1 7 '3 i 5 1 ~ B -
2
2
4 .5
4 5
4
4
1
1
7
1
•6
6
1
1
7
7 3
3 2
2
5
,§,
l
J
9
9
B
B [
.2 4 5 4 1 1 5 1 7 3 ~ 6 7. 9 B
2 4 .5 4 1 .l 5 '1 2 ~ 7 6 7 9 a·
J:dio 2.diQ ·.
[
[
..
[
.

teiiip1iite <tme~~
. .

tip>
.
-
vc>:lcf QuickSort('j ;ip
t£ioctakie < ctok1et t
Niz [], . int odakle, int dokle) {
.· \ ~--
[
.. ·t.if;pi_vot .;Nlz[(odak le + d<;>kle) I 2]; · · '-'L~ L-_J~l \..
. ~1: lpqk = odalle, dpok = (!c:>klu.(" v<;t.-:11- -e. t I v ~ I
wiiil.ci(Niz [lpok].<piv ot). lpok++;
wijj.l.e nhz [ di;)ok]' :> pivot) . dpok.:.-;
[
~

i:f(lpok :<= dpok) {


tip poin ·"'· Ni.z [lpok]; Niz[lpok] = Niz [dpok] i NiZ [dpok} = pom;
[
"
/ }
1pok++·; . dpok--;

QuickSort(N iz, odakle, dpok); .QuickSort( Niz, lpok, dokle);


-
} · .. ,· [
Primijetimo da .se ova funkcija poziva drug!Wije nego doSadamje funkcije za sortiranje. Nairne,
-
umjesto broja elemenata niza funkciji se kaO parametri prosljeduju indeks pOOetD.og i krajnjeg. elementa
niza koji ~ sortiriL Ovakva konvericijaje neophodna da bi se funkcija mogla rekurzivno pozivati nad
0~

dijelov4,im ni.za. Uzmalu izinjenu, :funkcija QuickSoJ;t se


moli.e prepraVm da prilivata iste parametre
kao . i .ostale funkcije za ·sortiranje: ·Za tu svrlru; funkcija se ~ prepi1iviti da ·formalni parametar
odakle ima podrazumijevanu vrijcdnost 0. Pored toga, potrebno je obmuti redosljed parametara, jer
0
samo krajnji plinUnetri mogu imati podrazumijevane Vrijed!losti. Ovakva modifikacija ostavlja se
i!itaocima za vj~u. · · 0
Opisani postupak u veeini slui!ajeva radi zaista veoma brzo. Medutim, moltC se poklizati da je ovaj
postupak ponekad dosta osjetljiv na izbor elementa koji se uZim.a za pivot. Na primjer, ~ se susre6u
implementacije u kojima se za-pivot uzhna prvi element u nizu, ali takav izbor je dobar samo za dobro
. izinje§ane nizove, Lako je pokazati da ovakav izbor pivota u sllli!aju daje niz potpuno' sortiran ill skoro
0
. sortiran vodi takoder ka vremenu izvmavanja koje je proporcionaln o kvadratu broja elemenata niza. Ovo
. se ne ddava kada .se za pivot uzima elem~ iz sredjne niza, kao §to je uradeno u prikazanoj .izvedbi.
-u
ce
Medutjm, i Z11 takvu izvedbu moguee je konstruisati nizove za koje pn"lammi algoritam mditi sporo.

Da bi se izbjegao ovaj. problem, uvCdene su 'T{IZlii!ite mooifikacije algoritma. Jedna oo poZIIIItijih


modifikiwija poznata je ·pod nazivom lnedijan-3, u"-kojoj si za pivot bira sredrifl po velicini izmedu
0
prvog> pos/jednjeg i sredrifeg eleinenta niza. Ipak, maZda se rtajboljr rezultati postifu tako §to se pri
svakom rekurzivnom pozfvu pivot izabere kao posve slliCqjni element niza. Na taj nai!in je vjerovatnoea
· da ee se u svakom rclrurzivnom pozivu izabrati b~ Iiepovoljan pivot svedena na posve zanemarljiv
D
4 D
r.
\
.,

-n

-[]
-
.[] int random( int n) {
- return (1ong)n *rand() I (RAND_MAX + 1);
{l }

- Princip rada ove funkcije je o/Sigledan. Pretvorba u tip 1ong izvrllena je da se izbjegne eventualno
prekoraiSenje koje more nalitati prilikom mnorenja
-0 .
·Kada smo se upoznali sa funkcijama za generiranje slu/Sajnih brojeva, moZemo pokazati i kako
se
n:iore. napraviti brzo sortiranje sa slueajnim izborom pivota (engl. randomiZed quicksort). Za tu svrhu,
-0 dovoljno je samo nar~bu koja de:finirll vrijednost pivota promijeniti da glasi ovSko:

tip pivot= Niz[oda kle + random( dokle + 1- odakle) ];


.

-fJ
m
.,.
Nairne, s obzirom da random (n) uvijek vrl!Ca slu/Sajan broj u ops~gu od 0 do n-1, slijedi daje indeks u
uglastoj zagradi u prikazanoj naredbi sluCf\ian broj u opsegu od odakle <;lo dokle, a to je upravo ono
.
.~to namjepot rebno.
{J
Postupak "quicksort" je, opeenito gledano, jedan od najbdih poznatih postupaka za sortiranje. Uz
"' izvjesne modifikacije moguee je postici j~ neka ubrzal\ia, ali ne bitna Pored toga, takve modifikacije
-o

znatno !lSiomjavaju samu funkciju. Treba reei da su poznate .brojne: varijarite j modifikacije ovog
metoda, ta)!;o da se u literaturi susreee puno razli/Sitih implemyntacija algoritma: 'pod istitD imenom
"quicksort". N$lost, l5ak se i u knjigama ISesto susreeu i neispravne implemeJ¥acij(; koje u izvjesnim
{] · rijetkim slueajevima ne rade ispravno (imP,Iementadja koja je prikazana ovdje je garantirano isprailna u
svim slueajevima). Nairne, mada je osnovna ideja ovog postupka prili/Sno jednostavna, ·prilikom same
izvedbe razdvajanja niza lako je moguee napraviti izvjesne propusre:koji. naizgled rade;: iako ne rade
{] dobro u nekim specijalnim siucajevima Stoga je najbolje sa algoritmom "quicksort" 'lllllogo ne
eksperimentisati, nego koristiti onu varijantu za koju je sigurno da uvijek radi ispravno, i to bez
~
improvizacija i nepotrebnih modifikacij!l-

D Na lrniju pri/Se o sc~u, treba ukazati na jo~ jednu ISinjenicu. Metod "(mickS<irt" je ·ooigledno
· rekurzivan, a takvi su i skoro svi dlugi brzi postupci za sortiranje (osim Shellovog sortiranja). Stoga
je
D prirodno orekivati da bi nerekurzivna verzija ovog metoda trebala da bude jo~ bda, s obziroln da smo
ranije vidjeli da su nerekurzivna tjclenja uvijek efikasnija od rekurzivnih. Mada je ovo taiSno i za: ovaj
metod, "quicksort" je·tipiiSan primjer algoritnfll za koji se ne isplati traZiti nerekurzivno tjclenje. Nairne,
·nerekurzivni "quicksort•: je sasvim neZnatno brZi od rekurzivnog, a oko 3 puta je sloreniji, i zahtijeva
0 pomoene nizove (koji u rekurzivnoj verziji nisu potrebni): 'MoZda nekome izgleda /Sudno to ~o ovaj.
metod radi brzo usprkos ISinjenici da funkcija QuickSo rtrekurzi vno poziva samu sebe na dva mjesta,
~to je u sluCf\iu prob!ema Hanojskih kula i ra/Sunanja Fibona/Sijevih brojeva vodilo

0

ka eksponencijalnom
trajanju izvrllavanja .· Odgovor na ovu zagonetku leZi u tome da se u svakom rekurzivnom pozivu
fi.inkcije QuickSo rt veli/Sina dijela niza koji treba sortirati smanjuje na otprilike polovinu, tako da

D 5

n
se o&~~t~W:i!~~~j,e~~~~~eb~()Je:: ~$~~~~~~~'6~~ezm~~t.!'~~ [
rie~6~l%~ki 2ii ~o~e iia nmi o~imo iaooir eienieii~~; iiij~@ldffij<lje Wi~iriciite D.i2a prije
liego. stci pozovemo funkciju za sortiranje napiuilii:ui slu&ijium vfijetiijpsiiina,. ~ je poinocu opislinih
funkcija veoma lako ui!initi. Medutim, ukoliko IJI'Qbat& da iuipunite n~id iliZ slueajnini. vrljednostima a
[
zatim da ispiStete te vrijeooosti ria ekran, primijeticete da su te Vri)edn:oSti, m~da potpiino nasumi<!ne, iste
svqld put kadO p(Jnovo pokrenete program! Razlog za tu i!injeriicllle~ u tome da funkcija rand (pa
preina tome i random, koja je izvedena iz nje) zapf!lvo pri s:VakoJ:n. poziw viaca !cao rezultat sljedeei
[
<!lim jedJie unaprijed fiksira!Je i tafuo o~ene sekvence brqievQ,FoJ~je ~o formiralui Wi itgleda lalo
da njelii elementi nemaju Dik:akve medusobne ve~. Ipak, ta sek:Yericaje ista sva)ci put lalda pokrenete
prop. Ponekad ovakvo pona8anje liije poZeljno, tako da c++ pcisj(:Qujei funkciju ~rand (takoder u [
biblioteci cstdlib) kojoj se kao paiametilr prosljeduje eijeli liroj; tZv.. "sjeme" ( eitgl. seed) poniocu
kojeg se vr8i izbor sekvtmce koju gerierira funkcija. rand (fi.Inkcija srand ne vraea nikakvu vrijednost).
Ukoliko Zelimo da se svaki put Ialda se program pokrene generira riova sekcenca; .potrebno je na po(!etku [
programa funkciji srand kao argument proslijediti neku vrijedtlost koja se je ·druga(!ija pri svakom
pokretanju programa. JC:dna moguenost je iskOristiti rezultat furikcije time iz biblioteke ctime (iii
. time. h u starijim verzij(llllll kompajlda) ,koja'~da joj se prosiijedi 0 kao argunient kao rezultat vra6a [
broj sekundi kojije protelalo od ponoci 1. Januara 1970. godine do tre,Iiutka poziva funkcije Gasno je da
)e taj rezultat rnzli<!it pri svakom pokretanju programa). Dakle, naredba oblika ·
.,
srand(time( OJJ;
·.N
c
.ubal!ena na po<!etak programa uzrokova6e generiranje nove sekvence slu<!ajnih brojeva pri svakom
p(,kretanj)l pro~ MD.oge verzije kompajfera 'za C+t posjeduju u biblioteci cstdlib i funkciju ·o
raridolni>:e bez.parametara koja radi ~ §to i gore prikazana naredba.Ipak, treba voditi ra<!una da ova
liin.kcija liije ~dardna u jeziku C++ i ne mora je poddavati svaki kompajler.·

·Recimo sada nek~Hko rijeei o pretranvanju. Gelleraino je problem pretraZivanja znatno jednostavliiji 0
¥-o4 prgblema
sortiranJa. mada i pretrativanjl} i'8Zirih sloZenih struktura podatalal (kao §to su npr. grafovi,
stabla, Iiste itd.) moZe biti dosta komplikovano. Po~to se opisane strukture podatalal izuC-avaju tek na
vi~im kursevima programiranja .ili na teoriji rugoritama, ovdje eemo se ograniciti samo na pretraZivanje
D
nizova. Cilj pretraZivanja liiza je pronaci na kojoj poziciji se nalazi element koji posjediife neko svojstvo.
Na primjer, 1\esto je potrebno prona6i gdje se nalazi element koji je jednak nekoj fiksnoj vrijednosti koja
se obifuo naziva kljue pretrage. Sljedeea generi<!ka funkcija vraea kao rezultat indeks prvog elementa u
liizu Niz od N elemenata koji je jednak vrijednosti kljuc. U slul!aju da talalv element ne postoji,
funkcija vraea lalo rezultat -1, ~ moZe sluZiti kao indikacija da pretraga liije bila uspje§na (s obzirom
da -1 ne moZe liiialda biti indeks nekog elep1enta u liizu):

temp1ate <typename tip>


int Pretraga(ti p Niz[], int N, tip Kljuc)
for(int i = a;· i < N; i++)
D
if(Niz[i] == Kljuc) return·i;
return -1;
D
6 D
L: '
-D
~

{]
.,.

-fJ
~

-D
,..

-D
""
-{] 1:eq,.iat. <~ tip>
i.rlt: Bin arri al?r etra ga (tip Niz [],
.,. int N, tip i<lj uc) ·{
±nt lpok = o, dpo k = N - 1;
-{] whi le(l pok <= dpok ) {
.tilt 'sre din a = (lpo k +.dp ok) I 2;
~
;!.f. (Niz [sre dina ] == K1j uc) retu rn
sred ina;
e~se if(N iz[s red ina ] < K1j uc)
{] }
else.dpo k = sred ina - 1i
lpok = sred il)a + 1;

,. retu rn -1;
-0
.,.
}

Ovd je su, slii!no kao i kod "quicksort" algoritma,


iskorutena d.va mdek:sa lpQ!>-i,.dpok koji na
poCdku poka zuju na prvi i.posljednji elem ent .
{] .ria poee tak i kraj onog dijela niza u kojein
niziL Nlikoii sv3kog ~Cfujil;' oVi. indeksi se pom
u
treb a llii'Stliviti prettagu. K&kif 81;~ svakom
jeraju.
niza prep olov ljava (g. opada eksponencijalnom koraku veliiSina
1'!
brzlnom), vrije me ~vanja ovog algo
najg orem sluiSaju proporcioiJalna je sa lo~ ritma u
n = 1000000 linearna pretraga ino! e zahtijevati iwniesto sa n. Razliki iDo~ biti di:asti.OOa. Npr. za
D n
traZeni element u najvi~ 20 koraka, fu> je ubrzanje do 1000000 koralai; dOk bhiiinia pretraga pronalazi
od 50000 putal · · ·
"
0

Ol!i gled na .manit binamog pret:rdivanja je
trebiJ!D.o pret :rdiv ati nesortiran niz, prirodrio
pr~ iii prvo sortirati niz pa koristiti bina
~to niz koji se pret rafu je mor a biti
sortiran. Ukoliko
je postaviti .pitanje da li se ~e isplati kori
stiti lineamu
mu pretmgu. Odgovor zavisi od to~ koliko
0 treb a pret :rdiv ati (g. koliko puta Cem.o pozi
sveg a neko llko elemenata, bclje je koristiti
~ vrem ena od linea me pretrage. S
vati funkciju za pretrafivanje). Ukoliko je potre
linea mo pret l'mv anje , jer i najb r!e sortiranje
elemenata niza .
Jmo ttafi ti
~i znatno
' drUge strane, ukoliko je potr ebno da l:ramno
velik i broj radi~Sitih
0 elem enat a, l!esto se isplati prvo sortirati Diz
svak i elem ent koji se 1raZi kotistiti bina mu
elem enat a niza koji su jednliki kljuiSu, bina
(s obzirom da se to tadi samo jewmput), a nako
pretragu. Treba jo§ naglasiti i tQ. da ukoliko
n toga za
postoji vi§e
ma pretraga nalazi neki ad njih, a ne num o
sluiSaj kod line ame pretrage. prvi kao §to je
] · '

]
]
1
7
./) . .
. l
·... ·: . . . .
. .~

. . ..
[
....... . . : .
. . . . ·- ..
.. - ·. [
. . . . ·. -·
.. . . . .

. . . . . [
-· [
. . . ·.. ',•

_. -
:
... . :..· ·. -·
. . ··. .
-':- . [
·.·· . [
. . . . . --

[
:....
. - [

[
. . : .
. ·- -
.- ·.; . [
. _· ·. ~-:_ . . .
[
. [
. . . -
- -·

[
... ' .

. ·. :f

·-~. ·.
[
[
r
D
.I
u
. u
.r
'
ru. '' .


~

"-

u
f1 ST RI NG OV I KAO NIZOVI ZNAKOVA

0 Svi programi koje smo do sada razmatrali


praksi obradivali su iskljucivo brojcane podatke. Med
se cesto javl ja potr eba za programima koji
nenum.ericke prirode. Stog a je u jezi k C++
utim , u
obraduju tekstualne podatke,_ odno sno poda
ugradena podrSka za rad sa tekstualnim poda
tke
r{] stringovima kako se oni uobiClijeno nazivaju
u programiranju.
cima, odnosno

- C++ podrZava dva naci na za rad sa stringovi


ma Prvi naein posmatra stringove kao obie
{] znak ova ri Cetn.u su • e neke dodatne konvencije ko ·e ne vri' ede
Je po postanku st&ij~ i uz nezn atne dopune,
ne nizove ·!
za obiene nizove. Ov.g naein (
- znatno kasnije i _poSmatra stringove kao pose
preuzet lZje zika C. Drugi naCinje ujez ik
bne tipove podataka (definirane preko tzv. klas
a),
c++
uved en i
isno !
{] od nizo va U ovom poglavlju Cem.o detaljnije
nizo va znak ova ·
razm obit i prvi naein, odnosno tretiranje strin
neov
gova kao).
- Osnovne ideje rada sa stritigovima kao nizo
-o koji ee uCitati reCenicu (odnosno proizvoljan
zatim ispisuje unijetu reCenicu unatraSke (od
virna znakova moz.emo razmotriti na primjeru
slijed znak ova) .sa ulaznog uredaja (tipieno
posljednjeg znlikR kli prvom). Slitan prog ram
programa
tastature).o.1L
~~ pisali ramJe, iih koJr Je lZVrtao unesenu rijee
rijdi ti. Prvi prob lem je sto operator izdvajan
, fiksne dllZine. Ovdje se javlj aju dva prob lema
smo vee
koja treb a /
ja "»" i orira n oje ocigledno treba uzet i u obm .
- da bism o ispravno u rtali kompletnu reCenicu.
naei na da saznamo kad smo proCitali sve
gr problem je Sto pomoCu. operatora "> >" nem
amo '
-o- znakovi prosto "biti zatraZen novi unos sa
}5:i n.ge t oJ
znakove iz ulaznog toka, nego Ce nakon Sto
tastature. Oba problema se mog u rijesiti pozi
umjesto koriStenja operatora "»" . Ova funk
se iscrpe svi
voin funkcije ·
cija izdvaja tekuci znak iz ulaznog toka (pri
tome trait unos sa ulaznog uredaja ukoliko ·
je ulazni tok prazan, slieno kao i operator
{] izdvojeni znak kao rezultat, bez obzira da
li se radi o oqienom znaku, razmaku ill ozna
(fiktivnom znak u ' \n • koji ozna eava kr'\i reda
">>"), i vrae a
ci kraj a reda .
-· ),Sto ga sljedeei program obavlja tr~ .zada
tak:

D
.
#in clud e <ios trea m>
usin g nam espa ce std ;
int mai n() {
0

cha r rece nica [lO O], znak ;
i~t bro jac = 0, i;
cou t << "Un esi nek u ·reC enic u: ";
whi le(( zna k = cin .ge t()) != '\n' )
0
'
cou t << "Re Cen ica ispi san a naop
for {i = bro jac - '1; i >= 0; i--)
rece nica [bro jac+ +J = znak ;
ako gla si: n;
cou t << receni~a[i];
)

0 Prirnijetimo da se u ovom prog ramu javl ja pom


alc cudna konstrukcija ·
whi le{ (zna k = cin .ge t ()) !=· '\n' )
0 . koja se veollll\i,i:esto koristi u C++ prog
ram ima Pomocu nje prvo dodjeljujemo prom
rezultat p<>ziva funkcije cin . get {), a zatim jeuljivoj znak
] oznake kraj a reda • \n •, sto predstavlja uvje
demonstrira situ acij uuk ojoj znak dodjele "="
provieravamo da li je ·dodijeljena vrijednos
t pod kojim se izvodi petlja.Ovo je interesan
tan
t razlicita od
primjer koji
moze biti koristan unutar uvje ta Da smo dodj
razdvojili jedn o od drugog, dodjela bi mor elu i uvjet
ala ostati izvan petlje, talco da bi morala biti
1 kraju petlje. Drug im rijecima, odgovarajuci

znak = cin .ge t();


dio programa bi morao glasiti: ·
pono vljena na

'
1 whi le {znak ! = '\n' ) (
rece nica [bro jac+ +J
znak = cin .ge t();
znak ;

]
{f~i? ,::~~l
'-~-·-.~.: ·· ..:.. ~(->i~pl-
: -~
.. ~. · "
L
'~~i:c.-:-::. ;.;(~- ~<·.
~~::/QYf'!t¥,-A-·f
. ~:.~-t ·:· r;-!"...:l:
~.>(~" ·t~-,.._-..r.-:-
. · .. ~
...
-._., --·
.--'.
1-
~' i . .Alternativrio bismo mogli koristiti i do-whi1e petlju u kombiuaciji sa naredbom if:
tr:~tP> .. 'do { . . ' . . . [-
·.r . znak = cin. get {) ; . . .

~
if(znak != '\n') recenica[bro jac++J - znak;
) while(znak != '\n'); ·
·"
· U svakom slueaju, upotrebom ove neobiene konstrukcije maeajno smo skratili progranL. .
[
Treba takoder primijetiti da smo u ovom programu preeutno pretpostavili da unesena reCenica neee
biti d11Za od I 00 znakova Ukoliko korisnik unese vi§e od I 00 znakova doCi ee do problema, jer ee se
· prekoraCiti dozvoljeni opseg indekSa u· nizu recenica. S!o moil.e dovesti do kraha programa. Ovaj [
problem se lako moil.e rije§iti modifikacijom uvjeta u while petlji tako da se ona ptekine ukoliko
promjenljiva broj ac koja broji uilesene. znakove dostigne viijednoSt 100. Drugim rijeeuria, petlja bi
-
mogla glasiti ovako: [
while( (znak = cin.getO) != '\n' && bro·ac < 100)
-
. Sa do sada izloZenim konceptima bi se teoretski mogao napisati bilo koji program koji obraduje
[
podatke tekStUalnog tipa Medutim, iole. sloZenija manipulacija sa tekStualnim podacima·bila bi izuzetno -
mukotipna ukoliko bi se orii morali obradivati iskljuCivo znak po znak. Stoga p++ posjeduje skupinu
:fimkcija koja omogneava manipulacije sa strihgovima kao cjelinom. Na primjer, umjesto uCitavanja [.
znakOva sa tastature znak po znak poiivom :fuukcije cin. get {), moguee je pomo6u :funkcije
~ [cin.getline{ ueitati-.citav ~ makova odjednom..·. Ova :fuukcija se moil.e kOrlstiti ru1vi8e naCina, a
. ; obteno se kortsti sa dva ill tri parilmetra Ukoliko se koristi sa dva parametra, tada prvi parametar [
edstavra niz ·znakava. u kaji se smjesta"u rocitimi znakavt dok drugi paramefar redstavra
maksimalni brofznakava iji e se procitati (u s.l~ju da se prije toga dostigne ri reda, biee proCitano
-
.. - .
manje ZDakoVll;' odriOsno neee bin zatrail.en'unos ri~v;i,h znakova). Drugim rijeCima, naredba
. - ..:: -__ . ·-,~ -') -.'·
[
C§::n.getlin e(recenica, soU .,
-:-'
zatr3Ziee od korisnikit unos sa ulaznog uredliJ'a (tastature), a zatim smjestiti najvi§e 50 procitanih.
[j

makova u niz recenica (Ukoliko je wieSeD:o·manje od 50 znakova smjestiee se svi znakovi)..Ukoliko
se ova funkcija pozove sa tri parametr:it (§to se Ijede koristi), tada prva dva parametra imaju isto maeenje
kao i u pretbodnom sil!ClYU, dok treCi ariunetar predstavl"a znak ka ·; ce se ko - · · o a
unosa. Drugim rijeeinui; Cimce· se svi ZIUlC1 do sene prcCita navedeni znak ill dok se ne
ka zavrsetka
procita onoliko
0.
Ziiiii«iva koliko ·e Zlidano drugim parameti;om. Tako ee poziv:fuukcije

... cin.getlil).~3rec8riif:a, ·59, •. '); .... ·.


. ~· ..-<> ( 1.1·' ''·' .- 0
: ~
..;J/., :.
'-:,! ••
zatraZiti unos sa tllaznog uredaja, a zatim procitati najvi§e 50 znakova iz ulaznog toka u niz recenica,
pri eemu se Citanje prekida likoliko se procita znak "." (taCka)..Pri tome se taCka uldanja iz ulaznog 0
... .1'' ··:··. taka,. ali ne prebapuje·u niz. Ukoliko se dostigne kraj reda, a nije proCitano 50 znaJmva njti je proCitan
znak ·,, . ", bice zatraZen unos novih znakova sa ulaznog uredaja. Treba napomenuti da: je poziv funkcije
"EizLgetl'in e sa·dvlfpaiame tra·tdentiean pozivu ove :fuukcije Sa tri parametra~ kojem je treei 0.
parametar jednak oznaci kraja reda '\n •, Drugim rijeeima, sljede6a dva poziva su iden1iena:

... r~ ,_
cin.get.lirie (recenica,
cin.getline (recenica, SO,
50) i'
'\n');
0
Vrijedi jo§ napomenuti da se i funkcija a in. get takoder m~ile pozivati sa dva iii tri parametra, poput
funkcije cin. get line; sa veonia sli<:nini.pejstvom. Pri tome je jediua razlika sto za razliku od funk ··
u
cin. getline funkciia cin. get ne uldanja granicni znq ozn kraja reda iii Zn.ak riaveden kao treei
parametar) ~ ulazuog toka, nego ga ostavlla u ulazuom to!gl.
: .· ·'
''
·
D
. '

;
, . !. D
···,
rl
;{: ) •

{!"
-.fJ . u slueaju kadasmo ~ove iz ulaznog toka citali znak po znak gozivom funkeije cin. get ()' -
mogli smo taeno znati koliko smo znakova unf e · s obzirom da smo brojali unesene znakove (pomocu
--[] promjenljive brojac. Medutim, ukoliko koristimo ooziv funkcije cin.getline javlja se problem
kako da utvrdimo koliko smo znakova unijeli. Jedan od nacinaje pozvati funkeiruin. ~count{ijkoja
vra6a kilo rezultat broj znakova koji su proeitani prilikom posljednjeg Citanja utiin, u jeZikii C++
-.[] ovaj problem, i mnogi srodni problemi koji !lastaju zbog cinjenice da tekstovi sa kojima radimo mogu
biti razlicite dliZine, rije~ je na mnogo univerzalniji naein uvoderijem jednog posebnog mak sa ASCll
. 0 ~
sifrom 0, koji se uzima kao oznaka kraja stringa (to nije znak • o • nego znak cija je ASCII si.fra nula). , ~-~,

-
.[]
Nula je iskoriStena kako zbog jednostavnosti manipulacija sa brojem 0, tako i zbog Cinjenice da 0 nije · ;-o· ,
ASCII Sifra nijedn~"normalnog" znaka koji bi nam trebao zatrebati pri ispisu. Ovai specijalni mak' ·'·;~/,
tipieno se naziva NUL. Gotovo sv.e C++ funkeije poStujn ovu· konven.ciju o tzv. nul-terminiranim
..... stringovima, po kojo · se nailazak na znak NUL tretira kao kraj stringa bez obzira da li iza njega slijedi jos
znakova Zbog toga, funkcije cin. getline i cin. get (kada ~ korisi:i sa parametrima) obavezno
{] 5mjesta'ju znak NUL nakon posljednjeg proCitanog znaka Tako, ukoliko nakon poziva fuDkcije
-~ cin.getline(recenica, 50);
.[] sa tastature unesemo :fraiu "Za 10 dana", u nizn recenica cemo imati ovakvu sitnaciju (brojevi u
~
zagradi prikazuju ASCIISifre navedenih znakova): ·
.[]
-.[]
-.[] Sa "?" smo omaeili elemente niza ciji je sadrZaj nepredvidljiv (oni ce sadrZavati vrijednosti koje su
se od. ranije zatekle na tim lokacijama). Uz ovakyu konvenciju posve je lako napisati funkciju koja ce
odrediti kolik;o je zaista dugaCak string, odnosno.k'oliko se zuakova nalazi ispred graniCnika:--.:_~_./
: .;.- .•·
.,. int duzina stringa (const char Niz ['] ).
{] - int bro]ac 0;
while(Niz[brojac] != 0) bJ::ojad+;.
-{] )
returp. Proj ac; ·

- Ovu funkeiju moren;10 iskoristiti npr. na sljedeei nacin:


··:

{] char a[lOO];

-{] cout << "Unesi neki niz znakova: ";


cin.getline(a, 99);
cout << "Unijeli ste "<< duzina_stringa(a) << 1'znakova.";

Jezik C+f vee posjeduje ugradenu funkciju nazvanu [strlen fiz


biblioteke {cstring /(odnosno
~

-1stri~ u starijim kompajlerima) koja radi istu stviir kao i upravo napisana funkcija
D
.,.
'tru:Z:ina_stringa. Dakle, u praksi, ovu funkciju neeemo pisati, nego ee~g koristiti gotovo funkciju
~Slijedi alternativna verzija programa koji ispisuje naopako recenicu ncitanu sa taStature:

{l #include <iostream>
#include <cstring>
..... using namespace std;

ll · int main() (

-n char recenica[lOO];
cout << "Unesi neku reC.enicu: · ";
cin.getline(recenica, 99};
cout << "ReCenica ispisana naopako glasi£ ";

- )
, for(int i = strlen{recenica) ·- 1; i >= 0; i--) cout << recenica[iJ;

D
...... 3
1
I
'

Obratini() pamju da je
cin.getline za 'edanman'aod
p=alna.
e
dozvoljeua vrijednost za · drugi parametar u funkciji
dnZine nizazbo Cin'enice da seuvijeksm'eS ta iNUL grani&lik;
za .. oji moramo obezbijediti prostor. Zabomvljanje ove cinjenice je eesta greSka u programima. ·

Mada operatori umetanja "«" i izdvajanja ">>" generalno ne mogu raditi sa Citavim njzovima nego ·
samo sa individualnim elementima niza. oni ipak prihvataju nizove znakova kao operande. Tako, -ukoliko
se iza opellltOm "»" navede neki niz znakova, na izlami tok 6e biti ispisani svi znakovi niza jedan ?:!!.
~ sve do oznake kraja stringa (graniCnika NUJJ. Ova Cinjenica znatno olakSavarad sa stringovima,
Jer omogueava pisanje konstrukcija poput

char recenica[lO O];


cout << "Unesi heku reCenicu: ";
[
cin.getline (recenica, 99);
cout << "Unesena reCenica glasi: " << r~cenica;
_·,·-._.'\: . [
. S_lieno vrijedl_i ~.operator"»~. !ak?, mada:konstruk<:ij~dn ~>a .•ene~o nije dot;voljeua za -
slueaJ kada promJenlJ!Va a predstavlja mz, ona Je dozvolJena UKo1ikl[ Je a mz znakova. Ipak; ova
konstrukcija njje e!syivalegJna eoRvu funkc11e cin. qeUine iz -dva_ razloga. Prvi razlog je [
nemoguenosf ogranieenja broia znakova koji ¢e biti proCjt!!1!i Drugi razlog je Cinjenica da operator ">>• -
"U'vijek prekida izdvajanje iz ulaznog toka nailaskom na prvi razmak ili ImY. reda. Na primjer,
pretpostavimo da smo napisali sljedeCu sekvencu naredbi: [,
char recenica{10 0];
cout << "Unesi neku reCenicu: ";
cin >> recenica; :~-~::-.::·:. [
.,
cout << "Unesena reCenica glasi ::. " <::; Jtec;:enica;

. Ovaj program ne bi radio naoeekivani naCilL)~ai~;.~_e)minu bi iz unesenereCenice hila ispisana samo .[


l prva fijec, jer bi se izdvajanje ii ulaznog ~~ka7~vrsil~·Jif!prvom razmaku, dok bi svi ostafi znakovi (pa i '
• ostale. rijeci reeenice) ostali u· ulaznom tokp, i ..lhoglf1f>Fse kasriije izdvojiti ponovnom upotrebOfu
• ~eratora "»". Uko!iko naiJ1 zbog nekog r~~f:jpiavo treba da iz ulaznog toka izdvajaiiJ.o rijee po
,_rijee, operator"»" more Jlliti od koristLJP!I%·1i yeelhi slueajeva, za unos stringova sa tastature znat:n'o je
[
povoljnije koristiti funkcijti cin. get line ili everitwllno cin. get nego operator "»". Od koristi more -
biti i funkcija§in. peek ( >{ bez argumenata koja vraea kao reznltat koji je tekuCi znak u ulaznom toku,
ali bez njegovog izdvajanja iz ulaznog toka, Sto bi uradila funkcija c~n. get () .
[
'
' Bitno je istaCi da u slueaju kada se u istom programu naizmjenieno koriste operator "> >• i funkcije
cin. get line odnosno cin. get more lako doCi do problema ukoliko programer nije onrwn To se
[
naJ1akSe :nore dogoditi uko!iko se u 1stom programu unose i brbjcani i tekstualni podaci. Na primjer, -
razmotrimo sljedeei isjei)ak iZ programa:

int broj; '~- 4 ~


u
char tekst [ 100 J ; ·. '''
cout <,_< "U~sli
cin >> brojT
fueki.

b;roj:
·
•;
0
·cout << "Unesi ne_ki ·t-ekst: ";

Y
cin. getline (tekst; 99);

k~o

u-
,
Ovaj isjeeak neee raditi je oeekivano. Nairne, probleme pravi operator izdvajanja "»" koji _·
prekida izdvajanje na prvom razmaku iii oznaci kraja reda, aline uklarija iz izlaznog Joka znak na kojem
je izdvajanje prekinuto. Talco, pretpostavimo daje na pitanje "Unesi neki broj:"_ korisnik unio neki broj ·
(npr. 123) i pritisnuo tipku ENTER. Tada 6e se u ulaznom toku na!aziti znakovi o1 o, o2 o, o 3 o i ozuaka
D
kraja reda '\no. Naredba cin >> broj 6e izdvojiti znakove 0 1 •, o2 o, o3 o iz ulaznog tok ali oznaka
• Ja reda 0 \no i dalje ostaje u ulaznom to . Ka.da bi se nakon toga ponovo koristio operator"»", ne D
bi bi!o roblema, 'er on svakako ignorira razmake i oznake kraja reda. Medutim, funkcija cin. getli!!L_
odmah na poeetku pronalazi oznaku kraja reda u u!aznom to (i pri tom ga anja}, Gime se njen rad
D
4
1)1 '
T
~-

o--

··~

n,_ odm ah zaVI'Sava, i u niz tek st nee


·prazan string, Sto svakako ·mje ono
dov oljn o je nakon uCitavanja broja
e se smj'estiti niSta osim graniCnika
Sto bi trebalo da bode. ReSell' e
NUL, tako da tek st postaje
mo.ze biti pos ve jednostavno: l.r-

n
pozvati funkci' cin ~ et koja ·
je ostala u ulaznom toku (rezultat ove ee ukloniti ozn aku kra ja reda koj a
radi korektno: funkcije mo iem o ignorirati). Na.prim
jer, sljedeCi i~eCak programa
....;' ·
in t bro j;
0
~--~
. cha r tek st [10 0];
cou t << "U nes i nek i bro
cin >> bro j;
j: ";

~
cin .ge t ();
cou t << "U nes i nek i tek st:
cin .ge tlin e(t ek st, 99 );(

[l Opisano 'eSe!l'e dodu5e ne· ·es in# ~

roblem ukoliko 'e rilikom uuo.sa


c broja a prij e pritiska na tipku · . uuio jo~ podataka (npr. jos bro
a: tlldii ostati u ulaznom. tokU i titi pokupljem nail jeva ill
bro ·a k · · nak on uno
nek ih drugih znakova): Oni
askom na poziv funk_cije ci.n iet
@ moZda na'b ol'e nakon naredbe
cin >> bro j o no is raznili
cin . ge t () u petlji sve dok sen e pro
Cita znak za kiilJC 3 o osno na
lin e. Stoga je
ulazhi tok .po ziv om . funkcije
r~m poput sljedeee:·
) wh ile ·(c in. get () != '\n 'J;
rO /

- Jos je lakSe istu stvar obaviti pozivo


m funkcijeJ cin . ign ore } na sljedee
i nacin:.
{] cin .ign ore (lO OO O, '\n ');
....

D on
pam met rom (nlijeesee se kao prvi
"' ne sam o kad a radirno sa strin!lovima
,
broj). Opisanu telmiku moZeino kor
istiti
0
..
pad ata ka prihvatiti "svjeie" podatke
ulaznom toku prilikom prethodnog
uno sa Na priiiiljer:'
da

.. ,.·;-
budemo sigurni da ce naredba· za
sa ulazno1g lll~fi~ ne neke podatke koj
' '·-;/~·...,
uno s
i su eventualuo preost3li u

0

in t bro jl, bro j2; ·
cou t << •un esi prv i bro j:
cin >> bro jl; ·
cin . ign ore (1 000 0, ' \n '_) ;
0
'
· cou t << "Un esi- dru gi_ bro
cin >> bro j2; .
j : ";

Na ovaj nacin eemo biti sigurni ~--

J ~e, c
da ee se na zab ·ev "Unesi dru ·
o_iko e konsnik prilikom zahtjeva .bro':" zaista traZiti uno s bto 'a sa
"Unesi prvi bwj ·" unj o odm ab dva
bro ja
. ~~
. .
Na ovo m mjestu eemo jos dem
] Pretpostavimo da smo napisali seg
onstrirati kako ostvanti .bolju'-lwn
ment programa pop ut sljedeeeg: ,: '
(rolu iiqd ylaznim tokom.
f~*! - :ti .
1<
wh ile (l) { . - ~~··,;- -
.•.;-:o

] int bro j;
cou t << ~·unesi bro j: ";
,.
~. ~·

,...
cin >> bro j;
cou t << ''U nij eli ste bro
1 }
j " << bro j << end l;

Ovlij isjeeak ne radi nista posebno:


I u beskonacnoj petlji. Medutim r
Da bismo vidjeli sta se tac na de5
trai i od korisnika·da unese broj, ispi
suje ga i ponavlja istu sekvencu
·e" olucliti" ukoliko korisnik umjesto
ava i kako mozemo reagirati- u ov
bro·a unese neki tekst.

l. detaljnije sta se desava ukoliko kor


isnik unese nesto sto nije broj u tren
im situacijama, razmotrimo
utku kada program ocekuje broj.

5
T ~l
~

r '· ,-,. ,.. fr. / 'I· II


-. ~---" ?/
.-J
n ·.:-c l ;,

{I=-~·,(' ~-~
d! ~?c--~~ .. /
-{. (~~':..
:1
~

~:-!.r i•·:~

f
~

1
~

-f
[
-
[
-
[
-
[
-
mozemo ulazni tok l:>risati
. sigui:ni da ce sljedec;i l>roj :Uvij~k biti
·-0
. .. ' ..
0
'-

Cin >>·
u-
'
if( !cin)"
cout"<< "Nemojte se salit;iJ
cin. clear() ;
:.>'
brojJ_\n";

.t.•.-'.
. .:·
0-
)
~· <~-;~~:;*<<.i~~~l; 0-
'.-~-

broj
. cin. ignore
) .
!"
'
~

n
,_.,

-
0-
u-
ll-
cout << duzina_st ringa("M oj tekst.: .''):;_·
int duzina = strlen("M oj tek!;it ... ");
u-
6
u
n
Li >.
)

-0 ,

-n. Bitno je napomennti da stringovne konstante omedene navodnicima uvijek imaju unisau
grani~ iza posljednjeg mak!J. iako. ga rm eksplicitno ne pisemo. Da nije tako, ilavedeni primjeri ne bi
radili kako treba
NUL

-n
..;
.
Striligovne' .Jsonstant~",ne samo da se m9gu upotrijebiti kao parametri funkcija koje oeekuju
konstantne ll.izove makov3; nego stringovne konstante zapravo i jesu konstantni njzoyj makoya i sroga
.

-0 se mogn npotrijebiti hila gdN gdje bi se inaCe mogao upotrijebiti konstantni niz znakova .Stoga je
sljedeCi primfer posve korektaD, i lspis~je tiiZ milkova iz rijeei "Primjer", svaku u posebnom _r~u:, y
·_ - .. - (i ,-

~
. for (int i F 'ol ~- ~ 7; ii-+l cd\.lt « "Primjer" [i] « end!;
{1 Moguenost
••• •:;..:-~ ~.-_··.:::'

navodenj~. s :c ' •• : ' '


/. • . _,.:.;..

, ·:. ' · "


".1'

arametara funkci'ama ko ·e oceku ·


~

-0.,
.

D
'
D
,,

D
~
Naravno, u ovom IJrlrP.jeru neJID!i_ OS<lb~t§.
0 Sve medutiJ;n itekako.dobija

postane generiCka
broj a · mo2e prosiriti da
"' unositi razliciti tipovi

0
.,
· podataka

Kao i svaici fungi niz, . prilikom deklaracije. N a

0 primjer:

.cchar 'd', ='a', 'n', 0};


· cout <<
o· •';
·t:::out.. <<:; "I:'j en<t,du.ztnaj I' n znak.ova. n ;-


J

ima clanova u .
da .napi8enlo graniCnik a da
poznato da u
clanova se popwnjava.m
da ll.iz ima devet

J kOd inicij3lizirahil:t nizova


inicijalizacione 1i5te),
. . pri cemu
ne bio ilbaCen; i primjer
iza poruice "Dobar dan" ispisalajos gomila besinislenih

iza znaka "l1") sve dok se ne bi naiSlo na . .
J
,
shvacena kao graniCnik). Iz isfog rliZioga, fmlkcij!L:;<:l
nego sto treba.

]
] ...
char r.ecenica [ 10"] - "D9bcir dan'~;

cout << "ReCenica glasi: ·<< recenic~; 11

cout << "Njena duZina Je u << strlen(tecenica) << "znakova.";


I
7
' [
[
DuZinu niza smo mogli i izostaviti, g, mogli_ smo pisati' samo .

char receni ca[] = "Dobar dan";


[
Prostor neophodan za pam¢enje NIU. graniCnika ee automatski biti predviden, jer ~ podrazu
stringovne konstante sa4rZe granicnik ··
mijeva da [
Poznato je da se, IiaZalos~ svi nizovi inogu iniciializirati soma prilikom defdaraclfe~ Isto. vrijedi
stringove, bez obzira na naefn inicijalizacije. To iskljucuje mognCnnst pisanja konslrnk
i za
ciia poput
[
sljedeee, koje bi mogle biti jako korisne: -
char recenic a[lOO] ;
receni ca = "Ja sam prva reCeni ca ... ";-
[
~
cout << recenic a << endl;

.
receni ca =· "A
cout << recenic a << endl;
ja sam druga reCeni ca ... " ·.
·.-~..
·. [
. ,·· - ~-~~ -~ . .
Navedena sekyeica je naZalost sintaksno neispravna. Sreeom, ipak je; 'uz neznatno drugaeij
moguce postiCi sliean efekat. PretpoSlavimo da smo IlaRisa!i fimkciju kopira j string
u sintaksu
sa dva
[
arametra od,kqjih su oba 'nizovi znakova, koja kopira sve znakove drugog niza u rvi
niz do NUL
gram a, ~ucuJUCi i njega. Takoder pretpostavuno . Je drugi parametar lwnstantan niz, tako
prilikom poziva fimkcije more kao parametar proslijediti stringovna konstauta (diUgl paramet
biti konstimtan niz, s obzirom da fimkcija neee mijenjati sadrZaj drugog, vee samo prvog niza).
da se - ·
ar smije
[
TIJ(!a je

1
posve legalno pisati sljedeee naredbe, koje Ce imati isti efekat kakav bi trebao da una
naredbi koji nije dozvoljen:
:~\~.:~::: ·'.
·
prethodni slijed
[
·char re~eniCa[lOO]; }.:_.;.-;:.·-.,i.~~:~ · ·.
·'
: kopir< !j_strin ?"(rece nica, ••~i~.~"'t~, r"j!C:enica .•. '~);
·
[
cout << r~cenl.C? << end~~---ff-~:~:~.:~,:~·-,o,;:-~~:P.(\. '··
kopira j_strin g (receni ca, ~i}~\ ~a-:;!'!1'
;
· :
Hi:clga recenic a ... ") ; ·
0'
cout << recenic a << -endl;- .,, - ~-- --~-. .:
-·.. •. ._
Razmotrimo kako bi ~ mogia riapi~:ruri'k~jko;.i.raj_string. Vjerovatuo je najoCigl
... _·_:_~ :/ _.-· _ .::~~--

ednija
<;_'l .
D
sljedeea izvedba: · , , "' . . . .
'
void kopira j_strin g(char Odredi sni[], 'ponst char Izvorn i[]) { · D
int i = 0;
while( Izvorn i[iJ. != 0) [
-
?dredi sni !.i)''l;;; .fzvorn i [i]; D
}
J.++; ...,
-t,_·-,. -
Odredi sni [ i] = lJ;
. ~
n ~

. Medutim, ista funkcija ie w:qi.l'~~ini i:Imogo efikasnije, na prili~no neabican naein:


•r· . '"" . '·o, ~· '"
....- • !o:
.
vo~d k<;>Piraj~stri'!"i1~l;''Odredisni[], canst char
Izv'orn i[])
D
-
~nt 1. = .q; ·~· · ~_. ~~ ·, __.- _- ·. _. ·l-
while(O dredisi) .i1i.J'·', ;, Izvorn i[i]) i++;
• u ~

Obratimo pamju da je unutar uvjeta petlje upotrijebljen operator "=" a ne "==". Nije u pitanju
ovom konstrukcijom se i-ti znak niza I zvorni kopira u Hi znak Odredi sni i usputpro
greSka:
vjerava da li
kopirani znak razlicit od nule (u skladu sa naeinom kako se tretiraju uvjeti u C++-u). Ukoliko
nije, petlja
u-
se prekida. Istu stvar inozemo postici i na sljedeei nacin, pomocu for petlje kojaje dvostruk
tijelo joj je prazno, au uvjetu se koristi operator "=" umjesto "==":
o neobiC:na:
&
-

8
U;- •

[}....:
rr-.. ~
vo id ko pir aj str ing (ch ar Od
)
red
for (in t•i ~ 0; Od red isn i[i] isn i[] , oon st cha r Izv orr ii[] ) {
~ Izv orn i[i ]; i++ );

[} . Ova kvi neo bie ni primjeri poslast


Medutim, jos bolje Ijesel\ie je fun
ica su ve¢ini autora udZbenika o
·c-u , a nesto Ijed e o C++-u.
it~ .. kciju ko pir aj_ str ing uopf:e ne
posj~~je u~d~u ~ciju)s;rcpyJiz pisa li, s obzirom daj ezi k C+ + vee
bi? li~ ~e c~t rin g
[} fun kcu a ko pu aJ_ stn ng k?ja_u
OJU SID(} pisali c1sto IZ edukativnih
prin cipu radi istu ~ar ~o ~~isaha
\.. .. potp1mo korektau, pod ulje tom da razloga). Dakl.e, slJedeci plllliJer je
smo ukljuCi:li biblioteku cst rin g u
program:
[} cha r rec eni ca[ lOO ];
str cpy (re cen ica , ·"Jfl. sam
piv
a reC eni ca ... ") i
'"' cou t << rec eni ca << end l;
str cpy (re cen ica , "A ja sam
[} cou t << rec eni ca << eri dl; dru ga rec eni ca .•. ");
!...,;
Fun kci ja str cp y se eesto ~rlsti za kopiranje jed nog niza znakova
.[} 1,...,
kon stru kci ja pos ve legalna:
·
u drugi. Tak o je sljedeea

cha r sl[ lOO ], s2[ 50] ;

G
1-,1
str cpy (sJ ,, s2) ;

Jed ina
G 1...-
niz mo ra {>iti '
programa,
eksrp]ii~lll:o rezerviran za potreb
se
velik da
izv
e smje~ja elemenata· ruza).. an •

D
\..,.
Stringovne konstante se ne
u~etom

g prilmje:r, raz mo trim o slje:dei:u


proslijeden kao parametar:
kojia, lnij<:nJ!~.
.· . if)f'··
obicni (nekon$tantni) niz znakova.
niz a (precizuije, 1\iegov prvi zna k)
.. · .. koj
Na
i je
vo id pro ble ma tic ni_ pri mj er(
0
.,i
cou t << .s << end l;
s[O J ~ 'E' ;
cha r s[] J

0
'"'
Ova kvu funkciju nik ad ne bi trebalo
pozivati kao u sijedeeem primj~
pro ble ma ticn i.:_ pri mje r ("A lma
..
i• •'
·

J
~ Postoji nekoliko razloga zbog eeg
");

a ovo ne treba raditi. Prvo, kako je


po svojoj prir 9di konstanta, kompajl stringovna kon stan ta "Alma"
] citanje, ali ne i upis oduosno izmjenl
mem onJ e koj e je za8tieeno od upis
er ima puno pra vo da je s~~sti ·•l,l.
!.: U tom slucaju, naredba do\tie!e s
dio memorije k9ji dozvoljava
Cb J ,<; E • cil pristupiti podrucju
• a, i program ee se ~erovatuq, "~i
ti". Cak i ukoliko ova dodjehi
"prode" (Sto zavisi i od kompajlera
i od operativnog s1st~a na kojeD;l!ll" pro
] ee biti izmiena sadriaja neeega sto
'neoeekil'an efe kat Na primjer, sup
bi trebalo da bud e ·fiepromjenl)t:,;o
, ,sto
gram izvlsavz), njen efekat
na kraju moze imati posve
' rotno ocekivanjima, naredba ,
for (in t i = 1; i <= 3; i+-+ )
1 ne bi tri put a ispisala tekst "Alma"
problemati~ni_piitnje
r~."Alma' 1 );

na ekranu, vee jed anp ut tekst "Ahna"


nakon prv og poz iva funkcije pro ble a dva puta tekst "Ehna", jer bi
I Moguci sui jos gori scenariji. Na prim
ma tic ni_ pri mj er sad rlaj "ko nsta
jer, pogledajmo sljedeeu sekvencu
nte " "Alma" bio promijenjen!
naredbi:

I
9
,l!I
"

i
......
problem aticni_ primj er ("Alma •) ;
cout -<< "Aima".<< endl;' 1-'
naredha ispisa ·
Ovaj primjer, ukoliko se program n,e "srusi", na veeini kompaJlera dovesee do toga da ee

-f
nakon. pozi.ya funkcije ispisati ·tekst "Eima". Ovo je potpuno neo&ldvano, ier ova naredl!a
eksplicitno
te(u OVOID
.·Isp!suje tekst "Alma". Medutim, veeina kompajl era vi5estruke pojave isle stringovne konstan
svojstvo naziva se §!awrge
primjeru "Alma" ) Cilva na jednom te istom mjestu u memoriji. OVo
)_ 2fr'a (engl. string merging). Stoga, · ukoliko poziv funkcije proble maticn i primj
ce
li stringovne konstante, ta izmjena se odraziti i na sve druge pojave iste stringovne konstant
er izmijeni
eu 1.....
i ~ Ovo bi svakako moglo da hude veoma zhunjujuee, Zbog toga novi standin-d jezika C++ strogo
; propisuj e da je zabranjeno prosljedivati stringovne konstante fuukcijama ukoliko odgovar
paramet ri nisu deklarirani kao konstantni, i kompajl er ne bi trebao da dazvoli ovakve
ajuci formalni
pozive. NaZ;dost,
e. To ne vrijedi
1_,
veliki broj kompajlera (gotovo svi) toleriraju ovakve pozive, uz nepredvidljive posljedic
,. kao Sto je strcpy. Na primjer,
, samo za korisniCki · napisane · fuukcije, nego i za ugraden e fuukcije
sljedeea konstruk cija jenedoz voljena (i upitno je sta hi se njom upp6e
bi trebcio da je dapusti:
trehalo da postigrie), kOmpajl er ne
· f
·strcpy ("abcr' , "def"); f
\,.;;;

upozorenje), uz
Medutim,. ova konstrukcija ce "proCi" na veeini kompajlera (u holjem shieaju uz
···· nepredv idljive posljedi ce koje variraju od mogueeg kralia programa pa do zamjene.
· konstan te "abc" stringovnom konstantom "def" koja ee se odraziti svugdje gdje
konstan ta ·"abc" upotrijehljena u program u Mada nekome ovakav efekat more
sad.rZaja stringovne

djelovati
je stringovna
kao · "zgodan .
f
~
ni sistem. dozvolja vaju,
trik", njegova upotreba je, Cak i u slueaju da je konkretan kompajler i operativ
imati naredba
izuzetno losa taktika koju ne hi trehalo koristiti ni po koju cijenu. Jos gore posljedice more .>J

~
strcpy ("abc"-, "d~fghij k");
•• i';:f>.
.....
U ovom slueajuse duZa stringovna konstan~ "deJ'gh: i.j k" pokuSava prepisati u dio memori
je u kojem
se euva kraea stringovna konst.anta " abc",·.& . ne. Sam.o da ee prehrisati ovu stringovnu
konstantu,. nego
Ce i prebrisati sadrZaj nekog dijela me!I!-orij~ zif\:kojip.e ZnaiDO kome pripada
"abc" rezervirano je taeno onoliko prostoia koJiko.opa zauzima, tako da vee·pros
(za stringov
tor koji
n~ konstantu
slijedi more ~
bezazlen e.
pripaelati nekom drugom). Naravno, posljedice SU: .· potj>uno nepredvidive i nikad da --,v
D
· Funkcij~strca~iz bi1Jliateke cstring slionaje fuukciji strcpy, aline kopira drugi paramet
prvi, nego nadoVezuje drugi patiunetar na kraj stringa predstavljenog prvim parametr
·
9ID. Stoga
ar u
ee u
-
sljedeCi priJnjer ispisati reOenicu "Dohar dan!":

·char recenic a[lOO] ; } D


f strcpy (receni ca, . "D<?bar ");
strcat (receni ca·, 11 dan! n) ;
cout << redmic a « ~ndl;

Cesta greSka kod poeetnika je pisanje konstrukcija poput


D
strcat ("Dobar "', ."dan·! 11
); 0
koje posjeduju
Ovi1 greska je narocito eesta kod korisnika koji poznaju neke druge programske jezike,
funkcije sa kojima se moie ovako raditi. Medutini to nije slucaj sa fimkcijo m
neispravan zbog istog razloga kao u slucaju funkcije strcpy. Nairne, ovaj poziv
strcat: ovaj po~ je
hi poku5ao da
u
na konstanta
nadovez e stringovnu konstantu "dan ! " na kraj ortog dijela memorije gdje se cuva stringov
"Dobar n' cime ne samo .
da hi prornijenio Sadrlaj ove stringovne konstante, nego bi j·prebris ao s3.ddaj
'
ima smisla
Q
memorij skih Iokacija koje joj ne pripadaju. -Stoga se moie zakljuciti da funkciju strcat

D
10
'2 I
IJ ..•
-IJ -- ·..rrv. i ,-. '
r.J•--.J.· I. '
-~v u
- J
!/c.....? ;.):·.---".1.1-~-~:.h' ! : Jr.\(:1 {""
11·•
koristiti samo uk:oliko je njen prvi argument niz koji vee sadrZi. neki string (eventualno prazan)
dovoljno veliki da more prihvatiti string koji ee nastati nadovezivanjem. ·
i koji je

-n _Posljednjastvar o_~ojoj eemo g~y~ti u~?yom po~aylju


da Je potrebno p.apravttJ. program kOJI ce traziti od konsnika da .
f.,li Zamislimo
da Iozinka
-~
nije ispravna, 6d korisnika treba da se traZi novi unos, sve dok lozinka ne bude isp~ Pretpost
avimo,.
-o
·~
na prilrijer, da lozinka glasi "HRKLJUS". Prir6dau pokuSaj bi bio da probamo napisati program
isjeCak poput sljedeeeg:
ski

char lozinka [100];


{] do (

- cout << "Unesi lozinku : ";


cin.ge tline(l ozinka , 99);
-o
...
if (lozi_nk a != "HRKLJVS"-) cout << "PogreS:na lozinka !
} while( lozink a != "HRKLJ
,, US");
11
.;

{] Mooa ee ovaj primjer proci ~taksno, on neee raditi u skladu sa oCekivanjm'ul. ·N~iwe, ki.Jko sn
stringovi nizovi, na niih sene mogu nonnaluo primjenjivati operatori poredenja "<", ">",
"<=", ">=",
,. "--• i • !-", nego se poredenja moraju vrSiti element po element Dodu8e, kasnije eemo
vidjeti da
operatori poreiienja u principu prihvataju i &itave nizove kao o'jierande (to je razlog zbog eega
{] primjer sintaksno ispravan), ali sen tom slueajn ne porede sadriaji nizova ne o adrese
je gomji
d'e su nizovi
smje5teni u niembriji, sto si o ni ·e ono oga. unesenu lozinku. moramo porediti znak
"' po znak sa reljenoJ;Illozinkom da bismo ispitalijednakost. Na primjer, mog)o hi se raditi ovako:
-o
...1
.. char lozink a [100];
do { -~ ·, •..

{] cout << "Unesi lozinku : "; ,,,


cin. get line (lozink a, 99}; ... ,. _-.:~,-!_-~;:· .·~_:, ~,
,i int dobra lozinka = 1; . ·'·'
for(in t i-= o; i < 7; ,_ i++)-- ~-.r, · .-.~:{\
{] · if(lozi nka(i] != "HRKL JUS"(i: J4Aobr a_lozin ka
if (!dobra lozinka ) cout ,4'<. ,n•oii'f~sn" lozinka ! ";.,
0;
} while (! dobra_ Iozinka ); · ·,.c, ' .. ·· ··:.>::. ·
"' · •

0 . · _Ne hi bio nikakav problem napisati fiui.kciju koja hi za dva strings prosljedena kao paramet
da li su jednaki iii irisu (i vratila odgov'?J' kao rezultat), Sto Cit;llac more uradiq kao korisnu
rl is),itala
Vj~bu.
' Medutirii; takva funkcija vee postojiugradelia u biblioteku cstring pod inienom /strcmp j.Ova
0
'
vraea kao rezultat nulu ukoliko su dva.stringa prosljedena kao parametri jednaki, a u ..suprotn
neki broj razlicit od nule (ne nu.Zno jedinicu). Stoga bismo prethQdlrl_prlmjer mog)i
funkcija
om vraca
jednosta vnije.
napisati ovako: · · · ..
0
'
char lozinka (lOO];
do {
cout
D cin:. ..getline
<< "Unesi lozinku : ";
(lozink a,. 99); ·, , ..
if(strc mp{loz inka, "HRKLJUS''} != 0) cout << "PogreS na lozink a!";
) while (strcrn p(lozin ka, "HRKLJUS") != 0); ..
J Obratimo paZ!lju da se uvjet "! = o" more. izostaviti s obzirom na to kako funkcioniraju
uvjeti u
jeziku C++. Bitno je da za jednakost stringova svi znaci moraju biti doslovno jednaki,
l;j. moraju se
podudarati kako velika i mala slova. Stoga, stringovi "HRKLJUS" i "Hrklju s" nisu jednaki.
Takoder, ~
J duiine stringova moraju biti jednake, tako da stringovi "HRKLJUS" i "HRKLJUS " nisu jednaki.

Funkcija strcrnp radi znatno vise od obicnog testiranja stringova najednakost: U slucaju
daje prvi ; /
J string /eksiko aftki (g. po abecednoin poretku is red dru o stringa, funkcija strcmp
vraca kllo
rezultat neki broj manji od nule· (standard ne proovida koji, ali vidjeeemo . a z og nacma
·o se
funkcija strcmp obicno koristi, to nije ni bitno). U slucaju daje prvi string lek5ikograftki
I iza drugog

11
I
1
..
, stringa, fimkcija stmnp vraCa kao reznltit uekj broj yet; ad nule Ovo je naJ"bolje ilustrirati na
konkretnom primjero: [
'

·char rijecl[SO], rijec2 [50];


cout << "Unesi dvije rijeci: ";
cin >> rijecl >> rijec2;
[ '
if.( !strcmp(rijecl, rijec2)) cout << "Rijeci su jednake\n";
else {
cout << "Rijec " << rijecl << " je po abecedi "; [.
if(strcmp(rijecl, rijec2) < OJ cout << "ispred"
·el.se cout << n iza ";

}
cout << " rij~i • << rij_ec2 << endl; [
'
"" _Funkcija st.rcmp zapevo ne vrSi p~r~enic:,.~~ po abecedno~ poretku, nego po poretku ASCII
Sifti; a libeceaili oredak e rosto aa
sl edica ctnJemce ASCII sifre rastu po abecednom poretku.
[J
Medutun, po ASCII tablici sva velika slova dolaze ispred malih ova, o se string "Dami.r"rialaZi
pop<iretku iSpred stringa "DAMIR". Stojejos gore, string "Drvo"-nalazi se (zbog velikog slova "D") po
p<:>retku ispred stringa "cipela" .. Iz istog razloga, svi stringovi koji poCinju cifranul nalaze se po 0 '
poretku ispred stringova koji poCinju slovima Neke .. verzije kompajlera za C+* .poznaju i funkciju
{ stricmijkojaje potpuno analogna funkciji strcmp, aline praVI DikllkVU i'azii.ku izmedu velikih i malih
slova. lp!ik, ova funkcija nije staudardna ujeziku C++. Stoga, ukoliko :lelimo da poredimo stringove po
VD
abecedi ne. praveCi. razliku izmedu malih i velikih slova; najliolie je prije pnrettenja sya mala slova u
stringovima pretvmjti u Velika, ill obmuto. To moZemo lako uCiniti koristeCi. a#etilw nag

velikli:· · · ·
w*oypiw_
·
YD
fujeduo:stirna_ Na primjer, sljedeCi. primjer ee pretvori)i sva mala slova u stringovnoj promjenljivoj s u

for.(int i = 0; i < strlen (S); i;!;,+l


if(S[·i] >='a' && S[i]-<= 'z''}lS,[i] +='A'- 'a';
!< . .
q
'
Alternativno, mo:lemo koristiti i funkclju[toupper ]iz biblioteke cctwe (ctype.h u starijim.
verzijama kompajlera) kojp. mak pros1jed~-kao argument pretvara u vellko slovo ako se radi o malom
si0 vu, ainaee ga ostavlja neizmjenjenog (analogna funkcija[t6Iow~y iz iste biblioteke vrSi pretvorbu u
n •
~slova): ·

·for(int~i.= O; i < strlen(S); i++J S[i]·= toupper-(S[i]);


. · .
n '

Jos jedan problem ,k;oji sejavlja prilikom upotrebe funkcije strcmp na na5im podruCjimaje lito ova·
funkcija ne zna ispravno porediti ·stringove u kojima se javljaju ~a slova poput "{;", "s" itd s obzirom .
n '
da oni li.emaju jedinstvene sifre po ASCII standardu. OvaJ problem se sve do nedavno Ijeliavao JJ;,& rame
ne ba5jednostavne naCine. Tek u novijim staudardimajezika C++ uvedene sui funkcije koje rade slieno
poput funkcije strcmp, ali koje vode raeuna o regionalnim specificnostima poput makova koji se jayljaj_!l'
u nacionalnim (neeugleskim) jezicima u skladu sa regionalnim postavkama raCunara na kojem se ,
n
program izvrliava Ove fuukcije su nesto komplikovauije za upotrebu i zahtijevaju izvjesne predradnje{'
tako da o njima ovdje neee biti govora .
..
,.;
'
u
u~.

D:

12 ..,,
-If ..::·

-~ ,.
v. . .
' VISEDIMENZIONALNI NIZOVI
-n
' ObiCni. Gednodinienzionalni) nizovi pogodni su za predstavljanje podataka koji se mogu urediti u

-n
<
neki slijed,. kao Sto su npr. troSkovi neke fabrike
kadajednodimenzionalni
mjesecim.:. za jednu godinu.
Na

-0.
-0

-0
-:i ---
·, ...

Ovom deklaracijom smo definlrali novi ti Red, ko'i predstavl"a niz od ndjvise 5 ~ijelfh qrojeva (pri
-0 tome i~·samo definiranno vi tip, aline i konkretlin primjerakpromjehljivih tog tipa. na ouma mozeroo
obavljati· neke•'operacije). Ovakva deklaracija· nani omogucava da definiramo konkretne p:tiriijerke
• promjerujivih tipa Red, na primjer: . · · ·. ·
-0., L~ed R1 ,· Rz) . '

iJ

~0 '·· '·-;

.,-·.
·. ~&~
·:..:;>
·}1:1. •

Ovim smo definirali promjenljivu Tabela ko~.pr!:_dstavlja niz od najvise 4 elementa, nazvanih
-lJ Tabe1a[OJ , Tabela[1]· ; Tabela[2J i Tabelaf3l;.Medu~ 5vaki Olfovih'elen'J.enataje tipaRed,
• k2ji predstavlja niz od. najvise 5 cijelih broj~af Stoga promjerujivu Tabela moiemo poSillll1hu:i kao

-o

dvodimenzionalnu tabelu (niatricu) koja se slistoji od 4 reda i 5 kolorui (s obzirom da svaki rea ima 5
elemenata). Kako su redovi tabele (.odnosDo clementi niza Ta}?ela) semi po sepi iednodjmenzionalni
nizovi (tipa Red), to pojedinaCnim elementima syakog reda'mohim o prishzpiti navodetijeft jos jednog

{J lndeksa. Na primjer, treci red tabele Tabelaglas l. Tabela [ 2) (s ob.zirom da ind~ksi pocinju od nule),
'dok pojedinaCrii. elenienti treeeg r¢0a t,ID~le .Tabela' glaseJ;;be la(2J [~ Tahela[2l [1J,
Tabela [2) [2] i Tabela [2] [3]. Ovo je ilustrirano sljedeeom ~m; .~ k_QJpj je: red· Tabela [2]
"
D

osjenCen,a.
- pojedinaCni
. element Tabela [2] [1] dvostruko osje'ncen:
'

Tabela 0
. . '
· · ·

u
'
2

n
,
3

t 0 1 2 3 4 +--' indeks
kolone
indeks
reda

Niz definiran na ovaj naCin, g. kao niz obiCnih nizova, naziva se dvwjirrzeuziona/n{ niz, a Cesto se
susreee i izraz matrica, zbog analogue 5trukture podataka u matematici. OCigledno, dvodimenzionalni
· nizovi su naroCito pogodni za predstavljanje podataka koji se mogu organizirati kao tabele sa viSe redova
--~

1
~.
l
i vi8e kolona. §toga, CH omoSl!:Cl!va da se dvOdimenzionalni
·[
ilizovi definiraju i nep~r.eano, bez
pre!hodnng cWininuija poseb nog il!Zovnog tipa koji J>redS!av!ja
iza navodlmja imena proinjenljive potrebno je navesti dva para
pojedinaene iedov e taliele:...Z!l tu .svrhu,
uglastih zagrada i u njima odgovarajuee [
dimeftzije (koje, slicno kao
kod joonodiiD.enziorialhlh ilizova, moraju biti konstante). Na
primjer,
promj enljiv u Tabe la mo@i smo nepilsriidno deklaiirati ovako

I int Tabe la [4] [5] ;(


:
r
Smisa o ove deklaracije je isti kao i prethodne deklaracije u kojoj
ga iskoristili za deklaripmje promj~jive Tabel a. Nairne, ovom
smo prvt> definirali tip Red; a zatiin
deklaracijom Tabe la postaje niz od
[
najviSe 4 eleinenta u kojein je svaki element niz od najvise 5
cijelih brojeva, Sto moZe!no tumaeiti i kao
tabelu sa najvjSe 4 reda i najvise 5 killona. Bez bzira na nacin
za
. a, sam. se!>e se onaila kao .. . . enzion
deklaraci"e, ·svaki red dvodimenzi<>!l3lnog
mz, i kao takav se moZe koristiti svugdje
[
gdje je z-Voljena upoireba jed:iJ.odimenzionlllnih nizov a

Rad sa dvodimenzionalnim nizovima cemo prvo ilustrirati na


je potrebn.o napraviti progl-am koji traZi da se unesu ocjene za
jedno m jednostavnom prinUeru. Neka [
gnipu stud~ iz nekoliko predmeta, a
. koji Zlitlm. ractma i ispisuje prosjeenu ocjenu za svakog studen
- · dvocjimtmzioillilru niz o~j e~e koji cuva tabelu ocjena studen
;koi9iie·p~ete. Program d~onstrira tipican naein manipulacije
ta posebno. Za tu svrhu definiran je
aia, i Ciji iedo:vipredstavljaju stiid¢nte, a
kojem se l(on5te ugnjeZdene f'orJXl..!!i_titi- jedna for petlja unutar
sa dvodimeniionahiiin: niZOvima u
c
druge). Uimtrasnja petlja broji kolone
niza, a vanjsk a petlja broji redove:

#incl ude <iost ream >


0
'• #incl ude <iom anip>
using name spaoe std;
cans t int MaxB rojSt udena ta = 50;_
cans t int MaxB rojPr edme ta = 10;·
int main () (
int BrojS tuden ata, BrojP rectm eta, Stud ent, Predm
int Ocjen e[Ma xBro jStud enatd f[Ma xBro jPred meta] ; et;
cout << "Kol iko ima stude nata: · "; ·
cin >> BrojS tuden ata; ·
cout << "Kol iko ima predm eta: ";
cin >> BrojP redm eta;
for(S tuden t =·O; Stud ent< BrojS tuden ata; Stude
nt++)
cbut << "Une si ocjen e •Za stude nta " <<St uden t +
for(P redm et = 1 << ":\n" ;
0 ; Predm et < BrojP redm eta; Predm et++)
cout << " Predm et " << Predm et + 1<< ": ";
cin >> Ocje ne[St uden t] [Pred met];
}
cout << endl;
)
cout << "B.roj .. sttide nta ·. Prosj eCna ocj ena \n";
'cout << n_.:_ _____ __ ..,.___ ----- ----- ----- -\n" ;
for(S tuden t = 0; Stude nt < BrojS tuden ata; Stude
nt++)
doub le Suma = 0;
for(P redm et = 0; Predm et < BrojP redm eta; Predm
et++)
Suma += Ocje ne[St uden t] [Pred met];
cout << setw( 8) << Stude nt + 1 << setw( 20) <<
setpr ecisi on(2 )
<< Suma I BrojS tuden ata << endl;
}

Probl em sto se dimenzije niza moraju znati unaprijed (s obziro


m da moraju biti konstantue). Ijeilava
··· se slieno kao kod jed:iJ.odimenzionalnih nizov a tako Sto se predv
dimenzija koje se mogu oeekivati prilikom koriStenja progra
ide dimenzije koje su veeeod najveCih
ma. Pri tome, treba biti oprezan zbog

2
0
-n.
Cinj~<;e da dvgdimenzionalni nizovi znatno vi5e tro5e
IDeJl10riju nego oiJieni niz<)vi. Na primjer,
· dy~imzionaliii riii cijelih brojeva od 200 · redova i 100 kolona
u suStini. Zahtijeva proStor za
m~oriranje 200 ~ 100 = 20000 cijelih brojeva! Zbog toga, sa diinenz
ijama dvodimenzionalirih nizova .
nikiida ne treba pretjerivati.
·D Neki programski jezici, kao lito je npr. Pascal, dozvoljavaju da se indeks
piSu u jednom paru uglastih zagrada razdvojeni zarezom, npr.
i viliedi.menzionalnih nizova
·•
-D T~1;
.• litobi trebao da bude sinonim za Tabel a[2J [1]. Na llalost, ova
{] iSpraVna, u jeziku C++ neee Pt-oizvesti oeekivario dejStvo. Nairne, izraz
·- -~· . . . .
-' -· .
pri)nje na vee vise puta spomin -.-. '
konstrukcija, mada je sintaksno
u zagradi 2, 1 bi6e shvaGen kao
..
janog i ~po zhi cuvtiJiog" zarez-operatora: Rezult at ovog. iZraza
.
-''

bice 1,
tako". da Ce koJistrukcija Tabel a[2i1] biti zapravo shvllljena kao Tabel
-H
~
Tabel a !21 !11 ~ Na ovajde talj trebaju naroCito da pare korisni
Iieki sliean programski jezi.k. . ·
a[1], a ne kao
ci koji su prije C++-a konstili Pascal ill

{] Kako je svaki red dvodimenzionalnog niza obiCni jednodimenzi


dvodiinenzionalD.og niza mogu prosljedivati kao parametri funkci
onalni · niz, to se redovi
. jednodimenzionalne nizove odgovaraju6eg tipa elemen;rta. Na primje
jama koje kao parametre oeekuju
r, neka je data sljedeea funkcija,
-0 koja iSpisuje eleinente jedil.odirmmzionalnog niza realnih brojeva:

void ispis i niz (doub le Niz [h .. int N) {


• for(i nt i-= O; i < N; H+).''c 6i'£t « Niz[i l « endl;
{] . .' );.
·~;

' Ukoliko pretpostavirno da je data sljedeea deldar~~ija:

D
,'- .i·
··-.·;
doubl e A[lO] [10]; >· -,z_
j '>.;f.: ..

n
' ispis i niz(A [3], 10); ~
eti red tablice realnih bro"eva 1\. (ne

D ispisi ::::niz (A[SJ , 10); ;:/

SljedeCi poziv medut im nije ispravan, jerfull kcija ispis i .niz oee~j
' e niz rea/nih brojl!yfl, dokje A niz

n nizova rea/nih brojeva:

ispisi _niz( A, 10);

0 Da bi pozivi poput retho o o e n raviti funk · ·u koja kao arametar


oeelaije upravo niz nizova tj. dvodimenzionalni niz). Primjer takve
ispisuJe e emente dvodimenzionalnog niza prosljedenog kao parame
funkcije je slj cija, koja
tar red po red, pri eemu su elementi
0 unutar jednog reda razdvo jenijed nim razmakom:

void ispisi - tablic u(dou ble Tab[] [10], int M, ·


int N) {
·

for(i nt i-= O; i < M; i++) '[

0 for(i nt j = 0; j < N; j++) cout << Tab[i ] [j]


cout << endl;
<< endl;

0
)

Ovakvu funkciju mollemo pozvati na sljedeCi nacin:

ispis i_tab licu( A, 10, J.O);

]
3
..
Bitno ·e uoCi.ti "edno o ·een·e kod funkci"a ko"e kao ~~e pli!;iv$ ju dvoditnetizionlilne
·l,lizov~Naiine,. mada prva dimenzija niza mo.ze a i ncfmor abiti zildaria
J>rilili;~ cldaracije fonnlilnog
palaitie tra u zaglavlju funkcije, druga dimenzija niza o{wyepw mora biti ifadima,_ Drugim rijeCima,
zaglavlje funkcije ispisi tablic u nije moglo izgledati ovako:

X void ispisi~tablicu (doubl e Tab [] [], int M," int N) [


Postoje dva razloga za .ovo ogranieenje: formaln i i su8tinski. Sa formaln
og aspekta, funkcije
dopuStaju da njihovi formalni parametri blidu nizovi nepoznirte duZine, ali tip
pOtpliUosti poznat. Kako su dvodimenzionalni nizovi zaprayo nizOvi .nizOvll
elemenata niza mom biti u [
"eli::ti:J.ent" ponovo niz), njihova "duZina" (koja zapravo predstavija broj redova)
(g. nizovi Ciji je svaki
moZe ostati nepoznata,
ali. tip tijihoVih "elemenata" · (koji su ponovq nizovi) ·lllora biti u J><itpUJiosti
nedpl,!D1ica, sto zaprilvo znaei da i broj elemenata sviikog "eleinenta" f\l<>.m bl.ti'P.i)Z
pomat, bez ikakvih
r:tat, a to je upravo broj
[
koiona izvomo g dvodimenzionalnog niza. OVo moZda z\iuci zapetlj3ito,
ali· postaje jasuije ukoliko
dvodimeD.zi.Onalni niz A definiramo posredno, uvodeei pom.o~tlp.R~d: ·
· [
typed ef double Red[lO ];
Red A[lO];

i ukoliko funkciju ispisi tablic u definiramo da ima sljedeee zaglavl


[
je, koje Je u su8tini
ekvival~tno zagJavlju koje sino prvo napisali:
void ispisi _tabli cu(Re d Tab[], int M, int N)
[
~"

p ovom ~ucaju, formalni parametar Tab je niz iz~fjbinate duiine, ali Ciji 5u elementi tipa R~ct; koji je
potpun o poznat (i predstavlja nizovni tipJJrl..nlgyiSe 10 realnih brojeva) u
. Pored navedenog razloga forn;talne prirode, koji se mogao prevazici da

parame tara koji predstavljaju dvodimenz!onahri,)iizovi .sa obe nepoznate


su autori jezika C++ to
zeljeli, postoji i drugi razlog s.ustiiiske prirode koji.je ipak doveo da se zabrani
deklaracija formalnih
dimenzije. Nairne, eov.jek
u
;

obieno zamislj a da su elementi dvodimenZionalnih nizova razmjeS


teni kao elementi neke
dVodimenzionalne tab/ice, kao u sljedeeerrl." pilm.jeru koji ilustrira kako se
elemen ata nekog dvodimenzionalnog niza (reC:imo A) sa 3 reda i 4 kolone:
obieno zamiSija raspored
.
0
0 I 2
0 A[O][O] A[OJ[l] A[OJ[2] ;-\(0][3]
3
0
l A[l][O] A[l][l] A[l][2] A[1][3] 0
2 A[2][0] A[2J[l] A[2][2] A[2][3]
n
Medutim, fi1emorijl! mCnnara nije dvodimenzionalna nego jednodimenzionalna,
mogU. redati jedino lineam o, odnosno jedan za drugim. Tako je, u suStini, pmvi
u memoriji predsti vljen sljedeeom slikom:
i elementi se u memoriji
raspored ovih elemenata n
0 I 2 3 4 5 6 7 8 9 10 II B
A[O][O] ~[O][l] A[0][2] A[0][3] A[l][O] A[l][l] A[1][2] A[1][3] A[2][0]
A[2][1] A[2][2] A[2][3]

Vidimo da se element za koji zamiSljamo da se nalazi u i~tom redu i j-toj


Q
J<:oloni zapravo nala2:i na
(4i+;)-toj pozicij i u sekvencijalnom poretku elemenata ii memoriji. Genemtiziranj
moZeillo zakljuC:iti da se element u i-tom redu i]-toj koloni dvodimenzionalne
em ovog primjera lako
tablice koja imaM redova D
4 n
0
o.

'

i Nkolona Dilll!Zi na (l/-i +J}toj poziciji u S!lkv~cijalnom poretku. I>~e, da bi se pristupilil elementu
u
se
i-tom redu i j-toj kokmi; brojkolon a N niora biti FOznat (da. bi izraCunao i=Jz N·i+J), rnada broj
0 redovaM ne mora da bude poznat!

Bez obzira ria raz!oge (formalne iii suStinske), fimkcija koja ima formalni parametar tipa
D
.;
dvodimen zionalno niza prihvatice kao stvarni · iirametar JSkJ.- ·
deklarirana druga dimenzija slare sa gom . imennjom naiJeaeiiiim u
dvodinlellrioii.alni niz Cija se
definiciji formalnog parametra. ·
I'retpoStavimo, na primjer, da imarno sljedeee deldaracije:
iJ
~
double Tab1 [10] [10]; Tab2 [20] [10], Tab3 [10] [20];

prva tri su legalna, dok Cetvrti


iJ Uz ovakve .deklaracije- od slje<leea
nije dozvoljen Ger ~" .deklanra
--
na
4poziva fimkcije
-'. '

druga
--.'

dimeizilja
-
•'
ispisi_t-ablicu;
niza Tab3.
.
koja
' . -
'

iznosi 20 ne slaze sa
.
ocekivano m
~
drugom dimei1ZI;om fonnalnog paraDJ.Wa Tab koja iznosi 10). :Primijetimo da prvi poziviSpi suje samo
prvih 5 redova i 6 kolona tabijceTa bl od uklipno 10 redova i 10 killona (Sto ujedno ilustrira kakvaje
{] svrha postojllnja pariinleta£a M i N, pog~to~o parametra N s obzironi da druga di_menzija mora biti
... fiksirarla u deklatacij i paial:tietra): ·

-o
.,;
ispisL_t ablicu(T ab1,
ispisi tablicu( Tab1,
5, 6);
10, 10);
20, 10);
ispisi-,t ablicu·( Tab2,

-o

ispisi::: :tablicu (Tab3, 10, 20); j(

Postoji doduse jedan indirektan i mnb~ preporucl jiv nacin da se ipak napravi fimkcija
ispisi-tab lieu koja Ce prihvatiti dvodinl~ohalni niz cija ni jedna dintenzija nije fiksna (dakJe,
za
-0
~
koju ee sva 4 prethodna poziva biti posve.legiiina). Naime, poznato je da
mogu da rade sa tipovima koji nisu unaprijed poznati. Stoga, mozemo da
(sablonske) fimkcije
- sljedecu generiCku
fimk~iju:__
-o t~late <typenar ne Tip> ;, . .
•,,,
void ·ispisi_ tablicu (Tip Tab [], '1nt M, · int N)
.;

for(int i = 0; i < M; i++) { .·i;~i ,,


-o
.,;
for(int j = 0; j < N; j++)' cout « Tab[i] [j] <.< encil;
cout << endl;

{]
.,
Ideja ove fimkcije je .da ukoliko joj kao prvi parametar proslijedinlo npr. dvodinlenzionalni niz

-o Tab2, tip Tip Ce se identificirati sa nizovnim tipom od najvise 10 rea/nih elemenata Ger je Tab2 niz
20 takvih nizova), Sto se uklapa u ~ion, i fimkcija se more izvrsiti. Oy,akvo rie"@je iweffl~odn<;_iz
mom se kao prvi parametar proslijedit i
od
dy~ ,.
ne
" razl9!!.a. f.w!, o.v.ako napisanoj fimkciji ispisi_t ablicu
-=samo dvOdii:nenzionalni_niz, nego i bilo kakav obiCnijednodintenzi~alni_.!JU; .(pri ee
-{] eemu
identificirati sa tipom elemenata tOg niza), nakon eega ce fimkcija da "padne" pri pokuSaju da
se tip Tip
se
,.. parametar Tab indeksira sa dva indeksa. PJngi
raziog je Sto se pri regularno m pozivu fimkcije nad
dvodintenzionalnirn nizom tip Tip identificir a sa citavim nizovnim tipom, d<ik ne postoji nikakav nacin
-o.,. da saznamo kakav je tip individualnih elemenata tog niza, Sto more jako ograniciti primjenu fimkcije
(npr. ne postoji naCin da unutar fimkcije deklariram o neku lokalnu promjenlj ivu Ciji se tip stare sa tipom

..-o
individual nih elemenata niza.}.

Tehnika prenosa viSedinlenzionalnih nizova kao arametara u ci" e ilustrirana -e kroz sljedeei
pnmJer. · se o istom prinljeru za raeunanje prosjeCnih ocjena za skupinu studenata koji je v 10
a u
razmotren, samo Sto je ovaj put napisan na modulara n naCin, uz upotrebu fimkcija i prenosa parametar
n
fimkcije. Funkcija UnosOcj en a unosi ocjene za sve predmete u dvodim!l!lzionalni,Piz koji je proslijede
kao parametar , dok fimkcija Prosjek raCuna · rosjek ocjena za "ednog studen Cije su ocjene
prosljeden e kao parametar. Obratite paznju na upotrebu rije . conse deklaraciji formalnog parametra
fimkcije Prosj ek. Naime, kako se nizovi uvijek prenose po referenci (sto omogu¢ava promjenu

5
. Lr
odgovarajuceg stvamogparametra nad kojim je funk:cija pozvim
a),.veorna lijepa p_taksa je sve parametre
_mzovnog tipaia koje se ne. oCekuje da ih funkcija pronnjeni deklar
naCin ee komiJajlei prijaviti greSku u slueaju da funkcija pokuS
parametra (stO programer IDOZe neS\jesno u<furiti), lfune se oJakSa
irati kao konstantne parametre. Na taJ
a da promijeni sadrZaj odgovarajueeg [
va otkrivanje greSaka U progra!lJima
iincl ude <iost ream >
. iincl ude <iom anip> [
using name sPace std;
cons t int MaxB rojSt udena ta = 50;
cons t int MaxB rojPre dmeta = 5;
[
void Unosgcjena(iQ~ Tabe la(] [Max BrojP redm eta],
int Brojs tuden ata, int Broj\ >redm eta) {.
for.( int stude nt = O; ·stud ent < Brojs tuden ata) Stude
[
nt++r {
cout << "Une s.i.oc jene za stud enta " <<St uden
t+ 1 << ":\n" ;
for(i nt Predm et = 0 ; Predm et < BrojP redm eta; Predm
cout << n Predm et " << Predrnet + 1<< "· ";
et++) · { [
cin >> Tabe la[St uden t] [Pred met];

cout << endl; [


doub le Pros iek(c onst int Ocje neJed nogS tuden ta[],
doub le Suma 0;
int N) { [
for(i nt i = 0; i.< N; i++) s~". += Ocje neJed nogS
retur n Suma I N; tuden ta[i];
)

int main ()
0
int BrojS tuden ata, BrojP redm eta;
int Ocjen e[Ma xB"ro jStud enata ] [Max BrojP redm eta];
cout <<. "Kol iko ima studenat~'.: ";
0
cin >> BrojS tuden ata;
cout << "Kol iko im9- predm eta! ,'';
cin >> BrojP redm eta;
Unos Ocjen a(Ocj ene, BrojS tuden ata, BrojP redm eta);
0
cout << "Broj stude nta Prosj eCna ocjen a\n";
cout << u ____ ..:. ___ "'!"'_____ ----- ----- ----- -\n" ;
for(i nt Stud ent= 0; Stude nt < BrojS tuden ata; Stude
cout << setw( S) << Stud ent + 1 << setw( 20) ·<< setpr
nt++)
0
ecisi on(2 )
)
<< Prosj ek(O cjene [Stuc ient] , BrojP redm eta) << endl;
n '

u{t
'

I typed ef doub le Matr ica [10] [1~];


n
-
'
definira '!IOVi tip Matr ica koji predstavlja dvodimenzionalni niz
redov a i namfe IO koTona Ovaj tip moZen:!o iskoristiti za defini
deklaracijom
matricu) realnih bro "eva sa na"vi8e 10
ranje o toih matri ca Na primjer,
0-
l_Ma trica A, B, C; l 0
deklariramo tri konkretne pron:Uenljive A, B i C Cijije tip dvodim
enzionalni niz realnih brojev a Takoder
je moguce novodefinirani tip Matrica iskoristiti za deklaraciju
primjer, sljedeei prototip funkcije
formalnih parametara fuiikcija Na (f
6 fr '
..·· r
Li
{].
void Ispis iMat ricu (Mat rica A, int M, ·int N).

D ·•
·potpu no je ekvivalentu{ sljedeCelll prototipu: -~
-~-
void Ispis iMat ricu( doub le A[lO J[lO] , int M, int
N);
f isani ristup je narocito korist an ca"evima kada se u progra mu koristi vise funkcija koje kao
param etre pririJ.aju dvodimenzionalne nizove iste vrste.
Na taj nacm se omogu_ va konzis tentno
~l tipizirail.je p3t$e tara u sVim fuDkCIJapla. Tako, u slueaju
da se npr. promi jeue deklarirane dimen zije ·
:~tffij~~t!-~aJ~::; )~ il= ~Je:ee==~~%~o~ ~d ~~~JJ~:~~ :a!:~~~~ V
1 0 0
matri~e istci~ fon:i:t!!Ul {broj red ova i kolon a takode r zadaje korisn
{] unesef
ik), a zatim ra~ i ispisllje zbir dvije
mamce.. Obratite paZn.ju na funkciju 'unes iMat ricu koja prikazuje korisniku infonnacije o
ie
- ind~k~m~ }~ i kolone eleme ritako ji se unosi na naein kako je
od jedmiee naville): ..
uobieajeuouniatematici (indeksiranje
{]
#incl ude <iost ream >
'
#incl ude <iom anip>
{) using name space std;
' cons t int MaxM = 20;
cons t int MaxN = 20;
{] typed ef doub le Matri ca[Ma xM] [MaxN];
' void Unes iMatr icu (Mat rica A,:'(;j:nt M,- int N) {
-Q for(i nt i = 0; i < M; i++'lT;.'"''
for(i nt j. = O; j < N;'jrl '+J {
• cout << " Eleme nt". {"' •<< i + 1 << fl·fl << j + 1 <<
II) : i
cin » A[i] [j]; ·' ' U

D ,
void Saber iMatr iCe (cons t Ma.tric:;l A, co~st
D

int M, int N) { ··W
for(i nt i = 0;_ i < M;· i++)._ '.
Matr ica B, Mati ica C,

for(i nt j = 0; j < N; j++) .

D
.
)
C[i] [j] = A[i] [j] +.B[i ] [j];

void Ispis iMat ricu (cons t Matr ica ·A, int M, int
N) (

.0
for(i nt i = 0; i < M; i++) {
for(i nt j = O; j < N; j++)
cout « setw( 8) « A[i] [j];
cout << endl;
0-

)
)

int main ()

0

int BrojR edova , BrojK olona ;
Matr ica Ml, M2, M3;
cout << "Une si broj redo va,i broj kalon a ni&tr
ica; ";
cin >> BrojR edova >> BrojK olona ;
0
'
cout << nune si prvu rnatr icu:\n ";
Unes iMatr icu(M l, BrojR edova , BrojK olona );
cout << endl << "Une si drugu matr icu:\ n";

a Unes iMatr icu(M 2, BrojR edova , BrojK olona );


SaberiMat~ice(Ml, M2, M3, BrojR edova , BrojK
cout << endl << "Zbir ovih matr ica je:\n ";
olona );
Ispis iMat ricu (M3, BrojR edova , BrojK olona );.
] )

] .,,.
7
l
.[ ,
Fl,IDkcija SaberiM atrice u ovom prograniu prima 3 matrice ~~ Pcl!l>iffi.!!#e: A i B. p~~vljaju
matrice koje se sabiraju, dok c predstavlja matricu u koju ce biti smje8ten iiiiicunati zbir dvije matrice.
Bilo bi mnogo ljepSe kad bi fuukcija SaberiM atrice mogla da vrati zblr.niairica kao rezulta( g. kad
bi
[
njen prototip mogao izgledati ovako:

Matrica SaberiM~trice(const Matrica A, const Matrica B, int M, int N); [


Pri tome bi poziv fuukcije SaberiM atrice trebao izgledati ovako:
M3 = SaberiM atrice(M 1, M2, BrojRed ova, BrojKol ona);
[
. Na Zal.ost, · fuukcije u jeziku C++_ ne mlfw vractiti nikakve nizove kao rezultat. pa tako
visedirilenzionalne nizove. Stoga, ovme de aracije i ov8kVi pozivi nisu moguci. (bar ne sa ovako
de:finiranim tipom Matrica) . Kasnije cemo vidjeti da se ovaj pro!Jlem mozerife8 iti upotrebom tzv.
ni
[
ldasa (g. d_yfinjrnojern matrice kao klase, a ne kao niza), jer za razlikti od ~va, fuukcii\j...momvra6 ati,,.
_kl§ ~o zywn!lt, [
'
Dvodimenzionalni nizovi se takoder mogu inicijalizirati prilikom deklaracije. Pri tome se
inicijalizaciona lista mora sastojati od listi koje sluze za inicijalizaciju svakog ·od redova posebno. Na
prmuer: ·
[ ,

int A[3] [4] = {{3, 4, 2, 5), {4, 1, 2, 3), {3, 1, 0, 2));

Inicijalizacione liste za dvodimenzionalne nizove.4e,~to se pisu takq da se svaka od listi koje sluze
za
c ,
inicijalizaciju pojedinih redova pise u novom rMir Na taj nacin inicijalizacija postaje preglednija,
matriena struktura dvodimenzionainog niza uocljivijli:' · · ·
a
0-
int A[3] [4] ~ (,{3, 4, 2, 5), \ V--
.
{4; 1, 2, 3)·,.
{3, 1, o, 2));
.,
.
. 0
Kao i u slucaju jednodimenzionalnih nizoya, ukoliko inicijalizaciona lista sadrZi. manje elemenata
nego Sto iznose deklarirane dimenZije niza, nildoStajuCi elementi se inicijaliziraju na nulu. Tako se
sljedeeem primjeru, u Illlitri.ci M prva tri elem:enta u prvOI!l redu (zapravo redu 0) i prva dva elementa
u 0-
u
sljedeeem redu inicijaliziraju na navedene vrijednosti, dok se svi ostali elementi (od Ukupno 10 x
elenienata ui pretpostavku da je tip Matrica definiran kao rnatrica sa maksimalno 10 redova i
kolona, kao ujedD.om od prethodnih primjera) inicijaliziraju na nulu:
l0
10 0-
Matrica M= {{3, 5, 6), {4; -2));
D-
Kod inici ·aliziranih dvodimenzionalnih nizova, prva dimenzi ·a se moze izostavi · ·
· eemu se tada
ona automatski odJN!Ue na OS110VU broja po stt za jnjcijalizacijU_,!edOVa Ynntar mjcijaJiza
Tako ee, u sljedeeem primjeru, prva dimenzija niza biti automatski postavljena na 3:
cione liste:
0 ;_

int A[] [4] = {{3, 4, ·2, 5), {4, 1, 2, 3), {3, 1, o, 2));

Medutim, druga dimenzija sene smiie izostaviti. tj. ne smije se pisati:


D
int A[][] = {{3, 4, 2, 5), {4, 1, 2, 3), {3,- 1, 0, 2});
D
Razlozi za OVu zabraim SU identiCni razlozirna zbog eega nije dozvoljeno izostaviti drugu dimenziju
U
deklaraciji formalnih parametara fuukcija
D
Medu dvodimenzionalnim nizovima narocito se isticu dvodimenziona/ni nizovi znqlmyf!. koji se
mogu shvatiti kao nizovi stringova. Svaki element takvog nizaje obibli niz zriakova, odnosno string,
sa
kojim se moze postupati na naCin koji je opisan za rad sa stringovima. Ovakve nizove mozemo koristiti

8 ll
Fl
ll..
n
l

kad god je !!Otrebno !!ameenje skupine stringova; na primjer pain~je imena svih. uCenika

n
~

u razredu.
liiiena svih mjeseci u godini, itd. Kilo iltistraciju kako niditi sa niZom: stringova, sljedeCi
program
'Omogueava korisilikU da uneSe spisak imena, i tada dil i.iabere podSpisak (na primjer imena sa
rednlni
brojevima od 10 do 20) koji ee biti ispisan.

n
<e':t

#includ e <iostre am>


. , using namesp ace std;

n const int MaxVe licinaS piska = lOO;


const int MaxDuz ina = SQ.;
void Ul}OSijllen%(char Imena[] [MaxDu zina + 1], ·int· N) {

D
..
for(in t f - 0; i < N; i++) {
cout << "Unesi " <<. i -+ 1' << " .. ime.: ";
cin. getline (Imen,a [i], MaxDu zina);

D
. ' void Ispisirn ena (char Irnena[] [MaxDu zina + 1], int Odakle , int Dokle)
for (int i - Odakle ; i <= Dokle; i++).
D
.'
cout << Im~~a[i - 1] << endl;
)

int main() {
0
··•
int Broj, Pocetak , Kraj;
char Spisak[ MaxVe licinaS piska] [MaxDu zina + 1];
c?ut << "K<;liko imena Ze~~*~' da unesete ? ";

0 •
c1n >> BroJ;
cin.igno re(lOO OO, '\n.');
Unesim ena(Spi sak, Broj);
.. <.'}
. ..;·
cout << endl;
[] ceut << "Unesi te redni brb.j prveg i ~adnjeg irnena kojeg zelite: ·,;
ci.rl >> Pocetak >> Kraj; :.'
• Ispisimena(~pisak, Pecetak , Kraj);

0 •
)

Prilikom racla sa nizovima stringova. <J.ohill id~Jac jw pryo pomo¢ri type<ie f nafedbe definiratj
poseban tip koji predstavlja string odredene inaksimalne diJZ:ine, a zatim taj .tip iskoristlti za defullran
t..--"
0
~
nizova takvog tipa Ovaj pristup je narocrto pogodan ·Ukoliko treba definirati viSe razlicrtib ~va
istim stringovliim tipom. Ukoliko se pojavi potreba da mijenjamo strukturu striD.govnog tii:l8,
je
nad
tada se
promjena treba izvrSiti samo na mjestu gdje je tip definiran (g. u typede f naredbi). Sljede¢i
program
J
.
je modifikaeija prethodnog programa, u kojem je isk~ten ovaj pristup: · ·
#includ e <iestre am>

J

using namesp ace std;
const int MaxVe iicinaS piska = 100;
const int MaxDuz ina = 50;
] ltyped ef char Ime[Ma xpuzina + ll;)
, void Unesim ena ~Ime Imena [ J ,, i-nt N) ·
] for(in t i - 0; i <-N; i±,r) {
cout << "Unesi " << i + 1 << ". ime: ";
cin.ge tline(I mena[ i], MaxDu zina);

1 )

void Ispisim ena(Im e Imena[ ], int Odakle , int Dekle) {


'
for(in t i - Odakle ; i_ <= Dekle; i++)
I ceut << Imert?f i :-: 1] << endl;

9
)

int main( ) {
int Broj, Pocet ak, Kraj;
Ime Spisa k[Ma xVeli cinaS piska J;
cout << "Koli ko imena Zelit e da unese te? ";
cin >> Broj;
cin.ig nore(l OOOO , '\n');
Unosi mena( Spisak , Broj) ;
cout << endl;
[
cout << "Unes i te redni broj prvoq i zadnj eq imena koj
eq zeli te: ";
cin >> Pocet ak >> Kraj;
Ispisi mena (Spis ak, Pocet ak, Kraj) ; [
)

Dvodililenzionalne nizove zn~ova je takoder moguc e inicijal.izirati


dvodililenzionalnih nizova, i njihje mogue e inicijalizirati elemen t po
priliko m deklaracije. Poput svih [
elemen t (tj. znak po znllk), kao npr.
u sljedee em primjeru:

char Imena Dana[ 7] [12] =


[
{{'P' , I Q T 1 'n'' '.e I 1 'd', I j I I 'e ~ , I 1I I ' J. ' ' 'a', I k' 1 0),
{ 'U'; I t I 1 I Q I I 'r', 'a',
{ Is I 1 I r' I ' 1. ' ' '.'
J '
1
8 I 1
I

'd f,
kl I 0),
I aI 1
0)'
-- [
{ 'c'' I eI I Itt 1 'v', I r I I It I I I aI I I kI I
0)'
'
{I pI I I !=I I It I I
'a'' 'k', 0)'
{ Is
{ 'N',
I I I

'e',
U l
1
tb I
I d I
1

I
'a',
I j
l t l 1

I I
'a', 0)'
I 9 I 1 I 1I I I j I I I a I I 0));
[.,
' -~

Kako je ovakv i uticijalizacija krajnje nezgrapri~ doivol jeno je da


se pojedini stringovi unutar niza
stringova inicijal.iziraju stringovnim konstantama, iq6. ti sljedeeoj inicijal
izaciji, koja predstavlja mnogo
[
preglednijti varijantu prethodne inicijalizacije: · .;

~
/cha r Imena Dana [] [12] = { "Pone djelja k" ~ 11 Utara
nC;etv rtak", "Petak n,_ "Subota~,· "Ned jelja" };
k" I "Srijed~",
} [
Ovdje je takode r iskoriStena Cinjellica da se prva dililenzija priliko
Medutim, kako se ~a dimenzija mora zadati,. nju je ·ootreb no zadati
m inicijalizacije more izostaviti.
prema dnZini ua&ugqg sfringa
[
koji ee se pamtiti u nizu (ovdje je to string "Poiledjeljak" ajaje duZina
U, a dimenzija 12 je postavljena
zbog potreb e za pameenjeni NUL graniCnika). Meduj:itD, ovakvo Ij~enj
string mora zauzeti ista kolicina memorije (prema dUZini najdur eg stringa
mogu biti znatno )raCi. Na ovaj nacin se neracionalno troSi memo
e ima nedost atak ~o se za 8vaki
), bez obzira ~o neki stringovi
rija Kasriije cemo vidjeti da se ovaj
u•
proble in moZe rijesiti uz pomoc pokazi vaea .·

j):1
'
inicijalizirani nizovi stringoya se Cesto mogu iskoristiti da ncin!! progra
m znatno kraCim. Na primjer,
0,
sljedeCa funkcija,· koja ispisuje naziv mjesec a Ciji je redni broj
zadan kao parametar, bez nizova
stringova bi se mogla napisati jedino pomoe u gloma mib vi8estrukih
switc h-cas e konstrukcija:
if-el se konstrukcija iii pomoe u D
,

void Ispisi imeM jesec a(int Mjese c) {


char Imena Mjese ci[] [+OJ = {"Jan uar", "Febr u·ar",
"Maj 11
rr I Juni n, "Juli II I
"Mart ", "Apr il",
"Augu st" I "Septe mbar" I ".Okto bar" I
0
"Novembar "Dece mbar" }; 11
,

)
cout << Imena Mjece ci[Mj esec + 1] << endl;
D
Analog uo dvodimenzionalnim nizovima, . postoj e i trodimenzion
opCenito visedimenzio.nalni nizovi. pri eemu se riietJso }rori~J•
trodililenzionalni niz morem o shvatiti kao niz ciji su elementi
alni, cetverodimenzionalni i
yiSe od 3 dimeuziie. U su8tini, D
dvodimenzionalni nizovi, ill kao
dvodimenzionalni niz ciji su elementi obicni nizovi. U svakom slueaju
more se pristup ati preko jednog, dv.a ill tri indeksa. Ako zamisl imo
, trodimenzionalnim nizovima
trodililenzionalni niz kao viseslojnu D
10 D
fl
·!IJ
1.,-•
,. '
rl].
'
"""' prostomu stru1cturu ciji svaki s1oj predstavlj!! matricu, tada navod
enjem je<lnog..indeksa pJistupll!llo
D
1..~
navooenom s1oju, navodenjem dva indeksa pristupamo navoo
navodenjem tri indeksa pristupamo navedenom e1ementu u naved
primjer trodimenziolialoog niza, moZen!o posmatrati situaciju
enom rtidu u navedenom sloju, dok
enom redu u nav'edenom sloju. Kao
u kojoj imamo Sko1u sa 10 odjeljenja u tb-
r[J koioj u svakom odje1jenju ima po 36 uCenika, a svaki ueenik ~a
ovoj Skoli mozemo predstaviti sljedeeim trodimenzionalnim nizom
:
12 predmeia. Ocjene svih u6enika u
H
/ int Ocjen e[lO] [36] [12]; J
{1
•.. E1ementima ovakvog niza pristupamo sa tri indek sa Prvi indeks
bro. redstavr a redni .bro. ucenika unutar izabrano od. er en.
predstav1ja broj odjeliema, drugi
dok treCi indeks preds tavr a redni broj
{] predmeta za izabranog uci:nika .Na primjer, Ocj ene [ 4] predst
odjeljenja (dvodiili.enzionalni niz), Ocj ene [ ~ l [7] predstav1ja
av1ja ocjene . uCenika iz eetvrtog
.,. ocjene sedmog uCeriika iz clltVrtog

n
odje1jenja (jednodimenzionalni niz}, dok ocj ene [ 4] [ 7] [ 5] predSt
avlja petu ocjenu sedmog ucenika iz
cetvrtog razredil (broj).
.... #'-·
Trodimenzionalne nizove moZen!o definirati i postupno pomoeu
typed ef naredbe na viSe razliCitih
{] naein a Na primjer, niz Ocjene iz prethodnog primjera moguce
je defuiirati i na sljedeea 4 ekvivalentua
naeina, koji ilustriraju razlicite naeine na koje se trodimenzionalni
niz moire interpretirati:
5 typed ef int ocjen eJedn ogUc enika [l2];
{] L Ocjen eJedn ogUc enika Ocjen e[lO] [36];
.~
r typed ef int Ocjen eJedn ogUc enika [l2];
'J
D
"''
typed ef OcjeneJednogUceni~a Ocje neJed nogO djelje
<..- Ocjen eJedn ogOd jeljen ja Ocj.l;me[ 10];
.- -
:
.-:''
·_ ·;::- :;~~}'~-;
nja[3 6];

c;· typed ef int OcjeneJednogf?.~t~:tA;~nja [36] [12];


0
.,
Z. Ocj eneJe dnogO dj elj enj a Ocj erie [10 l ;
.C:ty pede f int Ocjen eSko le[lO ] [36] [12];
··. , ·

i
0 Ocjen eSko le Ocjen e; ·. ':·.
Sliena 1ogika vrijedi i za nizove sa viSe od tri dimenzije. 0 viSed
..

im~onalnim nizovima vrijedi jos


·~

u
reei da rilikom pren<iSettja parametara :funkci"e ko"i su visedi
0
~
formalnom parametru
vi5edimenzionalnih mz<iva mo
enzi"e moraju biti zadane . .
menzionalni nizovi, u odgovarajueem
koja se nioile izostaviti. Inietj . ija
se miti pomocu uguijeZdenih listi, aualoguo kao u slucaj
u
dvodimenzionalnih nizov a Pri tome se takoder ·sve dimen
0

· eventnalno prve dimenzije.
zije moraju eksplicitlio navesti, osim

J

J

]
'

]
1
11
J
l
. . ~[
[
[
[
. [
. [
~

[
~

0
~

. . •' ; 0
.. ~··
. ' .'
0
0-
0-
0-
0
a-
a
D
D
D

ll •

1l
JZUZECI I NJUIOVA OBRAD<t

Prilikom pisanja iole komplikovanijih programa cesto se desava da neke od funkcija koje trebamo
napisati nemaju smisla za sve vrijednosti pararnetara Na primjer, rnnoge rnatematicke funkcije nisu
definirane za sve v;rijednosti svojih argumenata (ova primjedba se ne odnosi samo na matematicke
{1 funkcije - recirno, funkcija koja na ekranu iscrtava kvadrat sastavljen od zvjezdica cije se dimenzije
.. zadaju kao parametar nerna smisla ukoliko se kao parametar zada negativan broj}. Stoga je prirodno
postaviti pitanje sta bi nkci"a trebala da vrar L!Jkoliko joj se kao pararnetn proslijede takve
{1 vnJ osti funkcija nije definisana, iii op6enito, sta bi funkcija !!!]!_qla da uradi ukoliko su joj
"jiroslijedeni takvi parametii~e_~!!!l_ nema ~sla Sve do nedavno, ovaj problem se Ije8avao na razne
- nacine koji su bill vise irnprovizacije nego prava Ijesenja U posljednje vrijeme, standard jezika C++ je
{] predvidio naein za Ijesav,mje ovog problema zasnova:il na tzv. izuzecima (engl. exceptions). Medutim,
prije nego sto razmotrirno izuzetke i tebnike.njihove obrade, recirno neSto i o starijirn tehnikama kilko bi
.. se moglo pristupiti ovom problemU. Na taj nacin cemo bolje shvatiti prednosti koje oni donose. .

D Uzmimo kao primjer funkciju za raeunanje faktorijela Ova funkcija nije definirana za negativne.
vrijednosti argumenta Posrnatr!\imo medutim kilko 6e reagirati standardne izvedbe iterativne 1
rekurzivne verzije funkcije za raeunanje filktorijela ukoli.ko irn se kao argument ponudi negativan broj:
[I
..• long int faktorijel(int n) {
long int p = 1;

0
...
for(int i = 1; i <=71; i++} p *= i;
return .Pi

0
... ;
lo~g int faktorijel_reku rzi'vni(int n)
if(n == OJ return 1;
{

else return n * faktorijel_rek urzivni(n- 1};

0. Nije teSko zakljuciti da ce,iterativna verzija funkcije za racunanje faktorijela za negativne argumente
vratiti rezultat 1 Ger se for petlja ne6e izvrsiti nitijedanput), dok 6e rekurzivna verzija "srusiti" program
0
.
zagusenjem steka (s o,bzirom da iz rekurzije nece biti izlaza). OCigledno, niti jedno niti dnigo Ijesenje
nije zadovoljavajuce. Varijanta koju nipoSto ne. §'Piiemo. napraviti je .<in u funkciju. ubacujemo ispis
poruka koje 6e korisnika upozoravati o greSki, kao npr. u sljedeeoj funkciji:
0
~
long int faktorijel(int nl {
if(n < 0)
11

J., cout << '1 Faktorijel nije definiran z;a nega:tivne argumente! \n ;
else { .
long int p =' lj
for(int i =
1; i <= p; i++} p *= i;
] )
retUr~ p;

] Nairne, u ovom slueaju onaj ko poziva funkci'u ne bi imao nikilkvu kontrolu nad is isom oruke o
wes .: ona 1 se lSpisivaJa uvijek na isti naCin (kad god je argume_nt negativan), i pri svakom pozivu
· fi:!nkcije sa neispravnim argumentima Na primjer, u sljede6em izrazu
] '
rezultat = faktorijel (a) + faktorijel (b) - faktorijel (c);

u slucaju da sva tri argumenta a, b i c iniaju negatiVn.e vrijednosti, poruka o greSki bi se ispisala tri puta,
J sto vjerovatno mje. ono sto bisrno uljeli. Moze se 'postaviti pitanje zaSto bismo uop.ce pro'ljeru
ispravnosti argumenata prepustali funkciji, a ne onome ko poziva fonkciju, kao npr. u sljedeeem,

I progFamskom isjecku:
~
[
int n;
cin >> n;
if(n < 0)
[
cout << rrFaktoiijel nije definiran za negatiyne argumente!\ n";
else
cout << "Faktorijel od " << n << " iznosi " << faktorijel (n) << endl; r
Ipak, postoji barem nekoliko razloga zbog kojih bi testiranje ispravnosti argumenata trebalo biti
povjerenoflmkciji, a ne onome koje poziva. Prvo, cesto uvjeti pod kojirn funkcijama nije definirana msu [
posvejednosta vni, Na prirnjer, sljedeca·funkcija, koja racuna povrsinu trougla sa stranicama a, b i c
koristenjem Heronovog obrasca, nije definirana ukoliko a, b i c ne predstavljaju stranice troug!a, g.
ukoliko je a > b + c ill b > a + c ill c > a + b: [
double PovrsinaTro ugla(double a, double b, double c) {
double s = (a + b + c) I 2;
return sqrt(s * (s-a) * (s- b)'* (s- c)); [
} '

Stoga, ukoliko bi se ovakva funkcija morala pozivati Iia mnogo mjesta u programu, provjera ispravnosti [
argw;nenata prilikom svakog pciziva mogla bi biti veoma zamoma Drugo, ~a Cesto nije lake sanio -
posmatranjem argtllllenata ·· li ·e·funkci'a definiran ill :iJ.e oaotovo ukoliko ·· ··
Je · os om ormulom, nego se njena vrijednost izraeunava prema nekom algoritrnu. Posmatrajmo, na [
prirnjer, sljecte6u fui!kciju dva realna argumenta a i b: -
double Tajanstvena (double. a, double b) f.
[
f }
double s = 0;
for(int i = 0; i < a; i++) s += (a+ i) I
return s;
(a + s - b * i);

Ova funkcija ocig!edno nije definirana za one vrijednosti argumenata a i b kod kojih ee se u toku_
'

[
-
racunanja u nazivniku. izraza unutar for petlje pojaviti. nilla Postoji beskonaeno mogo parova [
-
~ -

argumenata a i b zakojese to maZe (npr. za a= '3 i b = 4 u drugom prolasku kroz petlju), ali
vee 6e one biti otk:rivene tek u toku . Stoga
[
~

u
Jedna mogu6nost prepuStanja brige o argumentima fuukci'i je uvodenjc::J~onven,cije da fuukcija u
u
~

slucaju da nije definiriula vra, rezultat neku unaprijed dogovo;:enu vrijednost. Na prirnjer, kako je
povrSina trougliJ. uyijek pozitivna, IDOZemO se dogovonti da fUDkcija PovrsinaTro ugla vrati kilO
rezultat -1 u slucaju da argumenti ne predstavljaju stranice trougla, kao u sljedecoj definiciji:
u-
double PovrsinaTro ugla(double a, double b, double c)
if(a > b + c I I b > a + c I I c > a + b) return -1;
double s = (a + b + c) I 2;
0-
return sqrt (s * (s - a) * (s ...: b) * (s ·- c));
} D
-
. U.ovom slucaju, onqj ko poziva funkciju maze znati da Jije funkcija odradila svoj posao ispravr10 na
taj naeiu Sto 6e provjenti re2;llltat fuukcije, i ukiJliko je rezultat 1, to je indikacija da nesto nije u redu.
Naprlmjer:
0
/
D
2
n
u
{]
double a, b, cl p; -:
cout << "Uriesi stranice trougla: ";
cin >> a >> b >> c;
p = PovrsinaT roUgla(a, b, c);
i f (p == -1) cout ":<.< 11 Uneseni podaci ne obrazuju stranice trougl?~-! \n' 1 ;
else cout << npov~sina trougla je
11
<< p << endl;

-[] Ovakav pristup more se koristiti ~jednostaynijim primjerima, ali on posjeduje nekoliko ozbiljnih
nedostatak a Prvo, cesto se javljaju funkcije koje kao rezultat mogu vratiti praktieno svaku rea/nu
-vri[ednost, tako da ne postoji nikakva specijalna "nemoguca" vrijednost koju hismo mogfi vratiti kao
~

-[] 4iidikator greSke. Npr funkcija Taj anstvena iz maloprije navedenog primjera je upravo takva Jedno
moguee Jjesenje je u slueaju greske vratiti neku neocekivanu i veoma malo vjerovafliu vrijednost, poput
100
npr. 10 • Na taj nacin bi funkcija Taj anstvena mogla izgledati ovako: ..
-[] double Tajanstve na(double a, double b). {
double s = 0;
for(int i = 0; i < a; i++}
{j if(a + s == b * i) return 1e100;
else s += (a+. i) I (a+ s - b * i);
~
return s;

{]
Testni primjer za ovu funkciju mogao bi izgledati ovako:
"
D double a, b, f;
cin >> a >> b;
f = Tajanstve na{a, b);
if(f == lelOO) cout << "Funkcija nJ..)e definiran a!\n";
else cout·<< "Vrijedno st funkCije_ 'je " << f <"S endl;

S obzirom da je zaista vrlo nevjerovatno (mada teoretski ne i nernoguce) da ova funkcija u


0 n=alnim okolnostima vrati 10 kao rezultat, ovo polurjesenje uglaynom zadovoliava Medutim, .
sl"edeci roblem sa "e5en.. a
100

ti a nasta·e 'u situaciji kada pozvrulU funkciju treba upotrijebiti


' unutar nekog slozenijeg izraza Pretpostavimo, na primjer, da smo ciju faktorije l mo ciraii

0 take da vraea rczultat -1 u slucaju da faktorijel nije definiran. Pretpostavimo dalje da ovakvu funkciju
ze!irno da iskoristimo u programu koji racuna broj mogucih kombimicija od k elernenata iz skupa koji
' ima n elemenata Kao Sto je poznato, broj ovakvih komblnacija raeuna se po formuli n! I [k! (n-k)!], Sto

0 znacl da bismo mogli koristiti sljedeci programski isjecak:


int n, k;
cin >> n >> k;
0 cout << faktorij el (n) I ( faktorij el (k) * faktorij el (n - k));

Medutim, u ovom primjeru nikakve koristi za testiianje gresaka ne bisrp.o imali od toga Sto funkcija ·
0 faktorij el vraca -1 u slucaju greSke, jer se njeni pozivi nalaze kao sastavni dio slozenijeg izyaza Da
bismo imali ikakve koristi· 0d ovakve povratne vrijednosti, morali bismo izraz u kojem se javlja funkcija
faktorij el razbiti na sastavne dij~Jlove, kao u sljedecem primjeru:

J int n, k;
long int fl, f2, f3;
cin >> n >> k;
] fl = faktorije l(n); T2 = (faktorij el(k); f3
if(fl == -1 II f2 == -1 II f3 == -1) cout «
~ faktorij el(n- k);
"Nesto nije u redu!\n";
else cout << f1 I (f2 * f3);

J )'leelegantnost ovog prun1era je Vise nego ocigledna. Konacno, posljednji nedostatak IJesenja
iasnovanilr na vracanju specijalnih vrijednosti u slucaju gresaka je sto su oni neprimjenljivi u funkcijama
koje ne vracaiu nikakvu vrifednost: _Qvaj problem Ijesava se lako prepravkom funkcija koje ne VI:a6aju
I
3
l
[
vrijednost u funlccije koje viaeaju vrijednost 1 iii 0 u zavisnosti da li je funlccija uspjemo odradila'SVoj
posao iii nije ( ovakva Ijesenja smo do sada u vise navrata koristili).
[
Zbog mnostva pomenutih nedostataka, metoda vracanja specijalnih vriiednosti kao rezultati .u/
· slucaju greske moze se koristiti samo u jednostavnim slucajevima. Efikasnija metoda je upotreba [
'g!obalnih promjenljivih kao indikatora gresaka. Sve do uvodenja konsepta izuzetaka ujezik C++, ovo Je
•bila najvise upotrebljavana metoda za obradu gresaka, i opcenito Iieoeekivanih situacija. Ideja ove
metode je da se deklarira neka globalna promjenljiva, koja u normalnim okolnostima uvijek ima [
. vrijednost 0, a da se u slueaju greSke nJena vrijednost postavi na 1. Kako je ta promjenljiva globalna, ona
se moze postaviti unutar funkcije, a citati izvan nje, sto znaCi da sama funkcija moze indicirati da je
doSlo do greSke, · dok pozivaoc funkcije moZe lako prmderiti i utvrditi tu cinjenicu. Na primjer, neka je [
data sljedeca globalna promjenljiva: ,
in.t Greska = 0;
[
Tada eismo funkciju faktorijel mogli prepraviti da izgleda ovako:

long ~nt faktorijel(int n) { [


:if (n. < O) !
Greska = 1;
return -1; [
long :i.nt p = 1;
for(int i = 1; i <= p; i++) p *= i;

}
return p; D
Uz ova1.-vu prepravku, imali bismo i sljedeei primjer za racunanje broja kombinacija:
D
int n, k, komb;
cin >> n >:> k;
.koltlb = faktorijel (n) I (faktorijel (k) * faktorijel
:i.f(Greska) cout << "Neste nije u redu!\!1";
(i:l - k)); 0
else cout << kornb << endl;

Primijetimo da smo bez obzira na to sto za indikaciju greSke koristimo globalnu promjenljivu 0
Greska, takoder vratili -1 kao rezultat iz fitokcije. To je ucinjeno stoga Sto funkcija mora rz#to vratiti i
~ ~ <k
--~iji!f!5m: 00 _greSke ne
. u ovom slucaju ta povratua vrijednost uopee nije bitria, jer za testiJ;anje da li
povratuu vrijednoSt, :ilego vrijednost g!obalne promjenljive Greska. D
Vamo je napomenuti da.je je onaj ko pozove funkciju dliZan nakon Sto obradi greSku i preduzme
odgovarajucU: akciju (npr. zatraZi novi unos podil.taka) vratiti vrijecinost globalne promjenljive Greska
na 0, jer 6e u suprotnom svaki sljedeei poziv funkcije,_biti protumaeen kao neispravan (s obzirom da
sama funkcija nikada ne vraca ovu promjenljivu na nulu). Ova situacija je potpuno analogna situaciji da
0
korisnik nakon obrade greSke prilikom unosa podataka sa ulaznog toka mora pozvati ftmkciju
cin. clear () da obri5e indikator greSke ulaznog toka, o cemu smo ranije govorili. D
Opisani metod funkcionira u praksi moZe funkcionirati prilicno dobro. Medutim, osnov:ni nedostatak
ovog koncepta je upotreba globalnih promjenlji'vih, koje su po svojoj prirom vidljive i kome treba da
budu, i kome ne treba da budu vidljive, Cime se naru5ava konceot modulamosti, po kojem bi svaki
u
identifikator trebao da bude vidljiv samo on orne ko taj identifikator treba da koristi. Stoga, postoji velika
moguGIIost da dode do nehoticne pogresne upotrebe promjenljive k,oja sluZi kao indikator greske, Dalje,
lako' se moze desiti da pozivalac funkcije zaboravi da obri5e indikator greske nakon Obrade greSke, sto
§ko_~~£yest\ do kasnijih_problema ·· . . · .

'PraktiCn:o svi do sada opis1!iri problemi rije~<;ni su kada 'e u 'ezik C++ uveden koncept izuzetaka.
I=ec! ,su nacm reakcije funkcije na nepredvidene okolnosti, npr. na ·argumente za koje CIJa ruJe
u
definirana. U slucaju da funkcija ustanovi dane moze odraditi svoj _posao, ili·da ne moze vratiti nikakvu
n-
4 L I
J
fJ

0l-
rfl
L..
smislenu vrijednost (npr. stoga sto nije za navedene argumente), funkcija umjesto da vrati
vrijedno st treba da baci izuzetak (engl. hrow exception . Obratimo pa.Zn.ju na terminologiju:
vrijednosti
~oN, koja
funkcije se vracaju iz funkcije, a izuzeci se acaJu. Za bacanje izuzetaka koristi se naredba
{] ima slienu sintaksu kao naredba return: . iza nje slijedi izr!IZ koji identificira izuzetak
i<Ojt se baca
funkcija faktor ij el prilagod ena za
(kasnije cemo vidjeti srnisao ove identi:fikacije). Na primjer,
~

bacanje izuzetaka mogla bi izgledati ovako: ·


-[] long int faktor ijel (int n)
. if (n < 0) th'iow n;
lonsr int p = 1;
{] for(in t i = 1; ··i <= Jli i++) p ~= i;
return p;
}
{]
.. Razmotrimo sada sta se de5ava ukoliko pozvana funkcija baci izuzetak (npr. ukoliko ovako
funlCciju faktor ij el pozoverno sa negativnim argumentom). Ukoliko ne preduzme llJ.O.
napismm
nikakve
a,
{] · izmjene u ostatku prograrna, nailazak na naredbu throw prosto ee prekinuti izvrsava
odnosno prva nepredvidena situacija doves6e do prekida programa. Ovo sigurno nije ono
nje program
Sto .Zelimo.
-{] Meduti.m, izuzeci se nvijek bacaju sa ciljem da budu uhvacen i (engl. gz~li>-
koriste se kljuene rij~~iL~ _i catch ycoje .s: uvijek koriste zajediio, _na
Za "hvataiij
nacin opisan
. \:,.,
e" izuzetaka
sljede6om
blokovs kom konstrukcJ,Jom, koja donelde podsjeca naif- else konstrukCljU:
-{] . try !0 . ( ; ·;.
~~ ~-·
-poku3 ay, "\ /,_ ·
... m· . V
.\. r
-·ca-tch (jormalni parametar) (j)
D t!J
Hvatanje izuzetka \

j". Ukoliko
Pri nailasku na ovu konstrukciju, prvo se izv):Sava skupina naredbi oznacena sa "Pokusa
a, tj. ukoliko se sve naredbe
prilikom izvrsavanja ovih naredbi ne dode ni do kakvog bacaJ!ia izuzetak
ne6e se uopee izvrSiti,
okoncaju na regularan naciu, skupina naredbi oznaeena sa "Hvatanje izuzetka"
ce
odnosno program nastaviti izvr5avanje iza zatvorene viti()aste zagrade koja oznacava kraj
ovog l;Jloka
(ti. iza cijele try - catch konstrukcije). Medutim, ukoliko prilikom izvrsavanja naredbi u bloku
), izvrsavanje
"PokuSa f'. dode do bacanja izuzetka (npr. pozove se neka funkcija koja bac;i izuzetak
naredbi koje eventualno slijede u bloku "PokuSaj" s~ prekida, a izvrsava nje program a se nastavlja od/
. .. •
prve naredbe u skupini "Hvatmy·e izuzetka''. Iza natedbe ·ca
Na taj nacm,
jednog formalnog parametra, koji ee p - vatiti vrijednost baeenu naredbom throw.
biti "uhva6en .a" u naredbi cat@- Ta Vrijednost
naredbo in throw mo~ se "baciti" vrijednost koja ce
0 moze hpr. oznacavati sifru greSke (u slucaju da je moguce ·Vise rawcitih vrsta
blok'u "Hvatan je izuzetka" mogn u slucl!iu potrebe iskoristiti viije<inost ovog paramet
gresaka)
ra da
, a naredbe u
=aju sifru
se _izuzetak
greSke, i da u zavisnosti od sifre preduzmu razlicite 'akcije. Sljede6i primjer ilustrira kako
0 baeeniz funkcije faktor ij el moze uhvatiti na mjestu poziva (npr. iz glavnog program a): .

try '{

0

int n, k;
cin >> n >> k;
cout << faktori jel(n) I (fakto rijel(k ) * fakto" ijel(n ~ k));

·catch( int e).{


D cout << "GreSk a: faktor ijel od "· << e << ".. nije definir an! \n";

n i k su
U razmotrenom primjeru treba obratiti pa2:nju na nekoliko cinjenica. Prvo, promjenljive
i stoga se
"clefinirane kao lokalne promjenljive u try bloku, i kao takve, ona ne postoje iZ'ian tog ·blok8,
ijel je prilikom )lacanja
ne mogu korisi:iti niti unutar catch bloka. S druge strane, funkcija fakto"
]
5
I
{
[
-
izuzetka kao identifikaciju izuzetka iskoristila upravo svoj formalni paraiiletar n, talco da naredbe u
catch bloku :inogu lako saznati problerriatienu vrijednost argumenta koja je dovela do gres"ke. Na
[
primjer, ukoliko pri testiranju ovog programskog fragmenta ~o ulazne podatke .n=4 i k=6, na
ekranu eemo dobiti ispis poruke "Greska: faktorijel od -2 nije definiran!". Zaista, pri raeunanju broja
kombinacija za n=4 i k;,6, pojavljuje se potreba za racunanjem izraza 4!/[6!·(-2)!] u kojem·je
[
problematican upravo faktorijel od -2.

Prilikom bacanja izuzetaka, iza naredbe throw more se na6i izraz bilo koiefl tipa, ukljuenjuCi i
[
stringovne konstante. Pri tome, treba voditi raeuna da 6e izuzetak biti uhva6en samo u slucaju da~
b~ceno~i~Jkf;;s_triktnoodgozara tipu fonnalnog varametra navedenog u naredbi catch (npr. ukoliko.
'ii:iredb"i: throw ad cjelo6rojm izuzetak, on neee biti uhvacen ukoliko naredha catch ocekuje formalni
[
_pararfietar tipa double). SljedeCi primjer demonstrira funkciju faktorijel koja baca izuzetak tipa
stringovne konstante:
[
long irtt faktorijel (int n)
if(n < 0) throw "Faktorijel negati"I.'Ilih brojeva nije definiran";
-
long int p = 1;.
for (int i = 1; i <= )1.< i++) p *= i;
[
return p;
}
[
Ovakav izuzetak mozemo uhvatiti kao u sljede6em primjeru:
try {
-int n;
[
cin >> n;
cout << 11 :E:"aktorij el od " << n << ~ -iZnosi << faktorij e:l (n) << endl;
/

catch(const· char poruka[])


cout << poruka << endl;
D
Cesto se desava da jedna fimkcija piniva dml9~ dmga trecn, treca eetvrtu itd. Pretpostavimo na
primjer, da neka od funkcija u lancu pozvanih fuukcija (npraRe6a) baci izuzetak. Prirodno je postaviti
pitanje.zdje ce takov iziaetak biti uhvacen. Da bismo odgovo . na oyo pitanje, razmotrimo sta se tacna
desava prilikom bacanja izuzetaka !:!J<:oliko se prilikom izvrSavanja neke funkciie naide na naredbu
0
throw, njeno izvrSavanje se prekida(osim u sluc;iju da se naret!ha throw nalazila unutar try bloka, Sto
'je specijalni slueaj koji 6emo razm.atrit:l kasnije} i tok nrograma se vra6a na rn)esto paziva funkciie. Pq
tome se desavaju iste stvari kao i pri regularnom zavrset;ku. funkcije (npr. sve lokalne promjenljive
0-
funkcije bivaju uniStene). Dalji tak programa sada bitn<;> ovisi da Ii je funkcija koja je bacila i=tak
pomana iz unutraSnjosti nekog t;ry blo~ ili nije. Ukoliko je funkc~zvana iz t g bloka, izvodenje
naredbe unutar kaje se nalazi. poziv fuDkcije i svih nared.bi koje even . o slijede WJ, nje u try bloku se
0
prekida, i tok programa se preusmjerava na pocetak odgovaraju6eg catch bloka, kaa Sto je vee. opisano.
Medutirn, ukaliko funkcija koja je bacila izuzetak vik QOZ1f!!pa iz nekog try bloka, izvrsavanje funkcije
iz koje je problematicna funkcija pozvana bi6e takodetpi~kimito, kilo daje upravo ona bacila izuzetak, i
0-
kontrola tbka prograrna se prenasi na mjesta poziva te funkcije (u slucaju da je pozyana funkcija bila
pozvana iz main funkcije, prekinuce se sam program, a ista stvar bi se desila i u slucaju da se izuzetak
baci direktno iz main funkcije). Pastupak se dalje ponavlja sve dok iZJm:tak ne hnde nhvacen u nekaj od
0
funkcija li lancu pazvanih funkcija, nakon cega se tok programa nastavlja u pripadnam ·ca."tch blaku
· (koji odgovara mjestu gdje je izuzefuk uhva6en). Ukoliko se u toku ovog "razrnotavanja" poziva dode i
do same main funkcije, a izuzetak ne bude uhvacen ni u njoj, program 6e biti prekinut
n
Opisani mehanizam prasljedivanja izuzetaka je veama prirodan i logiCan, mada pri prvom citanju
maze djelovati pamalo zblJ1l.jujuce. Situacija postaje rnnago jasnija nakan Sto nizrnotrimo sljede6i
n
primjer, u kojem main funkcija poziva funkciju kornbinacl.je, kaja opet paziva funkciju faktorijel'
kaja maze eventuaJna bi!citi izuzetak: ·
n
6
nl
II

#includ e <iostrea rn>


using namespac~ std;

n long int faktor ijel(in t


if(n < 0) thrown ;
~) (
ll long int p = 1;
for(in t i = 1; i <= ~; i++) p *= i;
return p,~

int kombin acije(in t n, int kl {


return faktorijel(~) I (fakto rijel(k ) * faktor ijel(n - k));
)
• int main()
[} try {
int n, k;
cin >> n >> k;
cout << kombin acije(n , k);
D )
catch (int e) {
nije definir an! ' 1 ;
cout << "GreSka : Faktor ijel od ·" << e <<
11

D )

funkcija ce
Pretpost avimo da smo pokrenuli ovaj program i zadali ulazne podatke n=4 i k=6. main
0 prvo pozvati funkciju kombin acij e sa parametrima 4 i 6, koja s druge strane tri
faktor ij el sa parametrima 4, 6 i -2 respe1.iivno. Prva dva poziva zavrsavaju uipjeSn.o
puta poziva
,
funkciju
medutim u"
' trecem pozivu dolazi do bacanja izuzetka, i tok program a se iz funkcije faktor ij el
vraea u funkciju

0 kombin acije. Medutlln, kako u funkciji kombin acije funkcija faktor


bloka, prekida se i izvr5avanje funkcije kombinacije, i tok programa se vraca
ijel
u main
nije pozvana iz try
funkciju. Kako je u
ajueem
u odgovar
main funkciji funkcija kombin acij e pozvana iz try bloka, izvrsavanje se nastavlja
0 catch bloku, u kojem se prihvata izuzetak bacen iz funkcije faktor ijel, i ispisuje
foktorije l od -2 nije definiran".J2!:Y.gim..tijeeima, izuzetak baeen iz funkcije faktor ijel
poruka "Gres[uz:
~fen je tek
e. Sasvim drllgn
l! fhnkciji ma i u, nakon Sto je prethodno "prosao" neuhvacen kroz funkciju kombin acij
0 situaciju imarno u sljedeeem primjeru, ~ kojem se izuzetak hvata vee u funkciji kombin
acij e:

#includ e <iostre am>

0 using namesp ace std;


long int faktor ijel(in t n) {
if(n < 0) thrown ;
0 long int p = 1-;
fo_r (int i = 1; i <=
return p;
lti i++) p *= i;

int kombi nacije( int·n, int k) {


try {
return faktor ijel(n) I (fakto rijel(k ) * faktor ijel(n - k) );

catch (int e)
return 0;

int main() {
int n, k;
cin >> n >> k;
·,. cout << kornbinacije(n~ k); ,_

]
7
\
l
r
Pretpostavimo ponovo isti poCetni se<:nario, "(j. daje program pokrenut sa ulaznim podacima n.=4 i
k= 6. main funkcija ponovo poziva funkciju kombinacij e, koja dalje tri puta poZiva funkciju [
faktorijel, pri eemu prilikom treeeg poziva dolazi do bacanja izuzetka Tok programa se iz funkcije
faktorijel vraca u funkciju kornbinacije. Medutim,· u ovom primjeru funkcl!a faktorijel je
pozvana iz try bloka unutar funkcije komhinacii e_, tako da izuietak biva uhvaeen vee u funkciji [
kombinacij e, i tok programa se prenosi u odgovarajuci .catch blok nnutar fimkcije i<el!ll;>inad j e
Tamo se nalazi 'naredba return 0; kojom se vrsi regularni povratak iz funkcije kombinacij e, pri
eemu se lcao njen rezultat vraca upravo vrijednost 0. Stoga ce u glavnom programu kao rezultat biti [
ispisana upravo nula (ovakVo pona5anje ima smisla izvesti, jer je razuru1jivo da je broj kombinacija od
sest elemenata koje se mogli napraviti izborom iz cetveroclanog. skupa upravo nula). Dalcle, funkcija
kombinacij e se zavrsava_ norma/no, bez obzira Sto je ona uhvatila izuzetak koji je baeen iz funkcije [
faktorij el. Takoder, primijetimo da formalni parametar e u catch blokti nije iskoriSten ni za ·sta lj
prosto je jgnoriran. To smijemo uraditi kada god nas ne ;gpjma kako Je doS!o do izuzetka, yee samo da
je do njega doslo. Jezik C++ dozvoljava da se u takvinl slucajevima umjesto formalnog argumenta pisu
~tri tacke, kao u s1jedeeem isjec"ku: ., ~ ·
[
try { .·
return faktorijel(h) I (faktorijel(k) * faktorijel(n ~ k)); [
}
catch( ... ) {

}
return 0; [
[ Ovakav catch blok uhvatice bilo koi,i iZ!!zetak, hez ohzira na njegov tip. I [
Iz izlozenog razmatranja lak<i se more zakljuciti da se izuzetak koji bude uhvaeen u nekoj od
funkcija ne rosljeduje dalje iz te funkcije, nego se srriatra da se funkci'a ko'a ·e uhvatila izuzetak
zavr5ava regularno. Me utim, sasvim Je legalno da funkcija koja uhvati izuzetak nakon !ito eventualno [
'iZvrSi neke ecifiene akcf e u skladu sa nastalom situaci' om, ponovo baci izuzet (isti ili neki drugi),
a<? u sljedeeem primjeru:
#include <iostream> 0
·using namespao~ std;
long int faktorijel(int n) (.
if(n <OJ throw "Pogresan argument u funkciji faktorijel";
D
long,int p = 1;
for(int i = 1; i <='}?; i++) p *= i;
return p;

int kombinacije(int n, int k) {


try.{
return faktorijel(n) I (faktorijel(k) *· faktorijel(n- k));
8
catch( .•. ) {
throw nPogreSni argumenti u funkciji kombinacije"; D
int main()
try (
u
int; n, k;
cin >>. .n >> k;
cout << kombinacije(n, k);
u
catch(const char poruka[])
cout << poruka << endl; u
8
n
Ll ~

-n
- U ovom primjeru, funkcija faktorije l baca izuzetak koji biva uhva.Cen u fimkciji kornbinac ij e.
Medutim, ova funkcija u svom catch bloku baca novi izuzetak, koji biva uhvacen unutar funkcije
main. Krajnja posljedica 6e biti da 6e biti ispisana poruka "Pogresni argumenti u fonkciji kombinacije"
na osnovu cega se jamo vidi da je u main' funkciji uhva6en (novi) izuzetak koji je ·bacila funkcija .
kombinac ije, a ne prvobitno baeen.i izuzetak kojije bacila funkcija faktorije l (.i kojije uhvacen u
funkciji kombinac ij e).
{] Nekada se mou desiti da je potrebno da funkcija uhvati izuzetak izvrsi neke akcije koje su
neophodne za obradu izuzetka, a ·da nakon toga isti izuzetak proslijedi dal' e (funkciji koja ju je pozvala).
{] ara. . , v problem ni ·e da funkc.. c isti izuzetak ko '1 e 1 uhvatila Medutim, C++ za tn.svrhu
.dozvouava i. oristen e naredbe throw bez navodenja nikakvog izraZa. i.Za n·e,. U tom slucaju se
.... Eoc!rwrm.Jeva da i'nrJkcija baca isti izuzetJk koji Je upravo · vatila Ovo je jedini slucaj u kojern se
na"i"eaoa throw moZe ].i:oristiti bez ';og argumenta Naravno, takva throw naredba moze se nalaziti sarno
{] unutar nekog ca tch:floka -

Mada se izuzeei obien0 bacaju iz neke od funkcija koje se pozivaju iz nekog od try blokova bilo
{] direktno iii' indirektno (\i. posredstvom drugih funkcija), dozvoljeno je i da se izuzeci bacaju nevezano
- o~ poziva funkcija Tako je, na primjer, sljede6a konstrukcija Savrseno legali!a:

{l try {
double x;
cin >> x;
{] i-f(x == 0) throw nNula nem.a reciproCn u vrijednos t!\n";

.. cout << "ReciproC na vrijed:no st bioja " <<" x << " glasi " << 1/x:;

catch(con st char poruka[])


cout << poruka;

I ak, ovu mogu6nost ne treba recesto koristi · ·er se ovako. isane konstrokcije uvijek mogu
0

napisati koriStenjem obicne i f else konstrukcije, a bacanje izuzetakaje prilicno
mnogo prirodnije napisati
~evno po pitanju
na sljede6i naCin;
racunarskih resursa Na primjer, prethodni isjeeak se mogao
·-
0 double x;
Gin >> x;
i f {x == 0) cout << "Nul a nema reciproC:n u vrij ednost! \n'·';

0 e1se ~out << "ReciproC na vrijednos t broja " << x << u glasi " << 1/x;

Bacanje izuzetka direktno iz try kon.Strukcije moZ., eventnalno imati smisla u primjerima poput
sljede6eg, u kojem se jz{,zetak baca u slucaju da se ispostavi da prilieno sloZeni raeun koji se provodi (za
0 ovaj primjer je posve nebitno sta ovaj racun radi) ne moze da se obavi zbog dijeljenja nulom:
try (!) .
0 doUble p = 0;
· for(int i = 0; i -< a; i++) l
' double q = 0;
~
for(int j = 0; j < b; j++)
if(a + s ==
b * i) throw 0;
q += (a+ j) I (a+ s - b * i);
l
] }
p += q * i;

Cout. << .1'Rezultat je n << P << endl;

] CDcatch(., .. ) ().
C:out·<< "P~oblem:' doslo je do dijeljenj a nulom!\n" ;

]
9
1
c
[
I ovaj primjer bi se mogao da prepravi da ne koristi bacanje izuzetaka, samo sto bi u to!ll slucaju [
1di-~a1:~ ~alo ulvise problakema da se :'ispbetlj~o·: iz dtkvos~o u~~eZdene bpetlje u ·kslucaju da detektiramdmaho
1
_
Je JenJe n om. 0 v o, pomocu acanJa IZilZe a, cun uocuno pro 1em, to programa se o •
nastavlja unutar catch bloka Bez obzira na sve pogodnosti koje nude izuzeci, u posljednje vrijeme se
sve vise susreCu programi koji sa upotrebom izuzetaka preljeruju, i koriste · bacanje izuzetak;;. za [
'ijesavanje situacija koje su se mog!e prirodnije rijesiti obienom upotreboni if- else ili switch- case
konstrukcija Kao sto je vee reeeno, takva metodologija, mada izgleda da mnogima djeluje "modernoin" [
i "savremenom", ne smatra se dobrom programskom praksom.

Bilo koji try blok more imati vise pridruZenili catch blokova, koji hvataju razlicite ti ove izuzetaka. ·
Na j:minJer, onstrukcija poput s ~ ece Je posve ispravna: [

try {

I
Neke_nar~dh~
[
catch (int broj I
Obrada I
I
catch(const char tekst(Jl {
[
'
Obrada 2
I
catch_( ..• ) [
Obrada_3

Ukoliko prilikom izvrsavanja skupine ·naredbi "N~ke_nar~db~" dode do lia~anja izuzetka qjelobrojnog
[
'
tipa, on ce biti uhvacen u prvom catch bloku, odnosno izvrsice se skupina naredbi "Obrada_l".
Ukoliko se baci izuzetak tipa stringovne konstante, on ce biti uhvacen u drugom catch bloku, dok ce
tre6i catch blok uhvatiti eventuahw baeene izuzei:ke nekog drugog tipa Kada se baci iZuzetak, catch
blokovi se ispituju u redoslijedu kako su navedeill; i prvi liiok k;oji moze Ulivat:tt:t IZ11Zetak ciji se ti slare
sa nave enim ti om reuzuna n·e ovu obrad dok se o '.catch o ovi ne izvr5av:i"u. Zbog toga, se
eventualni catch blok sa tri tac"kice umjesto form og pariunetra smije nalaziti samo•. na posljednjem 0
mjestu u nizu ·ovakvih blokova, jer u supromom ni jedan catch blok koji slijedi ne bi nikada bio izvrsen
(s obzirom da catch blok sa tri taCkice hvata izuzetke bilo kojeg tipa). ·
D
Izlaganje o izuzecima zawSi6emo riapi>menom da mnoge ugradene funkcije jezika C++ (narocito
one koje su u standard jezika C++ uS!e relativno skoro) tak~der mogu bacati izuzetke, koji se hvataju
isto kao i izuzeci baceni iz :korisniCki definiranih funkcija. J:'faZalost; starije matematiCke funkcije (poput.
sqrt, log, pow itd.) ue,
Racaju imzitt£ u $~l,leaju gresaka, bar ne po standardu iezika C++ :(iako ii:na
kompajlera u kojima i ove funkcije bacaju izuzetke). Ovo je Steta, jer greSke koje mogu nastati usljed
pogreSnih parametara ovih funkcija ne mogu biti tretirane na isti naein kao greSke koje nastaju u
korisniCki definiranim :funkcijama, Ov&i problem se lako moze ·rijesiti tako Sto 6emo za svakn takyu
0
:funkciju koju namjei:avamo koristitfnapraviti vlastitu verziju, koja u slucaju greske. baca izuzetak, a u
·suprotilom samo poziva ugradenu funkciju. Na primje;r; moremo napisati vlastitu funkciju sqrt (sa
velikim "S") koja za Ilegativne argumente baca izuzetak, a inaee pozi.va ugrademi funkciju sqrt:
u
0
}
. t·
Ako nak6ii' toga u programu l!111jesto funkcije sqrt budemo uvijek koristili iskljucivo funkciju
D
Sqrt, moCi cemo za kontrolu'i "hvatanje" gresaka i drugih izuzetnih situacija koristiti sve tehnlke koje
p~a mehanizam bacanja i hvatanja izuzetaka opisan u ovom. poglavlju.. ·
~

10
u
POKAZIVACI I POKAZIVACKA ARITMETIKA

Svaka promjenljiva koja se deklarira u programu zauzima odredeni prostor u IDell\Oriji, i syakqf
promjenljivoj se dodjeljuje tacno odredeno mjesto u memoriji. Poznato ·e da svaka Iokaci"a u memori"i
·una svo ·u adresu, ko"a o um ··i. Slijedi da svaka promjenljiva posjeduje svoju
adresu, koja odreduje njeno Jitiesto u memoriji. Na primjer, pretpostavimo da imamo sljedecu
deklaraciju:

int Broj";

Nailaskom na ovu deklaraciju, prevodilac (kompajler) ce promjenljivoj Broj dodijeliti odgovarajucu


Iokaciju u memoriji, tako da 6e ova promjenljiva dobiti svoju adresu. Pretpostavimo, na primjer, da je
ovoj promjenljivoj dodijeljena adresa 4325. Taqa imamo sljedeeu memorijsku sliku:

Adrese 4324 4325 4326

Broj

Ukoliko nakon ove deklaracije izvrsimo dodjelu neke vrijeduosti promjenljivoj Broj, npr. dodjelom
{1 Broj = 56;

efekat ove dodjele bi6e smjestanje vrijeduosti 56 u memoriju na adresu 4325 dodijeljenu promjenljivoj
{J Broj, kao Sto je prikazano na sljede6oj slici:
...
n
-
Adrese 4322 4323 4324
I
t
4325
s6
4326 4327 4328 4329

u
...
Broj

U stvamosti je situacija nesto sloZenija nego na prikazanoj slici. Nairne, memorija se obieno adresira po
ba"tima, tako dajedna memori"ska lokaci"a moze rimiti sa!no j"OOn.obaJtnn vrijeduost, dok c· bro" e
promjenljive obicno zahtijevaju vise bajta za memoriranje sadr ]a (danas najces6e 4). Stoga ce
promjenljiva Broj u stvarnosti zauzeti ne samo jeduu, nego vise susjeduih lokacija (npr. 4325, 4326,
4327 i 4328), _eri Cemu pod adresom promjenljive smatramo adresu prve od zauzeffh lokacija (1j. 4325).
Medutim, radi pojeduostavljenja diskusije koja slijedi, mi 6emo sadrZaj memorije crtati kao da jedua
promjenljiva uvijek zauzima jednu memorijsku Jokaciju. Ovo pojeduostavljenje ne6e se bituo odraziti na
su5tinu izlaganja .

Razumije se da za pristup promjenljivoj Broj nije uop6e potrebno da poznamo na kojoj se adresi u
memoriji ona nalazi, jer njenom sadrZaju uvijek moZe!no pristupiti koristeci njeno simbolicko ime Broj.
Medutim, eesto se okazuje korisnim imati proJitienljive ko"e kao svo· sadria· ima"u adresu 11eke dru e-
e,romjeplilxe. Takve promjenljive nazivaju se pokozivacfie pomters prom]en!jive (iii skraCeno, samo
pokozivaci iii pointen). fokazivaeke promjenljive se deklariraju tako da se ispred njihovog imena stavi
znak "*" (zvjezdica). Na primjer, sljedeea deklaracija deklarira promjenljivu Pokazivac koja nije tipa
"cijeli broj", nego "pokazivac na cijeli broj": I

] ~ int *Pokazivac;

J
1
-l
.[
Kao i svaka druga promjenljiva, i pokazivac"ka promjenljiva zauzima mlredeni prostor u memoriji.
-
Ukoliko pretpostavimo da je kompajler promjenljivoj Pokazi vac dodijelio npr. adresu 4329, dobijatno [
sljedeeu memorijsku sliku:

Adrese 4322 "4323 4324 4325 4326 4327 4328 4329 [


I I 56 I -
t t [
Broj Pokazivac
-
Naravno, ovom deklaracijom jos uvijek nije dodijeljena nikakva vrijednost promjenljivoj [
I Pokazi vac Medutim, pokazivaCkim promjenljivim ne smiju se neposreano do<lJeiJlvati bro[ew, Stoga
• kompajler neee dozvoliti dodjelu poput sljedeee: ' . -
[
XPokazivac = 4322;

. Umjest~. toga, pok~vaekim promjenljivim se dodjeljuie ~~esa neko§ o~jelcta n . romj~ji:'e) n


-
koJa se dobtJa uz pomoc unarnog prefiksnog Qperatora 'k, kOJl moZe1no cttati ' esa od". a pnmJer, [
syede6om dodjelom promjenljivoj Pokazivac se dodjeljuje adresa promjenljtve Br.oj (odnosno '-

vrijednost 4325 u konkretnom primjeru):


LPokazivac = &Broj; J u-
Nakon ove dodjele, sitnacija u memorijije kao na sljede6oj slici:

Adrese 4322 4323 4324 4325 4326 4327 4328 4329


0
-
I 56 · I I I I 4325
0
-
Broj Pokazivac
\ ·:
Ukoliko bismo sada pokuSali da ispisemo sadr!laj proinjenljive Pokazi vac, dobili bismo ispis
n-
adrese na kojoj je smjestena promjenljiva Broj, odnosno broj 4325 u navedenom primjeru (strogo
gledano, ne6e se ispisati 4325 nego Ox10e5 zbog,,konvencije da se adrese uvijek ispisuju u
heksadekadnom brojnom sistemu, a "Ox" je prefiks za beksadekadni brojirl sistem u jeziku Crt-).
0
...
· Naravno, taean ispis striktno zavisi od toga promjenljiva Broj zaista smjeStena u sto se
ne moze unaprijed znati. Zbog
D
.....
\•
,
primjer, sljedeea naredba D
....
lcout << *Pokazivac;j

llf* 6 e broj~jer ·e sadrZa"lokacfe na koju pokazuje promjenljiva Pokazivac upravo 56. Operator ll
® naziva se jos i operator e erenciranja dok se operator *" · aziva i operator re erenciranJcn
Ukoliko je "x" pokazivae tipa "pokazivae na tip Tip", tadli je tip izraza "*x" prosto tipa "Tip".
Dereferencirani pokazivac more se koristiti u bilo kojem kontekstu u kojem bi se mogao koristiti bilo
koji izraz ciji tip odgovara tipu na koji pokazivae pokazuje. Stoga je sljedeea naredba potpuno legalna, i
n
ispisuje brojeve 57 i 112:
cout << *Pokazivac + 1 << endl << 2 * *Pokazivac;

U ovoj naredbi trebarno obratiti pa2:nju na dva detalja Prvo, operator dereferenciranja ima veei
£!joritet od aritmetickib operatora (sabiranja, mno2:enja, itd.) tako da se izraz *Pokazi vac + 1 ne
• mterpretira kao * (Pokazivac + 1) vee kao (*Pokazivac) + 1 (kasnije cemo vidjeti kakvo bi taCno
'
2
n
riJ
'i
~--

rl]
L
· znaeenje imala prva intetpretacija, kojaje takoder snlislena). Drugo, u izrazu 2 * *Pokaziv ac prva
~ezdica predstavlja operator mnoZellja, dok druga zvjezdica predstavlja operator
dereferencirailja
Kako se razmaci mogu izostaviti, istu naredbu smo mogli napisati i ovako:

cout<<* Pokazi va.c+l <<endl <<2* *Pokazi vac;

Medutim, na ovaj nacin je veoma nejasno Sta koja ~ezdica predstavlja, pa ovakvo pisanje treba
izbjegavati. Vjerovatno najjasnije znaeenje dobijamo ukoliko upotrijebimo zagrade:

cout << *Pokaziv ac + 1 << end1 << 2 *. (*Pok;;z ivac);

Veoma VaZna cinjenica je da dereferencirani pokazivac JZ_redstavlja 1-vrijednost, odnosno more se I


naei sa lijeve strane znaka dodjeljivanja, i na njega se mogu primijeniti operatori poput "++" i " ".

Stoga su dozvoljene naredbe poput sljedecih:

··- *Pokazi vac = 100;


(*Pokaz ivac)++;
{] ' Prva naredba ostavlja sadrZaj lokacije na ko'u ukazu'e promjenljiva Pokaziva c na 100, dok druga
• naredba wecava sadrZaj lo actje na koju ukazuje promjenljiva Pokazi vac za 1. U koukretnom
{] primjeru, kada promjenljiva Pokazi vac ukazuje na promjenljivu Br~j, efekat ovih naredbi je isti kao
da smo neposredno pisali

a Broj
Broj++;
= 100;

0
0

Nakon sto smo vidjeli sta su pokazivaci,.potrebno je razjasniti cemu oni sluie. Ocigledno je da nam
pokazivaei omogucavaju indirektni pristtii/ nekaj promjenljivoj, "medUtim jav~a se pitanje sta ce nam
.
ovakva indirekcija kada sadrZaju promjenl.f:i've moremo pristilpiti i direktno. Vidje6emo kasnije da

J

osnovna snaga pokazivaea lezi u cinjeniqj da oni ne mora~u uvijek ~okazivati na isti obie]sat
(promjenljivu), vee se tokomizv rsavanja tograma ob ekat na- o 1 om po azuJu more mfen'ati. Na
primjer, promj . ~Iva Pokaziva c moze jedno vrijeme pokazivati na promjenljivu Broj, da bi joj

]' kasnije dodijelili adresu neke druge promjenljive. Pored .toga, vidje6emo i da pokazivaCi mogu
okazivati ita bil ko · m ·esto u memoriji, a ne samo na ru ·esto ko ·e ·e ve6 re ' eku
promjenliJVu. sto rma velike priinjene kod tzv.' dinamiclfe alokacije memorije, o ojoj 6ento posebno
govoriti i koja predstavlja ositovni razlog zbogkoje gtreba ovladati koriStenjeru pokazivaea
J Prije nego sto se upoznamo ~. primjenama pokazivaca, bitno je napomenuti da bez obzira sto
pokazivaei i dalje iml\iu veliku primJenu u jeziku C++, oni se mnogo mmge koriste nego Sto su se
I koristili u jeziku C. Nainte, u jeziku C pokazivaci Su se morali koristiti da se simnliraju neke stvari koje
su naknadno dodate ujezik C++, a nisu postojale u C-u, kao sto je npr. prenos parametara o re erenci.
Na primjer, ukoliko u jeziku C++ relimo da napiseruo funkciju koja e razmijeniti vrijednost dvije
promjenljive koje joj se prenose kao parametri, mozeruo napisati funkciju poput sljede6e:

void Razmije ni(int &Prva, int &Druga)


int Pomocna = Prva;
Prva = Druga; Druga = Pomocna;

Ukoliko bismo sada reljeli da razmijenimo vrijednost dvije cjelobrojne promjenljive a i b, to bismo
mogli uraditi prostim pozivom poput

Razmij eni (a, b);

3
l
~

f ~

[
)Razmijeni(&a, &b);/ [
Takoder, samu funkdju Razmij eni treo . romi'eniti da um·esto ci'elih bro'eva [
lff' fJL~Ie ~~- Tada je moguCe upotrijebilf openitor dereferenciranja da se pomocu njega in i~:e o
• prlstupf11
\
r
.
JU memorijskih 1okacija gdje se nalaze stvami parametri i da se na taj naein izvrsi
razmjena Na taj nacin funkcija Razmij eni mogla bi izgledati ovako:

void Razmijeni(int *Pokl, int *Pok2) ·· {


int Pomocna = *Pokl;
*Pokl ~ *Pok2; *Pok2 = Po~ocna; ,.. \ , . •,···;.:.:~. [
;:"rl:'f

Mada napisana funkcija izgleda dosta sliM~ kae;'funkcija napisana preko prenosa parametl(ia po
. referenc4 poCetniku nije posve 1ako shvatiti kak() ona radi. Neka je npr. a - 5 i b - 8 i neka je fulikcija
Razmijeni pozvana na opisani nacin. S1jede6a slika ilustrira situaciju nakon izvrsavanja svake od Iiaredbi
0
u funkciji Razmij eni (navedene adrese i raspored u memoriji uzeti su kao cisto hipotetiCki primjer):

Razmijeni(&a, &b); . ~~
0
~ifti ~.
Adrese 3144 3145 3146 3147 3148·· 3149 3150 3151
I 5 I 8 I I 3144 I 3145 I D
t L __+.3
a
··r . . . ·-·---····--··--··•··..!
b
• i
L....................-·············l····················-·l-·.1 .
Pokl Pok2 0
int Pomocna = *Pokl;

Adrese _::.:....,.....:::3.:.144.:..:....r:3~1,.:.:45::....,.-=3,,1'-'4.::.6-,-::.31:..4:_:7,.'·r·,.:..:::·:3.:.14.:.:8:....;-_::3150
l 5 I 8 I I 314,FI ~145 I
3:_o1-"49::....,.--"'-"=-.-~:.:....r"''-
I
3151
5 I
n
·-
*Pokl ~ *Pok2;
t
Pomocna
n ......

D
Adrese
I
ta
3144 3145
8 I s
1' +1' ..
I
'3146
I
+,!
3147
3144 I
.!
3148
3145

:............T····t:.-.-.-~:::::::.-.-.-~:.-::::~·.-::::.r::~............-.. l-.1
b Pokl Pok2
I
3149 3150
I
t
3151

Pomocna
5

u
*Pok2 = Pomocna;
Adrese 3144 3145 3146 3147 3148 3149 3150 3151
I 8 I. 5 I I I
3144 I 3145 I 5

ta
L. . +
b
······-·········--·. ··-···. -1·---.. . . . . . -J•!
··r. . t·-·····-···-·········-·•-..!
Pokl
. .-
Pok2
t
P·omocna
Dl

Naravno, Jje8enje napisano jezika C++ koriStenjem pre,i}osa parametara po referenci je Dl


mnogo jednostavnije i jas:ni.iJ~:/i~edutim, veoma ilustrati.vno · demonstrira

II

. .J!'·--
4
f(
!I
L-~

D.
i ~

n~~
ao promjenljiva sm·estena na lokaciju na ko·u
kontekstu u kojem i hilo koja drilga

0
~.,;
void Obrisi Ci,ntjPromjenljiva) '{
}
PromjenljiY~ ~ 0;
.. ·

0w koja postavlja promjenljivu koja joj je prosljedena kaJirr,gument na 0, sasvim je moguee koristiti poziv
funkcije poput ·

0
'i,....,.,
Obrisi{*Pokazivac);

Ovaj poziv ce postaviti na 0 Iokaciju na kojJ!,pokazuje proinjenljiva Pokazi vac.


0
'-~ . J~om po~vaeu mo~ do~jeli~fl! 1,;t~ai.ivac samo ukoliko
se okazu ·u iza Na I
pnmjer, ukoliko rmamo deklarac!Ju ·. ·;: . ·~iit1 i ,. · ~· · · •
,0
..... ,~
.
~nt
*
Pokl,
*
!¥'
.
Pok2,
;r-:·\ ::/ ~;~---·-.·"11:.'
"''·~~ -;, . .
. :~... 1;
.
tada je dodjela Pokl = Pok2 posve Jeg~~;:ijl:akon nje Pokl i Pok2 l)Okazuju na istu lokaciju u ~
D
'\..-.
memoriji (isto vrijedi za dodjelu Pok2... = Po,)."S ~ruge strane, ukoliko imamo deklaracije
int *Pokl;

D
L
. double *Pok2;

p
Treha razlikovati ove dodjele
t•
'-'

0
\,!,.
int *a, b;

Q samo a pokazivacka promjenljiva, dok je b ohiena cjelohrojna promjenljiva Moguee je pomocu naredhe
typedef definirati i novi pokazivacki tip. Na primjer, deklaracijom
0
,.,.,
#'I typedef int *PokNaJ;nt; J

0
~
. uveli smo novi tip PokNaint koji predstavlja tip pokazivaca na cijele brojeve. Stoga, deklaracijom

L_PokNaint pl, p2; J


0

deklariramo dvije promjenljive pl i p2 koji su pokazivaci na cijele hrojeve.

Mada u svojoj osnovi moZemo reCi da pokazivaCke promjenljive u sehi interno sadrZe takoder

a brojeve (koji predstavljaju adrese nekih objekata), C++ pokazivacke promjenljive tretira posve drugaCije
nego ohiene hrojeane promjenljive. Stoga, mnoge aritrneticke operacije nad pokazivaekim promjenljivim
~
nisu dozvoljene, a i one koje jesu dozvoljene interpretiraju se drugacije nego sa hrojCanim I'll
] promjenljivim. Na primjer, nije dozvolleno §!!brati, pomnoZiti ili podijeliti dva pokazivaea (razlog za ovu f!
zabranu je Cinjenica da se ne vidi fa
Sta hi smisleno mogao pckazivati pokazivac koji hi se dohio ~ •
~
mnoZelljem adresa dva drilga objekta). Slieno, nije dozvoljeno pomnoZiti ill podijeliti pokazivac sa

] hrojem, ili obrnuto. Takoder; mada se vrijednost pokazivaca more i8p~ati (u heksadekadnom ohliku) na
izlazni tok, cout, nije dozvoljeno sa tastature · toka cin. Medutim,
.. \\•• ~ ~ i
od drugog. U nastavku cemo razmotriti srnisao ovih operacija.
] ···.f.-t.
• . •·
..,-j ,,'
5
I J "
~
I

·f
~

Znaeenje pokazivaeke aritmetike najlakSe je objasniti na primjeru u kojem pokazivae pokazuje na


neki element niza (napomenimo da operator referenciranja "&" kao svoj argument prihvata bilo kak:vu
1-vrijednost, odnosno bilo S!a $to moZe stajati sa lijeve strane operatora dodje!jiyanj;~, stoga argument
f
~

operatom "&" moZe biti i indeksirani element ni7..a; s druge stmne, izrazi popuf &2 i & ( a + 2 ) su
besmisleni). Pretpostavimo da imamo sljedeee deklaracije: '
f
~

.:;·double Niz[5] = {4.23, 7, 3.441, -12.9, 6.03};


Z double *p = &Niz[2];

\ Ovim smo postavili pokazivac p da pokazuje na element niza Niz [2]. Medutim, razmotrimo sada
f
• Cinjenicu da e!ementi niza tipa double sigurno ne mogu stati u jednu jednobajtnu memorijsku lokaciju.
Pretpostavimo npr. dajedan element ovakvog niza zauzima 8 bajta (u skladu sa IEEE 754 standardom).
Memorijska slika nakon ovih deklaracija mog!a bi izgledati ovako (adrese su ponovo izabrane posve
&
nasumicno):

Adrese ... 370+377 378+385 389~ .•


. ; -_ . 11'.

~314+401 402+409
.

550 ...
[
I 4.23 I 1 I
J~ t.i,
·3'im ·· . ~12.9 6,o3
ti
i':.. ~~-............._.....:.....__,_,_,_..............
I 386 I
fi---
Pokazivac p pokazuje na element .Niz (2], a n·e ~V'lvarni siufrzaj je adresa 386 (naravno, u skladu D
~

sa pretpostav!jerum pnmJerom memorijske slike). Razmotrimo sada izraz p + 1. vaJ 1zraz ponovo
predstav!ja pokazivac ali ko'i okazu'e na eleme Niz [ 3 Stoga njegova stvarna vrijednost nije 387
(386+1) nego 394. Dakle dodavan·e 'edinice na ne · azivac da'e kao rezultat novi okazivac ko'i D
~

pokazuje na sljedef:i element niza u odnosli na element na koji pokazuje izvorni pokazivac. Pri tome,
'II
• ·stvarna adiesa ne mora nuZn.o biti poveeana za 1. Zapravo, mo!lemo zilkljuciti da se stvarna adresa koju

• sadrZi pokazivae
ovakva
·
·
(izraZenu u bajtima). Mediltim,
koliko zaista neki element D
~~~~'Ukp~!!l!..;:v
·prethodni element (u navedenom . .
S druge
izraz oblika
p - 1 pokazuje na
~
gdje je p pokazivac a n cijeli broj (iii rna klikav · ·
pokazuje na element niza koji se nalazi n elemenata ispred odnosno iza elementa niza na koji pokazuje
,
pok~y~~.:P.· Stoga ee s!jedeea naredba ispisati elemente
- .
niza 3.4,41,' 12.9 i 6.03: D
for(int i = 0; i <= 2; i++) co'ut ·<< * {p + i);
D
Uocite razliku izrnedu izrazat*'<P"71 )7i izr~(odnosno (*p) + i) koji, kao Sto smo ranije
vidjeli, imaju posve drugacije ~Takoder, 'JGilro:(e svaki dereferencirani pokazivac 1-vrijednost, to
su izrazi poput izraza , 0
~

*(p- 1} = 8.5

sasvim smisleni (ovaj izraz ce postaviti vrijednost elementa niZll; Ni z [ 11 na 8.5~.


0
~

·I
Nad pokazivaekim promjeriljivim se mogu primjenjivati i operatori "+=", "-=", "++" i "--" cije je
znaeenje analogno kao za obiene rom'eril" e sarno Sto se koristi pokazivaCka aritmetika Na pnmJef.
0
~

p += 2 promijeniee sadrZaj pokazivaCke promj · g1ve p t o po ~e na e emen mza oji se nalazi ~


• dva mjesta ispred elementa niza na koji p trenutno pokiiZUje, dok
· promjenljve tako da pokazuje na prethodni element nizi u .odnosu
ee
--p promijeniti sadrZaj pokazivac"ke
na element na koji p trenutno
il
naCin koristiti tokom
niza.
pointers), kao Sto je ilustrirano u n
n
s!jedeeem primjeru su Niz i p deklarirani,kao uranijimprimj erinla):

6
n
II
f} .
._

f} p=&Niz[O] ;
for(int; i = 0; i < 5; i++) {
' " cout << *p;
p++;

t-t/Dereferenciranje i inkrementiranje (odnosno dekrementiranie) pokazivaca se eesto obavlja u istom


izrazu, sto je ilustrirano u sljedecem primjeru (koji je ekvivalentan prethodnom):
.. p = &Niz[O];
for(int i = 0; i < 5; i++) cout << *p++;
D
.' .& <:>
U posljednjem primjeru, izraz @~erpretira se kao ~ a ne kao ( *p) ++ koji irna druga&ije,
ranije obja8njenq znaeenje.
0.
'

0
\..- -~

0~.,; ..~
p = Niz; ,J//
for(int i = 0; i < 5; Jt+) cout << *p++; IV

0
'-•
Stoga ne treba da cudi da 6e izraz poput cou)::· « Niz na ekranu ispisati neki heksadekadni broj.
_?:apravo, bice ispisana adresa prvog elementa 1ziza

PoSto se nizovi po potrebi autoniatski konvertiraju u pokazivaee, slijedi da se i na nizove more


0
1----·
prirnijeniti pokazivacka aritiDetika. Stoga, elemente niza Niz:.moremo ispisati i ovako:
,
_"..,.
for (int i = 0; i < 5; i++) Qt>ut << * (Niz + i);
u .-.t- ...,... :" ':

Tak.oder, izra:z~~bog au~mafike ~?~t,~rzi·e nizova? P?kazivaee i. pok~vaeke ari~etike


ekvivalentanJ e na pm pogled besiDlslenonrlzr¥11 iz + 2: rmJe uspostav!Jena tl.]esna veza =edu
0
~
pokazivaca i nizova u jezicirna C i C++. Ovi jezici su menutu vezu ucinili jos ffJeSIIlJOm (kakva ne
postOJl niti u jednom drugom programskom jeziku) uvocfen·em konvencije da izrazi oblika a [nJ i
C• (a + ni) budu eotguni sinonimi, bez obzira da li je a irne niza 1 po azJV • girn rij rma,
'\I
0
~
indeksiranje se more piffi'iileruti i na pokazivaee! Ovo ilustrira sljedeei prirnjer koji ispisuje elemente
, •' 4.23, 7, 3.441 i -12.9 i koji pokazuje kako se u C++-u mogu~ulirati nizovi sa negativnim indeksima
kakvi postoje u nekini drugirn programskinij eiicirna (npr. u Pascalu):

0 p = Niz + 2;
for(int i = -2; i <= 1; i++) cout <<'p[i];

D Podsjetimo se da dodjel~~aisto znaeenje kao~


T
~

Bez obzira na tijesnu vezu izmedu pokazivaea i riizova, na irnena nizova ne se primijeniti I
.0
operaton "+-"~ "--", "++" i "--" koji miieniaju sa.drZ~ pokazivaCke promjenljivt,\5>C:sno lokaciju na'
koju om pokazuju. imena nizova (saniii za sebe, b'ez indeksiianja) uvijek se tretiraju kao pokazivae na /
prvi element niza, i to se ne moie promijenili. Stoga se irnena niibva ne moBU koristitl kao ldizeCi
] pokazivaci. •

Kako se nizovi po potrebi automatski konvertiraju u pokazivaee kada se upotrijebe bez indeksa,.~
] \\\
svaka funkcija koja kao svoj formalnj parametar oeekuje pokazivae na neki tip kad stvarni parametar
prihvatiti niz elemenata tog tipa (naravno, formalni parametar ce pri tome pokazivati na prvi element
• niza). Vrijedi i obratno: funkciji koja kao formalni parametar oeekuje niz moremo kao stvarni paranietar
proslijediti po~vac odgovarajueeg tipa Zapravo, C++ uopee ne pravi razliku izmedu formalnog
]
7
~
l
·1-
Tip" (u oba
\, parametra tipa "pokazivae na tip Tip" i formalnog parametra tipa "Niz elemenata tipa
, Slueaja funkcija dobija adresu prvog elementa niza). To nam omoguca va da funkcije koje obraduju ·[
nizove moZem.o realizirati i preko klizeeih pokazivaca Na primjer, funkcijU koja
elemente niza realnih brojeva mozemo umjesto uohicajenog nacina realizirati i na
6e ispisati
sljedeci nacin:
na ekranu
--

~void IspisiN iz(dou ble *Pokaz ivac, int N) {


I

f--
~ } for(i~t i = 0; i < N; i++) cout << *Pokaz ivac++ << endl;

. Ovu funkciju mozemo pozvati na posve uobicajeni naCin:


1
IspisiN iz(Niz , 5); .. ·:'. '[,_,
vac [ ]. U oba
. Nikakve razlike ne bi bilo ni da smo formalni parametar deklarirali kao double Pokazi
slueaja on bi se mogao koristiti kao klizeci pokazivac. f
f Mogu6e je deklarirati i P,f!.'ffliV,~f:~na/%i?tJf:'J,~<; o~Mqe. ~a prim~~, deklaracijom
canst double *p; J,t/-
da se sadd~
deklariramo pokazivae p na konstantnu realnu vrijednost. Ovakvi pokazivaei omogu¢ay;iju
pokaziva cem izrazi
.:jf lokacije na koju oni pokazuju cita. ali ne i da se mijenja. Na primjer, sa ovakvim
ali ~I
cout « *.P i Broj = _P [2] su legalni (p~d ll\jetom daje ~roj realna promjenljiva),
formaln iparame tar Pokaziv ac u prethodn oJ.
*p = 2.51 p(2] = o rusu (odavde odmah VIdimo <jase
funkciji mogao deklarirati kao const double· *Pokaz ivac).
ne
Na ovom mjestu potrebno je razjasniti neke ceste zablude vezane za pokazivace na konstant
'f objekte. Prvo, pokazivac na konstantniobjekat ne6e automatski uciniti objekat na koji
• konstantom. Na primjer, ako je p pokazivac na koristant nu realnu vrijednost, a Broj
on pokazuje
neka realna D
-
(nekonstantna) promjenljiva, dodjela p = &Broj
Promjenljiva moci
D
.....

'

sama za
pokazivaCi mogu se deklarirati na sljedeCi
pona8aju se upravo
naCin: ·
0
-
double *canst p = &Niz[2 ]; 0
-
IJI ·er muse naknadno vrijednost vise
• <> •

"
nstantni objekat, npr. deklaracijom
0
-
canst double *const p = &Niz[2 ];
0
-
Moze se postaviti pitanje .za5to se uop6e patiti sa pokazivacima i koristiti
1ranja Ako zanemarm10 dinamic o ac1Ju
ukoliko se ista stvar more obaVI .1 uz pomoc ·
memorije, 0 kojoj 6e kasnije biti govora i koja se ne mo'te izvesti bez upotrebe pokaziva
razlog je efikasnost Nairne, mnoge radnj e se mogu neposrednije obaviti upotrebom klizeCih
ca, osnoVlli
pokazivaea
0
jalno, jedan
nego pomoeu indeksiranja, naroCito u slueajevima kada se elementi niza obraduju sekvenci
za drugim. Navedimo jedan klasiCni Skolski primjer koji se navodi u gotovo svim udZbeni
programski jezik C (Jjede za C++, jer se C++ ne hvali toliko pokaziva cima koliko C).
cima za
Nairne,
D
iz bibliotek e cstring ) koju smo
razmotrimo kako bi se funkcija kopiraj strin · odnosno strc y
razmatrali u po av JU o strmgovima mogla realizirati uz pomoc klizeCih pokliZlvaea IZvoma
"funkcije kopira j_strin g glasilaje ovako:
vemja
D
8
D
lrJ
"
a
,_4
void kopiraj string(ch ar Odredisn i[], const char Izvorni[] ) {
D int i ·o; ·
while(Izv orni(i] != 0)

n
~--·t

Odredisn i[i] Izvorni[i ];


i++;

~-~ Odredisn i[i] 0;

'
0
~-J
(iJ
Zamijenimo sada parametre Odredisni i Izvorni klizecim pokazivacima Odmah vidimo da nam
indeksna promjenljiva i vise nije potrebna:
n
i.,,.J
'· ·void kopiraj string (char *bdredisn i, const char *Izvcirnil
while(*Iz vorni !- 0) {
@

0
I 1
*Odredisn i = *Izvorni;
Odredisni ++; Izvorni++ ;

p
~.,;

*Odredisn i = 0;
/,1\ ,

~ . .J
V) "
- '
Dalje, oba inkrementiranja moremo obaviti u istom izrazu u kojem vrsimo dodjelu. Takoder, test

.
0
....,.
razliCitosti od 0 moremo izostaviti (u skladu sa tretmanom uvjeta ujeziku C++) cime dobijamo sljede6u
verziju funkcije:
_void kopfraj string(ch ar *Odredisp ,i, const char *Izvorni) {
0,... while(*Iz vorni) *Odredisn i++
*Odredisn i = 0;
*Izvorn1+ +;

u ~.,i
Konaeno, kako je. u jeziku C++ dodjela takoder izraz, rezultat izvrsene dodjele je zapravo· rezultat izraza
*Izvorni (inkrementiranje se obavlja naknadno) koji je id(mtiean sa izrazom u uvjetu while petlje.

DL
Stoga se funkcija more svesti na sljedeci oblik ·
,...
void lropiraj string (char *Odredisn i, cons.t char *Izvorni)
wh1le(*Od redisn1++ *Izvorni+ +);
0L

Djeluje nevjerovatno, zar ne.l? Prilliijetimo daje nestala potreba c!lk i za dodjelom *Odredisn i = 0, jer
0L. je lako uociti da 6e ovako napisana petlja iskopirati i NUL granicnik. Ovaj primjer veoma ilustrativno
pokazuje u kojoj mjeri se klize6i pokazivaCi mogu iskorisl;iti za optirnizaciju koda (dodu8e, po cijenu
citljivosti i razumljivosti, mada se na pokazivacku aritmetiku programeri brzo naviknu kada je jednom
poenu koristiti). Funkcija strcpy iz biblikoteke cstring implementiranaje upravo ovako. Doduse, ne

R ba8 u potpunosti: prava funkcija strcpy iz biblikoteke cstring implementiranaje taeno ovako:
~

char *strcpy(c har *Destinat ion, const char *Source)_ {


.

G
h.
char *Base Destinati on;
while(*So urce++ ='*Destin ation++};
return Base;

G
...
~ Praktieno jedina razlika je u tome Sto (prava) funkci~a strcpy _pored toga Sto -obavlja kopiranje .11
vraca kao rezultat pokazivac na prvi element niza u ko "i se vrSi ko iran"e (isto svojstvo posjeduje i • •

~~
C!Ja s rca . pnmJerom smo ujedno vidjeli i da funkcija more kao rezultat vratiti pokazivae.
Povratna vrijednostkoju vracaju funkcije strcp i strcat na"ce§ce se iPDorira .kao sto smo i mi radili
utnn, ova povratna vrijednost more se nekada korisno upotrijebiti
l
'-~
u SVlDl osadaSnjim pnmJenma.
za ulaneavanje funkcija strcpy i/ili strcat. Na primjer, posmatrajmo sljede6u sekvencu naredbi (uz
pretpostavku da su recenica, rij eel, rij ec2 i rij ec3 propisno deklarirani nizovi makova):

l
'-..,.
9
r
J-
strcpy(recenica, rijecl);
strcat(recenica, rijec2);
f
strcat(recenica, rijec3);
cout << recenica; -
.'
Zahvaljujuci cinjenici da funkcije strcpy i strcat vracaju pokazivac na odrediSill niz, ove Cetiri
naredbe mozemoRompakttiije zaplSatl u VldU sljedeee naredbe:
J-
\ cout << strcat.(strcat (strcpy(recenica, rijecl), rijec2), rijec3);
f
Treba napomenuti da pomenuto svojstvo funkcija strcat i strepy more poeetnika da dovede u
zabludu. Nairne, mnogi poeetnici eesto isprobaju naredbu poput sljedeee:

;( cout << strcat ( "Dobar "I "dan! n);

Pokazj,'{acka aritmetika moze se veoma lijepo iskoristiti zajedno sa funkcijama koje barataju sa
stringovima (strcpy, strcat, st;,:cmp itd.). · Na primjer, ukoliko je potrebno iz niza zitakova
~~~~~~:ygi..!!~r.ll!~~~?.,_ to najlakse mozei:no uraditi

<; strcpy (:i:-ecenica-2,
,.
&recenica [ 9 J ) ;
L_ strcpy (recenica2, rE7c.enica + 9) ;
n
_,

Ista tebnika more 'se" ·isi<'-Orlstiti i sa funkcijama koje prihvataju proizvoljne vrste niiova kao
D
'-'
parametre, odnosno .koje prihvataju pokazivaee na proizvoljne tipove~ Na primjer, pretpostavimo da
relimo iz raillje dekiariranog niza realnih brojeva Niz·;~spisati samo drugi, treCi i eetvrti element (1j.
elemente sa indeksima 1, 2 i 3). Nema potrebe da prcjinivljamo vee napisanu funkciju IspisiNiz, sl D
.._j
obzirom da ovaj cilj motemo veoma jednostavno o~ariti jednim od sljedeea dva poziva, bez obzira da •
li je funkcija napisana da prihvata pokazivace 'ilil!nizove ·kao svoj prvi argument, i bez obzira da li je
napisana koriStenjem indeksiranja ill kiizeCih pokazivaca: 0
~

~ IspisiNiz(&Nj,z[l], 3);
2_. IspisiNiz (Nif'"'+ 1:
.
3); ..... ~. ·
.,.,.- . ,.
~ u
~

,
Ova univerzalnost ostvarenaje autoJ:Witskom konverzijom nizova u-pokazivaee, kao i moguenostu da se
indeksiranje primjenjuje na pokazivaee kao da se radi o nizovima
....
PokazivaCi se- mOgu ,jorediti pomoC~ operatora 11 <11 , "> 11 , "<=", ">=", 11 == 11 i n! ='' pod uvietom da
n
pokazuju na isti tip.__ ~a pokazivaea na razlicite tipove ~ rq.o~ se porediti, Cak i ukoliko su tipovi na
• koje r
pokazivaei pokazuju uporedivi-(npr. pokazivaci na int double). pva pokazivaca (Aa isti tip) su
jednaki nkoliko pokazuju na istu adresu. Prvi pokazivac je manji od drugog ukoliko pokazuje na
lokaciju n memoriji koja je ispred lokacije na koju.pokazuje drugi pokazivac (npr. ukoliko pokazuje na
element niza sa manjim indeksom od elementa niza na koji pokazuje drugi pokazivaC), a veCi od drugog 0
.._j

n
ukoliko pokazuje na lokaciju u memoriji ko"aje iza lokacije na koju pokazuje drugi pokazivac. Treba
praviti razliku izmedu poredenja popu pl == p koje poredi dva pokazivaca (ko"i mogu biti razliCiti
, Cak i ukoliko su sadrtaji lokacija na koje om i>o ~u is_!!) i poredenja poput pl = *p2 OJe por
• _sadriaje lokaci"a na koje pokazuju dva pokiiiivaca (koji mogu biti isti Cak i o o su pokazivaCi
razliCiti). Takoder, zbog automat e onvemje mzova u pokazi • oredenja poput<Bijf == Niz3'
gdje su Nizl i Niz2 nizovi istog tipa sasvim su legalna i orede adres na kojima su u memonji
{]I
smjesteni nizovi Nizl i Niz2, a €ifiliriaje nizo'§ kako bi ne o mogao pomisliti (sadrZaje nizova -
{l
10
I.' ~,j
n.
. !
..... J

fl sadrZaje dv<!

' J

n Tijesna veza izrnedu nizova i pokazivaea i C:injenica da se nizovi znakova tretiraju donekle razliCito
od osta!ih nizova ima kao posljedicu da se i g_okazivaci na znakove tretiraju neznatno llrugacije nego
pokazivaei na druge ohjekte. Tako, ukoliko je p pokazivac na znakove (tj. na tip char), naredba ispisa
cout << p nece ispisati adresu smjeStem1- ·u pokazivac p, nego sve znakove iz memorije pocev od
u
"adrese smje= polcazivae p pa sve do NUL graniCnika. Na ovaj nacin je, kao prvo, ostvarena
konzistencija sa tretmanom znakovnib nizova od strane ohjekta izlaznog toka cout, a kao drugo, /
omoguceni su neki interesantni efekti. Na primjer, sljedeca skupina naredhi · •

f
char recen.l.ca [] = "Principi p.r.ogramiranja";
char *p = &recenica [ 9] ; . . tt--
cout << p; ~ .

ispisa6e t~kst "programir~ja" n11. ehan!·}l~ hakon · · · . ·


u
reeenice smjeStene niz receb:ii::a (jrldekSiran". poeillje od nule), a to je upravo prvi znak druge rijeei
u nizu re\'enica, odnosno pi>~ ltijel!':teksta koji glasi "prograrniranja". Naravno, umjesto izraza
&recenica [ 9] mogli smo pisatt!l' recenlC:a + 9 (s ohzirom da hi se u ovom primjeru upotreha imena.
recenica hez indeksa ilutomatski kOJ:?.V'ertirala u pokazivac na prvi element niza, nakon cega hi
pokazivaeka aritmetika odradila ost:jtak posla). Takoder, uopce nismo ni morali uvoditi pokazivacku
promjeuljivu p: mogli smo prosto pisati. · ·
·""'\
')char recenica [] = "Principi pr9grarnitari5.a";
(_ cout << &recenica [9];

odnosno

char recenica [] = "Principi prograrn~ranj a";


cout << recenica + 9;

ff Pokazivaei na znakove sujedini okaziV!Wiko"i se mo kori t1 to c · . Tako, ako


1 'je p pokazivac na znakove, naredha ulaza f.in >> p ce zn · . ove pnstigle sa ulaznog toka .{do. prvog
, ra~nka! s:njesti~ u memoriju po~v ~4 ¥Jfese i&'Stene u _pok~vaeu p. Slicno, ~jedi _i ~ naredhu
poput cln, getllne (p, 100) . Zajedi).o .Sji pokaZivackom antmetikom, ovo se moze 1skonsttt1 za razne
interesantne efekte. Na primjer, pomocu sekvence naredbi ., ·

char recenica[lOO] = "Pocetak: ·",.'*P = &recenica(9j;


cin >> p; ·.._ · t {!

' "'-·· .. -~·. .


. - . -~-~-- ~·'l
sa tastatnre 6e se unijeti }edna rijec, i smjestiti u niz recenica poeev od desetog znaka, odnosno taCno iza
teksta "Pocetak: ". I ovdje smo mogli izhjeCi uvodeJ\ie promjeuljive pi pisati.!Oin >> &recenica [ 9]
iii cin » ecenica + 9. Ukoliko hismo umjesto jedne rijeci Ze!jeli unijeti citavu lini;u leks/a, koristili
hismo in. getline (p, 90) odnosn-;;;bezpromjenljive p, cin. get line (&recenica [9], 90) iii
·-;;:;:-getline (recenica + 9, 90). Maksimalna duZina 90 odredenaje tako sto je od maksimalnog
kapaciteta od I 00 znakova odhijen prostor za NUL graniCnik, i prostor koji je vee rezerviran za tekst
"PoCetak: ". ~,

PokazivaCi i pokazivaeka aritmetika omogueavaju prilicno moene trikove, koje hi inaCe hilo znatno
teze realizirati. S druge strane, pokazivaci mogu hiti i veoma opasni, jer lako niogu "(Jdlutati" u dio neki
nepredvideni dio memorije, sto omogu6ava aa
mdiiektno pomocu njih promijenimo ptakticki hilo koji
di~ memorije wosJj~~ ?V~ intervencij~ SU pret<~ZnO ~epred~~~: i ~~0 f~). ~a p~jer,. ~
svrm dosadaSn)lm pnWJenma rm smo pokazivaeku antmetilm konstili isk!Jucivo sai?bkazivael!Da koll
pokazuju na neki ele!l!.ent niza Zapravo, pokazivacku aritmetiku hi tako i trehruo koristiti. Medutim,
razmotrimo sljede6u sekvencu naredbi: . ·
]
.
'
11
II
.f
int a = 5, *p &a;

X p++;
*p = 3;

· Ov4te smo prvo deklarirali cjelobrojnu promjenljivu a koju smo inicijalizirali na vrijednost 5, a
zatim pokazivacku promjenijivu p koja pokazuje na promjenljivu a (odnosno, sadiZi adresu promjenljive
a). Nakon togaje na promjenljivu p primijenjen operator"++". NaSta sada pgkazuje promjenliiva g? U
skladu sa pokazivaCkom aritmetikom, p pokazuje na adresu neposredno iza prostora koji zauzima
promjenljiva p. Nakon toga ee naredba dodjela *p = 3 "tamo" upisati vrijednost 3. Medutim, Sta se
nalazi "tarno"? Odgovor je nepredvidljiv: moZda neka druga promjenljiva, moZda niSta parnetn<i, a
II moZda neki podatak od vitalne vafuosi:J. za rad operativno sistema! Samim tim, posljedica ove dodjele
je nepredvidljiva U svakom slucaju, dodjelo * = 3 "napali srno lokaciju ciju svrhu ne znarno, Sto je
strogo zabranjeno. Za pokazivac koji je "odlutao" t o vise ne znamo na sta pokazuje karemo da je
n
I .
~

divti gokazivac (to ne znaci dane znarno koja je adresa u njemu, nego dane znamo kome pripada adresa
na o)u on pokazuje). Divlji pokazivaei nikada se ne. hi trebali pojaviti u"programu. NaZalost, greSke
koje nastaju usljed clivljih pokazivaea veoma se teSk9 otkrivaju, a priticno ihje lako napraviti. Smatra se
[Iw
da oko 90% svih fatalnih gresaka u dana8njim profesronalnirn programima nastaje upravo zbog ilegalnog
pristupa memoriji preko clivljih pokazivaca! · .,..,..,,. ·
D
u
U vezi sa clivljim pokazivaeima neophodno je naglasiti jednu nezgodnu osobinu: svi pokazivaei su
neposredno nakon dekl~ clivlji.._,sve dok im se eksplicituo ne. doclijeli vri"ednost! Nairne, kao i sve
Ostale promjenljive, njihova vrijednost je ne nirana neposredno nakon deklaracije, sve do prve 0
......
dodjele (osim u slueajevima kada se inicijalizacija vrsi uporedo sa dodjelom). Tako je i sa pokazivacima:
njihova poeetua vrijednost je nedefinirana, tako da se sve do prve dodjele ne zna ni na sta pokazuju! Na
primjer, sljedeea sekvenca naredbi ima. nepredyjdljive posljedice jer "napada" nepoznati clio memorije, s
obzirom da se ne zna na sta p pokazuje: ·
0'-'

int *p;
*p = 10;
0
;..,./

' D
_Sljedeei izrazito neispravan primjer je takoder eest !cod pocetuika:
._)
char *p;
y cin >> p;
....
cout << p; -~
D
Mada onome ko isproba navedeni primjer more izgledati da racli korektuo (odnosno da ispisuje .na
ekran rijec prethodno unesenu sa tastature), on sadrZi katastrofalnu greSku. Nairne, ,kako je p
neii~fcii,aliziran B~kazi:vac~ _njegov sadrzaj_ ;e ?eprMvidljiv, pa ~e i potp~_o nepredvidljivo gdj_e ce ~: D
uopce u memonJI SIDJeSI:J.I:J. znakoV!. proc1tam sa tastature! Moze se des1t1 da se program kOJI sadrZi
ovakve naredbe "srusi" tek nakon vise sati, ukoliko se ispostavi da su srnjesteni znakovi "upropastili"
neke bitue podatke u memoriji. Moze se desiti da u startup pokazuje na neki clio memorije zabranjen za 0
upis od strane operativnog sistema. U tom slucaju program ee se srusiti odma!I (zapravo, operativni

,,
••
sistem ee prekinuti njegovo izvrsavanje). U tom slucaju cak moremo reei da srno imali sreee!

Pokazivaeima na konstantue znakove mogu se inicijalizirati da pokazuju na neku stringovnu


konstantu. N a primjer:
0
t:; canst cha_r *p "Ovo j e neki string ... ";
D
......
£ cout << p;

Ovakvim pokazivacima je cak moguee i naknadno dodijeliti stringovne konstante, pri eemu ovakva D
~

"dodjela" naravno ne dodjeljuje sarnu stringovnu konstantu pokazivackoj promjenljivoj ( ona nema
"prostora~' da primi cijeli niz znakova u sebe), vee adresu stringovne kanstante. Medutim, bez obzira na
to, ovakva "poludodjela" more zajedno sa specijalnim tretmanotn proizvesti interesantue efekte. Na
primjer, sljede6i primjer je posve legalan:
D
U:
12
II I'
j..J

p~

!l const char *recenica ;


recenica = "Ja sam prva reCenica ...
cout << recenica << endl;
~ .,

n
'" recenica ="A ja sam·ctruga reCeni~......:..__
cout << receniGa << endl; .

~,. ..,..
Ranije smo vitljeli da slicna konstrukcija nije moguca sa nizovima makava, nego da se mora koristiti

n
....
t
konstrukcija poput sljedeee:

char recenica[l OO];

n
L..
[
~trcpy {recenica . nJa sam prva reC.eni ca
cout << recenica << endl;
.n);

~y ( recenica, "A ~~--c:f_Egga .r.e.Cenica.... ..--!'.} .;_ .


cout << recenica << endl;

[1' V eoma je va.Zna je 'ilaciti bitnu razliku izmedu navedena dva primjera, U prvom pnmJeru,
"'·· recenica Je pakazivae, kaji prva pokazuje na j~u stringavnu kanstantn, a zatim na drugu. S druge
strane, u drugam primjeru, receniqa je niz :mtlkova (za kaji je rezerviran prostor ad 100 mjesta za
D
•••
makave), u kaji se prva kopira j§na stringavna kanstanta,, a zatim druga .Ovu razlika je veoma va.Zna,
mada na prvi pogled djeluje nebitna, jer je krajnji efekat isti. Medutim, kaka je u prvam primjeru
recenica pakazivac na konstantne znakove, izmjena sadrfuja na koji on pakazuje nije maguca Staga
[] bi u primjeru paput sljedeeeg prevacWac prijavio greSku:
L. const char *Ime;

'
Ime = "Elma 11 ;
D
•··
Ime(O] = 'A';
cout << Irne;
II Ilegaino: Irne pokaznje na KONSTANTNE znakovel •

0
L.
Na ovome bi sva priea o pakazivacima na makave mogla da zavrsi da nijejedne nevolj~ Nairne, pa
pasljedn'em standardu 'ezika C++ kam a'leri ne bi trebali da e da e ob'" · · ·
ne oriStiuftne) makave dadjeljuju adrese stringavnih kanstanti. KaZelllo "ne bi trebali", jer gatava svi
faspolaZivi kompajleri za C++ dozvoljavaju takve dadjele (s abziram da su one dugi niz godina nacelno
D
L,.,.,
bile dozvoljene, bez abzira sto nisu smjele da budu). Staga 6e sljedeci primjer "proei" kwz ve6inn
.,..rasnoloZivih C++ kampajlera:
D
[.
char *Ime;
Ime = "Elma";
. ,·.

Dr.-.,.
f Ime(O] = 'A';
cout << "Elma";

"Repertoar" mo cih as!'edica· ove sku ine naredbi ·e raznovrstan. MaZda se program "srn8i" zbag

c,D
ga 8to Ime pakazuje na stringovnu konstantn kajaje mazda smjestena u diomemarije kojije zabranjen
za upis. Ukoliko to nije slucaj, gotavo sigumo da Cem.o na ekranu umjesto "Elma" imati ispisano
"Alma", bez obzira sta naredba ispisa eksplicitna ispisuje tekst "Elma". Nairne, obje pojave stringavne
kanstante "Eima" gotovo sigurna se u memariji cuva·u · m ·estu (sjetimo se stapanja stringova),
D
~-~
pa e se tzmjen s zaJa stringovne onstante" (izmjena kanstante je vee sama pa sebi apsurdna)
adraziti na svaku pajavu te stringovne kon:stante. Uglavnom, avakvam nekonzistentnom dadjelom

D
l_,

fl
1,..,,
,... adrese stringovne konstante pakazivaeu na nekonstantne makave u mogucnosti smo da proizvedemo
praktieno iste nereljene efekte kao kada stringovnu konstantn proslijedimo funkciji kaja vrSi izmjenu
sadrZaja niza, a eemu smo ranije gavorili. Navedima jos jedan katastrofalan primjer kaji se more sresti
kod poeetnika (i koji kampaJ1er ne bi trebao uapee da dozvoli):
char *recenica ;
recenica "Ja. sam recenica . .. "; tz..
D
'L, .. cin >> recenica;

u
~- -J
13
f ~

...Ill , Postavlja se pitanje gdje ce se u memoriju smjestih' niz znakova koji unesemo sa tastature? Odgovor je
jasan: na naJgore mogu6e mJesto preko znakova stringovne konstante "Ja sam reeenica,.. "! Pored toga,
ukoliko je uneseni niz znakova duii od du.Zine te stringovne konstante, viSak znakova ee "pojesti" i
£ I
~

Sadr.fuj memorije koji se naiazi iza ove stringovne konstante! Ukoliko pam operativni sistem odmah
prekine ovakav program, imamo mnogo sreee. Gora varijanta je da program pocile neispiavno raditi tek
nakon nekoliko sati, kad mu zatreba sadrZaj unistenog dijela memorije! · ·
{ l..

Iz svega Sto je reeeno bitno je shvatiti da se d trin azivacima na znakove


.niposto ne smije shvatiti kao ' ~epa i eiegantna ·zamjima za funkciju strcpy", nego kao neSto sto treba
koristiti sa izuzetnim oprezom, i to obavezno sa..P!efiksom const. Na taj nacin ce nas kompajler
j
r
~

upozoriti poku!iamo h izvrsiti nedozvoljeni "napad" na memoriju.


' . {._;
Interesantno je napomenuti dane postoje samo pokazivaei na jednostavne objekte, kao Sto su cijeli i
iealni brojevi iii znakovi. Pokaziyaee je rnoguee napraviti na hilo kqje objekle. Tako npr. postoje
pokazivaci na.nizove, pa i pokazivaci na pokazivace (tzv. dvojnipokiizivace). Takoder se i:nogu napraviti
i nizovi pokazivaca. Ovakve sloZelle tipove najlakse je napraviti pomocu typedef deklaracija. Na
G
-..)

primjer, neka su date sljedeee d~Jklaracije: · · ·

typedef int.*PokNqCijeli;
D
'-'
typedef int NizCijelih[10];
PokNaCij eli p1 ['30 J;;
NizCijelih *pZ.;
PokNaC:i,j eli *p3;
0
.....
''·

0
·").·

U ovom primjeru p 1 je niz od 30 pokazivaea .ila cijele brojeve, .1'2 je pokazipc na niz ad 10 cijelih
)>rojeva, dok je p3 pokazivac na pokazivae na cijele brojeve. Ov8kve konstrnkcije moguee je deklarirati i '-'
neposredno, bez typedef deklaracija (mada typedef deklaracije cine cijelu stvar mnogo jasnijom). Na
primjer, iste deklaracije mogle su se napisati i ovako:

int· *p1 [36]; - tMtr ~. ·


0
,_,
int (*p2) [10]; -P~11tt'lll/1"'h><.'l\­
int · **p3; D
'-'

Obratimo pafuju
predstavlja izmedu
pokaiivac deklarac:U~i'~~~~~;;~~~~:~~~;~~~~~
niz. Na uizvjestan
nd razlike u odnosu na"&okazivac", pa su u
0
drugom primjeru zag!ade bile neophodne da Mada konst:rUkC!Je poput navedenih -'
izgledaju veoma egzotieno, ~otreba zit njima dinarniCke alokacije memorije, pa 6eplo
o njima govoriti tom prilikom. Vrijedi jos napomeniiti ·da· se ovakve konstrnkcije mogu uslomjavati
unedogled (npr. principijelno je moguee napraViti pokazivqc na niz od I 0 pokazivaca na pokazivace na
0
~

niz od 50 rea/nih brojeva), mada se.JJOtreba za ovako slozenim konstrnkcijama javlja zaista iznimno
rijetko, i samo u veoma 'specifiCnim primjenama.

Od "egzoticnih" vrst~ pokazivaea potrebno je jos objasniti okazivace na fonkcije. · se deklariraju /


0
u

slicno kao i prototipovi funkcija, saq:IO uz jednu dodatnu Z'\dezdicu 1 par z

4~ (*PoJQlaFn) (int, int) 1}


a primjer, deklaracija •
0
l..

deklarira promjenljiw PokNaFn koja predstavlja pokazivac na (Unkciju lwja prima dva cjelobrojna
parametra, a vrata cjelobrojni rezultat. Dodattii par
zagradaje neophodan, jer bi deklaracija
D
L...

;~ V.
y' int *PokNaFn(int, ':int)

predstavljala prototip (Unkci~e Pol<Ni;w .twja primil .dya ctelobro(na param.etra a_ vra~a vp,1g$gi5 ":1.
u
u
_£yell bro; kao rezultat. Kao 1 u slucaJu mzova pokazivaea 1 pokazivaea na mzove, 1 ovdje hi! nek1 naem
"filrikc1Ja" ima prioritet u odnosu na "j)okazivac". ·

14
rrI -L
,,.,,
I ---

Q
Li
[} ]'okazivaci na funkcije u sebi s"!j!'ie.Odrevufimlwije dre.sa masins
izvr5ava cl!ID' fimkciju. Stoga se ovi pokazivaci..~~tlferencirat:i, niti se na njm m:ore '/
ama ko'i

~· primij~njivati pokazivacka aritmetika (lpal('oni se mogu porediti m.;dusobno}:' M:~utiin, pokaziva~iliia • ,

Q ,-iiifunkci'e se maze dodi'eliti ime nekejimkcije, pod uvjetom da ·e njen ti . saglasan ·sa_tipGm-funkcije.ruL
, , . koju funkcija pok~. Pored toga, na po azivaee na .CIJU ~e p~j~rtiti_p_gziyjU_~~if!', kao da
.'; '
'
se radi o funkciji (prilikom takvog poziva, poziva se funkcija na k.aJnlioliazivae pokazuje). Na primjer,
neka je deklariran pokazivac na funkciju PokNaFn na vee opisani nacin, i neka su date dvije funkcije
0
~1
Min i Max (od kojih prva vraea manji a druga veei od dva cjelobrojna argumenta):

int Min(int a, int b) { ·

0
return (a < b) ? a : ,:i);·

int Max(int a, int b) {


0
u
return (a < b) ? a : h;

q Tada su dozvoljene konstrukcije poput sljedeee (uz,pretpostavku da su a i b cjelobrojne promjenljive):

PokNaFn = Min; ..
cout << "Minimum je: ,; << PokNaFn(a, b);

0,
' '
....
[
PokNaFn = Max; · <";/
cout << "Maks.imum je: -'~ <<' Po~aFri(~, b);

g Dakle, pokazivaci na fimkcije OJ!!.Ogucavaju indirektan..wzh• firn?rcua iJokom imrsavanja programa I


~ pokazivati na razlicite funk_sje, kao Sto pokazivaei na obicne promjenljive omogucavaju indiretan •
pristup sadrzaju promjenljivih i tokom izvrSavanja prograi:ria mogu pokazivati na razlicite promjenljive.
..
0 Da bismo uvidjeli primjenu pokazivaea na furtkcije,
prirnjer~
ilustrativan
numericke
I
•• Ukoliko je funkcija.f{x) n an~aliz~·~e:·.~~~~~~~~~~~~~
su ~~~~~~~~~
f{b) ~~~~~
....0
(tj. ukoliko je.f{a)·.f{b)<O), tada funkcjj~ nulu unutar.ititervala (a, b), koja se lako more
odrediti postupkom polovljenja int.~ry.ala· (i!ite, p~~~li'1hinarne pretrage): Prvo biramo
taeku c=(a+ b)/2 tacno nil srt:<lllll in~~.ala(a, kojern od podintervala (a, c) o.dnosno
0
•..
(c, b) funkcija rnijenja znak. Nal!:oii tog; .intl~l¥.,)!:oji ne. SadrZ:i· n'uhi odbacimo, cime smo sirinu
intervala sveli na polovinu. sve dok ·sirina intervala ne postane manja od
unaprijed zadane tacnosti E. U Iako j\l.napisati funkciju NulaFunkcij e

0.. kojoj se kao parametri zadaju granice


je tacnost defurinina kao
tacnost. )'edna izVedba oye funkcije je sljedeea (u kojoj
sa vri.)ednoscu· 10~'): ··

0
.,~
(f (a)
if(a > b)
*
while(b - a > eps) {

0.•. double c = (a+b)/'2;·


if(f(a) * f(c) < 0) b =c;
else a = c;

] )
return (a + b) I 2; . ··~

] · Qva funkcija poziva funkciju f cija se nula tra.Zi. Na piinijer, ukoliko relimo da pronaderno nulu
furtkcije.f{x) -~ -x-1, morali btsmo pretliodiio negdje u prograniu defurirati furtkciju f kao
j;.

] double f(double x)
return x * x * x - x - 1;

1
15
I
l
~

.·[
~

. Nakon toga, funkciju NulaFunkcij e bismo mogli pozvati na uobieajeni nacin:


~'[
cout << "Nula f(x) na (1,2) je "<< NulaFunkcije(1, 2) << endl; ~

Osnovni problem ·sa ovl!ko napisanom funkcijom NulaFunkcij e je u tome Sto ona'uvijek poziva
jednu te istu funkciju - funkciju f. Sta ukoliko nam je potrebno da u istom programu nademo nulu
![.......
funkcijej(x) na intervalu (I, 2), zatim nulu funkcije g(x)=cosx-x na intervalu (0, 1) kao i nulu funkcije
sinx na intervalu (3,4)? Sa ovako napisanom funkcijom NulaFunkcije morali bismo napisati tri
verzije iste funkcije, od kojih bi jedna pozivala funkciju f, druga funkciju g, a treea funkciju sin.
[
L..
Prirodno ·e ostaviti pitan'e more lise nekako funkc .. i NulaFunkcije priJik~ll1.P.oziva S!IO...P.!iitj koju
funkciju treba da poziva, Odgovor na ovo pitanje nude upravo pokazlv na funkcije. Nairne, f treba j
deklarirati da bude formalni parametar tipa pokazivac na fonkciju koja prima jedan rea/an argument, a ~

'!/ ~
vraca rea/an broj kao rezultat. Nova verzija funkcije NulaFunkcij e mogla bi sada izgledati ovako:
double NulaFunkcije(d ouble (*f) (double), double a double b, ·
le eps 1e 7) i!J
a) * f(b) > 0) throw "f(a) i f(b) :;;u istog znaka!";
~
if(a >b) throw "Nekorektan interval!u;
while (b - a "> eps) {
double c = (a+b)/2;
~
~
if(f(a) * f(c) < 0) b c;
else a = c;
return (a + b) I 2;
CD ,·.: .-..
Pretpostavimo daje u programu pored funkcije f na propisan nacin dek!arirana i funkcija g (u sk!adu sa
~
~-
svojom definicijom). Tada bismo funkciju NulaFunkci j e mogli iskoristiti na sljedeci naCin:
"i!K
('cout << "Nula f(x. ). na (1,2) je '-~~·."'<_._'.N'!l·a. Funkcije(f, 1, 2) <_< endl;
J cout « "Nula g(x) na (1,2) je ~,}~<: Nf'laFunkcije(g , ·1, 2) «end!;
L.-Cout « "Nula sin(x) na (3,4) je -~~:,IS:f'NulaFtJ,nkcije(sin, 1, 2) « endl;
. ·, ~ w···_.·J -~-"- \ 0
....
A Primijetimo da se prilikom poziva funkcije k~w prvi.parametar navodi ime fimk:Qije kqju funkeija-
' NulaFunkcii e treha ~ poziva Pri tome je sve]e&l;o da li'se.f.adi o korisniCki napisanoj funkciji poput
f ill g, ill ugradenoj funkciji sin, sve dok njen tip odgovar!!- tipu:na koji pokazivac pokazuje. Potrebno 0
~

je jos napomenuti da izmedu funkcija i pokazivaea na funkci'e osto" sliena veza kao izmedu nizova i

o
okazivaea ·na elemente · va Nairne, · e funkcije kada se upotrijebi amo za~.<:.;._(bez zagrada koje}
avaJU poziv funkcije) automatski se konvertira u.pokOZivac na fonkciju. Stoga se ne treba cuditi Sto
6e naredba poput · -·--· ·-· -·-- ~
0
_.

cout << sin; Q


'-~- .
ispi&ati nekakav heksadekadni broj .(adresu ma8inskog prpgrama koji izvrsava funkciju sin). Takoder,
--
ovim postaje jasnije Sta se zapravo de8ava u slucaju ~ zaboravimo navesti par zagrada () prilikom
pozivanja neke funkcije koja nema parametara . . · 0
_.

Bituo je napomenuti da i pokazivaci na funkcije sadrZe slueajne vrijednosti dok im se eksplicituo ne


dodijeli vnJednost. To moze potencijalno biti veoma opasno. Na primjer, sljedeea sekvenca naredbi u
......
void (*PokNaFn) (int);
PokNaFn(S);
f.f.n
·- d~ pNv<r;(~ .~"'
~ •

11\0. i2.£iI.A potU'PI!\<-~


i
.1;-q lm.-14• o. 'L • j f
ac~<;J.t<Hl ~-J'I

skoro sigurno ce "srusiti" program, jer pokazivac PokNaFn sadrZi na poCetku nepredvidljivu vrijednost,
u
~

pa 6e i indirektui poziv posredstvom takvog pokazivaea pozvati ma8inski program sa nepredvidljive


adrese, i uz nepredvidljive posljedice.
[I'
-'

p~~~ p~
M
1\q 'l'U.b;ro.[Oko- 'IJC.i' 1~ 1c\~1~<7o'Cv'l1 P.JI~
/l!\l.IW\cM\' ll.k~ ,~ ~e,wto- t:f~·
16
~ p,..·~ ~/li.bt, ~0\.{~
. 'r.
c1AU..~I'1 /U.~.t/l/><\
u
Vee smo rekli da..Q_okazivaCima nije dozyoljeno eksnlicitno dodjeljivati hrajeve_. Medutim, postoji/
jedan broj koji se srnije dodijeliti svakom tipu pokazivaea: broj nula (0). Pokazivac kojemje dodijeljena'
vrijednost 0 naziva se !:! cesto se obilje2:ava sa NULL (ne NUL), tako da mnoge biblioteke
funkcija definiraju NULL koja ima vrijednost 0. Po konvenciji, smatra se da
nul-pokaziViJC ne pokazuje ni na sta. Obieno se pokazivac inicijalizira na nulu kada eksplicitno ilelimo
da naglasimo _pa pokazivac jos uvijek ne pokazuje ni na sta. Na primjer:

(i~
~~- ./

Na taj nacin lako moilemo kasnije ispitati u programu da li pokazivac pokazuje na nesto smisleno tako
Sto eemo prosto testirati da li je vrijednost pokazivaca nula Pored o~ednih testova tipa p -- o
odnosno p ! - 0, sintaksa1ezika C++ dozvoljava i navoden ·e izraza~~dnosno p unutar uvjeta if
naredbe (sve Sf0 nije nu a smatra se tacnim, pa makar to bioi pokazivac . · fl
'

Konvencija da se pokazivae k:lilji ne po~je ni na sta eksplicitno inicijalizira na nulu more uciniti
..
divlje pokazivaee "manje divljjplO: 'Pored toga, nul-pokazivaei se cesto vracaju kao rezultati iz funkcija
ko 'e kao rezultat vraeaju pok~vac, u sluea·u dane vrate neku smislenu vri'ednost. Na primjer,
. f biblioteka cstring sadrZi veoma korisnu funkciju tr koja una dva stringa kao parametre. Ova
• funkcija ispitnje da li se drugi string sadrZi u prvom s · gu (npr. string "je lijep" sadrZi se u stringu
"danas je lijep dan"). Ukoliko se nalazi, .!UWfcija vraea klto rezultat pokazivac na znak unutar prvog
stringa o_d kojeg poci~lje tekst. identic~ Ma:ioi)l_;ptringu (u navedenofu pfunjeru, -~o bi bio pokazivac ~a tp
prvu poJavu slova 'j" u stnngu "dallas Je ItJep dan"). U suprotnom, funkciJa kao rezultat vraca
nul-pokazivac. ,SliedeCi. primjer demonstrira kako se ova funkcija moze iskoris~ (obratite pamju na igr~
sa pokazivackom aritrnetikom):

.char rec;mica
c1n. getl1ne jlO.O_L_ff£.?;.!!l.l.Jl.W
(recen1ca, 99) ; __-. co_<:j.c4,j_fi;__
._·,_,--- _*_p_
··
cin.getline(fraz~, 99); .... ·--~---. =

pozicija = strst'r(recenica , ;f~~.);


\ if (pozicija) ~ ·_, ~:.}- -~}.:_(-
cout << "Navedena _fr~."~a-.~_,.~~..-M__·_·-it_ zi u_ recenici poceV od "
<< pozicij a - rec~nic~.df1.t.-'1I;"~~~-}~ II_, znaka \n II;
else !:" · -;. ~
/ _,o!) ·-
' cout << "Navedena fraza 'Se·ne n~lazi u recenici \n";
. ..... ~...
_ ' .... ~ ·.' .

Pored funkcije strstr, biblioteki-"~~t~ing, i slicnu funkcij~"¢)samo sto je njen drugi


saili-z;
parametar znak a ne string (prihvata ·se i l)iojcima vrijednost, sa zilli&Jhem ASCII sifre). 0na vra¢a
pokazivae naprvu pojavu navedenog znaka u sfi:ingu. iii nul-pokazivae uk.oliko takvog znaka iiema. Ova
funkcija se mo.ze zgodno iskoristiti da se dobije}pokaziv!\C na NUL ghmiCnik,stringa (za tu svrhu, funkciji
strchr treba proslijediti nulu kao drugi parafuetar).f _ , .· .. ·
Mada je reeeno da pokazivacima nij~~ilodjelj;;~ brojeve, niti je moguee pokazivacu na
jedan tip dodijeliti pokazivac na drugi tip, _· sto'i illdiiektnamo · enostda se ovakva dod'ela i · ··
pomo6u operatora za pretvorbu tiMva l)pecasting operatora). Na primjer, neka iinamo sljedete
deklaracije: ·-"' · "· ·
0
int *PokNaint; :.P.'>
double *PokNaDouble; t
Tada pretvorba tipova dozvoljava, dana sopstveni rizik, izvr~imo.j ovaky~E~~le: //!
f S PokNaint = (int *) 3446;
; l..PokNaDouble = (double *) PokNaint;
·C
yV" Ovakve dodjele su veoma opasne. Prvom dod'elom smo eksplicitno posta\~li PokNaint da pokazu'e na
adresu 3446, mada ne znamo sta se tamo nalazi. Drugom o ~e om smo postavili PokNaDouble da

17
~
-~
. pokazuje na istu adt:esu na koji pokazuje PokNaint, Sto~je
takoder veoma opasno. NJe, aim se na.
{
nekoJ lokaciji nalazi cijeli broj tamo ne more u isto vrijeme biti realni broj. Pored roga na raz!J.Ci.te
'bpove pokazivaea pokazivacka aritmetika ne djeluje isto. Stoga su ovakve pretvorbe ostavljene samo
onnna koJI veoma dobra znaju sta njima iele da postignu. Treba napomenuti da se rillY r m broja u
t
pokazivac dobija pokaztvac, koji se dalje moze dereferencirati kao i sv~ diugi pok
naredba poput sljedeee sasvim legalna: • ·\
ac. Stoga je .

I
~
~
' -'
.p "'
Ova naredba ee na adr u 3446 u memoriju smjestiti broj 50 (poslj£dice ovakvih akcija preuzima
programer, i u "normalnim" programima ih ne tre ~ oristiii). Jezici '=: i C++ su rijetki jezici koji
omogueavaju ovakvu slobodu u pristupirna resiii:srma ntcunara, Sto ihtcini idealnim za pisanje
sistemskog softvera (naravno, za tu svrhu treba izuzeti:to dobro p'tznavlm arhit~ racunara i
··· . ,.,operativnog sistema za koji se pise program). . ~- ... · ·
~
. ·~ Da bi~mo e~asno ~0~ koristi~ ~okaziv!ICe~:"~otr~o u~,\~.:.~e j: jos i ~ ~-
_generickim II t ~0
pokazrva_czma. Ovi pok~vae1 se de~aJu_kap;,Po~vae~ na void, 1 i?nJih se smatra daJe n:po~~~ ,. •

l
na kOJI lip taCno pokazuJl!. Stoga se om, slieno pokazwaerma na f\mkCIJe, ne mo~ dereferencira)l, mti
se sa njirna more vrsiti_pokazivaCka a,ritme~a: Medutim, ovi pokaztvaei J>U jos ogrrurl~enijt..sa njima~ 1-/;/-
ne more raditi grakticno mlta ~e dok's~ o ocu o er '. · .za pretvorM!Pfl. ova ne retvore u o azivac
~
~ u neki konkretau tiji Medutim, tteneriCkom pakazi~ri t~ze odijeliti ma lwji drugi pokazivac, i
fullkcija koJa prrma kao formalni parametai' gener16~o~v'ac prihvatiee kao stvarni parametar bilo
lwji pokazivac. Stoga su se generiCki pokaZivaei inte!Izivnd ·koristili prije nego sto su u jezik C++ ·
~
uvedene generiCke (sablonskeJ; funkcije pomocu kljuike :ljj~ci <f:'~ _Nainie, oni su ranije hili
jedini nacin da se naprave ~e koje mogu prihva'tati nizi>ve razlicTilh tipova kao parametre. Tipican /
'pninjer'je fuiikciJaCii3 ~)1blloteke cstd~ib • je 11aslijedena jos iz jezika C koja obavlja' ~
~
_11ortiranje QuickSort postupk<iin'(dobro ste procitilj: :QuickSort postupak postoji ugraden u standardne
C:+, tak. o_ da_ smo i r~i,U
bi?li~~ke jezika C i. _ _ :· ._.._' eiju. ''Q_~. ·ckSo!F~j~i iz eduk~~ razloga).
=~~}~~ ::~:e:~j:;:r~o~r•~j{t~-~sort kons.b, nakon cega
~
~
double Nlz[10.)
qsort(Niz, 10,
- (5,,3, •8.13,~_,_._:;s,:r2_, .~,-._o·,.1,.4."5,
•.-_
sizeof(double)·i .kr:j,t'\irioj;};;····~t ..
-2.3., 3, 1},

~
cout << "Sortiran niz glasi: "-; ~--~.:. -~- ,· :~";;;~4:----,t_·..,·~-
for(int i = 0; i < 10; 'in}. cout)'< ti,{'zi[ii~ end!; ·
. -~. . ,• . . . . . ·. ·;:. ... ... .

J!.roizvoljnog tipa,
deklariran kan
pokazivae prihvata oolceiti.vae nrc>iZvnlili<li> rio:1)!l
~
\~.~j~e~~~~~r;=:u.~A ~
niza
fl
L.
Pri tome, funkcija qsort
mora da obavlja neke veoma
u pokazivac ·na neki konkretau tip i
UK\juC:UJU pretvaranje generiCkog pokazivaea
sa velicinom elementa niza da bi uopee mogla da ~
fl
'
pristupa elementima niza Opis o_vih;lii>rzlan!ll znamo izlazi izvan okvira. ovog teksta

. Najinteresanmi'i arametar funkcije qsprt je cetvrti parametar, kojeg smo u prethodnom primjern
nazV:~ ~Ovaj par:ln_Jetar deklarir ·_je kao po~zivac na ljt~kciju. Nainie, ~-cij~ qsor~ je
0
~

narmJenJena ude veoma umverzalna, u lu da moze da sorina mzove posve razlic1tih II ov 1 o


l?Otpnno proizvolinim kriterijirna Stoga, kad god funkcija qsort treba da pro'ljeri da li su dva elementa J
1i'ispravnom poretku, ona popva funkciju zadanu ~ Cetvrti parametar, prenoseei joj kao parametre , ,
n
.:.J

18
fl
.n
Ij
n .;,._ -J /' .

pore~
. .

n
.n1
. pokazivace na dva elementa koii se Napomeriimo da funkcija qsort pojma nema ni Sta uopee
sortira, a pog?tovo P?. ko~e~.!aiteriju, stogaj~ p~ziv~je ~cije laite~ja neopho~o. Iz istog razlo~ase
kao parametn funkciJilaitenJa ne mogu prosljedivatt sam1 _elemenll kop porede, vee samo pokazivaci no
~ijaqsotlne.zna.stqs_ztti_~lerngntj1j to gen~ricki pokozivaci (1j. pokazivaci na •
f
: P, nepoznati tip), sa prefiksom canst, s obziro eta funkcija laiterija ne treba i ne .. · · elemente
.' '
na koje pokazivaci,pok · ". FunkCIJa. 'teri dufua je da funkciji qsort vrati infonnaciju o poretku

n
i
"e!emenata, i to broj ve •i. · : · ~: su e. ementi u krivom pore/ky, broj manji od nule ukoliko su
ele~_enti u ispravnom por-o/ : 'op.?siio nulu.~oli.ke su eleiiie~ti ;~~"!· FunkciJn lait~rij~ du.Zan j~-~a
nap1se programer, ~· onaJ ·. . ·. a filllk~Jll' ,qsort. FunkclJa !aitenJa se moze nap1san na razlicite

n
"''"'
naeine (i po obieaju, kr:f.· i nai;ini su manje citljivi). Za konkretan primjer, funkcija laiterija bi mogla
izgledati ovako: l ·· · ,. .
'
••
[] int ~~~~~~~~~.©) b;
il•
if(*al
.' i f (*al

p
'
G
return 0;
':·.:..

q
}
Analizirajmo

i., .. -,i

R
n· Prethodna funkcija '?"- t•er:L.)·Yfll:9~.!sK1J'
0
d
se tr8Zi samo da znak te:~ta~~ad<~·:if~
moremo mnogo jednostavnlje

g
9
g
~
~
~
~
l
I,
19 •
~

...
~
r[._.
~
~
~
~
~
~0

. lf·
~
·~
~
.. ~

. " fl
'-'
:~ ... :.

~
u
'
~

.· .. , .' . .
. ':;_f, .
.
~
; . ··. '
u
c

c
'-'

~
L

• n
~

n
u l ..
6.•
l}
.... '
···.
[} ·'
"DINAMICKA: ll'O KAC IJA MEMOl.UJE -~- -......
...
G
••
Do sada smo pokazivaee koristili i.sJdjueivo tako·§to smo im dodjelj
vee odranije postojao zauzet memor iski rosto . na primjer, adresu
· e ement a ruza slringovne konstantne. Na tij naCin, pokazivaei su
ivali adrese objeka ta za koje je
neke druge promjenljive, nekog
djelovali samo kao neko egzotie no

G ••
sredstvo pomoc u kojeg su se dod!lSe mo · ostiCi int esantni efekti
o oji ne donose ni§ta radikalno novo. Zaista, sve §to je dernon
pokazivaeima, osim primje ra koji koriste pokaZivaee na funkcije (koji
i ostvariti prilien a op=i~?cija
strirano u po v:~u o
se ne mogu realizirati bez Iijih)
moglo bi se u naeelu n jeziku C++ ostvariti i bez njih, eventualno na
G
....
je u jezik C++ uveden prenos parame tara po referenci (prije uvoden
izvod.iv bez upotrebe pokazivaea) i generiCke (Sablonske) funkcije
neki duZi nacin, pogoto vo nakon §to
ja referenci, sliean efekat nije bio
(koje su se ranije simulirale preko
generiCkih pokazivaCa, uz UJl?.~el.i~~eoma rogobatnih konstrukcija):
.G--.. '
~--~
..... -f<-Jliaw Sri · p"Okaiivaei'"d.Otma~"k1ibtblli 1 i iia dilil!liiittcom "itloltaci'tlm aod:etoin) 'memor
i}e. f
Pod dinamiCkom o cfo •metnori"e o<k.azumijevamo mogu6nost
da progra m u toku izvrsavan.Ja
G
..
zatraZi. da mu se dodijeli odredena k<iliCina. mernori" e ko ·a ram e m e ila
raspo ag sve o eventua.!*Q,. qe · ~a~~ n,Lihoyo oslobadanje. Takvim,
blokov ima memonJe, mou se Jl!istwati:is,kliuc'!Vb poinoeu pokaziva&i.
zauzeta, i kojom on mou
diliiiDiicla dodijeljenim
DinamiCka alokac ija mernorije
G ~.
postoj ala je jos u jeziku C, i osfv.J~riv'a!a""se pozivo m ~pe mallo
biblioteke cstdl ib (iii stdlib .h'u starjjiW verzijama•l«~ihpajler
alokac iju na&:Illo radi i u jeziku C++, C++ Iiffili mnogo fleksibilnije
c iii neke srodne funkcije iz
a). Mada ovaj nacin za dinamiCku
naeine, talco da u C++ progra mima
po svilku cijenu treba izbjegavati naCine za dinamiCku dodjelu memor
G l. ~
ije naslijedene izjezik a C.

G
·~·
Q
.' )

SltK:ajUneiJsi>jeJta.n$1< bi!,Cil izuzetak.


R Osnov uu upotre bu operat ora
"r•J•' o o A ·;.;:.·

neil: til\ibolj_e je i!iistrirati,na ko$et nom primjeru.


'f··
Pretpostavimo da
0
L•
namje data sljede6a deklaracija:

.f .I int *Poka zivac;


· ·,
,,

0
... ....
_ __ ;
deflnirana

. -._,.
0 Adreu
....
~~3~7~58~·~3~7~59~~3~~~o~~r:~~7~6~~~~"r3~7~6~2~3~7~63~~3~7M~~37~6=5-.~

I I m-¥i. ,1· ,,_I I·
a
,.... t !____·--···--···;~
. ~,--,•. --:-
??? :.
-7:>-_.
Pokaz ivac

a •
Ukollko sad izvrSimo nared1Ju

~okazivac = new int!)


J operat or new 6e potraZiti slobodno mjesto u mernoriji koje je dovoljno veliko da prihvati
jedan cijeli
broj. Ukolik o se takvo mjesto pronade, njegova adresa ce biti vracen
a kao rezultat operat ora new, i
]
1 1
.....,l
-i-
" _ .dodijeliew ookaziv.a®..Epkazi;ygp. frelpostavim9,.na primjeF, <J.aje slo.bedt!.o mjesto..pronadeno";na"'
- · adresi 3764. Tada ee rezultat operatoia ne~:~ biti pokaztvac na adresu 3764 koji treba da sadrii cijeli broj "~1
(ovo bi moglizapisati kao (int *) 3764), koji se molre dodijeliti pokazivaeu Pokazivac, tako daee on
pokazivati na adresu 3764. Stanje u memoriji ce sada izgledati ovako:
-
Adrese .3758
~~~~=-~~3~764~~~~,~~,~-~~~~~,=-
3759 3760 3761 3762 3763 3764 3765
·f-
f L . -.....:. . . . _.__. ._______________. __ 1'. i[
Pokazivac '""
Pored toga Iokacija 3764 postaje zauzeta, u smislu da ee biti evidentirano da je ova lokacija
_rei'ervmma za upotrebu od strane programa, i ona do daljnjeg si~ neee biti iskori§tena za neku drugu f
namjenu. Stogaje sasvim sigumo pristupiti njenom sadtZaju putem jlpkazivaea Pokazi vac (on viSe nije
. divlji po~YJI..ID.., StQgl!.s~ den:fer!'ll~kazil!IW Pokaz.ivac u' pofuunostj ppn!iSa lraa-ftromienljbla, f . :rO
. I
iako Ioka$.a ~ koju.on pokazuje nema svoje simboliCko,Jmi. 'Stoga su haredbe.poput sljede6ih po8ve • ......
:troreldiie (llSJI!Saee 5 1 18): ·· · ·
.
*Pokazivac = 5;- v--<4-~~-·-- ~"""""'
.J,.,J.,,~ •.".;;. •.' • .J•.• ;.,;i_ "
r
.. ~pf/>'\COC. ~
~-- "'-"'~'&,. ~'W'<'I
~o
L
cou.t << *Pokazi vac; · " P"''fiAM..., ' " <.1
*Pokazivac =.3 * *Pokazi~c + 2;
(*Pokazivac) ++; :· · 1
cout << *POkazivac;

Kako se ova Iokaci"a u polJiiinosti pona5a kao prom·ennva (osim Sto l!!~maJYm!Lime), k3Zemo da on~
predstavlja inamlc!w prorgjen iivu. akle, . ·eke promjenljive se stvaraju primjenom operatora :* rO
....,
new, i njih6vom sadrZaju se ID()~ ristu iti iskl'u o tern okoziva koji na njih pokaztije. .Pored
automatsld promJenglVI , oJe se automatski stvara u nil mjestu deklaracije i automatski uniStivaju na
kraju bloka u kojem su deklarirane (takve su sve lokolnepromjenljtve osim onih koje sli deklarirane sa rO
0
atributom static), i statiC/dh prolnjenljivih koje "~rt~~ cijeto vrijeme dok se program izvrSava (takve

~
su sve globalne promjenljive i Io~e promj~jivlt;<J,!lflarirmie;,.sa atributom static), dinamiCke
' flromjenljive Se D!Ogll ~ za ~ech :rrstu \)~j~i\(.J! ~e postoj~ Que se stvqraj": ~ zab~ey • j
• kao ~ .•~o ~oro VJdjetJ, uniJ,IaVaJu na ~h!i(!ll-: Sam()t~;., razliku. v od ~to~a~skih 1 statiCkih
promJenlJivih, dinami3ke promJenlJJV!il" neJW~Ju ·1D!ena. (stoga · rm se moze prtstupl1i samo pomocu
pokazivaea). · <·, .;;. "·· :· ·· ·
~
~
·~

ll
'-'
Sada ee staDje u ~emorlji biti kao na slj~ecoj_ ~lici:
. "·.~-'. ·.
Adrese -"''-i-:::..37:..::5:.::8_·,·:::..37.:..::5:::9...,.....:;;3.7:.;.:.6,_::0..,.-:::..37:...:."6:..:1'-r-:::..37:...:·6::::2:,-.:::.3.:.:76::::3:,....::3..:..;76:.;4:...·.,--::3:.:...76,5:..,-=-
0
~

t 3764 I I I I I 5

t -D
! .
• • =---ooMH-------··-.-·---·---- --··-.! . '

Pok,azivac

Pokazi vac vee prilikom njegove deklaracije. Drut


Razumije se da se rezultat operators new mollao odmah iskoristiti za inicijalizaciju pokazivaea
rijeCima, sljede6akonstrukcijaje posve Iegalna:
u
......

ll
l 2
n
IJ
[J

..
fl.
.,._. -,¥:
.;. ",!·
-

Prilikom kori~ten·a o eratora new, treba voditi racuna da uvi"ek- osto'i mo


·- .·
6nost d3 on baci
izuzetak. .Dod~e, vjerovatnoca da u memoriji neee biti pronaden prostor za
[} veoma je mala, ali. se treba naviknuti na takvu mogu6nost, jer cenio uskoro dinamiC
jedan jedini eye I'OJ
ki alocirati znatno
glomaznije objekte (npr. nizove) za koje lako moze nestati memorije. Stoga bi
•·. se svaka dinamiCka
alokacija trebala izvoditi unutar try bloka, na naeiu kojije principijelno prikazan
G try (
int *Poka zivac
u sljedeCem isjeCku:

1.-·· new int(S) ;


[] I
catch ( ..•• ) (
1..-o•
· cout << "Problem::.Nema govolj no II!emorije! \n";

.. ·":"--~-
.)
I Q
Q '
'' delete Pokaz ivac; MV
G
'
~--·
G '
• uni~tieemo dinamiCku promjenljivu na kojupo kaziva c Pokaz
ivac pokazuje. Pri tome je vamo da
rll2jasnimo Sta se podrazumijeva pod tim unistavanjem. Pokaz ivac ee i dalje pokaziv
nakoju je pokazivao i prije, samo ~0 Ce se izbrisati evidencija 0 tome daje taiokac
rijeCima, ta lokacija more nakon uniStavanja dinami6){e promJiiillJIVe btti tSkon~
ati na istu adresu
ija zallZeta. Drugim
ena od strane nekog
~--II drugog (npr. operativnog sistema), pa Cak i od strane sainog piograma za neku drugu
svrhJL Stoga, vi~e //I
Q nije sigumo pristupati sadr2;aju na koju Pokaz i vac pokazuje, odnosno on je
ponovo postaq dtvlji 6,,
pokazivaC. Divlji pokliZivaei koj1 pokaiUJU na objekte koji su iz bilo kojeg razloga
prestali da postoje
L. ~ (jedan od mogucih razloga je njihova eksplieitD.o uriistavanje pozivom operatora
delete ) n8zi.vaju se
[} _vj;ffip o[pziva @ (engl. hanging pointers).p;:;r. , ·'\\ _ .
: Treba napmnenuti da vise6i pokazivaCi ~ogu nastati i ~~~zaiio od dinamicke alokaci
~-
SljedeCi primjerpokazuje kako nesvjesno mo2iemo stVoriti viseCi pokazivac: je memorije.

G
LJ
·int *Pqka Zivac; .
· · · _

aw
(
int Lokaln a = 5;
Pokaz ivac = &Loka lna;
) :7#
*Poka zivac = ·6.;
} U· ovom primjeru, pokazivae Pokaz ivac je unutar bloka postavlien da
pokazQje na· lokalnu _
~· -- promjenljivu . Lokaln a koja je. deklarirantt;:Hnutar bloka. .Jyfedutirrli,.po zavdetk
. u --bloka,..-··lokalna
} jiron\ienljiva prestaje da postoji. tako da je Pokaz i vac pOstao vise6i pokaziv
promjenljivu koja je prestala da postoji (situacijaje analogua kao pri brisanju dinamiC
ae, jer pokazuje na
,._...
pomoeu operatora delete : Pokaz i vac i dalje pokazuje na isto mjesto u memori
ke promjenljive J
ji. ali program vi5e ne •
} smatra da to mjesto pripada nekQj promienljivoi). Treba se euvati v.i.seeih pokaziv
uostalom svi divlji pokazivaCi) _veoma eest uzrok fatalnih !!re~aka u prograntiut~
aCa, jer su oni (kao i
koje se te~o otkrivaju,
·• s obzirom da im se posljedice obtcno uoce tek nakuadnol

1 if Sve dinamicke promjenljive se automaf$ki uni~tavaju po zavdetku p~


napomenuti da ni jedna dinanliCka promjenljiva nece hili unistena sama od
Medutim, bituo je
sebe prije zavdetka
programa, osim ukoliko je eksplicitno ne unistimo primjenom operatora delete
. Po tome se one bitno
' razlikuju od automatskih promjenljivih, koje se automatski ~tavaju' na kraju
bloka u kojem su
definirane. Ukoliko sinetnemo sa uma o.vu ciujenicu, moZeino zapasti u·probleme.
-· Pretpostavimo, na
primjer, da smo izvrsili-sljedecu sekvencu naredbi:
lr i
J
I 3 (
f
}'?-.~k*P~Js;oE~.Z_g-%-c
= .1'!~~ int;;
··">.:.·• •.
*Po azJ. vac = 5;
Poka.z;i.vac ·= new int;
· -- · ·.·-·-[
.. ~~

*Pokazivac = 3;
~

U ovom primjeru, prvo se stvara jedna dinamicka promjenljiva (recimo, na adresi 3764), nakon &:ga {
se njen sadrZaj postavlja na 5. Iza toga Slijedi nova dinamiCka alokacija kojom se stvara nova dinamiCka ~

promjenljiva (reeimo, na adresi 3765), a njen sadrZaj se postavlja na 3. Pri tome, pokazivac Pokazi vac
pokazuje na novostvorenu dinamicku promjenljivu (na adresi 3765). Medutim dinamiCka promjenljiva {
na adresi 3764 ni'e unistena, osuo dio ·memori"e u kojem se ona nalazi · ·· a zauzetim. , ~

Kako okaziva · vac vi~ ne kazu"e na nju, njenom sadrZaju vise ne moZelno "stu "ti reko
ovog pokazivaCa. · Zapravi, na ovu dinamiCku. promJ ~~vu VI ne pokazuje niko, tako da je ova
a_in~i_i!kll promj~jiva p~stala !zfriena (niti joj moZelno pristupiti, niti je moZelno izbrisati). Ova
{
situaciJa prikazanaJe na slJede6oJ s ct: . · · .•.
. ·. ·: ., . 37~-l' 376f1' 37i>l "'''3762• ·:16:3' :3'764 3765"'--:::~-~
I 3764 I I I
t 5 3

....iJ
, _ !- - _ _ _ _ _ _ _ _ _ _ ..;+
Pokazivac

Dio memorije koii ;rnnz;ima izgubljena dinamicka promjenljiva ostaje rezerviran sve do lmjja
f ·progr~:a~r je izgubljen za program. Ovakva pojava naziva. se· curenje m_emorije (engl. memory
·O
• "leak) r lja dosta eestu greSku u programima Ova greSkaje na neki naCin suprotna greSkama
usljed upotrebe divljih i viseeih pokazivaea (kod divl"ih i visecih pokazivaea imamo pokazivaee koji ne
pokazujuni na kakav smislen prostor, dok ko ·curenja memorij imamo rezerviran prostor na kojeg niko
·o
ne pokazuje). Mada je curenje memorije manje u o osu greSke koje nastaju usljed divljih iii
viseCih pokazivaca, ono se takoder teSko uocava i mo.ze da dovede do ozbiljnih problema Razmotrimo
na primjer sljede6u sekvencu naredbi: ·
~nt *p;
for (int i =. 1; i <= 3.000,i++)
..
p -.= new int;
',\\'"

*p = i; '
}
iJ-
U ovom primjeru unutar for petlje je stvoreno 30000 dinamiCkih promjenljivih. jer je svaki poziv
operatora new stvorio novu dinamiCku promjei6u, od kojih njti jedna nije uniStena (s obzirom da nije
kormen operator delete). Medutiru, od tih -~00 promjelftjivih, 29999 je ~blieno, jer na kraju -u
pokaziv~<i£a§i!Jje
promjenlji:va zanz1ma
£!0
na pgsliednju stvorenu promjenljivu! pretposta\i jedna cjelobrojna
aJta, oVIm smo bespotrebno izgubili 119996 bajta memorije, koje ne moZen!o
uz:- da
osloboditi, sve dok se ne oslobode automatski po zavrsetku programal
·.··~-·
. , .. - ·~ ;"":>"=r~<-.1·•·?:'~ ...,. --: . ;..-..=~ ... -~ . ·. _,-_,_.._. '·· ;·c_•..•
Jedan od tipiCnih situacija koje mogu dovesti do curenja memorije je stvaranje dinarniCke
promjenljive unutar .neke funkcije preko pokazivaea koji je lokalna promjenljiva unutar te funkcije.
Ukoliko se takva dinamiCka promjenljiva ne uniSti prije zavr§etka funkcije, pokazivae koji na nju
pokazuje biee unisteu, tako da 6e ona postati izgubljena Na primjer, sljedeea funkcija demonstrira takvu
-11
situaciju: 1]
void curenje(in t n) { -
}
int *p = new int;
*p = n; ·u
Prilikom svakog poziva ove funkcije stvara se nova dinamiCka promjenliiva. koja postaje posve
nedostupna nakon zavrsetka funkcije, s obzirom da .se pokazivac koji na nju pokazuje uni§tava, tako da

!
{
.ostatak programa-cnema mogu6noSt niti da·pristnpi takvoj promjenijivoj. niti d!f ie''tllli~ti. St<iga· 'SVaki.
poziv fuilkcije curenj e stvara novu izgubljenu promjenljivu, odnosno prilikom svakog poziva ove
fuilkcije_ koliCina izgubljene memorije se poveeava. Stoga bi sV'aka fuilkcija koja stvori neku dinamiCku
promjenl!ivu trebaia i. CJa je ~- Izuzetak od ovog praviTa moie imati smisla jedino ~oliko se.
noyostvllfena ·dinami8ka promjenljiva stvara putem gln"alno uokaziya Ca (kojem se more pristupiti i
izvan funkcije), ill ukoliko fuilkcija vi'aca kao rezultat pokaiivae na novostvorenu promjenljivu. Na
primjer, sljedeea funkcija more imati smisla:
int *stvori (int n) {
int *p =new int(n);
return p;
)

Ova funkcija stvara novu ~cku prontienljivu, inicijalizira je na vrijednost zadanu parametrom, i
vraca kao rezt,~/tat kazivac; a novostvorenu rom'enl'ivu. Na taj naein omoguCen.o je da rezultat
funkcije bUde .dodije!jen neko ~·pX'!ll50 k0jeg__.~ ka8ilije ;meici 'i\nslu¢ti
novo~enoj
dinamickoj promjenljivoj, i eventualno izvmti njeno uni~Vanje. Na primjer, sljedeCi slijed naredbi je
posve smislen: ·

j
int *Pokazi vac;
Pokaziv ac = stvori(l O);
cout << *Pokaziv ac;
delete Pokaziva c;

Napomenimo da se funkcija stvori mogla napisati i kompaktnije, bez deklariranja Iokalnog


pokazivaea:
int *stvori (int n) {
return ne.w int (n) ;
)

Nairn?: new je ope~ator


koii vra_ea pokazivac _kao ~ezultat. ;~ ~-
bn v_ smije _biti vraeen
funkctJe. Takgder, mteresantno Je napomenuti daJe na prvt ;,~ v~ma neobtena konstrukG\1a .
~.re~tat iz
~
sintaksn~nosve i~a (s obzirom da funkcija stvorj, vraea kao rezultat pokaztvaC
, a dereferencirani
pokliZF Je 1-vn;e ost), mada je upitan smisao .·Jii!kve konstrukcije (prvo se stvara dinamiCk;a
promjenljiva sa vrijedno~eu 5, nakon tog~ njena m-ost mijenja na 8, ina kraju se gubi svaka veza
sa dinamiCkom promjenljivom, jer po~vae na nju nije nigdje saeuvan). Ipak, mogu se pojaviti
situacije u kojima slicne konstrukcije mogu biti od koristi, stoga je korisno m~ da sn one moguce.

Kreiranje individualnib dinamiCkih ·promjenljivih nije od osobite koristi ukoliko se kreiraju


promj,;:ulj1ive prostih tipova (kao ~o sn'nprY~nl'bjiie. pronlji:nljivej, . ·..,..
tekkada
~ Medutim, matno je
. iiNi' dinamicki nizovi. ito cija v~~~~;;.!~~
taloder operator new izi kojeg'"ponovo slijedi ime tip i!lemenata niza),
nakon eega u uglastim zagradama slijedi broj elemenata nim !roji krejramo M~ za razliku od
de~arac~je ~biCnib (statickib) nizova, trareni brgt.eiemenata niz:t
ne mora bitj ~''!- v~ more biti
prmzvolJan tzraz. Operator new ee talla potraZi.ti · slo60dilo mJestO u ~emonJI u koJe bt se mogao
smjestiti niz traZene velicine navedenog tipa, i vratiti kao rezultat pokazivae na pronadeno mjesto u
memoriji, ukoliko takvo postoji (u snprotnom ee biti baeen izuzetak). Na primjer, ukolikoje Pokazi vac
deklariran kao pokazivac na cijeli broj (kao i u dos~njim primjerima), tada ee naredba

~kazi vac = new int rsJ:tJ


I
5 j
~
-~
IX!traZiti ki?;(W~'FIQ!lJ11nriji kojije dovoljan da, prihvati ,pet cjelobrojnih vrijednCMti,.i u Slueaju da . . _.rr
proil3de V prostor, .dop~{ite njegovu adresU pokaziviWu Pokazi vac (bitno .je naglasiti da U
uglastoj zagradi nije morala lti konstanta 5, vee proizvoljan CJelobrojni 1Zraz, koji moZe sadrZavllti i L
promjeilljive). Na piiJnjer, neka je pronaden prostor na adresi 4433, a neka se sama pokazivaCka
promjenljiva Pokazivac nalazi na adresi 4430. Tada memorijska slika nakon uspjeS!log izvrSavanja.
prethodne naredbe izgleda kao na sljedecoj slici (radi jednostavnosti je pretpostavljeno da jedna
rf
L.
cjelobrojna promjenljiva zanzima jednu memorijsku lokaciju, Sto u stvarnosti nije ispunjeno):

Adrese 4430
~T,~44~37
4431 4432
3°,~~~=.~~,~~~=-~=-~~~
4433 4434 4435 4436 4437 ~
tL _________________f
Pokazivac ·
&
Ovl!ko,kteii:
kaziv!We. mogu j:lrimjen"ivati (podsjetimo se da se [n] s u yu
. Medutimr'k$.0:~-na ··~--
ep
~
~
p · mterpretira kao * (p+n uz prunJenu pokaziv.Wke arittiletlke), dinamicki niz moZe!no koristiti
na posve isti nacin kao i obi nz niz, pri eemu umjesto imena niza lroristimo pokaziva9. Na primjer, da
bismo postavili sve elemente novokreiranog dinamiCkog niza na nulU, moZemo koristiti for petlju kao
da se radi o obienom nizu: ·
·Y.f~or(int i. = 0; i < 5; i++) Pokazivac[il = O;
D
~

asp1eld:a pro~;razneza gotovo da nema nikakve razlike izmedu koriStenja obiCnih i


obiCnih deklaraciji, i n

koji
Cf:odmahpo
int * z
f
· (int n) {
int *p =new int[n];
for(int i = 0; i < n; i++) ·P [i] = 0; ~
return p; .. .
) .
-~; 'W
Pomo6u ovakve funkcije moZe!no jednostavno kreirati dl'l'lamicke nizove kqji 6e automatski biti
0
inicijalizirani nulama. Na primjer:

~nt *DinamickiNiz = StvoriNizinicijaliziran Nulama(lOO); u


-
Ovako. ·
ll
'

template <typename Tip>
Tip *StvoriNizinicijalizira riNulama(int .n) {
Tip *p·= new Tip[n];
}
~
IV/ D
)
for(int i = 0; i < n; i++) p[i] = 0;
return p; n
Uz pomoc ovakve funkcije mo~emo stvarati inicij3lizirane dinamiCke nizove proizvoljnog tipa kojem se
mou dodijeliti nula Na primjer,
D
'
(
i
6
n
- · do!lble. *DinamickiN

iz• ~ StvoriNiz·!
• ·• .
nicij ali-ziranNula ma<dauble:< fllFO) .;
- • ?." ' ' -- ,._ •-. . .• .
.lJl
• - ..• A'.,.

Primijetimo da smo prilikom ziva funkci"e e licitno morali navesti tip elemenata niza u siljastitn
zagradama <'>. To je p<>trebno stoga Sto iz samog poziva funkc11e m]e mogu zakljuciti sta tip Tip
predstavlJa, s obzirom da sene pojavljuje upopisu formalnih parametara funkcije. · .
Karla. nam neki dinamiCki niz vise nije potreban, moZel:no ga takoder uniStiti (ti. osloboditi prostor
kojije zauzimao) pom.oeu operatora delete samo uz neznatno drugaCiju sintaksu u kojoj se koristi par
uglastih zagrada Tako, ukoliko pokazivac Pokazi vac pokazuje na dinarnicki niz, uniStavanje
dinarnickog niza realizira se pomoeu naredbe

W' ~e[] PokazivaCT )

. N~phodno j~ napo~c:n~ti da.sq!'gl~ zapa<~eMJt N~~, postupci dinamiCk~_aloka~je obiOOih ·


-~~~~!~ili~~jlvihb_!,.l!!-?.,arn'~-~""S;vatoitern "'~stopav~a~~.nada.potpunkr0'~~J~~~!!'kb,';_~ _.,.,,,,,
· m po~'-"1'""'- DJ ovog· nsanJa -ruJ~.ISti. :. 6" lle. ·..., o govon · se emnue FousanJe o 1.-Wll
dinarniCkili promjenljivih realizira uz pomo6 Operatora new i delete, dok se kreirm:ije i bri8anje
dinamickih nizova realiziril uz pomog pperatora new [ J i delete [ ]. (zaista, C++ intemo· posmatra ove
'VariJante kao posve IiiZ1W1te operatore). MadS postoje situacye u kojima bi s_e dinarnicki nizovi mogli
obrisati primjenom obienog operatora delete (bez uglastih zagrada), takvo brisanje je uvijek veoma
rizieno (pogotovo ukoliko se radi o nizovima Ciji su elementi slozeni tipovi podataka poput struktul-a i
klasa). Stoga, ne trebli mnogo razmiSijati, nego se drZati pravila: dinarnicki nizovi se uviiek mongu
brisati da delete [ J. Ovdje treba biti posebno oprezan zbog Cinjenice da nas kompajler nece upozoriti
ne upotrijebimo li uglaste zagrade, s obZirom na Cinjenicu da k0111Pajler ne moie znati na Sta pokazqje
pokazivae koji se navodi kao argunrent operatom delete. -

Ranije smo vidjeli da se pokazivaCi i njzovi htogu koristiti gotovo rui identicair naein. Najuocljivija
razlika sa aspekta programera je Cinjenica da: ime niZa: (obicnog) uvijek pokazuje na rvi element niza
tako da nad imenom niza ne moZel:no izvrSiti niti Jedn~ operaciju koJa 1 ove a do omjeile adrese rill
koju on pokazuje (poput dodjele, ill operatora popnti:·+'=" ·. "++"). U tom smislu, nizovi se po:riilSaju
· veoma slieno kao kon.rtantni pokazivaci. Zaista, sa,>ll~~~a progni'qlera gotovo da nema nikakve razlike
izmedu deklaracije statiCkog niz;l poput · ., · ·. '·· ~.,

Q~~--N~z_:_l~ 1
i sljedeee deklaracije, u kojoj se koristi
memoriju: _ _ _ _ _ _ _ _ ___,__--
. . .iii·._inicijaliziran na dinarniCki dodijeljenu J
Gt *const Niz
--.--- ·-
~ new
-----
in~{i'oo] J
je
. ,veoma do "';
potpuno rezervira se prostor za 100 elemenata niza u
memoriji, a promjenljiva Niz upotrijebljena bez indeksa po potreb.i se automatski konvertira u pokazivac
na poeetak tako rezerviranog bloka memorije. Ovo je ilustrirano na sljedet:oj slici:

1329

Niz

'U skladu sa ovim primjerom, kada raeunar treba da izvrSi pristup elenientu Niz [21, on 6e uzeti
adresu ria kojoj se rialazi niz (1230 u navedenom primjeru), iatitn je sabrati sa 2 (uz pretpoSf!~vku da
sva,ki element niza zauzima jednu lokaciju, Sto je ovdje pretpostavljeno zbog jednostavnosti) i na taj
!
(
f
......
-:[
-,;_;::~~41 dobiti adre.su na kojoj.se.nlJ!azi trd.enie1ement(.t2.32 uovom,pmnjeru)d!.,.drug& strane, u.drugom ~ _,-~ , -;

slueaju u memoriji na poCetku imamo rezerviran rostor samo za kazivac Niz, n8k6n cega se poztvom {
operatora new pro azi prostor za smJeStanje 100 e1emen;rt;, ni«! i adresa nadenog prostora
.. pok3Zivaeu Ni z. OVo je ilustrirano na sljedeeoj slici:

At/rese 1230 1231 1232 1233 1234 1235 1331


I 1232
t ........__!- ·

Niz

. U ovom slueaju ee raCunar kada treba da izvrSi ristu elementu Niz 2 rvo uzeti adresu na kojoj
{
'
se nalazi pokazivac Ni z u navedenom primjern), zatim proCitati sadrZaj te adrese da utvrdi na koju
adresu pokazivae pokazuje (1232 u navedenom primjem), i tek til$. sabrati sadrZaj kojije proCitan sa 2, o·
. ·Cjmq s:.s:lobija.~. trarenoa ~1em.ent1 (1234). VidimQ.,cia.~~¢aku. kada j~en.pabzivjtc,., ~ . _ .. 7·1
javlja: jedan stepen indirekeije vik Medutim, bez obzjril na veliklf i'azliku u intemoj realizaciji, ova dva - C
· SlucaJa se zaista pona8aju veoma ilieno sa aspekta programera j>osto 'e samo dvi ·e ro · .. .n
razlike u po!Wanju nizova i konstantnih pokazivaca. Prva razlika je u upotrebi operato !LJ
jasno ".vidi" razliku iztuedu nizova i pokazivaea. Tako ee, na primjer, naredba ....

! cout << sizeof(Niz); ;0....


u prvom primjeru ispisati velicitrn koju zauzima niz (to ee biti '400 bajta ukoliko sva:ki cjelobrojni
podatak zauzima 4 bajta, §tO je. danas najees6i slueaj), dok ee u om s1uca· biti ispisana velicina ko ·;
zauzima pokazivac (najeesee 4 bajta). Druga ritzlika jc: :U·. upotrebi operatora n &" u prvom .s1ueaju izraz
&Ni z predstavlja adresu na kojoj se na/azi niz Ni z~,.~ja j~okazivil£ ~ nj?:Cifelib ha¥v•a Isti
:0
'-
izraz u drugom s1ueaju predstav1ja adresu na kojoj se :na/azi pokazivac Niz, koja je<:!iEYpokozivac na I
.. . dvostruki pokazivac).· Mada u oba primjera ovaj izraz predstavlja istu
posmatramo njenu brojeanu vrijedn<;>st), tipovi ovog izraza su razliCiti u prvom i drugom ~
slueaju, i prema tonie, predstav1jaju pokazivace rlizlicitih lipova (koji se stoga i pona8aju razlicito).

Vee ·e reeeno da hi dinamiCka <. okacija .memoiije trebaia uvijek da se vdi unutar try b1oka, s
obzirom da se rnoZe desiti da alokacija ·• uSpije; To pogot9vo vrjjedi za ~gmpiCkn algkucim mzova.

~
Nainie, alokucija sigumo neee uspjeti ukoliko se zatraZi alokaclja niza kopzanzima vi8e prostora nego
Sto izuosi kolicina slobodue memorije. Stoga, primjer, koji alocira diuamiCki niz Ciju veliCinu
zadaje korisnik, a zatim unosi e1emente niza · iispisuje ih u obmutom porelku, ilustrira kako
primjer ee sigumo baciti izuzetak u slucaju da
~
· se ispnivno treba raditi sa dinamiCkim
zatraZite alociranje niza od recimo 100000000
try {
int n," i;
cout << "Koliko zelite brojeva? "; rU
L..
. .,... c.hn :>> n; :. >:, ..

~
int *Niz = new int[n];
cout << "Unesite brojeve:\n";
for(i = 0; i < lO]·i++) cin » Niz[i];
cout << "Niz brcijeva ispisan naopako glasi:\n";

~
for(i = 9; i >= ·o; i--) cout << NJz[i] << endl;
delete [] Niz;
)

~
catch ( •.. ) {
cout << "Nem.a dovoljno memorij e! \n";
}

~
Slieno obiCnim diuamickim promjenljivim, i dinamiCki nizovi se uni.Stavaju tek na zarvktkn
P!Ograma, ill· eksplicitnom upotrebom operatora delete [ J. Stoga, pri njihovoj upotrebi takoder treba
voditi raeuna da ne dode do curenja memorije, koje IDOZe biti znatno ozbiljnije nego u s1ucaju ObJCnih
I u
I
\ ll
~--· ..~.promjenljiW! (s obz;irom·.da dii!amiCki · nizovi mogu .~uzimati.. mnogo "'Vik• memorije,
pogotovo ukoliko im je broj elemenata veliki). Narocito treha paziti da dinamCki niz kQji se alocira
unutar,nek efunkci'e reko· kazivaeako 'i.'e lokalna romjenljiva obav zno treba iuniStiti pri'e
zavr8etka funkciie, inaee ce taj dio memorije ostati trajno zauzet do zavrSetka programa, i o ga nece
moCi osloboditi (izuzetak nastaje jedino u slueaju ako fiinkcija vraea kao rezultat pokazivae na alocirani
.. niz). Visestrukim pozivom takve funkcije (npr. unutar neke petlje) mo.Zeino veoma brzo nesvjesno
~ti svu raspoloZivu memoriju! Dakle, svaka funkcija bi prije svog zavr8etka morala osloboditi svu
memoriju koju je dinamiCki zauzela (*' Ukoliko vraea pokazivac na zauzeti ~o memorije), i to bez
obzrra kako se funkcija zavr8ava: nailaskom na kraj funkcije, naredbom return, ill bacanjem izuzetka!
ff se cesto . da Sto baci takoder da za sobom
...'II
. : . __void f (i!lt n) , . J. ,
... ·.• --. "• ''fi:' -ti'- •. -~:··' ·~ .... _..._;
. • .• - .,..,,...
~- ·- ·4f.." »~1nt *p ·= neW int
,,;.
g(n);
• ··.·
delete[] p;

U ovom primjem, fi,Ukcija f zai•ta hrire djnmpiCki niz p po svom zavr8etlru. ali prohlem nastaje nkoliko_ /
funkcija g koju ova funkcija poziva baci izuzetak! Kako se taj izuzetak ne hvata u funkciji f, ona 6e
takoder biti prekinuta, a zauzeta memorija ne6e biti ·oslobodenil. Ovaj problem se more rije§iti na
sljedeCi naein: .. .
..
''

void f (int n) {
int *p =·new int [n];

try {
g (n); w····
t• )
catch( •.. )
- ';~-

delete[] p;
thi"ow;

delete[] p;
)

U ovom rim'eru u funkci"i f izuzetak koji eventualno baca fiuikcija g hvatamo samo da bismo mogli
izvrSiti brisanje zauzete memorije, nakon ga pro uedujemo ue, .navodenjem
. _nru:edbe ~~~\lz param~a - '"-""'"•.·:.:>--~ ·-- . .·''
Jz svega sto je do sada reeeno more se zakljuciti da dinamiCka alokacija memorije sama po sebi nije
I komplicirana, ali da je
na

try {
int *a= new int[nl], *b =new int[n2], *c =new int(n3];
II Radi nesto sa a, b i c
delete[] a; delete[] b; delete(] c;
}
catch( •.. )
cout << "Problemi sa memorijom !\n";.

!
i
J
1:.

i[
.L
..•• U-ol(Om is' . .. 'Cka . It 1i slueaj~_,Pll, alok- ne
re, prljaV-1ft1'e-se. .......
" • gre§ka. Medutim, problemi mogu nastati u slueaju da, na pnmJer, o cije prva dva niza uspiju, a
"[
alokacija treeeg uiza ne uspije. Tada ¢e treCi. poziv operatora new baciti izuzetak, i izvrSaviinje ee se
nastaviti unutar catch bloka kao sto je i oCekivano,~memorlja koja je zauzeta Sl!~dvije uspje8ne -
alokacije ostaje zauzeta! Ovo moZe biti veliki probiein. Jedan nilCin da se rijesi ovaj problem,
·prilicno rogobatan, je da se koriste ugnijeZdene try - catch strukture, kao na primjer u sljedeeem
maaa :[
"-'
isjeCku: · ·
try { 1[
int *a= new int[nl]; "-
try {
int *b = new int[n2];
try {.
int *c =new int[n3];
f
.L
I I Radi nesto sa a, .b i
;,,~~de~~H a1 deletef), b;
} .. .
1[
~

catch (; •. ) {
delete [] :b;
throw; 10
}
}
""'
catch( ... )
delete(] a;
·;D
.. ~,··. ~

thrOw; f·i:-'

}
}

catch ( ••. ) { ·
;:~i.j·:
'l~-~-~~- -.
;0
......
cout << nProblemi sa ·memorijom ! \t~,.,;
}
:0
.....I .
Najbolje je da sami analizirate tok naVedenog iijeeka. uz ralicite pretpostavke, koje ·mogu biti: prva ·

~o
alokacija nije uspjela; druga alokacija nije uspjela; treCa alokacija nije uspjela; sve alokacije su uspjele.
.
Na Uti naCin eete najbolje shvatiti kako
.
ovo Jji!Senje.tadi.
~ ~

:O
"-'

problema:
~int *a = o, *b = O, *c = 0;
{]
~

try {
a = new int[nll; b .;=-new int[n2]; c = new int[n3] ;·
I I Radi nesto s.a a, b i c {]
~

.. } . ·.·< . ,_.
catqh( .•• ) {

}
cout << "Problemi sa memorijom! \n";
delete [] a; delete(] b; delete[ i c;
~
.....
U ovom primjeru svi p<ikazivaei su prvo inicijalizirani na nulu, a zatim je u try bloku pokuSana
dinamicka alokaCi.ja niemorije. Na kraju se na sve pokazivaee pritqjenjuje delete [ 1 operator, bez
11
.....
obzira da li je alokacija uspjela iii nije. Tako ee oni nizovi ko~ su alocirani svakako biti uniSteni, a
·. likoliko alokqcija nekog od nizova nije u$Rje!a, odgovarajurn potCJizivac ee i dalje o$ti nul-pokaiiilac (s
obzirom da kasnija dodjela nije i.Zvrseria jer je operator new bacio izuzetak), tako da operator delete [ 1
neee sa njim uraditi nista, odno.~.o neee biti nikakvih neZe!jenih efekata.
-·o
1l
.....
)
11
10 {
-fl
IJ
.-
n
lt--·:4
·/'
,.
0 ...., ..
·:.,... -*:·R-ammtrimo.- . _ k;\Ko se vrSi _.djnami&a 'lllokacija dvo.dimenz/onalnih nizova. '0\Fdje je ,gffi)acija
znatno SJ6ZI:nija," s obzirom su . enz10n lliZOVI mzo · _. ga se za indirektni pristup
dvodirnenzionalnim nizovima trebaju koristiti' sloZep.iji po . vacki tipovi, kao sto su pokazivaci na
•.
1.-_._,.:
I' I
n niiove, nizovf pokdziiiaca i pokazivaci na pokiiiiVace, zavisno od primjene. Nlijlakse je. ostvariti •
_diriarmckU atokaciju dvodimenzionalnog ~ kod kojeg je druga dimenzija unaprijed pomata (npr.
matricu Cijije broj kalona unaprijed pomat). pretpostavimo npr. da druga dimenzija niza kojeg ho6erno
tl
• •(J
-*" X•nJ
n
l.--,.,
da alociramo iznosi 10, ada je prva dimenzija zadana u promjenljivoj n (koja nije unaprijed pomata).
•-M>
Tada ovu alokaciju inoZI:mo ostvariti pomoCu sljedeee konstrukcije:

L- s-typed ef int Niz[10] ;


'r- --
,,-_- ,_,
.:-::: :.--:. 1"-t

n
L
i Niz * a=new Niz (n] ; · ,..- - . ·- - -
~--~----­

~ -= ~ ":~~:_ ~ ~
fll..of&>(n' ......v.xc.

0
!
...

~--

D
'I,._,..

n'

n
~,..,..

~-·

D
\...,_...

D
....
0. e/.OeLJ el9·
"""' I I
·1'
0
o-··1
a+n-1

0- omenuti da za dinamiCku alokaciju dvodimenziollllinog niza sa poznatom !lrugom


dimenzi'o in ni'e neo hodno uvoditi novi nizovni ti mocu e nar mme, Ista alokacija se
""
0
mogla ubavi!i4 samo pomocu jedhe.naredbe na sljedeCi naom: ''"''"' ·;:>'-'! · ~ ·"' ·-
~t (*a) (10]= new int(n] (10]; J
0 Naime, u ovom primjeru deklaracijom int ( * al f 1 o J J!eposredp:o deklariramo bo pokazivac no niz a
od 10 cijelih brojeva, dok konstrukciju new in t rn J ( 1 o J moZenio Citati kao "Botri@_!!.IDei!l()rijj mg5tor
·.-1 za n elemenata ko 'i su ti a nizova .9:!1 10 cijgih brojeva". Drugim rijeCima, op:,rator new ( J dopuSta
i
~- ar u ~obavezho ~a nalaziti
'] kof!'J!f!Jita·
samo Sto se u dni om am u astih z
Zbog toga nije mogu6e neposredno primjenom operatora new [ J alocilfui dvolmzi onalne
dl___'cke nizove Cija druga dimenzija nije unaprijed poznata. . .
·-··

J Da bismo vidjeli kako dinamicki alocirati nizove-15ija druga ilimenzija nije poznata ui:uwrijed,
se upoznati sa · · po sebi, nizovi pokazivae a nisu nista osobito:eto su
~

sljedeca deklaracija ·
]
. (
1
-l
. f-
-~·-;;- . ~ _c;t .:'.:.!i;i.ZI?c;>}!J5]9 -~_,..... .. ... , -~ .-: ·. "·- --·,
- deklarira niz Ni zPok od 5 elemenata koji su pokazivaei na cijele brojeve. Stoga, ukoliko su npr. Broj 1, f
~roj 2 i Broj 3 cjelobrojne promjenljive, sve dolje navedefiekonstmkcije imaju smisla-

NizPok[OJ = &Brojl;
NizPok[l] = &Broj2;
II NizPok[OJ pokazuje na Brojl
II NizPok[l] pokazuje na Broj2
f
NizPok[2] =new int(3); I I Alocira dinamicku promjenljivu
NizPok[3] =new int[lO]; 11-Alocira dinamicki niz [
NizPok[4] =new int[Brojl];
*NizPok[O] = 2;
I I Takoder...
I I Djeluje poput Br-ajl = 3;
z _ -
Broj3 = *NizPok[l];
*NizPok[Brojl] = 5;
II Djeluje poput Broj3 = Broj2;
[
cout << NizPok[2];
cout << *NizPok[2];
II
II
II
mijenja promjenljivu Broj24
adresu ... -
delete NizPok[2];
dinamicke promjenljive ...
promjenljivu - _f
de'~l!!te[J"'·Ni"~!?,qkHJi
NizPok[3JT5J = 100;
. -.. ~- ~- 1 ,. rii·z A,~~--~:..: .....~0;,..-r... ;-:...... ~
•·
-
D
-
[i J . ·
[il [j J zapravo
_ . napomenuti- da se _nizovi pokazivaea takoder mogu
inici"alizirati rilikoru deklaracijC?,,pod tivjetom da svi izrazi4d'lhicijalizacionoj listi predstavljaju
0
-
pokazivace (ili 0). Tako. smo ~- p~t DiiJ::edbi i.ii-P., () og··prunJera mo am
-0
1 p
lDICIJatiZliCije na sljedeei naCin: \ - - '!(.;,. • !ilc !:~5 " __
. " :·~l'.' ~~~- ..
int *NizPok[S] = (&Brojl, &Broj2, -n~w int, new int[lO], new int[Brojl] };
...
0

ovom -
-sve -dok "eleinenttiha~ ovakvog _,.,
moZemo pristupati sa a [ i J [ j J (a moZeffio, zahvaljujuci pokazivackoj
aritmetici) ne trebamo se sekirati o stvarnoj organizaciji u memoriji. Zaista, a mozenio koristiti kao.
dv.odimenzionalni nfi: sa 10 redova i m kolona, iako se radi samo 0 veoma 0e~orsimulaciji. Pravo stanje
n
u memoriji moglo bi se opi~ati rec1mo SlJeae6oru Slikom:

a! OJ.a ftJ _...-ra;;.!:..;9;.!]T"'" _.,--.,---.---.---T-


u
-
I
t
!

I ~ I .I j I t .. I I .
-~:-----,.----· . . ~HH _ _ _ _, , , . . .

. n
If' u
-
a i
VI
u.......

12
!
(
u
I n
0 __,

n i,...-5-

-n ~-·
.,
Frimi.jetimo•da'nam. simUlaci·a dvodimenzionalnili 1Lizova rek<r nizova pokazivaea oin:oguea'W' eak: i
..._da napravrmo ~e ~dv~jmen.zio~e nizove" kod kojih. razliCiti "r OVf' li1111JU. . cJit ~j .,
elemenata. Ovakvi "mzoVI" naztVaJu se (engl. ragged arrays). Na p11111Jer, ukoliko • ·

n
' ;
izvrSimo sekvencu naredbi

int *a [10];
·

for(int i = 0; i < 10; ·i++) a[i] =new int[i + 1];


. .

n LJ reda, treCi. element tn r "grbavim ilizovima" more se ostvariti uSteda memori ·e ukoliko

n
')
je potre no zaparntiti elemente neke trougaone iii simetrii\ne matriq:

D
!
~-;
-~· . .,..

[JL,
Na kraju, razmotrimo
0 ~ ...

0
~..

0
._,
I a[i] =new int[m];
"'iij~--.

0
l.
Nakon ovoga, a moiemo koristiti k s · · dimenzionalnom nizu i isati a- · · , mada je
a_zapravo pokaziv{lc na [ffiffi'iva~ (dv_ojnipokazilJfj[;~ai~ kako_je a pokaziv~ (n k~vae), na
nJega se moze prumJem mdeksrranJe, tako . lla ~'a [~J mteqJretira kao ~ (aH). Medutiii:l, nakon"

n
.,.
I
dereferenciranja dobijarno ponovo pokazivac (jer je a pokazivae na
primijeniti indeksiranje, tako da se a [i] [j J zapravo inteqJretira
interpretaciju, za nas
ponovo more
Bez obzira na

0
....
kao dvojni pokazivac:

0
••
· t int **a =new int* [n]; J . .:;/i' ·
for(int i = 0; i < n; i++) a[i]=new int[m];

Naravno, u oba slucaja ovakav "dvodimenzionalni·niz''·morali bismo· bpsati .pmlllipno (prvo sve redove, ···~'·

0 a zatim niz pokazivaea koji ukazuju na poeetke redova):

Sfor(int i = O; i < n; i++) delete[] a[i];


·

"·'
2 delete [ J a;
D Interesantno je uporediti obiene (staticke) dvodimenzionalne nizove, 4inarnicke dvodimenzionalne
"' ·nizove sa poznatom drugom dimenzijom, sunulirane dinarniCke dvodimenzionalne nizove sa poznatom
0.. prvom dilrienzJ.JOID, i simUliiane dinarnicke-dvodiilleiiZionalne nizove sa obe dimenzi"e n oznate. U sva
Cetiri. slucaja Zli pnstup individualnim elementima mozemo konstiti sm a £i J [ j J, s tim Sto se ona u
drugom slucaju logicki inteJ]lretira kao ( * (a+ i ) ) [ j J, u treeern slueaju kao * (a [ i J + j } , a u Cetvrtom

J slueaju kao * (* (a+i} +j l. Medutim, uzmemo li u oozir da se ime Diza upotrijebljeno bez indeksiranja
auto:t:b.atski konvertira u pokazivae na prvi element tog niza, kao i 'Cinjbnicu da su istinski elementi
•• dvodimenzionalnih nizova zapravo jednodime~onalni nizovi, doci 6erno do veoma interesantnog
] i
," (13
!
,j
_, .....

f.'
.....;

-·· ...,,. zaklju&ka da SU,.).J••.~ Cefui..,~~.!YPaja ~~,.petiri-:sintakse-(.,HJ ~jh ·('*'(a+i}) fj'];" * (a.liiJ.+<j·) i ...-., ...[
·
-, * (* <a+ i l +j. l) u potpunosti ekvivalentne, i s\raka od njih se mo.ze koristiti u sva eetiri slueaja! Naravno
·· da se u praksi uvijek koristi sintaksa a [ i 1 [ j l , _ali je za razwnijevanje su.Stine kolisuo. znati najprirod.niju
inteipretaciju za svaki od navedenih slucajeva

Nakon Sto smo razmotrili kako se vrsi dinaruicka alokacij~ dvodimenziqualnih nizova, lako mo.zemo
f
. napraviti :funkcije za dinamiCko stvaranje i ~tavanje matrica proizvoljnih dimenzija Na primjer:

f
• J •
;
/ cfuubl:e **StvoriMatric u (·irit, Bro.jRedov.a, int BrojKolona) (
double **Mat = new double* [B-ro]Redova]; ·
for(int i = O; i < BrojRedova;_.i+"+ ) MatTi) ·= new douJ:>le[BrojKo lona];
return Mat; . , .-
'
void UnistiMatricu (doubl.e *x,.,~,,,_..
fop (int i = Ohi <
.. ..
l
. · ) . dEil:ete [l" Matj,'i "£:: · 'J
...
,.
--~~~i'f; . . . ~ .! •

-~~~~~- ..-.: .
int n, m; · _'W·-
·; ~
cin >> n, m;
doubl:e **Matrica
I I. Radi nesto
:0 ~

Unis.tiMatricu (M<ttri:
:0 i..J

fsoo
D
L
niz

a Ovo
.fl i...J
u . ne · . . kod kojih druga

-~
dimenzija nije poznata unapi"ijed. Oni se mogu veoma viP.rnn simuJirati; ali ne u potpunosti sameno.
Takotfer, primijetimo da u :funkciju . moramo prenositi i broj kolona, jer nam je
potreban u for petlji, a'njega nije mogu~ pokazivaCa.

~
sa n i lllc
pokazivaCi inicijalizirajli''fta nule):
.,
...
fl
~

~· ..
.i
try
int i, ·**a = n~w int* [n];
"'
for(i ;;•.Q; i <:;•n;'i++) a[i]·;. of..; ..
. ,,, . ~·.
u
._
..I
try l!) .;· . ..i;..
for(i 'O;;:,t < n; i++) a[i], pew int[mJ.;
fl
·=. =
Q) ,, . . .
catch( ••• ) '«J. 1.:..
for(int i =:
0; i < n; i++) del:ete[] a[i];

fi)
delete [] a):
throw;- D
~

u
. ·:.
.l..
catch( ••• ) l. x.,J· .
cout << "Problem~< sa memorijo~,! \n~; ._

I 0
l 14 L..

n
.. ,

.r[I '•

I.#
· -· Dinamicka- alokacija memorije ima-;velike prilfijene. u .praksi. .Pretpostavimo;·'na
· primjci'; :c~a. je
f ~c
)f-.' neqphodllo !;a tastature unijeti nekoliko reeenica, pri eemu broj reCenica nije unaprijed
poznat Dalje,
-·~·-··

'
6. neka je poznato da duZine reCenica mogn Zliatno variraJi, ali da neee biti.dliZe od 1000 znakova
Jasno je
da n3m je potreban dvodimenzionalni niz znakova ali kakav? Kako broj reCenica nije
[!~- dimenzija nije poznata unaprijed. Sto se tire druge dimenuje, mogli bismo je fiksirati na
poznat, prva
1000 znakova, .
ali je vem;na je neracionalno za svaku reeenicu rezervirati prostor od 1000 znakova, s obzirom
' da ee
'"" veeina reeenica biti znatno Ja:ae.a,. ~ogo je bolje za svaku recenicu zauzeti ono/iko prostora
[~
koliko
zaista zauzima.. Na taj naCin dobijamo "grbavi niz" reeenica, odnosno dvodimenzionalni niz
znakova u
kojem svaki red ima razlicit broj znakova Sljede6i primjer ilustrira kako to najbolje mo!iemo
- izvesti:
Broj~ecenica,
'

f~.:)~~~- )~~
0- !
T

int
cout << "Koliko
i;
. _i:-eCen'ica: ";
·~

.0~ ... m·~~ ,,


....
I '

[t I .
i,..W
}
for(i

G
<<; endl;

Uovom
L. ~ Nakon toga,

G ~
alocirani prostor.
deklariran lokalno unutar
.·Piimijetimo da je RadniP rostor
se 'aql;i>matslki uniS!ava cim se petlja zaVI'si. Kada smo unijeli ••

G
l.
reeenice, sa njima mo!iemo Sta god relilttl:~.
poretku u odnosu na poredak u kojem smo ih unijeli).
navedenom primjeru, i!!pisnjemo ill, u.-obmutom

G L,.

[}'
l~

G
...
' .

~
-char Pomocna[lOOO] ;, · .·
strcpy( Pomocn a, Recen ice[i]) ;

~lot.~ it
·~
. . strcpy( Receni ce (i.J, Receni ce [i+l]);
strcpy( Receni ce[i+l] , Pomocn a);
' :; ...:.- . - '~ _. .....*"-~:'-'~;:,:-~_! .... : .....

~
·--~
Ova strategija bi vrijeQila i za slucaj dinamickog niza reeenica, u slucaju da smo za svaku
3Iocirali podjednak prostor (mada 6emo uskoro vidjeti da za.slueaj din'attiiCkih ni;rova
efikasniji pristup). Medutim, u o · ..
reCenicu
postoji mnogo
koJsdti ovakvu razmjenu,' s obzirom da smo za 'H 1
~
svaku reCenicu alocirali taCno on ·
0·'-•. · ·- zai - · · ~toga bt. optranje liZe ~
r emce na mjesto koje je vmzima la kra6a reeenica neizostavno dovelo do pisanja u nedozvo
ljeni dio
4

memorije {npr. preko neke druge recenice), Sto bi moglo vrlo ~erovatno dovesti i do kraha
programa!
}
......

}

}
l
......
j
~j
~

•·<'·char ~-~s>.J.ll?C:ni .=. J1,~9enic~LJ,J_; ••.. .... ·~ . - ... -~ -' ·. ~,,


· j_ Recemice[i] = Recemice[i+"l]";. Recenice[i+l] = Pomocni;
..w

~r
-
., f
-
T[-
'i[
"-'

f
1[
-~
-
~
~
fl
.:....

Bitno je ~~ti!
fl
J!'l

iz

. . . . . . . . .
u fimkciii kriterija u odnosu na
( ovo je jos jedan
koji bi se po~@ potpuno identi&o
fl 0

.· . . . ..· . . ne .. C++). Naime,"funkdja kriterija_do~ija·kao


parametre pokaztvace na dva elementa niza koji se porede. To 6e u slucaju obicnog dvodimen2i0lialriog
iiiza makova biti pokiiitvaci na prvi znak recenica koje se porede Medutim, u sluCaju sortiranja gore
--·n
""'
definiranog dinmmckog mza recenica, niz koji sortiramo je zapravo niz po~vaCa, tako da 6e funk:cija
kriterija kao parametre .clobiti pokazivace na pokaztvace na prvi znak recenica koje se porede: To.
zapravo maCi da 6e se prihvaeeni pokazivaCi morati dodatno dereferencirati da se dobave pok8ZlvaCi na llc
prve makove reCenica koje cemo eventualno proslijediti fimkciji strcmp. Naravno, kako fimkcija
kriterija uvijek dobija genericke pokaztvace, olli 6e se prvo morati pomoeu 1 '@I y IfF konstrukcije
(char**) konvertirati. u odgovarajuCi dvojlli pokazivae koji 6e nakon dereferenciranja dirti obiCni
pokazivae. ·

V e6 smo rekli da DizOvi p~aca glavnu primjenu imaju prilikom simuliranja dinarniCke alokacije
dvodimenzionalnih nizova M~ nizovi pokazivaea na znakove mogu imati veliku primjenU: i
i IIH\·
'
16

n 1
n-.
. .
'
lh .. " '
.!.-,

ff
f}
iL, '

neovisno o4-.4i!L~ alokacije memGrije!. Zami
euvamo imena svakog od 12 mjeseci' u godini.
odnosno dvodimenzionalni niz makova, koristili
'
sli!Do-r-na primjer, da je neophodno da'"u:nelrofu-ni
Ukoliko za tu svrhu korisiimo obiean illz stringova
bismo slie<feeu deklaraciju!
zu

~
char· Ime naM j9se ci[1 2) [10] = {"Ji mua !", "Feb ruar 11 , "Ma rt", 11Apr i1",
,;Maj ", "Jun i n I "Ju li u, "August"_, .. Sept emb ar", "Ok
"Dec ernb ar"} ; toba r",. "Nov emb ar",
·
[} U ovom slueaju smo za svaki naziv morali · zauz
eti po I 0 ;makova, koliko imos i najduZi naziv
.,.
I ("Septembar"), ukljucujuCi i prostor. za NUL grani
Cnik. .Medutim, innogo je racionaluije definirati
pokozivaca nakonstantne makove, na: SljedeCi na/ljn niz *'-
[} •
Con st char
·

*.Lm•en;~cM:J.e••e.c:.L.l..L«
' { "Jan uar" , "Feb ruar " I "Ma rt", "Ap
"•"" !!.lll~~rt" 11
ril n,
Sept emb ar", "Ok toba r", "Novembar"
[}~-- ..,.. ~'" •· ... ' ·"·· "'· ~ .. ······'' " •....... "' •..
I

Ovakva iniCijalizacija
· da se poKkivaCi na konstaDtne znakove mogu
G L.w
inicijalizirati stringovnim
prvo m slueaju se za niz Imen aMj .
prostor kopiraju navedene string:o
postoji velika razlika u ove dvije definiCije. U
wosfur od 12. 10= 120 mak ova nakon eega se u
taj
· druge strai:te, u drugom slueaju se za niz
Ime naM jese ci zauzimaprostor za
Q .
stringovne konstante koje su sv!lkako.p()hqmjime·n
memorijski prostor.
· koji se inicijaliziraju dapo kazu ju na nilvedene
,eog<f:je u me:QJ.oriji pa se. na taj naCin ne trosi doda
treba
tni
Dl. da bi trebalo niz ,,,

. ~
I
L--..
Ako uzmemo u obzir da mogu kl!Q rezultat pokoztvace, m~Zelno napraviti vrlo
0L,_..
interesantnu funkciju koja kao rezultat ~Jmlf
mjeseca .Cijije redni broj (od 1 do 12):
cha r *Im eMj esec a(in t Mjes~~)
·-~::·

@
;¥,:const cha r * Imen aMj esec i" Pt] '
{ '~ Janu ar" I II Febr uar" , "Mart n,. ".i\.prillf
0
4- ...;,
"Maj ", "Ju ni", "Ju li" 1 "Au,~
"Nov embL r", "De cem bar" };.
retu rn Imen aMj esec i [Mjese'{~ 1 ;
.
"Sep texn bar" , "Ok toba r",, ·w: \
I

g (}]
ne '\'l'aCa ime
'

g cou t << ImeM jese ca (5) ;.


na

0
1,.,,
strc py(N ekiM jese c, Ime Mje seca (3))

'.·-i slicne konstrukcije. Zaptavo, zbog autOilll\.tsk


;

e konverzije,nizova u pokazivaet: funkcija ImeM


se mog la napisati i pomoeu obienog dvodimen jesec a'-·"- ·
0
...
'
'· f,
· nepotreban utroSak memorije. !l yezi sa funkCijama
omenuti da niposto ne smijemo kao rezultat funk
zionalnih nizova znakova, ali bi na taj naCin imal
koje kao rezultat vraeaju pokazivaee potrebno je jo§
cije vratiti pokaztvac na neku loka/nu rom]en1iv
i

definiranu unutar te n ije, u ?/<


0
'""'
promJ utva prestaje pos oJa
pokaztvacl
s u uu se radi o statiCko rom enfivoj. Nilime, takva
CIJa zavr§i, tako da ee zapravo kao iezultat iti vra6
en viseCi f

a Priea ·o nizovima pokazivaea ne bi hila potpuna


. ~· Ovakve egzoticne tvorevine takoder mogu
kada ne bismo spomenuli i nizove ~tvacq lW
. imati veoma interesantne prlmjene.
I
~~porno~ ~~ n:n-edbe definirali ostavimo •
novi nv·o lcNa g;n koji pr~vlja pokazivae na
ko a rihvata Jedan ct eli bro kao ar ent !f#aca ao rezultat realan bro · funkciju
,,, t;yp edef dou ble (*Po lcNa Fun) (intJ j;

]
l
-~-·- --
·f
_Nakon.oVIJ)cve definicije sasyjmje lako dll!jnirati niz ookazivaea na funkcije: __ "• •!C,.. ·- · - (
. . f

JI PokNaFn f [10]; ....


Ovim je f niz od 10 pokazivaea na funkcije (koje prihvataju jed<m cijeli broj klio argument, a vra6aju ~1]
__ ;

rea1ni broj kllO rezultat). Ovakllv niz se moZe deklarirati i neposredno, bez typedef naredbe:
(double (*f[lO]) (int)'";) ty
-·D
ne

cout << fl (x) -<< endl « f2 (x) << f4 (X) -iJ


·-- -,--. ~o
<< endl << fS(x) << ;endl"<~ endl << f8 (x)
,...... _
<< endJ._,,::<- :1!9,(-?<h:-:j;,<;--endi <,;;~l1!ij:~~~
' ~~.: . ''i ,c': ' ~

:*' __ iej_!er:i]it?; ~
Nizo'?: ~okaziv!Wa na funkcij~ nude_ ~~ino el!lgFtije_lj uopCiti na proizvoljan broj
funkciJa:
J 2.t; doub~Ei·
- - 1-~ - - _- - - -

(~f[10]) !:1.'\-,t) .,;,, !!1, f9, flO);


1J
• for(~nt ~ O; 1 < 10; 1++)
=
1J
~

Ill..,
,. se ]
indeksa. Iskusniji
_pored ovdje navedetiih primjena
1J
,.- 1-'
1J
D
·u
? I"""
vll

~~1
\
., .... .;·_- ..

-.

d~
D
-\J-- D
i
18
u
-
n
n
. n_ ...
F' r ·-
"
STRUKTURE KAO SLOZENI TIPOVI PODATAKA

Nizovi se u programiranju koriste za smje5tanje skupine povezanih poda!aka od kojih su svi istog
tipa (na primjer, popis ocjena za jednog studenta ili za grupu studenata, kolicine padavina u toku svakog
mjeseca u godini, itd). S druge strane, u praktiCnim problemima se eesto pojavljuje i situacija kada treba
euvati na primjer ime (sa prezimenom), odjeljenje, platni
[}
~- -f~

G 1.-i•

G
G
...
u.
' Obratimo pafuju na taCka-Zl!lez koji se nalazi · Z!lvrsne vitieaste :mgrade; koji se veoma eesto

u zab?ra:vlja, a ciju cemo ulo.oro. obj~ti. PJ;o9Ve!jljjve ;:m_e.;· Odj,el-~en_·.J·· e, ,Platn~Broj i Plata
naztvaJU se po(Ja (engl. fields fJJI:ukt:re ill a!;bt strukmr~l'ii. :t'-.'" ff"t : . _.·. , . ' .. .
Slieno kljuenoj rijeCi typedef?'kljuona~ee struct" samo dffkira novi_ fY!.'_(ic~ ce,mo zvati
... 10

u
••
struktumi tip), a ne i konkretue primjetke_objekita tog tipa Tako; ita primjer, tip R4fTSaino opisuje
koja karakteristiena svojstvi ".(atribtife) posje@je ;bilo koji radnik. Tek nakoii;<'lti'f;deldatirnmo

a. ~ .;
odgovarajuce promjenljive slogoVI!og ii.pa"kao na•primjer u deklaraciji

·.} vf/ Radnik Sekrei:ar,


_-'>"'j·~----- )t: . ~~~t •

Sluzb~~~~'l~~nS.$rti;; -kf-F'~~IJ-v< &t&~ ~'pql!&4nil


/ · · '·
·._.·:--. --. . . --.... . . . '~ -::- ·•.

Q Sekretat, ~zbenil<, Monter . · Portir sa . moZem.o


'..---~

D
Li
tJ1' strilct Radnik Sekretar,

Ovakva sintaksa dozvoljenaje i ujeziku C++, ali se


u
... ~

] struct Radnik {
-· char Ime[30];
char Odjeljenje[lO];
J
.. ,I
int PlatniBroj;
double Plata;
} Sekretar, Sluzbenik, Monter; Portir;

l
·.-J.
Sada pestaje jasna uloga taeka-zareza iza zatvorene viticast" zagrade: njime govorimo da u tom trenutku
.ne felimo da definiramo ni jedan konkretan primjerak tog tipa

} Pojedin~a polja. (~b,_rti) ~utar slo~ovnih pro~jenljivih ponaSaj~ se poput individua~nih


~ Jlrowjenljivzh odgovaraJuceg llp~ NJrma se pnstupa tako sto prvo navedemo zme slogovne promJen(Jrve,

}
--~
I
{
;.
-
-l
~tim znak ( odnosno operator) taCka (.) L konaeno. imepolja unutar slogovne promienljive,.Na primjer,
sve sljedeee konstrukcije su potpw10 korektne: ·r-
strcpy(Sekretar.Ime, "Ahmed Hodzic")i
Sekretar.Plata = 530;
strcpy(Sluzbenik.Ime, "Dragan KovaCeviC");
cout << Sekretar.Plata;
·r-
cin >>. Sekretar.Odjeljenje;
.u
cin.getline(Portir.Ime, 50);
Portir.Pl.ata = Sekretar.Plata '- 100;
-
"0-
~o

~o
operatora u druge operacije koje ee se ob;ivliiati
-
strukturama). Na primjer, nije moguee jednim i.iik@:rorn postaviti sva polja u promjenljivoj Sekretar, ~o
vee je to potrebno uciniti nizom iskaza poput: -
~
strcpy (Sekretar-IIli<ll.'. "Ahmed Hodzic");
strcpy(Sekretar.Odj~enje, "Market':L.p.g");
Sekretar;PlatniB;roj ,;;.. 34; · -"-• .• ·
Sekretar.Plata = 530;
·'
Takoder, bez upotrebe preoptereeenja operatom sljede& ko~cije su besmislene: 11
....

~
cout << Sekretar;
X cin >> Portir; .

D
i(J
-
D
~
~~;~;~~;~- kako po vrijednosti, tako
Na primjer, i po referenci.
pretpostaviino da
Zelimo di se, Sto mamo, more opisati sa
tri koordinate i, y iz. U jednom od mnijih poglavlja za tu svrhu koristili smo obiean niz od tri elementa
Medutim, kako funkcije ne mogu da vracaju nizove koo rezultate, funkcija vektorskiProizvod koju
n
-
smo pisali zabtijevala je tri parametra: dva vektom koji se mnoze, i treei vektor u koji ee biti prihvaeen
rezultat. Mnogo je bolje wnjesto niza definirati strukturU Vektor koja opisuje vektor u prostoru, na :o
primjer pomocu sljedeee deklaracije: · -
struct Vektor (
double x, y, z; ·o
I;

·o
'D
~

2
.f:l
n. .

·n·- . . -_- -
1- ~--
.' . . . _. ....

#incl ude <iostr eam> .


[} -
using names pace std;
struc t Vekto r {
doubl e x, y, z;
[} };
lr.--i. void Unesi Vekto r{Vek tor &V) {
cout << "X "; cin >> V.x;
G i.---io
cout << "Y
. cout << "Z
"; cin >> V.y;
"; cin >> v.z;
} •.. ·
Q
••
void Ispisi Vekto r(Vek tor
cout << " {" << V. X ~s<<.. ·n.,_
.
-,.~: ~-
v.z << "}";
}

Q Vekto r SumaV ektora (VektSl\~l:<


Vekto r V3; · ·
L.~ V3.z Vl.z + V2. z;
V3.x = Vl.x
retur n V3;
D1...--!.
}

Vekto r VektorskiProizvod"~,••~ V2) {

Q1,..--it
Vekto r V3;
V3.x = Vl.y * V2. z - Vl. z '* V2 ·fiJil·
_V3.y = Vl.z * V2.x - Vl.x * V2.zf
V3.z = Vl.x * V2.y - Vl.y * V4.x;
DL.,~
retur n V3;

n ~--~
in t main () {
Vekto r A,' B;
cout << "Unes i prvi vektor :\11-" ;
Unesi Vekto r(A); .. .

a•••
cout << "Unes
Unesi Vekto
i
r·(BJ;
drugi ~.ektor:
-/ .
_\::p.".
.
cout ~< "Suma ova dva,ii- e>ktor it. ~-«·;
Ispis~Vektor (Suma Vekto ra (i\-, -~);.
;
JiiA.\ii·
·
'

P.rozi vod je: ";


[} cout << endl << "Njih
Ispisi Vekto r{Vek
ov
torski Proiz
.yektd
vod(A
"rski
, B));
d }

au

Q
u
r.-1{
Vekto r Suma Vekto ra(Ve ktor Vl, Vekto r V2)
Vekto r V3 = {Vl.x + '12.x, Vl.y_ + V2.y, Vl.z + V2.z}
;
retur n V3;
rr
ki.
}.

{
Vekto r Vekto rskiP roizv od(Ve ktor Vl, Vekto r V2) *
~w Vekto r V3 = {Vl.y * V2.z - Vl.z * V2.y, Vl.z * V2.x - Vl.x V2.z,
Vl.x * V2.y - VLy * ·v2.x} ;
retur n V3;

~
}

~.~
,, 3
Iii
J
1
Rad sa struktumim tipovinia eemo ilustrirati na jos jednom jednostavnom primjeru. Cesto se
zahtijeva program koji Stampa detalje u uplatama na predracunskom izvjestaju, npr. za platrie soiskove
ill za koutrolu u samoposluzi. Ovdje je napisan jednostavan program koji koristi strukturu Up lata za
l
~

cuvanje podataka 0 uplati. Strukturna promjenljiva NovaUplata se prvo prenosi po referenci !! fimkciju
Ci tajUplatu, koja postavlja vrijednosti u sva njena polja Nakon toga, ona se prenosi po vrijednosti u ~c
funkciju stampajUplatu, koja ispisuje na ekran detalje o uplati u zahtijevanom obliku (u nekom ~

realnijem programu ovi detalji bi se vjerovatq.o trebali ispisivati na stampac umjesto na ekran), Program
za svaku uplatu tr8Zi da se unese datum uplate·u cibliku DDIMM/GGGG (npr. 23/07/1997). a Z8tim ime
nplatitelja, i iznos yplate , · .,\... ,
"'[
1-'
#include <iostream>
#include <iomanip>. JO
using namespace std;

-10
const int Ma.ksima~na.Du.z~n~

struct Uplata
int Dan, Mjesec,
char Uplatitelj[M<ik1lin•al.na, n
double Izrios;
+ 1]; ][]
};

void CitajUplatu (Up lata &U) \ ···{:~. .


char c; . I I Sluzi za preska)canje znaka 'I' prilikom unosa datunia JO
cout << "Unesi datum up·lat€'·. u·;9bliku DDIMMIGGGG: ";
, cin >> U.Dan >> c >> U.Mjesec :>:> c >> U.Godina;
cin:.ignore (1000 · · · ~ri "i zaostal
• cou << Unesi ime uplatitelja:. •·i·:.
"sm "
JO
.cin. getline (U. Uplatitelj, MaksiriklnaDuzin.aimena );
cout << "Unesi iznos uplate.: "; .;_.
ciD. >> U.Iznos; ·
J[J
}

void StampaiUplatu (Uplata U)'i;j- . f



cout << endl << U. Uplati tel'... • ," .j.e,c-uplatio (la) iznos ad " 11
<< setprecision(2) << U.Iin:os ·.,:::<: ~:KM dana " << U.Dan << "I"
<< u.Mjesec << "I"··.<< U.Godina· << ·endl << endl;

int main() I
D
Uplata Novat:lplata; ;.j, ;~·'':

::~e ~~~~~~~r ~-·~ M ciJ;.,:r


CitajUplatu (N··· aUplata) i
'd') I D
· StampajUplatu(NovaUp lata);
ccut << "Zelite li jos uplata (DIN)?"; ]
cin >> Odgovor;
f ciri.ianqre(JOQO, '\n'); II Obrisi eventualni visak znakova

}
cout << endl; ]
u prethodnom primieru zaista nj_je bjlo ;,eophodno euvati promjenljjye koje sadrZe ime uplatitdja.
i?;nos uplate itd. u strukturi, jer smo u jednom trenutku radili samo sa jednom up/atom (iako je Upotreba
struktuniog tipa omoguCila da prenosimo u funkcije sve podatke za obradu odjednom koristeCi. ·samo
n
jedan parametar).
.
obradujemo skupinu
Ipak, ova situacija nije uobieajena u stvamom Zivotu. Mnogo eesee Zl:limo da
...._
siogova, na pnm;er sve uplate nplaeene u proteklom mjesec!L iii pot!atke o svim.
D
iadnicima u preduzee iii SVilll studentima na jednoj godini. ~a modeliranje podiltaka iz takvih sistema...:..-
iz realnog Svijeta moZe!no koristiti_~q,vef!'Uktli{!!,_ o osno nizove ciji je svaki element struktumog
tipa. Na primjer, sljedeee definicije tipa i deklaracije promjenljivih ornogncavaju nam da predstavimo·
skupiriu radnika:
-·o
4
n- .
~r:;;:-
1i
... .. const int MaksimalniBrojRadnika = 100;

n- "''
struct Radnik {
char Ime [30];
char Odjeljenje[lO];
int PlatniBroj;
double Plata;
...,, };

[ It
Radnik Radnici[MaksimalniBrojRadnika};

Cr -~
Radnici [3] .Ime

[} Tako, na primjer, ukoliko preltpO!;tav .BrojRalfnika predstavlja stvarni


.. . broj radnika u preduzeCu; moZem.o " - -. ·;

5for(in.t i = 0; \ i <
o- ~- ...
2. cout << Radnici[i].Ime <<

za
[l
. " . . Polja unutar struktura i sama mogu bit! slorem ·.
ponovo struktumog tipa Tako;,kombiniraju6i nizo.vd
podataka Ona, mogu biti nizovnog, pa Cak i
slo.gove,moZem.o ~ti vrlo sloW!e gtrnlcf1rre
. podataka koje .susreeemo u problemima iz realnog Zivota. Na primjer, zamisl.irix> da relimo opisati jedan
razred U Skoli. Razred se sastoji od ueenika, !lcSVaki ueenik. opisan je imenom, prezimenom, datumom
rod:enja, spiskom ocjena, prosjekom i i:D.fon:haqjom da li je. ucenik pro8ao ill nije. Spisak ocjena
I}... predstavlja niz cijelih brojeva (koji ima ono!iko !'lemenata• koliko ima pre<IJheta), dok se datum rodenja
sastoji od tri cjeline: dana, mjeseca i ~odine· Ti;ldenja, kojh su cijeli brojevi. Stoga je <najprirodnije
definirati strukturni tip Ucenik, koji opisllje jedpog uCenjka::.~strukture Ucenik mogu bill Im~
[} [._~
"P_rezime, DatumRodjenja, Ocjene, l;'rosjek h?rol?,z: A~mei Prezime su oCiglednonizovi
Wuk?Y"-. atribu! p~?s?.ek j: r~g ~R~A_o.k.}e_ Prif!ttCkayromj~ji~ Atribnt ps;xne cem~
defimrai:J kaq mz '(l!fhb broJeya dok ~!f~'8t!.'i..but9'i.
~=.O-flP"JaPefimratt da bude tlpa Datwn. .P!!._
[J;~-~
eemuje Daturii,ponovo strukturni tip kojlfse.sastoji od tri atributl\;,Dan, Miesec i Godina. Na kraju,
definiraCemo promjenljivu ucenici. ko_i,il. ee biti niz Ciji ee i::l~eriti biti tipa Uce~ik:" Na osnovu
.provedene analize moZem.o nap1siiti sljedeCe deld~acije: . .· ..
iJ'

Or... I
~
const int MaxBrojUcenika = 30;
const int BrojPredmeta"f:-12;
struct · Datum {
[J
1.:-w };
irit Dan, -Mj esec, Godina;

struct Ucenik (
[f
k-·1•
·I char Ime [20], Prezime [20];
• Datum D"l.tumRodjenja;
int Ocjene[BrojPredmeta];

~...
double Prosjek;
int Prolaz;
) ;

~b-1.
Ucenik Ucenici[MaxBrojUcenika];

~.....
1 5
l
j_
•o'"r •"•"•

1
Pojedmim dijelovima ovakve slorene strukture pri~pamo kombinacijom indeksa i iwena polja na
Sasvim logiean nacin. Na primjer, ukoliko treba postaviti godinu rodenja treceg ueenika na 1988, i
devetu ocjenu istog uCenika na 4, moremo pisati: 1
r:; Ucenici
2
[3].DatwnRodjenja.Godina = 1988;
Ucenici[3].0cjene[9] 4; =
·
I
~ad sa sloZenim tipovima podataka ilustriraeemo programom koji prvQ.~vnih
podataka o svim ucenicima u razredu, zatim ra.Cuna prosjek i utvrduje prolaznost za svakog ucenika, i na
kraju, prikazuje na ekiililu izvjestaj o svim uCeiriciaa u razredJ!. IzvjeStaj se sastoji od reeenica poput
I
Ucenik Marko Markovi4 ''f
.:.u
za one ueenike koji su proS)i, ·iiirOO;~•;:al

Ucenik Janko Jat.rkol~iC,.roil'oin .zz;;;.J9, ]


zaoneuCenikek~inisupru·~u. stJ:tikhlirano, uz pomo6 mnoStva funkcija, tako da je
lakse pratiti Iogiku pro1~lll, i
sto ~~··-~--
' b.~~ modifikacije. Takoder su kori§teni prototipovi
onda Na ovaj naCin se
]
<V!llllo" razvoja,pd vrha na . ·--., ,.,, programa, pa tek onda
njegove detalje, poeevSi od krupn,iJih ka sitnijim. ]
#include <ios;tream>··· ·.' _,,,. . ""· .<-?t"
#include <i.orl!&nip> ''
'
:. r~

using nameSpace std; JD


canst int MaxBrbjUcenika =.'.JO;,
canst int BrojPredm~ta
struct Datum {
12; =
11
~~t Dan, Mjesec, Godina;
};

struct ur;:11nik 1 . 1 '"!· ·-


]
·• char rme [201 ,'; Pre:?~~J.20J.;.
• Datum DatwnRodj<!llilj<fl /··.
int Ocjene [BrojPreilineta]; ·
double Prosjeki · ·
:o
, int Prolaz; -\. f'·.l-
}-;-- -~~-'-~, -~-:·~~/
.

int mq.ln (-} ( . . . . .:__ .- ·. ..·:,.


JO
int BrojUcenika;·'-' ·• ·
void UnosUcenik<l, (Ucenik Ucenici [], int BrojUcenika) ;
void ObradaUcenika (Uceni.k Ucenici [ l, int BrojUcenika) ; ID
void Ispislzvjestaja(Ucenik Ucenici[],int BrojtTcenika);
Ucenik Ucenici[MaxBrojUcenika];
Cout << "Koliko ima uCenikci: ".;
cin >> BrojUcenika;
11
-UnosUcenika(Ucenici, BrojUcenika);
-ObradaUcenika(Ucenici, BrojUcenika);
-Ispislzvjestaja (Ucenici, BrojUcenika);
}
Il
void ·unosUcenika (Ucenik Ucenici [ J, int ·arojUcenika}
void UnosJednogUcenika(Ucenik &U);
for(int i 0; i < BrojUceni.ka; i++) i
CD
D
cout << "Unesite pOdatke za " << i + 1 << " uCenika:\n";
-UnosJednogUcen.ika (UceniCi [i]);
I
D
(j)
TI
6
.fl
..
--- --. --- - ---~--

!}.
.. .
; j •

rr....·
. I
·-···.-··

vo id Un osJ edn oqU cen ika (Uc


eni k &U) (
&D) ; ·
' vo id Uno sDa tilm a (Da tum
[]- vo id Un osO cje ria (in t Oc jen me ;
·co ut·· <<· "TrtJ.e: ·n;- ·t:J .n·
>> U.I
erl ; :Ln t Bro jPr edm eta ·) ;-

i.l~
>> U. Pre zim e;_
cou t << "Pr ezi me : "; cin
odj enj a);
-Un osD atu ma (U. Da tur oR
[}.... ~unosOcjena(U.Ocje ne, Bro jPr edm eta );
i
{
vo id Uno sDa tum a(D atu m &Dl
[}• I
cou t << "Da n rod enj a: ";
cin >> D.D an;
"_; cin >> D.M jes ec;
...... cou t << "M jese c_ rod enj 'a:
"; cin t->> l:r. Go din a;·
cou t << "G odi na rOd enj a:
[} }
n. - 0;.· i »•·n
[
_vo id Un osO cj ena (in t Ocj ene .,
< "ip,
for (in t i
cou t <<· "O Cje na ·iz _." -<<
Q_ cin » Oc jen e[i ]; fl .· --: :~:/
<
}
}
O:·'-"'
Or.
~...-;

vo id
Sum aoc j en~
... , .·;;:-'_~-~<-~--.
Or
k'- U . p ro~az =
1 1; . . . .· .:-~:;.·
' .
i ~ 0; i < Bro jPr e~~ ta) i++ J ,.
for (in t _. .· ,-_-
... __

Sum aOc jen a += U.OcjeneJ;i:~;,· =·'o ,~·


ne[ i] == 1) lf.P rol< >z.
if( U.O cje
} -1 -<F-~--- _;:~·-·--/.
qr~,W.Elqme:'ta;
u. Pro sj ek = Sum aoc j ena /_
Q }

~~~ ~~~ ~~~ ~~~


vo id I isZ
;\1
aJe
~~-
dno
cc~
Uce
efn
n ·.
ji~
t( ceh
~(+U)f~,
c=iik ;
-=i~n~t~~
!;,~
~~~~"-
i'.,.l'l

.
;1.
!.

Q ~~~~i~~ ~n~ ~;
1
i < Bro:l~;~x~~; i++ ) >~>¥~-:;~- · •· .
d.C ;i [i] ) ;. ., -,., '·
-Isp isZ aJe dno gU cen ika ··(U c!jh
- - · -~~-. r-- _ :· . ---- -.i----~~~-~~j~.
-~
[} } ·
Ispis.~aJedn 0 g!Jcen$&,. (Uc eni k
Ui~{_c; ". · _. _,~_;J< .
~j.

(}
,vO id.
VOJ.d ISp J.SD atu ma (Dati1fi\c D)
cou t << "UC eni k " << -V·~ Ime
j
~< " " ~5\(
enj a);
.·. ,
J.,.
\,,
"'·'1. ·.
-:Pr eZ. riie << " ·ra den "; 1
- Isp isD atu ma (U .Da tur oR odj · . . ·· ·
if (U. Pro laz ) end l;
c~sion{2)·- <<" U.P ros jek <<
~~'-'
" ima pro sje k " << set pre
cou t <<
fr0..-~
}
els e
cou t << " mo ra pon avl j a ti
ra· zre d\n ";

vo id Isp isD atu ma (Da tum D). {


Drl,.i. cou t << D.D an << ' 1
" << D.M jes ec << ~." << D.G od- ina ;

ti a u nik . Nema
, kor istil i smo sla M · niz yc. eni ci.p iji su ~lemcnti stru ktu re
U ovo m primjilru Uc eni ci bi
.
nizo yi stru ktura ne mo gu biti amtcki. U tom .slu eaju , pro mje nlji vu
irik akv og raz log a da i
treb alo de:finirati kao gokaziv_a1_ na
struhru~~?..W~? odn?SJio
kao. ·

rg; ;en ik *U~enici]

7
J
nakon eesa- bismo, ~ samgmo koliko zaistrt ima _nCenika
J
_p-ebati izvrSiti aiobcij u rlinaWiCkog niza
,uCenika i dodijeliti pronijenljivoJ ucenic i lidresu rvo elementa takvo niza

IUcenici = new Ucenik [BrojU cenika ] ;}


moeu naredbe
J
I
Sve ostalo u program u bi, zahvaljujuci cinjenici da se na pokazivaee more
moglo ostalo isto, osinl sto hi na kraj programa trebalo dodati i naredbu
primjel\iivati indeksiranje, 1
delete [ J Uceli.i ci;

Pored toga,. bilo bi v·,eo_r~,.pj(;pe,f\II:lji,vo dodati i hvatanje izuzetka koji eventua


1no moze baciti operator
1
new u slueajil da .dirllUiriCl~la.J~!<III~j~~,ne
1
1
.•..
.-.. __
I
struc t Niz {
int Eleme nti[l
JJ
]
]
]
]

~ ~~~~~i i~~~~~ ~~~~~r nz~·~n ~~~-m~ a~-~k~ ~~~~~~ u~-~ii j~ek~p ~ren~o ~~~p~o ::
IliWin ·
neSto ne bi
niz koji .le
niz prenes.:n kao pararnetar, jedini
da formiramo pomoCni
11
i_ da unntar
funkcije radirno 8a njim · ..
]
'

neki objekat-tipa Niz. Ovim SQJ,() doSli -
teksta slijede dalja produbljivanJa ove ,_,a_,_..,.

Do sada Sm.o uvijek kada smo radili sa nizovima, u funkciju kao pararnet3r obavez ]
no prenosili ne_
samo niz, nego i broj elemenata niza (koji funkcija ne bi drugaCijc mogla
saznati). Y slueaju matrica .
inoraii smo pored rnatrice prenositi i broLredoya, kao i broj kolona Sve ovo
~ !JiOZe izbjeCi Ukoliko
fu · cfi ee atributi biti ne samo sam niz, nego i stvami bro· n·e ovih elemen ata
odnosno, u slueaju matrice, stvarni broj redova i kolona). Na ovaj nacin, 5Ve
]
informacije koje opiSUJU
niz (njegovi elementi i dimenzije) upakovane su u jednu strukturu, koju !JiOZemO
prenijeti kao jedinst ven
pararnetar u funkciju, pa Cak i vratiti kao rezultat iz funkcije .. Qlrn.i pristup
progrmnu, koji od korisnika traZi da nne~ dvije matrice istog formata (broj
ilustriran je u sljedee em
redova _i kolona takoder
]
zadaje korisnik), a zatim raeiria i ispisuje zbir dvije uneseue matrice . Upored
ite ovaj program sa sliCnim
program om u poglavlju o viredi:menzionalnim nizovim a Ova dva program
sitne detalje, funkcionalno ekvivalentna, samo Sto je lako uociti da ~ u verziji
a su, zanemarinio li neke
koja slijedi funkcije
]
·koriste i poiivaj u na mnogo elegautniji nacin.

]
8
#incl ude <iost ream >
'
n~
#incl ude <iom anip>
... using name~pace ·Std.;.
cons t.int MaxD imenz ija =
n-.. struc t Matr ica (
int· BrojR edova , BrojK olona ;
10;

,' -~
doub le Elem enti[M axDim enzija ] (Max Dime nzija]
;
nr. );

void Posta viDim zi"e{ Matr ic


if{Br ojRed ova < 1 II· BrojK olona < {

[t J thrOw "Dim enzije


if(Br ojRe dova > ~a.x••LDleilZ:
I throw "Dim enzij e

u 10!·-·
. ·f1;Br ojRed ova = BrojR edova i"
) ...

fl for(i nt j·= 0;
cout << ImeM atrice <<
cin >> M;Ele ment1 (i]. [j] + 1 << ")
~{/:j,
".,

G • h
)
)

cout << endl;

0 )
)

Q 'I
~ •
I "Mat rice
leotov-a · !·'i' Mf .Broj Redo va)
·,;;;.
M3; .#'. .
~PostaviDimenzije{M3,

0 for{ int i = 0; i < Ml.


for{ int j = 0; j <
M3.E lemet :tti [i] [ j ]

0 )
retur n M3;

int !Jlain (J {

0 ·Matr~ca
int M, N;
A, B;
,
cout << "Une si broj reao
......~h ~
cin >> M >> N;
0 ~{ . ;.. . . .
:-F

·, ·.
-Post aviD imen zij e {A,< M,· N) ;-Pos tavilH menz ij
e {B, M, N);
cout << "Une si -matr icu A: \:q.";
_unesiMatric~{"A", A);

a co~t << ·rr_unesi m.~tricu B: \n";


._..Un esiMa tricu{ "B", Bl;
cout << ~Zbir ave _dvij e matr ice.je :\n";

0 ) -
~ spisi Mat: ricu {•Zbi rMatr ica {A;
..
~canst _char ··Poru ka[])
B) , 1) ;

J
cout << Poruk a; · ·
)

]
9
..
...;[
][
Matri ca definiran statiCki
U ovom programu je za pamcenje elemenata matrice unutar strukture
dvodimenzionalni niz Eleme nti, sa fiksnim dimenzijama, dok se stvame
dimenzije pamte uatnbu tima
je funkciji Posta viDim enzije .
J[
BroiR edova i BrojK olona . Postavljanje ovih atributa povjereno
postavljanja je u Cinjenici da ova
Prednost njihovog posmvljanja pomocu ove funkcije urnjesto direktnog
funkci'a more da provjeri da li su zeljene dimenzije matrice veee od
izuze!1\!l:5ukoliko jesu. a taj nacin se sprecava se greSkom postave
deklariranih · enzi';J, i.Jia! ?!-
dimenzije matrice koje su vece f =[
prostora rezerviranog za smjestan1e elemenata matrice.
J[
biti veoma zahtjevno, kako po
pitanju
funkcije po referenci, stVai":r,ri
prilikom prenosa parametara u
parametre, tako da fuukcija radi sa
][
kopijama stvarnih param etara ·.· zanzimaju mnogo prostora, gubi se mnogo
vremena na njihova kopiranje0·.
cinjenicu da se ista . .
se trosi i memorijski prostor, ·s obzirom na
i u formalnom paramt1ru. Na primjer, uz ][
pretpostavku da svaki realni memoriji, saino za euvanje elemenata matrice u
· strukturi Matri ca cuva se· . se 8 -10 · 10 = 800 bajta, a nekolik
dimenzija matrice. Prilikom ·
o bajtova se trosi i na pameenje
. ·po~>'a. ljmkcije,;._ovi bajti se posve bespotrebno kopiraju u funkciju.
matrice bile veCi.
0[
UtroSak vremena i memorije bio bijos(veCi ill!. su'de!darirane dimenzije
'· . ·';''

]Jj
···r.
J[]
=tJ
J1J
}[]
,..
.[J
U prethodnom pro@:amU, ·~a Matri ca zauzima mn~go memor
ije, i to bez obzira na stvame
dimenzije · matrice,. jer
dimenzijami.
· elemenata matrice definiran staticki, sa fiksnim
~
~
u
u
ii~~~i~~ij~~~~~~~ irajM atricu
memorije ukolik o u proces u kreiran
eemu smo ranije detaljno govorili. Pored funkcije Kreir ajMat ricu,
ja
zbog toga sto vodi brigu o
matric e ponestane memorije, o
u ovom programu se koristi i
da u ovom slucaju, za
D
.... ,~

funkcij~nistiMatri~ ciji je zadatak oslobadanje rnernorije. Primijetirno

10
n
,17
rr':·:·'·_-~- ·· ·
L.

rr••..,
razliku od sliene funkcij e iz primje ra u pretho dnom poglavlju, .nije potreb
o dimen zijama matric e, s obziro m da su ti podaci vee sadrZani u
ovoj funkci ji kao parame tat.
no u funkci ju prenos iti podatk e
struktu ri Matri ca koja se proslje duje

rr ~~
#incl ude <iostr eam>
#incl ude <ioma nip>
using names pace std;

[f... struc t Matri ca {


~nt BrojR edova , BrojK olona ;
doubl e **Ele menti ;

ct I;

[}-......,
E!_J;ojKolcina;
..j~\ - . '
-~r;,

o-... {§!
for (i = 0; i < BrojK olona ; ·i;ttl __
MoEle menti [i] = new doublE !,'f$ro jKolon a];
.
:oElem enti En);=
.'ii'>·,
o;

[J... ~0 0 o) { . o•. :!~t '"·"',


~
for(i = 0; i < BrojK olona- '; ;i.-1-+1 ·~elete[J MoEl emen
ti[i];
throw ; :';

[J ~-i.,
I
retur n M;
I

[t ~--u
or ~n 1 = 0; i < MoBro jRedov <l; i;+.t,}f ·
for (int j = 0; j < M':iBr('ijKolilmci~' :f++) {
cout << Ime << " [ • -~<;±_ ::+:',.~ :<< · •, • « j,· + 1
G~.J, } cin » MoEle menti !ji' d;iiJ··jt-. <.:, ·
. ·._.:
. ·•.·.
-:_,;~
~
.. · '"
·<·~-
:I : ;_~ ..
« •] ,
no

I -
'f:
;;

0
.._' ,_,__ .•.
void Ispisi Matri cu (Matr ica· M, ii{i: sfhn aispi s . . .
{ .·
,.J for(in~ i -:- O; i ~ MoB:;9 jll.7do v.a; i+~) ( ..
, ,;;~;' ..
for(~nt J = 0; J < M•BJ; PJ.Kol ona; ]++)_
t'J.,:. •;:,i('_,
cout « setw (Sirin~'Ispisa) <:< MoF;Jerii!<lnhJfh),. ['J;j;
0 cout « endl; , ·~ ., :.,~ ·:!f<•,;. .·.
·-· }
'
'• -~·
to!
-;.f//'
0
.. -~
I
Mat:L ica Zbi_rM atrica (Matr ica Ml, Matri ca · ·
i
!. ...,. . . .
oBrojR edova o= M2oB rojRed ova II ';M2oBroj.~<¥!ova. !=
Mf! oBrojR edoira )
~ "Matr ice nemaj u )edna ke dimen zije!\n .l':f •;'\
Q - Matri ca M3 =· Kreir ajMa tricu (MloBrojRedova~ MloB'
for(i nt i = 0; i <MLB rojRe doya; i++)
rojKo lonal ·;
• ·
for(i nt j = 0; j < Ml.Br ojKol ona; j++l ,~!·
'1. M3oE lemen ti[i] [j] = Ml.El emen ti[il (j] + M2oE lemer
iti(i] [j];
r retur n MZbir ;
I . h~

void rmist iMatr icu(M atrica M) !


pif(Mo Eleme nti !- 0)
• for(i nt i = 0; i < MoBr ojRed ova; i++) delet e[lM oElem
enti[i ];
delet "' [] M.Ele me;>t i;
]
1
11
I
.J
Jl
· ·. int main () I
~-Matrica A= {0, 0, OJ, B = {0, 0, 0}, C = 16, .0, 0};
int M, N;
][
-c.out << "Unesi broj redova i kolona za matrice:\n";
cin >.> M >> N;
<§X) I
A= KreirajMatricu( M; N); -
][
B = KreirajMatricu( M, N);-
cout << "Unesi matricu A:\n";
-UnesiMatr-ict,i( "A", A);
[[
cout << "U.[?.es.i matricu B: \n";
- UnesiMat::r;:i.c:y. ( "B",
cout << "~p,f~---~_ye . .-
-IspisiMa~'l:f'uC>;:: := ·
I
} .. :>> {,'\~{ .•....•.
(§~~·~~~:~~a ?*'~~ijno.
} .. · •' .. ·~··.?· . .. · · ·.·.· . . . ·. .. .
I
..-UnistiMat:.;:4-cU:·J&Jil"'Uni":tiMatricu·(B)· ;-UnistiMatricu (C);
}. . ._· .:"i/;~:rt~ '' . ·. - ~~,: . J[]
Vi<limo da je !.lobi·eni ro takoder .wlo d~· mi. ut rethodnog ro Medutim, u
njemu se javljajl,.l. n'eki
• _-
A i B definirali i matricu
detalji
c, a
l<:oji.ni~
. - -
postOjali
.... '
uinjesto,lllli:edbe·:
._
....
u
·
j)re!h!> .
.,..,_.1-i_ ·'
•·/';.,.~ ... ,
oln programu. Prvo,
~--:
ovdje smo pored matrica
]
. . __ ,_ . ·.. . .J -~~~~-~---"t-~;. ~~,_:-.-~-:r.
IspisiM;>tricu'lzb irMatri<:ir'(A('Bi :kt>;~(;.
. .._ .· ... ' :~---•·:,.- ~-
l]
koju smo imali u pfethodn~m pro~~~~~~~~javlj.a ~~~a
.. ,... ,"--·;_~::- • ~ • <- • --~"if.,. ._.. ....
_
Ispi~;i.f;~Hcu (C ZbirMatr.ica(P!"}!~~-fJ; JO
kojaje funkcionalno ekvivalentna slijeduod dvijeliil;\"edbe~:· ·
.[
C = ZJ;lirMa~rica (A, B);
IspisiMatr~cu
.
1 .
'-'. :!~- _.,-_._-:-· ·
..•· •. ,. ;. "./"; ·
7) ;-,<·· ·. ·
··~ ·.
_,,.~jY;~-i-:
IJ
'Ill Problem je u ·tome Sto funkcija
KreirajMat.ricu }i kao rezultat vra6a D
~-·
bi se mogla neposredno prenijeti
c.
n
n
D
sva

;o
D
~u~~~~~~~~ ~~~~~~~~~ ~~~~sami, Na kraju programa potrebno je eksplicitno
inicijalizrranona
elemenata).
sve
.uniStititri B· . rezerviran
A, za smjeStanje njihovih
Pretpostlvimo sada da stvarahje matrice A uspije, ali da prilikom stv3:ranja matrice B dode do bacanja
izuzetka (npr. zbognedovoljrie kolicine raspoloZive meri!.orije). Izuzetak ee biti uhvaeen u catch blok11,
n
ali stvorenu niatricu A trel:ia ~brl5ati: Njeno brisanje ee se ionako desiti nakon ci tch bloka pozivom
funkcije UnistiMatricu. Medutim, Sta je sa ·inatricama B i c? Naredna 'dva poziva funkcije
UnistiMatri~u .trebaju da uniSte i njih, a:;one nisu ni stvorene! Medutim, ako paZljivije pogledamo
n
. j!ttkgijp ':l.~istiMatricu, vidjeCem.o da ona' ne radi nista u slueaju da polje Eiernenti u matrici sadrZi

12
a
OJ
..::1

re~-
nul-pokazivac. Kako smo na poeetku polja Element i u sve tri matrice inicijalizirali na nulu, one
[} matrice _koje nisu ni stvorene i dalje 6e imati ovo nul-pokazivac u ovom polju, taka da funkcija
0.(-1
UnistiM atricu neee nad njima nista ni uraditi. Da nismo prethodno izvrilili inicijaliza
ciju polja f
Element i na nul-pokazivac, mogli bi nastati veliki problemi ukoliko funkciji UnistiM
atricu P
[} proslijedimo matricu koja nije ni stvorena (tj. za cije elemente iiije alociran prostor). Nairne, pokazivac
Element i bi imao neku slucajnu vrijednost (jer sve neinicijalizirane promjeuljive imaju
~
slucljjne r~
"· g~ "' .
[}
vrijednosti), .
m na
.
Je
•• :f
,
~i ....
posve vodi nieemu dobrom). OCiglednoje da problem
nastaje zbog cinjenice unutar na poeetku imaju
[}
~·!:!
nedefinirane vrijednosti. usKoJcu
rijeiliti kreiranjem StrUktUrnih tipova cija se
~moZe ovaj problem ! !! !
- bez da
L,;w),J4

-~ ~,,,
k~e
Ovom prilikom je neophpdno ukazati
·

[f ~- f·l
Matrica A, B;.
[} A = KreirajM atricu (10,

. "
B = A;
A.Eleme nti [5] [5] = 13;
B.Eleme nti[5] [5] = 18;
[1 cout << A.Eleme nti[5] [5];
\ '

Or
I '

~
~
,
,

~
Cinjenica da "-*:jOO,Ite:.·u_drugu kopiraju samo
}: pokazivaCi, a ne i oito na oni pokazuju n8Ziva . nazivamo plitkjm /.J':Jea-
.J . kanjiapw. Plitko kopiranje obieno ne pravi neke . sve dok imamo u "'f'-'·''l!C
""'vidu Cinjenicu da dobijamo plitke kopije), ali djelluje poimanju kako bi
J. dodjeljivanje trebalo da radi. Vj!i_e¢em.·
.. o da se i oVaj
operatora tako da se operatoru(,;.::)P,r&mijeni ~je_ ·
nego i dinamiCkih elemenata na koje pokazivaCi p(ikazuju
I "
Citatelj se sada moZe zapitati zbog eega stalno navodimo prltujere r~:probematiCnih situacija uz
napomenu da 6e problem biti rijeilen kasnije,.umje%io da odm'ah p&nudimo rjeilenje u kojem se navedeni
problem ne javlja. Razlog za ovo je. SljedeCi; j8ko je tclko shvlltiti zbog &.lga neSto treba riuliti on8ko
kako bi se trebalo Plditi ukoliko se prethodno, __ne shvati sta bi 8e desilo kada bi se radilo drugaCije,
odnosno ako bi se radilo onaka kako se ne trebaradit i. Takoder, prilieno je teilko shvatiti razloge za
upotrebu nekih naprednijih teluiika kqji na prV:i pogled djeluju komplicirano (kao Sto su konstruktori,
destruktori, preoptereeeuje operatora itd.) ukolik<i prethodno ne ·shvatimo do kakvi se problemi javljaju
ukoliko se ove tehnike ne koriste. ··

13
'If
J
1
1
1J
]
~-

]
]
]
]
]
ill
ID

ID
1fJ
ID
10
1D
n L..

0[
0[ KLASE I OBJEKNO O
RIJENTIRANI P R IS T U
P

no
U ranijirn poglavljirna
sm o razmotrili strukture
mo gu cuvati citavu sku koje .'pred:stavljaju slo ren
pinu raznovrsnih podatak e tip ov e po da tak a koje
a, od neki mo gu biti ponovo
strukturoog tipa.

ct
[f1.1-•

st ru ct Da tum {
~nt Da n, Mjes~c
} ;
, Go din a;
?f.t
. ·..

Po lja Dan, Mj es ec i Go
din a oCigledn~ su namijen
·"
stvarni datum. Medutim jena da cuvaju dan, injese<
, kako sii ov a po ija pra ; i go din u koji tvo re neki
spr~va da na pis em kticnno obient;,cjelobroj
o ne~o p6 pu t ne promjeniji ve, ·ni~ na
[I
\:-h" Da tum D;
·.., ...._~ · s ne

D. Da n·= 35 ;

rr ,,.
D. M jes ec = 14 ;
D. Go din a = 20 04 ; 3.:~···
.. be z ob zir a Sto je datum
[J D. Go din a pona8aju kao
35 . 14. 2004.
obicne cje:lollro;ine
:~la.Medutim, kako se D. Dan,
da D. M jes ec i
'" . ' nikakav

(t
Razm.ot o. jos jed an
mo gu cn ost i rirn pri mj er koji il~~~=j~
~ manipulacije sa nje
st ru ct St ud en t {
nirn po lji tpa .
~ {~1f)t~ ·._ · .,.
;m.~~~~J$~r;~iiu:~zb
og preslobodne ·
Ch ar Ime [3 0) , Prezi~ :.:'~·;: ·
e [30 ] ?;. · ) '
]
t,

in t rn de ks ; \i~~ · .---lj~,
in t oc 3€ me [5 0] ;
do ub le Pr os je k;
].
'
. ;.·-
};

QC,igledno je da bi po lje oii


Pr os je k trebalo da bu de . ··..
• k& :va aa sv e oc en e ne "vezan9:" za po lje oc Je ne·.- - .
ko g studenta postavimo . N):edutim, niSta na s ne
eli sU Jiotpuno npr. na 6,· .~ prosjek na 10
se
. odvojena jed na 0 a
og, ne . ~esD.o poveiait~
.. . '
.
.
om po ne nte
. OViijiolja pona8aju ka
Jem ie cjelilie.
o
.
,· . Jed na od mogucnost
i kojirna mo ?e mo djelim
furik~ije ko je Ce pristt icno rijeSiti ova] pro ble m
je da definiramo izvjesne
ipati po ljim a strukture
. ·sti tik t& om koristimo lsk na . strogo kontr()liran !IJICin
.ljiWi:vo naptsane furikcije , a da. Zatim pn raa u sa
:fulikc'ljU: Po sta vi ba tu m ko ja za j>ristup poljima. Na prim.jer
bi {iostavljam po lja Dai>, , mo gli bis mo postav.iti
' piforl.osikao prv i pa ram M jes ec i Go din a unuta
eta r u funkciju na vrijed r st:nJktUr.e ko jas e
tonie, bi funkcija mo gla nosti zaclane .<!mgiy,l, tre
provjeriti ·smislenost para! eirn i Cetvrtirn .ParainetrO
odgovam.juCi (npr, baciti lletara i pi-eduiefi nek:u m. Pri
izuzetak). Na prinyer, tak akciju u slu caj u da on i
godiD.a prestupna izv ed en aje va fun kc ija bi mogla izg!ed nis u
u skladu sa gregorijanskiiil ati ovako (pr ov jer a da li
kalenda rom): je
'

1
J[
][
void PostaviDatum(Datum &D, int Dan, int Mjesec, int Godina)
' int BrojDana[12] {31, 28, ·31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
if (Godina % 4 = 0 && Godina % 100 != 0 I I Godina % 400 == 0)
BrojDana[1] = 29;
][
if(Godina < 1 II Mjesec < 1 II Mjesec > 12 II Dan < 1
II~ BrojDana [Mjesec - 1])
~ "Neispravan datum! \n";
U[
D.Dan = Dan; D.Mjesec = Mjesec; D.Goctina = Godina;

Napisanu funkci)u Posta viDa tum moremo korikti 2:a PostavW 'da~a na konzistentan nacin
][
(<J!lkle, sva polja. odjedanjput), uz provjeru legalnosti. "Tako ee, u naredndm prirujern, prva postavka
proci bez problema, dok ee druga baciti izuzetak: '" ][
Datum Dl, D2; ·t~.:''
PostaviDatum(D1, 14, 5, 2004};
PostaviDatum(D2, 35, 14, 2004);
·~.
JI
Medutim, ovim je problem sarno djelomiffio rije8en, Nas nista ne prisilJ!lva da morarno koristiti funkci'u
PostaviDatum. JM uvt ek ·e moguee direktno ristn ati poliima·, .· · . e Datum i tako u nju uni'eti ]
, nekonzistentan sadrzaj. Problem je Sto je funkcija PostaviDa:t,.:·p\?tpUjl,?. g VOJena od strukture
Datum, ne predstavlja njen dio, i nicim ne riameee njeno kori,Stenje. . . : #'" ·

Citalac se prirodno more zapitati
/ · ·

moralo biti izametano sta mozemo raditi a sta


J
ne, odnosno zaSto se ne bismo jeelnostavtic IW.scip;line i pru;tupali elementima strukture na
propisani nacin. Problem je u tome sto Je••.~:ct
jedan u slorenim ·
~:;cij>lirte u manjim ·· · koje razvija
J
1
l
l
I(
~
m

2
nl. . ····- .... --,""'"

n: ,._
ovdje stavlja srediste pa.Znje na ope
n~ daje kao rezultat 8. Medutim,
raciju sabiranja ( +) kojoj se kao arg
wnenti salju podaci 5 i 3, i koj a
l \_..
. podatkom 5 primjenjuje akcija 3
novi podatak 8. ~e moze se re6i da
sa aspekta objektr)o orijentirane
+
(koju moZem.o twnaCi.ti kao "povee
-filo zofije, u ovom slueaju se nad
aj se za 3 ·~ koja ga transformira

ft je jedna od ove dviie filozofije (pro u·


ispravna a da je druga neispravn ceduralna i objektno orijentirana)
a PRJ,e '!'! js~.fu,§MJQ jmaP¥a
, , pokiiZala
1 aa
se za potrebe razvoja slozenijili pro
gra ma objektn o
ziicita, gle!lj:ill' Medutim, pra ksa
je
IJ' efikasnijom, produktivnijom orij entirana filozofija pokazala znatno

ct , i otpomijom ~greSk<: \l.razvoju


...-- .., . -.'-
-:.
pro gra ma

CD
[t
. ·.··

GJ
(t
{l
[t
fJ
u Datum D1, D2;
>·-
D1 .Po sta vi (14 , 5, 200 4\·;
D2 .Po sta vi (35 , 14, 200 4); .,..
a Nemojte misliti daj e ovim izvrSen
koristili ( obicnu) -~c!.~u P~.stavi
treb da u u D.~. tum ..
. D··. o.· .P.ro_. ~jen
rom enu naCiua raznusl an Fun sin.--~.·e.z e u_
:~<~ -~- :~:
a samq promjena sintak,se u o.duosu

·.staru
..
na raniji pri mje ru koj em sm o
..
lo,, ~¢uti!n ta promjet!a
rr..t • 0 je!p ~1 j o2;o_ok se
~cij .·. Po sta v, rti~{e~/ujg nJ!d
cki;t ~e . d.oS
kao argument sah u
nam kon st donos1 ta promJena nac .gpj~ktim_a Dl_i !';~fpbrzo Cem O
ma raznuHJanJa shvatiti kak vu
·· . ·. ;·:,

l Razmotrimo sad aka ko bi setreba

,
mo gla bi, na primjer, izgledati ova
. ko:
lainiplementirati funkiija cl_anica•
Posta.;,i. Njena implementacija

l"' vo id Datum:": Po sta vi (in t D,


in t Bro jDa na[ 12] ~ {31 , '28
if( G % 4 ·-- b && G %
in t M, int · G) (
, 31, 30, 31 1 30, '31 , 31,
,:;lo; 31, 30, 31} ;
100 != 6 .II G %. 400 L 0)
_BrojDana [1] = 29 ;.
1 if( G < 1 II D < 1· II
/ <§"hro0 "N eis pra van dat
• Dan = D;_ Mjes~c =
· i
.M < 1 II M > 12. 11 p;: >-B
um !\n ";
··
roj Da na[ M- 1])
M; Go din a =. G;

1
,,
}

I
3
J[
. Ov~l'e moZeJ:no.~oCitl n:kolilm detal'a ko'i odudara' od impl~entaci'~ klasiCn:ih ~ci'a.~
1spred rmena funkcue nalaz1 se dodatak Dat1111!: : . Ova konstrukcua ukazi!Je da se ne radi o obtCiioL
funkciJi, nego o funkciji clanici klase Datum. a taJ IiaCin je omogueeno da mogu postojati obiena J[
funkcija i funkci'a clanica isto inien kao ida vise razlicitih klasa ima'u funkci'e clanice istih imena.
Znak : : " (dupla dvotaCka) taicoder ·spada u operatore, i obieno se naziv operator razlucivostt, · ' I
'
N_. . . . [

vidokruga ill dosega (engl. scope operator). Tipieno se koristi u obliku klasa: :'idenll to i ozna va "..,j .'

d~ S:. i~entifikator identifikator. ?cin_,osi. na a?ibut odn?sn~ ..~et~u. koJa pnpada klasi _klasa~
pnnnJetimo da se unutar funkct e clamce direktuo pnstupa atnbutima Dan, Mjesec 1 God~
navoaenja na koji Sf3 konkretni objekat oYi atributi_ o sada nije bilo moguee. Ovakvu .
l[
~-

.. direktuom . atributima klase . .clanice te klase. Ovo je


se
][
'
nad nekim konkretnim obj1:ktQJm
funkcije clanice iste klase, a lrn'ii ,<,.,,n rn~oJro
unutar clanice .
J[
][
/
0[
[]j
koji se ita [JfJ
Dan )i:>l<Jga smo fuukciju clamcu Postavi sasvim
legalno mogli napisati i ovako: ---~~ ,,
]
..
~:1i.~- ~~:;- :,. ·..
void Datum: :Postav i (int D, int M•,';i1~1rt""G) ... { .. ,·
int Bro]Dan a[12] {31, 28, 31; S!l, 3'f··, 30, 31, 31, 30, 31, 30, 31};
if(G % 4 == o && G % 100 !=--·t':.:ll G % 400 == 0)
BrojDan a[1] = 29; > ., ·-•··
if(G < 1 II D < 1 II.M < 1 1'1-M > 12."11 D > BrojDan a[M- 1])
]
:~tfl~-~-"NeisPraVan datumt\n ";

, (*-~.Dan = D;
.
(*this)_ .Mjesec = M; (*this) .Godina = G;

Ovo zaprav~ zn~i da se $Yal<afunkcija c!anjca interno inter:pretira kao obicna funk~ija koja ima
/!/
pokazivac_ this kao skriveni"plif.i'hietar. Stoga se metoda ·Posta vi intemo pona5a kao obiena funkcija
(nazovimo je Postavi _Obitri~)"ksljedecint protoiponi:
.
]
]
void Postavi_ Obicl1! {Datum *this, int D, ·int M, :i,nt G) 7'·
----- ---
]J
dok se njen poziv nad objektoni D1 interpretira kao
~stavi Obicna (&D1, 14, 5, 2004); ·· . ]
·Iv.i:aila ovakva interprctacija·more pomoCi onome ko se prvi pUt susreee sa objektno orijentiranim ·
prlstupo¢ iJa shv!!ti.~ 8e zai~:il~~aya, o njoj ne treba previ8e misliti, s obzirom da odvraea progra'ipei'a ]
od objeidno orijefttiranog-iliZmisijanja i okreee ga nazad ka procedur~om razmiSijanju, ·ti. ·po8matran:ju
funkcijakao cjelina posye Odvojenih od objekata na koje se one primjenjuju.
]
]
4
....
n-
- L...

ft
- ;...,.

Treba napomenuti da se u jez iku


n~ !tJko
C++ izuzetno eesto susreee 'eii
JC ·:l;li nju uvedena posebna i pre Cka.konstrukci'a oblika
~
glednija sintaksa obi ika x- >i '
4-:: tl
· mo!iemo pisati tlli s-> Da n. Mo Stog!l, umjesto ( *thi~
Zem.o reCi da se u jez iku C++
klase upotrijebinio samosta~no k god unutar funkcije glamce nek
e
ime nekog i!J!ibut.a te li:lase (vid
ft podrazumijeva da ispred navede
nog atributa {metode) pi8e thi s->
jeeemo c1a to isto vrijedi i za me
.
tod e) I

[f
ct
(f.
[
(t
rr
~ 1-•
primjer, funkciju -

[J[ ~~~~~~~~~~[;~~~~~~~~
if( Go din a % 4 == 0. && ~~~~~~30, 31 , 30, 31 );

0[
,
Go din a % 100 >!F 0 II
Br ojD ana [1] = 29; Go din a % 400 == 0)
if (Go din a < 1 I I Dan <
1 II Mj~eiiec:"- < .·1 II Mj
II Dan > Bro jDa na [M jes ese c > 12

a
ec - :n,J:-:f
- thr ow ·"N eis pra van datum~
.

thi s-> Da n = Da n; t~is->


•• \
n'·t""''; ~-. -~
J
..
Mjesec = '_!4j~es'ec;- thi
s-> Go din a = Go din a;

a Drugi naein, koji se eesee kor


Da tum : :Da n, eksplicitno nag
metodu Po st'a vi mogli napisat
isti, je upotreba operatora razl
la§avamo d8 nuSlilrio na atribut
Da
i ina sljedeei naCin, U koJem izb
uCivo~Tl!!co, ukoliko napi001llo
n ICojl~ klasi Dat um . Sto
jegavamo upotrebu pokazivaea
ga smo

1 vo id Da tum : :Po sta vi


in t Bro jDa na[ 12J
if (G odi na % 4 == 0 &&
(in t Da n, int - Mj ese c,
(31 , 28, 31, 30, 31, :3o
ln t Go din a) '(
, 31 , · 3'1 , ':Jo, 31 , 30,
thi s:

Go din a % 100 != 0 II 31} ;


] Br ojD ana [1] = 2-9;
if( Go din a < 1 II Da n <
1 II Mj ese c < 1 II Mj
Go din a % 400 = 0)

I 1 Da n> Br ojD an a[M jes ese c > 12


9 ec- 1])
thr ow "N eis pra van dat um
1 , Da tum : :Da n = Da n; Da tum
! \n" ;
: :M jes ec = Mj ese c; Da tum
: :Go din a Go din a;

1
1
I
5
-'[
;w

·:[
.,.,
pozove neku drugu funkciju
ili metodu nazva.n#:lfek; ,FlinCkijaKoj aPri!RaDat4.z n:KaoParamet ar koja kao parametar prima •
I -

objekat tipa Datwn,.(kojq j*potrebno kao stvm:rij:parametar preniieti objekat nad kojim je metoda
NekaMetoda pozvaz\a. t~ i)litnp!ementacij~meto~<;NekaMetoda mogla izgledati ovako:
. . . ' -~· ..
][
A'
][
I
L.' l
]
]
]
struct Datum { ·
. private:
·;:
]]
~-
int Dan, Mj esec,· Godina; . ·
public:
void Postavi(int D, ·int M; i;f~~i!;
! .
]]
}; . . -~. .......

- Na taj. nacin smo atri~ute Dan, Mj ~~:e'<; i :Godin~ ~~oglasili privamim, .dok smo metodu Post~vi -·
proglasili javnom~ . . ..b . • imetodam ·:mo!fu Se pl"i$J>iti Sarno lzt(ela fimkci'a clani I
lJ
(metoda2 te iste kl e liZ tzvf:iii;ljpie{js{!:fli•piikiliiz /dqse k<.ije ·. () r3Zmotriti RJ&o kasriije. Bilo k3icav •
pri$lp privatnim metodama iilf!ibutima iz ~~tjilih -~jelova progr3Jna je zabranjen i dovodi do prija've _
gre~e od strane kompajlera Zbog toga naredbe j>Opu_t sljedeeihpostilju zi:lbranjene:
l1
Dl.Dan = 20;
001it << Dl. Dan; ~
Primijetimo <Ia ·e ovim ~stalo zabranjeno ne samo .direktno mi'
. Cak -~ citati njegovu vrij _os( IJivatru attjJmti 0
ninkcijeelani ce klase i pnjatelj~e fuilkcije Klase p
VnO ne OSlO osfatak progiari:ul, OSun za
n ovaJ nacin SlllO. klasu :U~1Jili po~no
D
I .:a!:f!::d=)~,~~=k~: ~i:~a;!:o:~~~~~-t bb}tlfu~i~~dt~~~: 0
D
• njima! izlaz iz ovog probiert;ij~posve
jednostaVJIIl: treba~ioJ-fuetadn
u obiekat fiiiJt ce'rQdifi ·
nesto korisno sa objektom. };fa primjer, mogjleeje 4o0ati lilet!>d\i''i:'sp{si koja ispisuje datUin iul ekrail.
Stoga cemo prormjeniti deklaracijll klase Dafunl da iZgieda Ovak&·* -··
. - ~. . ..
· · D
6
n
rr ~,,.
str uct Dat um (
( pri vat e:
I irit Dan , Mje sec ,····G odin a;
.pu blic : ·
)

.... ...
_


ft
"'-•"'
:·'
(
\_

};
voi d Pos tav i (in t D, int
voi d Isp isi ·o;
M, int G);


[]....,. N aravno, met odu I sp is i je potrebno ':;.•.,
i implementirati, sto je po8Ve jednostavno
:
:--·
voi d Dat~-, : rsp isi ( J ( · . .
'-• . •• .o-~,:.
cou t <<D an< < "." -<< MjeS
Ct } ·
e.c::: ... -<<··-~'-··-" ~< Gqd ina;
· -_ ,. ':\' _, -,: -~ •. · . ~,::~;afr:~ ., : ' ·
Sada vee sa objektima tipa Datum moz1
1¢.~;:fa&ti fl~je.~: m~p-~.postavljati
[t ispisivati ih. Sto gaje legalno napisati slij
eqeg!i·~~r.~ncu nm:&lbi: . · . '. /;1} sadriaj i

[t 5~~~~~:~~J!!~e~' j!~!~~ '"~: -•"\ •~- ; 4· . ;~~4J.WJ''


( D.I spi si( );. .. ·. ,./ }*4~-.-"·.·,,,ff!r,·;
OI Primijetimo da smo na ovaj naein oStr
postavka, ispi si 1]i8ta drUgo. · ··
o o~anicili ~ ..... ~·· . ..,
·
_instancama te klase. Priii.cip
atnb un klas e definiraju iskljucivo se sv1 /
OI iln!trilmtima trebao da 5e ~i prek o,.

~ t funk~ ci :~a~·~cliaru~-~-ca.~ O~v~l\i~p~·rm~·~c~ip~n~a~zi~v~at~~~§~,~~~~r~~rrrrr:~ cini Nata]


ostv arcn ajcs trog a kontrola nad.·

~
prvi (od uku . 0
, ~m~~
hiding). naein
(engl. encapsulation)

a j:~::~i~~~Jt~ ~~~=~k~~j!~~:~. ~:~:.primjenjivati nad


tim

u
Q
a
a ~ ·
cla ss Datum {
int Dan , Mj ese r., GO dina i
· Pnb .lic :

l
voi d Pos tav i(in t D, int M, int
G) ;
voi d Isp isi (); .....- ,_._

a
·-.:
};
:~~

a
J
•••
]
7
1
J[
]
class Datum {
·int Dan, Mjesec,·· Godina;
public:
void Postavi {int D, int M,. int G) ;
]
I void Ocitaj (int &D, int &M, int &G);
};
void Ispisi () ;
]
rinp!ementacija metode Oci taj je veoma jednostanva:

void Datum: :Ooitaj (int &D, int &M, int &G)


D - Dan; M = Mjesec-; G = Godina;-·;:: - -· :"
n
}

Sada bismo mogli napisati pr~Jiramski isjecak poput slj~e<\eg:


; .-
li
Datum Dat;
·•.;;-.,·,~·..-•\:... -f1,_.-:
;;.·:,
Dat. Posta vi (30',\:ip, 2002);
int Dari, Mj, GOdi -1- .~,.
.. ~
.
,;
-~_.- ....,
li
~
·
' ;
Dat.Ocita j(Dan, Mj, God)';
cout << "Dan = " << Daf', ~tt . ;~~Ts~c _:;ic " << Mj << "Godina = " << God;
. Mogu6e je napisati, jos .fl~i~iltrij~ ~:je~nje:. Nairne, ~o malo razmislimo, vi1j¢~~o. ~ n~a
nikakve stete od mogucnosti C1tanJa atribyta Dan, Mj eo;ec.: 1 Godina, dok mogucnost llli]enJanJa ovih
atributa b.ez koritrole ilije poZeljna (u¥o~imilpo da ie sasVim mogti6e zamisliti situacije u kojima nije
[
P?ie!j~~ ni Citati ~jeSn.e_ atribute ~a8ii), 9;i~ahJ; ?'Vilt; ~~buta ~ozemo omogu6iti tako sto ~emo dodati
tri triV1)alne funkct)e clamce Vra hDan, '$tmtiMJ esec 1 Vra t1Godinu bez parametara, koje ce prosto .
vraCati kao rezultat vrij'ednosti atributa Daii;:lil:je.se.c.: i Godina:· ·.
1[
· •·
-, class. Datum { .
·int Dan, Mjesec, Godina;
::Of ·..•.
--~:'~-
.
-m
public:

~
) void Posta vi (int ·~'{. int M, . fn't:jl;
. void Ocitaj (int '&D; int &M; int~'&G);
int VratiDan (); ' ·):

int VratiMjes ec ( i;

~
.:.
int Vrati.Godi nu (); ·
( · ; void Ispisi 0;
1

int Datum: :Vratiban () .{


n
}
return Dan;
~
int Datum::V ratiMjesec ()
~eturn MjeS~c;
D
int DatJlm · · VratiGodi nu ()

}
return Godina;
n
Sada moZeillo pisati i ovakve pro;m.unske isjeeke: _:

Datum D;.
. ~. u
D.Postavi (~0, 12, 2002); . . ·. . . .
.cotit ·<< "Dan . • << D. VratiDan () << " Mj~esec. = ,; << D. VratiMjes ec ()
<<"Godi na=" <<.D.Vra tiGodinu( ); D
8
·, n
OJ.
rt
ct
Na ovaj naCin omogucili smo
Citanje atributa Dan, Mj ese c
po mo cu pristupnih funkcija i Go din a, dodu5e ne posve dir
Clauica Vr ati Da n, Vr ati Mj ektno, vee
susreeu sa objektuo orijeutira ese c i Vr ati Go din u. On
nim pristupom ova indirekci im a koj.Lse prv i pu t
Medutim, dugoroeno gledan ja djeluje kao nepotrebna

·rt kontrolom projektanta klase.


·po d izvjesrum ukolnostima
bacanjem izuzetka). U praksi
o ov aj pristup donosi mnoge
Na primjer, funkcije za pristu
~1ate !ainu vrijednost atr
ibuta
koristi, jer je pona.Sanje kla
p pojediliim atnbutuna mogu
ili cak da odbiju da vrate vri
komplikacija.
se po d pu no m .
se nap1sati da h
se cesto jav lja ju situacije gdj jednost (np r.'
It Mnogi programeri imaju odb
smatraju da je potrebno
ojnost ka definiranju trivijal
e ovakvo pona.Sanje mo re da
im a smisla.
nili metoda poput v'r ati Mj

,svalm ese c itd. jer


[][ Da bis e·· · · kako deklarirati, tako i

~a
tum
2
'~
lve metope. osi m me tod e Po
[)[ · dekfaracije (u tom slueaju,
· kompletua):
me tod a Po sta vi se· sta vi odmah na mjestu nji
mo ra implementirati negdje;
' ·
hove
dJitgdje da bi k!asa bila
'·'
cla ss Da tum (

DI · in t Da n, Mj ese c-, Go
pu bl ic:
vo id Po sta vi {in t· D,
din a;
... , l! ,_ ,, '·
in t M, in ·f G}-; ~· ..-~.
'i~­
[][ vo id cic ita j (in t &D,.
D =D an ;" M· =:M jes
'in t. &M, in t &G) ( ,,
ec ;. G· = Go din a;
'
) . ..
in t Vr ati Da n'( ) ( re tu
rn Da n; )
Q[ in t Vr ati Mj ese c() · (
..
re tu rn Go din a; _J A.~>_•_~,:_:_:_--.-
1
in t Vr ati Go din u() ( re tu rn Mj ese C;
vo id Is pi si () i .
co ut << Dan << ri
· ' '•
Ol J;
)
II << M] ·es ec <<; ~-' .• r <<
Go din a << If II,·
. '

Ipak, VaZnO je napomemi~ da


rn odnlah pri deklaraciji) ili ii\i
pro gra m se na mjestopozurl
ni'e. sve'edno da li se
iin'deklaraciie klase. U · IT,oni
tcida im Ienientira .unutar dekl
'slueaJU, p _·om sv ·og -po
ac_qr~i'e J
(tj.
l;pro~to umecu sve nar ziv a metode u •
eqb e _(Jd kojih se metoda sastoji
] slueaju sve naredbe cid )f6jill'
po iiv a -ka o potprograil'!· 'fci
~~fii:efcicta l;astojlCl!v.Uu npj~lj
;~\i94t je neZ17fJ(rio' b~(:ta dru
, dok se u drugom
npm 11J.iestu u memoriji, dok se
sama metoda
potp~<)grama i po:yta'tiik~-Pi gog, jer se ne troSi vrijem
i~(igrijma, ali 'trosi Y!~ii if!~ e na poziv
me tod a sitStoji milltiplicira U'j i}j4rij~ jei' se citava sku p$l l,ll
] Ra zli ka u zauzecu niernorije
pra:ktieno pravilo: nietode Icc>
:irografuu orio!iko pu ta k.oiiko
postaje \ZiaZI!jna tek ttkoliko
je pu ta ta mc;ioda upotrijebljen
metoda' s!,idrZi vi&e 'harjWbi.
lre dbi od ko jih se
a u programu.
' .· 'sa sto 'e od svega joo,lle iii d:v
i'e nar'OO_ e (eventualno, do tri
Stoga vrijedi

] I treba implemenl'frati odmah.


sam o o minidbainadodjeljiyan
• deklaraciie klase _(ovo pog
uyutar 4eklarflfii.!!_ Ktdsec mo7.e
ja), cirlle dobijamODaJ)liini.
se toleriran i·-vi.Se naredbi, uk
Sv e ost ile inetode tr~ba imple
naredbe)
oli ko se radi
otovo vrijedi za metode koj melitiratiizvan
kOnstrukcije). e sadrZe petlje i druge si~i
· · ·_· - · · Qgiiill.Sl{e
1 Iz navedenih primjera nioze se
primijetiti da se sve metode
. .·- . _

kategorija me tod a samo cita JPOgu podijeliti u dvije katego


jii !ifribute klase, ali ih ne -ml rije. Jed na
I me tod e Oc ita j, Vr ati Da n,
. @Sr~~o7j} Druga vrsta m~oda, ,~
vr ati M jes ec , Vr ati GJ d'i
Sto je meto~ P~s~av
ienjaju,;_ Ta kve su, u prethodno
nu i Isp isi . Takve me
m p~jeru,
tod e nazivajil se
_naZJ.vajU se(jjzutatori)U Jez i, mJJf.en1/:,U atd.but~ kla se nad k_o~# su
pnmljeDJene. Takve fim!<:cue
· oznaCiti ~cijeaJ!!tJl ikn C'B $l SID3;;:;; dobrom pra
? liljtienom rijeci co ns t, ko ksom wse'!Jno
defiDii'll pop!S p ·. _. ____ . .. met()de. jas e navodi nakon z_atvore
Od ovakvog ozri;ICavanja im ne zagrade _Iwj_a
om ogu eav a komj>ajleru _prijav a dvije k9 ris ti. C8 ; nli
ilgreSke u slueaju da Jim•tai
me e za ko ju koni.:eptualn lafili!Cin
.da bu de inspektor poku~amo
cs ne t mo gue e je .defin
da promijeuim9 vrijedn.Qsiliekogtod od atribu~,;pomocu
o zrun.n,o, ~ ~ejja/
irati konstaniiieo1Jiekte, na kljtic1Jtl rijem •
takvim koristantnim objek:i:im isti nacin. kao i np r cjelob
a moguee je pozivati saino roj ne kon stl!nte. _Nad
metode inspektore, a ne i me
tode mutatore.

9
Jl
]!
Tada korilpajler iskljucivo na osnovu postojanja odnosno nepostojanja kljuene rijeei canst u deklaraciji
nielode zakljucuje da lise radio inspekti>ru iii mulaloru. S!oga bismo deklaraciju klase Datum moglijo§
bolje izvesti ovako: ][
class Datum
int Dans Mjesec, Godina;
public:
][
void Posta vi (int D, int..._,.M,
..iint-· G);·

]
,
void Slj edeci () ; .. ··"'..
void Ocitaj (int &D, int·'~,. -:tnt &G) .canst
·o = Dan; M = Mjesec; G ~ ·GodiP~.{

int Vratilian () cons!; { return ·rl,an'i\L :··


int VratiMjesec O canst { returil 'M-]·e;,i';.c;
<
:[
·'·'---·.. ..,... ... -~ __ ,

int VratiGodinu () canst { reb.ii:n.·Go'd'l :iia;

:[
Y..._- :•'"'-~ ~
void ·Ispisi (J·i:const-{ ~-: . :.

)
Cout << nan·.!_<< II " << Mjesect:<<"' n'. _tf << GOdina << n
.' " •

);

Ovom
Jt
na
~
~
void Datn1JI' ·Sljedeci(L
--int BrojDana[12 l = 3,1, 30,· 3·1, 3~,- ~0,. 31, 30; 3l:);
if(Godina% 4 . . ··. !;,;-·,q. -I i. Goilina % 400 ,;;= 0)
,-
Bro'i Dana [ 1] = 29,; ·
Dan++;
if(Dan > BrojDana M<~-~~c
Dan = 1; Mjesec++r.
m
' --".~+-
}
if (Mj esec > 12). {;;_
Mjese·c ·=., l.i GOdina++;:;
-~:,,__· ·~:f: <'
·.'ft..
m
T:,.::- _.:: . ~
}

· Naein njene upotnibe lllislrifaslj<'lie


...·_ ·.-

o~ipriinjer:.
; m
'._ .

DatUm D;
o;Postavi(3 1;
JD
D. S1j edeci () ;
D.Ispisi();
u
u
Klilso Datum mo7.eino profuiti. $1ij6~·dvije.karisti.e inetode. Dodaeemo metodu VJCatiimeMj eseca
u
· koja -vrnca·- pilin naziv nije~a ·pahr~JJ#,og_u wrtllinu (pri:clznije, pokazivac na prvi ·p!lik_JUIZiya). kao i
• • • • • ., -- -

ni~~ I~P~;>iLijepo ~P~-~ifije .~.f.l t~~o _1SJiis~ _nazivom mj~i:il UIDJesto.


~ • - •0 • -·

broJcanog tsptsa.. Obemet<><Ie. su naravno nispetabn, a unplementirae emo ih IZVan deklaractJe ki~®:
_.-., - • ' • ' • • • .., - - • • • • ' • • • • • • • • •• • - • • - '• - --.. ' ••

D
D
10 n
. '
l'h
n
nc ·cl ass Datum {
nr••- int Dan , Mj_ esec , Go din a;
pu bli c:
voi d Po sta vi( int D, int M,

rt voi d Slj ed eci ();


voi d Oc ita j(i nt &D, int &M,
)
D = Dan ; M
int G);

int .&G ) can st


= Mj ese c; G = Go din a;

[t int Vra tiD an ( J con st ( ret urn


int Vra tiM jes ec () can st { .:1:- Dan; ) ·
1 --c ha r *Vi a til;meMj ese ca () cpn eturn Mj ese cl
si:; · · . .
[t int Vra tiG odi nu () con st { -i:,e
voi d Isp isi () con st {
cou t << Dan << ". " <<
t1l:Pl! ..
··.·~. :<~:··s ·
'Go din a;
MJ·_ese_c ~< " " << Go
) din a << " ".
[t
··,h
-vo id Isp isi Lij epo () con st; :~~i:.· .
0 '

);
•.·

[t Iinplementacija metoda Vratiim~jese


cha r
~ai.Is
. ·. .
pij'Li.
.-c.'

rr "M art ", "A pri l",

'
"O kto bar "
/
{][
" << Go din a <<
[][
II II •
0 ,

u
a
a . $ad a smo vee dobili pristojno wn
OcigJedno, sk:up akcija koje klasa
obiljbilenoin klju eno mty ecj upu blic
ieJ
poo:lrZliVa· de;fin:ifiiiie
. Stoga se opiis jav ttog
a (engl. class inteiface).

Primijetimo da je u objektno orijenti


rl!lloin pr~!gr!\\Wr8J1j1J~rii.ogu(1e J~~p~f
klase Od ki>risnika k/ase (pri tinJ. O
a inteovo
got (g. da
rfejsnika 5tanisu
sa njo
Sk•·~-nhlazvoju ~l():ZellijilJiA>!:(ig!~

::~~~~~~~!~!~~~~;~~~!~~:~~""
mo u "'<>'u"
istamosa
iqiirdj,~int

klasa mogbi bi se koristiti ba).


] "fako, razVijenu klasu Datum bismo
. ·~o sa: datumima, bez ikakve pot
u mnostvu . . . prg,. grruri~
mogli k<iristiti ·
rebe da uopee
.pr;incip paZivanio prin cip pon ovn e
] · adUta objektrio orijentiranog programiranja

. Interes:m~o napom~~ .da smo mi


dO ~ na ~- mjesta o~J.. ~riJicip
) Naunc, obJckti ulaznog 1 izlaznog toka
Dlligiene naredbe, vee obiene prinnjen
ciT\ 1 cou t koJC smo.konstili Odsamo
ljive!'
koristili posve !eW:Jesno.
g poCctka rusu nikakvc
inStariea klase 1~ Lrean~ aco uL kao inst Precizirije, c.in j~ u zaglavlju ios tre am deklarirana kao
anca klase u~Lream. Klasa .i~ Lr·.;,a.u
l 11
defiuira skup atributa i
_jl
][
metoda za pristupanje ulamom toku (tipieno tastaturi), {ok klasa ostream definira sirup atributa i
metoda za pristupanje izlamom toku (tipicno ekranu). Na primjer, jedna od metoda klasedistre.am je
metoda getline, dok je jedna od metoda ldase a stream metoda width. OVo ·obJasnJava upotrebu
](
sintaksi poput cin. getline (recenica, 50) ili cout. width (10). Vidimo da se ovdje zapravo radi
o pozivanju metoda getline odnosno width nad objektima cin odnosno cou): respektivno. Naravno,
ove metode negdje moraju biti implementirane (i jesu implementirane negdje unutar biblioteke ]f
iostream). Medutim, cinjenicaje da smo mi eve objekte od samog poCetka koristili ne znajuci kako su
uopce ove metode implementirane (niti je potrebno da znamo). Ovo i jeste osuovni cjlj: razdvojiti
intet:fojs klase ad njene implementacije. DoduSe, ostaje jgs jedna tajna vezane·za objekte cin 1 cout J[
koja ib na prvi pogled Cini iJOsebnim: magija operatora "«" i "»". Ova tajna ee se ~asniti u narednim
poglavljima, cime cemo vidjeti da dn i cout ni po Cern,¥ nisu posebniu odnosit na bile koji drugi
objekat! _' · _ __
][
Vee je reeeno da je dqbra praksa sve atribute drZat:i iskljucivo u privatnom dijelu klase. S druge
strane, metode su uglavnoni )ljavnom dijelu klase. Mo!le 5e postaviti pitanje ima li sil:risla definirati neku
\ od metoda kao privatnu metodu. Odgovor je potvrdan, ukoliko smatramo da 1113ka od metoaa mo!le biti
.J[
t od koristi da se poziva IZ neke druge metode, ali mr ielimo ·da dopustimo dQ se 'ta metoda poztva iz tt:-
ostatka programa. Na primjer, pretpostavimo da,¥o u prethodnom primjeru Jgase Datum inetodu
Vrati ImeMj eseca deklarirali u privatnom dijelu klase, kao u sljedeeoj deklaracijLj
0[
class Datum {
int_Dan, Mjesec, Godina;
J[
char *VratiimeMjese ca() const;
public:
void Postavi(int D, int·M, int G);
void Slj edeci () ; ·· .
JlJ
void Ocitaj (int &D, int &M, int &G) co~st
D = Dan; M = Mjes~c; G ~ Godina; ·
int VratiDan () const { retun( rian; )
~
int VratiMj esec () .::const { re~_fni"Mj eseo; . )
int VratiGodinu{i'..i const- ·{ retu\:-n''Godina; .)
void Ispisi () const { · . JD
cout << Dan << ". " << Mj·ese·c << " ,-,n · << Godina << " 11
;

);
void IspisiLijepo() canst;
··-J-.:;;.':\t
.:: _'j;\ J[]
U tom sluCaju, metodavr;;.t:d'itteMjesec~ bi se normalno mo@a pozivati iz nietode Ispl~iLijepo
(kao iiz rna koje dnige n:i,etoi!e kl!!se .batum), ali se ne bi mog!a pozivati ni odakle drugdje (za osiatak
~
programa ona praktieno ne b{ili po~o.la!a). ·
-~
Objektno orijentirani prisPtp razyoju demonstriraeemo na josjednoj _interesantnoj klasi koju Ceino
o
razviti: . e ostavimo da nam ·e. -.. trebnaJ4.a8aVekt6r ko"aee 'isivliti Vektor u,prostoru. Po~je

.-
dgbrog
,_,._,_. -· ·f_, ..
~
oiijentll-iiri9g
·.· - -.
-;.f:~v·.~:_.·
diw]na, OVi
z
daje sVaki prostorni velctordefin{ratlsa iii,k lirdiriate,x, y i kg}&'§¢ tij$!) !iiti iatn uti ov.:: klase,
sldadu. Sa. prinCipimit 9bje')fui6 -· :.:•-, _.-,, ·_
-~·-::-:,-..
·a:tri,~iiti ·i:e \iiii
... :·.-•;:.· ·." . . .. -
privatni
, .
(bez, ... ,..
obzira
.
u.
Sto u ~
ovom slueaju ima smisla po5taviti'bilo 'koji, iflljMina f?.ilo fdiju 'vrijl!@est), a uveS¢emo metode
~ostavi, oci taj, vrati. x:vra,t_i · .yJyj:-id;i' z icoje Sii iu:i;!!ii:lgne ~Il.FiiJ!Ji inqOclama klase Datum
(na ov:Y na¢1Ii onemogucav_~o da s~ koo!~ii!aJ~ye~ora: postavljaJu qdvojen~(j(j druge, vee simio sve tri
. sJruPa, sto je mnogo>sinisi#je). Pot\)(1 iog~~f!Y:e~~) nietodll: r~gis:i k()ja ispisuje vektor kao ·
ll
skupinu od tri koordinate uiu!tar yiticastib'~aclatazdvojerie .zareiima (npr. {3, 4,2!), metodu
Duzina kojavraca kOO reiriltat <:biku vektof';i; ·koo i :rrie«loo MrlOziSaSkalarom i Saber iS a koje
mnoze vektor Sa ~om (zad~i;;; kaq't~etm) p~o~o slibii-aJU Y~or'sa diiigun vektorom·
n
(takoder V.danim kao parmmitai).'J.Na tllj ~1:do~iliitA~ ~Med~ dei4;u-lil;iju J4ase, u kojoj su sve
metcide dovoljno jednostawe da i:riogu biii ii:i:Jpf~J~'@iliiilie \mhl3¥ same dcl(latacije kliise: .. n
12 n
r·4
nc cl as s Ve kto r [
do ub le x,_._y, z;
pu bl ic:
vo id Po sta vi[ do ub le

n: )
vo id Oc ita j(d ou bl e &x
x, do
Ve kt or ::x = x; Ve kt or ub le y, do ub le z) [

,
::y = y; Ve kt or ::z = z;

x = Ve kt or ::x ; y = Vedo ub le &y, do ub le &zJ ca ns t [


DC vo id Is pi si( J ca ns t
co ut << "{." << x <<
[
kt or ::y ; z = Ve kt or ::z
;

"," << -.y << "," << z


oc J
do ub le Vr ati x() ca ns
do ub le Vr ati -y () ca ns t [ re tu rn x; )
t [ ret iir n' y; )
<< "} ";

do ub le Vr a ti-z ( J ca ns
t
do ub le Duzin~() ca ns t [ re tu rn z·;. )
[j vo id Po mn oz isa sk ala [r et ur n sq rt( x *
rom (do ub le s) [ x *"' x + y * y + z * z) ; )
s;
VJ [ x += V.x ;_ y '+= V. y *= s; z..'*= s; }
vo id Sa be ris a(V ek tor
};
y; z += 'V .z; J
[ Primjer je dovoljno jasan ila
.

ne traZi posebna obja5njenja


koriste metode Po mn oz i:S
ask ala rom i Sa be riS a, koj Interesantan j~ jedino naein
na koji se
[[ klase Ve kto r (koji.ee na ekr
ove dvije metode na izvjes
anu ispisati 7. 071068, [15
tan naCin pona51\iu poput ope
i je ilustriran u sljedeCem. primj
, 20 , 25} i {2 2, 23 , 27 J), iz
eru upotrebe
Csga vidimo da se
trebalo da bude jasno i iz nae ratora "*= " i "+=" (Sto bi!"iz
ina kako su one definkane): medu ostalog,
[ Ve kto r vl , v2 _;
vl :P os tav i(3 , 4, 5) ;
;
IT- .
v2 .P os tav i(7 , 3, 2) ;
co ut << Vl . Du zin a () <.<
vl. Po mn oz iSa Sk ala rom (5) en dl ;
vl .Is pi si () ; ;
co ut << en dl ;
OI vl .S ab er iS a( v2 );
vl .Is pi si () ;
. ·'

or
] uCitl.iti takO StO CemO ambute
trivijalne metode Po sta vi_
X, y l ZproStO
x, Po sta ;,.i _y tri.nove
atributa x, y odnosno z na ee vf:ij~osti
vrijednost zadanu p!1111llletrom
J koordinittu vektora v na s,
suvi~na komplikacija, posto
potreba da u potpunt?sti pro
umjesto v .x = 5 pisati v-:-Po
je veoma jak:i razlozi za ovu
mijeilimo intenni,org~ci
. Ta ko Cem.o
stavi~x ( 5). ... .
prakSU. Pretposta:vimo ~a se
po5ta:vimo x .
djeluje kaojJOtpuno ·
u buducnosti pojavi
cjelobrojnil irtributa koordina ju koor~·\'eku>J·c;,:i da_
npr. Unij~sto.utri
] Tada bismo U siuiiaju da su
te cuvamo uatrlbufu tipa cje
atrib~ti bill jaVni, sV;uo_ prisfu
l<ibrojnOg rii.za (na.zVanog npr
. Ko ord lna te) .
v.K oo rd ina te[ OJ (npr. p tlp~ v. x mor3Ji Zamijemti
v.K oo rci iri ate t'o J = s). ;S pris~pClm tipa
Po st a vi _x, dovoljno je samo dnige sttane,ukc ,ilik ~cib(le p0put
] bez problema koristiti koristr
ukc
prc:ilnijeniti tuenu implementa
eiju. U o~ -pi~gnmia ~
o:u,ru;mo
j (fiiije ;nio~
traZi. vise pisanja, ali objekino ija poput v. Po sta vi- '-x <5) . ,TiCrio j~ da 6bjeidiio qriJeritii
orijentiraru pristup nije ni n!! ilfiil:iriStup
. pristupu se mnogo me mlsli na biidziehost i Cirljenicu miji:iljen :za p!Sllllje malih progr(ii!U{Y ovgin
na dil ~ 'se Svaki ph}~ koji
1 ill kaSnije morilti piepiavljati
priprerOa teren da eventuain
, nadogrildivati i usavciava
ti. Objektno orijeniiranq Pt
iceD,ili'Vrij@i prije
:~anje nam
e kaSnije iritervencije na prog
r~u budu Sto je g'<id _inogu&i
t>ezilOiciJe.
I U klasi Ve kto r, metode
vraeaju nikakav rezultat, sto
konstrukCije poput v2 = vl.
~omnoziSaSkalarom i Sab~riSa
mo re djelovaii p:rirodno. Ipa napi$3ne su j{ad metode 'kd
J<i:•'Zbog te cirijeruce, neke je ne
Po mn oz iSa Sk ala rom (S ) tl)kpdej. priiqdne
nisu izvodive (metoda ne vi
I ak m~ kao
13
~~r

Ji
rezultat Sto bismo mogli pridruZiti drugom vektoru). Stoga bismo veoma interesantan efekat mogli
ostvariti ukoliko bismo izmijenili ove dvije metode tako da ka6 rezultat vracaju izmijenjeni vektor. Tako
bi konstrukcije poput vl. Pomno:z;iSaSkalarom( 5) i dalje ostale legalne (s obmom da uvijek moZe1no
ignorirati vraeeni rezultat), alibi tiinekonstrucije v2 = vl. PomnoziSaSkalarom (5) pa cak i laneane
:r
(kaskadoe) konstrukcije popnE vl. PomnoziSaSkalarom ( 5) . Ispisi () postale posve legalne. Nairne,
u ovom drugom p~jeru, vl.PomnoziSaSkalarom(5 ) ee kao rezultat vratiti vektor, na koji se onda J[
moze prjm.ijeniti metoda Ispisi. Tako dqbijamqsljedeeu verziju klase Vektor, u kojoj radi kratkoce .,
...
ne6emo ponovo pisiifi definicije atributa i ostalili metodaklase koje su ostale iste:

class Vektor {·
J[
II Ovdje treba umetnuti.definicije· atributa i preostalih metoda
Vektor PomnoziSaSkalarom!pou ple s) {
x. *= s; y *= s; z *= s; · ··
][
return
-(.
*this-~!··.
. ,.. :· · ·-· ;:;..~<-- '·
)
Vektor Saberisa (Vektor VI {
X += V ~xr-~·y +=. V . . y; ·z--+= V. z;·
j
][
· return *this; ·
][
. •:
) ·: j.

);
.
, Prirnijetimo kak? je ovom priliko~ p~~vac~isk~riSt~ ~a
:-raeafije ~:e ][
metode (ne zaboravnno da dereferencrram this ~arlva I u v
• metoda po:z;vana). Sljede&f 8ekvenca :tiaredbi .dovodi do oeekivanog\~q~isa,Jlj. ispisa {15,20,25) i
{22, 23,27) ), tako da izgleda da pr~t4odnotjesenje radi korektno:

Vektor Vl, v2;


. -i}!.'
)y
. .
,_._ Jt
vl .. Postav.l.(3, 4, 5)-;": .. '". -.;:~-
v2.Postavi(7, 3,· 2_)~.,·-'- .<:.~f-_'.
vl.PomnoziSaSkala'rom:(S ) .J::'gpisi D.i
cout << endl; · ·- · ·
:_:
- ·
::;·:' "'. · .--·.--. ][
vl.SaberiSa(v2) .I. .. :.:· ... -~~- <, .

Medutim, sljede6i prirnjer


.. •.. ·
,· '::j--'"~<_,..,_:=_...
u skiiiau"sa ocekivanjima. ·Nairne,
- Jc
mada bi se moglo oC€lki,iail dva piiul 'ispisati 122, 23, 271. biee
jedanput ispisano f 2 2, ]lJ
.... ......,:-·.:.
v2· ''~··""~
vl. P01nn.~·~ r..saber.iSa
·- .
~ .
. ·-. ::·
(v2). ; I~~isi ();
Jo
:.•·"-~-

JtJ
~
npr. uko)iko on prf:dstav~ja Io~ilnu
Jioi1~mje nije svojstveno s;·w:··r:·u:i klasaiUlll

~
se ma kakve vrijeilnosti vracaju iz mq lfilkve
·rrumuS!jafi, ono nam nikada do sada nije 'sii:retiilo. ~
vi. PomnoziSaSka;i.arom [5) . sa!:l~;sa (v2) . Ispisi ();
.. . -- .-~~y - ~
t
14 ~-
'i.
)01.
rt U ovom slucaju, konstrukcija vl.
{1[ ~j
Po mn ozi SaS kal aro m( 5J mnoZi
vektora vl koji poprima vrijedn
vektora. Medutim, vraeeni vektor
ost ( 15 , 2 o, 2 5 J), i vraea kao
vektor vl sa 5 (Sto se odraZava.
na
rezultat vrijednost izmijertieno~
Iiije obje~at vl, nego neka njeg_ov
kopiju (koja takoder ima vri]edn a bezimena identicna kopija! Na
t[ vrijednost tog bezimenog vektora
vek tor koji ima vrijednost ( 22,
oST {~0,, 25 J}primijenjuje
(koja Safi postaje (22 ,23 ,27 }),
se metoda Sa be ri Sa Tii2 J ko]a
nnj
i vraea kao rezultat nov i bezime
tu
enj a
23, 27 }. Nad ovim vektorom prim ni rJ:p.}:rNf
naravno ispisuje (22 ,23 ,27 }. ijenjuje se metoda Isp isi () koj

ill ~sila nad vektorom vl, dok


~redstavljaju kopije objekata
imao niikon pnmjene metode Po
Medutim, ~o se prva .metod
su se sve ostale llletode izvrSile
koje su vraeene iz'lilllkctje! Sto
ga·
a Po mn ozi SaS kal aro m! 5J · zai
nad nekim bezimenim vektqrilna
vek tor vl zacfrU!va vrijednost kakvu
a
sta
koje ~
je
[}[ . po ziv vl. Isp isi O isp isa tiu
mn ozi SaS kal aro m (5 )., odno8n
pra vo {l5 ,20 ,25 ). ..
. ·'
p ( 15, 20, 25}. Zbog toga ee slje
·
dec i
(;injenica da se iz funkcije uvijek
vraca l«ipija ~bjekta koj ije navede
[}[ objekat, nije nam do sada .sme\;l
la (naprotiv, hila je vooin~ kprisn
iJnali potrebu da nad obj(:Idoln vraCen
n iza ret urn naredbe a ne sam
a), s obzirom da nikadli do sad a
nismo
promijeni sam Vfi!Ceni obj~at im iz funkcije prumjeninio neku
MMutim; kao Sto vidimo, uvoden akc iju koj a bi treb ala da
DI koje se_ mo~ primj~jivati ~cije
vracama vn] edn osn tz funkciJa
(tj. kad se na rezu t 'edile me
k?j e mogu _myenjati objekte _(tj.
w.o .n raVJti proble!1le ukoliko
jem klasa·koje definir!Uu objekt
msm<je mut!!!eri)- ttog~ o;ra~<av hae
se metode mutaton oZtva u ula
e nad 1
in.
todei ·(movo pnmJenJUJe ncano
ga metoda). ta
or sttuacije je veoma jednos.tavan,
pomalo apstraktan pojam referen
funkcija moze da kao rezultat
ali.• poli¥tl.o neo tca n
. p.r.ogramer na nJeg.ane navjkn
ce: Da bismo objasuili kako rije&
viati referencu na neki objekat,
'? Izlaz iz ove
e, jer kor
iti ovaj probiem,4odSjetimo se isti
da
alternativna imena za objekte a da reference efektivno pi:edsta
(intemo reference su vljaju
OI dereferenciraju bez potrebe :i:a ·na objekte koji se automatski

:::~:~:~:~~~~!~~~i~iii~~~·;iz~fuDK~I:c~IJ~e~.~Pogleda]mo
•. "* "). U klasicnom procedura
lnom /

DI ·
napisali funkciju •
pre nes eoa por efekllk\ie
ren ci
teftneni::u n<u:j.elol•roj-ni objekat:
a in t &Max (in t·
if( a > b) r~ll:ui•i:l
ret ur n br
~.-·.~.:
·.::,f.-...

a
Q
J
]
]
1
in t *Max (in t *a ,. int ·
*b) . ( .
1 if{ *a > *b) ret urn a;
ret ur n b;

I
15 .
Jj
]j
Dalje, pretpostavimo da je ovako napisana funkcija Max upotrijebljena u sljedeeem programskom
isjeCku:

int p = 5, q = 6;
1[
*Max (&p,- &q) = 1;
cout << p << " " << q; ][
Ukoliko razumijete sta su i kako djeluju pokazivaei, lal<O cete uvidjeti da ce ovaj primjer smjestiti u
veeu od. pronijenljivih p i q (odnosno promjenljivu q) vrijednost I, koristeei indirektne manipulacije sa
njihovim adresama Sada je lako objasniti i kako djeluje'Prethodni primjer koji koristi reference: on radi
][
na isti nacih kao i ovaj pr.iinjer sa pokazivaeima, samo uz'koriStenje drugaCije sintakse, koja omogucava

~
da se sakrije Cinjenica cia se !1 stv~ radi o vjestim manipulacijama sa adresama Reference su prikriveni
pokazivaci, cija u otreba sakrhia .rim' enu adres " ". ' . . "* " .i
se Ullp Cl 0 koriste,_.J:!okmvaci SU kankretniji pojmovi Od referenci, koje je lakSe objasniti na niVOU

~
atl!itektme racunara, . dok .Su i~ference apstraktniji pojmovi koji se trude da udalje korisnika od
posmatranja stvari rui nivou arhitekture raeunara. Reference su uvedene pretemo zbog Cinjenice da se
mnogi programeri pmsto piaie · sintakse za rad sa pokazivacirtla, koja je pri raciii sa referencama

~
izbjegriuta. Interesantno .le da. 5u pi:i prvom susretu sa njima reference obieno razumljivije onima koji
slabije poznaju arhitektUru~uiiara nego onimakojije ne poznaju. ·· .
. ' - ·-·

Vr~~Jtfe::renci ~. funkcij~
·. nudi interesantne moguenosti, ali ga treba koristiJ:i sa izuzetnim
oprezom: ~opko fubkcija v!aea referencu, .titda se iza naredbe return mora4'alaziti jskljnCivo ,
p_romjenljivaili; opCenitije, '1-vriiednost. jer se samo na 1-vrijednost more postaviti referenca ~ ~
prograiiler mora da iir~ti/ Ji!IZi #'fie vrati iz funkcije_referencu na objekat koji je prestao postoj~
primjer, da u funkciji MaX. koja

funkcije bila vraeena · · · ··


vra6areferencu parametri .a i b nisu bill preneseni po referenci (odnosno
da i sami nisu bile refeteriee); ohi bi presta/i postojati nakon ~V£Setka funkcije Max, tako da bi iz. ~
~
nam It
~
i Sal:>erisa · da umjeSto
~bjej<;til )><ijj;,_'ifi:•!Jp:lo d.i(~r1!fimo, vraea .referencu rui objekai tipa
ve.ktor kojiaj?r~d¥i~XljiK ,k~J1~V,f,!JI~i() (,~o'sno (aiitor teksta ·se ovom
prilikom izvitija,ra skrive;'1i J~of!./i:tlli(]c ~;em objclcat Stoga je u klam Vektor -~
dovoljno izvTSiti ·

class Vektor . v
I / Ovdje treba

~
·.umetnuti:
;;._:.-: ', .•.
-~~..

~~ -~;·
-- -_
definicije
· Vektor &PomnodSa:Skal" arom (doUble s) {
*= s; y z
:$'' -- ..

~= s;
atributa i preostalih metoda
~
~
r:eturn *th.l.s;
)
. Vektor &SaberiSa (Vektor · V) {
x.+= v_x;_.~ += V.y; z += v_i;

);
return *this;
~
Sada ee ulancani poziv poput yl, PomnoziSaSkalar om (5) .SaberiSa (v2) zaisia raditi u skladu sa
oeekivanjima Prvi poziv inetode PomnoziSaSkalar om ( 5) ~jeniee vektor vl i vrlii:iti kao rez.iltat
referencu na iwijerijeni .vektor vl koja $anl0 pre<istavlja njegovo altemativno im~ (treba re~ :ii -~­
o
preru8eni pokazivac na njega?) tako da ce· sljedeC:i poziv ni.etode Saberi sa (v2 l Zaisia djelovati na "'lf u
16 D
vektor vl, Sto je u·skladu sa oeekivanjima Kao
Sto vidimo, utroSili smo mriogo. priee, ali je bitno
krajnje Ijesenje potpiillo jedll,ostavnol daje

U prethodnirn primjerima smo koristili Sintaksu


poput vl. Sab eri sa (v2) da saberemo vektore
v2. Mad a je ova sintaksa u potpunosti u dubu vl i
objektno orijentirane filozofije (sjetimo se kakv
objektno orijentirano glediSte na interpretaciju izraz o je
a 5+3), samo 6e najradikalniji zagovornici striktnog
objektno orijentiranog pristupa insistirati na upotr
ebi ovakve sintakse cak i u slueaju operacija kao
sabiranje, koje bi bilo prirodnije izraziti Cisto pro~ sto je
uralnom sintaksom popu t Sum aVek
(sjetimo se proceduralnog gledista na interpreta tora (vl, v2)
cijJfizraza 5+3), pogotovo u kontekstU dodjele !ezu
neko m tre6em vektoru (npr. v3 = sum aVe ktor ltata
li(vl , v2) ). Medutim, bitno je naglasiti da time
smo definirali tip Vek tor kao klasu nismo izgub Sto
ili pravo da piSemo obic nejim kcije (koje nisu funk
clanice) koje kao parametre primaju objekte tipa cije
vek tor, i koje vraeaju objekte tipa Vek tor
re~tat. Stog a nam niko _ne brani da napl8emo kao
ob!,(Snn funkciju sum avek t6ra koju ceino upra
pozivati. na gore navedeni naCin (tj. laio Standardnu vo
~ada izvjesni radikalisti smatraju da pisan
fiinkciju, a ne 'prirn ijenje nu nad nekii n objek tom).
je vakvili fimkcija nije u · dubu objektno orije
programiranja, v~ina ipalc -ima rniSljenje da 0 ntiranog
pisanje 9,vakVih fimkcija u umjerenoj koliCini
· objektno orijentiranoj filozofiji, pogo.tovo ukol he Steti
iko vodi ka intnitivno prirodnijoj sintaks.i. Stog
a 6emo IIi
napisati funkciju sum aVe ktor a koja koristiti
ga tako napisana funkcija ne6e imifti privilegii
ce
gore opisimu sintaksu. j\{edutim. moramo voditi
racuna 'f'
u pri~a privatnim atrjl!!l.tima.hl~<:L\!:!l.k!:.g.E
zbog toga sto nije funkcija clanica nego obiena (upr avo '
funkcij~). Stog a cemo ovu funkciju
indirektan naein, koristeei funk cfe clanice Pos m9rati napisati na
tavi , Vra ti x, Vra ti y i Vrai!!f z. kojima
moZe!no posr o pnstnpiti atrib utim aklas e Vek i
tor: \
Vek tor Sum aVe ktor a(Ve ktor vi, V~ktor
V2) {
Vek tor V3; ..·.•
V3. Pos ta vi (vl. Vra ti x () + .Y2 •Vra ti x
(), Vl. Vra ti y () + V2. Vra ti y () 1
Vl.V rati _z() +v2-:-vrati_:Z());·;iit~--
- -
retu rn V3; .. . ' '
} 1':~:; . ; .
·- -. . -' . 'jj;l

posv~;:r~!n:o!6l~f~:~n;rir~ct!Jr~~~a~t·~Ai.f~z:!a~~~~;Z~~v:e=j~b~1:
·.-;.iy~:' . •:. ":~ .

man je osnovana nego' u slucaju sabiranjil, i vci6


doiili)ii:t;'j.(ri\ai-i dulj objekl:!io orije1Jtirarie filozofije.
Nairne, vee smo :vj<ljeli da infonnacije
infon nacij u o x koordjnati vektora v. do~ijam6i()z
o oojtlktn
'dq~~ti';piJ~vomnietOda _Dad njiffi, tak,9 da
ivop ~d.¢ Yt<~l: i_(< ljad v~o/~w ir, i_j, po;ziv<mi
v. Vra ti-X (). Kalw je i duZinavektora izvjesM
infonD,'!I:ija:o pbjektt1·ir¢1ft.qr~oja dodtiSe nije atrip
ali se izvod i iz atrjb uta), n~ bitnog railo ut
.-. -. ··--·:·- - ··. -~
ga , . ,za
.-, -- -_·: __da dqbijailJe gve.. inf{)rlj\a~l}e l!:o!{sijmo ~ciju
sintaksu. KoriStel\iem jedinstvene sin,takse·ine , - _,_,~·->·;-.,··_.:.:_._.,_
...
pr11vimo konceptu;;Unu ·razlil,cii. -.·._,-
~._-::··.•·;·;.
..• _ .,,, .. - •...
,,.o··~.-

vekto. ra i !Ueg ~edu ripr. koordinate


ove duZin e {oba pojm a pred stavl
- - '

prinijenom istih sintl)ksnib kons - - -- . jaju infof.- lllicl


'
- . -. -
je .o v~kto. ril ]i:oje dqbi
. - , "·· jamo na isti naCin, tj.
cije :fiekilj §injenica niipisaeem. - .i obicn
-:~::.
-... - - . ·... -·:
trukcija). Ipak, radi demonstra ' --, ·--~-
.. . '

jimk ciju Duz lna koja prima kao parametar vekto 0 u


r, a vra~ ij_jegovU d,)~riil; Jliko da se tiJ.oie koj-j
sintakSa riuz ina <v>. Ovdje relimo da istaknemo cin·eni~ <iamoie. stlti
ftnikcija sa istim imenom, bez opasnosti o"sio·ati funkci'a Claruca i obiena
kompajler)iolni' · · ir bzirom da se
naci nu poztva (funkciJe C . e se UVIJe poztv o
aju na nekim obj\lktpiD, osim zyentnalno iz
funkcije clan ic; iste klase). Stoga bi (obienu) funk druge
ciju Duz ina niogli napisiui oVako:
dou ble Duz ina( Vek tor V) {
retu rn V ."Duzina () ;
)

Prirnijetimo da je definicija funkcije Duz ina


trivijalna, jer smo prosto iskoristili (istoimenu)
ouz ina nad objektom koji:je proslijeden kao param _metodu
etllr, koja upravo radi ono sto nam i treba · ·
. Vratinio se na implementaciju funk cije· sum
aVek tora. MoZe!no reC:i da smo imali sreee Sto
Vekt or ima metode Vra ti_x, vrat i_y i Vra klasa
ti_z koje ipak omogueavaju daje dnos tavn o prist
npimo

17
,j
"....~~­

]
vnjednostima koordinata vektora. Da nismo imali ove me!nrle ne&o da smo morali koristiti metodu
-
Ocitaj, implementacija funkcije SumaVektora hila bi mnogo komplikovanija: ·
. . ]
Vektor SumaVektora (Vektor Vl, Vektor V2) (
double Vl_x,.·Vl_y, Vl_z, V2_x, V2_y, V2_z;
Vl.Ocitaj(V l x, Vl y, Vl z);
V2 .. 0citaj (V2-x, V2-.y, V?-z);
Vektor V3; -
Jf
- ·-

}
V3.Postavi( Vl_x + V2_x, Vl_y + V2 ·'i• Vl z + V2_z);
return Y3; ~--~
,~
If
.,
j
j
i
-~t.:.:~
· Vektor stimaVektora (V~ktor Vlj :y~ktor
Vektor v3;
v3.x = vl.x i: v2.x; v3.y ""-vl.y ,+, v2.y;. v:3-.z = vl.z + v2.z;
return v3;

, Na. svu sre6u, tako n~Sto je moglice. ·. NafiJ~,


, ··: ··;tt.f

.urtutar
. ,-.-"-.

ileklaracije klase moguee je izvjesne obiene


i
tikkcije (koje nisu funkcije clanice k)ase) P!!lglasiti ~Hjateljima k/asSJ Cime one dobijaju pravo pristupa
privatnim atributima i metodalna.~ ld~.e. Neku":W!t 'a:Je ~oguce proglasiti prijateljem klase tako Sto
,se unutar deklaracije klase nayede liljucriJi.rijee 'rii¥~.4> ifiiltm;I protottp. . CIJe koju progla5avamo
1
prijate_~em. Ovim funkctJa ne postuje ctj~"'(:,~~- ·: i dalje s,e poziva kao obiena funkcija), samo
obija pmvo pristupa privatnim atribuJ:ima, l.dl!S,$;~jedi deklatllClJa klase Vektor koja progla5ava ;~
funkciju SumaVektora prijateljem klase ye iWj
sto omogucava njenu implementaciju na gore
navedeni naCin:

class Vektor { _
·
;
.; · ~/Ji:
:: _.,1 ·"·:: ~-
'
". '
'
::, :; . :;:.;:•,· ·
·
~
~
-~o~~e x, y, z; .: ::: . \4tJ~} __ _
pubh.c· . ~- ,-~- 11'; · ··
v.,;id.Posta vi(do$le.x, dbubi '"y,;Jdoubd-e ~) {
· y_ektor:";i·,= ~4.~-:-:'[ekto:r-·=··=-):' =-.,_f;,t·v~kt?.~~-~: :-z· = z~ .· _ "",.

!aid

} .
O~i
. . ... _ ·.- "i/1:'·

taj tdJ;,;!:fe &x;, doub.ll &y, 4o®lei '&zJ'


. x = vektoz:::*~: y =·Vjktor:·:y i z.=>'y.i~for'::z;
. '·':': . .,.. :-" :,;.. 'i' :ll'!J .
··.

'.
· · · · __ ·

. : ·:
#""'
b~~st v
-void rspisi o !f:biis.t c.:l-, .,, ~:.

'.}
· . "
cot;.t <'< ·,j ·{ ri~-'-<-< ..x- ~<-.'.~;, ·"-.-·:.·i;~'fy. << ·,r " << .z-- << , } n;
• • • . -.~:. :..... _·_~:::)i_: I ~,1~r~~." . _,' . I
D
~
doubl!> Vrati •;K () canst :•I i::'~®:_rri x; J
4otible Vr#li'y() (:On$t '[ r~tii'#:Jif; } .
dbilble Vr?ti--::;z 0 -~Qft~;;;{ . r!>f\lrilt':Z; }
doUble. Duz~ina.(;~· corfJ!{t<.{ ret\iiiii'f~sqrt (X * X + y * y + Z * Z);
vektor &P61illi<;>~lsaS{alaroin (doUble 5 > 1
x ?'"= fi-;.-·.~y :*= s; z· *= s;
~.turn ·*this;
v
}''
Vektor &SaberiSa(V ektor v)
:x_+= v.x; ·y·'+= v.y; z += v.z;· ru
} .,
.;qaturn *this;
.

·,
ii:Sfriend Vektor. ZbirVektora: (Vektor vl, Vektor ·v2) ; ·
};
ru
18
~
,n
Neka klasa mo.ze bilo koju funkciju proglasiti svojim prijateljem. Naravno; to "prijateljstvo" ima

.' '·
smisla jedino ukoffirota :fimi«.iJa nna neke veze sa tom klasom, ijto se tipieno de5ava u tri slueaja: ako
funkcija prima parametre koji su tipa te klase, ako funkcija vraca rezultat koji Je ttpa te kfase (ili
pokazivaea na tu klasu, ili reference na tu klasu), ili ako funk~ija deklarira lokalnu varijablu tipa te klase '
(naravno, moguee je da se de8ava i sve ovo skupa, kao u p~eru navedene funkcije sumaVekto ra).

Dugo vremena su postojale rasprave o tome da li prijateljske funkcije stete objektuo orijentiranoj
:filozo:fiji. Jedan argumentje .bio da one nilrusavaju sakrivanje podataka. To misljenje je odbaceno zbog
CfiiJetrice da nijedna funkcija sama sebe ne moze proglasiti prijateljem neke klase (i na taj naein
neov!aSteno pristupiti njenim atributima), vee upravo sama klasa .definira kojim funkcijama "moze
\jerovati". Ako klruia "ima povjerenje" u svoje fuukcije clanice,. zailto ne bi mogla imati po\jerenje i u
obiene funkcije koje sama Specifizira? Drugi argument je da prljate!jske funkcije pods.ticu koristenje
sintakse ko a ni ·e u hu ob 'ektno orijentiranog programiranja. Ovo je doduile taeno, ali je Cinjemca da
objektno ori'entiranu filozofiju ne nn s1 a a, v snovna postulata: sakrivanje podatakO,
enka ~ul i a ni:Jslje ivanje 1 · o zam . . · ~e o onJen a sm a m porno 1
razmisljamo na obje · orijentiran na in; ali sama za sebe ne cini. objektuo orijentiranu filozofiju.
Program koji postuje postulate obj~ktuo orijentirl!lle :filozofije neee postati neobjektuo orijentiran
ukoliko se s vremena na Vrijeme ~oristi sintaksa koja nije strogo objektuo' otj.jentirana. Sto se tiee
postulata objektuo Orijenti.rime j'ilozo:fije; priJateljske funkcije ne narusavaju ni eukapsulaciju, jer se
proglailenje funkcije prijateljskom' takodei- mOZe smatrati dijelom. interftjsa klase (g. opisom sta se sa
i
klasom n:'-o~ raditi) n,eneCim odvoje~ o~ ~~e~ 'do~ eemo kasnije vidjC(ti da p~jat~J.jske ~cije ne
naru8avaJU m preostala dvakoncept a: naslJedivlinJe 1 polimorfizat:Q. Dakle. nema m1eslil tvrdnJama da su
prijateljske funkcije ikakVa SIIletnja objektno orijentpiinom pristupu programiranjp. ·
· .... _.... :.·. . ;P·•·\··· ~

I Ponekad je po~ebri~ ucini prijateljem neke klase, g. da


joj se omoguci · · · · To se more uciniti isto kao pri
proglasenju metode moia navesti i ime pripadne
klase praeeno klase

b, friend
"..
Cime se citava

B.
prijateljem klase A

Svrha ovog poglavlja hila je d.?-' uvede ci~LOca koje vode ka objektno
orijentiranom prist\ipu progiamiranju: '{ eCina
izrazava s=ju u r\jil10vil k9rist i · · ·.
sa
. lffiSTetu Ovim konceptima
·· potrebno uloZiti u objektno
orijentirano progiariliriUije(s obzirom da vecu discip!illu i razmiSljanje
unaprijed) iSplativ. ~oa. je odg~vor na ovo pit~j~~.J\~~9 u\jeii.cemo se u naredllim
poglavljiml!, u kojima 6e se jasilo vidjeti sve · oii]entiranog pmgramiranja kroz ~e
tehnike k9je bi bile jako teSko 9stvarive pr~~alnog prQgramiralljl\.
:;}
-~:~~~i; ~. _t L
', .,_"I

'I 19
' ' . t
~
~
~
(
~
. -
~
~
0t:J
~
~
-"1- .,,- •

. .
. :r·.' -t~w···.
.

•·' " .
u
-
. ' ·.. . #.::: .
0
.....;

. fl ......;

····.';.

. . . . _:;;:
.
' .
. n
~

fl
.· . .

.....;

".
.
D
__,

. ll
-
D
__,

ll
__,

Ill
lJ
.Q[ ;_
~
'n: ' ' I. _"-'5 .....,.. ::.H-< -.-
........,._,_,
J '
Q U pretohodnom poglavlju smo vidjeli da koncept skrivanja podataka i uvodenje funkcija &illiica za
strogo kontroliraill pristup klase omogucava da sprijt;Cimo da se atributimil nekog objekta dodijele talve

q vrijednosti koje bi sam objekat uCinili besmislenim. Medutim, i dalje. veliki problem maZe predstavljat!._
cin ·eni !Ia, oput svih ostalih promjenljivih, promjenljive imaju nedefiniran sadrZaj sve dok im se
eksplicitno ne dodijeli vrijednost owy pro em se ' ues• 0 se sv promjenljtva-
iii.icijalizira ·odmah pri deklaraciji."Medutim, niko ·nas ne prisiljava da inicijalizaciju moramo izvrSiti.
Stoga, u ogramiranju veonia eesto nasuyu eSke koje su poSljedica neinicijaliziranih vrijecJnosti
.
Q promjenljivih. Obje o onjentirano programiranje nudi az IZ. ove sttoaciJe uv
Elji -~ korisnika da mom izvrSiti inicijilliza_·.
· ns ora,
· ciju objekilta (i_• to na Strogo kontronran naCin) .
prilik.2!!L!Jftl!Q.ve deklaracije ili~Ckog objekta ~(pomoeu operatora ·new), Konstruktori
ll
Q .. f;lkoder 91119gueavliju da. se .altemativno.izvrSi ~tl>.maiska inicij~ja af:ril:>uta obJt:kta na neke·~
' J>odrazuinijevane vrijednost:i, u slucajll da se inicijaliiacija ne nayede ekSpficitiio: ' ' ' '

n OpCenito
I kada dode doreeeno, konstrUktori definiraju inu akci a ko ·e. se aut01natski izvrsavaju onog trenutka
&
njegovog stvaranJa . g. priJi1col11 nailaSka na njegovu deklaraciju, o osno prilikom

q ' amai:lliCkog kierranJa objekta ·pomo6u opemtora new); Po fonhl, konstruktori podsjeeaju na funkcije
Claniee-klase;-samo·itfruvijek"imaju~isto·ime·kao·t1dasrrfcojoj'pripadajll't-n
klasa maZe imati .viSe konsttnktora, OJI se ·
f Iil.omju
· · ~- . · · a:·Jedna ·
. ov po . OJu· 'i/ili tipu parametara. •
1
n I
Takoder, poput obiCnih funkcija; konstruktor maZe imati i podnizumijeilane parametre.
, .

Upotrebu konstruktom eemo prvo ilustrirati na.jednom jednostavnom primjeru. Pretpostavimo da


~ .,;
smo razvili klasu Komplek sni koja treba da predStavlja kompleksni brcij. Znaeenje atributa i metoda

0
b- .•
prikaz:ine k!l;tse jasan je sam po sebi; taka danema potrebe'd a ·dlijemo detaljnija objaS.njenja. Pri tome
sino ptedvidjeli i postojanje jedne prljateliske f1mkriije ·tiazvane ZbirKom pleksnih , ko)u eemo.
implementimti kasnije. Orio na sta ovdje treba obmtiti paZilju su tri konstruktora, od kojih je jedan bez
·

u
,. '
parametara; dok su druga dva sajednim i dva parametra iegpektivno:
,._,.class Komplek sni { . .r
:.·

u 1
{i. double Re, Im;
public:
· - Komplek sni {) { Re ~ Im ~ O; }
- Komplek sni (double x) { Re ·=('x; Im ~ 0; }
'"' ·f.:,. -Komple ksni(dou ble r, double i) { Re ~ r; lin~ i; J
u
L, ~
.fc(
· .:.jS
void Postavi (double r, double il {Re ~ r; Im ~ i; J
void Ispisi () { ·cout << "(" << Re << "," << Im << ", "; }
double Realni() { return Re; J
double J'inagina rni () { return Im; }
D
~.
};
friend Komplek:Sni ZbirKom pleksnih (Komple kqni a, Komplek sni b);
. ' .

u
·~
Naravno, stvarna klasa za o iS komp~eksnih brojeva trebala bi imati znatno viSe metoda il.e o
gapisana klasa; ali na ovom mjestu ze o da se o o na konstru re, Razmotrimo prvo ./
konstruktor bez parametara. Konstruktori bez pammetam se antomatski pozivaju nad obJektOlri Prifikom

u
-
naihtska na deklaracuu odgovamju6eg objekta bez eksJ>licitno navedene inicij~ci.Je. Na primjer,
Ukoliko se izvrSi sljedeea sekvenca naredbi:

Komplek sni a;
. ' · · _;

u cout << a.Realn i(} << " " << a.Imagi narni(};
~
na ekraitu ce se ispiSati dvije nule, a ne neke nedefinirane vrijednosti. Prilikom d~acije
objekta.a
ititomatski ·e pozvan konstruktor bez pammetara koji je izvrSio inici'aiiZ8ci · atributa Re i Im na n.ule (u
/f
D
... ' adu sa naredbom unutar tiJe a onstrulctora), Tako er. prilikoiri stvaranja dinamiCkog objekta porno
operatom new, stvoreni objekat 6e autorilatsktbiti inicijaliziran konstrllktotom.bez pammetara. Stoga 6e;
.
~
sljedeca sekvenca naredbi takoder ispisati dvije nule:
0
1
n
..
~
]
'

I
KompL~ksni. _tppk;.: -. ... ..:: '

p6k = new Kompleksni;


cout << pok->Re.alni () << • " << pok->Imaginarn i (); n
f KonstrUkto~ ~a parnmetrima pozivaju se uki>liko se prilik<im deklaraciJe odgovaraiueeg objekta odnosno ·,
• prr:upQtrebi operatora. new eksplicitno u zagradama navedu parametri koje !reba pmslijedjti
.konstruktore. Pri tome, ukoliko ue postoji konstruktor Ciji se broj ·i tip parametara
. . ne sl8Ze sa navedenim
u n
parametrima, kompajler prijavljuje greh Na primjer, ukoliko se izvrSi sljedeea sekvenca naredbi:

Kompleksni a, b (3, 2), c (1), d, e (6, ~1);


a. Ispisi (); b .• Ispisi () ; c. Ispisi ().; d. Ispisi () ; e. Ispisi () ;
t
na ekranu 6e redom biti ispisano ( o, o), (3, 2), ( 1, o), ( o, o) i ( 6, -1) . · Detaljnija (lbja8njenja
vjerovatno nisu potrebna Slic3n efekat mogli bismo' poStiCi i upotrebom operatora riew i diliami&e
-~
:·aiokacije objekata:
'. ~-,.-;.:_:::_;~:~;-,~ ·_;. ,._. l'·" ___.,,•• ,_ ,-, ·,: '-:'··-: _:_~..
•~··
--~...
· ·
·-
·
.. , . : . . -- '·.·;r-.··.: ~. . ,. ~
Komp;teksni *pa =.
new Kompl,eksni,. *pb · = new Kompleksni (3, 2);
Kompleksni *pc =',·new Kompleksn:i'(1'),
. · *pd = new Kompleksni;
Kompleksni *pe =···new KoJI!pleksni (.6, -1); . ~
pa->Ispisi (); Pb:->Ispisi'(); _pc-'-?':Ispisi (); pd->Ispisi (); pe->Ispisi ();

'Rlldi·koltzi~lil1<ll.f~p-mg~arft•'!5Ji!Zil('C+.t-:~ozvo:ua:va ·i aa seJ?romleiiT}Ive ftrosiih iiiJiwa tiiPi-. tiiiii :int, ·1


double, char, ild.) inicijalizii-aju _tzv; konstruktor.skvm sintaksom; odnosno navodenjem vrijeduosti u
zagradi.Tako je, na priiJ\ier, fun.jeslo · -- - ·" ·
&
· ·
int a = 5,- b.= 3;
double c!'F 12.• 245; . :z.
j· ~
char d = 'A';-· .
'
~
-~~ .

.
dozvoljeno pisati:
. .
-~~~ ,-.·

~
·[int a(5), b(3); . ·.
::: doubl.e c_ (12:245) ;·.',' .,
char d('A'); .·


klase. Kompleksni se u
~

class KomElekSni {
double Re, Im; ....
public: · : ·.·
u
~

Kompleksni(do ubte.r- 0, double i_= 0) { Re = r; Im = i; }


void Postavi(dotil:;le r, double. i) { Re = r; Im = i; }
void Ispisi ()- {_ ·cout <<' "·(·.":. Re <'<. "," << Im << n, n; ) << u
. clc:mJ:ll ft,,f.e«l';-j,JJ.J< ! rc@:tu::.n ,Re.; _} . _ ..
double Imagw~nn (} (. return Im; }
·-·· _.,..., •.
,__ ... - ~~-·
·.~:-::t'~~!'' . ~.
. ~! 0
~

}; friend Kompleksni.
.
ZbirKompleksnl h (Komp;Leksni a, Kompleksni b) ;
. .. . . ~

D
D
~

Uk<iliko neka klasa ima konstruktore ali medu njima nema· kvnstruktora bez parametara, ·tada £Ir I/ I
11Wf!U6e kreirati instance te klli§e bez eksplicltnog naVoaenja parametara k0j1 ce se ~proslij iti
kOnstruktoru. Slieno, riije moguee kreirati dinamicke objekte te klase primjenom new· oP'qatora bez • • •
D
~

. . ·J.:'

2
D
n
lJ ,.

o~L.-•
rt·7 . ., .JJBVodenja·neophodnfu,paramet
ara;';Pretpo~o, na primjer;
Datum_ (radi jednostavnosti, ova klas
poglavlju), koj a ima samo konstrukto
"da.smo·nap:isali-sljedecu1dasu n~
a 6e biti siro:maSnija od istoimene
r sa tri parametra:
u -
kla se razVijene u pre tho dno m

rt cla ss Dat um { .
int Dan , Mje sec ," Go din a;
pu bli c:

rt -Da tum (in t D, int M, int G)

);
voi d Po sta vi( int D, int M, { Po sta vi (D, M, G); J
vo id Isp isi () { cou t << D
int G);
<< •. " <<.M <<- " • << G; )

[{ Pri tom e, :funkcija Po sta vi 6e biti


implementfrana na isti naCin kao i u prethodnom poglavlju:

~ -·
_vo id pa: tum : : Po sta vi( int D,
- - -in t Bro jDa na[ .l2L "' {3l i j.i;"o M, int G) .{
if( G % 4 == 0 && G % 100
.
.281 .31,- $o';_ '31,_. ~o'; 31-,_
!;= 0 11 G % 400 = 0) ·' ,_·
. · -· .. _ . ____ · _..
31, · :30, :3i , '30 , 31J i--, ·--- < -'-'•

Q Bro jDa na [l] = 29;


if (G < 1 II D. < l .11 M < 1 .
. II
' di.,-;
thr ow "N eis pra van ·da tum ! \n" 1>{ > 12 II D > Bro jDa na [M ~ l])
;· -
Dan· =' D; Mj ese c = M; Go din
.) . a = G;!
Or
.J. Kak o · r klase Datum u ~tini treba <laprild
i isti1 stv adm o i metpda. Po sta vi, unu
[} konstruktora samo smo prosto poz
v metodn Pos t<ivi sa istim parame tar tije la
J ma kOJe funkcije clanice, IDOZe poz
ineto~ primjetijuje). Int~esan~o je da
vati bilo koj a J:Qetoila,iste kJase bez
rna
lrima (iZ konstruktora se, -kao iz /
navodenja obj ekt a nad koj im se n

n 'l
~o Je ta met oda dek!anran
k~~ a ni~t oi!i l ~OZ
a lZO me ovo 'Je oC:Istu,pi)IlJe o4
identiflklltorima koji su PfllJ,!lo<lno
one mo gu6 ena je prostadek\Diacija
de§pimnl. ill
tipa~<" '
.oar -
-
e 0
_pra

·
. • .
vila
- m~~ iz iste klas_e Cak i
da se SIRlJemo obr aea ti' samo ••
jiajav~. OvakVom deflnicijotn
. !dase Da tuin
II

Q Dat um D; - ooJ--<r ~- Q<;<dc, o~

Umjesto toga, neo pho dno je navesti--:~ ····- .


~
.
. ,. :~.-
,:;
piirametre koj i 6e se kori!lfiti Zllinicij;Uizaciju objekta:
Q .
. .-

Dat um D (7, 12, 200 3); - ~.


\'f
;,
;.,
1\\ .:'.

\\- .b~ :. -·-


. .

..-~
_.· .. _- -~· .. :. .
Pri tom e je bitno da parametri udu .. ·0:
smtsliJm Ukoliko' kda mo besu¥Slen
D- izuzetak
61ti stvoren.
vo baciee a funkcija Pos tav :i koj datum konstruktor 6e baciti
a se ziv a iz:·konstr\lldora), _i ob ek3
f D nec e uo 00
J
t-:·" •
.
0-· Vjerovatno 6e se nek o zai>itati zbo
radi istn stvar. Konstruktor se poziva
,_
g eeg a smo pore4. koi:Istniktora def
prilikom stvaranja obj ekt a i same tada
-

inirali i me tod u Po sta vi koj a "


. Da nism o definirali metodu ~,, 1
,n1
· Po, ;.ta vi, ne bismo bili u moguCriti - _·
s'!Nia'iiaknadno'prornij~o sadrzaj
Q vidj~ '!_a ~ismo ipak b~ ~ mogu6nosti,
ali P_O cijenu ?sj~o'g gubi~ na e:i
objekta (-zapravo, uslcoro 6emo
·· - ·
kasniJe zelimo da pronnJenuno datu
m pohranJen u (JfF kqjtranQ¥1) obJektn ik~osti). Ov~, ~oliko
D, mozemo prosto pisatl:
f
~.Postavi(30, 4, 200 4); •
J Iz istih razloga, nije mogu6a ni dina
miCka dodjcla pop ut
].
alij e sljede6a do.~jela pos ve korektn
a:
J Datuni *po k = new Dat um (7, 12, 200 3); ~td
\- lflro {' oi<_

1
3
...J
l !

~ r[
'
.
....J

. J[
.
I .
.. mogli . . . samo untitar metoda iste (lito jc:i besmisleno), eventtiillno
' mike od funkcija prijateljak lase ill metoda prijateljske klase (ovo ponekad· more da ima smisla). J[
IstO vrijedi i za stvaranje dinamiCkih primjeraka te klase pomoeu operatora new.

U prethodni m poglavljima vidjeli smo da se


navo enJ vnJ osti svih polja unutar vitiCastih zagrada
mo
Na
inicijalizirati prilikom deklaracije
primjer, likoliko Je 1lp Da um ael:iiili8D._ ..
J[
kao struktura, moguea je deklaracija sa inicij3liZ8clJOm poput sljedeee (primijetimo da je ·navedena
inicijalizacija besmislen a sa aspektako rektnosti dahJIDa): j
= {35, 14, 2004};
_Datum D

,'\cll'6'' Mecfnti!J),.kl~e se ne mogu ovako inicij~ Za njiho~ inicijalizaciju kpnste se koristruktori. / . ·. ·-If
ll
moZc:'liricijaliZirati~ rlstom

.
. .PreCIZnije; tiasa: se ile
I· maw
vrijedn.osti li vitiCastim zagtadain:{t Uk'Oliko sadrZi •....
jedan pnvatni ambut ca sva1Ca prava k1asi1 ili sadrZi) ifili ako klasa ima definirane konstrukt oie
, (~ je takoder gotovo pravilo .,. dobro napisana kbisa uvijek treba imati konstruktore). Razlozi za ovo.
sli
,-<

· i
·a
prilieno jasni:. inicijalizaci listom vrr osti u vitiCastim o •· · nek · It ·
""u. za•.r
'vatnim atributima klase, a konstrukt ori sv
t'liZlilelf·'trcf 'ffii: · ·. u nStOmmJ oonosn:'K oJa · tisnamo·' ·J;e.pmva nfe viijoonosi:r u··adiovarajU.&i · 1[)
a atribute, konstfuktori mogu na sebe preuzeti dodaine akci" e . 0 ut ro .ere .· · akci :v:iiosti parametai:a) koje J!

,
I ee g · · vnu ~CJJ ciJn objektil; pa Cak izvrSiti i nmoStv'o a (vidjeeelil.o uskoro
• je kreiranje diruimiCki illocit 111Z0vanajboljll prepustiti uptavo kimStruktorima). 110
' . ~

ru
~
uzmemo 11 se klasa 1sto kl!Q
mogu 'poinoeu op~ra "=" (pri tome ·se,_ kao i kod
struktura, svi atributi objekta sa desne strane l?rosto kop)raju 1i o4&~ju~ ·atribute objekta sa lijeve
Da
t\.irlt 'mQre ostvariti i sljede6om
~
strmie), vidimo da se naknadna, piumjena objektll ;D i:ipa
konstrlikcijo!J), bez upoirebe metode Postavi :, . ·· · ··

~D= W '\'~~-'~ -".


;:>atum(30, 4, 20.04);.;
"f;>~' .. • .

U ovom slueaju, poziv konstruktora sa desne strane kreira6e I!rivremeni objekat tipa Datum koji 6e
se u
~

inicijalizirati na navedene vrijedn.ciStl; a: zatim ee tako kreirani objekat biti iskopirau u objekat D (nije
Io8e "ti. da se svi automatski k:reiami · "vremeni ob "ekii automatski ·

efek:at ove. g,9djele je sliean kao da smo ~isali:


·u kada se ustanovi da
viSe J!iffl &9trebni, faKo . sene moramo plaSiti da Ce njiliovo stv8ranje dovesti do curenja memorije
. ~ • ~
). . u
~

n
Drugim rije}l\m!!>.
. .. ·. ,, ' . - .
. -,-,.~-'

Datum Privrem eni(30, 4, 2004);


D = Privrem eni;

Marla ovaj primjer nedvosmisleno ilustrira da smo mogli pro6i i bez metode Postavi, njena primjena je
zuatno efikasnija, jer nen1a potrebe za stvaranjem privremen og objekta i njegovim kopiraujem u objekat
koji .Zelimo postaviti.
u
~Da bismo bolje shvatili Sta se de~ava, vratimo se na klasu Komp1ek sni koju smo ranije napisali.
Neka je otrebno deklarirati promjenljivu a ti a Komp1ek sni i inicijillizirati ·e na ko leksni broj
u
1, 2). Najueposredniji naem da ovo uradimoj e slijedeCi:

~ Komplek sni a (1, 2);


u
4
(
I
u
n
I, l

f'-~~ .• -''·~ •l.Medut!m;;postoje.,joS..dva naCinaoda postignmp.y isti _efekat -Naime;· -I!Iol¢Ce- jlj.izvrSl:fi 'iilicijalizacij'u
• _nekog Olijekta i poi!Ioeu znaka "=", ali iskliuCivo objektom ~tog tipa-:Na prilnjer, sasvim 8u moguee
sljedeee konstrukcye: ·
<; Kompleksn i a (1, 2); W
:?- Kompleksn i lb = ':5' ··....:

n ~.
Stoga je drugi illlcin da izvrS:imo inicijalizaciju objekta a sljedeCi (ukoliko Citaocu sintaksa koja se ovdje
koristi djeluje odnekud poznata, r~o samo dli tip complex lmji srilo koristili ranije nije nilia drugo

n
nego klasa definirana u istoimenom zaglavlju complex): - - ·
/1/ Kompleksn i a = Kompleksn i (1, 2);
,,
t
0
,; -f.
'!,., ...
Pored toga, moguea je i sljedeCa sekvenca, u kojoj se koristi gaknpfna 4odiela (ali samo ziilivaljuiuCi
• Cinjenici da klasa Kompleksn i- posjeduje ikon$l:Uktor bez param!ltm:a,. dok bi prethodnl! naredba hila
·· Iriogucaib ezteprei:po SiaV'ke):" -''·_·-··-·· _-- j.- ••, - J: -. ·: ------ ·-· -- ---- ---: ~·- ,· ,_.,

0
!
1.-
~
~
,v/Komple ksni a;
V" a = Kompleksn i (-1, 2);

_Marla_ sve trinav(l(!e~~ ~g~ci ·~; __ JOiA'Q4-!<.i£li .lif~.!IJ.. ~U.--Wib.- ·~:. ~- dika .razlika u... ogled!L
e nosti. Prva kons cija kreira objekat a i inicijalizira ga na (1, 2 ) . Druga konstrukcija kreira ~ ·
prtvremeni objekat kojiinicijalizira na (1; 2 ) a zati. ga {foP u
__ -ira obje-kat <l_: -~re6a_ k~nstruk_ dja kreira -
m___

objekat a i inicijalizira ga na (1, 2) posredstvom 1wnstruktora bez yaralr!etara, gza~im kreira


privremeni objeka~ inicijalizira lJa nil (1,2) i na·k;raju.kopira u objekai'a. OCigledno je prva ·
konstrukcija ubjedljiv~ najefikasnija, dokje posljednja k'oDstrukcija ubjedljivo n!jjneejjk~ja

_CinjemEca:cMdil~~~ !!!Q8!
mo:le pozvliti i
napisaii
~~~~
Jjesenje je sljedee•e:

Kompleksn i ZbirKompi e'kt;hih (Kcnnp1eksnL;a,,- :Koinpleks ni b)


-Komplek sni c; .•-.· -_,!_,_;Jf_·.-·. ..
c.Re = a.Re + b.Re; c.Im _., a-.• riir-.+ J;>.-Im;-
return c; . ;;£/·;_.,~... '·
: ~,_,.;~'-
0
''T~
: . ---- . -

) U ovom primjeru se nepotrebn~ 'j,oziy~ konsl:nlktoi bez parameiara za objekat


..

da bisnio na kraju
.

c;
• ~eno promijenili njegove atribute. Bolje hi bilo Qdmah pr;imijeniti'konstruktor sa'dva parametra da:

0 ~cijalizira objekat c na neophodne vrijednosti:- · · ·

r
·~"' . Kompleksni_ZbirKomp~-~~~pi):i(!<omp~~~sn_ i_,,a, i<omp1eks ni _b)-_[ , f v/
··--·- Kompleks ni·cfa.Re+ --b·::Re, a.rm·+-b. Im);
0
··.···
· · ~-
. · return c; ·
- ) . .

0
...
Mr4nrim ·. ukoliko uoCimo da se konstruktor mo.Ze pozvliti kao {imkcija. za'kljucic5emo da nam uopee nije -
potrebmi lokalni objekat c, neg!> mo:lemo da iskoristimo i privremeni objekat koji kreira -konstruktor • ••
If/
kada se l!potrijebi kao funkcija: · ·

0 Kompleksn i ZbirKomp leksnih(Ko mpleksni a, Kompleksn i b) {


_return Kompleksn i (a.Re + b.Re, a.Im + b.Iin); -
)

a
~
U ovom slueaju konstruktor eira ·vremeni objekat koji inici ·aliziramo na :leljene vrijedtiosti i
_vra6amo ga kao re tat iz funkcije.
] (
5 )
1
• .." _,,.;.: ~izdale~ iscrpljene SV~•moguenosti primjt;nepoziva11:ja konstruk!:Qil[!cl;odj#cija:®a --
hismo uVic:ijeli jo~ 11eke primje11e, tazmotrimo prvo jedan primjer kako Se nilpisane timkcije mogu
primijeniti. Primjer je jasmi. sam po sebi, i ispisuje {a , l1 J : ·

t.//
Kompleksni a {3, 12), b {5, -1);
Kompl':'k_~_ni c = ~birK'?~,f'_J.-.eksnih {a, b); . ~~-..
r[
L
/111 c. Isp~s~ {).; . ·..0 :,-:-

Medutim, Cinjeniclida se ko11struktori mogu pozvati kao fimkcije omogu6ava i ovakve ko11strukcije:
{
~
-,- --~

. ,; j Komplek~ni -~·;;, ZbirKompleksnih{Kompl eksni {3, 12), ··Kampleksni {5, -1));

-i
VV c. Ispisi {); • . ·

· Ova konstrukcija je efektivno


.
ekvivalentna sljedeCoj konstrukciji:
. .
. ·, . . .. . .. . ·. ·.. ;. _Or[
w· ~<--·.
. • ..JComplel<sn±, Pi1,.vr~eni1{3;·12),, Pri_v!;.emeni2{5, -1); , · ... · ..
'rfomplekSni'c .::.z~irK()mp:ieksrr:ih{l?r£vr.eni.e;,_':ij_, Privremeni2);.
c. Ispisi {),}.·
: .
-
(
Na osnovu o11oga sto smo vidjeli u prethodnom poglavlju o mf'hanizmu vraeanja ohjekata kao rezultlta
1Z fuDkctJa, jasno je da su tp.oguca 1 SlJedeea konstrukcija: -
-
...... ---~ ''i{ .: . .. .. ... . . .' ....
ZbirKomple1<snihJI<a!!lpl eksni_{3, 12), Kompleksni {5, -1) J. Ispisi {); .£1f/
[
!!1• Ipak hitno je 11apomen~ 5o preno8enja ~hjekata koji _ vraCeni kao rezultlt iz konstuktora direktno kao sn [
parametar neke-druge furikcue mogu6e samo. u .$l!i&ju se 0 ovara u6i foriiililiii arametar prenoSl 0 aa
vrijednosti (kao Sto jeste :z3 slu l\1 fimkcije Zb'irKofuplekstiih). Ukoliko hi se formalni pimunetar -
prlhvatao po referimci, tada hi odgovarajuCi .stvlirJ!i •parametar ·mofa!) hiti promjenljiva ill batem
1-vrijednost {npr. element niza ill dere(er¢11~ pokazi"ll9): Medutim, ffivremeni objekat koji II [
· konstroktor vrati kao rezultat nife 1~y,-ijediiiJ$f, te;se 11~ liJ.oze ~l$iti li fulikcije po re[erenciJ
. . ·- - . . ::. :
·
'- '•,_:.~:-;.-:,. . __ '·-~r· - . . .
'• -
Sve ~ je ovdje reeeno, cSsta je pos1je<lf<;<~..,Q!njenice da se ko11S!rukto~ mogu pozivati kao fimkcije, i [
potpuno je u skladu sa oCekivanjimil. Medutim ;~osve neocekivanp,.~e i sljedeCe konstrukcije: ·
.
·
>
- ~0
.·;.• .• ,
. -
Kompleksni a{3, 12), b '=· 2, · c, d;c'f/,c '·· •·
[
c = ZbirKompleksnih {a, · 4) ·;
d = 7; .. . '.- ·_. . . r- _- .. -.
-
U ovom · gem ohjektima tipa~kompleksni dod:et ·efrw· realne bro ·eve, inicijaliziramo ih realnim .
u
bro 'evima, i• sal'emo rea ne. brP.f~e fimkciju· koja ocekuje parametre tipa Kompleksni! .Pri tome ·
u-

"
ukoliko ispiSemo sad!Zaie o promJ .. lfl VI, u . . o sn se u. ovom pnmJeru re · brojevi
• •
· pOnaSali kao elementi klase Komplek·· -.: sa 'ID"g111arillm di elomJet!naldm mill. Neko hi naivno mogao
po Je ovo posve pnrodno, s ·... · om da' se realni brojevi zaista mogu shvatiti kao specijalan
u
slu&lj kompleksnih brojeya_Medutim, piavo pitanje je ko/fo.kompajler ovo mole do zna;'S'·obrii:'dirrda- .,
Kompleksni nije ugradeni tip podataka, vee klasa koju smo mi napi.saiil? Tim prije Sto slican pokuSaj
da objektn tipa Da ttl!!l pokuSamo dodijeliti broj 11e6e uspjeti... ·

., Odgovor na ovu misteriju leZi u konstruktoru jednim parametrom ko 'i smo definir;ili unutar klase sa
, . Kampleksn!, aime, ko
specijalno znaeen~ g po
kOmPaJ1er DeCe 0 "aviti es D 0 Ce 0 .eritt da fi maZda ta klasa sadrZi konstruktor sa
j J!liil!!Iletrom koii prihvata kao paran1etar tip onoga §to po~aino d jjeliti o ~e Uko · I) ,
tak8V konstruktor 11e postoji, biee prijavljena gr~ Medutim, ukoliko takav konsb:uktor postoji, oil ee
hiti iskori§ten da stvori privremeni objekat tipa te klase (kao da smo konstruktor sa jednim parm'!!eirom
pozvali kao fimkciju) uzimajuCi 0110 Sto pokmavamo dodijeliti objektn kao parametar, te ce nakon togu •
stvor~~at biti iskoristen umjesto o11oga ~ pokmavaliJ.o dodi.jeliti objektn. Drugim rijeeima,
dodjel~ zapravo interpretira kao · /

6 ~
n
.. ,,."""~' \ d ··~~mp~ek.sni (7h; { _ . __ · .... ,~_ ......

Sliean proces se odvija i prilikom pren,o~enja parametara u funkcije, tako da se poziv ·

c '= ZbirKomp le.ksnih(a, 4);

zapravo interpretira kao

c = ZbirKomp lekshih(a, Kompleks ni(4)); . ;

se
• neke klase
·
. . .I
Na1·
neophodnu •

parametar\!)
: OM
ntZaCljl su tipa Kompleksn i deklaracijom poput
. ~Kompleksr ii *Dinamick iNiz = new l<ompleks ni [100};. U/. !
f
Nainte, i u tom slucaju, svi elementi stvorenog dinamiCk:og niza bill bi inicijalizirani konstJ!ul5torom bez
_parametara

t Situacija je znafno SloZenija u slu~ju da klasa inla konstrukt~ie, , a


··

~.ko
L . or )?llZ
parametara. U tom slu~ju, neposredne deklaracije nizova klasa (kako statiCkih, .tiJ.ko i ~Ckih) hi$P... · ·
moguce. Na printjer, nijedna od sljedeee dvije deklaracije ~;§e biti prihv~: · · · "-----'

(
I 7
'1
!
~
.: ~ _ V,;p;<t.UI!L~N:b;<.Patuma[10.0]; :. . - - - .• ,.,.,,. ..,U , - '"·" · ·· -···-~~· :c...,J
-- . 1\ Datuin *DinaiitickiN izDatwila = new Datum[100]; 71\ ~
~ f, . U ovakvoj situaciji, mogu~
je d~Jdarirati
·edino sta~cki
i ici alizirani niz klasa ri eemu se ~
• • ·· ~?ija1izaciJa e emenata mza vr J. od rna kojeg drugog niza (navodenjem Zeljenih elemenata niza
unutarVilicast ill zagrada). Pri tome 8e moraju navesti svi elementi niza. Medutim, kako su u ovom
slu~ju elementi niza orimterci klqse tih elementi u VIti&IStllll zagractama mora.jn bjti takoder primjerci
iSte klaSe. Slijedi (t(oni moraju biti ill promjenljive iste klase, ill rezultati primjene konstruktOra
pozvanog kao fuDkcija Na primjer, sljede6a konstrukcija se moZe upotrijebiti da kreira inicijalizirani niz
1
od 5 datnma· ·

Y/_ Datum NizDatuma[5 ] ·= {Datum{31, 12; 2004), Datum{B, 4, 2003) 1


~
[
VV. 1 Datum{14, 7, 1998), Datum(4, 11, 2000), Datuin{6, 2, 2005) };

... ;:···
~~~~~~~-·~~--•..~
.......... ~
.. ~-"l!.~_s;__ .•..-~-.-1
W
,., /Datum D{1, 1, 2Q00);
Datum NizDatuma[1 0] =
.
{D, D, D, D,. D, D, D, D, D, D);

niza na
1
~

izvrSiti inicijalizaciju na .( 0, 0) u · se
primjer, za ldasu
. ne navede, medutim
~
~
nije- posve jasno na koje vrijOOii.osti bi trebalo)nicijal izirati elemente ldase Datum u sbicaju da se
ekspli~tuo ne navedu dan, _mj~ i_ godina Sto~~ je bolje Jje~le umjes_tg;!NE'!ldasa koris_titi_~tzove /
pokozNaca na k/ase. Ovo IJeSenJe b16e demqnstrJrano lilalo kasruJe. · ·
"

1 sve
niz konstruktore sa
nemora
~
elementi biti

~
paran1etara: Na primjer,
moguee je deklarirati sljedeCi niz:

v¢' Kompleksni Niz [10] .~..:·;;~omp1eksni(4, 2), Kompleksni (3), 5};

~
. -~-~~

U ovomprimjeru elen~ent Niz[OJ biee inicija!iziran na (4,2), element Niz[1J na {3,0), element
Niz [2] na (5, 0), a ostali elementi na {0, 0). Primijetimo daje inicijalizacija elementa Niz [2] na.

~
·{5, o) navodenjem samo broja 5 moguea zahvilljujuCi pretvorbi tipova koja se. ostvaruje pomoeu
konstruktora sa jednim pmetrom ( ovakva inicijalizacija U:e bi hila mogu6a da je konstruktor sa jednim
Param.etrom klase Kompleksni definiran kao eksplicitui kol!Sfi:Uigor._po~~ kljllCI!.e_ rijeCi -~,;cit),
·.. -~ l

Opisani problem sa konstruktorima i nizOVima klasa u praksi ne predstavlja osobit problem, s


obzirom da se u objektno orijentiranom programiranju mnogo Ce56e od samili nizova klasa korist¢ n.izovi ~
pokazivaea na k/ase. Razlog tome je Sto eesto ne znamo unaprijed na koje ~ treba inicijali$ti. ·,
~ente klase. Pretpostavimo, na primjer, da Zelimo da unosimo podatke o deset ~ sa tast;iture i ·
da ill smjeStam.o u niz. 09igl00Ii.o, ne moZemo znati na koje vrijt$,osti treba ini9ijalizirati dlltiii)l prije
nego Sto podl!tke o njemu unesemo sa tastature. Ukoli'ko bismo d~klarirali ni!ptavili obi.can niz datuma,
~
~
on bi zbog postojanja konstruktora moraO na poCetku biti inicijaliziran neeii:n, bilo ru:Cnim navodenje.ID
inicijaliziacije za svaki element, bilo dodavanjem konstruktora bez parametara u kli!SJl Datum koj;l 11i
izvrSila neku podrazmnijevanu inicijalizaciju. Medutim, u oba slueajli radimo bespo!reQ1lu inicijiiliz8cijl)..

~
Objekata kojima CemO svakako promijenjti S'li&ilj Cim se podaci 0 kODki'etnoin di$illi11 unes'u sa
.tastature. S~mnogo bolJe deklaristati n~kozhiaca na Da tmn, a saine dlltiii)le k:teitati dinainicid
' pomoCii operatora new onog trenutka kada po o DJemu budu poznati. Nakon toga eemo pokazivae na
'
' ....

·'" U.
8
lJ;
_... _j •••
<

[} ...
l~
.n .
;>

.. .novostv<irlmi. objekat, smjestiti u niZ; .a-samom objek:tll Cemo .indirektilo priSfiliiati. pre~kazivaCa.
!!
1

Y HUSirirajmo ovo na konkretnom J)linijeru.. DeklariiaCeffio niz


pokazivaea ria Datum,koji cemo nazvati.
- ·~ •.
~;.. NizD atum a (i~o se, striktno reCel)o, radio nizu pokazivaea
nadatume): ·
G vt:lo atum *NizDatuma [lOi;
. ,· .· ..

p-]' Bitno · istaci da nizove okazivaea .na .klase uvfek


_ blema bez obzira
lS kakve k:onstruk:!?re: _a;>~P. (s ~?zirom da k
inic
'' k!ase, tako da ce lDlClJ ori ne ij~~ju_Po~vaCe, n~go prmyer e j
ya bill odgodena ia trenutak karla dinamicki krerramo Objekat pOrnOCu 0
'"" operatora new). Dalje sa ovakvim nizom pokazivaea ~kla
se moliemo raditi kao i da se radi o nizu
ristiti operat~r@ Na primjer, za ispis ·
[} \ . klasa, samo cemo za poziv metoda wnjesto operatoraL_:/ko
L . , treCeg elemeJ;J.ta niza umjesto NizDatuma [3). Ispi si () .koristicemo NizDatiuna [3] "'>Is pisi () ·
~ (podsjetiJno se da je ovo zapravo ekvivalentno sa (*Ni
I} .. . CinjeDJca . r
zDat uma [3l). Ispis i () . Prema tome,
o sa pokazivaCima_ na )dase ll!lljesto sa klas!II!!H gotOvo
da ne
·
. , , '·"· ,,,_,.•.~~:£#·!!;cije cinji:liice!·@:9~".; 1D1Qsi ilikak vn ·
1.-l. . memorije {mad aje veoma mala sansa dace se
E!w ·mo~ baciti·.·.izJI.ze.ml!!~;il-'<Slu9iii 'd3: 'pon-estahe' "'''··· · :;.:
ovo desiti, s obzirom dajedan·datum zanzima veoina
G'"
1
malo riremorije) tako da treba predVidjeti hvatanje izuzetka,
treba na kraju i izbrisati. Sve ovo je demonstrirailo u slje
diiiiiijia sa tastature, i koji nakon toga ispisuje sve unesene datum
i ~sve diniuniCki stvorene objekte
dece m~amu, kojitraZi da se unese 10 ~~

Q .-. .
'iJatilin w:&I zl5atiililii' rror;
e:

~1 int ii ..
for( i = O; i < lO;_i ++) NizDat17!ll<i(iJ = o;.:
Q
'"
.~t"C~<-'::i~~.}~~atuma:\n"; :. >~· .
1( _for (i = 0; i < 10; i++) (J)~~~A
n .~nt. Dan, ~jesec, Godi na;
IJ" 1
cout << ' Datum. " << i + 1· << rr :·". << endl
;
; . cout << " Dan: "; cin·> > Dan;
~- L
cout << " Mjes ec: · ";_ cin >> Mjes ec;

~
cout << " God i_nk "; ci.n >> Godip.f_;
. try if) -af:,~ .. ·c~·.
L
·:t :· .,.
NizDatuma ~i. lJ ;.•-. ~ ,i)e~ .Datum. . (Dan,. Mjes ec, Go~:ii~a);

~
(JJ - :J...b''"'"" ~ 'l. W'
catc h (con st ci'iar · Gres.ka [) )·i_/7 .91~4,.,.1. '
~
i cout << "Pog resan datu m!\n ";
,._ i--

(JJ~ ~~
0

11
U "~ 2 ~4;".
· for( .
cout << "Un ijeli ste datuin~: \n" ~
i = 0; i < 9; i++). { ·""""'"""

g NizD atum a[i)- >Isp isi() ;


~61.~.2..

~-
,. }-
. ..
cout << end! ;
} - 1<th" "- ~ -2.
~.,J;...,.,.,

1
-hl.:~-
catc h ( ... ) { _ "t:i/.""""""" c,.j,A, 4
,. cout << "P;o blem i. s~ memo rijom ! \n";
} - .:j,"""'""''
0 "'"'..... .1
1 ~=o ~ ~: ~ ::+~e:l::f::a:::~ inici::r::~Ul:a;::t:.~~ da /

~
izb' emo even e bleme na: kraju sa dele te operatorom u sluea'u da neka od aloka
nije uspjela Takoder, treba primijetiti da, so zrrom je NizD cija Slueajno •
atuma ~biCW gtatiCkl niz inicij~JU
. njegoVih elemenata na nwe smo mogli izvrSiti i bez for petlji;
; deklaracijom poput / .
' pna tum *Ni"zDatuma[lO] = {0); /J:/
"

~ (
class Student { .
c:liar Ime i prezime [50.] ;
int Indeks;
Datum DatumRodjenja;
public: .
II Ovdje bi trebalo definirati interfejs klase
};

DatumRodjenja
nekog objekta tipa Student.
odmah

'

01
f.c
1
DatumRodjenja u skladu sa U konslruktor Jdase Student, a zatim ce
unutar tijela konstruktora iuicijaliziriiti proo_Stala dva BJributii !me_i _pre z ime i Indeks:
1
class Student {
char Ime_i_prezime-[50];
int Indeks; · 't
' .

:..-··"'·'··
. . .

1
~
Datum DatumRodjeii.ja;
public: . ~
-· Student (const char Ime [] int Ind 0
~
~ DatumRodienja(Dan, Mjesec, Godina)
strcpy(Ime i_prezime, Ime); Student::Indeks = Indeks;
0> . -
II Ovdje bi trebalo definirati ostatak interfejsa klase

....~
};

J) Neko bi se mogao zapitati za5to su se morale uvoditi konstruktorske iuicijalizacione Iiste, odnosno

~
• 'Z,. zar nije bilo moguee dopustiti da se samo pri deldaraciji atributa Da tumRodj enj a napi.Se neSto poput
Datum DatumRodjenja(14, 5, 1978);

10
~
II
ul j
. '

~
[h '(0:·:·--n~f:-;.:._:.:: ·~:-~~- .• . -·~-'>- ·' .... ~. ~.......... .........
kao .k()~ deklaracija obiCnih PI:Ontienljivi,h tipa Datum. RaZ!og za to je
s]jedeCi: da je omogu
.. :.s. . ;o.,.· ..-. < • •• ····_d•:\' r :~;·.§-;:;.,_..~ .•. _·.-_.

w :pO~ednosiavljenje, S!:Lobjekti tiP!' s~~~~n~ bi_uvije~ inill1i atribut D~tumBodj enia inicija eeno tikvo
liziran na istu , I
f.} vnjedn ost Ovako, konstmlctQrske .JlllCIJalimone liste omogucavaJu
definira kako ee biti inicijaliziran atribut Da tumRodj ehj a.
da ~onstruktor cibJekta Stude nt •
"J
Konstruktorske inicijalizacione · e moraju se koristiti za inici'alizaci"u
!} J>iti propisno llllCIJ
onih atribu ko 'i mora·u
am. M utim, ·one se mogu oristiti i za inicijalizaciju ostalib atributa,
II
~ . .,I sto Se .i inicijalizacija proiJUenljivih sa prostim tipovima moZe obavlja slieno kao • •
ti konstruktorskom sintaksoi:n.
Tako Smo i inicijalizaCiju atributa Indek s mogli izvrSiti u konstruktorsko
G
,... ~cijomstrcpy): ··
j inicijalizacionoj Jisti (d.9k sa
.}!!!ihnww Ime,.io prezir ne to nismo,mgg]i.Jmuliti. ier on ~giexa strpstno k:gpinm ie znak P9 ~
· · ·. ··
[} . . . .· . : cl.;ss Stude nt { · . .
: ~ "-;·;,.:,;,,....,. " --'···, .,,.olla,!Zo-.J;me._),:;.Pre>;·4Jne[S9J,'-.;· '· '· .. ··"· :~- --~
~,..; · . . int Indek s; · .
f1_ . Datum Datum Rodje nja;
Ll publi c:
~. Stude nt(co nst char Ime[] , intin deks , int Dan, intM jesec .
, int Godln a)
Datum Rodje nja (Dan, Mjese c, Godin a)," Indek s (Indek s) {
·
[} .strcp y(Ime :.._iyr ezime , I-me) ~ ~
}
' ~ I

i.' I I Ovdje bi treba lo defin_ irati
Q }; <J~atak_
.
;.~
terfe jsa klase
/
~ -~

Q
......

J
.~

]
na

] [ int Broj = 5;
.· ...
d
i naknadnog dodjeljivanja poput
] 5'int Broj; .-··]' .·
~- . .•
•. .:-!1, •

. i ..,:··
·•
·.·;.::~'
Z.Bro j "' 5;
·. · . . •. !.' .··
J Naravno, atributi koji ne mogu ostati neinicijalizirai! ~oiaju se
inicijalizactonoJiisti (tu nemamo tZbora . og ove nunom e
ii'iicr alizirati . u konstruktorsko · /
e u efikasnosti. mnogi prograilleri sve •
Sto je moguCe llllctializirati )1 konstruktorskoj inicijalizacionoj listi inicijal
iziraju unjoj, tako da se Cesto
de5ava ~ wo tijelo konstruktora ostane potpuno prnzno. Na primje
J se mogao napisati i ovako (sa praznim tijelom):
r, konstruktor klase Komp lek:ri'

l
J
class Komp leksni {
doubl e Re, Im;
publi c: I!"'*'~ h..i~t.A'Jh"""' ,4ofq
~~Kompleksni (doub le r = 0, doubl e i = 0) ~
:_Re( r), Im(i) ~}
I I Ovdje slije di ostat ak ~nterfejsa
);
klase ... ~~

li
..
u

d
_,_____ d
~u .,
patnmRodj enj a, bez obzira Sto. je navedeiJ. kasnije ti inicijalizacionoj listil U veCini slueajeva:
redoslijed inicijalizlicije nije bitail, medotim u rijetkim sitUacljania karla je program'eru bitan redoslijed "
kojim se inicijaliziraju pojedini atributi, treba voditi raellna o ov<ij Cinjenici. d

d
.: :·.
~ -: --··
rl
L..:

f[
.,;.1~.1i11J:le•nt
(const char· Ime{•t;,·;t.; c.::
01:1rd'ie bi ;~:r<¥1:f,!ilo . ~·let'i~~;
'.· ..... ·'·
.) '{
~

i.nt M, i.nt G) '[


-
"'[
svalru . potrebu za
parametara! Medutim, kao
-
na '[
'-"

·-•
f

1
1
\ KonstJuktori predstaVlja~
alokacijommemorij1 .,e~(~i~~
1
bismo ovo uvidjeli, 1 · · n:ap~viiilo
(nazovimo je Vekto:r:N)
koordinata), pri eemu je. . n. 'nioguee Zlidavati; .. .
koji se
opisiije sa n
je uvesti atnlmte
1
BrojElemenata i Elementi, kojirespektivno predstavljaj!l dini.enziju\>~ktora"i dinamiCki. alociran niz
komponenti yektora. K1asu cemo ita.piSati samo sa minimalnim interfejsi>ni, koji cini ko.Jistrulqtrr bez
parametara koji ·inicijalizira dim~ju vektora na 0, a pokaiivae na elemente na l'lUl-pokazivai!, zatim I
metoda Stvori koja vrSi dinamicku alokaciju, metoda Unisti koja brise alocirani prostor, IP.etoda
Ispisi koja u vitiCastim zagradaina ispisuje komponente vektora niedusobno razdvojene zarezom, kao
i metoda Element koja omogueava pristup komponentama vektora: I
-~
/ I
(
( --u
.
I 12
fl
"

···-~····'""'class VektorN·.{ ·-'<r'~ -. -, ··-·! ·•:1,,~i-:· .., ~--;:.~ .. ·· , __ o

· · int :BrojElem enata} · · , . ' .• u. .·


· - L .J • · II' -.4 .:,. .. ,.~:- i)J<.ic li-~o"''t·.". .f'l'r .
double *Elementi ; "'"'"-' '' !IM<•• 1 <
public:.· ~~ . II iJ
VektorN() : BrojEleme nata (0), Elenienti (0) {) 1zt~<-<-UI«,'
void Stvori('in t N)·· { BrojElem enata = N; Elementi =·new double!Nl_ ; )
void Unisti() { d~ete[] Elementi; )
void .Ispisi () ;
double &Element (int N);
);

Slijedi i implementacija metoda I spi s i i E 1 eme;; t koje nisu implementirane ·okvim klase.: ··
::~~-.
u
- . .
-v'oid VektorN:: Ispisi () r>
cout << • { •; p; ::
for (int i = 0; i <. 1; i+t')

cout << <<


cout "'~:~~.fai~~:;~:~~~~;i~;~~
Element!. - 1]
}

-double
if(N < •.:?
indeks! \n'{.;.. ·.
'._;•
:--,;
J
Implementacija metode·· ·. j ~! :
u dozvoljenoin · ·nriiil111fit fJlfltno'
uobieajeno u Il!lllb:mllltiC:i}'\i
metode

VektorN vl,
try {
vl. Stvori ( 5 :
•· ~}:El<3111E>n};

"1J:~J'-f:!~,~~~]~4f
v2. ~s.pp:uL;"·
vl.
}
catch( •.. ) .{
·-:.
cout <<
}
vl. Unisti () ;

ovomogu6e ).

Bitno je primijetiti da neee nastati nikakvi problemi zbog pozivanja metode Unisti u sluclijti da
kreiranje nekog objekta nije uspjelo, zbog Cinjenice da je konstruktor inicijalizirao pokaziva& na
nul~pokaziv!W, a·znamo da operator del10t!O ne radi niSta u slilcaju kada. se primijeni na nul-pokazi"i'i1C~
U ovom sluaaju. konstruktor nas autoiniltski tje.Sava mnogih briga (sjetimo se primjera u rimijlm.
poglavljima u kojima smo se o ovom problemu morali Sl!Ini briuuti).

13
II
IL

R
pri
Mada
VektorN on _ a
l'rimijetitiW da se-p!V~«'
.inu dimenzionaln.ost
~~R
odreduje Mnogo je pametnije ·umie8to konstruktora bez parariwtara- uvest!Jcinstruktor sa I
jednim parametrom k:oji p~vlJa 4jii@:M ~ koj~ ee odmilh pri d~araciji yekiO~ ~ti '
, (!illlllili&U 8loklWtJU memonJe. Na taJ _ _m
1 odllliill nakon Sto je stvoren, i neeemo imati
o btti Sl
prob~ema
da vektor rma ISpravnu dimenz1onalnost
ukoliko ucaJnO za oravrmo pozovemo ~
metodustvori. Ova metoda o vi§e neee Iii sto' · · a n'enu ulogu pteuzeee konstruktor sa
}ednini parametrom. Tako vi8e ne6emo moCi ni deldarirati vektore Cija enzija riije. specifizirana.
Umjesto toga, !leljenu diinenzionalnost vektora zadavaCemo priliko.tn njegove deldaracije. Slijedi nova
definicija klase vekto:r u kojoj je dinami~a.al~kacij~ ~emorije povjerena konstruktoe . _ ....-....
t
class VektorN {
int BrojElemenata;
-~
· ... .. ·: .. -
double *Elementi;
-P1#if.:iit''vektori< (int~{fr·rs'r6j'E:!emtri:ii!~ d'i:,:r;· -E1em:e'n:u. = new do.)bl.e [NJ i't ·
{
vo1d Unisti() {delete[] Elementi; }
void Ispisi 0;
double &Element (int N); {
};

~

~
[c
Zeljenu inicijalnu -~
(
, Ei'e:menti (new double [N] ) (f.!
-explicit
for(int = 0; ·..., fr+<> _li[j<l.o (
(f) -~· -
1 (J
~
Na taj naein,
-
try {
VektorN vl {5), ·_ v2·(3);:t'
vl.El~ent {1) = 3;- -Jl:Et,~etlt {ZJ =·'/5; vi. Element (3) = -2;
· · r... !,
u
-
vl.Element(4)>)" O; vl·-~~nt(S) ..=;.1; ; :.·

v2.El~e':t (l) = 3.< ~2 .EJ'eJ$?~t.i<i!> ;,; 0; v2_.Element (2)


~
2;
vl. Ispl.SJ. (); v2. I!lPJ.si (); ·
vl.Unisti(); -v2.Unisti();
}

--u
catch( ••• ) I
cout << "Problemi Sa memorijom!\n";
}

Ul U ovom u
-
' 6 •

u
-
14
;
i
(
I
u
11
IJ

. . . . - - ,-
~~~~~~~~~~.~~~~b~il~o~b~i~~~~ _,1/"
- ' - -
'~ ___ · . _, -.
.. .i; .Da bi Se izbjegli ovakvi problemi, a takoder i piol.>leini koji mogtt nastati zbog cmjenii:e claje veo
Iako zabordviii eksplicitno pozvati meto du za Unistavruye ~
objekta (meto du unis ti u naSem prinijeiu) ~
Sto bi svakako dovelo do curerija memorije, u je~ C-H-
su pored konstruktora uvedeni i t,kstrukton.
Desti uktor . o ut konstruktora, neka vrSta :funkci"e clanice klase ko.
a se au tski 'ziva ono
trenutka k~ objelg!t te ase prestaje postojati (tipiCrio
na kraju bloka un . ~eg 1e obj
· deklafuan. ili po izlaSku 1i funkcije u koJOfiJ objekat
1 deklariran j>omo6u naredbi retur n. ill throw.).
Zadatak destruktora e cia oslobodi dodatne reSui-se koje je objekat 2:auzeo prilikom
svog stvaranja,
, o osno p om poziv a konstruktora (ti resursi su o 1 · o 'namiCki alocir
otvorene datoteke na diSkii; i druge stvari). Slicno konstrukto ana memo rija, · mogu 1tt1
ru, destruktQri f<!koder neniaju ooVratni tip,· ·
.ali za razliku od kopstruktoJ!J..-.~~ !Yr..dane.wa·'(UI·na·ramet
nalaze. samo sa mz!!ksom (7'~ ispred im~ Slijedi an .. a iine jm je istn kao.. imt'kl.ase. kojoj se.
primjer klase Vektor~ u-kojojsm,oudefin

. .

irali /
destruktor (njegovim uvodenjem otpal ajepO treba za metod
om unis ti): ~ '>: ,., ~: '· · · · · · · ·· •

r
·
alas s Vekt orN (
. int Broj Elem enata ;
doub le *Ele ment i;
publ ic:
· ~:r:n:•n veul 5rNf i"nt NJ: Bro]Eiemem.a:ta (NJ'. :ElemeriH
-Vek torN () ( dele te[] Elem enti; } ~ (new Q.olilile tN'ii 0 ~b~,
void Ispi si ();
doub le &Ele ment (int N);
};

f'
brinu ti o tavanju. objekta
njegovog stvaranja):
/ r • -i
~,_::~
try ( . .. .. . ....,,
Vekt orN vl (5), gvliJ (3);; -: "''. ,
vLE leme nt{l) = 3; 'l'l-E leme iij:(2 )·=.·5 ;. vl.
vl :Eaem ent (4) ;;. O; ii'LE leme nt(S) ;, i;'•< .= -2;
...
v2.E leme nt(l) · =· 3; v2.Elem~nt('2). = O; it2.E
l
vl .• Ispi si () ·; v2. I,;spi si () ; · "' ti'~
' . .
} -~~-
.. ~-·--
'

; . , ...----·
catc h ( •.. ) ( · . . .
cout << "Pro blem i s·a mE;mt~rijo~-! \~";-·.
}
·>• -~

II
l
.,
. ·;-_..

I
Iz izlofe nog se vidi cia su destruktori veom a korisni, i oslobadaju
nas mnog ih problema, a njihova
deklaracija je sasvim jedno stavn a Zbog toga se moZe
smatniti pravilom cia svaka klasa koj~ ima
konstruktor u kojc;111 se vrSi dodatno zauzimailje raCun
arskih resuri;a (tipiean primj er je din:imiCka
alokacija mc;morije) obavezno mora imati destruktor, koji
zauie ti pri!ik0m izVrsaviuija lroliStruktora. Ipak, poStoji
ce osloboditi S\'e resurse koji su dodatno
i jedan pote.D.'cijlilni problel)l o kojc;m se do$ia
II
•••
rijetko govori (ali JiaZalost s=;m:oblc;m D:i~e rijedak) ~?ii
destruktore. O~problc;mu cemo govon ti malo kasniJ IJlOZe nastnpiti kod, J?.as~. koj~-r!fj@qju
e, kadii kada budemo obji&iJaVali oge z~
uvoaeilje tzv. konstrukio ra kiJpije. · · '· · ··
(
I
----- ... , ~,je.. reeeno"d8.:.5e de~ri. uopee ·Iie
n
kotiStruktot nije do laaja iZvrSio.
~>t-'<'-t

~
I ~
malo··

.
Matrica sa
i destruktOrima. Takoder, bimo je
n:~~~~~~~ da je veoma negrW!loruClHvo bag!lj iP'?ietke iz tiestruktora (sreeom, ovo je rijetko
~
p Madaje to u prine1pu CIOzxoljeno, bacanje izlizetaka iz destrulaora mou il nekim situacijama

•. . •
iZa':Wati veoma Cu!)ne efekte, tako daje bacanje izuzetaka iz des1:ruktQra naj~lje potpuno izbje6i. · ·
. . ..::-·· :.·_:· ;_.;.o>·;: Y-- .· ~ . .:J~·-~· ..:· :_·: :.. ~·.,._,-"'. ,.;:. -~·-; ____ ; ;:;~;-·: .-... . -. :- ,.., ..
·~
pestruktori se takoder automatski pozivaju i pri upotrebi operatora delete i delete [ l u slueaju da
' smo sa new stvorili objekat koji sadrZi kotlStrilldOie i desti:uktore. Na primjer, likoliko smo dinamiCkt
stvorili neki objekat tipa VektorN naredbom poput ~
~
tJ/'y§!~t;g_J;:!L~!?Q~. ;= !'!~W Y§.l>tm::NL?.l.i
~ Ce njegovo.brlsanje pomo6u naredbe

delete pok; ~
~
~
.,
~
~
c~
. . { . . ...

~
Na osnovu specijalne cloge koju irilaju konstruktori ·sa jednim parametrom (automatska. pretvorba
tipova), ovakva naredba hila hi interpt:eni-aua kaO · ·
· [v1 vektoiN('i) l ;_ d~ll,;~~r~· ::t: -ol.}>.., •~ d~~ ·o6;r~. V;,. -··· ,., . :
~
=
. :~~:;:::~" . .
Rime bi se postigao sasvim neoCekivan efekat: stvorio bi se novi, sedmodimenzionalni vektor, koji bi bio
dodijeljen objektu vl (a_usput bi se pojavio i mnogo ozbiljniji problem uzrokovan glitkim koniranism 0
kojem eemo govoriti k8da budemo govorili o konstrnktom kopije). SiiCna neoCekivaila s1tuacij11 ~
bi ~o!fr~ bi nek?} funkciji koja oCeknje .obj~t tipa VektorN kao parairi~ bio. pr~slij~en. brQ~ (~j I ~
~

brOJ b1 b10. prOslijeden konstruktoru sa jednim parametrom, nakon eega b1 k9nSii)i1Sam obJC::Ja!t b10 .
proslijeden funkciji, a to sigumo nije uljeno pona8anje). Ovako, oznaeavarijem konstruktora sa • ~D
c
~lici},{ zabraniuje se njegovo koriStenje za automatslru pretvorbu tipova iz cjelobroJucog n tip
VektorN, tako da ovakve besmisiene konstrukcije neee biti ni dozvoljene (g. dov~ do prijave greske .
. od Siilliili kompajlera). .
~
u

16
u
·__,
•f1;
I
. · ·:- ·- • 'Ve6inu stViiti okojimif smo do sada go\t6rili il~a sijedeei pro8mm,
prograi n za obradu rezultata ucemka u Iazredu koji je bio napi5an u poglavlju
kojLoliavija::iStu kaofiuikcyii
0 strukturama, samo Sto je
napisan u duhu objektno orijentiranqg program iranja Program je prilieno dugaCa
k i relativno sloZen, pa ·
ee nakon njegovog pril<lwi uslijediti detaljna analiza njegovi h pojedinih dijelova: · · · · ·
#inclu de <iostr eam>
#inclu de <cstri ng>
#inclu de <ioman ip>
using namesp ace st.d;
const int BrojPr edmet a = 12; I I Pri testir anju smanj ite ovaj broj .

clasa Ucenik {
char Ime[20 ], Prezim e[20];
Datum Datum Rodjen ja;
·. ;:n.1::·o-c:]-eners.roJi:'reametal; ·
public : .
Uceni k(cons t char Ime[], .const char Prezim e[J, -into;_ -
void UpisiO cjenu( int Predm et, int Ocjen a);
int M, int G);-k~
double Prosje k(); ·
int Prolaz (); .,. .
; void Ispisi () ; '-~ ,;/
1
clas~ ;Razre d { .. . . . .·
:en z Kapac itet, BrojE videnj :iranih ; ..
Ucenik *·*Uce nici; ·· ~~ ·
public : . . . . . _
expli cit Razre d(int BrojUcenik~) -~ Kapai: :itet (Broj'( Jcenik
al, · 1 .. I. ,__,
BrojE vident iranih ( 0) , UCE!tUCi (new Udmik '> [~rb:)Ucenika]
) {I- e~.rt.
~Razred();- dPat:-uJ.o.kot · · ·· "'4~ ..·n., ../(~·,/:, · ·
void Eviden tirajUc enika( Ucen;i .k *U);
void UnesiN ovqgU cenika () _;
.. r·~ "'<~ . .}"f<
void Ispisi izvjes taj () i
..,.""V<t
);
.' ..

\l¥in t main() { - ~"""""'· ~ '


int BrojU cenika ;
cout << "Kolik o ima ucenik a: ";.
-~{f-BrojUcE!nika;. . :•. ·;U,_,_,,_,,.: -· _ -'''--'
Razred R (BrojU cenika ) ;
for(in t i = 1; i <= BrojU cenika ; l,++) \
cout << "Unes i podatk e za " << i << 11
\
ucenik a: \n";
R.Une siNovo gUcen ika();
).
R.Isp isiizv jestaj ();
tp
catch ( .•. ) {
co_ut << "Prob lemi sa ,memor ijom! \n";
)
)

(
(
r~ f
-'
Jl
l[
. ~ ·.
"~-
.,-£tt•o4:·
__ ~~;Qptum:~D<~t;wnCint•., int-M, int~Gt { ··-·"·~ -- --- ' ~.;...,.. :T.-1>
>.n BrojDana 2] = {31, 28, 31, 30, 31, 30, 31,. 31, 3o·-, 31, 30, 31}-; -
<'YA]
i~tWNI\. if(G % 4 = 0 && G % 100 != 0 II G % 400 = 0) .
· 0 '•JIA"-' ~..
"" v""""
Broj Dana [ 1] = 29;
'"'"'') if(G < ·1 II D <.1 II M < I II M > 12 II D > BrojDa,na[M- 1])
throw "Neispravan datum!\n";
Dan = D; Mjesec = M; Godina = G;
}
n
"'{'~--~~'(< - Ucenik' :Ucenik (const char Ime
~'";z;/.ct,;l-( >.n
. char Prezime [ ,
, >.nt M, int G) : DatumRodjenja (D, M; G) { ·
1[
Q. \ae~Q<
• •
.
-~
•<1Ci.'>'l1
_
.
if (str1en (Ime) > 19 II str1en (Prezime) > 19)

strcpy(Ucem.k .. Ime, Ime), -.:._1>~.*'~:;.1'1


.
throw "Pr~d~~acko ime ~li prezime!\n"; 1_ • ~·»'.w.l~o- .d<< \'f.:l~
·cyu, .fow · t.,.;..,.;;..· ..~·-'
l'l ~1, r 0 0 o/tl ~ r_··c-:~ ,- '"'f4
n
n
. . strcpy(Ucenik: :Prezime, Prezime);. •

for(int i ,= 0; i < BrojPredmeta; i++) Ocjene[i] 0: 1; -f4J4v·.?<


) . ,. . ' . ·, .. , .··. .--
. ' . .'. ' .. . - . . .. . ~- . . ' """:. ~- ..
voi4 Ucenik::U is' int Predmet, int Oc'ena {
if cjena < 1 II Ocjena > 5) throw "Pogresna ocjena!\n";
if(Predmet < 1 I I Predmet > BrojPredmeta)
throw "Pogresan broj predmeta! \n"; . • .
l Ocjene [Predmet - 1] = Ocjena; . -: _~ ~1/'AA r« od~otJ/".,1!4 '(YUchn.if
· Ir
.c). 0 ,J,1
~41e ~"r \.<>ii;t'i\{'_
~ouble Ucenik: : Prosi ek
c;toUb1e SumaOcj ena 0;
o { ~
.,~
01 ,:._)Q_ · for(int i. = 0; i < BrojPredmeta; i++) SumaOcjena += Ocjene[i];
}
return SumaOcjena I BrojPred.meta; ll
'
"""'--1:. o-Jc..
~~oio:~ t 1\-
!t<A-'-"' jW:_.,;_jQ
.int- Ucenik: : Prolaz ( l {
- for(>.nt i

return 1;.
0; i < BrojPredmeta; i++)
if(Ocjene[i] == 1) return 0; -
' . ,, '1""'
•1 • 11 j"'d·~'vwt
1. '"':''
,,
k
Ir
"<.-4 c-c;l"'
void Ucenik: .: Ispisi () { _________ ~ · tJ-fl"''~
. ---
t>Jl>(
jM
f ok.
' fY'V
~ ~ l'q lol«« ~~-
f"" ~\Jii4.- "))~ ~
!I ~ rv</ ptfW.·!!. -
~
cout << 11 Ucenik. ·ri · << Ime· <<. ~ "· << Prezime << " roden ";
f,p),~- \q
u·'"·;t( ·~{';~)e_
DatumRodj enj a. Ispisi () i.
if (Prolaz () )
cout. << " ima prosjek " << setprecision(2) << .Prosjek() << endl;
t
~
else ·
cout << n mora ponavljati razred\n";
}
,;f.---- (''t't i 0~1 ~vi ~~ r'f(lo(:
-~lcb.
~
Razred: :-Razred() {-
Wc-V¥' for(int i - O; i < BrojEvidentiranih; i++) delete Ucenici[i];
delete[] Ucenici;
Cl<-'l'uol
void Razred::EyidentirajUcenjkaCUcenik *Ul
if(BrojEvidentiranih >-' Kapacitet) throw "Previse ucenika!\n";
Ucenici[BrojEvidentiranih++] = U; ~
~
~
}

void Razred: :UnesiNovoqUceniki!J) {


~int D, M, G, LosUnos = 1;
char Ime[200], Prezime[200];
while(LosUnos) { -~
cout << "!me: "; cin >> !me;
cout << "Prezime: 11 ; cin >> Prezime;
cout << "Dan rodenja: "; cin >> D;
cout << "Mjesec rodenja: "; cin >> M;
cout << "Godina rodenja: ";. cil'l: >> G;
~
18
!
(
I
--~
: --. _,; ··<-.r- ·-~~~>-'·. '··- .. :
void Razred ::Ispis irzvjes taj(} "mL.fod ~r 1ft>vx
cout << endl; f.u/ILf_q :
for(in t i = 0; i < BrojEv identir anih; i++}
Ucenic i [i] ->Ispi si ();- z '~'"'t'ff ~iJi1if~l·

U .ov0111 programu su depnirane 1ri klase: Datum, Ucenik i Razred. 0 klasi Datum nema
se niSta
viSe ril6i nego §to je (j{j sada ve6 re&no. Klasa Ucenik deklarira atribute Irne,
Prezirne ,
Da turnRodj enj a i Ocj ene, pri eemu atri_but Ocj ene predstavlja klasicru niz Ci.ji je broj
demena ta
odreden koilstantom Broj Predrne ta. U interfeisu klase ucenik nalazi se konstruktor koji
iniciializira
atribute. Irne, Prezirn e i DaturnRodjenj:C. u"Skladu sa (za postavljanje
datuma rodeDJa konste se .parametra), a iwe osjene inicijalli:ira na 1 (l!lko da se smatra
da ucenik nije
za£involjio ptedmet sve dok ne dobije pozitivnu ocienu iz n~a). D3Ije su deklarirane metode
Prosj ek
koja vra6a prosjek ueenika, Prolaz koja vra6a jedinicu ukoliko je ucenik pro~ a nulu
ako nije, i
Ispis koja ispisuje podatke o ueeniku. Sve ove metode su dovoljno jednostavne da o njima
ne treba
po5ebno gavoriti. Pored toga, imamo i metodu UpisiO cj enu sa dva parametra koji predstav
ljaju lmij
predmeta i ocjenu, i koja vrSi upis odgovarajuee ocjene, vodeCi raeuria da se lie zada pogre8an
broj
tll-edmeta ill ocjena izvan opsega od.l do 5 (u suprotnom se baca izuzetak). ·

'·j~ii~~;K~ap~a~c~J.~.t~e~t~·~na~ V~ezJ.~.~ ~z~:aidan§it~p~m~a~"~'etr~oim,~ i ~ ~ ~ postaV~.~.~ ~a~ na~.'o;:·


I nulu, i vrSi dinaliliCku alokaciju niza preko pokazivaea ucenic i u sld3du sa Zeijenim
.•
kapacite tom ·
.
-'·-

' razreda
· ·
Pored konstruktora, klasa Razred sadrZi metode Eviden t·irajUc enika, UnesiN ovogUc
enika i
· Isp:i:~iiz"?estaj. ~eto~ E.vi.den~ira?Uc.enika.prima kao p~etar po~v~ ~obi~ tip~~
ucem.k, SIDJeSta g~ u din31DI~ mz eviden~ u~ <m;eko pokazivaea Ucem.~J.) 1 po:vecav
a broJ. .
ev~dentiranih uCenika za 1. Pri tome se baca izuzetak ukolikO Je razred eveiitual
tto vee popunJen. MetOda
UnesiN ovogUc enika traZi da se sa tastature omovni podlici o jedn,om uCeniku (ime, prezime
i <W:um,
rodenja), ki"cira dfiiiiffiic:td novi obj~llt tipa Ucenik koji inicijalizira unes¢nim podaciinil,
traZi. da se
unesu ocjene za uCenika iz svih predmeta, uptSUJe unesene ocjene u kt:eirani objekllt (pozivoi
n tilet<ide
. UpisiU cj <mu) i, konaeno, evidentira uCeirika (tLupisuje g;1 u dit!llllii~ kreiTani. niz u~enilql)
poziv<>in
metode Eyicten tirajUc enika. Pri tome se hVilmJu SV11ZUZeCi koji bieventu alno mog'if'bi
, ti baeeni

19
J[
~~~~~~~~g~~~~~·iaiun~o~~~-~SF~I!i,o~nru~:v.~ij;a~s~veidiok~,;se~ne~uni~~-='.==~·· •.• i

I[
, l nse destruktoru moire ·. reswsa su na
Pf objekat koji se uniStava, a ne nufuo samo resursa zruizetih uii'utar·konstruktora klase.
~~~
J

n
. . . . . . . . . -· . . ·. ··_ . . .

, 0$1je jqs da se osvruen:to.na glavni program~in fi1n1Nijij ;Nak~n Sto smo prakti&tu•sve-po-slove-; ..-I[
povjerili klasama, glavni progi:am posaye trivija)an. U njemu se. nakon Sto. se sa tastature unese .zelieoi

~
broj uCenika urazredu,prvo deklarii:ajednakonli:retna instancaklase Razred sa · kapacitetom, a
zatim se ovom Jnstancom u petlji poziva metoda UnesiNovogUcenika · sve dok sene un svi ·
uCenici. Na kraju se pozivoni metode Ispisiizvjestaj ispisuje traZeni izvjeStaj. ~ve ovo je

~
.....uklopljeno.. u. ..try-.blok~koji..lwata-..e:ventuitlne. izuzetke.k<>ji-·magu-biti··baeeni·-sa"mznih·-mjesta·ukoliko·
neka od clinamiCkih alokacija memorije ne uspije.
.-,_·
Citatelju ce sigurno ·. upasti u oCi da je ovako napisan progJ;lllll skoro dvostruko duZi. od slienog
programa koji je koristio samo struki:ure i bio napisan u lijsto proceduralnom dubu. Zbog toga se · ·
postavlja pitauje da 1i se uloZeni trud isplati. Odgovor je svakako potvrdgn, s obzirom da je posljednji
Jr
program mnogo pogodniji za eventualna. proSirenja koja se mogu Iako rea1izirati proSirujuci :razvijene
klase novim metodama, pri Cem.u od velike pomoci mogu bi:ti metode koje su do tada razvijene. Pored .
·toga, razvijeni program iina strogi sistem zaStite od unosa besmislenih podataka, Sto nije bio slucaj sa
I[
izvomim programom.

~
~
JtJ
Da bismo uyjdjeli potrebu za konstruktorom kopije, razmommo Sta se u normalnim sitlilicijama

v< · ·,f.
de8ava kada se jedail objekat kopira u drugi (npr. objekat A u objekat B). Do ovakvog kopirafija moire
do6i u Cetiri situacije~ se neki ob 'ekat inlcijalizira drugim objektom iste klase,Vkada se 'ViSi
do.dj~l'ivan ·e. nekog objekta drugom- objektp iste klase, · se n · ·o ~e ·. .prefliJsl 'ptYVHjednosll il
w
\
• ci'u . se . ·. . _·. . . .. · · · a1ni arametar , if!s-8$ se neki
objekat vraea kao rezuftqt izfimlv;ije. PodrllZIIJ11ijevano pona8anje prilikom kopiranja je daSe svi atributi
objekta A presto kopiraju u odgovarajuee atribUte ob'ekta B. M~ kadli god obiekti §tdr!le A
~
~ • _po . ace, OVO po . ~evano k iranje dovodi do pojave tzv. Ut~ ·e koju Sll'IO VeC spOii\l:iiJaii, ./!~
t
' l _u koj~j ~on oprrarija ?ba objekta ~ po '!. oje po~ju ria isti o?iekat u ~ill:!i?fiii:.£_ • 1~
1rombinacijl sa destruktonma, plitke kopt;e mogil btti f'ata4te. N81lli.e, pllltp.o~vnno da ob;~ A 1. B """
• -sadrZe pokazivaee na isti diilai:!ricki niz li memoriji, i da zbog 11-ekog I82:loga obj~ A prestaue po!itoj$.
Tada ee se pozvati njegov destruktor koji vjerovatno briSe taj dinatniCki nlz. M~. objekat B (koji i
dalje Zivi) sada sadrZi pokazivae na uniSteni .
niz, i dalje posljedice su nepiedvidljivel I . w
- Razmotrimo jedail konkretan, naizgled bezazlen pr.imjer koji ilUS\rira ovo o Cem.u smo govorili
PretpostaVimo da irelimo klasu VektorN koju smo napiSali proSiriti ftwkpijoril ZbirVektora koj11 vraca ~
kao rezultat zbir dva n-dimenzionalna vektoi:a koji su joj proslijedeni kao parametri. Da bisnio ovoj

20
~
41
LJ
·~ •..
.

~-···h ·funkcijh>tnogueili"pnstup privatnini cSimoviii


funkciju prijatelja ldase:
lii ldilse ·Vek torN ; -deldarifacem6je u m~ejsu
·kliistf·ICao·

~'
clas s Vek torN {
int Bro jEle men ata;
dou ble *El eme nti; - v'~>1.r
pub lic:
c··
...
~
exp lici t Vek torN (int N) ·: Bro jEle
..:ve ktor N () { del ete [ ]. Ele men ti; }men ata (N), Elem enti (new dou ble [NJ) {}
voi d J;sp isi (); ·
y'

~
dou ble &El eme nt (i>;it' N) -; _
frie nd Vek tqrN Zbir Vek tora '(Ve ktor N
}; vl, Vek torN v2) ;
/ ....
..~ "


.,·
Implementacije metoda Ispi $.i. i El~ent
sti iste koo i nulije, a implementacija :nlc cije
.· Zbil:;~e~toradmogla bk izgledath>Vakll"(primj.j 4 . .
(;Qmo da je. ova funkcij@ rniii'liJa:J@idgld3ririfu
prijateli klase, ier u suprotnomne b1 postojao na:Ci
g da ooa sazna dimenziw ll kaOY- !-·" ·-.;c

~
. .
vektora): · -· · · . ·· .
Vek torN Zbi rVe ktor a (Ve ktor N vl, Vek
if (vl. Bro jEle men ata .!= v2 .Bro jEle men torN v2) {
ata)
thro w "Ve ktor i koj i se sab iraj u mor
aju bit i iste dim enz ije! \n";
Q Vekl?oi:'N···v·il+vi"•Broj.Eiiemenata')-·;---· ··
for (in t i = 0; ~ < vl.B rojE lem ena ta;
v3.Elementi[:¥~= vl.E lem
i++)
ent i[i] + v2. Ele men ti[i] ;

~
retu rn v3;
}

. Na prvi pogled je sve u redu, i uz pref:Bpst


0!..,)
·- napisati naredbu poput
·
avku da su a, b i c tri vektom iste dimenzije
·
moguce je

.;;(. vekt orN c ,; Zbi rVe ktor a (a, b); jd/-


"
0 'If Na Zalost, niga
sve ba8 Ulko Iijepo kao sto
• ' , napisana nar ba mou dovesti do telli ~gl~
Napisana ldasa sadrZi ozbiljan prop
·

h posljedica koje se ocitavaju tek .nakon izvje ust, a gore


1., ·•

Nairne, .~on gornje naredbe sva trL¥ektox;a snog vremena.


0
~,.
za8to, razmotrlmo Sta se zaista de~a pri gom
~ i b u forrnalne pamrnetre vl i v2, Pri tome
a, b i c sadiZavaee viseee poklizivaee! Da bism
jein poziVIL · o dolazi do ko iran'a stv · ·
nastaju guke
Avi~kojirna l'i a dnosno 2 i b ~
o Vidjeli

n
..•
pokazivaee na iste dijeloye memorije. Nakon toga
vektora vli v2, koji ee_ biti vm6en iz funkci'e
f!>rne 6e pokaziv · u ve
se onmra o · vektor v3 oji se popunjava zbirom
ri Cenn1 ee do6i don · ovo" ko iran'a u ve
· v3 i c P.okazivati na isti dio meiiloriie). Med r,.; .
UniStavaju se sva tri lokalna vektom vl, v2 i v3 utilu , ~ zavrS et!ru fiiDk~
cije o·
0-· ovog uniStavanja dolazi do oZivan' a desti-Ukt
· ifuiSti.ti dinarniCki alocirahe nizove na koje
(fi ·
ora ldase Vek t rN
· su takoder Iokalni ob 'ekti . Prilikoin

pokazriju pokazivaeiummtar vektom vl; v2 i_v3


tri ob 'e . koji Ce

B. - -·~S:~:!;~:::=!etfov~kti>!~nb~S::o~~~~~~!~~=!~~a;:·-,·· {sto i jeste


... ··~-.
,... oSiobOdene dijelove memurije, ta1m da njillovo
dalje koriStenje mou imati kobne posljedice!
.
a

objekta uniStiti svoj" a ne i "tudi"


niz.
] .. izmed.Q;plitke i.potpune (duboke) kopije:
~ l{-
(
I
I 21

j
a
.. .J'Jitka kopija:

,...... a
Duimkakopij:i; .
":!(..~~,- _:.; : ,,,
_CO·-··-
__
j
v----~- Dinamicki niz
I
Dinamicki niz l
~/-?
Broj~lemenata BrojElemenata I
Elemeriti
/,;'
~

Elementi
... I[
vl
BrojElemenata
+ ,/
I vl
+
BrojElemenata //
/
?71 Dinamicki niz

t
Elem.enti Eleme11-ti

J[
][.
. . . . .. korisituktor ,
kako je to definirano u kopije.
poi!tu);>ko:m (samo kopiriui.jein atributa) nego na •
cilk i klase koje .nemilju eksplicitno
definirnn konstruktor .kopije imaju podrazumijevani lwnstruktor kopite (koji programer ne mora pisati)
l
· k-eJio-Gbavlja-:presta-kopiranje atributa·Jclase, ··· ·· · · · · · ·· · " ····· · ··· · ··--· _... •·· ·' · ····· · ··.--·--·· .. ·· ...... · · · ·· ·· · ·

tje~!veeSli"reeeno,
edi da ·e rjeSellj~ opisanog problema th,finiranje konstrtiktora ko · i"e. Kao Sto
1
rue..·
!'<>fi sekppjra (koji je naravno ponovo tipa
0arametar!!:o"i edStavl"a konstantnu referencu na ob"ekat
eklaractJaidase VektorN izgledaCe ovako: 1
class VektorN {
int BrojElemenata;
double *Elementi;
public:
1
- exp.licit VektorN{int Nl : BrojF;lem.~e:nata {~, ~l_e_menti (new double [N] ) { )
VektorN(const VektorN &V); - ~~ 11Wf1~
-vektorN() { delete[] Elementi; )
void Ispisi();
1
doubl~ &Element(int N);

);
friend VektorN ZbirVektora(VektorN vl, VektorN v2); ID
S obziroin da konstruktor kopije nije posve kratak; njegmrtt
deklaracije klase.
~
t.·I! ~
oy·-,_... -.. ··.'~ .. ,~(:- , •• · • · _ · ;......,.,.. :;..,-,. ~.; •:':Li"ri•: · --
VektorN: :VektorN(const VektorN &V) {
BrojElemenata - V.BrojElemenata;
Elementi =new ·double[V.BrojElemena ta];
D
for(int i = O; i < V.BrojElemenata; i++)

)
Elementi[ij = V.Elementi[i];
D
~
D
22
n
11
I~.
--
~-
rt ~,,­ . ....... . -'- .
. ;·

li .. b); . o<:. :;;~;'.'•


·.: -'::;·.

Q za se

g deiiriilra veoma slieno kao i konstruktor kopije. Medutim,


se oslanja na postupak pr~ptereeivanja operatora kojem je

Napomenimo da smo konstruktor kopije za k!asu Vekt orN


posve
za
eeno sljedeCe poglavlje.
se /
jer .-

g · ;:·•·"'
, .. ·
IIIWin
(ova implementacija je izvedena. u skladu sa: pravilom
k<>~o· ilrici"""~aci n "listi·treba · "ci"
~~: '"~Wfr-,9 <!!: . . , PlJ ~~
mogli _ . implementirati i na sljed,e6i
da. sve ~to Sli moZe inicijaliziratj u
· · · ukonstruktorsko" · "ci"aliziiCion · ·- "cradi · · -·
,-. .· ~IU.L!Ii. .• ;;~··:QJlfflti. , . ®lJ~ . ., ....

G Vekt orN: :Vek torN (con st Vekt orN &V) : Broj Elem
Elem enti( new doUb le[V .Broj Elem enata ]) {
enata (V.B rojE leme nata) ,l ~t~
f
g )
for( int i = 0; i < V.Br ojEle mena ta; i++)
E1.@!!l!"nt.U.11 = V,l;:.,),§!ll<m.UUl.1
~~~~~
·rq·

Rezimira' o kada ·e otrebno da neka klasa ima konstrukto


r ko ""e. ckneralno, svaka klasa cije
G metode (a pogotovo k or vr dinamiCku alokaciJU memorije ·
ob~Wezno da ima destruktor. Ukoliko smo sigurni da objek gi!l,_raeunarSldh resursa,~ba-
ti te klilse ne6e i>iii' jlrenosem 'iiO" W{leooosti -~
kao parametri u funkcije, neee biti vraCani koo rezultati iz funkc

~
ije, i neee biti koruteni za inicija!izaciju /
· drugih objekata iste klase, konstruktor kOpije moZe
lno izbjeCi (takav slucaj smo imali kod klase •
Razr ed). Ukoliko to nije slueaj, konstruktor kopije je
obavezan. Takoder, nkoliko piSemo klasu za

g
kilsnije koriStenje koja 6ii se moCI upotrebljavati i u drugim
progrmnima, moramo predvidjeti konstruktor
kopije, jer ne znamo unaprijed Sta ce koriSnik klase raditi
sa klasom. Stoga se kao pravilo. u objekttJ.o
&iijentiranom programiranju u jezik u 01+ uzima da svaka
dobrg napisana k/asa koja ima destruktor
obavezno treba imati konstruktor fro i ·e (u sljede6em pogla
vlju' eemo ovo pravilo pro&riti dodavanjem

9 nasta i preoptereceni operator lje e").


Razmatranje o konstruktorima i destruktorima (nkljueujlic
prikazom programa koji definira klasu Matr ica koja veom
·

i i konstruktore kopije) zavr~eemo~

Q dinamicko uprnvljanje memorijom. Detaljan opis rada progr


a efektno enkapsulira u sebe tehnike za
ama slijedi odmah nakon njegovog prikaza:
I
o

q #inc lude <ios tream >


#inc lude <i·omanip>
#inc lude <cst ring>
·-:;.'\l.~:j,Qg n~space
~-
std; · ·---~·-r;.e .. <;_·_
clas s Matr ica {
int BrojR edov a, Broj Kolo na; .
doub le **El emen ti;
] char ImeM atric e[lO ];
void Alok acija Mem orije (int BrRe d, .int BrKo
l);
.J publ ic: ·
Mat rica( int M, int N, cans t char Ime[ ] = "");
) Matr ica(c onst Matr ica &MJ;
-Mat rica ();
void Unos () ;
] void Ispi s (int Sirin aisp isa) ;-·
frien d Matr ica Zbir Matr ica(M atric a Ml, Matr
ica M2);
) ;

I (
(
I 23
-~
.
]
............... ,...
void. Mat:dca:·>A lokacijaMeii iOriie.iint BrRed.... int Br,K9i!,) .{ --,... '
]
·~ :
.~ _ .~ -
int i;
~c,cl.\0 i _. <)'Elementi = new double* [BrRed] ;
i~t;,c.Jl'~r 2_for(i =O.-; i <BrRed; i++l Elementi[il = o;

"><, ~fN~~>e'.t ~o! (i = b; i < BrRed; i++) 2


Elementi [i] = new doub1.e [BrKol]; j
~-~
oli%ww:e_~ mufue..
1
}
catch( ••• ) I
for (i • = 0;. i < BrRed; i++) delete [] Elementi [i];
delete[] Elementi;
1
.I
throw;
li
.~~
·.. , ..,
Ma rica·· atrica int rRed, int 'BrKol co.nst char. Ime
.. '·"·•; :,-., .)'lrojRedo)ta '(arR!adl BrojKo bna Brl,<o;Lt.L·
· if st.r'len (!mer "> 9)' throw "Predtigam<:a
.
"'tme·!
.
\n";
·'·""" ··.·: ·.;e .•.•. ,.~, . .2;., ... · .••. i
strcpy(ImeM atrice, Ime);
---.uokacija Memorije (BrRed, BrKol);
1
AlokacijaMe morije(BrojR edova, BrojKolona) ;
i
for(int i = 0; i <. BrojRedova; i++)
for(int j. = 0; j < BrojKolona; j++)
· Elementi [i] [j] = M.Elementi [i] [j];
l
- Mairica::-M atrica() 1
or(in·t l . - 0; i < BrojRedova; i++) delete[] Elementi[i] ;
(
delete[] Elementi;
(
void Matrica: :Unos {)
for(int i - 0; i < BrojRedova; i++t
for(int j = 0; j < BrojKolona; j++)
cout << ImeMatrice << " [" << i + 1 << " , n << j + 1 << "l n.
'
[
cin » Elementi[i] [j]; ·

}
I
[
v:oid Mgtrj ca:: IsPis (int Sirin~Ispisa.} {
for(int i - 0; i < ·BrojRedova ; i++) ·I·
for(int j = 0; j < BrojKolona; j++) [=
cout << setw(Sirina ispisa) << Elementi[i] [j];
.cout << endl·; . .... "

}
}
u
Matrica ZbirMatrica (Matrica Ml, Matrica M2) I
'if(Ml.BrojR edova !_: M2.BrojRedo va II M2.BrojRedo va != M2;BrojRedo va)
throw "Matrice nemaju jednake dimenzije!\n rr;
Matrica M3(Ml.BrojR edova, Ml.BrojKolo na);
u
for(int i = 0; i < Ml.BrojRedo va; i++)
for(int j = 0; j < Ml.BrojKolo na; j++)
M3.Element i[i] [j] = Ml.Element i[i] [j] + M2.Elemen ti[i] [j];
~
return M3;
I
D
u
-
24
11
·±nt'-jili:iin () -{T... ~ · .. ., .. -
·- ,. ___ _ -
int M/ "N;.
. .
cout <<- "irne si broj redo va i kalon a za
matrice:\~";
_cin >>·M >> :N;
try {
Matr icaA {M, :ij, "A") , B(M, N, "B") ;
cout
I
<< "Une si matr icu A: \n";
A. Unos (·). ; ·
cout · <<: "Une si matr icu B: \n";
B.Un os(); ·
cout << "Zbi r ave dvij e matr ice je:\n ";
Zbir Matr ica(A , B) .Isp is(7 );
}
catc h ( ..• ) {
cout << "Nema dovo ljno mem orije !\n";
.. : . ...
. ' . . --~ -~

Vidimo da red konstniktorai destrukto interfe's ove klilse


sadrZi metode Unos i Ispis , koje su
dovoljno jednostavne, tako da se o njima nema mnogo toga
re6i Interesantno je jedino istaCi metoda
rsgi s zahtijeva ~ p~~ ze~jenu Sirin~ ispisa kqji
···d'VlJ&metede·definirana-Je-·t·pnJateljska--funk'CIJll'"Zlri'rMa'tr" za~ti sv~ ~Iem_ent ~ce. Pored ove
6e
ipa·koJa·vm--sabrranJe''dVtjlnnl!tt:lce-, kojaj e'
takod erjas na sama po sebi. Razumije se da bi stvama klasa
Matr ica ko·a bi bila otrebljiva u viSe
razliCitih progrfUM :n;toral~ · . znatno bo~ji interfejs (na~rimjer ne_po~oji nij~ met
omo!IU6ava priStup mdivtdualnim elementima matnce). 1 oja
M~utim, ovdje iUSmo zeijeli da program
iSpadne predug!iliak; Jer je osnovni cilj programa da uvidim
o kako su implementirani konstruktori i
destruktori klase Ma tr i ca..

/'Kon strul ctor _klase Matr ica ~~-


tri p:am etra Prva dva parametra predstavljaju
matiice, dok tre6i parametar, koji se more izostaviti, preds ~ljene
dimenzije
tavlja ime matrice dato kao string, koji se
koristi pri ispisu prilikom unosa elemenata _matrice (u slucaj
u izostavljanja podrazumjieva se prazno
ime). Konstruktor atributa BrojR edov a, BrojK olcin a i ImeM atric e

Samametoda Alok acija Mem orij e vrsi klasiCni postnpak


dinamiCke alokacije dvodimenzi!!n$iog
niza koji smo ve6 korist:ili, slieno kao funkcija Krei rajM
atric u iz poglaVlja o strukturama Pri "·,_,, JV
bitno naglasiti da se ova metoda brine da poCisti iza sebe
sve izVr1lene da I!IP'~:ija
memorije ne uspije do kraja Nairne, izuzetak 1Z

HI
' I•
e ne sebe u
neee poCistiti (niti ce ga moCi poCistiti), sto tiaravno vodi ka
curenju memorije.
P,Ko nstro ktor kopije klase Matric?._ pored kopiranja
atributa BrojR edov a, BrojK olona i
ImeM atric e obavlja novu dinamicku alokaciju (pozivom
metode Krei rajM atric u) nakQn eega
kopi:ra elenient po element sve elemente izvome dinamiCke
matrice u novokreirani prostor. K~o,
diiStrilktor kl8Se Ma tr i ca brine se da se oslobodi sva memo
rija koJa Je zauzeta u procesu kreinfu.ja
matrice. Ostaje jos glavni program (:funkcija main ) koji je
dovoljno jednostavan dane zahtijeva n,ikakva
posebna objallnjenja ., ·
(
1 25 I
'
'j
. . .
]l
.

~u da~~~~;~~!~!~~~
·, ;.

..·•.· > reeimojoS.ito ~~··'·'·~~··"j

j
j
mnogo
reforence counting).· j
t · Opisana tebnika zvuCi· 5asvim ·jednostaVrio, ·i Citalac bi bez ikakvih problema mogao pTeJlill'viti kla5u · · ·
If Matrica i prethod!ri progralri tako dakoristi brojanje ref'erenciran·a Citaoc.USe pr~uje di!,ro·ilJi'l!4i · · .·. ·--f
.. ·- . ' Jra9VJe :· · ... ·.•u·p(alfsije simacijaneSto· .zenija;Na.iJ:ii.e;Jrnko$ei dalj¢.·kotlste'plitk¢ Jroj:)ije;''''"'~ ,,:..JI,
bilo koja modifikacija dinaiiiiCkih eleriienata jednog obje)tla rilijenja i <J.irianrlcke elemente dttigog ·. ·
objektll Ger se,_ zapravo, ~ o istim el~entinta u m~oriji). Ovaj IJI?.til~ se mo7.e rije~ti ~~ St?. se il · 1·
metodiima koJe vr8e pnStup elementima klase vr81 nova aloka,ciJa 1 duboko koprranJe Jedino u •
siiuaCiji!Jllll kada uvidimo da je to zaista neophodno (npr. u situacijama kad8 treba mijenjati 'e!emente
.·.ailllmli§k2gJlW....»,.l».:Qj@.. r.~<;r.e.m:.il:!l!J.j!h..im!l.Y..e;¢u..w:ijednost ..od.I;•.sto.Je,..5igimm...znak..da..Jos.ne!G.
pokaziVae pokazuje na isti dinamiCki niz). Ova tehnika, nazvana kopiranje po potrebi (engl. ·copy if l[
necessary1 neSto je sloZel!ija i·ovdje neeemo ulaziti u detalje. Cilj je bio samo da se Citalac upozna sa
osnovnim idejama kako se rad sa klasama koje. zanzimaju mnogo memorijskih reSur:sa !JlOZe uCiniti
t,! efikasnijim. Ako 2;atlemarimo aspekt eflkasnosti, moZe1no reCi da poStupakkreiraiJ.ja dnbokili kopija koji
J! .smo vee objasnili u pot);iunosti zadovoljava""" dmge aspekte Za ispravno koriStenje klasa.
1[
'
lC
~
1
t
~
.--~---10"-Sj:t:~.i<_:· " . '"<.
. .. ; b~~

~
~
~

26
~
'lrl '
'
:ot
IJ
'
- •
/o
~~
,W
·q PREOPT ERECIVANJE OPERAT ORA

g Sloreni tipovi podat8ka kao Sto su strukture a pogotovo · klase koje smo uveli u .prethodnim
poglavljima omogueavaju dizajnirauje takvih tipova podataka koji na jednostavan i prirodan nacin
. modeliraju stvame objekte sa kojima se susteCem.o prilikom Ije8avanja stvarnih problema. Medlltim,

g jedini operator kojije na poeetku definiran za ovakve tipove podatakaje operator dodjele "=". Sve.ostale
· operacije nad slozenim objektima do sada smo izvodili bilo pozivom funkcija i prenosenjem objekata
kao parametara u funkcije, ·bilo poziv<im funkcija clanica nad objektima. Tako smo, na primjer za ispis
nekog objekta v tipa Vektor koristili poziv v. Ispisi (), dok smo za sabirruije dva vektora vl i v2 i

Q dodjelu rezultata treeem vektoru v3 koristili konstrukciju v3 = ZbirVektora (vl, v2). Rad sa tipom
Vektor bio bi znatno olak5an kada bismo za manipulacije sa objektima ovog tipa mogli koristiti istu
sintaksu kakvu koristimo pri radu sa prostim ugradenim tipovinia podatakll; tj. kada bismo za ispis
Q
u
vektora mogli koristi kostrukciju ·emit << v, a za sabiranje konstrukciju v3 = vl + v2. Upravo ovakvu
rilogu6nost nudi :nlllli
preopter~civanje operatora. ·. Pi-ciciznije, preopterecivauje opeiat<ira nam
omogucava da nekini od operatora koji su definiran:l za proste tipove podataka daino ~SaO i za 'slorene

Q tlpove podataka koje smo sarni definirali.

Preoptereeiyan je operatora ostvaruje se uz pomoc operatorskih fimkcija. Operatorske funkcije


izgledaju kao i. klasicne funkcije, samo sto llinjesto imena imaju kljuenu rijee opera tor iza koje slijedi
Q oznaka nekog od postojeeih openifora. Operatorske funkcije mogu biti i funkcije clanice klase, ali takvu
cemo Jl1ogu610st razmotriti neSto k8snije. _· Za _sada cemo pretpostaviti da su operators,ke· funkcije
wedene kao obiene "funkcije. 'Operatorske funkcije mogu imati dva parameJra, uk~liko ]e navedeni
Q operator btnarni operator, iii jedaii jlaranietar ukoliko je navedem operator unarni operiiior. Medutim,
bar(ll]l jedau ·od parametara operatOrske flmkcije mora b1ti neki ·Slo:reni tip podat8ka (struictUra iii klasar

g Na piimjer, neka je <kia sljedeeadekiaracija~ase ve kto r ( radi jednostavnosti, u kla.S! je definiran samo
za
konstruktor i trivijalne metode pristup atriliutima klase):

g
class Vektor {
· doUble x·, y, z;
public: · ·
Vektor(doub le x, double y, double ·z) x(x), y(y), z(z) {)_

~
double. Vrati X() OOI}St { return XI
double vrati y(J Canst { return y; )
double Vrat(::z () co'nst { return z;· l - -·-··--·.
) ;

0- . .

. .Za ovakvu klasu moZeillo definirati sljedecu operatorsku funkciju koja oba~lja sabiranje dva vektora
(razmak iza rijeei opera tor mo~ se izostaviti): .
a
....
Vekto_r operator t fyejctgr ylf. ~ktor v2 l
return Vektor (vl. Vrati:.._x 0 + v2. Vrati_x ()·,
vl.Vrati_y( ) + v2.Vrati_y( ), vl..Vrati_:Z () + v2.Vrati z());
J
~
)

. Operatorsku funkciju principijdno je moguce pozvati kao i svaku drugu funkciju. Na primjer,

l likoliko sua, bi c objekti tipa:Vektor, sljedeeakonstn ikcijaje sasvim ispraV:na:

c =operator +(a, b);


· ·

"'
J :Medutim, razlog zbog eega se uopce uvode operatorske funkcije je tome sto je sada moguce prosto pisati
• c = a + b;

I

_Objasnimo ovu mogucnost lillllo opcenitije. Neka je "*"
proizvoljan binarni operator podrZan u
· jeziku C++ i neka su xi y neki objekti od kojihje baremjedau tipa strukture iii klase. Tada se izraz

I I
-J
X* y
'i
zapravo interpretira kao f
* (x,
operator y)

Drugim rijecima, pri nailasku na neki izraz sa slozenim tipovi.ma podataka koji sadr:Zi biname operatore,
f
prilikom interpretacije tog izraza · pozivaju se odgovarajuee operatorske funkcije, koje odgovaraju
upotrijebljenim operatorima (kako po ozmici operatora, tako i po tipovima argumenata). Ukoliko takve
operatorske funkcije ne postoje, prijavljuje se sintaksna greSka. Slicno vrijedi i za slueaj unarnih
operatora. Ukoliko je "*"
neki unarni operator, tada se izraz
i
!
interpretira kao

ope.rator * (x) .J
· . Kao primjer, mo:lemo definirati sljedeeu operatorsku funkciju za klasu Vektor, koja omogucava da
se imarna varijanta operatorit "-" moze primijeniti na objekte tipa Vektor (sa znaeenjem obrtanja
smjera vektora, kao Sto je uobieajeno u matematici):
1
Vektor operator .:: (Vektor v) {
return Vektor (-v. Vrati_x() , -v. Vrati_y (), . -v. Vrati_z ()) ;
~
~
)

Izvjesni operatori (kao sto je upravo poril.eputi operator,;-:-") postoje iu Ull3ffiOj i ubinamoj varijap.ti,

~
. tako da moumo imati za isti operator operatorsku furikdju sa jedninl par3Jneitoin (koja odgovara
unarrioj varijatiti) i sa dya para111¢tr~ (koja odgovara binal'fi~j vilrijanti), T3ke,. na primjer, za klasu
Vektor mozemo definirati i binaitii operator "-"· za oduziiDari.Je mi sljedeCi nacin: -- · .·

Vektor Operator - (Vektor vl, Vektor v2) (


return Veki:oor (vl. Vrati x () - ·v2. Vrati x() ,
vl.Vrati <y() - v2.Vrati - y(), vl .• Vrat.i.
... - z () - v2.Vrati_ z ());
~
. ---. --.. .---

Medutim, istu operatorsk]i~'Pk9ijll iJlogli smo napisati illlllogo'jednoStairnije na slj~eei naein:


~

·~
'-''-"

Vektor · oP.,rat<ik ·- cV~ktor vl, Vekto:i: ~2K · {


.raturll . vf·+:. ·~~y2.;·- .·. _.
)

. 9Ydje je i~~ori~~..3iftlj~Cl1 Slilopr~~odno de~ op~~y :•~a.i#t!"inus" .za tip vektor


d.4
(takO: daje k0"m,p3jler ~~~~· ~-Z!f~£i koi!§~gija -vz,);.~. i ~~ogefi,niiiili,. ~::. '"bfuaFioJierator "+~
~
se 'Ve~ora). Ov.iti¢ ~e treli#~
~
(tako. da. koinpiij1er Znli f'~o .• Siil)ii'~ju dva Jiirlyi!<1 poilii$1iti da $ino umjesto
vl -_v2_ mogli 1\llPisif#Jfi.,- J'~~;_i,:obzirom.
+ i# ~~huitry~~tgi~#~ ? ~~~ istlL ~ Nairn~,
znaCenJe tzraza vl + ~v;2Je o(t11ll1.1Je _dobro dei'inirano, s QbiJroli19a ~mo pt~o definirali znaCenJe
binamog opei-atoi-a "+'; i'Uri~<lg' ltitiu~ za:'i,eidore~ s''~de Sftillie,'':Zii~cl,rije'iZriiZll vl - v2 tek
·~
trebamO da definiramo (i !Q upnivo' pisanJem 0Vf3 operator8ke fi.mkcij~fUpo~ebl$ lzraza Vl - V2 unutar
operatorske funkcije zab§rni opertjtor "-". bi~ bl zi!Pravo lnterpretii:lin !<;ao da ova operatorska funkcija
treba da poziva samu ~Jg. kao rekurzija, itobeziziiiZ ll)! Pored talia. programer inia puno pravo da
napise operatorsku funkclju Za 'binmlu opClralor "-" kako god zeli ·(pll Cak i ta:ko ·da uopee ne obavlja
oduzimanje nego nesto drugo), tako da iZrazi vl + -v2 i vl - v2 uopee ne moraju iniati isto znaeenje
~
(mada to nije dobra praksit). U svakoni slucaju, pr:Vi od ovih izraza se interpreiira kaO
operator + (vl, oper~'t:or ,_ (v2).)
·~

2 ~
lfl
adrugi kao

operator -(vl, v2)

Operatorske funkcije se takoder mogu deklarirati da budu funkcije · prijatelji klase. U praksi se •
gotovo uvijek tako radi, s obzirom da u veeini slucajeva operatorske funkcije treba da budu u stanju da
pristupaju internim atributima klase. Na primjer, sasvimje razumno ·u klasi Vektor operatorske funkcije
koje smo razmatrali deklarirati kao funkcije prijatelje klase: ·
class Vektor {
··double x, y, z;
public:
Vektor(double x, double y, double z) x(x), y(y), z(z) {f
double Vrati x() const { return x; )
double Vrati y() const {return y; f.
double Vrati-z () cOI1st 1 return z; f
friend Vektor operator + (Vektor vl, Vektor v2) ;.
friend Vektor operator -(Vektor v);
friend Vektor operator ~(Vektor vl, Vektor v2);
f;

Uz ovakvu deklaraciju, definicije pomenutih operatorskih funkcija mogle bi se pojednostaviti:


Vektor operator + (Vektor vl, Vektor v2) {
return Vektor(vl.x··+ v2.x, vl..y-+ v2.y, ~1;;:· + v2.z);
Vektor operator ~ (Vektor v) {
return Ve_~tor(-v.x, -v."y, --v.z};
}

·Vektor operator.- (Vektor vl, Vektor v2) I


return Vektor(vl.x- v2.x, vl.y- v2.y, vl.z- v2.z);

Moremo primijetiti dauslqc!lju d3 sm,Q oper~orskt! funkci]u :z;a binarni operat()r "-" definirali
skraeenim postupkom. (preko .sablj3hja i .~og·· tniti~), ne ·IIi ·!Jilo poti;ebe da)e '~e~ariramo kao
funkciju prijatelja klase, aline pi J>ilo ill §te(e. ~mafra ~ .i!ollrompiilksom sVe qperlltorSk;e fw!kcije tcoje
manipuliraju sa objektii!Ja. neke idase ~kjipii;ati kaO: ·. prijatelje .te·. klase; '}er se '(i;di posmatranjem .
interfejsa klase
.
jasno vidi
'
kqji sil · ~e J)peratori .iteiiniiaDi ~-·_ dafu'
' . - . ··- . ', ·. ' ._ . : ,;.._._...,.-. -_ :, .. ,• --'· ,,.,' ·.·--·_'· .. -_.••.... <·. \!asu:
-.· : ·-·-. -· _·-· ,-;_:., '· ·.
iJ__ ,.__!iasta~k!I
;~-~·; ' ...•..·-
· &mo ·
J~ _. -: -

podrazumijevati da su sve operittOrske ~ntk#Je koje blllferii.o de~ d(#~e kaq Jffijatelji I<I;ise sa .
kojom manipuliraju. ·· · ·· · · · ·· · · · · · · · · ·· ' · ·· ·· ·· ·. ·· · · ·· · ·

po :;v;:;;~ ~::~=~~; t1r··t1:~4i~l~~j:~y~~ft~!~<&~S~~~p~ =1:·


. • ' ':- .. ·• .;,-"·'·. :k.~ ._ .., ·--.-•.'---... , . ..,,_,,.,- _···- ·:···""",,_ .._.- . . - -•• --.-~-.- .. _-_,._.,_,, .. _,_~----~-- -~---
J ~·1·~'.;- ...· ·.· -·~::_,,,
treba pozvat:t Jl ko~OJ si~'Wi lfli,iiJilWJ.er, lg!),<:C)je 4()zyoljen6 pmniioZiti reaJiti'bi'IJJ sa vekt:Otoru,
prirodno bi bilo de.finfuiti sljedecn qjieratoiS!{Ji funkc_ijn: ·. · ·. ' ' · ·. · · · · . ··· ·. >• ·. · ·

Vektor operator *(doubled, Vektor v) (


return Vekt0r(d -* v.-x~ d *. v.Y, d.* v:z);
}

Nakon ovakve definicije, izrazi poput 3 * v iii c * vgdje je v vektor..a c re~anbroj postllju posve
smisleni. Medutiru, izraz poput ,;. • 3 je i dalje beSirii5IeD, i dove~ce ··a;; pri}irv'e: gre~e. Nllfuie,
prethodnom definicijom kompajler je "naucio" kako 5e mnoZi broj sa vektorom, iili ne i vekti>r sa
brojem! Neko bi niogao prigovoiiii dabi kompaJler piosto mogao prlmijeniti komritati:lini zikon na
operator "* ". Medutiru, nsvojeno je da se piilikom preoptereCi.varija o}>eratora n{ prave nikakve
pretpostavke o eventualnoj korimtativnoSti operatora, jer bi u snprotnom bilo nerrioguce definirati
operatore koji krSe ove zakone (npr.. ne · bi bilo moguee definirati ninorenje mahica, koje nije

.3
j_L

* 3, moramo definirati jos jednu


~
komutativ no). Zbog toga, ukoliko irelimo dati smisao izrazima poput v
operators ku funkciju za binarni operator" *", koja bi glasila ovako ,§
Vektor operato r *(Vekto r v, double d) •
return Vektor(d * v.x, d * v.y, d * v.z); ··~

Ova funkcija se od prethodne razlikuje S!l!llO po tipu parametar a Mogli smo pisati i ovako:

Vektor operato r *(Vekto r v, double d) {


return d * v;
lf
Na ovaj nacin smo eksplicitno rekli da je v * d gdje je v vektor a d broj isto Sto i d * v, a postoji
~
oJ?eratorska funkcija koja obja8njava kakav je smisao izraza d * v. Ipak, nije preljerano dobro jednu ·~
operators ku funkciju definirati preko drugih definirauih operatora u slueaju kada se operatorska funkcija
m~ i neposredno definirati najednost avan naCin, jer se time gubi na efikasnosti.

Pretbodne definicije jos uvijek ne daju smisla izrazima poput a * b gdje 8u i a i b vektori. Za tn
svrhu potrebno je definirati jos jednu operatorsku funkciju, cija Ce oba parametra biti tipa Vektor.
~
Medutiru, u materuatici se produkt dva vektora moire interpretirati na'dva naeina: kao skalami produkt
(ciji je rezultat bro;), i kao vektorski produkt (ciji je rezultat vektor). Ne mozemo napraviti obe
interpretacije i pridruZiti ih operatoru "* ", jer se u tom slucaju neee znati na koju se interpretaciju izraz ~
a * b odnosi (u mateniatici je taj ·problem rijesen uvodenjem razliCitih oznaka operatora za ove· dvije

~
se
interpretacije, tako da operator·.; .• oznacava skalai:ni, a operator "x" vektorski produkt). Slijedi da
moramo odluciti za jednu o4 interpretacija Ukoliko se dogovoriruo da izraz a * b interpretiramo kao
skalarni produkt, moZenio hapisiiti sljedeeu operatorsku funkciju, koja definira tn interpretaciju:

~
.,,. . '.

double operato r * (Ve.ktor vl, Vektor v2) {


·.• return vl~·X *. Vz~x---+ vl.y * v2.y +·V1.z' * v2.z;

mogucnosti da def'inilrarrto ~
oPeratOr ""':". Na·
vee ·.~
.. , . . dva vektli#
prodUit. · .·.~
i~91#3'1!J!10st<oj~iih oJper!ttor:ll p1:osirimo ulogu da · vektorski.
prii'nij1mje:n, na vektore predStavlja vektorski prcidult,
pre:dsta,v1jia n:;;t.n,,,· vektorski produkt. Na ~ost, takvo
... kada su a i b brojevi, izraz a I b ciznacav~
za
Operator "%",taka da definiramo da nam a% b ozn!Wava
=· '"-''" -·e:-··-··- dii znak "%" we vizuelno podsjeea na znak "x" od znaka "/;;):
D
CVektor vl, Vektor v2) {
--~~y * V2.z -. vl.·z * v2.y, vl.z * v2.x- vl.x * v2.z,
D
v2.z) ;'
} ·.~
.. :Porro toga sto nije m.~iuee uv#iti ·nove operatore, nije inoguee 'ni promijeniti prioritet operatora

~
bi ·
Tako, da $1110na PrlmJer.c;!~~,da operlltor "&" preds!avlja vektorski produkt, njegov prioritet
ostao niZi cid prioritefit operat<)ra "+", taka da bi se izraz vl + v2 & v3 .interpretirao kao
(vl + v2) & v3 a ne ki\o vl+J'v2 & v3). Ovo je jos jedan razlog zbog eega je izbor opermora "%"

~
·
relativiJ.o dobar izbor za vekfor5kiprodukt dva vektora. Nairne, prioritet ovog opermora je u istom rangu
kao i pnoritet klasienog 'i!iieiatofli
. . ~a mnoilenje "* ". ·

4 ~
111
Na ovom mjestu CemO jos jednom naglasiti da opecitorske funk:cije moraju imati harem jedan
. argument koji je tipa strukture ili klase. Ovo je uradeno da se sprijeei moguenost promjene znaeenja:
pojedinih operatora za proste ugradene tipove. Na primjer, nije moguce napisati operatorsku funk:ciju ·
poput ·

int operator +(int x, int y) (


return x * y;

kojom bismo postigli da 2 + 3 bude 6 a ne 5. Mada bi, u izvjesnim situacij~a, promjena znacenja
izvjesnih operatora za proste ugradene tipove mogla biti od koristi, konstruktori jezika C++ su zakljuCili
da bi Steta od moguee zloupotrebe ovakvih konstrukcija mogla biti znatuo veca od eventualne koristi, pa
su odluCili da zabrane ovakvu mogucnost

Gotovo svi operatori ugradeni u jezik C++ mogu se preopteretiti (ti. dodefinirati). Jedini operatori
koje nije moguce preopteretiti su operatori ": : ", ". ", ". *", "?:" i operator sizeof, s obzirom da ovi
operatori· imaju u jeziku c++
toliko ·specmcne primjene da bi mogu6nost njihovog preoptereeivanja
dovela do velike zbrke. Tako je moguee preopteretiti sljedeee binarne operatore:

+ * I % << >> < <= > >=


--""· . != & I && II += -= *=
I= %= &= I= <<= >>= ->*

zatim sljedeee unarne operatore:

+ & * ++
kao i sljedeee spedja!rie opciatore koje je teSko svrstati medu go~e prikazane operatote:

[l () new n~~[ ] d.elete delete [ ]

Svi navedeni
,
binarn! operat~{iositn
.. - . ·. . . -. - :-, ..__ x,.. . -- -·
operatoradodjele
: - . _, --.. -: ·'. -"
"=",....kao i svi _navedeni
_, _-_ : . ..· .
unarni operatori,. mogu
se preopteretiti pa vee ppis~!ili§i,tl (pd~ii preoptereeivanje !)peratora: "++" i "--" zahtijeva) neke
dodatne. specifiendsti koje ceifi't
kilsnije. objasniti}. {) pi:eciPtlifeeivanju operatora .dOdjele Jam. i 0
.· . .--.,---~:_.,_"'_~-;
.. --~--- :~:-J-;_;~~
.. _-, •.. ,-._:;.: .. .. _ ..... ,;-._.·.'•.-·_:·
~;:-(,.;:::··~-'-~--·._.; 1:-·:.,~:'-

preoptere9YI!l1JU sp.llf~Jalnih,.9P~!il goyopc~o P.~!>.k~J~' l'nJe to!la eemo rect nekoliko n)eCI o
.-.--·-· . •.:··-. _ .
:',;:·;:.,..:-~~~·'' .. ;.··--·: ..
:·.··---~ ~--~

I
·tome. ka:ko hi trebiJto.:ffetit/kr?fj,vatr poje<!int\ operii!Oie. ~~o. "treJi#o" jer. prq~et lm.a ·punu •
slobQdujiil Zna:cenJ~ Jiojei!inQ!::wiiriif?riJ_;~ slo~e#~]iJlo:V~ ·p~a d,e:fitili-a liakd gixl ieli. ~ako je

=~~~J~~~1~~-~ftri~¥¢%~t~i~-~~~~~~~#t:7oat';~:
....•¥=!f,~ Pi!:~~J~·W~;-~~~se~;~~~\~~!,~tisto~e~~fueek:Z !ii!zie~~:nt
1
k~k~Jbdna&n~~f(!J?r'iiii~ki:Ma.trica. StPga·~~ ~vku u rdi par iijtilli kai<() bi treJ?a!o
· detii:llriffi izYI'esne'~ore da Wiliroo kOiiZiste.ticijli iia Cirik ~6"od iaillje znamo sa dejstvom pojedinili
oPilratof,j ~pii.J~ . =~~ii~~.·
~ .· ; '
{'
.. .-..
.. .· . .· . .· . • ·. ..• .· . . . . ... .. ..
J?"Vo pr#0Jo ''liQhton!l" p~~iD. 1J#¢ere6iy!l#ja op~qra k~ da je neki ·operator potrebno
detiip,rati #
lll(ki ti!?I~()~~~je iD.@~"lloJa5tli~ ~L#f9.Pciat~r!re.bao da zili!Ci za taj tip. Na
primjer, . .saMm
je p o Silt. IifcopW.or ·~+~ .trelia¢ 'PJI ~¥i .~ .ilva objekta koji ptedstavljaju neke ·
matematske ~ ~ ~oje'je po)iu:ri sa}iirmija !!efipirtiii. 'T~oder, Ukoliko pravimo klasu koja
ouiogueava nid sa"iliZOViinil':mllkoV:ii,'iiD!{]m,jsla definir8tl operator"+" koji bi mogao da predstavlja
nadovezivimje iriz0ylizi13ke>cij&faii'na 'dtugi{kao U''h't\id1D ~.;a:iij~ BASIC-a i Pa5cal-a, odnosno kao
s
funk:cija strcat iillibllottiki:cstririg). druge strarie~ t~oje dati SQ!isleno znaeenje.izraZu a+ b za
slueaj kada sua i l:l objektl idiise stucient. .

Drugo pravilo prepOn!~uje. da kada god definiramo neki od, binarnih aritmetickih operatora kao sto
"*" itd. ·tr~b.~O'defi:Dirati i.odgoy8rajuCe opefcit~e sa pridru.Zivanjem poput "+="!J 11-=",
·su "+", "- 11,

5
f
da unijesto a = a + b
~
"*=" itd. Nairne, pri radu sa prostim ugradenim tipovima programeri su navikli
piSu a += b. Stoga bi lijepo bilo da isto vrijedi i za rad sa slozenim tipovim
de:finiran operator "+": Medutim, ova se neee podrazumijevati samo po sebi, jer
a za koje je prethodno
je "+=" posve drugaciji ][
uopee ne povlaci da je definiran i
operator od operatora "+", i cinjenica da je definiran operator "+"
operator"+=". Pored toga, izraz a+= b seinterp retiraka o
opera tor +=(a, b)
J
iz eega slijedi da se on principijelno maze definirati taka da ima potpuno drugaci
a = a + b, koji se interpretira kao
je znaeenje od izraza
t
a= opera tor +(a, b)

Ipak, takva definicija bi bila protivna svim mogucim kodeksima programerskog


bonton a Stoga bi i
znaeenje. Slijedi jedan
operator "+=" trebalo definirati taka da izrazi a = a + b i a += b imaju isto
jednost avan naCin kako se avo mo2:e izvesti za tip Vektor :
void opera tor += (Vekto r &vl, Vekto r v2)
.. l
)
vl = vl + v2;
f
prenosi po referenci.
· . Ovdje je _veoma bitno uociti da se prvi parametar u operatorsku funkciju
Nairne, izraz- a += b koji se interpretira kao opera tor += (a, b) treba da promije
a, a to je moguee ostv~ti jedino prenosom po referenci. Takoder, treba primije
ni vrijednost objekta
titi da smo se u izrazu
. To i nije lose,
1
"+" za vektore
vl = vl + v2 oslonili na Cinjenicu da smo definirali znacenje operatora
jer na tl!i naein cvrsto drzimo konzistenciju izrnedu znaeenja operatora "+" i "+=".
zbog efikasnosti ne 2:elimo oslru:tjati na definiciju operatora "+" za klasu Vektor,
Medutim, ukoliko se
operatorsku funkciju za
je dtugih opei-atora:
f
operator "+=" mozemo "napisati ina sljedeCi nacin, koji je posve neovisru i od definici

void. opera tor += (Vekto r &vl, Vekto r v2) . { .


Vl~~ +~ v2.X; vl.y += v2 .. y; vl.z += v~-~~--
1
)

Obje naveciene definicije operatorske funkcije zaoper ator ,;+="· rade posvedobr():
ulifadeoe :Nairn~;
l~ak, one riisu u
ia sl~~jkada
i
sa
potpunosti saglasne Otiiin kako operator "+=" djeluje proste D.a tiliove.
su a, b 1c objekti nekog prcisfog:iigradenog tipa (npr, ~jcilobrojilej)r()!iijciiljtve) ~je
a = b ~=_c. Sa <>':ak? ruiiiisl!)loinop~rskom J.lln1f~offi._i tipQ3J1Ve)<t~(!<i mjilh,
c-
iegai:no piSJitl.
l~~,j~r~~?.Joj.
!ie J10St .~akvti.
1
povratm tlp definirali da bude void (t.J. 4a ne ~ ~), taka da 1Z\'iiZ
b +=.
vrijednost koja bi ~ I?iJ:i d~j~ljena promjeniJiv:o.J Qvaj ~~t\\kf/~(
mo!lificiratioperat~ .furikci)
... ' '
.
u"ifuvta
..
'
ea kao rezult¢
' '•. .
iztilijen
: ._- :·
r:
jeriti yrije44o
. -- .-._ . . --. . -
) 6@~ tako §l;~o .
St,_.vektora
'. "
·._~ ...:--_- .
. . . ~
Vekto r ope:iia tor += \Vekto r &vl, Vektci r vz) { -~
vl = vl + v2; ·
ret~rn vl;

--~
)
. . . .·· ·.. '' -_. :. <:-.:..--;". . . . :- :_ . _- . _- ·. .
. .. ;....
obzitom da o}ierato (it"d\Ue !~·takod er nasi vrijednc ist:
Ova je moguee kraCe zapisati ina sljedeCi tiiiCin, s • • •• .~ - • - .• • ••.•• <_ •

Vekto r opera tor +=(Ve ktor &vl, Vekto r v2) {


return vl =·vl + v2; ~
Pored toga, preporueuje se da ovakve operatorske funkcije umjesto same
vektora vrati reftrencu na njega: ·
vrij$o srl .izinijenjenog · ·
-~
Vekto r &op~ator += (Vekto r &vl, Vekto r v2) {
return vl = vl + v2; ~
6 ~
ll
Ovo omogueava da se izraz u kojem se javlja operator "+=" postane 1-vrijednost, odnosno
da se maZe
naci sa lijeve strane znaka jednakosti. Mada se ovakva mogucnost iznimno rijetko koristi,
ona postoji za
proste ugradene tipove, i stoga nije na odmet podrZat:i je i za sloune tipove. · ·
Kao Sto je vee reeeno, programer ima slohodu da definira operatore kako god reli. Tako
je posve •
moguce definirati operator poput "+=" cak i ukoliko za isti tip nije definiran operator"+".
Na primjer,
uzrnimo da je R ohjekat tipa Razred, a·u ohjekat tipa ucenik, pri eemu su klase Razred
i ucenik
deklarirane kao u prethodnom poglavlju. Neko hi mogao doci na ideju da definira operator
"+=" koji hi
djelovao na ove klase, pri cemu bi izraz poput R += u imao maeenje upisivarija ueenika
u u razred R.
Medutim, ovakvo Ijesenje se ne smatra dohrim, s ohzirom da 1\iegovo maeenje nije posve
ocigledno na
prvi pogled, a i nema nikakve veze sa sabiranjem. Sigurno je izraz poput R. Dodaj Ucenika
Q jasniji i prirodniji. Odavde slijedi zakljuCak da operatore treha definirati samo u slueajevi
potreha za njibovim definiranjem prirodno name6e.
(Ul mnogo
ma kada se

~ Sljedeee pravilo preporucuje ·da ukoliko smo se uopce odluCili da definiramo operator
klasu, treha definirati i smisao operatora "==" i " l =", Ovi operatori h~ naravno, trebali
jednako st odnosno razlicitost dva ·ohjekta (mada, · naravno, nerua nacina .da prograineru
e za neku
da testir~u

Q poStuje ovakvu implementaciju.,. on ove operatore mou definirati kako god hoce). Za
odgovarajuce operatorske funkcije hi mogle izgledati ovako:
naredimo da
klasu Vektor,

0
u
int operat or ==(Vek tor vl, Vektor v2) {
· ·return vl. x ~= v2 . x && vl. y == v2 . y && vl. z v2. z;
)

Q int operat or != (Vektor vl, Vektor v2) {


return vl.x != v2.x II vl.y != v2.y II vl.z != v2.z;
)
···.···
g Operatorsku funkciju ia operator "! =" smo mogli napisati i na sljedeCi naein, oslanjaju
postojeeu defii:Uciju opeiatorske 'funckije za operator "==" i na maeenje operatora " ! " priiit.ijel\
ci se na
jenog na
cjelobrojne tipove: ·· ·

Q int operat or != (Vektor vl, Vektor v2) .,{


return ! (vl == v2);

0
-
)

Na ovaj nacin smo istaldi da zel;i!no da ma&nje izrl!Za vl ! = v2 treha da hude isto'kaoTznacenje
~
. ! (vl ==' v2i, ~oS\l'~epo~.leva smno po·sehi svedok ne definiramo daje tako. Nairne,
D ova dva ~a~o J~ Z!l proste ugradene tipove;, principije~\je mogu6e_
m;ida su ·
..• i
preporueuje) definirijti opm;at!ile ~==" i "! =" na takav nacin da ovi izrazi hudu razliCiti.
(nlijda'sci ne

0
~
Za sl~;~j · ka(ia je ohjekte !xlredenog tipa moguee staviti u odredeni · poredak; ·pieporn~l
definir!!ti®erai<>te ;''S"· "<:" ";>·".i ";>=". N!! primjer, za ohjektl) tipa studen t, ima ~Ia
jivo. je ·
~~~ da
· je jed!i!l ~ent '!v~~., oil ~ ·aJm ima bolji prqsjek, itd. J8W i za ostale operatore
'. i q,V~jejrijedi
0
~
~raVilq ~·~ ~yi ~')1 ofi~R:jl~&e ne()Vi~ j¢lino~ drug~g, pa je 5Vilkom od _nj~ po~
potpuno nevezan:~. ziliiCen.Ja M~ posve Je J;ISUO da hi ov~ operatore trebalo definirat
i fl!ko d3 pusta
'f"ti
odr3Zavajii slliJsli? ~a z:l
~~J~e koji se razn1atraju. Kako za vektore poredak ni]e definifan; ove
a
J
operatore ziiklasli' Vektor necen,lo definirati.
. :· ··,· . .
. · ·
Interesantno je P.'Z;m<>triti operatoi e "«" i "» •. Mada programer i ove operatore maZe <lefil!irat
i da
J · obavlj~u rna ka1o/u
:fimkciju, #jihovo prirodno znacenje je ispis na izlazni tok i Citanje sa ulam<ig toka
Stoga, kad godje ohjekte iie~·Jdase moguee na smislen naein ispisivati na ekran ill unositi
sa tastatore, .
pozeljno je poc:hfati dase ~e iad!ije obavljaju pomoeu operatora "«" i "»". Na primjer,
ukoliko je v ·
objekat klase V~ktor, SasViin je prirodno podrZat:i ispis. vektora na ekran pomoeu
J' cout « v ~jesto konstrukclje v. r spisi ( l koju smo do sada koristili. Razmotrimo
konstrukcije
kako se ovo
more uraditi. PrVoprimijetimo da se izraz cout « v interpretira kao

1 7
I
JL
][
ope rato r <<(c out, v);

Ukoliko se sjetimo da objekat cout nije niSta drugo


nego jedna instanca klase ostre am, lako Cem.o J[
funkcije treba da bude tipa ostre am, a drugi tipa •
zakljuciti da prvi parametar t:raZene operatorske
siti po reforenci. Nairne, klasa ostre am je veom a
Vek tor. Pore d toga, prvi parametar semo ra preno
slo:lena klasa koja sadrZi atribute poput pozicije tekue
eg ispisa koji se svakako rnijenj~u tokom ispis a l[
Ukoliko bi se parametar cout prenosio po vrijednosti
, sve izmjene ostvarene tokom ispisa odraz ile bi se
objek at-co ut, Sto bi onemoguCilo dalji ispravan
samo nalo kalnu kapiju objekta cout , aline ina sam
rad izlaznog toka Stoga, tr~ena operatorska funkcija
more izgledati ovako: J[
void oper ator <<(o strea m 11 &co ut, Vek tor v)

}
cout << { <<
11 11
v .. x << ,
11
<< v.y << "," << v.z << "}";
J[
etar mora takoder zvati cout (mad a nema nikakvih .
-Nar~vno, nema nikak vih razloga da se formalni param
razlo ga i da se ne zove tako), stoga smo istu funkciju
inogl i mipisati i ovako: J[
v)
void oper ator <<(o strea m &iz laz, Vek tor
izlaz ·-<< ""{" << v.x << "," << v.y <.< "," -<< v.z << "}"; · ][
nicu da je cout obiena promjenljiva (iako veoma
Ovim prim jerom Sm.o samo htjeli da istaknemo Ciuje
specifienog tipa). Takoder, treba istaci da podrSka
za ispis "obiCnih" tipova podataka konatrukcijama
nijeoStvarena nikakvom posebnom magijoln, ti.ego
su
~
. popu t cout « 3,- cout « "Poz drav " i slieno ije za oper ator" <<'' koje
varajuee operatorske funkc
u biblioteci" iostr eamj edno stavn o definirane odgo a
obavljaju njiho v ispis. Prvi parametar ovakvih opera
torskih funkcija je naravno tipa a strea m, drugi
t int,' char *- itd.
ID
parametri predstavljaju proste ugmdene tipove popu .

_Prethodne izvedbe operatorske funkcije za operator


"<<" posjeduju jedan veliki n~ostatak.Naime,
suvl i v2v'ektori,nakojuSino!)aviklipri~lidusa
~
kons ilukc ijapo putc out << vl'« " "« v:i gdje
Nairne, oya konstrukcija 8e inter pt'et k kao · ' -
prostim ugrad enim tipo~?> nece biti prihvacend.

(. (cou t << vl) << " ") << v2


~
cia iglii poVrntni tip void , izraz CO!lt <.< vl ne ~osi
Medutim, kako smo'operatorsku.funkciju definirali
bude primijenjen op~ "<<": Ukoliko
nikakVu povd tnu vrljednost nako ju ,bipo novo mogaO da da prethodna koti.sl:iuK~ bude Zl!piavo
~
zeliino·_ da po ~ rtadovezivanje, mi zapta vo ~elin).o .. ••• -., ·.. -- ·
. . ·- .. .. ' . - .. . ''
. .. •. ka'
mter pretu ana _ o
. •· ·
D
cout << yl;
cout << n ".'
cout << .·.v2; D
rjeSei{~e ~~pnani~7: 8Pa~to~. ~cija kao i~~ treba jla vrati~J>}~Y<> ~bje~ c?ut !
da J>pd~ !3kod er ostre al\L ·ll!J.·_ bt ~.,,IZbJeglo
Sada se
Stoga povra tm tip ove <>Pefid;Orske f\u)ketJe _tr¢ba
ti.epotrebno koplr iinji obje~ #~ut Priliir~Ifi ]lov.tlifi<~
iZ ~~je, wilje~'samo!l co~'f::obfe}# '#3ea se D
e t\mtmije zaoj>~or "«" izgl~a?vako:
reforeni:a na njega: Tako bi polx)ljsiina ver:iija operatorsk
.

a strea m &op erato r « (ostr eam &cou t', Vek


COUt << ~ { . << V .X << n 1
11 n <<. V • Y <<
11
.

tor v) f
1 li
<< .V. Z << n} ".i
u
u
retu rn cout ; ·· ·
}

za ispis prostih tipova izvedene tako da koo rezultat


Ako. uzme mo u obzir da sui operatorske funks:ije
uvijek vraea ju cout (upravo sa ciljem da podrZe
napisati i nezn atno lmiee:
nadovezivanje), istu· operatorsku funkciju. nio:lemo
·· ·· · · · I
8
D
ff
ostream &operator <<(ostream &cout, Vektor v) {
return cout << "{" << v.x << "," << v .. y << ",." << v.z << "}";

Primijetimo da se objr,kat cout i prenosi po referenci i vraca po referenci. Ukoliko to ne ucinimo,


postoji velika sansa da 6e nam kompajler prijaviti greskn (sto je sretna okolnost). Nairne, u mn()gim
izvedbama klase ostream njen konstrnktor kopije je deklariran u njenoj privatnoj sekciji, sto spreeava
neovla8tene osobe (to jest, nas) da vr8e kopiranje objekata .ove klase, a pri. prenosu parametara po
vrijednosti iii vra6anju objekata iz funkcija dolazi upravo do kopiranja (koje je zabranjeno). Jnace, /
deklariranje konstrnktora kopije u privatuoj sekciji je cest trik koji projektanti klase koriste ukoliko zele.
da sprijeee korisnika klase da moze vrsiti kopiranje instanci te klase.

Na potpuno analogan naein mo:iemo definirati i operator ">>" za Citanje sa ulaznog toka, samo
trebam.o voditi racuna da je cin instanca klase istream. Tako bi operatorska funkcija koja bi omogucila
citanje vektora sa tastature konstrukcijom poput cin » v, pri eemu bi se vektor unosio kao obiena
trojka brojeva razdvojenih razmacinia, izgledala ovako: · ·

istream &operator >>(istream &cout, Vektor &v) {


return cin >> v . x >> v.y >> v.z;

Bituo je napomenuti da se ovdje drugi parametar takoder mora prenijeti po referenci, jer konstrukcija
poput cin » ·v, koja se zapravo interpretira kao operator »(cin, v), mor;l da prornijeni
vrijednost objekta v. · · · · ·· ·

bd binamili-operatofa.inoguCeje reo tefeti:ti ·as i o eratore "&", """, 1'\ "&&", "U ", "->* 11 i ", " ..
11

Meduttin, ovi operaton imaJti p ·cno specificna znaeenja zit ugradene tipove, i dosta je teSko zatllls tJ.
, sta bi oni trebali da radeuk01iko bi se prirnije:tiiii na slorene tipove podataka, m3da nesumnjivo postoje
slucajevi kada i njihovo pr~pterecivanje ni()ze biti korisno. Stoga se pn:opteie6ivanje ovih operatora ne
preporucuje, osirn u sluc_ajeVima kada .za to postoje jaki razlozi. Isto tako, ne preporucuje se bez velike ·
potrebepreopterecivati Wiaiiie op'~:raiore "*" i "&". · . · · . . ·

Kao ilustniciju do sada iZ!orenih koncepata, slijedi prikaz i irnplementacija prilicno upotrebljive
. ~ klas~ ~a11e K()mpl6ksii~':k?.Ja .timo~~vy~sa ko1I!plek5nirn brojev,umi. Klasaje po funkcionalnosti
' veoimi slien!l tipu (k13.$i.J pp!itplex' .jz.fstoitn7Jle bibliotel<;~ lmju smo ranije l<;oristili, samo sto·je ne8to·
• sirOJD.ii.fui.ja sa ,funk:cijamit; K!lk<> Je ifimkcije .pnjatelje ~ talmdl:f moguce ii:nplementirati odmah
lUiutiU- dekl~~ ki~;~~~#J:a.#li sepilfio staiidardnimi op~J<ItOrsk:ini fimkcljama (sto je uputuo
.· . ritditi s!iJno nk.~Wc~ iip je'~l? ¥~~); to je u ovomprimjern i uradeiio, iznZe¥ opei'at~e funkcije Za ·
operator"»", ~jeje tijel~i\eSto du:ie: ·

cJ.a§~. Kompleksni (
· ~:-_douple r, i;
public': . ··.....
· K.;nipleksniJc:tP\ibie t '0, .·double i - 0) : r (r), i (i) {I
iri$lld Koiiipleksiii oP<i:tator +(Kompleksni a) { return a;
f"ri'~P<f koinPleksni 6P<a.:ator - (Kompleksni a) !
return K()jripieksl1~(-~.r; -a. i);
} . ; j·.
friend Kompleksni 'e>pj#-ator -t (Kompleksni a, Kompleksni b) . {
,;eturn
.
~ompleksriit-a':r
'· .-- .. - ·--
+ b.r, a.i + b.i);
}
friend Kompleksni, <)pe;ator - (Komplekimi a, Kompleksni b) {
_rft!turn-a- ·+. '-:q;_-_- ~--- · · -
.} .:·.' . - ~.-:. - .. - - . . ;- .. ··l ...
friend Kompleksni operator * (Kompleksrii a, Kompleksni b).
:teturn Kompleksni(il.r .* b.r- a.i * b,i, a.r * b.i + a.i * b.r);
J

9
!
friend Kompleksni operator I(Kompleksn i a, Kompleksni b) (
i
}
double d = b.r * b.r + b.i * b.i;
return Kompleksni ((a.r * b.r + a.i * b.i) I d,
(a.i * b.r- a.r * b.i) I d); !
friend int operator == (Kompleksni a, Komp,leksni b) (
return a.r == b.r I I a.i == b.i; 1[
} "'·
friend int operator !=(Kompleks ni a, Kompleksni b) (

}
return ! (a == b); 1[
friend Kompleksni &operator +=(Kompleks ni &a, Kompleksni b) (
return a = a + b;

friend Kompleksni &operator -= (Kompleksni &a, Kompleksni b) (


f
~
return-a= ·a- "b;
}
friend Kompleksni &operator *=(Kompleks ni &a, Kompleksni b) {
return a = a * b;

~
}
friend Kompleksni &operator /=(Kompleks ni &a, Kompleksni b) {
return a = a I b;

~
}
friend ostream &operator <<(ostream &cout, Kompleksni a) {
return cout.<< "{" << q..r ~< "," << a .. i << ")";
}

~
friend istream &operator >>(istream &cin, Kompleksni &a);
friend double abs(Komplek sni a) {
return sqrt(i:t.r * a.r +>:Li * a.i);
}
frien,d double arg (Kompleksni a) 1·

}
return atan2 (a. i, a. r) ; ~
~
friend Kompleksni sqrt(Komple ksni a).(
double p ':'. sqrt (abs (a))' q = ai:g (a) /:2;
return ~ompie_ksni (p * cos (q) , p * sin ( q) ) ;
} ...

~
I ;_
......
_

n
-~
~
}

Vidimo da 5u u ovoj klasi pedrZana Cef:iri oSiloVii3 !lritnieticia.oper~"+", "-", "*" i "/", iatim
odgovaraju6i pridruZuju6i opeiafori "+,;,", "-=~, "*=" i ''l="~ ..oPeratorf:p~enja ·~,_c" i ''! =", lcao i
operatori za ulaz i izlaz "»" i "<<". Pri t()meje predvi(!eli!) d3 se kompi~ni brojevi unose odnosno
ispisnju kao parovi realnih u zagradama, ra1lvojeni zareziina {ripr. (2' 3) ). s.;,e papisail.e
~
ne treba poseb~o obj~javati. ilidino je p(>trebno

~
. operatorske funkcije sn-piisVe
objasniti ulogu kimstrukcije . u ~orSkoj funk:ciji Za operator .
Nairne, ini smo do sada cin, u oblikll · o , oditoSito
bez
-~
10 ··~
;r1 I
.111

f'.t
nI 1lll!!fr·~ eemu se reljeno stanje zadaje parametrom. Tako, parametar ios: : badbit oznaeava
l]eispravno stanje (ios: : badbi t je zapravo konstarita pobrojanog tipa denmrana unmar klase ws u
biblioteci iostream), taka daje svrha poziva cin. clear (ios: :badbit) upravo 1q dmwdemo ulazni
tok u neispravno stanje. ~a.Sto ovo raclimo?IPrimijetimo da se ovaj poziv vrsi u slueaju kada na ulazu

1 aetektirnmKRak koh se ne bi trebao da pojavi na tom mjestu (npr. kada na mjestu gdje oeekujemo
orvo;:ellu zagradu zatekuemo nesto drugo). Ovim smo postig!i da u slucaju da prilikom unosa poput
cin » a gdje je a promjenljiva tipa Kompleksni ulazni tok dospije u neispravno stanje u slucaju da

~
DJ.smo ispravno unijeli kompleksan broj. Na taj nacin ce se operator"»" za tip Kompleksni ponasati na
isti nacin kao i za slucaj prostih ugradenih tipova Alternativno Ije5enje bilo bi bacanje iznzetka u slueaju
neispravnog unosa, ali u tom slucaju bismo imali razlicit tretman gresaka pri unosu za s)ucaj tipa

~
Kompleksni i prostih ugiadenih tipova .

Pored ovih operatora,.de:finirane sui tri obiene funkcije (ne funkcije clanice) abs, arg i sqri: koje

~ •
respektivno vracaju modul, argument i kvadratni korijen broja koji im se proslijedi kilo argument
(cinjenica da funkcije abs i sqrt vee posto"e ni"e rob! 'er "e dozvol'eno imati. funkcije istih imena
:Koje sern · ~u po tJ.pmmna argnmenata). Ovo sve zajedno cini sasvim solidnn po~ radu sa
• komplekSrirm brojevima Primijetimo daje unutar funkcije arg elegantno iskoriStena funkcija atan2 iz

~t standardne matematicke biblioteke, koja radi upravo ono sto nam ovdje treba Ne treba zaboraviti da je u
program koji implementira ow klasu obavezno ukljuciti i matematicku biblioteku (cmath iii math.h),

~
zbog upotrebe funkcija kao sto su sqrt, a tan2, sin itd

Ukoliko bismo testirali gore napisanu klasu Komple.ksni, mogli bismo uciciti da su automatski

~
podrZane i mjesovite operacije sa nialnim i kompleksnim brojevima, iako takve operatore nismo ··
eksplicitno definirali. Na primjer, izrazi 3 * a iii a + 2 gdje je a objekat tipa Kompleksni sasvim su
!egalni. Ovoje posljedica cin'enice da k!asa Kompleks,ni ima konstruktor sa "ednim ara ..
(zapravo, 'kia ko or sa odrazumi"evanim aram . .. "i se 0 ze rotnmaeiti i k
\~
. •
:Ko or sa jednim parametrcim} koji omogueava automatsku pretvo'rbu tipa ·double u tip
*
kompleksni. PoSto Se izrazi 3 a i a+ 2 zapravo intrepretiraju kao operator * (3, a) odnosno
opera tor + (a, 2) , konverzija koju obavlja konstruktor dovodi do toga da se ovi izrazi dalje

~ interpretiraju kao operator *(Kompleksni. (3), a) odnosno operatoiO ··(a, Kompleksni (2})
Sto ujedno obja.Snjava ~to su ovi izrazi le~alni. Primijetimo da l>i u ovom slueaju bilo potowio
pogre5no definirati oPeiirtorsku funkciju za rnnozimje realno bni" a sa koni leks . 'er . nm
~lf!! . definiCI om o ut s e
Kompleks~i operator *(doUbled, Kompleksni a) {
·

~
return Koinpleksni (d * .a .·r, d * a. i); ·
:.·'.

Nairne, u tom slucaju pri naila5ku na izraz tipa 3 * a kompaJiet. he bi !liogao da <lit .li .tr~l>a . zna
~
' • ' ' • • _' --- - _. - _•, ' ' ' ' -:r--- • -_•,_ •-.. -•..-,-;:.,. '
• -"•' .• • •' ,'- _.M" • • • '_ •" - .C•"• • ·~ r -~

~~en~~ golJlJ? dePili.l)iju. op,eiatl)r,lke fimkcije, ·iii ~e!Japrvi ~~~~j·e~ pr$\tlr.i~~ u ~Ji.~f~~~gi"!'i~. i .
prumJeruti operator za B.lilO,.,e1J.Ja dva kompleksria J:lroJa. U nav!l!i~m Pt!W~ rt1~~W p~~ ~~-~)a
god da se st£ategija pm,njeni, ali je programer mogao da isprogr»i};j~a i. di}ig_~ijn liJr~iJ~ ZQ!)g ~<>SjtJe /

~ 'I
usvojeno da kori:t ajler pnjavljuje greful kll.da od sto-· ino enlist da se isti izriiZ in ... "i'et,imti , maze
na VI e razlicitih na a, koJI ne moraju nuZ11obiti ie<lnaki. · · ··· ··
. . . . .. .

. Razmotrimo sada preoptereCivanje operato . "++~-;,;~_-;;)Njihova ~!!cl!ift.\ost u <)dl;l!lsuriapi>{ale


~ unaine operatore je u tome Sto oni imaju i piefiksn.11 po · · oblik, npr.lllQZe se pisaJi ;H~ ili 11-+:1-.
Prefiksni oblik ovih operatora preoptereeuje se na isti naCin kao i svi ostali Ullanii opim!foii. oifuosn<i

~
izraz ++a interpretira se kao operator ++(a). Definir~o, na pnmjer, openijOr "++" za klasJ1 vE;'ktor
sa znacenjem poveeavanja svih koordinata vektora: za jedinicu (koriSt eid ovakvog openiJ:oia je
diskutabilna, medutim ovdje ga. samo
definiranio kao primjer); Kako je za ugradene tipove. defil)iraito" da
je rezultat operatora "++" vrijednost objekta nakon izmjene, uCini6eJno da ist9 vrijedi i za ope!Rtor "++"

h koji definiramo za klasu Vektor. Stoga ovaj operator moZ¢to de~ati pomoen sljede& operatorske
funkcije:
J,!
'
•- I~ 11
1
_Ll

I[
-
Vektor &operator ++(Vektor &v) {
v.x++; v.y++; v.z++;
return v; I[
----- •:

Citaocu je vjerovatno sasvim jasno za8to je parametar v prenesen po referenci. Medutim, manje je
jasno zbog eega smo kao rezultat vratili referencu na izmijenjeni objekat, a ne sam objekat. Ovim smo
ll
samo reljeli da opona8amo veoma rijetko koristenu osobinu po kojoj je za ug~:adene tipove podataka ·
\ rezultat pre:fiksnog operatora "++" 1-vrijednost, rna koliko to izgledalo eudno (npr. ukoliko je a
• cjelobrojna promjenljiva, izraz ++a = 3 je posve legalan, koliko god da jenjegov srnisao upitan).
ll
V aZn.o je napomenuti da definiranjem prefiksne verzije operatora "+ +" odnosno "-:-" nije automatski
definirana i njihova postfiksna verzija Na primjer, ukoliko je v objekat tipa Vektor, prethodna ll
definicija ucinila je izraz ++v legalnim, ali izraz v++ jos uvijek nema srnisla Da bismo definirali i

~
~ostfiks~u ;erziju operat()ra "+~"; trga matj ~a se.~ poput a-i-+ _gdje je a ~eki sl~reni tip P?~akm Ill
0 binami operatori, ali ~iji jedru'
mterpretiraJU kao o era tor++ a 0 .))rugim njeCima, postfiksni operaton "++" 1 "--" tretlraJU se
orruvijek cijeli broj...Q. Zbog toga bismo postfiksnu verziju •••
operatora "++" za klasu Vektor mo efinirati na sljedeCi nacin (primijetimo da smo morali definirati
drugi parametar, bez obzira sfo ZUlllilO daCe njegova vrijedJiost uvijek biti nuJa): ll
Vektor operator ++(Vektor &v, inti) {
.

Il
~
Vektor pomocni = v;
v.x++; v.y++; v.z++;
return pomocni;

prefiksn~ ~ postfi.ksne verzije operatora "++" i "--" imaju i~o


i
dejistv·o na op<::raJnd, ~ !!~~~ie,P~ samo vracena vrijedno~ (po§#iksne verZije ovih operatora wacaju
i.l · ~ istu fuukci()!lalno~ SID() simuliralf i u prikazanoj
Vektor. ·Pri.rni.jetimo da ovaj put nismo vratili
ll
nl za pro~e ugradene ~poye rezultat postfiksnog operatora "++"
][
referencii kao rezultai:.
nije i-vrij~~o;8t~·~·~·~~~&~~~m; a++ ;. 3 nije I~giuai'Cbez obZira sto
n nikad
.vovoni slucaju hila.
1 1 jer
. ·. referc:ncu kao ii:zultat,
· viSii6u rcifereii.CJi! ·'· .
++a = 3 jeste). cak bi u
objekat. pomocni premje da Zi.vi po
·· · ·
• zavr5etku funi<cije,
:0:
JjJ
I ]J
.-·S~eno, Ukoliko.je •1• rie~J~ami o~~~or, ~az
uida St; *,i ~~ra kao ~rator * (x} u ru
slueaju daje odgov~!f.!juq~<Jpejidoiska filnbija definjmlia kao obWria :fulikcija, a kao~
u slueaju da je ilet'i';it;3D;ii kaq)imkcijli claiiica Za'slucaj" opertu,ora "++" odnosno -- , za njihove
preflksne ver:Zije ~e4i)~b stb l za SV:e o~e unarneoperato re; "ilo~ se njihove po~ne verzije u l~
. $lucaju· da sti odgoViitafo¥ -:oj)etatornke fimkcije lfefinirane kad fiinkci]e clanice interpretiraju kao
x. o~rator ++ {o) odnosno x. operator _:_ ( o) cu: fiktivnini
sajednini cjelobrojnim argumentom).

Pogledajmo kako bi mogle izgledati definicije operatorskih fuukcija za binami operator ;,+;. i unarni
lD
minus Za klasuVektcir ukoliko bismo .seodlucili da ih implernentirari:to kao fuukcije clanice klase. Za
tu svrhu bismo morali nezilatno izmijeniti deklaraciju same klase, da dodamo odgovarajuee prototipove .
(ili cak i kompletne definicije) za opei:atorske fuukcije clanice: . Ill
12
·rU
l.
I~ I
·u•L
q
q class Vekto r {
double x, y, z;
public :
Vekto r(doub le x, double y, double z) x(x), .y(y), z (z) (}
double Vrati x() const { return x; }

Q double Vrati y(J const ( return y; }


double Vrati= z() const { return z; }

q );
Vekto r opera tor +(Vek tor v) const;
Vekto r opera tor-() const {retu rn Vekto rt-x, -y, -z); }

g Operatorsku funkciju clanicu zaunar ni operato r"-" smo implementirali odmah


klase radi njene kratkoee. Ni definicija operatorske funkcije za binarni operator
smo se ipak odluCili da je implernentiramo izvan deklaracije klase tek da uoeimo
unutar deklaracije
"+" uije mnog<i duZa, ali
kako treba izgledati,
zaglavlje operatorske funkcije clamce k!ase n slueaju kada se ona implementira
izvan k!ase (primijetimo
R da prva pojava ri"eei Vektor oznaeava povratni tip funkcije, dok druga pojava rijeei
operatorom ": :" oznacava 'da se radio Ciju l!'anicik!ase Vektoi l: · .
Vekto r zajedno sa
· ..,

0'' Vekto r Vekto r::ope rator +(Vek toi v) const {


return _Vekt or(x + v.x, y· + v.y, z + y.Z);

0
,.,
Pri susretu sa ovako definiranom operatorskom funkcijom pol!ettiici se u prvi mah
.odnose imena atributa poput x~ y i z koja su upotrijebljena samosta!no, hez operato
zbune na sta se
ra "_" koji oznacava
pripadnost. Medutim, ne tr!<ha zahoraviti da .se radi o funkciii clanici (ti,.met
D
'
!,.....
.
primJ.j!llljuje nad nekim o/fletlom.Taaa se ova nnena odnose na imena ono
·. ~jim Je meto~ )lnnll]eiiJena, Ffa
odi),
li'o..
·a e uvi"ek
tno oh'e . n ·
I?riii!Jer, tzrazv l + v2 !!, ~e su vl 1 :v2 vektorl; hiee interpretirau ~(}
vLope rator + (v2), ta],<:o da Ce$.X, y_i_z_odnositi na iitrihute objekta vl
D
-·-
metoda informaciju o ohjektu nad kojim je primijenjena dohija preko pokaii:v
jasnije ukoliko uocimo dide istaoperatorsk,a funkCija ~lanica·mogla napisati i ovako:
·-.- - .. -- .
(po!Isjetimo se da ~3ka
aca this),. Ovo postaje · ·
. ' . • . ...' -· ...
'
.· '

0
.--~
)
Vekto r Vektor ':: opera tor + (Vekto r V) const {
return Vekto r(this- >x + v:£;
. this:_>
-. - .
y + v.y, this->z .·+ v;z);
~--.

0
"
. : '- - . _. ··-· :_\/:.:.::
Jos jedan naein da n~pikmoi~tu fiinkciju clru#<l.u n;togao hi ~gl~ ~ya,kg
.'-·· _-.-· .. . .· ·._- ...
(pri een;tu se ne nitv~.
eksplicit:Iio pokazivae this, ali se ek~licitno iSticf: da s~ ~, y i z {)drio~e na oJ>jekat
kl~e Vektorlilld.
_-:_ --~·-·:_::_... · ... - . - -__.>;_:.·

'"'f' .
n
kojimj e funkcija c!anica primijerijeu); . . .. . . .· ...
., Vekto r Vekto r: : oP.,rat cir +(Vek tor JT) const { ·
return Vekto r(Vek tor::x + v.i<, Vekto r.::y + v.y, Vekto r::z +
v.z);
0 )

funk~~~~~!:rlrl?~nf:!~u~~~a]~~!~~~:~~·. 4~!#l~~!ie:%~~i~~;~~
a r~ po~Ctimo.~···se ~~·poput·~·w·i~~l':jf··t<~ 'rt~--~~}f~i?fil~v'r~.'~
opera tor * (x, y) ill x ; o!)e;.., tor *(yJ u
~o da li je odgoyilra_JiicaoYi~qsti
fi!rik#ja 6pe'r~ka
ohiena fi!nkcij;r iii ~~ja ~laJ!ic~Jciase:#~rm~fWp6~& ~illlll"J#p.P,~$o?;!+"
klasi Kompl ehinL Vidjeli smo'd,a 5u 2:apyl!fjujuci ,Pq~anjri koliSjrii!ctg!"#.:.~
J,.oji~i4e~,ii.
jednin:(ji~ii,l:!'9.m)
alrtomatskoj pri:tvoibi. ~v11 kojli;se osty~ kii~~ioOi, i7fi!ii ·Ji<li§fa
+. 3 i. ·3.. fa gdjae ~.
ohjekat tipa Kompl eksni potjmno !egalni; ~!'Pos.~llVimO SiJJla di!.Sri:t~.}IP.j
~
operatorsku fi!nkciju za 9peiator "+" defuili-atikai> ~cijti cianicu klase i<oiti!)I
.o~~9Jtu fiml?rif~? kao
eksni, Tada hi se qva
prethodna izraza intc:rpretmiia kao a.oper ,.tC>r +\3ii 3,opeZ:a.1:or -J:faJ:
Prvi ~bi i dalje Jiio
legal an Ger hi se on, zllhva1juju6i auto~tskoj preivorhi. jjpova pri preim_su.PiJi¥'e
tp:a. u funkcije, .dfllje
interpretirao kao a, ciJ?&rator + CKonipleksni (3) ) ), dok bi drugi izr8Z hio ilegalan
, jer 3 nije objekat
nad kojim hi se mog!a primijeniti neka metoda Drugim rijeeima, izraz 3 + a postao
hi ilegalan ma4,a bi
~ + 3 i dalje hiofegalan! · • ·

13
I
JL

kom cia kada se god nek:i binarni operator definira _


JI
' I G· Ovaj primjer moZem.o generalizirati zakljuc
ja clanica klase, tada se na ervi operand ne x~•e nikakve
' • f pomoc u operatorske funkcije koja je funkci
automqtskii pretvorb;tipo~a. Na taj nacin, definiranje operatorske funkcij
e kao funkcije_EIImi<Qlj<JnJjl: ][
d (Sto je vHIIJlVO VeC i iz cinjenice
uvoo.ITzrazitu asimelrijiiii nacin kako se tretiraju lijevi i desni operan
se desni operand prenosi kao
da se operatorska funkcija tad izvodi nad lijevim operandom, dok
·parametar). Stoga, ukoliko nam ova asimetrija nije peU!jn a, opei-at
orsku funkciju treba definirati kao
je bolje definirati operatorsku

f obienu funkciju, dok u slucaju cia nam ova asimetrija odgovara, tada
ugradene tipove, vecina binarnih
~
funkc iju kao funkciju Clanjcu Da budemo koukretni, za proste
"!=", "& 11 , " " " , "1 "&&" i nil"
11

operatorapoput "+", "-", "*", "!", "%", "<", "<=", ">n, ">=", ==",
11 ,

bolje preopterecavati operatorsk:im


tretiraju oba svoja operanda ravnopravno, tako da je ove operatore
lje razmat rane klase). S druge strane, nek:i od
funkcijama definiranim kao obiene funkcije (tipicno prijate
operatorakao Sto "~" =-" -= "*='' " ="
11 11 11 110
=" "&=" ""'="-"
1zraz1to asimetrii!ni, zbog toga sto modificiraju svoj lijevi operand (koji
!=", "<<=11 11 >>=" s · ·
zbog toga mora biti 1-vrije
i su
dnost) ~
Zbog toga je. ove operato re mnogo bolje preoptereCivati /
li ne .kvliie s!ld&j svog ·desnog operanda
operatorsk:im funkcijama koje su clanice odgovarajuCe klase (vidjee
uopce ilernamo izbora .- odgoyarajuca operatorska funkcija mora biti
erno kasnije cia za operator "=" .
clanica klase). Pogledajmo· kako bi •
[
. Za .klasu Vekto r (pri tome
mogla izgledati definicija'· operatorske funkcije za operat or "+="
pretpostavljamo cia smo u deklaraciji klase Vekto r dodali odgoyarajuci
prototip): [
Vekto r &Vek tor::o perato r +=(Ve ktor v) {
x += v.x; y += v.y; z.+= v.z;
retur n * tJ:li_s; ·-{
}
/ .-

;rru~~~triti.pos\jednjunaredbu ove funkcije.


· · ·
Podsjetimo se da bi izraz poputf'vl += v2f
v3 = vl += v2
[
[
-
[
u
# }
D
iii jos kraee kao
. I. r. Vekto r ~vekt~~.' .<Qpe rator += (Vekt or v) I
0
VV re·tur#. '*~~~:~=--*this + v;
} D
~oder su asinletriCni o. prirodi. Medu · _!1jih ne moZerno definiratieprvi
·1 ~. ~ · .. ori "<<" i ">;.'' ilijcore kao
limo daobav ljajufu nkciJu · aza . osnoul aza). Nairne, kakoj
• • funkcijeclanice'(barljetJk<
parametar opeiitoj'Sk~fUilkcljezaoperator "«" obieno tipa a stream
, a za opera tor"»" tipa istrea m, D
e clanice klasa ost~eai!l· odn,o5no
slijedi da. bi. OdgO'viiri!Jiice :~peratorske finikcije trebale biti funkcij
istrea m, s ob~:da ~ <iperatorske fuhkcije CJ.anice primjenjuju
nad svojim lijevim operimdom.
m i doplllljivati ih novim
·~
Medutiin, kako.m je poreljn o lirijerijati de~clje.kla5a ostrea m
i istrea
a ne da se mijenjaju), kao J.jesenje
funkcijama clanicama (ove klase su napisane sa ciljern da se kariste;
~
ilam oStaje koiistcllje klasi~ funkci ja ·

14 u
f1
\ Sto se unarnih operatora tiee, za njih je u slistirii svejedno da Ii se definiraju preko obicnih
operatorskih funkcija iii operatorskih funkcija clanica klase. Mnogi programeri sve unarne operatore
. 2efiniraju preko · operatorskih funkcija clanic•, jel:._talaia_ prakSa eesto vodi ka neznatno kraCoj
implementactJl. Operatore "++" i " " gotovo svi programeri definiraju preko operatorskih funkcija
Ctrullca, maaa za to ne postoje izraziti razlozi ("ljerovatan razlog je sto se oni eesto mogu smatrati kao
specijalni slucajevi operatora "+=" i "-=", koji se tipieno izvode kao operatorske funkcije clanice).

Moguenost preoptereeivanja nekih specijalnih operatora mou takoder imati veoma interesatne
primjene. Posebno je interesantna moguenost preoptereeivanja operatora " [ 1" i " () " koji se normain o/
koriste za pristup e1ementima niza, odnosno ·za pozivanje funkcija Kako klase nisu niti nizovi, .niti
funkcije, nad objektima neke klase ne mo se normalno rim. en "ivati ovi o eratori. N a primJer, Ukollko
Je a o ~e at neke klase, sami po sebi izrazi a [51 odnosno a (3, 2) nemaju smisla (druga sitnacija bi
A hila da je a niz klasa). Medutim, eesta situacijajc: da intamo kl~ koje s_e pq,!W9ioj strukturi _eonallaju
l poput !!iZoll~(tipican primjer SU k!ase VektorN i Razred koje smo ranije razVijali), s obzirom da U sebi
' envaju iz"ljesne elemente (ovakve klase se nazivaju/liOntejnerske klasfi/). Takoder, moguee je napraviti
!I ~~ic: se gg !JYOjoJ ~ ponallaju poput fimkci(':_ (p?rnjer bi mogla bi~ klasa koja b~ opisivala
Vom CtJl shoefictJ enlt mogu zadavatt). PreopterectvanJe o atora " [ 1" 1 " () " omogucava da se
klase koje 5e pona§ajU. kao nizovi korisJe koo a se radi o nizovima, odnosno da se ase koje se
ponallaju poput funkcija koriste koo da se radio jimkcijama.

Razmotrimo jedan konkretan primjer. U klasi VektorN koju smo definirali u prethodnom poglavlju
imali smo funkciju c!anicu Element koju smo koristili za pristup elementima n-dimenzionalnog
vektora. Na primjer, Ukoliko je v objekat klase Vekt,;rN, koriSti!i smo rogobatne kollstrukcije poput
v .Elemen t (3) = .lOili cout « v .Elemen t (2), Bilo bi mnogo prirodnije kada biSmo mogli pisati
samo v[31 = 10 iii coirt « y[21. u norma!niin okolll stWk
avo nije moguee, s <lbziiom da v ni"e
niz. PreoptereCivanje operatora " [ 1" .e ornogucitt . . o'vo postane moguee.- PreOpferecivanje ovog
. Oj}eratora sasvim je jednostavno, a izvodi se deflniranjem opetatorske fi.mkci.le ;,pe,:,ato r []. koja.
obaveZn.o mora biti.,miJ.kciia ~lanicq )daie ia koju se definira ovaj operator. Pri tome se izraz oblika
tfr- ·x ry 1 interi)retira kao · · · · ·
.:;
x.operat or[1(y)c b--> .. f
Odavde neposredno slij~
~
• -._ ':-:, . ,·.
da zeW:~;~~o~o umj~o
ukollko •
' -" ·'···: .• ·- -·.- •• '
da: - - • v.Eleme nt (i) inoumo pisati
.--"!f>>'j.J,~ ~
- . . - . - .
prosto v[i], sve_ St<}'tr!lba dl>.madimo je da Pl:?i¢jeni .
mo ime funkcije clanice Element i u
operato r f 1, dok njrifia defuijcija· trio~e ~- isia;'~Wedi p<iboljSmia d.!lfWcija klase vektorN, u
k~joj SID() po!ed ()PW,i1tpra "[l ''#put de~i gp~~ "+" i "<,;::" umjest~funkcije ZbirVek tora i
metode Ispisi, koje ~o koristiJi u ranijirrid '¢:finiCij b'
cl~~s vekto~N J ..;.'.
~4J~t Bioj"E~e~enata;
. dbt.ible *Elemen ti;
P"W~c:_ .....·. ··.·.. .· . .
- i>Xf;lici t ·v:e.ktorN (.int n) : BrojElei nenat& (n), Element i (neW' double [n1) {)
- VektorN (ci.nst VektorN &v) ; .
-vektorN 0 1 delete [ 1 Element i; l--' ~c.~..
f~~end. o;;tream <i:op~rator << Jostre?Ji l &cout, VektorN v); - -~ -~. '< < "
dio\ible.~rator n (int i) !::cini!Jj, : . . . - P"}p' <~ ._:-c_ "J"
.frierid :ve.ktorN oj;erato r -1: (Vektor~ v.1, VektorN v2); _ fW"f'-1 ."'f""·· "+-"
); .. :
- VektorN : :VektorN(C:~nst Vek_torN &v> ! BrojElem enata (v.Bro "E.lemen ata),
E ementl. new o . Q v. ro -e'"·ena a .
for(int i - 0; i < v.BrojEl eniehata ; i++)
Element i[i1 = v.Elementi[~1; · ·
}

15
}[
}
ostream &operator <<(ostream &cout, VektorN v)
.. cout << " {";
for(int i = 0; i < v.BrojEle menata - 1; i++)
cout << v.Elemen ti[i] << ",";
return cout << v.Elemen ti[v.BrojE lemenata - 1] << "}";
If
}

double &VektorN ::operator [](inti} const (


if (i < 1 1 1 i > BrojEleme nata) throw "Pogresan indeks! \n";
~
return Element i[i- 1];
1[
VektorN operator +(VektorN vl, VektorN v2) (
if (v1 ..BrojElem enata ! v2 .BrojElem enata)
throw 11 Vektori koji se sabiraju moraju Diti iS.te dimenzije !\n";
VektorN v3(v1.Bro jElemenat a);
j
for(int i = 0; i < vl.BrojEl emenata; i++)·
. v3.Eleme nti [i] = vl.Elemen ti [:i.] + v2 .Elementi [i];
return v3 i ;~
j
}

t Jasno je da objekte ovakye klase, zbog cjnjenice da je defitrifan operator " r J " moZemo lmristiti kao l[
! nizove ito kao arne e ·· · kod kojih se ro ·erava opseg indeksa i l:iji indeksi oCin'u od ·edi ·
-Izvjesne standardne bibliKote ·e jezika c++ kpo sto su valarray i vector, definiraju istoimene klase
koje su gradene vrlo slieno kao klasa VektorN koju ovdje razvijamo, samo sa daleko veCim brojem 1[
metoda. Stoga k()risnici jezika C++ rnnogocese e koriste _objelcte klasa val array i vector J
se sa njima .· . raditi kao sa obicnim nizovima, a njihovo kori.Stenje je ne •
umjesto obiCnih
· Na · · . vratiti kao rezultat iz aobjekat 1[
1[
biblioteke jezi:ka C++~ ..
koja detaljnije
. . .. ·... . . . t' .,,,;,;· ....· .. · . . · . .
_Bitno je naglasi~ d~ J<a9a. ~~ ~ feku kl~ d~~.~~tor n[ 1",i=, x [ yJ. gdj_e je_ x (}~jekat te · /jl
1[
!a;:en:;:faLa;::a ~~~;;~ks~;nela n~;.;· s:~~~~j?~;-~~~S:~ ~~r~o ~=..... ·
operatore, progniriter ~p~vo da operator "El" definfra ~o god zefi. Na pripljer, sasVimjem oguee ~
de:llnirati ovaj openitof'~:da "indeks" (pod ~odnicl®; jei: s~t:D,e rndi o_pravomi !ideksu) u
~a uop~ nije crjeil' ' "oj; nego~pr, realni b~iij, strint'l.~. ne~'l(iugi obje~t Na pf#li:jer, lie'k~
·
smo definirali klasu Tablica koja
· ·"._ ·_
cuv:i Vrijedtia#.r
.•., --· '· ...... ...,.... .,.l.--:-
-·--.~,

ie~e fi»!!cij~ Zlld.'?te


•,;r-'-
---·-·~~--:-:-···-.··.-.

ll\hler#'no ti
_- · -·Y·_--·.
tack~a I,
• ··
2, J l[
· itd. i nekaje T objekat klase Tabl ica. Prirodnoje 4efinjniti')) pciiltor~.u" t,al<;q ~ T [ 2] daje;;yrt,jeWJ ,ost
funkcije u tacki 2. MedUtiW,. fsto tako pedjednako"jma smiStaiief'iiiiraii f)Vilj op~ori za n~lol:!rojne
"indekse", takq da npr. T [2. 65] prc:K:Jei:u vrljed'n.9stiflmk~e tacki 2:65 ~ izV.iesne .
tiaje u. 1[
pretpostavke, npr. da je funkcija pnbliZno !ineiulia izmedu~iidanib i~a (ova:jjlostupak P4matje it
Naovom'i:i:l }estii.n~;po jiripf~entir# t~ klaSU, .
~
numerickoj matematici kao lineama inierpolacij a},
nego smo samo Zeljeli dati ideju za sta hi se "indeksirahj e reillnitti. brojem" niogl.o npotnjebiti.
. . . . -.' .-'
. . .· .. . . .
. . . .. -.. -

f Narocitoje interesantnamogtienost da se defuiirakla sakod koje o ; 'or • [J" k,ao "mdclcs" rihv~
:llimg. Ovakve itse slu2:e za tmp ementaCljU tzv. asocijatrvni nizova Na priiojer, ileka je p<itrebno
napraviti neki objekat naliJc niZJI U!W!!p stanovnis tvo kQjibi cuvao informilcije o broju stanovlrika ·
1[
pojedihih gradova, ali Ito)iln se koristio tako ila k:io •mife"ks" =!ajemo ime grada: Nil primjer: . · ·· · .
Stanovnis tvo ["Sarajevd~ = 500000; ·.
. ~- I[
Stano.vnis tvo [ "Banja Luka"l = 350000;
Stanovnis tvo [ "Mostar"] = 150000;
cout << Stanovnis tvo["Sara jevo"];
Razlika = Stanovnis tvo [ "Banja Luka"] - stanovnis tvo ["Mostar" ];
I[
16 ]J
I [ I
Nije veliki problem definirati klasu ko ·a ee imati definiran o erator " [ J " koji prihvata stifug kao
parametar, i koji omogueava yPravo gore. navedene konstrukcik Na primjer, sljedeci primJer ustrira
I

Jedllu relativno jednostavnu implementaciju ovakve klase, koju smo nazvali Asocijativn iNiz
(glomazni konstruktor kopije koji je definiran u ovoj klasi moguce je izostaviti ukoliko smo siguini da se
objekti ove klase ne¢e prenositi u funkcije po vrijednosti, vracati kao rezultati iz funkdje, ill koristiti za
inicijalizaciju drugih objekata iste klase, ali sto je sigurno, sigurno je):
canst int MaxBrPojmova = 1000;
~_as_s ~-~qcija}:j.vniNiz- ~{
irit BrojPojmova ;
char *Pojmovi[Ma xBrPojmova] ;
double VrijednostitM ax)3rPojmov a];
public: · "~ ;.-;, · ·
Asocijativn_ iNl.z,() _ ' Broj~o}_'l'mova(O) {) -k~~
-Asocijativ niNiz(); - ~<ll.. 1 . ··
Asocijativn iN·iz\c.;nst Asocijativn iNiz &A) 1- ~~-AI!"!"'~ , . ,
double &operator;,[ ] (const char Poji)lll[ll; -f2J1UXJ/i-.,J"~~,.[J
J; -i ·: .

double &Asocijat:i.v niNiz: :ap..rator. (] (const char Pojam.[]) ( ..


<Jfor(int i - 0; i < BrojPojmova ; i++) ; ··· ' · •· '· ·
l if(strcmp (Pojam., Pojmovi [i]) =,..; 0) returrt'vrijedno~ti'(i];
if (Broj Pojmova >= _MaxBrPojmov a) throw -"Popunj en niz!. \i:l~·;
- Pojmovi [BrojPojmova ] = new char [strlen (Pojam) + 1]; '
strcpy{Pojm ovi [BrojPcijmov a], Pojain); · · ·.
Vrijednosti[ BrojP()jmov a] 0; - fi0/4'., 1\<,<11'1~ =
return Vrijednosti [BrojPojmov a++]; .. •\' /l.t' . · -- · _,_-_.:_-e-.-_·.•. ·
.. . . . '--l-f~~-~'<>1 f"'1' '.IW.J' -<1."· . "'1:
. . . - ~.' _: ... _,.;...!f_~1 ' ··-- '·\ ~--' ~~""· .• ;,jf
Asoi::ijativn iNiz: :-Asocijativ niNiz!l { · · - 'Jri}t
for(int i 0; i < Br'?jfojmova ; i++) delete[] Pojmovi[i];
.--_-;..:-.:
Asocijativn iNiz: :AshcijatiY: niNiz.(const Asoci iativniNiz &l\.) {
· BrojPojmova - A.Bfo)Poj'!!§ii'<lJ. ·. if' · _.- ' .
for(int i ,..; 0; i ·< BrojP&]i.meva':i i++) { . - ·. .
Vr_ijednci_,s_ti_[.i_.·.,J_,_.:.--'·.·_-.-.-_·.·._,_"}1.: Vrij e·iljl?_·_:_-'.·,-.:_•.:. ii_t_· i [i]; Pqj._movf;_-_['il . :e.L .:_ ~-«o£,.ttk~(T ..
.I ." .. " ·:. _' ~- _ . 'IJ_ ~-. ( _.,;\:py k4_.·. . .
fc· :£,
~CD .· ,,_, . . ·-'--.~ "'/l~-k~"p~l>n-.,d,)
fo;~~:~vfu/!--!;;: ~~~~~~~~~:~~A~;~;m!viJ;il + <t~~~, ·- . ·. . . . ·.
stiqpf(Pojm ovi [i], iCPojmovi [i]); ·
' )
(1)
catch ( ... J CD
· for (~nt i = 0; i < BrojPoj·mbva ; i++) delete[] Pojmovi [i]; . ·
. -~row;

_Uz ovalco definiranu klasu dovoljno bi bilo imati deklaraciju poput


. -- . .
~--AsocijativniNiz Stanovnistv o;

pa da dobij~o asocijativni niz Stanovnistv o sa kojim se moZe manipulliati kako je inaJo~ ()pisario.

~ 01 Obj3snimo sadarad ove klase. Privatni atribut BrojPojmova vodi raCunaotome kolik~jep(Jjm~va
• '(npr. upena gnu:lova) evidenfuano. Konstruktor klase ovaj broj inicijaliiirana nulu(i ne rildi niSta viSe), .
• a on se pove6ava za 1 svaki put kada se kao "indeks" upotrijebi pojam koji 5e nije .ranije j)ojavljivao,.. ---- - -
z/~vl'tni atribut Pojmovi cuva do tada definirane pojmove. Bolie!eeeno, euvaju se pokazivacina .
:i. _
~ a· Nairne, alternativa bi bila koristiti dvodimimzionalni ni'i: znalcova za cuvanje pojmova, ali kako

[ 17

r
ll
}l
tazliCiti pojmovi mogu biti osjetno tazliCitih duZina, bolje je prostor za pojmove alocrrati dinamiCki
(nakon sto ~ sazna -~a konkretnog P.~jma), ~ ~:,~ol!l ~~-movJ_Q)l~ati po~ivae .na alocrr:un
~stgr. Atnbut Vn]ednosti cuva VTIJednost:I koje su pndruZeiie pojmovnna (npr. broJ stanovnika
}t
pridruZen nekom gradu). Primijetimo daje maksimalni broj pojmova ogranicen na vrijednost konstante
MaxBrPojmova (1000 u navedenom primjeru). U nekoj boljoj izvedbi k!ase AsocijativniNi z i sam
prostor za pojmove i odgovarajuce vrijednosti mogao bi se defininiti dinamicki. }l
ll
}l
ll
.-·
. .. ,
ll
·-~·-

ll
.do tada nepoznatim
.•'·
·Yl'nl.m ;NaZalost, · ovo je
lf
,.,,~ '·~'" u.@astiin za~adama nalazi sa

J!
If
1{
lf
lf
I[
Definiranje ~vo~ opefllti>ra o~o.gueav~ ~ ~.· objekti··· ~e~e klase (koji ~avno ~su funkcije) kori~e IJ
1{
kao da0 ~ufimkc_z;~, g. cia, se ~ UJill)ll konstt smtaksa koja .·jzgl~ kao poz_rvfu~ye. C~u:£¥9 moze 'II
aa SIUZI? Zarmslimo da nasa klasa .VektorN treba da .· pos!UZl za .smje§tarije kqeficgenata nekog ~ ••
poiillbma. Kako sU polinoini funkdje ()1 matematiCkom), prirodno bi bilo omogliC:iti da se tako.definirani- 1[
polinoini mogu koristiti kao funkcije. Na pimljer, ukoliko je v. objekat klase VektorN (koju bi sada.
bolje bilozvao Polinoni,' ali radi jednostavnosti joj neCeniv mijenjati ime), prirodno bi bilo omoguCiti
silitaksu oblika v (x) kojabi raeunala vrijednostpolinom a Ciji su koeficijenti definirani u objektn v u I[
¥,
tacki x, ~- vrijednost izraza v1x + v2'.0 + ... +
--
18
pri cemu sii {v~, v2, ... vw} elefuertti vektora v (ovaj

J[
if
polinom je bez slobodnog clana jer smo uveli konvenciju ·da se indeksi elemenata vektora obiljezavaju
od jedinice, ali to je po potrebi lako izmijeniti). Ovo eemo omoguciti upravo preoptereeivanjem
OE.eratora" () "za klasu VektorN. Slijedi definicija izmijenjene klase VektoN, u kojoj je navedena samo
implementacija ove operatorske funkcije, dok implementacije ostalih elemenata klase ostaju isti kao i u
prethodnoj definiciji:

G~-·~
VektorN _poli·(
poli (1] = ;3;
cout << .poli ·

G
L.!-·
~··
·-
1 ·'

~ ~~Hi~ii ii ii i..
·~.'. ·
(Iiii:leltS,tiranje """- "· in¥dt,~~sa~kolonairadi~duo~d
pr~i>Pteretiti Oi?er.iJ:OI " [] " da
Sa
ld~.~~~~~=~t~£:~ lm:oviima NaJiri:te, kao S!o' smo vee
I'~
lr . x[iJ [j] zapravoznaCi (x[i]) [j],
kiase zapnivo interpretira kao
(x.operat or [ l (i)) [j].

19
JJ

od jedinice a ne mll.e).
Jf
moguee ugraditi provjeru opsega drugog indeksa, niti posti¢i da se on kreee
objekat neke ase
~oguenost je izvesti da operatorska funkcija za operator " [ J " vrati kao rezultat
koja takotler ima preopterecen operato r"[]", o da ee izraz x [i] [j l biti interpre tiran kao Jf
J
[ (x. opera tor [] (i)) .opera tor [] (j

Ovo tjesenje je naZalost prilicno komplikovano (jedna mogu6nost je da redove


rnatrice ne cuvamo li ~
obiCnim nizovima, nego u nekoj klasi poput Vektor N koja se pona8a poput niza
" [ l "). Medutim, mnogo jednostavnije, e!egantnije i efi.kasriije !jes~je
i ima definiran operator
je umjesto operatora " [] "
__preopteretiti operator " () " koriste6t gp~Latorskil funkciju sa dva parametrq,
Sto je veoma lako izvesti. n
Doduse , tada ce se elementima neke matnce (recimo A) umjesto sa A (i.l [ j l
bai! nije u dnhu jezika C++ (ve6 vise liCi na BASIC iii FORTRAN), ali je ovakva
prirodnija od C++ sintakse A[il [j ]. Sva tri predloZena tjeswja bice
pristupati sa A ( i ,. j ) sto
sintaksa mozda cak i
demonstrirana u t
pnmjemz1a na kraju ovog poglavlja ' ·

t
R
..
.Ill
~
~
II
--~
••

[
-~
i
-~
Madll. je oneJrator
preopteretiti obi•en6Jtn oJiei'altOi
:1(
ovaj . .

i
.~
..; operato ra

:~
jednostavnosti, navesCeJillo
operatorske funkcije za OP<lt"atonlodjele:
class Vektor N

public :
-1
-t
Vektor N &oper ator = (Vekto rN v) ;
}i -

·[
20

f
VektorN &VektorN: :operator = (VektorN v)
if(BrojEle menata < v.BrojEle menata) {
dele.te [] Elementi;
Elementi =new double[v. BrojElem enata];

BrojE~emenata = v.Brojelem enata;


for(int i = 0; i < v.BrojEle menata; i++)
Elementi[ i] = v.Elemen ti[i];
return *this;

Uz ovakvu izvedhu o eratorske funkcije za operator, realokaci"a (tj. dealokaci"a i /".


. memori"e izvodi se samo u s uca u e vektoru man"e dimenzwn osti dod·er ·e vektor veee
enzionalnosti (npr. ukoliko je od ranije vl hio eetvorodimenzionalni a v2 oostodimenzionalni vektor, ,
aodjela poput vl = v2 mora izvr~iti reillokacij!l da hi vl hio spreman da pribvati sve komponente
vektora v2). U svakom slucaju, ovcije rnnogo efikasnije nego kad hi se realokacija vx:Sila uvijek. ·

..._;;,.-.
,,

··.. ::

. tip doubl~,
nje,go,~a cfuZina· (raziunije se !Ia je ovakva pretvorba u·Jpiti1a:s:aaij
.. .. -,.;..
_

class VektorN

public:

operator double () const; - J" -1'-; ·-r~ .b'""''"+i1/,., :h}~""l


);

Vektor: :operator double() const {


double suma 0;
for (int i = 0; i < BrojElem enata; i++)
suma += Elementi[ i] * Elementi [i];
return sqrt(suma );
)

21
J1
]
J1
I[
/cout << (double )v;
;/ cout << double (v);
;/ d = v;
]
y cout << sin(v);

. Napomenimo daje funkcij~ notacija oblika double (v), kao i do sada, moguea samo za
slu~aj tipova ]
poput long int, char * itd
~ije se ime sastoji odjedne rijeCi, talco dane dolazi u obzir za tipove

korisne, ali sa njimli ne treba. re ·eriva. ·er ovakve konverzi"e ti iCn:o vo e en u ormacra
li
· npr. zamJenom v!lktora njegovoindUZinom.gllbe se sveinfor o njegovom poloZl1ju ). Takoder,
li
macije

- previ§e de · anlh koriverzra inoze ila zbun1 koin a·IerO'Na


onvefZ!Je lZIDe u a pa etpostavinio, ria pritiljer, da su Tipl hip2 dva tip3,
ro~ito je nezgodn o imati
i da je
medusobne
definirana

~~
f
konverzije
konverz
iz tipa T.eipl.
ija ostvaren u.· u.·p········T··.·.i.p.2, bo 1 konvem.·h·:·a· iz. ·pa,Tip2
konstruk
da su za objekte tipova Tipl i Tip2
tonim iii
.
.
ti.
...i. pl (nebitno je da 1i su. ove
u.. tip.. T
funkcijama :ia konverziju tipa). Pretpostavinio dalje
opeiatori za sabirarij~. Postavlja se pitanje kako treba
ll
f interpretirati izraz oblik~ x +ygdje je . . ·tipa Tipl a y objekat tip~ Tip2 (iii obrnuto). Da Ji
0
treba objebt X pretvoriti .
pretvoriti u objekti tipa ·
. sabiranje objel,aita tipa Tip2, iJi treba objekat y
· tipa · ·· KompaJler neina n~ina da
· bismo morali eksplicitrio
ll
razrije§i ovu dilemu.
nagl(lSiti. ~ . . . . .
Kada bismo
koinpleksnih
.

J
n
~!¥.¢•W 8al?iflmja ·~;oti~pleJC>!#.h hrojc:va sa re3lnim bro}evitrul i •
da od preVise definiranili [

... ,.
'
[
[
'Cla~s ;el<tor t .. · .
. ·. ·.· . · p~~~;ex, }!'.:zr . . ·<. [
lo~ ... v~ktotot·~(bt,·yfOJ.,,·z(Oi. {l ·· .:. ·
x(x), yfy), z I z) {)
~~~ ;-. vektorf d6iibiti .'k,, dcitihl:.fl! y, double zl :
IO~-Vektoi'(cori~(:a;;fu,i<;N'iz[3J) ~'x(Niz !o]), y(Niz[ ll), z(Niz!2 ll 11 [
{~Lh(i~t~t~ ~~tt sqr~S~~;:: 1~:q: :r; . : }
1
~t4.~~ -~;'tii~o;~~
operat or +(V13ktor v) { ;return *tfUs; ). _
Vektor
, ,, Vektor operal; dr ':'(Vekt:pr v) { return Vektor (-x, -y,
r(-
-z);
" -1 ,, ;
I - II- '
1
[
p«.ct<J t-(2<4- -- frien(j Vektor' cii;iera tor + [Vektor vl, Vekt0 r :v2) {
(vl.x +.• v2.x, vl.y + v2.y, vl.z + v2.z);
return Vektor
i .... ·. · . .
l"'&"l"1"'-"~''- fr~elld Vektor operat or -(Vekt orvl, Vektor d)-v2){
.
return vl + -v2; I
[
· .·• ,1 •r," - fr1end Vektor operat or·* (Vektor v, dol)ble
f"'"i·''r-- d, v.y
return Vektor..(v.x *.., .......
I . .
* <;[, v.z * . d);
- ... ,.....,..... [
l"''";j ~!':.''"" -· friend Vektor operat or *(doub le d, Vektor v) { return v * d; 1

22 ~
fk"'uJ · -· frien d doub le oper ator * (Vek tor yl, Vekt
or v2) (
;,.-pt. _¥_.~./1 retur n vl .. x * v2.x. + vl.y * v2 .. y + vl.z
* 'v2.z ;
,J )
(!<.Ct.-1_ ·1...7L't-- frien d Vekt or oper ator % (Vek tor
vl, Vekt or v2 j (
''Y· '' retur n Vekt or (vl. y * v2.z - vl.z * v2.y ,
vl.z * v2.x - vl.x * v2.z , vl.x * v2.y
- vl.y * v2.x );
frien d int oper ator ==(V ektor vl, Vekt or
v2)
retu rn vl.x == v2.x && vl.y == v2.y && vl.z
== v2.z ;
...j -.
(f If
frien d int oper ator !=(V ektor vl, Vekt or
v2) retu rn! (vl == v2); )
Vekt or &op erato r += (Vek tor v) ( retu rn *thi
s = *thi s + v; ) ( f'<""'d· E'{CL1c'h'.(
Vekt or &op erato r -= (Vek tor v) ( retu rn *thi
s
Vekt or &op erato r *=(d ouble d) (ret urn *thi = *thi s - v; )
s= *thi s* d; ).
''h ;. ~ -~,"',
1
J
frien d ostre am &op erato r <<(o strea m &cou
t, Vekt or v) (
retur n COUt << Jl { '1 << VoX << II If << V o Y
}
1 << 11 I II << V • Z << n} U; - (1-l-pi';j. ftC:<: ,.,
frien d istre am &o., erato r >>(i strea m &cin
,· Vekt or &v) ( - j'<vu:j. -~,.> i'
retur n cin >> ~.x >> v.y >> v.z;
} ..,__
);
doub le &Ve ktor: :ope rator [] (int i) cans t (
if(1 l) retu rn x;
else if(i == 2) retu rn y;
else- if (i == 3) retur n z;
else throw ""N"eispravan indek s! \n II;

U ovoj klasi se uglav nom ne pojav ljuje nista novo o ·eer'.m···~:- n.isrnto
nema potre be da podro bnije razma tramo · ·

] a[3] = (5, 6, 8};


v = a;

]

I Sljed eea intere santn a klasa koju eemo raZJYofriti je klasa


euvanje informacija 0 vi-einenskim trenucimapfedStiivljenim u
·-c··

n~an
~ ~rij.,;.>~, kojaj~ ~limijenjeba;;.a
foriiri sati, mm~ta i sekUi idi:. .. . . '
clas s Vriie me (
· int h, m, s; ·
publ ic:
Vrije me() : h(O) , m(O) , s CO) ()
Vrij eme (int Ji, int m, ints ).;
oper ator long int () ( retu rn 3600 L · ;
* h + 60L * in + s; } '- ::f« /~/A <t
u,"'"J {~,., J ,
23
-- .:-·

J
Vrijem e &oper ator ++!l ( return *this+ = 1;
lf
Vr~jeme &ope rator- -()

-
}
( return *this -= 1;
Vr~]eme &oper ator ++(in ti) {
Vrijem e pomocn a - *this; *this += 1; return pomocn a; •
If
yrijem e &oper ator --(in ti) {
Vrijem e pomocn a = *this; *this -= 1; return pomoc~a; lf
friend Vrijem e opera tor +(Vrij eme ~, int n);
friend Vrijem e opera tor (Vrijem e v, int n) ( return v
friend long int o~rator -(Vrije me vl,
return (long int)vl (long int)v2 ; -
Vrijem
"""""
e,v2)
~o
(
~
+ -n; }
. l.
l>fi""',lv ,.
f
} . .

Vrij.em e &oper ator += (int n) · ( return *this = *this + n;


- n;
}
}
]_[
Vrijem e &oper ator - (int n.l { return *.this = *this
{_.,. _ -A!,-
1
.!_r1en d 1nt opera tor --(Vrj jeme Vrjjem e y2)
_o,.,~;//1'<4' ¢-<>tj ~- f"".,
vl;

return (long int) vl (long. int) v2;.

friend int oeera tor !=(Vri jeme vl, Vrijem e v2) (.

}
return (long int) vl ! = (l.ong int)v2 ;
(
1[
friend int opera tor <(Vrij eme vl, Vrij~e v2)
· return (long int)vl < (long int)v2 ;

friend int opE;ra tor >(Vrij eme vl, Vrijem e v2) {


-retu rn (long int)vl > (long int)v2 ;
1
irien dint opera tor <=·lvri jeme vl, Vrijem e v2F [
1[
!
return (long int) vl <= ('long int) v2;
)

· frien<;l : .int C>pE;:rator >=(Vri jemoi( vl, Vrijem e v2) '(


• >
1f
retUrn {lohg int) vl >= (lonif f!'t).v2 ;
. lf
. . I ;.=i.:r~i:. :e=n~.d~.-~o~s~t~r~e~iam~c.~·"&~-" · · l;:P~e! ;r:;·a~t;sol,lr;:_· -~<s:.:~·-·l;l!i~<JS~t£r~· e!;'_.a~m_! !.·',-_!!!&;.s:c;.s:oullut::.....-'V'-'rc:Jj.;']:/'.e"'m"'ee-"-S.J-<)• - ~ ~ r'c/4lU
-~ ~--··- VrHem. e"···vr.He
th ···_·m· _···_;_··.r],_·_!l_b_·.h. i·n.t ffi, i.nt s! { .· ·
. 23. I -I m < 0. .I f m •, > 59 . I I s < 0 I I s > 59)·
·

vP\·_._
· I:E ·. < ' ...
0 -·-·11-.h''>
.··.··''i"::'- .
~~~~ -~.*'f~~,~-?ra~<;> .vl:-ijeme-!\~ ;
11
,.., ·
= s;
-~
VrJ.J.e me::h ·=:.ll; VrJ.]em e::m
.
= m; VrJ.Je
.
me::s
. !"""
·---~- .
}

~
~--."-'· ·J.
Vrijem e ofr<lt~J;--i.(Vrijeme s, ipt n) · 1 ·
'fong. 1n ·. -p" . Jlong int) s + n;
% Gil);
retu~n'Vrij~mioi(!P 1 3600) ·% 24 1 (p % 3600) 1 Go, (p % 36001
.- .. ~
ostrea m &oper ator <<(ost ream &coutA Vriiem e s)
if(s.h < 10) coot « 0; ........ -
5

· - "----

~
COlit . -·.<< 1
s·jl--<<. --":
' '' . .···
-
.
"•,
if(s.:m , < _10) cout « 0;
cOut·--_-<<'· _ $:~-m=--<<- ·": n;
if(s·:s . <' ·lo) cout « 0;

}
cout- :<~' s·."_s';
retu-~n_ ~cout; J
Konstruktor kla5~ bez parametara kreira objekat tipa tipa Vrij eme inicijali
konstruktor sa tri pl!rametra omoguc ava inicijalizaciju na zadani broj sati, minuta
ziran na 00:00:00, !lok
i sekOndi, pri Ce:mu se
~
a za pretvor bu u tip long int
-~
provjerava isprnvn ost postavljenih vrijeduosti. Operatorska funkcij
pretvor be broj to isto
omogue ava preJivorbu ,zilpisa o vremen u u veliki cijeli broj, pri Ce:muje rezultat
"++" i ·--" omogileavaju
vrijeme izraZeno smno u sekundama. Operatorske funkcije za operatore

24 ~
r
poveeanje odnosno smanjenje zapisanog vremena za l sekundu, pri cemu se izvedbe
ovili operatora
oslanjaju na izvedbe operatora "+=" i "-=" koji su de:finirani neSto kasnije. PodrZane su kako
prefiksne,
tako i postfiksne verzije ovih operator a Jlinarni o erator "+". mo cava da objekat
tipa Vri ·
saberemo sa cfelim bro·em n r. n ri cemu kao rezultat dobfamo vri·eme koje zan se
di predn·aCi
ispred vt:_em_e'!!!.~!..~~nogu oQjektu Vrj ieme.-IiDp ementaCIJa ove operatorske CIJe prvo pretvara
vnjeme u brOfsektiri.Oi, zal:ini ga sabiia sa n,l konacno, zbir onovo razla2:e na sate, minute i sekunde, a
rezu!tirajuci objekat tvori pozivom konstruktora Slieno dejstvo ima i marm operator "
", samo Sto je
njegov rezultat vrijeme koje za n sekundi kilsni iza vremeila. zapisanog u objektu
· Vrij erne ..
Implementacija ove operatorske funkcije svodi se na sabiranje sa -n. Pored. toga,
podrZan oje i
medusobno oduzimanje dva objekta tipa Vrij eme, pri eemu se kao rezultat dobija broj sekundi
izmedu
dva navedena vremena Operatori "+=" i "-=" uvedeni su da omoguee izraze tipa·v += n
i v -= n kao
altemati vuizraZ imay = v + ni v = v- n. De:fin.icijarelacionih.operatora'~=",: !=", 11
n<", ">", "<=" i
">=" omogueava poredenje dva vremena u hronolSkom poretku. Njihova impleiiientacija
je trivijalna, i
svodi se na poredenje zapisa ovih vremena izraZenih samo brojem sekundi. Konacno,
operator "<<",
.. omogu& va ispis vreniena n fonnatu.hh:mm:ss __ . · - ·· ·

Demonstrirajmo sada upotrebu napisane klase Vrijeme na jednom jednostavnom


primjeru.
Pretpostavimo da smci .izvrliili sljedeen sekvencu naredbi:

Vrijem e sl(9, 25, 38), s2(13, 44, 6), s3;


cout << sl <.< " " << s2 << " " << s3 <<endl;
if(sl < 52) cout "Prvo vrijeme je ispred drugog !\n";
else if(sl > s2) cout "Prvo vrijem€ ; je iza drugog! \n"_;
sl++; s2--;
cout << sl << " " << s2 <<endl; --~.-
cout << sl +. 10 << " "
<< s2 - 10 << " ";
s3 = sl + 60;
cout << s3 << endl; · . ;;,
sl += 3600; ~2 -= 3600; .•
GOut <:<. s.i ··<<. " " << s2 << endl;
53 =Vrijeme (10, 7, 26);
cout << s3 << endl << (long int) s3 <'"¢- 11
• '~;
cciut.<< sl-: ..s2 <<. endl;

· Ove naredbe ee dov~Sti do sljedeeegprikaza na ekranu:


09:25:3 8 13:~4:06 00:00:0 0
Prvo irdj eme- 'je lspred dr]J,gOg!
09!25:3 9 13<44! 05. . ,,
o9:25::4 9 13:,1':3:55 09:26:3 9
10:25:3 9 l2:44!0 5
10:07:2 6 3644.6 8306

.~~~!lj~Jtsl:S:~~;~i:.~¥~~i;;~~~;i~:~· !\~~:z::~~~ri:~!v?n::
ZWikova kaO. iJa se radi & ptostini i!gradeimn tijl<iY!~ :~z potr~be za upotrebom funkcya
kao Sto su
strcpy, si:i:-(:a,t, stra,';yi tcl Zapravo ova'kfijS~ S#ri~~ §tringovni tip kakavpoStoji i!.ekim drugim
u
jn-ogranislci~jeziciiDa 19io ~to ~ BAsic, m{i4eprij{~#'iiJePiiscala,
iid. Kao i do sada, prvo eemo
prikazaii Sam.uklasu i njertiiimpiementaciju, nilkoneega§lijedi detaljuo objalinjenje impleme
.. . . . ~
ntacije:
cl,;_l3~. String ·{ _·
int Bro)Zn akova, Kapaci tet;
char· *Sadrz aj; ·
public : .
explic it String (int n = 0) : Broj Znakova .(O), Kapaci tet (n),
· Sadrza j (new char[n + 1]) { Sad~zaj [0] = 0; J - k~
1
String (const .char S[]); ' 0~ .
String ( const String &s) ; - l:>-wJf/1J;)fdL I>. "I\}

.25
Jl
J[
~- -string( ) { delete[] Sadrzaj ; )
;>tring &operat or =(St.Eing ~!
friend ostream &operat or << (ostream &cout, String. S.l
----r9tu rncaur « s. sactrzaj; ·-- - ---------- ---------- ·
{ J[
)
friend istream &operat or >>(istre arn.&cin , Stririg &S);
Char &operat or [] (int i);
int Duzina() const { return BrojZna kova; )
- J[
Friend String operato r+(Strin g 51, String 52);
(;
{{;:~~ :::;~r (~!ir~~g~~L);.
friend into erator ==(Str1n g si String S2
_? lf
);
return strcmp( adrzaJ, S2.Sadr zaj) == 0;

friend int o rator <(String 52) (


ll
< 0;
)
return strcmp(S 1.Sadrza j,

friend int operato r >(~tring SJ. String S2b {


J[
return strcmp(S 1.Sadrza j, S2.Sadr zaj) > 0;
)
I[
); J[
String: :String( const char S []) _ { _ ~~~'q
Kapacit et BrojZnak ova strlen (S); · }~""
Sadrzaj = new char [BJ:O;jZn akova + 1] ;
strcpy(S adrzaj, s) ;
J[
)

String: :String~String &sF;~,


---,_-,.-:. Kapac±t·e -t-
Sadrzaj =
--i!'rtl-j
new
zna:kova
char[Bro
- s .
jZnakoii,
Bt6j'Zil,a
a: lj;
.
,kova
+
i l
strcpy (Sadrz~j, s. Sadrzaj) ; "-' '' '-
) . . - - -

·.String &String : ;c,p.a;,ato r -cktring S),


' '-;:
..:-::·
-
. ---
!
~
BrojZna kova.- S.BrojZn akova;
if (Ki!,paci tet < Bro) Znakova) {
deiete [ l . sadrzaj.; .. - .
Kapacit et =.BrojZn akova;
sacti;zaj = njow Char [Broj zn·a:kova + 1];
)
"·- .-l '

strcpy(S adrzaj, s:sadrz aj); ·


.

··._, .. m
return *thi_s;

char &String ::o'!?era tor J.J (int il ( · ·· ·


ID
· if ( i < 0 11 i > Broj Znakova) throw ~-b!eispr <W~n indeks! \ri";
return Sadrzaj [i]; - · - · · . . "
m
· String Stri pg · ·operato r (]__ (; nt l. int j l I {
. if ( i < 0 I I i >= Broj Znakova 1- I j < 0 II j >= Broj Znakova I I i > j )
throw "Neispra van opseg~\n"; ~
String S(j - i + 1);

~
S.BrojZn akova = j - i + 1;
for(int k = i; k <= j; k++) S.Sadrz aj[k- i] = Sadrzaj [k];
s;sadrza j[S.Broj Znakova ] = 0;
return S;

~
26 lD
rU
l{
Q SJ::dng ~-rater +(String Sl, String S2) (

~
String.S3(Sl.BrojZnako va + S2.BrojZnakova);
strcpy(S3.Sadrzaj, Sl.Sadrzaj);
strcat(S3.Sadrzaj, S2.Sadrzaj);
S3.BrojZnakova ·= Sl.BrojZnakova + S2.BrojZnakova;
return S3;
G.. )

String &Strinq::operator + (StringS) (

G - if(Kapacitet >= BrojZnakova + S.BrojZnakova)


BrojZnakova += S.BrojZnakova;
strcat(Sadrzaj, S.Sadrzaj);

Q )
else *this = *this + S;
return *this;
} -...... _

Q istream &o~ r >>(istream &cin, String &S). (


char Prlvremeni[lO ;
cin >> Pr-ivremeni;'
Q S = Privremeni;
return cin;

g Analizirajmo sada ovu klasu. Ona sildrZi p0kazivac Sadrzai na prostor za cuvanje znakova stringa dll'.,
(koji. 6e.~e-~ocirati din~cki), illtim ~-infon;nacije o broju znako_va u ~~-(a~but BrojZnakov~) ~

g kao 1 koliCini stvamo alocrrane memon e atnbut Ka c · tet ko maze h ti eca od stvamo broJa " ~ ~
. i:nakova u strin_gu (111!, ()yaj ~~iS~ s? smanjuje potre~a za pre~om alokacijom). Glavni koi)S .. or
kon~~r-~erra pnl?.8ll string,_ pn CeriJ.u opcto_nalni parametar-konstruktor~_omoguCava cia: se za~a .·._-.:..
kplicina memorije koja ce inicijalno biti zauzeta za Cu.vanje elemenata stringa (km1strUktor je deklaman

Q kaO eksplicitan da sprijecimo mogucnost da se ~gu dodijeli cijeli broj). Uveden je io~ il:dan
Icons . or ko 'i kao 'iii ·.·· .··•·· ·:'-''. a obiCni konstlul'tni niz znakov koji nakon oba"ljene al(Jkilcije
n,iemorije kopira . taj niz Ziiilk?ya u alocirani prostor. Ovaj onStruktorje uved~ da ombguci
0
....
inicij3lizaciju Stringova obieuiiii :ifringovnim iconStiiD.~ (tj. nizovima ZllakOVa omedeWm znakbma
riavo<Ja), tliko da su oioguce iniGijiilizacije i dodjele tipa ' · · ·

g · -··f~tting s :•;as8'f~tring!:'; .. .
= .·.·.· • . · · ..· .... ·.··.::···.~.
. Pored toga, ovaj ko~or oJ:Il!igucava da se prakticno u svim situacijanui. kl\da. se kao paraD).etar iii
•. • - , ' , ···.--.·,._ .- . . . • ·o -((; ;,._.- . . . . , -. • "· . . . • . . - ·. . - . .-.. : . } • • .
operll!ld .o~kuje .o~t kl~ 'String,,c JJID.jesto . njega moZI: upotrijeJ:ri~, pbien,i Diz :pako~ iJi
0
... . Srring<iYfia,konstanta: Jld kp~ra vrijtdijos sp<imenuti i konstnJk!oi ko,ije, koji .o~Jaylja yeS: 9obro
pi>~at;i #raJ<, a clja)e unpl~taclja veoma sli6Jlapretho~ kons1lilti;t9&, ~Je ko~r
tu
k,pjiije, je ~bieno i ~egova ~~a, opefi!torSka :fimkcija Clanica za op~Oj: dQdjefe,;(Ill!T,~VI:l<iJ~je i
0
...
0
~
'
0
· ~~s~or, f~ji se
· (}pei!lf9i'

. . ':''.
~dJele

Q'Odjele,
._ .
se Wile
o/fefzli
@.
o'~~je ~tete IJieip,orij_: prije ne~o ~Q {lpje~(j>~~~;Po~~BJj.).
n,¢ ~s1 bewotrebnu r~okacjJu D1eiJ10nJe uk9liltO:odre4i~ strillg y~c 11Ila
J,pyoJJa,~p~itet ~J>fiilvii#.J;halco~e striJigakoji se dodjelju]e odi~snqin ~:;,;~y~JltJiici
.~orii saSi6m su l p e <ivakve
·'- - . ·'. -: ..- .;-. .-, .....,.
;-,

fimkcij.ofn strcpy i rijoj srodnfui funkcijama;


. --
konstiukcije,
.
koje omoguCavliju da se- ne. l:iJ.oram9- piititi
. '" --~
sa -' '•

0
~
.~tring
....

s = ."A
s = ."Ja s·am string!-";

sada sam neki drugi' string .... ";

~
~
Klasa string definira i nekoliko veoma korisnih operatora. Operator za ispis • <<" (Cija je. definicija
trivija.ID.a) omogueava jediJ.ostavno ispisivanje objekata klase string· na ekran, a operator ">>"
omogueava unos objekata klase string sa tastature. Unos se prvo vrli u neki prlvremeni niz i:n;lkova,
J

koji se po obavljenom uiJ.osu dodjeljuje samom objektu (za ovu dodjelu zasluZni su ·konstruktor i
operator dodjele). Operator,; [ 1" omogueava da pojedinim znako-rima unutar klase String pristupamo
na identican nacin kao da se radi o obiCnim nizovima znakova, samo uz provjeru ispravnosti indeksa.
]
• 27
1
ll

clanice Duzina . Veoma


Jf
Treimtnu duZinu (broj znakova) stringa moZeiilo saznati pomocu funkcije
na kraj prvog stringa
koristan operator je i binami operator "+" koji nadovezuje drugi string
hnplementacija ovog operatora ne bi trebala da predstavlja neki problem za
nje omogueava
analizu (za ostvarivanje
konstrukcije poput: •
Jf
nadovezivanja iskoriStenaje funkcija strcat ), a njegovo postoja

String sl = "Prin cipi ", s2 = "progr amiran ja", s3;


;
I[
s3 = sl + s2 + " nudi veoma intere santne moguC:nOsti"
cout << s3;

Primijetirno da je mijesanje objekata tipa String sa obiCnim stringovnim konstan


tama moguee ll
u
objekte tipa String. Jasno je
zahvaljujuci konstruktorom koji vrsi pretvorbu obiCnih znakovnih nizova u
n je i operator "+="
da je ovakav rad mnogo efikasniji nego upotreba naredbi strcpy i s treat. Definira
·
da podrZi konstrukcije poput

Strin gs= ~Preoptere6ivanj6 ";


s += "oper_ atora" ; [
cout << s;

Radi. efikasnosti, umjesto trivijalne implementacije tipa return *this


= *this + s, koja bi
zahtijevala konstrnisanje zbira striugova a zatirn kopiranje konstrnisanog zbira
u odrediSte, prikazaD.a
[
i da. odrediSni string
implementacija vrSi samo nadovezivanje pozivom funkcije strcat ukoliko ustailov
vee irna dovoljan kapacitet da prihvati nadoveiani dio. U suprotnom, postupamo
na operatore "=" i "+" koji ce obaviti neophodne realoka cije memori je. ·
klasicno, pozivajuci se
· · [
Veoma iuteresantan operator je operator " ( l "· koji ~ip.ogucava. da iz stringa Ill1 [
jednostavan naciu
krlijnjeg Zilaka koje treba
izdvojimo neki njegov dio. U zagradama je potrebno nave~t:l iudeks pcieei:nog i
izdvojiti iz striuga, a kao reiU!tat s.e dobya iip~ay!) dii) stringa u navooen oin opsegu iudeksa
hnpl~~ntacija o~O.g op'eratora kreira. poinoCni ~Jt¥,&ii .se ,vr:aca ~ao re.~~' [
a u koji se kopiraju
ucuJe konsb1JkctJe poput: . · · ·
znakoVItz navede11og opsega UvodenJe 9vog opet~tOfil8ln()g
·>1"' . .
. .·.·. •. '·'. . . . . . .
.
String~--= _."Ovdje fali .... "; _·_-/ __ ,..,~~ ·
cout << ·s (0,
.
4)
. . '·
+ "
. .
nesto" t .sJ5~
-; -;- ._ ·L;n·;
... . [
. KOnaCno, ~e~je r~IaciOnih oPerafu~c{ "~-~"~>:•i I~_", <.'.',. "?'",_ "<="·. ,~ ~~;~·-
11 z~_ kt.~ string . ..
) kori~;iliJeiu.obi~
oniogu6ava da oJ>jekt~ klase String moZeiilo upoi:edivilti{po abecednom krite#ju
telacionih opei-aiOra !Jez potrebe za korlstenjeiu flliil<<;lje
konstmkcije: · · · · · · ·
strcpy . Oviin
·
posiiiju
·· ·
mo_gll& i ovlikve
-[
D
,·;·

string iozink a;'


cout· .:;< ··unes i lozink u: ";
CiD. · >> ·lozirtk a; ·
if (lo~i~ka !~ "Hrklj us") e;out

inip~;;ntiniju ove opetat&e iutefno· su· ieaTirira


u
Naraw o, ~{ fimkcije koje
he \iPravo pomocu
· · · · ·. · · · · ·· · · · ·.· ..·· •· · ·
funkcije shi:II!!L
D
Razvijena klasa ~tring
je oci~~ovoorna korisna Zbog togaje dob~omali da standardna
bibliot eb .string . je~a C++ .sadtz(v e6. naiiisiJhu kli!Sil koja se fiikodei- zove
§ tt:ing (sa nia1im
poeetnfm slovom), koja ima gotovo iStu ~cioniiJnost kJasa bo
Stringk qJI{·SJ ho :UiJtavo napisal i D
Drugim rijecima, dovoljno je uprogr .ini stiiViti direktiw'
#incli.t cte <strini i}·n1k ofl ~a moZeiilo
koristiti tip string bei potrebe da se maltretiraino sa dosta rieigo4.flim :funl<Cij
za
mrta mampuiaciju
nizovima znakova (strcp y, strCinp ltd.). !reba ipak napome niil:i. izvjeSut:i.SijD.e railike izmedu
slstr ing zvala
D
standardne klase string i klase string koju smo taZVili Metoda koja se ii ~jlda
ga, kllisa string
Duzina, uklasi string zove seleng .th ill size (podrZaD.e su obe vilrijante). Po/i:dto
nema definiran operator"< l ", nego 5e wii.jesto njega koristi metoda silbstr sa dv;i ,jiigum.e nta. U ostalim
smo razvi.li. Pri
D
stvarima, upotreba klase string je praktieno ideritienakao upotreba klase string koju

28 ~
ll
tome klasa string ima i neke dodatne metode, koje na8a klasa String nema, i njena implementacija je
efikasnija od na.Se implementacije, jer koristi brojanje referenciranja da smanji broj nepotrebnih
kopiranja. Na krajujos recimo da pored operatora ">>" koji omogucava samo Citanje rijee po rijee, klasa
string definira i funkciju (ne metodu) getline za citanje Citave recenice sa tastature, sintaksom tipa
getline (cin, recenica) (za razliku od cin.getline (recenii::a) koju koristimo kada citamo
stringove zadane kao obiene nizove znakova). Ova izmjena sintakse je uradena iz prostog razloga sto
nije bilo moguce preopteretiti metodu getline za klasu istream da pri)J.vati kao parametar objekte
tipa string, s obzirom da nernamo direktan pristup deklaraciji i implernentaciji klase istream.

Pos!"ednja klasa koju · demonstrirati u ovom avru · a .


'--., koju smo vee ~j 1 u prethodnim poglavljima, ali koja je ovaj put prosirena podi"Skorn za operatore:

class Matrica (
int BrojRedova, BrojKolona;
double **Elementi;
char ImeMatrice[lO];
void AlokacijaMemor.ije (int BrRed, int BrKol);
void DealokacijaMemorije(int BrRed);
p\lblic: ·
Matr.ica(int M, int N, const char Ime_[] = nn);
Matrica(const Matrica &M);
-Matrica () ( DealokacijaMemorije (BrojRedova); )
Matrica &operator =(Matrica M);
friend istream &operator >>(istream &cin, Matrica &M);
friend ostream &operator << (ostream &cout, . Matrica M);
friend Matrica operator + (Matrica Ml, Ma\i.iica M2); ·: · ·.
doUble *oparator [](inti) f'return Elementi[i]; )
· double &operator () (int i; int j);
}; - . ' •, ·. . . _: ,~:'_..:_~--~t~~~/15~ ~~
void Matrica: :AlokacijaMemorije('rnl;"·BrRed, int -ilrKol) I
int J.; . .- ·,_ ~.;- ··-.
Elementi = new double*
. . _.
[BrRed]
'
r'"'. •, ·.· 'f·'·· .-..••
for(i = 0; i < BrRed; i++)
. . -. .
Elementil,i-1;,
-. -... _. ..
= 0;'

try ( .
for (i = o; · i < BrRect; i++v. .·.
Elementi [ .H ,;., niow dou:bi;),"p3rKol J ;
) .
catch( .•• ) ! ... . .
pealokai::ijaMeinori}e (BrR,ecil;
-~-~OW; - . .
I
I
. void Matrica: :DealokacijaMemorije (int. BrRed) {
fortint i ,; o; i < ErRed; i ++) delete [ J Eleinenti [ i J ;
a.;i.;t.;
.
[] El ~i)ienti
' .•.. · .
; . . . .
I
Matrica: :Matrica(irit BrRed, int BrKol, const char Ime [ l) (
Bro]Redova ;._ ErRed/ Bro)Kolona ;, BrKol;
if (strlen(I~e) ;;: '9) : thro:W• "Predugacko ime ! \n";
strcpy(:i:ine"Matrice, fmi"Y; .
AlokacijaMemoi:ije (:EirRed; BrKoll;
I
Matrica: :Matrica (con8t Matrica &M) .(
· BrojRedo;,a· =c M.BrojRedova; BrojKolona M"':".BrojKolona;
sj:rcpy (ImeMatrice, M.IJl1eMatrice);
AlokacijaMemorije(BrojRedova, BrojKolona);

29
--- ----.

JJ
. ]
for(int i = 0; i < BrojRedova; i++)
for(int j = 0; j < BrojKolona; j++)

)
Elementi [i] (j] = M.Elementi [i] [j]; ]
Matrica &Matrica::operator =(Matrica M) {
if(BrojRedova·< M.BrojRedova I 1 BrojKolona < M.BrojKolona)
DealokacijaMemorije(B rojRedova);
]
AlokacijaMemorije(M.B rojRedova, M.BrojKolona);

strcpy(ImeMatrice, M.ImeMatrice);
BrojRedova·= M.BrojRedova; BrojKolona = M.BrojKolona;
JJ
for(int i = 0; i < BrojRedova; i++)
for(int j = 0; j < BrojKolona; j++)
Elementi[i] (j] = M.Elementi[i] [j];
I[
return *this;

istream &operator >>(istream &cin, Matrica M)


for(int i = 0; i < M.BrojRedova;·i++)
JJ
for(int j = 0; . j < M.BrojKolona; j++) {
cout << M. ImeMatrice. << " [" << ·i + 1 <<
cin >> M.Elementi[i] [j];
II
, IJ
<< j + i ~< "] = "; Jf
return cin;
Jf
ostream &operator <<(ostream &cout, Matrica &M) {
e>~><o-r<f~ dct
~""" g'l"'
~"""'*· 'f'l\1;\\() i
int Sirinaispisa = coui:-.width(); ...
for(int i= o;· i < M.BrojRedova; i+;,t .. {
for (int j = o; j < M.BrojKolcma$'iJ.+-i-)
----·::;.
""<>~~fZ!'¥'o-d<M<.
,.,~\,., dt/ohA.~lNWI,.
Jf
cout << setw (Sirinaispis?,:)?i~~ ~.(Elementi [i] [j J: :Q-t'vu'nu.._ ~\.oe,

I ==:: ::.::'" . ' ,)ft,~~·; ' . J


Matrica operator + (Matrica ~;;· M:li:Joi6C! :M2)
if (Ml. BrojRedov<l, :! ~ M2 . Brcij Redo ira I ),:''M:2 • Broj Redo ira ! = M2.Bro) Redova)
1
· throw "Matrice .nemaju jednake d;im~iliije.J\n"; ·
Matrica M3 (Ml:Bi:~jRedova, Ml.Broj,K;Jiona); ·
for(int i = 0; i '<
Ml.BrojRedova;' i++)·
J1J
for (int .j = o; ·.) < Ml.BrojKolona; j++}
M3.ElementiUl [jl = MLE:lemenb [il(j.f + M2.J;;lementi[iJl~]l
return M3J- · · · · ·· · J1J
)

double &Matrica:: opE,ratoz-. () (int i, int j) . {


if(i<l t 1· i>Broj.Redova II ·j<l [ 1 j>BrojKolona)
throw_ w.IndekSi izvan opseg'a! \ri"; .
lJ
return Elementi[i ~ 1] [j - 1];
)
JD
Prije nego Sto detatjnije objasnimo poj~e detaije ove)di)Se, ilustrirajmo kollkoje sada eiegimtan
rad sa objektinia klase Mat;,ica, nil sljedecem testnom prlnijeru:

int M;r N;
·
10
cout << "Unesi broj redova i kalona za niatrice:-\n";
cin >> M >> N;
try {
J[J
MatricaA(M, N, "A"), B(M, N,
cout << "Unes.i matricu A: \n";
cin >> A; lD
30 1l

cou;t << "Unesi matricu B:\n";


cin >> B;
cout << "Zbir ave dvije matrice je:\n" << setw(7) <<A+ B << endl;
cout << "Element_matrice Ana poziciji (1, 1) je 11
;

cout << A(l, 1) << " odnosno " << A[01 f.01 << endl;
I
catch( ... ) {
cout << "Nema dovoljno memorije! \n";
I

U deklaraciji i implementaciji ove klase ima mnogo detalja koji su praktieno identicni u na8im
. ranijim definicijama klase Matrica, pa 6emo na ovom mjestu ukazati samo na izmjene koje smo ovdje
napravili. Konstruktor i konstruktor kopije ostali su isti kao u prethodnoj verziji klase Ma tr ica.
Destruktor je pretrpio sitnu izmjenu, i sada se svodi samo na poziv privatne metode
Dealokacij aMemorij e kojoj je sada. posveeen zadatak oslobadanja memorije koja je bila rezervirana
za smjestanje elemenata matrice. Ovo smo uradili zbog ~tede pisanJ];)jer se ovaj put postupak
dealokacije poziva sa tri razlicita mjesta (iz qestrukt<;>ra, .iz metode Alokacij aMemorije u slucaju
greSke, kao i iz operatoi:ske funkcije za operator dodjele). Dodata je operatorska funkcija za operator
dodjele koja obavlja duboko kopiranje, vodeci pri tome racuna da ne obavlja realokaciju memorije u
slucaju kada to nije potrebno (npr. pri dodjeli neke matrice drugoj matrici koja je prethodno bila istog ill
veeeg formata).

Operatorske funkcije za operatore "+" i "»" zamijenile su raniju funkciju ZbirMatrica i mei:odu
(funkciju clanicu) Unos, pri cemuje njihova implementacija ostala prakticno ista (osim !lto operatorska
funkcija za operator· ">>" nije funkcija clanica). Takoder operatorska funkcija za operator "<<"
zaniijenila je ranijumetodu Ispis. Medutim, metoda ispis imalaje i parametar kojim smozadavali
Ze!jenu sirinu ispisa Ovdje smo omogucili d!!''~}irina ispisa zadaje na prirodan uaCin pomocu
manipulatora setw. Na primjer, ukoliko je A matlj~R)<?~o zadati konstrukciju poput ·
set~(IO) i;·~1;J+~?.,; .
da
cout «
.
«A; .:
.
omo~Cimoi~is ~ce A I>ri eemu c~. za ~~o'p~~fiti zauu:to p~
···~
'? mj:sta ~teresantn?je
~otriti nak,oJI ~acm ()P:r~to~ska funkciJ~ Zll;,f.flr~t9r;f}J: sazn,l!Je koja Je ~.ll b~~ I><J!lfavlJ~na
J:J;ll!Mpulatoroll1 setw, 0\:.\?.Je,Q~ll!"eno .POZIV()I)l llletode. W1dth bez. parl!llletara nad objekt()m cout
· iCojaVrliciil<liO~llifulitOOi)oSilivfj~·~1Sjffsa. · · · • ·. • .· •· · · .; < < ·· .••.. · .· .·•· · : • .• · .· ·. · . ·

.Konaeno, klasa Ma trica definfra I operatllre ·" () " i • [ 1". Operatorska fqnl{cija ~. <;>peiat9r " {)"
om.ogucava prisfup elementinia matrice navodenjem indeksa reda i ~olon¢tazqv9- ~a\mu~
Zagrada (npr. A< 2, 3 l ). fo-i eemu in!iekSi reoova i k9lorui idu odjedlnice,·a pod!Zanii' _iii { pfov;da
igpravnosti ind!)ksa Pore.d t()ga, PodiZana je i uP<>treba operatota "U" i slil.flt,kse poput!};[2J b1, 'jill
oyaj put indel,Si se kreeu od nule, i provjera ispravnosti indekSa ,mje podrZ<!nl\, Naini¢, ~pi#q@:u
fimli:ciju za oyaj operl)!?£ implementirali smo tako Sto oJierl!t9r.;; [f".z~ p~j~rlJen ni!{!h~ffi§ii'cnfi.
A [2 1) vrati Pf!~ivg:c n.f.l ~ov;ujticired niatrice, dok se. dJt!g~ prfr,1?~.op~~~ " U",JliJ1JiijeA~uJe R~ .
viaeeni pokaZivac na u9qicajeni naCin. Na taj nacin, na tretn:ilm piVog !itq~ksa bi~() i Plii~.@cati (tij.)r.
da lllu provjeravamo OJ}S!:g ida ga pomjerimo da kreee oajedinice), l!ll ~.lre@.~D~.'IM~~;ne.
moZeillo. Radi .
konzistencije,

odlucili smo se dane vrsimo nlkakve m3nipuladje
.. .
ni nild pi'viql
-
!ndeldoili.
·_•. :-·"-"<· . ·.·• ..
~-
. . :. - ' .
Ukoliko
.
je zbog nekog
._
razloga zaista neophodtio
-
da e!einentinia
' . m'atrice
. . ..Ze!imo
·__
<!ll pnstllp$o
_,,.\-,-:·.
'' '-, '··
koristeei standardnu sintaksu za rad sa dvodimoozionalnim nizovima A [ i 1 [ j 1, a Ze!imo ··.:1a imarilo ·
moguenost da uticenio na tretman oba indeksa, jedino lje!lenje je
da operator "r 1• prinrljenjoo lla
matricu vrati kao reZllltat ponovo nc:ku klasu koja ima preoptereeen•Operator " [ 1", i da u pdgovaiajuCoj
ciperatorskoj funkciji za tn klasu izvr!limo obradu i tretman drugog indeksa Ovu tehniku demi:>rtsitffali
smo u narednom primjeru, u kojem smo definfrali klasu nazvanu PristupnikReduM;;J.t;r:L~e u ~ojp
smo "upakovali" pokazivac na red matrice. Tako, operator "r 1" primijenjen na mai:ricu vraca kilo
reZllltat objekat ove klase u koju je upakovan pokazivac na odgovarajuci red matrice, a zatim druga

31
I
· -1r
]I
primjena operatora " [ J " djeluje na vraeeni · objekat · ove klase. Pri tome odgovarajuca operatorska
funkcija dohvaea tra2:eni element matrice preko ovog pokazivaea, i vraea referencu na njega, kao sto je i
uobieajeno. U ovom primjeru smo iskoristili mogucnost da utieemo na oba indeksa, tako da smo J[
realizirali da se kontrolira opseg oba indeksa, i da se oba indeksa krecu od jedinice. Prikazaeerno
kompletnu definiciju klase PristupnikR eduMatrice, kao i neophodne izmjene u. samoj klasi
Matrica: rr
·class PristupnikR eduMatrice
double *PokNaRed;
int BrojKolona;
PristupnikR edMatrice(d ouble *PokNaRed, int BrojKolona)
If
: PokNaRed(Po kNaRed), BrojKolona( BrojKolona) {I
public:
-double &operator [] (int j);
J.1
friend cl~ss Matrica;
I;
double &Pristupnik ReduMatric e!:operator [] (int "j) {
]f
if(j < 1 II j :> BrojKolona) ·throw "Indeksi izvan opsega! \n";

)
return PokNaRed [j '- ll ;·
Jf
class Matrica {

public:
·.- ~ ~l·. :. •
J[
PristupnikR eduMatrice operator[] (~nt i) ;_

);
J[
PristupnikR eduMatrice Ma.tric:a.~

I
if(i < 11.1- i > Br-ojll.eclov·a
li
[
J1j
J1]

.-; ;:,-_.
J1J
10
][1
][]
JD
32 J[1
NASLJEDIVANJE I POLIMORFIZAM

Kada smogovorili o filozofi"i ob"ektno ori"entirano ro amiran·a, relcli smo da su n"ena cetiri
osnovna nace a sakr(va[!i"' in.ljrmat;_ija,,!J.nlmpsul';!ciia, nas (e iY.anje 1 e_o]imorfizam .• Sa sakrivanjem
infopnacija i enkapsuiacijom smo se vee detaljno upoznall. Sada je vrijeme da se upoinamo i sa
preostala dva naceia, nasijedivanjem i po!imorfizmom. Tek kada programer oviada i ovim naceiima i
pocne ih upotrebijavati u svojim programima, maze reci da je USVOJIO koncepte objektno orijentiranog
prograiDJra~

~asljetlivanje je metodoiogija lcoja omogucava da mo2emo defmirati neku klasu lcoja nasljetluje
• vecinu svojstava nekeVec postojece klase. Na primjer, ukoiilco definiramo da je klasa B nasljedena JZ-
lciase A, tada klasa B automatski nasijeduje sve atribute i metode lcoje je posjedovaia i klasa A, pri cemu
j~ moguce u lciasi B dodati nove atribute i metode lcoje klasa A nije posjedovala, kao i promijeniti
defmiciju nelce od nasljedenih metoda Klas~tada se naziva~na. <jiS/l()Vna iii rq.(iiteljska klasa za
k!ast@a za lciast@azemo da je izvedena iii nasljedena iz klas A.

~oma je vafuo da se ispravno shvati kada treba lcoristiti nasljedivanje. Cijeli mehanizam
nasljedivanja zamisiJenJe taka da se neka klasa (recimo B) treba nasijediti JZ nelce druge klase (recimci A)

primjer, Student
Ul]~H)JnlraniStudent iii doktorslcog studija). Cinjenica je dace klasa
Diplorniran istudent sigurno sadr2avati nelce atribute i metode lcoje klasa student ne sadrzi (npr.
godinu dipiomiranja, temu odbrane dipiomslcog rada, itd} Medutim,
neospoma je cinjenica da svaki . i student, taka da sve sto ima smisla da
se radi sa studentom ima smisla da se · studentom. Stoga je sasvim ·osnovano
iz klase Genera!no, prije nego
sebi postaviti pitanje

•• ~~~~~:~~~a~ da Ii se primierci
A
,..;,;::;;~
treba lcoristiti alco i

~~-~~
nazvane Vektor2 i
veki:or. Ocigledno ce k!asa ifektor3 . . kao i klasa Vektor2 (i jednu
lcoordinatu vise), talco da na prvi pogied djeiuje priroC!no koristiti nasljedivanje i de~irati klasu
Vekto~3 lcao izyedenu kla§u iZ klase v;;kte>r2.Medutim, cmjenica je da svaki trodimenzimlafui vektor
nije ujedno i dvod'tmenzionaim vdctor,'tilko.Oa uovcn:rlprimjib nije uputno lcoristiti javnonil!ljedivanje. ~
Naravno, sam jezilc nam ne bratii da to uradimo (kompajler i'Ie ulazi u filoZOfsfediskllsije tipa da li je •• D

nesto sto ste vi uradililogicno iii nije, nego Sarno da lije slntaksno dop!JSteno iii nije).J1.1edu1:fm, Ukolilco
fiJ bismo uradili ~o ~sto,lcm~gli bi s~ uv:liti ~nevolje.lc~aime, vidjece~o-~j~zii<.C++ ?ob_pustaklda se
f prim erci i_zve ene .. ase onste u sVJm 4 onte ti~a u OJe:Ql se mo~Q_(_l~-~~ 1_pnmflerc! ~e . ase.
• 0 iiiaci da i se pnriljerci klase Vektor3 mogft'fCoristiti svugdje g cre i primjerU ase VeffdH. s
druge strane, to ne mora biti opravdano jer trodimenzionalni vektori nisu dvodimenzionalni vektori, i
sasvim je moguce zamisliti operacije lcoje su definirane za dvodimenzionalne vektore a nisu za
trodimenzionalne vektore. Tvorci jezika C++ zamislili su da se u ovakvim siucajevima uriljesto javnog
lcoristi privatno nasijedivanje. Medutim, privatno nasljedivarije nasi i svoje lcomplilcacije, talco da je u
ovom slucaju bolje definirati klase Vektor2 i Vektor3 posve neovisno jednu od druge (tj. bez
Jl
111 koristenja ikalcvog nasljedivanja)._ Djeluje apsurdno, ali ukoliko bas ielimo da korjstimo javno
't nasljedivan ·e, tada ·e bol"e klasu v or2 nasli"editi iz klase tor3! Zaista, dvodimenzionalni
' ve on jesu specijalni slucaj trodimenzionalnih vektora, i mogu se koristiti u svim kontekstima gdje i
Jl
trodimenzionalni vektori. Vjetovatno djeluje cudno da je ovdje nasljedivanje opravdano, s obzirom da
dvodimenzionalni vektori imaju jednu koordinatu manje. Medutim, istu stvar mozemo posmatrati i tako ][
da srnatramo da dvodirnenzionalni vektori takoder sadrZe tri koordinate, ali da im je treca koordinata
uvijek jednako nuli!

Tipicna gresk~ .u _razmisljanju nastaje kada programer pokusava ~-relaciju "sadrZi" izvede preko /
][
nasljedivanja, · odnosno da nasljedivanje izvede samo zbog toga sto neka klasa posjednje sve stQ_ •
posjeduje i neka vee osto'eca k:lasa. Na primjer, ukoliko utvrdimo da neka k:lasa B konceptualno treba
a sadrii k:lasu A, velika greska u pristupu je takav odnos izraziti tako sto ce k:lasa B naslijediti k:lasu A.
][
Cak vrijedi obratno: t~ je gotovo siguran znak da klasa B ne tr.eba da bude naslijedeila iz k:lase A.
Umjesto toga, k:lasa B treba da sadrZi atributkoji je tipa A. Na primjer, k:lasa Datum sigurno ce· imati
atribtite koji cuvaju pripadni dan, mjesec i godinu. Kl.asa student mogla bi imati te iste atribute (koji bi
][
mogli cuvati dan, mjesec i godinu rodenja studenta), i iste metode ko]e omogucavaju pristup · tim
atributirna, ali to definitivno ne znaci da k:lasu Studenttreba naslij~diti iz k:lase Datum (student" nije
datum). Pravo tjesenje je U k:lasi Student um'esto osebnih atrib\l:~.za dan m'esec i odinu todenja_
][
koristiti 'edan atriJ?EttiJ?a Datum koji opisuje datum rodenja. a ta~ na~in postizemo da klasa StUdent
sadrii. asu-iiab:iin. Ovakav tip odn<isa izinedu dvije klase, u kojemjedriii kli).s~ sadcii dn:igu, a ko}i snio l(
vee ramje koristili, naziva se (iiYegacijEJi stiStinski se razlikuje od naN~~~YanJa davnog). Tre~a
napomenuti da privatno i zasticeno nasljedivanje rie omogueavaju sustinski iiista sto sene bi riloglo · ..
ostvariti agregacijom, osim sto se koristi drugacija sintaksa (analogiJa siptaks't koja se koristi kod javnog
nasljedivanja,_a ne kod agiegacije). Zbog toga o ovim · nasljedivanja necem() govoriti. JI
Nakon sto smo objasnili kad 1~~~~-~~~~~:~:rn~-~ozemo reci kako se ono ./#
u kojoj cemo: radi ••• li
ostvaruje, i sta se niim' postiie. Pr•~tpos,l'aVJim•;>"~ .
Jedr10stavncisti, definirati samo atribute · . i broj indekSa,
konstrUktor sa dva._pararp.erra (ime i broj

class Student {
-.
JI
char Ime[SO]>
int rnd.eks;
public , · · : 0: ._ ·
student (const char ~""o·"·
I
. strcpJ ist.u.CI~t: .' rtiu3.'
} . .
char *vrati_i'!"' () con~t {
. , '· . JJJ
. int vit<li:i_ing~13 o coliiit. {
void r~isifi ~pnst {
cout << ·"StUdent 11
<< · tme· << " JIJ
}
};

Ukoliko ze!hno-da definilamo k:lasu DiplomirarliStu dent koja je nasljedena iz k:lase Student a
JD
~-· ••, -.
posjeduje novi afribut koji predstavlja ·godinu diploiniranja i odgovarajucu metodu za pristup tom
atributu, to mozemo ililiditipa sljedeci nacin:
;..-----~
JD
class I!_iE_lomi~aniStudent : public.Student {
~n
public:
o 1naDiplomiranja ;
· ]]
DiplomiraniStud ent {const char Ime.[J, int Ind, int GodDipl)
.0 Student {Ime, Ind) ,....E_odinaDiplomir~a {GodDipl) {}
int vrah_godinu_d1plol]!,j.~ { return GodinaDiplomir anja; }
};

11
11
. --,--·--·· ---- -,-.--·--

Vidimo da se nasljedivanje ostvaruje tako sto iza naziva klase sta · o dvotacku iza ko·e sli"edi
kljuenuj jecgubli c i ime bazne kl~se. U izvedenoj klasi !reba deklarirati samo atribute iii meto koje
dodajemo (ill metode · koje mijenjamo, sto cemo uskoro demonstrirati)~ Svi ostali atributi i metode
·
'nasljeduJU se iz bazne klase. Medutim, ovdje postoji jedan vaZar! izuzetak; konstruktori se nikada ne
naslieauiu. Ukoliko je bazna klasa posjedovala konstruktore, izlredena klasa ih mora ponovo defimrati.
/I
•'
·Razlog za ovo je. cinjenica da su konstruktori namijenjeni da inicijaliziraju elemente objekta, a objekti
nasljedene klase gotovo uvijek imaju dodatne atribute koje konstruktori bazne klase ne mogu da
inicijaliziraju (s obzirom dane postoje u baznoj klasi). Ukoliko zaboravimo da definiramo konstruktor u
izvedenoj klasi, u slucaju da bazna klasa posjedu~ koristruktor bez parametara, on ce biti iskoristen da
6/1
lnictjaliZJra on~atribute kojt posti:Jje u baznoj klasi, dok ce novododani atributi ostati neinicijali3'i!J!!!i U
,If./.;-'
svim ostiillm slucajevima . kompajler ce prijaviti sresku. u navedenom primjeru, u klasi
•• -.
Diplomi ran.istud ent -definiran je konstruktor sa tri parametra, koji pored imena i broja indeksa·
zahtijeva da zadamo i godinu diplomiranja studenta.

. Konstruktor izvedene klase gotovo uvijek treba da odradi sve sto je radio i konstruktor bazne klase, a
· nakott. toga da odradi akcije specificne za izvedenu klasu. Da bismo izbjegli potrebu za prepisivanjem
Jfl
koda, k truktor izvedene k!ase otovo o ravilu treba da ozove konstruktor bazne klase. To se moze
izvesti.jedino u konstruktorskoj inicijalizacijskoj listi, ta o o se nave e rme azne ase i u zagradama
r
'
parametri koje treba proslijediti konstruktoru bazne klase. Tako, u navedeno m primjeiU; konstrukt or1
klase Diplomi rariistud entpaziv a konstruktor klase student da inicijalizira atribute Ime i Indeks,
a pored ,toga (takoqer u')i;pns,truktorskoj inicijalizacijskoj listi) inicijalizira i svoj specificni atribut
GodinaD iplomira tij'a. ;,_ ·. . .

_Yafuo je ·naglaSiti da atributi i metoodd~e~~~~S,~~~~~fc!;f~~~~~tc~·a~k~n~i~m;;~e~to~d~aj,m~a


klase koja je· iz nje nasljedena.: ~gim ii direktan
pristup atributima Ime i _.!ndeksi ........,.. , ... •u " '
veoma jeci.D.ostavno ·
novu klasu koj~_n:asljedtuj(~ tu t.t.•••...c•.or
privatnim elementim
.·---. - __, _, a

X int GodDipl) {

·· f rei:Urio. GodinaD
~.. . iplomira nja; }

se po pravima
;;"ri.<lun a definira se
>d) I
· atnbutima Ime. i Indeks •
pravo sve metode klase Diplomi raniStud ent (ukljucujuci i konstruktor} mogle bi
im pristtipiti, i definicija konstruktora poput gore navedene postala bi korektna (u navedenom primjeru
to i nije previse bitno, jer je prethodna defmicija konstruktora koja poziva konstruktor bazne klase
svakako elegantnija). Slijedi modificirana verzija klase student, u kojoj atributi Ime i Indeks imaju
(Zasn6eno pra'V9_Eristupa: · ··

3
'-'.
!J

{
j[
char Ime[SO ];
int Indeks;

P~ -
public :
Studen t (const char Ime [] , int Ind) Indeks( Ind) {
J[
strcpy( Studen t::Ime, Ime);
}
char *vrati_ ime() const { return Ime; )
int vrati_i ndeks () con.st { return Indeks; }
. J[
void Ispisi () const {

}
cout << 11
Studen t -" -<< Ime << 11
ima indeks 11
<< Indeks ;
J[
};

U nastavku cemo podrazumijevati da su atributima Ime i Indeks data zastjcena prava


pristupa. lpak,
iraniS tudent -
j
bez obzira na ova prava pristupa, bitno je naglasjti da se konstruktor klase riiplom
mo ao na isati ovako, ·er je u konstruktorsko' inici"alizaci"sko' listi mo 6e inici"alizirati samo
oji su ~eposre~o deklariranj_u tqi klasi, bez obzira na prava pristupa atributa u baznOJ ast:
atribute
j
class Diplom iraniSt udent : publi_c _St;,udent {
· ~ ±ne-·Gadirian1Ploffi~i-~~Ja;'
public : J
X Diplom iraniSt udent(c onst char Ime[], int Ind, int GodDip l)
Indeks (Ind), Godina Diplom iranja(G odDipl) {
strcpy( Studen t::Ime, Ime); J
}
}
int vrati_g odinu_ diplom iranja () const { return GC>din aDiplom irimja;


} ;

' • • ' .;'• . ~''!,::,:.-:·c";<.:_>;:i•,.'"_ ' '.,' • . o· ' • _' -_· •


J[J
Nad objektima nasljedene klase mogu se keftsPt!;J¥~ irieto"de kao i nad objektim a bazne
k!ase. Tako
su sljedece konstrukcije sasvim korektne:
-
/;,:·J:~:X;\'-i•, ·, · · .
;-·~J4.~<t;t~~~~~~;~r~-
·
j]
studen t Patak 11 12.3,4:)~:r_-·_;:~t:. :: ~,,.
sl ( Paja 11 I

s2 ( 11 M±·k~Jici~#"!tr 3_~).2, 2004) ;


Diplom iranistu

~~~~:;~:~~~~;
dent

f:'7' :r.~~:~:"i ·. :• 1J
Ovaj primjer dovesce do sljedece g ispisa:
_,. , .. ' 11
Student Paja Pata~iina fndefls1234
Stutknt Miki 1)-faus Jii,ll inileb 3412 . . 11
se javliapo treba da nas1iedenae tdas~ WliJjieni neku od metoda)<:oje suiietmir30tlu
f S drug~straite, ~toprimjer,
• baznoj k!asi. Na kfasa Diplom irai:J.is tudent mme da proniijen i metodu Ispisi tilko' da
- uzn1e u ohzfr i godinii diplomirania studenta. Izmijenjena khisa mogla bi izgledatl ~vilko:
· lJ
L
class Diplom iraliiSt udent : pub~ic Studen t · {
1nt. Godina Diplom iranja;
·.publi c:
11
f~~ Diplom iraniSt udent(c onst char Ime[], int Ind, int GodDip l)
: Studen t(Ime, Ind), Godina Diplom iranja(G odDitih · {}
int vrati_godinu~diplomiranja() const { return Godina Diplom iranja;
} ~
void Ispisi( ) colist {
cout << 11 Studen t II << Ime << II diplom irao n << Godina Dip"lom iranja

}
<< 11
• godine , ima indeks '' << Indeks ;
.:.···
~
};

~
4

~
Primijetimo da ova izmjena ne bi bila legalna da atributima Ime i Indeks nije dato za.Sticeno pravo / /
pris~ (u suprotnom bismo morali k<iristiti metode vrati_ime·i vrati_indek s da pristupimo ovim
atributima). Uz ovakvu izmjenu, prethodni primjer doveo bi do sljedeceg ispisa:

Student Paja Patak ima indeks 1234


Student Miki Maus, diplomirao 2004. godine, ima indeks 3412

Drugim rijecima, naJ


objektom s2, koji je tipa Diplomirani Student, poziva se njegova vlastita
metoda Ispisi, a_g_e metoda nasljedena iz klase Student. Nasljedena verzija metode Ispis·i i ~
rl'tstupna uld · iranistuden t, ali ukoliko iz bilo kojeg razlo a zelimo da ozovemo upravo
nju, tu zelju moramo eksplicitno naznaciti pomocu operator ": : ":"j[ako, ukoliko blsmo nad <ibjektom
s2 zei]eh da pozovemo metodu Ispisi nasljedenu iz klase Student, a ne metodu Ispisi definiranu u
klasi Diplomirani Student, trebali bismo pisati

/ s2. Student:: Ispisl!J]

J Na isti n~cin je ~oguce u nekoj od met?d~ koj;~?difi~i~;;;;;c; u _n~~ljedenoj ~asi p~zvati. istoimenu
, metoau nas(Jedenu IZ bazne klase. Na pnmJer, u sljedecoJ definiCIJI klase D1plom1ran istudent
metoda Ispisi poziva istoimenu metodu nasljedenu iz njene bazne klase: ·

_cl~sa Di,glomirani.§~ude_:;t ;:,_ pubJ-ic:: Stude~ {


1nt Goa~naD1plom1ran]a;
public:
I.
f~
-- Diplomirani Student(con st char Ime[], int Ind, int GodDipl)
: Student (Ime, Ind), GodinaDiplo miranja (GodDipl)- {)
int vrati_godin u_dipiomira nja() const { return GodinaDiplo miranja; }
void Ispisi() cbnst {
dod~ Student: : Ispisi () i ... .
M-~ a diplOfnii;';ao~:j'.e_._i!-!-;<< GodinaDiplo miranja << " godine
11
cout << ", ;

w~ l :.fi,~t~/
Sada bi Ta<Jije navedeni primjer upotrebe <ivili"kli!})':d,#V~9--d() sljedeceg ispisa:
Stud{!nt P~Ja
Patak itfa indeks 17?/;;;l;,'~]:. :,~)t• _ .
Student Miki Mails i,nd~k,Y_ .~4,f-NiJ· t!t}/ditiirao je 1004. go dine
iJi#:
Treba napomenuti da jekvali-filador st@~rit ;.';::lspred poziv~ m~tode Ispisi veoma bitan, jer bi bez
njega kompajler shvatio da metoda :r~J¥-si poziva samu sebe, sto bi bill) protUnia~eno kilo rekurzija
(bez izlaza). i.: -
-~··' .~

Vee smo rekli da se konstruktori ne ilru;ljeduju, nego da iZvedena ldasauvijek ~ora de:fininti svoje
-
m kon~~ore_ (~lJiinjl:'ci i konstrukt?r kopije? ukoiiko ga _je baziJ.a ~a imafa}. Zbo~ :tO~a. se pe
1
! nasi edu u m autmnatske retvo ev ko e se o tv v s onma ·
• • • param<'Jf&{lL(koJl m5u o:inaceni sa ~xi>Uc t), nego ih nasljedena klasa n1ora po1J.\R:o~efiAirati ~ko!iko
' zeli da zadrZi moguenost automatske pretvorbe ·u objekte izvedene klase. Pored ~ozl.strukt~ ·~ I
#

svo "stva bazne kla5e ko ·a e ·ed ·I! su o erat rska nkci'a z r dodiele " " i deklan i'e
.. ~riiate!istyq. - eopterecem operator dodjele se ne nasljedu'e zoog to a Sto 'e <ibilmo ti" e8no ve:ia:n uZ
· onstruktor kopije koji se ne nas jeduje. Dek!aracije prijateljstva se nasljeduju jer bi njihovo automatsko
i:Iasljedivanje omogucilo razne zloupotrebe. Drugim rijecima, ukoliko je neka fimkc!ja@deldarirana: kao·
prijatelj k!ase@ona niie Ujedno i priiateli k!ase@)Jasliedene iz k!ase@Ukoli ko :Zelimo da zadrZimo
pri"ate!'stvo i u nasl'edenoj klasi, funkci"u f ponovo treba proglasiti ··ateijem klase unutar deklaracije
1/~
•••
~- Osim konstruktora, operatora dodjele i prijateljstva, svi ostali elementi bazne
u iZvedenoj klasi (ukljucujuci i operatorske funkcije ).

5
J
Sasvim je moguce da yji!e klasa bude naslijedeno iz iste bazne klase. Pored toga, ~_j!lfl_
ci!av \anac_nasljedivanja. Na primjer, klasa c moze .biti naslijedena iz klase B, koja je opet
imati i
naslijede na iz J[
.c=::::!-...
klase A. Konacno , moguce je da neka klasa naslijedi vise klasa, lj. da bude izvedena
iz vise od jedne
bazne klase. Na pririi]er, sljedeca konstrukcija

class C : public A, public B (


J
j
f deklarira k\asu C koja je izvedena iz baznih klasa A i B. U ovom slucaju se radi o tzv. (visestrnkom
• nasye ivan ·u Mada visestruko nasljediv anje moze ponekad biti i korisno, ono sa sobom vuce mnoge
ne oumice koje se moraju posebno razmotriti (npr. sta se desava ukoliko vise od jedne
bazne klase
j
su bazne klase takoder izvedene
imaj u neke a tribute iii metode istih irnena, zatirn sta se desava ukoliko
k!ase, ali koje su izvedene iz jedne te iste bazne klase, itd.). Zbog toga se ovdje necemo
visestruk om nasljedivanju, tim prije sto nisu rijetka misljenja da visestruko nasljediv
zadrZava ti na
anje unosi vise }
zbrke. nego sto donosi koristi.

Vee je receno da
. j

,
koristiti

uv•=•·a mogucnost ima\a veoma


• se ujedno shvatiti
ranije naglasili. U suprotnom bismo mogli doci u potpuno neprirod
i kao objekat
ne
b:izne
situacije . Na
klase, sto
pnmjer,
smo vee
ukoliko
1[
!ase Datum
bismo k!asu studen t naslijedili iz k!ase Datum, tada bi svaka funkcija koja prima objekat'k
p.rihvatala i objekat tipa Studen t kao paramet.ar, sto tesk() da mo.ze imati smisla:.. Jos
da se u svim navedenim situacijama sve specificnosti iz\iedene klase gube. TakO,
je bitno miglasih.·.
ukoliko promjenljivu
kao pararrietar
~
• s2 koja je tipa ·niplom iraniSt udent osal"efu() kao. · aiametai
neko' ·funkci'i k<i"a
o ~e t hpa Student_,_ o9aci o godini tfipl&mlraif~ iz "rom·eru'ive s2 bice i orirani.
Takoder,
' . pn
tll<ohko ;z:y;simo dodjelu poput s1 = s2 dje je sj, pioiffierujiva tipa stude;,t ;:,uprom
jen\jivu sl se I -.10
kopiraju samo ime i broi indeksa 1z promjerujive's(dl>kse'"inforn'lacija ogodini' dlp!Omi ranja ignorira (s •
obzirom da promjenljiva sl, koja je tipaSj:u dent:,ni jeu sil\nju da ovu informactju prihvati)
~r . . ·y(f/' -. . . . ..
. ·

1111
10
........
Veoma vazno l~~~~~~;~
U opcen)S iucaju. Objj ekt:j
1U
izvedene ·klasi::
kl\!Se, · ~~~
izvedeneStog~a
student. ·ohzini~~~·~·~~~~~~~~~~ii~~i.~~~~i.~i~~~~~X 1U
V promjen ela_~lileri~>·~gc•drrtu
iakododjljiva diJ?lomiJ·aii;[l!),

11
11
· 1zvedene klase koji ne postoje u baznoj klasL ·
.
~-
~ Nas\jedivanje dobija s.,;,oju punu snagu i primjenu tek u kombinaciji sa nokazivacima.
(uz
Nairne, slicno
neminov an gubitak
kao 'sto se objekat bazne klase moze dodijeliti objekat izvedene klase ·
specifienosti koje nosi objekat iivedene klase), tako se i:r>Okazivacu~ tip_ bam'< klase
mo:le dodijeliti -~
Tilk<iqer, sVaka-
adresa nekog objekta izvedene klase iii neki drugi pokazivac na tip !ZVedene k!ase.
pokaziva c na up bame kfase moze primiti
furikcua koja kao prima kao ·parametar iii vraca kao rezultat

~
6

1~
bjekta izvedene
kao parametar iii vratiti kao rezultat pokazivac na tip izvedene klase (iii ac:lresu nekog.o
deklaraciju
klase). Na primjer, neka su s 1 i s2 deklarirani kao u pretbodnjm primjeriina. i neka hnamo

l Student *pokl, *pok2; ]

Tada su sljedece dodjele sasvim legalne, mada su oba pokazivaca pokl 1 pok2 deklarirani kao
· pokazivaci na tip Studen t, a objekat s2 je tipa Diplom iranistu dent:

~pokl = &sl;
1-' pok2 = &s2;
pokazivaca,
Razumije se da smo.isto tako mogli odrnah izvrsiti inicijalizaciju prilikom deklariranja ovih
tako da bismo isti efekat postigli deklaracijom ·

(stude nt *pokl = &sl, *pok2 = &s2; \


ukazu'u
Razmotrimo sada kako ce se onasati o · okazivaci ukoliko nad ob'ektim a na ko'e oni
primijen imoneku metodu pomocu operatora ":.>" pa primjer, sljedecomkonstrukcijom:
pokl-> Ispisi( );
cout << endl;
~ pok2-> Ispisi( );

Ovaj primjer ce dovesti do sljedeceg ispisa:

Student Paja Patak ima indeks 1234


Student MikiMa us ima indeks 3412
t, bez ·obzira ~to pokazivac pok2
Vidimo da je u oba slucaja pozvana metoda Ispisi iz klase studen
· · . . .· ...
pokazuje na objekat tipa . . ·· ' .
p

/
. Zbog ranog povezivanJa, izgleda b~ da:susve Url'orillitcije o ~pecftic1J.dsti objeka!a
tipa
a
oiplomiranistu~nt _ ta~Oderizgubij~elad~J&~iv~c4.Ifutip Stu~t<fodljetjeiria3.dn:sa6bjekt
~ec;ficD. c>s&'lnoi a
tipa Diplomiranistud~nt. K'ada se U:e Ji:l'lrl~te pokl,!ilvaqi,jiJ:sn~ je ~ qi,''iiubljenja
doci, jer o,bjekat bazne klase ne moze (}!:LJmhvati.'S\"~ 8P-ecifiCI!OS(i.9bje~ji\f~4end1d
a5e (kOjiilad rzi
vise informacija). s <ifuge strline, )aSili}'je da ~ sf!_ ~®Stii po~a'~i; ac;·~~g g)ibljenja
specificllOSti ne bi mOra/a tf~ lai~ta, maoaje ~ po~~~ na ti~ st~dent, ooje ~ei'i;p da
.. po!=je na objekat tipa DlplamiraniStud~nt, k.9jl.pifslo/i. ~~I!#' ~e u.in~m9rl ji, tliko da' rie postilji
. nikakav gubitak mformac ija :Medutinl, da JJ.e. &i do~fo aa 'g\Ioljertja spetifien os!i izvedene ldase
(odm>sno ~a bi poZiv metock ~spisi nad obJel4orit ~a koji pokazUje po!(az;vac
pok2isp isao
se
inforinacij e kao da radi 0 diplomiranom a ne obiCOOriistudentu), tteba odluku 0 rome
koja se nietoda
. I~pisi poziva donijeti na osnoVu toea na sta po~zap'(iiric;klji!l£ e.'Ue ria 'Os_novu to~ ka~le­
deklqrirqn. Drugim rij ecima, odluku. o. tome koja se metoda poiiva ne !J:'eba se d<inositi unaprijed 1/J
; u azi
zvr5avanja •••
prevodenja programa,. nego je tteba odgoditi do samog ti'enutkil. poziviim etode (u vrijemei
~~ cemo
prograrna), jer u opeem sliicaju tek ta:da.inoze biti pilznato ria: slit pokazivac zaista po~~
[fiifzopo viifvilii} e(ellgl.l ate bindi!iif }
vidjeti u jednom od narednih primjera). Ova strategija nazivase

Da bismo ostvarili kasno p~vezivanje, ispred deldaracije metode ria koju Ze-limo da se
prinlienjuje
m kasnog
kasno poveziv anje treba dodati kljucnu rijei}'vi rtua:yM etode koje se pozivaju strategijo
Ispisi
pozivanja nazivaju seftrtua lne metode/odnosno virtualne fonkcije clanice. Stoga cemo metodu
u klasi Studen t deklarirati da postane virtualna metoda: ·

7
j
clasl!l .Stude nt {
protec ted:
char Ime [SO]; ·
ll
~~d
public :
!-
int Indeks ;

Studen t (canst char Ime [], int Ind)


strcpy (Stude nt::Im e, Ime);
Indeks (Ind) { t
}
char *vrati _ime( ) const { return Ime; }
. j
int vrati indeks () const { return Indeks ; )
- virtua l v;:;id Ispisi () const {

}
cout << "Stude nt " << Ime <<
11 ima indeks " <<. Indeks ;
I[
} ;

.sa ovakvom izmjenom, indirektni Roziv metode Ispisi pomocu opera toraQ
pokl i pok2 dovesce do zeljenog isptsa
nad pokazivacima i
Studen t Paja Patak ima indeks 1234
Studen t Miki Maus ima indeks 3412, adiplomirao je 2004. godine J
/ Bitno je nag!asiti da se kl'ucna ri'ec virtua l ise samo utar dek!araci'e
ase 'tl!'ko da ~ slucaju da //./ 1[
virtua l . e trebamo (L!!L • • • li
• virtualnu metodu implementiramo izvan deklaraci·e klase, kljuenu rijec · ·.[
··· ·
smijemo ponav Jati.
primjene. Na primjer, ]
> Kasno povezivanje i virtualne metode omogucavaju mnogobrojne interesantne
razmotrimo sljedeci prograrnski tsJecak:
S:t;ude nt *s = 11
new Studen t ( 11 Paja Patak ,
. S->IS pisi o'i - ,).,""'~· ~ ..dOd'~ -f.-rl>f·.
·
1234); i
t
cout << endl; _-..
delete s; · . . · . .
s = new nfPiOmiraniS1;ud.ei:tt { ''Miki ··Maus II 3_412, I

_ s->Isp isi (); - ,},@~ 'P"ll\.,y ~a...t.. ?'~~·/

~
_d~lete s; - ..

:~

. -·--·.
a tako da se ona
~
Vec smo rekli da se. polimorfuo pona5anje neke promjenljive tipieno realizir 1fl
· ko'a •· mal.cii ·ednu virtualn u metodu , ci'a ·e definici'a /.~1
dek!arifa kao okaziv acni(nd ru .· · !I
... promij.enjeria U ne OJOd k!asa nasJjedenih iz te bazne k!ase. U tom s]ucaju se
od!uka 0 tome koju zaista
Da je to zaista neophodno
metodil trebapozvati (tj ..iz koje Idase) odgada sve do samog treriutka poziva. fl
metode Ispisi (iz klase
demonstrira sljedeei piim}er, u kojem se odluka o tome koja se od dvije JY
prije samog trenutk a poziva, jer odluka
studen t ili iz klase· Diplom iranist udent) ne more donijeti
predvid jeti:
zavisi od podatakakoje konsnik unosi sa tastature, koji se ne mogu unaprijed

~
8

~
fl
char Ime[SO];
int Indeks, GodDipl;
Student *s;
cout << 11 Unesi ime i prezime studenta:";
cin.getline(Ime, 49);
cout << 11 Unesi broj indeksa studenta:";
cin >> Indeks;
cout "Unesi godinu diplomiranja ili 0 ukoliko student·
<< rr

t. joS nije diplornirao: 11 ;


11
<<
.. . cin >> God.Dipl;
...,~ dot«+, if (GodDipl == 0) s = new Student (Ime, Indeks); ·
~~-~ · else s =new DiplomiraniStudent(Ime , Indeks, GodDipl);
.'"'<! If I"" s->Ispisi ();
s. .
I
,

~
. tipoya. Na . . .

iJM~p~.,. - Student *Studeni;i [51 ;


""' to-12~~.. ·studenti[O! = nel< Student("Paja Patak", 1234);

or~
Studenti[1J = n ...........·.:. Dipl. omiran. iS. t)lc}ent("Ml.ki Maus", 3412, 2004);
Studenti [2] new Student ("Dusko Dugousko", 4123);
. studenti[3] ~e>.'student("Tom.Mac'ak",.2341); ··
Studenti[4] ne_w DiplomiraniStudent("D zeri Mis", 4321·, -1997);

Ll' Strogo osma o ove naredbe deklariraju niz nazvan Studenti od pet pokazjvaca na objekte tipa_
I
stu en , CIJIID elementima'Iqisnije dodjeljujemo adrese pet dinamicki stvorenih objekata, od kojih su •
kltri tipa studke;,_t,_ a dva ti~da'#~~lomkairadanistudd.7nt._ Me~uti~,_sjetim.o se daklse niwvipokaziva~ana
11:·. ·.
~L ase..mo onsti 1
oro 1 enti~no o se ra 1 _o, mzovnna c1 1 su e ementi ase, samo !ito za pnstilp
atributima i meto~rna umj~~t() operatora .. ·. onstimo operator"->" Dalje, kako je metoda Ispi~i.
11 virrueh!a, njena primjenanll,qpojedinim pokaziva,cin!a'dov.Odi do razlicitog dejstva u Zllvisnosti ad toga
~ll 3-a kakav objekat konkre~ pakazivac pokazuj': . f{~~~ ~-~aiedba poput ' i /~ . ·

11Lti for(int ~ = Q; i < 5; i++) Stu?iililtH~.:->Ispisi(); U/

'[l dovesti do slj(:de,~eg ,. '':. ·.

~
g
~

· ·· Vi!Zno je naglasiti da;• bez obzira na polinlo~·ne moremo.preko pokazivaca na baznu klasu j·
Q · pozvati neku od n.Ietoda. ~oia postoJl samo u 1ZVedenoj. klasi, a tie..i u .'!laznoj klasi,. cak i ukiiliko taj ,
pokaiivac trenu!no p6~· na objeklit 1zve.dene klase. Na pnmJer, · sljede6a konstrukcija nije
·,
D
.
l.-.,1
I
f dozvoljeria, zboitilinf~t~ Yi:'Qdekhiririm kao]Jobzivac nil klasu stude~t koja ne posjeduje metodu
• vrati_godinu~diplomi-ranja,bez obzira ~to.je on inicijaliziran talco da pokazuje na objekat klase
DiplomirariiStudent:

u
....,..
..

n 9
J
\}
(\
Stude nt *s = new Diplo miran iStud ent ("Mik i Maus"
cout << s->vr ati_g odinu _dipl omira nja();
, 3412, 2004) i
J[
revodilac nema garimcije da
Ovo nije dozvol"eno zb to a sto u trenutku revoden·a ro ·arna
promJen JIVa zaista polaiZuJe na obJekat oj i posjeduje ovu metodu. Zaista,
bi
kada bi bio dozvoljen poziv
doci do velikih problema, s
I[
metode vrati_ godin u_dip lomir anja nad promjenljivom s, moglo
pokazivati na objekat koji uopce
obzirom na cinjenicu da je s pokazivac na tip Stude nt, tako da moze
ne sadrii podatak o godini diplomiranja. Stoga su autori jezika C++ usvojil
dozvoljeni. Ukoliko nam ·e b ' o da nad okaziv acem ko"i ·e dekl
i da ovakvi pozivi ne tudu
·an da okazu·e na baznu
lf
inetodu koja je definirana samo u izv deno · klasi, a szprn i smo da u
klasu primijemmo ne
posmatranom trenutku taJ po aZivac zaista pokaz te na objekat_ir::rgd
ene klase, mo:l:emo na pok~
nu klasu pomocu operatora za
l[
primiJemn eks licitnu konverzi·u tlpa u tip po aZivaca na izvede
metodn koju zelimo. Na
r uti a type-casting opetatora), a zabtn na rezultat pretvorbe primijeniti
primjer, nad promjenljivom s iz prethodnog primjera mogli bismo uraditi
sljedece:
1[
IJ(/'· cout << ( (Dipl omira niStu dent *) s) - >vrat i_god inu_d iplom iranj a () ;

Ovakve konstrukcije preduzirnamo na vlastitu odgovomost, s obziro


nepredvidljive ukolik o@ne pokazuje na objekat koji je tipa Diplo
m da posljedice mogu biti posve
miran iStud ent. Ukoliko nam je
!
·vac rnoiemo
potrebno da u toku izvrSavanja ro ama is i o na sta a ·e neki olimo
oristiti operato typei koji se koristi na nacin oji je sasvimjasan iz
sljedeceg primjera:
1
if(typ eid(* s) == typeid (Dipl omira niStu dent) )
cout << ((Dip lomir anistu dent* )s)->v rati_g odinu _dipl omira
else
nja();
11 ;
l[
cout << 11 Zalim , s ne pokaz uje na diplor nirano g stude nta!

Bez obzira na cinjenicu da pretvorba pokazivackih tipova iz jednog u


drugi i typei d operator mogu
ponekad biti korisni, pa cak i neophodni (inace ne bi bili ni uvederii), njihov
a intenziv'na upotreba gotovo
·
.i
~
sigumo ukazuje na pogresan pristup problemu koji se ijesava. ·

~
• ·~

~
op~za
· ireba iZbje6 po

~
Iieko liko klasa koj i
,!)vim iikovitni je
"'-~
•••
geometrijske Jikove, na primje r krugove, pravougaonike i trouglove. rfl
klasu nazvanu Lik koja ce
zajednicko da. posjeduju ·obim i poVr.sinu. Stoga mozemo derdarirati !I
koji ce sadriavati naziv Jika
sadriavati samo SVOJStva zajedniCka za SVe Jikove, kao sto je atribut Naziv
·koja ispisuje osnovne podatke o
("Krug", "Trougao", itd.), metode Obim i Povrs ina, i metoclu Ispisi //1.'1. rfl
samostalno1 nego iskljucivo kao ·
liku (naziv, obim i povr.Sina). Klasa Lik ]1ije namijenjena da se koristi ~
bazna kJasa za klase Krug, Pravo ugaon ik i Troug ao, koje c~mo naslije
h
diti kJase Lik. cime zilpravo ' • • ,
Pored toga, definiracemo i klasu
izraiavamo cinjenicu da krugovi, pravougaonici i trouglovi jesu likovi.
-~
10
-~
'-'

Il
I-
~·f. \

[1
i Kvadrat nasljedenu iz kiase Pravaugaanik (koja odraZaVa cinjenicu da SU kvadrati specija!na forma
pravougaonika), kao i. klase PravaugliTraugao i PravilniTrougaa nasljedene iz klase Traugaa

G koje redom predstavljaju pravougli i_pravilni Gednakostranicni) trougao ka<:> specijalne forme trouglova.
Na taj nacin dobijamo cijelu hijerarhiju klasa, kao na sljedecoj slici:

g
.).

~
c]~- PravaugliTraugao
... -·-·-:···

~
Krenimo od definicije klase Lik. Kako ova klasa ne predstavlja nikakav konkretan lik, ne moumo
. ·, specifizirati nikakve konkretne atribute (osim naziva), niti ikakve konkretne postupke za_ racunaJ1ie
~

q
obirna i poluprecnika. Medutim, kako cemo u kiasi Lik defmirati metod I o·u ce sve ostale
klase rtaslijediti ko·a oziva metode za racunan e <i Ima 1 ovrsine te metod~ ·obavezno moramo
efmirati i u kiasi Lik, pa makar i ne radile nista srnisleno. Usvojicemo ·da ove metode za klasu :dk
~ : prosto vradaJU nulu klio re.zultat, a u svakoj od rtasljedenih kiasa definira6emo_ prave postupke za
[J·L racunanje obima i povrsine, u skiadu sa konkretnomvrstori:t lika. Stoga ce prva verzija defmicije kiase
Lik izg!edati ovako (kasnije cemo uvidjeti da ce biti potrebne izvjesne modifikacije u dekiaraciji ove
_ klase da bi sve radilo kako !reba): · ·

-~4ko 4q -
class Lik {
protected:
chci.r Naziv[20};
f1~(7 public:

Lt .~~"""
double Obim() canst { return· 0; ·Y'c:
double Pavrsina () canst { return .0; ·.}
void Ispis () canst { ·•. ·

~
cout << "Lik: " << Naziv << .. e;{df- << 11 6bim: II << Obim() « en<:ll
<< II PovrSina: rr << Povrsina() << endl;
}

~
};

~ je

~ _cl!i!J!!S I<rug : public Lik {


. -~o.~ie ·r; _ . -'__ ... _ _ , -,

i
. . . . public: _ · · _ _ ·\
~---Krug(doUb7_"_· i) ·" r(r}. f_strcp.·y(Naziv, _".KJ:ug"); }• iid. -:. -_ J. _"·-',_,, ~··.
double ob~mo const { return: 2 * PI * r; } ;-?· !1'110o40,..~ ~~ 'r-·
double Pavrsina() canst { r.eturn r * r * PI; } ~ to(-_ . ·

~
-}. . .. ) . .
. .t ·:·

Na s!ican nacin cemo defmirati i kiase Pravougaaniki Trougao (a!r!bute klase Traugao oznacili II
i smo sa protected, s obzirom da ce nam ti kiasi PravaugliTrougao 1zvedenoj iz rtje· trebati • •
mogucnost pristupa evim atributima). K!asa Pravaugaonik posjedovace dva, a ldasa Trougao tri
atribilta koji cuvaju dllZine strimi'ca. Tu su i odgovarajuci konstruktori sa dva odD.osno tri parametra za

~
inicijalizaciju tih atributa, kao i: odgovarajuce definicije metoda :z:a racunanje obima i povrsine (po\'rsinu
trougla u funkciji duZine stranica racunamo pomocu Heronovog obrasca):

1I
'r.
.,
_clas_s. Pr~~q~anpi.k : p~-~~Z Lik {
double a, ; ·
public:
Pravoug aonik(do uble a, double b) a(a), b(b) {
strcpy{N aziv, "Pravou gaonik ) ;
11

}
double Obim() const { return 2 *
double Povrsina () const { return
};
class Trougao : public Lik {
protec~
double a 1 b, c;
public:
Trougao (double a, double b, double c) a(a), b(b), c(c) { -- ~~~
11
strcpy{N aziv, "Trougao );

} .
double Obim() const { return a + b + c; }
double Povrsina () const {
return sqrt((a +b+c) * (-a+b+ c) * (a-.b+c ) * (a+b-c )) /4;
}
.}; ... ,, ....
_

Sada cemo iz klase Pravoua aonik izvesti k!asu Kvadratta koja opisuje kvadrat kao. specijalan
sluCaj pravougaoridd. Jedino sto cemo promijerrin· u OVOJ asi odnosu na njenu baznu klasu
(Pravoug aonik) je konstruktpr (koii se svakako ne nasljeduje), ~ obzirom da se kvadrat opisuje sa
jedmm, a ne sa dva parametra. Ovaj konstrukt6r postaviceoba atributa koji opisuju pravougaonik na iste.
VnJednost1, s obzirom da je kvadrat upravo pravougaonik sa jednakim stranicarna. Svi ostali elementi
(ukljucujuci i metode za racunanje obima i povrsine) mogu se prosto naslijediti, jer se obim i povrsina
kvadrata mogu racunati na isti nacin kao i za pravougaonik (ako uzmemo jednake dllZine stranica):
_c1ass Kvc::drat: __ _: public Pravou~c\onik {
public: · '
~-- Kvadrat( doub:I.e a) : P~J'Ongaonik(&r §J { strcpy{N aziv 1 n.Kvadra t 11 ) ; }.

}; . . .

Pri!Tiijetimo da bismo napravili veliku ko~ceptualnu gresku da smo prvo definirali klasu Kvadni.t a
zatim1z nje izveli k!asu Pr~vougaonik .. Do ovakvog pogre8nog rezoliovanja mogli bismo doci ukoliko
btsmo- brzopleto zakljucili da se kvadrat opisuje jednim atributom (duZinom stranice), a kvadrat sa dva
atributa (duZin~dvaju stranica), tako da pravougaonik zalitijeva vise atributa za. ()pis nego kvadrat
Medutim, pr:ayaj~ cmjeillcaila i kvadrat isto tako posjeduje sve atribute koje posjeduje ipnivougaonlk,
saino- su. oni medtisobn6jednaki. Kvadrat je specijalan slucaj pravougaonika, a ne obrnuto, tako da klasa
. -- ·- .• .- . .. :. --- . . ·_ •

. Kvadrat treba djJ. bu~e iZVedena a Pravoug aonik bazna klasa. Svi kvadrati su pravougasmfci ali syj
. ·• - . -_.· :·- '·· .: _. . . . (>,.

pravougaoriici nisu kvadrati. ·

Na s)ican nacin cemo izldase Trougao izvesti klase Pravoug liTrouga o i Pravilni Trougao . I
u ovom ~Iucaju dovoljno bi bilo.promijeniti samo konstruktore. Medutim, u.kJasi Pravoug liTrouga o
smo promijeruli i metodu za l:aci.Jnanje povrsine. Nairne, povr8ina pravouglog trmigla moze se iznicunati
·
mnogojednostavnije nego komplikovanom Heronovom formulom, tako dana· ovaj ·nacin dobijamo na
.
efikasnosti i tacnosti (jer Heronova formula moze da akumulira gre8ke usljed zaokruZivanja):

clas~Jlfavou9li_!rouga.o__ : gublic Trougao {


publl.C. ·
.- Pravoug liTrouga o(double a, double b)
' Trougao (a, b, sqrt(a *a+ b.* b)) {
strcpy(N a-ziv, "Pravou gli trou~ao' 1 );.
}
·double Povrsina () const { return a * b I 2/ }
};

12
claff PravilniTrougao : public Trouqao {
pUb C: . · .
PravilniTrougao(double a) : Trougao(a, a, a) {
strcpy{Naziv, 11 Pravilni trou9ao 11 ) ;
}
};

' Ovim smo definirali sve potrebne klase. Medutim, ukoliko bismo pozeljeli da isprobamo napisane
klase, veoma brzo bismo vidjeli da nesto nije u redu: Na primjer, pretpostavimo da smo sa napisanim
klasama izvrsili sljedece naredbe:

Pravougaonik p(S, 4);

g ~
1've i17v:l,u',.,;,,
'
-.(-v.a;
~ :1-opt~O
(.t'''~-(J"'
f-
Krugk(3);
p. Ispisi () ;
COUt
k.Ispisi();
- cout << "0 =
<< 11 0 = 11 << p·.Qbim() <<

k.Obirn()
11 p p. Povrsina () < < endl;
" << « " P 11
<< k.Povrsina() << end,l;

'j Ove naredbe dovele bi do sljedeceg ispisa na ekranu:

g Lik: Pravaugaonjk
Obim: 0

g
Povrsina: 0
O=J8P=2o
Lik:Krug
Obim: 0

g Povrsina: 0
0 =18.849556 p = 28:274334

9
g
p ., "
""'
m
~

...D.
J
~ cliiss 'Lik {
] public:·
~ ~~·~ $. virtual double Obirn() const { return 0; }
,.. ~ fY\1 ~- 2. virtual double Povrsina () canst { return 0; } ·
.I Mtol\tu:.n.,c..t . void Ispis () cons t {
; L\~' bv'/l'JvN ,· cout << "Lik: n << Naziv << endl << "Obim: 11 << Obim() << endl
r <·< 11 PovrSina: 11 << Pov:;-si:D.a() << endl;
}
};
J

13
~
Uz ovakvu izmjenu sve ee raditi u skladu sa ocekivanjima. U ovom
govezivanjem i virtualnim metodama javila se neovisno od polimorfizma
,
primjeru
koji se u ovom
WJreha
up kasnim
pnmje ru ne ]T
· .
koristi.

Iz izlozenog primjera mozemo vidjeti da virtualne metode donose jeclnu


sustinsku noyost u odnosu 1[
funkcije su omogu eavale da novonapisani
na sve sa cime smo se ranije susretali. Nairne, klasicne
l dijelovi programa mogu da Jmriste stare dijelov~ programa (koristeei
pozive funkcija)~ 'i5ez ikakve
' potrebe da mijenjamo vee napisane dijelove programa. Medutim, virtual
ne funkcije nam nude upravo
II 1[
obmuto: da stari (tj. vee na isani di'elovi ro ama bez ikakve potreb
e za izm]enama mogu pozivay ..•
iti ·napisani! Zaista, posmatrajmo metodu Ispis i iz prethodnog
dijelove proe;j;ama koji ce te
primjera. Ova metoda poziva metode Qhjm i Povrs ina, ali kako
se radi o virtualnim metotama,
unaprijed sene zna na koje se metode Obim i Povrs ina (tj. iz koje klase)
ti pozivi odnose sve do samog
f
Ispis i pozove. Sasvim je ·
trenutka poziva, kada ee to biti odredeno objektom nad kojim se metoda
moguee da se kasnije odluctmo da u program dodamo podrsku za
isjecke, poligone, itd.). Ukoliko ove likove implementiramo kao klase
nove likove (npr. elipse, kru:lne
naslijedene iz klase Lik i
Ispis i (koja je vee davno
f
~
definiramo odgovarajuee metode za racunanje obima i povrsine, metoda
, bez potreb e da vrsimo ikakve izmjene u
napisaila) ce u slucaju potrebe pozivati novonapisane metode
samoj defmiciji metode Ispis i. N:a~t~aJ~-n~a~c~in~,~-~~~~
~~:~~i~~;~~~~~~=i
~
mogu pozivati novonapisane
. Moguenost da stari dijelovi programa bez ikakve potrebe za izmjenama
dije]ove programa, a koju nam nude virtualne funkcije, leZi u osnovi
orijentirani prislup . .Sve dok u programu ne pocnemo koristiti virtual
onoga
ne
znak
sto se naziva objektno
funkcij
da
e (cime program
ispravno razmisljamo o
~
pripremamo da se automatski "adaptira" na eventualna prosirenja, sto je

~
(cak i ukoliko u programu
buduenosti) ne · mozemo govoriti o objektno orijentiranom_QIQgJam~
vee samo o <ilij.ektno baziranom
intenzivno koristimo klase i nacela objektno orijentirane filozofije),
pro&amu (tj. programu zasnovanom na objektima}.

~
.
$

mjestu ipak susreli sa


Ako malo pl!Zijivije razmislimo, sjeticemo se da smo se i ranije na jednom
funkciju ne znajuei o kojoj se
jednim mehanizmom koji omogueava da neka funkcija poziva drugu
funkcije. Zaista,

~
pokazi vaCi na
funkciji radi sve do samog ·trenutka poziva. Taj mehanizam ostvaruju
u f, pri cemu se sve do tremitka
funkcija NulaFunkcije koju smo pisali pozivala je "funkciju" nazvan
funkcije f <idnosi (stvarna
poziva funkcije NulaF unkci j e ne zna na koju se stvarnu funkciju oznaka
je). Tako, jednorn napisana

~
funkcija koju predstavlja f zadaje se kao parametar funkcije NulaF unkci
u koja se napise tibuduenosti,
funkcija NulaF urikci je bez ilaikve izmjene moze·pozivati svaku funkcij
i sa funkcijom ({sor€ )iz
pod uvjetom da joj se opa prenese kao paranietar, Slican slucaj ii:ruimo
biblio.teke~OE ~cija :a poredenje_elemena~ niza~ji se sortiraj u doba kada]e naptsana ,
u poziva funkciju kriterija /
za koJU poJma nema kako lZgleda, sta radt. 1 ko1a definitivno mJe btla
funkcija gsort (funkciju kriterija pise progra mer koji koristi
naptsa
funkcij
na
u qsort ), Dakle, pokazivaci na
rna bez ikakve izrnjene oziva·u
-~
funkcije takoder na neki nacin ude mo cnost da staii di'elovi ro ·
novonapisane· t]e ove prognima, samo sto ·e otreba · ·
ueba da nas preljerano cudi. Naii'i'!e;·na aju ovog pog av ja eemo
kci"a "edno i'a. Ovo otkriee ne
vidjeti da su virtuelne funkcije
ni pokazivact na oOJekie. j
~
zapravo"prero§eni pokazivaci nafimkcije, isto kao sto su reference preru8e ,
Izvjesni citaoci ee se vjerovatno zapitati zbog cega snio uopce definirali
klasu Lik kao baznu klasu
(naziv lika) i jedna metoda
~
za klase Krug, Pravo ugaon ik i Troug ao. Nairne, jedan zajednicki atribut

~
neki osobit razlog da izvedemo
sa zajednickom defmicijom (metoda za ispis podataka sa likom) i nisu
ao prosto napisemo neovisno
bas ovakvo nasljedivanje, umjesto da klase Krug, Pravo ugaon ik i Troug
smo ostvarili si:njestanjem ovih
~d ikakve · zajednicke bazne klase, s obzirom da je usteda koju

~
ju koja bi nastala kada bismo ove
zajednickih elemenata u klasu .Lik neznatna u odnosu na situaci
biti veee kada bi izvedeni objekti
elemente posebno definirali u svakoj od ovih klasa. Ustede bi mogle
u baznu klasu. Medu~, postoji
posjedovali veei broj zajednickih elemenata koje bismo mogli smjestiti
strukturu, a to je mqey!;nost
~
jedan mnogo jaci razlog zbog cega smo se odlucili za ovakvu hijerarhijsku

14

~
II
u'~
~ polimor(izma._ Nairne, ukoliko definiramo neku promjenljivu koja je tipa pokaziv
ac na k:lasu Lik, takvoj / / /
romjenljivo· cemo moci dodi"eliti okazivac na bilo koju od k:lasa koji su izveden
i iz k:lase Lik (lj. na • • *

~
bilo koji lik). Pored toga, kako su metode Obim 1 Povrs1 na vtrtua e, pozivi ovih
promjenljivon'i prmzvodtce razlicite efekte u zavisnosti od toga na koji lik
metoda nad takvom 6/mCT
promjenljiva pokazuje,
odnosno tmacemo polimorfnu promjenljivu. Na primjer: • .
~· Lik *lik =new Pravou gaonik (S, 4);
li~spisi () ;
cout.< < 11
0 = 11
<< liJc6D bim() <<

~
II p " << likE}:: Povrsin a-(}
delete lik; << endl;
lik =new Krug(3 );
likE§ Ispisi () ;

~
cout << "0 = 11
<< liJGO bim () << 11
P = 11
<<-likE _..5:Po vrsina( ) << endl;

U navedenom primjeru prom'enl"iva lik je· iskoristena kao _olimorfna


rom'en riva. Da metode
Obim i Povrsi na nizu de arirane kao virtuelne, u ovom primjeru ne bi ispravn

o radio cak i njihov
samostalni poziv nad promjenljivom lik (a ne samo posredni poziv iz metode
Ispisi ), jer bi zbog
ranog povezivanja .lffi_m _ · e.r zakljucio da treba pozvati metode Obim i Povrsi
na_E kfase Lik (s
obZJTom a Je proii\)enljiva · i deklarirana ao po

~
vac na Lik). Mo2emo zakljuciti da su virtualne
, metode uvUek potrebne kada zelimo koristiti polimorfizam; ali s druge strane,
prethodni primjer nas je
1 uvjerio da one mogu biti potrebne i neovisno od polimorfizma .. One su zapravo
neophodne kad god neka} If 1

q od metoda treba da poziva druge metode, pri ceniu se u trenutku pisaljja k:lase
metode (lj. na koje metode iz mnostva istoimenih metoda koje mogu biti definira
iz te klase) ti pozivi odnose.
ne zna na koje ,se tacno
ne u klasama izvedenim -
!LJJ~

~
Zahvaljujuci polimorfizmu, mozemo deklarirati heterogeni niz likova, odnosno
niz Ciji su el~nti
lik6vi razlicitih tipova. Sljedeci primjer demonstrirajedan takav niz. Nakon dek:lara
cije i inicijalizacije, _
nad svakirn elenientom ovog niza poziva se meto.da Ispisi , koja proimodi razlicite
ispise u zavisnosti

~
od toga koji lik sadrZi koji element niza: -
Lik *Likov i[10] = (new Krug(3 ), ·new Pravou gaonik (s; 2),
new Krug(5 .2) ,- new Kvadr at{4)
11 I new. Trouga o(3,
new Pravou gaonik (7. 3, 2. 16·) , new" Pi::"av ilniTro ugao (4
.15) ,
5, 6),

tJ new· Krug(l O), new Pravou gliTro ugao(4 :,,


for(in t.i = Oi i < 10; i++)
2), new Kvadr at(3) };

g Likovi [ii~spi,s_ i Oi -. _. . _, _'- . c. ,


~) .i\'1 Lil:!~ ~"'{j"' "'-"' folrl!-oecc, .
Razumije se_ da Ljkovi nlje stvarno niz koji sadrzi razlicite objekte, vee mz
.
ciji elementi _pok(lhuju na
raz/iCite objekte-:'Medutim, za nas je bitno da ovaj niz niozemo koristiti kauda
0
~."'
raz/iCite. objekte.
se radio nizu koji sadrii
. -
Da bismo u potplniosti iskoristili polimorfizam, sve metode bilo· keje bazne
11 .k:lase koje mogu
J
...
~~
eventualno biti promijenjene u nekoj od izvedenih klasa trebale bi bez izuzetk
virtualne (u slucaju dane koristimo polimorjizam ovo nije neophodno). Takobi
a biti qek:larirane kao
i nietoda Povi:-s ina u
,/
k:lasi Trouga o (kojaje izmijenjena u·klasi Pravou gliTro ugao takoder trebala
] a ism() Se U"]en 1 Uto, razmotrirno sJjedeci primjer:
biti dekiariramt kao

~
Trouga o *t- neW Pravou gliTro uqao(S , 4);

] cout << t GPov rsina (};.

Primijetimo prvo daje gomja inicijalizacija Iegalna, jer pokazivac na klasu Trouga
• o maze pokazivati na
-oqiekat klase Pravou gliTro uqao koji je izveden_ iz ~je. Medutim, ukoliko
metoda Povrsi na nije / / /
1
I
dek:larirana kao virtualna, njen poziv nad pokazivacem t pozvace metodu Povrsi
a ite iz k:lase Pravot.igil.Trc:;~g;;t-;;:5-obzironiaa}eE-deKliini1in kao pokaziv
-
pc:_vezivanje)! - · --
·
na iz k:lase Trouga o •• "
ac ria Trouga o (rano '
. ---
15
\f
..
Prirni"etirno da ·e u · · ++
, ~' Stoga se polimorfue rom' e tve mo
rfizarn o anicen sarno na · ve ko'i su izvedeni iz !Ste bazne
pon atJ. kao rornjenl'ive razliihtih. tipova, a 1 sarno
j[
mcigla je sadrZavati (preciznije pokazivati)
, rnanje iii vise sro nih tipova. Na prirnjer, promjenljiva lik
razlicite vrste likova, ali je mogla sadrZavati samo likove, a
. ,
S\icno heterogeni nizovi se ponasaju kao nizovi k;oji
.
ne i npr. ne8to drugo (recirno studente).
sad!Ze elemente ralicitih, ali metlusobno srodnih
likove ·
]
·tipova. Upravo zbog toga nam je, i hila potrebna klasa Lik.
nisu kao imale · klasu
...I j
klasama kojes u iz nje izvedene.
j
rci apstraktne bazne klase, niti .se
U norma lnim okolnostima, nikada se ne deklariraju primje
primjerci bazne klase kreiraju dinamicki pornocu operatora new.
da uradimo tako nesto, npr. da izvrsimo sljedece deklaracije:
Medutim, do sada nas niko ne sprecava
Jf
Lik 1;
Lik _*pl = new Lik;
. ···-..' .
i
. ·--.
Jasno je.da s~ ..., · •>. e deklar aci' sko · e jer se sa prim'e rcirna klase Lik ne moze uraditi nist
onsito. Stoga posto jhiaci n da se ovakve deklaracije ormalno
zabrane. Za tu svrhu dovoljno je u klasi
lementirane (umjesto da im dajemo neku
J[
Liktle Re od virtualnih metod a (najbolje sve) ostaviti neimp
rnlu:lje iii vise besmislenu implementaciju). Da bisino to ura!1il
ti.apisati omak u "= 0", kao u sljedecoj deklaraciji k!ase Lik:
i, urnjesto tijela metode trebamo prosto
i
class Lik {
publ ic'
-virtu al doub le Obim () cons t = 0;
virtu a.l doub le Povrs ina () cons t ":'"
!
void Isp~s() cons t [
cout << 11 Lik: 11 << Naziv << endl << 0bim:
11

<< 11 Povr. Sina: · 11 << Povr sina () << endl;


11
<c:: Obim (} <:< en.dl
t
};
}

t
~
,
0
~
lfl
~
.....-:-• Konstruktori se ne mo deklarirati kao virtualhi ali destru
ktori mo . Zapravo; kada se god koristi
estruktor!! koji se · rnedusobno razlikuju,
~
polirriorfizam; a bazna klasa i izvedene kfas\! posje UJU

~
lan. Nairne, u suprotnom bi u situaciji
destruktor bazne klase obavezno mora biti deklariran kao virtua
kada- pokl!Ziva& na baznu klasu pokazuj e na objekat izvede
ue ldase, priliko munii ltavan ja objekta bio f
destruktora izvedene klase)! '
pozvan pogreilan destruktor (destruktor bazne klase, umjesto

~
16

~
,.
1fl
-J;l- S /'<1 III/.f- I
tf t: c'L:.-f i (!It'/ f

R A D SA D A T O T E K A M A
Svi do sada napisani progra
mi imali su SllStinski nedost
trenutka ka da se program zav atak da se svi uneseni podac
r5i. Ovaj problem se Jje5av i gube onog
predstavljaju strukturu podat a uvodenjem datoteka (engl.
aka koja omogueava trajno files). Datot!llg:
van)ske memorije (obieno na .smjestan ·e informacra na nek
har om od
izmedu dv a pokretanja programa d dis . ve pn mj ene raeunara u kojima podaci moraju bit ure da' a
obavezno zahtijevaju upotrebu i sai
za obradu teksta mo m posje
dovati moguenost da se doku datoteka. Na primjer, bilo koj !uvani
ment sa kojim mdimo samtva i program
buduCnosti u bilo kojem tre na disk, tak o da u
nutku moZe!no ponovo pokre
samtvan ka o datoteka), i nastav nuti program, otvoriti taj do
iti raditi sa njim. Slieno, kument (koji je bio
evidencije o studentima mo bilo kakav ozbiljan progra
ra posjedovati ·moguenost m za vodenje
studentima, inaee hi bio po trajnog envanja svih unese
tpuno neupotrebljiv .(jer bis nih podataka o
ponovo unositi vee unesene mo pri svakom pokretanju
infoll!lllcije). programa morali
U jez iku C+t- podrZana su dv
a naCina.za rad sa: datotekam
njemu se rad sa datotekama a. Prvi naein naslijeden je iz
zasniva na primjeni izvjesnih jez ika C, i u
"f" (npr. fop en , fc lo se , fg funkcija Cija imena uglavno
et, fp ut, fre a< i fw ri te, m poCinju slovom
parametarn obavezno zahtije fp rin tf, fsc an f, itd.), i ko
vaju pokazivae i1a stiukturu je kao jed an od
datotelre. Na ov om na &l u rad nazvanu FIL E, koja pred$ta:vlja
a sa datotekama se neeemo tzv. deskriptor
.. mnogo jednostavniji i tleksi zaddavati, s obzirom da jez ik
bilniji naein mda sa datotekam C++ podrZava i
ko jij e veo ma sliean naeinu a zasnovan na ulaznim i izl
koriStenja objekata ula mo g azn hn tokovima,
nastavku razmatmti samo ov ·i izlaznog toka cin i co ut. Zb
aj naein mda sa datotekama. og toga eemo u
Vee sm o rekli da su ci n i co ut
zapmvo inStance idasi sa im
definh:ane u· biblioteci ios
tre inn , a koje pred&tavljaj enima{[skle~ ~koje
standardnim ulaznim odnosno u objekte ulaznog i · aznog su
izlaznim uredajem (tipieno tok a povezane sa
rad sa datotek mommo sami definirati svo tastaturom i ekranom). Da
je ins bismo omoguCili ··i
. su definirane u biblioteci fst tan cel da sa nazvanih i f str ea m i
dak>tekama Obe klase p<lkJ&
· aat.Oteke sak ojo m se tok pov
of str ea m iz klase os tre am
rea m, a: koje predstavljaju
I'uju konStruktor sa jednim
ezuje. Po red toga, klasa- ifs
ulazne osn o izl azn
sfri!lgovnim parametrom ko
tre am je naslijedena iz kla
e tok

se
of str e
ov
koje ;.
e povezane sa
ji predstavlja ime )
r,
, tako da instance klasa if ist rea m, ak las a"' •
operatore ko je posjeduju ins str ea
tance kla sa ist re am i os tre am m i of str ea m posjeduju sve metode i
i manipulatore po pu t set w, , odnosno objekti ci n i co ut
itd. . To uld
umjesto objekta co ut koristimo Tako se upis u datoteku VIii na isti naein kao isp is na ekran, juw je
vlastitu ifistancu klase of str samo -
istu stmkturu kao i odgova ea m. fri tome te lcmjmna
rajuCi ispis na ekran. Na datoteka im ati
llliZlVom "B RO JEV I. TXT" i primjer, sljedeCi primj~ kre
u nju upisati spisak prvih 100 iraCe datoteku po d
te broj i njegov kvadrat ,biti razdvoje prirodnih brojeva i n.lihovih
kvadrata Pri tom e
ni zarezom, a svaki pa r broj--k
: vadrat bite smjeSten u novo
#i nc lu de <f str ea m> m redu:
us in g na me sp ac e std ;
in t ma in( ) (
of str ea m Iz la z ("B RO JE
VI .TX T" );
fo r( in t i = 1; i <=
10 0; i++ )
Iz, l.a z << i << ", " <<
} i * i << .en dl; .

Nakon pokretanja ovog pro


grams, ukoliko je sve u red
sam prograll! bit e kreirana u, lt direktoriju (folderu) u
no va datoteka po d imeno ko jem se nalazi
pregledati po mo eu bilo kojeg m "BRQJE\TI. TXT". Njen
tekstualnog editora (npr. No sad da j se moZe
serije operativnih sistema). tePad-a ukoliko radite po d ne
Tako ukoliko po mo eu tek kim od Windows
datoteke "B RO JEV I • TXT", nje stu alnog editom otvorite sadrZa
n sadzZaj te izgledati isto ka j novokreirane
pomoeu objekta izlaznog tok o da su odgovarl!iuCi brojev
a co ut. Drugim rijeCima, i ispisaui na ekran
(ovdje su upotrijebljene tri taC nje n sad da j hi trebao izgled
ke da ne prikazujemo Citav ati taCno ovako
sad da j):

\
1
jL
,.

1,1
2,4
}l
3,9
4,16
5,25
l[
99,9801
100,10000 J[
Ime datoteke moZe biti bilo koje ime kojeje u sldadu sa konvencijama operativnog sistema na kQ.jem
se pr9gl'lliil izvr~a. Tako, na primjer, pod MS DOS operativnim sistemom, ime datoteke ne smije biti
dliZe od 8 znakova i ne smije sadrZavati razmake, dok pod Wmdows serijom operativnih sistema imena
If
datoteka mogu sadrZavati razmake i mogu biti dugaCka do 255· znakova. Ni pod jednim od ova dva
operativna sistemaimena datotema ne smiju sadrZavati neki od znakova "\","I", •: ", "*", "?", "<", ">",
"1", kao ni znak navoda. Tak<Xter, veomaje neprepomcljivo koriStenje znakova izvan engleskog alfabeta
u imenima-datot eke (npr. namh slov'a), jer takva datoteka moZe postati neCitljiva na raeunam na kojem
f
nije instalirana podrSka za odgovarajuei sknp slova. Sliene konvencije vrijede i pod UNIX odnosno
Linux operativnim sistemima, samo je na njima sknp zabranjenih znakova ne§to Siri. Najbolje se ddati
l[
. kratkih imena sastavljenih samo od slova engleskog alfabeta i eventualno cifara. Takva imena su legalna
praktieno pod svakim operativnim sistemom.

Imena datoteka tipieno sadrZe taCku, iza koje slijedi nastavak (ekstenzija) koja se obieno sastoji od
~
----tri-slova.-Korisnik-moZe-zadatLekstenijU-kalrnLgodZelL{pod_nyjetom_da_SC..BJ~StpjLQ!l Jegalnih znakova1
medutim ve6i.na operativnih sistema koristi ekstenziju da utvrdi Sta predstavlja sadrZaj datoteke, i koji
program treba antomatski pokrenuti da bi se prikazao sadrZI9 datoteke Ukoliko joj probamo neposredno
lt
pristuPiti izvan programa, npr. duplim klikom :mik na njenu ikonu pod Wmdows operativnim sistemima
( ovo je tzv. asocijativno pridruitvanje bazirano na ekstenziji). U grafiCkim operativnim sistemima, ikona
pridruZena datoteci tak<Xter moZe zavisiti od njene ekstenzije. Stoga je najbolje datotekama koje sadrf.e
tekstualne podatke davati ekstenzije ".TXT", Cime oznaeavamo da se radi o tekstualnim dokwnentima.
1
Wmdows operativni .sistemi ovakvim datotekiuna automatski dodjeljuju ikonu tekstualnog dokwnenta, a
pri!cazuju ih pozivom programa NotePad. Ukoliko bismo kreiranoj datoteci da1i na primjer ekstenziju
".BMP", Wmdows bi pomislio da se radio slikovnom dokwnentu, dodijelio bi joj ikonu slikovnog
1
.dokwnenta, i po~ bi da je otvori poQloCu programa Paint, §to sigurno ne bi dovelo do smislenog
~ja. Moguee je. ekstenziju izostaviti u potpunosti. U tom. slueaju, Wmdows dodjeljuje datoteci
ikonu koja oznaeava dokwnent nepoznatog sadrZaja (ista stvar se de!ava Ukoliko se datoteci dodijeli
w
ekstenzija koju operativni sistem nema registriranu u popisu poznatih ekstenzija). Po~ pristupa
takvoj datoteci izvan programa pod Wmdows operativnim ~stemima dovodi do prikaza dijaloga u kojem
·~
nas operativni Sistem pita koji program treba kOristiti za prlstup sadrZaju datoteke.

! Jme datoteke mou ·saddavati i lokaciju (tj. specifikaciju uredaja i foldera) gdje ulimo da kreiramo
datotekli Ova lokacija se zadaje u Sk18dU sa konvencijama kQiiki'etnog operativnog sistema pod kojim se
~
~
program i.zvriava. Wmdows serija operativnih sistema naslijedila je ove konvencije iz MS DOS
operativnog sistema. Tako, ukoliko ulimo da kreiramo datoteku "BROJEVI • TXT" u folderu "RADNI" na
flopi disku, pod MS DOS iii Wmdows operati-vnim sistemima to moZemo uraditi ovako:

ofstream Izlaz("A:\\RA DNI\\BROJE VI.TXT");

Po4sjetimo se da po ovoj konvenciji "A:" oznaeava flopi disk, dok znak "\ • razdvaja imena foldera u
~
putanji do Zeljene datoteke. Znak "\" je uduplan zbog toga sto u jeziku C++ znak "\" koji se pojavi
izmedu znakova navoda oznaeava da iza njega moZe slijediti znak koji oznaeava neku specijalnu akciju
(poput oznake "\n" za novi red1 tako da ukoliko Zelimo da izmedu navodnika imamo bukvalno zoak
~
"\ ", moramo ga pisati udvojeno. Na ow Cinjenicu se l!esto zaboravljakad a se u specifikaciji imena
datoteke treba da pojave putanje. Usput, iz· ovog primjera je jasno zbog ~ga sama imena datoteka ne
Nima
smiju sadrZavati.znakove poput ·: • iii ., '" je ooto dodijeljena specija!na woga.
~
~
2
tU
fl
u
0 ~·~ Kako je formalni parametar konstruktora klase of strea
m stringovnog tipa, mollemo kao stvami
parametar navesti bilo koji niz znakova, a ne samo
0
... ~
konstrukcijaje sasvim legalna, i prikazuje kako raditi sa
stringovnu konstantu. Na primjer, sljedeea
datotekom Cije ime nije unaprijed pom ato:
char Ime[ lOO] ;
0
..
cout << "Un esite ime dato teke koju zeli te
cin. getl ine( Ime , 99);
ofst ream Izla z(Im e);
krei rati :";

0
.
'
'
'
Mo7.e se desiti da upisivanje podataka u datoteku zbog .
popum). U tom slueaju, izlazni to· dospjeva u ne1spravno
nekog r;IZio a ne u i 'e (npr. ukoliko se disk
stanje, .i operator •! • primijenjeu na njega daje
)
'
kao rezultat jedinicu. Mo7.e se desiti da ni samo kreir (
0
....
popunjen do kraja na samom poCetku, disk za8ticeu
anje datoteke ne uspije (moguCi r;IZiozi su disk
od upisa, neispravno ime datoteke, nepostojeea
lokacija, itd.). U tom slueaju izlazni tok je u neispravno
m stanju odmah po kreiranju. Sljedeei primjer
·
( f
pokazuje kako mozemo preuzeti kontrolu nad svim •
0
,
izlaznog toka vezanog sa d!!lntekom·
nepredvidenim situacijama prilikom krejran,ja -'

"· ofst ream Izlaz ("BR OJEV I.TX T");

u
.
i
if (! Izla z)
cout << "Kre iran je dato teke nije uspj elo!
else { \n";
/
i

'
'
for{ int i = 1; i <= 100; i++) { '
0
J
Izla z << i << ",n << i * i << endl ;
if (! Izla z) {
r, cout << "Nes to nije u redu sa upiso m u dato
teku !\n" ;
iJ )
brea k;
)

p
}

1..-_.

u
I ;
~-·

u·-·
u
...
od mjesta na kojem se
prethodnim programom mollemo i§atati i ispisati na ekran

#inc lude <ios tream >


"BROJEVI. TXT" koju smo
pomoeu sljedeeeg programa: kn:~irali

u #inc lude <fst ream >


usin g nam espa oe std;
int main () {
u ifstr eam Ulaz {"BROJEVI. TXT")';
if( !Ula z)
cout << "Otv aran je dato teke nije uspj elo!
\n";
0
··•
else {
int Broj 1, Broj 2; ·
char Znak;
for( int i = 1; i <= 100; i++) {
a Ulaz >> Broj 1 >> Znak >> Broj 2;
cout << Broj 1 << " " << Broj 2 << end! ;
.
J )

] 3
.
1
l
{
U <ivom programu smo namjemo prilikom ispisa na ekranu brojeve razdvajali razmakom, bez obzira §to .
su u datoteci razdvojeni zarezom. Svrhaje da se.pokaZe kako se vrSi citanje podataka iz· datoteke, dok sa -
.proCitanim podacima program moze raditi Sta god Zeli. {
Nedostatak prethoduog programa je u tome ~o se i§Citavanje podataka vr8i for petljom, pri ~u (·.
unaprijed moramo znati koliko podataka_ sadiZi datoteka U praksi se obieno javlja potreba za Citanjem. , {
datoteka za ko ·e ne mo koliko elemen
on o se dostigne kraj datoteke. Dostizanje da testiramo na taj naCin Sto poknSaj citanja nakon Sto
je dostignut kraj datoteke dovodi ulazni tok u neispravno stanje, Sto moZenlo testirati prim.jenom
f
• . U tom Slueaju se citanje vr8i u petlji koju prekidamo \

.{
~

operatora " ! ". SljedeCi primjer radi istO kao i prethodui; ali ne pretpostavlja prethoduo pomavanje broja
elemenata u datoteci: -
int main() { {
ifstream Ulaz ( "BROJEVI. TXT") ;
if( !Ulaz)
cout << "Otvaranje datoteke nije uspjelo!\n";
else {
) -
.{
int Brojl, Broj2;
char Znak;
-
while(l) { {
Ulaz >> Brojl >> Znak >> Broj2;
i f ( !Ulaz) break; -
I
cout << Brojl << " " << Broj2 << endl;
[
}
}
[
">>"
-
[
~

int main() { '


ifstream Ulaz("BROJEVI. TXT");
if( !Ulaz)
( n
-
cout ·<< •otvaranje datoteke nije uspjelo!\n";
else {
int Brojl, Broj2;
1 [
char Znak; ~

while(Ulaz >> Broil >> ZPak >> Broj2l


cout << Brojl << • "<< Broj2.<< endl; j u
}
}
-
zbOg
Nedostatak navedenih d~ja je u tome §to ulazni tok mof.e dospjeti u neispravno stanje ne samo
knSa·a Citan·a nakon kra·a datoteke, ne o i iz · razloga, kao §tO je npr.. nailBZak na ·
u
-
nenumeriCke znakove · om Ci

-u
a ro'Canih ill nailazak na fiziCki oSteeeoi dio diSkiL
/ ·~ Stoga su uv ene metode o , ap. 1 fail parantetara), pomoeu kojih moZemo samati riizloge
i dolaska toka u neispravno stanje. et ~vraea jedinicu ukoliko je tok dospio u neispravno stanje
zbog poknSaja citanja nakon kraja datoteke (u suprotnom vra6a nulu). Metoda~ vraea jedinicu
I. ukoliko je razlog dospiievanja toka u neispravno stanje neko fizicko oSteCenje, ill zabnuUena o.peracija ~
i nad tokom. Metoda fail vraeajedinicu u istim sluCajevima kao i metoda bad, ali ukljueuje i slueajeve
J. kada je do dospijevanja toka u neispravno stanje do!lo usljed nailaska na neoeekivane podatke prilikom
-
( . CitaJija (npr. na nenumericke znakove prilikom Citanja broja). Na ovaj naCin moZeo:to samati da li je do
··- prekida Citanja do~o prosto usljed dostizanja kraja datoteke, ill je u pitanju neka druga greSka. Ovo
u
-
demonstrira sljedeCi program u kojem se vrm Citanje datoteke sve do dostizanja njenog kraja, ill nailaska
na neki problem. Po zavr5etku citanja ispisuje se razlog zbog eega je Citanje prekinuto:
u
-
4 u
Tl
int main () { ·
ifstr eam Ulaz t"BR OJE VI.T XT" );
if( !Ula z) .
cou t << "Otv aran je dato teke nije usp
\ else ( jelo ! \n";

) int Bro jl, Broj 2;


char Znak ;
whi le(U laz >> Bro jl >> Znak >> Broj 2)
coW: << Broj 1 << " " << Bro j2 << end
l;
} '
if(U laz. eof( )) cout << "Nema vise pod
atak al\n ";
else ·if(U laz.b ?Od ()) cou t << "Da tote ka
else cout << "Da tote ka sad rzi neoc ekiv je vjer ova tno oste cen a!\n •;
}
ane pod atke !\n" ;

Veoma je VliZno je napomenuti da se wi oodp


p~ u tekstualnim datotekama Cnwiju iskij
slijed znakova, bez obzira na stvamu vrstu upisa ueivo kao
nih poda taka Tako se, prilikom upis a u tekst
datoteke, u njih upisuje taeno onaj niz znakova ualne
koji bi se poja vio na ekranu prili kom ispisa
poda taka Slieno, prilikom Citanja poda taka iz tekst istih
ualne datoteke, r~ ee se po~ti isto kao
niz znakova od kojih se datoteka sastoji unesen da je
pute m tastatw:e. Stog a je mogo6e, uz iz\:jesnu
opreza, u tekstualnu datoteku upisati poda tak jedn dozu
og tipa (npr. cijeli broj), a zatim ga iscitati iz
datoteke kao podatak drugog tipa (upr. kao niz iste
znakovnih promjenljivih). Drugim rijeCima, tekst
, datot eke nemaju precizno utvrdenu s ualn e
vee 'e n'iho va struktur kao j naCin int creta
e tekstualnih datoteka, iskljuCivo pod kontrolom ci'e vee
' omogucava veliku fleksibiluost pri radu sa tekst programa koji ih ·oblllduje. Ova Cinjenica
ualnim datotekama, ali pcredstavlja i eest uzro k
pogotovo ukoliko se :qjihov sadiZaj ne interpcretir greSaka,
a na pravi naCin prilikom Citanja Na primjer, uk:ol
tekstualnu datoteku upik mo zaredom prvo broj iko u
2, a zatim broj 5, u istom credu i bez ikak vog razm
izmedu Iliih, prilikom Citallia ee isti podaci biti inter aka
pietirani kao jeda n broj - broj 251

ofst ream Izla z ( "PRVA. TXT ");

Izla z.cl ose ();


Izlaz .ope n("D RUG A.TX T");

Tok se mo.ze nakon zatvaranja pono vo povezati


sa datotekom na koju je prethodno bio povezan.
Medutim, treba mipomenuti da svako otvaranje
ulaznog toka: posta vlja kurzor za citan je na poce
datoteke, tako da nakon svakog otvaranja Citanje tak
datoteke kreee od njenog poCetka (uk:oliko sami
pomjerimo kurz or pozivom metode seek g, o ne
_naeina kako zapoCeti Citanje datoteke ispoCetka
eemu ee
kasnije biti govora). Ovo je ujed no jedan od
.///
Klase ifst ream i ofst ream takoder posjeduju
konstruktore bez parametara, koje kcreiraju ulazn i .,.
i odnosno izlazni tok koji nije veza n niti na
konkretnu datoteku, tako da je deklaracija popu t jedn u

ifst ream Ulaz ;

.·: -~··

5
' il
) sasvim legalna. Ovako definiran tok mou se.koristiti smno nakon ~ se eksplicitno otvori (i pove:le sa
jf
.
1
konkretnom dat_?tekom) pozivo~ m~e open. Takoder, treba napomt:?uti da kl~e ifst~eam i
ofstream sadiZe destruktor ko oztva metodu close tako da se tokoVI autOJnatski zatvaraJU kada
· ovarajuCi objekat OJl predstavlja tok prestane postojati (drugiln rijeCinla, nije potrebno eksplicitno l[
u
vrliti zatvaranje toka:, kao nekim drugirn progrmnskim jezicirmi).

ve6 smo vidjeli da prilikom kreiranja objekta izlaznog toka datoteka sa kojom se vezuje izlazni tok
· ne mora od ranije postojati, vee da ce odgovarajuca datoteka automatski biti kreirana Medutim, ukoliko
datoteka sa tiavedenim imenom vet5 postoji, ona ee biti uniStena, a umjesto nje ee biti kreirana nova
i
prama datoteka sa istim imenom. Isto vrijedi i za otvaranje izlamog toka pozivom nietode open.
Ovakvo pona5anje je eesto pouljno, medutim u nekim situacijama to nije ono Sto ulimo. Nairne, resto
~ se javlja potreba da dopisemo neSto ila kraj vee postojeee datoteke. Za tu svmu; konstruktori klasa
t:rl
i
Yl.
. i fstream i of stream. kao i metoda open posjeduju i drugi parametar, koji daJe drn!!!lne !ijleCi1ikacije
kako treba rukovati sa datotekom. U slueaju da ulimo da podatke upisujemo u vee postojel:u datoteku, i
tadil k80 drugi parametar konstruktom odnosno •metodi open trebamo proslijediti vrijednost koja se
dobija kao binanui disjunkcija konstanti ios: :out i ios: : app, definiranih unutar klase ios (binama
disjunkcija dobija se primjenom operatora " I"). Konstanta ios: :out oznaeava da ulimo upis, a
konstanta ios: : app da ulimo nadovezivanje na vee postojeeu datoteku (od engl. append). Tako.
i
ukoliko ulimo da profuimo postojeeu datoteku "BROJEVI. TXT" brojem 101 i njegovim kvadratom,
!
izviSieemo naredbe

of stream Izlaz ( "BROJEVI. TXT", ios: :out I ios:: app) ;


Izlaz << 101 << •,• << 101 * 101 << endl;
J i
ee biti kreirana nova
I u ovOJll slueaju, ukoliko datoteka "BROJEVI. TXT" ne postoj~ prosto

Interesantan je i sljedeCi primjer, koji poziva metodu get da ispiSe .sadrZaj proizvoljne tekstualne
datoteke na ekran, znak po znak:
J
#include <iostream>
#include <fstream>
1
using riamespace std;
in t main () {
··char Ime [100], Z11ak; .
1
cout << •unesi ime datoteke koju zelite prikazati: •;
cin >> Ime;
ifstream Ulaz(Ime);
~
~
while { (Z11ak = ·ulaz. get() I != EOF)
cout << Z11ak;
)

' i
r Iz ovog primjera moZerilo naumti jo§ jednu interesantnu osobinu: poziv metode get vraea kao rezultat
konstanty._~_QF_ @j!l j~t.vrijednost..::::l). u slueaju da ulazni tok dospije u neispravno stanje (npr. zbog
poku.§aja mtanja iza kraja datoteke). Ovu osobinu smo iskoristili da skratimo program.
~
· · ·Bitno je naglasiti da se i smn izvorni progrmn pisan u jeziku C++ takoder na disku ~va kao obii!na
tekstualna datoteka Tako, na primjer, moZemo prethodni progrmn snimiti na disk pod imenom
~
"PRIKAZ. CPP", a zatim ga pokrenuti i kao ime datoteke koju ulimo prikazati unijeti njegovo vlastito
ime
. "PRIKAZ. .CPP". Kao posljedicu, progrmn . Ce na ekran izlistati sarilog sebe. ~
Pored I?asa if stream~ o~stream, postoji iklasa fstream, ~oja _dj~uje kao ko~~~j~ kl~ /
(, ifstream 1 of stream. ObJekti klase fstream mogu se po potrebl lcqnstiti kao nlam• ill kao izlazm ,
) tokovi. Zbog toga. konstruktor klase fstream, kao ·i ..metoda. open, obavezno zahtijevaju drugi •
~
~
j. parametar kojim se ~ da 1i tok otvaramo kao ulazni tok ill izlazni tok (ow specifikaciju

6 ID
J.
I
<. navo dim o tako Sto kao parametar zadajemo vrijednos
t kons tante. ios : :in odnosno ios : :out ). Tako
( moZelno istu prll!D.jenljivu zavisno od potre
be koristiti kao ulazni iii kao izlazni tok Na prim
prog ram t:mZi od korisnika da uno si sa tasta jer, sljedeCi
ture slijed brojeva, koji se zatim upisuju
"RA ZLI CIT I. TXT", ali 5amo ukoliko unes u datoteku
eni broj vee ranije nije unijet u datoteku (tako
dato teka sadrZavati samo razlicite brojeve): da ee na kraju

#inc lude <ios trea m>


#inc lude <fst ream >

{,),Q_
.,{~
~
i)..'~
.
~ l
usin g nam espa ce std ;
int mai n() (
fstr eam Dat otek a ( "RAZLICITI, TXT",
i.f( !Da tote ka) (
Dat otek a.cl ear( );
ips: :in) ;

Dat otek a ("RAZLICITI. TXT", ios: :ou t);


' t.''-i'""'~ )
~ ~Datoteka.close();
whi le (1) { .
i.nt Bro j, Tek uci;
cou t << "Un esit e bro j ·co za izla z):
cin >> Bro j; ";
i.f(B roj == 0) bre ak;
Dato teka .ope n("R AZL ICIT I.TX T", ios
whi .le(D atot eka >> Tek uci) ::in );
if{T eku ci == Bro j) brea k;
i.f (Da tote ka. eof () ) .( .
Dat ote ka.c lear (); -- ""'"" " '¥ _~
1 1, A-'/!v·j·
·r · ,0, £,
tW<A4C..'Wl& I l - J fkx..(v, A'UI\ql!U''lfll
'~ 'YJC.Lj
Dat otek a.op en ("RAZLICITI.TXT", ios
Dat otek a << Bro j << end l; : :ou I ios : :app ); -./
)
)
)

U ovom primjeru, tok se prvo otva ra za citan


je. U sluel\iu da odgovarajuea datoteka ne post
dospijeva u neispravno stanje. U tom slueaju, oji, tok
Q ~ dovOdi ao .!!_akon oooravljanja toka, t6.k se zatv arai otva
.kreiranja nove prazne datoteke. Na kl'ilju
. glavnu · petlju. Unutar glavne petlJe, nakon se ra za pjsan,is.
u svakom slueaju iOk zatv ara prije u1aska u

u
§to se od korisnika unese broj, tok se Otva
datoteka ·se iSCitava da se utvrdi da li ona ra za Citanje, i
vee sadd i traZeni broj. Ukoliko se ttaZeni
traganje se prekida, a novouneseni broj se ne broj pl'Oil3lfe,
upisuje. U sluCI\iu da traZeni broj nije na4e
....
' traganja ee biti dostignut Iaaj datoteke, i tok ee
do6i u neispravno stanje. U tom shWaju, tok
n, prilikom
se oporavlja
u
\
~·-'"'
'.
pozi vom metode clea r, datoteka se otvara za
datoteku ne treba briSIIti, vee da u is !reb
dato
upisivanje (podsjetimo se da ozna,ka ios : : app
a izvd iti na n ·en
Primijetimo da se tok svaki put unutar petlje
svakom prolazu kioz petlju citanje datoieke vdit
govori da
, a novouneseni broj se upisuje u
iznova otva ra i zatvara, Sto osigurava da ee
se u
i od njenog poCetka:
·D
1,.,
, Ono Sto Cini objekte klase fstr eam posebno
interesantnim je mogu6nost da se om mog u
koristiti
istovremeno i kao ulazni i izlazni tokovi.

n
~.<:t.
disjunkciju konstanti
Za tu svrhu kao drugi parametar treba zada
.ios : :ou t i ios : :out . Ova mogucnost se
datotekama, pa Cem.o o njoj govoriti kada bude
ti binamu
njetlro korl$ti pri radu sa tekstualnim
mo govorili o binarnim datotekama
·

u Nem a nikakvog razloga da u istom programu


tokova vezanih na datoteke. Pri tome je ·obie
sasvim je legalno imati i vi8e tokova vezanih na

ne moZenlo imati viSe objekata ulaznih ill
no viSe razliCitih tokova vezano za razliCite
·dato
izJaznih
teke , ali

n
~-·
istu datoteku. Vi8e ulaznih odnosno izlaz nih
obieno koristi u slueajevima kada program tokova se
treba da istovremeno obraduje viSe dato teka
pretpostavimo d3 imamo program koji treba da Na primjer,
... datoieke-"sTUDENTI.TXT", koja cuva poda
obraduje podatke 0 studentima, koji supo hran
tke o studentima, i "ocJENE.rx-r:~ koja cuva
jeni u dvije

u
~ ...
ostvarenini"rezu!tatima Datoteka "STUDENT!.
TXT" organizirana je tak!> da za svakog studenta
i>odatke o
prvi red

~ 7
t
sadrZi njegovo im e i pr~e
tako da se za sv po oZ
zatim ocjena ko ju je stUde
, a dru · red Jtiegov br oj ind
eni isp it u jed no m red u ek sa Da tot ek a "OCJEN
nalazi prvo broj indeksa
E ~TXT" organizirana je
stlidenta koji je poloZio
l
nt ostvario na ispitti. Na ispit, a
tii.ogle bi izgledati ovak primjer, datoteke "sTUD
o: ·
EN T I. TXT" i "O CJEN E. TXT" [
STUDENT!. TXT:
Pe ro Pe ri c
12 34
Huso Hu sic
l
41 32
Marko M ar ko vi c [
31 42
Meho M eh ic
23 41 [
OCJENE.TXT:
12 34
41 32
12 34
7
B
I
6
23 41 9
12 34 10
41 32 9

Slijedi pt ik az programa
koji ee za svakog stlide
ocjene u datoteci "OCJEN nta iz datoteke "STUDEN
E. TXT", izraCuDati Jtiegov T I. TXT" prona6i njego
ekranil {odnosno komerit prosjek, i ispisati njego ve
ar "NEECUENJEN" uk vo im e i izraCunati pro~
oliko stl ide ntn em a ni tij ek na
ed nu ocjenu):
#i nc lu de <i os tre am
#i nc lu de <i om an ip >>
#i nc lu de <f str ea m >
us in g na m es pa ce st d;
in t·· m ai n () {
if st re am St ud en ti( "S .
TU DE NT I.T XT ") ;
w hi le 111 1 ·~
oh ar Im e[ 10 0] ;
in t In de ks , Te ku ci
do Ub le ·sumaOcjen in de ks , Te ku ca Oc je na , Br oj Oc je na
a = ~ 0;
st ud en ti. ge tli ne (I m 0;
if ( !S tu de nt ,i) . .b re ak e, 99 );
St ud en t! >> In de ks ;·
::- stu de n1 ;i. ig no re .(l OO;
if st re am Ocjene(".O O, '\ n' ); ·
w hi le (O cj en e >> TeCJENE,TXT");
ku
if (T ek uc iin de ks = ci in de ks . >> Te ku ca Oc je na )
In
su m ao cj en a += Te ku de ks ) {
Br oj Oc je na ++ ; ca Oc je na ;
}
co ut << Ime << " ";
if( Su m aO cj en a == 01
el se co ut << se tp re co ut << "NEOCIJENJEN\n";
) ci si on (2) << SumaOc
jena F Br oj oc j.e na <<
I en dl ;

U ov om programu se
za svakog pr oa tan og
kr oz atavu datoteku stlidenta iz datoteke "ST
"ocJENE. TXT" se svaki
"OCJENE. TXT" sa cil jem
:da se pr on ad u
UDENT! • TXT"
sv e njegove oc je ne
vm
pr ola za k
pu t izn ov a otvara pri sv (datoteka
ak om prolasku kr oz vanjs
ku petlju). Ob rat im o pa
m ju na

8
poziv metode ignore nad ulaznim tokom
Studenti. Ovo jli, kao Sto vee znamo, potr
iz bilo "kakvog ulaznog toka nakon citanja ebndraditi kada god
brojcanih podataka pomoeu operatora "»"
tekstualne podatke poZivom metode getl Zelimo Citati
ine.
spremniku moZe dovesti do pogreSile interpre U suprotnom, oma ka za kraj reda koja je ostala u
tacije, kao i pri unosu sa tastature.
Datoteke koje smo do sada razmatrali bile
podaci u n"ima ili su iskljucivo tekstualne datote/f:e Sto znac
em tskl'ucivo o ruz i da su svi
CIT sifri (stoga se tekstualne datoteke eest ov ko'i su intemo redstavljenf moe
o nazivaju i ASCII datoteke). Na primjer, u svo'ih
tekstualnoj datoteci cuva se kao slijed znak broj 35124318 u
ova '3', '5', 'I', '2', '4', '3', 'I' i '8', odnosno
51, 53, 49, 50, 52, 51, 49 i 56 uzmemo , kao slijed brojeva
li u obzir njihove ASCli Sifre. Medutim
raeunara nisu ovako interno zapisani. , podaci u memoriji
Na primjer, ukoliko se isti broj 351243
cjelobrojnoj promjenljivoj, ona ee (uz pret 18 nalazi u nekoj
postavku da cjelobrojne promjenljive zau
predstavljenakao odgovarajuCi binami broj zimaju 32 bita) biti
, t;j. broj OOOOOOIOOOOIOlllllllOIOOOIO
li ovaj binarni broj u 4 bajta, dobijamo bina llllO. RazloZimo
rne brojeve 00000010, OOOIOlll, llllO IOO
nakon pretvaranja u dekadni brojui siste i OIOIIIIO, sto
m daje 2, 23, 244 i 94, llto se oCigledno
zapisa u obliku ASCII Sifri pojedinih cifa osjetno rilzlikuje od
ra -
Pored t ote ·ezik C++
odr3zava naCin na koji su podaci zapisaui drZava i tzv. bin ame datote Ciji sadrZaj u potpunosti 1.1
u memorij1 ra ara. U ovakvim dato
"Zapisaui kao slijed znakova sa ASCII siframa, ama, rusu (
stoga se njihov s3dmy ne moZe kreirati
pomoeu tekstualnih editor.i kao Sto je Not niti pregledati )
epad (preciznije, pokullaj njihovog uCit
editor prikazaCe potpuno besmislen sadrZaj, avanja u tekstualni .
s obzirom daCe editor pokuSati da inte rpr¢
kao ASCII sifre, Sto ne odgovara stvarnos ra njihov sadrZaj
ti). Na fundamentalnom fizickom iuvou
binaririh datoteka nema nikakve razlike iZm.edu tekstualuih i
- datoteka je samo hrpa povezanih bajt
memoriji. ,Stoga je jedina razlika izmedu ova na eksternoj
tekstualuih i binamih razlika u interpretaci
korisnik datoteke (programer) mora biti svje ji. Drugim rijeeima, j_l
stan Sta njen sadrZaj predstavlja, i da se pon
tim (g. dan e pokullava interpretirati sadr alla u sldadu sa (
Zaj biname datoteke kao slijed znakova i
obmuto). j
Binarne datoteke imaju izljesne .Predno
sti u odnosu na tekstualne datoteke. Kak
odraZavajn Sfan je racunarSke memOnJe, raCU o one direktoo
Dar WOZe efi)!;asnije Citati njihov sadJZaj
jer nema potrebe za konverzijom podatak i vrSiti upis U njib,
a iz zapisa u vidu ASCli Sifara u intemu _bin
i obmuto. Takoder, zapis u binarnim dato arnu reprezentaciju
tekama je nerijetko kraei u odnosu na
datotekama (k:ao u prethodnom primjeru zapis u binarnim
zapisa
4 bajta u binarnoj datoteci), ali ne uvijek. Tak broja 35124318, koji zahtijeva 8 bajtova u tekstualnoj, a
su zna!no kraCi i efikasniji nego program oder, programi koji barataju sa binarnim datotekama Cesto
i koji manipulirajn sa tekstnalnim dato
ponekad nellto teZi za shvatiti, s obzirom teka
da se barata sa internom reprezentacijom pod ma (mada su
koja ljudima nije toliko bliska kOiiko ataka u memoriji,
odgovllflliuCi tekstualrii zapis). Kao man
mot emo nmrestj nemoggenost njibovog u binarnih datoteka
kreiranja i preg!edanja njihovog saddaja
editora. Naime, dok tekstualnu datoteku koju Zeliino obrrutivati u nekom progmmn Jako
putem tek...tiiii1irili
nekim tekstuainlm editorom, za kreiranj mo7.emo kreirati
e biname datoteke nam je ootreban vlas
nedostltlik biniilllill datoteka moZe nek titi program. Ovaj
ad da post
datot z 'cen od radoznalaca koji bi Zel'eli da ane i prednost, s obzirom da je sadrZaj binamih j 17. /L
eda'u ili even no izini'ene ·
Na U\j naCin, podaci po ueru u binarnim datotekama su u nekomtual smislu "sigumiji" od podataka
, JUI<r ~
pobranjenih u tekstualnim datotekama.

9
)
l
JJ
Rad sa binamim datotekama Ce!;no prvo ilustrlr!W najednom jednostavnom primjeru. Sljedeei
program traZi od korisnika da uD.ese 10 cijelih brojeva sa tastature, koji se prvo smj~ju u niz,a zatim se
]
·.. <Sitav S3drZIY niza."istresa" u binamu datoteku nazvanu "BROJEVI. DAT":

#include <fstream>
lf
#include <iostream>
\ .using namespace std;
int main () {
D
'L ~
/ int Niz[10];
for (int i = 0; i < 10; i++) cin » Niz [i];
· of stream Izlaz ( "BROJEVI. DAT", ios: :out I ios:: binary) ;
. Izlaz.write ((char*)Niz , sizeof(Niz) );
}

progrnma
.
u tekuCem direktoriju biee · kreirana
.
datoteka
.
"BROJEVI.
..
DAT".
l[
Nakon pokretanja ovog
tJkoliko bismo ovu datoteku uCitali u neki tekstualni editor, dobili bismo besmislen saddaj, iz IaZloga'
koje smo vee spomenuli. Stoga, binamim datotekama nije dobro davati nastavke poput ".TXT" itd, jer
njihov sadrZig nije u tekstualnoj fupni. i ekstenzija ".TXT" mogla hi zbuniti korisnika (a moZda i
t
) ~
operativni sistem). Ukoliko kasnije zelimo da proCitamo sadrZig ovakve datoteke, moramo za tu svrbu
nilpraviti program koji ee koristiti metodu read. Na primjer, sljedeCi program ee uCii:ati sadrZIY kreirane
biname datoteke "BROJEVI. DAT" U niz, a zatim ispisati saddaj uCitaitog niza na ekran (radi
jednostavnosti, izostavieemo provjeru da li _datoteka zaista postoji): · · ··

#include <fstream>
#include <iostream>
~
using namespace std;
int main() { ~
int Niz[10];
i fstream Ulaz ( "BROJEVI • DAT", ios: : in · ios: :binary) ;
Ulaz.read(( char*)Niz, sizeof(Niz) );
for (int i = 0; i < 10; i++)· cout << Niz [i] << endl;
~
} "<
_U oba sl~a, kao prvi parametar inetoda write i read iskoril!tenoje ime niza Niz. Poznato je da ~
se .ime niza: upotrijebljeno' samo za sebe automatski konvertira u pokazival! na prvi element niza (g. u
&Niz [ o 1), leon se operatorom kpnyemje (char* l konvertira u pokazival! na zuakove Cisto da bi se
zadovoljila forma metoda write odnosno read. Dalje, treba primijetiti da smo u oba ~a prilikom ~
~otvaranja biname datoteke k30 drugi parametar konstruktoru naveli i opciju ios: :binary, oja govori
se
da se radi o binamoj datoteci. Mole postaviti pitaqje zbog <Sega je ova opcija neop . . . Ukoliko na
fizi&:om nivou ne postoji nikakva mzlika iZmedu telcstualnih i binamih datoteka. Razlog je u sljex!ef.em·
pri radu sa t~ datotekama, program ima pravo da izmijerii broj~ reprezentaciju izvjesnih
~
znakova da omogu6i. njihov ispravan trebnan na operativnom sistemu na kojem se program izvdava (to
se naj~ dc:Sava sa makom za prelaz u novi red • \n • koji se na nekim operativim sistemima
predstavlja kao bajt 10, na nekim kao bajt 13, ana nekim kao par bl\ita 13,10). S druge strane,_ opcjja
~
lias: : binary]prosto govori da nilgJ!rye izn:Uene bajtova ne smiju da se vrie, jer one ne predstavljaju
rure makova, vee interni zapis podataka u rOOunarskoj memoriji . -~

~
U navedenim primjerima, cijeli niz smo prosto jednom naredbom "istresli~ u binamu datoteku, a
z3tim smo ga takoder jednom iwedbom "pokupili" iz datoteke. Na taj naCin smo dobili veoma
jednostavne programe. Medutim, ovdje nastl!ie problem ~ smo pri tome morali mali da niz ima 10
, e1emenata. Nema nikakvo razlo da i elemente binarne datoteke ne atamo ··edan "edan. odliosno
tl · da ih ne upisujemo jedsn po jMan Naime, !.!Q!! binamih datoteka postoji "kurzor" koji govori e rU
~ [ SJn? sti~ sa Citanj~ odnosn'?_ pisanjem. Tako, ukoliko ~ s_vj~sni anjeni~ da su e~~enti nek~ m_za '-

~ smJdteni u memon u sekvenetJa,lno, edsn za sasvun e asno da sn 1 e1ementi mza bran em u


o~vani tako da iza pryog elementa sliiedi drugi, itd. fjedino §to elementi nisu ·U
CCI
-
10
·U
Jl
pobranjeni u vidu skupine znakova).. Ovo nam
omogueava da elemente datoteke "BROJE
mof.emo ~vati i ispisivati ·na ekranjed VI • DAT"
an po jedan, bez potrebe za uata van jem Cita
nal!in uop ee ne mor amo znati koliko je elem vog niZa. Na ng ·
enata niza zapisano u datoteku:
·
#in clu de <fs trea m>
#in clu de <io stre am>
usi ng nam esp ace std ;
int mai n() {
if stre am Ula z ( "BROJEVI.DAT", ios
wh ile( !) { : :in I ios : :bin ary ) ;
int Bro j;
Ul~z.read{(char*)&Broj,
siz eof (Br oj) );
if( !Ul az). bre ak;
cou t << Bro j << end l;
}
}

Primijetimo da je u ovo m slu&tju bilo neop


hodno korilienje adresnog operatora "&"
prom jenl jive Bro j. Naime, met oda rea d ispr ed ime na
kao prvi parametar zahtijeva adrefflph
treba uCitati. a za raz1iku od ime na nizova, je~~::::!a*
ime na obiCnih promjenljivih se ne konV;tiT8
tJk8Ziv.We. Interesantno je jos napomenuti da metode jl{Zrtqmatski u
rea d i wri te kao rezultat vraa yu referenc
ok nad ko}im su potv ane, ~o omogueava u na
da se prethodni program skra6eno napiSe
(naime, refe renc a na tok koji je u neisprav na sljed eei naCin
nom stauju pona8a se kao log ifu neistina)
:
#in clu de <fs trea m>
#in clu de <io stre am>
usi ng nam esp ace std; .
·int mai n() {
ifst rea m Ula z("B ROJ EVI .DA T", ios
int Bro j; ::in I ios ::bi nar y); .
wh ile (Ul az. rea d ( {ch ar*) &B roj, size •'.~
of( Bro j))J
cou t << Bro j << end l;
}

J Kao ~o elemente biname datoteke moZelno Citati 'edan po jedan, mo


~ po 1 Naravno, u slu&t' da treba Citav niz hran
nare dbo m (Sto je ve iti u
u8teda u pisanju u odnosu na slu~ kad
a bismo elemente niza hge li da
I

pobraniriio u tekstualnu datoteku, naroCito
ukoliko se radi o nizu Qji su elementi stru
Me&rtim, uko liko ima mo jako g razl oga kture iii klase).
Zll ~. niko nam ne brani da elemente niza
upisujemo jeda n po jeda n. Na primjer, ukol u bina mu datoteku
iko ulim o da u bina mu datoteku S!Jljestim
niza osim elem enta sa indeksom 6, to mok mo o sve, elem ente
uraditi ovako:
ofs trea m Izla z("B ROJ EVI .DA T", ios
for (in t i = 0; i < 10; i++ ) ::ou t I ios ::bi nar y);
if( i != 6) Izla z.w rite ((ch ar* )&N
iz[i }, siz eof (Ni z[i) ));
Adresui operator "&" ispred Niz [il je. tako
der potreban, jer se indeks{rani elem ent
interpretira automatski kao adresa tog elementa niza ne
. Tak oder, kao argument operatora siz eof
Niz [iJ mog li smo stavi.ti i Niz [OJ jer svi umjesto
elemeuti nekog niza imaju istu velicinu. Nara
pisati i siz eof (int ) s obzirom da znam vno, mogli smo
o da su svi elementi niza tipa int . Med
IjeSen.ja su fleksibilnija, s obzi rom da utim, pret hod na
ne zahtijevaju nikakve izmjene ukoliko
promijenimo tip elemenata niza Ni z. se odlu cim o da

Iz izloZenih prim jera nije teSko izvuCi jeda


n
ill bina mim datotekama, onaj ko Cita njihov sadropCi zakljucak. B.ez obzira da li radimo sa tek.<h111lnim
bj mora biti svjestan niihove strukture ~
ispravno interpretira njih
ov sadrZllj. Dru gim rijeeima, nije potrebno Qi mog ao da
poznavati taeno sadrZaj datoteke, ali

11
~.

l
se mora mati Sta njen sadrZaj predstavlja Bitno je shvatiti da sama datoieka predstavlja ·sarilo hrpu
bl!ifova, i nikakve iuformacije o njenoj strukturi nisu u njoj jlohranjene: 0 tome treba da: vodi I8Cuna
-
i[
iskljnmvo oDl\i ko Cita datoteku. Na primjer, sasvim je mogu6e kreirati niz studenata i istresti. atav
sadrZaj tog niza u binamu datoteku, a zatim u~itliti tu iStu binamu datotelro u niz realnih brojeva
Nikakva greSka neee biti prijavljena, ali 6e ·sadrZaj niza biti potpuno besmislen. Nairne, program 6e
~
prosto lupu binamih brojeva koji su predstavljali zapise o studentima uCitliti u niz realnih brojeva, i
interpretirati istu lupu binamih brojeva kao iapise realnih brojeval i
i
i
[
zivom metoda ~
( Metode see kg odnosno seekp mogu se koristiti i sa dva parametra, pri ~u drugi parametar moZc:
~
~
\ imati samojednu od sljede6e tri vrijedni>sti: ios: :beg, ios:: end i ios: :cur. Vrijednost..io s.!.:be?
je vrijednost koja se uk.oliko se diUgi izostavi, i o~a da poziciju kurzOra

! Zc:limo da od S druge strane, ukoliko je diUgi parametar

~
nova
treba da bude negativan prije kraja datoteke).
drugi parametar ios: :cur. tada se now poZicija kurzora·odredena prvim parametrom zadaje
) relativnq uo4ngsu na tekutu p'lfUu lauzora, koja filda: mo~ blti kllko pozitivan, tako i negativan broj.
Sljedeciveomajednostavan primjer ispisuje na ekran koliko je duga&a (u bajtima) datoteka povezana sa
nlamim tokoin Ulaz: · . ~
(
~
-) Ulaz,seekg( O, ios: :end); · .
<:,_ cout <<· "Datoteka je dugal:ka • << Ulaz.tellg( ) << • bajtova•;

Metoda seekg Dam. omogueava da, uz~ izvjestan trod, moZc:mo i!Citavati datoteke proizvoljnim
redom, a· ne samo sekvencijalno (od pOOetka ka kn\ju). Ovo je iskori§teno u sljede6em programu koji
i§Citava ranije kreiranu datoteku "BROJEVI. DAT" u obmutom pOretku, od kraja ka ~ '(radi ~
jednostavnosti, prikazanje samo glavni program):
int main() {
~fstream Ulaz("BROJE VI.DAT", ios::in I ios::binary );
!
~
Ulaz.seekg(O ,, ios: :end);
int Duzina =
Ulaz.tellg ();
- int BrojElemen ata = DUzina I sizeof (int);
cout << "Datoteka je duga " << Duzina << " bajtova, a sadrzi "
<< BrojElemen ata <<" elemenata.\ n";
cout.<< "Slijedi prikaz sadrzaja datoteke naopacke:\n ";
for(int i = BrojElemen ata - 1; i >= 0; i--) {
~
~
int Broj;
___ Ulaz.seekg (i * sizeof(int) ); ....
Ulaz.read( (char*)&Bro j, sizecif(Bro j));
cout << Broj << endl;

}
}
L~
ti
. i·~
Slilfuo, metoda seekp nam omoguCava da vriimo gpi§ na proizvoljno
mjesto u datoteci, a ne samo
na Iijen mg. Ovo 5Vojstvo iSkoriSteno je u sljedeCem prognmni koji
udvostrul!ava sadrZaj svih elemenata
binarne datoteke "BRO JEVI. TXT", bez potrebe da se prethodno svi
elementi uCitaju u niz, pomno.ze sa
dva, a zatim modificirani niz vrati nazad u datoteku. U programu
je takoder iskori§tena osobina da se
objekti klase fstre am mogu otvoriti istovremeno kao ulazni i
kao izlazni tokovi (ponovo je radi
jeduostavtiosti prikazau samo glavni prowam):
int main () {
fstre am Datot eka(" BROJ EVI.D AT", ios:: in I ios::
int Broj ; out ios:: bina ry);
while (Dato teka. read ((cha r*) &Bro j, sizeo f (Bro
j))) {
cout <<·B roj << endl;
Broj *= 2; _
f~ -';> Dato teka •. seekp (- (int) sizeo f (Broj ), ios:: cur); . I
~"¥"! -) '11~ '(J~ ~ .
Datoteka.write((ch~*)&Broj, sizeo f(Bro j));
(>-!C~,~Vf
~fo!GA ptMet- fv¥"'1
flhW\~;;.:;l'"i }
}
. ~ ~olo-;t'
. - . I!J.c4vvtcr- ~- ~~ Mu +)ll".xcl
t;;>C. ·'-

· · f.~~u
......o...,.,see
-~~
flf'llu ovom
6"'1 programu, metoc1a see •e 1·skou,.ten
-"• a da rnJen · · 1rurzor za ISanJe
. upisuje prepih preko upravo proCitauog elementa. dua koirverzija ement"'k'OJI·· se
rezultata sizeo f operatora u tip
int neophodua ·e zbo Cin"enice da je tip rezultata koji
vraCa operator sizeo f tipa nepredznaenog
cijelog broj (unsi gned tiJ>a tako dana njega operator unami operat
or negacije "-" ne djeluje ispravno
(ovo je eesta gre OJU Je teSko uoCiti). Uz malo vjeStine, mogli bismo napraviti i progr
sadrZaj datoteke na disku (npr. BubbleSort postupkom), bez njenog am koji :sortira
ucitavanja u niz. Za tu svrhu trebali
bismo se dosta "igrati" sa metodama seekg i seekp da ostvarimo
Citauje odnosno upis u datoteku u
proizvoljnom poretlaL Citaocu se savjetuje da proba ovakav progra
m sastaviti Za vje!bu. Ipak, treba
voditi raCuna da je pristup elementima datoteke znatno sporiji nego
pristup elementiuia u memoriji, tako
da "nesekvencijalni" pristup elementima datoteke treba izbjegavati k;tda
god je to mogu6e.
Bitno je naglasiti da u slueaju kada vrfrmo upis u datoteku a kurzo
ko ·e isujeino uvi ·ek se re i:su ·u r r nije na njenow !sraju, podaci
sto ·eCih · odnosno ne Vl'SI se niihavo wnetanje na
m"esto kurzora . StO smo vtdjeli iz preth og priinJera). Ovo se mo.ze destiti bilo ako
kurzor primjenom metode seekp , bilo ukoliko koristimo tok otvore smo ponyerali
n i za Citauje i za pisanje pa se usljed
ranije izvr~.og Citanja kurzor nalazi negdje usred datoteke.
~
. se ~ 2QIIef11u.negdje u sredinu datoteke.. ·
dllto~ neki niz, umetnuti ono Ito Zelimo na odgovaraju~ mjesto u nizu, a zatim tako se
ponovo "istresti" u datoteku. Naravno, ovo Ije§enje je prihvatljivo izmijenjen niz
samo ukoliko datoteka nije prevelika,
tako da se njen sadiiaj mo.ze smjestiti u niz. U suprotnom, P9trebno
je koristiti komplikovanija Ije~ja,
koja ukljueuju kreiranje pomoCnih datoteka (na primjer, prepisati
sve podaike iz izvome datoteke od
poCetka do mjesta umetauja u pomoenu datoteku, Zatim u pomoCnu
datoteku dopisati ono Ito Zlllimo da
dodamo, nakon toga prepisati ostatak izvorne datoteke u pomoCnu,
i konalfuo, prepisati Citav11 pomoenu
datoteku preko izvome datoteke). Isto tako, nema jednostavnog naCina
da se iz datoteke izbriSe neki
element MoguCa Ije§enja takoder ukljumlju ucitavanje Citave datote
ke u niz, ill koriStenje pomoene -.
datoteke. U svakom sluagu, pomoenu datoteku na .kraju treba izbrisa
ti. Za brisanje datoteke mo.ze se
koristiti funkcija remo ve iz biblioteke cstdi o, koja kao piUllll).etar
zahtijeva ime datoteke koju .zelimo
izbrisati. Brisanje je moguee samo ukoliko na datoteku nije vezan
nijedan tole (eventnalne tokove koji
su bill vezani na datoteku koju .zelimo izbrisati prethodno treba zatvor
iti pozivommetode close ).
Binarne daioteke su naroCito pogodne za smjeStanje sadrZaja slogov
obzirom da je cijeli sadrZaj sloga ill instance klase moguee odjedn a ill instanci klasa u datoteke, s )
om upisati u datoteku ill proCitati iz
datoteke (u slueaju tekstualnih datoteka, svaku komponentu sloga
ill klase potrebno je upisati odnosno
Citati posebno). Ovo ·e ilustrirano u sljedeeem programu, koji kreira
binamu datoteku "STUDENT! .DAT"
koja ee saddavati datke o studen o unose sa e:

13
rr·
11
:iinclude <fstream>
· llinclude <iostream>· ~
li
usi:ng namespace std;
struct Student {
char Ime[20], Prezime[20];
int Indeks, BrojOcjena;

I;
int Ocjene[JO];

int main() {
r1
int BrojStudenata;
cout << "Koliko ima studenata? ";
cin >> BrojStudenata;
~
ofstream Studenti{"STUDENTI.DAT", ios::out I ios::binary);
for(int i = 1; i <= BrojStudenata; i++) {
cin.ignore(1000, '\n');
Student NekiStudent;
r1
~
cout << "Unesite podatke za • << i << • studenta:\n";
cout << "Ime: ";
cin.getline(NekiStudent.Ime, 19);
cout << "Prezime: ";
cin.getline(Nekistudent.Prezime, 19);
cout << "Broj indeksa: •;
cin >> NekiStudent.Indeks;
!
~
cout << "Broj ocjena: •;
cin >> NekiStudent.BrojOcjena;
for(int j = 1; j <= NekiStudent.BrojOcjena; j++) {
cout << •ocjena iz • << j << "· predmeta: •;

~
cin >> NekiStudent.Ocjene[j];
I
} Studenti.write((char*)&NekiStudent, sizeof(Student));--d~4 ~~

} . -~~~
Kako se ~ binamih datoteka ne mo:te pregledati tekstl!alnjm editorima za Citanje ovako
~
. ~e aatOteke oder treba napisati. progrnm. SljedeCi program Cita podatke o studentima iz kreirane
d8t01ilke, i Z4 svakog studen1i tsp!SUJC rme, prezime, broj indeksa i prosjek (prosjek se·raama na osnovu
podataka o ocjcnama); dodu§e u ne bu najljepkm fonnatu: ~
~
iinciude <fstream>
iinclude <iostream>
using namespace std;.
struct Student {
char Ime[20], Prezime[20];
int Indeks, BrojOcjena;
~
~
int Ocjene [30];
I;
int main() {
int BrojStudenata;
Student NekiStudent; . . ...
ifstream Studenti ("STUDENTI.DAT", ios: :in· I ios: :binary);
whi1e(Studenti.read((char*)&NekiStudent, sizeof(Student))) {
~
~
double Prosjek = 0; ·
for{int i = 1; i <= NekiStudent.BrojOcjena; i++l
Prosjek += NekiStudent.Ocjene[i];
Prosjek /= NekiStudent.BrojOcjena;
cout << •rme: • << NekiStudent.Ime <<·" Prezime: "
<< NekiStudent.Prezime << • • << "Indeks : •
<< Nekistudent •. Indeks << • Prosjek: • << Prosjek .<< .endl;
JIJ
I
JlJ
~
14

·rf
-··.

~I

class Stude ntska Sluzb a I


stude nt stude nti[lO O];
int BrojS tuden ata;

publi c:

void Sacu~aj{const char Ime[] );


void Obno vi{co nst char Ime[] );
);

Tada bi implementacija metod a sacuv aj i Obnov i mogla izgledati ovako:

void Stude ntska Sluzb a::sac uvaj{ const char Ime[] ) I


ofstre am Izlaz{ Ime, ios::o ut I ios::b inary );
Izlaz .writ e({ch ar*)t his, sizeo f{*th is));
if {! Izlaz ) throw "Nest e nije u redu sa upisom ! \n";
}

void Stude ntska Sluzb a: :Obno vi {cons t char Ime[_]) I


ifstre am Ulaz{ Ime, ios:: in I ios::b inary );
if{!U laz) throw "Dato teka ne.po stoji! \n";
Ulaz. read{ {char *)this , sizeo f{*th is));
if{ !Ulaz ) throw "Nest o nije u redu _sa citanj em! \n";
}

Primijetfuw da smo kao prvi parametar metodama write odnosn


o read proslijCdili J;>Okazivlii!
this; Cime mvo snimamo l"amo vo sadrZa" memori"e ko ·· zanzima·objekat nad
koilm su pozva ne metod e sacuv ai ill ohnmr i Velicinu objekta sazuaje
mo po1llOCU siZeo f {*thi s),
jer *this predst avlja objekat uad kojim je metoda pozvana. Zaprav
o, umjesto sizeo f (*thi s) smo
moglip isali sizeo f {Stud Emtsk aSluz ba), ali naova j nal!inneovisim
o od styamog imenaklase.
~

) Situai:ija se komplicira ukoliko kontejnerska klasa korlSti dinamiCku


alokaciju memorije, §to je
\ veoma ~st slueaj. Zamislimo, na primjer, daje klasa stude ntska
sluzb a organizirana ovliko: _
class .Stud entsk aSluz ba {
Stude nt *Stud enti;
int Brojs tuden ata, MaxB rojStu denat a;

publi c:
stude ntska Sluzb a{int Kapa citet) : Brojs tuden ata(O ),
MaxB rojStu denat a.(Ka pacite t), Stude nti (new Stude nt [Kapa
citet] ) I}
void Sacuv aj(co nst char Ime[] );
void Obno vi{co nst char Ime(J );
};

. U ovom sluea"u, prethodne implementacije metoda Sacuv a. i


ObnQvi
Nairne, U: ovom slueaju, sama klasa stude ntska Sluzb a ne sa ·; unutar
neec raditi kako
treba.
sebe niz stu nata, nego
( samo polazz ivacna dinamiCki alociran niz studenata ko ·· se nalazi negdje u memoriji
izvan prostora lroji
~- zauzima sama a. Stoga, metode Sacuv aj i Obnov i treba prepraVI u u o zrr ovu

IS
,-_ &jenico. Prepmvka metode _sacuvai je tJ;ivijalna! "samo je pored saddaia same klase OOtrebno u
) datoteku Snimiti i- sadrZl\j dinami&f alocil;anog niza.- Njegovu adresu mamo preko pokaziv!Wa
\'t
,_
~ -~-, studenti, a dlmnu mo!l\emo odrediti jednostavuim I'IWunom kao. broj elemenata niza pomnoZen.u sa
~ ..-7 veli&omjednog elementa niza:

void StudentskaSluzba::Sac uvaj(oonst char Ime[]) {


I
ofstream Izlaz(Ime, ios::out I ios::binary);:
Izlaz.write((char*)th is, sizeof(*this));
Izlaz.write((char*)St udenti, BrojStudenata * sizeof(*Studenti));
£
}
if(!Izlaz) throw "Nesto nije u redu sa upisom!\n";
i
?i
\1 !
iji~~~~~~J_-!
~
void StudentskaSluzba::Obn ovi(oonst char Ime[]) {
ifstream Ulaz(Ime, ios::in I ios::binary);
if(!Ulaz) thr~w "Datoteka ne postoji!\n";
Student *Pomocna = Student!;
Ulaz.read((char*)this , sizeof(*this));
Student! =_Pomocna;
Ulaz.read((char*)Stud enti, BrojStudenata * sizeof(*Studenti));
11
~
if(!Ulaz) throw "Nesto nije u redu sa citanjeml\n";
)

Prikazano rje~je radi uglavnom dobro, ali posjeduje jedan bitan nedostatak. Nairne, ukoliko bismo
poku§ali da sadrZaj oJ:dekta klase studentskaSluzba izvjesnog kapaciteta probamo obnoviti iz
datoteke u koju je snimljen sadrZaj objekta klase StudentskaSluzba ve6eg kapaciteta, doCi Ce do
kraha programa, jer dinamiCki alocirani niz u objektu Ciji sadrZaj Zelimo da obnoviliio li.ema dovoljnu
~
~
veliCinu da se u njega moZe uCitati Citav snimljeni niz. Bolje rj~je je da u slul!aju da jc !gm'lcllet
objektal!iji sadrZaj obnavl"amoman'i u odnosuna itet objektako'i 'esniinren u datotekuizvdimo
o !JU mem<>nJe (1j. da poveCaino !qlpacitet razmatranog objekta). Ovo rje~je je izvedeno u

~
-- sljedeeoj implementaciji metode Obnovi: -
void StudentskaSluzba::Obn ovi(oonst char Ime[]) {
ifstream tJlaz(Ime, ios: :in I ios: :binary);
if(!Ulaz) throw "Datoteka ne postoji!\n";
Student *Pomocna = Studenti;
int Kapacitet = MaxBrStudenata;
n
Ulaz.read{(char*)this , sizeof{*this));
if(Kapacitet < MaxBrStudenata) {
delete [] Studenti;
[
Studenti =new Student[MaxBrStudena ta];

~
}
Studenti = Pomocna;
Ulaz.read((char*)Stud enti, BrojStudenata * sizeof{*Studenti));
if{!Ulaz) throw "Nesto nije u redu sa citanjem!\n";
}
L[
Kao altemativu ovom rj~ju moZemo navesti i jednostavnije rj~je, koje takoder radi veoma
dobro, ali je nc:Sto manje efik8sno, jer se realokacija vrSi i kad treba i kad no treba: -~
16
~
r.l
r '-~i5t'" ,~u\Q\,f-,_' ~&. :;::?.,-'.: ~ '~~~:\%?.!·~~·~ ·~ .-~· J

'~: . . ,' .,
. .
...,
' . . '\ ~.
void_ StudentskaSlu~l:la: :.OI:!novi (con~
char Ime[]) {
ifstrea m Ulaz (Ime, ios: :in ·) ias: :biliar y);
if ( !Ulaz) throw "Datot eka ne postoj i·! \n";
- delet e[] Stude nt!;
Ulaz. read(( char* )this, sizeo f(*thi s));
stude nt!= new studen t[Max BrStud enataJ ;
Ulaz.r ead((c har*)S tuden ti, Brojst udp.na ta * sizeof (*Stu denti) );
if(!Ul az) throw "Nesto nije u redu sa citanj em!\n ";

Jo~ sloZenija situacija nastupa Jl slu~ju kada konteinerska 1dasa

t
koristi dinamiCki alocirane nizove
koji ne sadrZe saroe nhjekte, nego pokliZivaee na objekte, ~o je takoder Cest sl~j
n praksi, naromto
klidii su objekti instance neke klase koja saddi samo koilstruktore sa parametrima U tom
sl~u, kao
~ VeC znffi.DO. samB kontei?':fl*a klasa. ~t;Z;ni mkazivaC,- Pretpostavimo, na
Studen tskaSl uzba orgamzrrana na sljede6i primjer , JC kJasa
· - ·
class Studen tskaSl uzba (
studen t **Stu denti;
int BrojS tudena ta, MaxBr ojStud enata;
public :
Stude ntskaS luzba( int Kapac itet) : BrojS tudena ta(O),
MaxB rojStu denata (Kapa citet), Stude nti(ne w'Stud ent*[K apacit et])
(}
void Sacuv aj(con st char Ime[]) ;
void Obnov i(cons t char Ime[]) ;
};

~
u· ovom ~ju, nakon §to u datoteku snimimo sam sadrZaj klase, ne trebamo u datoteku snimati
sam dinamiCki niz na koji pokazuje pokazivae studen t!. Naime, ovaj niz ne sadrZi
same objekte koje
:re!imo cla snimimo, nego pokazivace na njih. Umjesto toga, u datoteku je potrebno snimiti sve o!Jjekte
na lroje po!rgzutu pokazivaCi koji se nalaze u nlzu na kqji polrazUje pokazivac stude
nti. Stoga bi u
I ovom sluCIYu, metoda Sacuva j mogla izgledati ovako (primijetimo daje sizeo
f (**Stu denti) isto
1._ §to i sizeo f ( *Stud enti [i] ) ill sizeo f (Stude nt)):

void Stude ntskaS luzba: :Sacuv aj(con st char Ime(]) (


ofstre am Izlaz( Ime, ios::o ut I ios::b inary );
Izlaz. write ((char *) this, sizea f(*thi sl);
for(in t i = 0; i < Brojst udena ta; i++l
Izlaz. write( (char* )Stud enti[i ], sizeof (**St udent i));
if(!Iz laz) throw "Nesto nije u redu sa upisom !\n";
}

Za pisanje metode Obnovi moZe!no iskoristiti istu logiku. Ovdje je prikazana jednost
avnija izvedba
metode, koja vm realokaciju memorije neovisuo od ~ga da li je ona zaista potrebn
a iii nije:
void Studen tskaSl uzba:: obnov i(cons ,t char Ime[]) {
ifstrea m Ulaz(I me, ios::i n I ios::b inary );
if(!Ul az) throw "Datot eka ne posto ji!\n" ;
delete [] Stude nt!;
Ulaz.r ead((c har*)t his, sizeo f(*thi s));
Stude nti =new Studen t*[Ma xBrStu denata ];
for(in t i = 0; i < BrojS tudena ta; i++) {
stude nti[i] =new Stude nt;
Ulaz.r ead((c har*)S tuden ti[i], sizeof (**St udent i));
}
if(!Ul az) throw "Nesto nije u redu sa citanj em!\n ";
}

,....
17 /
I
I

i
l
nego . . .alokacije prostom
i'
I za svakog studenta operatora ne'!l).konstruktqru bismo proslijediti bilo kakve· parametre
pod uvjetom da su (da sene desi dakonstruktor baci izuzetak), s obzirom da ee stvami sadrZaj
objekta student biti .1JCitan iz datoteke, bez obzira kabv je sadrZaj postavio konstrukt01:.
Citaocu 8e savjetuje da · .da naj;lme efikasniju varijantu metode Obnovi koja ee obavljati realokaciju
memorije samo u slul!aju da za iljmn zaista postoji potreba· . ·

You might also like