You are on page 1of 252

Veleučilište u Rijeci

C++
mr. sc. Jasminka Tomljanović, viši predavač
Veleučilište u Rijeci

Popis literature za studij i polaganje ispita

J. Tomljanović: Programiranje
Julijan Šribar, Boris Motik: Demistificirani C++
T. Čukman, V. Bolt: C/C++, Procon, Zagreb, 1994.
Bruce Eckel: Thinking in C++, Second Edition, Prentice
Hall, 2000.
Borland C++ Vodić za profesionalne programere,
Bruneau Babet, Znak, Zagreb, 1995.

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 2


Veleučilište u Rijeci

Popis literature koja se preporučuje kao dopunska

R. Sedgewick: Algoritmus in C++, Addison -


Wesley, 1999.
N. Wirth: Algoritmus+Data Structures=Programs,
Prentice Hall, 1976.

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 3


Veleučilište u Rijeci

Mogućnosti C++ programskog jezika


Prvi programi pisani su na materinjem jeziku računala
(0 i 1)
Viši programski jezici pružali su programerima bolje
izražavanje logike programa i strukture podataka
Strukturalnim programiranjem najznačajniji
strukturalni element bila je podjela između koda i
podataka
Objektno orijentirano programiranje (OOP) predstavlja
evolucijski korak u razvoju softvera
OOP poboljšava učinkovitost programara
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 4
Veleučilište u Rijeci

OOP je analogno ljudskom mozgu


Ljudski mozak je divovski skup pojedinačnih moždanih
ćelija
U računalnoj terminologiji, svaka ćelija je objekt koji
ima osnovni materijal (podatke) i programirano
ponašanje (kôd)
Objekti su jedinice koje kombiniraju informacije o
stanju i ponašanju, a svaki objekt može slati poruke i
odgovarati na njih (kao i ćelije mozga)

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 5


Veleučilište u Rijeci

Porijeklo C++

C++ potječe i iz norveške vojske


Norvežani su napravili jezik Simula (jedan od prvih
jezika koji koristi klase)
Klasa je programska jedinica koja sadrži i podatke i
odgovarajuće funkcije → klasa je tip objekta
Simula je razvijena za odražavanje događaja tj.
model organizacije programa prema događajima
nije identičan modelu objektne orijentiranosti
objektna orijentiranost je prirodan način primjene
organizacije prema događajima
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 6
Veleučilište u Rijeci

Bjarne Stroustrup (1978. g. napisao simulator za


distribuirane računalne sustave kao dio svog doktorskog
rada na univerzitetu Cambridge) je utvrdio da je uporaba
klasa u jeziku Simula savršen način izražavanja
interakcija različitih računala u mreži, ali Simula nije bila
učinkovita sa sistemskim programiranjem velikih
razmjera na čemu je on radio
Trebale su mu karakteristike objektno orijentiranog
jezika Simula u kombinaciji sa snagom i učinkovitosti
jezika kao što je jezik C
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 7
Veleučilište u Rijeci

Stroustrup je napravio jezik C s dodatkom s


klasama
“C s klasama” prošao kroz manje promjene da
bi postao C++

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 8


Veleučilište u Rijeci

Prelazak s C-a na C++

C++ je “bolji C od samog sebe”


C++ je nadskup jezika C
Program preveden u C-u može se prevesti i u
C++-u
C++ ne nameće objektnu orijentiranost
Programer u C-u može programirati u C++
poštujući samo nekoliko pravila koja ovaj jezik
nameće
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 9
Veleučilište u Rijeci

Osnovna svojstva C++ programskim jezikom

Uključuju sva četiri svojstva objektno-orijentiranog


razvoja:
Enkapsulaciju
Skrivanje podataka
Nasljeđivanje
Polimorfizam

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 10


Veleučilište u Rijeci

Klase: organizacija prema objektima

Objekt je samo struktura podataka koja može


imati funkcije u vezi s tim podatcima
Klasa je tip objekta
Usporedba sa sklopovljem računala
čipovi
grafička
kartica

CPU

memorijski
kontroler
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 11
Veleučilište u Rijeci

Sklop računala ne odražava razliku između koda i podataka


Ploča se sastoji od velikog broja nezavisnih čipova povezanih
tako da šalju signale jedni drugima
U objektno orijentiranom pristupu čipovi su objekti
Terminologijom C++ jezika, marka i model čipa (npr.
Pentium) predstavljaju klasu, a pojedinačni čipovi su objekti
Kao i moždana ćelija, čip ima i kôd (ponašanje) i podatke
(informacije)
Osnovna jedinica objektne orijentiranosti nije ni kôd ni
podatci, već klasa objekta koja sadrži i kôd i podatke

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 12


Veleučilište u Rijeci

Objektna orijentacija
imitacija objekti
grafičke
kartice ove “iglice” predstavljaju
(kôd i podatci) javne interfejse objekata

imitacija
CPU-a
(kôd i podatci)
imitacija
memorije
(kôd i podatci)

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 13


Veleučilište u Rijeci

Enkapsulacija i skrivanje podataka


Pojam crne kutije
Čipovi međusobno komuniciraju samo preko
određenih iglica, a detalji pojedinog čipa nisu poznati
ostalima
Niti jedan čip se ne može miješati u rad drugog čipa
Proizvođači računala ne moraju ništa znati o
funkcioniranju unutar čipa jer je njima samo važno da
ulaz i izlaz čipa rade ono što proizvođač tvrdi da rade
Sustav radi jer svaki čip ima specifikaciju koja točno
određuje njegovo ponašanje
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 14
Veleučilište u Rijeci

Pronađemo li drugi čip s istom specifikacijom stari se


može zamijeniti, a sustav radi potpuno isto kao prije
Funkcioniranje unutar novog čipa može biti potpuno
drukčije, ali to korisnika nije briga
Dokle god se dva čipa u sustavu ponašaju isto, svaki
čip je zamjenljiv
Razvoj softvera ima veliku potrebu za zamjenljivim
dijelovima da bi se ispravile greške, poboljšali
učinkovitost ili dodali nove mogućnosti

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 15


Veleučilište u Rijeci

Kod C-a veze između različitih modula, interfejsi,


mogu se uspostaviti na razini datoteke
U C++ jeziku jedinica zaštite podataka nije više
ograničena samo na razini datoteke; ona može biti
proizvoljne veličine – kao klasa
U C++ jeziku možemo svaku funkciju ili podatak (član)
napraviti privatnim na razini klase i oni su nevidljivi
ostatku programa i ne može im se pristupiti
Javni članovi nekog objekta čine njegov interfejs (engl.
interface)
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 16
Veleučilište u Rijeci

Razdvajanje interfejsa i unutrašnjosti naziva se


enkapsulacija (eng. encapulation), ili, opisno rečeno
“skrivanje unutrašnjosti” ili skrivanje podataka (eng.
data hiding)

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 17


Veleučilište u Rijeci

Polimorfizam: decentralizirana kontrola

Analogija s hardverom:
možemo poslati opću naredbu print a da ne znamo
ni proizvođača niti model pisača, te ako svi poštuju
isti protokol za komunikaciju morala bi naredba
print pokrenuti ispisivanje
Hoćemo da naredba izvrši: ispisivanje dokumenta
Na naredbu će matrični pisač reagirati drukčije od
laserskog

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 18


Veleučilište u Rijeci

Korisnik se ne mora opterećivati time koju


inačicu komponente koristi – on će tražiti od
komponente uslugu, a na njoj je da to obavi na
odgovarajući način i to se zove polimorfizam
(eng. polimorphism)

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 19


Veleučilište u Rijeci

Iskoristivost i nesljeđivanje

Rješavajući neki problem možemo uzeti neku već


gotovu komponentu koja je blizu rješenja i samo
joj dodati nove mogućnosti
To se zove ponovna iskoristivost (eng. reusability)
i za novu komponentu kažemo da je naslijedila
(eng. inherit) svojstva komponente iz koje je
izgrađena

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 20


Veleučilište u Rijeci

Sadržaj

Tokovi upisa i ispisa


Dvodimenzionalna polja
Stringovi

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 21


Veleučilište u Rijeci

Tokovi upisa i ispisa


Program u C-u
#include<stdio.h>
int main(){
printf(“Program u C-u\n”);
return 0;}

Program u C++ header datoteka u kojoj se nalazi deklaracija objekta std::cout


namespace u kojem se nalaze svi objekti, klase i funkcije iz
#include<iostream> standardne biblioteke
int main(){ objekt klase iostream (tok ispisa) { tok upisa je std::cin }
std::cout<<"Program u C++-u\n"<<std::endl;;
return 0;}
operator dosega manipulator za prijelaz u novi red
endl; = “\n”
operator umetanja jer se njime
podatak umeće na izlazni tok { >> operator umetanja za tok upisa }
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 22
Veleučilište u Rijeci

#include<iostream.>

int main()
{
std::cout<<"Velicina tipa int je: \t\t"<<sizeof(int)<<" bajta. \n";
std::cout<<"Velicina tipa short int je: \t"<<sizeof(short)<<" bajta. \n";
std::cout<<"Velicina tipa long int je: \t"<<sizeof(long)<<" bajta. \n";
std::cout<<"Velicina tipa char je: \t\t"<<sizeof(char)<<" bajta. \n";
std::cout<<"Velicina tipa float je: \t"<<sizeof(float)<<" bajta. \n";
std::cout<<"Velicina tipa double je: \t"<<sizeof(double)<<" bajta. \n";

return 0;
}

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 23


Veleučilište u Rijeci

Velicina tipa int je: 4 bajta.


Velicina tipa short int je: 2 bajta.
Velicina tipa long int je: 4 bajta.
Velicina tipa char je: 1 bajta.
Velicina tipa float je: 4 bajta.
Velicina tipa double je: 8 bajta.
Press any key to continue

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 24


Veleučilište u Rijeci

Dvodimenzionalna polja

Dvodimenzionalna polja se u memoriji slično smještaju


kao jednodimenzionalna ali se radi lakšeg prikaza
predočuju u obliku dvodimenzionalne matrice s
određenim brojem redaka i stupaca
Npr.:
#define BR_RED 2
#define BR_STUP 3
float matrica [BR_RED][BR_STUP];
float matrica [BR_RED][BR_STUP]={{5.5,4.4,-8.2},{2.4,5.1,81.5}}
matrica[0][0]=5.5; matrica[0][1]=4.4; matrica[0][2]=-8.2
matrica 5.5 4.4 -8.2 matrica[1][0]=2.4; matrica[1][1]=5.1; matrica[1][2]=81.5
2.4 5.1 81.5

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 25


Veleučilište u Rijeci

Ispisivanje elemenata dvodimenzionalnog polja

Za ispis se koristi dvostruka petlja


for (i=0; i <BR_RED; i++){
for (j=0; j<BR_STUP; j++)
cout<<matrica[i][j]<<“\t”;
cout<<endl;
}

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 26


Veleučilište u Rijeci

Nizovi znakova
Operacije i funkcije sa znakovima se većinom nalaze u header datoteci
string.h
Znakovni nizovi su skupina znakova koji su raspoređeni unutar elemenata
nekog znakovnog polja
npr.: char kolegij[12+1]=“PROGRAMIRANJE”

P R O G R A M I R A N J E \0
0 1 2 3 4 5 6 7 8 9 10 11 12 13
tj.: kolegij[0]=“P”
kolegij[1]=“R”
kolegij[2]=“O”

kolegij[12]=“E”
kolegij[13]=“\0”
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 27
Veleučilište u Rijeci

Učitavanje nizova znakova

get() → učitava znak po znak


getline() → učitava string bez \0
read() → učitava iz datoteke do EOF

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 28


Veleučilište u Rijeci

Funkcije definirane nad stringovima


strcpy(s2,s1); →kopira s1 u s2
strncpy(s2,s1,n);→kopira najviše n znakova s1
u s2
strcat(s1,s2);→sadržaj niza s2 nadovezuje
na kraj niza s2
strncat(s1,s2,n);→n znakova niza s2 dodaje
na kraj niza s1
strlen(s);→vraća broj znakova do završnog
znaka ‘\0’
strcmp(s1,s2); →uspoređuje dva stringa
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 29
Veleučilište u Rijeci

Sadržaj

Tipovi podataka
Varijable
Konstante
Vanjski opisi i definicije
Eksplicitne konverzije podataka
Formatirani ispis

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 30


Veleučilište u Rijeci

Tipovi podataka
Osnovni:
cjelobrojni
realni
s pokretnom točkom (floating point)
znakovni
enumeracijski
prazan (void)
veličina izražena u broju byte-ova koje
zauzimaju u memoriji
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 31
Veleučilište u Rijeci

sizeof(float)<=sizeof(double)<=sizeof(long double)
sizeof(char)<=sizeof(short)<=sizeof(int)<=sizeof(long)
Granične vrijednosti:
za cijelobrojne vrijednosti: #include<limits.h>
INT_MIN,INT_MAX,LONG_MIN,LONG_MAX,...
za realne vrijednosti: #include<float.h>
FLT_MIN,FLT_MAX,...
Logički tip koristi vrijednosti true i false
Logička konstanta false=0,
bilo koja druga vrijednost=true
konverzija true u cjelobrojnu vrijednost=1
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 32
Veleučilište u Rijeci

Varijable
globalna: opisana izvan svih blokova i
definirana u cijelom programu
lokalna: definirana unutar bloka
globalne i lokalne varijable su vidljive u skladu
s definicijom sve dok ih ne zakloni u
umetnutom bloku lokalna varijabla istog imena
:: (scope resolution operator – dvostruka
dvotočka; operator za određivanje područja)
omogućuje uporabu globalne varijable kad je
“zaklanja” lokalna varijabla istog imena
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 33
Veleučilište u Rijeci
#include <iostream>
int a=0; //globalna varijabla
void main()
{
int a=1; //lokalna varijabla
{
int a=2; //lokalna varijabla
cout<<a<<endl; //ispisuje vrijednost lokalne varijabla a: 2
cout <<::a<<endl; //ispisuje vrijednost globalne varijabla a: 0
}
cout<<a<<endl; //ispisuje vrijednost lokalne varijabla a: 1
cout<<::a<<endl; //ispisuje vrijednost globalne varijabla a: 0
}12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 34
Veleučilište u Rijeci

2
0
1
0
Press any key to continue . . .

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 35


Veleučilište u Rijeci

Konstante

predprocesorskom naredbom #define


modifikatorom const
prednost uporabe modifikatora const je
kontrola slaganja tipova

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 36


Veleučilište u Rijeci

Vanjski opisi i definicije

Da bi varijabla ili konstanta bila vidljiva iz više


modula potrebno je:
Definirati ju u samo jednom modulu kao globalnu
U modulima u kojima treba biti vidljiva deklarirati ju kao
vanjsku s modifikatorom extern
Da bi varijabla ili konstanta bila vidljiva u cijeloj
datoteci u kojoj je opisana koristi se modifikator
static

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 37


Veleučilište u Rijeci

int a; //globalna varijabla


void main()
{
int b; //lokalna varijabla b
extern int x; //varijabla x je definirana na drugom mjestu
static int c; //lokalna statička varijabla c
a=1; //dodjeljivanje vrijednosti globalnoj varijabli a
int a; //lokalna varijabla a
a=2; //dodjeljivanje vrijednosti lokalnoj varijabli a
::a=3; //dodjeljivanje vrijednosti globalnoj varijabli a
}
int x=4; //definicija i inicijalizacija varijable x i ignorira modifikator extern

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 38


Veleučilište u Rijeci

Opis dviju globalnih varijabli pomoću datoteke


zaglavlja
//moj_header.h – vanjska deklaracija
exter int x;
extern double y;
...
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//dat1.cpp
#include ”moj_header.h”
int x;
...
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//dat2.cpp
#include ”moj_header.h”
double y;
...
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 39
Opis varijabli unutar bloka može biti bilo gdje
Veleučilište u Rijeci

ali prije prvog korištenja


#include<iostream>
using namespace std;
void main()
{
int brojac1;
for(brojac1=0; brojac1<3; brojac1++) //varijabla brojac1 vidljiva je do kraja main f-je
{
int i=0; //automatskoj varijabli i dodjeljuje se vrijednost 0 pri svakom prolazu kroz ciklus
static int j=0; //statička varijabla j inicijalizira se na 0 kompajliranjem a u svakom prolazu
//kroz ciklus imati će vrijednost dobivenu u prethodnom prolazu

for(int brojac2=0; brojac2<5; brojac2++)


cout<<"i= "<<i++<<" j= "<<j++<<endl;
}
cout<<endl<<"brojac1= "<<brojac1<<endl; //brojac1 živi i izvan for
// cout<<brojac2<<endl; //GREŠKA brojac2 se uništava izlaskom iz bloka u kom je definiran
}12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 40
Veleučilište u Rijeci
i= 0 j= 0
i= 1 j= 1
i= 2 j= 2
i= 3 j= 3
i= 4 j= 4
i= 0 j= 5
i= 1 j= 6
i= 2 j= 7
i= 3 j= 8
i= 4 j= 9
i= 0 j= 10
i= 1 j= 11
i= 2 j= 12
i= 3 j= 13
i= 4 j= 14

brojac1= 3
Press any key to continue . . .

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 41


Veleučilište u Rijeci

Eksplicitna konverzija podataka

Osim automatske konverzije tipova podataka,


može se izvršiti eksplicitna konverzija
(tip)<izraz> ... vrijedi i u C-u
tip(izraz) ... funkcijski oblik koji vrijedi samo u C++
npr.:
double x;
x=2.3+4.2; ............. // X=6.5 i u C-u
x=(int)2.3+(int)4.2; ........... // X=6.0 i u C-u
x=int(2.3)+int(4.2); ........... // X=6.0 samo u C++

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 42


Veleučilište u Rijeci

Formatirani ispis

uporabom f-ja klase ios


manipulatorima

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 43


Veleučilište u Rijeci

najčešće korištene f-je tzv. flegovi su:


left – lijevo poravnanje
right – desno poravnanje
dec – ispis cijelih brojeva u dekadskom obliku
oct - ispis cijelih brojeva u oktalnom obliku
hex - ispis cijelih brojeva u dekadskom obliku
scientific – ispis u formatu mantisaExponent
fixed – ispis u obliku s fiksnom točkom
skipws – preskakanje praznina pri učitavanju
unitbuf – pražnjenje izlaznog toka nakon svake
izlazne operacije
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 44
Veleučilište u Rijeci

with(len) – f-ja objekta cout kojom se zadaje širina


ispisa od len kolona i vrijedi samo za
prvi podatak izlaznog toka
precision(num) – definira se broj num decimala
fill(ch) – zadanim znakom ch zamjenjuju se
praznine ispred ili iza broja

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 45


Veleučilište u Rijeci

#include <iostream>
using namespace std;

void main()
{
cout.width(20); //širina ispisa
cout.precision(6); //broj decimala
cout.fill('*'); //popunjava znakom * nepopunjena mjesta
cout.setf(ios::fixed | ios::right); //ispis s fiksnim zarezom i
//desnim poravnanjem
cout<<123.456<<111.1111<<endl;
cout<<222.222<<endl;
}

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 46


Veleučilište u Rijeci

**********123.456000111.111100
222.222000
Press any key to continue . . .

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 47


Veleučilište u Rijeci

Manipulatori su operatori koji zajedno s


operatorom << modificiraju način na koji se
podaci prikazuju; uključiti header file iomanip.h
endl – prelazak u novi red
setw(n) – ispis podataka u polju širine n znakova s
desnim poravnanjem
– poslije ispisa podatka širina polja se
postavlja na podrazumijevajuću širinu
setprecision(n) – zadaje točnost ispisa realnih
brojeva
– pri ispisu s fiksnom točkom n zadaje se broj
decimala (flag fixed)
– ispis u obliku mantisaExponent zadaje se broj decimala
48
mantise (flag mr. sc. Jasminka Tomljanović, viši predavač
scientific)
Veleučilište u Rijeci

#include<iostream>
#include<iomanip>
using namespace std;

void main()
{
int c1=100, c2=960;
cout<<setw(10)<<"PROIZVOD"<<setw(12)<<"CIJENA"<<endl
<<setw(10)<<"Lopta"<<setw(12)<<c1<<endl
<<setw(10)<<"Tenisice"<<setw(12)<<c2<<endl;
}

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 49


Veleučilište u Rijeci

PROIZVOD CIJENA
Lopta 100
Tenisice 960
Press any key to continue . . .

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 50


Veleučilište u Rijeci

#include<iostream>
#include<iomanip>
using namespace std;

void main()
{
const double pi=3.141596;
cout<<"pi="<<setiosflags(ios::fixed)<<setw(15)<<setprecision(8)<<pi<<endl;
}

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 51


Veleučilište u Rijeci

pi= 3.14159600
Press any key to continue . . .

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 52


Veleučilište u Rijeci

Za promjenu baze brojevnog sustava mogu se


koristiti slijedeći manipulatori:
dec – baza je 10
oct – baza je 8
hex – baza je 16

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 53


Veleučilište u Rijeci

#include<iostream>
using namespace std;

void main()
{
int i=11, j=17, k=25;
cout<<i<<"\t"<<j<<"\t"<<k<<endl;
cout<<oct<<i<<"\t"<<j<<"\t"<<k<<endl;
cout<<hex<<i<<"\t"<<j<<"\t"<<k<<endl;
}

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 54


Veleučilište u Rijeci

11 17 25
13 21 31
b 11 19
Press any key to continue . . .

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 55


Veleučilište u Rijeci

#include<iostream>
using namespace std;

void main()
{
int i, j, k, m;
cout<<"Upisite 4 cijela broja: ";
cin>>i>>oct>>j>>hex>>k>>dec>>m;
cout<<i<<"\t"<<j<<"\t"<<k<<"\t"<<m<<endl;
}

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 56


Veleučilište u Rijeci

Upisite 4 cijela broja: 10 10 10 10


10 8 16 10
Press any key to continue . . .

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 57


Veleučilište u Rijeci

Još neki standardni ulazno-izlazni manipulatori:


setfill(int) – znak za popunjavanje praznina
flush – prazni izlazni tok
ws – ignorira praznine na ulaznom toku

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 58


Veleučilište u Rijeci

Sadržaj

Funkcije

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 59


Funkcije
program

Main () Func1

{ Iskaz; _________ Func3


_________
func1(); _________
Func2
_________
_________ _________
Iskaz; return Iskaz _________
Func3() _________
func2(); _________ return

Iskaz; Func4 _________


return
Func 4
func4();
_________
} Iskaz; _________
_________
_________
return

mr. sc. Jasminka Tomljanović, viši predavač


Funkcije
su potprogrami u C i C++
potprogrami koji ne vraćaju vrijednost umjesto tipa imaju
oznaku void

opći oblik funkcije:

<povratni tip ili void> ime_funkcije (<tip> par1, <tip> par2, ...
,<tip> par N)
{
.
<blok instrukcija>
.
return <povratna vrijednost>; // izostavlja se ako je funkcija
tipa void
}

mr. sc. Jasminka Tomljanović, viši predavač 61


Funkcije
Razlikujemo formalne argumente (navode se u zaglavlju funkcije) i
stvarne argumente (navode se kod poziva funkcije).
Prilikom poziva funkcije formalni parametri poprime vrijednosti
odgovarajućih stvarnih parametara.
Formalni argumenti predstavljaju lokalne podatke funkcije i alociraju se
na stogu, kao i lokalne varijable
Povratak iz funkcije je pomoću naredbe return, kojom se ujedno vraća i
vrijednost funkcije:
funkcija u C++ može imati više izlaza (time se narušava
pravilo pravilnog programa!)
funkcija koja ne vraća vrijednost (umjesto tipa ima oznaku
void):
ne sadrži povratnu vrijednost iza return ili
uopće ne sadrži return (povratak je na kraju funkcije)

mr. sc. Jasminka Tomljanović, viši predavač 62


TIP funkcije (i povratne formalni argument
vrijednosti) (lokalni podatak; alocira se na stogu)

float Convert(float TempFar)


{
float TempCel;
TempCel=((TempFar - 32)*5)/9;
return TempCel;
}
lokalne varijable funkcije main
int main(){ (alociraju se na stogu)
float TempFar;
stvarni argument
float TempCel;
cout<<"\nMolim Vas unesite temperaturu u Farenhajtima: ";
cin>>TempFar;
TempCel=Convert(TempFar);
cout<<"\nEvo temperature u Celzijusima: ";
cout<<TempCel<<endl;
return 0; }

mr. sc. Jasminka Tomljanović, viši predavač


#include <iostream>

float Convert(float);

int main(){
float TempFar;
float TempCel;
cout<<"\nMolim Vas unesite temperaturu u Farenhajtima: ";
cin>>TempFar;
TempCel=Convert(TempFar);
cout<<"\nEvo temperature u Celzijusima: ";
cout<<TempCel<<endl;
return 0; }
float Convert(float TempFar)
{
float TempCel;
TempCel=((TempFar - 32)*5)/9;
return TempCel;
mr. sc. Jasminka Tomljanović, viši predavač
}
Lokalne i globalne varijable
Lokalne varijable su one varijable koje su
definirane samo u funkciji i izvan nje nisu
definirane

Globalne varijable su one koje su definirane


izvan svake funkcije i raspoložive su svim
funkcijama u programu uključujući i main ()

mr. sc. Jasminka Tomljanović, viši predavač


#include <iostream>
void myFunction(); // prototip

int x=5,y=7; // globalne varijable


int main()
{
cout<<"x iz main: "<<x<<"\n";
cout<<"y iz main: "<<y<<"\n\n";
myFunction();
cout<<"Povratak iz myFunction!\n\n";
cout<<"x iz main: "<<x<<"\n";
cout<<"y iz main: "<<y<<"\n";
return 0;
}
void myFunction()
{
int y=10;
cout<<"x iz myfunction: "<<x<<"\n";
cout<<"y iz myFunction: "<<y<<"\n";
}
Veleučilište u Rijeci 12.1.2020.

x iz main: 5
y iz main: 7

x iz myfunction: 5
y iz myFunction: 10
Povratak iz myFunction!

x iz main: 5
y iz main: 7
Press any key to continue

67
Argumenti funkcije

Svaki važeći izraz može biti argument funkcije,


uključujući konstante, matematičke i logičke
izraze i druge funkcije koje vraćaju vrijednost
Ne moraju svi argumenti funkcije biti istog tipa

mr. sc. Jasminka Tomljanović, viši predavač


Parametri su lokalne varijable
Argumenti koji se predaju funkciji su za nju
lokalni
Promjene izvršene na argumentima ne utječu
na vrijednosti u funkciji koju pozivamo
To znači da se u funkciji napravi lokalna kopija
svakog argumenta i ta se kopija tretira kao i
sve lokalne varijable

mr. sc. Jasminka Tomljanović, viši predavač


#include <iostream>
void zamjena(int x, int y);
int main()
{
int x=5, y=10;
cout<<"\nMain. Prije zamjene, x je: "<<x<<" y: "<<y<<"\n";
zamjena(x,y);
cout<<"Main. Poslije zamjene, x je: "<<x<<" y: "<<y<<endl;
return 0;
}
void zamjena(int x, int y)
{
int temp;
cout<<"\nSwap. Prije zamjene, x: "<<x<<" y: "<<y<<endl;
temp=x;
x=y;
y=temp;
cout<<"\nSwap. Poslije zamjene, x: "<<x<<" y: "<<y<<endl;
}
Main. Prije zamjene, x je: 5 y: 10

Swap. Prije zamjene, x: 5 y: 10

Swap. Poslije zamjene, x: 10 y: 5


Main. Poslije zamjene, x je: 5 y: 10
Press any key to continue
Povratne vrijednosti

Funkcija vraća vrijednost ili je void


Npr.:
return 5;
return (x>5);
return (myFunction());

mr. sc. Jasminka Tomljanović, viši predavač


//demonstracija višestrukih return iskaza
#include <iostream>
int Doubler(int AmountToDouble);
int main(){
int result=0; int input;
cout<<"\nUnesi broj izmedju 0 i 10.000 za udvostrucenje: ";
cin>>input;
cout<<"\nPrije pozivanja udvostucivaca... ";
cout<<"\nulaz: "<<input<<" udvostrucen: "<<result<<"\n";
result=Doubler(input);
cout<<"\nPovratak iz udvostrucivaca...\n";
cout<<"\nulaz: "<<input<<" udvostrucen: "<<result<<endl;
return 0;}
int Doubler(int original){
if (original<=10000)
return original*2;
else
return -1;
cout<<"Ovdje ne mozete!"<<endl;}
Unesi broj izmedju 0 i 10.000 za udvostrucenje: 9000

Prije pozivanja udvostucivaca...


ulaz: 9000 udvostrucen: 0

Povratak iz udvostrucivaca...

ulaz: 9000 udvostrucen: 18000


Press any key to continue
Unesi broj izmedju 0 i 10.000 za udvostrucenje: 11000

Prije pozivanja udvostucivaca...


ulaz: 11000 udvostrucen: 0

Povratak iz udvostrucivaca...

ulaz: 11000 udvostrucen: -1


Press any key to continue
Podrazumijevani parametri
Ako prototip funkcije deklarira podrazumijevanu
vrijednost za parametar ona se koristi ako nijedna nije
osigurana
Nekim, ili svim parametrima funkcije se mogu
dodijeliti podrazumijevane vrijednosti uz uvjet ako
neki od parametara nema podrazumijevanu vrijednost
tada nijedan prethodni parametar ne može imati
podrazumijevanu vrijednost

mr. sc. Jasminka Tomljanović, viši predavač


//demonstracija uporabe podrazumijevanih vrijednosti
#include <iostream>

int AreaCube(int length,int with=25,int height=1);


int main(){
int lenght=100;
int with=50;
int height=2;
int area;
area=AreaCube(lenght,with,height);
cout<<"\nPrva povrsina iznosi: "<<area<<"\n";
area=AreaCube(lenght,with);
cout<<"\nU drugom pozivu povrsina iznosi: "<<area<<"\n";
area=AreaCube(lenght);
cout<<"\nU trecem pozivu povrsina iznosi: "<<area<<"\n";
return 0;}
AreaCube(int lenght, int with, int height)
{
return (lenght*with*height);
}
Prva povrsina iznosi: 10000

U drugom pozivu povrsina iznosi: 5000

U trecem pozivu povrsina iznosi: 2500


Press any key to continue
Inline funkcije
Kad se poziva definira se funkcija kompajler stvara
samo jedan skup instrukcija u memoriji i kad se
pozove izvršenje programa “skače” na te instrukcije i
po povratku iz funkcije vraća se na slijedeću liniju iza
poziva funkcije. Ako se funkcija poziva više puta
program skače na isti skup instrukcija toliko puta
koliko se poziva
Postoji osobina koja je iznad “skakanja” na funkcije i
iz funkcija a to je inline funkcija koja se kopira izravno
na mjesto poziva funkcije. To je dobro primjenjivati na
male funkcije da ne povećamo kod i zato ako smo u
nedoumici bolje je izostaviti inline funkciju
mr. sc. Jasminka Tomljanović, viši predavač
//demonstracija inline funkcije
#include<iostream>
inline int Double(int a);
int main()
{
int a;
cout<<"Upisi broj: ";
cin>>a;
cout<<"\n";
a=Double(a);
cout<<"Rezultat je: "<<a<<endl;
a=Double(a);
cout<<"Rezultat je: "<<a<<endl;
a=Double(a);
cout<<"Rezultat je: "<<a<<endl;
return 0;
}

int Double(int a)
{
return 2*a;
Upisi broj: 8

Rezultat je: 16
Rezultat je: 32
Rezultat je: 64
Press any key to continue
Veleučilište u Rijeci

Referencni parametri
Parametri se predaju f-ji:
po referenci (by reference) – radi neposredno s
varijablom kao
stvarnim parametrom
– predaje se adresa
stvarnog parametra (&)
po vrijednosti (by value) – radi s kopijom
vrijednosti varijable
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 82
Referenca u listi argumenata funkcije
takvi argumenti se ne alociraju se na stogu nego dijele memorijski
prostor sa stvarnim argumentom
stvarni argumenti po povratku iz funkcije poprime vrijednosti
odgovarajućih formalnih argumenata

Primjer: reference

void zamjena (int &prvi, int &drugi) {


int pom = prvi;
prvi = drugi;
drugi = pom;
}
Ne radi se o prijenosu vrijednosti,
void main (){
nego su
int a=5;
formalni argumenti reference stvarnih!
int b=10;
zamjena (a,b);
cout << “a = “ << a << endl; // 10
cout << “b = “ << b << endl; // 5
}
mr. sc. Jasminka Tomljanović, viši predavač 83
Statički članovi
označavaju se pomoću ključne riječi static.
statička lokalna varijabla ima doseg lokalne, a trajanje globalne varijable
ne alociraju se na stogu
vrijednost statičke varijable ostaje sačuvana do ponovnog poziva funkcije

Primjer:
void funkcija_stat () { Inicijalizacija statičke varijable vrijedi
int a=777; samo za prvi poziv funkcije!
static int b=777;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
a = 7; b = 70;};
int main () {
cout << "1. poziv funkcije :" << endl;
funkcija_stat();
cout << "2. poziv funkcije :" << endl;
funkcija_stat();
return 1;}
mr. sc. Jasminka Tomljanović, viši predavač 84
Rekurzije
je svojstvo potprograma da može pozivati sam sebe.
Rekurzija može biti direktna ili indirektna
Direktna je kada funkcija poziva drugu funkciju
Indirektna je kada funkcija poziva drugu funkciju koja
poziva prvu funkciju
Problemi u kojem se postupak primijenjen nad
podacima primjenjuje i s rezultatom, te se to ponavlja
do prekida definiranog postavljenim uvjetom rješava
se rekurzijom
Zaključujemo problem rješavamo rekurzijom kada je u
samoj definiciji problema rekurzija
mr. sc. Jasminka Tomljanović, viši predavač
Kada funkcija poziva samu sebe izvršava se njena
nova kopija. Lokalne varijable u drugoj kopiji su
nezavisne od lokalnih varijabli u prvoj. Ne utječu jedne
na druge više nego lokalne varijable u main() na
lokalne varijable u bilo kojoj funkciji koju ona poziva.

mr. sc. Jasminka Tomljanović, viši predavač


Primjer (računanje n!) :

int fakto (int n){


if (n ==1) //sidreni uvjet
return 1;
else
return n*fakto (n – 1); //pojednostavljenje
}
void main () {
cout << fakto (5) << endl;
}

mr. sc. Jasminka Tomljanović, viši predavač 87


int fakto (int n){
if (n ==1) // sidreni uvjet rekurzivni poziv funkcije
return 1;
else
return n*fakto (n – 1); //pojednostavljenje
}
void main () { aritmetički izraz poprima vrijednost
cout << fakto (5) << endl; tek nakon što se izvrši
} funkcija fakto

Za izvršenje rekurzivne funkcije potrebno je osigurati:


 sidreni izraz : 1! = 1
 rekurzivnu formulu ili postupak : n! = n * (n – 1)!

Sidreni izraz (uvjet prekida) omogućuje izlazak iz rekurzivne funkcije


(tj. spriječava beskonačno pozivanje funkcije), a rekurzivna formula
ili postupak trebaju pojednostaviti zadatak, odnosno, približiti ga
sidrenom izrazu.
mr. sc. Jasminka Tomljanović, viši predavač 88
Kako funkcionira rekurzija?

glavni fakto fakto fakto fakto fakto


program n=5 n=4 n=3 n=2 n=1

PUSH A,5 PUSH B,4 PUSH B,3 PUSH B,2 PUSH B,1
A B B B B

RETURN 120 RETURN 24 RETURN 6 RETURN 2 RETURN 1

Rekurzivnim pozivom poziva se ista funkcija (proces),


ali ne i isti skup lokalnih podataka jer se za svaki poziv funkcije ti podaci
alociraju na stogu (stvara se novi stog međurezultata).
Po povratku iz rekurzivne funkcije restauriraju se sa stoga odgovarajući
lokalni podaci.
mr. sc. Jasminka Tomljanović, viši predavač 89
Preopterećenje funkcije
predstavlja korištenje istog imena za različite implementacije funkcije
funkcije istog naziva moraju se međusobno razlikovati po potpisu
(=broju i tipu argumenata)

void ispis (int y){


cout << "int:" << y << endl;
};
void ispis (char y[]){
cout << "char[]:" << y << endl; int main(){
}; ispis (10);
void ispis (float y){ ispis ("znakovni niz");
cout << "float:" << y << endl; float x=2.73;
}; ispis (x);
void ispis (double y){ ispis (5.61);
cout << "double:" << y << endl; return 1;
}; }//main

mr. sc. Jasminka Tomljanović, viši predavač 90


Pokazivač na funkciju
naziv funkcije predstavlja pokazivač na funkciju

#include <iostream>
using namespace std;
float zbroj(float a, float b){
return a+b;
};
int main(){
cout << zbroj(3,5) << endl;
cout << (int)zbroj << endl; // adresa funkcije
return 1;
}

Operator dodjele tipa; u suprotnom se


adresa evaluira kao 1 (logička istina)!

mr. sc. Jasminka Tomljanović, viši predavač 91


Upotreba pokazivača na funkciju
double kvadrat(double x){
return x*x;
};
double kub(double x){
return x*x*x;
};
double izracun(double(*funkcija)(double), double x){
cout << "x = " << x << endl;
return funkcija(x);
};
int main(){
cout << izracun (kvadrat, 5) << endl;
cout << izracun (kub, 3) << endl;
cout << izracun (sin, 0.5) << endl;
cout << izracun (cos, 0.5) << endl;
return 1;
}
mr. sc. Jasminka Tomljanović, viši predavač 92
double kvadrat(double x){
return x*x;
}; prvi argument je adresa funkcije
double kub(double x){ tipa double s argumentom tipa double
return x*x*x;
};
double izracun(double(*funkcija)(double), double x){
cout << "x = " << x << endl;
return funkcija(x);
};
int main(){ poziv zadane funkcije Oprez s tipovima
cout << izracun (kvadrat, 7) << endl; argumenata; nema
cout << izracun (kub, 5) << endl; automatske konverzije
cout << izracun (sin, 0.5) << endl; tipa float u double!
cout << izracun (cos, 0.5) << endl;
return 1;
adresa funkcije
mr. sc. Jasminka Tomljanović, viši predavač 93
}
Veleučilište u Rijeci

Sadržaj

Pokazivači

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 94


Veleučilište u Rijeci

Pokazivači

Predstavljaju memorijske adrese


Na tim adresama mogu se nalaziti podaci
različitih tipova: varijable, funkcije ili objekti
Podatke kojima pristupamo preko pokazivača
nazivamo dinamičim podacima zato jer njihova
lokacija u memoriji nije zadana prilikom
prevođenja programa nego tek tijekom
izvršavanja programa

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 95


Veleučilište u Rijeci

Uporaba pokazivača doprinosi fleksibilnosti


programiranja tj.: pokazivačka varijabla koja
sadrži adresu jednog dinamičkog podatka
može se “preusmjeriti” tako da pokazuje na
neki drugi dinamički podatak istog tipa

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 96


Veleučilište u Rijeci

Osnove pokazivača

Statička varijabla predstavlja imenovani


memorijski prostor koji sadrži vrijednost
npr.: int x;
x=7;
time određujemo da se tijekom izvođenja
programa rezervira memorijski prostor veličine
4 byta kojemu ćemo pristupati preko
identifikatora x

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 97


Veleučilište u Rijeci

Tijekom izvođenja programa možemo prostoru


mijenjati vrijednost ali ne možemo mu mijenjati
memorijsku lokaciju
Za razliku od statičke varijable, pokazivač je
varijabla koja pokazuje na drugu varijablu
To znači da ona sadrži memorijsku adresu na
kojoj se nalazi vrijednost
Taj memorijski sadržaj, na koji pokazuje
pokazivač, predstavlja dinamičku varijablu
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 98
Veleučilište u Rijeci

Pokazivač označavamo znakom *, odnosno:


int *p;
kažemo da je varijabla p pokazivač na dinamičku
varijablu tipa int
sada pokazvačkoj varijabli treba dodijeliti
memorijski prostor za dinamičku varijablu:
p=new int;
time osiguravamo da neka nova new naredba ne
zauzme isti memorijski prostor
dinamičkoj varijabli možemo pridružiti vrijednost:
*p=777;
12.1.2020. 99
mr. sc. Jasminka Tomljanović, viši predavač
Veleučilište u Rijeci

Pridruživanjavrijednosti dinamičkim varijablama


i pridruživanje vrijednosti pokazivačima
npr.:
int *x=new int; *y=new int;
*x=55;
*y=*x; //pridruživanje vrijednosti dinamičkoj varijabli
y=x; //pridruživanje vrijednosti pokazivaču tj. sada
// oba pokazivača sadrže adresu iste dinamičke
//varijable
*y=99; //ova naredba dovodi do toga
cout<<x; //da i *x ima vrijednost 99
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 100
Veleučilište u Rijeci

Oslobađanje memorijskog prostora

Kada dinamička varijabla nije više potrebna


poželjno je osloboditi (dealocirati) memorijski
prostor koji zauzima:
delete p;
Time se memorijski prostor dinamičke varijable
oslobađa za neku drugu namjenu, ali pokazivač
zadržava vrijednost memorijske lokacije što je
potencijalno opasno

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 101


Veleučilište u Rijeci

Poželjno je takvom, trenutno slobodnom


pokazivaču pridružiti vrijednost NULL (nulta
adresa označava neupotrebljeni pokazivač)
p=NULL;
ili
p=0;
Izrazi su ekvivalentni jer je NULL definiran kao
konstanta s vrijednošću 0
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 102
Veleučilište u Rijeci

Korištenje adresnog operatora (&)


Dok pokazivači sadrže adrese dinamičkih
podataka, pomoću adresnog operatora možemo
dohvatiti adresu statičkog podatka
Npr.: int *pok;
int x=22;
pok=&x; //usmjeravamo pokazivač na statičku varijablu x
cout<<*pok<<“\n”; //ispisuje se 22
Izraz &x ima značenje “memorijska adresa
statičke varijable x” pa se može pridružiti
pokazivaču pok
12.1.2020. 103
mr. sc. Jasminka Tomljanović, viši predavač
Veleučilište u Rijeci

Reference

Označavaju se adresnim operatorom &, a služe


kao drugo ime za neki memorijski prostor
Npr.:
int x=33;
int &y=x;
cout<<y<<“\n”; //ispisuje se 33
Identifikator y je u stvari drugo ime za varijablu
x, tj. predstavlja isti memorijski prostor
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 104
Veleučilište u Rijeci

Sadržaj

Dvodimenzionalni dinamički niz

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 105


Veleučilište u Rijeci

Pokazivači na pokazivače

Dinamičko polje proizvoljnog broja redaka i


stupaca

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 106


Veleučilište u Rijeci

Dvodimenzionalno dinamičko polje može imati


varijabilan broj redaka, ali broj stupaca mora
biti poznat.
Dvodimenzionalno dinamičko polje dimenzija
n*m, tj. polje u kojem unaprijed ništa nije
poznato.

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 107


Veleučilište u Rijeci

Prvo

Treba deklarirati pokazivač na jednodimenzionalno


polje pokazivača.
int ** Polje;
Svaki član polja pokazivača će pokazivati na
početak jednog retka dinamičkog polja.
Polje=new int*[redaka];

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 108


Veleučilište u Rijeci

Drugo

Treba deklarirati redak dimenzije [stupaca+1]


pri čemu prvi stupac sadržava informaciju o
stvarnom broju članova s podacima.
Polje[i]=new int[stupac+1];

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 109


Veleučilište u Rijeci

**polje
0 1 2 br_el_retka-1
0 polje[0] polje[0][0]
=stupac ....
polje[0][stupac]

polje
1 polje[1]
polje[1][0] polje[1][stupac]
=stupac ...
2 polje[2]

...
 0 1 2 br_el_retka-1
br_redaka-1 polje[n-1] polje[n-1][0]= polje[n-1[stupac]
stupac ...

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 110


Veleučilište u Rijeci

Zadatak

Napišite program u kojem se stvara


dvodimenzionalno dinamičko polje ZADATAK u
koji se za učitani broj studenata unose samo
ocjene točno riješenih zadataka iz
Programiranja. Izračunajte za svakog studenta
srednju ocjenu i upišite je kao zadnji podatak u
njegovom redu. Ispišite polje ZADATAK.

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 111


Veleučilište u Rijeci

#include<iostream>
using namespace std;

void stvori(float **ZADATAK,int n)


{
int m;
for(int i=0;i<n;i++)
{
cout<<"Broj zatadaka "<<i+1<<". studenta:";
cin>>m;
ZADATAK[i]=new float[m+2]; //dodjeljivanje memorijskog prostora el. redaka polja
ZADATAK[i][0]=float(m);//upisivanje broja točno riješenih zadataka za i-tog
//studenta na 0-toj poziciji u i-tom retku
}
}

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 112


Veleučilište u Rijeci

void ucitaj(float **ZADATAK,int n)


{
int i,j;
for(i=0;i<n;i++)
{
float suma=0;
for(j=1;j<=ZADATAK[i][0];j++) {
do
{
cout<<i+1<<". student "<<j<<". ocjena:";
cin>>ZADATAK[i][j];

}
while(ZADATAK[i][j]<2||ZADATAK[i][j]>5);
suma+=ZADATAK[i][j];
}
ZADATAK[i][j]=suma/ZADATAK[i][0];
}
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 113
}
Veleučilište u Rijeci

void ispis(float **ZADATAK,int n)


{
for(int i=0;i<n;i++)
{
for(int j=0;j<=ZADATAK[i][0]+1;j++)
cout<<ZADATAK[i][j]<<" ";
cout<<endl;
}
}

void dealokacija(float **ZADATAK,int n)


{
for(int i=0;i<n;i++)
delete [] ZADATAK[i]; //briše retke polja
delete [] ZADATAK; // briše polje pokazivača na retke polja
ZADATAK=NULL; // preusmjerava pokazivač na polje pokazivača na ništa
}
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 114
Veleučilište u Rijeci

void main()
{
int n;
cout<<"Unesite broj studenata:";
cin>>n;
float **ZADATAK=new float*[n]; //stvara se niz od n pokazivača na tip float
cout<<endl;
stvori(ZADATAK,n);
cout<<endl;
ucitaj(ZADATAK,n);
cout<<endl;
ispis(ZADATAK,n);
cout<<endl;
dealokacija(ZADATAK,n);
}

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 115


Unesite broj studenata:3 Veleučilište u Rijeci

Broj zatadaka 1. studenta:4


Broj zatadaka 2. studenta:5
Broj zatadaka 3. studenta:3

1. student 1. ocjena:3
1. student 2. ocjena:4
1. student 3. ocjena:5
1. student 4. ocjena:2
2. student 1. ocjena:3
2. student 2. ocjena:3
2. student 3. ocjena:3
2. student 4. ocjena:4
2. student 5. ocjena:4
3. student 1. ocjena:5
3. student 2. ocjena:2
3. student 3. ocjena:3

4 3 4 5 2 3.5
5 3 3 3 4 4 3.4
3 5 2 3 3.33333
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 116
Press any key to continue . . .
Veleučilište u Rijeci

Sadržaj

Zapisi (strukture)

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 117


Veleučilište u Rijeci

Zapis

Struktura; slog; record


Složeni tip podatka koji objedinjuje različite
tipove podataka
Svaka komponenta zapisa ima svoje ime preko
koje joj se pristupa
Ime komponente:
ime_zapisa.ime_komponente

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 118


Veleučilište u Rijeci

Deklaracija zapisa
struct identifikator {
deklaracija komponente_1;
deklaracija komponente_2;

Deklaracija komponente_N;
} identifikator;

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 119


Veleučilište u Rijeci

Primjer

struct student {
long int mat_br;
char prez_ime[35];
char adresa[40];
double pros_ocj;
}stud;

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 120


Veleučilište u Rijeci

Komponente zapisa

stud.mat_br;
stud.prez_ime;
stud.adresa;
stud.pros_ocj;

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 121


Veleučilište u Rijeci

Primjer

Napišite program u kojem je definiran zapis čije


su komponente: mat_br, prez_ime, adresa i
pros_ocj koja se računa nakon učitanih ocjena.
Ispišite komponente zapisa.

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 122


Veleučilište u Rijeci

#include <iostream>
using namespace std;

int main () {
int O=1, B=0, S=0;
struct student {
int mat_br;
char prez_ime[35];
char adresa[40];
double pros_ocj;
} stud;
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 123
Veleučilište u Rijeci

cout << "Maticni broj studenta: ";


cin >> stud.mat_br;
cout << "Prezime i ime: ";
cin.ignore();
cin.getline(stud.prez_ime,sizeof(stud.prez_ime));
cout << "Adresa: ";
cin.getline(stud.adresa,sizeof(stud.adresa));
while (O>0) {
cout << "Ocjena: ";
cin >> O;
B++; S+=O;
}
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 124
Veleučilište u Rijeci

stud.pros_ocj=(float)S/B;
cout << "Student: " << stud.mat_br << " " <<
stud.prez_ime << endl;
cout<<" Adresa: "<<stud.adresa<<endl;
cout<<" Prosjek: " << stud.pros_ocj << endl;
system("pause");
return 0;
}

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 125


Maticni broj studenta: 1234 Veleučilište u Rijeci
Prezime i ime: Matic Mate
Adresa: A. Starcevica 3, 51000 Rijeka
Ocjena: 3
Ocjena: 4
Ocjena: 5
Ocjena: 2
Ocjena: 3
Ocjena: 4
Ocjena: 4
Ocjena: 2
Ocjena: 5
Ocjena: 3
Ocjena: 0
Student: 1234 Matic Mate
Adresa: A. Starcevica 3, 51000 Rijeka
Prosjek: 3.18182
Press any key to continue . mr.
. . sc. Jasminka Tomljanović, viši predavač
126
12.1.2020.
Maticni broj studenta: 123Veleučilište u Rijeci
Prezime i ime: Ivic Ivo
Adresa: A. Kovacica 4, 51 000 Rijeka
Ocjena: 4
Ocjena: 3
Ocjena: 2
Ocjena: 2
Ocjena: 4
Ocjena: 0
Student: 123 Ivic Ivo
Adresa: A. Kovacica 4, 51 000 Rijeka
Prosjek: 2.5
Press any key to continue
12.1.2020. . .Tomljanović,
mr. sc. Jasminka . viši predavač 127
Veleučilište u Rijeci

Neimenovani zapis

je onaj zapis kojem se odmah pridružuje


varijabla i koristi se samo tamo gdje je
deklariran i nije mu potrebno dodijeliti ime
Npr.: struct {
long int mat_br;
char prez_ime[35];
char adresa[40];
double pros_ocj;
}stud;
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 128
Veleučilište u Rijeci

struct student{
long int mat_br;
char prez_ime[35];
char adresa[40];
double pros_ocj;
};
int main(){
student stud;

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 129
Veleučilište u Rijeci

Sadržaj

Vezane liste

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 130


Veleučilište u Rijeci

Vezana lista
Vezana lista je oblik dinamičkog čuvanja
podataka čiji broj elemenata nije unaprijed
poznat. Predstavlja skup elemenata povezanih
pokazivačima u:
jednom smjeru => jednostavna vezana lista
u dva smjera => dvostruko vezana lista
Temelji se na uporabi struktura (zapisa,
slogova) i pokazivača tj. osnovni element liste
je struktura koja sadrži pokazivač na slijedeći
element.
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 131
Veleučilište u Rijeci

Jednostavna vezana lista


može se deklarirati na slijedeći način:
struct element_liste Komponenta strukture istog tipa
kao i struktura. Dozvoljeno je jer
{ se radi o pokazivaču!
char podatak[10];
struct element_liste *slijedeci;
};
struct element_liste *pocetak_liste;
na početak liste pokazuje pokazivač pocetak_liste
zadnji element liste u komponenti za vezu
(slijedeci) sadrži vrijednost NULL. Ako je lista
prazna pocetak_liste
12.1.2020. mr. sc. Jasminkatakođer ima vrijednost NULL.
Tomljanović, viši predavač 132
Veleučilište u Rijeci

(glava_liste)
pocetak_liste
podatak podatak podatak
slijedeci slijedeci
... NULL

 Podatkovni sadržaj glave liste nije bitan jer je glava samo pomoćni element
liste!

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 133


Veleučilište u Rijeci

Postupak stvaranja jednostvne vezane liste

najprije ćemo inicijalizirati praznu listu


slijedećom naredbom:
pocetak_liste pocetak_liste=NULL;

pocetak_liste
NULL

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 134


Veleučilište u Rijeci

za stvaranje prvog dinamičkog objekta (prvog


elementa liste) moramo mu dodijeliti
memorijski prostor naredbom:
pocetak_liste
NULL

novi=new element_liste;
novi *novi
?
?

gdje je novi pokazivač na struct element_liste


12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 135
Veleučilište u Rijeci

Dinamičkom objektu (elementu liste) novi


mogu se dodijeliti vrijednosti:
strcpy(novi->podatak,“Prvi“,10);
novi->slijedeci=pocetak_liste; // odnosno NULL
što prikazuje slijedeća slika:
pocetak_liste
NULL

novi *novi
Prvi
NULL
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 136
Veleučilište u Rijeci

da bi varijabla pocetak_liste pokazivala na


početak tj. na prvi element liste treba joj
pridružiti vrijednost varijable novi naredbom:
pocetak_liste=novi;
dobili smo listu od jednog elementa
pocetak_liste

novi *novi
Prvi
NULL

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 137


Veleučilište u Rijeci

ako želimo ponovo dodati novi element u listu


moramo opet operatorom new rezervirati
memorijski prostor

novi= new element_liste;


novi *novi
?
?

pocetak_liste
Prvi
NULL

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 138


Veleučilište u Rijeci

i nakon izvršenja slijedećih naredbi:


strcpy(novi->podatak,“Drugi“,10);
novi->slijedeci=pocetak_liste;

podatkovni dio drugog elementa liste je


definiran

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 139


Veleučilište u Rijeci

sada slika izgleda ovako:


novi *novi
Drugi

pocetak_liste
Prvi
NULL

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 140


Veleučilište u Rijeci

da bi varijabla pocetak_liste pokazivala na


početak ponavlja se naredba pridruživanja:
pocetak_liste=novi;

novi *novi
Drugi

pocetak_liste
Prvi
NULL

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 141


Veleučilište u Rijeci

Programsko rješenje stvaranja liste dodavanjem


elemenata na početak liste
#include <iostream>
using namespace std;
struct element_liste
{
char podatak[10];
element_liste *slijedeci;
};

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 142


Veleučilište u Rijeci

void pisi(element_liste *tekuci)


{
while(tekuci!=NULL){
cout<<tekuci->podatak<<endl;
tekuci=tekuci->slijedeci;
}
cout<<endl;
}
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 143
void main() Veleučilište u Rijeci

{
element_liste *pocetak_liste,*novi;
pocetak_liste=NULL;
cout<<"Upisite sadrzaj liste:"<<endl;
novi=new element_liste;
cin.getline(novi->podatak,10);
while(strcmp(novi->podatak,"")!=0)
{
novi->slijedeci=pocetak_liste;
pocetak_liste=novi;
novi=new element_liste;
cin.getline(novi->podatak,10);
}
cout<<"Sadrzaj liste je:\n";
pisi(pocetak_liste);
}
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 144
Veleučilište u Rijeci

Upisite sadrzaj liste:


Prvi
Drugi
Treci
Cetvrti
Peti

Sadrzaj liste je:


Peti
Cetvrti
Treci
Drugi
Prvi

Press any key to continue . . .


12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 145
Veleučilište u Rijeci

Vezana lista sastoji se od:


glave liste
prvi element u listi
pokazivač na listu sadrži adresu glave liste
pomoćna uloga (može se koristiti za privremeni
smještaj podataka)
elemenata liste (definiranih odgovarajućom
strukturom) koji sadrže
podatke
pokazivač na slijedeći element liste i
(eventualno) pokazivač na prethodni element
liste (tada je to tzv. dvostruko vezana lista)
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 146
pokazivač na
podatkovni slijedeći element
dio u listi
kraj liste

NULL
podatkovni dio liste
glava

prazna lista sastoji se samo od glave liste


pokazivač na slijedeći element u zadnjem elementu liste ima
vrijednost NULL
pogodna kontrolna struktura za čitanje liste je iteracija tipa while
jer
nije poznat broj elemenata liste (nema zadanu dimenziju, kao
polje)
nula kao vrijednost logičkog izraza omogućuje izlazak iz petlje
mr. sc. Jasminka Tomljanović, viši predavač 147
Primjer: vezana lista studenata

Element liste (TIP podatka):

struct student{
int mat_br;
char prez_ime[35];
int god_stu;
student *slijedeci;
};

mr. sc. Jasminka Tomljanović, viši predavač 148


struct student{
int mat_br;
char prez_ime[35]; podatkovni dio elementa liste
int god_stu;
student *slijedeci; pokazivač na slijedeći element u listi

};

mr. sc. Jasminka Tomljanović, viši predavač 149


struct student{
int mat_br;
Komponenta strukture istog tipa
char prez_ime[35 kao i struktura. Dozvoljeno je jer
int god_stu; se radi o pokazivaču!
student *slijedeci;
};

mr. sc. Jasminka Tomljanović, viši predavač 150


Veleučilište u Rijeci

Alokacija glave liste:

student *lista = new student;

lista -> slijedeci = NULL;

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 151


Alokacija glave liste:

student *lista = new student;

glava liste studenata

kraj liste
lista -> slijedeci = NULL;

za statičke strukture i klase koristi se operator ‘.’ ,


a za dinamičke (dostupne preko pokazivača) ‘->’

Podatkovni sadržaj glave liste nije bitan jer je glava samo


pomoćni element liste!

mr. sc. Jasminka Tomljanović, viši predavač 152


Dodavanje novog elementa na kraj liste:

NULL

NULL
lista zadnji novi

Koraci dodavanja novog elementa na kraj liste:


pronaći zadnji element u listi
alocirati novi element
povezati zadnji element u listi s novim
upisati NULL vrijednost pokazivaca slijedeci u novi element liste (kraj liste)
upisati podatkovni sadržaj u novi element liste

mr. sc. Jasminka Tomljanović, viši predavač 153


Dodavanje novog elementa na kraj liste:

student *novi,*zadnji;
zadnji = lista;
while (zadnji->slijedeci) traženje zadnjeg elementa u listi
zadnji = zadnji->slijedeci;

novi = new student;


zadnji -> slijedeci = novi; dodavanje novog elementa u listu
novi -> slijedeci = NULL;

cout << "Maticni broj: "; cin >> novi -> mat_br; upis
cout << "Prezime i ime: "; cin >> novi -> prez_ime; podatkovnog
cout << "Godina studija: "; cin >> novi -> god_stu; sadržaja

mr. sc. Jasminka Tomljanović, viši predavač 154


Ispis svih elemenata vezane liste:

Ispis počinje od prvog


student *tekuci = lista -> slijedeci; elementa iza glave!
Tipična struktura za čitanje
vezane liste !
while (tekuci){
cout << "Maticni broj: " << tekuci -> mat_br << endl;
cout << "Prezime i ime: " << tekuci -> prez_ime << endl;
cout << "Godina studija: " << tekuci -> god_stu << endl;
cout << "---------------------" << endl;
tekuci = tekuci -> slijedeci;
}; kretanje kroz listu
mr. sc. Jasminka Tomljanović, viši predavač 155
Pretraživanje liste prema ključu (matični broj):
student *tekuci = lista -> slijedeci;

while (tekuci){
if (tekuci -> mat_br == mat_br){
cout << "Maticni broj: " << tekuci -> mat_br << endl;
cout << "Prezime i ime: " << tekuci -> prez_ime << endl;
cout << "Godina studija: " << tekuci -> god_stu << endl;
cout << "---------------------" << endl;
break; // izlaz iz petlje za pretraživanje
};
tekuci = tekuci -> slijedeci;
};

mr. sc. Jasminka Tomljanović, viši predavač 156


Brisanje elementa liste:

NULL
mat_br=X

lista prethodni brisi

Koraci brisanja elementa liste:


pronaći element u listi za brisanje (prema zadanom
ključu) i njegov prethodnik
povezati prethodni element liste s onim iza elementa za
brisanje (= premostiti element koji se briše)
dealocirati element liste koji se briše
mr. sc. Jasminka Tomljanović, viši predavač 157
student *brisi = lista -> slijedeci, *prethodni = lista;

while (brisi) {
if (brisi -> mat_br == mat_br){
prethodni -> slijedeci = brisi -> slijedeci;
delete brisi;
break; // izlaz iz petlje
};
prethodni = brisi;
brisi = brisi->slijedeci;
};
mr. sc. Jasminka Tomljanović, viši predavač 158
Sortiranje vezane liste (bubble sort; prema
matičnom broju uzlazno):
1 2

NULL
5 3 6

lista,
tekuci slijedeci
prethodni

efekat zamjene mjesta


preusmjeravanjem pokazivača

mr. sc. Jasminka Tomljanović, viši predavač 159


Postupak:
prolazi se ponavljaju dok ima zamjena (indikator=1)
unutar prolaza koristi se pokazivač tekuci za kretanje kroz
listu
pokazivač slijedeci sadrži adresu slijedećeg elementa u listi
(tekuci -> slijedeci), a prethodni adresu prethodno
elementa
usporede se matični brojevi u tekućem i slijedećem
elementu
ako ima potrebe za “zamjenom mjesta”:
u tri koraka preusmjere se pokazivači
indikator = 1 (indikator zamjene)
mr. sc. Jasminka Tomljanović, viši predavač 160
student *prethodni,*tekuci,*slijedeci;
int indikator,brojac=0; indikator zamjene; izlaz je ako ostane 0
do{ nakon prolaza
indikator = 0;
tekuci=lista->slijedeci; tekuci se kreće do predzadnjeg
prethodni=lista; elementa liste
while (tekuci->slijedeci){
slijedeci=tekuci->slijedeci; uvjet za “zamjenu mjesta”
if (tekuci->mat_br > slijedeci->mat_br){
prethodni->slijedeci=slijedeci; preusmjeravanje pokazivača
tekuci->slijedeci=slijedeci->slijedeci; • odgovara zamjeni mjesta
slijedeci->slijedeci=tekuci; elemenata kod polja
indikator=1;
} //if Voditi računa o rasporedu pokazivača
prethodni=tekuci; prethodni, tekuci i slijedeci na tri
uzastopna elementa liste!
tekuci=tekuci->slijedeci;
} //while
161
} while (indikator==1);mr. sc. Jasminka Tomljanović, viši predavač
Dealokacija vezane liste:
student *tekuci,*prethodni;

pokazivač prethodni kasni


prethodni=lista;
jedan element u odnosu
tekuci=lista->slijedeci; na tekuci

while (tekuci){ dealokacija elementa liste


delete prethodni; uključuje dealokaciju glave
prethodni=tekuci;
liste
tekuci=tekuci->slijedeci;
}//while

delete prethodni; dealokacija zadnjeg elementa liste


lista=NULL; Liste više nema!

mr. sc. Jasminka Tomljanović, viši predavač 162


Dealokacija vezane liste:
funkcija za dealokaciju liste treba vratiti NULL pokazivač

student *dealokacija_liste(student *lista){


.
funkcija vraća pokazivač na student,
. (ovdje je to NULL pokazivač)
return NULL;
};

 poziv funkcije za dealokaciju liste:

lista=dealokacija_liste(lista);

mr. sc. Jasminka Tomljanović, viši predavač 163


Usporedba polja i vezane liste
Alokacija memorije
polja: statička ili dinamička
<TIP> polje[<broj_elemenata>]; // statičko polje
<TIP> *polje = new <TIP>[N]; // dinamičko polje

kod dinamičkog polja može se u toku izvođenja programa


odrediti broj elemenata, ali se polje ne može proširivati

vezana lista: dinamička alokacija svakog elementa liste zasebno


<TIP> *glava = new <TIP>; // alokacija glave liste
glava->slijedeci=NULL; // TIP treba biti takav da uključuje
// pokazivač na slijedeći element u listi
mr. sc. Jasminka Tomljanović, viši predavač 164
Upis podataka
polje:
element polja već je alociran i pristupa mu se
uz pomoć indeksa
int polje[5];
polje[0] = 15;
vezana lista:
potrebno je najprije dinamički alocirati element liste i
upisati mu podatkovni sadržaj
student *novi = new student; // alokacija novog elementa liste
novi->mat_br = 12345;
strcpy (novi->prez_ime,“Perić Pero”);
novi->god_stu = 2;
prethodni->slijedeci=novi; //povezivanje prethodnog s novim
novi->slijedeci=NULL; // zadnji element liste
mr. sc. Jasminka Tomljanović, viši predavač 165
Ispis podataka
polje:
broj elemenata polja je poznat (zadat dimenzijom polja),
pa se tipično koristi iteracija tipa for:
int polje[5]={2,5,7,8,4};
for (i=0;i<5;i++)
cout <<polje[i]<<“ “; // ispis svih elemenata polja
vezana lista:
broj elemenata vezane liste nije unaprijed zadan,
tipično se koristi iteracija tipa while:
tekuci = glava -> slijedeci; Izlaz iz petlje osigurava
while (tekuci){ NULL vrijednost u zadnjem
elementu vezane liste!
cout<<tekuci->mat_br<<endl;
cout<<tekuci->prez_ime<<endl;
cout<<tekuci->god_stu<<endl;
tekuci=tekuci->slijedeci;} kretanje kroz listu
mr. sc. Jasminka Tomljanović, viši predavač 166
Dealokacija
polje:
statičko polje dealocira se pri završetku programa
dinamičko polje dealocira se pomoću operatora delete []
int *polje = new int[N];
delete [] polje;
vezana lista:
svaki element vezane liste mora se odvojeno dealocirati
pomoću operatora delete
tekuci=lista->slijedeci;
while (tekuci!=NULL){
iduci=tekuci->slijedeci; // iduci pamti poziciju slijedeceg el.
delete tekuci;
tekuci=iduci;
}; //while
lista->slijedeci=NULL; //Tomljanović,
mr. sc. Jasminka Lista jevišiprazna!
predavač 167
Veleučilište u Rijeci

Sadržaj

Datoteke

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 168


Veleučilište u Rijeci

Ulazno –izlazna klasa datoteke → fstream


Definira f-je za čitanje i upisivanje u datoteku
ifstream za ulazne datoteke
ofstream za izlazne datoteke
Unutar klase fstream deklariraju se datotečni objekti
koji sadrže sve potrebne podatke i postupke za rad sa
stvarnom datotekom na disku
npr: fstream d; //d je datotečni objekt iz klase
// fstream kojemu nije još
// pridružena stvarna datoteka
//na disku
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 169
Veleučilište u Rijeci

Stvarno ime datoteke je ime pod kojim je datoteka


vidljiva na disku preko operacijskog sustava
Stvarno ime datoteke pridružuje se datotečnom
objektu kod otvaranja datoteke funkcijom open

<datotečni objekt>.open (<stvarno ime dat>,<mod otvaranja>)


Mod otvaranja datoteke definira dozvoljene operacije nad
datotekom

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 170


Veleučilište u Rijeci

d.open(“prva.dat”,ios::in|ios::binary)
Datotečnom objektu d pridružena je stvarna
datoteka prva .dat
Datoteka je otvorena za čitanje u binarnom
načinu

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 171


Veleučilište u Rijeci

Datotečni pokazivač
datotečni pokazivač sadrži poziciju unutar datoteke gdje se
može obaviti operacija čitanja ili upisa u datoteku
pozicija je izražena u cijelom broju bajtova od početka datoteke
do mjesta upisa/čitanja
C++ razlikuje datotečni pokazivač za čitanje datoteke od
datotečnog pokazivača za upis u datoteku
Funkcije za očitavanje vrijednosti datotečnog pokazivača (tipa tell):
tellg() - vrijednost pokazivača za čitanje datoteke
tellp() - vrijednost pokazivača za upis u datoteku
Sintaksa:
int vrijednost = <datotečni objekt>.{tellg ili tellp}();

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 172


Veleučilište u Rijeci

Primjer 1:
d.open (“prva.dat", ios::in);
//otvaranje datoteke za čitanje
cout << d.tellg() << endl;
//0 -vrijednost dat. pokazivača za čitanje

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 173


Veleučilište u Rijeci

Npr.:
d.open ("d.dat", ios::out);
//otvaranje dat. za upis podataka
cout << d.tellp() << endl;
//0 -vrijednost dat. pokazivača za upis
otvaranjem datoteke u modu out datotečni
pokazivač za upis postavlja se na početak
datoteke.
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 174
Veleučilište u Rijeci

Funkcije za zadavanje vrijednosti datotečnog


pokazivača (tipa seek):
seekg() - postavlja vrijednost pokazivača za
čitanje datoteke
seekp() - postavlja vrijednost pokazivača za
upis u datoteku
Sintaksa:
<datotečni objekt>.{seekg ili seekp}(<vrijednost
dat. pokazivača>);
12.1.2020. 175
mr. sc. Jasminka Tomljanović, viši predavač
Veleučilište u Rijeci

Npr.:
d.open ("d.dat", ios::in);
// otvaranje datoteke za čitanje
d.seekg (5* sizeof(slog));
// postavlja datotečni pokazivač za čitanje
// na slog s rednim brojem 5

datotečni pokazivač za čitanje postavlja se na


poziciju sloga s rednim brojem 5

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 176


Veleučilište u Rijeci

Modovi otvaranja datoteke


Definiraju dozvoljen način rada s datotekama (za
čitanje ili upis podataka), početnu poziciju
datotečnih pokazivača za čitanje i upis, da li će se
koristiti postojeća datoteka ili otvoriti nova
Zadaje se kao drugi argument f-je open
Uključenje više modova otvaranja datoteke
postiže se korištenjem bitovnog ili operatora “|”
npr.:
d.open(“prva.dat”,ios::in | ios::out | ios::binary);
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 177
Veleučilište u Rijeci

Mod in
koristi se za otvaranje datoteke za čitanje
otvara postojeću datoteku, a datotečni
pokazivač za čitanje se postavlja na 0
(početak datoteke)
ako datoteka sa zadanim stvarnim imenom
ne postoji na disku, otvaranje ne uspijeva,
što se može provjeriti stanjem datotečnog
objekta:

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 178


Veleučilište u Rijeci

d.open(“prva.dat",ios::in);
if (!d)
cout << "Otvaranje nije uspjelo, datoteka ne
postoji na disku!" << endl;
else
cout << "Datoteka je otvorena!" << endl;

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 179


Veleučilište u Rijeci

Mod out
koristi se za otvaranje datoteke za upis podataka
datotečni pokazivač za upis se postavlja na 0
(početak datoteke)
stvara se nova datoteka na disku ili se postojeća briše
može se kombinirati s nocreate:
d.open(“prva.dat",ios::out | ios::nocreate);
//ne dozvoljava brisanje postojeće datoteke

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 180


Veleučilište u Rijeci

Mod noreplace
Datoteka neće biti otvorena , ako već postoji na
disku:
d.open(“prva.dat",ios::out | ios::noreplace);

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 181


Veleučilište u Rijeci

kombiniranjem modove in i out otvaramo


datoteku kao ulazno-izlaznu:
d.open(“prva.dat",ios::in | ios::out);
Otvara se postojeća datoteka koju je moguće
neovisno čitati i u nju upisivati podatke,
budući da su razdvojeni datotečni pokazivači
za čitanje i upis

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 182


Veleučilište u Rijeci

Mod trunc

briše sadržaj postojeće datoteke:

d.open(“prva.dat",ios::out | ios::trunc);

otvara se postojeća datoteka i briše se njen


sadržaj, kako bi upis počeo u praznoj
datoteci

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 183


Veleučilište u Rijeci

Mod app (append)


otvara postojeću datoteku za upis podataka,
ali na kraj postojeće datoteke, za razliku od
moda out.
datotečni pokazivač za upis sloga svejedno
dobiva vrijednost 0, radi zaštite postojećeg
sadržaja datoteke od promjene sadržaja

d.open(“prva.dat",ios::app);
// otvara datoteku za dodavanje novih zapisa
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 184
Veleučilište u Rijeci

Mod ate (at-end)


Otvara postojeću datoteku tako da se datotečni
pokazivač pozicionira na kraj datoteke i to je pozicija
prvog slijedećeg sloga za upis u datoteku. Time nije
spriječena naknadna promjena postojećeg sadržaja
datoteke, kao kod moda app:
d.open(“prva.dat",ios::out|ios::in|ios::ate);
// otvara datoteku za dodavanje novih zapisa
Najčešće se mod ate kombinira s modovima in i
out, radi upisa zapisa na kraj postojeće datoteke,
uz mogućnost čitanja već upisanih zapisa.

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 185


Veleučilište u Rijeci

Mod binary
otvara datoteku u binarnom načinu rada
nema konverzija kod upisa/čitanja podataka kao
kod tekstualnog načina rada (bitovni sadržaj ostaje
nepromijenjen)
dat.open ("datoteka.dat",ios::in|ios::binary);
//otvara ulaznu datoteku u binarnom modu
Binarni način rada koristi se kod datoteka s fiksnom
veličinom sloga jer bi svaka eventualna konverzija
mogla sadržaj zapisa učiniti nečitljivim.

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 186


Veleučilište u Rijeci

Tekstualna datoteka
Tekstualne datoteke sastoje se od podataka znakovnog tipa
(redova teksta)
svaki red završava kontrolnim znakovima
CR (Carriage Return; ASCII kod 13; prebacuje kursor na
početak reda) i
LF (Line Feed; ASCII kod 10; pomiče kursor u slijedeći
red)
zajedno, CR i LF čine znak EOLN - znak za kraj reda
da bi pročitali/upisali neki podatak, moramo
najprije pročitati/upisati sve prethodne

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 187


Veleučilište u Rijeci

Upis u tekstualnu datoteku


postiže se jednostavnim umetanjem teksta u
datotečni tok pridružen datotečnom objektu i
analogan je odgovarajućem konzolnom ispisu
teksta pomoću objekta cout.

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 188


Veleučilište u Rijeci
#include <iostream>
#include <fstream>
using namespace std;
int main(){
fstream d;
d.open("C:\\DATOTEKE\\tekst.txt",ios::out);
d<< "Ovo je prvi red teksta u tekstualnoj datoteci." << endl;
d << "Ovo je drugi red." << endl;
int a = 13;
d << a << endl;
d.close();
return 0;}
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 189
Veleučilište u Rijeci

Čitanje tekstualne datoteke


postiže se pomoću metode getline datotečnog
objekta. Sadržaj se učitava u znakovni niz, koji
predstavlja redak iz tekstualne datoteke.

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 190


Veleučilište u Rijeci

#include <iostream>
#include <fstream>
using namespace std;
int main(){
char red[80];
fstream d;
d.open("C:\\DATOTEKE\\tekst.txt",ios::in);
while(d){
d.getline (red,sizeof(red),'\n'); //čitanje reda iz datoteke
cout << red << endl; // ispis na ekran
};
d.close();
return 0;}
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 191
Veleučilište u Rijeci

Ovo je prvi red teksta u tekstualnoj datoteci.


Ovo je drugi red.
13

Press any key to continue . . .

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 192


Veleučilište u Rijeci

znakovni varijabla red koristi se za učitavanje


pojedinih zapisa (redaka teksta) iz tekstualne
datoteke, koji su međusobno odvojeni znakom
<eoln>
za čitanje tekstualne datoteke koristi se
funkcija getline, s ulaznim argumentima:
Znakovnim nizom koji se učitava
veličinom znakovnog niza koji se učitava i
znakom za oznaku kraja reda "\n“
kontrolni znak "\n" označava kraj retka u
tekstualnoj datoteci
12.1.2020. (kao viši
mr. sc. Jasminka Tomljanović, i konstanta
predavač eoln)
193
Veleučilište u Rijeci

Kontrola kraja datoteke postiže se pomoću


funkcije eof. Funkcija eof vraća vrijednost
logičke istine tek kad čitanje zapisa iz datoteke
ne uspije. Zato je kontrola kraja datoteke
smještena neposredno iza čitanja datoteke
pomoću funkcije getline.

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 194


Veleučilište u Rijeci

Datoteke s fiksnom veličinom sloga

Svi zapisi su istog tipa pa se još zovu i tipizirane


datoteke
Potrebno je deklarirati tip zapisa pomoću struct
Npr.: struct student{
int mat_br,g_upisa;
char prez_ime[35];
};

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 195


Veleučilište u Rijeci

Čitanje datoteke sa slogovima


student s; //varijabla koja će se čitati/upisivati u datoteku
fstream d; // datotečni objekt
d.open(“studenti.dat",ios::in|ios::binary);//otvara datoteku
// za čitanje
d.read ((char*)&s,sizeof(s)); // čitanje podataka iz datoteke
podatak s se čita iz datoteke pomoću f-je read
nakon pročitanog podatka datotečni pokazivač
premješta se na adresu prvog slijedećeg zapisa u
datoteci
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 196
Veleučilište u Rijeci

Upisivanje slogova u datoteku slogova


char* - predstavlja operator dodjele tipa jer f-ja read
definira prvi argument kao argument tipa char*
sizeof(s) – veličina sloga s izražena u bajtovima

Podatak s se upisuje u datoteku pomoću f-je write


d.open (“studenti.dat", ios::out | ios::binary); //otvaranje
// datoteke
d.write ((char*)&s,sizeof(s)); // upis u datoteku

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 197


Veleučilište u Rijeci

#include <iostream>
#include <fstream>

using namespace std;

struct student // tip zapisa koje sadrži datoteka


{
unsigned long int mat_br;
int g_upisa;
char prez_ime[35];
};

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 198


Veleučilište u Rijeci

student s; // varijabla čiji se sadržaj upisuje /čita u/iz datoteke


char naziv_datoteke[40]; // fizičko ime datoteke

void kreiranje_datoteke()
{
fstream datoteka; // datotečni objekt
cout<<"Unesite naziv datoteke u koju cete spremati podatke: ";
cin>>naziv_datoteke;

datoteka.open(naziv_datoteke, ios::out | ios::binary);

if (!datoteka) // ako datoteka ne postoji na disku obavjest o tome


cout<<"Neuspjesno otvaranje datoteke!";
else
datoteka.close (); // u protivnom zatvaram datoteku
}
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 199
void unos_podataka_u_datoteku () Veleučilište u Rijeci
{
fstream datoteka; // datotečni objekt
char dalje = 'n';
datoteka.open(naziv_datoteke, ios::out | ios::ate | ios::binary); // otvori datoteku za pisanje,
//dodavanje na kraj i u binarnom modu
cout<<"\n\nUpisite podatke: \n\n ";
do {
cout<<endl;
// unos vrijednosti
cout<<"Maticni broj:"<<"\t"; cin>>s.mat_br;
cin.ignore();
do{
cout<<"Prezime i ime:"<<"\t";
cin.getline(s.prez_ime, 35);
} while (strlen(s.prez_ime) <= 1); // jednostavna petlja kojom sprječavamo unos praznog im
cout<<"Godina upisa:"<<"\t"; cin>>s.g_upisa;

datoteka.write((char *)&s, sizeof(s)); // zapis u datoteku


cout<<"\nDalje (d/n)? ";
cin>>dalje;
}while (dalje == 'd');
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 200
datoteka.close(); }
Veleučilište u Rijeci
void ispis_podataka_o_svim_studentima ()
{
fstream datoteka; // datotečni objekt
datoteka.open(naziv_datoteke, ios::in | ios::binary);

cout<<endl<<"Ispis svih podataka"<<endl;


cout<<"----------------------------------------------"<<endl;
do
{
datoteka.read((char *)&s, sizeof (s)); // pročitaj slog iz datoteke
if(datoteka.eof()) break; // ako je u čitanju došlo do kraja datoteke, prekini

cout<<"Maticni broj:"<<"\t"<<s.mat_br<<endl;
cout<<"Prezime i ime:"<<"\t"<<s.prez_ime<<endl;
cout<<"Godina upisa:"<<"\t"<<s.g_upisa<<endl;
cout<<"----"<<endl;
} while (!datoteka.eof());

datoteka.close ();
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 201
}
Veleučilište u Rijeci

void main()
{
kreiranje_datoteke ();
unos_podataka_u_datoteku ();
ispis_podataka_o_svim_studentima ();
}

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 202


Veleučilište u Rijeci
Unesite naziv datoteke u koju cete spremati podatke: C:\DATOTEKE\studenti.ini

Upisite podatke:

Maticni broj: 1
Prezime i ime: Ivo Ivic
Godina upisa: 2006

Dalje (d/n)? d

Maticni broj: 5
Prezime i ime: Ana Anic
Godina upisa: 2007

Dalje (d/n)? n

Ispis svih podataka


----------------------------------------------
Maticni broj: 1
Prezime i ime: Ivo Ivic
Godina upisa: 2006
----
Maticni broj: 5
Prezime i ime: Ana Anic
Godina upisa: 2007
----
12.1.2020 mr. sc. Jasminka Tomljanović, viši predavač 203
Press any key to continue . . .
.
Veleučilište u Rijeci

Sadržaj

Klase i objekti
Konstruktori i destruktori

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 204


Veleučilište u Rijeci

Osnovni pojmovi OOP

klasa predstavlja tip


objekt prestavlja instancu tipa
klasa definira svoje članove
članovi klase su:
atributi (podatkovni članovi)
metode (funkcijski članovi)

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 205


Veleučilište u Rijeci

Deklaracija klase
deklaracija struct naslijeđena je iz C-a i definira
isključivo atribute
deklaracija class u C++ definira atribute i
metode (potpune objekte)
deklaracija class uvodi specifikatore pristupa
koji određuju prava pristupa članovima klase a to su:
public
protected
private
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 206
Veleučilište u Rijeci

class
private
nevidljivo iz dijelova
atributi
programa van klase metode

public
vidljivo iz dijelova atributi
programa van klase metode

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 207


Veleučilište u Rijeci

Primjer klase
class pravokutnik {
public: int x1,y1,x2,y2; //javni članovi klase dostupni izvan klase
private: int sirina, visina; //privatni članovi dostupni unutar klase
public:
int povrsina (){ //javni član klase
visina = y2 – y1; //pristup privatnim članovima klase
sirina = x2 – x1;
return sirina * visina;
} //povrsina
}; //pravokutnik

pravokutnik o1,o2,*kvadrat; // objekti iz klase pravokutnik


12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 208
Veleučilište u Rijeci

o1.x1=5; o1.y1=5; o1.x2=15; o1.y2=10; // javni članovi objekta o1


cout << "Povrsina pravokutnika o1: " << o1.povrsina() << endl;
o2.x1=10;o2.y1=10;o2.x2=15;o2.y2=25; // javni članovi objekta o2
cout << "Povrsina pravokutnika o2: " << o2.povrsina() << endl;
kvadrat=new pravokutnik; // dinamička alokacija objekta
kvadrat->x1=6;kvadrat->y1=6;kvadrat->x2=10;kvadrat->y2=10;
cout << "Povrsina kvadrata: " << kvadrat->povrsina() << endl;
delete kvadrat; // dealokacija objekta

//o1.sirina=10;o1.visina=5; // Privatni članovi klase i nisu dostupni


// izvan klase nego preko metoda klase

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 209


Veleučilište u Rijeci

Unutarnji i vanjski pristup članovima klase

unutarnji (privatni) je pristup članovima klase iz metoda


klase gdje su definirani i moguć je za sva tri specifikatora
pristupa
vanjski (javni) je pristup članovima klase izvan klase i
moguć je samo za specifikator public
zaštićeni pristup protected članovima klase znači pravo
pristupa članovima klase iz metoda klase gdje su
definirani i iz metoda podređenih klasa tj. klasa koje
nasljeđuju odgovarajuće članove

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 210


Veleučilište u Rijeci

Atributi i metode

atributi pripadaju objektima iz svojih klasa


fizički
metode pripadaju objektima iz svojih klasa
samo logiči
Svaki objekt iz klase sadrži svoje vlastite
podatke, a svi objekti iz iste klase koriste iste
metode

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 211


Veleučilište u Rijeci

class klasa{
public: int atribut;
void metoda(){
cout << "metoda" << endl;
} //metoda
}; //klasa
klasa objekt1,objekt2;
int main(){
cout << sizeof(objekt1) << endl; // 4 ( =sizeof(int) )
objekt1.atribut=11;
memcpy (&objekt2,&objekt1,sizeof(klasa)); //kopiranje objekta
cout << objekt2.atribut << endl;
return 1;
} //main
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 212
Veleučilište u Rijeci

Javno sučelje klase i implementacija klase

javno sučelje klase čine svi njeni članovi s


javnim pristupom (public) i preko javnog sučelja
objekti komuniciraju s okolinom
implementaciju klase čine javno sučelje klase
i članovi koji nisu vidljivi izvana klase tj. oni koji
imaju privatni ili zaštićeni pristup
predstavlja način na koji se reprezantacija objekta
ostvaruje
vrijedi princip skrivanja podataka jer nisu svi članovi
dostupni izvana
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 213
Veleučilište u Rijeci

Enkapsulacija

enkapsulacija predstavlja objedinjavanje


javnog sučelja i implementacije (odnosno svih
članova klase) u cjelinu
prema principu enkapsulacije metode su
logički pridružene podatkovnom sadržaju
objekata
p1.povrsina() : metoda povrsina koristi
podatkovni sadržaj objekta p1 (x1, y1 ,x2, y1,
sirina i visina; fizički pripadaju objektu)
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 214
Veleučilište u Rijeci

Pokazivač this
iz jedne klase moguće je definirati neograničen
broj objekata
klasa “ne zna” nazive svojih objekata
pomoću pokazivača this moguće je unutar
klase doznati adresu objekta, odnosno:
*this predstavlja sam taj objekt na način kako
je dostupan iz koda klase
u većini slučajeva nije neophodno navoditi
pokazivač this: this -> x skraćeno se piše x
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 215
Veleučilište u Rijeci

class klasa{
public: int a,b;
void metoda(){
cout << "Adresa objekta preko kojeg je metoda pozvana:"<<(int)this <<endl;
cout<<"Vrijednosti atributa su: "<<this->a<<" i "<<this->b<< endl;
} //metoda
}; //klasa
klasa objekt1,objekt2;
void main(){
objekt1.a=11; objekt1.b=15;
cout << "Adresa objekta objekt1: " << (int)&objekt1 << endl;
objekt1.metoda();
objekt2.a=22; objekt2.b=25;
cout << "Adresa objekta objekt2: " << (int)&objekt2 << endl;
objekt2.metoda();
}12.1.2020.
//main 216
mr. sc. Jasminka Tomljanović, viši predavač
Veleučilište u Rijeci

Operator ::
Operator :: naziva se operator dodjele
područja ili operator pripadnosti
pripadnost se odnosi na klasu ili područje
imena (namespace)

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 217


Veleučilište u Rijeci

Operator :: može se koristiti za


definiciju metoda izvan tijela klase
pristup drugim područjima imena (namespace)
pristup statičkim članovima klasa
statički članovi klasa ne pripadaju svakom objektu
pojedinačno, nego im je pristup moguć preko svih
objekata klase
pristup članovima pobrojenja deklariranim unutar klasa
pristup globalnim varijablama u području dosega
lokalnih
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 218
Veleučilište u Rijeci

#include<iostream>
int a; // globalna varijabla a
class klasa{
public: int a,b;
static int c; // vrijednost c se dijeli između svih objekata klase
enum {pon,uto,sri,cet,pet,sub,ned}; // pobrojenje
void metoda(); //prototip metode
}; //klasa
void klasa::metoda(){ //metoda pripada klasi klasa
std::cout << "Metoda izvan tijela klase" << std::endl;
} //metoda
klasa objekt1,objekt2;
int klasa::c=5; //ne pripada svakom objektu pojedinačno

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 219


Veleučilište u Rijeci

int main(){
objekt1.metoda(); // kod poziva nema razlike
char a; // lokalna varijabla a koja prekriva istoimenu globalnu var.
a = 'A'; // podrazumijeva se lokalna varijabla
::a=11; // ovo je globalna varijabla a
std::cout << klasa::ned << std::endl; //pristup članu pobrojenja
std::cout << klasa::c << std::endl;
klasa::c=22;
std::cout << objekt1.c << std::endl;
std::cout << objekt2.c << std::endl;
} //main

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 220


Veleučilište u Rijeci

Objektna dekompozicija programa


Objektna dekompozicija programa dijeli
podatke, kojima se logički pridružuju
potprogrami koji rade s tim podacima
takva integracija podataka (atributa) i
potprograma za obradu (metoda) definirana
je odgovarajućom klasom (princip
enkapsulacije)
objekti iz zadane klase mogu se
neograničeno multiplicirati i pridruživati
stvarnim objektima
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 221
Veleučilište u Rijeci

podatkovni kontekst objekata su svi njegovi


atributi i ostaje sačuvan do dealokacije objekta i
nema potrebe pri svakom pristupanju objektu
prenositi mu cijeli podatkovni kontekst
osnovni princip je da se procesi pridružuju
podacima tj. podatkovni kontekst objekta postoji
od alokacije objekta i samo mu se po potrebi
mijenjaju pojedini dijelovi
princip skrivanja podataka (odvajanja sučelja od
implementacije) implementiran je pomoću
specifikatora pristupa public, protected i private
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 222
Veleučilište u Rijeci

Konstruktor

konstruktor je metoda koja ima isto ime kao i


klasa, a poziva se automatski kod alokacije
objekta. Specifičnosti konstruktora u odnosu
na ostale metode:
konstruktor nema definiran tip (ne vraća vrijednost)
konstruktor se ne nasljeđuje
može postojati više konstruktora za istu klasu (tj.
može se preopteretiti)
konstruktor ne može biti statički član
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 223
Veleučilište u Rijeci

Destruktor
destruktor ima isto ime kao i klasa samo što
ispred imena klase dolazi znak ~ (tilda). Poziva
se automatski kod dealokacije objekta.
Specifičnosti destruktora u odnosu na ostale
metode:
Destruktor nema argumenata
Destruktor (isto kao i konstruktor) nema tip, ne vraća
vrijednost i ne nasljeđuje se

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 224


Veleučilište u Rijeci

class pravokutnik {
public: int x1,y1,x2,y2;
private: int sirina, visina;
public:
pravokutnik(){ //konstruktor 1
cout << "Kostruktor (bez argumenata)!" << endl; };
pravokutnik(int x1_,int y1_,int x2_,int y2_){ //konstruktor 2
cout << "Konstruktor (s argumentima):" << endl;
x1=x1_;y1=y1_;x2=x2_;y2=y2_; };
~pravokutnik(){ //destruktor
cout << "Destruktor!" << endl;
}; //~pravokutnik
int povrsina (){ //povrsina
visina = y2 - y1;
sirina = x2 - x1;
return sirina * visina;}; //povrsina
}; //pravokutnik
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 225
Veleučilište u Rijeci

pravokutnik p2,*objekt;
int main(){
objekt = new pravokutnik; //alokacija objekta
delete objekt; //dealokacija objekta
pravokutnik p2(50,50,100,150); //pokreće 2. konstruktor
cout << "Povrsina p2=" << p2.povrsina() << endl;
objekt = new pravokutnik(20,20,50,60); //alokacija objekta
cout << "Povrsina objekta=" << objekt->povrsina() << endl;
delete objekt; //dealokacija objekta
}

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 226


Veleučilište u Rijeci

Sadržaj

Vezana lista objekata


Prijatelj klase
Nasljeđivanje
Virtualne metode i polimorfizam
Apstraktne klase

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 227


Veleučilište u Rijeci

Vezana lista objekata


Postupak : smjestiti sve operacije (metode) koje se odnose
na rad s vezanom listom u istu klasu s podacima koje
sadrži element vezane liste (princip enkapsulacije):
metode pripadaju elementima liste (objektima) samo
logički (ne opterećuju objekte)
klasa koja se odnosi na drugu vezanu listu može koristiti
istoimene metode
upotreba pokazivača this radi pristupa glavi liste iz
objekta
upotreba konstruktora: u pokazivač na slijedeći element
u listi upisuje vrijednost
12.1.2020. mr. sc. JasminkaNULL
Tomljanović, viši predavač 228
Veleučilište u Rijeci

Definiranje klase

class student{
private: student *slijedeci; //pokazivač na slijedeći element liste
public:
//javni atributi – podatkovni sadržaj elementa liste
int mat_br;
char prez_ime[35];
int god_stu;
//metode – sve operacije za rad s vezanom listom
...
...
}; //class
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 229
Veleučilište u Rijeci

Alokacija glave liste i pokretanje konstruktora

class student{
...
//metode – sve operacije za rad s vezanom listom
student(){ //konstruktor
slijedeci=NULL;
}; //konstruktor
...
}; //class
int main(){
lista=new student; //alokacija glave liste

} //main
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 230
Veleučilište u Rijeci

Metoda za dodavanje novog elementa listi

void dodaj_element(){ // dodaje element na kraj liste


student *novi,*zadnji;
zadnji = this; // this je glava liste
while (zadnji->slijedeci)
zadnji = zadnji->slijedeci; // pronalaženje zadnjeg elementa
novi = new student; // alokacija novog elementa liste
zadnji -> slijedeci = novi; // povezivanje zadnjeg elementa s novim
cout << "Maticni broj: "; cin >> novi -> mat_br;
cout << "Prezime i ime: "; cin >> novi -> prez_ime;
cout << "Godina upisa studija: "; cin >> novi -> god_upisa;
}; //dodaj_element

Poziv metode:
lista -> dodaj_element();
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 231
Veleučilište u Rijeci

Metoda za ispis svih elemenata liste

void ispisi_sve_elemente(){ // ispis svih elemenata liste


student *tekuci = this -> slijedeci; // početni element za ispis
while (tekuci){
cout << "Maticni broj: " << tekuci -> mat_br << endl;
cout << "Prezime i ime: " << tekuci -> prez_ime << endl;
cout << "Godina upisa studija: " << tekuci -> god_upisa << endl;
cout << "---------------------" << endl;
tekuci = tekuci -> slijedeci; // kretanje kroz listu
}; // while
}; //ispisi_sve_elemente

Poziv metode:

lista->ispisi_sve_elemente(
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 232
Veleučilište u Rijeci

Metoda za pretraživanje liste


void pretrazi_listu(int mat_br){ //pretraživanje prema matičnom broju
int nadjen=0;
student *tekuci = this -> slijedeci;
while (tekuci){
if (tekuci -> mat_br == mat_br){
nadjen=1;
cout << "Maticni broj: " << tekuci -> mat_br << endl;
cout << "Prezime i ime: " << tekuci -> prez_ime << endl;
cout << "Godina upisa studija: " << tekuci -> god_upisa << endl;
cout << "---------------------" << endl; break;}; //if
tekuci = tekuci -> slijedeci;}; // while
if (!nadjen) cout<<"Element nije pronadjen u listi!"<<endl;
}; //pretrazi_listu

Poziv metode:
lista->pretrazi_listu(mat_br);
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 233
Veleučilište u Rijeci
Metoda za brisanje liste
void brisi_element(int mat_br){int nadjen=0;
student *brisi = this -> slijedeci, *prethodni = this;
while (brisi){
if (brisi -> mat_br == mat_br){
nadjen=1;
prethodni -> slijedeci = brisi -> slijedeci;
delete brisi; break; // izlaz iz petlje
}; // if
prethodni = brisi;
brisi = brisi->slijedeci;
}; // while
if (nadjen) cout << "Element je izbrisan iz liste!" << endl;
else cout << "Element nije pronadjen!" << endl;
}; //brisi element

Poziv metode:
lista->brisi_element(mat_br);
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 234
Veleučilište u Rijeci
Metoda za sortiranje liste uzlazno prema matičnom broju
void sortiraj_listu(){
student *prethodni,*tekuci,*slijedeci;
int indikator,brojac=0;
do{ indikator = 0;
tekuci=this->slijedeci;prethodni=this;
while (tekuci->slijedeci){
slijedeci=tekuci->slijedeci;
if (tekuci->mat_br > slijedeci->mat_br){
prethodni->slijedeci=slijedeci;
tekuci->slijedeci=slijedeci->slijedeci;
slijedeci->slijedeci=tekuci;
indikator=1;} //if
prethodni=tekuci;
tekuci=tekuci->slijedeci;} //while
} while (indikator==1);
}; // sortiraj listu
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 235
Poziv metode: lista-> sortiraj_listu();
Veleučilište u Rijeci
Metoda za dealokaciju liste

student *dealokacija_liste(){ //dealokacija liste


student *tekuci,*prethodni;
prethodni=this;
tekuci=this->slijedeci;
while (tekuci){
delete prethodni;
prethodni=tekuci;
tekuci=tekuci->slijedeci;
} //while
delete prethodni;
return NULL;
}; //dealokacija_liste

Poziv metode:
lista=lista->dealokacija_liste();
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 236
Veleučilište u Rijeci

Prijatelj klase
Prijatelj klase predstavlja izuzetak od pravila da
privatnim članovima klase mogu pristupati
isključivo metode iste klase.
Pojedina klasa može dodijeliti nekoj funkciji,
metodi neke klase ili čitavoj klasi pravo pristupa
vlastitim privatnim i zaštićenim članovima.
Takve funkcije, metode i klase nazivaju se
prijatelji klase, a označavamo ih pomoću ključne
riječi friend.
“prijateljstvo” klasa
12.1.2020. nije obostrano! 237
mr. sc. Jasminka Tomljanović, viši predavač
Veleučilište u Rijeci

class osnovna{

friend void funkcija1(); // funkcija1 je prijatelj klase osnovna


friend void kolega::fclan1(); // metoda fclan1 klase kolega,
friend class prijatelj; // kao i klasa prijatelj

private:
void privatna(){ // prijatelji klase mogu pozivati ovu metodu
cout << "Privatni funkcijski clan!" << endl;
};
};

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 238


Veleučilište u Rijeci

Nasljeđivanje
Nasljeđivanje je postupak kojim se iz postojeće
klase izvodi nova, tako da ta nova klasa:
zadržava (tj. nasljeđuje) sve atribute i metode
osnovne klase (osim privatnih)
implementacija metoda može se promijeniti
nova klasa može uključivati i druge članove, osim
naslijeđenih (polimorfizam)
moguće je da jedna klasa naslijedi više osnovnih
klasa (višestruko nasljeđivanje)

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 239


Veleučilište u Rijeci

pristup članovima osnovne klase iz objekata izvedene


klase definiran je odgovarajućim specifikatorom tipa
nasljeđivanja (private, protected ili public).
prava pristupa naslijeđenim članovima mogu biti
reducirana u odnosu na prava pristupa iz objekata
osnovnih klasa

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 240


Veleučilište u Rijeci

Primjer jednostavnog nasljeđivanja: vozila


UML – dijagram klasa

vozilo
godiste,tezina,
snaga_motora,
max_brzina

ispis()

automobil kamion autobus


nosivost broj_sjedala

ispis() ispis()

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 241


Veleučilište u Rijeci

jednostavnog nasljeđivanja: vozila


class vozilo{ // definira zajedničko za sva vozila
public:
int godiste, tezina, snaga_motora, max_brzina;
void ispis(){
cout << "Vozilo : " << endl;
cout << "Godiste : " << godiste << endl;}; //ispis
};
class automobil : public vozilo{}; //automobil nasljeđuje vozilo
class kamion : public vozilo{ //kamion nasljeđuje vozilo
public: //tip nasljeđivanja
int nosivost;
void ispis(){ // metoda ispis je redefinirana
cout << "Kamion : " << endl;
cout << "Godiste : " << godiste << endl;
cout << "Nosivost : " << nosivost << endl;};
};
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 242
Veleučilište u Rijeci

Zaštićeni članovi klasa


Zaštićeni članovi klasa (protected) mogu se nasljeđivati,
ali su dostupni još samo unutar klasa koje nasljeđuju
osnovnu klasu tj. nisu javno dostupni
Primjer:
class lista{
protected: lista *slijedeci; //za upotrebu u izvedenim klasama
}; //lista
class student:public lista{ //operator dodjele tipa
...

zadnji = (student*) zadnji->slijedeci;


};12.1.2020.
//student mr. sc. Jasminka Tomljanović, viši predavač 243
Veleučilište u Rijeci

Tipovi nasljeđivanja
Prava pristupa naslijeđenim članovima klasa mogu i
ne moraju biti ista kao u osnovnoj klasi, što je
određeno tipom nasljeđivanja:
javno nasljeđivanje (public) određuje da će svi
atributi i metode osnovne klase imati ista prava
pristupa iz izvedene klase kao i iz osnovne klase.
zaštićeno nasljeđivanje (protected) određuje da će
naslijeđeni članovi osnovne klase biti dostupni iz
izvedene klase, ali s najvišim pravom pristupa
protected (tj. svi javni članovi osnovne klase postat
će zaštićeni u izvedenoj).

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 244


Veleučilište u Rijeci

privatno nasljeđivanje (private) određuje da će svi


naslijeđeni članovi osnovne klase u izvedenoj klasi
imati pravo pristupa private (tj. bit će privatni u toj
klasi i neće se moći dalje nasljeđivati).

specifikacija zaštićenog nasljeđivanja


class izvedena : protected osnovna{
...
};
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 245
Veleučilište u Rijeci

osnovna

public: void fpub()


private: void fpriv()
protected: void fprot()

klasa_public klasa_private klasa_protected

izv_public izv_protected
izv_private

public: void public: void


fklasa_public() public: void fklasa_private() fklasa_protected()
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 246
Veleučilište u Rijeci

Višestruko nasljeđivanje

klasa_prva klasa_druga

void ispis(kilometraza,
int kilometraza, godina godina)

klasa_izvedena

void ispis()

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 247


Veleučilište u Rijeci

Virtualne metode i polimorfizam


Problem objektnog programiranja je visoki
stupanj tipizacije što zahtijeva mehanizam
automatske konverzije tipova
Polimorfizam omogućuje jednostavnije rukovanje
heterogenim strukturama podataka
koristi mehanizam virtualnih metoda i kasnog
povezivanja (eng. late binding)

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 248


Veleučilište u Rijeci

Primjer: Vozila
različita vozila (npr. automobili, autobusi i kamioni)
predstavljaju objekte iz različitih klasa s jednom
osnovnom klasom koju nasljeđuju (vozilo)
zadana struktura podataka (ovdje vezana lista) sadrži
objekte iz sve tri klase
da li je moguće prijeći cijelu strukturu (ovdje vezanu
listu) pomoću istog pokazivača (npr. iz klase vozilo)?
ako svaka od klasa koje se odnose na vozila definira
vlastitu metodu za ispis podataka, da li je moguće
preko pokazivača iz klase vozilo pozvati odgovarajuću,
tako da se ispišu podaci za odgovarajuću vrstu vozila?
12.1.2020. //kasno povezivanje249
mr. sc. Jasminka Tomljanović, viši predavač
Veleučilište u Rijeci

korištenje virtualnih metoda u osnovnoj klasi


znači da će se kod poziva odgovarajuće metode
koristiti mehanizam kasnog povezivanja koji će
prepoznati tip (klasu) odgovarajućeg objekta (iz
klase koja nasljeđuje osnovnu) i pozvati
odgovarajuću metodu

12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 250


Veleučilište u Rijeci

Apstraktna klasa
Apstraktna klasa je klasa iz koje se ne može
instancirati objekt, nego služi samo kao osnova za
nasljeđivanje
da bi klasa bila apstraktna, mora sadržavati barem
jednu čistu virtualnu metodu
Primjer:
class apstraktna{
public:
int kilometraza,godina;
virtual void unos()=NULL; //čiste virtualne metode
virtual void ispis()=NULL;};
pokazivač na funkciju
12.1.2020.
dobiva vrijednost NULL
mr. sc. Jasminka Tomljanović, viši predavač 251
Veleučilište u Rijeci

Primjer:
class apstraktna{
public:
int kilometraza,godina;
virtual void unos()=NULL; //čiste virtualne metode
virtual void ispis()=NULL;};

pokazivač na funkciju dobiva vrijednost


NULL, što znači da ne postoji implementacija
te funkcije (metode)
12.1.2020. mr. sc. Jasminka Tomljanović, viši predavač 252

You might also like