Sie sind auf Seite 1von 71

Programiranje 1

1. UVOD U PROGRAMIRANJE

1.1. O računarima

Bilo koji računarski sistem danas sastoji se od hardvera i softvera. Hardver


predstavljaju sve opipljive dijelove računarskog sistema, od tastatura, monitora,
centralnih jedinica i sve što one sadrže. Hardver nekog sistema može se sastojati i od
kilometra kablova, nekoliko stotina kilometara optičkih vodova, te cijele infrastrukture
koju određeni sistem koristi.
Softver je svaki neopipljivi (virtualni) dio računalnih sistema. U software spadaju svi
programi (sistemski i aplikacije), baze podataka, podaci spremljeni na raznim
čipovima, i doslovno svaki dio informacije unesen u računarski sistem.

Svi današnji računari temelji se na poznatoj Von Neumanovoj arhitekturi. Ova


arhitektura opisuje jednostavno računar, i nije se promijenila u više od pola stoljeća.

Ulaz Spremnik Izlaz


(memorija)

Upravljanje
(procesor)

Von Neumanova arhitektura računara

Eniac – prvo računar temeljeno na elektronskim cijevima. Snaga i brzina računara na


razini današnjih kalkulatora. Programiralo se pomoću premještanja kablova i
prespojnika. Kvarilo se je u prosjeku svakih par minuta. Energija potrebna za rad
zahtijevala je posebnu malu elektranu.

Od Eniaca do danas – Danas računar sa preko deset milijuna tranzistora stane na


par kvadratnih milimetara silicija, a energija potrebna za rad je zanemariva.

Von Neumanova arhitektura računara svejedno ograničava izradu programa na


današnjim računarima, tako da svaki program, koliko god složen bio mora biti
preveden i slijedno izvođen.

Svaki program unesen u računar sastoji se od niza informacija, a svaka informacija


zahtjeva mjesto za skladištenje.

Osnovna jedinica informacije u računarskim sistemima je bit. Bit kao elementarna


informacija može imati dvije vrijednosti: 1 ili 0. Svaka informacija u računarskom
sistemu sastoji se od niza bitova, uključujući programe, slike, baze podataka itd.

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 2

Često je nezgodno koristiti samo Bit kao jedinicu za količinu informacije, te zato
postoje i izvedene jedinice:
Byte – informacija koja se sastoji od 8 Bita, dakle od osam vrijednosti jedinica ili nula
Kilobyte (KB) – je količina informacija od 1024 Byta (ne 1000 kao što neki misle, već
zato što je 210=1024)
Megabyte (MB) – je isto što i 1024 KB odnosno 1048576 Byta
Gigabyte (GB) – sadrži 1024 MB informacija
Terabyte (TB) – je još uvijek rijetko korištena jedinica i sadrži 1024 GB informacija

Brzina računara se ne mjeri u MHz, već u broju operacija u sekundi. Obično se koristi
jedinica FLOPS (Floating point Operations Per Second) i govori koliko operacija sa
pomičnim zarezom računar napravi u sekundi. Ova jedinica je obično premala, pa se
koristi MFLOPS=1000000FLOPS.

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 3
2. OPĆENITO O PROGRAMIMA I PROGRAMSKIM JEZICIMA

Računarski program je skup naredbi koji govori računaru na koji način da obavi
određeni zadatak. Tekst programa koji je čitljiv programeru i korisniku zove se izvorni
kod programa, dok je izvršna verzija programa binarna, i može je čitati i izvoditi samo
računar.

Programski jezik je skup leksičkih, sintaksnih i semantičkih pravila koja uobličuju


strogu strukturu pisanja izvornog koda.

Svaki program sastoji se od naredbi. Naredbe se sastoje, u ovisnosti o programskom


jeziku, od izraza, konstanti, identifikatora i poziva.

Općenito postoji više razina programskih jezika, i podijeljeni su u generacije jezika.


Do danas postoje jezici od prve do pete generacije, no to nije jedina podjela
programskih jezika, oni se također razlikuju po namjeni, načinu izvršavanja,
strukturiranosti i proceduralnosti.

2.1. Podjela programskih jezika po namjeni:


Programski jezici za numeričke probleme
Programski jezici za poslovne probleme
Programski jezici temeljeni na listama i nizovima
Višenamjenski jezici (u ovu skupinu spadaju .NET jezici)

2.2. Podjela po načinu izvođenja:


Imperativni – postižu funkcionalnost pridjeljivanjem vrijednosti i njihovim ispitivanjem,
te skokovima (Ada, C, FORTRAN, Pascal)
Funkcionalni jezici – ne postoji pridruživanje, temelje se na funkcijama i listama (Lisp,
ML, LOGO)
Ciljno orijentirani jezici – temelje se na izvršavanju upita, dok način na koji se on
izvršava ostaje sakriven (Sql, Prolog)
Objektno orijentirani jezici – temelje se na manipulaciji objektima (VB 6.0)
Hibridni jezici – u ovu skupinu spadaju .NET jezici i C++

Po strukturiranosti jezici mogu biti strukturirani i nestrukturirani

Po proceduralnosti mogu biti proceduralni i neproceduralni

Generacijsku podjelu danas smatraju najbitnijom.

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 4
2.3. Podjela programskih jezika po generacijama

Jezici prve generacije temelje se na strojnom jeziku, tj. kodovima naredbi koje izvodi
direktno sam procesor. Programi su napisani u binarnim kodovima, i vrlo su nečitljivi.
Kasnije su dodani simbolični nazivi naredbama, no skokovi su bili izvedeni prema
hardverskim adresama koje su zadane brojem.

Primjer programa u strojnom kodu:

Zanimljivo je što se i danas svaki program na kraju svodi na ovu razinu, jer to je jedini
oblik programa koji računar razumije. Za prevođenje jezika viših razina u jezike niže
razine koriste se programi zvani prevodioci ili compileri.

Drugu generaciju programskih jezika predstavljaju simbolički programski jezici ili


Assembli. Od jezika prve generacije razlikuje se u tome što su uvedena simbolička
imena adresa (labeli) i jednostavniji pristup adresiranjima putem mnemoničkih kodova
pojedinih naredbi. Mnenonik ili mnemonički kod je simbolički prikaz binarne naredbe,
npr. Naredba 001011 predstavlja se mnemonikom MOV.

Primjer programa pisanog u jeziku druge generacije:

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 5

Programski jezici treće generacije temelje se na proceduralnoj paradigmi, tj.


Program se izvodi putem pozivanja procedura, osim samo jednostavnog dodjeljivanja
vrijednosti i njihovog ispitivanja. Ovakvi jezici prevode se u jezike nižih razina da bi se
mogli izvoditi, i često jedna naredba jezika ove razine predstavlja mnogo naredbi
jezika niže razine. Uneseno je razrješivanje izraza i prevoditelj vrši niz analiza koje
olakšavaju pisanje programa i ispravljanja pogrešaka.
U ovu skupinu pripadaju jezici C, Pascal i drugi.

Primjer jezika pisanog u jeziku treće generacije:

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 6
Jezici četvrte generacije temelje se uglavnom ma objektno orijentiranoj paradigmi, te
raznim generatorima koda i korisničkim sučeljima. Ovi jezici su obično kombinacija
raznih alata, tako da je većina napornih i dugotrajnih postupaka automatizirana i
pojednostavljena. U ovu skupinu pripadaju .NET jezici, Java, Delphi itd. Program
napisan u jeziku četvrte generacije predstavlja alat za brzu i jednostavnu izradu svih
vrsta aplikacija.

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 7
Primjer aplikacije u jeziku 4. generacije:

Jezici pete generacije su uglavnom usko specijalizirani jezici koji često kreiraju cijele
aplikacije potpuno automatski putem raznih Wizarda i slično. Razvoj ovakvih jezika je
u početnoj fazi.

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 8
2.4. PROGRAMSKI PRISTUPI
2.4.1.Neproceduralno programiranje

Ovaj pristup programiranju temelji se na slijednom izvođenju nekog programa.


Uglavnom se sastoji od jednostavnog niza naredbi gdje je izvedeno grananje putem
goto ili slične naredbe. Ne postoje pozivi metoda i funkcija. Ovi jezici su zastarjeli i
nedovoljno razvijeni za današnje potrebe.

2.4.1. Proceduralno programiranje

Temelji se na izvršavanju slijednog programa, s time da je moguće pozivati određene


dijelove koda iz nekog drugog konteksta, i povratak nakon poziva. Ovaj pristup
omogućava složenije strukture pisanja koda uključujući rekurzije.

2.4.2. Modularno programiranje

Modularno programiranje omogućava fragmentaciju koda na module koji mogu biti


pisani u različitim datotekama, i tako pojednostavljuje programe i povećava njihovu
čitljivost. Unesen je pojam dijeljenja koda između aplikacija.

2.5. Event driven arhitektura (Arhitektura temeljena na obradi događaja)

Ova paradigma temelj je programskih jezika čija glavna namjena je obrada nekih
događaja koji se dešavaju u izvođenju koda. Ova arhitektura je u potpunosti
drugačija od proceduralne, zato jer ne postoji neki glavni kod koji se izvršava, već se
čeka na neki događaj (zahtjev operativnog sistema, unos podataka od korisnika itd.) i
tek kada se on desi, započinje se poziv proceduralnog niza koji ga obrađuje. Na ovoj
arhitekturi temelji se VB 6.0

2.6. Objektno orijentirana paradigma

Najnovija paradigma koja se temelji na objektima i odnosima između njih. Svaki


objekt može imati svoja svojstva, metode i akcije koje taj objekt opisuju, a izvođenje
koda je takvo da se «objekti brinu sami o sebi» i komuniciraju sa drugim objektima.
Pod time da objekti «brinu sami o sebi» misli se da je njihov kod neovisan o nekim
vanjskim objektima sa kojima on komunicira, i koji koriste svojstva tog objekta. Na
ovoj arhitekturi temelji se većina komercijalnih programskih jezika danas.

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 9
2.7. OSNOVE FAZE RAZVOJA PROGRAMIRANJA

¾ Analiza problema
¾ Postavljanje modela
¾ Izrada algoritma
¾ Izrada dijagrama toka
¾ Kodiranje programa
¾ Prevođenje programa
¾ Testiranje programa
¾ Dokumentiranje programa
¾ Eksploatacija programa

Svrha programa je rješavanje problema, najčešći način rješavanja je pomoću tri


modela prikazano na slici 1:
¾ model podataka
¾ model procesa i
¾ model resursa.

model rješenja:
• Model podataka sadrži definiciju podataka (nazive, vrste, dimenzije,
ograničenja
• vrijednosti...) te strukture podataka (nizovi, skupovi, datoteke, tablice...)
• Model procesa može biti prikazan različitim tehnikama (dijagram toka,
dijagram strukture procesa, dijagrami akcija....), ali svi oni, na svoj
način, prikazuju slijed odvijanja procesa.
• Model resursa sadrži definiciju računalnih resursa i njihovih svojstva
(operacijski sistem, vrsta programskog prevodioca, svojstva jedinica
računara...) koje su potrebne da bi program uredno radio.

Model
procesa

Model
Model
podataka
podataka

slika 1 – Shema riješavanja problema

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 10

3. ALGORITMI

Pojam algoritama (dijagram toka) je jedan od najstarijih i najvažnijih pojomova u


matematici. Teško je da se precizno definiše algoritma, jer pripada grupi osnovnih
pojmova kao što su skup ili tačka. Samo ime dolazi od imena srednjovjekovnog
uzbekistanskog matematičara Al-CHWARIZMI koji je još u IX vjeku analizirao ovu
problematiku. U početku algoritmom se nazivaju samo pravila računanja s brojevima,
kasnije i pravila obavljanja ostalih zadataka u matematici, u XX vjeku, pojavom
računara, pojam se proširuje na informatiku, a zatim i na druga područja. Precizan
opis svih pravila i postupaka potrebnih za postizanje željenog rezultata. Evo nekih
definicija koje bliže opisuju algoritam.

Definicija 1.
Algoritam je tačan opšte razumljiv propis koji definiše proces transformacije početnih
podataka u traženi rezultat.

Definicija 2.
Algoritam je tačan propis o tome koje operacije nad kojim brojevima i u kom
redosljedu treba izvršiti da bi se rješili svi zadaci nekog zadatog tipa.

Definicija 3.
Algoritam je konačni skup pravila koja daju redosljed operacija za rješavanje
specifičnog problema.

Najbitnije osobine algoritma su:

¾ Određenost je osobina algoritma da za iste početne podatke daje uvjek


iste rezultate.
¾ Razumljivost. algoritam treba da bude razumljiv. ovo je relativni pojam i
zavisi od nivoa obrazovanja korisnika.
¾ Masovnost je osobina algoritma da se mogu rješavati svi zadaci istog
tipa.Rezultativnost je osobina algoritma da on mora da vodi ka rješenju
zadatka ako su početni podaci iz skupa mogućih podataka.
¾ Konačnost je osobina algoritma da se algoritam realizuje sa konačno
mnogo koraka. Pri tome ta konačnost treba da je ostvarljiva, tj. da može
da se realizuje za neko razumno vrijeme.

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 11
3.1. Šematsko prikazivanje algoritma

POČETAK, KRAJ ULAZ JE SA


TASTATURE

SMJER U KOME SE
ODVIJA ALGORITAM IZLAZ JE
MONITOR

IZLAZNI UREĐAJ
ULAZ PODATAKA JE PRINTER

IZLAZ PODATAKA RADNI BLOK

ULAZ/IZLAZ
PODATAKA ODLUKA

ULAZ JE SA
BUŠENIH KARTICA KONEKTOR

Primjer algoritma

Bilo koji problem se može riješiti izvršavanjem serije akcija u određenom Redosljedu.
Akcije koje će se izvršiti i redosljed u kojem će se to odvijati nazivamo algoritam.
Iskustvo pokazuje da je najteži dio riješavanja programerskog problema na računalu
upravo razvijanje algoritma za riješenje. Jednom kad je određen ispravan algoritam,
razvoj programa za sam alorgitam je poprilično jednostavan.

Sljedeći primjer pokazuje korektan i nekorektan sljed događaja za algoritam kojim


želimo opisati pokretanje automobila:

KOREKTAN SLIJED NEKOREKTAN SLIJED

√ otključavanje automobila √ otključavanje automobila


√ sjedanje u automobil √ sjedanje u automobil
√ paljenje motora √ paljenje motora
√ otpuštanje ručne kočnice √ pokretanje automobila
√ pokretanje automobila √ zaustavljanje
√ zaustavljanje √ otpuštanje ručne kočnice

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 12

Je li tačka unutar ili izvan poligona?

3.2. PSEUDOKOD

Pseudokod je neoficijelan jezik koji pomaže programerima u razvijanju algoritama.

√ Pseudokod nije programerski jezik.


√ Njegova svrha je riješiti program prije pisanja u
√ programerskom jeziku kao što je Visual Basic.
√ Pseudokod se sastoji jedino od izvršnih naredbi – onih
√ koje se izvršavaju kada program iz pseudokoda pretvorimo
√ u Visual Basic i pokrenemo.

Skica programa, napisana u formi na način da se lako može pretovriti u pravi kod. Na
primjer pseudokod za bubble sort

može se napisati na slijedeći način:

while not at end of list


compare adjacent elements
if second is greater than first
switch them
get next two elements
if elements were switched
repeat for entire list

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 13

3.3. UVOD U STRUKTURU KONTROLE

√ Naredbe u programu se izvršavaju jedna iza druge u slijedu kako su i napisane


tj. s lijeva na desno, te odozgo prema dolje(slijedovno izvršavanje).
√ Različite naredbe omogućuju programeru da odredi izvršavanje neke naredbe
prije slijedeće iz niza (prenos kontrole). Korištenje naredbe goto omogućuje
prenos kontrole na neku od mogučih destinacija u programu.
√ Cijeli program može biti napisan i bez korištenja goto naredbe, pomoću tri
različite strukture kontrole:
• slijedovna struktura
• selekcijska struktura
• ponavljačka struktura

Dijagram toka

Dijagram toka je grafičko predstavljanje algoritma ili


jednog njegovog dijela. Crta se korištenjem simbola
kao što su krug, pravokutnik, romb i oval koji su
međusobno povezani strelicama toka. Dijagram toka
algoritma započinjemo sa
ovalnim simbolom koji sadrži riječ “Begin” a
završavamo sa istim simbolom koji sadrži riječ “End”.

Slijedovna struktura
Slijedovna struktura je ugrađena u Visual Basic. Ukoliko nije drugačije određeno,
računar izvršava naredbe Visual Basica jednu nakon druge slijedom kojim su i
napisane.

Selekcijska struktura (struktura odluke)


Potprogrami Visual Basica mogu ispitati uslove te, ovisno o rezultatu
ispitivanja, izvesti različite operacije.
Visual Basic osigurava tri tipa struktura odluke:

• If / Then
• If / Then / Else
• Select Case

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 14
If / Then struktura izvršava određeni izraz jedino u slučaju ako je ispitivani uslov
zadovoljen.
If / Then struktura izvršava izraz ako je uslov istinit (True), ili ga preskače ako je uslov
lažan (False).
Zbog toga što ili izvršava ili ignorira određenu akciju nazivamo je i jedno-selekcijska
struktura.

PRIMJER: If / Then selekcijska struktura

If je uspjeh studenta veći od ili jednak 60


Prikaži “Prošao” pseudokod

If / Then / Else struktura omogućuje programeru da odredi izvršavanje različitih


izraza ovisno o tome dali je izraz True ili False.

PRIMJER: If / Then / Else selekcijska struktura

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 15

Visual Basic sadrži funkciju IIf koja zamijenjuje If/Then/Else strukturu.

lblStatus.Caption=IIf(uspjeh >= 60,“Prošao”,”Pao”)


IIf (izraz, istinitdio, neistinitdio)

Sintaksa
If/Then/Else struktura može biti smještena unutar druge If/Then/Else strukture te u
tom slučaju kažemo da je ugnježdena.

If je uspjeh studenta veći od ili jednak 90


Prikaži “Odličan”
Else
If je uspjeh studenta veći od ili jednak 80
Prikaži “Vrlo dobar”
Else
If je uspjeh studenta veći od ili jednak 70
Prikaži “Dobar”
Else
If je uspjeh studenta veći od ili jednak 60
Prikaži “Dovoljan”
Else
Display “Nedovoljan”

If uspjeh >= 90 Then


lblStudentUspjeh.Caption = “Odličan”
Else
If uspjeh >= 80 Then
lblStudentUspjeh.Caption = “Vrlo dobar”
Else
If uspjeh >= 70 Then

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 16
lblStudentUspjeh.Caption = “Dobar”
Else
If uspjeh >= 60 Then
lblStudentUspjeh.Caption = “Dovoljan”
Else
lblStudentUspjeh.Caption = “Nedovoljan”
End If
End If
End If
End If
Visual Basic kod
If uspjeh >= 90 Then
lblStudentUspjeh.Caption = “Odličan”
ElseIf uspjeh >= 80 Then
lblStudentUspjeh.Caption = “Vrlo dobar”
ElseIf uspjeh >= 70 Then
lblStudentUspjeh.Caption = “Dobar”
ElseIf uspjeh >= 60 Then
lblStudentUspjeh.Caption = “Dovoljan”
Else
lblStudentUspjeh.Caption = “Nedovoljan”
End If

If/Then/ElseIf je poseban slučaj If/Then/Else strukture . Prikazani primjer je ucijelosti


jednak prethodnom.

Visual Basic osigurava funkciju Switch koja može zamijeniti logiku višestrukih
If/Then/Else struktura.

lblStudentUspjeh.Caption=Switch(uspjeh >= 90,“Odličan”, _


uspjeh >= 80, “Vrlo dobar”, _
uspjeh >= 70, “Dobar”, _
uspjeh >= 60, “Dovoljan”, _
uspjeh < 60, “Nedovoljan”)
Switch(expr-1, value-1[, expr-2, value-2 … )
Sintaksa
Select Case višestruka selekcijska struktura je alternativa If/Then/Else strukturi za
izvođenje izabranog bloka izraza između višestrukih blokova. Struktura Select Case
radi sa jednim tekstualnim izrazom koji se jednom procjenjuje, na vrhu strukture.
Visual Basic zatim uspoređuje rezultat tog izraza s vrijednostima svakog izraza Case
unutar strukture. Ako postoji slaganje, izvodi se blok izraza pridružen tom izrazu
Case.

Select Case tekstualni izraz


[Case listaizraza1
[blok izraza1]]

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 17
[Case listaizraza2
[blok izraza2]]
.
.
[Case Else
[blok izrazan]]
End Select
Sintaksa

Ako postoji više vrijednosti u jednoj listi, te vrijednosti su razdvojene zarezima. Visual
Basic izvršava izraze u bloku Case Else (koji je neobavezan) ako ni jedna od
vrijednosti u listama izraza ne odgovara tekstualnom izrazu.

Select Case uspjeh


Case uspjeh >= 90
lblStudentUspjeh.Caption = “Odličan”
Case uspjeh >= 80
lblStudentUspjeh.Caption = “Vrlo dobar”
Case uspjeh >= 70
lblStudentUspjeh.Caption = “Dobar”
Case uspjeh >= 60
lblStudentUspjeh.Caption = “Dovoljan”
Case Else
lblStudentUspjeh.Caption = “Nedovoljan”
End Select

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 18
3.3.1. Ponavljačka struktura (struktura petlje)
Ponavljačke strukture omogućuju vam ponavljajuće izvođenje jedne ili više linija
programskog koda.

Visual Basic uključuje sljedeće strukture petlje:


• While / Wend
• Do / Loop
• For / Next
• For Each / Next

While / Wend struktura omogućuje ponavljajuće izvođenje jedne ili


više linija programskog koda ovisno o stanju uslova.

Do / Loop struktura se koristi za izvođenje bloka izraza neodređeni broj puta.


Postoji nekoliko varijacija ove strukture, ali svaka ocjenjuje brojčani uslov kako bi
odlučila hoće li nastaviti izvođenje.
Uslov mora biti vrijednost ili izraz koji se može ocijeniti kao False (nula) ili True
(različit od nule). Varijacije Do/Loop strukture:

• Do While / Loop
• Do / Loop While
• Do Until / Loop
• Do / Loop Until

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 19

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 20

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 21

For / Next ponavljačka struktura se koristi za ponavljanje izraza unutar petlje točno
određeni broj puta. Za razliku od petlji tipa Do/Loop, petlja ovog tipa koristi varijablu
nazvanu counter (brojač) kojoj se vrijednost povečava ili smanjuje kod svakog
ponavljanja petlje.

PRIMJER: For / Next ponavljačka struktura

Dim brojac As Integer


For brojac = 2 To 10 Step 2
Print brojac
Next brojac
Dim brojac As Integer
brojac = 2
Do While brojac <= 10
Print brojac
brojac = brojac + 2
Loop

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 22
Select Case tekstualni izraz
[Case listaizraza1
[blok izraza1]]
[Case listaizraza2
[blok izraza2]]
.
.
[Case Else
[blok izrazan]]
End Select
Sintaksa

Ako postoji više vrijednosti u jednoj listi, te vrijednosti su razdvojene zarezima. Visual
Basic izvršava izraze u bloku Case Else (koji je neobavezan) ako ni jedna od
vrijednosti u listama izraza ne odgovara tekstualnom izrazu.

Select Case uspjeh


Case uspjeh >= 90
lblStudentUspjeh.Caption = “Odličan”
Case uspjeh >= 80
lblStudentUspjeh.Caption = “Vrlo dobar”
Case uspjeh >= 70
lblStudentUspjeh.Caption = “Dobar”
Case uspjeh >= 60
lblStudentUspjeh.Caption = “Dovoljan”
Case Else
lblStudentUspjeh.Caption = “Nedovoljan”
End Select

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 23

Funkcija Choose je slična Select/Case strukturi.

Choose(indeks, izbor-1[, izbor-2, ... [, izbor-n]])

Sintaksa
Argument indeks sadrži vrijednost od 1 do broja zadnjeg izbora Argument izbor vraća
vrijednost iz liste nabrojenih izbora a prema vrijednosti argumenta indeks.

Print Choose(x,”Crveno”,”Žuto”,”Zeleno”)
Ako je x=1 prikazano je Crveno, za x=2 Žuto a za x=3 Zeleno.

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 24

4. Programiranje pomoću programskog jezika C++


Mikroprocesor i drugi logi_cki sklopovi ra_cunala imaju svoj vlastiti programski jezik
koji se naziva strojni jezik, a sastoji se od nizova binarnih rije_ci koje predstavljaju
instrukcije logi_ckim sklopovima i podatke koje treba obraditi.
Program napisan u strojnom jeziku nazivamo izvr_sni program ili izvr_snik^od
budu_ci da ga ra_cunalo mo_ze neposredno izvr_siti. Strojni jezik je odreden
arhitekturom ra_cunala, a de_nira ga proizvoda_c hardwarea. Izvr_sni program je
strojno zavisan, _sto zna_ci da se k^od napisan na jednom ra_cunalu mo_ze
izvr_savati jedino na ra_cunalima istog tipa.
Pisanje instrukcija u binarnom k^odu posve je neprakti_cno pa su razvijeni
simboli_cki jezici u kojima su binarne instrukcije zamijenjene mnemoni_ckim
oznakama. Programer unosi program napisan u mnemoni_ckim oznakama u
tekstualnu datoteku pomo_cu editora teksta i zatim poziva program koji mnemoni_cke
oznake prevodi u binarne instrukcije strojnog jezika. Program koji vr_si konverziju
naziva se asembler (eng. assembler) a sam se programski jezik naziva asemblerski
jezik ili jednostavno asembler. Program napisan u asemblerskom jeziku nazivamo
izvorni program (eng. source code). Pisanje programa time postaje dvostepeni proces
koji _cine pisanje izvornog programa i prevodenje izvornog programa u izvr_sni
program. Programer se tako oslobada mukotrponog pisanja binarnih instrukcija te se
dobiva do odredene mjere strojna neovisnost izvornog programa.
Sljede_ci primjer pokazuje dio izvr_snog k^oda (strojni jezik) i njemu ekvivalentan
izvorni, asemblerski k^od. Rad se o asembleru za Intelov mikroprocesor 8086 ([5]).

Pisanje programa u asemblerskom jeziku daje programeru potpunu kontrolu nad svim
komponentama ra_cunala. Programer stoga mora poznavati arhitekturu ra_cunala za
koje pi_se program te kontrolirati sve operacije koje ra_cunalo izvr_sava.
Programiranje i najjednostavnijih zada_ca rezultira velikim i slo_zenim programima pa
se programiranje u asembleru koristi se samo za speci__cne zada_ce vezane uz
manipulacije s hardwareom. Izvorni program napisan u asembleru nije prenosiv
izmedu ra_cunala razli_cite arhitekture. Zbog svih tih razloga za ve_cinu
programerskih zada_ca koriste se vi_si programski jezici.

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 25
Vi_si programski jezici (C, Pascal, FORTRAN, C++, Java, Perl, Python, . . . ) razvijeni
su kako bi se prevladali nedostaci asemblerskog jezika. Oni oslobadaju programera
potrebe poznavanja arhitekture ra_cunala, omogu_cavaju prenosivost programa
izmedu ra_cunala razli_citih arhitektura te br_ze I jednostavnije programiranje.
Programi napisani u vi_sem programskom jeziku moraju prije izvodenja pro_ci
postupak prevodenja u izvr_sni k^od _sto je zadatak prevodioca (eng. compiler) za
dani jezik. Naredbe vi_seg programskog jezika prilagodene su tipu podataka s kojima
programski jezik manipulira I operacijama koje nad podacima treba vr_siti. To je
osnovna razlika naspram asemblera koji je prilagoden na_cinu funkcioniranja
mikroprocesora i drugih logi_ckih sklopova. Zadatak je prevodioca da program
napisan u vi_sem programskom jeziku prevede u k^od koji se mo_ze izvr_savati na
zadanom ra_cunalu.
Na taj se na_cin program napisan u nekom vi_sem programskom jeziku mo_ze
izvr_savati na svakom ra_cunalu koje ima prevodilac za taj jezik.
Programski jezik C vi_si je programski jezik op_ce namjene. Razvio ga je Dennis
Ritchie sedamdestih godina pro_slog stolje_ca u Bell Telephone Laboratories, Inc.
Opis jezika dan je u knjizi Brian W. Kernighan, Dennis M. Ritchie:
The C Programming Language, Prentice-Hall, 1978. Tijekom sedamdesetih i
osamdesetih godina jezik se brzo _sirio te je American National Standard Institute
(ANSI) pristupio njegovoj standardizaciji koja je dovr_sena 1989. godine. Novi
standard uveo je zna_cajne izmjene u jezik koji se stoga, za razliku od prvotne
verzije, _cesto naziva ANSI-C. Novi je standard opisan u knjizi Brian W. Kernighan,
Dennis M. Ritchie: The C Programming Language, 2nd ed., Prentice-Hall, 1988.
Danas gotovo svi moderni C-prevodioci implementiraju ANSI-C verziju jezika. ANSI
standard usvojila je i Medunarodna organizacija za standarde (International
Organisation for Standardization) 1990. godine (ISO C). Kona_can ANSI/ISO
standard _cemo jednostavno nazivati C90 standard. Godine 1999. ISO je prihvatio
novi C standard koji uvodi manje dopune u C90 standard, a koji _cemo zvati C99
standard.

4.1 Elementi od kojih se grade strukture podataka


Struktura podataka se sastoji od manjih cjelina koje se udružuju u veće i međusobno
povezuju vezama. Uvodimo posebne nazive za cjeline, načine udruživanja i načine
povezivanja. Također, uvodimo pravila kako se strukture prikazuju dijagramima.

Ćelija . . . varijabla koju promatramo kao zasebnu cjelinu.To je relativan pojam (nešto
se u jednom trenutku može smatrati ćelijom, a kasnije se može gledati unutrašnja
građa iste cjeline). Svaka ćelija ima svoj tip i adresu.

Polje . . . (array u C-u). Mehanizam udruživanja manjih dijelova strukture u veće.


Polje čini više ćelija istog tipa pohranjenih na uzastopnim adresama. Broj ćelija je
unaprijed zadan i nepromjenljiv.

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 26
Jedna ćelija se zove element polja i jednoznačno je određena pripadnom vrijednošću
indeksa. Po ugledu na C, uzimamo da su indeksi 0, 1, 2, ... , N-1, gdje je N
cjelobrojna konstanta.

Zapis . . . (slog, structure u C-u). Također mehanizam udruživanja manjih dijelova


strukture u veće. Zapis čini više ćelija, koje ne moraju biti istog tipa, no koje su
pohranjene na uzastopnim adresama. Broj, redosljed i tip ćelija je unaprijed zadan i
nepromjenljiv. Pojedina ćelija se zove komponenta zapisa. Polja i zapisi se mogu
kombinirati. Na primjer, možemo imati polje zapisa, zapis čije pojedine komponente
su polja, polje od polja, zapis čija komponenta je zapis, i slično.

Pointer . . . služi za uspostavljanje veze između dijelova strukture. Pointer je ćelija


koja pokazuje neku drugu ćeliju. Sadržaj pointera je adresa ćelije koju treba pokazati.

Kursor . . . takoder služi za uspostavljanje veze između dijelova strukture. Kursor je


ćelija tipa int koja pokazuje na element nekog polja. Sadržaj kursora je indeks
elementa kojeg treba pokazati.

Dijagram pokazuje primjer strukture podataka koja se sastoji od niza zapisa


povezanih pomoću pointera, te od jednog polja zapisa. Zapisi su još međusobno
povezani kursorima.

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 27

Slika 1.2 Primjer strukture podataka.

4.1.2 Kreiranje prvog programa

Svi C-programi sastoje se od funkcija i varijabli. Funkcije sadr_ze instrukcije koje


odreduju koje _ce operacije biti izvr_sene, a varijable slu_ze memoriranju podataka.
Izvr_savanje programa po_cine izvr_savanjem funkcije main koja mora biti prisutna u
svakom programu. Funkcija main svoju zada_cu obavlja op_cenito pozivanjem drugih
funkcija. Tako se u na_sem programu poziva funkcija printf iz standardne biblioteke,
koja je zadu_zena za ispis podataka na ekranu.

Da bismo mogli koristiti funkcije iz standardne biblioteke zadu_zene za ulaz i izlaz


podataka program zapo_cinjemo naredbom

#include <stdio.h>

Njom se od prevodioca tra_zi da uklju_ci (include) u program datoteku stdio.h koja


sadr_zi informacije nu_zne za kori_stenje funkcije printf i mnogih drugih. Datoteke s
ekstenzijom .h nazivaju se datoteke zaglavlja (eng. header _les) i njihovo stavljanje u
o_stre zagrade < > informira prevodilac da se radi o standardnim datotekama
zaglavlja, koje se nalaze na unaprijed odredenim mjestima u datote_cnom sustavu.
Sljede_ca linija predstavlja deklaraciju funkcije main:

int main(void)

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 28

Funkcija mo_ze uzimati jedan ili vi_se argumenata i obi_cno vra_ca neku vrijednost.
Deklaracijom se uvodi ime funkcije, broj i tip argumenata koje uzima i tip povratne
vrijednosti. U na_sem primjeru ime funkcije je main i ona ne uzima niti jedan
argument. To je deklarirano tako _sto je u oble zagrade stavljena klju_cna rije_c void
(eng. void=prazan). Povratna vrijednost je tipa int, _sto je oznaka za cijeli broj.1

Iza oblih zagrada dolaze viti_caste zagrade koje omeduju tijelo funkcije. Tijelo
funkcije je sastavljeno od deklaracija varijabli i izvr_snih naredbi. Sve deklaracije
varijabli dolaze prije prve izvr_sne naredbe. U na_sem primjeru nemamo deklaracija
varijabli. Tijelo sadr_zi samo dvije naredbe: poziv funkcije printf i return naredbu:

#include <iostream>
using namespace std;
int main()
{
cout << “Hello, world!” << endl;
system("PAUSE");
return 0;
}

4.2. Generisanje izvršne datoteke

Nakon što se sačuva ovaj kod, treba ga kompajlirati, tj. proizvesti izvršnu mašinsku datoteku.
Ovo se izvodi korištenjem kombinacije tipki Ctrl+F9 na tastaturi, ili izborom opcije Compile u
meniju Execute, ili pritiskom na ikonu u nizu alata.
Nakon startanja procesa kompajliranja, pojavljuje se prozor sa porukama koje
prate process kompajliranja. Dev-C++ daje poruku u slučaju da nađe bilo kakvu grešku u
programu. U slučaju da nema grešaka, stvara se izvršna datoteka koja se naziva hello.exe.

4.3 Pokratanje programa


Pokretanje programa, koji smo prethodno kompajlirali, u Dev-C++ okruženju izvodi se
izborom opcije Run u meniju Execute, kombinacijom tipki Ctrl+F10 na tastaturi, ili pritiskom
na ikonu Prethodna dva procesa (kompajliranje i pokretanje) moguče je objediniti
pritiskom na tipku F9 na tastaturi, izborom opcije Compile&Run u meniju Execute, ili izborom
ikone. Program je moguče pokrenuti i van Dev-C++ okruženja, dvostrukim klikom
na izvršnu datoteku hello.exe.

4.4 Osnove programiranja


4.4.1 Struktura programa

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 29
C++ program se sastoji od jedne ili više cjelina za prevođenje, pri čemu ove cjeline
predstavljaju dio programa koji treba kompajlirati odvojeno od drugih cjelina. Tačnije, cjelina
za prevođenje je rezultat primjene preliminarne faze kompilacije, koja se naziva
predprocesiranje, na izvornu datoteku (source).
Izvorna datoteka obično počinje sa jednom ili više (predprocesorskih) direktiva #include, pri
čemu svaka od njih navodi predprocesor da kopira deklaracije entiteta (funkcija, globalnih
varijabli, tipova, itd), koji su definisani u ostalim cjelinama za prevođenje. Posmatrajmo
primjer iz prethodnog poglavlja:
U liniji 1 pozvana je datoteka iostream. Prvi karakter (#) predstavlja symbol, koji daje signal
predprocesoru. Svaki put kada pokrenemo kompajler, predprocesor je več pokrenut. U
principu, predprocesor čita kroz izvornu datoteku i traži linije koje počinju sa ovim
karakterom, tako da ih predprocesor prođe prije nego kompajler starta sa radom. Ukratko ova
linija znači: Ono što slijedi je

1 #include <iostream>
2 using namespace std;
3 int main()
4 {
5 cout << “Hello, world!” << endl;
6 system("PAUSE");
7 return 0;
8 }

ime datoteke. Nađi tu datoteku i odmah je pročitaj. Uglaste zagrade (<>) daju naredbu
predprocesoru da nađe zadatu datoteku koja je dio standardne biblioteke (u datom primjeru to
je datoteka koja sadrži definicije za ispis i upis). U slučaju kada bismo htjeli uvrstiti neku
svoju datoteku, umjesto zagrada bismo koristili znake navoda. Dakle, ova linija kaže
predprocesoru da nađe datoteku koja se zove iostream i da je odmah pročita. Naravno,
sadržaj tražene datoteke bismo mogli upisati u izvornu datoteku bez korištenja direktive
#include.
Linija 2 omogučuje pristup standardnom entitetu (namespace) koji se naziva std. Bez ove
linije, linija 5 bi se morala izvršiti na drugačiji način (std::cout << ....)
Linijom 3 počinje stvarni program sa funkcijom koja se naziva main(). Svaki C++ program
sadrži ovu funkciju. Funkcija predstavlja dio koda koji odrađuje određenu radnju. Inače,
program može da ima proizvoljan broj funkcija, pri čemu je funkcija main() specijalna. Kada
god se program starta, ona se automatski poziva. Sve funkcije počinju zagradom { i
završavaju zagradom }, a sve između ovih zagrada predstavlja dio funkcije.
Glavni dio programa je linija 5, koja predstavlja neku naredbu, tj. računarski korak koji daje
neku vrijednost. Kraj naredbe uvijek zavrčava tačka-zarezom. Naredba u datom primjeru šalje
string "Hello world \n" na tok cout (output stream). String je svaki niz karaktera koji se
nalazi između znaka navoda. Posljednji karakter u datom stringu (\n) je karakter koji
označava novi red. Stream je objekat koji izvršava ulazne i izlazne naredbe. cout je
standardni izlazni stream u C++ (standardni izlazni stream je obično ekran). Simbol << je
izlazni operator (usmjerivač toka) kojem je lijevi operand izlazni stream, a desni izraz, i koji
uzrokuje da se ovaj posljednji posalje na prvopomenuti. Dakle, u ovom slučaju string "Hello

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 30
world \n" se šalje na cout, tj. uzrokuje njegov ispis na ekranu. Linija 6 zaustavlja izvršenje
programa, kako bismo bili u mogučnosti vidjeti rezultat njegovog rada.
Bez ove linije program bi se nakon pokretanja izvršio, a konzola bi se zatvorila tako brzo da
bismo imali osječaj da program nije ništa ni uradio.

4.5 Proces kompajliranja


Kompajliranje C++ programa obuhvata nekoliko koraka, koji su večinom nevidljivi za
korisnika:
• prvo, C++ predprocecsor ide kroz program i izvodi instrukcije koje su specificirane
predprocesorskim direktivama (npr. #include). Rezultat ovoga je modificirani tekst
programa koji više ne sadrži nikakve direktive.
• zatim, C++ kompajler prevodi programski kod. Kompajler može biti pravi C++
kompajer koji pravi osnovni (asemblerski ili mašinski) kod, ili samo prevodilac, koji
kod prevodi u C jezik. U drugom slučaju, rezultujuči C kod je zatim proveden kroz C
kompajler kako bi se napravio osnovni kod. U oba slučaja, rezultat može biti nepotpun
zbog toga što program poziva podprogramske biblioteke koje nisu definisane u samom
programu.
• Na kraju, linker završava objektni kod njegovim povezivanjem sa objektnim kodom
bilo kojeg modula biblioteka koji program može pozvati. Konačan rezultat je izvršna
datoteka.

Slika 4.1 ilustruje prethodno navedene korake i za C++ prevodilac i za C++ prirodni
kompajler. U praksi su sve ove komande obično izvršene jednom komandom (npr. CC), a
korisnik ni ne vidi datoteke koje su se napravile u međufazama.

Slika 4.1 C++ kompilacija


4.6 Varijable

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 31
Varijabla je simboličko ime za memorijsku lokaciju u koju se mogu pohraniti podaci i
naknadno ih pozvati. Varijable se koriste za čuvanje vrijednosti podataka tako da se iste mogu
koristiti u raznim proračunima u programu. Sve varijable imaju dvije važne osobine:
• Tip, koji se postavlja kada se varijabla definiše (npr. cijeli broj, realni broj, karakter,
...)Kada se jednom definiše, tip varijable u C++ se ne može promijeniti.
• Vrijednost, koja se može promijeniti davanjem nove vrijednosti varijabli. Vrsta
vrijednosti koja se može pridružiti nekoj varijabli zavisi od njenog tipa. Na primjer,
integer varijabla može da uzima samo vrijednosti cijalih brojeva (npr. -5, 13, ..)

Kada se varijabla definiše, njena vrijednost je nedefinisana sve dok joj se ne pridruži
neka.Pridruživanje vrijednosti nekoj varijabli po prvi put naziva se inicijalizacija. Neophodno
je obezbijediti da se svaka varijabla inicijalizira prije nego se koristi. Također je moguče da se
varijabla definiše i inicializira u isto vrijeme, što je vrlo praktično. Naredni primjer pokazuje
različite načine definisanja i inicijaliziranja varijabli.

#include <iostream>
using namespace std;
main()
{
int a,b,c;
float x = 4.32;
int e,f,g;
char ime;
e = 4;
f = g = 12;
ime = 'C'
}

4.7 Memorija
Za pohranjivanje izvršnog koda kao i podataka sa kojima progam manipuliše, kompjuter ima
na raspolaganju RAM memoriju (Read Access Memory). Memorija se može zamisliti kao
neprekidan

Slika 4.2. Bitovi i bajtovi u memoriji

niz bita, od kojih svaki može da pohrani binarni broj (0 ili 1). Obično je memorija podijeljena
na grupe od 8 uzastopnih bita (ovo predstavlja bajt, byte). Bajtovi su uzastopno adresirani,
tako da je svaki bajt jedinstveno predstavljen svojom adresom (Slika 4.2).

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 32
C++ kompajler generira izvršni kod, koji mapira ulazne veličine na memorijske lokacije. Na
primjer, definicija varijable int zarada = 500; navodi kompajler da alocira nekoliko bajta
kako bi predstavio varijablu zarada. Tačan broj bajta koji je alociran i metod koji se koristi za
binarnu reprezentaciju cijelog broja zavisi od specifičnosti C++ implementacije, ali uzmimo
da se radi o 2 bajta. Kompajler koristi adresu prvog bajta na koju se alocira zarada kako bi
označio varijablu. Prethodna jednakost uzrokuje da se vrijednost 500 pohrani u ova dva bajta
koja su alocirana

Slika 4.3 Reprezentacija cijelog broja u memoriji

Treba napomenuti da je organizacija memorije i korištenje adresa koji se odnose na podatke


veoma važno za programera, dok tačna binarna reprezentacija podataka koje on koristi to nije.

4.8 Ulazno/izlazne naredbe


Najčešči način na koji program komunicira sa vanjskim svijetom je preko jednostavnih
ulazno/izlaznih (IO) operacija. C++ omogučuje dva korisna operatora za ovu svrhu: >> za
ulaz, i << za izlaz. U ranijem tekstu pokazana je upotreba operatora <<. Naredni primjer
pokazuje upotrebu operatora >>.

#include <iostream>
using namespace std;
int main (void)
{
int radniDani = 22;
float radniSati = 7.5;
float satnica, plata;
cout << "Kolika je satnica? ";
cin >> satnica;
plata = radniDani * radniSati * satnica;
cout << "Plata = ";
cout << plata;
cout << '\n';
}

Linija 9 čita ulaznu vrijednost, koju unosi korisnik i kopira je u satnica. Ulazni operator >>
uzima ulazni stream kao lijevi operand (cin je standardni C++ ulazni stream koji odgovara
podacima unesenim pomoču tastature), a varijablu (na koju se kopira ulazni podatak) kao
desni operand.

4.9 Komentari
Komentar je dio opisnog teksta koji objašnjava neke aspekte programa. Kompajler u
potpunosti ignoriše komentare u programu, tako da je jedina svrha koju komentar ima, da
pomognu onome koji če čitati program. C++ daje dvije mogučnosti pisanja komentara:

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 33
• Bilo šta napisano nakon //, pa do kraja date linije smatra se komentarom
• Bilo šta napisano između /* i */ smatra se komentarom.

#include <iostream>
using namespace std;
/* Ovaj program racuna ukupnu platu radnika, koja se zasniva na ukupnom broju
radnih sati I satnici. */
int main (void)
{
int radniDani = 22; // Broj radnih dana u mjesecu
float radniSati = 7.5; // Broj radnih sati u danu
float satnica = 33.50; // Satnica
float plata; // Ukupna mjesecna plata
plata = radniDani * radniSati * satnica;
cout << “Plata = “ << plata << ‘\n’;
}

Jasno da je da se prvi primjer može koristiti za komentar jedne I samo jedne linije (ili dijela
jedne linije), dok se posljednjim može komentarisati tekts upisan u više linija.

4.10 Imena
Programski jezici koriste imena kako bi se označile različite cjeline koje čine program. Osim
imena varijabli, ovdje spadaju i imena funkcija, tipova, te makroa. C++ postavlja sljedeča
pravila za pravilno kreiranje imena (ili identifikatora). Ime traba da se sastoji od jednog ili više
karaktera, od kojih bilo koji može biti slovo (tj, slova engleske abecede a-z i A-Z), broj (0-9)
i znak "_", pri čemu na prvom mjestu ne može da bude broj. Uz to, velika i mala slova se
razlikuju, tako da se, na primjer, varijable zarada i Zarada razlikuju.
C++ ne postavlja nikakvo ograničenje na broj karaktera u nekom identifikatoru. Međutim,
večina implementacija ima ovo ograničenje, ali je ono toliko veliko da ne predstavlja nikakav
problem (npr. i do 255 karaktera). Treba imati na umu da postoje odrežene riječi u C++ koje
su rezervisane, tako da identifikatori ne mogu uzimati njihova imena. Te riječi se nazivaju
rezervisane ili ključne riječi i date su u tabeli

Tabela 4.1 Ključne (rezervisane) riječi u C++

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 34
4.11 Cijeli brojevi
Cijeli broj (integer) se može definisati pomoču tipova short, int i long. Jedina razlika je
u tome da int koristi više ili barem isto bajta kao short, a long koristi više ili barem isto
bajta nego int. Ovo zavisi od računara na kojem se radi.
Konvencija je da cjelobrojne varijable uzimaju u obzir i pozitivne i negativne brojeve (kaže se
da su signed). Međutim, u slučaju kada se koriste kao unsigned, onda mogu uzeti samo
pozitivne vrijednosti (sa 0).

4.12 Realni brojevi


Realni broj se može definisati sa tipom float i double. double koristi više bajta i time
omogučuje veču opseg i veču tačnost pri predstavljanju realnih brojeva.

4.13 Karakteri
Varijabla karakter se definiše tipom char. Ona obuhvata jedan jedini bajt koji sadrži kod
datog karaktera. Ovaj broj je numerička vrijednost i zavisi od sistema kodiranja karaktera koji
se koristi (to je zavisno od mašine). Najčešči sistem je ACSII (Amercan Standard Code for
Information Interchange). Na primjer, karakter A ima ASCII kod 65, a karakter a 97.
Kao i interger i karakter može da bude signed i unsigned. Tako, signed karakter može da
sadrži numeričke vrijednosti između -128 i 127, a unsigned 0 do 255. Karakteri koji imaju
posebnu namjenu (ne predstavljaju karaktere koji se ispisuju) predstavljaju se
pomoču escape sekvenci, kao npr:
‘\n’ – novi red
‘\t’ – novi tabulator
‘\v’ – novi vertikalni tabulator
‘\b’ – backspace
‘\’’ – znak navoda (apostrof)
‘\”’ – dvostruki znak navoda
‘\\’ – backslash (/)
‘\a’ – zvučni signal

4.14 Stringovi
String je uzastopni niz karaktera koji se završavaju nultim karakterom. Tako je, barem, bilo u
jeziku C. Ipak, u C++ uveden je novi tip podataka koji se naziva C++ string klasa, pa je
moguče na mnogo prirodniji način manipulisati varijablama sa više karaktera. Sljedeči primjer
pokazuje njenu upotrebu.

#include <iostream>
using namespace std;
main()
{
char ch;
do {
cout << "Pritisnite K ili k za kraj, a bilo koju tipku za
nastavak \n";
cin >> ch;

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 35
if (ch != 'K' && ch != 'k')
cout << "Zelite nastaviti?\n";
else
cout << "Kraj programa";
} while (ch != 'K' && ch != 'k');
}

Ovaj primjer dobro funkcioniše jer završava program ako se unese "k" ili "K", odnosno
program se nastavlja ako se unese bilo koji drugi karakter. Problem nastaje ako korisnik
programa pritisne samo tipku ENTER. U tom slučaju objekat "cin" očekuje da se unese neka
vrijednost, pa tek onda pritisne ENTER.

4.15 Operatori
Ovo poglavlje obrađuje ugrađene C++ operatore koji se koriste za stvaranje izraza, pri čemu
izraz predstavlja bilo kakav proračun koji daje neku vrijednost. C++ nudi operatore za
izvršavanje aritmetičkih, ralacijskih, logičkih, bitwise i uslovnih izraza. Također nudi veoma
korisne “popratne efekte” (side-effect) kao što su pridruživanje, inkrement i dekrement.

4.15.1 Aritmetički operatori


C++ nudi pet osnovnih operatora, koji su sumirani u Tabeli 4.2.
Tabela 4.2 Aritmetički operatori

Osim ostatka pri djeljenju (%) svi aritmetički operatori prihvataju miješanje cijelih i realnih
brojeva. Opčenito, ako su oba operanda cijeli brojevi, i rezultat je cijeli broj. Međutim, ako je
jedan od operanada realan, onda je i rezulat realan (tipa double).
Kada su oba operanda pri dijeljenju cijeli brojevi, rezultat je također cijeli broj (tzv.
Cjelobrojno dijeljenje). U tom slučaju rezultat se zaokružuje na donju vrijednost, tj.
9 / 2 // daje 4, a ne 4.5!

-9 / 2 // daje -5,a ne -4.5!

S obzirom da neželjeno cjelobrojno dijeljenje predstavlja jednu od najčeščih greški u


programiranju, neophodno je da promijenimo jedan od operanada da bude realan broj, kao npr.

Int cijena = 100;

int volumen = 80;

double jedinicnaCijena = cijena / (double) volumen; // daje 1.25

Operator % daje ostatak pri dijeljenju dva cijela broja (oba operanda moraju biti cijeli brojevi),
npr. 13%3 daje 1

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 36

4.15.2 Relacijski operatori


C++ nudi 6 relacijskih operatora za računanje brojnih veličina (Tabela 4.3)
Tabela 4.3 Relacijski operatori:

Treba zapamtiti da se operatori <= i >= mogu korisiti samo u tom obliku, a da =< i => ne
znače ništa u ovom kontekstu.

Operandi nekog relacijskog operatora moraju biti brojevi. No, i karakteri su ispravni operandi
pošto predstavljaju brojnu vrijednost (sjetimo se ASCII tabele).
Relacijski operaotri se ne smiju korisiti ze poređenje stringova, pošto se u tom slučaju porede
njihove adrese, a ne sadržaj. U tom slučaju, rezlutat je neodređen. Ipak, postoje funkcije koje
mogu porediti i leksikografsku razliku dva stringa.

4.15.3 Logički operatori


Za kombinovanje logičkih izraza C++ nudi tri logička operatora (Tabela 4.4). Slično
relacijskim operatorima, rezultat pri korištenju logičkih operatora je 0 (false) ili 1 (true).

Tabela 4.4 Logički operatori

Logička negacija je unarni opearator, tj. ima samo jedan operand kojem daje negativnu
vrijednost.

4.15.4 Inkrementalni i dekrementalni operatori


Takozvani auto inkremetalni (++) i auto dekrementalni (--) operatori obezbijeđuju prigodan
način za povečavanje, odnosno smanjivanje brojne varijable za 1. Upotreba ovih operatora je
sumirana u
Tabeli 4.5., pri čemu se predpostavlja da je
int k = 5;

Tabela 4.5 Inkrement i dekrement operatori.

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 37

Kao što se vidi, oba operatora se mogu korisiti u prefiksnom ili postfiksnom obliku. Razlika je
velika, jer kada se operator koristi u prefiksnom obliku prvo se primijenjuje operator, a onda
se u izrazu koristi rezultat. Kada se koristi u postfiksnom obliku, prvo se računa izraz, a onda
se primijenjuje operator.
Oba operatora se mogu primijeniti kako na cjelobrojne, tako i na realne brojeve, iako se ova
karakteristika veoma rijetko koristi na realnim brojevima.

4.15.5 Operatori pridruživanja


Operator pridruživanja se koristi za pohranjivanje vrijednosti na neku memorijsku lokaciju
(koja je obično pridružena nekoj varijabli). Lijevi operand operatora treba biti neka
lijeva_vrijednost, dok desni operand može biti proizvoljni izraz. Desni operand se
izračuna i pridruži lijevoj strani. Pri tome lijeva_vrijednost predstavlja bilo šta što
zauzima neku memorijsku lokaciju na koju se može pohraniti neka veličina, može biti
varijabla, te zasnovana na pointerima i referencama.
Operator pridruživanja može imati mnogo varijanti, koje se dobijaju njegovim
kombinovanjem sa aritmetičkim i bitwise operatorima. Ove varijante su date u sljedečoj tabeli.

Tabela 4.6 Operatori pridruživanja

Kako operator pridruživanja sam po sebi predstavlja izraz čija se vrijednost pohranjuje u lijevi
operand, on se može korisititi kao desni operand za narednu operaciju pridruživanja, odnosno
može se napisati:
int m, n, p;

m = n = p = 100; // znači: n = (m = (p = 100));

m = (n = p = 100) + 2; // znači: m = (n = (p = 100)) + 2;

ili
m = 100;

m += n = p = 10; // znači: m = m + (n = p = 10);

4.15.6 Uslovni (ternarni) operator


Uslovni operator treba tri operanda (odatle ime ternarni).

operand1 ? operand2 : operand3

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 38
On ima opštu formulu: operand1 se izračunava, i tretira se kao logički uslov. Ako je rezultat
različit od nule, tada se izračunava operand2. U suprotnom, izračunava se operand3. Na
primjer:

int m = 1, n = 2;

int min = (m < n ? m : n); // min dobija vrijednost 1

Provjeriti šta je rezultat sljedeče upotrebe uslovnog operatora:

int min = (m < n ? m++ : n++);

Postoji još nekoliko vrsta operatora (npr. zarez operator, sizeof operator), ali o njema neče biti
riječi u ovom kursu.

4.16. Naredbe
Ovo poglavlje opisuje razne oblike C++ naredbi koje služe za pisanje programa. Kao i večina
ostalih programskih jezika, C++ nudi različite vrste naredbi koje se koriste u različite svrhe.
Tako se deklaracione naredbe koriste za definisanje varijabli, naredbe pridruživanja za
jednostavne proračune, itd. U narednom teksu biče objašnjene neke od njih.

operand1 ? operand2 : operand3

4.1 Jednostavne i složene naredbe


Jednostavna naredba je svaka naredba koja završava tačka-zarezom. Definicije varijabli i
izrazi koji završavaju sa tačka-zarezom su neki primjeri:

int i; // deklaraciona naredba


++i; // naredba sa popratnim efektom
double d = 10.5; // deklaraciona naredba
d + 5; // beskorisna naredba

Posljednji primjer pokazuje beskorisnu naredbu, jer nema nikakvih popratnih efekata.
Najjednostavniji oblik naredbe je linija koja sadrži samo tačka-zarez, tzv. null-aredba. No, i
ovakva naredba ponekad ima smisla, što če se pokazati u kasnijem tekstu.
Mnogostruke naredbe se mogu kombinovati u složene naredbe kada se grupišu između velikih
zagrada ({}), kao na primjer

{ int min, i = 10, j = 20;


min = (i < j ? i : j);
cout << min << '\n';
}

Ovakve naredbe su korisne iz dva razloga: a) omogučuju da se mnogostruka naredba postavi


tamo gdje bi inače mogla da se postavi samo jedna, i b) omogučuju da se u program uvede
scope (prostor). Scope predstavlja dio programa unutar kojeg varijabla ostaje definisana. Izvan

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 39
scope-a ona to više to nije. Ovo je veoma važna osobina o kojoj če više biti riječi kada se budu
objašnjavale funkcije.

4.2 Naredba if
Ponekad je poželjno da se izvrši određena naredba koja zavisi od ispunjenja nekog uslova.
Upravo tu mogučnost pruža if naredba, čiji je opšti oblik:
Prvo se izvršava izraz, i ako je rezultat različit od nule izvršava se naredba. U suprotnom,
ništa se ne dešava.
Na primjer, ako bismo željeli provjeriti da li je pri djeljenju djelilac različit od nule, imali
bismo:

if (djelilac != 0)
Kolicnik=djelitelj/djelilac;
Da bismo izvršili više naredbi koje ovisi o nekom istom uslovu, koristimo složenu naredbu, tj.
sve naredbe stavljamo između zagrada.
Varijanta if naredbe koja omogučuje da se specificiraju dvije alternativne naredbe, jedna
koja se izvršava kada je uslov ispunjen i druga kada nije, se naziva if-else naredba i ima
oblik:

if (izraz)
naredba;
if (izraz)
naredba1;
else
naredba2;

Ovdje se najprije izvršava izraz, i ako je rezultat različit od nule, izvršava se naredba1. U
suprotnom, izvršava se naredba2, što pokazuje i sljedeči primjer:

#include <iostream>
using namespace std;
main()
{
int x;
cout << "Unesite neki broj";
cin >> x;
if (x % 2 == 0)
cout << "Broj je paran" << endl;
else
cout << "Broj je neparan" << endl;
}

Pored prethodno navedenih varijanti, postoji i ugniježdena if naredba, u kojoj se javljaju više
od dvije alternative. Primjer takve varijente je:

if (callHour > 6) {
if (duzinaPoziva <= 5)
cijena = duzinaPoziva * tarifa1;
else

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 40
cijena = 5 * tarifa + (duzinaPoziva - 5) * tarifa2;
} else
cijena = osnovnaCijena;

4.3 Naredba switch


switch naredba omogučuje izbor između više alternativa, koje su zasnovane na vrijednosti
izraza. Opšti oblik switch naredbe je:
Prvo se računa izraz (koji se naziva switch tag), a zatim se rezultat poredi sa svakom od
numeričkih konstanti (koje se nazivaju labele), po redu kako se javljaju, dok se ne poklopi sa
jednom od komponenti. Nakon toga se izvršavaju naredbe koje slijede. Izvršavanje se izvodi
sve
dok se ne naiđe na naredbu break ili dok se ne izvrše sve naknadne naredbe. Posljednji slučaj
(default) može, a i ne mora da se koristi, i pokreče se ako nijedna od prethodnih konstanti
nije zadovoljena.
Klasični primjer ocijenjivanja nekog rada na osnovu osvojenih bodova dat je u daljem teksu:

switch (izraz) {
case konstanta_1:
naredbe;
...
case konstanta_n:
naredbe;
default:
naredbe;
}

#include <iostream>
using namespace std;
main()
{
int ocj;
cout << "Unesite ocjenu: ";
cin >> ocj;
switch (ocj)
{
case 5:
cout << "Imate 90 – 100 bodova" << endl;
break;
case 4:
cout << "Imate 80 – 89 bodova" << endl;
break;
case 3:
cout << "Imate 70 – 79 bodova" << endl;
break;
case 2:
cout << "Imate 60 – 69 bodova" << endl;
break;
default:
cout << "Imate ispod 60 bodova" << endl;
}
}

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 41

4.4 Naredba while


Naredba while (naziva se i while petlja) omogučuje ponavljanje neke naredbe sve dok je
ispunjen neki uslov. Opšti oblik ove naredbe je:

Prvo se izračunava izraz (naziva se i uslov petlje). Ako je rezultat različit on nule tada se
izvršava naredba (naziva se i tijelo petlje) i cijeli proces se ponavlja. U suprotnom, proces se
zaustavlja.
Na primjer, ako bismo željeli izračunati zbir svih brojeva od 1 do n, upotreba while naredbe
bi izgledala kao:

i = 1;
sum = 0;
while (i <= n)
sum += i++;

Interesantno je da nije neuobičajeno za while naredbu da ima prazno tijelo petlje, tj. null-
naredbu. Takav primjer je problem nalaženja največeg neparnog faktora nekog broja

while (n % 2 == 0 && n /= 2)
;

Ovdje uslov petlje izvršava sve neophodne kalkulacije, tako da nema potrebe za tijelom.

4.5 Naredba do
Naredba do (naziva se i do petlja) je slična naredbi while, osim što se prvo izvršava tijelo
petlje, a zatim se provjerava uslov. Opšti oblik naredbe je:
while (izraz)
naredba;

Prvo se izvršava naredba, a zatim provjerava izraz. Ako je izraz različit od nule cijeli
proces se ponavlja. U suprotnom, petlja se zaustavlja. do petlja se manje koristi nego while
petlja. Obično se koristi kada se tijelo petlje mora izvrčiti najmanje jedanput bez obzira na
ispunjenje uslova. Takav primjer je ponovljeno unošenje nekog broja i izračunavanje
njegovog kvadrata dok se ne unese 0:

do {
cin >> n;
cout << n * n << '\n';
} while (n != 0);
Za razliku od while petlje, do petlja se nikada ne koristi sa praznim tijelom prvenstveno
zbog jasnoće.

4.6 Naredba for

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 42
Naredba for (for petlja) je slična naredbi while, ali ima dvije dodatne komponente: izraz
koji se izračunava samo jednom prije svega, i izraz koji se izračunava jednom na kraju svake
iteracije.
Opšti oblik naredbe for je:
Prvo se izračunava izraz1. Svakim prolazom proz petlju se izračunava izraz2. Ako je
rezultat različit od nule izračunava se izraz3. U suprotnom petlja se zaustavlja. Oblik while
petlje koja je ekvivalenta do petlji je:
for petlja se najčešče koristi u situacijama kada se neka promjenljiva povečava ili smanjuje
za neku veličinu u svakoj iteraciji, odnosno kada je broj iteracija unaprijed poznat. Sljedeči
primjer računa zbir svih brojeva od 1 do n:

sum = 0;
for (i = 1; i <= n; ++i)
sum += i;

Bilo koja od komponenti u petlji može biti prazna. Na primjer, ako se uklone prvi i treči izraz,
onda

do petlja liči na while petlju:


do
naredba;
while (izraz);
for (izraz1; izraz2; izraz3)
naredba;
izraz1;
while (izraz2) {
naredba;
izraz3;
}

for (; i != 0;) // je ekvivalentno sa: while (i != 0)


bilo-sta; // bilo-sta;
Uklanjanje svih izraza u petlji daje beskonačnu petlju:
for (;;) // beskonačna petlja
bilo-sta;

Pošto petlje predstavljaju naredbe, mogu se pojaviti unutar drugih petlji (tzv. ugniježdene
petlje).
Na primjer:

for (int i = 1; i <= 3; ++i)


for (int j = 1; j <= 3; ++j)
cout << '(' << i << ',' << j << ")\n";
daje parove skupa {1,2,3}

5 Funkcije

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 43
Ovo poglavlje opisuje funkcije, koje definiše korisnik, kao jedan od glavnih građevinskih
blokova u C++ programiranju. Funkcije obezbijeđuju prikladan način upakivanja nekog
numeričkog recepta, koji se može koristiti koliko god je to puta potrebno.

5.1 Definicija funkcije


Definicija funkcije se sastoji od dva glavna dijela: zaglavlja ili interfejsa, i tijela funkcije.
Interfejs (neki ga nazivaju i prototip) definiše kako se funkcija može koristiti. On se sastoji od
tri dijela:

Imena. Ovo je, u stvari, jedinstveni identifikator.


Parametara (ili potpisa funkcije). Ovo je niz od nula ili više identifikatora nekog tipa koji se
koriste za proslijeđivanje vrijednosti u i iz funkcije.
Tipa funkcije. Ovo specificira tip vrijednosti koji funkcija vrača. Funkcija koja ne vrača
nijednu vrijednost bi trebala da ima tip void.

Tijelo funkcije sadrži računske korake (naredbe) koji čine neku funkciju.
Korištenje funkcije se izvodi njenim pozivanjem. Poziv funkcije se sastoji od imena funkcije,
pračenim zagradama za pozivanje (). Unutar ovih zagrada se pojavljuje nula ili više
argumenata koji se odvajaju zarezom. Broj argumenata bi trebao odgovarati broju parametara
funkcije. Svaki argument je izraz čiji tip bi trebao odgovarati tipu odgovarajučeg parametra u
interfejsu funkcije.
Kada se izvršava poziv funkcije, prvo se računaju argumenti i njihove rezultujuče vrijednosti
se pridružuju odgovarajučim parametrima. Nakon toga se izvršava tijelo funkcije. Na kraju,
funkcija vrača vrijednost (ako ista postoji) pozivu.
Sljedeči primjer ilustrativno pokazuje definiciju jednostavne funkcije koja izračunava
vrijednost stepen cijelog broja na neki cijeli broj.

int Stepen (int baza, unsigned int eksponent)


{
int rezultat = 1;
for (int i = 0; i < eksponent; ++i)
rezultat *= baza;
return rezultat;
}

Linija 1 definiše interfejs funkcije. Ona počinje tipom funkcije koji se vrača (u ovom slučaju
int).
Nakon toga je dato ime funkcije (Stepen), a zatim njena lista parametara. Funkcija Stepen
ima dva parametra (baza i eksponent) koji su tipa int. Sintaksa parametara je slična sintaksi
definisanja varijabli, tj. nakon tipa daje se ime parametra. Međutim, nije moguče nakon tipa
dati niz parametara odvojenih zarezom, kao u
int Stepen (int baza, eksponent) // Ovo je pogrešno!
Zagrada { u liniji 2 predstavlja početak tijela funkcije.
Linija 3 definiše lokalnu varijablu.
Linije 4 i 5 računaju stepen varijable baza na varijablu eksponent pomoču for petlje.
Rezultat se pohranjuje u varijablu rezultat.

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 44
U liniji 6 vrača se vrijednost rezultat kao rezultat funkcije.
Zagrada } u liniji 7 predstavlja kraj tijela funkcije.
Naredni primjer pokazuje kako se funkcija poziva. Posljedica poziva funkcije je da se
vrijednosti argumenata 2 i 8 pridružuju parametrima baza i eksponent, respektivno, a zatim
se računa tijelo funkcije.

#include <iostream>
using namespace std;
main (void)
{
cout << "2 ^ 8 = " << Stepen(2,8) << '\n';
}
Kada se program pokrene daje sljedeči izlaz:
2 ^ 8 = 256
Opčenito, funkcija se treba definisati prije nego se koristi. To se može uraditi na više načina,
kao što je pokazano u narednim primjerima.

Primjer 1.

#include <iostream>
using namespace std;
double Stepen (int baza, int eksponent)
{
double rezultat = 1;
for (int i = 0; i < eksponent; ++i)
rezultat *= baza;
return rezultat;
}
main ()
{
int a,b;
cout << "Unesi bazu:";
cin >> a;
cout << "\nUnesi eksponent:";
cin >> b;
cout << a<<"^" <<b<<" = " << Stepen(a,b) << '\n';
system("PAUSE");
}

Primjer 2.
Treba napomenuti da se deklaracija funkcije sastoji od njenog prototipa, tako da je za
deklarisanje dovoljno ispisati samo njen prototip. Na taj način, kompletna definicija funkcije
se može dati kasnije, kao što je pokazano u narednom primjeru. Također je moguče izostaviti
nazive parametara
u deklaraciji, ali to nije preporučljivo.

#include <iostream>
using namespace std;
double Stepen (int baza, int eksponent); // deklarisanje funkcije
/* moguce je funkciju daklarisati i na sljedeci nacin
double Stepen (int, int);

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 45
*/
main ()
{
int a,b;
cout << "Unesi bazu:";
cin >> a;
cout << "\nUnesi eksponent:";
cin >> b;
cout << a<<"^" <<b<<" = " << Stepen(a,b) << '\n';
system("PAUSE");
}
double Stepen (int baza, int eksponent)
{
double rezultat = 1;
for (int i = 0; i < eksponent; ++i)
rezultat *= baza;
return rezultat;
}
Primjer 3.
Radi preglednosti veoma je korisno sakupiti sve funkcije u posebne datoteke, i umjesto
njihovog definisanja u sklopu izvršne datoteke, treba samo pročitati tu datoteku. Na primjer,
ako je definicija funkcije Stepen data u datoteci StepenInt.h, onda bi prehodni program
bio:

#include <iostream>
#include “StepenInt.h”
using namespace std;
main ()
{
int a,b;
cout << "Unesi bazu:";
cin >> a;
cout << "\nUnesi eksponent:";
cin >> b;
cout << a<<"^" <<b<<" = " << Stepen(a,b) << '\n';
system("PAUSE");
}

Ovdje treba paziti gdje se datoteka StepenInt.h nalazi. U primjeru koji je dat, ona se nalazi
u istom direktoriju kao i izvršna datoteka. U suprotnom, treba dati tačan (relativni ili
apsolutni) položaj (path) iste.

5.2 Parametri i argumenti


C++ podržava dva oblika parametara: vrijednost i referencu. Parametar po vrijednosti prima
kopiju
vrijednosti argumenata koja im se prenosi. Kao posljedica toga, ako funkcija napravi bilo
kakvu
promjenu na parametrima, ovo neče promijeniti vrijednosti argumenta. Na primjer,
#include <iostream>
using namespace std;
void Foo (int broj)
{
broj = 0;

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 46
cout << "broj = " << broj << '\n';
}
int main ()
{
int x = 10;
Foo(x);
cout << "x = " << x << '\n';
system("PAUSE");
return 0;
}
parametar broj u funkciji Foo je parametar po vrijednosti. On se ponaša kao lokalna
varijabla u funkciji. Kada se funkcija pozove i vrijednost x se prenese, varijabla broj primi
kopiju vrijednosti varijable x. Kao rezultat toga, iako varijabla num u funkciji mijenja
vrijednost na 0, to neče utjecati na varijablu x. Program če dati sljedeči izlaz:
broj = 0;
x = 10;
Za razliku od parametra po vrijednosti, parametar po referenci prima argument koji se prenosi
i sve obavlja direktno na njemu. Bilo koja promjena parametra po referenci u samoj funkciji,
direktno se odnosi i na argument, tj. i on se mijenja. Da bismo definisali parametar po
referenci, potrebno je dodati simbol & iza tipa parametra u interfejsu funkcije, tj. u
predhodnom primjeru interfejs funkcije
Foo bio bi
void Foo (int& num)
U kontekstu pozivanja funkcija, a na osnovu prethodno iznesenog, razlikujemo dvije vrste
pridruživanja: priduživanje prema vrijednosti i pridruživanje prema referenci. U praksi (u
pogledu funkcija) se mnogo više koristi priduživanje prema vrijednosti.

5.3 Globalne i lokalne varijable (globalni i lokalni scope)


Za sve što se definiše izvan programskog scope-a se kaže da ima globalni scope. Tako, sve
funkcije koje smo do sada koristili imaju globalni scope, i predstavljaju globalne funkcije. No,
i varijable se mogu defnisati u globalnom scope-u, tj. izvan svih funkcija koje se koriste u
programu. Na primjer:

int godina = 1994; // globalna varijabla


int Maksimum (int, int); // globalna funkcija
int main (void) // globalna funkcija
{
//...
}
Treba zapamtiti da su globalne varijable automatski inicijalizirane na vrijednost nula.
Pošto su globalni entiteti vidljivi na svim programskim novoima, oni moraju biti jedinstveni
na nivu programa. To znači da se globalne varijable ili funkcije na globalnom scope-u ne
mogu definisati više nego jedanput, iako se ime funkcije može definisati više puta sve dok su
im parametri (njen potpis) jedinstveni. Globalni entiteti su opčenito pristupačni bilo gdje u
programu.
Svaki blok u programu definiše lokalni scope. Na taj način, tijelo funkcije predstavlja lokalni
scope.
Parametri funkcije imaju isti scope kao i tijelo funkcije. Varijable koje su definisane unutar
lokalnog scope-a su vidljive samo u tom scope-u. Lokalni scope može da bude ugniježden, pri
čemu unutrašnji scope poništava vanjski. Na primjer, u

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 47

int xyz; // xyz je globalna varijabla


void Foo (int xyz) // xyz je lokalna varijabla u tijelu funkcije Foo
{
if (xyz > 0) {
double xyz; // xyz je lokalna varijabla u ovom bloku
//...
}
}
Imamo tri različita scope-a, od kojih svaki ima različitu varijablu xyz.
Opčenito, životni vijek varijable je ograničen na njen scope. Tako, na primjer, globalne
varijable traju svo vrijeme izvršenja programa, dok se lokalne varijable kreiraju kada se uđe u
njihov scope, a uništavaju kada se izlazi iz njihovog scope-a. Memorijski prostor za lokalne
varijable je rezervisan prije izrvršenja programa, dok je memorijski prostor za lokalne
varijable alociran ‘u hodu’ u toku izvršenja programa.

Pošto lokalni scope poništava globalni, to lokalne varijable sa istim imenom kao globalne
varijable onemogučavaju pristup globalnim varijablama unutar lokalnog scope-a.
Na primjer, u int greska;
void Greska (int greska)
{
//...
}
globalna varijabla greska je nepristupačna unutar funkcije Greska, pošto je poništena
lokalnim parametrom greska.
Ovaj problem se može prevaziči korištenjem unarnog operatora :: (unary scope operator),
koji globalni entitet uzima kao argument, kao u primjeru
int greska;
void Greska (int greska)
{
//...
if (::greska != 0) // odnosi se na globalnu varijablu error
//...
}

5.4 Rekurzivne funkcije


Za funkciju koja poziva samu sebe kažemo da je rekurzivna. Rekurzija je opšta programska
metoda koja se primijenjuje na probleme koji se definišu u odnosu na same sebe. Na primjer,
problem računanja faktorijela je primjer rekurzivne funkcije.

Faktorijel je definisan sa:


Faktorijel od 0 je 1.
Faktorijel pozitivnog broja n je n puta faktorijel od n-1

Posljednji dio definicije jasno pokazuje da je faktorijel definisan u odnosu na samog sebe, te
se stoga može predstaviti rekurzivnom funkcijom, npr.
int Faktorijel (unsigned int n)

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 48
{
return n == 0 ? 1 : n * Faktorijel(n-1);
}
U principu, sve rekurzivne funkcije se mogu napisati koristeči iteracije. Naime, treba imati u
vidu da u slučaju velikog broja poziva funkcija (u primjeru faktorijela je to veliki broj n),
dolazi do zauzimanja velikog memorijskog prostora (tzv. runtime stack), pa je upotreba
iteracija bolje rješenje. No, u nekim slučajevima elegantno i jednostavno rekurzivno rješenje
može da bude bolja opcija.

U slučaju faktorijela, iterativna opcija je bolja, pa bi funkcija imala oblik:


int Factorijel (unsigned int n)
{
int rezultat = 1;
while (n > 0) rezultat *= n--;
return rezultat;
}

5.5 Opterečene (overloaded) funkcije


U prethodnim poglavljima je pomenuto da je moguče definisati više funkcija sa istim imenom,
pri čemu njen potpis mora biti drugačiji. Ovaj postupak se naziva opterečivanje (overloading,
specijalni oblik polimorfizma) i predstavlja jednu od osnovnih karakteristika OOP.
Ako bismo željeli da naša funkcija Stepen ima mogučnost korištenja realnih brojeva umjesto
cijelih, ili čak da izračunava vrijednost stepena broja 2 na neki realan broj, onda bismo
definisali dvije dodatne funkcije sa istim imenom, ali različitim potpisom. Sljedeči primjer
pokazuje korištenje ovakvih funkcija.

#include <iostream>
#include <cmath>
using namespace std;
int Stepen (int baza, int eksponent)
{

int rezultat = 1;
for (int i = 0; i < eksponent; ++i)
rezultat *= baza;
return rezultat;
}
double Stepen (double baza, double eksponent) // funkcija Stepen sa
realnim parametrima
{
return exp(eksponent*log(baza));
}
double Stepen (double eksponent) // funkcija Stepen sa jednim
parametrom za izračunavanje stepena broja 2
{
return Stepen(2.0,eksponent);
}
main (void)
{
double a,b;
cout << "Unesi bazu:";
cin >> a;
cout << "\nUnesi eksponent:";

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 49
cin >> b;
cout << a<<"^" <<b<<"= " << Stepen(a,b) << '\n';
cout << "2^" <<b<<"= " << Stepen(b) << '\n';
system("PAUSE");
}
Iz primjera se vidi da sve funkcije imaju isto ime, ali različite tipove, a u drugom slučaju i
različit broj parametara. Treba paziti da pri pozivu pojedinih funkcija svi tipovi argumenata
odgovaraju tipovima parametara (broj 2 je cijeli broj, dok je 2.0 realan!!!)

6. Polja
Ovo poglavlje objašnjava polja i ilustruje njihovu upotrebu pri definisanju varijabli. Polje se
sastoji od niza objekata (nazivaju se i elementi niza), koji su istog tipa i zauzimaju neprekidan
memorijski prostor. Opčenito, samo polje ima simboličko ime, a ne njegovi elementi. Svaki
elemenat je identificiran njegovim indeksom, koji pokazuje položaj nekog elementa u nizu.
Broj elemenata u nizu naziva se dimenzija polja. Dimenzija polja je fiksirana i prethodno
određena, i ne može se promijeniti u toku izvršenja programa.
Polja su pogodna za predstavljanje podataka koji se sastoje od mnogo sličnih, individualnih
objekata. Primjeri za to su lista imena, tabela gradova i njihovih sezonskih temperatura.

6.1 Definisanje i inicializacija polja


Varijabla polje je definisana specificiranjem njegove dimenzije i tipa njegovih elemenata. Na
primjer, polje koje obuhvata 10 mjerenja visine (od kojih je svaka cijeli broj) može se
definisati na sljedeči način:

int visina[10];
Pristup individualnim elementima nekog niza vrši se indeksiranjem niza. Prvi elemenat niza
uvijek ima indeks 0. Na taj način, visina[0] i visina[9] označavaju prvi i posljednji
elemenat niza

visina, respektivno. Svaki elemenat niza se može tretirati kao varijabla tipa cijeli broj. Tako,
na primjer, da bi smo trečem elementu ovog niza pridružili vrijednost 177, pisali bismo:
visina[2] = 177;
Pokušaj pristupa nepostoječem elementu nekog niza (na primjer visina[-1] ili visina[10])
može uzrokovati ozbiljnu grešku (tzv. runtime greška, ili greška 'indeks izvan granica’).
Procesiranje bilo kojeg niza obično uključuje korištenje petlje, koja ide kroz niz od elementa
do elementa. Sljedeči primjer pokazuje funkciju koja računa srednju vrijednost nekog niza:

const int velicina = 3;


double Srednja (int broj[velicina])
{
double srednja = 0;
for (int i = 0; i < velicina; ++i)
srednja += broj[i];
return srednja/velicina;
}

Kao i kod ostalih varijabli, vrijednosti elemenata niza se mogu inicijalizirati. U tu svrhu
koriste se zagrade{}, između kojih se specificira lista početnih vrijednosti elemenata niza koje
su odvojene zarezom. Na primjer, nt broj[3] = {5, 10, 15};

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 50
definiše niz broj, i inicijalizira tri elementa ovog niza na vrijednosti 5, 10, 15, respektivno.
Ovo je tzv. eksplicitno inicijaliziranje. Kada je broj vrijednosti u inicijalizatoru manji od
dimenzije niza, ostali elementi su inicijalizirani na nulu, kao u slučaju: int broj[3] = {5, 10}; //
broj[2] je inicijaliziran na 0
Kada se koristi potpuni inicijalizator (broj početnih vrijednosti odgovara dimenziji niza),
dimenzija niza postaje suvišna i može se izostaviti, tj. broj elemenata je implicitan u
inicijalizatoru (implicitna inicijalizacija). U ovom slučaju inicijalizacija niza broj se može
izvršiti i na sljedeči način:

int broj[] = {5, 10, 15}; // dimenzija nije potrebna


Još jedan primjer u kojem se dimenzija niza može izostaviti je kada je niz parametar u nekoj
funkciji. Na primjer, funkcija Average iz ranijeg primjera se može napisati na bolji način, ako
se postavi da dimenzija niza nije fiksirana na neku konstantnu vrijednost, nego se dodaje još
jedan parametar, tj.

double Srednja (int broj[], int velicina)


{
double srednja = 0;
for (int i = 0; i < velicina; ++i)
srednja += broj[i];
return srednja/velicina;
}

Kompletan program bi, u tom slučaju, bio:


#include <iostream>
using namespace std;
double Srednja (int broj[],int velicina)
{
double srednja = 0;
for (int i = 0; i < velicina; ++i)
srednja += broj[i];
return srednja/velicina;
}
main ()
{
int velicina;
cout <<"Broj elemenata ....";
cin >> velicina;
int n[velicina];
for(int i=0;i<velicina;i++){
cout<<"n["<<i<<"]= ";
cin>>n[i];
}
cout << "Srednja vrijednost je .... "<<Srednja(n,velicina) <<
"\n";
system("PAUSE");
}
Sljedeči program predstavlja primjer pomoču kojeg se unosi, sortira i ispisuje neki niz. Pri
tome,sortiranje je izvedeno od največeg prema najmanjem elementu niza.

#include <iostream>
using namespace std;

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 51
int main ()
{
// DEKLARACIJA
int x[10];
int y[10];
int i, j, n;
// UNOSENJE
cout << "Unesite broj clanova polja: ";
cin >> n;
for (i = 0; i < n; i++)
{
cout << "Unesite clan br. " << i << ": ";
cin >> x[i];
y[i] = x[i];
}
// SORTIRANJE
for (i = 0; i < n-1; i++)
{
for (j = i+1; j < n; j++)
{
if (y[i] < y[j]) swap(y[i],y[j]);
}
}
// STAMPANJE
cout << "x:" << '\t' << "y:" << endl;
for (i = 0; i < n; i++)
{
cout << x[i] << '\t' << y[i] << endl;
}
}

Interesantno je napomenuti da je i C++ string niz karaktera. Tako char str[] = "HELLO";
definiše varijablu str kao niz šest (6) karaktera: pet slova i prazan karakter (null-character).
Završni prazan karakter postavlja kompajler. Za razliku od toga, char str[] = {'H', 'E', 'L', 'L', 'O'};
definiše varijablu str kao niz od 5 elemenata.

6.2 Multidimenzionalni nizovi


Niz može da ima i više nego jednu dimenziju (dvije, tri, i više). Ipak, organizacija niza u
memoriji je ista kao i prije, tj. neprekidna sekvenca elemenata. Percepcija programera, pak, je
drugačija. Na primjer, pretpostavimo da je srednja vrijednost temperatura po godišnjim
dobima za tri australijska grada data sljedečom tabelom

Ovo se može predstaviti dvodimenzionalnim nizom cijelih brojeva:

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 52
int godDobTemp[3][4];
Ovo je u memoriji predstavljeno kao neprekidan niz od 12 elemenata tipa cijeli broj.
Programer, međutim, može to zamisliti kao tri reda od po 4 elementa u svakom, kao na Sl.
II.6.1.

Slika II.6.1 Organizacija varijable godDobTemp u memoriji

Kao i kod jednodimezionalnih nizova, elementima nizova se pristupa preko indeksa. No,
neophodan
je dodatni indeks za svaku dimenziju. Na primjer, srednja temperatura u Sidneju u toku ljeta,
data je
elementom godDobTemp[0][1].

Inicijalizacija niza se može obaviti pomoču ugniježdenog inicijalizatora, kao:


int godDobTemp[3][4] = {
{26, 34, 22, 17},
{24, 32, 19, 13},
{28, 38, 25, 20}
};

Pošto se ovaj dvodimenzionalni niz mapira kao jednodimenzionalni niz od 12 elemenata,


moguče je koristiti i:

int godDobTemp[3][4] = {
Prolječe Ljeto Jesen Zima
Sidnej 26 34 22 17
Melburn 24 32 19 13
Brizbejn 28 38 25 20

... 32 19 13 28 26 34 22 17 24 38 25 20 ...
First row Second row Third row
Prvi red Drugi red Treči red

26, 34, 22, 17, 24, 32, 19, 13, 28, 38, 25, 20
};

Ipak, bolja opcija je korištenje ugniježdenog inicijalizatora, pošto ne samo da je pregledniji,


nego daje i dodatne mogučnosti. Na primjer, ako nam je samo prvi elemenat svakog reda
različit od nule, a ostali su jednaki nuli, mogli bismo koristiti:
int godDobTemp[3][4] = {{26}, {24}, {28}};
Također je moguče izostaviti prvu dimenziju (implicitna inicijalizacija), kao u:
int godDobTemp[][4] = {
{26, 34, 22, 17},
{24, 32, 19, 13},
{28, 38, 25, 20}
};

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 53
Procesiranje multidimenzionalnih nizova je slično jednodimenzionalnim, s tim da se moraju
korisiti ugniježdene petlje. Sljedeči primjer pokazuje pronalaženje maksimalnog elementa u
dvodimenzionalnom nizu iz prethodnih primjera.

#include <iostream>
using namespace std;
const int redovi = 3;
const int kolone = 4;
int godDobTemp[redovi][kolone] = {
{26, 34, 22, 17},
{24, 32, 19, 13},
{28, 38, 25, 20}
};
int najvecaTemp (int temp[redovi][kolone])
{
int najveca = 0;
for (int i = 0; i < redovi; ++i)
for (int j = 0; j < kolone; ++j)
if (temp[i][j] > najveca)
najveca = temp[i][j];
return najveca;
}
main ()
{
cout << najvecaTemp(godDobTemp) << "\n";
system("PAUSE");
}

Napomena: Treba paziti kako se inicijalizira vrijednost kontrolne varijable najveca u


prethodnom primjeru. Ovdje se koristila vrijednost nula. Međutim, najbolje bi bilo kada bi se
inicijalizirala na vrijednost prvog elementa niza, jer u slučaju svih negativnih elemenata niza,
nula bi rezultat funkcije bez obzira da li je član niza ili ne.

7. Datoteke
Ovo poglavlje pokazuje kako se podaci dobiveni pokretanjem nekog programa mogu sačuvati
njihovim pohranjivanjem na neku datoteku. S obzirom da čuvanje podataka nema svrhu ako
tim podacima ne možemo da pristupamo, biče objašnjeno i kako pročitati podatke sa neke
datoteke.

Datoteka, pri tome, predstavlja skup podataka koji su snimljeni na neku formu trajne memorije
(hard disk, CD-ROM, floppy disk, ...). Datoteci se pristupa preko njenog imena (filename), u
čijem sastavu se obično nalazi ekstenzija (dio imena iza tačke), koja označava tip podataka u
datoteci (npr. .doc za Microsoft Word, .xls Microsoft Excel, .cpp za C++ izvršnu datoteku,
itd.).
U osnovi, postoje dvije vrste datoteka: tekstualne i binarne. Tekstualne datoteke sadrže tekst,
dok binarne mogu sadržavati i kompleksnije vrste podataka, kao što su slike, izvršni programi,
baze podataka, itd. Tekstualnim datotekama je nešto jednostavnije pristupiti, pisati podatke u
njih, te čitati sa njih. Upravo to je i razlog zbog čega če se primjeri u ovom poglavlju odnositi
samo na njih.

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 54

7.1 Standardna biblioteka fstream


U ranijim poglavljima koristili smo standardnu biblioteku iostream (io se odnosi na
input/output), koja pored ostalog, daje mogučnost ispisivanja na standardni izlaz (ekran,
monitor) pomoču cout, te čitanje sa standardnog upisa (tastatura) pomoču cin. Međutim, ova
datoteka nam ne omogučava da podatke trajno sačuvamo. U tu svrhu se koristi standardna
biblioteka fstream (f se odnosi na datoteku, tj. file), koja omogučava pisanje na i čitanje sa
datoteka. Ovo se postiže pozivanjem sadržaja fstream sa:

#include <fstream>
Datoteka fstream definiše tri nova tipa podataka:

ofstream. Ovaj tip podataka predstavlja stream za izlazne datoteke (o se odnosi na


output). Pravac izlaza je sa programa na datoteku. Ovaj tip podataka se koristi za kreiranje
datoteka i pisanje informacija na njih. Ne može se koristiti za čitanje datoteka.

ifstream. Ovaj tip podataka predstavlja stream za ulazne datoteke (i se odnosi na input).
Pravac ulaza je sa datoteke prema programu. Ovaj tip podataka se koristi za čitanje
informacija sa datoteka. Ne može se koristiti za kreiranje datoteka i pisanje na njih.

fstream. Ovaj tip podataka predstavlja opčenito stream za datoteke, ima karateristike I
ofstream i ifstream. On može kreirati datoteke, pisati na njih i čitati sa njih.

7.2 'Životni’ ciklus pristupa datotekama


Kada program pristupa datotekama, bez obzira da li ih čita, ili na njih piše, ili čini oboje, on
prolazi kroz sljedeče korake:

Datoteka prvo mora da se otvori. Ovo otvara put u komunikaciji između datoteke i stream
objekta u programu (fstream, ifstream, ofstream), koji se koristi u pristupu datoteci.

Nakon otvaranja program čita sa datoteke, piše na nju, ili čini oboje.

Na kraju, program zatvara datoteku. Ovo je bitan korak, pošto održavanje komunikacije
između datoteke i stream objekta zahtijeva resurse, tako da zatvaranje datoteke oslobađa ove
resurse kada više nisu potrebni. Uz to, postoji mogučnost da se kasnije u programu ne može
pristupiti datoteci ako nije zatvorena prije prethodnog pristupa.

7.2.1 Otvaranje datoteka


Bez obzira da li se sadržaj datoteke treba pročitati ili se na datoteku trebaju ispisati neki
podaci, datoteka prvo treba da se otvori. Naredna poglavlja pokazuju kako se to obavlja.

Otvaranje datoteke za pisanje


Datoteke sa pisanje se mogu otvoriti pomoču fstream i ofstream objekata na dva načina:
(i) pomoču metode (member function) open, ili (ii) pomoču konstruktora (constructor).

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 55
Otvaranje pomoču funkcije open Prvi argument funkcije open je ime i lokacija datoteke koja se
treba otvoriti. Međutim, moguče je dodati i drugi argument zavisno od toga da li se fstream i
ofstream poziva funkciju open, ili se želi neki drugi modul od onog koji se daje.
Datoteka u koju želimo pisati podatke ne mora postojati. U slučaju da ne postoji, ona če se
automatski kreirati pod imenom i na lokaciji koju smo upisali. Lokacija se može dati kao
relativna (relative path) i apsolutna (absolute path). Pri tome, relativni put predstavlja lokaciju
u odnosu na naš program, tj. datoteka se stvara u direktoriju u kojem se nalazi i naš program.
Ovo postižemo na sljedeči način:

ofstream izlaz;
izlaz.open("studenti.txt");
Za razliku od relativnog puta, apsolutni put predstavlja lokaciju koja započinje slovom drajva,
sadržeči sve direktorije i poddirektorije dok se ne dođe do datoteke. Na primjer, ako je
datoteka studenti.txt u direktoriju Pedagoski, a ovaj je podirektorij direktorija UNZE, a sve se
nalazi na tvrdom disku sa slovom C, onda bi se datoteka otvorila na sljedeči način:

ofstream izlaz;
izlaz.open("C:\\MFZE\\Pedagoski\\studenti.txt");
Vidimo da se u tom slučaju koriste po dva znaka \\, jer samo jedan između navodnika
predstavlja escape-sekvencu (poglavlje II.2.10).

Bez obzira da li koristimo relativni ili apsolutni put, argument za funkciju open ne mora da
bude neko ime (riječ), nego i (string) varijabla, kao što je to u sljedečem primjeru:

ofstream izlaz;
char imeDatoteke[80];
cout << "Unesite ime datoteke: ";
cin >> imeDatoteke;
izlaz.open(imeDatoteke);

Važno je zapamtiti da je korištenje relativnog puta bolja opcija, jer se može desiti da neki
direktorij u apsolutnom putu ne postoji, naročito ako se program koristi na nekom drugom
računaru (sa drugačijim direktorijima).

Korištenje drugog argumenta u funkciji open definiše modul u kojem se datoteka treba
otvoriti.

Neke od opcija (tzv. file mode flag), koje se mogu koristiti date su u Tabeli II.7.1.
Tabela II.7.1
Opcija (file mode flag) Opis
ios::app Postoječi sadržaj datoteke je očuvan i sav izlaz se ispisuje na
kraj datoteke.
ios::binary Informacija se na datoteku piše u binarnom obliku.
ios::in Infomacija če se čitati sa datoteke. Datoteka se ne kreira ako ne
postoji.
ios::out Informacija če se zapisati u datoteku. Postoječi sadržaj datoteke
je poništen.

Ako za otvaranje datoteke koristimo ofstream objekat, onda ne moramo koristiti dodatne

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 56
argumente, ali treba zapamtiti da u tom slučaju možemo samo upisivati informaciju da
datoteku, ali ne i čitati sa nje. Ako bismo, na primjer, željeli da pratimo greške izazvane
pokretanjem nekog programa i željeli sačuvati sve zapise o tome, koristili bismo opciju
ios::app, tj.

ofstream izlaz;
izlaz.open("studenti.txt", ios::app);
Međutim, ako se za otvaranje datoteke za pisanje koristi fstream objekat, treba se dodati još
jedan argument, tj. opcija za pisanje (ios::in). U ovom slučaju bi bilo:
fstream izaz;
izlaz.open("studenti.txt", ios::out);

Otvaranje pomoču konstruktora Konstruktori su funkcije koje se automatski pozivaju kada se


pokušava kreirati primjerak (instanca) nekog objekta (instanca prema objektu je isto što i
varijabla prema tipu podatka). Oni mogu biti opterečeni (overloaded), tako da isti objekat
može imati konstruktor sa nijednim, jednim, dva, ili više argumenata. U prethodnim
primjerima (npr. fstream izlaz;) korištene su naredbe sa konstruktorima bez argumenata.

Naredni primjeri pokazuju upotrebu konstruktora sa jednim i dva argumenta, respektivno:


ofstream izaz("studenti.txt");
fstream izaz("studenti.txt",ios::out);

Primjena konstruktora, u stvari, omogučava deklarisanje i inicijalizaciju primjerka nekog


objekta. Kao i u slučaju deklarisanja i inicijalizacije varijabli, korištenje jednog od načina
otvaranja datoteke zavisi od samog programa i naših potreba.
Otvaranje datoteka za čitanje Sve što je rečeno u prethodnom poglavlju može se primijeniti i
na otvaranje datoteka za čitanje.

Jedina razlika je što se, uz korištenje objekta fstream, umjesto objekta ofstream koristi
iostream objekat. Uz to, datoteka sa koje se čita mora postojati, jer se pokretanjem jednog
od prethodnih objekata ne kreira datoteka.
Stoga, otvaranje datoteke za čitanje se može otvoriti na jedan od sljedečih načina:

ifstream ulaz;
ulaz.open("studenti.txt");
fstream ulaz;
ulaz.open("studenti.txt", ios::in); //obavezno dodati argument ios::in
ifstream ulaz("studenti.txt");
fstream ulaz("studenti.txt", ios::in);

Otvaranje datoteka za čitanje i pisanje


Kao što je ranije rečeno, objekat fstream se može koristiti za otvaranje datoteka i za pisanje i za
čitanje. U tu svrhu koristi se sljedeča sintaksa:

fstream izlazUlaz;
izlazUlaz.open("studenti.txt", ios::in | ios::out);
ili pomoču konstruktora: fstream izlazUlaz ("studenti.txt", ios::in | ios::out);
U oba primjera korišten je tzv. bitwise operator (|), koji ima isto značenje kao logički operator
(ili).

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 57

Provjera da li je datoteka otvorena. Prije nego počnemo čitati podatke sa neke datoteke,
korisno je znati da li ona uopšte postoji. Provjera se može izvršiti na dva načina. Ako se
datoteka ne može otvoriti za čitanje, onda je: (i)
vrijednost ifstream objekta jednaka NULL (nula), (ii) vrijednost funkcije fail objekta
ifstream je true(1). Sljedeči primjer ilustruje korištenje oba načina.

#include <fstream>
#include <iostream>
using namespace std;
int main (){
ifstream ulaz;
ulaz.open("studenti.txt");
cout << "(ulaz) = " << ulaz << endl;
cout << "(ulaz.fail()) = " << ulaz.fail() << endl;
return 0;
}

Ako datoteka studenti.txt ne postoji nakon izvršenja programa dobijamo:


(ulaz) = 0
(ulaz.fail()) = 1
U slučaju da postoji izlaz bi, na primjer, bio:
(ulaz) = 0x22fed4
(ulaz.fail()) = 0

Pri čemu 0x22fed4 predstavlja memorijsku lokaciju (adresu) ifstream varijable ulaz.
Za razliku od ifstream objekta, ofstream objekat koji pokušava otvoriti datoteku koja ne
još postoji nije NULL, a njegova fail funkcija ima vrijednost false(0). To je zbog toga što
operativni sistem kreira datoteku, ako ona ne postoji. Ipak, i u ovom slučaju je korisno
provjeriti da li datoteka postoji. Naime, ako datoteka postoji, ali ima osobinu read-only,
dobičemo negativan odgovor o njenom postojanju (vrijednost iostream objekta je NULL, a
funkcije fail je true, tj. 1).

7.2.2 Zatvaranje datoteka


Svaka otvorena datoteka se treba zatvoriti prije nego se napusti program. To je zbog toga što
svaka otvorena datoteka zahtijeva sistemske resurse. Osim toga, neki operativni sistemi imaju
ograničenje na broj otvorenih datoteka kojima se ne 'manipuliše'.
Zatvranje datoteka se vrši pomoču funkcije close. Sljedeči primjeri pokazuju njenu upotrebu
pri zatvaranju datoteka za pisanje i čitanje:
ofstream izlaz;
izlaz.open("studenti.txt");
// skup naredbi
outfile.close();
ifstream ulaz;
ulaz.open("studenti.txt");
// skup naredbi
ulaz.close();
7.2.3 Pisanje na datoteke

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 58
Pisanje podataka na datoteku se izvodi pomoču operatora za ispisivanje (<<), kao što je to bio
slučaj sa ispisivanjem na ekran (cout <<). Jedina razlika je u tome što se ovdje koristi
fstream ili

iostrem objekat, a ne cout objekat.


Sljedeči program pokazuje primjer upisivanja podataka na datoteku studenti.txt:
#include <fstream>
#include <iostream>
using namespace std;
int main (){
char podaci[80];
ofstream izlaz;
izlaz.open("studenti.txt");
cout << "Zapisivanje u datoteku" << endl;
cout << "=======================" << endl;
cout << "Upisite razred: ";
cin.getline(podaci, 80);
izlaz << podaci << endl;
cout << "Unesite broj studenata: ";
cin >> podaci;
cin.ignore();
izlaz << podaci << endl;
izlaz.close();
return 0;
}

Upotrebom drugog argumenta pri otvaranju datoteke za pisanje (ios::app) možemo dodavati
sadržaj na postoječu datoteku kao što to pokazuje sljedeči primjer. U ovom primjeru
zapisivanje se prekida nakon unosa znakova ***.

#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main ()
{
string x;
ofstream izlaz;
izlaz.open("podaci.txt", ios::app);
while (x != "***")
{
cout << "Unesite neki tekst (za kraj unesite ***):" << endl;
cin >> x;
izlaz << x << endl;
}
izlaz.close();
}

7.2.4 čitanje sa datoteka

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 59
Analogno prethodnom poglavlju, čitanje podataka sa datoteka obavlja se pomoču operatora za
čitanje (>>) kao što je to slučaj sa ispisivanjem sa tastature (cin>>). Sljedeči primjer
nadopunjava onaj iz prethodnog poglavlja, tj. nakon što korisnik upisuje informacije na
datoteku, program čita iste podatke i ispisuje ih na ekran.

#include <fstream>
#include <iostream>
using namespace std;
int main (){
string podaci;
ofstream izlaz;
izlaz.open("studenti.txt");
cout << "Upisivanje u datoteku" << endl;
cout << "=====================" << endl;
cout << "Unesite razred: ";
getline(cin,podaci);
izlaz << podaci << endl;
cout << "Unesite broj studenata: ";
cin >> podaci;
cin.ignore();
izlaz << podaci << endl;
izlaz.close();
ifstream ulaz;
cout << "Citanje sa datoteke" << endl;
cout << "===================" << endl;
ulaz.open("studenti.txt");
getline(ulaz,podaci);
cout << podaci << endl;
getline(ulaz,podaci);
cout << podaci << endl;
ulaz.close();
return 0;
}
Međutim, vidimo da je u ovom slučaju korištena C++ string klasa umjesto varijable podaci
tipa
char.

Na taj način se pomoču funkcije getline može ispisati ime razreda koje ima više od jedne
riječi.
Prethodni primjer se može napisati i na programerski adekvatniji način upotrebom funkcija za
čitanje i pisanje na datoteku.

#include <fstream>
#include <iostream>
#include <string>
using namespace std;
bool upisiDatoteku (ofstream&, char*);
bool citajDatoteku (ifstream&, char*);
int main (){
string podaci;
bool status;
ofstream izlaz;

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 60
status = upisiDatoteku(izlaz, "studenti.txt");
if (!status)
{
cout << "Datoteka za ispisivanje se ne moze
otvoriti\n";
cout << "Program se zavrsava\n";
system("PAUSE");
return 0;
}
else {
cout << "Pisanje u datoteku" << endl;
cout << "==================" << endl;
cout << "Upisite razred: ";
getline(cin, podaci);
izlaz << podaci<< endl;
cout << "Unesite broj studenata: ";
cin >> podaci;
cin.ignore();
izlaz << podaci<< endl;
izlaz.close();
}
ifstream ulaz;
status = citajDatoteku(ulaz, "studenti.txt");
if (!status) {
cout << "Datoteka za citanje se ne moze otvoriti\n";
cout << "Program se zavrsava\n";
system("PAUSE");
return 0;
}
else {
cout << "Citanje se datoteke" << endl;
cout << "===================" << endl;
getline(ulaz, podaci);
while(!ulaz.fail()) {
cout << podaci << endl;
getline(ulaz, podaci);
}
ulaz.close();
}
system("PAUSE");
return 0;
}
bool upisiDatoteku (ofstream& datoteka, char* strDatoteka)
{
datoteka.open(strDatoteka);
if (datoteka.fail())
return false;
else return true;
}
bool citajDatoteku (ifstream& datoteka, char* strDatoteka)
{
datoteka.open(strDatoteka);
if (datoteka.fail())
return false;
else return true;
}

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 61

8. Urađeni primjeri

Primjer 8.1

Primjer 8.2

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 62

Primjer 8.3 (Primjer korištenja IF petlje)

Primjer 8.4 (primjer za računanje korijena)

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 63
Primjer 8.5

Primjer 8.6 (izračunavanje Plata)

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 64

Primjer 8.7 (Određivanje parnih i neparnih brojeva)

Primjer 8.8(Naredba switch za određivanje visine)

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 65

Primjer 8.9 (Matrica)

#include <cstdlib>
#include <iostream>
#include <fstream>

using namespace std;

int main(int argc, char *argv[])


{
unsigned int n,i,j;
float A['n']['n'],B['n']['n'];
cout<<"Unesite dimenzije matrice A:\n";
cout<<"n = "; cin>>n;
cout<<"n = m"; n=m;

ifstream unos;
unos.open("matrica.txt");
for(i=0;i<m;i++)
for(j=0;j<n;j++)
{
cout<<" A["<<i<<"]["<<j<<"] = "; unos>>A[i][j]; cout<<" "<<A[i][j];
B[i][j]=0.;
}

cout<<endl<<endl;

for(i=0;i<m;i++)
{
for(j=0;j<n;j++)
{
cout<<A[i][j]<<"\t";
}
cout<<endl;
}
cout<<"\n\n----------------------------\n";

for(i=0;i<n;i++)
for(j=0;j<n;j++)
for(int k=0;k<n;k++)
{
B[i][j]+=A[i][k]*A[k][j];

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 66
}

for(i=0;i<m;i++)
{
for(j=0;j<n;j++)
{
cout<<B[i][j]<<"\t";
}
cout<<endl;
}
cout<<"\n\n----------------------------\n";

system("PAUSE");
return EXIT_SUCCESS;
}

Primjer 8.10 (Kalkulator)

#include <iostream>
#include <math.h>
using namespace std;
void meni()
{
cout<<"\t::MENI::\n";
cout<<"1. Sabiranje"<< endl;
cout<<"2. Oduzimanje"<< endl;
cout<<"3. Mnozenje"<< endl;
cout<<"4. Djeljenje"<< endl;
cout<<"5. Provjera"<< endl;
cout<<"6. Korijen"<<endl;
cout<<"7. Suma uzastponih brojeva"<<endl;
cout<<"8. EXIT"<< endl;
}
int main(void)
{
float a, b, c;
int izbor, x, y;
do {

meni();

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 67
cout<< endl;
cout << "Vas izbor: ";
cin >> izbor;
system("cls");
switch (izbor)
{
case 1:
{
cout <<"Unesite a i b"<< endl;
cin >> a >> b;
c= a+b;
cout <<"Zbir je: "<< c << endl;
system("pause");
system("cls");
}break;

case 2:
{
cout <<"Unesite a i b"<< endl;
cin >> a >> b;
c= a-b;
cout <<"Razlika je: "<< c << endl;
system("pause");
system("cls");
}break;
case 3:
{
cout <<"Unesite a i b"<< endl;
cin >> a >> b;
c= a*b;
cout <<"Proizvod je: "<< c << endl;
system("pause");
system("cls");
}break;
case 4:
{
cout <<"Unesite a i b"<< endl;
cin >> a >> b;
c= a/b;
cout <<"Kolicnik je: "<< c << endl;
system("pause");
system("cls");
}break;
case 5:
{
cout <<"Unesite x i y"<< endl;

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 68
cin >>x>>y;
if (x>y)
{
if (x%2==0)
cout <<"x je veci od y i x je paranbroj.\n";
else
cout<<"x je veci od y i nije paran broj.\n";
}
else
{
if(y%2==0)
cout<<"y je vece od x i paran je broj.\n";
else
cout<<"y je veci od x i nije paran broj.\n";
}
system("pause");
system("cls");
}break;
case 6:
{
cout<<"Unesite broj" <<endl;
cin >> a;
cout<<"Korijen je "<<sqrt (a)<< endl;
system("pause");
system("cls");
}break;
case 7:
{
int suma=0;
cout<<"Unesite broj" <<endl;
cin >> x;
for (int i=0; i<x+1; i++)
suma=suma+i;
cout<<"Suma uzastopnih brojeva je: "<< suma << endl;
system("pause");
system("cls");
}break;
case 8:
{
cout<<"Hvala na koristenju.\n";
}break;

}
}while(izbor>0 && izbor<8);

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 69
Primjer 8.11

#include <stdio.h>
/* Funkcija binom() racuna binomni koeficijent. */
long binom(int n, int k)
{
long rezult=1;
int i;
if(n == k) return 1;
if(k == 0) return 1;
for(i=n;i>n-k;i--)
rezult=rezult*i;
for(i=1;i<=k;++i)
rezult=rezult/i;
return rezult;
}
int main(void)
{
long bnm;
int n, k;
for(n=0;n<10;n++){
for(k=0;k<=n;k++){
bnm=binom(n,k);
printf("%ld ",bnm);
}
printf("\n");
}

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 70
return 0;
}

Primjer 8.12.

#include <stdio.h>
#include <math.h>
double epsilon=1.0E-10;
double kosinus_kuta(double x[], double y[]);
int main(void)
{
double a[3], b[3];
double cos_phi;
int i;
printf("Unesite vektor a.\n");
for(i=0;i<3;++i){
printf("a[%d]= ",i+1);
scanf(" %lf",&a[i]);
}
printf("Unesite vektor b.\n");
for(i=0;i<3;++i){
printf("b[%d]= ",i+1);
scanf(" %lf",&b[i]);
}
cos_phi= kosinus_kuta(a, b);
if(fabs(cos_phi) < epsilon){
printf("Vektori su okomiti.\n");

Mašinski fakultet Mostar dr.Senad Rahimić


Programiranje 71
printf("Kosinus kuta = %f\n", cos_phi);
}
else{
printf("Vektori nisu okomiti.\n");
printf("Kosinus kuta = %f\n", cos_phi);
}
return 0;
}
double norma(double x[]) {
int i;
double suma;
suma=0.0;
for(i=0;i<3;++i) suma = suma + x[i]*x[i];
return sqrt(suma);
}
double produkt(double x[], double y[]) {
int i;
double suma;
suma=0.0;
for(i=0;i<3;++i) suma = suma + x[i]*y[i];
return suma;
}
double kosinus_kuta(double x[], double y[]) {
double cos_phi;
cos_phi=produkt(x,y);
cos_phi=cos_phi/(norma(x)*norma(y));
return cos_phi;
}

Mašinski fakultet Mostar dr.Senad Rahimić

Das könnte Ihnen auch gefallen