154

Click here to load reader

Demistificirani C++.pdf

Embed Size (px)

Citation preview

  • 1

    1. To C++ or not to C++?

    Vie nego bilo kada u povijesti, ovjeanstvo se nalazi na razmei. Jedan put vodi u oaj i krajnje beznae, a drugi u potpuno istreblje-

    nje. Pomolimo se da emo imati mudrosti izabrati ispravno.

    Woody Allen, Popratne pojave (1980)

    Prilikom pisanja ove knjige mnogi su nas, s podsmijehom kao da gledaju posljednji primjerak snjenog leoparda, pitali: No zato se bavite C++ jezikom? To je komplici-rani jezik, spor, nedovoljno efikasan za primjenu u komercijalnim programima. Na kraju, ja to sve mogu napraviti u obinom C-u. Prije nego to ponemo objanjavati pojedine znaajke jezika, nalazimo vanim pokuati dati koliko-toliko suvisle odgovore na ta i slina pitanja.

    Ovo poglavlje zamiljeno je da dade okvirne informacije itateljici ili itatelju. U njemu e se pojaviti mnotvo pojmova koji nisu neophodni za daljnje itanje knjige. Neki od tih pojmova bit e dodatno objanjeni u kasnijim poglavljima. Stoga, ako vam neto nije jasno, nemojte se obeshrabrivati jednostavno preite preko toga i nastavite.

    1.1. Povijesni pregled razvoja programskih jezika

    Osnovno pitanje je to C++ ini boljim i pogodnijim openamjenskim jezikom za pisa-nje raznovrsnih programa, od operacijskih sustava do baza podataka. Da bismo to ra-zumjeli, pogledajmo kojim putem je tekao povijesni razvoj jezika. Na taj nain e mo-da biti jasnija motivacija Bjarne Stroustrupa, oca i majke jezika C++. Dakle, krenimo od stoljea sedmog.

    Prva raunala koja su se pojavila bila su vrlo sloena za koritenje. Njih su koristili iskljuivo strunjaci koji su bili osposobljeni za komunikaciju s raunalom. Ta komuni-kacija se sastojala od dva osnovna koraka: davanje uputa raunalu i itanje rezultata obrade. I dok se itanje rezultata vrlo brzo uinilo koliko-toliko snoljivim uvoenjem pisaa na kojima su se rezultati ispisivali, unoenje uputa programiranje se sastojalo od mukotrpnog unosa niza nula i jedinica. Ti nizovi su davali raunalu upute kao to su: zbroji dva broja, premjesti podatak s neke memorijske lokacije na drugu, skoi na neku instrukciju izvan normalnog slijeda instrukcija i slino. Kako je takve programe bilo vrlo sloeno pisati, a jo sloenije itati i ispravljati, ubrzo su se pojavili prvi pro-gramerski alati nazvani asembleri (engl. assemblers) koji su instrukcije iz asemblerskog jezika prevodili u strojne instrukcije.

    U asemblerskom jeziku svaka strojna instrukcija predstavljena je mnemonikom tj. nekom pridruenom kraticom koja je razumljiva ljudima koji itaju program. Tako se za

    Dem

    istifi

    cira

    ni C

    ++

    4. iz

    danj

    e (

    201

    4)

    www.

    elem

    ent.h

    r

  • 2 1. To C++ or not to C++?

    zbrajanje najee koristi mnemonik ADD, dok se za premjetanje podataka s jednog mjesta u memoriji na neko drugo mjesto koristi simbol MOV. Time je postignuta bolja itljivost programa, no i dalje je bilo vrlo sloeno pisati programe i ispravljati ih jer je bilo potrebno davati sve, pa i najdetaljnije upute raunalu za svaku pojedinu operaciju. Javlja se problem koji e kasnije, nakon niza godina, dovesti i do pojave programskog jezika C++: potrebno je razviti programerski alat koji e osloboditi programera rutinskih poslova te mu dopustiti da se usredotoi na problem koji rjeava.

    Zbog toga su se pojavili vii programski jezici koji su preuzeli na sebe dio rutinskih dosadnih programerskih poslova. Primjerice, vii programski jezici omoguili su da programer prilikom pisanja programa vie ne mora voditi rauna o tome na kojoj je adresi u memoriji podatak pohranjen, ve da podatke dohvaa preko simbolikih imena koja sam programer zadaje, koristei pri tome uobiajenu matematiku notaciju. Kako su se raunala koristila za sve raznovrsnije namjene, tako su stvarani i novi programski jezici koji su bili pogodniji za dotine namjene. Tako je FORTRAN bio posebno pogo-dan za matematike proraune, zatim BASIC koji se vrlo brzo uio, te COBOL koji je bio u pravilu namijenjen upravljanju bazama podataka.

    Oko 1972. se pojavljuje jezik C, koji je direktna pretea dananjeg jezika C++. To je bio prvi jezik ope namjene te je postigao nevien uspjeh. Vie je razloga tome: jezik je bio jednostavan za uenje, omoguavao je modularno pisanje programa, sadravao je samo naredbe koje se mogu jednostavno prevesti u strojni jezik, davao je brzi izvedbeni kd. Jezik nije bio optereen mnogim sloenim funkcijama, kao na primjer skupljanje smea (engl. garbage collection) : ako je takav podsustav nekome trebao, korisnik ga je sam napisao. Jezik je omoguavao vrlo dobru kontrolu strojnih resursa te je na taj nain omoguio programerima da optimiziraju svoj kd. Poetkom devedesetih godina pro-log stoljea, veina komercijalnih programa bila je napisana u C-u, ponegdje dopunjena odsjecima u strojnom jeziku kako bi se kritini dijelovi sustava uinili dovoljno brzi-ma.

    No kako je razvoj programske podrke napredovao, stvari su se i na podruju pro-gramskih jezika poele mijenjati. Sloeni projekti od nekoliko stotina tisua, pa i vie redaka na kojima rade timovi od desetak ili stotinjak programera, vie nisu rijetkost, pa je zbog toga bilo potrebno uvesti dodatne mehanizme kojima bi se takvi programi uini-li jednostavnijima za izradu i odravanje, te kojima bi se omoguilo da se jednom napi-sani kd iskoristi u vie razliitih projekata.

    Bjarne Stroustrup (roen u Danskoj) je 1979. godine zapoeo rad na jeziku C s klasama (engl. C with Classes). Prije toga, on je radio na svom doktoratu u Computing Laboratory of Cambridge te istraivao distribuirane sustave, granu raunalne znanosti u kojoj se prouavaju modeli obrade podataka na vie jedinica istodobno. Pri tome je koristio jezik Simula, koji posjedovao neka vana svojstva koja su ga inila prikladnim za taj posao. Na primjer, Simula je posjedovala pojam klase (engl. class - vrsta, razred, klasa) strukture koja objedinjava podatke i operacije nad podacima. Koritenje klasa omoguilo je da se koncepti problema koji se rjeava izraze direktno pomou jezinih konstrukcija. Dobiveni kd je bio vrlo itljiv i razumljiv, a g. Stroustrup je bio posebno fasciniran nainom na koji je sam programski jezik upuivao programera u razmiljanju

    Dem

    istifi

    cira

    ni C

    ++

    4. iz

    danj

    e (

    201

    4)

    www.

    elem

    ent.h

    r

  • 1.2. Osnovna svojstva jezika C++ 3

    o problemu. Takoer, jezik je posjedovao sustav tipizacije, koji je esto pomagao koris-niku u pronalaenju pogreaka ve prilikom prevoenja.

    Naoko idealan u teoriji, jezik Simula je posrnuo u praksi: prevoenje je bilo iznim-no dugotrajno, a kd se izvodio izuzetno sporo. Dobiveni program je bio neupotrebljiv i, da bi ipak poteno zaradio svoj doktorat, gospodin Stroustrup se morao potruditi i pono-vo napisati cjelokupni program u jeziku BCPL jeziku niske razine koji je omoguio vrlo dobre performanse prevedenog programa. No iskustvo pisanja sloenog programa u takvom jeziku je bilo frustrirajue i g. Stroustrup je, po zavretku svog posla na Cam-bridgeu, vrsto sebi obeao da vie nikada nee takav sloen problem pokuati rijeiti neadekvatnim alatima poput BCPL-a ili Simule.

    Kada se 1979. zaposlio u Bell Labs (kasnije AT&T) u Murray Hillu, zapoeo je rad na onome to e kasnije postati C++. Na osnovu svog iskustva steenog prilikom rada na doktoratu pokuao je stvoriti univerzalni jezik koji e udovoljiti dananjim zahtje-vima. Pri tome je uzeo dobra svojstva niza jezika: Simula, Clu, Algol68 i Ada, a kao osnovu za sintaksu je uzeo jezik C, koji je ve tada bio vrlo popularan i koji je uostalom bio stvoren u Bellovim laboratorijima.

    1.2. Osnovna svojstva jezika C++

    etiri su vana svojstva jezika C++ koja ga ine objektno orijentiranim:

    1. enkapsulacija (engl. encapsulation), 2. skrivanje podataka (engl. data hiding), 3. nasljeivanje (engl. inheritance) i 4. polimorfizam (engl. polymorphism).

    Sva ta svojstva doprinose ostvarenju takozvane objektno orijentirane paradigme pro-gramiranja.

    Da bismo to bolje razumjeli, pogledajmo koji su se programski modeli koristili u prolosti. Pri tome je svakako najvaniji model proceduralno strukturiranog programira-nja.

    Proceduralno programiranje zasniva se na promatranju programa kao niza jedno-stavnih programskih odsjeaka, procedura. Svaka procedura je konstruirana tako da obavlja jedan manji zadatak, a cijeli se program sastoji od niza procedura koje sudjeluju u rjeavanju zadatka.

    Kako bi koristi od ovakve podjele programa bile to izraenije, smatralo se dobrom programerskom taktikom odvojiti proceduru od podataka koje ona obrauje: time je bilo mogue pozvati proceduru za razliite ulazne podatke i na taj nain iskoristiti je na vie mjesta. Strukturirano programiranje je samo dodatak na proceduralni model: ono defi-nira niz osnovnih jezinih konstrukcija, kao to su petlje, grananja i pozivi procedura, koje unose red u programe i ine samo programiranje daleko jednostavnijim, a napisani kd itljivijim.

    Princip kojim bismo mogli obiljeiti proceduralno strukturirani model jest podijeli-pa-vladaj: cjelokupni program je presloen da bi ga se moglo razumjeti pa se zbog toga on rastavlja na niz manjih zadataka procedura koje su dovoljno jednostavne da bi se

    Dem

    istifi

    cira

    ni C

    ++

    4. iz

    danj

    e (

    201

    4)

    www.

    elem

    ent.h

    r

  • 4 1. To C++ or not to C++?

    mogle izraziti pomou naredbi programskog jezika. Pri tome, pojedina procedura tako-er ne mora biti rijeena monolitno: ona moe svoj posao obaviti kombinirajui rad niza drugih procedura.

    Ilustrirat emo to primjerom: zamislimo da elimo izraditi kompleksan program za obradu trodimenzionalnih objekata. Kao jednu od mogunosti koje moramo ponuditi korisnicima jest rotacija objekata oko neke toke u prostoru. Koristei proceduralno programiranje, taj zadatak bi se mogao ralaniti na sljedee operacije:

    1. listaj sve objekte redom; 2. za pojedini objekt odredi njegov tip; 3. ovisno o tipu, pozovi odgovarajuu proceduru koja e izraunati novu poziciju

    objekta; 4. u skladu s tipom podataka auriraj koordinate objekta.

    Operacije odreivanja tipa, izraunavanje nove pozicije objekta i auriranje koordinata mogu se dalje predstaviti pomou procedura koje sadravaju niz jednostavnijih akcija.

    Ovakav programski pristup je bio vrlo uspjean do kasnih osamdesetih godina dva-desetog stoljea, kada su njegovi nedostaci postajali sve oitiji. Naime, odvajanje poda-taka i procedura ini programski kd teim za itanje i razumijevanje. Prirodnije je o podacima razmiljati preko operacija koje moemo obaviti nad njima u gornjem pri-mjeru to znai da o kocki ne razmiljamo pomou koordinata njenih vrhova ve pomou moguih operacija, kao to je rotacija kocke.

    Nadalje, pokazalo se sloenim istodobno razmiljati o problemu i odmah strukturi-rati rjeenje. Umjesto rjeavanja problema, programeri su mnogo vremena provodili pronalazei naine da programe usklade sa zadanom strukturom.

    Takoer, dananji programi se pokreu pomou mia, prozora, izbornika i dijaloga. Programiranje je pogonjeno dogaajima (engl. event-driven) za razliku od starog, sek-vencijalnog naina. Proceduralni programi su korisniku, u trenutku kada je bila potrebna interakcija korisnika (na primjer zahtjev za ispis na pisau) prikazivali ekran nudei mu opcije; ovisno o odabranoj opciji, izvoenje kda se usmjeravalo na odreeni program-ski odsjeak. Pogonjeno dogaajima znai da se program ne odvija po unaprijed odre-enom slijedu, ve se programom upravlja pomou niza dogaaja. Dogaaja ima raznih: pomicanje mia, pritisak na tipku, izbor stavke iz izbornika i slino. Sada su sve opcije dostupne istodobno, a program postaje interaktivan, to znai da promptno odgovara na korisnikove zahtjeve i odmah (ovo ipak treba shvatiti uvjetno) prikazuje rezultat svoje akcije na zaslonu raunala.

    Kako bi se takvi zahtjevi jednostavnije proveli u praksi, razvijen je objektni pristup programiranju. Osnovna ideja je razbiti program u niz zatvorenih cjelina (objekata) koje meusobno surauju u rjeavanju problema. Umjesto specijaliziranih procedura koje barataju proizvoljnim podacima, radimo s objektima koji objedinjavaju podatke i operacije nad tim podacima. Pri tome je vano to objekt radi, a ne kako on to radi. To omoguava da se pojedini objekt moe po potrebi izbaciti i zamijeniti drugim koji e istu zadau obaviti bolje.

    Objedinjavanje podataka i operacija naziva se enkapsulacija (engl. encapsulation) objekt se ne sastoji iskljuivo od podataka ve sadri i metode neophodne za operacije nad tim podacima. Pritom su podaci privatni za svaki objekt te nisu dostupni ostalim

    Dem

    istifi

    cira

    ni C

    ++

    4. iz

    danj

    e (

    201

    4)

    www.

    elem

    ent.h

    r

  • 1.2. Osnovna svojstva jezika C++ 5

    dijelovima programa. Na taj su nain podaci zatieni od neovlatene promjene izvan objekta koja bi mogla naruiti njegovu cjelovitost. Mehanizam zatite podataka naziva se skrivanje podataka (engl. data hiding). Svaki objekt svojoj okolini prua iskljuivo podatke i operacije koji su neophodni da bi okolina objekt mogla koristiti. Ti javno dostupni podaci zajedno s operacijama koje ih prihvaaju ili vraaju ine suelje (engl. interface) objekta. Programer koji e koristiti taj objekt vie se ne mora zamarati razmi-ljajui o nainu na koji objekt iznutra funkcionira on jednostavno preko suelja trai od objekta odreenu uslugu.

    Objektni pristup ima izravnu analogiju sa svakodnevnim ivotom pa pokuajmo opisane principe ilustrirati na praktinom primjeru. Iako mnogi automobil percepiraju kroz tehnike podatke kao to su maksimalna brzina, ubrzanje, potronja goriva ili boja karoserije, osnovna namjena automobila jest prijevoz osoba ili robe. Dakle, automobil promatramo kroz operacije koje on prua tj. koliko osoba ili robe moe prevesti i u kojem vremenu. Za obavljanje te operacije potrebna mu je izmeu ostaloga odreena koliina goriva koje pokree motor i akumulator koji osigurava struju za elektropokreta kojim se motor aktivira. Sreom, za pokretanje motora voza ne mora spajati ice aku-mulatora na elektropokreta, kao to ni tijekom vonje ne mora sam dolijevati gorivo u cilindar automobila. Te operacije su enkapsulirane u mehanizmu motora, odnosno auto-mobila. Cijev za dotok goriva, kablovi za svjeice i turbo-ubrizgavai su skriveni od vozaa, pod pokrovom motora. Da nije tako, lako bi se moglo dogoditi da voza ili sluajni prolaznik nestrunim prkanjem zamijeni cijev dotoka goriva i kablove svjeica te prouzroi zapaljenje automobila. Vozau je za upravljanje automobilom na raspola-ganju volan, papuica gasa, konica, spojka i ruica mjenjaa te kontrole ine suelje preko kojega voza obavlja operacije nad automobilom.

    Kada PC preprodava, vlasnik poduzea Taiwan/tavan-Commerce sklapa rauna-lo, on zasigurno treba kuite (iako se i to ponekad pokazuje nepotrebnim). To ne znai da e on morati poeti od nule (miksajui atome eljeza u aici od Kinderlade); on e jednostavno otii kod susjednog dilera i kupiti gotovo kuite koje ima prikljuak na mreni napon, ATX napajanje, ladice za montau diskova te otvor za DVD pogon. Tako je i u programiranju: mogue je kupiti gotove programske komponente koje se zatim mogu iskoristiti u programu. Nije potrebno razumjeti kako komponenta radi dovoljno je poznavati njeno suelje da bi ju se moglo iskoristiti.

    Takoer, kada projektanti u Renaultu ele izraditi novi model automobila, imaju dva izbora: ili mogu poeti od nule i ponovo proraunavati svaki najmanji dio motora, asije i ostalih dijelova, ili mogu jednostavno novi model bazirati na nekom starom modelu. Kompaniji je cilj to bre razviti novi model kako bi pretekla konkurenciju, pa e zasigurno jednostavno uzeti uspjean model automobila i samo izmijeniti neka nje-gova svojstva: promijenit e mu liniju, pojaati motor, dodati elektroniku za pouzdanije upravljanje. Slino je i s programskim komponentama: prilikom rjeavanja nekog pro-blema moemo uzdahnuti i poeti kopati, ili moemo uzeti neku ve gotovu komponen-tu koja je blizu rjeenja i samo dodati nove mogunosti. To se zove ponovna iskoristi-vost (engl. reusability) i vrlo je vano svojstvo. Za novu programsku komponentu kae se da je naslijedila (engl. inherit) svojstva komponente iz koje je izgraena.

    Dem

    istifi

    cira

    ni C

    ++

    4. iz

    danj

    e (

    201

    4)

    www.

    elem

    ent.h

    r

  • 6 1. To C++ or not to C++?

    Korisnik koji kupuje auto sigurno nee biti presretan ako se njegov novi model raz-likuje od starog po nainu koritenja, primjerice da se umjesto pritiskom na papuicu gasa auto ubrzava povlaenjem ruice na krovu vozila ili sputanjem suvozaevog sje-dala. On jednostavno eli pritisnuti gas, a stvar je nove verzije automobila krae vrijeme ubrzanja od 0 do 100 km/h. Slino je i s programskim komponentama: korisnik se ne treba optereivati time koju verziju komponente koristi on e jednostavno traiti od komponente uslugu, a na njoj je da to obavi na adekvatan nain. U primjeru s rotacijama tijela, korisnik e od svakog pojedinog tijela zatraiti istu operaciju da se zakrene a tijelo e operaciju izvesti na njen svojstven nain. Svojstvo da razliiti objekti istu ope-raciju obavljaju na razliite naine zove se polimorfizam (engl. polimorphism).

    Gore navedena svojstva zajedno sainjavaju objektno orijentirani model programi-ranja. Evo kako bi se postupak rotiranja trodimenzionalnih likova proveo koristei objekte:

    1. listaj sve objekte redom; 2. zatrai od svakog objekta da se zarotira za neki kut.

    Sada glavni program vie ne mora voditi rauna o tome koji se objekt rotira on jednostavno samo zatrai od objekta da se zarotira. Sam objekt zna to uiniti ovisno o tome koji lik on predstavlja: kocka e se zarotirati na jedan nain, a kubini spline na drugi. Takoer, ako se kasnije program proiri novim tijelima, nije potrebno mijenjati program koji rotira sve objekte dovoljno je samo u novododanom objektu definirati operaciju rotacije.

    Dakle, ono to C++ jezik ini vrlo pogodnim jezikom ope namjene za izradu slo-enih programa jest mogunost jednostavnog uvoenja novih tipova te naknadnog do-davanja novih operacija.

    Razliku izmeu proceduralnog i objektno orijentiranog modela mogli bismo po-istovjetiti s razlikom izmeu ahovskog mea i bitke na bojnom polju. U oba sluaja sukobljavaju se dvije vojske i tijekom borbe obje strane gube sudionike, a pobjednik je ona strana kojoj kljune figure ostanu netaknute. Meutim, u ahu igrai povlae poteze tako da osobno svaku figuru pomiu prema definiranim pravilima. S druge strane, u stvarnoj bici zapovjednici samo izdaju naredbe koje vojnici izvravaju. Zapovjednik ne mora znati kako se puca iz pojedine puke ili gaa iz topa; on samo mora znati kada li jevo krilo treba krenuti u napad te izdati odgovarajue zapovijedi. Svaki pojedini voj-nik e shodno toj naredbi izvesti odgovarajue radnje u skladu sa svojim poloajem i mogunostima.

    1.3. Usporedba s C-om

    Mnogi okorjeli C programeri, koji sanjaju strukture i dok se voze u tramvaju ili razmi-ljaju o tome kako e svoju novu rutinu rijeiti pomou pokazivaa na funkcije, dvoume se oko toga je li C++ doista dostojan njihovog kda: mnogi su u strahu od nepoznatog jezika te se boje da e im njihov supermunjeviti program za zbrajanje dvaju jednozna-menkastih brojeva na novom jeziku biti sporiji od programa za raunanje fraktalnog skupa. Drugi se, pak, kunu da je C++ odgovor na sva njihova ivotna pitanja, te u fana-tinom zanosu umjesto Kristovog roenja slave roendan gospodina Stroustrupa.

    Dem

    istifi

    cira

    ni C

    ++

    4. iz

    danj

    e (

    201

    4)

    www.

    elem

    ent.h

    r

  • 1.3. Usporedba s C-om 7

    Moramo odmah razoarati obje frakcije: niti jedna nije u pravu te je njihovo milje-nje rezultat nerazumijevanja nove tehnologije. Kao i sve drugo, objektna tehnologija ima svoje prednosti i mane, a takoer nije svemogua te ne moe rijeiti sve probleme (na primjer, ona vam nee pomoi da opljakate banku i umaknete Interpolu).

    Kao prvo, C++ programi nisu nuno sporiji od svojih C ekvivalenata. U vrijeme adolescencije jezika C++ to je bio est sluaj kao posljedica neefikasnih prevoditelja zbog toga se uvrijeilo miljenje kako programi pisani u jeziku C++ daju sporiji izved-beni kd. Meutim, kako je rastao broj prevoditelja na tritu (a time i meusobna kon-kurencija), kvaliteta izvedbenog kda koju su oni generirali se poboljavala. tovie, dananji prevoditelji esto bolje daju efikasniji izvedbeni kd iz C++ izvornog koda nego iz ekvivalentnog C kda. Osim toga, jezik C++ sadri neke konstrukcije, kao to su umetnute (engl. inline) funkcije, koje mogu znatno pospjeiti brzinu konanog izved-benog koda. Ipak, u pojedinim sluajevima izvedbeni kd dobiven iz C++ izvornog kda doista moe biti sporiji, a na programeru je da shvati kada je to dodatno usporenje prevelika smetnja da bi se toleriralo.

    Nadalje, koncept klase i enkapsulacija uope ne usporavaju dobiveni izvedbeni program. Dobiveni strojni kd bi u mnogim sluajevima trebao biti potpuno istovjetan onome koji e se dobiti iz analognog C programa. Funkcijski lanovi pristupaju podat-kovnim lanovima objekata preko pokazivaa, na slian nain na koji to korisnici pro-ceduralne paradigme ine runo. No C++ kd e biti itljiviji i jasniji te e ga biti lake napisati i razumjeti. Ako pojedini prevoditelj i daje loiji izvedbeni kd, to je posljedica loeg prevoditelja, a ne mana jezika.

    Takoer, koritenje nasljeivanja ne usporava dobiveni kd ako se ne koriste virtu-alni funkcijski lanovi i virtualne osnovne klase. Nasljeivanje samo uteuje programe-ru viestruko pisanje kda te olakava ponovno koritenje ve napisanih programskih odsjeaka.

    Vi rtualne funkcije i virtualne osnovne klase usporavaju program. Virtualne funkcije se izvode tako da se prije poziva konzultira posebna tablica, pa je jasno da e poziv svake takve funkcije biti neto sporiji. Takoer, lanovima virtualnih osnovnih klasa se redovito pristupa preko jednog pokazivaa vie. No, usporenje je u veini realnih slua-jeva neprimjetno i zanemarivo u odnosu na koristi koje koritenje virtualnih funkcija donosi. Na programeru je da odredi hoe li koristiti inkriminirana svojstva jezika ili ne. Da bi se precizno ustanovilo kako djeluje pojedino svojstvo jezika na izvedbeni kd, nije dobro nagaati i kriviti C++ za loe performanse, ve izmjeriti vrijeme izvoenja te locirati problem.

    Sagledajmo jo jedan aspekt: asembler je jedini jezik u kojemu programer tono zna to se deava u pojedinom trenutku prilikom izvoenja programa. Kako je progra-miranje u asembleru bilo sloeno, razvijeni su vii programski jezici koji to olakavaju. Prevedeni C kd takoer nije maksimalno brz posebno optimiran asemblerski kd e sigurno dati bolje rezultate. No pisanje takvog kda danas jednostavno nije mogue: problemi koji se rjeavaju su ipak previe sloeni da bi se mogli rjeavati tako da se pazi na svaki ciklus procesora. Danas, kada na izradi programa nerijetko radi istovremeno desetak i vie programera, dizajneri programa prvo moraju definirati module (objekte), njihovu funkcionalnost i specificirati njihova suelja. Tek na osnovu tih specifikacija

    Dem

    istifi

    cira

    ni C

    ++

    4. iz

    danj

    e (

    201

    4)

    www.

    elem

    ent.h

    r

  • 8 1. To C++ or not to C++?

    pojedini programeri razvijaju module i testiraju ih, a na kraju dolazi povezivanje modula i testiranje cjelokupnog programa. Ukoliko su suelja na poetku bila dobro definirana, povezivanje modula e biti vrlo jednostavno i program e skladno raditi. Proces se moe usporediti s izgradnjom naselja: prvo urbanisti definiraju globalni raspored naselja te gabarite i funkcionalnost koje pojedine zgrade moraju zadovoljavati: okvirne dimenzije, gdje e se nalaziti ulaz, hoe li to biti stambena ili poslovna zgrada, vrti ili kola. Tek potom arhitekti na osnovu tih postavki projektiraju pojedine zgrade. U tom sluaju ne moe se dogoditi da se na etverokatnu zgradu naslanja prizemnica, a ispred njih uope nema nogostupa niti dovoljno parkiralinog prostora, jer se nasuprot, tik uz kolnik, nala-zi neboder od osam katova.

    Moda e konani izvedbeni kd biti sporiji i vei od ekvivalentnog C kda, ali e jednostavnost njegove izrade omoguiti da dobiveni program bude bolji po nizu drugih karakteristika: bit e jednostavnije izraditi program koji e biti laki za koritenje, s vie mogunosti i slino. Uostalom, manje posla vea zarada raj zemaljski! Osim toga, danas je esto vrlo vano brim razvojem pretei konkurenciju i prvi izai na trite, diktirajui uvjete (i cijene). to vrijedi programeru ili firmi pisati program u C-u ili assembleru zato da bi dobili maksimalnu brzinu izvoenja, ako e se na tritu s goto-vim proizvodom pojaviti nekoliko mjeseci ili godina kasnije od konkurencije, kada e trite ve biti zasieno slinim, neznatno sporijim proizvodima? Nova raunala s veim mogunostima su sposobna uiniti gubitak performansi beznaajnim u odnosu na dobi-tak u brzini razvoja programa. Tehnologija ide naprijed: dok se gubi neznatno na brzini i memorijskim zahtjevima, dobici su viestruki.

    Naravno, C++ nije svemoan. Koritenje objekata nee napisati pola programa um-jesto vas: ako elite provesti crtanje objekata u tri dimenzije i pri tome ih realistino osjenati, namuit ete se poteno koristite li C ili C++. To niti ne znai da e poznava-nje objektne tehnologije jamiti da ete ju i ispravno primijeniti: ako se ne potrudite prilikom dizajniranja objekata te posao ne obavite u duhu objektnog programiranja, nee biti nita od ponovne iskoristivosti kda. ak i ako posao obavite ispravno, to ne znai da jednog dana neete naii na problem u kojem e jednostavno biti lake zaboraviti sve napisano i poeti od jajeta.

    Ono to vam objektna tehnologija prua jest mogunost da manje panje obratite jeziku i nainu na koji ete svoju misao izraziti, a usredotoite se na ono to zapravo elite uiniti. U ve spominjanom sluaju trodimenzionalnog crtanja objekata to znai da ete manje vremena provesti razmiljajui gdje ste pohranili podatak o poloaju kamere koji vam ba sad treba, a vie ete razmiljati o tome kako da ubrzate postupak sjenanja ili kako da ga uinite realistinijim.

    Objektna tehnologija je pokuala dati odgovore na neke potrebe ljudi koji rjeavaju svoje zadatke raunalom; na vama je da procijenite koliko je to uspjeno, a u svakom sluaju da prije toga proitate ovu knjigu do kraja i preporuite ju prijateljima, naravno. Jer tak dobru i guba knjigu niste vidli ve sto godina i ba vam je bilo fora ju itat.

    Dem

    istifi

    cira

    ni C

    ++

    4. iz

    danj

    e (

    201

    4)

    www.

    elem

    ent.h

    r

  • 1.4. Usporedba s Javom 9

    1.4. Usporedba s Javom

    Nakon to je izalo prvo izdanje knjige, jedan od eih komentara je bio: A zato (radije) niste napisali knjigu o Javi?. Odgovor je vrlo jednostavan: da smo onda napisa-li knjigu o Javi, ta knjiga bi ve nakon godinu dana bila zastarjela! Kada smo krajem 1995. godine poeli pisati knjigu, Java je bila tek u povojima (u svibnju te godine objav-ljena je prva alfa verzija Jave).

    Budui da su u meuvremenu i C++ i Java proli kroz niz dopuna i izmjena, neza-hvalno je raditi iskljuive usporedbe tipa ovo je puno bolje napravljeno u jeziku A nego u jeziku B. Pokuajmo samo naznaiti koje su znaajnije razlike izmeu Jave i jezika C++; konane zakljuke preputamo itatelju.

    1.4.1. Java je potpuno objektno orijentirani programski jezik

    To znai da se sve operacije odvijaju iskljuivo kroz objekte, odnosno preko njihovih funkcijskih lanova (metoda). Stoga je programer od poetka na neki nain prisiljen razmiljati na objektno orijentirani nain. S druge strane, jezik C++ omoguava pisanje i proceduralnog kda. Iako se nekome moe uiniti kao prednost, ovo je zamka u koju vrlo lako mogu upasti poetnici, posebice ako prelaze sa nekog proceduralnog program-skog jezika, kao to je jezik C. Naime, ako usvoji proceduralni nain razmiljanja, prog-ramer e se teko prealtati na objektni pristup i iskoristiti sve njegove pogodnosti. Ovo je danak to ga jezik C++ plaa zbog insistiranja na kompatibilnosti s jezikom C. Stvaratelji jezika C++ (ukljuujui i gospodina Stroustrupa) nisu eljeli izmisliti potpu-no novi jezik koji bi iziskivao da se sve aplikacije prepiu u tom novom jeziku, ve su nastojali da postojei izvorni kdovi mnotva aplikacija pisanih u jeziku C (ne zabora-vimo da je jezik C osamdesetih godina XX stoljea bio najrasprostranjeniji programski jezik) budu potpuno zdruivi s novim jezikom i da se ti kdovi bez potekoa mogu prevesti na prevoditeljima za jezik C++. Ovakav pristup podrazumijevao je mnotvo kompromisa, ali je omoguio tisuama programera i programskih kua postepeni i bez-bolan prijelaz s jezika C na jezik C++. To je znaajno doprinijelo popularnosti i opem prihvaanju jezika C++.

    S druge strane, Java je potpuno novi programski jezik, neoptereen takvim naslje-em zbog toga su neke stvari rijeene daleko elegantnije nego u jeziku C++. Uosta-lom, Javu je stvorila grupa C++ programera koji su bili frustrirani nedostacima jezika C++.

    Ipak, napomenimo da je i u Javi mogue napisati proceduralni kd koristei samo jednu klasu i/ili definirajui sve funkcijske i podatkovne lanove statikima. Ovo je nerijetko sluaj kada se Jave dohvati programer nauen na proceduralni nain razmilja-nja. Jedino opravdanje za ovakvu zloupotrebu jezika jest neznanje.

    1.4.2. Java izvedbeni kd moe se izvoditi na bilo kojem ra unalu

    Java izvorni kd se ne prevodi u strojni kd matinog procesora (matini kd, engl. native code) nego u poseban, tzv. Java binarni kd (engl. Java bytecode) kojeg Java virtualni stroj (engl. Java Virtual Machine, JVM) interpretira i izvodi. Prednost ovakvog

    Dem

    istifi

    cira

    ni C

    ++

    4. iz

    danj

    e (

    201

    4)

    www.

    elem

    ent.h

    r

  • 10 1. To C++ or not to C++?

    pristupa jest da se prevedeni Java kd (teoretski) moe izvravati na bilo kojem raunalu s bilo kojim procesorom i operacijskim sustavom uostalom, ovo je jedan od udarnih reklamnih slogana za Javu. Ovo ipak vrijedi uz neke ograde!

    Kao prvo, na tom stroju mora postojati i vrtiti se (odgovarajui) virtualni stroj. Za popularnije platforme, poput Windows ili Linux platformi postoji zadnja verzija virtual-nog stroja, no za neke egzotine platforme mogu iskrsnuti problemi. Uz to, da bi pro-gram pisan u Javi bio stvarno prenosiv na bilo koju platformu, ne smije sadravati ope-racije specifine za odreenu platformu. Na primjer, operacije vezane uz datoteni sus-tav ili grafiko suelje mogu se znaajno razlikovati od platforme do platforme.

    Osim toga, Java binarni kd nee biti optimiziran za dotini procesor. Na primjer, velika veina dananjih procesora ima ugraene instrukcije za operacije s realnim broje-vima koje omoguavaju da se dijeljenje dva realna broja izvede u svega nekoliko takto-va procesora. Budui da se Java binarni kd mora izvoditi i na raunalima s procesorima koja nemaju ugraene instrukcije za realne brojeve, izvoenje takvih operacija bit e openito sporije.

    Zbog toga, kao i zbog injenice da se Java binarni kd interpretira, a ne izvodi iz-ravno, Java programi su i do desetak puta sporiji od ekvivalentnih programa prevedenih iz nekog drugog jezika. Dodue, novije verzije Java virtualnih strojeva pruaju mogu-nost pravovremenog prevoenja (engl. Just-In-Time compilation), kojim se prilikom pokretanja programa Java binarni kd prevodi u matini strojni kd i kao takav izvodi. Brzina izvoenja takvog kda je usporediva s brzinom matinog izvedbenog kda. Me-utim, taj kd treba prvo prevesti, to znai da se dio vremena namijenjenog izvoenju programa troi na prevoenje iz Java binarnog u matini izvedbeni kd. Za programe u kojima se vei dio kda izvodi samo jednom to moe predstavljati znaajni gubitak vremena, odnosno usporenje programa.

    to je s prenosivou kda pisanog u jeziku C++? Budui da se program pisan u je-ziku C++ prevodi u strojni kd, prilikom prevoenja se mora navesti za koju platformu se taj kd generira taj izvedbeni kd je neupotrebljiv na drugim platformama. Treba-mo li isti program prevesti tako da se moe izvoditi na Windowsima i na Linuxu, morat emo ga posebno prevesti za svaku od tih platformi.

    Programski kd esto poziva funkcije iz programskog suelja operacijskog sustava to omoguava vrlo brzo izvoenje programa i maksimalno koritenje sklopovskih mo-gunosti raunala. No, kako se programska suelja razlikuju za pojedine platforme, pisanje programa koji bi omoguio stvaranje izvedbenog kda za razliite platforme moe biti vrlo mukotrpno. Sreom, postoje biblioteke (poput biblioteke Boost) koje omoguavaju jednostavniju komunikaciju s razliitim platformama. No, za razliku od virtualnog stroja koji predstavlja meusloj tijekom izvoenja, multiplatformne biblio-teke u jeziku C++ su meusloj koji se koristi tijekom prevoenja programa. Tijekom izvoenja su one potpuno transparentne pa je njihov utjecaj na brzinu zanemariv.

    1.4.3. Java nema pokaziva a

    Davno su prola vremena kada su se na sm spomen rijei pokaziva (engl. pointer) zatvarali prozori i zakljuavala vrata, a djecu tjeralo na spavanje (i kada se osoba koja je

    Dem

    istifi

    cira

    ni C

    ++

    4. iz

    danj

    e (

    201

    4)

    www.

    elem

    ent.h

    r

  • 1.4. Usporedba s Javom 11

    javno izjavila da je napravila funkciju koja vraa pokaziva na neki objekt smatrala genijalnim ekscentrikom koji i usred ljeta nosi vunenu kapu i duge gae). Meutim, jo i danas su pokazivai baba-roga kojom se plae programeri-utokljunci. Stoga e takvi aklamacijom prihvatiti istrjebljenje pokazivaa.

    Dodue, zavirimo li pod haubu vidjet emo da se u Javi svi objekti osim nekolici-ne ugraenih, dohvaaju preko pokazivaa1 ono to je dobro jest da nema pretvorbi izmeu pokazivaa i objekata koje omoguavaju raznorazne (obino nenamjerne) ha-keraje i redovito zavravaju ruenjem ili blokiranjem programa. Iako su pokazivai jedan od najeih uzroka pogreaka u poetnikim C/C++ programima, mnogi iskusniji programeri znaju koliko je neke stvari tee napraviti bez pokazivaa na funkcije ili fun-kcijske lanove.

    1.4.4. Java nema viestrukog naslje ivanja

    Nasljeivanje omoguava kreiranje korisniki definiranih tipova podataka koristei i proirujui osobine ve postojeih tipova. esto je poeljno naslijediti osobine razliitih tipova tada se u jeziku C++ primjenjuje viestruko nasljeivanje. Kao primjer, uzmi-mo tipku u nekoj aplikaciji koja umjesto standardnog oblika (tipka sa sjenanjima i tekst) ima oblik bitmapirane slike. Tipina primjena takve tipke bi bila u pregledniku datoteka sa slikama umjesto da izlista imena datoteka taj preglednik e prikazati male sliice, a pritiskom na tipku otvorit e se aplikacija u kojoj sliku moemo obraivati. Naa tipka oito ima svojstva obine tipke (reagira na klik mia i u tom sluaju pokree neku akciju), kao i svojstva bitmapirane slike (mora se znati iscrtati). Umjesto da prepi-emo cjelokupan kd oba tipa objekta, bit e dovoljno naslijediti njihova svojstva, even-tualno modificirajui neka od njih.

    U Javi nema viestrukog nasljeivanja implementacije. Kako se viestruko naslje-ivanje ne koristi esto, tvorci jezika Java smatrali su da ga nema smisla dozvoliti, po-sebice uzevi u obzir probleme koje viestruko nasljeivanje moe prouzroiti sustavu za skupljanje smea. Meutim, Java dozvoljava viestruko nasljeivanje suelja. To zahtijeva neto drugaiji stil programiranja koji je orijentiran prema sueljima objekata.

    1.4.5. Java ima ugra eni sustav za automatsko upravljanjem memorijom

    U jeziku C++ programer mora eksplicitno navesti u kdu da eli osloboditi memoriju koju je prethodno zauzeo za neki objekt. Propusti li to napraviti, tijekom izvoenja pro-grama memorija e se troiti, smanjujui raspoloivu memoriju za ostatak programa il i za ostale programe. Napravi li pak to prerano u kdu, unitit e objekt koji bi eventu-alno mogao kasnije zatrebati. Curenje memorije ili prerano unitenje objekata je vrlo esti uzrok blokiranja rada programa ili cijelog raunala. Dobar C++ programer mora

    1 U terminologiji Jave, umjesto pokazivaa (engl. pointer) koristi se naziv referenca (engl. refe-

    rence) iako se radi o istoj stvari. Budui da su pokazivai bili prili no ozloglaeni meu pro-gramerima, autori Jave su odabrali drugi naziv da ne bi u samim poecima odvratili programe-re. Valja napomenuti da reference u Javi nisu isto to reference u jeziku C++.

    Dem

    istifi

    cira

    ni C

    ++

    4. iz

    danj

    e (

    201

    4)

    www.

    elem

    ent.h

    r

  • 12 1. To C++ or not to C++?

    imati pod kontrolom gdje je rezervirao prostor za neki objekt i gdje e taj prostor oslo-boditi.

    U Javi se sam sustav brine o oslobaanju memorije koja vie nije potrebna sustav za automatsko upravljanje memorijom (engl. garbage collector - sakuplja smea, smet-lar) ugraen je u Java virtualni stroj i automatski se pokree po potrebi. Naravno da e se za sve one koji su iskusili gore opisane probleme u jeziku C++ ovo uiniti kao zemlja Dembelija. Dodue, za jezik C++ postoje komercijalne i besplatne biblioteke koje ugra-uju mehanizme za skupljanje smea u kd, meutim injenica je da ono nije ugraeno u sam izvedbeni sustav.

    S druge strane, mnogi programeri imaju zamjerku na automatsko sakupljanje smea jer sustav sam procjenjuje kada treba to sakupljanje zapoeti i nerijetko se dogaa da to bude upravo u trenutku kada va program obavlja neku zahtjevnu, vremenski kritinu operaciju te e sakupljanje smea usporiti izvoenje programa. Zato i kod ugraenog automatskog sustava za sakupljanje smea treba esto paziti da se novi objekti u memo-riji ne stvaraju neracionalno i bez ozbiljnije potrebe.

    tovie, budui da programer nema nadzora nad unitavanjem, ne moe eksplicitno unititi objekt te ne moe kontrolirati redoslijed koji se objekti unitavaju.

    1.4.6. Java ne podrava preoptere enje operatora

    Preoptereenje operatora omoguava da se funkcionalnost operatora moe proiriti i za korisniki definirane podatke. Primjerice, operator zbrajanja + definiran je za ugraene tipove podataka kao to su cijeli ili realni brojevi i znakovni nizovi. No, ako uvedemo kompleksne brojeve kao svoj novi tip podataka, realno je za oekivati da emo poeljeti zbrajanje kompleksnih brojeva izvoditi pomou operatora +. Bez mehanizma preoptere-enja operatora to nije mogue, ve smo prisiljeni koristiti neitljiviju sintaksu preko poziva funkcijskog lana.

    1.4.7. U Javi su operacije s decimalnim brojevima loije podrane

    Izvorno je Java bila koncipirana uz pretpostavku da ju veina korisnika nee upotreblja-vati za sofisticirane numerike proraune. Budui da je osnovna misao vodilja autora Jave bila prenosivost kda, nisu do kraja implementirani svi zahtjevi koje postavlja IEEE 754 standard za raunanje s decimalnim brojevima te nisu do kraja iskoritene sve sklopovske mogunosti nekih procesora (npr. Intelovih) koji imaju ugraene instrukcije za operacije s decimalnim brojevima. Rezultat toga je i neto sporije izvoenje takvih operacija. No, kako je u specifikaciji jezika Java zapisano, prosjeni korisnik ove nedos-tatke najvjerojatnije nee nikada primijetiti.

    1.4.8. Java ima na raspolaganju ogromnu biblioteku

    Java okruenje (engl. Java Platform) osim virtualnog stroja zaduenog za izvoenje programa, sadri i vrlo bogatu biblioteku od nekoliko tisua gotovih klasa i suelja koji podravaju itav niz operacija ukljuujui rad s datotekama i mreom, matematike

    Dem

    istifi

    cira

    ni C

    ++

    4. iz

    danj

    e (

    201

    4)

    www.

    elem

    ent.h

    r

  • 1.5. Usporedba s jezikom C 13

    funkcije, grafike operacije, rukovanje bazama podataka, obradu teksta, kriptografiju. Sve te klase su dostupne programeru prilikom pisanja kda, ali i korisniku tijekom izvo-enja programa na odredinom raunalu. Upravo ta bogata biblioteka klasa je jedan od glavnih razloga popularnosti Jave, jer programer ne mora sam pisati esto banalne ope-racije, niti mora traiti i kupovati neku komercijalnu biblioteku.

    C++ je u svoj prvi standard iz 1998. godine (poznat pod oznakom C++98), osim standardne biblioteke funkcija naslijeene iz jezika C, ukljuio i standardnu biblioteku predloaka (STL) koja je podravala rad sa skupovima podataka i generike operacije. Za specijalizirane namjene, programeri su bili prisiljeni kupovati komercijalne proizvo-de, koristiti malobrojne besplatne biblioteke ili ih sami pisati. Sreom, 1998. godine poeo je razvoj Boost biblioteke, besplatne i javno dostupne biblioteke klasa koja, poput biblioteke u Javi, podrava iroki spektar operacija. Razvoj te biblioteke je bio tako uspjean da je njen veliki dio uao u sljedeu verziju standarda jezika C++ prihvaenu 2011. godine, poznatu pod oznakom C++11.

    1.4.9. Java je jezik u vlasnitvu jedne tvrtke

    Iako su prevoditelj za Javu i Java virtualni stroj besplatni za individualne korisnike, injenica jest da su oni vlasnitvo i pod kontrolom jedne tvrtke. To znai da neke kom-ponente morate licencirati, a ako ta tvrtka jednog dana propadne, ne postoji jamstvo da e netko preuzeti cjelokupnu tehnoloku podrku. Dodue, krajem 2006. godine tvrtka Sun (pod ijim je okriljem Java stvorena) je otvorila kd u namjeri da ga uini slobo-dnim i javno dostupnim programskim kdom (engl. free and open-source software). U meuvremenu, tvrtku Sun je kupila tvrtka Oracle i nastavila s odravanjem i razvojem Jave.

    S druge strane, jezik C++ od samih poetaka nije u niijem vlasnitvu (ili to bi ne-ki rekli: ope je drutveno dobro), a njegov razvoj je pod nadzorom meunarodne organizacije za standardizaciju ISO/IEC. Odbor za standardizaciju ini nekoliko deseta-ka eksperata iz cijelog svijeta i podran je od najjaih svjetskih softverskih i hardverskih tvrtki.

    1.5. Usporedba s jezikom C

    C je jezik koji je izmislio Microsoft kao odgovor na Javu (a .NET platformu kao odgo-vor na Java virtualni stroj). Iako imenom podsjea na C++, jezik C je daleko sliniji Javi, s tom razlikom da C podrava neke stvari kojih u Javi nema. No, osnovne stvari koje su reene za Javu u prethodnom odjeljku u najveoj mjeri vrijede i za C.

    1.6. Ima li smisla u iti jezik C++?

    Zbog ponekad komplicirane sintakse, C++ esto prati glas vrlo neitljivog i komplicira-nog jezika. Jedan od glavnih uzroka tome je viestruki pristup podacima: podacima moemo pristupati izravno, preko pokazivaa (odn. adrese) i preko reference. Ti razliiti naini pristupa podacima pruaju fleksibilnost koja nije mogua u drugim jezicima, ali

    Dem

    istifi

    cira

    ni C

    ++

    4. iz

    danj

    e (

    201

    4)

    www.

    elem

    ent.h

    r

  • 14 1. To C++ or not to C++?

    su nerijetko i uzrok pogrekama koje poetnicima znaju zagorati ivot. Java i C, koji su razvijeni na iskustvima jezika C++, nemaju tako kompliciranu sintaksu i dobrim dijelom podravaju programske konstrukcije koje podrava jezik C++. Zbog toga je razvoj programa u tim (i slinim novijim programskim jezicima) bri nego u jeziku C++. Meutim, C++ ima nekoliko bitnih prednosti od kojih emo spomenuti najvanije.

    Izvedbeni kd je u strojnom jeziku i optimiran za odredino raunalo tako da je br-zina izvoenja maksimalna. tovie, kd u jeziku C++ moe biti napisan tako da izrav-no barata s memorijom ili sa sklopovljem raunala.

    Predloci (engl. templates) u jeziku C++ omoguavaju pisanje generikog kda koji se moe primijeniti na razliite tipove podataka. No to nije sve: predloci se mogu koris-titi za automatizirano generiranje kda. Iako Java i C podravaju generike tipove, ta podrka je, u odnosu na ono to pruaju predloci u jeziku C++, simbolina i slui is-kljuivo za osiguranje tipske sigurnosti (engl. type-safety), tj. onemoguava pridruiva-nje i operacije izmeu meusobno nekompatibilnih tipova.

    Zadnja, ali ne najmanja vana prednost jezika C++ jest njegova rasprostranjenost i popularnost. Po svim statistikama, jezik C++ je trenutno (sijeanj 2014.) meu tri-etiri najpopularnija programska jezika (vidi npr. http://www.langpop.com), a zajedno s jezi-kom C (koji se u tim statistikama vodi zasebno) uvjerljivo vodi.

    1.7. Zato primjer iz knjige ne radi na mom ra unalu?

    Primjeri kda u knjizi su usklaeni s aktualnim Standardom jezika C++ iz 2011. godine. Testirali smo ih pomou prevoditelja koji je uglavnom usklaen sa Standardom, ... ali nikad se ne zna. Lako se moe dogoditi da se poneki primjer ne moe prevesti ili da ne radi ono to je napisano u knjizi zbog pogreke koju smo napravili u pripremi knjige.

    Drugi razlog moe biti neusklaenost prevoditelja kojeg koristite sa Standardom. Naime, zahvaljujui velikoj popularnosti jezika C, programski jezik C++ se brzo proi-rio i prilino rano su se pojavili mnogi komercijalno dostupni prevoditelji. Od svoje pojave, jezik C++ se dosta mijenjao, a prevoditelji su kaskali za tim promjenama. Zbog toga se esto dogaalo da je program koji se dao korektno prevesti na nekom prevoditelju, bio neprevodiv ve na sljedeoj inaici prevoditelja istog proizvoaa.

    Takva raznolikost i nekompatibilnost prevoditelja nagnala je Ameriki Nacionalni Institut za Standarde (American National Standards Institute, ANSI) da krajem 1989. godine osnuje odbor (s kdnom oznakom X3J16) iji je zadatak bio napisati Standard za jezik C++. Osim eminentnih strunjaka (poput g. Stroustrupa) u radu odbora sudjelovali su i predstavnici svih najznaajnijih softverskih tvrtki. U lipnju 1991. rad odbora je preao u nadlenost Meunarodne Organizacije za Standarde (International Standards Organization, ISO). 14. studenog 1997. godine prihvaen je ISO standard jezika C++ (ISO/IEC 14882, poznat pod nazivom C++98), koji je ratificiran 1998. 2003. godine prihvaena je aurirana verzija standarda (C++03) koja je ukljuivala samo ispravke i nije donijela nikakve bitne promjene u jezik.

    Odbor za standardizaciju nastavio je raditi na sljedeoj verziji Standarda jezika, ko-ja je prihvaena u kolovozu 2011. pod nazivom C++11. Taj Standard unosi u jezik niz novina koje e biti opisane u ovoj knjizi, ali odrava i kompatibilnost prema postojeem

    Dem

    istifi

    cira

    ni C

    ++

    4. iz

    danj

    e (

    201

    4)

    www.

    elem

    ent.h

    r

  • 1.8. Literatura 15

    kdu sav postojei kd (ukljuujui i primjere iz prethodnih izdanja knjige) bi se i dalje, bez promjena, morao moi prevoditi na novijim prevoditeljima usklaenim sa standardom C++11. Za oekivati je da e protei jo koja godina prije nego svi prevodi-telji u potpunosti budu podravali zadnju inaicu Standarda (osobito se to odnosi na neke egzotinije konstrukte) pa se nemojte iznenaditi ako vam prevoditelj koji koristi-te otkae poslunost i pone prijavljivati pogreke na ispravnom kdu. U takvim situaci-jama svakako provjerite dokumentaciju koja dolazi uz prevoditelja.

    Sljedea verzija standarda, pod oznakom C++14 trebala bi se pojaviti tijekom 2014. godine, a ukljuivala bi tek neznatna poboljanja i ispravke pogreaka.

    Na kraju spomenimo da osim Standardiziranog C++-a, postoji i takozvani C++/CLI (od engl. Common Language Infrastructure). To je Microsoftovo proirenje jezika C++ sintaksom koja omoguava koritenje .NET okruenja (engl. .NET Platform). Budui da ova proirenja izlaze iz okvira standardnog jezika C++, neemo se njima baviti.

    1.8. Literatura

    Tijekom pisanja koristili smo literaturu navedenu na kraju knjige. Ponegdje se pozivamo na neku od tih knjiga, navodei pripadajuu oznaku u uglatoj zagradi. Od svih navede-nih knjiga, najreferentniji je trenutno aktualni standard jezika C++ iz 2011. godine; moe se kupiti kod Amerikog Nacionalnog Instituta za Standarde (ANSI) ili kod Me-unarodne Organizacije za Standardizaciju (ISO). Na Internetu se mogu nai besplatne radne verzije (engl. draft) Standarda1, dostupne u PDF (Acrobat Reader) formatu.

    Sm Standard ne preporuujemo za uenje jezika C++, a takoer vjerujemo da nee trebati niti iskusnijim korisnicima Standard je prvenstveno namijenjen proizvoaima softvera; svi prevoditelji (engl. compilers) bi se trebali ponaati u skladu s tim standar-dom. No, smatramo da bi svaki ozbiljni C++ programer morao imati knjigu B. Strous-trupa: The C++ Programming Language (etvrto izdanje!) to je uz Standard svakako najreferentnija knjiga u kojoj ete nai odgovor na vjerojatno svaki detalj vezan uz jezik C++ (knjigu ne preporuujemo za uenje jezika). Uz nju, najtopliju preporuku zasluuje knjiga S. Lippmana, J. Lajoie, B. E. Moo: C++ Primer (peto izdanje) u kojoj su neki detalji jasnije objanjeni nego u Stroustrupovoj knjizi.

    Zadnje poglavlje ove knjige posveeno je principima objektno orijentiranog prog-ramiranja. Literatura vezana za to podruje nije striktno vezana uz jezik C++, tako da je u popisu literature navedena zasebno. S navedenog popisa, svaki ozbiljniji programer trebao bi proitati naslove [Meyer97] i [Gamma95].

    Uz to, mnotvo odgovora te praktinih i korisnih rjeenja moe se nai na Internetu. Svakako preporuujemo posjet mrenim stranicama navedenima u popisu literature.

    Nakon to je izalo prvo izdanje knjige, jedan od najeih upita koje smo dobivali jest bio: Moe li se pomou vae knjige programirati u (MS) Windowsima?. Ova knji-ga prua osnove jezika C++ i vjerujemo da ete se, kada nakon par mjeseci zaklopite zadnju stranu, moi pohvaliti da ste nauili jezik C++. Za pisanje Windows programa trebaju vam, meutim, specijalizirane knjige koje e vas nauiti kako steeno znanje

    1 Iako se radi o radnim verzijama, one su gotovo u potpunosti identine slubenom Standardu.

    Dem

    istifi

    cira

    ni C

    ++

    4. iz

    danj

    e (

    201

    4)

    www.

    elem

    ent.h

    r

  • 16 1. To C++ or not to C++?

    jezika C++ iskoristiti za tu namjenu. Od takvih knjiga svakako vam preporuujemo (to nije samo naa preporuka!) sljedee dvije knjige, tono navedenim redoslijedom:

    Jeff Prosise: Programming Windows with MFC (2nd Edition), Microsoft Press, 1999, ISBN 1-57231-695-0

    Jeffrey Richter: Windows via C/C++, Microsoft Press, 2007, ISBN 978-0735663770.

    Iako se radi o dosta starim naslovima, osnovni koncepti se nisu mijenjali i te knjige su u velikoj mjeri jo uvijek aktualne.

    I na kraju, preporuujemo naslov koji smo koristili za neke od algoritama u primje-rima:

    Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest: Introduction to Algorithms, The MIT Press, Cambridge, MA, 1999, ISBN 0-262-03141-8

    1.9. Zahvale

    Zahvaljujemo se svima koji su nam izravno ili posredno pomogli pri izradi ove knjige. Posebno se zahvaljujemo Branimiru Pejinoviu (Portland State University) koji nam je omoguio da doemo do Nacrta ANSI C++ standarda iz 1997. godine, Vladi Glaviniu (Fakultet elektrotehnike i raunarstva) koji nam je omoguio da doemo do knjiga [Stroustrup94] i [Carroll95] te nam je tijekom pripreme za tisak dao na raspolaganje laserski pisa, te Zdenku imiu (Fakultet elektrotehnike i raunarstva) koji nam je, tijekom svog boravka u SAD, pomogao pri nabavci dijela literature.

    Posebnu zahvalu upuujemo Ivi Mesari koja je proitala cijeli rukopis te svojim korisnim i konstruktivnim primjedbama znatno doprinijela kvaliteti iznesene materije. Takoer se zahvaljujemo Zoranu Kalafatiu (Fakultet elektrotehnike i raunarstva) i Damiru Hodaku koji su itali dijelove rukopisa i dali na njih korisne opaske.

    Boris se posebno zahvaljuje gospoama ribar na tonama kolaa pojedenih za vri-jeme dugih, zimskih noi itanja i ispravljanja rukopisa, a koje su ga kotale kure mr-avljenja.

    I naravno, zahvaljujemo se Bjarne Stroustrupu i dekima iz AT&T-a to su izmislili C++, na najdrai programski jezik. Bez njih ne bi bilo niti ove knjige (ali moda bi bilo sline knjige iz FORTRAN-a).

    1.9.1. Zahvale uz drugo i tre e izdanje

    U prvom redu zahvaljujemo se svima koji su kupili prvo izdanje knjige koje je raspro-dano u relativno kratkom vremenu bez njih ne bi bilo drugog izdanja knjige. A onima koji su fotokopirali ili skenirali knjigu poruujemo da e se posthumno pei u vjenoj vatri Xeroxovih i Canonovih tonera, a djeca e im izgledati kao najloiji skenovi na prastarim UMAX skenerima (naravno, svoje grijehe e okajati unite li odmah fotokopi-ju/sken i kupe primjerak knjige u knjiari).

    Zahvale upuujemo i svima koji su dali prijedloge ili nas upozorili na pogreke u prvom i drugom izdanju.

    Dem

    istifi

    cira

    ni C

    ++

    4. iz

    danj

    e (

    201

    4)

    www.

    elem

    ent.h

    r

  • 17

    2. Vrijeme je da se krene...

    to je to naredba? Da ugasim svjetiljku. Dobra veer. I on je ponovo upali.

    Ne razumijem ree mali princ. Nema to tu razumjeti ree noobdija. Naredba je na-

    redba. Dobar dan. I on ugasi svoju svjetiljku.

    Antoine de Saint-Exupry (19001944), Mali princ

    U prvom poglavlju proletjet emo kroz osnovne pojmove vezane uz programiranje i upoznat emo se sa strukturom najjednostavnijih programa pisanih u programskom jeziku C++. Prvi odjeljak prvenstveno je namijenjen itateljicama i itateljima koji nisu nikada pisali programe u bilo kojem viem programskom jeziku i onima koji su to mo-da radili, ali je od tada prola itava vjenost. Slijedi odjeljak u kojem je opisano to itateljici ili itatelju sve treba za upis, prevoenje i testiranje primjera. Odjeljkom 2.3 poinje konkretni dio knjige.

    2.1. to je program i kako ga napisati

    Elektronika raunala su danas postala pribor kojim se svakodnevno koristimo kako bismo si olakali posao ili se zabavili. Istina, tonost prvog navoda e mnogi poricati, istiui kao protuprimjer injenicu da im je za podizanje novca prije trebalo znatno manje vremena nego otkad su alteri u banci kompjuterizirani. Ipak, injenica je da su mnogi poslovi danas nezamislivi bez raunala; u krajnjoj liniji, dokaz za to je knjiga koju upravo itate koja je u potpunosti napisana pomou raunala.

    Samo raunalo, ak i kada se ukljui u struju, nije kadro uiniti nita korisno. Na dananjim raunalima se ne moe ak ni zagrijati prosjeni ruak, to je inae bilo mo-gue na raunalima s elektronskim cijevima. Ono to vam nedostaje jest pamet neopho-dna za koristan rad raunala: programi, programi, mnotvo programa. Pod progra-mom tu podrazumijevamo niz naredbi u strojnom jeziku koje procesor u vaem raunalu izvodi i shodno njima obrauje podatke, provodi matematike proraune, ispisuje teks-tove, iscrtava krivulje na zaslonu ili gaa va avion F-16 raketama srednjeg dometa. Prilikom pokretanja s diska, DVD-ROM-a ili USB memorije, program se uitava u radnu memoriju raunala i procesor poinje s mukotrpnim postupkom njegova izvoe-nja.

    Programi koje pokreete na raunalu su u izvedbenom obliku (engl. executable), ra-zumljivom samo procesoru vaeg (i njemu slinih) raunala, sretnim procesorovim roditeljima negdje u Silicijskoj dolini i nekolicini zadrtih hakera irom svijeta koji jo uvijek programiraju u strojnom kdu. U sutini se strojni kd sastoji od nizova binarnih znamenki: nula i jedinica. Budui da su dananji programi tipino veliine vie mega-

    Dem

    istifi

    cira

    ni C

    ++

    4. iz

    danj

    e (

    201

    4)

    www.

    elem

    ent.h

    r

  • 18 2. Vrijeme je da se krene...

    bajta, nasluujete da ih autori nisu pisali iz-ravno u strojnom kdu (kamo sree da je tako ne bi Microsoft tek tako svake dvije godine izbacivao nove Windowse!).

    Gotovo svi dananji programi se piu u nekom od viih programskih jezika (FOR-TRAN, BASIC, Pascal, C) koji su donekle razumljivi i ljudima (barem onima koji imaju nekog pojma o engleskom jeziku). Naredbe u tim jezicima se sastoje od mnemonika. Kom-biniranjem tih naredbi programer slae izvorni kd (engl. source code) programa, koji se pomou posebnih programa prevoditelja (engl. compiler) i povezivaa (engl. linker) prevodi u izvedbeni kd. Prema tome, pisanje programa u uem smislu podrazumijeva pisa-nje izvornog kda. Meutim, kako pisanje kda nije samo sebi svrhom, pisanjem prog-rama u irem smislu ukljuuje i prevoenje, odnosno povezivanje programa u izvedbeni kd. Stoga moemo govoriti o etiri faze izrade programa:

    1. pisanje izvornog kda 2. prevoenje izvornog kda, 3. povezivanje u izvedbeni kd te 4. testiranje programa.

    Da bi se za neki program moglo rei da je potpuno zgotovljen, treba uspjeno proi kroz sve etiri faze.

    Kao i svaki drugi posao, i pisanje prog-rama iziskuje odreeno znanje i vjetinu. Prilikom pisanja programera vrebaju Scile i Haribde, danas poznatije pod nazivom po-greke ili bugovi (engl. bug - stjenica) u prog-ramu. Uoi li se pogreka u nekoj od faza izrade programa, izvorni kd treba doraditi i ponoviti sve prethodne faze. Zbog toga postu-pak izrade programa nije pravocrtan, ve manje-vie podsjea na mukotrpno petljanje u

    krug. Na slici 2.1 je shematski prikazan cjelokupni postupak izrade programa, od njego-va zaetka do njegova okonanja. Analizirajmo najvanije faze izrade programa.

    Prva faza programa je pisanje izvornog kda. U principu se izvorni kd moe pisati u bilo kojem programu za ureivanje teksta (engl. text editor), meutim velika veina dananjih prevoditelja i povezivaa se isporuuje kao cjelina zajedno s ugraenim prog-

    Poetak

    Upis i ispravkeizvornog kda

    Prevoenje

    Pogreke tijekomprevoenja?

    Da

    Povezivanje

    Pogreka tijekompovezivanja?

    Izvoenje programa

    Pogreke tijekomizvoenja?

    Konac

    Da

    Da

    Ne

    Ne

    Ne

    Slika 2.1. Tipian razvoj programa

    Dem

    istifi

    cira

    ni C

    ++

    4. iz

    danj

    e (

    201

    4)

    www.

    elem

    ent.h

    r

  • 2.1. to je program i kako ga napisati 19

    ramom za upis i ispravljanje izvornog kda. Te programske cjeline poznatije su pod nazivom integrirane razvojne okoline (engl. integrated development environment, IDE). Danas najpopularnije razvojne okoline za C++ su Visual Studio tvrtke Microsoft te besplatni i javno dostupni Code::Blocks, CodeLite, Eclipse CDT i Dev-C++ neovisnih autora. Nakon to je (prema obino nekritikom miljenju programera) pisanje izvornog kda zavreno, on se pohrani u datoteku izvornog kda na disku. Toj datoteci se obino daje nekakvo smisleno ime, pri emu se ono za kdove pisane u programskom jeziku C++ obino proiruje nastavkom .cpp , .cp ili samo .c , na primjer pero.cpp . Nastavak je potreban samo zato da bismo izvorni kd kasnije mogli lake pronai.

    Slijedi prevoenje izvornog kda. U integriranim razvojnim okolinama program za prevoenje se pokree pritiskom na neku tipku na zaslonu, pritiskom odgovarajue tipke na tipkovnici ili iz nekog od izbornika (engl. menu) ako prevoditelj nije integriran, poziv je neto sloeniji1. Prevoditelj tijekom prevoenja provjerava sintaksu napisanog izvornog kda i u sluaju uoenih ili nasluenih pogreaka ispisuje odgovarajue poruke o pogrekama ili upozorenja. Pogreke koje prijavi prevoditelj nazivaju se pogrekama pri prevoenju (engl. compile-time errors). Nakon toga programer e pokuati ispraviti sve navedene pogreke i ponovo prevesti izvorni kd sve dok prevoenje kda ne bude uspjeno okonano, nee se moi pristupiti povezivanju kda. Prevoenjem izvor-nog dobiva se datoteka objektnog kda (engl. object code), koja se lako moe prepozna-ta po tome to obino ima nastavak .o ili .obj (u naem primjeru bi to bio pero.obj ).

    Nakon to su ispravljene sve pogreke uoene prilikom prevoenja i kd ispravno preveden, pristupa se povezivanju (engl. linking) objektnih kdova u izvedbeni. U vei-ni sluajeva objektni kd dobiven prevoenjem programerovog izvornog kda treba povezati s postojeim bibliotekama (engl. libraries). Biblioteke su datoteke u kojima se nalaze ve prevedene gotove funkcije ili podaci. One se isporuuju zajedno s prevodite-ljem, mogu se zasebno kupiti ili ih programer moe tijekom rada sam razvijati. Biblio-tekama se izbjegava opetovano pisanje vrlo esto koritenih operacija. Tipian primjer za to je biblioteka matematikih funkcija koja se redovito isporuuje uz prevoditelje, a u kojoj su definirane sve funkcije poput trigonometrijskih, hiperbolnih, eksponencijalnih i sl. Prilikom povezivanja provjerava se mogu li se svi pozivi kdova realizirati u izved-benom kdu. Uoi li poveziva neku nepravilnost tijekom povezivanja, ispisat e poru-ku o pogreki i onemoguiti generiranje izvedbenog kda. Ove pogreke nazivaju se pogrekama pri povezivanju (engl. link-time errors) sada programer mora prionuti ispravljanju pogreaka koje su nastale pri povezivanju. Nakon to se isprave sve pogre-ke, kd treba ponovno prevesti i povezati.

    Uspjenim povezivanjem dobiva se izvedbeni kd programa. Taj kd e raditi up-ravo ono to je programer zadao naredbama izvornog kda, no sasvim je mogue da to ne odgovara onome to je izvorno zamislio. Program e sadravati logike pogreke. Primjerice, moe se dogoditi da program radi pravilno samo za neke podatke, dok se za druge podatke ponaa nepredvidivo. U tom sluaju radi se o pogrekama pri izvoenju (engl. run-time errors). Da bi program bio potpuno korektan, programer treba istestirati program da bi uoio i ispravio te pogreke, to znai ponavljanje cijelog postupka u

    1 Ovdje neemo opisivati konkretno kako se pokreu postupci prevoenja ili povezivanja, jer to

    varira ovisno o prevoditelju, odnosno povezivau.

    Dem

    istifi

    cira

    ni C

    ++

    4. iz

    danj

    e (

    201

    4)

    www.

    elem

    ent.h

    r

  • 20 2. Vrijeme je da se krene...

    lancu ispravljanje izvornog kda - prevoenje - povezivanje - testiranje. Broj ponavlja-nja e biti manji to je program jednostavniji i iskustvo programera vee. Meutim, kako raste sloenost programa, tako se poveava broj moguih pogreaka i cijeli postu-pak izrade programa neiskusnom programeru moe postati mukotrpan.

    Za ispravljanje pogreaka pri izvoenju, programeru na raspolaganju stoje programi za otkrivanje pogreaka (engl. debugger - doslovni prijevod bio bi istjeriva stjenica ili buba, odnosno stjeniji terminator). Radi se o programima koji omoguavaju prekid izvoenja izvedbenog kda programa koji testiramo na unaprijed zadanim naredbama, izvoenje programa naredbu po naredbu, ispis i promjene trenutnih vrijednosti pojedinih podataka u programu. Najjednostavniji programi za otkrivanje pogreaka ispisuju iz-vedbeni kd u obliku strojnih naredbi. Meutim, veina dananjih naprednih programa za otkrivanje pogreaka su simboliki (engl. symbolic debugger) iako se izvodi preve-deni, strojni kd, izvoenje programa se prati preko izvornog kda pisanog u viem programskom jeziku. To omoguava vrlo lagano lociranje i ispravljanje pogreaka u izvornom kdu programa. tovie, veina integriranih razvojnih okolina u sebi ukljuuje module za otkrivanje pogreaka, tako da programer unutar nje ne samo da pie, prevodi i povezuje program, ve ga odmah moe testirati i ispravljati.

    Valja napomenuti da za simboliko debuggiranje, prevoditelj u izvedbeni kd mora ukljuiti i dodatne podatke, kao to je na primjer veza prema datotekama izvornog kda. Ti podaci omoguavaju da u svakom koraku izvoenja izvedbenog kda debugger zna koja naredba u izvornom kdu je taj odsjeak izvedbenog kda generirala. Uoimo rije odsjeak u prethodnoj reenici: prevoditelj svaku pojedinu naredbu u izvornom kdu razlae u niz strojnih instrukcija (na slici 2.2 prikazan je jedan primjer) te bi praenje izvoenja kda preko strojnih instrukcija (ak i preko njihovih asemblerskih mnemoni-ka) bilo izuzetno komplicirano ak i vinim programerima. Takoer, dodatni podaci u izvedbenom kdu omoguavaju da dobijemo ispis vrijednosti varijable preko imena koji smo za nju koristili ili ak da vrijednost varijable sami promijenimo. Oito je da e zbog tih dodatnih podataka koji su potrebni samo za debuggiranje, duljina izvedbenog kda biti vea. Za konanu verziju kda koji se isporuuje korisniku ti se podaci izostavljaju pomou odgovarajuih opcija u postavkama prevoditelja i povezivaa.

    Osim pogreaka, prevoditelj i poveziva redovito dojavljuju i upozorenja. Ona ne onemoguavaju nastavak prevoenja, odnosno povezivanja kda, ali predstavljaju po-tencijalnu opasnost. Upozorenja se mogu podijeliti u dvije grupe. Prvu grupu ine upo-

    naredba u izvornom kodu generirani strojni kd asemblerski mnemonici

    a = 5 c7 45 ec 05 00 00 00 mov dword ptr [a],5

    b = a + 3

    8b 45 ec 83 c0 03 89 45 e0

    eax,dword ptr [a] eax,3 dword ptr [b],eax

    Slika 2.2. Primjer naredbi u viem programskom jeziku i pripadajueg generiranog strojnog kda u heksadekadskom prikazu te asemblerskih mnemonika

    Dem

    istifi

    cira

    ni C

    ++

    4. iz

    danj

    e (

    201

    4)

    www.

    elem

    ent.h

    r

  • 2.2. Boj ne bije svjetlo oruje, ve srce u junaka 21

    zorenja koja javljaju da kd nije potpuno korektan. Prevoditelj ili poveziva e zanema-riti nau pogreku i prema svom nahoenju generirati kd. Drugu grupu ine poruke koje upozoravaju da nisu sigurni je li ono to smo napisali upravo ono to smo eljeli napisati, tj. radi se o dobronamjernim upozorenjima na zamke koje mogu proizii iz naina na koji smo program napisali. Iako e, unato upozorenjima, program biti preve-den i povezan (moda ak i korektno), pedantan programer nee ta upozorenja nikada zanemariti ona esto upuuju na uzrok pogreaka pri izvoenju gotovog programa. Za precizno tumaenje poruka o pogrekama i upozorenja neophodna je dokumentacija koja se isporuuje uz prevoditelj i poveziva.

    Da zakljuimo: to nam dakle treba za pisanje programa u jeziku C++? Osim ra-unala, programa za pisanje i ispravljanje teksta, prevoditelja i povezivaa trebaju vam jo samo tri stvari: interes, puno slobodnih popodneva i dooobra knjiga. Interes vjerojat-no postoji ako ste s itanjem stigli ak do ovdje. Slobodno vrijeme e vam trebati da isprobate primjere i da se sami okuate u bespuima C++ zbiljnosti. Jer, kao to stari junohrvatski izrijek kae: Nima dopisne kole iz plivanja. Stoga ne gubite vrijeme i odmah otkaite sudar deku ili curi. A za dooobru knjigu(ta-ta-daaam tu sada mi upadamo!).

    2.2. Boj ne bije svjetlo oruje, ve srce u junaka

    Nakon to ste uz hrpu neuvjerljivih isprika uspjeli otkazati sudar, otvorili ste knjigu na ovoj stranici, ukljuili raunalo i zbunjeno zurite u ekran ... to sada? to mi jo fali? Ponovimo jo jednom to nam je neophodno za izradu programa (osnovne upute za koritenje nekih najpopularnijih prevoditelja itatelj moe nai u Prilogu D).

    2.2.1. Integrirana razvojna okolina

    Za poetnika e svakako biti najbolje da instalira neku integriranu razvojnu okolinu koja u sebi ve ukljuuje prevoditelja, poveziva i modul za otkrivanje pogreaka. Uz najpo-znatiju komercijalnu razvojnu okolinu, Microsoftov Visual Studio, na raspolaganju su i besplatne razvojne okoline1. Microsoft nudi besplatnu inaicu Visual Studio Express, koja se od komercijalne verzije razlikuje samo po nekim mogunostima koje za poet-nika nisu bitne. Za one koji zaziru od Microsofta ili ele raditi na operacijskom sustavu koji ne spada u skupinu Microsoftovih Windowsa, preporuujemo Code::Blocks ili Eclipse koji omoguavaju razvoj programa na Windows, Linux i Mac OS X operacijskim sustavima. Code::Blocks je razvojna okolina napravljena iskljuivo za pisanje programa u jeziku C++. Eclipse je razvojna okolina koja se moe koristiti za pisanje programa u itavom nizu programskih jezika, a za izradu C++ programa neophodan je CDT dodatak (engl. plugin). Obje razvojne okoline koriste zasebne prevoditelje i module za otkrivanje pogreaka treih proizvoaa. Ti moduli mogu se zasebno instalirati i konfigurirati, ali su redovito ve ukljueni u instalacijski program.

    1 Koritenje takvih razvojnih okolina je besplatno samo za osobnu upotrebu; za komercijalnu

    izradu programa valja proitati uvjete licenciranja.

    Dem

    istifi

    cira

    ni C

    ++

    4. iz

    danj

    e (

    201

    4)

    www.

    elem

    ent.h

    r

  • 22 2. Vrijeme je da se krene...

    2.2.2. Prevoditelj i poveziva

    Prevoditelj (engl. compiler) je program koji e nam omoguiti da programe pisane u jeziku C++ prevedemo u izvedbeni kd. Dananji prevoditelji najee imaju pridruen poveziva (engl. linker), tako da ga ne treba posebno instalirati. Prevoditelji i povezivai se pokreu iz komandne linije, navoenjem neophodnih parametara, to za poetnika moe biti prilino mukotrpno i podlono pogrekama. Daleko je jednostavnije pokretati ih iz razvojne okoline, pritiskom na neku tipku ili odabirom stavke u izborniku.

    Osim Microsoftovog prevoditelja koji se isporuuje uz Visual Studio, najpopularniji prevoditelji za programe pisane u jeziku C++ su GCC (GNU Compiler Collection) i Clang. Oba prevoditelja su besplatna, a GCC je vrlo esto ukljuen u instalacije razvoj-nih okolina, poput spomenutih Code::Blocks i Eclipse.

    Bez obzira hoete li koristiti neki komercijalni ili neki besplatni prevoditelj, za is-probavanje primjera iz ove knjige vano je da bude usklaen s najnovijim standardom jezika C++ ili da ga barem veim dijelom podrava.

    2.2.3. Program za ure ivanje teksta

    Ako imate integriranu razvojnu okolinu, u njoj je ukljuen i vrlo moan urednik teksta. Veina tih urednika podrava sintaksno isticanje (engl. syntax highlighting) tako da kljune rijei jezika, imena varijabli, tekstove, komentare prikazuje u razliitim bojama. To omoguava uoavanje pogreaka ve tijekom pisanja kda.

    Odluite li se koristiti prevoditelj iz komandne linije, trebat e vam zasebni urednik teksta (engl. text editor) u kojem ete izvorni kd upisivati, ispravljati te pohraniti na disk prije pokretanja prevoditelja. Postoje urednici teksta koji podravaju sintaksno isticanje za jezik C++, a mogu se i konfigurirati da se iz njih pokree prevoenje prog-rama. U krajnjoj nudi, za pisanje programa moe posluiti i Notepad pod Windowsima ili vi-editor pod Linuxom. Namjeravate li koristiti neki moniji urednik teksta, pripazite da izvorni kd pohranjujete kao isti tekst, a ne u nekom posebnom formatu.

    2.2.4. Program za otkrivanje pogreaka

    On e vam omoguiti da, kada jednom uspjeno prevedete i pokrenete program, lake otkrijete pogreke u programu. Integrirane razvojne okoline imaju ga ve u sebi uklju-ene tako da je mogue vrlo jednostavno pratiti izvoenje kda, naredbu po naredbu, te u svakom trenutku provjeriti vrijednosti pojedinih podataka.

    Uz komandne prevoditelje ponekad dolaze i pripadajui debuggeri, koji dodue nemaju rasko integriranih programa za otkrivanje pogreaka, ali slue svojoj svrsi.

    2.3. Moj prvi i drugi C++ program

    Nakon to smo se konano naoruali svim potrebnim, bez mnogo okolianja i filozofi-ranja, napiimo najjednostavniji program u jeziku C++:

    Dem

    istifi

    cira

    ni C

    ++

    4. iz

    danj

    e (

    201

    4)

    www.

    elem

    ent.h

    r

  • 2.3. Moj prvi i drugi C++ program 23

    int main() { return 0; }

    Utipkate li nadobudno ovaj program u svoje raunalo, pokrenete odgovarajui prevodi-telj, te nakon uspjenog prevoenja pokrenete program, na zaslonu raunala sigurno neete dobiti nita! Nemojte se odmah hvatati za glavu, laati telefona i zvati svoga dobavljaa raunala. Gornji program zaista nita ne radi, a ako neto i dobijete na zaslo-nu vaeg raunala, znai da ste negdje pogrijeili prilikom utipkavanja. Unato jalovosti gornjeg kda, promotrimo ga, redak po redak.

    U prvom retku je napisano int main() . main je naziv za glavnu funkciju u svakom C++ programu (u nekim programskim jezicima glavna funkcija se zove glavni program, a sve ostale funkcije potprogrami). Izvoenje svakog programa zapoinje i zavrava naredbama koje se nalaze u njoj.

    Pritom valja uoiti da je main samo simboliko ime koje daje do znanja prevoditelju koji se dio programa treba prvo poeti izvoditi ono nema nikakve veze s imenom izvedbe-nog programa koji se nakon uspjenog prevoenja i povezivanja dobiva. eljeno ime izvedbenog programa odreuje sam programer: ako se koriteni prevoditelj pokree iz komandne linije, ime se navodi kao parametar u komandnoj liniji, a ako je prevoditelj ugraen u neku razvojnu okolinu, tada se ime navodi kao jedna od postavki projekta. Tone detalje definiranja imena izvedbenog imena itateljica ili itatelj nai e u uputa-ma za prevoditelj kojeg koristi.

    Rije int ispred oznake glavne funkcije ukazuje na to da e main() po zavretku izvoenja naredbi i funkcija sadranih u njoj kao rezultat tog izvoenja vratiti cijeli broj (int dolazi od engleske rijei integer koja znai cijeli broj). Budui da se glavni prog-ram pokree iz operacijskog sustava (Linux, Mac OS, MS Windows), rezultat glavnog programa se vraa operacijskom sustavu. Najee je to kd koji signalizira pogreku nastalu tijekom izvoenja programa ili obavijest o uspjenom izvoenju. Taj kd e operacijski sustav ili program koji je pozvao na program, eventualno iskoristiti da bi odabrao daljnje akcije koje treba poduzeti.

    Iza rijei main slijedi par otvorena-zatvorena zagrada () . Unutar te zagrade trebali bi doi opisi podataka koji se iz operacijskog sustava prenose u main() . Ti podaci nazi-vaju se argumenti ili parametri funkcije. Za funkciju main() to su parametri koji se pri pokretanju programa navode u komandnoj liniji iza imena programa, kao na primjer:

    dir /p /s

    Ovom naredbom se pokree program (komanda) dir za ispis sadraja kazala i pritom se predaju dva parametra: /p i /s . U naem C++ primjeru unutar zagrada nema nita, to

    Svaki program napisan u C++ jeziku mora imati tono (ni manje ni vie) jednu main() funkciju.

    Dem

    istifi

    cira

    ni C

    ++

    4. iz

    danj

    e (

    201

    4)

    www.

    elem

    ent.h

    r

  • 24 2. Vrijeme je da se krene...

    znai da ne prenosimo nikakve argumente. Tako e i ostati do daljnjega, tonije do poglavlja 8 u kojem emo detaljnije obraditi funkcije, a zasebno i funkciju main() .

    Iza main() slijedi otvorena vitiasta zagrada { . Ona oznaava poetak bloka nared-bi u kojem e se nalaziti naredbe glavne funkcije, dok zatvorena vitiasta zagrada } u zadnjem retku oznaava kraj tog bloka . U samom bloku prosjeni itatelj (neupuen u vjetinu itanja tarot karata) uoit e samo jednu naredbu, return 0 . Tom naredbom glavni program vraa pozivnom programu broj 0, a to je poruka operacijskom sustavu da je program uspjeno okonan, togod on radio.

    Uoimo znak ; (toka-zarez) iza naredbe return 0. On oznaava kraj naredbe te prevoditelju daje do znanja da sve znakove koji slijede interpretira kao novu naredbu.

    Radi kratkoe emo u veini primjera u knjizi izostavljati uvodni i zakljuni dio glavne funkcije te emo podrazumijevati da oni u konkretnom kdu postoje.

    Pogledajmo jo na trenutak to bi se dogodilo da smo kojim sluajem napravili ne-ku pogreku prilikom upisivanja gornjeg kda. Recimo da smo zaboravili desnu vitias-tu zagradu na kraju kda:

    int main() { return 0;

    Prilikom prevoenja prevoditelj e uoiti da funkcija main() nije pravilno zatvorena, te e ispisati poruku o pogreki oblika Pogreka u prvi.cpp redak xx: sloenoj naredbi nedostaje } u funkciji main(). U ovoj poruci je prvi.cpp ime datoteke u koju smo na izvorni kd pohranili, a xx je broj retka u kojem se pronaena pogreka nalazi.

    Zaboravimo li napisati naredbu return :

    int main() { }

    neki prevoditelji e javiti upozorenje oblika Funkcija bi trebala vratiti vrijednost. Iako se radi o pogreki, prevoditelj e umetnuti odgovarajui kd prema svom nahoenju i prevesti program. Ne mali broj korisnika e zbog toga zanemariti takva upozorenja. Meutim, valja primijetiti da esto taj umetnuti kd ne odgovara onome to je progra-mer zamislio. Zanemarivanjem upozorenja programer gubi pregled nad korektnou kda, pa se lako moe dogoditi da rezultirajui izvedbeni kd daje na prvi pogled neob-janjive rezultate.

    Zadatak: Izbacite iz gornjeg kda desnu vitiastu zagradu } te pokuajte prevesti kd. Pogledajte koje e pogreke i upozorenja javiti prevoditelj.

    Znak ; mora zakljuivati svaku naredbu u jeziku C++.

    Dem

    istifi

    cira

    ni C

    ++

    4. iz

    danj

    e (

    201

    4)

    www.

    elem

    ent.h

    r

  • 2.3. Moj prvi i drugi C++ program 25

    Zadatak: U nekim knjigama starijeg datuma nije rijetkost nai da je funkcija main() navedena (definirana) kao:

    void main()

    gdje je void kljuna rije koja oznaava da funkcija ne vraa nita, tj. da (eventualno) obavlja nekakvu operaciju, ali ne vraa nikakav rezultat kdu koji je tu funkciju pozvao. Iako je ovakva definicija funkcije main neispravna jer nije u skladu sa standardom jezi-ka C++, zamijenite u prethodnom primjeru int oznaku tipa funkcije main() oznakom void i pokuajte prevesti kd. Nakon toga jo uklonite naredbu return 0 iz tijela fun-kcije main te ponovno prevedite program.

    Dok su vai programi relativno kratki, lake ete razluiti pogreku i povezati je s poru-kom prevoditelja. Gornji savjet e od posebne koristi biti onima koji nisu vini engles-kom jeziku (u kojem su poruke pa valjda svih C++ prevoditelja).

    Programi poput gornjeg nemaju ba neku praktinu primjenu, te daljnju analizu gornjeg kda preputamo poklonicima minimalizma. We need some action, man! Stoga pogledajmo sljedei primjer:

    #include using namespace std; int main() { cout

  • 26 2. Vrijeme je da se krene...

    li s njima dozvoljene operacije. Jedna od osnovnih znaajki (zli jezici e rei mana) jezika C++ jest vrlo oskudan skup funkcionalnosti ugraenih u sam jezik: u sam jezik nisu ugraeni niti jedna funkcija ili klasa, jezik definira svega desetak ugraenih tipova (3.4), a skup kljunih rijei (tj. rijei koji imaju specijalno znaenje u kdu) sastoji se svega od 70-ak rijei (vidi tablicu 3.1 na str. 46), od kojih se etvrtina vrlo rijetko koris-ti. Ta oskudnost olakava uenje samog jezika, te bitno pojednostavnjuje i ubrzava pos-tupak prevoenja. Za specifine zahtjeve na raspolaganju je veliki broj odgovarajuih biblioteka funkcija i klasa.

    Datoteke zaglavlja nalaze se obino u potkazalu include unutar kazala u kojem je instaliran prevoditelj. Znatieljnicima eljnima znanja preporuujemo da zavire u te datoteke budui da se u njima moe nai dosta korisnih informacija, ali svakako valja paziti da se sadraj tih datoteka ne mijenja.

    U drugom retku kda napisana je naredba using namespace std . using i namespace su kljune rijei jezika C++ kojima se aktivira odreeni imenski prostor ili imenik (engl. namespace), a std je naziv imenika u kojem su definirane sve standardne funkcije i tipovi, ukljuujui i one iz ve spomenute biblioteke iostream . Imenici su uvedeni da se izbjegne sraz istih imena funkcija, klasa ili objekata iz razliitih bibliote-ka. Na primjer, ako dvije razliite funkcije iz razliitih biblioteka imaju isto ime, prevo-ditelj e javiti pogreku ako ne moe razluiti koju od tih funkcija elimo doista pozvati (slino kao to dvije osobe s istim imenom moemo jednoznano razlikovati samo ako navedemo i njihova prezimena). Kada ne bismo imali na raspolaganju imenike, jedino rjeenje u takvom sluaju bilo bi promijeniti ime funkcije u jednoj od biblioteka, to esto nije mogue jer proizvoai redovito te biblioteke isporuuju u ve prevedenom obliku.

    Da nismo aktivirali cijeli imenik std , za svako ime definirano u tom imeniku mora-li bismo navesti puni naziv koji obuhvaa imenik i ime, meusobno odvojene operato-rom :: (dvije dvotoke). Konkretno, prethodni program bismo morali napisati kao:

    #include int main() { std::cout

  • 2.3. Moj prvi i drugi C++ program 27

    Ona je u programu napisana unutar znakova navodnika, koji upuuju na to da se radi o tekstu koji treba ispisati doslovce. Biblioteka iostream bit e detaljnije opisana kasnije, u poglavlju 21.

    Meutim, to jo nije sve! Iza znakovnog niza ponavlja se operator za ispis, kojeg slijedi endl . endl (od engl. end-of-line, kraj retka) je manipulator (21.6.6) u biblioteci iostream koji prebacuje ispis u novi redak, to jest vraa kursor na poetak sljedeeg retka na zaslonu.

    Matovita itateljica ili itatelj e sami zakljuiti da bi se operatori za ispis mogli dalje nadovezivati u istoj naredbi:

    cout

  • 28 2. Vrijeme je da se krene...

    neete uspjeti vidjeti niti na ovaj nain. Naime, u poglavlju o klasama i njihovim des-truktorima neki od primjera poruke ispisuju pri izlasku iz programa, tj. nakon gore spo-menutih naredbi.

    Zadatak: Kako bi izgledao izvorni kd ako bismo eljeli ispis endl znaka staviti u pose-bnu naredbu? Dodajte u gornji primjer ispis poruke Imamo C++!!! u sljedeem retku (popratno euforiko sklapanje ruku iznad glave nije neophodno). Nemojte zaboraviti dodati i ispis endl na kraju tog retka!

    Osvrnimo se jo jednom na smisao ukljuivanja datoteka zaglavlja. Podsjetimo se kako smo zbog izlaznog toka cout morali na poetku programa ukljuiti zaglavlje iostream i aktivirati imenik std . Kada tijekom analize programskog kda naleti na rije cout , budui da ona nije kljuna rije jezika, prevoditelj e pretraiti sva ukljuena zaglavlja ne bi li u njima pronaao znaenje (tj. definiciju) te rijei. Nakon to uspjeno pronae njenu definiciju, prevoditelj nastavlja s operatorom

  • 2.3. Moj prvi i drugi C++ program 29

    S druge strane, koritenje izlaznih tokova pojednostavljuje pisanje kda za ispis po-dataka. Programer ne mora eksplicitno specificirati kojeg je tipa podatak, ve e prevo-ditelj sam to zakljuiti i prikazati ga na odgovarajui nain. Ukoliko nam taj podrazumi-jevani nain ne odgovara, na raspolaganju su nam dodatni operatori kojima moemo dodatno fino ugoditi prikaz. Osim toga, funkcija printf() ograniena je samo na ispis u konzolu. elimo li iste podatke upisati u datoteku, morat emo upotrijebiti fun-kciju fprinf() , a za ispis u znakovni niz koji nam moe posluiti kao spremnik (buffer) posegnut emo za funkcijom sprintf() . S druge strane, izlazni tokovi omoguavaju da se istim naredbama podaci mogu ispisivati u konzolu, u datoteku ili u memorijski spremnik. Ulazno-izlazni tokovi bit e detaljno e opisani u 21. poglavlju.

    Prije nego to zavrimo s ovim odjeljkom, pozabavimo se jo malo manipulatorom endl kojim smo osigurali da se kursor prebaci na poetka novog retka. Isti efekt postigli bismo da smo umjesto endl u izlazni tok stavili znak za novi redak '\n' :

    cout

  • 30 2. Vrijeme je da se krene...

    2.4. Moj tre i C++ program

    Sljedei primjer je pravi mali dragulj interaktivnog programa:

    #include using namespace std; int main() { int a; // deklariramo varijablu za prvi broj cout > a; // unos prvog broja int b; // deklariramo varijablu za drugi broj cout > b; // unos drugog broja int c; // deklariramo varijablu za rezultat i c = a + b; // pridruujemo joj zbroj unesenih brojeva // ispisujemo rezultat: cout

  • 2.4. Moj trei C++ program 31

    poruke moete utipkavati bilo to i to po potrebi brisati tek kada pritisnete tipku Enter, program e analizirati unos te pohraniti broj koji je upisan u memoriju raunala.

    Radi saetosti kda, u veini primjera koji slijede, pretprocesorska naredba za ukljui-vanje iostream biblioteke nee biti napisana, ali se ona podrazumijeva. Koriste li se ulazno-izlazni tokovi, njeno izostavljanje prouzroit e pogreku kod prevoenja.

    No, zavrimo s naim primjerom. Nakon naredbi za unos prvog broja slijede potpu-no istovjetne naredbe za unos drugog broja b, a zatim slijedi naredba za raunanje zbro-ja

    c = a + b;

    Ona kae raunalu da treba zbrojiti vrijednosti varijabli a i b, te taj zbroj pohraniti u novodeklariranu varijablu c, tj. u memorijski prostor koji je prevoditelj rezervirao za tu varijablu. Vrijednost te varijable ispisuje se zadnjom naredbom prije naredbe return .

    U poetku e itatelj zasigurno imati problema s razluivanjem operatora >. U vjeri da e olakati razlikovanje operatora za ispis i uitavanje podataka, dajemo sljedei naputak.

    Primjerice,

    >> a

    preslikava vrijednost u a, dok

    moemo zamisliti kao strelice koje pokazuju smjer prije-nosa podataka [Lippman91].

    Dem

    istifi

    cira

    ni C

    ++

    4. iz

    danj

    e (

    201

    4)

    www.

    elem

    ent.h

    r

  • 32 2. Vrijeme je da se krene...

    Zadatak: Izostavite deklaracije varijabli a i b pa provjerite koje e pogreke javiti pre-voditelj.

    Ako ste primjere iz prethodnog odjeljka isprobavali na raunalu s Microsoft Windows operacijskim sustavom, zasigurno ste primijetili da se pri izvoenju programa slovo ne ispisuju ispravno. Problem nije u vaem raunalu, ve u nainu na koji konzola u Windowsima tretira znakove specifine hrvatskom jeziku (isto vrijedi za veinu znakova koji nisu iz engleske abecede). Budui da se radi o problemu koji je specifian za izvedbenu platformu a ne sam jezik C++, rjeenje problema navest emo u prilogu knjige. U daljnjim primjerima emo stoga izbjegavati znakove specifine za hrvatski jezik.

    2.5. Komentari

    Na nekoliko mjesta u navedenim primjerima kda moemo uoiti tekstove koji zapoi-nju dvostrukim kosim crtama (// ). Radi se o komentarima. Kada prevoditelj naleti na dvostruku kosu crtu, on e zanemariti sav tekst koji slijedi do kraja tekueg retka i pre-voenje e nastaviti u sljedeem retku. Komentari dakle ne ulaze u izvedbeni kd prog-rama i slue programerima za opis znaenja pojedinih naredbi ili dijelova kda. Komen-tari se mogu pisati u zasebnom retku ili recima, to se obino rabi za dulje opise, primje-rice to odreeni program ili funkcija radi:

    // // Ovo je moj trei C++ program, koji zbraja // dva broja unesena preko tipkovnice, a zbroj // ispisuje na zaslonu. // Autor: N. N. Hacker III //

    Za krae komentare, na primjer za opise varijabli ili nekih operacija, komentar se pie u nastavku naredbe, kao to smo vidjeli u primjerima.

    Uz gore navedeni oblik komentara, jezik C++ podrava i komentare unutar para znakova /* */ . Takvi komentari zapoinju slijedom /* (kosa crta i zvjezdica), a zavra-vaju slijedom */ (zvjezdica i kosa crta). Kraj retka ne znai podrazumijevani zavretak komentara, pa se ovakvi komentari mogu protezati na nekoliko redaka izvornog kda, a da se pritom znak za komentiranje ne mora ponavljati u svakom retku:

    /* Ovakav nain komentara preuzet je iz programskog jezika C. */

    Stoga je ovakav nain komentiranja naroito pogodan za (privremeno) iskljuivanje dijelova izvornog kda. Ispred naredbe u nizu koji elimo iskljuiti dodat emo oznaku /* za poetak komentara, a iza zadnje naredbe u nizu nadodat emo oznaku */ za zak-ljuenje komentara.

    Dem

    istifi

    cira

    ni C

    ++

    4. iz

    danj

    e (

    201

    4)

    www.

    elem

    ent.h

    r

  • 2.5. Komentari 33

    Iako komentiranje programa iziskuje dodatno vrijeme i napor, u kompleksnijim programima ono se redovito isplati. Dogodi li se da netko drugi mora ispravljati va kd, ili (jo gore) da nakon dugo vremena vi sami morate ispravljati svoj kd, komentari e vam olakati da proniknete u ono to je autor njime htio rei. Svaki ozbiljniji progra-mer ili onaj tko to eli postati mora biti svjestan da e nakon desetak ili stotinjak napisa-nih programa poeti zaboravljati emu pojedini program slui. Zato je vrlo korisno na poetku datoteke izvornog programa u komentaru navesti osnovne generalije, na primjer ime programa, ime datoteke izvornog kda, kratki opis onoga to bi program trebao raditi, funkcije i tipovi definirani u datoteci te njihovo znaenje, autor(i) kda, uvjeti pod kojima je program preveden (operacijski sustav, ime i oznaka prevoditelja):

    /********************************************************** Program: Moj trei C++ program Datoteka: Treci.cpp Funkcije: main() - cijeli program je u jednoj datoteci Opis: Uitava dva broja i ispisuje njihov zbroj Autori: Boris (bm) Julijan (j) Okruenje: Penderi MEeee Gledljivi C++ 14.0 prevoditelj **********************************************************/

    Prije su se u komentarima na poetku datoteke kronoloki navodile i promjene koje su na toj datoteci raene, tj. koji su dijelovi kda i funkcionalnosti dodavani, mijenjani ili uklanjani. Danas se to vie ne radi jer svaki ozbiljniji programski projekt koristi neki alat za praenje i nadzor promjena u izvornom kdu (engl. revision control, version control ili source control) u kojem se vodi evidencija o svim promjenama.

    Dobro i razumljivo pisani kd iziskuje vrlo malo komentara. Iako komentari u sa-mom izvornom kdu mogu doprinijeti njegovoj razumljivosti, s koliinom komentara ne treba pretjerivati, jer e u protivnom izvorni kd postati nepregledan. Naravno da ete izbjegavati banalne komentare poput:

    int a, b, c; // de