Beruflich Dokumente
Kultur Dokumente
ER
ZITET U Z
E
N
I
UN
IC
SI
IC
AEN IS
S
UNIVER
ZE
ST
UDIORUM
Pedagoki fakultet
Katedra za matematiku i informatiku
Aleksandar Kara
Zenica, 2009.
A.Kara
Sadraj
Sadraj
1 Uvod
1.1 Kratki istorijat programskih jezika
1.2 O proceduralnom programiranju . .
1.3 Programski paket Dev-C++ . . . .
1.3.1 Instalacija . . . . . . . . . .
1.3.2 Kreiranje prvog programa .
1.3.3 Pokretanje izvrne datoteke
Kviz pitanja . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
1
1
2
4
5
7
9
10
2 Osnove programiranja
2.1 Struktura programa . . . . . . .
2.2 Proces kompajliranja . . . . . .
2.3 Varijable . . . . . . . . . . . . .
2.4 Memorija . . . . . . . . . . . .
2.5 Ulazno/izlazni usmjerivai toka
2.6 Komentari . . . . . . . . . . . .
2.7 Imena (identifikatori) . . . . . .
2.8 Tipovi podataka . . . . . . . . .
2.8.1 Brojevi . . . . . . . . . .
2.8.2 Logiki tipovi . . . . . .
2.8.3 Karakteri (znakovi) . . .
Kviz pitanja . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
11
11
13
14
15
16
17
18
19
19
22
23
24
3 Operatori
3.1 Aritmetiki operatori . . . . . . . . . . . . . . . . . . . . . . . .
3.2 Relacijski operatori . . . . . . . . . . . . . . . . . . . . . . . . .
3.3 Logiki operatori . . . . . . . . . . . . . . . . . . . . . . . . . .
27
27
29
30
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
3.4
3.5
3.6
3.7
3.8
3.9
3.10
3.11
Bitovni operatori . . . . . . . . . . . . .
Inkrementalni i dekrementalni operatori
Operatori pridruivanja . . . . . . . . . .
Uslovni (ternarni) operator . . . . . . . .
Operator razdvajanja (zarez-operator) .
typedef imena . . . . . . . . . . . . . . .
sizeof operator . . . . . . . . . . . . . . .
Hijerarhija operatora . . . . . . . . . . .
Kviz pitanja . . . . . . . . . . . . . . . .
Zadaci za izradu . . . . . . . . . . . . . .
4 Naredbe
4.1 Jednostavne i sloene
4.2 Naredba if . . . . . .
4.3 Naredba switch . . .
4.4 Naredba while . . . .
4.5 Naredba do . . . . .
4.6 Naredba for . . . . .
Kviz pitanja . . . . .
Zadaci za izradu . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
30
31
32
32
33
33
34
34
35
37
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
39
39
40
41
42
43
44
45
46
5 Funkcije
5.1 Definicija . . . . . . . . . . . . .
5.2 Parametri i argumenti . . . . . .
5.3 Globalne i lokalne varijable . . . .
5.4 Rekurzivne funkcije . . . . . . . .
5.5 Optereene (overloaded ) funkcije .
Kviz pitanja . . . . . . . . . . . .
Zadaci za izradu . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
47
47
51
53
54
55
56
58
.
.
.
.
59
59
63
65
65
naredbe
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
6 Polja (arrays)
6.1 Definisanje i inicijalizacija
6.2 Multidimenzionalna polja
Kviz pitanja . . . . . . . .
Zadaci za izradu . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
7 Pointeri
67
7.1 Osnovno o pointerima . . . . . . . . . . . . . . . . . . . . . . . 67
7.2 Dinamika memorija . . . . . . . . . . . . . . . . . . . . . . . . 68
7.3 Pointeri i polja . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
ii
7.4
7.5
7.6
Aritmetika sa pointerima
Funkcijski pointeri . . .
Reference . . . . . . . .
Kviz pitanja . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
71
73
75
77
8 Datoteke
8.1 Standardna biblioteka fstream . . . .
8.2 "ivotni" ciklus pristupa datotekama
8.2.1 Otvaranje datoteka . . . . . .
8.2.2 Zatvaranje datoteka . . . . . .
8.2.3 Pisanje na datoteke . . . . . .
8.2.4 itanje sa datoteka . . . . . .
Kviz pitanja . . . . . . . . . . . . . .
Zadaci za izradu . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
79
79
80
80
85
85
87
90
91
9 O objektno-orijentisanom programiranju
9.1 Proceduralno i objektno-orijentisano programiranje
9.2 Prednosti objektno-orijentisanog programiranja . .
9.3 Karakteristike objektno-orijentisanih jezika . . . . .
9.3.1 Objekti . . . . . . . . . . . . . . . . . . . .
9.3.2 Klase . . . . . . . . . . . . . . . . . . . . . .
9.3.3 Nasljeivanje . . . . . . . . . . . . . . . . .
9.3.4 Ponovna iskoristivost . . . . . . . . . . . . .
9.3.5 Kreiranje novih tipova podataka . . . . . . .
9.3.6 Polimorfizam i optereivanje . . . . . . . . .
Kviz pitanja . . . . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
93
93
96
97
97
98
99
99
100
100
101
Literatura
103
Popis pojmova
105
iii
Poglavlje 1
Uvod
1.1
Uvod
predstavlja korijen razvoja nekih danas veoma zastupljenih jezika, kao Pascal,
C, C++ i Java. Pascal je poeo sa upotrebom 1968. godine, a predstavljao
je, i jo uvijek predstavlja, veoma dobar edukacioni alat.
Jezik C je razvijen 1972. godine, kada se dogodio prelaz ka savremenim
programerskim jezicima. U osnovi, jezik C je nastavak jezika B i BCPL, ali
obuhvata mnogo karakteristika jezika Pascal.
Kasnih 70tih i poetkom 80tih razvija se nova programerska metoda
objektno-orijentisano programiranje (OOP). Bjarne Stroustoup je na osnovu
prvih OOP jezika (SIMULA, 1967. godina) uspio razviti nastavak jezika C
poznat pod nazivom "C sa klasama" (eng. C with classes), koji se kasnije
(1983) razvio u potpuni jezik. C++ se razvio kako bi se bolje organizovala
sirova snaga jezika C koristei OOP, a sauvala njegova brzina te mogunost
manipulisanja mnogobrojnim tipovima podataka.
Ranih 90tih interaktivna televizija postaje tehnologija budunosti, i kao
takva je zahtijevala specijalni jezik. Tako je Sun Microsystems razvio jezik
Java, koji se neto kasnije poeo koristiti za web dizajn, poto je projekat
interaktivne televizije (bar u tom periodu) propao.
Naravno, ovdje pria o programskim jezicima ne zavrava, i samo je pitanje
kakvi e se jo jezici razviti, naroito sa pojavom biolokih i kvantnih kompjutera. Ipak, injenica da je u samo 50 godina od razvitka prvog programskog
jezika do danas razvijeno vie od 4000 kompjuterskih jezika, govori sama za
sebe.
1.2
O proceduralnom programiranju
Za bilo koji problem vjerovatno postoji jednako puno naina da se isti analizira
i rijei kao to je ljudi i tehnologija da to urade. Tako se sa programerskog
aspekta, na primjer, problem moe podijeliti (dekompozirati) algoritamski ili
proceduralno, tj. u odnosu na sekvencu ili proceduru dogaaja koji se moraju
desiti. Alternatvno, problem se moe rijeiti pomou "objektno-orijentisanog"
pristupa, posmatrajui razne cjeline koje utjeu jedne na druge i uzimajui u
obzir njihovo meusobno djelovanje. Ova dva pristupa u dekompoziranju problema algoritamski i objektno-orijentisani su dva pristupa koji programeri
najee koriste. Pristupi su figurativno prikazani na Sl.1.1.
Algoritamski pristup poinje optim zadatkom koji treba izvriti (kao to
je "omoguiti korisniku da izvri opte bankarske funkcije"), zatim dijeli opti zadatak na naredne nivoe specificiranijih podzadataka (kao to je "proces
podizanja novca", te "proces stavljanja depozita"), te na dalje nivoe jo specifinijih zadataka (kao to su "upitaj korisnika na vrijednost depozita" ili
Uvod
1.3
okruenje. Danas, najpoznatije C++ okruenje predstavlja Microsoftov proizvod Visual C++ .NET. Meutim, ovaj, kao i veina ovakvih programa, je
komercijalan i nije dostupan svim korisnicima. Ipak, mogue je nai veliki
broj besplatnih C++ okruenja. Jedno od takvih okruenja je i Dev-C++ .
Najnoviju verziju pomenutog programa mogue je nai na web stranici firme
BloodshedSoftware (http://bloodshed.net/download.html).
1.3.1
Instalacija
Uvod
a)
b)
1.3.2
Upisivanje koda
Nakon pokretanja programa Dev-C++ , prvi korak u kreiranju koda je otvaranje novog zadatka. Dev-C++ prua vie opcija, ali se za sada moemo
ograniiti na jednostavne programe koji se mogu napisati u jednoj datoteci
opcija File/New/Source File, kao to je prikazano na slici 1.7. Nakon odabira
ove opcije, otvara se prozor u koji treba upisati kod, na primjer
#include <iostream>
using namespace std;
int main()
{
cout << "Vozdra, raja\n";
system("PAUSE");
return 0;
}
Nakon ispisivanja (dobija se prozor kao na slici 1.8), kod sauvamo negdje
na hard disku ili drugom nosiocu memorije, npr. pod imenom vozdra.cpp.
Generisanje izvrne datoteke
Uvod
Pokretanje izvrne datoteke, koju smo prethodno kompajlirali, izvodi se izborom opcije Run u meniju Execute, kombinacijom tipki Ctrl i F10 na tastaturi,
ili pritiskom na ikonu .
Prethodna dva procesa (kompajliranje i pokretanje) mogue je i objediniti
pritiskom na tipku F9 na tastaturi, izborom opcije Compile&Run u meniju
Execute, ili izborom ikone .
Program je mogue pokrenuti i van Dev-C++ okruenja, dvostrukim klikom na izvrnu datoteku (vozdra.exe) ili koristei MS-DOS terminal (Command Prompt) tako to se pozicioniramo u direktorij u kojem se nalazi izvrna
datoteka i ukucamo njeno ime..
10
Uvod
Kviz pitanja
1. Programski jezik C++ pripada ........... jezicima.
2. ta je osnovna karakteristika proceduralnog programiranja?
3. Kako se jo naziva proceduralno programiranje i zbog ega?
4. Nabroj nekoliko programskih paketa koji omoguavaju pisanje i kompajliranje programa napisanih u C++ !
Poglavlje 2
Osnove programiranja
2.1
Struktura programa
C++ program se sastoji od jedne ili vie cjelina za prevoenje, pri emu ove
cjeline predstavljaju dio programa koji treba kompajlirati odvojeno od drugih
cjelina. Tanije, cjelina za prevoenje je rezultat primjene preliminarne faze
kompajliranja na izvornu datoteku (eng. source file). Ova faza se naziva i
predprocesiranje.
Izvorna datoteka obino poinje sa jednom ili vie (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 prevoenje.
Posmatrajmo na prvi primjer iz prethodnog poglavlja:
1
2
3
4
5
6
7
8
#include <iostream>
using namespace std;
int main()
{
cout << "Vozdra, raja\n";
system("PAUSE");
return 0;
}
12
Osnove programiranja
Tok (stream) je objekat koji izvrava ulazne i izlazne naredbe. Tok cout je
standardni izlazni tok (obino ekran) u C++ . Simbol << je izlazni operator
(usmjeriva toka) kojem je lijevi operand izlazni tok, a desni izraz. Ovaj
operator upuuje desni operand na lijevi. Dakle, u ovom sluaju string "Vozdra
raja \n" se alje na cout, tj. uzrokuje njegov ispis na ekranu i pomjeranje u
sljedei red.
Linija 6 zaustavlja izvrenje programa, kako bismo mogli vidjeti rezultat
njegovog rada. Bez ove linije program bi se nakon pokretanja izvrio, a konzola
bi se zatvorila veoma brzo, tako da bismo imali osjeaj kao da program nije
nita ni uradio.
1 String
2 naslijeeno
2.2
13
Proces kompajliranja
Kompajliranje C++ programa obuhvata nekoliko koraka, koji su veinom nevidljivi za korisnika:
Prvo, C++ predprocesor ide kroz program i izvodi instrukcije koje su
specificirane predprocesorskim direktivama (npr. #include). Rezultat
ovoga je modificirani tekst programa koji vie ne sadri nikakve direktive.
Zatim C++ kompajler prevodi programski kod. Kompajler moe biti
pravi C++ kompajler, koji pravi osnovni (asemblerski ili mainski) kod,
ili samo prevodilac, koji kod prevodi u C jezik. U drugom sluaju, rezultujui C kod se zatim prevodi kroz C kompajler kako bi se napravio
osnovni kod. U oba sluaja, rezultat moe biti nepotpun zbog toga to
program poziva podprogramske biblioteke koje nisu definisane u samom
programu.
Na kraju, linker zavrava objektni kod njegovim povezivanjem sa objektnim kodom bilo kojeg modula biblioteka, koji program moe pozvati.
Konaan rezultat je izvrna datoteka.
Slika 2.1 ilustruje prethodno navedene korake i za C++ prevodilac i za
C++ prirodni kompajler. U praksi su sve ove naredbe obino izvrene jednom naredbom (npr. CC), a korisnik ne vidi datoteke koje su se napravile u
meufazama.
C++
program
C++
prevodilac
C++
program
C++
prirodni
kompajler
C
kod
C
kompajler
Objektni
kod
linker
Izvrna
datoteka
14
Osnove programiranja
2.3
Varijable
Varijabla je simboliko ime za memorijsku lokaciju u koju se mogu pohraniti podaci, koji se naknadno mogu pozvati. Varijable se koriste za uvanje
vrijednosti podataka tako da se iste mogu koristiti u raznim proraunima u
programu. Sve varijable imaju dvije vane osobine:
Tip, koji se postavlja kada se varijabla definie (npr. cijeli broj, realni
broj, karakter, ...). Kada se jednom definie, tip varijable u C++ se ne
moe promijeniti.
Vrijednost, koja se moe promijeniti davanjem nove vrijednosti varijabli.
Vrsta vrijednosti koja se moe pridruiti nekoj varijabli zavisi od njenog
tipa. Na primjer, cjelobrojna varijabla (int) moe uzeti samo vrijednosti
cijelih brojeva (npr. -5, 13, ...).
Kada se varijabla definie, njena vrijednost je nedefinisana sve dok joj se
ne pridrui neka. Pridruivanje vrijednosti nekoj varijabli po prvi put naziva se inicijalizacija. Neophodno je da se svaka varijabla inicijalizira prije
nego se koristi. C++ podrava dvije vrste inicijalizacije: (i) inicijalizaciju
kopiranjem (eng. copy-initialisation) i (ii) direktna inicijalizacija (eng. directinitialisation). Inicijalizacija kopiranjem koristi znak jednakosti, =, dok se
direktna inicijalizacija izvodi pomou malih zagrada, (), kao u sljedeim primjerima:
int broj(10); // direktna inicijalizacija
int broj = 10; // inicijalizacija kopiranjem
U oba sluaja varijabla broj je inicijalizirana na vrijednost 10. Treba napomenuti da inicijalizacija ne predstavlja pridruivanje (iako se u inicijalizaciji
kopiranjem koristi znak jednakosti), nego se deava onda kada se varijabla
definie i kada joj se da poetna vrijednost. S druge strane, pridruivanje
predstavlja ponitavanje trenutne vrijednosti varijable i zamjene novom.
Takoer je mogue da se varijabla definie i inicijalizira u isto vrijeme,
to je vrlo praktino. Naredni primjer pokazuje razliite naine definisanja i
inicijaliziranja varijabli.
1
2
3
4
5
6
#include <iostream>
using namespace std;
main()
{
int a,b,c;
float x = 4.32;
2.4. Memorija
int e,f,g;
char ime;
e = 4;
f = g = 12;
ime = C
7
8
9
10
11
12
15
2.4
Memorija
Za pohranjivanje izvrnog koda kao i podataka sa kojima program manipulira, kompjuter ima na raspolaganju RAM memoriju (eng. Random Access
Memory). Pri tome, memorija se moe zamisliti kao neprekidan niz bita, od
kojih svaki moe da pohrani binarni broj (0 ili 1). Memorija se obino dijeli na
grupe od 8 uzastopnih bita (ovo predstavlja bajt). Bajtovi su uzastopno adresirani, tako da je svaki bajt jedinstveno predstavljen svojom adresom (Sl.2.2).
C++ kompajler generie izvrni kod, koji mapira ulazne veliine na memorijske lokacije. Na primjer, definicija varijable
int zarada = 500;
16
Osnove programiranja
adresa
...
1211
1212
1213
1214
1215
1216
1217
bajt
bajt
bajt
bajt
bajt
bajt
bajt
...
Memorija
bit
...
1211
1212
1213
bajt
bajt
bajt
1214
1215
10110011 10110011
1216
1217
bajt
bajt
...
Memorija
zarada
2.5
Najei nain na koji program komunicira sa vanjskim svijetom je preko jednostavnih ulazno/izlaznih (IO) operacija. C++ omoguuje dva korisna operatora za ovu svrhu: >> za ulaz, i << za izlaz. U ranijem tekstu pokazana je
upotreba operatora <<. Naredni primjer pokazuje upotrebu operatora >>.
1
2
#include <iostream>
using namespace std;
3
4
2.6. Komentari
5
17
{
int
radniDani = 22;
float radniSati = 7.5;
float satnica, plata;
6
7
8
9
10
11
12
13
14
15
16
17
2.6
Komentari
Komentar je dio opisnog teksta koji objanjava neke aspekte programa. Kompajler u potpunosti ignorie komentare u programu, tako da je jedina svrha
koju komentar ima, da pomogne onome koji e itati program. C++ daje
dvije mogunosti pisanja komentara:
bilo ta napisano nakon //, pa do kraja date linije smatra se komentarom3 ,
i
bilo ta napisano izmeu /* i */ smatra se komentarom.
Sljedei primjer pokazuje upotrebu oba naina pisanja koemntara.
1
2
#include <iostream>
using namespace std;
3
4
5
6
7
8
9
3 naslijeeno
iz jezika C
18
Osnove programiranja
float
float
float
10
11
12
radniSati = 7.5;
satnica = 33.50;
plata;
13
14
15
16
17
18
Prvi nain se moe koristiti za komentar jedne i samo jedne linije (ili dijela
jedne linije), kao to je to demonstrirano u linijama 14 (cijeli red), te linijama
9-12 (dio reda). Drugim nainom se (koristei /* i */), pak, moe komentarisati
tekst upisan u vie linija (linije 4-5).
2.7
Imena (identifikatori)
Programski jezici koriste imena kako bi se oznaile razliite cjeline koje ine
program. Osim imena varijabli, ovdje spadaju i imena funkcija, tipova, te
makroa. C++ postavlja sljedea pravila za pravilno kreiranje imena (identifikatora):
ime treba da se sastoji od jednog ili vie karaktera, od kojih bilo koji moe
biti slovo (tj, slova engleske abecede a-z i A-Z), broj (0-9) i znak " ", pri
emu na prvom mjestu ne moe da bude broj.
velika i mala slova se razlikuju (zarada nije isto to i Zarada).
C++ ne postavlja nikakvo ogranienje na broj karaktera u nekom identifikatoru. Meutim, veina implementacija ima ovo ogranienje, ali je ono toliko
veliko da ne predstavlja nikakav problem (npr. i do 255 karaktera). Ipak, treba
imati na umu da postoje odreene rijei u C++ koje su rezervisane, tako da
identifikatori ne mogu uzimati njihova imena. Te rijei se nazivaju rezervisane
ili kljune rijei i neke od njih su date u Tabeli 2.1.
Pored navedenih pravila o davanju imena varijablama, postoji i veliki broj
prihvaenih konvencija, koje se uglavnom koriste radi lakeg praenja programa. Neke od vanijih su:
imena varijabli se obino piu malim slovima
za davanje imena se obino koriste mnemonika imena, tj. imena koja
poblie opisuju varijablu
19
continue
default
delete
do
double
else
enum
extern
float
for
friend
goto
if
inline
int
long
new
operator
private
protected
public
register
return
short
signed
sizeof
static
struct
switch
template
this
throw
try
typedef
union
unsigned
virtual
void
volatile
while
ime moe da ima i vie rijei, koje su obino razdvojene donjom crtom,
ili su direktno povezane sa poetnim velikim slovom rijei koja se dodaje
imenu.
No, bez obzira na konvencije, opte je pravilo da se jedna odreena konvencija
konstantno koristi.
2.8
Tipovi podataka
Brojevi
U C++ su ugraena dva osnovna tipa brojeva, i to: cijeli i realni brojevi.
Cijeli brojevi
Cijeli broj (eng. integer ) se moe definisati pomou tipova short, int i long.
Jedina razlika je u tome to int koristi vie ili barem isto bajta kao short, a long
koristi vie ili barem isto bajta kao int . Ovo zavisi od kompjutera na kojem
se radi.
Konvencija je da cjelobrojne varijable uzimaju u obzir i pozitivne i negativne
brojeve (tada se kae da su oni tipa signed). Meutim, u sluaju kada se koriste
samo pozitivne vrijednosti, ukljuujui i 0, koriste se sa predznakom unsigned.
Ovo vrijedi i za realne brojeve.
Najee se pri definisanju cijelih brojeva koristi tip int, koji u kompjuteru
obino zauzima 4 bajta (mada kod nekih starijih kompjutera zauzima 2 bajta).
S obzirom da 4 bajta predstavlja 48 = 32 bita, i da prvi bit odreuje predznak
20
Osnove programiranja
broja, preostaje nam 31 bit da pohranimo vrijednost nekog broja. Na taj nain
se tipom int mogu pohraniti svi brojevi vei od najmanjeg negativnog broja
231 = 2147483648
i manji od najveeg mogueg pozitivnog broja
231 1 = 2147483647
Treba napomenuti da se cjelobrojne veliine u izvornom kodu mogu prikazati u jednom od tri brojna sistema, i to: dekadskom, oktalnom i heksadecimalnom. Pri tome, naravno, dekadski brojni sistem je sistem brojeva od 0-9,
oktalni 0-7, i heksadecimalni 0-9,A-F.
U jeziku C++ oktalne vrijednosti se piu tako da se ispred prve cifre broja
napie broj 0, nakon ega slijedi oktalni zapis broja, kao npr.
int broj = 010;
Ipak, bez obzira koji od prikaza koristimo pri pridruivanju neke vrijednosti,
na ekranu se ispisuje broj u dekadskom brojnom sistemu. Tako u sljedeem
primjeru za svaki sluaj ispis je jednak broju 32:
int broj = 32;
cout << broj;
Realni brojevi
21
U prvom sluaju koristi se klasini nain prikaza broja sa decimalnim zarezom, dok je u drugom i treem sluaju koriteno nauno oznaavanje (eng.
scientific). Pri tome, u naunom oznaavanju je mogue koristiti i malo i veliko slovo "e", ali ne smije biti nikakvih praznina unutar broja (izmeu cifri i
slova e, te iza predznaka).
U sluaju da nam tanost na sedam decimala nije dovoljna, koristimo brojeve sa dvostrukom tanou, tj. brojeve tipa double. U principu, za prikaz
decimalnih brojeva najbolje je uvijek koristiti tip double, jer je brzina obavljanja operacija sa ovim tipovima na dananjim kompjuterima podjednako velika
kao i sa tipom float.
Ogranienja brojevnih tipova
<<
<<
<<
<<
<<
<<
<<
<<
<<
<<
<<
<<
INT_MIN
INT_MAX
LONG_MIN
LONG_MAX
FLT_MAX
DBL_MIN
<<
<<
<<
<<
<<
<<
endl;
endl;
endl;
endl;
endl;
endl;
Simbolike konstante
22
Osnove programiranja
2.8.2
// greka!!!
Logiki tipovi
Logiki tipovi su vrlo kasno uvedeni u standardni jezik C++ . Prije nego se
uveo tip za ovu vrstu podataka, bool (od engleske rijei boolean, po matematiaru Booleu), u ovu svrhu su se koristili cijeli brojevi 0 i 1 (mada se umjesto
1 mogao koristiti bilo koji broj razliit od 0).
Osnovna karakteristika logikih tipova je da mogu imati dvije vrijednosti,
i to: tano i netano (eng. true i false)5 . Primjer definisanja logikih varijabli
je:
bool jaSamStudent = true;
bool autoLeti
= false;
2.8.3
23
Karakteri (znakovi)
Varijabla karakter (znak) se definie tipom char (od engleske rijei character karakter, znak) i uglavnom se pie kao samo jedan znak upisan izmeu jednostrukih znaka navoda . Ona obuhvata jedan jedini bajt koji sadri kod datog
karaktera. Ovaj broj je numerika vrijednost i zavisi od sistema kodiranja karaktera koji se koristi (to je zavisno od kompjutera). Najei sistem je ACSII
(eng. American Standard Code for Information Interchange). Na primjer,
karakter A ima ASCII kod 65, a karakter a 97.
Kao i cijeli broj i karakter moe da bude signed i unsigned. Tako, signed
karakter moe da sadri numerike vrijednosti izmeu -128 i 127, a unsigned 0
do 255.
Sljedei primjer pokazuje upotrebu tipa char za jednoznakovne varijable:
1
2
3
4
5
6
7
8
9
10
#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;
11
if (ch != K && ch != k)
cout << "Zelite nastaviti?\n";
else
cout << "Kraj programa";
}while (ch != K && ch != k);
12
13
14
15
16
17
Pri pokretanju, ovaj program se nastavlja ako se unese bilo koji drugi karakter osim k ili K. Ako se, pak, unese k ili K, program se zaustavlja. Problem
nastaje ako korisnik programa pritisne samo tipku ENTER. U tom sluaju
objekat cin oekuje da se unese neka vrijednost, pa tek onda pritisne ENTER.
Osim klasinih karaktera (slova i sl.), postoje i karakteri koji imaju posebnu
namjenu (ne predstavljaju karaktere koji se ispisuju). Oni se predstavljaju
pomou tzv. escape-sekvenci, kao npr:
\n - novi red
\t - novi tabulator
\v - novi vertikalni tabulator
24
Osnove programiranja
\b
\
\"
\\
\a
backspace
znak navoda (apostrof)
dvostruki znak navoda
backslash (/)
zvuni signal
Znakovne varijable se, ipak, najee koriste kao nizovi karaktera (eng. string)
za ispis tekstova. O ovome e biti vie rijei u poglavlju 6 (polja).
Kviz pitanja
1. Koliko main funkcija moe biti u programu?
2. Koja je uloga include direktive?
3. ta radi predprocesor?
4. ta radi kompajler?
5. ta radi linker?
6. Koja je razlika izmeu tipova podataka unsigned int i int?
7. ta predstavlja varijabla?
8. Da li je mogue definisati vie varijabli jednom naredbom? Ako jeste,
dati primjer.
9. ta je od navedenog ispravna definicija varijable:
a)
b)
c)
d)
int n=-100;
unsigned int i =-100;
signed int = 2.9;
long m=2,p=4;
identifier
dva 15
ukupna-plata
ukupna_plata
default
proc.program
25
Poglavlje 3
Operatori
U ovom poglavlju su obraeni ugraeni C++ operatori, koji se koriste za stvaranje izraza, pri emu izraz predstavlja bilo kakav proraun koji daje neku
vrijednost. C++ nudi operatore za izvravanje aritmetikih, relacijskih, logikih, bitovnih i uslovnih izraza. Takoer, tu su i veoma korisne "popratne
pojave" (eng. side-effect) kao to su pridruivanje, inkrement i dekrement.
3.1
Aritmetiki operatori
Ime
Sabiranje
Oduzimanje
Mnoenje
Dijeljenje
Ostatak pri dijeljenju
Primjer
12+4.9
3.98-4
2*3.4
9/2.0
13%3
Rezultat
16.9
-0.02
6.8
4.5
1
Osim ostatka pri dijeljenju (%) svi aritmetiki operatori prihvataju mijeanje cijelih i realnih brojeva. Openito, ako su oba operanda cijeli brojevi, i
rezultat je cijeli broj. Meutim, ako je jedan od operanada realan, onda je i
rezultat realan (na primjer, tipa double)1 .
Kada su oba operanda pri dijeljenju cijeli brojevi, rezultat je takoer cijeli
broj (tzv. cjelobrojno dijeljenje). U tom sluaju rezultat se zaokruuje na
donju vrijednost, tj.
1 Ovakav
28
Operatori
9/2
-9/2
daje 4, a ne 4.5!
daje -5, a ne -4.5!
// daje 1
ili u tzv. starom nainu pisanja u jeziku C (sa tipom meu zagradama):
double jedinicnaCijena = (double)cijena/volumen; // daje 1.25
Ipak, stari nain pisanja se ne preporuuje u pisanju programa koji e se kompajlirati na C++ kompajlerima.
Operator % daje ostatak pri dijeljenju dva cijela broja (oba operanda moraju biti cijeli brojevi!!!), npr.
13%3 daje 1
29
Prilikom koritenja aritmetikih operatora veoma vano mjesto zauzima pojam preljeva. Naime, u sluaju da zbir brojeva prelazi maksimalno dozvoljenu
vrijednost, koja je navedena u poglavlju 2.8.1, dobivena vrijednost moe biti
negativna. Ovaj fenomen se lako moe pokazati na slici 3.1 ako se za tip int
pretpostavi da ima 2 bajta, tj. 16 bita (to znai da je maksimalan pozitivan
broj jednak 215 = 32767)
oduzimanje
-2
-1
sabiranje
1
int
-32767
-32768
32766
32767
Dakle, ukoliko neku varijablu koja ima vrijednost 32767 uveamo za samo
1, vrijednost koju dobivamo je -32768 (!!!), odnosno za jedan vea od najvee
mogue u smjeru kazaljke na satu na slici 3.1.
3.2
Relacijski operatori
C++ nudi est relacijskih operatora za raunanje brojnih veliina (Tabela 3.2)
Pri tome, treba zapamtiti da se operatori <= i >= mogu koristiti samo u
tom obliku, a da =< i => ne znae nita u ovom kontekstu.
Operandi nekog relacijskog operatora moraju biti brojevi. No, i karakteri
su ispravni operandi poto predstavljaju brojnu vrijednost (sjetimo se ASCII
tabele).
Relacijski operatori se ne smiju korisiti za poreenje stringova, poto se u
tom sluaju porede njihove adrese, a ne sadraj. U tom sluaju, rezultat je
30
Operatori
Ime
Jednakost
Nejednakost
Manje od
Manje ili jednako
Vee od
Vee ili jednako
Primjer
5==5
5!=5
5<5.5
5<=5
5>=5.5
5.5>=5
Rezlutat
1
0
1
1
0
1
3.3
Logiki operatori
Za kombinovanje logikih izraza C++ nudi tri logika operatora (Tabela 3.3).
Slino relacijskim operatorima, rezultat pri koritenju logikih operatora je 0
(false) ili 1 (true).
Tabela 3.3: Logiki operatori
Operator
!
&&
||
Ime
Logika negacija
Logiko i
Logiko ili
Primjer
!(5==5)
5<6 && 6<6
5<6 || 6<5
Rezlutat
0
1
1
3.4
Bitovni operatori
31
&
|
>>
>>
Ime
Binarna negacija
Binarno i
Binarno ili
Iskljuivo ili
Pomaknuti desno
Pomaknuti lijevo
Primjer
\011
\011 & \027
\011 | \027
\011 \027
\011>>2
\011<<2
Rezlutat
\366
\001
\037
\036
\002
\044
Ime
Inkrement prefiks
Inkrement postfiks
Dekrement prefiks
Dekrement postfiks
Primjer
++k+10
k++ +10
k+10
k +10
Rezlutat
16
15
14
15
3.5
Takozvani auto inkrementalni (++) i auto dekrementalni () operatori obezbijeuju prigodan nain za poveavanje, odnosno smanjivanje brojne varijable
za 1. Upotreba ovih operatora je sumirana u Tabeli 3.5, pri emu se pretpostavlja da je
int
k = 5;
32
3.6
Operatori
Operatori pridruivanja
Operator pridruivanja (=) se koristi za pohranjivanje vrijednosti na neku memorijsku lokaciju (koja je obino pridruena nekoj varijabli). Lijevi operand
operatora treba biti neka vrijednost, npr. lijevaVrijednost, dok desni operand
moe biti proizvoljni izraz. Desni operand se izrauna i pridrui lijevoj strani.
Pri tome lijevaVrijednost predstavlja bilo ta to zauzima neku memorijsku lokaciju na koju se moe pohraniti neka veliina; moe biti varijabla, te zasnovana
na pointerima i referencama.
Operator pridruivanja moe imati mnogo varijanti, koje se dobivaju njegovim kombinovanjem sa aritmetikim operatorima (mogua je kombinacija i
sa bitovnim operatorima). Ove varijante su date u tabeli 3.6.
Kako operator pridruivanja sam po sebi predstavlja izraz ija se vrijednost
pohranjuje u lijevi operand, on se moe koristiti kao desni operand za narednu
operaciju pridruivanja, odnosno moe se napisati:
int m, n, p; m = n = p = 5; // isto kao: m = (n = (p = 100));
m =(n= p = 100) + 2;
// isto kao: m = (n = (p = 5)) + 2;
ili
m = 100; m += n = p = 5;
3.7
Uslovni operator treba tri operanda (odatle ime ternarni). On ima optu formulu:
operand1 ? operand2 : operand3;
3.8
33
3.9
typedef imena
Kljuna rije typedef omoguava definisanje novih imena (sinonima) za postojee tipove podataka. Opta formula ima oblik:
typedef tip novo_ime_tipa;
Dakle, typedef definicija poinje kljunom rijei typedef, nakon ega se ispisuje tip podatka i identifikator. Pri tome, identifikator ne uvodi novi tip
podatka, nego samo sinonim (nadimak) za postojei tip. Ovaj identifikator se
moe koristiti bilo gdje u programu u kojem bi se mogao koristiti i sam tip.
Na primjer, sljedei primjer pokazuje koritenje sinonima prirodni, za prirodne, tj. nenegativne cijele brojeve.
typedef unsigned int prirodni;
34
Operatori
3.10
sizeof operator
sizeof operator slui za raunanje veliine bilo kojeg podatka ili tipa. To je
unarni operator, koji za operand moe imati tip (npr. int, char, . . . ) ili izraz,
a kao rezultat daje broj bajtova koji operand zauzima u memoriji raunara.
Ovaj rezultat je u potpunosti zavisan od raunara na kojem se radi. Naredni
primjer ilustruje koritenje ovog operatora za raunanje veliine osnovnih tipova podataka.
1
2
#include <iostream>
using namespace std;
3
4
5
6
7
8
9
10
11
12
13
14
<<
<<
<<
<<
<<
<<
<<
sizeof(char)
sizeof(short)
sizeof(int)
sizeof(long)
sizeof(float)
sizeof(double)
sizeof("HELLO")
<<
<<
<<
<<
<<
<<
<<
"
"
"
"
"
"
"
bytes\n";
bytes\n";
bytes\n";
bytes\n";
bytes\n";
bytes\n";
bytes\n";
3.11
=
=
=
=
=
=
=
1
2
4
4
4
8
6
bytes
bytes
bytes
bytes
bytes
bytes
bytes
Hijerarhija operatora
Slino pravilima u matematici o redoslijedu izvoenja pojedinih raunskih operacija, i redoslijed koritenja pojedinih operatora u nekom izrazu u C++ je veoma bitan. Stoga se operatori dijele na razliite hijerarhijske nivoe, pri emu
operatori na viim nivoima imaju prednost nad onim koji su nie. Tabela 3.7
daje prikaz hijerarhije nekih od operatora operatora u C++ , od onih sa najveim prema onim sa najmanjim prioritetom. Pri tome su operatori sa istim
prioritetom smjeteni u isti blok (odvojen horizontalnim linijama).
35
Na primjer, u izrazu
a=b+c*d;
prvo se rauna c*d, jer znak mnoenja * ima vei prioritet od znaka sabiranja
+ i znaka pridruivanja =. Rezultat mnoenja se zatim dodaje varijabli b, jer
operacija sabiranja ima vei prioritet od operacije pridruivanja.
Ovakav nain definisanja hijerarhije je neophodan, jer se pojedini operatori
koriste za vie namjena. Takav primjer je znak plus, +, koji se moe koristiti
kao binarni operator za sabiranje, unarni operator za promjenu znaka nekog
broja, ali i kao operator za uveavanje (postfiks i prefiks inkrement). Ako, na
primjer, elimo sabrati dva broja, pri emu je drugi broj prethodno uvean za
jedan, imamo izraz:
c=a+ ++b;
odnosno
c=a+(++b);
Kviz pitanja
1. Koji od logikih operatora su unarni, a koji su binarni?
2. ta radi inkrement operator?
3. ta radi dekrement operator?
4. Objasni ta radi sljedea naredba:
cout >> --broj!
36
Operatori
5. Dodati zagrade sljedeim izrazima tako da se pokae kojim redom se izraunavaju pojedini operatori:
a)
b)
c)
d)
double d = 2 * int(3.14);
long k = 3.14 - 3;
char c = a + 2;
char c = p + A - a;
12. Napisati izraz koji koristi relacijski operator koji ima vrijednost true ako
varijabla var1 nije jednaka varijabli var2.
13. Operatori && i ||:
a) Porede dvije numerike vrijednosti
b) Kombinuju dvije numerike vrijednosti
c) Porede dvije Boolean vrijednosti
37
Zadaci za izradu
1. Napisati program kojim se unosi oitavanje temperature u Farenhajtima,
te daje ekvivalentna temperatura u Celzijima, koristei formulu:
tempC = 5/9*(tempF - 32)
(Primjer: 104 F = 40 C)
2. Napisati program koji unosi oktalne brojeve, i daje rezultat u decimalnom
obliku. Na primjer,
Unesi oktalni broj: 214 Oktalni(214) = Decimalni(140)
38
Operatori
Primjer
n=25
n+=25
n =25
n*=25
n/=25
n%=25
n &= 0xF2F2
n |= 0xF2F2
n = 0xF2F2
n <<= 6
n >>= 6
Ekvivalentno sa
n=n+25
n=n25
n=n*25
n=n/25
n=n%25
n = n & 0xF2F2
n = n | 0xF2F2
n = n 0xF2F2
n = n << 6
n = n >> 6
sizeof
sizeof
++
+-!
*/%
+
> < >= <=
== !=
&
|
&&
||
? :
= *= /= += -= &=
= |= %= >>= <<=
,
znaenje
globalno podruje
izbor lana
izbor lana
indeksiranje
poziv funkcije
uveaj nakon
umanji nakon
veliina objekta
veliina tipa
uveaj prije
umanji prije
unarni operatori
mnoenja
sabiranja
bitovni pomaci
poredbeni operatori
operatori jednakosti
bitovni i
bitovni ili
bitovno iskljuivo ili
logiko i
logiko ili
logiko i
pridruivanja
Primjer
::ime
objekat.clan
pointer->clan
varijabla[indeks]
funkcija(argumenti)
broj++
broj
sizeof izraz
sizeof(tip)
++broj
broj
!broj
izraz % izraz
izraz + izraz
izraz izraz
izraz <= izraz
izraz == izraz
izraz & izraz
izraz izraz
izraz | izraz
izraz && izraz
izraz || izraz
izraz ? izraz : izraz
vrijednost *= izraz
razdvajanje
izraz,izraz
Poglavlje 4
Naredbe
Ovo poglavlje opisuje razne oblike C++ naredbi koje slue za pisanje programa. Kao i veina ostalih programskih jezika, C++ nudi razliite vrste
naredbi koje se koriste u razliite svrhe. Tako se deklaracione naredbe koriste
za definisanje varijabli, naredbe pridruivanja za jednostavne proraune, itd.
U narednim poglavljima bie objanjene neke od njih.
4.1
Jednostavna naredba je svaka naredba koja zavrava taka-zarezom (;). Definicije varijabli i izrazi koji zavravaju sa taka-zarezom su samo neki od primjera,
kao u sljedeim sluajevima:
int
i;
//
++i;
//
double d = 10.5; //
d + 5;
//
deklaraciona naredba
naredba sa popratnom pojavom
deklaraciona naredba
beskorisna naredba
40
Naredbe
4.2
Naredba if
U sluaju da elimo izvriti vie naredbi koje ovise o nekom istom uslovu,
koristimo sloenu naredbu, tj. sve naredbe stavljamo izmeu velikih zagrada.
Varijanta if naredbe koja omoguuje da se specificiraju dvije alternativne
naredbe, jedna koja se izvrava kada je uslov ispunjen i druga kada nije, naziva
se if-else naredba i ima oblik:
if (izraz)
naredba1;
else
naredba2;
#include <iostream>
using namespace std;
3
4
5
6
main()
{
int x;
7
8
9
10
11
12
13
41
4.3
Naredba switch
42
Naredbe
4.4
Naredba while
4.5. Naredba do
43
Tijelo petlje while moe biti prazno, tj. sa null -naredbom, ali to nije uobiajeno. Ipak, sljedei primjer, problem nalaenja najveeg neparnog faktora
nekog broja, pokazuje i jedan takav sluaj.
while (n % 2 == 0 && n /= 2)
Ovdje uslov petlje izvrava sve neophodne kalkulacije, tako da nema potrebe
za tijelom.
4.5
Naredba do
44
4.6
Naredbe
Naredba for
Naredba for (for petlja) je slina naredbi while, ali ima dvije dodatne komponente: (i) izraz koji se izraunava samo jednom prije nekog prorauna koji se
ponavlja, i (ii) izraz koji se izraunava jednom na kraju svake iteracije. Opti
oblik naredbe for je:
for (izraz1; izraz2; izraz3)
naredba;
45
while (i != 0)
bilo-sta;
// beskonana petlja
U liniji sa ispisom (cout << setw(5)<< i*j;) koriten je operator za manipulisanje setw(), koji se koristi za formatirano ispisivanje. Naime, brojka
unutar zagrada (u gornjem primjeru to je broj 5) predstavlja najmanji prostor
predvien za ispis podataka u izlaznom toku.
Kviz pitanja
1. Koja od petlji (for, while, do) se izvrava barem jednom?
2. Koja od petlji je najbolji izbor kada je broj iteracija poznat?
3. Napii naredbe za sljedee:
a) provjera da li je broj neparan,
b) provjera da li je broj neparan i negativan,
c) dati apsolutnu vrijednost nekog broja.
4. Pretpostavljajui da je n = 20, ta e biti rezultat sljedeeg koda:
if (n >= 0)
if (n < 10)
cout << "n je malo\n";
else
cout << "n je negativno\n";
46
Naredbe
6. Tano ili netano: inkrementalni izraz unutar for petlje moe smanjiti
varijablu petlje.
7. Blok nekog koda je odvojen .....
8. Koliko puta se izvrava tijelo do petlje?
9. Dati sintaksu naredbe switch!
Zadaci za izradu
1. Napisati program koji daje najmanji zajedniki sadrilac dva cijela broja!
2. Napisati program koji daje najvei zajedniki djelilac dva cijela broja!
3. Napisati program koji daje sve proste brojeve izmeu 2 i nekog broja N.
4. Savreni broj je broj koji je jednak zbiru svojih djelilaca. Napisati program koji daje prvih N savrenih brojeva!
5. Napisati program koji daje sve savrene brojeve manje od 10000!
6. Jedna od metoda za rjeavanje nelinearnih jednaina je metoda polovljenja intervala. Napisati program koji daje rjeenje nelinearne jednaine
pomou ove metode, pri emu su ulazni podaci interval u kojem se nalazi
rjeenje, te tanost (razlika izmeu dvije uzastopne iteracije).
7. Napisati program koji rjeava nelinearne jednaine pomou metode tangente, tj. Newton-Raphsonove metode!
Poglavlje 5
Funkcije
Ovo poglavlje opisuje funkcije koje definie korisnik, kao jedan od glavnih
"graevinskih" blokova u C++ programiranju. Funkcije obezbijeuju prikladan nain pakovanja nekog numerikog "recepta", koji se moe koristiti koliko
god je to puta potrebno, i predstavljaju okosnicu tehnike proceduralnog programiranja.
5.1
Definicija
48
Funkcije
se izvrava tijelo funkcije. Na kraju, funkcija vraa vrijednost poziva (ako isti
postoji).
Sljedei primjer ilustrativno pokazuje definiciju jednostavne funkcije koja
izraunava vrijednost stepena cijelog broja na neki cijeli broj.
1
2
3
4
5
6
7
Linija 1 definie interfejs funkcije. Ona poinje tipom funkcije koji se vraa;
u ovom sluaju radi se o cjelobrojnoj vrijednosti, int . Nakon toga je dato ime
funkcije, Stepen, a zatim lista njenih parametara. Funkcija Stepen ima dva
parametra (baza i eksponent) koji su tipa int. Pri tome, uzeto je da varijabla
eksponent ima samo pozitivne vrijednosti (unsigned int), jer je i funkcija Stepen
cjelobrojnog tipa int1 . Sintaksa parametara je slina sintaksi definisanja varijabli, tj. nakon tipa daje se ime parametra, osim to se parametri ne odvajaju
zarezom, kao u
int Stepen (int baza, eksponent)
// Ovo je pogreno!
#include <iostream>
using namespace std;
3
4
main(void){
1U
sluaju da se funkcija eli proiriti i na stepenovanje na negativne cijele brojeve, imala bi realni tip,
a linija 5 prethodnog primjera imala bi oblik:
rezultat*=1./baza
pri emu varijabla rezultat mora biti realna.
5.1. Definicija
cout << "2 ^ 8= " << Stepen(2,8) << \n;
5
6
49
#include <iostream>
using namespace std;
3
4
5
6
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
main ()
{
int a,b;
cout << "Unesi bazu:";
cin >> a;
cout << "\nUnesi eksponent:";
cin >> b;
cout << a<<"^" <<b<<" = " << Stepen(a,b) << \n;
system("PAUSE");
}
Vidi se da je funkcija Stepen definisana prije glavnog programa (sve funkcije, koje se koriste u nekom programu, moraju se definisati prije glavnog
programa, dakle prije funkcije main). U ovom sluaju, funkcija ima tip double,
tako da moe da "pokrije" vie mogunosti (vee rezultate, decimalne brojeve
kao rezultat). Poziv funkcije, linija 20, vri se pomou Stepen(a,b), pri emu
tipovi oba argumenta a i b, odgovaraju tipovima parametara funkcije baza i
eksponent, respektivno.
50
Funkcije
Primjer 2.
Treba napomenuti da se definicija funkcije sastoji od njenog prototipa, tako
da je za definisanje dovoljno ispisati samo njen prototip. Na taj nain, kompletna definicija funkcije se moe dati kasnije, kao to je pokazano u narednom
primjeru. Takoer je mogue izostaviti nazive parametara u definiciji, ali to
nije preporuljivo.
1
2
#include <iostream>
using namespace std;
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
main ()
{
int a,b;
cout << "Unesi bazu:";
cin >> a;
cout << "\nUnesi eksponent:";
cin >> b;
cout << a<<"^" <<b<<" = " << Stepen(a,b) << \n;
system("PAUSE");
}
21
22
23
24
25
26
27
28
29
Dakle, funkcija je definisana u liniji 4, koristei njen potpis. Vano je napomenuti da je u ovom sluaju neophodno staviti taka-zarez (;) nakon definisanja, jer linija 4 predstavlja naredbu. Sjetimo se da se nakon definisanja
funkcije ne stavlja taka-zarez nakon zagrade }, koja zatvara tijelo funkcije.
itava definicija funkcije data je linijama 22-29.
51
Primjer 3.
Radi preglednosti veoma je korisno sakupiti sve funkcije u posebne datoteke,
i umjesto njihovog definisanja u sklopu izvrne datoteke, treba samo proitati
tu datoteku. Na primjer, ako je definicija funkcije Stepen data u datoteci
StepenInt.h,tj.
\\ sadrzaj datoteke StepenInt.h
int Stepen (int baza, int eksponent)
{
int rezultat = 1;
for (int i = 0; i < eksponent; ++i)
rezultat *= baza;
return rezultat;
}
5.2
Parametri i argumenti
52
Funkcije
sljedica toga, ako funkcija napravi bilo kakvu promjenu na parametrima, ovo
nee promijeniti vrijednosti argumenata. Na primjer, u programu
#include <iostream>
using namespace std;
void Funkcija (int broj)
{
broj = 0;
cout << "broj = " << broj << \n;
}
int main ()
{
int x = 10;
Funkcija(x);
cout << "x = " << x << \n;
system("PAUSE");
return 0;
}
Za razliku od parametra po vrijednosti, parametar po referenci prima argument koji se prenosi i sve obavlja direktno na njemu (vie o referencama u
poglavlju 7.6). 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 & (ampersand) ispred varijable
koja je parametar u interfejsu funkcije, tj. u prethodnom primjeru interfejs
funkcije Funkcija ima oblik:
void Funkcija (int &broj)
53
5.3
54
Funkcije
//...
}
}
imamo tri razliita podruja, od kojih svaki ima razliitu varijablu xyz.
Openito, ivotni vijek varijable je ogranien na podruje iste. Tako, na
primjer, globalne varijable traju svo vrijeme izvrenja programa, dok se lokalne
varijable kreiraju kada se ue u njihovo podruje, a unitavaju kada se iz njega
izae. Memorijski prostor za lokalne varijable je rezervisan prije izvrenja
programa, dok je memorijski prostor za lokalne varijable alociran "u hodu" u
toku izvrenja programa.
Poto lokalno podruje ponitava globalno, to lokalne varijable sa istim
imenom kao globalne varijable onemoguavaju pristup globalnim varijablama
unutar lokalnog podruja. Na primjer, u
int greska; \\globalna varijabla
void Greska (int greska) { \\lokalna varijabla
//...
}
5.4
Rekurzivne funkcije
55
U principu, sve rekurzivne funkcije se mogu napisati koristei iteracije. Naime, treba imati u vidu da u sluaju 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 rjeenje. No, u nekim
sluajevima elegantno i jednostavno rekurzivno rjeenje moe da bude bolja
opcija.
U sluaju faktorijela, na primjer, iterativna opcija je bolja, pa bi funkcija
imala oblik:
int Faktorijel (unsigned int n) {
int rezultat = 1;
while (n > 0) rezultat *= n--;
return rezultat;
}
5.5
56
Funkcije
Iz primjera se vidi da sve funkcije imaju isto ime; prva i druga imaju razliite tipove, dok trei oblik funkcije Stepen ima razliit broj parametara. Treba
paziti da pri pozivu pojedinih funkcija svi tipovi argumenata odgovaraju tipovima parametara (broj 2 se tretira kao cijeli broj, ali 2.0 kao realan!!!)
Kviz pitanja
1. Da li funkcija moe imati vie od jednog argumenta?
2. Da li funkcija mora imati return vrijednost?
3. Da li funkcija moe imati vie od jedne return vrijednosti?
4. Da li je mogue da funkcija nema ni argumente ni return vrijednost?
57
58
Funkcije
Zadaci za izradu
1. Zadatke 1, 2 i 3 iz Poglavlja 3 rijeiti koritenjem funkcija.
2. Napisati funkciju koja daje sve proste brojeve izmeu brojeva 2 i nekog
broja N. Funkcija treba da ima jedan argument.
3. Napisati funkciju bisekcija, sa argumentima a i b za granice intervala, te
epsilon za tanost i funk za funkciju f(x), koja rjeava nelienarnu jednainu pomou metode bisekcije; funkcija treba da vraa rjeenje jednaine
f (x) = 0. Definisati funkciju funk, koja daje vrijednost traene funkcije
f (x).
4. Prethodni zadatak rijeiti za Newton-Raphsonovu metodu!
5. Napisati program koji sadri funkciju NZS, koja kao rezultat daje najmanji zajedniki sadrilac dva broja.
6. Napisati program koji sadri funkciju NZD, koja kao rezultat daje najvei
zajedniki djelilac dva broja.
7. Napisati funkciju koja provjerava da li su dva broja brojevi prijatelji.
Brojevi prijatelji su oni brojevi kod kojih vrijedi da je svaki od njih jednak
zbiru djelilaca drugog.
8. Dati funkciju koja kao rezultat daje traeni broj parova brojeva prijatelja.
Kao argument dati broj traenih parova.
Poglavlje 6
Polja (arrays)
Ovo poglavlje objanjava polja (neki autori upotrebljavaju i izraz niz) i ilustruje njihovu upotrebu pri definisanju varijabli. Polje se sastoji od niza objekata (nazivaju se i elementi polja), koji su istog tipa i zauzimaju neprekidan
memorijski prostor. Openito, samo polje ima simboliko ime, a ne njegovi
elementi. Svaki element je identificiran njegovim indeksom, koji pokazuje poloaj nekog elementa u polju. Broj elemenata u polju naziva se dimenzija polja.
Dimenzija polja je fiksirana i prethodno odreena, i ne moe se promijeniti u
toku izvrenja programa.
Polja su pogodna za predstavljanje podataka koji se sastoje od mnogo slinih, individualnih objekata. Primjeri za to su lista imena, tabela gradova i
njihovih sezonskih temperatura, i slino.
6.1
Definisanje i inicijalizacija
60
Polja (arrays)
visina[2] = 177;
Kao i kod ostalih varijabli, vrijednosti elemenata polja se mogu inicijalizirati. U tu svrhu koriste se zagrade {}, izmeu kojih se specificira lista poetnih
vrijednosti elemenata polja koje su odvojene zarezom. Na primjer,
int broj[3] = {5, 10, 15};
definie polje broj, i inicijalizira tri elementa ovog polja na vrijednosti 5, 10, 15,
respektivno. Ovo je tzv. eksplicitno inicijaliziranje. Kada je broj vrijednosti
u inicijalizatoru manji od dimenzije polja, ostali elementi su inicijalizirani na
nulu, kao u sluaju:
int broj[3] = {5, 10}; // broj[2] je inicijaliziran na 0
61
Vidi se da se pomou definicije int broj[] omoguava vea fleksibilnost dimenzije polja, pa je kompletan program u tom sluaju:
#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");
}
Sljedei program predstavlja primjer pomou kojeg se unosi, sortira i ispisuje neki niz. Pri tome, sortiranje je izvedeno od najveeg prema najmanjem
elementu niza.
1
2
3
4
5
#include <iostream>
using namespace std;
int main ()
{
// DEFINISANJE
62
Polja (arrays)
int x[10];
int y[10];
int i, j, n;
// UNOSENJE
cout << "Unesite broj clanova polja (<10): ";
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;
}
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
str[] = "VOZDRA";
definie varijablu str kao niz od sedam (7) karaktera: est slova i jedan prazan
karakter (null -karakter). Zavrni prazan karakter postavlja kompajler. Za
razliku od toga,
char
definie varijablu str kao niz od 6 elemenata. Treba naglasiti da prethodni primjer nije ispravan, jer svaki pravilno inicijalizirani niz karaktera mora obavezno
63
6.2
Multidimenzionalna polja
Polje moe da ima i vie nego jednu dimenziju (dvije, tri, i vie). Ipak, organizacija polja u memoriji je ista kao i prije, tj. neprekidna sekvenca elemenata,
pa je percepcija programera neto drugaija od one koja se namee na prvi
pogled (kao multidimenzionalna). Na primjer, pretpostavimo da je srednja vrijednost temperatura po godinjim dobima za tri bosanskohercegovaka grada
data tabelom 6.1.
Tabela 6.1: Srednje godinje temperature gradova
Ime grada
Sarajevo
Tuzla
Zenica
Proljee
10
13
14
Ljeto
20
21
23
Jesen
10
12
11
Zima
1
3
4
10
20
First row
10
Prvi red
13
21
Second row
12
Drugi red
14
23
11
...
Third row
Trei red
Kao i kod jednodimenzionalnih polja (nizova), i ovdje se elementima pristupa preko indeksa. No, neophodan je dodatni indeks za svaku dimenziju.
Na primjer, srednja temperatura u Zenici u toku ljeta, data je elementom
godDobTemp[2][1].
Inicijalizacija polja se moe obaviti pomou ugnijedenog inicijalizatora, kao
u:
64
Polja (arrays)
int godDobTemp[3][4] = {
{10, 20, 10, 1},
{13, 21, 12, 3},
{14, 23, 11, 4}
};
= 3;
= 4;
int godDobTemp[redovi][kolone] = {
{10, 20, 10, 1},
{13, 21, 12, 3},
{14, 23, 11, 4}
};
65
Napomena: Treba paziti kako se inicijalizira vrijednost kontrolne varijable najveca u prethodnom primjeru; pravilno je postaviti na prvi lan polja,
umjesto pretpostaviti neku konanu vrijednost (na primjer 0).
Kviz pitanja
1. Da li neko polje moe sadravati i cijele brojeve, realne brojeve i karaktere?
2. Koji je indeks prvog elementa u nizu?
3. Koji je indeks posljednjeg elementa u nizu?
4. Koja je razlika izmeu inicijalizacije i pridruivanja?
5. Koja su dva naina inicijalizacije polja?
Zadaci za izradu
1. Napisati program koji rjeava sistem od N (treba unijeti ovu vrijednost)
linearnih jednaina pomou Gaussove metode eliminacije.
2. Prethodni zadatak uraditi pomou Gaussove metode eliminacije sa djeliminim izborom glavnog elementa.
3. Prethodne zadatke rijeiti koristei funkciju Gauss, odnosno GaussIzbor,
koje kao argumente uzimaju matricu sistema A, te vektor b.
66
Polja (arrays)
4. Napisati program koji daje koeficijente polinoma n-tog reda koji aproksimiraju proizvoljan broj taaka, na primjer m, pomou metode najmanjih
kvadrata.
5. Prethodni primjer napisati koristei funkciju MNKpolinom, koja kao argumente ima koordinate taaka (x,y), broj tih taaka m, te stepen traenog
aproksimacionog polinoma n, a njena vrijednost je niz koeficijenata polinoma.
Poglavlje 7
Pointeri
7.1
Osnovno o pointerima
Pointeri (pokazivai) predstavljaju adresu neke memorijske lokacije i omoguuju indirektni nain pristupa podacima u memoriji. Pointer varijabla se definie pokazivanjem na podatak odreenog tipa. Na primjer,
int *ptr1;
char *prt2;
moemo pisati:
ptr1 = #
broj
68
Pointeri
*ptr1
dereferencira ptr1 da bi se dobilo ono na ta on pokazuje, pa je time ekvivalentan num. Simbol * je operator dereferenciranja; on uzima pointer kao
argument i vraa sadraj memorijske lokacije na koju pokazuje.
Openito, tip pointera mora odgovarati tipu podatka na koji taj pointer
pokazuje. Meutim, pointer tipa void odgovara bilo kojem tipu. Ovo je veoma
korisno pri definisanju pointera koji mogu pokazivati na podatke razliitih
tipova, ili one podatke kojima tip u poetku nije poznat.
Pointer se moe konvertovati (pomou cast) u neki drugi tip. Na primjer,
ptr2 = (char*) ptr1;
7.2
Dinamika memorija
Pored programskog stoga (eng. stack ), koji se koristi za pohranjivanje globalnih varijabli, te blokova stogova za pozivanje funkcija, na raspolaganju je
i drugi vid memorije, koji se naziva hrpa (eng. heap). Ova memorija se koristi za dinamiko alociranje memorijskih blokova u toku izvrenja programa.
Zbog toga se ova memorija esto naziva i dinamika memorija. S druge strane,
programski stog se esto naziva statika memorija.
Za alociranje i dealociranje memorijskih blokova u hrpi (jo se naziva i javna
memorija) koriste se dva operatora. Operator new kao argument uzima tip i
alocira memorijski prostor za objekat tog tipa. On vraa pointer na alocirani
prostor. Na primjer,
int *ptr = new int;
char *str = new char[10];
alociraju prostor za jedan cijeli broj i prostor koji je dovoljno velik da pohrani
niz od deset karaktera, respektivno.
Memorija koja se alocira iz hrpe ne ispunjava ista pravila podruja definisanosti (eng. scope rules) kao normalne varijable. Na primjer, kada funkcija
Funkcija
void Funkcija (void) {
char *str = new char[10];
69
//...
}
vraa vrijednost, lokalna varijabla str je unitena, ali memorijski prostor koji
pokazuje na str nije. Ovo posljednje ostaje alocirano sve dok ga programer
eksplicitno ne oslobodi.
Operator delete se koristi za oslobaanje memorijskog prostora koji se alocira pomou new. On uzima pointer kao argument i oslobaa memorijski
prostor na koji taj pointer pokazuje. Na primjer,
delete ptr;
delete [] str;
#include <string>
char* CopyOf (const char *str)
{
char *copy = new char[strlen(str) + 1];
strcpy(copy, str);
return copy;
}
70
Pointeri
7.3
Pointeri i polja
prevodi kao
int broj = *(cijeliBroj+3);
Posljednja naredba se moe shvatiti kao: uzmi adresu prvog elementa polja,
poveaj je za 3, pogledaj ta se nalazi na toj adresi, te pridrui tu vrijednost
varijabli broj. Dakle, ako imamo definisano polje
int cijeliBroj[] = {1,2,3};
7.4
71
Aritmetika sa pointerima
str++ e "napredovati" str za jedan karakter char, tj. za jedan bajt, tako da
pokazuje na drugi karakter niza karaktera "VOZDRA", dok e ptr++ "napredovati" ptr za jedan int, tj. 4 bajta, tako da pokazuje na drugi elemenat niza
broj. Slika 7.2 pokazuje ovo shematski.
V O Z D R A \0
str
str++
10
20
30
40
ptr
ptr++
72
Pointeri
;
4
5
U liniji 3, uslov petlje pridruuje sadraj src sadraju dest, a zatim inkrementalno poveava oba pointera. Ovaj uslov postaje jednak nuli kada je
posljednji null -karakter pointera src kopiran u dest.
Pokazuje se da je varijabla koja predstavlja niz, kao to je to sluaj sa broj
sama po sebi adresa prvog elementa niza koji predstavlja. Stoga se elementima varijable broj moe pristupiti i preko aritmetike sa pointerima na broj, tj.
broj[i] je ekvivalentno *(broj+i). Razlika izmeu broj i ptr je u tome to je broj
konstanta, tako da ne moe pokazivati ni na ta, dok je ptr varijabla i moe se
iskoristiti da pokazuje na bilo koji drugi cijeli broj.
Sljedei primjer pokazuje kako funkcija najTemp, koja je pokazana u prethodnom poglavlju moe da se pobolja koritenjem aritmetike sa pointerima.
1
2
3
4
5
6
7
8
9
10
8
9
7.5
73
Funkcijski pointeri
definie pointer funkciju koja se naziva Uporedi koja moe zadrati adresu bilo
koje funkcije koja kao argumente uzima dva konstantna pointera tipa char i
vraa cjelobrojnu vrijednost. Takva je, na primjer, funkcija strcmp, koja slui
za uporeivanje stringova. Na taj nain imamo:
Uporedi = &strcmp;
//
//
//
//
//
//
//
direktni poziv
indirektni poziv
indirektni poziv (skraeno)
74
Pointeri
7.6. Reference
75
7.6
Reference
definie broj1, te broj2 kao referencu za broj1. Nakon ovakve definicije i broj1
i broj2 se odnose na isti objekat, kao da su ista varijabla. Treba naglasiti da
referenca ne kreira kopiju objekta, nego je nita drugo no simbolini nadimak
za isti. Na taj nain, nakon naredbe
broj1 = 0.16;
broj3 = broj1;
Takoer je mogue definisati referencu koja je konstantna (eng. const reference)1 . U tom sluaju, konstantna referenca mora odgovarati konstantnom
objektu. Sljedei primjeri pokazuju neke od primjena:
const int broj = 13;
const int &refbroj = broj; // u redu: i referenca i objekat su
// const
int &refBroj2 = broj;
// greska
1 C++ programeri ipak koriste ovaj pojam, iako on u stvari znai referencu konstante (eng. reference to
const)
76
Pointeri
Iako funkcija Zamijeni1 (linija 1), zamjenjuje x i y, ovo nema nikakvog efekta
na argumente koji se prosljeuju funkciji, jer Zamijeni1 dobija kopiju argumenata. Ono to se deava kopiji ne utjee na original. Za razliku od ovog sluaja,
funkcija Zamijeni2 (linija 7) prevazilazi problem koji ima funkcija Zamijeni1 koritenjem parametara pointera. Dereferenciranjem pointera, Zamijeni2 dolazi
do originalnih veliina i zamjenjuje ih.
Funkcija Zamjeni3 (linija 13) prevazilazi problem funkcije Zamijeni1 pomou
parametara referenci. Parametri postaju nadimci za argumente koji se prosljeuju funkciji i na taj nain ih zamjenjuju.
Osnovna prednost funkcije Zamijeni3 nad funkcijom Zamijeni2 je to je sintaksa poziva funkcije ista kao za Zamijeni1, te nema adresiranja ili dereferencranja. Sljedea funkcija main ilustrira razliku:
1
2
7.6. Reference
int i = 10, j = 20;
Zamijeni1(i, j); cout << i << ", " << j << \n;
Zamijeni2(&i, &j); cout << i << ", " << j << \n;
Zamijeni3(i, j); cout << i << ", " << j << \n;
3
4
5
6
7
77
Kviz pitanja
1. ta su pointeri ili pokazivai?
2. Koja je razlika u definisanju cjelobrojne varijable i cjelobrojne pointer
varijable?
3. Koje je znaenje tipa podatka u definiciji pointera?
4. ta je to null -pointer?
5. Koji operator se koristi da bi se pointer pridruio adresi neke druge varijable ili konstante?
6. Da li pointer moe pokazivati na razliitu memorijsku lokaciju u razliitim
vremenskim periodima u programu?
7. Da li na istu memorijsku lokaciju moe da pokazuje vie od jednog pointera?
8. ta je rezultat inkrementiranja pointer varijable?
9. ta je to dinamika memorija?
10. Koja je veza pointera i polja?
11. ta predstavljaju aritmetike operacije sa pointerima?
12. Objasni pojam funkcijskih pointera?
13. ta su to reference i gdje se najee upotrebljavaju?
Poglavlje 8
Datoteke
Ovo poglavlje pokazuje kako se podaci dobiveni pokretanjem nekog programa
mogu sauvati (pohraniti) na neku datoteku. S obzirom da uvanje podataka
nema svrhu ako tim podacima ne moemo da pristupamo, bie objanjeno i
kako proitati podatke sa neke datoteke.
Datoteka, pri tome, predstavlja skup podataka koji su snimljeni na neku
formu trajne memorije (hard disk, CD-ROM, floppy disk, itd.). Datoteci se
pristupa preko njenog imena (filename), u ijem sastavu se obino nalazi ekstenzija (dio imena iza take), koja oznaava tip podataka u datoteci (npr. .doc
za Microsoft Word, .xls Microsoft Excel, .cpp za C++ izvornu datoteku, itd.).
U osnovi, postoje dvije vrste datoteka: tekstualne i binarne. Tekstualne
datoteke sadre tekst, dok binarne mogu sadravati i kompleksnije vrste podataka, kao to su slike, izvrni programi, baze podataka, itd. Tekstualnim
datotekama je neto jednostavnije pristupiti, pisati podatke u njih, te itati sa
njih. Upravo to je i razlog zbog ega ce se primjeri u ovom poglavlju odnositi
samo na njih.
8.1
80
Datoteke
8.2
Kada program pristupa datotekama, bez obzira da li ih ita, ili na njih pie,
ili ini oboje, on prolazi kroz sljedee korake:
Datoteka prvo mora da se otvori. Ovo otvara put u komunikaciji izmeu
datoteke i objekta toka u programu (fstream, ifstream, ofstream), koji se
koristi u pristupu datoteci.
Nakon otvaranja, program ita sa datoteke, pie na nju, ili ini oboje.
Na kraju, program zatvara datoteku. Ovo je bitan korak, poto odravanje komunikacije izmeu datoteke i objekta toka zahtijeva resurse, tako da
zatvaranje datoteke oslobaa ove resurse kada vie nisu potrebni. Uz to,
postoji mogunost da se kasnije u programu ne moe pristupiti datoteci
ako prethodno nije zatvorena.
8.2.1
Otvaranje datoteka
Bez obzira da li se sadraj datoteke treba proitati ili se na datoteku trebaju ispisati neki podaci, datoteka prvo treba da se otvori. Naredna poglavlja
pokazuju kako se to obavlja.
81
sljedei nain:
1
2
ofstream izlaz;
izlaz.open("studenti.txt");
Prvom linijom je kreiran objekat izlaz tipa ofstream, dok se u drugoj liniji
kreira datoteka studenti.txt. Kao to se vidi, argument funkcije open je ime i
lokacija datoteke koja se treba otvoriti. Meutim, mogue je dodati i drugi argument zavisno od toga da li je funkcija open lan objekta fstream ili ofstream,
ili se eli neki drugi modul od onog koji se daje (vidi tabelu 8.1).
Datoteka u koju elimo pisati podatke ne mora postojati. U sluaju da ne
postoji, ona e se automatski kreirati pod imenom i na lokaciji koju smo upisali.
Lokacija se moe dati kao relativna (relative path) ili apsolutna (absolute path).
Pri tome, relativni put predstavlja lokaciju u odnosu na lokaciju programa, tj.
direktorij u kojem se nalazi izvorna datoteka.
Za razliku od relativnog puta, apsolutni put predstavlja lokaciju koja zapoinje slovom drajva, sadravajui sve direktorije i poddirektorije, dok se ne
doe do datoteke. Na primjer, ako je datoteka studenti.txt u direktoriju Pedagoski, a ovaj je poddirektorij direktorija UNZE, a sve se nalazi na tvrdom
disku sa slovom C, onda bi se datoteka otvorila na sljedei nain:
ofstream izlaz;
izlaz.open("C:\\MFZE\\Pedagoski\\studenti.txt");
Vidimo da se u tom sluaju koriste po dva znaka \, jer samo jedan izmeu
navodnika predstavlja escape-sekvencu (poglavlje 2.8.3).
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 sljedeem primjeru:
ofstream izlaz;
char imeDatoteke[80];
cout << "Unesite ime datoteke: ";
cin >> imeDatoteke;
izlaz.open(imeDatoteke);
1 Oba ova pojma, metode (eng. member function) i konstruktori, odnose se na klase, tj. dio su objektnoorijentisane paradigme
82
Datoteke
Opis
Postojei sadraj datoteke je ouvan i sav izlaz
se ispisuje na kraj datoteke.
Informacija se na datoteku pie u binarnom
obliku.
Informacija e se itati sa datoteke. Datoteka
se ne kreira ako ne postoji.
Informacija e se zapisati u datoteku. Postojei
sadraj datoteke je poniten.
83
ofstream izlaz("studenti.txt");
fstream izlaz("studenti.txt",ios::out);
a drugi
fstream izlaz;
izlaz.open("studenti.txt", ios::out);
Primjena konstruktora, u stvari, omoguava definisanje i inicijalizaciju primjerka nekog objekta. Kao i u sluaju definisanja (deklaarisanja) i inicijalizacije varijabli, koritenje jednog od naina otvaranja datoteke zavisi od samog
programa i naih potreba.
Otvaranje datoteka za itanje
3) pomou konstruktora
ifstream ulaz("studenti.txt");
fstream ulaz("studenti.txt", ios::in);
84
Datoteke
Prije nego ponemo itati podatke sa neke datoteke, korisno je znati da li ona
uopte postoji. Provjera se moe izvriti na dva naina. Ako se datoteka ne
moe otvoriti za itanje, onda je: (i) vrijednost ifstream objekta jednaka NULL
(nula), (ii) vrijednost funkcije fail objekta ifstream je true(1). Sljedei primjer
ilustruje koritenje oba naina.
#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;
}
85
Za razliku od ifstream objekta, ofstream objekat koji pokuava 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 sluaju je korisno provjeriti da li datoteka postoji.
Naime, ako datoteka postoji, ali ima osobinu read-only 2 , dobiemo negativan
odgovor o njenom postojanju (vrijednost iostream objekta je NULL, a funkcije
fail je true, tj. 1).
8.2.2
Zatvaranje datoteka
8.2.3
Pisanje na datoteke
#include <fstream>
#include <iostream>
using namespace std;
4
5
6
2 Datoteke
86
Datoteke
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;
7
8
9
10
11
12
13
14
15
16
17
18
19
20
87
}
izlaz.close();
}
8.2.4
itanje sa datoteka
Analogno prethodnom poglavlju, itanje podataka sa datoteka obavlja se pomou operatora za itanje (>>) kao to je to sluaj sa ispisivanjem sa tastature
(cin>>). Sljedei primjer nadopunjava onaj iz prethodnog dijela, tj. nakon to
korisnik upie informacije na datoteku, program ita iste podatke sa datoteke
i ispisuje ih na ekran.
1
2
3
#include <fstream>
#include <iostream>
using namespace std;
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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;
20
21
22
23
24
25
26
27
28
29
30
88
Datoteke
Slino primjeru iz prethodnog dijela, podaci se unose pomou funkcije getline (linija 13) sa neto drugaijom sintaksom. Ovdje pomenuta funkcija (definisana je kao funkcija, a ne funkcijski lan) ima dva argumenta: prvi tipa
iostream (cin), a drugi varijabla podaci. Na slian nain se pomou iste
funkcije podaci itaju sa datoteke (linije 23 i 25), pri emu je prvi lan objekat
ulaz tipa ifstream.
Prethodni primjer se moe napisati i na programerski adekvatniji nain
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 (){
char podaci[100];
bool status;
ofstream izlaz;
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;
89
90
Datoteke
ne mijenja.
Sukcesivno itanje
esto puta je potrebno proitati sve podatke sa neke datoteke, pri emu unaprijed ne poznajemo konaan broj informacija (na primjer, proizvoljan broj
vrijednosti neke varijable). U tu svrhu se koristi funkcija eof (od engleske rijei end of file), koja je tana ukoliko se proe posljednja linija u kojoj postoji
neka informacija. Sljedei primjer pokazuje upotrebu ove funkcije u problemu
itanja nizova karaktera (rijei).
#include <iostream>
#include <fstream>
using namespace std;
int main ()
{
char podaci[80];
ifstream saDat;
saDat.open("podaci.txt");
while(!saDat.eof()) {
saDat >> podaci;
cout << podaci << endl;
}
saDat.close();
system("PAUSE");
}
Linije 12-15, petlja while, omoguavaju sukcesivno itanje podataka sa datoteke podaci.txt. Kada se doe do posljednje linije sa nekom informacijom,
funkcija eof vraa vrijednost true i automatski se izlazi iz petlje. Na analogan
nain se mogu itati podaci rasporeeni u kolone.
Kviz pitanja
1. Nabrojati formate datoteka u kojima se mogu pohraniti podaci!
2. Koja standardna datoteka treba da se pozove kada program pie na datoteku ili ita sa nje?
91
Zadaci za izradu
1. Zadatke iz poglavlja 6, rijeiti tako da se unos podataka vri iz datoteke
ulaz.txt, a rezultati ispisuju u datoteci rezultat.txt!
Poglavlje 9
O objektno-orijentisanom
programiranju
Jo u uvodnom dijelu je reeno da C++ predstavlja jedan od najrairenijih
objektno-orijentisanih jezika. Stoga su u ovom poglavlju date neke od osnova
objektno-orijentisanog pristupa i razlika u odnosu na proceduralno.
9.1
94
O objektno-orijentisanom programiranju
programa za koji su prvobitno kreirani. Na primjer, objekat prozor (koji predstavlja prozor aplikacije u Windowsu, X Windowsu, MacOS, itd.) je neto to
programer moe koristiti u gotovo svakom programu koji razvija.
Objektno-orijentisano
MONITOR
Sve stvari i
radnje povezane
sa monitorom
RAUN
Sve stvari i
radnje povezane
sa raunom
Transakcija
Sve stvari i radnje
povezane sa
transaksijama
Proceduralno
TASTATURA
Sve stvari i
radnje povezane
sa tastaturom
Klijent
Sve stvari i radnje
povezane sa
klijentom
95
Na slian nain, objekat korisnik moe imati metode (procedure koje su dio,
ili lanovi objekta), kao to su "prikazati listu korisnikih rauna" ili "promijeniti adresu". Ove metode su procedure koje se odnose na objekat korisnik.
Procedura "procesiraj podizanje novca" ne bi postojala kao odvojena cjelina
unutar objektno-orijentisanog modela, nego bi se funkcionalnost, koja je sadr-
96
O objektno-orijentisanom programiranju
9.2
U mnogim sluajevima, dananje generacije programera su izloene samo objektno-orijentisanim i objektno-zasnovanim alatima i jezicima za razvijanje.
Upravo zbog toga, mnogi novi programeri prednosti objektno-orijentisanog
programiranja mogu uzeti zdravo-za-gotovo. Suprotno tome, programeri koji
su odrasli sa jezicima kao to su BASIC, COBOL i C ponekad imaju problema u tranziciji na objektno-orijentisano programiranje. Upravo iz razloga
to su kreirali mnogo korisnih i velikih programa koristei strukturno (a ne
objektno-orijentisano) programiranje, oni ne mogu odmah prepoznati prednosti objektno-orijentisanog programiranja. Kada ih okolnosti prisile da koriste objektno-orijentisane jezike i alate za razvoj, kao to su C++ i Visual
Basic, oni mogu ignorisati osobine ovih programa, i koristiti proceduralni ili
strukturni pristup.
Poto postoji mnogo prednosti objektno-orijentisanog programiranja, ne
samo da je vano kako koristiti objektno-orijentisane ili objektno-zasnovane
alate za razvoj, nego i kako ih korisiti na nain objektnog orijentisanja. Neki jezici (kao to su SmallTalk i Java) oteavaju mogunost nekoritenja objektnoorijentisanog pristupa. Ipak, ak i kod ovih jezika programeri treba da razviju
objektno-orijentisano razmiljanje da bi dobili punu korist od prednosti koje
su na raspolaganju.
Neke od prednosti objektno-orijentisanog programiranja ukljuuju:
sposobnost jednostavnog koritenja dijelova koda u razliitim programima,
tedei vrijeme u analizi, dizajnu, razvoju, testiranju, i debagiranju,
mogunost kupovine dijelova postojeeg, testiranog koda da bi se u razvoju omoguio komponentno-zasnovani pristup,
97
9.3
Objekti
98
O objektno-orijentisanom programiranju
Fiziki objekti: automobili u simulaciji saobraaja, komponente u elektrinim kolima, zemlje u ekonomskim modelima, avioni u simulaciji zranog saobraaja,. . .
Elementi u kompjuterskom okruenju: prozori, meniji, grafiki objekti
(linije, pravougaonici, krugovi), mi, tastatura, printer, . . .
Konstruktori za pohranjivanje podataka: polja, stakovi, linkovane liste,
binarna stabla, . . .
Ljudski entiteti: zaposlenici, studenti, kupci, prodavai, . . .
Kolekcije podataka: inventar, lini podaci, rjenik, tabela geografske irine i duine za gradove svijeta, . . .
Tipovi podataka koje definie korisnik: vrijeme, uglovi, kompleksni brojevi, take u ravni, . . .
Komponente u kompjuterskim igrama: automobili u utrci, pozicije u raznim igrama (ah, mica, ...), ivotinje u eko-simulaciji, suparnici i prijatelji
u avanturistikim igrama, . . .
Slinost izmeu programskog objekta i objekta iz stvarnog svijeta je rezultat spajanja podataka i funkcija: rezultujui objekat nudi revoluciju u programskom dizajnu. Ovakva slinost nije bila mogua izmeu programskih
konstrukcija i modeliranih stvari u proceduralnom programiranju.
9.3.2
Klase
U OOP kaemo da su objekti lanovi klasa. Na primjer, gotovo svi kompjuterski jezici imaju ugraene tipove podataka. Tako, tip int , koji predstavlja cijeli
broj, je definisan u C++. Pomou njega moemo deklarisati koliko god hoemo varijabli tipa int . Na slian nain, mogue je definisati mnogo objekata
iste klase. Neka klasa slui kao plan, ili templejt. Ona specificira koji podaci
i koje funkcije e biti ukljuene u objekte te klase. Definisanje klase ne kreira
nijedan objekat, kao to ni postojanje tipa int ne kreira nijednu varijablu.
Klasa je, na taj nain, opis mnogih slinih objekata. Ovo je u saglasnosti
sa ne-tehnikim znaenjem rijei klasa. Na primjer, Pink Floyd, Dire Straits,
Led Zepellin i Bijelo Dugme su lanovi klase rok grupa, ali ne postoji nijedna
grupa koja se zove rok grupa, nego su odreene grupe sa njihovim imenima,
koji posjeduju odreene karakteristike, lanovi ove klase.
9.3.3
99
Nasljeivanje
Ponovna iskoristivost
100
O objektno-orijentisanom programiranju
dodati joj neke osobine i mogunosti. Ovo se obavlja izvoenjem nove klase iz
postojee. Nova klasa e naslijediti mogunosti stare, sa mogunou dodavanja novih.
Na primjer, mogli smo napisati (ili kupiti od nekoga) klasu koja kreira
sistem menija, kao to je onaj koji se koristi u Windowsu ili nekom drugom
grafikom interfejsu. Ova klasa radi, i nema potrebe da je mijenjamo, ali
je mogue dodati neke karakteristike menijima na primjer, da svijetle ili
dodavanjem nekih drugih efekata. Da bismo ovo uradili, jednostavno bismo
kreirali novu klasu koja nasljeuje sve karakteristike postojee uz dodatak
svijetleih menija. Jednostavnost sa kojom se postojei softver moe ponovno
iskoristiti je vana prednost OOP. Mnoge kompanije su shvatile da mogunost
ponovnog koritenja klasa na novim projektima obezbijeuje poveani povrat
uloenog kapitala u originalni softver.
9.3.5
Jedna od prednosti objekata je da programeru daju pogodan nain za konstruisanje novih tipova podataka. Pretpostavimo da u naem programu radimo sa
dvodimenzionalnim poloajima (x,y koordinate, ili geografska irina i duina),
i eljeli bismo da operacije sa ovim poloajnim vrijednostima izrazimo normalnim aritmetikim operacijama, kao to je
pozicija1 = pozicija2 + koordinatniPocetak
gdje varijable pozicija1, pozicija2 i koordinatniPocetak predstavljaju par nezavisnih numerikih vrijednosti. Kreiranjem klase koja obuhvata ove dvije vrijednosti, i deklarisanjem da pozicija1, pozicija2 i koordinatniPocetak budu objekti
te klase, moemo, u principu, kreirati novi tip podataka. Mnoge karakteristike
C++ su usmjerene ka olakavanju kreiranja novih tipova podataka na ovaj
nain.
9.3.6
Polimorfizam i optereivanje
101
Kviz pitanja
1. Koje su razlike izmeu proceduralnog i objektno-orijentisanog programiranja?
2. Koje su karakteristike OOP jezika?
3. ta su to objekti?
4. Po emu se karakteriu klase?
5. ta je to nasljeivanje?
6. ta je to polimorfizam, a ta optereivanje?
LITERATURA
[1] C++ standard - ISO/IEC 14882
[2] Davis, R. C++ for Dummies. Wiley-Publisher Inc., 5. izdanje edition,
2004.
[3] Eckel, B. Thinking in C++, volume I-II. Prentice Hall, 2000.
[4] Hekmat, S. C++ Programming. Pragmatix Software Pty. Ltd., 2005.
[5] Kent, J. C++ demystified: A self-teaching guide. McGraw-Hill/Osborne,
2004.
[6] Liberty, J. Sams Teach Yourself C++ in 21 days. Prentice Hall, 1997.
[7] Lippman, B. C++ Essentials. Addison Wesley, 2002.
[8] Lippman, S. and Lajoie, J. C++ Primer. Prentice Hall, 2005.
[9] Motik, B. and ribar, J. Demistificirani C++. Element, Zagreb, 2. izdanje
edition, 2001.
[10] Press, W.H. Numerical Recipes in C++. Cambridge University Press,
1997.
[11] Schildt, H. C++: The Complete Reference. Osborne McGray-Hill, 1998.
[12] Stroustrup, B. The C++ Programming Language. Addison-Wesley, 3.
izdanje edition, 2000.
Osim navedene literature, koja je koritena u toku pisanja ovog udbenika,
itaoci se upuuju i na sljedee izvore, koji po svom sadraju ne samo da
zadovoljavaju potrebe kursa, nego daju i primjenu jezika C++ u oblasti numerike analize, to moe biti od velike koristi za studente odsjeka Matematika
i Informatika.
[1] http://www.alglib.net/
103
104
LITERATURA
Indeks
!, 30
++, vidi inkrement
, vidi dekrement
<<, vidi usmjerivai toka, 30
>>, vidi usmjerivai toka, 30
*, 27, 68
+, 27
-, 27
/, 27
/*...*/, vidi komentar
//, vidi komentar
<, 29
<=, 29
=, 32
==, 29
>, 29
>=, 29
%, 27
&, 30, 52, 67, 75
&&, 30
, vidi operator razdvajanja
, 30
[ ], 59, 69
, 30
|, 30
||, 30
char, 23
cin, 17
close, 85
const, 21
cout, 12
datoteke, 79
ciklus, 80
otvaranje, 80
za itanje, 87
za pisanje, 85
zatvaranje, 85
define, 22
definicija, 14
funkcije, 47
polja, 59
varijable, 14
deklaracija, 15
dekrement, 31
delete, 69
dereferenciranje, 68
Dev C++, 4
instalacija, 5
izvrna datoteka, 7
pokretanje, 9
prvi program, 7
do, 43
double, 20
eof, 90
escape-sekvence, 23
fail, 84
float, 20
for, 44
fstream, 79
funkcije, 47
argumenti, 51
definicija, 47
optereene, vidi optereivanje
parametri, 51
bitovni operatori, 30
bool, 22
brojevi
cijeli, 19
decimalni, 20
heksadecimalni, 20
ogranienja, 21
oktalni, 20
realni, 20
105
106
rekurzivne, vidi rekurzija
funkcijski pointeri, 73
globalno podruje, 53
hijerarhija operatora, 34
hrpa, 68
identifikatori, vidi imena
if, 40
ifstream, 80
imena, 18
include, 11
inicijalizacija, 14, 59
inkrement, 31
int, 19
ios, 82
iostream, 11
karakteri, 23
kljune rijei, 18
komentar, 17
kompajliranje, 13
konstante, 21
konstruktor, 81
konverzija, 27
eksplicitna, vidi static_cast
implicitna, 27
linker, 13
logiki operatori, 30
logiki tipovi, 22
lokalno podruje, 53
long, 19
main(), 12
memorija, 15
dinamika, 68
naredbe
jednostavna, 39
sloena, 39
new, 69
niz, vidi polja
ofstream, 80
open, 81
operator razdvajanja, 33
operatori, 27
aritmetiki, vidi aritmetiki operatori
bitovni, vidi bitovni operatori
Indeks
logiki, vidi logiki operatori
pridruivanje, vidi operatori pridruivanja
razdvajanje, vidi operator razdvajanja
relacijski, vidi relacijski operatori
uslovni, vidi uslovni operator
operatori pridruivanja, 32
overloading, vidi optereenje
petlja
do, vidi do
for, vidi for
while, vidi while
pointeri, 67
aritmetika, 71
funkcijski, vidi funkcijski pointeri
i polja, 70
pokazivai, vidi pointeri
polja, 59
multidimenzionalna, 63
preljev, 29
proceduralno programiranje, 2
reference, 75
rekurzija, 54
relacijski operatori, 29
short, 19
simbolike konstante, vidi konstante
sizeof, 34
static_cast, 28
std, 12
stog, 68
struktura programa, 11
switch, 41
ternatni, vidi uslovni operator
tijelo, vidi funkcije
tip, 19
brojni, vidi brojevi
karakteri, vidi karakteri
logiki, vidi logiki tipovi
typedef, 33
uslovni operatori, 32
usmjerivai toka, 16
varijabla, 14
while, 42
zaglavlje, vidi funkcije