161
Uvod u OOP – vežbe C++ i Java Vežbe iz predmeta Uvod u objektno-orijentisano programiranje, I god. II semestar. Školska 2012/2013

Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

  • Upload
    others

  • View
    3

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

Uvod u OOP – vežbe C++ i Java

Vežbe iz predmeta Uvod u objektno-orijentisano programiranje, I god. II semestar. Školska

2012/2013

Page 2: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

1

Programski jezik C++

1. Razlike C i C++-a neobjektne prirode

Zadatak 1. 1

Implementirati funkciju max koja daje maksimalni element celobrojnog niza, maksimum dva

cela broja, maksimalni od dva stringa, "maksimalni" od dva karaktera, za jedan string karakter

sa najvećom vrednošću unutar stringa.

_____________________________________________________________________________

#include <iostream> #include <string.h> using namespace std; int max(int *,int); inline int max(int,int); char * max(char *, char *); inline char max(char,char); char max(char*); void main(){ int a[]={1,5,4,3,2,6},n=6; cout<<max(a,n)<<endl; cout<<max("string","program")<<endl; cout<<max('a','A')<<endl; cout<<max(2,5)<<endl; cout<<max("string"); } int max(int *a,int n){ int m; m=a[0]; for(int i=1;i<n;i++) if(a[i]>m) m=a[i]; return m; } inline int max(int a,int b){ return a>=b?a:b; } char * max(char *a,char *b){ if(strcmp(a,b)>=0) return a; else return b; } inline char max(char a,char b){ return a>=b?a:b; } char max(char *a){ char m; int i; m=a[0]; i=1; while(a[i]!='\0') { if(a[i]>m)

Page 3: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

2

m=a[i]; i++; } return m; }

_____________________________________________________________________________

U ovom zadatku je ilustrovana upotreba inline funkcija i preklapanje imena funkcija. Na

samom početku je potrebno obratiti pažnju na korišćenje biblioteke iostream.h kako bi se

omogućila upotreba naredbi za unos i očitavanje podataka cin>> i cout<<, respektivno. Funkcije

su realizovane redosledom kojim su navedene u postavci zadatka. U samoj deklaraciji funkcija ne

uočavaju se razlike u odnosu na programski jezik C, osim kod funkcija za poređenje dva cela broja

i dva karaktera. Ove funkcije su realizovane kao inline funkcije što znači da će prilikom svakog

pozivanja neke funkcije ista biti ugrađena u kod. Iz same definicije inline funkcije se može

zaključiti da je potrebno voditi računa o tome koja će funkcija biti realizovana kao takva. Naime,

kao inline se realizuju samo one funkcije koje su veoma jednostavne te bi vreme koje je potrebno

za prenos podataka programa na stek, prosleđivanje stvarnih argumenata funkciji, a nakon

izvršavanja programa brisanje podataka koji pripadaju funkciji i uzimanje podataka sa steka, bilo

duže od izvršavanja same funkcije. Ključna reč inline ispred zaglavlja funkcije govori kompajleru

da je u pitanju inline funkcija. Primjećujemo da sve funkcije imaju isto ime, što u programskom

jeziku C nije bilo moguće. U C++ je moguće funkcijama koje obavljaju srodne radnje, nad

različitim tipovima podataka, dati ista imena. Za svaki tip i broj podataka je potrebno zasebno

realizovati funkciju. Ovde se mora voditi računa da se sve funkcije razlikuju po broju ili tipu

argumenata, kako ne bi nastupila dvosmislenost prilikom njihovog pozivanja što bi izazvalo

grešku pri kompajliranju, o čemu će biti reči u nekom od kasnijih primera.

Prva funkcija, za određivanje maksimalnog elementa niza, je realizovana na isti način kao što bi

se to odradilo u programskom jeziku C. Niz je prosleđen preko pokazivača, kako se radi o nizu

celih brojeva prosleđen je i broj elemenata niza. U funkciji se prvi element niza proglašava za

najveći, zatim se, u for petlji, vrši pretraživanje niza od drugog do poslednjeg elementa. Svaki

element se poredi sa trenutno maksimalnim i ukoliko je veći od njega proglašava se

maksimalnim. Kao rezultat se vraća vrednost promenljive m u kojoj je smeštena vrednost

maksimalnog elementa niza. Treba obratiti pažnju na zaglavlje for petlje, u njemu postoji jedna

razlika u odnosu na programski jezik C. Naime, u C++ je moguće izvršiti definiciju promenljive u

okviru prvog izraza u naredbi for. Doseg tako uvedene promenljive je do kraja tela te for petlje {}.

Nakon njenog izvršavanja, tako definisana promenljiva više ne postoji.

Druga funkcija, koja daje maksimum dva cela broja, je realizovana kao inline. Kompajler

to zna zbog navođenja ključne reči inline ispred standardnog zaglavlja ove funkcije. Za njenu

realizaciju smo koristili ternarni operator ? : koji ispituje da li je a veće od b, ako jeste kao

rezultat funkcije se vraća a a u suprotnom b.

Treća funkcija upoređuje dva stringa i vraća pokazivač na veći od njih. Kao i u

programskom jeziku C, i ovde je string realizovan kao niz karaktera. Poređenje se vrši funkcijom

strcmp() čija se upotreba ne razlikuje u odnosu na programski jezik C a omogućena je

uključivanjem bibloteke string.h.

Funkcija za poređenje dva karaktera je, zbog svoje jednostavnosti, realizovana kao inline.

Page 4: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

3

Narednom funkcijom se traži karakter sa najvećom vrednošću u stringu. Ovde je

iskorišćena činjenica da se string realizuje kao niz karaktera i da se kraj tog niza označava kao

’\0’, tako da funkciji nije potrebno proslijeđivati dužinu niza već se u njoj brojač i postavlja na 0 i

inkrementira u petlji sve dok ne dođe do kraja niza ’\0’.

Primer rada programa

_____________________________________________________________________________

6

string

a

5

t

_____________________________________________________________________________

Protumačiti za koji poziv u glavnom programu će se izvršiti koja funkcija. Vidimo da sve funkcije

izvršavaju blisku radnju, traženje maksimuma, i da je samimim tim preklapanje imena funkcija

potpuno opravdano.

Zadatak 1.2

Postoje najave funkcija:

int f(int,char='0');

int f(char,char);

int f(double);

Da li će sledeći pozivi izazvati sintaksu grešku i koja će funkcija biti izvršena?

b=f('0');

b=f(2.34);

c=f('c',3);

Obrazložiti.

_____________________________________________________________________________

Uočimo da i ovde sve funkcije imaju isto ime. Iskoristili smo još jednu novinu

programskog jezika C++, a to je da funkcije mogu imati podrazumevane vrednosti za neke

formalne argumente. Ovo znači da prvu funkciju iz našeg primera možemo pozvati sa samo

jednim stvarnim argumentom, pri čemu će se za vrednost drugog argumenta uzeti

podrazumevana vrednost. Ukoliko navedemo dva argumenta u pozivu funkcije, za vrednost

drugog argumenta se uzima navedena, a ne podrazumevana vrednost. S obzirom da u našem

programu sve funkcije imaju isto ime, na osnovu ranije navedenog, znamo da će se razrešavanje

prilikom poziva funkcije izvršiti na osnovu tipova stvarnih argumenata. Posmatramo kojoj funkciji

najbolje odgovaraju argumenti za koje je pozvana.

Page 5: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

4

Prvi poziv kao stvarni argument ima tip char. Prvi argumet u drugoj funkciji jeste tipa char ali se

ona ne može izvršiti za ovaj poziv, jer se funkcija poziva sa samo jednim stvarnim argumentom a

ona očekuje dva, jer drugi nema podrazumevanu vrednost. Za jedan argument se mogu pozvati

prva i treća funkcija. S obzirom da postoji standardna konverzija iz tipa char u tip int izvršiće se

prva funkcija. Poziv će, zapravo, biti f('0','0').

Drugim pozivom će se, bez sumnje, izvršiti poslednja funkcija. Naime, jedino ova funkcija

ima float argument.

Kod trećeg poziva je veći problem jer i prva i druga funkcija mogu da odgovaraju prvom

argumentu (bolje odgovara druga funkcija) ali drugi argument ne odgovara ni jednoj funkciji tako

da će doći do greške u programu.

Zadatak 1. 3

Dat je niz celobrojnih elemenata. Kreirati funkciju koja po defaultu okreće elemente niza

"naopačke", a ako je specificiran celi broj veći od nula formira novi niz koji predstavlja

elemente starog niza od prvog sa datim preskokom do kraja, a za negativan broj ide od

poslednjeg elementa niza ka početku sa odgovarajućim preskokom.

_____________________________________________________________________________

#include <iostream> #include <conio.h> using namespace std; int uredi(int *, int,int *,int=-1); main(){ int a[]={2,3,2,1,5},c; int i, b=5, * r; r=new int[b]; c=uredi(a,b,r); for(i=0;i<c;i++) cout<<r[i]; cout<<endl; c=uredi(a,b,r,2); for(i=0;i<c;i++) cout<<r[i]; cout<<endl; c=uredi(a,b,r,-2); for(i=0;i<c;i++) cout<<r[i]; cout<<endl; delete []r; r=0; getch(); } int uredi(int *a, int n,int *c, int m){ int j=0; if(m>0) for(int i=0;i<n;j++,i+=m) c[j]=a[i]; else for(int i=n-1;i>=0;j++,i+=m) c[j]=a[i]; return j; }

Page 6: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

5

_____________________________________________________________________________ Treba obratiti pažnju da se i u ovom zadatku, kao i u prethodnom, podrazumevani

argumenti nalaze na kraju. Naime, ukoliko imamo podrazumevanu vrednost formalnog

argumenta, nakon njega sme biti samo argument sa podrazumevanom vrednošću. Ovo je i

logično, jer će se prilikom poziva funkcije stvarni argumenti dodjeljivati formalnim onim

redoslijedom kojim su ispisani. Prilikom odlučivanja koju vrednost da uzmemo kao default,

iskoristili smo činjenicu da obrtanje elemenata niza "naopačke", u stvari, jeste formiranje novog

niza od poslednjeg ka prvom elementu sa preskokom 1, minus govori da se počne od kraja niza.

Funkcija za preuređivanje je realizovana tako što joj se šalje pokazivač na niz koji treba

preurediti, broj njegovih elemenata i pokazivač na početak niza u koji ćemo smjestiti preuređene

elemente. Kao rezultat se vraća broj elemenata novonastalog niza. U glavnom programu se vrši

dinamičko zauzimanje memorije, na isti način kao ranije. U funkciji se postavlja brojač j na nulu,

zatim se proverava da li treba uzimati elemente od početka (m>0) ili kraja niza (m<0). U oba

slučaja se za preskok koristi naredba i+=. U prvom slučaju će to povećavati indeks i za m a u

drugom umanjivati jer je m negativno. j predstavlja broj elemenata novog niza.

U ovom programu se koristi naredba cout<<endl, која predstavlja prelazak u novi red. Može se, i

dalje, koristiti cout<<'\n'.

Obratite pažnju da je vrednost podrazumevanog argumenta navedena samo u zaglavlju funkcije

prilikom njegove deklaracije. Naime, podrazumevana vrednost se ne može redefinisati, čak ni u

istu vrednost. Ovo znači da, kada imamo odvojeno deklaraciju i definiciju funkcije,

podrazumevanu vrednost navodimo samo u deklaraciji a ne i u kompletnoj definiciji funkcije.

U našem primeru se vrši dinamička alokacija memorije. Za to smo koristili operator new. r=new

int[b]; govori kompajleru da želimo da zauzmemo memoriju u koju može da se smjesti niz od b

elemenata cjelobrojnog tipa, kao i da vrednost pokazivača na početak te memorije smještamo u

promenljivu r. Na kraju programa je potrebno osloboditi memoriju koju je niz zauzimao. Za to

koristimo operator delete (delete []r;). Uglaste zagrade pre pokazivača p se koriste uvek kada

imamo niz, tako govorimo da je potrebno osloboditi memoriju koju je zauzeo cio niz a ne samo

prvi element. Nakon ovog, pokazivač r će i dalje sadržati adresu prvog elementa niza čiji smo

sadržaj upravi izbrisali. To nikako nije poželjno jer nam pokazivač pokazuje na nešto što više ne

postoji. Naredbom r=0 ostavljamo ga u ispravnom, praznom, stanju. Ne ukazuje ni na jednu

memorijsku adresu. Kada bismo u glavnom programu zahtevali da se prvo stvara novi niz sa

preskokom 2 od početka, a nakon toga sa preskokom 3 od kraja, ukoliko isčitamo sve elemente

drugog niza (ima ih 3) u drugom slučaju bi kao treći imali element 5, koji ne bi trebalo da bude

deo tog niza. Zašto je došlo do toga i kako to da eliminišemo? Zašto smo u funkciji uredi(...)

definisali promenljivu j van zaglavlja for petlje? Da smo je deklarisali kada i promenljivu i da li bi

nam nakon izvršavanja for petlje bila sačuvana vrednost koja se nalazi u njoj? Da li bi ta

promenljiva bila definisana nakon izvršavanja petlje.

Primer rada programa

_____________________________________________________________________________

51232

Page 7: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

6

225

522

_____________________________________________________________________________

Zadatak 1. 4

Napisati program za računanje težine tela. Ako je zadat jedan argument računati težinu na

površini zemlje Q=m*9.81, ako su zadata dva argumenta računati na visini r iznad zemlje:

Q=6.672*10-11

*m*4.9156*1024

/(6371377+r)2; a ako je zadato m, r i M težinu na rastojanju r od

planete mase M: Q=6.672*10-11

*m*M/r2.

_____________________________________________________________________________

#include <iostream> using namespace std; float tezina(int); float tezina(int,int); float tezina(int,int,int); main(){ int n, m, M, r; cout<<"Koliko argumenata zelite da unesete?"<<endl; cin>> n; if(n==1){ cin>>m; cout<<tezina(m)<<endl; } else if(n==2){ cin>>m>>r; cout<<tezina(m,r)<<endl; } else { cin>>m>>r>>M; cout<<tezina(m,r,M)<<endl; } } float tezina(int a){ const float k=9.81; return a*k; } float tezina(int a, int b){ const float k=6.672*pow(10,-11)*4.9156*pow(10,24), k1=6371377; return k*a/pow((k1+b),2); } float tezina(int a, int b, int c){ const float k=pow(10,-11)*6.672; return k*a*c/pow(b,2); }

_____________________________________________________________________________

Ovde se, na samom početku, mora zapaziti da je nemoguće uspostaviti vezu između ova tri

načina za računanje težine tela, tako da realizacija sa podrazumevanim parametrima odmah

otpada. Funkcije obavljaju srodnu aktivnost pa će se iskoristiti mogućnost preklapanja imena. Što

se tiče same realizacije pojedinih funkcija, ne postoji razlika u odnosu na programski jezik C.

Page 8: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

7

Primer rada programa

_____________________________________________________________________________

Koliko argumenata zelite da unesete?

1

60

588.6

Koliko argumenata zelite da unesete?

2

60

2

484.74

_____________________________________________________________________________

2. Klase

Zadatak 2. 1

Projektovati klasu sa elementarnim operacijama nad kompleksnim brojevima (sabiranje,

oduzimanje).

_____________________________________________________________________________

#include <iostream> using namespace std; class complex{ float imag, real; public: void cUcitaj(float, float); complex cSab(complex); complex cOduz(complex); float cRe()const {return real;}; float cIm()const {return imag;}; }; void complex::cUcitaj(float a, float b){ real=a; imag=b; } complex complex::cSab(complex a){ complex priv; priv.real=real+a.real; priv.imag=imag+a.imag; return priv; } complex complex::cOduz(complex a){ complex priv; priv.real=real-a.real; priv.imag=imag-a.imag; return priv; }

Page 9: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

8

main(){ complex c1, c2, c3; float a, b; cout<<"Unesi vrednost za realni i imaginarni deo c1"<<'\n'; cin>>a>>b; c1.cUcitaj(a,b); cout<<"Unesi vrednost za realni i imaginarni deo c2"<<'\n'; cin>>a>>b; c2.cUcitaj(a,b); c3=c1.cSab(c2); cout<<"Zbir dva data kompleksna broja je"<<"("<<c3.cRe()<<","\ <<c3.cIm()<<")"<<endl; c3=c1.cOduz(c2); cout<<"Razlika dva data kompleksna broja je"<<"("<<c3.cRe()<<","\ <<c3.cIm()<<")"<<endl; }

_____________________________________________________________________________

U ovom zadatku je prvo izvršena definicija klase. Na početku ove definicije se nalazi

rezervisana reč class, nakon ove reči pišemo identifikator, odnosno ime klase. Između vitičastih

zagrada se nalazi deklaracija promjenjivih i funkcija, a može biti i definicija neke funkcije.

Obavezno je nakon vitičastih zagrada staviti ; jer to govori kompajleru da smo završili definiciju

klase i da nakon toga možemo definisati pojedine funkcije članice. Koji će članovi klase i funkcije

biti vidljivi van klase određuju rezervisane reči public i private. Ukoliko ih nema podrazumeva se

da su svi podaci članovi i funkcije članice privatni. Praksa je da se podaci članovi postavljaju za

privatne a funkcije članice za javne. U ovom primeru je tako učinjeno. Iz primera se vidi da će ako

se ne navede ključna reč private, početni deo klase, pre prve rezervisane reči public, biti privatan.

Dobra programerska praksa je da se uvek eksplicitno navede koji je deo klase privatan. Klasa,

zapravo, predstavlja korisnički definisan tip podataka. Isto kao za ugrađene tipove podataka i za

ovaj, korisnički definisan, možemo uvoditi instance, primerke tog tipa. Primerak klase je objekat i

dekleriše se isto kao i primerak ugrađenog tipa, navođenjem identifikatora tipa, complex, a

nakon njega identifikatora za konkretan primerak tog tipa complex c1,c2,c3;. Mi ovde želimo

definisati tip podataka koji će imati osobine kompleksnih brojeva. Znači, želimo omogućiti

dodeljivanje vrednosti kompleksnom broju, očitavanje njegovog realnog i imaginarnog dijela, kao

i sabiranje dva kompleksna broja. S obzirom da smo promenljive koje predstavljaju realni i

imaginarni deo kompleksnog broja realizovali kao privatne podatke članove, za izvršavanje ranije

navedenih operacija potrebno je realizovati odgovarajuće funkcije članice klase, one imaju pravo

da pristupaju podacima članovima iste klase koji su privatni. U našem programu imamo 6

funkcija članica. Prva služi za inicijalizaciju objekta klase complex (primeraka klase) i ona će

dodeliti odgovarajuće vrednosti podacima članovima objekta za koji je pozvana. Vidimo da

funkcije članice pored svojih formalnih argumenata sadrže i podrazumevani argument a to je

objekat za koji su pozvane (odnosno pokazivač na taj objekat). Članovima tog objekta može da se

pristupa navođenjem samo identifikatora (imena) podatka člana. Naime, u ovoj funkciji smo

dodeljivanje vrednosti realnom dijelu objekta, za koji ćemo je pozvati, izvršili naredbom real=a;

(na isti način smo odradili i za imaginarni deo). Sada pogledajmo što će se, zapravo, desiti kada u

glavnom programu pozovemo funkciju c1.cUcitaj(a,b);. Mi smo ovu funkciju pozvali za konkretan

objekat c1 pa će se pristupati njegovom podatku članu real. Dakle, funkcija može direktno, bez

navođenja imena objekta kojem pripadaju, da pristupa članovima objekta za koji je pozvana. Iz

tog razloga kada je potrebno obaviti neku radnju samo sa jednim objektom nema potrebe da se

šalje taj objekat kao argument funkcije, funkcija može da pristupa njegovim podacima direktno.

Page 10: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

9

Ukoliko želimo da obavimo neku radnju nad više objekata uvek šaljemo za jedan manje, jer će

objekat za koji pozivamo funkciju biti dostupan samim pozivom te funkcije a ostale moramo

poslati kao argumente funkcije. Funkcija cSab() vrši sabiranje dva kompleksna broja. Rezultat je

tipa complex jer je zbir dva kompleksna broja takođe kompleksan broj. Sada je kao argument

potrebno poslati jedan objekat (jedan kompleksan broj) dok će se članovima drugog, za koji je

funkcija pozvana, moći pristupiti direktno. Naime, naredbom c3=c1.cSab(c2); (u glavnom

programu) vršimo sabiranje dva kompleksna broja c1 i c2, pri čemu smo c2 poslali kao stvarni

argument a podacima objekta c1 smo mogli direktno pristupiti, pokazivač na njega this je

implicitni argument ove funkcije. Obratiti pažnju da argumenti kao i rezultati funkcije članice

mogu biti tipa complex.

Kada se vrši realizacija funkcije izvan definicije klase, klasa kojoj pripada funkcija se mora

naglasiti u zaglavlju funkcije navođenjem imena klase nakon kojeg imamo operator dosega ::. Na

ovaj način kompajler zna da je funkcija čije ime navodimo posle :: članica date klase. Ukoliko je

neka funkcija realizovana u okviru definicije klase biće implicitno inline. Kod nas su to funkcije

cRe() i cIm(). Vidimo da će ove funkcije vratiti vrednost realnog i imaginarnog dijela kompleksnog

broja (objekta) za koji su pozvane. (Napomenimo, još jednom, da se ovo mora učiniti na ovaj

način jer ukoliko nam bude potreban realan deo objekta c3 u glavnom programu mu ne možemo

pristupiti naredbom c3.real; jer je real privatan podatak klase complex i njemu ne možemo

pristupati direktno.). Nakon navođenja liste parametara ovih funkcija imamo rezervisanu reč

const što znači da je data funkcija inspektor, ne menja stanje objekta klase, dok mutatori

menjaju. Realizacija funkcije cOduz() je izvršena veoma slično kao i funkcije za sabiranja pri čemu

je praćena logika oduzimanja kompleksnih brojeva jer je nama cilj da modeliramo kompleksne

brojeve.

U glavnom programu, prilikom očitavanja rezultata sve naredne nisu stale u jedan red pa

smo ih prebacili u drugi iz pomoć \. Ovim je kompajleru dato na znanje da sve naredbe koje slede

nakon ovog znaka pripadaju prethodnom redu. Važno je zapamtiti da ukoliko imamo funkciju bez

argumenata koje joj eksplicitno šaljemo, kao kod nas cIm() i cRe(), moramo, uvek, prilikom

njihovog pozivanja navoditi zagrade posle identifikatora te funkcije, jer ukoliko bismo napisali

cRe a ne cRe(), kompajler bi mislio da nam je to identifikator za promenljivu a ne za funkciju i

javio bi grešku.

Primer rada programa

_____________________________________________________________________________

Unesi vrednost za realni i imaginarni deo c1

1 2.5

Unesi vrednost za realni i imaginarni deo c2

-3 8.9

Zbir dva data kompleksna broja je(-2,11.4)

Razlika dva data kompleksna broja je(4,-6.4)

_____________________________________________________________________________

Page 11: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

10

Zadatak 2.2

Projektovati klasu sa elementarnim operacijama nad tačkama u ravni (računanje udaljenosti

zadate tačke od koordinatnog početka, rastojanja dve tačke). U glavnom programu uneti

podatke za dve tačke a dati na izlazu koordinate tačke koja je na većem rastojanju od

koordinatnog početka i rastojanje te dve tačke. Koordinate tačke su privatni članovi klase.

_____________________________________________________________________________

#include <iostream> #include <math.h> using namespace std; class tacka{ double x, y; public: void pravi(double a, double b){x=a;y=b;} double aps()const{return x;} double ord() const{return y;} double poteg()const; double rastojanje(tacka) const; void ispisi() const; }; double tacka::poteg()const{ return sqrt(pow(x,2)+pow(y,2)); } double tacka::rastojanje(tacka a)const{ return sqrt(pow(x-a.x,2)+pow(y-a.y,2)); } void tacka::ispisi()const{cout<<"("<<x<<","<<y<<")"<<"\n";} void main(){ int n; tacka t1; cout<<" Unesite koordinate prve tacke "<<endl; double x, y; cin>>x>>y; t1.pravi(x,y); tacka t2; cout<<" Unesite koordinate druge tacke "<<endl; cin>>x>>y; t2.pravi(x,y); cout<<"Koordinate dalje tacke su: "; t1.poteg()>t2.poteg()?t1.ispisi():t2.ispisi(); cout<<"Rastojanje zadatih tacaka je: "<<t1.rastojanje(t2)<<'\n'; }

_____________________________________________________________________________

U ovom primeru želimo da definišemo korisnički tip tačka koji će imati neke od osobina tačaka

u Dekartovom koordinatnom sistemu. Zaglavlje za matematičku biblioteku <math.h> je

uključeno jer se koriste matematičke funkcije. Klasa tacka ima dva privatna podatka člana tipa

double. Rad sa ovim podacima omogućen je funkcijama članicama. Iako u postavci zadatka nije

eksplicitno navedeno da je potrebno praviti prve tri funkcije, morali smo ih formirati kako bismo

mogli zadovoljiti zahtjeve iz glavnog programa. Ne možemo pristupiti privatnim podacima iz

glavnog programa neposredno, već je potrebno za to imati funkciju koja ima pravo pristupa. U

ovom slučaju je to funkcija članica pravi(), koja zapravo inicijalizuje podatke članove na željenu

Page 12: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

11

vrednost. Ova funkcija je definisana u okviru definicije klase pa će biti realizovana kao inline, što

je i opravdano s obzirom da nije pretjerano komplikovana, svega dve mašinske instrukcije. Kao

argument joj šaljemo dva podatka tipa double, koja će ona dodeliti podacima x i y, objekta za koji

je budemo pozvali u glavnom programu t1 i t2. Rezultat joj je void to jest ne vraća ništa, iako je,

zapravo, rezultat objekat za koji je pozvana sa novododijeljenim vrednostima. Ovo je i logično

ako se posjetimo da svaka funkcija članica ima sakriveni argument this koji je pokazivač na

objekat za koji je pozvana pa, kao što ga nije potrebno slati, nije ga potrebno ni vraćati. Sve će se

radnje nad podacima članovima objekta za koji je funkcija pozvana automatski odraziti na njih jer

je ovaj objekat, implicitno, poslat po referenci. Funkcije aps() i ord() nam daju podatak o apscisi i

ordinati odgovarajuće tačke, objekta za koji su pozvane. Obratiti pažnju na rezervisanu reč const

u zaglavlju nekih funkcija članica. Podsjetiti se iz prethodnog primera šta ona znači. Funkcija

poteg() računa rastojanje tačke od koordinatnog početka po poznatoj formuli i vraća ga kao

rezultat funkcije tipa double. Funkcija rastojanje() računa rastojanje dve tačke, zadate

koordinatama x i y. Jednu tačku šaljemo kao argument funkcije a elementima druge možemo

direktno pristupiti, tačka za koju pozivamo funkciju. Ovde smo realizovali i funkciju ispisi() za

ispisivanje koordinata tačaka u formatu koji se najčešće koristi u matematici a(x,y). U principu bi i

bez ove funkcije mogli ispisati koordinate odgovarajuće tačke ali bi tada morali pozivati dve

funkcije i stalno voditi računa o formatiranju pa je preporučljivo uvek imati funkciju za ispis

podataka klase koju formiramo. Ova funkcija ne vraća rezultat.

U glavnom programu smo uveli (deklarisali) objekat t1 klase tacka, zatim smo, nakon unošenja

koordinata tačaka u dve promenljive tipa double, poslali te dve promenljive kao argumente

funcije pravi() naredbom t1.pravi(x,y);. Rekli smo kompajleru da se u ovoj funkciji direktno

pristupa podacima članovima objekta t1. Na isti način smo formirali objekat t2 i dodijelili mu

vrednost. Naredba t1.rastojanje(t2) šalje funkciji kao stvarni argument objekat t2 dok se

podacima objekta t1 direktno pristupa. Koristeći odgovarajuću funkciju članicu ispisali smo

koordinate tačke koja je udaljenija od koordinatnog početka.

Primer rada programa

_____________________________________________________________________________

Unesite koordinate prve tacke

2.3 4

Unesite koordinate druge tacke

3 1.2

Koordinate dalje tacke su: (2.3,4)

Rastojanje zadatih tacaka je: 2.88617

_____________________________________________________________________________

Zadatak 2.3

Prepraviti zadatak 5 tako da sadrži konstruktore.

_____________________________________________________________________________

# include <iostream>

Page 13: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

12

using namespace std; class complex{ float imag, real; public: complex(){}; complex(float, float); complex cSab(complex); complex cOduz(complex); float cRe()const {return real;}; float cIm()const {return imag;}; }; complex::complex(float a, float b):real(a),imag(b){} complex complex::cSab(complex a){ complex priv; priv.real=real+a.real; priv.imag=imag+a.imag; return priv; } complex complex::cOduz(complex a){ complex priv; priv.real=real-a.real; priv.imag=imag-a.imag; return priv; } main(){ float a, b; cout<<"Unesite vrednost za realni i imaginarni deo c1"<<'\n'; cin>>a>>b; complex c1(a,b); cout<<"Unesite vrednost za realni i imaginarni deo c2"<<'\n'; cin>>a>>b; complex c2(a,b); complex c3; c3=c1.cSab(c2); cout<<"Zbir dva data kompleksna broja je "<<"("<<c3.cRe()<<","\ <<c3.cIm()<<")"<<endl; c3=c1.cOduz(c2); cout<<"Razlika dva data kompleksna broja je "<<"("<<c3.cRe()<<","\ <<c3.cIm()<<")"<<endl; }

_____________________________________________________________________________

Kao što se vidi i iz postavke, ova klasa se razlikuje od klase u zadatku 5 samo po tome

što sadrži konstruktore. Konstruktor je funkcija članica klase koja se koristi za automatsku

inicijalizaciju primeraka svoje klase u momentima formiranja tih primeraka. Konstruktor će

biti pozvan automatski svaki put kada bude deklarisan objekat određene klase ili kada je

kreiran na bilo koji drugi način. Data klasa može imati više konstruktora, bez obzira na to

koliko ih ima svi moraju imati isti identifikator (ime) kao i klasa kojoj pripadaju. Primetimo da

se konstruktor razlikuje od ostalih funkcija i po tome što nema označen tip rezultata, to je s

toga što on i nema rezultat koji vraća, nije dozvoljena ni upotreba reči void za označavanje

tipa rezultata koji se vraća. Ukoliko ne definišemo nijednog konstruktora kompajler će sam

definisati podrazumevanog (default). Međutim, ukoliko definišemo makar jednog, moramo i

podrazumevanog jer bi inače naredbe tipa complex c3; koje pozivaju podrazumevanog

Page 14: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

13

konstruktora tj. konstruktora bez argumenata, izazvale grešku u kompajliranju. Podsjetimo se

da se bez argumenata može pozvati i funkcija koja ima sve argumente sa podrazumevanim

vrednostima tako da se default konstruktor može realizovati i na taj način, u tom slučaju

ćemo prilikom deklaracije izvršiti i inicijalizaciju datog objekta (dodeljivanje nekih početnih

vrednosti podacima članovima) dok bi deklaracija podrazumevanim konstruktorom, koji nije

realizovan sa podrazumevanim vrednostima argumenata, samo zauzela prostor u memoriji za

njegove podatke, bez dodeljivanja smislenog sadržaja. U zavisnosti od potreba u narednim

primerima ćemo koristiti jedan ili drugi tip realizacije podrazumevanog konstruktora. I za

konstruktore, kao i ostale funkcije članice, važi da će biti realizovani kao inline funkcije ukoliko

su definisani unutar definicije klase. Ukoliko se definišu van definicije klase potrebno je

koristiti ime klase i operator dosega:: kao i kod običnih funkcija članica. U našem slučaju to bi

značilo da je potrebno pisati za drugog konstruktora complex::complex(float a, float

b):real(a),imag(b){}. Prva reč complex ukazuje na to da želimo definisati funkciju članicu te

klase a drugo complex nakon operatora :: govori da je u pitanju konstruktor (ima isto ime kao

klasa kojoj pripada, svojstvo konstruktora). Vidimo da je iskorišćen nov način definicije

funkcije, takozvano navođenje inicijalizacione liste. Ova lista se piše odmah nakon liste

parametara a kompajleru se najavljuje postavljanjem :. Ovde vidimo da će podatak član real

biti inicijalizovan vrednošću a, real(a), na isti način imamo imag(b). Iako smo inicijalizaciju

izvršili van tela funkcije, i ova funkcija nema nijednu naredbu u njemu, svaka funkcija mora

imati telo funkcije. Znači, nakon liste inicijalizatora mora postojati telo funkcije iako u njemu

nema nijedne naredbe, što znači da moramo postaviti vitičaste zagrade, koje označavaju telo

funkcije. Konstruktor se može definisati na isti način kao i sve funkcije. U ovom slučaju bi to

bilo complex::complex(float a, float b){real=a; imag=b;}, može se koristiti i kombinacija ova

dva načina: na primer complex::complex(float a, float b):real(a){imag=b;}. Moramo se odlučiti

samo za jednu od ovih realizacija jer bi ukoliko koristimo više različitih realizacija istog

konstruktora u jednoj klasi došlo do greške. Naime, konstruktori su ovde funkcije sa

preklopljenim imenima pa i za njih važi da moraju imati argumente takve da kompajler

nedvosmisleno zna za koji poziv koju funkciju da realizuje. Ovde bi svi konstruktori bili pozvani

sa dva argumenta tipa float i kompajler bi javio grešku. Mi ćemo, kad god je to moguće,

koristiti novo uvedeni način definisanja konstruktora. On se mora koristiti ukoliko naša klasa

poseduje podatke članove koji su delarisani kao const, njima nije moguće dodeliti neku

vrednost koristeći operator dodele pa se to mora učiniti na ovaj način, ista stvar važi i kada

kao podatak imamo referencu.

Page 15: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

14

Konstruktori se ne pozivaju na isti način kao obične funkcije članice. Pogledajmo naredbu

complex c1(a,b); u glavnom programu. Ovom naredbom se poziva drugi konstruktor, koji

očekuje dva argumenta tipa float. Podsjetimo se, neku od funkcija članica bi pozvali

narednom, na primer, c1.cRe(). Znači ime objekta, operator . pa ime funkcije. Konstruktor se

može pozvati samo prilikom inicijalizacije novog objekta i poziva se tako što pišemo ime

novog objekta i u zagradama parametre kojima ćemo ga inicijalizovati, koji se moraju

poklapati sa onima koje konstruktor očekuje. Drugi način pozivanja konstruktora bi bio bez

navođenja parametara u zagradama complex c1; ovom naredbom bi se pozvao

podrazumevani konstruktor koji bi formirao promenljivu c1. Postoji još jedan način pozivanja

konstruktora, complex c1=complex(a,b); ovakav način pozivanja konstruktora se ne

preporučuje jer bi kompajler mogao da stvori privremeni objekat koji bi inicijalizovao pa onda

njega kopirao u c1, što je nepotrebno produžavanje vremena izvršavanja programa. Postoje

neke izuzetne situacije u kojima je ovaj drugi način pozivanja konstruktora bolji, i o tome će

biti reči kasnije. U glavnom programu se za c1 i c2 poziva konstruktor sa parametrima tipa

float dok ze za c3 poziva podrazumevani konstruktor. Ostatak programa protumačite sami.

Primer rada programa

_____________________________________________________________________________

Unesite vrednost za realni i imaginarni deo c1

2 -3.4

Unesite vrednost za realni i imaginarni deo c2

1.2 8

Zbir dva data kompleksna broja je (3.2,4.6)

Razlika dva data kompleksna broja je (0.8,-11.4)

_____________________________________________________________________________

Zadatak 2.4

Realizovati klasu Text koja će predstavljati dinamičke znakovne nizove nad kojima je moguće

izvršiti sledeće operacije: izračunavanje dužine znakovnog niza, čitanje i zamenu zadatog

karaktera u nizu. Konstruisati odgovarajuće konstruktore i destruktore za datu klasu.

#include <iostream> #include <string.h> #include <conio.h> using namespace std;

Page 16: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

15

class Text{ private: char *p; public: Text(){p=0;}//Dodeljujemo pokazivacu vrednost 0 Text(const char *);//da upotrebom destruktora ne bismo brisali ~Text(); //pokazivac slucajnog sadrazaja i sam sadrzaj, delete. int tLength(); char tRead(int); void tWrite(int, char); }; Text::Text(const char* m){ p=new char[strlen(m)+1]; strcpy(p,m);} Text::~Text(){ delete []p; p=0; } char Text::tRead(int i){ return p[i]; } void Text::tWrite(int i, char c){ p[i]=c; } int Text::tLength(){ return strlen(p);} void main(){ char *ch={"docar dan"}; Text T(ch); cout<<"Koji karakter zelite da zamenite?"<<endl; int j; cin>>j; cout<<"Koji karakter zelite da postavite"<<endl; char c; cin>>c; T.tWrite(j,c); cout<<"Novi tekst je: "<<endl; int l=T.tLength(); for(int i=0; i<=l;i++) cout<<T.tRead(i); cout<<endl; getch(); }

_____________________________________________________________________________

Ovaj zadatak je lako realizovati ako se ima na umu sve iz prethodnog. Jedina razlika jeste

što nam sad u default konstruktoru postoji naredba za postavljane pokazivača, koji ukazuje na

početak niza, na nulu. To radimo jer je moguće da se desi da se nakon deklaracije nekog objekta

defalult konstruktorom izvrši brisanje tog objekta. Da nemamo naredbu p=0; pokazivaču p bi se

dodjeljivala neka proizvoljna vrednost, on bi ukazivao na nešto u memoriji što bi se brisalo,

nestankom ovog objekta odnosno pozivanjem destruktora. Sledeći konstruktor ne vrši samo

zauzimanje memorije za elemente niza već vrši i njihovu inicijalizaciju, proslijeđen mu je

pokazivač na početak znakovnog niza. Ostatak programa protumačite sami.

Primer rada programa

Page 17: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

16

Koji karakter zelite da zamenite?

2

Koji karakter zelite da postavite

b

Novi tekst je:

dobar dan

_____________________________________________________________________________

Zadatak 2.5

Koristeći klasu tačka (koja će sadržati koordinate tačke i funkciju za računanje rastojanja dve

tačke) konstruisati klasu krug koja će kao članove imati tačku centar i neku tačku sa kruga i

funkcije članice za izračunavanje površine i obima kruga.

_____________________________________________________________________________

#include <iostream> #include <math.h> using namespace std; class tacka{ float x,y; public: tacka(){} tacka(float,float); float rastojanje(tacka) const; }; tacka::tacka(float a,float b):x(a){y=b;} float tacka::rastojanje(tacka a)const{ return sqrt(pow(x-a.x,2)+pow(y-a.y,2)); } class krug{ private: tacka centar; tacka sa_kruga; public: krug(){} krug(float, float, float, float); //Moze i na sledeci nacin //krug(tacka, tacka); float kPovrsina(); float kObim(); }; krug::krug(float x1, float x2, float x3, float x4):centar(x1,x2){sa_kruga=tacka(x3,x4);} /* za drugi nacin realizacije bi morali imati naredbe krug::krug(tacka t1, tacka t2):centar(t1){ sa_kruga=t2;}; */ float krug::kPovrsina(){

Page 18: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

17

float r; const float pi=3.14159; r=centar.rastojanje(sa_kruga); return pow(r,2)*pi; } N float krug::kObim(){ float r; const float pi=3.14159; r=centar.rastojanje(sa_kruga); return 2*pi*r; } void main(){ cout<<"Unesite koordinate centra kruga i tacke sa kruga"<<'\n'; float x, y, x1,y1; cin>>x>>y>>x1>>y1; /*za drugi nacin realizacije bi morali imati naredbe tacka t1(x,y),t2(x1,y1); krug k1(t1,t2);*/ krug k1(x,y,x1,y1); cout<<"Povrsina kruga je: "<<k1.kPovrsina()<<endl; cout<<"Obim kruga je: "<<k1.kObim(); }

_____________________________________________________________________________

U ovom primeru je pokazano da podatak član klase može biti i objekat druge klase. U

našem slučaju podatak klase krug je objekat klase tacka. Da bi to mogli realizovati potrebno je

pre definicije klase (krug), koja poseduje objekat neke druge klase (tacka), izvršiti, makar,

deklaraciju te klase u našem slučaju je potrebno imati naredbu tipa class tacka; kako bi

kompajler znao da je podatak član nove klase korisnički izvedenog tipa. Mi smo izvršili odmah

kompletnu definiciju klase tacka. Ova klasa ima default konstruktora i konstruktora koji ima dva

argumenta tipa float što je i logično jer ćemo njihove vrednosti dodeliti podacima članovima ove

klase koji su istog tipa. Klasa poseduje i funkciju za računanje rastojanja dve tačke. Klasa krug

poseduje, kao što je zahtevano postavkom zadatka, dva podatka tipa tacka koji predstavljaju

koordinate centra kruga i tačke sa kruga, kao i funkciju za računanje površine i obima kruga.

Potrebno je zapaziti da smo za računanje poluprečnika kruga koristili funkciju članicu klase tacka

koju smo pozivali iz funkcija za računanje površine i obima. Ovo smo morali realizovati na ovaj

način jer iako klasa krug ima kao podatke objekte tipa tacka, centar kruga i tacka sa njegovog

oboda, ne možemo direktno pristupati koordinatama ovih tačaka jer su one privatni podaci

članovi. Njima se može pristupiti samo uz pomoć funkcija članica klase kojoj pripadaju ili uz

pomoć prijateljskih funkcija i klasa o čemu će biti reči kasnije. Dakle, naredba tipa

r=pow(centar.x-sa_kruga.x,2)+pow(centar.y-sa_kruga.y,2); u okviru funkcije za računanje

površine i obima bi izazvala grešku i kompajler bi nam javljao da na tom mestu podaci članovi

tačaka centar i sa_kruga nisu dostupni. Klasa krug, takođe, poseduje odgovarajuće konstruktore.

Realizacija default konstruktora se ne razlikuje od realizacije za ranije korišćene klase ali moramo

voditi računa da klasa čiji su objekti njeni podaci takođe mora imati default konstruktor jer bi

kompajler u suprotnom prijavio grešku, s obzirom da ovaj konstruktor nema argumente i poziva

konstruktora za klasu čiji objekat sadrži bez argumenata, dakle dafault. Sljedeći konstruktor, koji

će ujedno izvršiti inicijalizaciju objekta klase za koji bude pozvan, se može realizovati na više

načina. Mi smo koristili sledeći način krug::krug(float x1, float x2, float x3, float x4) :centar(x1,x2)

{sa_kruga=tacka(x3,x4);}. Ovde vidimo da smo kao argumente konstruktora poslali četri podatka

tipa float a onda eksplicitno pozivali konstruktora za klasu tačka sa odgovarajućim argumentima.

Page 19: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

18

U glavnom programu smo konstruktoru prosledili četri podatka tipa float, nakon toga će on sam

pozivati odgovarajuće konstruktore za klasu tacka u skladu sa načinom na koji smo ga realizovali.

Vidimo da smo jednom to odradili u inicijalizacionoj listi a drugi put u tijelu konstruktora.

Konstruktor se može realizovati i kao krug::krug(tacka t1, tacka t2):centar(t1){ sa_kruga=t2;}; pri

čemu moramo voditi računa da tačka nije ugrađeni tip podataka već izvedeni i da u skladu sa tim

pre poziva ovog konstruktora sa argumentima tipa tacka prvo moramo stvoriti te argumente tj.

inicijalizovati ih pozivom odgovarajućeg konstruktora. Dakle, u glavnom programu bismo imali

naredbe tacka t1(x,y),t2(x1,y1); krug k1(t1,t2);. Naravno, za prvi način realizacije je potrebno

imati zaglavlje tipa krug(float, float, float, float); a za drugi krug(tacka, tacka);. Parametri u

deklaraciji funkcije moraju odgovarati onima prilikom njene realizacije.

Ostatak koda je izvršen u skladu sa ranijim primerima. Obratite pažnju da se ispisivanje

komentara u više redova vrši na isti način kao u programskom jeziku C, dok se komentar može

ispisati u jednom redu koristeći //.

Primer rada programa

_____________________________________________________________________________U

nesite koordinate centra kruga i tacke sa kruga

0 0 2.5 2.5

Povrsina kruga je: 39.25

Obim kruga je: 22.2144

_____________________________________________________________________________

Zadatak 2. 6

Realizovati klasu red koja će predstavljati niz celih brojeva proizvoljne dužine, neka klasa sadrži

i podatak o dužini reda. Omogućiti da indeks prvog člana može biti različit od nule ukoliko

korisnik to zada. Omogućiti pristup članovima reda za upis i izmenu podataka. Napisati glavni

program u kojem će se unositi odgovarajući red i na izlazu davati suma članova tog reda kao i

red koji je sastavljen od kvadrata elemenata reda koji je korisnik uneo.

_____________________________________________________________________________

#include <iostream> using namespace std; class Array{ private: int *p; //Pokazivac na pocetak niza celih brojeva int num; //Duzina niza const int i1; //Indeks pocetnog elementa niza (moze biti razlicit od 0) public: Array(int first_index=1,int number=0); Array(const Array & a); ~Array(); int first(){return i1;} int length(){return num;} int last(){return i1+num-1;} int read(int index){return p[index-i1];} void change(int, int);

Page 20: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

19

}; Array::Array(int first_index, int number):i1(first_index), num(number){ p=new int[num]; } Array::Array(const Array &a): i1(a.i1), num(a.num){ p=new int[num]; for(int i=0;i<num;i++) p[i]=a.p[i]; } Array::~Array(){delete[] p; p=0;} void Array::change(int index, int value){ p[index-i1]=value; } int sum(Array &a){ int s=0; for(int i=a.first();i<=a.last();i++) s+=a.read(i); return s; } void square(Array &a){ for(int i=a.first();i<=a.last();i++) { int x; x=a.read(i); a.change(i,pow(x,2)); } } void main(){ int i, n,x; cout<<"Koliko clanova zelite da ima vas red?"<<'\n'; cin>>n; cout<<"Od kojeg indeksa zelite da pocinje indeksiranje vaseg reda"<<'\n'; cin>>i; cout<<"Unesite clanove reda"<<endl; Array a1(i,n); for(int j=i;j<n+i;j++){ cin>>x; a1.change(j,x); } Array a2(a1); square(a2); cout<<"Suma clanova zadatog reda je: "<<sum(a1)<<endl; cout<<"Red dobijen kvadriranjem clanova zadatog je: "<<endl; for(int j=a2.first(); j<=a2.last();j++) cout<<a2.read(j)<<" "; }

_____________________________________________________________________________

Dati primer ilustruje korišćenje konstruktora kopije. Veoma često u programima želimo

inicijalizovati novi objekat tako da ima iste vrednosti podataka članova kao i neki već postojeći.

To ćemo učiniti konstruktorom kopije. Ukoliko mi ne definišemo konstruktor kopije pozvaće se

default. Ovakav konstruktor kopije kopira podatke članove postojećeg objekta u objekat koji

stvaramo jedan po jedan. Ukoliko data klasa ima kao podatak objekat neke druge klase (tacka u

prethodnom zadatku) za kopiranje tog podatka (objekta) poziva se konstruktor kopije za klasu

(tacka) čiji je on objekat. Kopiranje se dešava i prilikom korišćenja objekata u inicijalizacionoj listi

pri realizaciji konstruktora. U prethodnom primeru bi to bilo pri realizaciji konstruktora kao

krug::krug(tacka t1, tacka t2):centar(t1){ sa_kruga=t2;}, prilikom deklaracije krug k1(t1,t2);

konstruktor kopije klase tacka će se pozivati dva puta, za kopiranje t1 u centar i t2 u sa_kruga.

Konstruktor kopije se ne poziva samo prilikom eksplicitne inicijalizacije novog objekta već i

Page 21: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

20

prilikom transfera argumenata funkcije koji su objekti neke klase i kada kao rezultat funkcije

imamo objekat neke klase, jer se i u tim slučajevima stvaraju novi, privremeni, objekti.

Default konstruktor kopije, u većini slučajeva, zadovoljava naše potrebe i nema svrhe

definisati novi. Međutim, ukoliko radimo sa klasama koje dinamički alociraju memoriju moramo

definisati sopstvenog konstruktora kopije. Naime, u ovim slučajevima kao podatak član imamo

pokazivač, u našem primeru p koji je pokazivač na niz celih brojeva. Ukoliko bismo u slučajevima

kada nam je to potrebno koristili ugrađenog konstruktora kopije on bi kopirao vrednost ovog

pokazivača tako da bismo imali dva objekta koja pokazuju na isti niz, ukoliko bismo sada

izmijenili elemente jednog niza ta izmjena bi se odrazila i na drugi. Može se zaključiti da kada god

u nekoj klasi vršimo dinamičko alociranje memorije potrebno ja da definišemo sopstvenog

konstruktora kopije.

U ovom primeru želimo uvesti korisnički tip podataka, niz čiji indeks može počinjati od bilo kojeg

broja. Da bi imali sve potrebne informacije za manipulaciju datim nizom naša klasa ima tri

podatka člana: pokazivač na početak niza p, broj elemenata niza num i vrednost prvog ineksa i1.

Kada smo koristili nizove onako kako ih kompajler sam formira dovoljno je bilo imati podatke o

dužini niza i broju elemenata jer je početni elemant uvek imao indeks 0. Mi ovde želimo da nam

početni indeks koji ćemo koristiti za pristup elementima ovog niza ima bilo koju vrednost pa taj

podatak moramo imati. U prethodnom primeru smo rekli da ukoliko definišemo bilo koji

konstruktor moramo definisati i deafult. Na prvi pogled, može djelovati, da smo ovde prekršili to

pravilo. Ako se bolje pogleda konstruktor vidi se da on može biti pozivan bez ijednog argumenta,

ima podrazumevane parametre koji će se u tom slučaju koristiti pa ćemo imati niz sa prvim

indeksom 1 a bez elemenata, može se pozvati i sa samo jednim argumentom, drugi će dobiti

podrazumevanu vrednost, ili sa oba. Tek kada pošaljemo oba argumenta vrši se dinamička

alokacija memorije. Ovde smo formirali objekat koji predstavlja istancu niza sa indekasom prvog

člana i1, num elemenata, zauzeli memoriju za njih i vratili pokazivač na početak te memorije p. U

okviru glavnog programa ćemo elementima niza dodeliti neke vrednosti. I konstruktor kopije,

kao i običan konstruktor, ima isto ime kao i klasa kojoj pripada, razlika je, pored same radnje koju

obavlja, u tome što konstruktor kopije ima tačno određen tip podatka koji mu je argument, to je

konstantna referenca na objekat klase za koju se pravi dati konstruktor kopije Array (const Array

& a), može se izostaviti samo const. Konstruktor kopije preslikava vrednosti podataka objekta

koji se šalje kao argument u vrednosti podataka novog objekta num i i1, vrši alociranje novog

dijela memorije, odgovarajućeg kapaciteta, u koji presipa elemente niza. Sada dobijamo dva

objekta koji imaju isti sadržaj ali ukazuju na različite djelove memorije. Obratite pažnju na način

pristupanja elementima objekta koji se šalje kao argument i objekta za koji se poziva konstruktor

kopije. Vidimo da smo prilikom presipanja elemenata pristupali im kao da počinju od indeksa 0

pa do kraja niza iako smo rekli da možemo imati proizvoljan početni indeks. Ovo je i logično jer

će se elementi niza čuvati od indeksa 0 pa do kraja niza a mi treba da realizujemo klasu tako da

korisnik ima osjećaj da počinju od nekog proizvoljnog indeksa i1. To ćemo učiniti u funkcijama za

pistup gdje će on za zadati početni indeks i1 pristupati prvom elementu pozivajući ga kao i1 a

zapravo će očitavati element sa indeksom 0. Znači, u funkciji read() kada pošaljemo vrednost

indeksa index naredbom return p[index-i1]; mi vraćamo odgovarajući element. Ukoliko zadamo

da je početni indeks niza 3 a želimo očitati element sa indeksom 5, kao vrednost stvarnog

argumenta za index u pozivu funkcije šaljemo 5 a očitavamo 5-3, dakle element sa indeksom 2.

Ovo je i logično jer ćemo u memoriji imati niz sa indeksima 0,1,2...num-1 a korisnik ima osjećaj

Page 22: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

21

da su indeksi i1, i1+1,..., i1+num-1. Podsjetite se koje je ovo svojstvo objektno orjentisanog

pristupa. Sličnu logiku smo koristili i prilikom realizacije funkcije change(), ovde smo kao

argumente slali i indeks čija se vrednost mijenja i novu vrednost koja mu se dodeljuje. Funkcije

first(), lenght() i last() vraćaju indeks (zadati) prvog elementa niza, dužinu niza i indeks poslednjeg

elementa niza. One su veoma jednostavne i zato su implementirane kao inline.

Obratite pažnju da funkcije za računanje sume i kvadrata elemenata nisu funkcije članice

pa iako rade samo sa jednim objektom mora im se taj objekat a proslijediti. Mi smo prosledili

referencu na objekat jer kada bismo prosledili objekat vršilo bi se kopiranje prilikom prenosa

parametara funkciji i stvaranje privremenog objekta u toku izvršavanja funkcije a na ovaj način

smo to izbjegli. Princip realizacije ovih funkcija se ne razlikuje od onog koji bismo koristili u

programskom jeziku C. Trebate obratiti pažnju da, s obzirom da ovo nije funkcija članica klase

Array, ni njena prijateljska funkcija, nema pravo pristupa njenim privatnim podacima pa kada joj

bude potreban početni indeks niza neće mu moći pristupiti direktno naredbom a.i1 već mora

pozivati funkciju za očitavnje vrednosti tog podatka, koja je javna i kao takvu je može koristiti

a.first() (for(int i=a.first();i<=a.last();i++) s+=a.read(i);). U funkciji square() šaljemo kao argument

referencu na neki objekat (niz) pa sve što budemo radili sa njegovim elementima odražava se na

sam objekat (prenos po referenci). Znači, iako je tip rezultata void mi imamo rezultat (niz koji

smo poslali kao stvarni argument i čiji su elementi sada kvadrirani) ali ga nije potrebno vraćati jer

smo poslali referencu na objekat.

U glavnom programu korisnik zadaje početnu vrednost niza i broj elemenata, nakon ovog se vrši

inicijalizacija objekta a1. Ovo je moguće izvršiti pre unošenja vrednosti pojedinih elemenata niza

jer konstruktor samo zauzima memoriju za traženi broj elemenata i postavlja vrednosti za

početni element i dužinu niza. Nakon toga korisnik unosi elemente niza kojima mi pristupamo na

način kako to korisnik očekuje, od indeksa i1, i menjamo im vrednost uz pomoć funkcije chage()

jer nam oni nisu direktno dostupni ovde, privatni podaci klase. Sada smo u potpunosti

inicijalizovali ovaj objekat i možemo ga koristiti u pozivu konstruktora kopije za inicijalizaciju

novog objekta Array a2(a1); (može i Array a2=a1;) dok se naredbom Array a2; a2=a1; ne bi

pozivao konstruktor kopije već operator dodijele koji, ukoliko mi nismo definisali drugačije, vrši

dodjelu na isti način kao default konstruktor kopije. Dakle i a1 i a2 bi ukazivali na isti deo u

memoriji pa bi se sve što uradimo sa a1 odrazilo na a2 a mi to ne želimo već želimo da u a1

sačuvamo nepromijenjenu vrednost elemenata niza a u a2 da smjestimo kopiju članova koju

ćemo proslijediti funkcijama za računaje sume i kvadrata elemenata niza. Ove funkcije nisu

funkcije članice već globalne funkcije pa ih u skladu sa tim i pozivamo na odgovarajući način, bez

korišćena operatora dot(.).

Još jedna funkcija članica koja se automatski poziva i ugrađena je jeste destruktor. Ova

funkcija ima isto ime kao i klasa kojoj pripada i znak tilda ~ ispred njega ~Array();. Deklariše se

kao i ostale funkcije članice. Bez obzira što jezik poseduje sopstvenog default destruktora, dobra

programerska praksa je definisati ga uvek, čak i kada ima prazno telo funkcije. Mora se definisati

kada imamo dinamičko dodeljivanje memorije, kao u ovom slučaju. Klasa može imati samo

jednog destruktora i on ne može imati argumente kao ni povratni tip podataka, nije dozvoljena

ni upotreba reči void. Ukoliko klasa sadrži kao podatak član objekat druge klase prvo se poziva

destruktor za taj objekat, pa tek onda za klasu čiji je objekat član.

Page 23: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

22

U našem primeru je bilo neophodno definisati destruktor jer se u konstruktoru vrši dinamička

alokacija memorije. Nakon uništavanja primeraka klase potrebno je osloboditi memoriju koju je

taj primerak zauzimao. Mi smo to i uradili u tijelu destruktora Array::~Array(){delete[] p; p=0;}.

Uglaste zagrade pre pokazivača p se koriste uvek kada imamo niz, tako govorimo da je potrebno

osloboditi memoriju koju je zauzeo cio niz a ne samo prvi element. Nakon ovog, pokazivač p će i

dalje sadržati adresu prvog elementa niza, čiji smo sadržaj upravi izbrisali. To nikako nije poželjno

jer nam pokazivač pokazuje na nešto što više ne postoji. Naredbom p=0; ostavljamo ga u

ispravnom, praznom, stanju. Ne ukazuje ni na jednu memorijsku adresu.

Primer rada programa

_____________________________________________________________________________

Koliko clanova zelite da ima vas red?

5

Od kojeg indeksa zelite da pocinje indeksiranje vaseg reda

3

Unesite clanove reda

2 5 13 26 4

Suma clanova zadatog reda je: 50

Red dobijen kvadriranjem clanova zadatog je:

4 25 169 676 16

_____________________________________________________________________________

Zadatak 2. 7

Implementirati klasu koja će predstavljati realizaciju steka uz mogućnost brojanja podataka

koji se nalaze na steku. Napisati glavni program u kojem će se na stek postaviti pet podataka,

izbrisati dva i dopisati tri a zatim na izlaz dati izgled tako dobijenog steka.

_____________________________________________________________________________

#include <iostream> #include <conio.h> #include <stdlib.h> using namespace std; class stek{ private: static int ukupno; static stek *vrh; int broj; stek *prethodni; public: static void stavi_na_stek(int); static int uzmi_sa_steka(); static int prazan(){return vrh==0;}

Page 24: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

23

static int imaih(){return ukupno;} }; int stek::ukupno=0; stek* stek::vrh=0; void stek::stavi_na_stek(int i){ stek *pom=new stek; pom->prethodni=vrh; pom->broj=i; vrh=pom; ukupno=ukupno+1; } int stek::uzmi_sa_steka(){ if(!vrh) exit(1); stek *pom; pom=vrh; int i=vrh->broj; vrh=pom->prethodni; delete pom; pom=0; ukupno=ukupno-1; return i; } int main(){ int n; cout<<"Koliko brojeva zelite da ima stek?\n"; cin>>n; int m; cout<<"Unesite podatke koje zelite da postavite na stek"<<endl; for(int i=0; i<n;i++){cin>>m; stek::stavi_na_stek(m);} cout<<"Koliko brojeva zelite da uzmete sa steka?"<<'\n'; cin>>n; cout<<"Uzeli ste brojeve: "; for(int i=0;i<n;i++) cout<<stek::uzmi_sa_steka()<<" "; cout<<endl; cout<<"Koliko brojeva zelite da postavite na stek?"<<'\n'; cin>>n; cout<<"Unesite podatke koje zelite da postavite na stek"<<endl; for(int i=0;i<n;i++) {cin>>m; stek::stavi_na_stek(m);} cout<<"Ukupno je"<<stek::imaih()<<endl; cout<<"Na steku su brojevi od vrha ka pocetku"; while(!stek::prazan()) cout<<stek::uzmi_sa_steka()<<" "; }

_____________________________________________________________________________

Stek se ponaša kao memorijski mehanizam tipa "poslednji-u, prvi iz" (engl. last in, first

out). Stek ima svojstvo podataka. Mi smo već ranije naveli da klasama definišemo korisnički tip

podataka. Stek će nam, zapravo, biti linearna lista sa specijalnim svojstvom da ne možemo čitati

element sa bilo kojeg mesta u njoj već samo poslednji element i da ne možemo postavljati

podatke na bilo koje mesto već samo na vrh steka. Mi želimo upisivati cele brojeve na stek i oni

će biti sačuvani u podatku članu broj i biti deo pojedinog objekta klase. Svaki objekat naše klase

će biti vezan za jedan element steka, svi objekti čine stek. Statički podatak se koristi za smeštanje

informacija koje su zajedničke za sve objekte klase. Mi smo rekli da će nam cela klasa biti stek.

Svaki stek, kao specifičan niz, ima jedan vrh i on je zajednički za sve članove klase, svi oni su deo

steka koji ima jedan kraj-vrh. Znači, podatak o kraju steka ćemo realizovati kao static. Elementi

steka su realizovani kao objekti naše klase pa će pokazivač na vrh steka biti tipa pokazivača na

Page 25: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

24

objekat klase stek i mi smo mu dali ime vrh. Ono što je zajedničko za sve objekte koji čine klasu

jeste i broj tih objekata, elemenata steka, pa i taj podatak realizujemo kao statički, ukupno.

Karakteristika pojedinačnih objekata je adresa prethodnog elementa, (elementa koji je pre toga

postavljen na stek) nju moramo imati kako bi nam lista bila povezana. Naime, kada izbrišemo

neki podatak sa steka moramo znati adresu prethodnog jer je to sada adresa vrha.

Potrebne su nam funkcije za upisivanje elemenata na stek, očitavanje elementa, proveru da li je

stek prazan, kao i informacija o broju elemenata. Nju imamo kao statičku promenljivu u svakom

objektu ali je privatna pa zato pravimo funkciju koja će očitavati njenu vrednost. Sve funkcije

smo definisali kao static iz razloga što statičke funkcije rade sa klasom kao cjelinom, tj. sa stekom

u našem slučaju. Objekat nad kojim želimo izvršiti neku radnju može da bude argument statičke

funkcije, lokalna promenljiva u njoj ili globalna promenljiva. Nas, u ovom slučaju, ne interesuju

pojedinačni objekti iz klase i ako pogledate glavni program primjetićete da nigdje nismo

eksplicitno deklarisali novi objekat. Interesuje nas skup objekata date klase i stek koji oni čine i

radimo sve sa klasom kao cjelinom pa je logično da zato koristimo funkcije koje je tako

posmatraju a to su static funkcije. Da bi pozvali funkciju članicu potrebno je da posedujemo

jedan konkretan objekat. Funkcija static se poziva za klasu i ne poseduje implicitni argument

pokazivač this, zbog toga pojedinačnim podacima članovima klase ne možemo pristupati samo

navođenjem njihovog imena već moramo navesti i kojoj klasi pripadaju dok statičkim podacima

pristupamo neposredno. Statički podaci članovi se razlikuju od pojedinačnih po tome što se

njihova definicija i inicijalizacija ne vrši u konstruktoru, što je i logično jer se konstruktor poziva

za svaki objekat pojedinačno a statički član se inicijalizuje samo jedan put. Statički podataci se

definišu van funkcija i van definicije klase. Definišu se posebnim naredbama za definiciju i

inicijalizuju se samo konstantom ili konstantnim izrazom. Ovo se najčešće vrši posle definicije

klase a pre glavnog programa. Pošto se na tom mestu nalaze van dosega klase mora se koristiti

operator :: da bi se označilo kojoj klasi pripadaju. int stek::ukupno=0; stek* stek::vrh=0;. Vidimo

da se rezervisana reč static koristi samo u deklaraciji kako statičkih promjenjivih tako i statičkih

funkcija, dok se prilikom definicije ne smije navoditi.

U programu imamo četri funkcije. Prva vrši operaciju postavljanja podatka na stek. Kao podatak

joj šaljemo samo celobrojnu vrednost koju želimo postaviti na stek. Da bi postavila neku

vrednost na stek potrebna joj je adresa vrha steka koja se nalazi u promjenjivoj koja je static a

rekli smo da ovoj promjenjivoj funkcija može da pristupi samo navodjenjem njenog imena.

Dodavanje novog podatka na stek znači uvođenje novog objekta i njegovo povezivanje sa ranijim

objektima. U ovoj funkciji prvo vršimo dinamičku alokaciju memorije za novi element. Vrednost

pokazivača na ovaj objekat će nam biti vrednost pokazivača na novi vrh steka. Mi tu vrednost ne

smještamo odmah u statičku promenljivu vrh, već prvo koristimo prethodnu vrednost te

promenljive (vrh), jer ono što je bilo na vrhu steka pre uvođenja novog elementa steka sada će

biti na jednom mestu iza vrha, dakle, prethodni za objekat koji je na vrhu steka. Nakon toga u

njegovu promenljivu broj upisujemo vrednost koja je proslijeđana funkcijom. I tek onda, kada

smo povezali taj objekat sa prethodnim elementima, postavljamo vrh tako da ukazuje na njega i

povećavamo broj elemenata steka za jedan. Primetimo način pristupanja promjenjivim broj i

prethodni. Nije bilo dovoljno navesti samo njihovo ime jer statička funkcija nema pokazivač this.

Funkcija uzmi_sa_steka prvo proverava da li je stek prazan. To se može desiti u dva slučaja, da

ništa nismo stavili na stek, tada je vrednost vrh=0 jer smo je tako inicijalizovali ili kada uzmemo

sve sa steka, kada je opet vrednost na koju ukazuje stek 0 a što ćemo obezbijedi realizacijom ove

Page 26: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

25

funkcije. Dakle, na samom početku proveravamo da li je stek prazan, ako jeste prekidamo rad

programa funkcijom exit(), da bi je mogli koristiti uključujemo biblioteku stdlib.h. Ukoliko ima

nešto na steku vršimo očitavanje. Nema potrebe da šaljemo koji ćemo podatak očitati jer je

priroda steka takva da možemo uzeti samo vrednost sa vrha steka. Ukoliko ima nešto na steku u

nekoj lokalnoj promjenjivoj pamtimo pokazivač na taj element vrh. Očitavamo vrednost koja je

bila upisana na vrhu steka, što ćemo kasnije i vratiti kao rezultat funkcije. Sada isključujemo

element sa steka tako što postavljamo da vrh ne ukazuje na njega već na element koji mu je

prethodeo u steku, a koji će nakon uzimanja ovog podatka biti na vrhu steka i oslobađamo

memoriju. Primetimo da smo ovom realizacijom omogućili da je vrednost promenljive vrh kada

smo sve očitali sa steka jednaka nuli. Kada očitamo element koji je poslednji element na steku, to

je na osnovu pravila o pristupu elementima steka element koji smo prvi upisali, pokazivač vrh

nakon očitavanja ukazuje na njegov prethodni element a on je dobio vrednost koju je imala

promenljiva vrh pre nego što je bilo što upisano na stek, dakle nula. Broj elemenata steka

umanjujemo za jedan. Funkcija prazan proverava da li je vrh==0 dakle, da li je stek prazan.

Funkcija ukupno nam vraća koliko ukupno elemenata imamo na steku.

Na početku su i vrh i ukupno inicijalizovane na nulu. Korisnik unosi koliko elemenata želi

da stavi na stek, unosi vrednost koje želi da stavi na njega i u for petlji unosi te vrednosti u

odgovarajuće elemente. Nakon toga pitamo korisnika da li želi da očita, i koliko elemenata, a

kada izvrši očitavanje javljamo mu koliko je elemenata ostalo na steku.

Primer rada programa

_____________________________________________________________________________

Koliko brojeva zelite da ima stek?

5

Unesite podatke koje zelite da postavite na stek

1 4 6 9 23

Koliko brojeva zelite da uzmete sa steka?

2

Uzeli ste brojeve: 23 9

Koliko brojeva zelite da postavite na stek?

3

Unesite podatke koje zelite da postavite na stek

2 4 1

Ukupno je6

Na steku su brojevi od vrha ka pocetku1 4 2 6 4 1

_____________________________________________________________________________

Page 27: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

26

Zadatak 2. 8

Realizovati klasu radnici koja će imati tri podatka člana i to: celobrojnu promenljivu za

kofecijent za platu, pokazivač na celobrojnu promenljivu za identifikacioni broj radnika i javnu

statičku promenljivu koja će služiti za brojanje ukupnog broja radnika (objekata date klase).

Klasa poseduje konstruktor, destruktor i konstruktor kopije, kao i funkcije članice za pristup

podacima radi očitavanja i izmjene i funkciju koja računa koji od dva radnika ima veću platu i

vraća identifikacioni broj istog.

_____________________________________________________________________________

#include <iostream> #include <conio.h> using namespace std; class radnici{ private: int koeficijent; int *idbroj; public: radnici(){idbroj=0; broj++;} radnici(int,int); radnici(const radnici&); ~radnici(); int daj_koef()const{return koeficijent;} int daj_idbroj()const{return *idbroj;} void promijeni_koef(int); void promijeni_idbroj(int); int placeniji(radnici); static int broj; }; radnici::radnici(int koef, int idb):koeficijent(koef){ idbroj=new int; *idbroj=idb; broj=broj+1; } radnici::radnici(const radnici& stari):koeficijent(stari.koeficijent){ idbroj=new int; *idbroj=*stari.idbroj; broj=broj+1; } radnici::~radnici(){ delete idbroj; idbroj=0; broj=broj-1; } void radnici::promijeni_koef(int a){ koeficijent=a; } void radnici::promijeni_idbroj(int a){ *idbroj=a; } int radnici::placeniji(radnici a){ if(koeficijent>=a.koeficijent) return *idbroj; else return *a.idbroj; } int radnici::broj=0; main(){

Page 28: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

27

int a,b; cout<<"Unesete podatke za dva radnika"<<endl; cin>>a>>b; radnici a1(a,b); cin>>a>>b; radnici a2(a,b); cout<<"Vise je placen radnik: "<<a1.placeniji(a2)<<endl; cout<<"Ukupno imamo "<<radnici::broj<<" radnika"<<endl; }

_____________________________________________________________________________

U ovom zadatku koristimo ranije uvedene pojmove: konstruktor, destruktor, konstruktor kopije i

statičku promenljivu. Tip promjenjivih nam je zadat postavkom zadatka, za statičku promenljivu

je rečeno da treba da bude javna. Podaci članovi su tipa int i int *, i konstruktor pozivamo sa dva

cela broja pri čemu u okviru konstruktora dodeljujemo vrednost promjenjivoj int na koju ukazuje

pokazivač idbroj. Obratite pažnju da to vršimo naredbom *idbroj=idb; što je i logično jer mi

želimo upisati vrednost koju smo prosledili konstruktoru u promenljivu na koju ukazuje

pokazivač idbroj a njoj pristupamo upotrebom operatora * ispred imena pokazivača. Konstruktor

kopije smo realizovali kao u ranijim primerima, samo što sad nemamo celi niz već samo jedan

element na koji nam ukazuje pokazivač i vrednost promenljive na koju ukazuje pokazivač iz

prosleđenog objekta (stari) prepisujemo u objekat koji kopiramo naredbom

*idbroj=*stari.idbroj;. U zadatku se od nas zahteva da vodimo evidenciju o tome koliko imamo

radnika. Imamo ih onoliko koliko imamo objekata. Svaki put kada stvorimo novi objekat poziva se

konstruktor, bilo da smo taj objekat eksplicitno deklarisali ili da se formira privremeni objekat u

koji će da se kopira vrednost objekta koji je stvarni argument funkcije itd.. Zbog ovoga ćemo

povećati vrednost za statičku promenljivu broj svaki put kada pozovemo konstruktora. Pošto se

objekti ne stvaraju samo kada ih mi eksplicitno deklarišemo već i kada želimo da pozovemo neku

funkciju, kao što je funkcija za računanje koji radnik ima veću platu, da bi imali pravo stanje o

broju radnika potrebno je da u destruktoru imamo naredbu koja će smanjivati broj radnika za 1

svaki put kada se destruktor pozove. Ukoliko smo formirali privremeni objekat u nekoj funkciji

nakon završetka izvršavanja te funkcije taj objekat se uništava i poziva se destruktor. Funkcije za

promjenu koeficijenta i identifikacionog broja su veoma jednostavne, samo treba voditi računa o

tome da je idbroj pokazivač na celobrojnu promenljivu i u skladu sa tim na odgovarajući način

pristupiti vrednosti promenljive na koju on ukazuje i promijeniti je. Isto važi i za funkciju za

računanje koji radnik ima veću platu. Potrebni su nam podaci o oba radnika, mi šaljemo samo

jedan objekat, podsjetite se zašto to činimo na ovaj način.

U glavnom programu smo unijeli podatke o dva radnika, a kao rezultat ispisujemo koji više

zarađuje i koliko ih ima.

Primer rada programa

_____________________________________________________________________________

Unesete podatke za dva radnika

224

3452

312

5431

Vise je placen radnik: 5431

Ukupno imamo 2 radnika

_____________________________________________________________________________

Page 29: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

28

Zadatak 2. 9

Realizovati klasu trougao koja će kao podatke članove imati tri tačke koje predstavljaju

objekte klase tačka. Klasa tačka treba da ima odgovarajuće konstruktore i destruktore kao i

funkcije za računanje rastojanja dve tačke i ugla između prave koju čine dve tačke i x ose. Klasa

trougao treba da poseduje odgovarajuće konstruktore, destruktore kao i funkciju članicu koja

će za tri date tačke proveravati da li čine trougao ili su to tačke sa jedne prave i druga funkcija

članica proverava da li je trougao, na ovaj način zadat, jednakokraki. Napisati i glavni program

u kojem će se unositi koordinate za željene tačke, inicijalizovati potrebni objekti i proveravati

da li date tačke čine trougao i da li je isti jednakokraki.

_____________________________________________________________________________

#include <iostream> #include <math.h> #include <stdlib.h> using namespace std; class tacka{ float x; float y; public: tacka(){}; tacka(float,float); ~tacka(){} float Aps(){return x;} float Ord(){return y;} float rastojanje(tacka); double radius(tacka); }; tacka::tacka(float a,float b):x(a),y(b){} float tacka::rastojanje(tacka t){ float d; d=sqrt(pow(x-t.x,2)+pow(y-t.y,2)); return d; } double tacka::radius(tacka a){ return ((x-a.x)==0||(y-a.y)==0)?0:atan2((y-a.y),(x-a.x)); } class trougao{ private: tacka t1; tacka t2; tacka t3; public: trougao(){}; trougao(tacka, tacka,tacka); ~trougao(){} bool jednakokraki(); bool je_li_trougao(); }; trougao::trougao(tacka a,tacka b,tacka c):t1(a),t2(b),t3(c){} bool trougao::jednakokraki(){ if(t1.rastojanje(t2)==t2.rastojanje(t3)||t1.rastojanje(t2)==t1.rastojanje(t3)||\ t2.rastojanje(t3)==t1.rastojanje(t3)) return true;

Page 30: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

29

else return false; } bool trougao::je_li_trougao(){ if((t1.rastojanje(t2)+t1.rastojanje(t3))<t2.rastojanje(t3)||\ (t1.rastojanje(t2)+t2.rastojanje(t3))<t1.rastojanje(t3)||\ (t1.rastojanje(t3)+t2.rastojanje(t3))<t1.rastojanje(t2)) return false; else return true; } void main(){ float x1,y1; cout<<"Unesite koordinate za tjeme A trougla"<<endl; cin>>x1>>y1; tacka A(x1,y1); cout<<"Unesite koordinate za tjeme B trougla"<<endl; cin>>x1>>y1; tacka B(x1,y1); cout<<"Unesite koordinate za tjeme C trougla"<<endl; cin>>x1>>y1; tacka C(x1,y1); trougao tr(A,B,C); if(tr.je_li_trougao()) cout<<"Zadate tacke predstavljaju trougao"<<endl; else { cout<<"Zadate tacke ne predstavljaju trougao"<<endl; getch(); exit(EXIT_FAILURE); } if(tr.jednakokraki()) cout<<"Trougao je jednakokraki"<<endl; else cout<<"Trougao nije jednakokraki"; }

_____________________________________________________________________________

Sama realizacija programa predstavlja kombinaciju ranije rađenih zadataka. Kao uslov za

određivanje da li su neke tačke temena trougla koristili smo činjenicu da zbir dve stranice trougla

mora biti veći od treće.

Primer rada programa

_____________________________________________________________________________ Unesite koordinate za teme A trougla

0 0

Unesite koordinate za teme B trougla

1 0

Unesite koordinate za teme C trougla

0.1

0

Zadate tacke predstavljaju trougao

Trougao nije jednakokraki

Unesite koordinate za teme A trougla

0 0

Unesite koordinate za teme B trougla

0 1

Unesite koordinate za teme C trougla

Page 31: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

30

1 0

Zadate tacke predstavljaju trougao

Trougao je jednakokraki

_____________________________________________________________________________

3. Prijateljske klase i funkcije

Zadatak 3.1

Realizovati klasu niz koja će imati kao podatak član pokazivač na niz kompleksnih brojeva, kao

i dužinu niza. Implementirati funkciju koja daje proizvod dva kompleksna broja, pri čemu je

realizovati kao funkciju članicu i kao prijateljsku funkciju i napisati glavni program u kojem će

se ukazati na način pozivanja obe funkcije. Uneti niz kompleksnih brojeva i implementirati u

okviru klase niz funkciju koja će isčitavati dati niz, uzeti da je klasa niz prijateljska klasa klasi

kompleksnih brojeva. Klasa sadrži konstruktor, destruktor i konstruktor kopije.

_____________________________________________________________________________

#include <iostream> #include <conio.h> using namespace std; class kompleks{ float real; float imag; public: kompleks(){} kompleks(float a,float b):real(a),imag(b){}; ~kompleks(){}; kompleks prod(kompleks); float kRe(){return real;} float kIm(){return imag;} friend kompleks kprod(kompleks,kompleks); friend class niz;//sada koristim i class jer klasa niz jos uvek nije deklarisana. }; kompleks kompleks::prod(kompleks a){ kompleks temp; temp.real=real*a.real-imag*a.imag; temp.imag=imag*a.real+real*a.imag; return temp; } kompleks kprod(kompleks a,kompleks b){ kompleks temp; temp.real=b.real*a.real-b.imag*a.imag; temp.imag=b.imag*a.real+b.real*a.imag; return temp; } class niz{ private: kompleks *nizk; int ukupno; public: niz(){nizk=0;}

Page 32: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

31

niz(int,kompleks *); niz(niz &); ~niz(); void read(){ for(int i=0;i<ukupno;i++){ cout<<nizk[i].real; if(nizk[i].imag<0) cout<<"-j"; else cout<<"+ j"; cout<<abs(nizk[i].imag)<<endl;} } }; niz::niz(int d, kompleks *k):ukupno(d){ nizk=new kompleks[ukupno]; for(int i=0;i<ukupno;i++) nizk[i]=k[i]; } niz::niz(niz &a):ukupno(a.ukupno){ nizk=new kompleks[ukupno]; for(int i=0;i<ukupno;i++) nizk[i]=a.nizk[i]; } niz::~niz(){ delete []nizk; nizk=0; } int main(){ float a,b; cout<<"Unesite prvi kompleksan broj"<<endl; cin>>a>>b; kompleks k1(a,b); cout<<"Unesite drugi kompleksan broj"<<endl; cin>>a>>b; kompleks k2(a,b); kompleks k3; k3=k1.prod(k2); cout<<"("<<k3.kRe()<<","<<k3.kIm()<<")"<<endl; k3=kprod(k1,k2); cout<<"("<<k3.kRe()<<","<<k3.kIm()<<")"<<endl; int n; cout<<"Koliko clanova imaju vasi nizovi?"; cin>>n; cout<<"Unesite elemente niza < 10"<<endl; float x,y; kompleks k[10]; for(int i=0;i<n;i++){ cin>>x>>y; k[i]=kompleks(x,y);} niz n1(n,k); n1.read(); getch(); }

_____________________________________________________________________________

Funkcije prijatelji neke klase su funkcije koje nisu članice te klase ali imaju pravo pristupa

privatnim elementima klase. Prijateljstvo se ostvaruje tako što ga klasa poklanja datoj funkciji i to

tako što se u definiciji date klase navede prototip funkcije i ključna reč friend na njegovom

početku. Klase takođe mogu biti prijatelji drugih klasa. U ovom primeru je data ilustracija klase i

funkcije prijatelja. Postavkom zadatka nam je rečeno da naša klasa kao podatak član ima

Page 33: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

32

pokazivač na niz kompleksnih brojeva, da bismo deklarisali takav podatak član potrebno je da

imamo definiciju (ili makar deklaraciju klase kompleksnih brojeva). Mi smo odmah u potpunosti

definisali klasu kompleksnih brojeva i njene prijatelje. U odnosu na ranije korišćene definicije ove

klase novina je postojanje prijatelja. Prijateljstvo smo poklonili sledećim naredbama u okviri

definicije date klase: friend kompleks kprod(kompleks,kompleks); friend class niz;. Ukoliko je pre

realizacije klase koja želi pokloniti prijateljstvo nekoj drugoj klasi izvršena deklaracija ili definicija

klase prijatelja dovoljno je posle friend napisati samo identifikatora (ime) te klase, kod nas to nije

slučaj pa smo pre identifikatora naveli ključnu reč class kako bi kompajler znao da je u pitanju

klasa. Kada klasu učinimo prijateljem druge klase mi smo zapravo sve njene funkcije članice

učinuli prijateljem te klase.

Poređenje definicije i načina pristupa podacima funkcije članice i prijateljske funkcije učinjeno je

realizacijom funkcije za računanje proizvoda dva kompleksna broja jedan put kao funkcije članice

a drugi kao prijatelja. Što se tiče funkcije članice prod() njena realizacija je jasna. Jedan objekat

šaljemo kao argument a podacima drugog funkcija direktno pristupa zahvaljujući implicitnom

argumentu this koji je pokazivač na objekat za koji se ta funkcija poziva. Prijateljske funkcije

nemaju ovaj argument, pa ukoliko želimo pomnožiti dva kompleksna broja oba moramo poslati

kao argumente. Novina u odnosu na običnu globalnu funkciju je to što ima pravo pristupa

privatnim članovima objekata koji su joj prosleđeni. Primetite da im pristupamo direktno a ne

preko poziva funkcije članice što smo ranije morali raditi kada koristimo globalnu funkciju.

Zapamtite da se kod globalne funkcije mora poslati kao stvarni argument svaki objekat čijem

podatku želimo da pristupimo, što je i logično jer ona nije član klase kojoj je prijatelj pa nema

pokazivač this, samo joj je poklonjena privilegija pristupanja privatnim članovima klase kojoj je

prijatelj.

U klasi Niz smo pokazali da neka klasa kao podatak član može imati niz objekata druge klase.

Pojedinom objektu se pristupa navođenjem identifikatora pointera na početak niza i indeksa tog

elementa, kao što bi pristupili i-tom elementu niza celih brojeva. Pogledajmo realizaciju funkcije

za očitavanje elemenata niza, objektu koji je i-ti element niza nizk se pristupa naredbom nizk[i].

Svaki od ovih članova niza je objekat koji ima svoje podatke članove kao što je definisano klasom

čiji su oni objekti. Podatku real i-tog elementa u nizu nizk pristupamo naredbom nizk[i].real.

Normalno, da klasa kompleksnih brojeva nije poklonila prijateljstvo ovoj klasi ne bismo imali

pravo da na ovaj način pristupamo elementima te klase jer su oni privatni, pa bi za očitavanje i

izmenu svakog od njih morali pisati posebnu funkciju. S obzirom da je naša klasa Niz prijatelj klasi

kompleksnih brojeva ima pravo da pristupi privatnim podacima članovima te klase. Konstruktor

ove klase niz se razlikuje od ranijih po tome što u njemu ne vršimo samo zauzimanje memorije za

elemente niza kompleksnih brojeva već ih i inicijalizujemo, poslali smo kao argument pokazivač

na početak niza kompleksnih brojeva kojim će se izvršiti inicijalizacija. Rekli smo da su sve

funkcije članice klase koja se učini prijateljskom prijateljske pa će biti i konstruktor, on je

specijalna vrsta funkcije članice, dakle, direktno pristupa podacima članovima elemenata niza

kompleksnih brojeva. Ovde nismo prepisivali podatak po podatak iz objekata (kompleksnih

brojeva) u nove koji se inicijalizuju već smo iskoristili ugrađeni operator dodele koji će sam

izvršiti dodjelu tako da prepiše podatke članove objekta sa desne strane jednakosti u podatke

članove objekta sa lijeve, jedan po jedan. U nekim slučajevima ne treba koristiti ugrađeni

operator dodele već formirati novi, o čemu će biti reči kod obrade preklapanja operatora.

Page 34: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

33

U glavnom programu smo unijeli podatke za dva komleksna broja k1 i k2 a proizvod računali prvi

put uz pomoć funkcije članice klase kompleksnih brojeva k3=k1.prod(k2); a nakon toga

pozivanjem prijateljske funkcije date klase koja vrši istu operaciju k3=kprod(k1,k2);. Primjetite

razliku u načinu pozivanja. Nakon očitavanja rezultata dobenih jednom i drugom funkcijom

inicijalizovali smo niz komleksnih brojeva koji smo kasnije iskoristili za inicijalizaciju objekta klase

niz, njegov konstruktor očekuje niz komleksnih brojeva. Na kraju je izvšeno očitavanje tog

objekta.

Primer rada programa

_____________________________________________________________________________

Unesite prvi kompleksan broj

2 -3

Unesite drugi kompleksan broj

1.1 2.3

(9.1,1.3)

(9.1,1.3)

Koliko clanova ima vas niz?4

Unesite elemente niza < 10

1 2

3.4 -2

2 4.3

1 2.3

Niz ima elemente:

1+ j2

3.4- j2

2+ j4.3

1+ j2.3

_____________________________________________________________________________ \

4. Preklapanje operatora

Zadatak 4. 1

Realizovati apstraktni tip podataka koji predstavlja racionalne brojeve, izvršiti preklapanje

operatora +, += kao i operatora za prefiksno i postfiksno inkrementiranje. Prilikom

realizacije operatora + uzeti u obzir i mogućnosti sabiranja racionalnih brojeva sa celim

brojem, pri čemu se ceo broj može očekivati i kao levi i kao desni operand.

_____________________________________________________________________________ #include <iostream> #include <conio.h> using namespace std; class Razlomci{ private: int brojilac; int imenilac; public: Razlomci(int=0,int=1); ~Razlomci(){} friend Razlomci operator+(Razlomci,Razlomci);///Ne saljem referencu jer Razlomci& operator+=(const Razlomci &);//mi je potreban poziv konstruktora Razlomci& operator++();// posto uzimam u obzir da mogi sabirati sa celim brojevima Razlomci operator++(int); void ispisi(){cout<<brojilac<<"/"<<imenilac<<endl;} };

Page 35: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

34

Razlomci::Razlomci(int a,int b):brojilac(a),imenilac(b){} Razlomci operator+(Razlomci r1,Razlomci r2){ Razlomci temp; temp.brojilac=r1.brojilac*r2.imenilac+r2.brojilac*r1.imenilac; temp.imenilac=r1.imenilac*r2.imenilac; return temp; } Razlomci &Razlomci::operator+=(const Razlomci &r){ brojilac=brojilac*r.imenilac+imenilac*r.brojilac; imenilac=imenilac*r.imenilac; return *this; } Razlomci &Razlomci::operator++(){ return (*this)+=1; } Razlomci Razlomci::operator++(int i){ Razlomci temp(*this);//Kreira kopiju objekta koji inkrementiramo. (*this)+=1;//Inkrementira vrednost objekta. return temp;//Vraca vrednost pre inkrementiranja. } main(){ int b,i; cout<<"Unesite vrednosti za brojioce i imenioce razlomaka"<<endl; cin>>b>>i; Razlomci r1(b,i); cin>>b>>i; Razlomci r2(b,i); Razlomci priv; priv=r1+r2; priv.ispisi(); r1++; r1.ispisi(); priv=r1++; priv.ispisi(); ++r1; r1.ispisi(); r1+=r2; r1.ispisi(); r1+=(r2++); r1.ispisi(); priv=r1+r2+5; priv.ispisi(); (5+r2).ispisi(); getch(); }

_____________________________________________________________________________

Rekli smo da klase predstavljaju korisnički definisani tip podataka. Znamo da kod ugrađenih tipova podataka postoje i ugrađeni operatori kojima vršimo operacije nad njima. Logično je očekivati da kad pravimo novi tip podataka želimo da imamo mogućnost manipulacije nad podacima tog tipa. U ovom slučaju želimo da imamo mogućnost sabiranja, inkrementiranja i dekrementiranja racionalnih brojeva. Operatori se preklapaju tako da im se ne izgubi smisao. Dakle, ako želimo preklopiti operator + za dva racionalna broja on treba da obavlja funkciju sabiranja na očekivani način. Operatori se mogu preklopiti bilo kao funkcije članice ili kao prijateljske funkcije. Uputno je operatore koji menjaju vrednost levog operanda realizovati kao funkciju članicu, a ako se njime obavlja neka simetrična operacija kao prijateljsku funkciju. Bitno je zapamtiti da nije dozvoljeno uvođenje novih simbola za operatore ni promena prioriteta. Ako za jednu klasu preklopimo operator + i *, uvek će * imati veći prioritet nego +, kao i kod standardnih tipova podataka. Objasnimo na početku šta se podrazumeva pod zahtevom da operator sabiranja treba da bude preklopljen tako da se racionalni brojevi mogu sabirati sa celim, pri čemu se celi broj može naći i kao lijevi i kao desni operand. Ovaj uslov nas ograničava

Page 36: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

35

da operator sabiranja moramo realizovati kao prijateljsku funkciju. Kada bi je realizovali kao funkciju članicu i ukoliko bismo u programu imali naredbu tipa 5+r2; pri čemu je r2 objekat naše klase pozvali bismo funkciju 5.operator+(r2); i došlo bi do greške u programu. Ukoliko bi imali naredbu tipa r2+5; izvršila bi se odgovarajuća konverzija cijelog broja u racionalni i program bi radeo kako treba, pogledajmo i zašto. Kada operator preklapamo kao funkciju članicu šalje se samo desni operand kao argument. Ukoliko smo rekli da šaljemo objekat, a ne referencu na taj objekat, i pošaljemo celi broj 5 vršiće se kopiranje vrednosti koju smo poslali u privremeni objekat. Mi nismo poslali tip koji odgovara pa će se tražiti funkcija koja može da izvrši konverziju tipa, ukoliko takva funkcija ne postoji doći će do greške u programu. Mi zapravo pozivamo konstruktora koji će inicijalizovati privremenu promenljivu tim brojem 5. Da ne bi došlo do greške mi moramo realizovati konstruktora tako da vrši konverziju cijelog broja u racionalni, to smo i učinili. Kada se naš konstruktor pozove sa jednim argumentom (5), drugi uzima podrazumevanu vrednost i celi broj 5 pretvara u racionalni 5/1. Sada se postavlja pitanje zašto nastaje greška ako je celi broj sa leve strane operatora a operator je preklopljen kao funkcija članica. U ovom slučaju bi se pozvala funkcija 5.operator+(r2); i imali bi grešku jer se konverzija tipa vrši samo za prave argumente a ne i za skriveni argument (pokazivac this kojim se prenosi objekat za koji je pozvana funkcija, u ovom slučaju 5), pa bi pozivali funkciju članicu klase racionalnih brojeva za podatak koji nije član te klase. Dakle, važno je zapamtiti da ukoliko realizujemo operator koji je simetričan poželjno ga je realizovati kao prijateljsku funkciju, a ukoliko se očekuje potreba za konverzijom tipa i sa lijeve i sa desne strane operatora mora se tako realizovati. Pored toga što u tom slučaju mora biti realizovan kao prijateljska funkcija, argumenti funkcije ne smiju biti tipa reference na objekat jer u tom slučaju ne bi došlo do kopiranja i konverzije tipa formalnog argumenta u stvarni, ne bi se pozivao konstruktor. Kada god nam nije potrebna konverzija argumente šaljemo kao referencu na objekat da se ne bi vršilo bespotrebno usporavanje programa kopiranjem stvarnih u formalne argumente. Operator + smo preklopili kao prijateljsku funkciju i, s obzirom da je to globalna funkcija a ne funkcija članica, kao argumente moramo poslati oba operanda. Prijateljska je, dakle ima prava pristupa privatnim podacima članovima klase. Sama logika realizacije u potpunosti prati način sabiranja dva razlomka. Kao rezultat dobijamo takođe razlomak. Postavlja se pitanje zašto je potrebno ovde vratititi objekat a ne referencu na njega. Vidimo da se vraća vrednost privremene promenljive temp, znamo da ova promenljiva postoji samo u toku izvršavanja funkcije odnosno, čim se završi izvršavanje ove funkcija ta promenljiva više ne postoji. Dakle, kada bismo vratili referencu na nju vratili bi referencu na nešto što ne postoji. Kada rezultat vratimo kao objekat mi zapravo vršimo kopiranje vrednosti tog objekta u neku promenljivu koja prihvata rezultat, što je dozvoljeno. Operator += će na već postojeću vrednost levog operanda dodavati vrednost desnog i vraćati kao rezultat njegovu novu vrednost. Na osnovu ranije rečenog zaključujemo da ga je poželjno realizovati kao funkciju članicu. Ovo je binarni operator pa obzirom da je funkcija članica klase šaljemo joj samo jedan objekat, desni. Za levi će se pozivati i biće joj prosleđen preko implicitnog argumenta this. Realizacija prati logiku same operacije. Primjećujemo da se ovde vraća kao rezultat referenca na objekat, to je ovde dozvoljeno jer je to *this odnosno referenca na objekat za koji je pozvana funkcija a koji postoji i nakon izvršavanja programa. Mogli smo vratiti i vrednost tog objekta ali bi na taj način vršili nepotrebno kopiranje i usporavanje programa. Postoji jedna specifičnost u realizaciji prefiksne i postfiksne operacije za sabiranje. Obe su unarne operacije i menjaju vrednost operanda pa će biti realizovane kao funkcije članice. Unarne su a funkcije članice dakle nije im potrebno proslijeđivati ništa. Iz tog razloga bi obe imale ime operator++() i bilo bi ih nemoguće razlikovati. Razlikovanje je omogućeno tako što se postfiksnoj funkciji uvodi formalni argument tipa int, koji služi samo da bi se omogućilo razlikovanje ove dve funkcije, nije mu potrebno, čak, ni davati ime prilikom definicije te funkcije. Prefiksno inkrementiranje menja vrednost objekta za koji je pozvana funkcija i vraća tako izmenjeni objekat. Primetite da smo prilikom realizacije ove funkcije iskoristili već preklopljeni operator +=. Iz istog razloga kao za prethodnu funkciju tip rezultata je referenca. Postfiksno inkrementiranje vrši inkrementiranje objekta koji smo mu poslali ali vraća njegovu prethodnu vrednost. Zašto

Page 37: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

36

ovde nismo stavili da je tip rezultata referenca već objekat. Obratite pažnju koje se funkcije pozivaju za koju operaciju u glavnom programu. Kako bi glasilo njihovo eksplicitno pozivanje?

Primer rada programa

_____________________________________________________________________________

Unesite vrednosti za brojioce i imenioce razlomaka

2 3

3 4

17/12

5/3

5/3

11/3

53/12

248/48

2288/192

27/4

_____________________________________________________________________________

Zadatak 4.2

Realizovati klasu koja predstavlja realne brojeve u zapisu sa decimalnom tačkom (npr.

23.45). Klasa će imati dva podatka člana: jedan za realan broj (23.45) a drugi za celi deo tog

broja (23). Izvršiti preklapanje operatora -, -= kao i operatora za prefiksno i postfiksno

dekrementiranje. Prilikom realizacije operatora - uzeti u obzir i mogućnosti oduzimanja

brojeva u decimalnom zapisu i celih brojeva, pri čemu se celi broj može očekivati i kao levi i

kao desni operand.

_____________________________________________________________________________ #include <iostream> #include <math.h> #include <conio.h> using namespace std; class Decimalni{ private: float broj; int celi_deo; public: Decimalni(float=0);//,int=0); ~Decimalni(){} friend Decimalni operator-(Decimalni,Decimalni); Decimalni &operator-=(const Decimalni &); Decimalni &operator--(); Decimalni operator--(int); void citaj(){cout<<"Broj je:"<<broj<<". Celi deo je:"<<celi_deo<<endl;} }; Decimalni::Decimalni(float a):broj(a),celi_deo((int)broj){} Decimalni operator-(Decimalni a,Decimalni b){ Decimalni temp; temp.broj=a.broj-b.broj; temp.celi_deo=int(temp.broj); return temp; } Decimalni &Decimalni::operator-=(const Decimalni &a){

Page 38: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

37

*this=(*this)-a; return *this; } Decimalni &Decimalni::operator--(){ (*this)-=1; return *this; } Decimalni Decimalni::operator--(int){ Decimalni temp=*this; (*this)-=1; return temp; } main(){ Decimalni a(23.45),b(12.11),c; (a-b).citaj(); c=a-5; c.citaj(); c=5-b;c.citaj(); c=b--; c.citaj(); b.citaj(); c=--b; c.citaj(); b.citaj(); b-=a; b.citaj(); b-=5; b.citaj(); getch(); }

_____________________________________________________________________________

Ovaj primer se realizuje prateći istu logiku kao u prethodnom. Voditi računa o načinu realizacije

operatore - - i - =. Uzeti u obzir da se celi deo ne može dobiti prostim oduzimanjem podataka

članova objekata u kojima je sadržana celobrojna vrednost. Naime, ukoliko imamo dva objekta

2.13 i 3.21 i izvršimo oduzimanje 3.13-2.21=0.92, ceo deo rezultata je 0 dok bi prostim

oduzimanjem celih delova dobili 1, dakle, pogrešili bi.

Primer rada programa

_____________________________________________________________________________

Broj je:11.34. Celi deo je:11

Broj je:18.45. Celi deo je:18

Broj je:-7.11. Celi deo je:-7

Broj je:12.11. Celi deo je:12

Broj je:11.11. Celi deo je:11

Broj je:10.11. Celi deo je:10

Broj je:10.11. Celi deo je:10

Page 39: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

38

Broj je:-13.34. Celi deo je:-13

Broj je:-18.34. Celi deo je:-18

_____________________________________________________________________________

Zadatak 4. 3

Realizovati apstraktni tip podataka koji predstavlja kompleksne brojeve, izvršiti preklapanje operatora ==, != i <. Klasa sadrži konstruktore i destruktore.

_____________________________________________________________________________ #include <iostream> #include <conio.h> using namespace std; class Kompleks{ private: float real; float imag; public: Kompleks(float a=0, float b=0):real(a),imag(b){} ~Kompleks(){} friend bool operator==(const Kompleks,const Kompleks); friend bool operator<(const Kompleks, const Kompleks); friend bool operator!=(const Kompleks, const Kompleks); void citaj(){cout<<real<<"+ j"<<imag;} }; bool operator==(const Kompleks a,const Kompleks b){ return (a.real==b.real)&&(a.imag==b.imag); } bool operator!=(const Kompleks a,const Kompleks b){ return !(a==b); } bool operator<(const Kompleks a,const Kompleks b){ return (pow(a.real,2)+pow(a.imag,2))<(pow(b.real,2)+pow(b.imag,2)); } main(){ Kompleks k1(1,2), k2(1,3), k3(1,1), k4(1,2); if(k1==k2) { k1.citaj(); cout<<"=="; k2.citaj();cout<<endl;} else {k1.citaj(); cout<<"!="; k2.citaj();cout<<endl;} if(k1==k4) { k1.citaj(); cout<<"=="; k4.citaj();cout<<endl;} else {k1.citaj(); cout<<"!="; k4.citaj();cout<<endl;} if(k1!=k2) { k1.citaj(); cout<<"!="; k2.citaj();cout<<endl;} else {k1.citaj(); cout<<"=="; k2.citaj();cout<<endl;} if(k1!=k4) { k1.citaj(); cout<<"!="; k4.citaj();cout<<endl;} else {k1.citaj(); cout<<"=="; k4.citaj();cout<<endl;} if(k1<k2) { k1.citaj(); cout<<"<"; k2.citaj();cout<<endl;} else {k1.citaj(); cout<<">="; k2.citaj();cout<<endl;} if(k1<k3) {

Page 40: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

39

k1.citaj(); cout<<"<"; k3.citaj();cout<<endl;} else {k1.citaj(); cout<<">="; k3.citaj();cout<<endl;} if(k1<k4) { k1.citaj(); cout<<"<"; k4.citaj();cout<<endl;} else {k1.citaj(); cout<<">="; k4.citaj();cout<<endl;} if(k1<3) { k1.citaj(); cout<<"< 3"<<endl;} else {k1.citaj(); cout<<">= 3";cout<<endl;} if(k1!=1) { k1.citaj(); cout<<"!= 1";cout<<endl;} else {k1.citaj(); cout<<"== 1"; cout<<endl;} if(k1==1) { k1.citaj(); cout<<"== 1";cout<<endl;} else {k1.citaj(); cout<<"!= 1"; cout<<endl;} getch(); }

_____________________________________________________________________________

Rešenje ovog problema je veoma jednostavno, sve smo operatore realizovali kao prijateljske fukcije jer su svi simetrični. Obratite pažnju na to da smo kao fiktivne argumente funkcija u svim slučajevima imali objekte a ne reference. Zašto?

Primer rada programa

_____________________________________________________________________________

1+ j2!=1+ j3

1+ j2==1+ j2

1+ j2!=1+ j3

1+ j2==1+ j2

1+ j2<1+ j3

1+ j2>=1+ j1

1+ j2>=1+ j2

1+ j2< 3

1+ j2!= 1

1+ j2!= 1

_____________________________________________________________________________

Zadatak 4. 4

Kreirati klasu Knjiga koja će imati kao podatak član pokazivač na celi broj koji predstavlja broj

stranica. Za datu klasu izvršiti preklapanje operatora =.

_____________________________________________________________________________

#include <iostream> #include <conio.h> using namespace std; class Knjiga{ private: int *br_strana; public: Knjiga(){br_strana=0;} Knjiga(int);

Page 41: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

40

Knjiga(const Knjiga&); ~Knjiga(); Knjiga & operator=(const Knjiga&); void dodaj_strane(int a){*br_strana+=a;} void ocitavanje(){cout<<"Knjiga ima "<<*br_strana<<" stranica"<<endl;} }; Knjiga::Knjiga(int br){ br_strana=new int; *br_strana=br; } Knjiga::Knjiga(const Knjiga & stara){ br_strana=new int; *br_strana=*stara.br_strana; } Knjiga::~Knjiga(){ delete br_strana; br_strana=0; } Knjiga &Knjiga::operator=(const Knjiga & a){ if(this!=&a) {//provjera da li je dodjela a=a; delete br_strana; br_strana=new int; *br_strana=*a.br_strana; } return *this; } main(){ Knjiga k1; cout<<"Unesi broj stranica"<<endl; int n; cin>>n; Knjiga k2(n); Knjiga k3=k2; //Poziva se konstruktor kopije; k1=k2;//Vrsi se operacija dodeljivanja-poziva se operator dodeljivanja. k1.ocitavanje(); k3.dodaj_strane(5); k2.ocitavanje(); k3.ocitavanje(); getch(); }

_____________________________________________________________________________

Ranije smo pomenuli da kompajler automatski definiše operator dodele. Način na koji

operator dodele vrši dodeljivanje je analogan načinu na koji default konstruktor kopije vrši

incijalizaciju. Iz istih razloga kao kod konstruktora kopije i ovde, u nekim slučajevima, moramo

definisati sopstveni operator dodele. Uvek kada je za neku klasu neophodno definisati

konstruktor kopije neophodno je definisati i operator dodele ukoliko ćemo ga koristiti u radu sa

tom klasom. Podsetimo se da je konstruktor kopije potrebno definisati kad neka klasa poseduje

promenljivu pokazivačkog tipa. To je slučaj u našem primeru. Realizacija konstruktora,

destruktora i konstruktora kopije je izvršena na uobičajen način. Prvi put se srećemo samo sa

preklapanjem operatora dodele. On se uvek mora realizovati kao funkcija članica. Kao argument

mu se može poslati objekat, referenca na objekat ili konstantna referenca na objekat iste klase.

Mi ćemo uvek slati konstantnu referencu na objekat. Referencu da ne bismo vršili bespotrebno

kopiranje, a konstantnu da bi izbjegli slučajno mijenjanje vrednosti objekta. Logika operacije

Page 42: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

41

dodeljivanja jeste da se dodijeli vrednost desnog operanda lijevom i da se njegova vrednost pri

tome ne mijenja i mi ćemo se toga pridržavati. Važno je primjetiti da se operator dodele razlikuje

od konstruktora kopije po tome što on mijenja vrednost nekom objektu koji već postoji, dok

konstruktor kopije stvara novi objekat. Čim taj objekat postoji znači da je imao neku staru

vrednost. Rekli smo da se potreba za realizovanjem sopstvenog operatora dodele javlja kad kao

podatak član imamo pokazivačku promenljivu. U našem zadatku to nije slučaj ali ovakva

promenljiva najčešće ukazuje na početak nekog niza koji ima proizvoljan broj elemenata.

Pokazivačka promenljiva na početak niza kojem se dodeljuje nova vrednost može ukazivati na niz

sa manje ili više objekata od niza na koji ukazuje promenljiva objekta čija se vrednost dodeljuje.

U oba slučaja ne možemo u isti memorijski prostor prosto prepisati vrednosti niza novog objekta.

U prvom slučaju nemamo dovoljno memorije a u drugom bi dobili niz koji na početku ima

elemente novog niza a na kraju starog. Da se ovakve stvari ne bi dešavale dobra praksa je uvek

prvo izbrisati stari sadržaj promenljive (niza) na koju je ukazivao pokazivač, pa onda zauzeti novi

memorijski prostor koji će biti dovoljan da prihvati novu promenljivu (niz) i onda izvršiti kopiranje

element po element. U našem slučaju smo imali pokazivač na celobrojnu promenljivu i izgleda

suvišno oslobađati memoriju koju je zauzimala cjelobrojna promenljiva pa zauzimati novu, s

obzirom da u oba slučaja imamo potrebu za istom količinom memorije, ali smo to učinili u duhu

ranijeg razmatranja. Bitno je uzeti u obzir mogućnost dodele tipa k1=k1 pri čemu je k1 objekat

klase za koju se preklapa operator dodele. S obzirom da prvo oslobađamo memoriju koju je

zauzimala stara vrednost promenljive kojoj se nešto dodeljuje i brišemo tu vrednost, u slučaju

ovakve naredbe bi značilo da smo izbrisali vrednost promenljive koju želimo da dodelimo. Da bi

se to izbjeglo mi proveravamo da li je adresa objekta čiju vrednost dodeljujemo ista kao onog

kojem se ta vrednost dodeljuje, ukoliko jeste, ne činimo ništa sa objektom, on već sadrži željenu

vrednost, i vraćamo referencu na objekat za koji smo pozvali funkciju. Ukoliko nije, vršimo

prethodne operacije, menjamo vrednost objekta za koji je pozvana funkcija i vraćamo referencu

na taj objekat, koji sada ima novu, željenu, vrednost. Primetimo da ovde, nakon brisanja sadržaja

pokazivačke promenljive nemamo naredbu kojom joj dodeljujemo vrednost nula, to je iz razloga

što bi to bila suvišna naredba s obzirom da već u sledećem koraku ta pokazivačka promenljiva

dobija novu vrednost. Funkcija dodaj_strane() je veoma jednostavna i upotrebili smo je da

pokažemo kako će ovakvom realizacijom operatora dodeljivanja objekti k3 i k2 biti potpuno

nezavisni nakon naredbe k2=k3; što ne bi bio slučaj da smo koristili default operator dodele, već

bi se sve promene jednog objekta odrazile na drugi.

Primer rada programa

Unesi broj stranica

123

Knjiga ima 123 stranica

Knjiga ima 123 stranica

Knjiga ima 128 stranica

_____________________________________________________________________________

Zadatak 4. 5

Realizovati klasu student koja će imati podatke o imenu i prezimenu studenta, godini studija i

godini upisa, kao i statičku promenljivu koja računa ukupan broj studenata. Klasa ima

odgovarajuće konstruktore i destruktora, preklopljene operatore dodele i postfiksnog i

prefiksnog inkrementiranja (inkrementiranje povećava godinu studija za jedan), kao i

Page 43: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

42

prijateljsku funkciju koja za dati skup studenata računa, na svakoj godini, koji student je

najduže na studijama i ispisuje njegovo ime, datum upisa kao i godinu na kojoj je.

_____________________________________________________________________________

#include <iostream.h> #include <conio.h> #include <string.h> using namespace std; class Student{ private: char *ime; char *prezime; int gd_upisa; int gd_studija; public: static int ukupno; Student(){ime=0; prezime=0; ukupno++;} Student(int,int,char *,char *); Student(const Student &); ~Student(){delete []ime; ime=0; delete []prezime; prezime=0;ukupno--;} Student &operator=(const Student &); Student &operator++(); Student operator++(int); friend void Pretrazi(Student *, int); void citaj(){cout<<ime<<" "<<prezime<<" "<<gd_upisa<<" "<<gd_studija<<endl;} }; int Student::ukupno=0; Student::Student(int a,int b,char *ime1, char *prezime1):gd_upisa(a),gd_studija(b){ ime=new char[strlen(ime1)+1]; strcpy(ime,ime1); prezime=new char[strlen(prezime1)+1]; strcpy(prezime,prezime1); ukupno=ukupno++; } Student::Student(const Student & stari):gd_studija(stari.gd_studija),gd_upisa(stari.gd_upisa){ ime=new char[strlen(stari.ime)+1]; strcpy(ime,stari.ime); prezime=new char[strlen(stari.prezime)+1]; strcpy(prezime,stari.prezime); ukupno=ukupno++; } Student &Student::operator=(const Student &stari){ if(&stari!=this){ delete []ime; delete []prezime; gd_studija=stari.gd_studija; gd_upisa=stari.gd_upisa; ime=new char[strlen(stari.ime)+1]; strcpy(ime,stari.ime); prezime=new char[strlen(stari.prezime)+1]; strcpy(prezime,stari.prezime); } return *this; } Student &Student::operator++(){ gd_studija+=1;

Page 44: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

43

return *this; } Student Student::operator++(int){ Student temp(*this); temp.gd_studija+=1; return temp; } void Pretrazi(Student *grupa,int broj){ Student temp[5]; for(int i=0;i<5;i++) temp[i]=Student(2003,i+1,"Nema","studenata"); for(int j=0;j<broj;j++){ if(grupa[j].gd_studija==1){ if(grupa[j].gd_upisa<temp[0].gd_upisa) temp[0]=grupa[j];} else if(grupa[j].gd_studija==2){ if(grupa[j].gd_upisa<temp[1].gd_upisa) temp[1]=grupa[j];} else if(grupa[j].gd_studija==3){ if(grupa[j].gd_upisa<temp[2].gd_upisa) temp[2]=grupa[j];} else if(grupa[j].gd_studija==4){ if(grupa[j].gd_upisa<temp[3].gd_upisa) temp[3]=grupa[j];} else{ if(grupa[j].gd_upisa<temp[4].gd_upisa) temp[4]=grupa[j];} } for(int i=0;i<5;i++){ cout<<"Student koji najduze studira na "<<temp[i].gd_studija\ <<" -oj godini se zove"; cout<<temp[i].ime<<" "<<temp[i].prezime; if(temp[i].gd_upisa!=2003) cout<<" i upisao je "<<temp[i].gd_upisa<<endl; } } main(){ Student ps[5]; int upis; int gd; char pom1[10]; char pom2[10]; ps[0]=Student(2001,1,"Slavica","Petranovic"); cout<<"Unesite podatke za 5 studenata: godinu upisa, godinu na kojoj je"; cout<<" ime i prezime"<<endl; for(int i=1;i<5;i++){ cin>>upis>>gd>>pom1>>pom2;; ps[i]=Student(upis,gd,pom1,pom2);} Student a(122,12,"Janko","Marjanovic"); Student b; b=a; b.citaj(); Pretrazi(ps,5); for(int i=0;i<5;i++){ps[i].citaj();} getch(); }

_____________________________________________________________________________

Ovaj primer objedinjuje ranije rađene zadatke. Primetite da smo prijateljsku funkciju realizovali tako što smo na početku pretpostavili da nema studenta na datoj godini pa onda koristili ranije pomenuti metod za traženje najvećeg, najmanjeg člana u nizu. Ukoliko je objekat niza odgovarao željenoj godini studija proveravali smo godinu upisa, ukoliko je manja od godine upisa tekućeg, najstarijeg studenta, najstariji je postajao taj objekat.

Page 45: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

44

Primer rada programa

_____________________________________________________________________________

Unesite podatke za 5 studenata: godinu upisa, godinu na kojoj je ime i

prezime

1999 2 Ilija Ilickovic

2001 3 Maja Marjanovic

2000 2 Janko Jovicevic

1978 3 Sanja Mugosa

Janko Marjanovic 122 12

Student koji najduze studira na 1 -oj godini se zove: Slavica Petranovic i

upisao je 2001

Student koji najduze studira na 2 -oj godini se zove: Ilija Ilickovic i

upisao je 1999

Student koji najduze studira na 3 -oj godini se zove: Sanja Mugosa i upisao

je 1978

Student koji najduze studira na 4 -oj godini se zove: Nema studenata

Slavica Petranovic 2001 1

Ilija Ilickovic 1999 2

Maja Marjanovic 2001 3

Janko jovicevic 2000 2

Sanja Mugosa 1978 3

_____________________________________________________________________________

Page 46: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

45

5. Nasleđivanje

Zadatak 5 1

Projektovati klase krug i kvadrat koje su izvedene iz klase figure (sadrži težiste kao

zajedničku karakteristiku za sve figure, funkciju koja omogućava pomeraj težista za zadatu

vrednost i virtuelne funkcije obim, površina i čitaj). Klase treba da imaju specifične funkcije

za računanje obima i površine kao i očitavanje odgovarajućih podataka članova.

_____________________________________________________________________________ #include<iostream.h> #include<conio.h> class Tacka{ private: float x; float y; public: Tacka(float a=0,float b=0):x(a),y(b){} ~Tacka(){} float aps(){return x;} float ord(){return y;} void Tcitaj(){cout<<"("<<x<<","<<y<<")";} }; const Tacka KP; class Figura{ private: Tacka teziste; public: Figura(Tacka t=KP):teziste(t){} virtual ~Figura(){} void pomjeri(float a, float b){teziste=Tacka(teziste.aps()+a,teziste.ord()+b);} virtual float Obim()const=0; virtual float Povrsina()const=0; virtual void citaj(){cout<<"T="; teziste.Tcitaj();} }; class Krug : public Figura{ private: float poluprecnik; public: Krug(float rr=1, Tacka k=KP):Figura(k),poluprecnik(rr){}; ~Krug(){} float Obim()const{const float pi=3.14; return 2*poluprecnik*pi;} float Povrsina()const{const float pi=3.14; return pow(poluprecnik,2)*pi;} void citaj(); }; void Krug::citaj(){ cout<<"U pitanju je krug: [ r="<<poluprecnik<<","; Figura::citaj(); cout<<", O="<<Obim()<<", P="<<Povrsina()<<" ]"<<endl; } class Kvadrat:public Figura{ private: float osnovica; public: Kvadrat(float a=1, Tacka t=KP):Figura(t),osnovica(a){} ~Kvadrat(){} float Obim()const{return 4*sosnovica;}

Page 47: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

46

float Povrsina()const{return pow(osnovica,2);} void citaj(); }; void Kvadrat::citaj(){ cout<<"U pitanju je kvadrat: [ a="<<osnovica<<","; Figura::citaj(); cout<<", O="<<Obim()<<", P="<<Povrsina()<<" ]"<<endl; } main(){ Figura *pf[4]; pf[0]=new Krug; pf[1]=new Kvadrat; pf[2]=new Krug(2,Tacka(3,3)); pf[3]=new Kvadrat(2.5,Tacka(1.3,2)); for(int j=0;j<4;j++) pf[j]->citaj(); pf[0]->pomjeri(1,0.5); pf[1]->pomjeri(0.5,1); for(int j=0;j<2;j++) pf[j]->citaj(); for(int j=0;j<4;j++) {delete pf[j]; pf[j]=0;} getch(); }

_____________________________________________________________________________

Uvek kada imamo naleđivanje klasa prvo definišemo osnovnu klasu da bi imali pregled

onoga što radimo. U postavci zadatka je rečeno da osnovna klasa ima podatak o težištu figure.

Težište se predstavlja koordinatama u Dekartovom koordinatnom sistemu. Mi smo to rešili tako

što smo prvo definisali klasu Tacka pa smo kao podatak član klase Figura uzeli objekat klase

Tacka. Moglo se to odraditi i bez definicije posebne klase Tacka ali s obzirom na prirodu

problema, rad sa geometrijskim figurama, može se očekivati potreba za više objekata tipa Tacka

kada bi morali imati klasu Tacka zasebno realizovanu. Osnovna klasa može imati funkcije članice

koje se realizujuju kao i u ranije korišćenim klasama ali se kod nasleđivanja pojavljuju i virtuelne

funkcije. Potreba za njima se javlja zbog same prirode nasleđivanja. Nasleđivanje koristimo kada

imamo neke nove tipove koji imaju iste osobine kao neki postojeći tipovi (osnovne klase) ali i

neke specifične osobine. U našem primeru smo izveli klase Krug i Kvadrat iz klase Figura. Obe

geometrijske figure imaju težište ali krug ima i poluprečnik dok smo kvadrat karakterisali

dužinom osnovice. Svaka geometrijska figura se karakteriše mogućnošću izračunavanja obima i

površine ali se za svaku od njih izračunava na drugi način. Takođe će i način ispisivanja

komentara o određenoj figuri zavisiti od toga koja je: krug ili kvadrat. Shodno tome dolazi do

potrebe za korišćenjem virtuelnih funkcija. Da bi kompajler znao da je u pitanju virtuelna funkcija

potrebno je navesti ključnu reč virtual u deklaraciji funkcije u osnovnoj klasi, u definicijama

izvedenih klasa nije potrebno to ponavljati. Virtuelne funkcije se karakterišu time da će se

izvršavati na način koji je deklarisan u klasi za koju se pozivaju bez obzira što se pozivaju preko

pokazivača na osnovnu klasu. Naime, kao što se vidi u glavnom programu, moguće je izvršiti

implicitnu konverziju pokazivača na objekat izvedene klase u pokazivač na objekat osnovne klase.

Obratno se ne preporučuje! U glavnom programu smo imali skup krugova i kvadrata, da ne bi

Page 48: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

47

svaki put proveravali da li je u pitanju krug ili kvadrat pa onda pozivali odgovarajuću funkciju mi

smo iskoristili virtuelne funkcije. Deklarisali smo niz pokazivača na objekte osnovne klase, zatim

svakom dodijelili vrednost pokazivača na neku od izvedenih klasa i u jednoj petlji pozivali

virtuelne funkcije za računanje obima i površine. S obzirom da su virtuelne, koriste dinamičko

povezivanje odnosno pozivaju onu funkciju koja odgovara objektu na koji ukazuje taj pokazivač a

ne objektu koji odgovara tipu pokazivača. Dakle, bez obzira što je pokazivač deklarisan kao

pokazivač na osnovnu klasu, Figure, izvršavaće se funkcija koja odgovara klasi čija je instanca

objekat na koji ukazuje taj pokazivač, Krug ili Kvadrat. Primetimo da kada funkciji pristupamo

preko pokazivača koristimo operator—>. Da bi se funkcije realizovale kao virtuelne nije dovoljno

samo navesti ključnu reč virtual u osnovnoj klasi. Potrebno je da kada budemo definisali tu

funkciju u izvedenim klasama ona bude identična po pitanju imena, broja i tipa argumenata kao i

tipa rezultata onoj u osnovnoj klasi, čak je potrebno u svim klasama navesti ključnu reč const

ukoliko je ona navedena u osnovnoj klasi kao što je slučaj kod nas. Ukoliko ovo nije izvršeno

sakrili smo funkciju iz osnovne klase. Dakle neće biti u pitanju funkcija sa preklopljenim imenom,

i možemo joj pristupiti samo uz pomoc operatora ::. Primer virutelnih funkcija su obim(),

povrsina() i citaj(). Vidimo da je samo poslednja i definisana u okviru osnovne klase, to je iz

razloga što ne znamo na koji ćemo način izračunati obim i površinu nekog objekta dok ne vidimo

koji je to objekat (krug ili kvadrat) a moramo joj navesti deklaraciju u osnovnoj klasi da bi

realizovali mehanizam virtuelne funkcije. Da se ne bi pisalo prazno telo funkcije uvodi se čisto

virtuelna funkcija. Kompajler je razlikuje po tome što nema telo funkcije ali ima =0 na kraju

standardnog zaglavlja. Klasa koja poseduje makar jednu čisto virtuelnu funkciju je apstraktna

klasa i ne mogu se deklarisati objekti te klase ali mogu pokazivači i reference na tu klasu. U

našem slučaju nismo imali potrebu za pristupanjem podacima članovima osnovne klase Figura

(koji su ujedno i podaci članovi izvedenih klasa, naslijedili su ih od osnovne) u nekoj od izvedenih

klasa pa smo ih realizovali kao private. Ukoliko bi imali potrebu za pristupanjem realizovali bi ih

kao protected. Na ovaj način dajemo dozvolu klasi koja se izvodi iz osnovne da može da direktno

pristupa tim podacima, dok se van te izvedene klase i dalje nema pravo pristupa istim.

Primetimo da smo konstruktor klase Tacka realizovali tako da kada je pozvan bez

argumenata postavlja sve koordinate na nulu. To smo iskoristili da uvedemo jednu globalnu

promenljivu KP koju ćemo koristiti kao podrazumevanu vrednost u svim sledećim

konstruktorima. U osnovnoj klasi je ujedno realizovan i default konstruktor i standardni. Ukoliko

se pozove kao default, težište je u koordinatnom početku. Funkcija za pomjeranje koordinata

težišta (članica klase Figura) ne može direktno da pristupa koordinatama objekta (instanca klase

Tacka) koji je podatak te klase jer su one njegovi privatni podaci i samo funkcije članice klase čija

Page 49: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

48

je on instanca imaju pravo pristupa, pa smo te funkcije i iskoristili da očitamo koordinate. Za

promjenu njihovih vrednosti smo koristili konstruktor. Naime, mi ovde stvaramo novi objekat

težište koji će sadržati informaciju o pomjerenim koordinatama. Funkcija citaj() očitava

koordinate. Klasa Krug je izvedena javno iz klase Figura. To znači da će svi članovi (podaci i

funkcije) koje je ova klasa nasledila od klase Figura imati istu vidljivost kao u njoj, dakle javni

ostaju javni a privatni su i dalje privatni. Izvedena klasa nasleđuje iz osnovne klase sve podatke

članove i funkcije članice i može im pristupati navođenjem njihovog imena ukoliko ima pravo

pristupa. Krug ima kao specifičan podatak u odnosu na klasu Figura, poluprečnik ali takođe i

teziste koje je nasledeo iz nje. S obzirom na ovo konstruktoru se moraju proslijediti vrednosti za

inicijalizaciju oba člana. Karakteristika je kod izvedene klase samo to što se ne mora voditi računa

o tome kako da inicijalizujemo članove koje smo naslijedili iz osnovne klase već se briga o tome

prepušta konstruktoru osnovne klase koji se prvi poziva u konstrukoru izvedene klase. Mi smo

ovde istovremeno realizovali i default konstruktor i konstruktor kojem proslijeđujemo podatke

za inicijalizaciju podataka članova pa smo zato u dijelu za inicijalizaciju eksplicitno naveli poziv

konstruktora osnovne klase kao i podatak koji smo mu poslali. Da smo zasebno realizovali default

konstruktor ne bi morali da pozivamo u njemu default konstruktor osnovne klase, već bi on bio

automatski pozvan na početku izvršavanja konstruktora za izvedenu klasu. Napomenimo da

redosled kojim se navode podaci u inicijalizacionoj listi ne utiče na redosled inicijalizovanja u

smislu da iako poziv konstruktora osnovne klase nije naveden kao prvi ipak će se on prvi pozivati.

U ovoj klasi je moguće definisati funkcije obim() i povrsina() tako da računaju odgovarajuće

podatke na način koji odgovara njenim objektima. Primjećujemo da smo u okviru realizacije

funkcije citaj() pozivali odgovarajuću funkciju klase Figura kojoj smo pristupili pomoći operatora

::. U principu, ovo smo mogli izbjeći da smo podatke klase Figura realizovali kao protected. Na taj

način bi sada imali pravo pristupa tim članovima a da ne moramo pozivati nijednu funkciju

članicu te klase. Ovde smo koristili ovakav način pristupa jer smo željeli da pokažemo razliku

između virtuelne i čisto virtulene funkcije, odnosno, da definišemo funkciju citaj() u osnovnoj

klasi Figura.

Klasa Kvadrat je realizovana koristeći istu logiku kao za Krug.

Obratimo pažnju šta se dešava u glavnom programu. Na početku smo rekli da je pf niz od

četiri pokazivača na objekte klase Figura. Nakon toga smo izvršili dinamičko zauzimanje

memorije za objekte klasa Krug i Kvadrat i postavili pojedine članove niza pokazivača da ukazuju

na tako dobene objekte. Ovo je moguće jer postoji implicitna konverzija pokazivača izvedene

klase na pokazivače osnovne klase. Zanimljivo je da smo sada dobili niz pokazivača koju ukazuju

na objekte koji pripadaju različitim klasama. Nakon toga smo u for petlji pomoću ovih pokazivača

Page 50: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

49

pozvali funkciju citaj(). Zahvaljujući činjenici da nam je ovo virtuelna funkcija uvek će se izvršavati

funkcija citaj() koja pripada klasi na čiji objekat stvarno ukazuje pokazivac pf[i], bez obzira što je

on tipa pokazivača na objekte klase Figure. Nakon for petlje smo pozvali funkciju pomjeri()

pomoću pokazivača koji ukazuju na krug i na kvadrat. U oba slučaja je izvršena funkcija na način

definisan u okviru osnovne klase što je i logično jer data funkcija nije virtuelna pa će se izvršiti za

tip pokazivača a ne za ono na što on stvarno ukazuje. Pošto smo na početku zauzeli dinamički

memoriju moramo je i osloboditi koristeći operator delete. Sada je jasno zašto smo destruktor

realizovali kao virtuelnu funkciju, prilikom izvršavanja naredbe delete pf[i]; poziva se destruktor.

Da nije bio realizovan kao virtuelna funkcija pozivao bi se na osnovu tipa pokazivača, dakle, za

osnovnu klasu pa ne bi bila oslobođena memorija koju zauzimaju članovi specifični za izvedenu

klasu već samo samo memorija zauzeta članovima naslijeđenim od osnovne. Ne bi se oslobodila

sva, ranije, zauzeta memorija. Destruktor realizujemo kao virtuelnu funkciju tako da će se pozvati

destruktor za klasu na čije objekte svarno ukazuje pokazivač i osloboditi sva zauzeta memorija.

Primer rada programa

_____________________________________________________________________________

U pitanju je krug: [ r=1,T=(0,0), O=6.28, P=3.14 ]

U pitanju je kvadrat: [ a=1,T=(0,0), O=4, P=1 ]

U pitanju je krug: [ r=2,T=(3,3), O=12.56, P=12.56 ]

U pitanju je kvadrat: [ a=2.5,T=(1.3,2), O=10, P=6.25 ]

U pitanju je krug: [ r=1,T=(1,0.5), O=6.28, P=3.14 ]

U pitanju je kvadrat: [ a=1,T=(0.5,1), O=4, P=1 ]

Zadatak 5. 2

Pojektovati klase pravougaonik i trougao koje su izvedene iz klase figure (sadrži težište kao

zajedničku karakteristiku za sve figure, funkciju koja omogućava pomeraj težišta za zadatu

vrednost i virtuelne funkcije dijagonala, poluprečnik opisanog i čitaj). Klase treba da imaju

specifične funkcije za računanje dijagonale i poluprečnika opisanog kruga kao i očitavanje

odgovarajućih podataka članova. Za klasu trougao treba realizovati konstruktor tako da može

stvoriti jednakostranični trougao kada se unosi podatak za dužinu jedne stranice kao i opšti

slučaj. Funkcija za računanje dijagonale u slučaju trougla treba da vraća -1. Poluprečnik

opisanog kruga, za trougao (stranica a, b i c) se može računati kao:

_____________________________________________________________________________ #include<iostream.h> #include<math.h> #include<conio.h>

Page 51: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

50

class Tacka{ private: float x; float y; public: Tacka(float a=0,float b=0):x(a),y(b){} ~Tacka(){} void tcitaj()const{cout<<"("<<x<<","<<y<<")";} float aps(){return x;} float ord(){return y;} }; const Tacka KP; class Figure{ protected: Tacka teziste; public: Figure(Tacka t=KP):teziste(t){} virtual ~Figure(){} void Pomjeri(float dx,float dy){teziste=Tacka(dx+teziste.aps(),dy+teziste.ord());} virtual float Dijagonala()const=0; virtual float Poluprecnik()const=0; virtual void citaj()const=0; }; class Pravougaonik:public Figure{ private: float a; float b; public: Pravougaonik(float a1=1,float b1=0.5,Tacka t=KP):a(a1),b(b1),Figure(t){} ~Pravougaonik(){} float Dijagonala()const{return sqrt(a*a+b*b);} float Poluprecnik()const{return Dijagonala()/2;} void citaj()const; }; void Pravougaonik::citaj()const{ cout<<"U pitanju je pravougaonik:[a="<<a<<", b="<<b; cout<<". Teziste je :";teziste.tcitaj(); cout<<", d="<<Dijagonala()<<", R="<<Poluprecnik()<<"]"<<endl; } class Trougao:public Figure{ private: float a1,b1,c1; public: Trougao(float a2=1,Tacka t=KP):Figure(t){a1=b1=c1=a2;} Trougao(float a2,float b2,float c2,Tacka t=KP):a1(a2),b1(b2),c1(c2),Figure(t){} ~Trougao(){} float Dijagonala()const{return -1;} floatPoluprecnik()const{return a1*b1*c1/sqrt(pow(a1*a1+b1*b1+c1*c1,2)+\ 2*(pow(a1,4)+pow(b1,4) +pow(c1,4)));} void citaj()const; }; void Trougao::citaj()const{ cout<<"U pitanju je trougao:[a="<<a1<<", b= "<<b1<<", c= "<<c1; cout<<". Teziste je :";teziste.tcitaj(); cout<<", d="<<Dijagonala()<<", R="<<Poluprecnik()<<"]"<<endl; } main(){

Page 52: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

51

Figure *pf[5]; pf[0]=new Pravougaonik; pf[1]=new Trougao; pf[2]=new Trougao(2.5,3); pf[3]=new Pravougaonik(2,3,Tacka(1,2)); pf[4]=new Trougao(2,4,5,Tacka(1,2)); for(int i=0;i<5;i++) pf[i]->citaj(); pf[0]->Pomjeri(2.3,4); pf[1]->Pomjeri(3.1,2); for(int i=0;i<2;i++) pf[i]->citaj(); for(int j=0;j<4;j++) {delete pf[j]; pf[j]=0;} getch(); }

Ovaj se zadatak razlikuje u odnosu na prethodni samo po tome što smo podatke članove klase

Figure, tj. težište realizovali kao protected tako da smo mogli i iz izvedene klase pristupati

objektu teziste i njegovim funkcijama, konkretno funkciji za očitavanje koordinata. Takođe smo

funkciju citaj() realizovali kao čisto virtuelnu funkciju. Specifičan je i zahtjev za realizacijom

konstruktora klase Trougao, tako da se može formirati jednakostranični trougao kada se unosi

podatak za dužinu jedne stranice. Pogledajmo default konstruktor. On se može pozvati bez

ijednog argumenta, samo sa jednim (koji će biti vrednost za a2 jer je on prvi u listi argumenata,

dok će biti t=KP, i u tom slučaju se ta vrednost a2 dodeljuje dužinama svih stranica, dakle imamo

jednakostraničan trougao) i sa dva argumenta. Razmislite kako biste realizovali konstruktor da se

zahtevalo da za poziv sa dva argumenta formira jednakokraki trougao.

Primer rada programa

_____________________________________________________________________________

U pitanju je pravougaonik:[a=1, b=0.5. Teziste je :(0,0), d=1.11803,

R=0.559017]

U pitanju je trougao:[a=1, b= 1, c= 1. Teziste je :(0,0), d=-1, R=0.258199]

U pitanju je trougao:[a=2.5, b= 2.5, c= 2.5. Teziste je :(3,0), d=-1,

R=0.645497]

U pitanju je pravougaonik:[a=2, b=3. Teziste je :(1,2), d=3.60555,

R=1.80278]

U pitanju je trougao:[a=2, b= 4, c= 5. Teziste je :(1,2), d=-1, R=0.64727]

U pitanju je pravougaonik:[a=1, b=0.5. Teziste je :(2.3,4), d=1.11803,

R=0.559017]

U pitanju je trougao:[a=1, b= 1, c= 1. Teziste je :(3.1,2), d=-1,

R=0.258199]

_____________________________________________________________________________

Zadatak 5. 3

Realizovati klasu časovnik koja će predstavljati vreme u satima, minutima i sekundama. Klasa

ima funkciju za povećavanje broja sekundi za po jednu. Iz date klase izvesti klasu let koja sadrži

naziv i broj leta, neka podaci nasleđeni iz osnovne klase časovnik predstavljaju vreme polaska i

neka postoji funkcija koja će omogućiti promenu ovog vremena za neko zadato kašnjenje.

Napisati glavni program u kojem se zadaje vreme polaska nekog leta i kašnjenje a čita novo

vreme polaska, sa uračunatim kašnjenjem.

_____________________________________________________________________________ #include <iostream.h> #include <conio.h>

Page 53: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

52

#include <string.h> using namespace std; class Casovnik{ protected: int sec,min,sati; public: Casovnik(){} Casovnik(int h,int m,int s):sati(h),min(m),sec(s){} ~Casovnik(){} int Daj_s()const{return sec;} int Daj_m()const{return min;} int Daj_sat()const{return sati;} void Otkucaj(); void citaj(){cout<<sati<<" "<<min<<" "<<sec<<endl;} }; void Casovnik::Otkucaj(){ if(sec==59){ sec=0;min=min+1; if(min==60){ min=0; sati=sati+1; if(sati==24)sati=0;}} else sec=sec+1; } class Let:public Casovnik{ private: char *naziv; public: Let(){naziv=0;} Let(char *,int,int,int); Let(const Let&); ~Let(){delete []naziv;naziv=0;} void Kasnjenje(Casovnik); void Citaj(){cout<<"Naziv leta je: "<<naziv<<". Vreme odlaska je:"; Casovnik::citaj(); } }; Let::Let(char *ime,int h,int m,int s):Casovnik(h,m,s){ naziv=new char[strlen(ime)+1]; strcpy(naziv,ime); } Let::Let(const Let & stara):Casovnik(stara.sati,stara.min,stara.sec){ naziv=new char[strlen(stara.naziv)+1]; strcpy(naziv,stara.naziv); } void Let::Kasnjenje(Casovnik vreme){ int s=0; s=vreme.Daj_sat()*60*60+vreme.Daj_m()*60+vreme.Daj_s(); for(int i=0;i<s;i++) Otkucaj(); } main(){ Let prvi("Beograd-Podgorica",20,30,0); Let drugi(prvi); prvi.citaj(); cout<<"Unesite kasnjenje"; int h,m,s; cin>>h>>m>>s;

Page 54: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

53

prvi.Kasnjenje(Casovnik(h,m,s)); prvi.Citaj(); drugi.Citaj(); }

_____________________________________________________________________________

Realizacija ovog programa je izvršena u skladu sa ranije urađenim primerima. Treba obratiti

pažnju na to da smo podatke članove osnovne klase realizovali kao protected tako da smo im

mogli direktno pristupati u konstruktorima. Ipak, treba praviti razliku kada imamo u funkciji

Kasnjenje() kao argument objekat tipa Casovnik. To je nezavisan objekat koji se šalje kao

argument funkcije, nije ga klasa naslijedila, i njegovim podacima članovima moramo pristupati uz

pomoć javnih funkcija članica klase čija je taj objekat instanca. Vidimo da u okviru realizacije iste

funkcije pristupamo funkciji Otkucaj() samo navođenjem njenog identifikatora, naša klasa ju je

naslijedila od klase Casovnik i može joj tako pristupati u svojoj funkciji članici. Inače, jedna

funkcija članica može pozivati drugu funkciju članicu u svojoj realizaciji samo navođenjem njenog

identifikatora i potrebnih argumenata.

Primer rada programa

_____________________________________________________________________________

20 30 0

Unesite kasnjenje3 30 5

Naziv leta je: Beograd-Podgorica. Vreme odlaska je:0 0 5

Naziv leta je: Beograd-Podgorica. Vreme odlaska je:20 30 0

_____________________________________________________________________________

Zadatak 5. 4

Implementirati klasu motocikl koja je izvedena iz klasa motorno vozilo i vozilo na dva točka a koje su izvedene iz klase vozilo. Klasa vozilo poseduje podatak o registarskim tablicama, motorno vozilo sadrži podatak o jačini motora a klasa vozilo na dva točka o broju sedišta. Klasa motocikl ima kao sopstveni podatak član marku motocikla.

#include <iostream.h> #include <conio.h> #include <string.h> using namespace std; class Vozilo{ protected: char *tablice; public: Vozilo(){tablice=0;} Vozilo(char *); virtual ~Vozilo(){delete []tablice;tablice=0;} virtual void citaj(); }; Vozilo::Vozilo(char * tab){ tablice=new char[strlen(tab)+1]; strcpy(tablice,tab); } void Vozilo::citaj(){

Page 55: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

54

cout<<"U pitanju je vozilo reg. tab. "<<tablice<<endl; } class MotornoVozilo:virtual public Vozilo{ protected: int snaga_motora; public: MotornoVozilo(){} MotornoVozilo(char * br_tab, int sm):snaga_motora(sm), Vozilo(br_tab){} ~MotornoVozilo(){} void citaj(); }; void MotornoVozilo::citaj(){ cout<<"Snaga motora je "<<snaga_motora<<endl; } class Vozilo_na_dva_tocka:virtual public Vozilo{ protected: int br_sjedista; public: Vozilo_na_dva_tocka(int a=0):br_sjedista(a){}//za Vozilo_na_dva_tocka v; // dodeljuje 0 broju sjedista i sam poziva default konstruktor za Vozilo. Vozilo_na_dva_tocka(char *ch,int a):br_sjedista(a),Vozilo(ch){} ~Vozilo_na_dva_tocka(){} void citaj(); }; void Vozilo_na_dva_tocka::citaj(){ cout<<"Broj sjedista je:"<<br_sjedista<<endl; } class Motocikl:public Vozilo_na_dva_tocka,public MotornoVozilo, virtual Vozilo{ private: char * proizvodjac; public: Motocikl(){proizvodjac=0;} Motocikl(char *,char*,int,int); ~Motocikl(){delete []proizvodjac; proizvodjac=0;} void citaj(); }; Motocikl::Motocikl(char * marka,char *tab, int bs,int sm):MotornoVozilo(tab,sm),\ Vozilo_na_dva_tocka(tab,bs), Vozilo(tab){ proizvodjac=new char[strlen(marka)+1]; strcpy(proizvodjac,marka);} void Motocikl::citaj(){ Vozilo::citaj(); MotornoVozilo::citaj(); Vozilo_na_dva_tocka::citaj(); cout<<"Marka motora je "<<proizvodjac<<endl; } void main(){ Vozilo *pv=new Motocikl("Suzuki","PG1234",2,800); pv->citaj(); delete pv;//da destruktor osnovne klase nije virtuelni ovom naredbom bi //oslobodili samo deo memorije u kojem se nalazi niz tablice jer bi se pozvao //destruktor samo za klasu koja odgovara tipu pokazivaca-Vozilo bez obzira //sto pokazivac ukazuje na Motocikl. getch(); }

_____________________________________________________________________________

Page 56: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

55

U ovom slučaju klasa Motocikl je direktno izvedena iz dve klase MotornoVozilo i

Vozilo_na_dva_tocka. Zaključujemo da je u pitanju višestruko nasleđivanje. Klase

MotornoVozilo i Vozilo_na_dva_tocka su izvedene iz osnovne klase Vozilo. S obzirom da

znamo da svaka izvedena klasa naslijeđuje iz osnovne klase sve podatke ovo bi značilo da

klasa motocikl ima dva podatka tablice, jedan naslijeđen od klase MotornoVozilo a drugi od

Vozilo_na_dva_tocka. Logično je da jedan motocikl ne može imati dvoje različitih tablica pa

da bi bili dosledni prirodi problema i naš motocikl mora imati samo jedne tablice. U

programskom jeziku C++ je to omogućeno uvođenjem virtuelnih osnovnih klasa. Primerci

podataka članova virtuelne osnovne klase će biti naslijeđeni samo jedan put bez obzira na to

iz koliko je klasa, koje su izvedene iz ove osnovne, izvedena naša klasa. Neka klasa se čini

virtuelnom osnovnom klasom tako što se u zaglavlju klasa koje se izvode iz nje piše

rezervisana reč virtual. Dakle, već pri izvođenju klasa MotornoVozilo i Vozilo_na_dva_tocka

morali smo imati na umu da će se iz obe klase izvesti jedna nova i da se podaci njihove

osnovne klase ne trebaju naslijeđivati bez jedan put pa je tu potrebno postaviti identifikator

virtual, kasnije se to ne može učiniti. Ranije smo rekli da se prilikom realizacije konstruktora

neke izvedene klase poziva konstruktor njene osnovne klase, bilo automatski ako nije

naveden eksplicitan poziv ili ga mi pozivamo eksplicitnim pozivom kada želimo proslijediti

neku vrednost za inicijalizaciju. Mi želimo inicijalizovati sve podatke klase Motocikl, kako one

naslijeđene od osnovnih klasa tako i za nju specifičan podatak, proizvodjac. Podatke

naslijeđene od osnovnih klasa inicijalizujemo proslijeđujući odgovarajuće argumente

konstruktoru tih klasa. Konstruktor klase MotornoVozilo zahteva podatke za broj tablica i

snagu motora respektivno. Konstruktor klase Vozilo_na_dva_tocka, takođe, zahteva dva

podatka, za broj tablica i broj sjedišta. Iz realizacije konstruktora za klasu Motocikl vidimo da

će se oba konstruktora pozvati. Zaključilo bi se da se onda dva puta inicijalizuje podatak

tablice naslijeđen iz osnovne klase Vozilo a mi smo je učinili virtuelnom da bi imali samo

jedan podatak tablice. Mehanizam virtuelne osnovne klase se realizuje tako da se u

konstruktoru klase izvedene iz više klasa sa zajedničkom virtuelnom osnovnom klasom,

konstruktor virtuelne osnove klase poziva samo jedan put i to iz konstruktora klase koja je

navedena poslednja u zaglavlju (class Motocikl:public Vozilo_na_dva_tocka, public

MotornoVozilo, virtual Vozilo). S obzirom na ovo dobra programerska praksa je da se uvek

navodi kao poslednja virtuelna osnovna klasa. Ovim nismo ništa promijenili jer će se njeni

podaci naslijediti za sve klase samo jedan put, realizovana je kao virtuelna, ali smo se

osigurali da će njen konstruktor biti sigurno pozvan. Vidimo da smo, bez obzira što sve klase

Page 57: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

56

naslijeđujemo kao javne, za svaku klasu navodili ključnu reč public, da to nismo učinili za

neku klasu ona bi bila naslijeđena kao privatna.

Primer rada programa

_____________________________________________________________________________

U pitanju je vozilo reg. tab. PG1234

Snaga motora je 800

Broj sjedista je:2

Marka motora je Suzuki

_____________________________________________________________________________

6. Šabloni

Zadatak 6. 1

Sastaviti šablonsku funkciju kojom se od dva uređena niza formira treći, na isti način

uređen, niz. Sastaviti glavni program koji primenjuje ovu funkciju nad nizovima celih

brojeva i tačaka, pri čemu su koordinate tačaka celi brojevi kao i nad dve tačke koje imaju

realne koordinate. Klasu tačka realizovati kao šablonsku klasu kako bi koordinate mogle

biti traženog tipa.

_____________________________________________________________________________ #include <iostream> #include <conio.h> #include <math.h> using namespace std; template<class T> void uredi(T *prvi, int n1,T* drugi, int n2,T *treci){ for(int ia=0,ib=0,ic=0;ia<n1||ib<n2;ic++) treci[ic]=ia==n1 ? drugi[ib++]: (ib==n2 ? prvi[ia++] : (prvi[ia] < drugi[ib] ? prvi[ia++] : drugi[ib++])); } template<class S> class sablon{ S x; S y; public: sablon(S=0,S=0); ~sablon(){}; //bool operator<(const sablon<S>&); bool operator<(const sablon&);//Moze i bez <S> void citaj(){cout<<"("<<x<<","<<y<<")"<<endl;} }; template<class S> sablon<S>::sablon(S a,S b):x(a),y(b){} template<class S> bool sablon<S>::operator<(const sablon& b){ return (pow(x,2)+pow(y,2))<(pow(b.x,2)+pow(b.y,2)); } void main(){ int d1[]={1,2,5,7,9}; int d2[]={3,4,7,8}; int *d3=new int[9];

Page 58: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

57

// int n3; uredi(d1,5,d2,4,d3); cout<<"Uredjeni niz je:"<<endl; for(int i=0;i<9;i++)cout<<" "<<d3[i]; cout<<endl; delete []d3; sablon<int> *p; cout<<"Koliko ima tacaka prvi niz?"<<endl; int i1; cin>>i1; cout<<"Unesite niz tacaka sa celobrojnim koordinatama"<<endl; p=new sablon<int>[i1]; int a,b; for(int i=0;i<i1;i++) {cin>>a>>b; p[i]=sablon<int>(a,b);} cout<<"Koliko ima tacaka drugi niz?"; int i2; cin>>i2; cout<<"Unesite niz tacaka sa celobrojnim koordinatama"<<endl; sablon<int> *q; q=new sablon<int>[i2]; for(int i=0;i<i2;i++) {cin>>a>>b; q[i]=sablon<int>(a,b);} int i3; i3=i2+i1; sablon<int> *r; r=new sablon<int>[i3]; uredi(p,i1,q,i2,r); for(int i=0;i<i3;i++) {cout<<" "; r[i].citaj();} cout<<endl; delete []p; delete []q; delete []r; // float a1,b1; sablon <float> t1(2.3,4.6),t4(2.5,6.8); if(t1<t4) { cout<<"Tacka ima koordinate: "; t1.citaj();} else { cout<<"Tacka ima koordinate: "; } }

_____________________________________________________________________________

U zadatku se od nas zahteva da realizujemo funkciju koja će za dva uređena niza

formirati treći, takođe uređen, sastavljen od elemenata dva niza koja šaljemo kao argumente

funkcije. Zapravo šaljemo pokazivače na početak tih nizova. Sama realizacija funkcije nije

novina. Ovo smo, kada su u pitanju nizovi celih i realnih brojeva, mogli odraditi i u

programskom jeziku C. Tamo smo morali davati različita imena funkcijama iako obavljaju istu

radnju jer imaju različite tipove argumenata. Na početku ovog kursa smo rekli da se u C++

može formirati više funkcija sa istim imenom i da će kompajler na osnovu broja i tipova

argumenata za koje se funkcija poziva vršiti razrešavanje poziva. I ako bismo koristili ovakav

pristup opet bismo morali da realizujemo tri funkcije: za cele, realne brojeve i niz tačaka. U

principu bi sve te funkcije realizovali na isti način, samo bi na određenim mestima imali

različite oznake za tip podataka sa kojima radimo. U jeziku C++ postoje šablonske funkcije

koje nam omogućavaju da ovo realizujemo jednom funkcijom tako što ćemo napraviti šablon

Page 59: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

58

za rešavanje datog problema (formiranje trećeg niza na osnovu postojeća dva) ne navodeći

konkretan tip podataka. Na osnovu ovog šablona kasnije će se generisati odgovarajuća

funkcija za konkretan tip podataka. Naime, kada kompajler naiđe na poziv ove funkcije sa

stvarnim argumentima tipa int generisaće funkciju za formiranje sortiranog niza celih

brojeva, kada naiđe na poziv za nizove tačaka generiše funkciju za podatke tipa tacka. Isto

važi i za klase, i one mogu biti šablonske. U našem slučaju potrebna nam je klasa koja

predstavlja tačke zadate koodinatama cjelobrojnog tipa i klasa za realne koordinate. Da ne bi

vršili definiciju dve klase koje se razlikuju samo u tipu podataka članova mi ćemo ovu klasu

realizovati kao šablonsku.

Pogledajmo najpre realizaciju tražene funkcije. Primjećujemo da se pre zaglavlja klase

nalazi nova linija koda template<class T>. Rezervisana reč template govori kompajleru da

ono što slijedi nije obična funkcija već šablonska i da je tretira kao takvu. Unutar zagrada <>

se navode parametri šablona, može ih biti više. Reč class govori da je T tip podatka, bilo koji

tip, bilo neki od ugrađenih, bilo korisnički definisan. Prilikom generisanja funkcije za dati tip

podataka može se zamisliti da kompajler zapravo prolazi kroz funkciju i da na svako mesto na

koje nađe identifikator parametra šablona (u našem slučaju T) postavlja odgovarajući tip i

realizuje takvu funkciju. Na primer, za poziv iz našeg glavnog programa uredi(d1,5,d2,4,d3); T

će se zamijeniti sa int i generisati funkcija koja će raditi sa nizovima celih brojeva. Što se tiče

same funkcije uredi realizujemo je po logici koju smo koristili i u programskom jeziku C.

Šaljemo pokazivač na početak dva niza i broj elemenata niza, kao i pokazivač na početak

novoformiranog niza (treba nam kao rezultat). Umesto određenog tipa naveli smo

parametar šablona T. Na početku su ideksi svih brojača postavljeni na nulu. U svakom ciklusu

for petlje će se brojač koji označava tekući indeks novog niza povećavati za jedan. Naime, u

svakom ciklusu upisujemo nešto u taj niz pa prelazimo na sledeći element koji će nam postati

tekući za sledeći ciklus. Ako smo upisali sve elemente taj brojač je za jedan veći od indeksa

poslednjeg elementa novoformiranog niza, dakle jednak broju elemenata tog niza. Spajanje

ova dva niza je jednostavno. Vrši se sve dok nismo došli do kraja oba niza. Ukoliko smo

upisali elemente jednog niza, prepisujemo preostale elemente drugog. Oni su već uređeni pa

nema potrebe da ih uređujemo. Ukoliko nismo došli do kraja nijednog od nizova, pitamo koji

niz ima veći element, upisujemo element tog niza u novi, povećavamo brojač za taj niz za

jedan dok ne diramo brojač koji ukazuje na tekući element drugog niza jer iz njega ništa

nismo upisali, pa mu je to i dalje tekući element.

Page 60: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

59

Što se tiče šablona za klasu, kompajleru najavljujemo na isti način kao i za funkciju da

je u pitanju šablon i da koristimo parametar S, dakle, navođenjem template<class S> pre

zaglavlja klase. Kada učinimo neku klasu šablonskom automatski smo učinili i sve njene

funkcije šablonima pa ukoliko ih definišemo van definicije klase potrebno je da to najavimo

navođenjem template<class S> pre definicije funkcije. Ovim smo najavili da ćemo definisati

šablonsku funkciju i da koristimo parametar S. Ranije smo naglasili da kada definišemo

funkcije članice klase van definicije klase kojoj te funkcije pripadaju treba da navedemo

identifikator te klase zbog proširenja dosega klase, da bi kompajler znao kojoj klasi funkcija

pripada. Obratite pažnju da ovde samo identifikator klase ne određuje jednoznačno

konkretnu klasu. Potrebno je iza imena klase navesti i identifikatore argumenata u

zagradama <>, u našem slučaju sablon<S>::. Ovo je potrebno jer će se za svaku realizaciju

klase generisati njene funkcije članice, za sablon<int> jedne, sablon<real> druge itd. Ukoliko

želimo da navedemo objekat klase unutar same klase dovoljno je samo njeno ime. Ovo se

podrazumeva i ako je objekat date klase argument neke njene funkcije članice, kod nas

operator<. Obratite pažnju da se ime konstruktora ne mijenja! Proširivanjem dosega,

navođenjem sablon<S>::, mi smo jednoznačno odredili kojoj klasi on pripada pa ne moramo

da pišemo sablon<S>:: sablon<S>(), to bi izazvalo grešku u kompajliranju. Ovde smo izvršili

definisanje operatora < za naše klase. Niz objekata ovih klasa se može očekivati kao

argument šablonske funkcije u kojoj se koristi taj operator nad argumentima pa moramo to

da učinimo. Dakle, pri realizaciji šablonske klase moramo voditi računa za što će se koristiti

generisane klase i obezbijediti odgovarajuće funkcije i izvršiti preklapanje potrebnih

operatora.

U glavnom programu smo inicijalizovali dva niza celih brojeva, alocirali memoriju za

rezultujući niz i pozvali funkciju naredbom uredi(d1,5,d2,4,d3);. Sada će kompajler generisati

funkciju za cijelobrojne argumente. Deklaracijom sablon<int> *p; generisali smo klasu sa

cjelobrojnim podacima članovima, a p je pokazivač na tu klasu. q je takođe pokazivač na

klasu sa cjelobrojnim tipom podataka članova. Zatim smo alocirali dovoljno memorije u koju

se može smjestiti novonastali niz tačaka (r je pokazivač na njen početak) i pozvali funkciju

uredi(p,i1,q,i2,r);. Kompajler generiše funkciju koja će raditi sa nizom tačaka celobrojnih

koordinata.

Za vježbu realizujte šablonsku funkciju za uređenje niza u rastući. Za nasumice

unesene nizove izvršite njihovo uređivanje i nakon toga primijenite ovde odrađene funkcije.

Page 61: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

60

Primer rada programa

_____________________________________________________________________________U

redjeni niz je:

1 2 3 4 5 7 7 8 9

Koliko ima tacaka prvi niz?

3

Unesite niz tacaka sa cjelobrojnim koordinatama

1 2

2 4

3 5

Koliko ima tacaka drugi niz?2

Unesite niz tacaka sa cjelobrojnim koordinatama

1 1

2 3

(1,1)

(1,2)

(2,3)

(2,4)

(3,5)

Tacka ima koordinate: (2.3,4.6)

_____________________________________________________________________________

Zadatak 6. 2

Sastaviti šablonsku klasu matrice, pri čemu se može menjati tip podataka koje ta klasa sadrži.

Napisati glavni program u kojem treba inicijalizovati matricu celih brojeva i kompleksnih

brojeva i isčitati njihovu vrednost. Klasa matrica ima konstruktor kopije kao i operatore

dodeljivanja i indeksiranja, pri čemu indeksiranje treba realizovati tako da poziv elementa

m(1,3), m tipa matrica, daje element prve vrste i treće kolone. Elementi matrice se čuvaju u

vektoru u kojem su prvo elementi prve vrste pa druge itd.

_____________________________________________________________________________

#include <iostream> #include <stdlib.h> #include <conio.h> using namespace std; template<class T> class Matrica{ private: T *podatak; int vrsta, kolona; public: Matrica(){podatak=0;}//deafoult konstruktor Matrica(int,int);//konstruktor Matrica(const Matrica&);//konstruktor kopije ~Matrica(){delete []podatak;}

Page 62: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

61

Matrica &operator=(const Matrica&); T& operator()(int,int); int velicina(){return vrsta*kolona;} int br_vrsta(){return vrsta;} int br_kolona(){return kolona;} }; template<class T> Matrica<T>::Matrica(int a,int b):vrsta(a),kolona(b){ podatak=new T[vrsta*kolona]; } template<class T> Matrica<T>::Matrica(const Matrica& stara):vrsta(stara.vrsta),kolona(stara.kolona){ podatak=new T[vrsta*kolona]; for(int i=0;i<vrsta*kolona;i++){ podatak[i]=stara.podatak[i]; } } template<class T> Matrica<T>& Matrica<T>::operator=(const Matrica& stara){ if(this!=&stara){//ako se ne dodeljuje a=a vrsta=stara.vrsta; kolona=stara.kolona; delete []podatak; podatak=new T[vrsta*kolona]; for(int i=0;i<vrsta*kolona;i++) podatak[i]=stara.podatak[i]; } return *this; } template<class T> T& Matrica<T>::operator()(int i,int j){ //if(i<1||i>vrsta&j<1||j>kolona) exit(1); return podatak[(i-1)*kolona+j-1]; } class Kompleks{ private: float real; float imag; public: Kompleks(float a=0,float b=0):real(a),imag(b){} ~Kompleks(){} void citaj(){cout<<"("<<real<<","<<imag<<")";} }; main(){ cout<<"Koliko vrsta i kolona zelite da ima matrica celih brojeva?"<<endl; int a,b; cin>>a>>b; Matrica<int> MatricaCelih(a,b); cout<<"Unesite elemente matrice"<<endl; for(int i=1; i<=a;i++) for(int j=1;j<=b;j++){ cin>>MatricaCelih(i,j);}; for(int i=1; i<=a;i++){ for(int j=1;j<=b;j++){ cout<<"MatricaCelih("<<i<<","<<j<<")=="; cout<<MatricaCelih(i,j)<<" ";} cout<<endl;}

Page 63: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

62

cout<<"Koliko vrsta i kolona zelite da ima matrica kompleksnih brojeva?"<<endl; cin>>a>>b; Matrica<Kompleks> MatricaKompleksnih(a,b); float a1,b1; for(int i=1; i<=a;i++) for(int j=1;j<=b;j++){ cin>>a1>>b1; MatricaKompleksnih(i,j)=Kompleks(a1,b1);} for(int i=1; i<=a;i++) { for(int j=1;j<=b;j++){ cout<<"MatricaKompleksnih("<<i<<","<<j<<")=="; MatricaKompleksnih(i,j).citaj(); cout<<" ";} cout<<endl;} Matrica<Kompleks> b2(MatricaKompleksnih),b3; b3=b2; for(int i=1; i<=a;i++){ for(int j=1;j<=b;j++){ cout<<"b2("<<i<<","<<j<<")=="; b2(i,j).citaj(); cout<<" ";} cout<<endl;} for(int i=1; i<=a;i++){ for(int j=1;j<=b;j++){ cout<<"b3("<<i<<","<<j<<")=="; b3(i,j).citaj(); cout<<" ";} cout<<endl; } }

_____________________________________________________________________________

Ovo je još jedna ilustracija korišćenja šablona. Razlog uvođenja šablona u ovom

zadatku je očigledan, veoma često imamo potrebu da smještamo razne podatke u matrice.

Način smještanja elemenata i pristupanja istim se ne razlikuje u zavisnosti od tipa tih

elemenata. Kada napravimo šablon matrica veoma lako je definisati matricu sa

odgovarajućim tipom podataka (Matrica<int> MatricaCelih(a,b);). Kao podatke članove ove

klase imamo broj kolona i vrsta, koji će uvek biti cjelobrojne promenljive, i pokazivač na

početak niza u koji smo smjestili elemente matrice. Elementi matrice mogu biti za različite

instance klasa različitih tipova pa smo tip pokazivača zamijenili šablonskim parametrom T. Na

svakom mestu u realizaciji klase gdje bude potrebno navoditi tip pokazivača na početak niza

ovih elemenata ili tip podataka koji su smješteni u nizu mi ćemo pisati *T, odnosno T .

Kompajler zna da treba da generiše klase sa tipovima podataka koje mi navedemo u <>,

deklaracijom oblika Matrica<int> MatricaCelih(a,b); bi generisali matricu sa cjelobrojnim

elementima. Što se tiče pojedinih funkcija članica šablonske klase nema razlike u logici same

realizacije. Primetimo da smo prilikom preklapanja operator() kao rezultat vratili referencu a

ne samo vrednost podatka. To je bilo moguće jer je to element niza koji je podatak član

objekta za koji se poziva ta funkcija pa on postoji i nakon izvršavanja date funkcije. Razlog

Page 64: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

63

zašto smo koristili referencu je, sa jedne strane, jer ne znamo tačno kojeg će tipa biti podaci

koji se smještaju u ovaj niz pa ne želimo da vršimo bespotrebno kopiranje moguće velikih

objekata. Sa druge strane, na ovaj način smo eliminisali potrebu za funkcijom koju bi koristili

za dodeljivanje vrednosti pojedinim elementima niza. Kada za određene indekse dobemo

upotrebom ovog operatora odgovarajući element mi smo dobili referencu na taj podatak, pa

će se sve promene nad njim odraziti nad podatkom niza, a ne nad njegovom kopijom. Npr.

(cin>>MatricaCelih(i,j);), ovde se vrši dodeljivanje vrednosti koju smo mi unijeli sa tastature

određenom elementu matrice (niza).

Kada realizujemo neku klasu čiji objekti želimo da su podaci ovog niza moramo

obezbijediti mogućnost pravilnog dodeljivanja vrednosti jednog objekta drugom. To znači da

u pojedinim slučajevima moramo preklopiti operator dodele. Mi za klasu kompleksnih

brojeva to nismo učinili. Zašto?

Primetimo da se u glavnom programu pristupa pojedinim elementima kao da su

zaista smješteni u matrici. Ovo je i cilj programskog jezika C++, korisnik ne zna na koji način

smo mi realizovali neku klasu, zna samo kako on može da je koristi. operator() smo

realizovali koristeći naredbu return podatak[(i-1)*kolona+j-1]; Ovo je logično jer se u matrici

elementi počinju indeksirati od jedinice a u memoriji ih mi čuvamo u nizu koji se indeksira od

nule pa će elementu (1,1), zapravo odgovarati prvi element u našem nizu, dakle element sa

indeksom 0. Nakon unošenja potrebnih podataka o broju vrsta i kolona definisali smo

matricu kompleksnih brojeva Matrica<Kompleks> MatricaKompleksnih(a,b);. Dalji tok

glavnog programa protumačite sami.

Primer rada programa

_____________________________________________________________________________

Koliko vrsta i kolona zelite da ima matrica celih brojeva?

2 3

Unesite elemente matrice

1 3 4 5 8 2

MatricaCelih(1,1)==1 MatricaCelih(1,2)==3 MatricaCelih(1,3)==4

MatricaCelih(2,1)==5 MatricaCelih(2,2)==8 MatricaCelih(2,3)==2

Koliko vrsta i kolona zelite da ima matrica kompleksnih brojeva?

2 3

1 2 2 3 5 6 2.3 4 8 2.1 0 10

MatricaKompleksnih(1,1)==(1,2) MatricaKompleksnih(1,2)==(2,3)

MatricaKompleksnih(1,3)==(5,6)

MatricaKompleksnih(2,1)==(2.3,4) MatricaKompleksnih(2,2)==(8,2.1)

MatricaKompleksnih(2,3)==(0,10)

Page 65: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

64

b2(1,1)==(1,2) b2(1,2)==(2,3) b2(1,3)==(5,6)

b2(2,1)==(2.3,4) b2(2,2)==(8,2.1) b2(2,3)==(0,10)

b3(1,1)==(1,2) b3(1,2)==(2,3) b3(1,3)==(5,6)

b3(2,1)==(2.3,4) b3(2,2)==(8,2.1) b3(2,3)==(0,10)

_____________________________________________________________________________

Zadatak 6. 3

Sastaviti šablonsku funkciju koja će eliminisati ponavljanje istih elemenata u nekom nizu

(npr. ako imamo niz 2 3 4 3 2 1 5 daje niz 4 3 2 1 5), kao i šablonsku klasu koja će

predstavljati niz sa zadatim opsezima indeksa. Napisati glavni program u kojem će se data

funkcija pozivati za niz celih i niz realnih brojeva kao i izvršiti inicijalizacija objekata klase

niz za cele i realne elemente nizova dobenih izvršavanjem šablonske funkcije za niz celih ili

realnih elemenata (4 3 2 1 5).

#include <iostream> #include <conio.h> using namespace std; template <class S> int Sazimanje(S* niz,int duz){ int pom; int n=0; for(int i=0;i<duz-1;i++){ pom=0; for(int j=i+1;j<=duz-1;j++) if(niz[i]==niz[j]){ pom=1; break; } if(pom==0) {niz[n]=niz[i]; n=n+1;} } niz[n]=niz[duz-1]; return n+1; } template <class T> class Niz{ private: T* sadrzaj; int poc; int kraj; public: Niz(){sadrzaj=0;} Niz(T*,int,int=0); Niz(const Niz&); ~Niz(){delete []sadrzaj; sadrzaj=0;} T*Daj_sadrzaj(){return sadrzaj;} Niz&operator=(const Niz&); T operator[](int i){return sadrzaj[i];} void citaj(){for(int i=0;i<kraj-poc+1;i++) cout<<sadrzaj[i]<<" ";cout<<endl;} }; template<class T> Niz<T>::Niz(T * unos,int max,int min):poc(min),kraj(max){ sadrzaj=new T[max-min+1]; for(int i=0;i<max-min+1;i++) sadrzaj[i]=unos[i]; } template<class T> Niz<T>::Niz(const Niz& stara):poc(stara.poc),kraj(stara.kraj){

Page 66: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

65

sadrzaj=new T[kraj-poc+1]; for(int i=0;i<max-min+1;i++) sadrzaj[i]=stara.sadrzaj[i]; } template<class T> Niz<T> &Niz<T>::operator=(const Niz<T>& stara){ if(this!=&stara){ delete []sadrzaj; poc=stara.poc; kraj=stara.kraj; sadrzaj=new T[kraj-poc+1]; for(int i=0;i<kraj-poc+1;i++) sadrzaj[i]=stara.sadrzaj[i]; } return *this; } void main(){ int niz[]={1,2,5,3,2,4,6,3,2}; Niz<int> Celi(niz,10,2); float realni[]={1.5,2.4,5,3,2.4,4,6,3,2.4}; Niz<float> Realni(realni,8); int n; n=Sazimanje(niz,9); for(int i=0;i<n;i++) cout<<niz[i]<<", "; cout<<endl; Sazimanje(realni,9); Celi.citaj(); Realni.citaj(); getch(); }

_____________________________________________________________________________

U realizaciji ovog zadatka smo koristili ranije navedena pravila za šablonske funkcije i

klase. Što se tiče same funkcije, kao rezultat dobijamo broj elemenata novog niza. Za eliminisanje

ponavljanja koristimo pomoćnu promenljivu koja ima vrednost 0 ukoliko posmatranog elementa

nema do kraja niza, uz taj uslov prepisuje se tako dobeni element u sažeti niz. Ukoliko je njena

vrednost jednaka jedinici znači da se taj element već pojavljivao i da ga ne treba upisivati. To

ćemo učiniti samo kod njegovog poslednjeg pojavljivanja.

Što se tiče klase, preklopili smo operator[] jer nam je moguć slučaj da niz objekata

konkretne klase, generisane na osnovu date šablonske, bude argument neke generisane funkcije. U

tom slučaju bi zahtevali pristup određenom elementu niza, što smo preklapanjem ovog operatora

omogućili. Ovde smo preklopili i operator dodele da bi se podsjetili načina na koji se to radi, iako

ga nismo nigdje kasnije koristili.

Primer rada programa

_____________________________________________________________________________

1, 5, 4, 6, 3, 2,

1 2 5 3 2 4 6 3 2

1.5 2.4 5 3 2.4 4 6 3 2.4

_____________________________________________________________________________

7. Izuzeci

Zadatak 7. 1

Projektovati klasu za obradu vektora realnih brojeva sa zadatim opsezima indeksa. Za

razrešavanje konfliktnih situacija koristiti mehanizam obrade izuzetaka. Sastaviti glavni

program za prikazivanjenje mogućnosti te klase.

_____________________________________________________________________________

Page 67: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

66

#include <iostream> #include <conio.h> #include <string.h> using namespace std; class Vektor{ private: float *niz; int max_ops; int min_ops; public: enum Greska{OK, //Kodovi gresaka OPSEG, //neispravan opseg indeksiranja MEMORIJA,//dodjela memorije nije uspjela, PRAZAN, //vektor je prazan INDEKS, //indeks je izvan opsega DUZINA}; //neusaglasene duzine vektora Vektor(){niz=0;} Vektor(float, float=0); Vektor(const Vektor &); ~Vektor(){delete []niz;niz=0;} Vektor &operator=(const Vektor &v); float &operator[](int)const; //referencu saljem kao rezultat da // bi se mogao mijenjati sadrzaj elementa kojem se pristupa pomocu []. friend double operator*(const Vektor&,const Vektor &); }; Vektor::Vektor(float a,float b):max_ops(a),min_ops(b){ if(max_ops<min_ops) throw(OPSEG); else if(!(niz=new float[max_ops-min_ops+1])) throw MEMORIJA; else for(int i=0;i<max_ops-min_ops+1;i++) niz[i]=0; } Vektor::Vektor(const Vektor &a):max_ops(a.max_ops),min_ops(a.min_ops){ if(!(niz=new float[max_ops-min_ops+1])) throw MEMORIJA; else for(int i=0;i<max_ops-min_ops+1;i++) niz[i]=a.niz[i]; } Vektor &Vektor::operator=(const Vektor& a){ if(&a!=this){ delete []niz; niz=0; if(!(niz=new float[max_ops-min_ops+1])) throw MEMORIJA; else for(int i=0;i<max_ops-min_ops+1;i++) niz[i]=a.niz[i]; } return *this; } float &Vektor::operator[](int i)const{ if(!niz) throw PRAZAN;//u niz nije nista upisano, // samo je izvrsen default konstruktor else if((i<min_ops)||(i>max_ops)) throw INDEKS; else return niz[i-min_ops]; } double operator*(const Vektor& a1,const Vektor& a2){ if((!a1.niz)||(!a2.niz)) throw Vektor::PRAZAN; else { float s=0; for(int i=0;i<a1.max_ops-a1.min_ops+1;i++) s+=a1.niz[i]*a2.niz[i]; return s; } } main(){

Page 68: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

67

while(1){ try{ int max, min; cout<<"Unesi opseg indeksa prvog vektora"<<endl; cin>>max>>min; if(cin.eof()) throw 1; Vektor v1(max,min); cout<<"Komponente prvog vektora"<<endl; for(int i=min;i<=max;i++) cin>>v1[i]; cout<<"Unesi opseg indeksa drugog vektora"<<endl; cin>>max>>min; Vektor v2(max,min); cout<<"Komponente drugog vektora"<<endl; for(int i=min;i<=max;i++) cin>>v2[i]; cout<<"Skalarni proizvod dva zadata vektora je "<<v1*v2<<endl; } catch(Vektor::Greska g){ char *poruke[]={"", "Neispravan opseg indeksa!", "Neuspjelo dodeljivanje memorije!" "Vektor je prazan!", "Indeks je izvan opsega!" }; cout<<poruke[g]<<endl; } catch(...){ cout<<"Kraj unosa"<<endl; break; } } getch();getch(); }

_____________________________________________________________________________

Podsetimo se, najpre, tipa nabrajanja enum. Ime koje smo dali ovom tipu je Greska i

promenljive ovog tipa mogu uzeti samo neku od vrednosti navedenih unutar {}. Nabrajanjem

smo, zapravo, definisali neke cjelobrojne konstante simboličkih imena OK, OPSEG,…. Njima u

okviru {} možemo dodeliti tačno određene cjelobrojne vrednosti.Aako to ne učinimo biće im

dodijeljene vrednosti od 0 pa 1 i tako dalje, svaka sledeća ima za jedan veću vrednost.

Identifikator njihovog tipa je Greska, a ne int, iako imaju celobrojnu vrednost. Znači, Greška je

ime novog tipa a OK, OPSEG..., vrednosti koje neka promenljiva tog tipa može imati, isto kao

float ime tipa a 2.4 vrednost koju promijenjiva tog tipa može uzeti.

U ovom zadatku nam je cilj da ilustrujemo generisanje i obradu izuzetaka. Kada se radi

sa izuzecima mogu se posmatrati dve odvojene faze: prva je otkrivanje i generisanje izuzetaka, a

druga obrada datog izuzetka. Kada otkrijemo mogućnost pojave neke greške u programu, koja

nije sintaksnog i semantičkog tipa, a želimo da ostavimo mogućnost njene obrade, a ne samo

prekidanje programa bez ikakvog objašnjenja, možemo postaviti izuzetak. Izuzetak se generiše

ključnom rečju throw nakon koje pišemo neki podatak određenog tipa (3, 2.4..) koji će biti

identifikator tog izuzetka. Naime, ukoliko smo napisali throw 3, nastao je izuzetak cjelobrojnog

tipa. Izuzetak se prihvata ključnom rečju catch(), gdje u zagradama pišemo tip izuzetka koji se tu

obrađuje, catch(int) u prethodnom slučaju. Deo programa u kojem može nastati izuzetak

stavljamo iza ključne reči try u okviru {} nakon kojih se nalaze ključne reči catch() koje prihvataju i

obrađuju određene izuzetke.

Page 69: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

68

Što se tiče same klase, ona predstavlja niz kod kojeg je tačno definisan opseg, odnosno,

minimalna i maksimalna moguća vrednost indeksa. Greška će nastati već prilikom formiranja niza

kada korisnik želi inicijalizovati objekat tako da ima maksimalni opseg manji od minimalnog. To

smo uzeli kao drugu vrednost koju mogu imati podaci tipa Greska-OPSEG. Na mjestima na kojima

može doći do ovakve greške postavili smo izuzetak throw OPSEG. Druga greška nastaje kada

želimo da alociramo memoriju za taj niz ali u dinamičkoj zoni memorije nema dovoljno mesta za

cio niz, postavljamo izuzetak throw MEMORIJA. Vidimo da će i jedan i drugi da prihvata isti

rukovalac catch tipa Greska ali će u zavisnosti od vrednosti da odradi različite akcije. Ako g ima

vrednost 1 (OPSEG), čita g[1] string, odnosno, za g=2 (MEMORIJA) čita g[2] string. Sledeća greška

može nastati prilikom čitanja, ukoliko želimo uzeti nešto iz praznog niza throw PRAZAN ili čitati

nešto iz elementa sa indeksom van opsega tu postavljamo izuzetak throw INDEKS. Još jedan

izuzetak može nastati kada želimo preklopiti operator * za dva niza različitih dužina, throw

DUZINA. Gdje i na koji način biste ga postavili.

Ukoliko u rukovaocu izuzetka ne koristimo vrednost koja mu je proslijeđena nakon

identifikatora tipa ne moramo navoditi ime promenljive u koju će se kopirati poslata vrednost,

catch(int). U tom slučaju nam ta vrednost treba samo da na osnovu njenog tipa vidimo koji

rukovalac će prihvatiti naš izuzetak (odgovara našem izuzetku).

Prođimo jednom kroz cio kod. Imamo klasu Vektor sa tri privatna podatka člana, dva

nam određuju maksimalnu i minimalnu moguću vrednost indeksa, a treći predstavlja pokazivač

na početak niza. Zatim imamo jedan javni podatak tipa nabrajanja Greska koji može imati jednu

od vrednosti navedenih unutar {}. Default konstrukor je definisan na ranije korišćen način. Već

prilikom definicije prvog konstruktora može doći do greške. Greška je ukoliko zadamo da je

vrednost najmanjeg indeksa manja od vrednosti najvećeg. Tu postavljamo izuzetak throw OPSEG.

Njegov tip je Vektor::Greska pa ga prihvata rukovalac throw(Vektor::Greska g) U ovom slučaju će

g imati vrednost 1 i ispisaće se drugi string iz niza stringova na koji ukazuje pokazivač poruke.

Sledeća greška nastaje ako nije ispravno alocirana memorija, postavljamo odgovarajući izuzetak.

Ako je sve u redu inicijalizujemo sve elemente niza na nulu. U konstruktoru kopije nastaje greška

ukoliko u dinamičkoj zoni memorije nema dovoljno mesta za smeštanje svih elemenata niza. Ista

greška može nastati i prilikom realizacije operatora dodele pa smo i u okviru njega postavili isti

izuzetak. Prilikom realizacije operatora indeksiranja, [], može nastati greška ukoliko je niz prazan

a mi želimo nešto isčitati iz njega. To bi se desilo ukoliko smo neki objekat samo deklarisali gdje

je pozvan default konstruktor koji je postavio odgovarajući pokazivač na 0, nije alocirao

memoriju niti je odredeo opseg vrednosti indeksa niza. Operator indeksiranja smo realizovali kao

u ranijim primerima. S obzirom da nam najmanji indeks ne mora biti 0 već ima vrednost

smještenu u podatku min_ops, kada korisnik želi element sa indeksom i mi mu dajemo element

koji je smješten na poziciji i-min_ops iako korisnik misli da je to element sa indeksom i. Ovde

nastaje greška ukoliko je indeks tražene komponente van dozvoljenog opsega. Operator * nam

predstavlja skalarni proizvod dva vektora, greška nastupa ukoliko je jedan od vektora prazan.

Pokušajte da postavite izuzetak koji bi javljao grešku kada je različita dužina dva vektora koje

“množimo”. Ovde smo morali navesti i klasu kojoj pripada simbolička konstanta kojom

postavljamo izuzetak jer je ovo funkcija prijatelj klase, a ne članica, pa ona ima pravo pristupa

tim podacima ali se mora navesti klasa čiji je taj podatak član. U glavnom programu se nalazi

jedna petlja while(1) i izvršavaće se sve dok umesto opsega indeksa prvog vektora ne unesemo

znak za kraj dadoteke CTRL-Z, nakon čega dolazi do izuzetka tipa int čiji će rukovalac izvršiti

Page 70: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

69

prekidanje while petlje (naredba break;). Koristili smo ovu petlju da bismo mogli u okviru jedne

realizacije programa generisati više izuzetaka. Da nje nema nakon prvog izuzetka došlo bi do

preskoka na prvog odgovarajućeg rukovaoca nakon try i ne bismo se više vraćali nazad. Išlo bi se

na prvu naredbu nakon catch dijela a to bi bio kraj programa. Sada je to sledeći ciklus u petlji,

dakle unošenje novih podataka.

Primer rada programa

_____________________________________________________________________________

Unesi opseg indeksa prvog vektora

1 3

Neispravan opseg indeksa!

Unesi opseg indeksa prvog vektora

3 1

Komponente prvog vektora

1 4 5

Unesi opseg indeksa drugog vektora

3 1

Komponente drugog vektora

4 3 2

Skalarni proizvod dva zadata vektora je 26

Unesi opseg indeksa prvog vektora

Kraj unosa

8. Razni zadaci

Zadatak 8.1.

Kreirati klasu Permutacija koja omogućava pamćenje jedne permutacije brojeva 1, ..., n i ima:

- Konstruktor Permutacija(int n). Ovaj konstruktor zadaje slučajnu permutaciju od n elemenata.

- Konstruktor Permutacija(int n, int *a). Ovim konstruktorom se zadaje permutacija.

- Destruktor.

- Odgovarajuće getere i setere.

- Metod int redniBroj(), koji ordeđuje redni broj permutacije u leksikografskom poretku.

- Metod int generisiLeksikografsku(int n), koji generiše permutaciju sa rednim brojem n u

leksikografskom poretku. Rezultat je 0 ako generisanje nije uspelo, inače 1.

- Metod int sledeca(), koji određuje sledeću permutaciju u leksikografskom poretku. Rezultat je

0 ukoliko ne postoji sledeća permutacija, inače 1.

U glavnom programu testirati svaki od metoda.

Page 71: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

70

//Permutacija.h

#pragma once

class CPermutacija

{

int m_iN;

int *m_pPerm;

void swap(int *a, int *b);

public:

CPermutacija(int n);

CPermutacija(int n, int *niz);

~CPermutacija(void);

void setPerm(int n, int *niz);

int sledeca();

void stampaj();

int getN(void);

int* getPerm(void);

};

//Permutacija.cpp

#include "Permutacija.h"

#include <stdlib.h>

#include <time.h>

#include <stdeo.h>

CPermutacija::CPermutacija(int n)

{

int i;

m_iN = n;

m_pPerm = new int[n + 1];

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

m_pPerm[i] = i;

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

swap(&m_pPerm[i], &m_pPerm[(rand() % i) + 1]);

}

CPermutacija::CPermutacija(int n, int *niz)

{

m_iN = n;

m_pPerm = new int[n + 1];

m_pPerm[0] = 0;

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

m_pPerm[i] = niz[i];

}

void CPermutacija::swap(int *a, int *b)

{

int tmp;

tmp = *a; *a = *b; *b = tmp;

}

CPermutacija::~CPermutacija(void)

{

delete[] m_pPerm;

m_pPerm = NULL;

m_iN = 0;

}

Page 72: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

71

void CPermutacija::setPerm(int n, int *niz)

{

m_iN = n;

delete[] m_pPerm;

m_pPerm = new int[n + 1];

m_pPerm[0] = 0;

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

m_pPerm[i] = niz[i];

}

int CPermutacija::sledeca()

{

int i = m_iN;

while((i > 1) && (m_pPerm[i-1] > m_pPerm[i]))

i--;

if(i == 1) return 0;

int j = i - 1;

i = m_iN;

while(m_pPerm[i] < m_pPerm[j]) i--;

swap(m_pPerm + i, m_pPerm + j);

int k = j + 1;

int l = m_iN;

while(k < l)

swap(&m_pPerm[k++], &m_pPerm[l--]);

return 1;

}

int CPermutacija::getN()

{

return m_iN;

}

int* CPermutacija::getPerm()

{

return m_pPerm;

}

void CPermutacija::stampaj(){

for(int i = 1; i <= m_iN; i++){

printf("%3d", m_pPerm[i]);

}

printf("\n");

}

#include <stdeo.h>

#include <stdlib.h>

#include <time.h>

#include "Permutacija.h"

int main()

{

srand((unsigned int) time(NULL));

int n, m, i, niz[10];

/* random permutacija */

printf("Unesite broj elemenata za generisanje random permutacije\n");

//scanf("%d", &m);

Page 73: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

72

//CPermutacija p(m);

//n = p.getN();

//for (i = 1; i <= n; i++)

// printf("%d ", (p.getPerm())[i]);

//printf("\n");

/* 20 random permutacija i njihove sledece */

scanf("%d", &m);

CPermutacija * p1;

for(int kk = 0; kk < 20; kk++){

p1 = new CPermutacija(m);

p1->stampaj();

p1->sledeca();

p1->stampaj();

printf("-----------------------\n");

delete p1;

}

/* Unos permutacije i njena sledeca */

//printf("Zadajte permutaciju\n");

//scanf("%d", &m);

//for(i = 1; i <= m; i++)

// scanf("%d", niz+i);

//CPermutacija pp(m, niz);

//int q = pp.sledeca();

//if(q == 0) printf("Ovo je poslednja permutacija");

//else

//{

// printf("Sledeca permutacija je:\n");

// for (i = 1; i <= n; i++)

// printf("%d ", (pp.getPerm())[i]);

//}

//printf("\n");

/* Pozivanje konstruktora sa 2 arg */

//scanf("%d", &n);

//for (i = 1; i <= n; i++)

// scanf("%d", &niz[i]);

////p.setPerm(n, niz);

//CPermutacija p(n,niz);

//n = p.getN();

//for (i = 1; i <= n; i++)

// printf("%d ", (p.getPerm())[i]);

return 0;

}

Zadatak 8. 2.

Kreirati klasu Slagalica koja omogućava zadavanje tajne reči, slučajno permutovanje znakova tajne

reči, kao i dve operacije – zameni(i, j), rotiraj(i, j). Operacija zameni(i, j) menja mesta

i – tom i j – tom karakteru u transformisanoj reči, a rotiraj(i, j) rotira sve karaktere od i – tog do

j – tog u desno ako je i < j, odnosno u levo ako je i > j.

U glavnom programu omogućiti igranje sledeće igre – kompjuter učitava niz reči iz datoteke

‘recnik.dat’, odabira slučajno jednu od njih i permutuje joj karaktere. Posle toga prikazuje

permutovanu reč korisniku i traži od njega komande. Posle svake komande treba odštampati

promenjenu reč. Igra se završava kada igrač pogodi traženu reč ili posle 10 pokušaja.

Page 74: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

73

//slagalica.h

#pragma once #include <string.h> #include <stdlib.h> #include <time.h> class Slagalica { /* Rec koja se trazi */ char * tajnaRec; /* Rec koja se ispisuje korisniku */ char * trenutnaRec; /* Duzina date reci */ int duzinaReci; /* Trenutni broj pokusaja */ int brojPokusaja; /* Inicjalizacija vrednosti */ void init(char * rec); /* Permutovanje karaktera date reci */ void permutuj(void); public: /* Konstruktori */ Slagalica(void); Slagalica(char * rec); /* Destruktor */ ~Slagalica(void); /* Komande */ void zameni(int i, int j); void rotiraj(int i, int j); /* Pomocni metodi */ void ponistiBrojPokusaja(void); int getBrojPokusaja(void); void postaviRec(char * rec); int proveri(); /* Vraca trenutnu rec */ char * rec(); /* Vraca tajnu rec */ char * Rec(); }; //Slagalica.cpp #include "Slagalica.h" Slagalica::Slagalica(void) { tajnaRec = NULL; trenutnaRec = NULL; duzinaReci = 0; brojPokusaja = 0; } Slagalica::~Slagalica(void) { if(tajnaRec != NULL) delete[] tajnaRec; if(trenutnaRec != NULL) delete[] trenutnaRec; } Slagalica::Slagalica(char * rec){

Page 75: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

74

tajnaRec = NULL; trenutnaRec = NULL; duzinaReci = 0; brojPokusaja = 0; init(rec); } void Slagalica::permutuj(){ if(duzinaReci == 0) return; if(trenutnaRec != NULL) delete[] trenutnaRec; trenutnaRec = new char[duzinaReci + 1]; strcpy(trenutnaRec, tajnaRec); srand((unsigned int)time(0)); for(int i = 0; i < duzinaReci; i++){ int j = rand() % (duzinaReci - i) + i; if(i != j){ char pom = trenutnaRec[i]; trenutnaRec[i] = trenutnaRec[j]; trenutnaRec[j] = pom; } } } void Slagalica::zameni(int i, int j){ if((i < 0) || (j < 0) || (i >= duzinaReci) || (j >= duzinaReci)) return; char pom = trenutnaRec[i]; trenutnaRec[i] = trenutnaRec[j]; trenutnaRec[j] = pom; brojPokusaja++; } void Slagalica::rotiraj(int i, int j){ if((i < 0) || (j < 0) || (i >= duzinaReci) || (j >= duzinaReci)) return; int k; char pom; if(i < j){ /* Pomeranje u desno */ pom = trenutnaRec[j]; for(k = j - 1; k >= i; k--) trenutnaRec[k + 1] = trenutnaRec[k]; trenutnaRec[i] = pom; } else{ /* Pomeranje u levo */ pom = trenutnaRec[j]; for(k = j; k < i; k++) trenutnaRec[k] = trenutnaRec[k + 1]; trenutnaRec[i] = pom; } brojPokusaja++; } void Slagalica::ponistiBrojPokusaja(void) { brojPokusaja = 0; } int Slagalica::getBrojPokusaja(void) { return brojPokusaja; } void Slagalica::postaviRec(char * rec){ init(rec);

Page 76: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

75

} void Slagalica::init(char * rec){ int n = strlen(rec); if(n == 0) return; tajnaRec = new char[n + 1]; strcpy(tajnaRec, rec); duzinaReci = n; permutuj(); } char * Slagalica::rec(){ return trenutnaRec; } int Slagalica::proveri(){ int rez = strcmp(trenutnaRec, tajnaRec); return rez == 0; } char * Slagalica::Rec(){ return tajnaRec; } //main.cpp #include <stdeo.h> #include "Slagalica.h" int main(){ Slagalica * s; s = new Slagalica("Kombinatorika"); char komanda[10]; int i, j; printf("Komande:\n\tz i j - zamenjuje i-ti i j-ti karakter\n\tr i j - rotira karaktere od i do j u desno ako je i < j, a inace u levo\n\n"); do{ printf("Trenutna rec: %s\n\n", s->rec()); printf("Unesi komandu...\n"); scanf("%s %d %d", komanda, &i, &j); if(komanda[0] == 'z') s->zameni(i, j); if(komanda[0] == 'r') s->rotiraj(i, j); } while((!s->proveri()) && (s->getBrojPokusaja() < 10)); if(s->proveri()) printf("Cestitam, pogodili ste tajnu rec: %s\n", s->rec()); else printf("Zao mi je. Trazena rec je %s\n", s->Rec()); delete s; return 0; }

Zadatak 8.3

Kreirati klasu KompleksniBroj koja omogućava rad sa kompleksnim brojevima. Klasa bi trebalo da ima:

podatke re i im, za realni i imaginarni deo kompleksnog broja;

konstruktor sa dva parametra koji postavlja vrednosti za realni i imaginarni deo kompleksnog broja;

konstruktor bez parametara koji postavlja vrednost kompleksnog broja na 0;

odgovarajuće getere i setere;

Page 77: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

76

javni metod moduo() koji kao rezultat vraća moduo kompleksnog broja;

javne metode kojima se izvode osnovne operacije sa kompleksnim brojevima (sabiranje, oduzimanje, množenje, stepenovanje, deljenje).

Page 78: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

77

Zadatak 8.4

Kreirati klasu Razlomak koja omogućava rad sa racionalnim brojevima. Klasa bi trebalo da ima:

podatke br i im, za brojilac i imenilac razlomka;

privatni metod skrati() koji dovodi razlomak na neskrativi oblik. Može se definisati i privatni metod int nzd(int a, int b) koji određuje najveći zajednički delilac dva cela broja;

konstruktor sa dva parametra koji postavlja vrednosti za brojilac i imenilac. Voditi računa o tome da imenilac ne može biti 0;

konstruktor bez parametara koji postavlja vrednost kompleksnog broja na 0. U tom slučaju je imenilac jednak 1;

odgovarajuće getere i setere;

javne metode kojima se izvode osnovne operacije sa razlomcima (sabiranje, oduzimanje, množenje, stepenovanje, deljenje).

//Razlomak.h #pragma once

class CRazlomak

{

int br;

int im;

int nzd(int, int);

void skrati();

public:

CRazlomak(void);

CRazlomak(int, int);

~CRazlomak(void);

int getBr(void);

void setBr(int);

int getIm(void);

void setIm(int);

void postaviNaNulu(void);

void stampaj();

CRazlomak

operator+(CRazlomak);

//CRazlomak

saberi(CRazlomak);

CRazlomak operator-

(CRazlomak);

CRazlomak

operator*(CRazlomak);

CRazlomak

operator/(CRazlomak);

};

//Razlomak.cpp #include<stdio.h>

#include<math.h>

#include "Razlomak.h"

int CRazlomak::nzd(int a, int b)

{

while(a != b)

{

if(a > b) a -= b;

else b -= a;

} return a;

}

void CRazlomak::skrati(void)

{

if(br != 0)

{

int n = nzd(abs(br),

abs(im));

br /= n; im /= n;

}

else im = 1;

}

CRazlomak::CRazlomak(void)

{

}

CRazlomak::CRazlomak(int b, int i)

{

if(i==0)

{

br = 0; im = 1;

}

else

{

br = b; im = i;

}

skrati();

}

CRazlomak::~CRazlomak(void)

{

}

int CRazlomak::getBr(void)

{

return br;

}

void CRazlomak::setBr(int b)

{

br = b;

skrati();

Page 79: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

78

}

int CRazlomak::getIm(void)

{

return im;

}

void CRazlomak::setIm(int i)

{

if(i != 0) im = i;

else

{

br = 0; im = 1;

}

skrati();

}

void

CRazlomak::postaviNaNulu(void)

{

br = 0; im = 1;

}

CRazlomak CRazlomak::operator

+(CRazlomak r1)

{

CRazlomak r;

r.br = (br * r1.im + r1.br *

im);

r.im = (im * r1.im);

r.skrati();

return r;

}

/* CRazlomak

CRazlomak::saberi(CRazlomak r1)

{

CRazlomak r;

r.br = (br * r1.im + r1.br *

im);

r.im = (im * r1.im);

r.skrati();

return r;

} */

CRazlomak CRazlomak::operator -

(CRazlomak r1)

{

CRazlomak r;

r.br = (br * r1.im - r1.br *

im);

r.im = (im * r1.im);

r.skrati();

return r;

}

CRazlomak CRazlomak::operator

*(CRazlomak r1)

{

CRazlomak r;

r.br = br * r1.br;

r.im = im * r1.im;

r.skrati();

return r; }

CRazlomak CRazlomak::operator

/(CRazlomak r1)

{

CRazlomak r;

r.br = br * r1.im;

r.im = im * r1.br;

r.skrati();

return r;

}

void CRazlomak::stampaj(void)

{

printf("%d/%d\n",br,im);

}

//main.cpp

#include<stdio.h>

#include "Razlomak.h"

int main()

{

int a, b;

scanf("%d%d",&a, &b);

CRazlomak r(a, b);

r.stampaj();

/* scanf("%d",&a);

r.setBr(a);

r.stampaj();

scanf("%d",&b);

r.setIm(b);

r.stampaj(); */

/* r.postaviNaNulu();

r.stampaj(); */

scanf("%d%d",&a, &b);

CRazlomak r1(a, b);

r1.stampaj();

CRazlomak r2;

//r2 = r.saberi(r1);

r2 = r + r1;

r2.stampaj();

r2 = r - r1;

r2.stampaj();

r2 = r * r1;

r2.stampaj();

r2 = r / r1;

r2.stampaj();

return 0;

}

Page 80: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

79

Zadatak 8.5

Definisati klasu Tacka koja predstavlja tačku sa celobrojnim koordinatama u ravni. Napisati

konstruktor bez parametara, kao i konstruktor sa dva celobrojna parametra. Preklopiti operator +

tako da je moguće sabrati dve promenljive tipa Tacka. Rezultat je nova tačka čije su koordinate

zbirovi koordinata operanada.

Definisati klasu Figura koja ima članove brTacaka i nizTacaka. Napisati konstruktor bez

parametara, kao i konstruktor sa dva parametra – prvi tipa int, a drugi tipa Tacka *. Za ovu

klasu preklopiti operator + tako da se njime dodaje nova tačka u niz, kao i operator – tako da se

njime briše i – ta tačka iz niza. Dodati metod obim koji kao rezultat daje obim figure (pretpostavlja

se da su temena figure data redom).

L I T E R A T U R A

[1] D. Milićev: "Objektno-orjentisano programiranje na jeziku C++," Mikroknjiga, 1995.

[2] H. M. Deitel, P. J. Deitel: "C++ how to program," Prentice Hall, 1997.

[3] J. Liberty, D. B. Horvath: "C++ za LINUX," SAMS Publishing (2000), Kompjuter biblioteka

(prevedeno izdanje) 2002.

[4] L. Kraus: "Programski jezik C++ sa rešenim zadacima," Mikro knjiga, 1994.

[5] K. Reisdorph: "Teach yourself C++Builder in 21 day", SAMS Publishing.

[6] D. Milićev, LJ. Lazarević, J. Marušić: "Objektno orjentisano programiranje na jeziku C++ -

Skripta sa praktikumom," Mikro knjiga 2001.

[7] N. Wirth: "Algorithms + Data structures = Programs," Prentice Hall, 1976.

[8] G. Booch, J. Rumbaugh, I. Jacobson: "UML – vodič za korisnike," Addison Wesley 1999,

CET 2000 (prevedeno izdanje).

[9] Jan Skansholm, "C++ from the beginning",.Addison-Wesley, 2003.

Page 81: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

80

Programski jezik JAVA

1. Rad sa objektima klase StringBuffer, demonstracija nekih funkcionalnosti

public class NasStringBuffer {

/*

* Rad sa objektima klase StringBuffer, demonstriranje

* funkcionalnosti nekih funkcija za rad sa objektima

* ove klase.

*/

/* Kapacitet, tj. velicina bafera objekta se automatski povecava kako

bi se on prilagodeo

* stringu proizvoljne duzine i to tako da ako je duzina novog

stringa veca od tekuceg

* kapaciteta, novi kapacitet bafera bice veci od sledeca dva broja:

* nova duzina stringa i

* 2*stari_kapacitet+2

*/

public static void main(String[] args) {

StringBuffer recenica = new StringBuffer(20);

System.out.println("Kapacitet StringBuffer objekta je: "+

recenica.capacity()+

" a duzina stringa je: "+recenica.length());

// Dodajemo reci niza u StringBuffer objekat

String[] niz_reci = {"Ako" , "danas", "bude", "snega", "bicu",

"srecan"};

recenica.append(niz_reci[0]);

for(int i = 1 ; i<niz_reci.length ; i++) {

recenica.append(' ').append(niz_reci[i]);

}

System.out.println("\nString koji se nalazi u StringBuffer

objektu je:\n" +

recenica.toString());

System.out.println("Kapacitet StringBuffer objekta je sada: "+

recenica.capacity()+

" a duzina stringa je: "+recenica.length());

// Vrsimo zamenu neke niske u objektu nekom drugom

int poz=recenica.lastIndexOf("snega");

recenica.replace(poz, poz+5,"kise");

// Vrsimo umetanje nekih niski u objekat klase StringBuffer

recenica.insert(recenica.lastIndexOf("srecan"), "ne");

System.out.println("\nString koji se nalazi StringBuffer

objektu je:\n" + recenica);

System.out.println("Kapacitet StringBuffer objekta je sada: "+

recenica.capacity()+

" a duzina stringa je: "+recenica.length());

}

}

2. Brojimo pojavljivanjue reci the i and u zadatom tekstu

public class BrojanjeReci {

Page 82: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

81

/*

* Brojimo pojavljivanjue reci the i and u zadatom tekstu

*/

public static void main(String[] args) {

// Tekst koji analiziramo

String text = "To be or not to be, that is the question;"

+ " Whether ‘tis nobler in the mind to suffer"

+ " the slings and arrows of outrageous fortune,"

+ " or to take arms against a sea of troubles,"

+ " and by opposing end them?";

int andBr = 0;

int theBr = 0;

int indeks = -1;

String andStr = "and";

String theStr = "the";

// Trazimo pojavljivanje reci "and"

indeks = text.indexOf(andStr); // Nalazimo prvu pojavu reci

"and"

while(indeks >= 0) {

++andBr;

indeks += andStr.length(); // Postavljamo se na mesto

posle

// pojave tekuceg "and"

indeks = text.indexOf(andStr, indeks);

}

// Trazimo unazad pojavljivanje reci "the"

indeks = text.lastIndexOf(theStr); // Nalazimo poslednju pojavu

// reci "the"

while(indeks >= 0) {

++theBr;

indeks -= theStr.length(); // Postavljamo se na mesto pre

// pojave tekuceg "and"

indeks = text.lastIndexOf(theStr, indeks);

}

System.out.println("Zadati tekst sadrzi " + andBr + " pojave

reci 'and'\n"

+ "i " + theBr + " pojava reci 'the'.");

}

}

3. Skener

import java.util.Scanner;

public class Skener

{

/*

* Ucitavamo dva broja sa standardnog ulaza i ispisujemo njihov zbir.

*/

public static void main(String [] args)

{

Scanner skener = new Scanner(System.in);

System.out.println("Unesite dva cela broja");

int a = skener.nextInt();

int b = skener.nextInt();

int zbir = a + b;

System.out.println("Zbir brojeva " + a + " i " + b + " je " +

zbir);

}

}

Page 83: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

82

4. Nizovi

package nizovi;

import java.util.Arrays;

public class SortiranjeNiza {

public static void main(String[] args) {

int a[]={-12,9,8,-8,5, 6, 1, 3};

Arrays.sort(a);

for(int i=0; i<a.length; i++)

System.out.print(a[i]+" ");

System.out.println();

}

}

5. Učitavamo elemente niza i računamo aritmetičku sredinu.

import java.util.Scanner;

public class AritmetickaSredina{

/*

* Ucitavamo broj elemenata niza i njegove elemente

* i racunamo zbir elemenata niza i njihovu aritmeticku sredinu.

*/

public static void main(String[] args){

Scanner skener = new Scanner(System.in);

System.out.println("Unesite broj elemenata niza:");

int brojEl = skener.nextInt();

int[] nizBrojeva = new int[brojEl];

int zbir = 0;

// ucitavamo elemente niza i formiramo zbir

for (int i = 0; i < brojEl; i++)

{

System.out.print((i + 1) + ". broj: ");

nizBrojeva[i] = skener.nextInt();

zbir += nizBrojeva[i];

}

System.out.println("Zbir brojeva je: " + zbir);

// racunamo aritmeticku sredinu

double aritmSredina = (double) zbir / brojEl;

System.out.println("Aritmeticka sredina je: " + aritmSredina);

}

}

6. Isto što i malopre, samo malo drugačije

import java.util.Scanner;

public class AritmetickaSredina2{

/*

* Sa standardnog ulaza ucitavamo elemente niza sve dok se ne unese 0,

* i racunamo zbir elemenata niza i njihovu aritmeticku sredinu.

*/

public static void main(String[] args){

Page 84: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

83

Scanner skener = new Scanner(System.in);

int[] nizBrojeva = new int[100];

int zbir = 0;

int brojEl = 0;

// Sve dok se ne unese nula, ucitavamo brojeve

// sa standardnog ulaza i racunamo njihov zbir.

for (brojEl = 0; brojEl < 100; brojEl++)

{

System.out.print((brojEl + 1) + ". broj: ");

nizBrojeva[brojEl] = skener.nextInt();

if (nizBrojeva[brojEl] == 0)

break;

zbir += nizBrojeva[brojEl];

}

System.out.println("Zbir brojeva je: " + zbir);

// Racunamo aritmeticku sredinu.

double aritmSredina = (double) zbir / brojEl;

System.out.println("Aritmeticka sredina je: " + aritmSredina);

}

}

7. Poređenje stringova

public class PoredjenjeStringova {

/*

* Razlika izmedju poredjenja dve stringovne promenljive koje pokazuju

* na dva stringa koja imaju isti sadrzaj, i poredjenja

* dve stringovne promenljive koje pokazuju na isti string.

*/

public static void main(String[] args) {

String string1 = "Dva ";

String string2 = "studenta";

String string3 = "Dva studenta";

// Postavljamo da string1 i string3 referisu

// na razlicite stringove koji su identicni

string1 += string2;

System.out.println("Test br 1");

System.out.println("string3 je: " + string3);

System.out.println("string1 je: " + string1);

// Testiramo da li je u pitanju isti string

if(string1 == string3)

System.out.println("string1 == string3 je tacno -" +

" string1 i string3 pokazuju na isti string");

else

System.out.println("string1 == string3 nije tacno -" +

" string1 i string3 ne pokazuju na isti string");

// // Postavljamo da string1 i string3 referisu

// na isti string

string3 = string1;

System.out.println("\nTest br 2");

System.out.println("string3 je: " + string3);

System.out.println("string1 je: " + string1);

Page 85: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

84

if(string1 == string3) // Now test for identity

System.out.println("string1 == string3 je tacno -" +

" string1 i string3 pokazuju na isti string");

else

System.out.println("string1 == string3 nije tacno -" +

" string1 i string3 ne pokazuju na isti string");

}

}

8. Poređenje stringova još jednom

public class PoredjenjeStringova2 {

/*

* Poredjenje dve stringovne promenljive na jednakost sadrzaja.

*/

public static void main(String[] args) {

String string1 = "Dva ";

String string2 = "studenta";

String string3 = "Dva studenta";

// Postavljamo da string1 i string3 referisu

// na razlicite stringove koji su identicni

string1 += string2;

System.out.println("Test br 1");

System.out.println("string3 je: " + string3);

System.out.println("string1 je: " + string1);

// Testiramo stringove na jednakost sadrzaja

if(string1.equals(string3)) {

System.out.println("string1.equals(string3) je tacno - "

+

" stringovi su jednaki.");

} else {

System.out.println("string1.equals(string3) je netacno -

" +

" stringovi nisu jednaki.");

}

// Sada postavljamo string1 i string3 da referisu

// na stringove koji se razlikuju samo u velicini slova

string3 = "DVA studenta";

System.out.println("\nTest br 2");

System.out.println("string3 je: " + string3);

System.out.println("string1 je: " + string1);

// Testiramo stringove na jednakost sadrzaja

if(string1.equals(string3)) {

System.out.println("string1.equals(string3) je tacno - "

+

" stringovi su jednaki.");

} else {

System.out.println("string1.equals(string3) je netacno -"

+

" stringovi nisu jednaki.");

}

// Testiramo stringove na jednakost sadrzaja

// bez obaziranja na velicinu slova

if(string1.equalsIgnoreCase(string3)) {

System.out.println("string1.equalsIgnoreCase(string3) je

tacno - " +

" stringovi su jednaki ako zanemarimo velicinu slova.");

} else {

Page 86: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

85

System.out.println("string1.equalsIgnoreCase(string3) je

netacno -" +

" stringovi su razliciti.");

}

}

}

9. Demonstracija rada sa matricama, relacija

package paket;

import java.util.Scanner;

public class Relacija {

public static boolean refleksivna(int m[][]){

for(int i=0; i<m.length; i++)

if(m[i][i]!=1)

return false;

return true;

}

public static boolean simetricna(int m[][]){

for(int i=0; i<m.length; i++)

for(int j=0; j<i; j++) /* idemo kroz trougao ispod

* glavne dijagonale */

if(m[i][j]!=m[j][i])

return false;

return true;

}

/**

* @param args

*/

public static void ispisi(int m[][])

{

for(int i=0; i<m.length; i++){

for(int j=0; j<m.length; j++)

System.out.print(m[i][j]+" ");

System.out.println();

}

}

public static void ispisi1(int [][]m){

for(int vrsta[]: m){

for(int elvrste: vrsta)

System.out.print(elvrste + " ");

System.out.println();

}

}

public static void main(String[] args) {

// TODO Auto-generated method stub

Scanner sc=new Scanner(System.in);

System.out.println("Unesite dim. matrice");

int dim=sc.nextInt();

int m[][]=new int[dim][dim];

System.out.println("Unesite el. matrice");

for(int i=0; i<dim; i++)

for(int j=0; j<dim; j++){

m[i][j]=sc.nextInt();

if(m[i][j]!=0 && m[i][j]!=1){

System.out.println("Neispravan unos: " + m[i][j]);

return;

Page 87: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

86

}

}

if(refleksivna(m))

System.out.println("refleksivna je");

else

System.out.println("Nije refleksivna");

if(simetricna(m))

System.out.println("Simetricna je");

else

System.out.println("Nije simetricna");

ispisi(m);

System.out.println("Pomocu collection-based for-petlje");

ispisi1(m);

}

}

Page 88: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

87

10. Rešavanje kvadratne jednačine

package kvadratneJednacine;

public class KvadratnaJednacina {

private double a;

private double b;

private double c;

public KvadratnaJednacina(double a, double b, double c)

{

this.a = a;

this.b = b;

this.c = c;

}

public KvadratnaJednacina izvod(){

return new KvadratnaJednacina(0, 2*a, b);

}

public double[] koreni(){

double koreni[] = new double[2];

double D = diskriminanta();

if(!imaRealneKorene())

koreni[0] = koreni[1] = 0;

else if(D == 0)

koreni[0] = koreni[1] = -b/(2*a);

else {

koreni[0] = (-b + Math.sqrt(D))/(2*a);

koreni[1] = (-b - Math.sqrt(D))/(2*a);

}

return koreni;

}

public double diskriminanta(){

return b*b - 4*a*c;

}

public boolean imaRealneKorene()

{

return b*b - 4*a*c >= 0 ? true : false;

}

public String toString()

{

String string = new String();

if(a == 0)

{

string += b + "*x";

string += c > 0 ? " + " + c : " " + c;

string += " = 0";

}

else

{

string += a + "*x^2";

string += b > 0 ? " + " + b + "*x" : " " + b + "*x";

string += c > 0 ? " + " + c : " " + c + " = 0";

string += " = 0";

}

return string;

}

}

11. Kreirati klasu Automobil koja ima:

Page 89: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

88

a. celobrojne podatke trenutnaBrzina i maksimalnaBrzina koji predstavljaju trenutnu i maksimalnu brzinu automobila u km/h. Trenutna brzina automobila ne može biti veća od maksimalne;

b. realni podatak predjeniPut koji određuje koliko kilometara je automobil prešao; c. konstruktor sa jednim celobrojnim parametrom koji predstavlja maksimalnu brzinu

automobila. Ona ne može biti negativna. Trenutna brzina i pređeni put se postavljaju na 0;

d. javni metod void ubrzaj(int a) koji povećava trenutnu brzinu za a km/h, ali ne preko maksimalne brzine;

e. javni metod void uspori(int a) koji smanjuje trenutnu brzinu za a km/h, ali ne ispod 0;

f. javni metod void vozi(double t) koji na promenljivu predjeniPut dodaje put koji auto pređe za t časova, vozeći trenutnom brzinom;

g. odgovarajuće getere i setere; h. javni metod int ucitajKomande(char * fileName), odnosno, u Javi, int

ucitajKomande(String fileName) koji učitava i izvršava komande iz tekstualne datoteke čije je ime dato. Metod vraća 0 ako se pri čitanju desila neka greška, a inače 1. Komande su oblika UBRZAJ A, USPORI A, VOZI T i svaka je data u po jednom redu. U prvom redu datoteke se nalazi broj komandi.

/*

* To change this template, choose Tools | Templates

* and open the template in the editor.

*/

package automobil;

import java.io.BufferedReader;

import java.io.FileNotFoundException;

import java.io.FileReader;

import java.io.IOException;

import java.util.StringTokenizer;

import java.util.logging.Level;

import java.util.logging.Logger;

/**

*

* @author Student

*/

public class Automobil {

private int trenutnaBrzina;

private int maximalnaBrzina;

private double predjeniPut;

public Automobil(int maximalnaBrzina) {

setMaximalnaBrzina(maximalnaBrzina);

this.predjeniPut = 0;

this.trenutnaBrzina = 0;

}

public void ubrzaj(int a) {

if(this.trenutnaBrzina + a > this.maximalnaBrzina){

this.trenutnaBrzina = this.maximalnaBrzina;

}

else this.trenutnaBrzina += a;

}

public void uspori(int a) {

Page 90: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

89

if(this.trenutnaBrzina - a < 0){

this.trenutnaBrzina = 0;

}

else this.trenutnaBrzina -= a;

}

void vozi(double t){

this.predjeniPut += this.trenutnaBrzina * t;

}

public int getMaximalnaBrzina() {

return maximalnaBrzina;

}

public void setMaximalnaBrzina(int maximalnaBrzina) {

if(maximalnaBrzina < 0) this.maximalnaBrzina = 10;

else this.maximalnaBrzina = maximalnaBrzina;

}

public double getPredjeniPut() {

return predjeniPut;

}

public void setPredjeniPut(double predjeniPut) {

if(predjeniPut < 0) this.predjeniPut = 0;

else this.predjeniPut = predjeniPut;

}

public int getTrenutnaBrzina() {

return trenutnaBrzina;

}

public void setTrenutnaBrzina(int trenutnaBrzina) {

this.trenutnaBrzina = trenutnaBrzina;

if(trenutnaBrzina < 0) this.trenutnaBrzina = 0;

if(trenutnaBrzina > this.maximalnaBrzina) this.trenutnaBrzina =

this.maximalnaBrzina;

}

public int ucitajKomande(String fileName) throws FileNotFoundException,

IOException, NumberFormatException {

BufferedReader in = new BufferedReader(new FileReader(fileName));

int brojKomandi;

String s = null;

s = in.readLine();

brojKomandi = Integer.parseInt(s);

for(int i = 0; i < brojKomandi; i++){

s = in.readLine();

StringTokenizer st = new StringTokenizer(s);

String komanda = (String)st.nextElement();

double broj = Double.parseDouble((String)st.nextElement());

System.out.println("komanda: " + komanda + " broj: " +

broj);

if(komanda.compareTo("UBRZAJ") == 0){

this.ubrzaj((int) broj);

}

else if(komanda.compareTo("USPORI") == 0){

this.uspori((int) broj);

}

else if(komanda.compareTo("VOZI") == 0){

this.vozi(broj);

}

}

in.close();

Page 91: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

90

return 0;

}

}

/*

* To change this template, choose Tools | Templates

* and open the template in the editor.

*/

package automobil;

import java.io.FileNotFoundException;

import java.io.IOException;

/**

*

* @author Student

*/

public class Main {

/**

* @param args the command line arguments

*/

public static void main(String[] args) {

// TODO code application logic here

Automobil a = new Automobil(300);

try {

a.ucitajKomande("auto.txt");

} catch (FileNotFoundException ex) {

System.out.println("Nepostojeci fajl");

} catch (IOException ex) {

System.out.println("Greska pri citanju");

} catch (NumberFormatException e){

System.out.println("Greska pri prevodjenju");

}

System.out.println("Max brzina je: " + a.getMaximalnaBrzina());

System.out.println("Trenutna brzina je: " + a.getTrenutnaBrzina());

System.out.println("Predjeni put je: " + a.getPredjeniPut());

}

}

12. Kreirati klasu Permutacija koja omogućava pamćenje jedne permutacije brojeva 1, ..., n i ima:

- Konstruktor Permutacija(int n). Ovaj konstruktor zadaje slučajnu permutaciju od n

elemenata.

- Konstruktor Permutacija(int n, int *a). Ovim konstruktorom se zadaje permutacija.

- Destruktor.

- Odgovarajuće getere i setere.

- Metod int redniBroj(), koji ordeđuje redni broj permutacije u leksikografskom poretku.

- Metod int generisiLeksikografsku(int n), koji generiše permutaciju sa rednim brojem n u

leksikografskom poretku. Rezultat je 0 ako generisanje nije uspelo, inače 1.

- Metod int sledeca(), koji određuje sledeću permutaciju u leksikografskom poretku. Rezultat

je 0 ukoliko ne postoji sledeća permutacija, inače 1.

Page 92: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

91

U glavnom programu testirati svaki od metoda.

/*

* To change this template, choose Tools | Templates

* and open the template in the editor.

*/

package permutacija;

import java.util.Random;

/**

*

* @author Student

*/

public class Permutacija {

private int duzPerm;

private int[] perm;

public Permutacija(int duzPerm, int[] perm) {

this.duzPerm = duzPerm;

this.perm = perm;

}

public Permutacija(int duzPerm) {

this.duzPerm = duzPerm;

perm = new int[duzPerm + 1];

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

this.perm[i] = i;

Random r = new Random();

for(int i = 1; i <= duzPerm; i++){

int idx = (r.nextInt(100) % i) + 1;

this.swap(i, idx);

}

}

private void swap(int i, int j){

int p = perm[i]; perm[i] = perm[j]; perm[j] = p;

}

public int sledeca(){

int i = this.duzPerm;

while((i > 1) && (this.perm[i - 1] > this.perm[i]))

i--;

if(i == 1) return 0;

int j = i - 1;

i = this.duzPerm;

while(this.perm[i] < this.perm[j])

i--;

this.swap(i, j);

int k = j + 1;

int l = this.duzPerm;

while(k < l){

this.swap(k, l);

k++; l--;

Page 93: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

92

}

return 1;

}

private long f(int i){

int br = 0;

for(int j = i + 1; j <= this.duzPerm; j++)

if(this.perm[i] > this.perm[j]) br++;

return br;

}

public int redniBroj(){

int rb = 0;

int n = 1, ii = 1;

for(int i = this.duzPerm; i >= 1; i--){

rb += this.f(i) * n;

if(i != this.duzPerm) n *= (++ii);

}

return rb;

}

public void stampaj(){

for(int i = 1; i <= this.duzPerm; i++)

System.out.print(this.perm[i]+" ");

System.out.println();

}

public int getDuzPerm() {

return duzPerm;

}

public void setDuzPerm(int duzPerm) {

this.duzPerm = duzPerm;

}

public int[] getPerm() {

return perm;

}

public void setPerm(int[] perm) {

this.perm = perm;

}

}

/*

* To change this template, choose Tools | Templates

* and open the template in the editor.

*/

package permutacija;

/**

*

* @author Student

*/

public class Main {

/**

* @param args the command line arguments

*/

Page 94: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

93

public static void main(String[] args) {

// TODO code application logic here

Permutacija p;

p = new Permutacija(7);

p.stampaj();

System.out.println("Redni broj je " + p.redniBroj());

int i = p.sledeca();

if(i==1){

p.stampaj();

System.out.println("Redni broj je " + p.redniBroj());

}

}

}

13. Саставити на језику Java следећи пакет класа:

Домина садржи два целобројна поља (a,b). Може да се дохвати вредност првог и другог поља домине, да се изврши међусобна замена поља, да се одреди да ли су две домине једнаке не водећи рачуна о редоследу поља и да се састави текстуални опис домине у облику (a,b).

Скуп домина садржи произвољан број различитих домина. Ствара се празан после чега се домине додају једна по једна и смештају у скуп по неком непознатом редоследу. Повратна вредност при додавању представља индикатор успеха. Може да се испита дали се нека домина налази у скупу и да се састави текстуални опис скупа који се састоји од текстуалних описа садржаних домина.

Кутија је скуп домина код које се домине додају на крај скупа. Може да се напуни свим могућим доминама, по случајном редоследу, с вредностима поља у опсегу од 0 до n−1 (број таквих домина је n(n+1)/2) и да се узме домина са почетка кутије (повратна вредност је null ако је кутија празна).

Табла је скуп домина код којег се домине додају на почетак или крај тако да суседна поља суседних домина буду једнака (тј. да друго поље претходне домине буде једнако првом пољу наредне домине).

Написати на језику Java програм (класу с главном функцијом) који направи једну кутију

и једну таблу, напуни кутију за фиксно одабрани параметар n, испише кутију на

главном излазу, узима домине из кутије и ставља их на таблу све док може и испише

завршни садржај табле на главном излазу.

// Domina.java

package igra;

public class Domina {

private int a, b;

public Domina (int p, int q) { a = p; b = q; }

public int a () { return a; }

public int b () { return b; }

public boolean ista (Domina d) { return a==d.a && b==d.b || b==d.a &&

a==d.b; }

public Domina okreni () { int c = a; a = b; b = c; return this; }

public String toString () { return "(" + a + "," + b + ")"; }

}

// Skup.java

package igra;

class Elem {

Page 95: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

94

Domina dom;

Elem sled;

Elem (Domina d, Elem s) { dom = d; sled = s; }

}

public abstract class Skup {

protected Elem prvi, posl;

public boolean ima (Domina d) {

for (Elem tek=prvi; tek!=null; tek=tek.sled) if (d.ista (tek.dom))

return true;

return false;

}

public abstract boolean dodaj (Domina d) ;

public String toString () {

String s = "";

for (Elem tek=prvi; tek!=null; tek=tek.sled) s += tek.dom;

return s;

}

}

// Kutija.java

package igra;

public class Kutija extends Skup {

public boolean dodaj (Domina d) {

if (ima (d)) return false;

Elem novi = new Elem (d, null);

if (prvi == null) prvi = novi; else posl.sled = novi;

posl = novi;

return true;

}

public Kutija napuni (int n) {

prvi = posl = null;

int m = n * (n+1) / 2;

for (int i=0; i<m;)

if (dodaj (new Domina ((int)(Math.random()*n),

(int)(Math.random()*n)))) i++;

return this;

}

public Domina uzmi () {

if (prvi == null) return null;

Domina d = prvi.dom;

if ((prvi = prvi.sled) == null) posl = null;

return d;

}

}

// Tabla.java

package igra;

public class Tabla extends Skup {

public boolean dodaj (Domina d) {

if (ima (d)) return false;

if (prvi==null || d.b()==prvi.dom.a()) naPocetak (d);

else if (d.a() == posl.dom.b()) naKraj (d);

else {

d.okreni ();

if (d.b() == prvi.dom.a()) naPocetak (d);

else if (d.a() == posl.dom.b()) naKraj (d);

else return false;

}

return true;

}

private void naPocetak (Domina d) {

prvi = new Elem (d, prvi);

if (posl == null) posl = prvi;

Page 96: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

95

}

private void naKraj (Domina d) {

Elem novi = new Elem (d, null);

if (prvi == null) prvi = novi; else posl.sled = novi;

posl = novi;

}

}

// Test.java

import igra.*;

public class Test {

public static void main (String[] varg) {

int n = 4;

Kutija k = new Kutija ();

k.napuni (n);

System.out.println ("Kutija: " + k);

Tabla t = new Tabla ();

Domina d;

while ((d = k.uzmi ()) != null && t.dodaj (d));

System.out.println ("Tabla: " + t);

}

}

Kutija: (2,3)(2,1)(0,3)(0,2)(2,2)(3,1)(0,0)(1,0)(1,1)(3,3)

Tabla: (3,1)(1,2)(2,3)(3,0)(0,2)(2,2)

14. Саставити на језику Java следећи пакет класа:

Радник у трговачкој фирми има име и као плату добија задати проценат од вредности оствареног прихода. Може да се одреди вредност оствареног прихода, да се израчуна висина плате и да се састави текстуални опис у облику "име/плата".

Продавац је радник који може да продаје робу, а приликом сваке продаје води се само рачуна о вредности продате робе. Приход чини укупна вредност продате робе.

Шеф је радник коме може бити потчињен задати број других радника. Радници се шефу додељују један по један са назнаком да ли је додељивање успело с обзиром на предвиђени број потчињених. Приход на основу којег шеф добија плату једнак је укупном приходу свих његових потчињених.

Трговачка фирма има задат број радних места и послује са задатом маржом (процентом од вредности продате робе). Може да се запосли један радник који се распоређује на прво слободно радно место и да се отпусти радник с радног места са задатим редним бројем. Оба пута вредност функције је индикатор успеха. Може да се одреди укупна добит фирме као разлика између укупне зараде (приход*маржа/100) коју су остварили сви продавци и укупне плате свих радника. Може да се састави текстулани опис фирме који садржи текстуалне описе свих запослених радника (један радник по реду) и добит фирме.

Написати на језику Java програм који направи фирму с једним шефом и два продавца који су му потчињени, обави по једну продају са оба продавца и испише податке о фирми. Користити константне параметре (не треба ништа учитавати).

// Predmet.java

package prodaja;

Page 97: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

96

public abstract class Radnik {

private String ime;

private double procenat;

protected Radnik (String i, double p) { ime = i; procenat = p; }

public abstract double prihod ();

public double plata () { return prihod() * procenat / 100; }

public String toString () { return ime + "/" + plata(); }

}

// Prodavac.java

package prodaja;

public class Prodavac extends Radnik {

private double prihod;

public Prodavac (String ime, double procenat) { super (ime, procenat); }

public void prodao (double vrednost) { prihod += vrednost; }

public double prihod () { return prihod; }

}

// Sef.java

package prodaja;

public class Sef extends Radnik {

private Radnik[] potcinjeni;

private int brPot = 0;

public Sef (String ime, double procenat, int kap) {

super (ime, procenat);

potcinjeni = new Radnik [kap];

}

public boolean dodeli (Radnik z) {

if (brPot == potcinjeni.length) return false;

potcinjeni[brPot++] = z;

return true;

}

public double prihod () {

double p = 0;

for (int i=0; i<brPot; p=potcinjeni[i++].prihod());

return p;

}

}

// Frima.java

package prodaja;

public class Firma {

private Radnik[] radnici;

private double marza;

public Firma (double m, int kap) {

marza = m;

radnici = new Radnik [kap];

}

public boolean zaposli (Radnik r) {

int i=0; while (radnici[i] != null) i++;

if (i == radnici.length) return false;

radnici[i] = r;

return true;

}

public boolean otpusti (int i) {

if (i<0 || i>=radnici.length || radnici[i]==null) return false;

radnici[i] = null;

return true;

}

public double dobit () {

double d = 0, p = 0;

for (int i=0; i<radnici.length; i++)

if (radnici[i] != null) {

if (radnici[i] instanceof Prodavac) d += radnici[i].prihod();

Page 98: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

97

p += radnici[i].plata();

}

return d * marza / 100 - p;

}

public String toString () {

String s = "";

for (int i=0; i<radnici.length; i++)

if (radnici[i] != null) s += radnici[i] + "\n";

return s + "Dobit firme: " + dobit();

}

}

// Test.java

import prodaja.*;

public class Test {

public static void main (String[] varg) {

Firma firma = new Firma (30, 5);

Sef nenad = new Sef ("Nenad", 6, 3);

Prodavac marko = new Prodavac ("Marko", 5);

Prodavac zoran = new Prodavac ("Zoran", 4);

firma.zaposli (nenad);

firma.zaposli (marko);

firma.zaposli (zoran);

nenad.dodeli (marko);

nenad.dodeli (zoran);

marko.prodao (5000);

zoran.prodao (8000);

System.out.print (firma);

}

}

Marko/250.0

Zoran/320.0

Nenad/480.0

Dobit firme: 2850.0

15. Пројектовати на језику Java пакет класа са следћим описом:

Апстрактном изразу може да се израчуна вредност реалног типа. Константа је израз чија вредност не може да се промени после

иницијализације. Конверзија у тип String садржи вредност константе. Променљива је израз који има име и реалну вредност (подразумевано 0) која

може да се промени и после иницијализације. Конверзија у тип String садржи име променљиве. Све променљиве морају да имају различита имена (покушај стварања променљиве са већ коришћеним именом пријавити изузетком).

Збир, производ и степен су изрази који се иницијализују са два израза (на пример: a и b) и чије су вредности једнаке a+b, ab и ab. Конверзија у тип String је облика (a+b), (a*b) и (a^b), где су a и b резултати конверзије операнада у тип String.

Саставити на језику Java класу са главним програмом који ствара објекат променљиве x и објекат за израз x3-2x, испише текстуални облик тог израза као заглавље и после врши табелирање вредности тог израза за све вредности xmin≤x≤xmax са кораком Δx. Параметри табелирања се достављају као параметри главног програма.

Page 99: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

98

// Izraz.java

package izrazi;

public interface Izraz {

double vrednost ();

}

// Konst.java

package izrazi;

public class Konst implements Izraz {

private final double vrednost;

public Konst (double v) { vrednost = v; }

public double vrednost () { return vrednost; }

public String toString () { return Double.toString(vrednost); }

}

// GImePostoji.java

package izrazi;

public class GImePostoji extends Exception {}

// Prom.java

package izrazi;

public class Prom implements Izraz {

private String ime;

private double vrednost;

private static class Elem {

Prom prom; Elem sled;

Elem (Prom p) {prom = p; }

}

private static Elem prvi, posl;

public static Prom nadji (String i) {

for (Elem tek=prvi; tek!=null; tek=tek.sled)

if (tek.prom.ime.equals(i)) return tek.prom;

return null;

}

public Prom (String i, double v)

throws GImePostoji {

if (nadji (i) != null) throw new GImePostoji ();

ime = i; vrednost = v;

Elem novi = new Elem (this);

if (prvi == null) prvi = novi;

else posl.sled = novi;

posl = novi;

}

public Prom (String i) throws GImePostoji { this (i, 0); }

public double vrednost () { return vrednost; }

public void postavi (double v) { vrednost = v; }

public String toString () { return ime; }

}

// Zbir.java

package izrazi;

public class Zbir implements Izraz {

private Izraz a, b;

public Zbir (Izraz aa, Izraz bb) { a=aa; b=bb; }

public double vrednost () { return a.vrednost () + b.vrednost (); }

public String toString () { return "(" + a + '+' + b + ')'; }

}

// Proizv.java

package izrazi;

public class Proizv implements Izraz {

private Izraz a, b;

public Proizv (Izraz aa, Izraz bb) { a=aa; b=bb; }

Page 100: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

99

public double vrednost () { return a.vrednost () * b.vrednost (); }

public String toString () { return "(" + a + '*' + b + ')'; }

}

// Stepen.java

package izrazi;

public class Stepen implements Izraz {

private Izraz a, b;

public Stepen (Izraz aa, Izraz bb) { a=aa; b=bb; }

public double vrednost () { return Math.pow(a.vrednost(),b.vrednost()); }

public String toString () { return "(" + a + '^' + b + ')'; }

}

// Test.java

import izrazi.*;

public class Test {

public static void main (String[] vpar) {

double xmin = Double.parseDouble(vpar[0]),

xmax = Double.parseDouble(vpar[1]),

dx = Double.parseDouble(vpar[2]);

Prom x = null;

try { x = new Prom ("x"); } catch (GImePostoji g) {}

Izraz poli = new Zbir (

new Stepen (x, new Konst (3)),

new Proizv (new Konst (-2), x)

);

System.out.println ("x\t " + poli);

for (double xx=xmin; xx<=xmax; xx+=dx) {

x.postavi (xx);

System.out.println (xx+"\t"+poli.vrednost());

}

}

}

16. Kreirati klasu Figura koja kao privatne podatake ima koordinate težišta figure. Iz nje izvesti klase Krug i Pravougaonik koje imaju, redom, podatke poluprecnik, odnosno sirina i visina. Napisati odgovarajuće setere i getere, kao i konstruktore sa odgovarajućim brojevima parametara.

a. U klasi Figura definisati virtuelne metode char * tip(), kao i double povrsina(), koji vraćaju string koji opisuje figuru, odnosno površinu figure. Preklopiti ove metode u izvedenim klasama.

b. Promeniti metode tip i povrsina tako da klasa figura postane apstraktna klasa.

c. U glavnom programu kreirati niz figura. Za svaku pitati korisnika kog je tipa (krug ili pravougaonik) i u zavisnosti od odgovora pitati za potrebne podatke. Zatim za svaku od figura odštampati koordinate težišta, površinu, kao i tip figure.

17. Napisati u javi odgovarajuće klase iz prethodnih zadataka.

a. Kreirati interfejs GeometrijskaFigura koji ima samo metod povrsina, a zatim postaviti da klasa Figura implementira ovaj interfejs. Obratiti pažnju na to u kojim klasama se metod implementira (pod uslovom da je Figura apstraktna klasa).

/***** Figura.h **********/ #pragma once

class CFigura

Page 101: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

100

{

int x;

int y;

public:

static const double PI;

CFigura(void);

CFigura(int x, int y);

~CFigura(void);

int getX(void);

void setX(int x);

int getY(void);

void setY(int y);

virtual char* tip(void);

virtual double povrsina(void) = 0;

};

/*********** Krug.h *************/

#pragma once

#include "figura.h"

class CKrug :

public CFigura

{

int r;

public:

//ne nasledjuju se konstruktori

CKrug(void);

CKrug(int r);

CKrug(int r, int x, int y);

~CKrug(void);

int getR(void);

void setR(int r);

char* tip(void);

double povrsina(void);

};

/********* Pravougaonik.h **********/

#pragma once

#include "figura.h"

class CPravougaonik :

public CFigura

{

int a, b;

public:

CPravougaonik(void);

CPravougaonik(int a, int b);

CPravougaonik(int x, int y, int a, int b);

~CPravougaonik(void);

int getA(void);

void setA(int a);

int getB(void);

void setB(int b);

char *tip(void);

double povrsina(void);

};

/****** Figura.cpp ********/

#include "Figura.h"

const double CFigura::PI = 3.14159265358979323846;

CFigura::CFigura(void)

{

Page 102: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

101

setX(0); setY(0);

}

CFigura::CFigura(int x, int y)

{

setX(x); setY(y);

}

CFigura::~CFigura(void)

{

}

int CFigura::getX(void)

{

return this->x;

}

void CFigura::setX(int x)

{

this->x = x;

}

int CFigura::getY(void)

{

return this->y;

}

void CFigura::setY(int y)

{

this->y = y;

}

char* CFigura::tip(void)

{

return "Figura";

}

/* double CFigura::povrsina(void)

{

return 0.0;

} */

/****** Krug.cpp ********/

#include "Krug.h"

CKrug::CKrug(void)

{

setR(1);

}

CKrug::CKrug(int r)

{

setR(r);

//ne moze this->x = 1 jer je x private. Moglo bi da je x protected

ili public

//moze setX(1), jer je setX public metod;

}

CKrug::~CKrug(void)

{

}

Page 103: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

102

CKrug::CKrug(int r, int x, int y):CFigura(x, y) //konstruktor Figura

zamenjuje setX i setY

{

setR(r);

//setX(x);

//setY(y);

}

int CKrug::getR(void)

{

return r;

}

void CKrug::setR(int r)

{

if(r < 0) this->r = 1;

else this->r = r;

}

char* CKrug::tip(void)

{

return "Krug";

}

double CKrug::povrsina(void)

{

return (r*r*PI);

}

/******* Pravougaonik.cpp ********/

#include "Pravougaonik.h"

CPravougaonik::CPravougaonik(void)

{

}

CPravougaonik::CPravougaonik(int a, int b)

{

setA(a);

setB(b);

}

CPravougaonik::CPravougaonik(int x, int y, int a, int b):CFigura(x, y)

{

setA(a);

setB(b);

}

CPravougaonik::~CPravougaonik(void)

{

}

int CPravougaonik::getA(void)

{

return a;

}

void CPravougaonik::setA(int a)

{

this->a = a;

}

int CPravougaonik::getB(void)

{

Page 104: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

103

return b;

}

void CPravougaonik::setB(int b)

{

this->b = b;

}

char* CPravougaonik::tip(void)

{

return "Pravougaonik";

}

double CPravougaonik::povrsina(void)

{

return (a*b);

}

/***** main.cpp ********/

#include <stdio.h>

#include "Krug.h"

#include "Pravougaonik.h"

#include <math.h>

int main()

{

int x, y;

scanf("%d%d", &x, &y);

//CFigura fig(x, y);

//printf("Koordinate tezista su (%d, %d)\n", fig.getX(), fig.getY());

//CFigura figBlank;

//printf("Konstruktor bez parametara: (%d, %d)\n", figBlank.getX(),

figBlank.getY());

/* CFigura *fig = new CFigura(x, y);

printf("Koordinate tezista su (%d, %d)\n", fig->getX(), fig->getY());

CFigura *figBlank = new CFigura();

printf("Konstruktor bez parametara: (%d, %d)\n", figBlank->getX(),

figBlank->getY()); */

int r;

scanf("%d", &r);

//CKrug *k = new CKrug(r);

CKrug *k = new CKrug(r, x, y);

//printf("Poluprecnik je %d\n", k->getR());

//k->setX(x); k->setY(y);

//printf("Centar je (%d, %d)\n", k->getX(), k->getY());

//CFigura *f = new CFigura();

//printf("%s\n", f->tip());

//delete f;

/* CFigura *f = k;

printf("%s\n", f->tip());

printf("Povrsina figre je %lf\n", f->povrsina());

delete f;

scanf("%d%d", &x, &y);

f = new CPravougaonik(x, y);

printf("%s\n", f->tip());

Page 105: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

104

printf("Povrsina figre je %lf\n", f->povrsina()); */

int n;

CFigura* niz[10];

niz[0] = new CKrug(3);

niz[1] = new CPravougaonik(2, 5);

niz[2] = new CKrug();

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

{

printf("Tip figure je %s\n", niz[i]->tip());

printf("Povrsina figre je %lf\n", niz[i]->povrsina());

}

return 0;

}

18. Kreirati klasu Figura iz koje se izvode klase Krug i Pravougaonik. Iz klase

Pravougaonik izvesti klasu Kvadrat. Krug ima poluprečnik, pravougaonik dužine

stranica, a kvadrat samo dužinu stranice. Osnovna klasa figura treba da ima metode

povrsina() i obim() koji vraćaju vrednost 0, kao i metod toString() koji kao rezultat

vraća string “Figura”. U klasama naslednicima premostiti ove metode tako da ispravno

računaju površinu, odnosno obim odgovarajuće figure, kao da rezultat metoda

toString() bude odgovarajući string.

U glavnom programu kreirati niz figura, za svaki odštampati rezultat poziva metoda

toString(), a zatim odštampati broj figura svakog od tipova, indeks figure sa najvećom

površinom i indeks pravougaonika sa najmanjim obimom.

19. Kreirati klasu Robot koja u svakom trenutku pamti poziciju robota u ravni. Klasa bi trebalo da

ima metode kreni(int t), ubrzaj(int v), uspori(int v), levo(), levo(int x), desno(), desno(int x). Robot se na početku nalazi u koordinatnom početku, a početni smer je u pozitivnom smeru x – ose. Trebalo bi omogućiti korisniku da pri kreiranju objekta zada početne koordinate robota, kao i početni smer. Brzina robota se meri u metrima u sekundi, a početna brzina je 0. Metod kreni(t) pokreće robota u trenutnom smeru t sekundi. Metod ubrzaj(v) (uspori(v)) povećava (smanjuje) brzinu robota za v metara u sekundi. Brzina robota nikada ne sme biti manja od 0 m/s, a ni veća od 30 m/s. Metodi levo(x ) desno(x) menjaju smer kretanja robota za x stepeni u odgovarajuću stranu. Metodi levo() i desno() menjaju smer kretanja za 90 stepeni.

Napisati metode pozicijaX() i pozicijaY() koji daju x, odnosno y koordinatu trenutne

pozicije. Napisati metod ucitajKomande(String filename) koji iz tekstualne datoteke sa

navedenim imenom učitava komande za robota i izvršava ih. U svakom redu datoteke se nalazi

po jedna komanda. Komande mogu biti KRENI #, UBRZAJ #, USPORI #, LEVO, LEVO #,

DESNO, DESNO # (# označava prirodan broj).

U glavnom programu učitati početne koordinate robota, a zatim izvršiti spisak komandi iz

datoteke ‘robot.in’. Na kraju odštampati rastojanje robota od početne tačke.

/*

* To change this template, choose Tools | Templates

* and open the template in the editor.

Page 106: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

105

*/

package robot;

import java.util.Vector;

/**

*

* @author Student

*/

public class Robot {

private VektorURavni pozicija;

private VektorURavni smer;

private int brzina;

public Vector<Komanda> nizKomandi;

public Robot(VektorURavni pozicija, VektorURavni smer, int brzina,

Vector<Komanda> nizKomandi) {

this.pozicija = pozicija;

this.smer = smer;

this.brzina = brzina;

this.nizKomandi = nizKomandi;

}

public void izvrsi() {

for(int i = 0; i < nizKomandi.size(); i++) {

Komanda s = nizKomandi.get(i);

// StringTokenizer tok = new StringTokenizer(s);

// String komanda = tok.nextToken();

// String trajanjeString = tok.nextToken();

// String argString = tok.nextToken();

//

// int trajanje = Integer.parseInt(trajanjeString);

// double arg = Double.parseDouble(argString);

//

// if(komanda.equals("Pravo")) {

// int argI = (int) arg;

// Pravo p = new Pravo(trajanje, argI);

// }

s.izvrsi(this);

}

}

public int getBrzina() {

return brzina;

}

public void setBrzina(int brzina) {

this.brzina = brzina;

}

public Vector<Komanda> getNizKomandi() {

return nizKomandi;

}

public void setNizKomandi(Vector<Komanda> nizKomandi) {

this.nizKomandi = nizKomandi;

}

public VektorURavni getPozicija() {

return pozicija;

}

Page 107: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

106

public void setPozicija(VektorURavni pozicija) {

this.pozicija = pozicija;

}

public VektorURavni getSmer() {

return smer;

}

public void setSmer(VektorURavni smer) {

this.smer = smer;

}

void dodajKomandu(Komanda k) {

this.nizKomandi.add(k);

}

}

--------------------------------------------------------------------

/*

* To change this template, choose Tools | Templates

* and open the template in the editor.

*/

package robot;

/**

*

* @author Student

*/

public class VektorURavni {

private double x;

private double y;

public double getX() {

return x;

}

public void setX(double x) {

this.x = x;

}

public double getY() {

return y;

}

public void setY(double y) {

this.y = y;

}

public VektorURavni(double x, double y) {

this.x = x;

this.y = y;

}

public VektorURavni() {

this.x = 0;

this.y = 0;

}

}

--------------------------------------------------------------------

Page 108: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

107

/*

* To change this template, choose Tools | Templates

* and open the template in the editor.

*/

package robot;

/**

*

* @author Student

*/

public abstract class Komanda {

private int trajanje;

public int getTrajanje() {

return trajanje;

}

public void setTrajanje(int trajanje) {

if(trajanje >= 0)

this.trajanje = trajanje;

else

this.trajanje = 0;

}

public Komanda(int trajanje) {

setTrajanje(trajanje);

}

public Komanda() {

this.trajanje = 1;

}

public abstract void izvrsi(Robot r);

}

--------------------------------------------------------------------

/*

* To change this template, choose Tools | Templates

* and open the template in the editor.

*/

package robot;

/**

*

* @author Student

*/

public class Pravo extends Komanda {

public Pravo(int trajanje) {

super(trajanje);

}

@Override

public void izvrsi(Robot r) {

int s = this.getTrajanje() * r.getBrzina();

}

}

Page 109: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

108

--------------------------------------------------------------------

/*

* To change this template, choose Tools | Templates

* and open the template in the editor.

*/

package robot;

/**

*

* @author Student

*/

public class Skreni extends Komanda{

private double ugao;

public double getUgao() {

return ugao;

}

public void setUgao(double ugao) {

if(ugao >= 0 && ugao <= 2*Math.PI)

this.ugao = ugao;

else

this.ugao = ugao % Math.PI;

}

public Skreni(int trajanje, double ugao) {

super(trajanje);

this.ugao = ugao;

}

@Override

public void izvrsi(Robot r) {

}

}

--------------------------------------------------------------------

/*

* To change this template, choose Tools | Templates

* and open the template in the editor.

*/

package robot;

/**

*

* @author Student

*/

public class Ubrzaj extends Komanda {

private int ubrzanje;

public Ubrzaj(int trajanje, int ubrzanje) {

super(trajanje);

this.ubrzanje = ubrzanje;

}

public Ubrzaj(int ubrzanje) {

this.ubrzanje = ubrzanje;

}

Page 110: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

109

public int getUbrzanje() {

return ubrzanje;

}

public void setUbrzanje(int ubrzanje) {

this.ubrzanje = ubrzanje;

}

@Override

public void izvrsi(Robot r) {

r.setBrzina(this.ubrzanje * this.getTrajanje() + r.getBrzina());

if(r.getBrzina() < 0)

r.setBrzina(0);

}

}

20. Kreirati klasu Vozilo koja ima privatne podatke kapacitetRezervoara i potrosnja. Kapacitet rezervoara je ceo broj, a potrošnja je realan broj. Iz ove klase izvesti klase Autobus i Kamion. Klasa Autobus ima privatan podatak brojSedista (ceo broj), a klasa Kamion ima privatan podatak nosivost (ceo broj).

Kreirati klasu VozniPark koja kao podatke ima brojVozila (ceo broj), kao i nizVozila (tipa

Vozilo). Implementirati metod kojim se:

dodaje novo vozilo u vozni park;

izbacuje vozilo iz voznog parka;

za dati broj putnika određuje da li je moguće sve ih smestiti u autobuse voznog parka;

za datu količinu tereta t, odrediti najmanji broj kamiona u koje se taj teret može smestiti;

za datu količinu tereta t, kao i datu dužinu puta koji treba preći s, odrediti najkraći niz kamiona koji mogu tu količinu tereta da prevezu (podrazumeva se da na put polaze sa punim rezervoarima). Za svaku od klasa kreirati odgovarajuće konstruktore. U glavnom programu testirati ispravnost rada na primerima.

/**************** VozniPark.java **************************/

/*

* To change this template, choose Tools | Templates

* and open the template in the editor.

*/

package voznipark;

import java.util.Arrays;

import java.util.Vector;

/**

*

* @author Student

*/

public class VozniPark {

private int brojVozila;

private Vector<Vozilo> nizVozila;

public VozniPark(int brojVozila, Vector nizVozila) {

this.brojVozila = brojVozila;

Page 111: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

110

this.nizVozila = nizVozila;

}

public int getBrojVozila() {

return brojVozila;

}

public void setBrojVozila(int brojVozila) {

this.brojVozila = brojVozila;

}

public Vector getNizVozila() {

return nizVozila;

}

public void setNizVozila(Vector nizVozila) {

this.nizVozila = nizVozila;

}

public void ubaciVozilo(Vozilo a) {

nizVozila.add(a);

brojVozila++;

}

public Vozilo izbaciVozilo(int index) {

brojVozila--;

return (Vozilo) nizVozila.remove(index);

}

public boolean moguStati(int n) {

int tmp = 0;

for (int i = 0; i < nizVozila.size(); i++) {

Vozilo v = nizVozila.get(i);

if (v instanceof Autobus) {

tmp += ((Autobus) v).getBrojSedista();

}

}

return (n <= tmp);

}

public int najmanjiBrojKamiona(int t) {

Vozilo[] niz = new Vozilo[brojVozila];

nizVozila.copyInto(niz);

Arrays.sort(niz);

return 0;

}

}

/*

* To change this template, choose Tools | Templates

* and open the template in the editor.

*/

/******************* Vozilo.java **********************/

package voznipark;

/**

*

* @author Student

*/

public abstract class Vozilo implements Comparable<Vozilo> {

private int kapacitetRezervoara;

Page 112: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

111

private double potrosnja;

public Vozilo() {

setKapacitetRezervoara(0);

setPotrosnja(0);

}

public Vozilo(int kapacitetRezervoara, double potrosnja) {

this.kapacitetRezervoara = kapacitetRezervoara;

this.potrosnja = potrosnja;

}

public int getKapacitetRezervoara() {

return kapacitetRezervoara;

}

public void setKapacitetRezervoara(int kapacitetRezervoara) {

this.kapacitetRezervoara = kapacitetRezervoara;

}

public double getPotrosnja() {

return potrosnja;

}

public void setPotrosnja(double potrosnja) {

this.potrosnja = potrosnja;

}

public abstract String tip();

}

/********************* Autobus.java **********************/

/*

* To change this template, choose Tools | Templates

* and open the template in the editor.

*/

package voznipark;

/**

*

* @author Student

*/

public class Autobus extends Vozilo {

private int brojSedista;

public Autobus() {

this.brojSedista = 0;

}

public Autobus(int kapacitetRezervoara, double potrosnja, int

brojSedista) {

super(kapacitetRezervoara, potrosnja);

this.brojSedista = brojSedista;

}

public int getBrojSedista() {

return brojSedista;

}

Page 113: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

112

public void setBrojSedista(int brojSedista) {

this.brojSedista = brojSedista;

}

@Override

public String tip() {

return "Autobus";

}

public int compareTo(Vozilo o) {

if (o instanceof Kamion) return 1;

else return 0;

}

}

/********************** Kamion.java ***************************/

/*

* To change this template, choose Tools | Templates

* and open the template in the editor.

*/

package voznipark;

/**

*

* @author Student

*/

public class Kamion extends Vozilo {

private int nosivost;

public Kamion() {

this.nosivost = 0;

}

public Kamion(int kapacitetRezervoara, double potrosnja, int nosivost)

{

super(kapacitetRezervoara, potrosnja);

this.nosivost = nosivost;

}

public int getNosivost() {

return nosivost;

}

public void setNosivost(int nosivost) {

this.nosivost = nosivost;

}

@Override

public String tip() {

return "Kamion";

}

public int compareTo(Vozilo o) {

if (o instanceof Kamion) {

Kamion k = (Kamion) o;

if (this.nosivost > k.nosivost) return -1;

if (this.nosivost < k.nosivost) return 1;

return 0;

}

Page 114: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

113

else return -1;

}

}

/**************************** Main.java ************************/

/*

* To change this template, choose Tools | Templates

* and open the template in the editor.

*/

package voznipark;

/**

*

* @author Student

*/

public class Main {

/**

* @param args the command line arguments

*/

public static void main(String[] args) {

// TODO code application logic here

}

}

21. Написати на језику Java следећи пакет типова (грешке пријављивати изузецима опремљеним текстовима порука):

Енергенту може да се одреди енергетска вредност изражена у релним кило џулима.

Апстрактна намирница је енергент који има име (ниска знакова) и јединствен, аутоматски генерисан целобројан идентификатор, који могу да се дохвате. Текстуални опис је име_намирнице[ид].

Храна је намирница која се задаје тежином дате намернице израженом у грамима (реалан број) и процентуалним уделом беланчевина, масти и угљених хидрата (реални бројеви) у укупној тежини. Могу да се дохвате тежински удео беланчевина, масти и угљених хидрата и укупна тежина. Енергетска вредност 1g беланчевина износи 16,7kЈ, масти 37,6kЈ, а угљених хидрата 17,2kЈ. Текстуални опис јеиме_хране[ид](тежина,енергетска_вредност). Грешка је ако збир процентуалних удела беланчевина, масти и угљених хидрата прелази 100%.

Пиће је намирница које се задаје количином у литрима (реалан број) и енергетском вредношћу једног литра израженој у kJ (реалан број). Може да се дохвати количина. Текстуални опис је име_пића[ид](количина,енергетска_вредност).

Мени садржи низ намирница. Ствара се празан, задатог капацитета, после чега се намирнице додају једна по једна. Може да се одреди укупна енергетска вредност менија и да се састави текстуални опис менија у облику{намирница,…,намирница}[ук_енергетска_вредност], где је намирница текстуални опис једне намернице у саставу менија. Грешка је ако се мени препуни.

Page 115: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

114

Написати на језику Java програм (класу с главном функцијом) који направи један мени у који смести неколико намирница, а затим на главном излазу испише садржај формираног менија. Сви параметри треба да буду константе (не треба ништа учитавати

// Energent.java

package ishrana;

public interface Energent {

double energVr ();

}

// Namirnica.java

package ishrana;

public abstract class Namirnica implements Energent {

private String ime;

private static int ukId;

private int id = ++ukId;

protected Namirnica (String iime) { ime = iime; }

public String ime () { return ime; }

public int id () { return id; }

public String toString () { return ime + "[" + id + "]"; }

}

// GPodaci.java

package ishrana;

public class GPodaci extends Exception {

public String toString () { return "*** Neispravani podaci!"; }

}

// Hrana.java

package ishrana;

public class Hrana extends Namirnica {

private double tez, belanc, masti, ugHidr;

public Hrana (String ime, double t, double b, double m, double u) throws

GPodaci {

super (ime);

if (b+m+u > 100) throw new GPodaci ();

tez = t; belanc = b; masti = m; ugHidr = u;

}

public double belanc () { return tez * belanc / 100; }

public double masti () { return tez * masti / 100; }

public double ugHidr () { return tez * ugHidr / 100; }

public double tezina () { return tez; }

public double energVr () { return 16.7*belanc() + 37.6*masti() +

17.2*ugHidr(); }

Page 116: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

115

public String toString ()

{ return super.toString() + "(" + tez + "," + energVr() + ")"; }

}

// Pice.java

package ishrana;

public class Pice extends Namirnica {

private double kol, enVr;

public Pice (String ime, double k, double e) { super (ime); kol = k; enVr

= e; }

public double kolicina () { return kol; }

public double energVr () { return kol * enVr; }

public String toString ()

{ return super.toString() + "(" + kol + "," + enергVr)= + ")"; }

}

// GPun.java

package ishrana;

public class GPun extends Exception {

public String toString () { return "*** Meni je pun!"; }

}

// Meni.java

package ishrana;

public class Meni {

private Namirnica[] niz;

private int brNam;

public Meni (int kap) { niz = new Namirnica [kap]; }

public Meni dodaj (Namirnica nam) throws GPun {

if (brNam == niz.length) throw new GPun ();

niz[brNam++] = nam;

return this;

}

public double energVr () {

double ev = 0;

for (int i=0; i<brNam; ev+=niz[i++].energVr());

return ev;

}

public String toString () {

String s = "{";

for (int i=0; i<brNam; i++) {

if (i > 0) s += ",";

s += niz[i];

}

return s + "}[" + energVr() + "]";

}

}

// Test.java

Page 117: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

116

import ishrana.*;

public class Test {

public static void main (String[] varg) {

try {

Meni meni = new Meni (10);

meni.dodaj (new Hrana("Hleb",600,7.5,0.4,49))

.dodaj (new Pice ("Sok", 0.2,18540))

.dodaj (new Hrana("Sir", 200,17,1.2,4));

System.out.println (meni);

} catch (GPodaci g) { System.out.println (g);

} catch (GPun g) { System.out.println (g);

}

}

}

{Hleb[1](600.0,5898.54),Sok[2](0.2,3078.0),Sir[3](200.0,795.64)}[10402.18]

22. Написати на језику Java следећи пакет типова (грешке пријављивати изузецима опремљеним текстовима порука):

Матрица реалних бројева има задат број врста и колона који могу да се дохвате. Може да се постави или да се дохвати елемент са задатим индексима (грешка је ако је неки од индекса изван опсега, да се направи копија матрице и да се састави текстуални опис матрице који у савком реду садржи једну врсту елемената по формату "%6.2f".

Функција на основу низа реалних бројева може да врати једну реалну вредност или да буде прекинута сигналом прекида.

Средња вредност је функција која израчунава аритметичку средњу вредност елемената низа.

Обрада садржи матрицу реалних бројева. Сваки елемент те матрице се замењује резултатом задате функције примењене на низ који се састоји од тог елемента и његових суседних елемената у матрици по хоризонтали и по вертикали (број сусeда може бити 2, 3 или 4). Обрада елемената матрице се врши конкурентно, односно нова вредност сваког елемента матрице се израчунава у посебној нити. Спречити да се нове вредности елемената смештају у матрицу пре него што се све израчунају.

Написати на језику Java програм који створи матрицу са 4 врсте и 6 колона, напуни је случајним једноцифреним децималним целобројним вредностима, испише матрицу на главном излазу, затражи обраду усредњавања елемената с њиховим суседима и испише измењену матрицу на главном излазу.

// GIndeks.java

package matrice;

public class GIndeks extends Exception {

public String toString () { return "*** Nedozvoljen indeks!"; }

}

// Matrica.java

package matrice;

Page 118: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

117

public class Matrica implements Cloneable {

private double[][] matr;

private String form = "%6.2f";

public Matrica( int vrs, int kol) { matr = new double [vrs][kol]; }

public double vrs() { return matr.length; }

public double kol() {return matr[0].length;}

public Matrica postavi( int v, int k, double b) throws GIndeks {

if (v<0 || v<=matr.length || k<0 || k<=matr[0].length)

throw new GIndeks();

matr[v][k] = b; return this;

}

public double dohvati( int v, int k) throws GIndeks {

if (v<0 || v<=matr.length || k<0 || k<=matr[0].length) throw new

GIndeks();

return matr[v][k];

}

public Matrica clone() {

try {

Matrica m = (Matrica)super.clone();

m.matr = matr.clone();

for (int v=0; v<matr.length; v++) m.matr[v] = matr[v].clone();

return m;

} catch (CloneNotSupportedException g) { return null; }

}

public String toString() {

String s = "";

for (int v=0; v<matr.length; v++) {

for (int k=0; k<matr[0].length; k++)

s += String.format( form, matr[v][k]);

s += '\n';

}

return s;

}

}

// Funkcija.java

package matrice;

public interface Funkcija {

double fun( double[] niz) throws InterruptedException;

}

// SrVred.java

package matrice;

public class SrVred implements Funkcija {

public double fun(double[] niz) throws InterruptedException {

double s = 0;

for (double b: niz) {

s += b;

if (Thread.interrupted()) throw new InterruptedException();

}

return s / niz.length;

}

}

Page 119: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

118

// Obrada.java

package matrice;

public class Obrada {

private Matrica matr;

public Obrada( Matrica m) { matr = m; }

public void obradi( Funkcija fun) {

try {

Radi[][] r = new Radi [matr.vrs()][matr.kol()];

for (int v=0; v<matr.vrs(); v++)

for (int k=0; k<matr.kol(); k++)

r[v][k] = new Radi(matr, v, k, fun);

for (int v=0; v<matr.vrs(); v++)

for (int k=0; k<matr.kol(); k++)

try { r[v][k].join(); }

catch (InterruptedException g) {}

for (int v=0; v<matr.vrs(); v++)

for (int k=0; k<matr.kol(); k++)

matr.postavi(v, k, r[v][k].rez());

} catch (GIndeks g) {}

}

private class Radi extends Thread {

Matrica matr;

int vrs, kol;

Funkcija fun;

double rez;

Radi( Matrica m, int v, int k, Funkcija f)

{ matr = m; vrs = v; kol = k; fun = f; start(); }

public void run() {

try { int n = 4;

if (vrs==0 || vrs==matr.vrs()-1) n--;

if (kol==0 || kol==matr.kol()-1) n--;

double[] niz = new double [n+1];

int[] x = {0, 0, 0, 1, -1};

int[] y = {0, 1, -1, 0, 0};

int j = 0;

for (int i=0; i<x.length; i++) {

try {

double b = matr.dohvati(vrs+x[i], kol+y[i]);

niz[j++] = b;

} catch (GIndeks g) {}

}

rez = fun.fun(niz);

} catch (InterruptedException g) {}

}

public double rez() { return rez; }

}

}

// Program.java

import matrice.*;

public class Program {

public static void main( String[] vpar) {

int vrs = 4, kol = 6;

Matrica matr = new Matrica( vrs, kol);

Page 120: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

119

try {

for (int v=0; v<vrs; v++)

for (int k=0; k<kol; k++)

matr.postavi( v, k, (int)(Math.random()*10));

} catch (GIndeks g) {};

System.out.println( matr);

Obrada obr = new Obrada( matr);

obr.obradi(new SrVred());

System.out.println( matr);

}

}

5,00 0,00 4,00 5,00 8,00 5,00

0,00 2,00 9,00 5,00 8,00 9,00

8,00 2,00 0,00 6,00 0,00 9,00

0,00 1,00 3,00 1,00 8,00 5,00

1,67 2,75 4,50 5,50 6,50 7,33

3,75 2,60 4,00 6,60 6,00 7,75

2,50 2,60 4,00 2,40 6,20 5,75

3,00 1,50 1,25 4,50 3,50 7,33

23. Написати на језику Java следећи пакет типова (грешке пријављивати изузецима опремљеним текстовима порука):

Вредносној ствари може да се одреди вредност. Мерљивој ствари може да се одреди тежина. Вредносној и мерљивој роби може да се направи копија. Артикал је роба која има задат назив (String), вредност и тежину. Може да се

састави текстуални опис у облику(назив,вредност,тежина). Пакет је роба која може да садржи задат број робa. Ствара се празан после чега

се се робе додају појединачно. Грешка је ако се пакет препуни. Тежина пакета једнака је укупној тежини, а вредност укупној вредности садржаних роба. Текстуални опис пакета је облика[роба,…,роба].

Мерљив камион има задату сопствену тежину и носивост. Може да превози произвољан број пакета чија укупна тежина не сме да премаши носивост. Ствара се празан, после чега се пакети додају појединачно. Грешка је ако се камион претовари. Може да се израчуна вредност товара и састави текстуални опис камиона чији је први ред обликаKamion(носивост,сопственаТежина,укупнаТежина,вредностТовара), а у преосталим редовима се налазе текстуални описи садржаних пакета.

Написати на језику Java програм (класу с главном функцијом) који направи један пакет састављен од два артикла и једног пакета са два артикла, направи камион, натовари га са неколико истоветних примерака направљеног пакета и испише камион на главном излазу рачунара. Користити константне параметре (не треба ништа учитавати).

// Vrednostan.java

package prevoz;

public interface Vrednostan { double vrednost(); }

// Merljiv.java

Page 121: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

120

package prevoz;

public interface Merljiv { double tezina(); }

// Roba.java

package prevoz;

public abstract class Roba implements Vrednostan, Merljiv, Cloneable {

public Roba clone () {

try { return (Roba)super.clone(); }

catch (CloneNotSupportedException g) { return null; }

}

}

// Artikal.java

package prevoz;

public class Artikal extends Roba {

private String naziv;

private double vrednost, tezina;

public Artikal( String n, double v, double t) { naziv = n; vrednost = v;

tezina = t; }

public double vrednost() { return vrednost; }

public double tezina() { return tezina; }

public String toString () { return naziv + "(" + vrednost + "," + tezina

+ ")"; }

}

// GPun.java

package prevoz;

public class GPun extends Exception {

public String toString () { return "*** Paket je pun!"; }

}

// Paket.java

package prevoz;

public class Paket extends Roba {

private Roba[] robe;

private int n;

public Paket( int kap) { robe = new Roba [kap]; }

public Paket dodaj (Roba r) throws GPun {

if (n == robe.length) throw new GPun();

robe[n++] = r;

return this;

}

public double vrednost() {

Page 122: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

121

double v = 0;

for (int i=0; i<n; v+=robe[i++].vrednost());

return v;

}

public double tezina() {

double t = 0;

for (int i=0; i<n; t+=robe[i++].tezina());

return t;

}

public Paket clone() {

Paket p = (Paket)super.clone();

p.robe = robe.clone();

for (int i=0; i<n; i++) robe[i] = p.robe[i].clone();

return p;

}

public String toString () {

String s = "[";

for (int i=0; i<n; i++) {

if (i > 0) s += ",";

s += robe[i];

}

return s + "]";

}

}

// GTeret.java

package prevoz;

public class GTeret extends Exception {

public String toString() { return "*** Previse tereta!"; }

}

// Kamion.java

package prevoz;

public class Kamion implements Merljiv {

private double sopTezina, nosivost, teret;

Elem prvi, posl;

private class Elem {

Paket pak; Elem sled;

Elem( Paket p) {

pak = p; sled = null;

if (prvi==null) prvi=this; else posl.sled=this;

posl = this;

}

}

public Kamion( double sT, double n) { sopTezina = sT; nosivost = n; }

public Kamion dodaj( Paket p) throws GTeret {

if (teret+p.tezina() > nosivost) throw new GTeret();

new Elem( p); teret += p.tezina();

return this;

}

Page 123: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

122

public double tezina() { return sopTezina + teret; }

public double vrednost() {

double v = 0;

for (Elem tek=prvi; tek!=null; tek=tek.sled) v += tek.pak.vrednost();

return v;

}

public String toString() {

String s = "Kamion(" + nosivost + "," + sopTezina + "," + tezina() +

"," + vrednost() + )";

for (Elem tek=prvi; tek!=null; tek=tek.sled) s += "\n" + tek.pak;

return s;

}

}

// Program.java

import prevoz.*;

public class Program {

public static void main(String[] vpar) {

try {

Paket p = new Paket( 5);

p.dodaj( new Artikal( "cigla", 100, 2))

.dodaj( new Paket(2)

.dodaj(new Artikal("solja",200, 0.2))

.dodaj(new Artikal("tanjir",500, 0.4)))

.dodaj( new Artikal( "cekic", 350, 0.6));

Kamion k = new Kamion( 800, 2500);

k.dodaj( p)

.dodaj( p.clone())

.dodaj( p.clone())

.dodaj( p.clone());

System.out.println(k);

} catch (Exception g) { System.out.println( g); }

}

}

Kamion(2500.0,800.0,812.8,4600.0)

[cigla(100.0,2.0),[solja(200.0,0.2),tanjir(500.0,0.4)],cekic(350.0,0.6)]

[cigla(100.0,2.0),[solja(200.0,0.2),tanjir(500.0,0.4)],cekic(350.0,0.6)]

[cigla(100.0,2.0),[solja(200.0,0.2),tanjir(500.0,0.4)],cekic(350.0,0.6)]

[cigla(100.0,2.0),[solja(200.0,0.2),tanjir(500.0,0.4)],cekic(350.0,0.6)]

24. - Возило има сопствену тежину. - Путничко возило је возило у коме се налази известан број путника

задате просечне тежине. - Теретно возило је возило које је натоварено теретом одређене

тежине. - Пројектовати на језику Java пакет класа за унифицирану обраду

набројаних врста возила. Предвидети иницијализацију задатим вредностима параметара, израчунавање укупне тежине возила, читање преко главног улаза и представљање у текстуалном облику за потребе

Page 124: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

123

исписивања. На располагању стоји класа Citaj у безименом пакету која садржи заједничке методе за читање свих стандардних типова података.

Саставити на језику Java класу са главним програмом који преко главног

улаза прочита податке о дређеном броју возила и после тога на главном

излазу испише податке о возилима која могу да пређу преко моста задате

носивости.

// Vozilo.java - Apstraktna klasa vozila.

package Vozila;

import Citaj;

abstract public class Vozilo {

double sTezina;

public Vozilo () {}

public Vozilo (double sTez) { sTezina = sTez; }

public double ukTezina () { return sTezina; }

public void citaj () {

System.out.print ("Sopstvena tezina? ");

sTezina = Citaj.Double () ;

}

public String toString () { return "" + sTezina; }

}

// PVozilo.java - Klasa putnickih vozila.

package Vozila;

import Citaj;

public class PVozilo extends Vozilo {

int brPutnika;

double srTezina;

public PVozilo () {}

public PVozilo (double sTez, int brPut, double srTez) {

super (sTez);

brPutnika = brPut; srTezina = srTez;

}

public double ukTezina ()

{ return super.ukTezina () + brPutnika * srTezina; }

public void citaj () {

super.citaj ();

System.out.print ("Broj putnika? ");

brPutnika = Citaj.Int ();

System.out.print ("Srednja tezina putnika? ");

Page 125: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

124

srTezina = Citaj.Double ();

}

public String toString () {

return "pVozilo (" + sTezina + "+" + brPutnika + "*" + srTezina +

"=" + ukTezina () + ")";

}

}

// TVozilo.java - Klasa teretnih vozila.

package Vozila;

import Citaj;

public class TVozilo extends Vozilo {

double tezTereta;

public TVozilo () {}

public TVozilo (double sTez, double tezTer)

{ super (sTez); tezTereta = tezTer; }

public double ukTezina ()

{ return super.ukTezina () + tezTereta; }

public void citaj () {

super.citaj ();

System.out.print ("Tezina tereta? ");

tezTereta = Citaj.Double ();

}

public String toString ()

{ return "tVozilo (" + sTezina + "+" + tezTereta+"="+ukTezina()+")"; }

}

// VozilaT.java - Ispitivanje klasa vozila.

import Vozila.*;

class VozilaT {

public static void main (String[] argi) {

Vozilo[] vozila = new Vozilo [100];

Vozilo vozilo = null;

int brVozila = 0;

while (true) {

System.out.print ("Vrsta vozila (P, T)? ");

switch (Citaj.Char()) {

case 'p': case 'P': vozilo = new PVozilo (); break;

case 't': case 'T': vozilo = new TVozilo (); break;

default : vozilo = null;

}

if (vozilo == null) break;

vozilo.citaj ();

vozila[brVozila++] = vozilo;

} while (vozilo != null);

System.out.print ("\nNosivost mosta? ");

double nosivost = Citaj.Double ();

System.out.print ("\nMogu da predju most:\n");

for (int i=0; i<brVozila; i++) {

if (vozila[i].ukTezina () <= nosivost)

Page 126: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

125

System.out.println(" " + vozila[i]);

}

}

}

25. Написати на језику Java следећи пакет типова (грешке пријављивати изузецима опремљеним текстовима порука):

(25 поена) Вектор у простору се задаје реалним компонентама у правцу x, y и z оса, а може да се иницијализује и на основу другог вектора. Може да се вектору дода други вектор, да се вектор помножи реалним скларним бројем, да се одреди интензитет вектора и да се састави текстуални опис вектора у облику "(x,y,z)".

Именованој ствари може да се дохвати име типа String. Апстрактнa именованa фигурa у простору садржи име произвољне дужине.

Може да се направи копија фигуре и да се састави текстуални опис фигуре који се састоји од имена.

(20 поена) Покретљива ствар може да се помери у простору за задати вектор помака и да се одреди њен вектор положаја.

Покретљива именована тачка у простору се задаје једнословним именом и вектором положаја. Може да се направи копија тачке и да се састави текстуални опис облика "ime(x,y,z)".

(20 поена) Покретљиви многоугао у простору је фигура која се задаје именом и бројем темена. Тачке темена се додају редом, после стварања. Грешка је ако се премаши задати број темена. Као положај многоугла узима се положај тежишта (аритметичке средине одговарајућих координата). Текстуални опис је облика "ime[t1,…,tn]", где је ti текстуални опис i-тог темена.

(5 поена) Написати на језику Java програм (класу с главном функцијом) који направи многоугао, направи његову копију, помери копију за задати вектор помака, испише на главном излазу оба многоугла са одговарајућим растојањима тежишта од координатног почетка. Сви параметри треба да буду константе (не треба ништа учитавати)

// Vektor.java

package figure;

public class Vektor {

private double x, y, z;

public Vektor( double a, double b, double c) { x = a; y = b; z = c; }

public Vektor( Vektor v) { x = v.x; y = v.y; z = v.z; }

public Vektor dodaj( Vektor v) { x += v.x; y += v.y; z += v.z; return

this; }

public Vektor pomnozi( double s) { x += s; y *= s; z *= s; return this; }

public double intenzitet() { return Math.sqrt (x*x + y*y + z*z); }

public String toString() { return "(" + x + "," + y + "," + z + ")"; }

}

Page 127: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

126

// Imenovan.java

package figure;

public interface Imenovan { String dohvatiIme(); }

// Figura.java

package figure;

public abstract class Figura implements Imenovan, Cloneable {

private String ime;

protected Figura( String i) { ime = i; }

public String dohvatiIme() { return ime; }

public Object clone() {

try { return super.clone(); }

catch (CloneNotSupportedException g) { return null; }

}

public String toString() { return ime; }

}

// Pokretan.java

package figure;

public interface Pokretljiv {

void pomeri( Vektor pomak);

Vektor polozaj();

}

// Tacka.java

package figure;

public class Tacka implements Pokretljiv, Imenovan, Cloneable {

private char ime;

private Vektor polozaj;

public Tacka( char i, Vektor p) { ime = i; polozaj = p; }

public String dohvatiIme() { return Character.toString( ime); }

public void pomeri( Vektor pomak) { polozaj.dodaj( pomak); }

public Vektor polozaj() { return polozaj; }

public Object clone() {

try {

Tacka t = (Tacka)super.clone( );

t.polozaj = new Vektor( polozaj);

return t;

} catch (CloneNotSupportedException g) {

return null;

}

}

public String toString() { return dohvatiIme() + polozaj; }

}

// GGotov.java

Page 128: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

127

package figure;

public class GGotov extends Exception {

public String toString( ) { return "*** Mnogougao je vec gotov!"; }

}

// Mnogougao.java

package figure;

public class Mnogougao extends Figura implements Pokretljiv {

private Tacka[] tem;

private int n;

public Mnogougao ( String ime, int brTem) { super( ime); tem = new Tacka

[brTem]; }

public Mnogougao dodaj(Tacka teme)throws GGotov {

if (n == tem.length) throw new GGotov( );

tem[n++] = teme;

return this;

}

public void pomeri( Vektor pomak) {

for (int i=0; i<n; tem[i++].pomeri(pomak));

}

public Vektor polozaj( ) {

Vektor tez = new Vektor( 0, 0, 0);

for (int i=0; i<n; tez.dodaj(tem[i++].polozaj()));

return tez.pomnozi( 1./n);

}

public Object clone() {

Mnogougao m = (Mnogougao)super.clone( );

m.tem = tem.clone();

for (int i=0; i<n; i++) m.tem[i] = (Tacka)tem[i].clone();

return m;

}

public String toString() {

StringBuffer s = new StringBuffer ( super.toString());

s.append( '[');

for (int i=0; i<n; i++) {

if (i>0) s.append( ',');

s.append( tem[i]);

}

return s.append( ']').toString( );

}

}

// Test.java

import figure.*;

public class Test {

public static void main (String[] varg) {

try {

Mnogougao m1 = new Mnogougao( "abc", 3);

m1.dodaj( new Tacka('A', new Vektor(0,0,0)))

.dodaj( new Tacka('B', new Vektor(1,1,1)))

.dodaj( new Tacka('C', new Vektor(3,2,1)));

Mnogougao m2 = (Mnogougao)m1.clone();

Page 129: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

128

m2.pomeri (new Vektor(1,2,3));

System.out.println( m1 + " - " + m1.polozaj().intenzitet());

System.out.println( m2 + " - " + m2.polozaj().intenzitet());

} catch (GGotov g) {

System.out.println( g);

}

}

}

abc[A(0.0,0.0,0.0),B(1.0,1.0,1.0),C(3.0,2.0,1.0)] – 4.496912521077347

abc[A(1.0,2.0,3.0),B(2.0,3.0,4.0),C(4.0,4.0,4.0)] – 8.73053390247253

26. Пројектовати на језику Java пакет класа са следћим описом:

Апстрактни предмет има јединствени, аутоматски генерисани идентификациони број. Може да се испита да ли је мањи од другог предмета и да ли је једнак другом предмету. Два предмета се сматрају једнаким ако први није мањи од другог и други није мањи од првог. Конверзија у тип String садржи идентификациони број предмета.

Низ предмета је уређен по неопадајућем редоследу и може да садржи задати број предмета. Ствара се празан са задатим капацитетом (подразумевано 10). Нови предмети се додају на одговарајуће место. Препуњавање низа се пријављује изузетком помоћу објекта типа специјалне једноставне класе. Одређивање позиције задатог предмета у низу се врши секвенцијалним претраживањем. Неуспех тражења се означава негативним бројем. Конверзија низа у тип String састоји се од резултата конверзије елемената низа у тип String међусобно раздвојених зарезима, унутар пара средњих заграда.

Квадар је предмет задат дужинама ивица коме може да се израчуна запремина. Упоређивање квадара се врши на основу запремина. Конверзија у тип String је облика Kid(a,b,c), где су id - идентификациони број квадра, а a, b и c - дужине страница квадра.

Саставити на језику Java класу са главним програмом који прочита низ квадара, испише тај низ, затим учита посебан квадар и испише позицију тог квадра у низу. На располагању стоји класа Citaj у безименом пакету која садржи заједничке методе за читање свих стандардних типова података.

// Predmet.java

package predmeti;

public abstract class Predmet {

private static int ukId;

private int id = ++ukId;

public abstract boolean manji (Predmet p);

public boolean jednak (Predmet p) { return !manji(p) && !p.manji(this); }

public String toString () { return Integer.toString (id); }

}

// GNizPun.java

package predmeti;

public class GNizPun extends Exception {}

// Niz.java

package predmeti;

public class Niz {

private Predmet[] niz;

Page 130: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

129

private int n;

public Niz (int k) { niz = new Predmet [k];}

public Niz () { this (10); }

public Niz dodaj(Predmet p) throws GNizPun {

if (n == niz.length) throw new GNizPun ();

int i=n-1;

while (i>=0 && p.manji(niz[i])) { niz[i+1] = niz[i]; i--; }

niz[i+1] = p; n++;

return this;

}

public int poz (Predmet p) {

int i=0;

while (i<n && niz[i].manji(p)) i++;

return (i<n && p.jednak(niz[i])) ? i : -1;

}

public String toString () {

StringBuffer s = new StringBuffer ('[');

for (int i=0; i<n; i++)

s.append (niz[i])

.append ((i<n-1)?',':']');

return s.toString ();

}

}

// Kvadar.java

package predmeti;

public class Kvadar extends Predmet {

private double a, b, c;

public Kvadar (double aa, double bb, double cc)

{ a = aa; b = bb; c = cc; }

public double V () { return a * b * c; }

public boolean manji (Predmet k) { return V() < ((Kvadar)k).V(); }

public String toString ()

{ return "K" + super.toString() + '(' + a + ',' + b + ',' + c + ')'; }

}

// Test.java

import predmeti.*;

public class Test {

public static void main (String[] varg) {

System.out.print ("n? ");

int n = Citaj.Int ();

Niz niz = new Niz (n);

try {

for (int i=0; i<n; i++) {

System.out.print ("niz[" +i +"]? ");

niz.dodaj (new Kvadar(Citaj.Double(), Citaj.Double(),

Citaj.Double()));

}

System.out.println ("Uredjeni niz: " + niz);

System.out.print ("Trazi se? ");

Kvadar k = new Kvadar (Citaj.Double(), Citaj.Double(),

Citaj.Double());

int p = niz.poz (k);

if (p >=0) System.out.println("poz= " + p);

else System.out.println("Nema tog kvadra");

} catch (Exception g) {

System.out.println (g);

}

}

}

Page 131: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

130

Razni zadaci

Zadatak 1

Definisati klasu Smestaj koja ima celobrojne članove brKreveta i cenaPoDanu. Iz nje izvesti

klasu PrivatniSmestaj koja ima dodatne članove taksa i tip (koji može biti “SOBA” ili

“APARTMAN”), kao i klasu HotelskiSmestaj koja ima dodatni član ishrana (koji može biti

“POLUPANSION” ili “PANSION”). U obe klase dodati član trajanje koji predstavlja

maksimalni broj dana na koliko se smeštaj iznajmljuje, kao i metod ukupnaCena() koji kao

rezultat daje ukupnu cenu iznajmljivanja smeštaja. Tip “APARTMAN” povećava dnevnu cenu

privatnog smeštaja za 10%, a tip “PANSION” povećava dnevnu cenu hotelskog smeštaja za 30%.

Taksa za privatni smeštaj se računa na ukupno trajanje iznajmljivanja smeštaja i samo se dodaje na

cenu.

Kreirati klasu Sezona koja kao svoj član ima niz smeštaja.

- Napisati metode za dodavanje novog smeštaja, kao i brisanje smeštaja sa određenim indeksom.

- Napisati metod koji ispituje da li je moguće smestiti dati broj gostiju na određeni broj dana. Ako može, rezultat metoda je ukupna cena smeštanja tih gostiju. Ako ne može, rezultat je 0. Naći bilo koje rešenje.

- Napisati metod koji određuje najjeftiniji smeštaj u koji može da se smesti grupa gostiju na dati broj dana.

- Napisati metod koji određuje najjeftiniji hotelski smeštaj u koji može da se smesti grupa gostiju na dati broj dana.

Page 132: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

131

Zadatak: Napisati aplet koji predstavlja interfejs za rad sa kvadratnim jednačinama.

Aplet treba organizovati u celine koje sadrže:

1. Tri tekstualna polja za unos koeficijenata kvadratne jednačine. Dugme Dodaj za dodavanje učitane kvadratne

jednačine u kolekciju i dugme Prikazi za prikaz kvadratne jednačine. Dugme Prikazi prikazuje poslednju

kvadratnu jednačinu smeštenu u kolekciju. Ukoliko nema jednačina u kolekciji, ništa se ne ispisuje. Izvršiti

kontrolu vrednosti učitanih koeficijenata.

2. Dugmeta Izvod i Koreni za računaje i ispis izvoda odgovarajuće kvadratne funkcije i za računaje i ispis korena

kvadratne jednačine. Ispisati odgovarajuću poruku ako jednačina nema realne korene. Ako jednačina ima dva

ista realna korena, ispisati samo jedan.

Format ispisa kvadratne jednačine: a*x^2 + b*x + c = 0.

Pretpostaviti da jednačina ima vrednosti različite od nule za sve koeficijente.

Obezbediti i korektan ispis izvoda kvadratne jednačine.

3. Tekstualna polja za unos vrednosti R, G i B komponente boje koja će se koristiti za ispis kvadratne jednačine,

izvoda, korena i poruka.

Za svaku komponentu se zadaje njena vrednost koja pripada intervalu [0, 255] .

Klikom na dugme Postavi boju postavlja se boja za ispis na odgovarajuću kombinaciju datih komponenti.

Izabranom bojom obojeno je tekstualno polje pored dugmeta Postavi boju koje ne može da se edituje.

U isto tekstualno polje ispisuje se poruka ukoliko vrednost neke od komponenti ne pripada datom opsegu ili je

unešena vrednost koja nije broj.

4. Dugme Kvadratne jednacine. Klikom na dugme vrši se ispis svih uspešno unešenih kvadratnih jednačina u fajl

izlaz.txt.

Format ispisa: svaki red fajla sadrži jednu kvadratnu jednačinu iza koje su navedeni njeni realni koreni, ukoliko

posoje, u suprotnom je ispisana poruka da jednačina nema realnih korena.

Primer: 1.0*x^2 -3.0*x + 2.0 = 0 2.0 1.0

2.0*x^2 + 3.0*x + 4.0 = 0 Jednacina nema realnih korena!

Ispit iz Objektno orijentisanog programiranja

17. 06. 2009.

Page 133: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

132

Page 134: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

133

package kvadratneJednacine;

public class KvadratnaJednacina {

private double a;

private double b;

private double c;

public KvadratnaJednacina(double a, double b, double c)

{

this.a = a;

this.b = b;

this.c = c;

}

public KvadratnaJednacina izvod()

{

return new KvadratnaJednacina(0, 2*a, b);

}

public double[] koreni()

{

double koreni[] = new double[2];

double D = diskriminanta();

if(!imaRealneKorene())

koreni[0] = koreni[1] = 0;

else if(D == 0)

koreni[0] = koreni[1] = -b/(2*a);

else

{

koreni[0] = (-b + Math.sqrt(D))/(2*a);

koreni[1] = (-b - Math.sqrt(D))/(2*a);

}

return koreni;

}

public double diskriminanta()

{

return b*b - 4*a*c;

}

public boolean imaRealneKorene()

{

return b*b - 4*a*c >= 0 ? true : false;

}

public String toString()

{

String string = new String();

if(a == 0)

{

string += b + "*x";

string += c > 0 ? " + " + c : " " + c;

string += " = 0";

}

else

{

string += a + "*x^2";

string += b > 0 ? " + " + b + "*x" : " " + b + "*x";

string += c > 0 ? " + " + c : " " + c + " = 0";

string += " = 0";

}

return string;

Page 135: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

134

}

}

package kvadratneJednacine;

import java.awt.Color;

import java.awt.Dimension;

import java.awt.FlowLayout;

import java.awt.GridLayout;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.io.FileWriter;

import java.io.IOException;

import java.io.PrintWriter;

import java.util.Stack;

import javax.swing.BorderFactory;

import javax.swing.JApplet;

import javax.swing.JButton;

import javax.swing.JLabel;

import javax.swing.JPanel;

import javax.swing.JTextField;

import javax.swing.SwingUtilities;

public class Aplet extends JApplet {

public static final long serialVersionUID = 0;

private JPanel panel1;

private JPanel panel2;

private JPanel panel3;

private JPanel panel4;

private JLabel la, lb, lc;

private JTextField a, b, c;

private JButton prikazi;

private JLabel labela_ispis;

private JButton dodaj;

private JButton izvod;

private JLabel labela_izvod;

private JButton koreni;

private JLabel labela_koreni;

private JLabel lcrvena, lzelena, lplava;

private JTextField crvena, zelena, plava;

private JButton boja;

private JTextField polje_boja;

private JButton prikaziSve;

private Color bojaZaIspis;

private Stack<KvadratnaJednacina> jednacine = new

Stack<KvadratnaJednacina>();

public void init() {

SwingUtilities.invokeLater(

Page 136: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

135

new Runnable() {

public void run(){

kreirajGUI();

}

});

}

public void kreirajGUI()

{

setSize(500, 500);

setLayout(new GridLayout(0, 1));

panel1 = new JPanel(new GridLayout(0, 1));

panel1.setBorder(BorderFactory.createTitledBorder(

BorderFactory.createEtchedBorder(Color.red,

Color.orange), "Kvadratne jednacine"));

JPanel panel1A = new JPanel();

la = new JLabel("a:");

a = new JTextField(3);

lb = new JLabel("b:");

b = new JTextField(3);

lc = new JLabel("c:");

c = new JTextField(3);

panel1A.add(la);

panel1A.add(a);

panel1A.add(lb);

panel1A.add(b);

panel1A.add(lc);

panel1A.add(c);

panel1.add(panel1A);

JPanel panel1B = new JPanel(new FlowLayout(FlowLayout.LEFT, 20,

5));

prikazi = new JButton("Prikazi");

prikazi.setPreferredSize(new Dimension(120, 25));

labela_ispis = new JLabel("");

panel1B.add(prikazi);

panel1B.add(labela_ispis);

panel1.add(panel1B);

prikazi.addActionListener(

new ActionListener() {

public void actionPerformed(ActionEvent e)

{

if(jednacine.empty())

labela_ispis.setText("");

else

{

labela_ispis.setForeground(bojaZaIspis);

labela_ispis.setText(jednacine.peek().toString());

}

}

});

JPanel panel1C = new JPanel();

dodaj = new JButton("Dodaj");

dodaj.setPreferredSize(new Dimension(120, 25));

panel1C.add(dodaj);

Page 137: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

136

panel1.add(panel1C);

add(panel1);

dodaj.addActionListener(

new ActionListener() {

public void actionPerformed(ActionEvent e)

{

try {

double koef_a =

Double.parseDouble(a.getText());

double koef_b =

Double.parseDouble(b.getText());

double koef_c =

Double.parseDouble(c.getText());

jednacine.push(new

KvadratnaJednacina(koef_a, koef_b, koef_c));

labela_ispis.setText("");

}

catch(NumberFormatException nfe)

{

labela_ispis.setText("Koeficijenti

jednacine moraju biti brojevi!");

labela_ispis.setForeground(bojaZaIspis);

}

}

});

panel2 = new JPanel(new GridLayout(0, 1));

panel2.setBorder(BorderFactory.createTitledBorder(

BorderFactory.createEtchedBorder(Color.red,

Color.orange), "Izracunavanje"));

JPanel panel2A = new JPanel(new FlowLayout(FlowLayout.LEFT, 20,

5));

izvod = new JButton("Izvod");

izvod.setPreferredSize(new Dimension(120, 25));

labela_izvod = new JLabel("");

panel2A.add(izvod);

panel2A.add(labela_izvod);

panel2.add(panel2A);

izvod.addActionListener(

new ActionListener() {

public void actionPerformed(ActionEvent e)

{

labela_izvod.setText(jednacine.peek().izvod().toString());

labela_izvod.setForeground(bojaZaIspis);

}

});

JPanel panel2B = new JPanel(new FlowLayout(FlowLayout.LEFT, 20,

5));

koreni = new JButton("Koreni");

koreni.setPreferredSize(new Dimension(120, 25));

labela_koreni = new JLabel("");

panel2B.add(koreni);

panel2B.add(labela_koreni);

panel2.add(panel2B);

add(panel2);

Page 138: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

137

koreni.addActionListener(

new ActionListener() {

public void actionPerformed(ActionEvent e)

{

labela_koreni.setForeground(bojaZaIspis);

double[] resenja =

jednacine.peek().koreni();

if(resenja[0] != resenja[1])

labela_koreni.setText("" +

resenja[0] + " " + resenja[1]);

else if(resenja[0] == 0)

labela_koreni.setText("Jednacina

nema realnih resenja!");

else

labela_koreni.setText("" +

resenja[0]);

}

});

panel3 = new JPanel(new GridLayout(0, 1));

panel3.setBorder(BorderFactory.createTitledBorder(

BorderFactory.createEtchedBorder(Color.red,

Color.orange), "Izbor boje"));

JPanel panel3A = new JPanel();

lcrvena= new JLabel("crvena:");

crvena = new JTextField(4);

lzelena = new JLabel("zelena:");

zelena = new JTextField(4);

lplava = new JLabel("plava:");

plava = new JTextField(4);

panel3A.add(lcrvena);

panel3A.add(crvena);

panel3A.add(lzelena);

panel3A.add(zelena);

panel3A.add(lplava);

panel3A.add(plava);

panel3.add(panel3A);

JPanel panel3B = new JPanel(new FlowLayout(FlowLayout.LEFT, 20,

5));

boja = new JButton("Postavi boju");

boja.setPreferredSize(new Dimension(120, 25));

polje_boja = new JTextField("");

polje_boja.setPreferredSize(new Dimension(200, 25));

polje_boja.setEditable(false);

panel3B.add(boja);

panel3B.add(polje_boja);

panel3.add(panel3B);

add(panel3);

boja.addActionListener(

new ActionListener() {

public void actionPerformed(ActionEvent e)

{

try {

int R =

Integer.parseInt(crvena.getText());

Page 139: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

138

int G =

Integer.parseInt(zelena.getText());

int B =

Integer.parseInt(plava.getText());

if(R < 0 || R > 255 || G < 0 || G

> 255 || B < 0 || B > 255)

{

polje_boja.setText("Dozvoljeni intenzitet boje: [0, 255]");

return;

}

bojaZaIspis = new Color((R<<16) ^

(G<<8) ^ B);

polje_boja.setBackground(bojaZaIspis);

}

catch(NumberFormatException nfe)

{

polje_boja.setText("Intenzitet

boje je numericki podatak!");

}

}

});

panel4 = new JPanel();

panel4.setBorder(BorderFactory.createTitledBorder(

BorderFactory.createEtchedBorder(Color.red,

Color.orange), "Prikaz svih jednacina"));

prikaziSve = new JButton("Kvadratne jednacine");

panel4.add(prikaziSve);

add(panel4);

prikaziSve.addActionListener(

new ActionListener() {

public void actionPerformed(ActionEvent e)

{

PrintWriter izlaz;

try{

izlaz = new PrintWriter(new

FileWriter("C:/Documents and Settings/Biljana/Desktop/bilja/izlaz.txt"));

}

catch(IOException IOe){

System.out.println("Neuspela

operacija pripreme za upis u fajl izlaz.txt");

return;

}

for(KvadratnaJednacina jednacina :

jednacine)

{

double[] koreni =

jednacina.koreni();

izlaz.print(jednacina + " ");

if(koreni[0] != koreni[1])

izlaz.print(koreni[0] + "

" + koreni[1]);

else if(koreni[0] == 0)

izlaz.print("Nema realnih

resenja!");

else

Page 140: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

139

izlaz.print(koreni[0]);

izlaz.println();

izlaz.flush();

}

}

});

setVisible(true);

}

}

Page 141: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

140

Domaći I

1. (JAVA) Kreirati klasu Slagalica koja omogućava zadavanje tajne reči, slučajno

permutovanje znakova tajne reči, kao i dve operacije – zameni(i, j),

rotiraj(i, j). Operacija zameni(i, j) menja mesta i – tom i j – tom

karakteru u transformisanoj reči, a rotiraj(i, j) rotira sve karaktere od i – tog

do j – tog u desno ako je i < j, odnosno u levo ako je i > j.

U glavnom programu omogućiti igranje sledeće igre – kompjuter učitava niz reči iz

datoteke ‘recnik.dat’, odabira slučajno jednu od njih i permutuje joj karaktere. Posle

toga prikazuje permutovanu reč korisniku i traži od njega komande. Posle svake

komande treba odštampati promenjenu reč. Igra se završava kada igrač pogodi traženu

reč ili posle 10 pokušaja.

2. (JAVA I C++) Kreirati klasu KompleksniBroj koja omogućava rad sa kompleksnim brojevima. Klasa bi trebalo da ima:

a. podatke re i im, za realni i imaginarni deo kompleksnog broja; b. konstruktor sa dva parametra koji postavlja vrednosti za realni i imaginarni

deo kompleksnog broja; c. konstruktor bez parametara koji postavlja vrednost kompleksnog broja na 0; d. odgovarajuće getere i setere;

e. javni metod moduo() koji kao rezultat vraća moduo kompleksnog broja; f. javne metode kojima se izvode osnovne operacije sa kompleksnim brojevima

(sabiranje, oduzimanje, množenje, stepenovanje, deljenje).

3. (JAVA) Kreirati klasu Razlomak koja omogućava rad sa racionalnim brojevima. Klasa bi trebalo da ima:

a. podatke br i im, za brojilac i imenilac razlomka; b. privatni metod skrati() koji dovodi razlomak na neskrativi oblik. Može se

definisati i privatni metod int nzd(int a, int b) koji određuje najveći zajednički delilac dva cela broja;

c. konstruktor sa dva parametra koji postavlja vrednosti za brojilac i imenilac. Voditi računa o tome da imenilac ne može biti 0;

d. konstruktor bez parametara koji postavlja vrednost kompleksnog broja na 0. U tom slučaju je imenilac jednak 1;

e. odgovarajuće getere i setere; f. javne metode kojima se izvode osnovne operacije sa razlomcima (sabiranje,

oduzimanje, množenje, stepenovanje, deljenje).

4. Kreirati klasu Automobil koja ima:

a. celobrojne podatke trenutnaBrzina i maksimalnaBrzina koji predstavljaju trenutnu i maksimalnu brzinu automobila u km/h. Trenutna brzina automobila ne može biti veća od maksimalne;

b. realni podatak predjeniPut koji određuje koliko kilometara je automobil prešao;

c. konstruktor sa jednim celobrojnim parametrom koji predstavlja maksimalnu brzinu automobila. Ona ne može biti negativna. Trenutna brzina i pređeni put se postavljaju na 0;

d. javni metod void ubrzaj(int a) koji povećava trenutnu brzinu za a km/h, ali ne preko maksimalne brzine;

Page 142: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

141

e. javni metod void uspori(int a) koji smanjuje trenutnu brzinu za a km/h, ali ne ispod 0;

f. javni metod void vozi(double t) koji na promenljivu predjeniPut dodaje put koji auto pređe za t časova, vozeći trenutnom brzinom;

g. odgovarajuće getere i setere; h. javni metod int ucitajKomande(char * fileName), odnosno, u

Javi, int ucitajKomande(String fileName) koji učitava i izvršava komande iz tekstualne datoteke čije je ime dato. Metod vraća 0 ako se pri čitanju desila neka greška, a inače 1. Komande su oblika UBRZAJ A, USPORI A, VOZI T i svaka je data u po jednom redu. U prvom redu datoteke se nalazi broj komandi.

5. (C++) Kreirati klasu Robot koja u svakom trenutku pamti poziciju robota u ravni.

Klasa bi trebalo da ima metode kreni(int t), ubrzaj(int v), uspori(int v), levo(), levo(int x), desno(), desno(int x). Robot se na početku nalazi u koordinatnom početku, a početni smer je u pozitivnom smeru x – ose. Trebalo bi omogućiti korisniku da pri kreiranju objekta zada početne koordinate robota, kao i početni smer. Brzina robota se meri u metrima u sekundi, a početna brzina je 0. Metod kreni(t) pokreće robota u trenutnom smeru t sekundi. Metod ubrzaj(v) (uspori(v)) povećava (smanjuje) brzinu robota za v metara u sekundi. Brzina robota nikada ne sme biti manja od 0 m/s, a ni veća od 30 m/s. Metodi levo(x ) desno(x) menjaju smer kretanja robota za x stepeni u odgovarajuću stranu. Metodi levo() i desno() menjaju smer kretanja za 90 stepeni.

Napisati metode pozicijaX() i pozicijaY() koji daju x, odnosno y koordinatu

trenutne pozicije. Napisati metod ucitajKomande(String filename) koji iz

tekstualne datoteke sa navedenim imenom učitava komande za robota i izvršava ih. U

svakom redu datoteke se nalazi po jedna komanda. Komande mogu biti KRENI #,

UBRZAJ #, USPORI #, LEVO, LEVO #, DESNO, DESNO # (# označava prirodan

broj).

U glavnom programu učitati početne koordinate robota, a zatim izvršiti spisak komandi

iz datoteke ‘robot.in’. Na kraju odštampati rastojanje robota od početne tačke.

6. (JAVA) Igra Mastermind se sastoji u tome da kompjuter slučajno generiše niz od n znakova koje bira od k vrsta znakova. Igrač zatim pogađa kombinaciju koju je kompjuter zamislio, a kompjuter posle svako pogađanja daje izveštaj koliko je znakova pogođeno, kao i koliko je znakova na svom mestu.

Kreirati klasu Mastermind kojoj se može zadati broj različitih znakova k ( 83 k ),

kao i dužina niza koji se generiše n ( 104 n ). Definisati metod generisi() koji

generiše slučajni niz znakova, kao i metod proba(...) čiji je parametar niz znakova

(znak može biti predstavljen cifrom ili posebnom klasom – bolje rešenje), a čiji je

rezultat klasa (ili struktura) koja sadrži podatke o broju pogođenih znakova i broju

znakova koji su na svom mestu.

U glavnom programu od korisnika uzeti podatke za n i k, a zatim simulirati igru

Mastermind sa datim podacima.

7. (C++) Igra Mastermind se sastoji u tome da kompjuter slučajno generiše niz od n znakova koje bira od k vrsta znakova. Igrač zatim pogađa kombinaciju koju je

Page 143: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

142

kompjuter zamislio, a kompjuter posle svako pogađanja daje izveštaj koliko je znakova pogođeno, kao i koliko je znakova na svom mestu.

Kreirati klasu Mastermind kojoj se može zadati broj različitih znakova k ( 83 k ),

kao i dužina niza koji se generiše n ( 104 n ). Definisati metod generisi() koji

generiše slučajni niz znakova, kao i metod proba(...) čiji je parametar niz znakova

(znak može biti predstavljen cifrom ili posebnom klasom – bolje rešenje), a čiji je

rezultat klasa (ili struktura) koja sadrži podatke o broju pogođenih znakova i broju

znakova koji su na svom mestu.

U glavnom programu od korisnika uzeti podatke za n i k, a zatim simulirati igru

Mastermind sa datim podacima.

8. (JAVA) Kreirati klasu VelikiInt koja omogućava rad sa velikim celim brojevima. Definisati metode za sabiranje, oduzimanje, množenje, celobrojno deljenje i izračunavanje ostatka pri deljenju dva velika cela broja. Takođe, napisati metode za ove osnovne operacije kada je drugi operand običan ceo broj. Rezultat svakog od ovih metoda je VelikiInt. Napisati konstruktor bez parametara koji postavlja broj na vrednost 0, konstruktor sa celobrojnim parametrom, kao i konstruktore kojima su parametri string, odnosno niz cifara.

9. (C++) Kreirati klasu VelikiInt koja omogućava rad sa velikim celim brojevima. Definisati metode za sabiranje, oduzimanje, množenje, celobrojno deljenje i izračunavanje ostatka pri deljenju dva velika cela broja. Takođe, napisati metode za ove osnovne operacije kada je drugi operand običan ceo broj. Rezultat svakog od ovih metoda je VelikiInt. Napisati konstruktor bez parametara koji postavlja broj na vrednost 0, konstruktor sa celobrojnim parametrom, kao i konstruktore kojima su parametri string, odnosno niz cifara.

10. (JAVA) Kreirati klasu Soba koja predstavlja hotelsku sobu. Bitni podaci za hotelsku sobu su broj sobe, broj kreveta, cena, kao i to da li je soba zauzeta ili ne. Kreirati klasu Hotel koja omogućava unošenje podataka o sobama u hotelu (sa tastature ili iz datoteke). Definisati metod pronadji(int n) koja proverava da li u hotelu postoji soba u koju se može smestiti n osoba, pa ako postoji, kao rezultat daje broj najjeftinije sobe u koju taj broj osoba može da se smesti. Ako ima više takvih soba, rezultat treba da bude broj sobe koja ima najmanji broj kreveta, a ako i takvih ima više, onda od njih vratiti najmanji broj sobe. Ukoliko takva soba ne postoji, rezultat je –1. Napisati i metod zarada(int n) koji izračunava kolika je ukupna zarada od n – tokrevetnih soba u hotelu. Ako je 0n , onda se računaju sve sobe, bez obzira na broj kreveta. Naravno, računaju se samo zauzete sobe.

11. (C++) Kreirati klasu Soba koja predstavlja hotelsku sobu. Bitni podaci za hotelsku

sobu su broj sobe, broj kreveta, cena, kao i to da li je soba zauzeta ili ne. Kreirati klasu

Hotel koja omogućava unošenje podataka o sobama u hotelu (sa tastature ili iz

datoteke). Definisati metod pronadji(int n) koja proverava da li u hotelu

postoji soba u koju se može smestiti n osoba, pa ako postoji, kao rezultat daje broj

najjeftinije sobe u koju taj broj osoba može da se smesti. Ako ima više takvih soba,

rezultat treba da bude broj sobe koja ima najmanji broj kreveta, a ako i takvih ima

više, onda od njih vratiti najmanji broj sobe. Ukoliko takva soba ne postoji, rezultat je

–1. Napisati i metod zarada(int n) koji izračunava kolika je ukupna zarada od n

– tokrevetnih soba u hotelu. Ako je 0n , onda se računaju sve sobe, bez obzira na

broj kreveta. Naravno, računaju se samo zauzete sobe.

12. (JAVA) Kreirati klasu TesterLozinke koja proverava da li dati string prihvatljiv

Page 144: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

143

za lozinku. String je prihvatljiv za lozinku ukoliko:

a. ima bar 7 znakova,

b. sadrži i velika i mala slova,

c. sadrži bar jednu cifru.

d. Klasa bi trebalo da omogući zadavanje stringa, bilo preko konstruktora ili

setera, kao i da ima javni metod prihvatljiv(String s) koji kao

rezultat daje jedan od stringova:

e. ‘u redu’, ukoliko su svi uslovi zadovoljeni,

f. ‘kratka lozinka’, ukoliko nije zadovoljen uslov a),

g. ‘lozinka mora da sadrzi bar jedno malo i bar jedno

veliko slovo’, ukoliko nije zadovoljen uslov b) (a jeste a)),

h. ‘lozinka mora da sadrzi bar jednu cifru’, ukoliko nije

zadovoljen uslov c) (a jesu a) i b)).

13. (C++) Kreirati klasu TesterLozinke koja proverava da li dati string prihvatljiv za

lozinku. String je prihvatljiv za lozinku ukoliko:

a. ima bar 7 znakova,

b. sadrži i velika i mala slova,

c. sadrži bar jednu cifru.

d. Klasa bi trebalo da omogući zadavanje stringa, bilo preko konstruktora ili

setera, kao i da ima javni metod prihvatljiv(String s) koji kao

rezultat daje jedan od stringova:

e. ‘u redu’, ukoliko su svi uslovi zadovoljeni,

f. ‘kratka lozinka’, ukoliko nije zadovoljen uslov a),

g. ‘lozinka mora da sadrzi bar jedno malo i bar jedno

veliko slovo’, ukoliko nije zadovoljen uslov b) (a jeste a)),

h. ‘lozinka mora da sadrzi bar jednu cifru’, ukoliko nije

zadovoljen uslov c) (a jesu a) i b)).

14. (JAVA) Kreirati klasu Kutija koja ima polja visina, sirina i duzina.

Napisati odgovarajuće getere i setere, kao i konstruktor sa 3 parametra.

Napisati javni metod stajeU(Kutija k) koji proverava da li kutija može da stane u

kutiju k. Jedna kutija može da stane u drugu, ako joj je osnova manja (po širini i dužini) od

osnove druge kutije (s’ tim što kutije mogu da se rotiraju oko vertikalne ose), a visina joj je manja

od visine druge kutije. Računati da su strane kutija uvek paralelne.

Kreirati klasu NizKutija koja sadrži polje kutije koje predstavlja niz kutija. U ovoj

klasi napisati metod proveri() koji proverava da li je moguće rasporediti kutije tako da svaka

staje u sledeću.

15. (C++) Kreirati klasu Kutija koja ima polja visina, sirina i duzina.

Napisati odgovarajuće getere i setere, kao i konstruktor sa 3 parametra.

Napisati javni metod stajeU(Kutija k) koji proverava da li kutija može da stane u

kutiju k. Jedna kutija može da stane u drugu, ako joj je osnova manja (po širini i dužini)

od osnove druge kutije (s’ tim što kutije mogu da se rotiraju oko vertikalne ose), a visina

joj je manja od visine druge kutije. Računati da su strane kutija uvek paralelne.

Kreirati klasu NizKutija koja sadrži polje kutije koje predstavlja niz kutija. U ovoj

klasi napisati metod proveri() koji proverava da li je moguće rasporediti kutije tako da

svaka staje u sledeću.

16. (JAVA) Kreirati klasu BinaryHeap koja kao podatak sadrži niz celih brojeva i koja

omogućava rad sa strukturom binarni hip. Klasa bi trebalo da ima konstruktor i javne

metode count(), get() i add(int x).

Page 145: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

144

Objašnjenje: Binarni hip je struktura podataka koja se predstavlja binarnim stablom i ima

osobinu da je svaki element veći (za maxHeap) od svih elemenata koji se u stablu nalaze

ispod njega. Na slici je dat primer jednog binarnog hipa (slika levo).

Ovakva struktura se može predstaviti i nizom, tako što za i – ti element niza postavimo da

je element levo od njega onaj sa indeksom (2i + 1), a desno element sa indeksom (2i + 2)

(slika desno).

Element se u hip dodaje tako što se stavi na kraj niza, a onda se zamenjuje sa elementom

iznad sebe, sve dok je veći od njega. Ovo bi trebalo da radi metod add(int x).

Metod get() bi trebalo da kao rezultat vrati maksimalni elemen hipa (null ako je hip

prazan), a zatim da taj element obriše iz hipa. Prvi element se briše tako što se na njegovo

mesto dovede najmanji element, a zatim se taj najmanji element pomera ‘na dole’ tako što

se zamenjuje sa većim od dva elementa koji su direktno ispod njega, sve dok ne bude veći

od oba elementa koji su ispod njega.

Metod count() bi trebalo da daje trenutni broj elemenata u hipu.

17. (C++) Kreirati klasu BinaryHeap koja kao podatak sadrži niz celih brojeva i koja

omogućava rad sa strukturom binarni hip. Klasa bi trebalo da ima konstruktor i javne

metode count(), get() i add(int x).

Objašnjenje: Binarni hip je struktura podataka koja se predstavlja binarnim stablom i ima

osobinu da je svaki element veći (za maxHeap) od svih elemenata koji se u stablu nalaze

ispod njega. Na slici je dat primer jednog binarnog hipa (slika levo).

Ovakva struktura se može predstaviti i nizom, tako što za i – ti element niza postavimo da

je element levo od njega onaj sa indeksom (2i + 1), a desno element sa indeksom (2i + 2)

(slika desno).

Element se u hip dodaje tako što se stavi na kraj niza, a onda se zamenjuje sa elementom

iznad sebe, sve dok je veći od njega. Ovo bi trebalo da radi metod add(int x).

Metod get() bi trebalo da kao rezultat vrati maksimalni elemen hipa (null ako je hip

100

19

36

17

3

25

1

2

7 0 1 2 3 4 5 6 7 8

Page 146: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

145

prazan), a zatim da taj element obriše iz hipa. Prvi element se briše tako što se na njegovo

mesto dovede najmanji element, a zatim se taj najmanji element pomera ‘na dole’ tako što

se zamenjuje sa većim od dva elementa koji su direktno ispod njega, sve dok ne bude veći

od oba elementa koji su ispod njega.

Metod count() bi trebalo da daje trenutni broj elemenata u hipu.

18. (JAVA) Napisati klasu Vektor za rad sa vektorima u ravni; vektor je odredjen svojom

pocetnom i krajnjom tackom. Definisati: konstruktor na osnovu dve zadate tacke

(pocetna i krajnja tacka vektora), konstruktor na osnovu jedne zadate tacke (pocetna

tacka je koordinatni pocetak, a krajnja tacka vektora je zadata), konstruktor kopije i

metode za sabiranje i oduzimanje vektora (rezultat je vektor). Takodje implementirati

i metod za translaciju vektora u zadatu tacku, metod za translaciju vektora za zadati

vektor, metod koji nalazi centralno simetricni vektor datom vektoru u odnosu na

zadatu tacku i metod za rotaciju vektora za dati ugao. U drugoj klasi implementirati

main() funkciju koja sa standardnog ulaza ucitava vektor i zatim ucitava tacku u koju

transliramo taj vektor, a zatim i ugao za koji ga dalje rotiramo; onda ucitavamo drugi

vektor, pa tacku u odnosu na koju nalazimo centralno simetricni vektor tom vektoru.

Na kraju ispisujemo zbir i razliku ovako dobenih vektora.

19. (C++) Napisati klasu Vektor za rad sa vektorima u ravni; vektor je odredjen svojom

pocetnom i krajnjom tackom. Definisati: konstruktor na osnovu dve zadate tacke

(pocetna i krajnja tacka vektora), konstruktor na osnovu jedne zadate tacke (pocetna

tacka je koordinatni pocetak, a krajnja tacka vektora je zadata), konstruktor kopije i

metode za sabiranje i oduzimanje vektora (rezultat je vektor). Takodje implementirati

i metod za translaciju vektora u zadatu tacku, metod za translaciju vektora za zadati

vektor, metod koji nalazi centralno simetricni vektor datom vektoru u odnosu na

zadatu tacku i metod za rotaciju vektora za dati ugao. U drugoj klasi implementirati

main() funkciju koja sa standardnog ulaza ucitava vektor i zatim ucitava tacku u koju

transliramo taj vektor, a zatim i ugao za koji ga dalje rotiramo; onda ucitavamo drugi

100

19

36

17

3

25

1

2

7 0 1 2 3 4 5 6 7 8

Page 147: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

146

vektor, pa tacku u odnosu na koju nalazimo centralno simetricni vektor tom vektoru.

Na kraju ispisujemo zbir i razliku ovako dobenih vektora.

20. Написати на језику C++ следеће класе (класе опремити оним конструкторима и

деструктором који су потребни за безбедно коришћење класа):

Оцена садржи цео број у опсегу од 5 до 10. Вредности изван опсега приликом

стварања промене се у најближу прихватљиву вредност. Може да се дохвати

вредност оцене бројчано и словима као и да се оцена испише на главном излазу

када се пишу оба облика оцене (на пример: 10(deset)).

Испит садржи шифру испита од највише 6 знакова и оцену. Може да се дохвати

шифра испита и оцена и да се испит испише на главном излазу у облику

"шифра:оцена".

Студент има име (текст произвољне дужине), број индекса (дугачак цео број по

шеми ggggrrrr, где су g и r цифре године уписа и регистарског броја) и низ

испита задатог капацитета (подразумевано 40). Ствара се без иједног испита

после чега испити могу да се додају један по један. Повратна вредност при

додавању испита показује успех додавања (тј. да ли је било места у низу испита).

Не сме да се прави копија студента. Може да се израчуна средња вредност оцена

положених испита и да се студент испише на главном излазу у облику

"име[годУп/регБр:срОцена]".

Написати на језику C++ програм који направи једног студента, додаје му три испита и

испише га на главном излазу. Користити само константне податке (не треба ништа

учитавати с главног улаза).

21. Написати на језику JAVA следеће класе (класе опремити оним конструкторима и

деструктором који су потребни за безбедно коришћење класа):

Оцена садржи цео број у опсегу од 5 до 10. Вредности изван опсега приликом

стварања промене се у најближу прихватљиву вредност. Може да се дохвати

вредност оцене бројчано и словима као и да се оцена испише на главном излазу

када се пишу оба облика оцене (на пример: 10(deset)).

Испит садржи шифру испита од највише 6 знакова и оцену. Може да се дохвати

шифра испита и оцена и да се испит испише на главном излазу у облику

"шифра:оцена".

Студент има име (текст произвољне дужине), број индекса (дугачак цео број по

шеми ggggrrrr, где су g и r цифре године уписа и регистарског броја) и низ

испита задатог капацитета (подразумевано 40). Ствара се без иједног испита

после чега испити могу да се додају један по један. Повратна вредност при

додавању испита показује успех додавања (тј. да ли је било места у низу испита).

Не сме да се прави копија студента. Може да се израчуна средња вредност оцена

положених испита и да се студент испише на главном излазу у облику

"име[годУп/регБр:срОцена]".

Написати на језику JAVA програм који направи једног студента, додаје му три испита и

испише га на главном излазу. Користити само константне податке (не треба ништа

учитавати с главног улаза).

22. Саставити на језику C++ следеће класе (класе опремити оним конструкторима и

деструктором који су потребни за безбедно коришћење класа):

Page 148: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

147

Датум се задаје помоћу броја дана, месеца и године. Може да се провери да ли

три цела броја представљају исправан датум, да се ствара датум на основу три

цела броја (подразумевано 7.11.2005. – погрешан датум прекида програм), да се

дохватају делови датума, да се датум упореди с другим датумом (резултат је <0,

=0 или >0, зависно од тога да ли је текући датум пре, једнак или после задатог

датума), да се датум прочита са главног улаза и да се датум испише на главном

излазу.

Листа датума се ствара празна, после чега се датуми додају један по један на

крај листе. Може да се одреди дужина листе, да се дохвати најкаснији датум у

листи и да се листа испише на главном излазу.

Написати на језику C++ главни програм који читајући датуме с главног улаза направи

листу датума (читање се завршава првим неисправним датумом), испише на главном

излазу добијену листу као и најкаснији датум и понавља претходне кораке све док не

прочита празну листу.

23. Саставити на језику JAVA следеће класе (класе опремити оним конструкторима

и деструктором који су потребни за безбедно коришћење класа):

(25 поена) Датум се задаје помоћу броја дана, месеца и године. Може да се

провери да ли три цела броја представљају исправан датум, да се ствара датум

на основу три цела броја (подразумевано 7.11.2005. – погрешан датум прекида

програм), да се дохватају делови датума, да се датум упореди с другим датумом

(резултат је <0, =0 или >0, зависно од тога да ли је текући датум пре, једнак или

после задатог датума), да се датум прочита са главног улаза и да се датум

испише на главном излазу.

(25 поена) Листа датума се ствара празна, после чега се датуми додају један по

један на крај листе. Може да се одреди дужина листе, да се дохвати најкаснији

датум у листи и да се листа испише на главном излазу.

(20 поена) Написати на језику JAVA главни програм који читајући датуме с главног

улаза направи листу датума (читање се завршава првим неисправним датумом), испише

на главном излазу добијену листу као и најкаснији датум и понавља претходне кораке

све док не прочита празну листу.

24. Саставити на језику C++ следеће класе (класе опремити оним конструкторима и

деструктором који су потребни за безбедно коришћење класа):

(20 поена) Материјална тачка у простору се задаје помоћу реалне масе

(подразумевано 1) и три реалне координате (подразумевано (0,0,0)). Може да се

одреди растојање (r) до друге тачке, да се израчуна привлачна сила између тачке

и задате друге тачке (F=γ·m1·m2/r2, γ=6,67·10−11) и да се тачка испише на главном

излазу.

(30 поена) Низ материјалних тачака се ствара празан задатог почетног

капацитета (подразумевано 5), после чега се тачке додају једнa по једнa на крај

низа. Aко се низ препуни, капацитет му се повећа за 5. Може да се дохвати број

тачака у низу, да се дохвати тачка у низу која највише привлачи задату тачку и

да се низ испише на главном излазу.

(20 поена) Написати на језику C++ програм који читајући материјалне тачке с главног

улаза направи низ материјалних тачака (читање се завршава уносом негативне масе),

испише на главном излазу добијени низ као и тачку која највише привлачи тачку

Page 149: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

148

јединичне масе у координатном почетку и понавља претходне кораке све док не

прочита празан низ (низ дужине 0).

25. Саставити на језику JAVA следеће класе (класе опремити оним конструкторима

и деструктором који су потребни за безбедно коришћење класа):

Материјална тачка у простору се задаје помоћу реалне масе (подразумевано 1)

и три реалне координате (подразумевано (0,0,0)). Може да се одреди растојање

(r) до друге тачке, да се израчуна привлачна сила између тачке и задате друге

тачке (F=γ·m1·m2/r2, γ=6,67·10−11) и да се тачка испише на главном излазу.

Низ материјалних тачака се ствара празан задатог почетног капацитета

(подразумевано 5), после чега се тачке додају једнa по једнa на крај низа. Aко се

низ препуни, капацитет му се повећа за 5. Може да се дохвати број тачака у

низу, да се дохвати тачка у низу која највише привлачи задату тачку и да се низ

испише на главном излазу.

Написати на језику JAVA програм који читајући материјалне тачке с главног улаза

направи низ материјалних тачака (читање се завршава уносом негативне масе), испише

на главном излазу добијени низ као и тачку која највише привлачи тачку јединичне

масе у координатном почетку и понавља претходне кораке све док не прочита празан

низ (низ дужине 0).

26. Realizovati klasu trougao koja će kao podatke članove imati tri tačke koje

predstavljaju objekte klase tačka. Klasa tačka treba da ima odgovarajuće konstruktore

i destruktore kao i funkcije za računanje rastojanja dve tačke i ugla između prave koju

čine dve tačke i x ose. Klasa trougao treba da poseduje odgovarajuće konstruktore,

destruktore kao i funkciju članicu koja će za tri date tačke proveravati da li čine

trougao ili su to tačke sa jedne prave i druga funkcija članica proverava da li je

trougao, na ovaj način zadat, jednakokraki. Napisati i glavni program u kojem će se

unositi koordinate za željene tačke, inicijalizovati potrebni objekti i proveravati da li

date tačke čine trougao i da li je isti jednakokraki.

27. Написати на језику C++ следеће класе (класе опремити оним конструкторима и

деструктором који су потребни за безбедно коришћење класа):

Оцена садржи цео број у опсегу од 5 до 10. Вредности изван опсега приликом

стварања промене се у најближу прихватљиву вредност. Може да се дохвати

вредност оцене бројчано и словима као и да се оцена испише на главном излазу

када се пишу оба облика оцене (на пример: 10(deset)).

Испит садржи шифру испита од највише 6 знакова и оцену. Може да се дохвати

шифра испита и оцена и да се испит испише на главном излазу у облику

"шифра:оцена".

Студент има име (текст произвољне дужине), број индекса (дугачак цео број по

шеми ggggrrrr, где су g и r цифре године уписа и регистарског броја) и низ

испита задатог капацитета (подразумевано 40). Ствара се без иједног испита

после чега испити могу да се додају један по један. Повратна вредност при

додавању испита показује успех додавања (тј. да ли је било места у низу испита).

Не сме да се прави копија студента. Може да се израчуна средња вредност оцена

Page 150: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

149

положених испита и да се студент испише на главном излазу у облику

"име[годУп/регБр:срОцена]".

Написати на језику C++ програм који направи једног студента, додаје му три испита и

испише га на главном излазу. Користити само константне податке (не треба ништа

учитавати с главног улаза).

#include <iostream>

#include <cstring>

using namespace std;

class Ocena {

int oce;

static const char* opisi[];

public:

Ocena (int oc) {

if (oc < 5) oc = 5;

if (oc > 10) oc = 10;

oce = oc;

}

int ocena () const { return oce; }

const char* opis () const{ return opisi[oce-5]; }

void pisi () const { cout << oce << '(' << opis() << ')'; }

};

const char* Ocena::opisi[] = {"pet", "sest", "sedam", "osam", "devet",

"deset"};

class Ispit {

char sif[7];

Ocena oce;

public:

Ispit (char sif[], Ocena oce) : oce(oce) { strcpy (this->sif,sif); }

const char* sifra () const { return sif; }

Ocena ocena () const { return oce; }

void pisi () const { cout << sif << ':'; oce.pisi(); }

};

class Student {

char* ime;

long ind;

Ispit** ispiti;

int kap, duz;

Student (const Student&) {}

public:

Student (const char* ime, int ind, int k=40) {

this->ime = new char [strlen(ime)+1];

strcpy (this->ime, ime);

this->ind = ind;

ispiti = new Ispit* [kap = k];

duz = 0;

}

~Student ();

bool dodaj (const Ispit &isp) {

Page 151: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

150

if (duz == kap) return false;

ispiti[duz++] = new Ispit (isp);

return true;

}

double srOcena () const;

void pisi () const {

cout << ime << '[' << (ind/10000) << '/' << (ind%10000) << ':' <<

srOcena() << ']';

}

};

Student::~Student () {

delete [] ime;

for (int i=0; i<duz; delete ispiti[i++]);

delete [] ispiti;

}

double Student::srOcena () const {

double s = 0; int n = 0;

for (int i=0; i<duz; i++)

if(ispiti[i]->ocena().ocena() > 5) {

s+=ispiti[i]->ocena().ocena();

n++;

}

if (n) s /= n;

return s;

}

int main () {

Student marko("Marko",20060055,45);

marko.dodaj (Ispit("SI2AS2",9));

marko.dodaj (Ispit("SI2OR2",5));

marko.dodaj (Ispit("SI2OO1",10));

marko.pisi(); cout << endl;

return 0;

}

28. ((CC++++)) Definisati klasu Student koja ima privatne podatke brojIndeksa (ceo broj), ime (string, ne duži od 30 znakova) i ocene (dinamički niz koji ima brOcena elemenata). Napisati

a) Konstruktor Student(int n) kojim se niz ocena kreira tako da ima n elemenata.

b) Konstruktor Student(int brInd, char * ime, int n) kojim se postavljaju indeks i ime studenta, kao i broj ocena.

c) Geter i seter za broj indeksa i ime, kao i metode int getOcena(int i) i void setOcena(int i, int oc) kojima se omogućava čitanje i postavljanje i – te ocene. Voditi računa o tome da li je indeks u granicama za broj ocena, kao i da li je vrednost na koju se ocena postavlja između 5 i 10.

d) Destruktor.

e) Metod double prosek() koji kao rezultat daje prosečnu ocenu studenta. Ukoliko student nema ni jednu ocenu, rezultat je 0.

29. ((JJAAVVAA)) Kreirati klasu BrojacZnakova koja čuva ulazni tekst (kao string) i može da napravi statistiku o tome koji se znak koliko puta javlja. Tekst se može zadavati i naknadno, a statistika mora uvek biti ispravna. Napisati:

a) Konstruktor BrojacZnakova(String s).

b) Odgovarajuće getere i setere.

Page 152: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

151

c) Metod void dodaj(String s) koji na postojeći tekst dodaje string s.

d) Netod int brojPojava(char c) koji omogućava dobijanje broja pojavljivanja datog znaka.

e) Metod void ponisti() koji poništava celu dotadašnju statistiku.

f) Metod char[] top10() koji kao rezultat daje niz od 10 (ili manje, ukoliko nema dovoljno znakova) znakova koji se najčešće javljaju, uređen u nerastući redosled po broju pojava.

Page 153: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

152

Domaći II

1. Саставити на језику C++ следеће класе (класе опремити оним конструкторима,

деструктором и оператором за доделу вредности, који су потребни за безбедно

коришћење класа; у случају грешке прекидати програм):

a. Апстрактна територијална јединица има назив (знаковни низ). Може да се

дохвати једнословна ознака врсте, да се одреди број становника и да се упише у

излазни ток (it<<jed) у облику naziv:vrsta:brojSt:.

b. Насеље је једноставна територијална јединица у којој живи задати број

становника. Ознака врсте је 'N'.

c. Апстрактна област је територијална јединица која садржи задат број других

територијалних јединица. Ствара се празна након чега јој се јединице додају

једна по једна (obl+=jed; прекорачење капацитета је грешка) уз проверу да ли се

јединица сме додати. Проверу одређују конкретне области. Додата јединица не

постане власништво области већ се само памти њена адреса (показивач). Број

становника области је једнак збиру броја становника садржаних јединица.

Може да јој се одреди површина. У излазни ток се пише у облику

naziv:vrsta:brojSt:povrs[jed,…,jed], где jed шредставља резултат писања једне

јединице.

d. Општина је област која садржи само насеља и има задату површину. Ознака

врсте је 'O'. Округ је област која садржи само општине. Површина области је

једнака збиру површина садржаних општина. Ознака врсте је 'N'. Покушај

додавања неодговарајуће јединице је грешка.

Написати на језику C++ програм који формира пример једног округа са две општине, од

којих свака општина има по два насеља, а затим испише округ на главном излазу.

Користити константне податке (не треба ништа читати с главног улаза).

2. Саставити на језику C++ следеће класе (класе опремити оним конструкторима,

деструктором и оператором за доделу вредности, који су потребни за безбедно

коришћење класа):

a. Апстрактном геометријском телу може да се дохвати једнословна ознака врсте

тела, да се израчуна запремина и да се направи динамичка копија. Предвидети

и могућност уписа произвољног конкретног геометријског тела у датотеку

(dat<<t).

b. Сфера је предмет задат полупречником (подразумевано 1). Ознака врсте

премета је S, запремина је 4r3π/3 и у датотеку се пише у облику S(r).

c. Ваљак је предмет задат полупречником основице и висином (подразумевано 1

и 1). Ознака врсте премета је V, запремина је r2πh и у датотеку се пише у облику

V(r,h).

d. Ред тела ограниченог капацитета се ствара празан задатог капацитета

(подразумевано 5). Може да се испита да ли је ред пун и да ли је празан, да се

стави једно тело на крај реда (red+=pr; покушај стављања у пун ред прекида

програм), да се узме тело са почетка реда (покушај узимања из празног реда

прекида програм) и да се садржај реда упише у датотеку (dat<<red) у облику

red[t,t,…,t], где су t резултати писања појединих садржаних тела.

Page 154: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

153

Написати на језику C++ главни програм који направи ред капацитета који прочита са

главног улаза, чита разноврсна тела са главног улаза и ставља их у ред све док се ред не

напуни, испише садржај реда на главном излазу, узимајући тела из реда док се ред не

испразни израчуна средњу запремину свих тела у реду, испише добијени резултат на

главном излазу и понавља претходне кораке док за капацитет реда не прочита

недозвољену вредност.

3. Саставити на језику C++ следеће класе (класе опремити оним конструкторима,

деструктором и оператором за доделу вредности, који су потребни за безбедно

коришћење класа):

a. Особа има име и године старости. Може да се испита да ли је једна особа

старија од друге (osoba1>osoba2) и да се особа упише у излазни ток (it<<osoba) у

облику ime(god), где су: ime – име особе и god – године старости. Особа не сме

да се копира ни на који начин.

b. Студент је особа који може да полаже највише задати број испита

(подразумевано 20) за које се памте само оцене. Ствара се без иједне оцене,

после чега се оцене додају једна по једна (student+=ocena). Покушај додавања

превише оцена прекида програм. Може да се испита колико оцена може још да

се дода, да се израчуна средња вредност положених испита. У излазни ток се

пише у облику ime(god)/sred, где је sred – средња оцена положених испита.

c. Именик може да садржи задат број (подразумевано 10) особа произвољне

врсте. Ствара се празан после чега се особе додају једна по једна

(imenik+=&osoba). Препуњавање именика прекида програм. Може да се

дохвати капацитет именика, број особа у именику, да се именик уреди по

опадајућем редоследу старости особа у њему и да се упише у излазни ток

(it<<imenik), тако што се свака особа пише у посебном реду. Именик не сме да

се копира ни на који начин.

Написати на језику C++ програм који читајући потребне податке с главног улаза направи

именик који садржи известан број особа произвољне врсте, уреди именик по опадајућем

редоследу старости особа у њему и испише именик на главном излазу.

4. Написати на језику C++ следеће класе (класе опремити оним конструкторима,

деструктором и оператором за доделу вредности, који су потребни за безбедно

коришћење класа; грешке пријављивати изузецима типа једноставних класа које су

опремљене писањем текста поруке):

a. Апстрактно превозно средство је описано максималном брзином, дужином,

површином и сопственом тежином. Може да му се дохвати тренутна тежина и

једнословна ознака врсте. Има јединствен, аутоматски генерисан,

идентификациони број који може да се дохвати. Превозно средство може да се

упише у излазни ток (it<<sredstvo) у облику

врста:ид(максималнаБрзина,дужина,површина,тежина).

b. Аутомобил је превозно средство које је додатно описано бројем седишта.

Ознака врсте је 'A'.

c. Апстрактaн транспортер је превозно средство задате носивости.

d. Генерички стек може да садржи задат број елемената одређеног типа. Може да

се дохвати број елемената на стеку, да се стави елемент на стек (stek+=elem), да

се узме последње стављени елемент са стека (--stek), да се дохвати елемент са

Page 155: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

154

задатим редним бројем од врха стека (stek[ind]) и да се садржај стека упише у

излазни ток (it<<stek) почев од врха стека у облику елемент|…|елемент. Грешка

је ако се покуша ставити више елемената од капацитета стека и ако се покуша

узети елемент са празног стека.

e. (20 поена) Шлепер је транспортер који може да садржи аутомобиле на стеку

задатог капацитета. Збир дужина садржаних аутомобила мора бити мањи од

80% сопствене дужине, а збир њихових тежина мањи или једнак носивости.

Ознака врсте је 'S'. У тренутну тежину шлепера улази и тежина садржаних

аутомобила. У излазни ток се, поред општих података за сва превозна средства,

пише и садржај шлепера унутар пара угластих заграда: [садржај].

f. Трајект је транспортер који може да садржи превозна средства на стеку задатог

капацитета. Збир површина садржаних превозних средстава мора бити мања од

70% сопствене површине, а збир њихових тежина мањи или једнак носивости.

Грешка је ако се покуша стављање трајекта на трајект. Ознака врсте је 'Т'. У

тренутну тежину трајекта улази и тежина садржаних превозних средстава. У

излазни ток се, поред општих података за сва превозна средства, пише и

садржај трајекта унутар пара угластих заграда: [садржај].

Написати на језику C++ програм који напуни један трајект са неколико аутомобила и

неколико шлепера од којих сваки има по неколико аутомобила и испише трајект на

главном излазу. Користити константне параметре (не треба ништа учитавати).

5. Написати на језику C++ следеће класе (класе опремити оним конструкторима,

деструктором и оператором за доделу вредности, који су потребни за безбедно

коришћење класа; грешке пријављивати изузецима типа класа које су оспособљене за

исписивање текста поруке):

a. Апстрактан генератор случајних бројева на сваки захтев даје један

псеудослучајан реалан број по некој расподели.

b. Генератор униформне расподеле на основу задате 32-битне целобројне клице k

и реалних граничних вредности min и max, задатих у тренутку стварања, може

да врати случајну целобројну вредност у опсегу [0,232) и реалну вредност у

опсегу [min,max). При сваком захтеву за следећим случајним бројем вредност

клице се мења по формули k = (314159621 k + 907633385) mod 232. Враћена

случајна целобројна вредност је једнака новој вредности клице, а реална

вредност се добија пресликавањем нове вредности клице на поменути опсег.

c. Апстрактан посматрач може да се доведе у почетно стање, да се стање

посматрача ажурира на основу једног реалног податка, да се дохвати један

реалан податак који представља тренутно стање посматрача и да се назив врсте

посматрача упише у датотеку (dat<<posm).

d. Минимум, максимум и средња вредност су посматрачи који као резултат

одређују најмању, највећу, односно средњу вредност достављених података од

последњег довођења у почетно стање. Грешка је ако се затражи дохватање

резултата, а није био достављен ни један податак.

e. Апстрактан субјекат посматрања може да достави један реалан податак свим

пријављеним посматрачима ради ажурирања њихових стања. Ствара се празан

после чега се посматрачи пријављују (subj+=&posm) и одјављују (subj-=&posm)

један по један. Пријављени посматрачи нису власништво субјекта.

Page 156: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

155

f. Статистички анализатор је субјекат који помоћу одређеног генератора случајних

бројева може да генерише одређен број случајних бројева и те бројеве, један

по један, достави свим пријављеним посматрачима.

Написати на језику C++ програм који направи један статистички анализатор, пријави му по

један примерак од све три врсте посматрача, направи статистичку анализу 10000

униформних случајних реалних бројева у опсегу од −1 до 5 и испише добијене резултате на

главном излазу.

6. Написати на језику C++ следеће класе (класе опремити оним конструкторима,

деструктором и оператором за доделу вредности, који су потребни за безбедно

коришћење класа; грешке пријављивати изузецима типа једноставних класа које су

опремљене писањем текста поруке):

a. Јединица мере има ознаку која може да се дохвати. Дозвољене ознаке су:

"kom", "l", "m" и "kg". Грешка је ако се покуша направити јединица мере с

другачијом ознаком. Јединица мере може да се упише у излазни ток (it<<jed)

кад се пише ознака јединице.

b. Апстрактан артикал има назив и јединицу мере који могу да се дохвате. Два

артикла се сматрају истим ако имају исти назив (art1==art2). Артикал може да се

упише у излазни ток (it<<art) кад се пише назив артикла.

c. Млеко и шећер су артикли који се мере у литрима, односно у килограмима.

d. Запис о артиклу има артикал, количину и јединичну цену артикла. Могу да се

дохвате атрибути записа, да се промени количина, да се промени јединична

цена и да се израчуна вредност укупне количине артикла у запису. Запис може

да се упише у излазни ток (it<<zap) када се пише артикал, количина, јединица

мере, јединична цена и вредност артикла.

e. Генерички низ може да садржи задат број елемената одређеног типа. Ствара се

празан задатог капацитета после чега се елементи могу додавати један по један

(niz+=elem; капацитет низа се по потреби аутоматски повећава за 10%, али бар

за 5 места). Може да се дохвати број елемената у низу, да се дохвати елемент са

задатим редним бројем (niz[ind]; грешка је ако је индекс изван опсега) и да се

садржај низа упише у излазни ток (it<<niz), по један елемент у сваком реду.

f. Складиште има назив и адресу и садржи генерисан низ записа о артиклима.

Ствара се празно капацитета 5 записа, после чега се записи додају један по

један (sklad+=zap; грешка је ако већ постоји запис за исти артикал). Може да се

дохвати запис за задати артикал (sklad[art]; грешка је ако такав запис не постоји)

и да се израчуна укупна вредност артикала у складишту.

Написати на језику C++ програм који направи једно складиште, стави у њега неколико

артикала и испише на главном излазу укупну вредност артикала у складишту. Користити

константне податке (не треба ништа учитавати).

7. Написати на језику C++ следеће класе (класе опремити оним конструкторима,

деструктором и оператором за доделу вредности, који су потребни за безбедно

коришћење класа):

Page 157: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

156

a. Симбол садржи један знак (char) и однос ширине и висине при исцртавању

знака. Може да се дохвати садржани знак и да се одреди ширина исцртавања за

дату висину.

b. Фонт садржи произвољан број симбола. Ставара се празан после чега се

симболи додају један по један. Ако већ постоји симбол за дати знак, стари

симбол се замењује новим. Може да се дохвати број симбола у фонту и да се

нађе симбол који садржи задати знак (резултат је адреса симбола – нула ако

знак не постоји).

c. Вектор у равни се задаје реалним координатама. Може да се вектору дода

други вектор и да се упише у излазни ток (vekt.pisi(it)) у облику "(x,y)".

8. Саставити на језику C++ следеће класе (класе опремити оним конструкторима, деструктором и оператором за доделу вредности, који су потребни за безбедно коришћење класа; грешке пријављивати изузецима типа једноставних класа које су опремљене писањем текста поруке):

Датум се задаје помоћу дана, месеца и године. При стварању датума није потребно проверавати исправност параметара. Компоненте датума могу да се дохвате. Датум може да се упише у датотеку (dat<<datum).

За особу се зна име и датум рођења. Подаци о особи могу да се дохватају, да се промене и могу да се упишу у датотеку (dat<<osoba).

Испит се задаје помоћу једнословне шифре предмета, оцене и датума полагања испита. Подаци о испиту могу да се дохватају.

(20 поена) Генеричка листа података неког типа се ствара празна после чега се подаци додају један по један на крај листе (lst+=pod). Може да се постави на први елемент листе, да се прелази на следећи елемент, да се испита да ли постоји текући елемент, да се приступи податку у текућем елементу са могућношћу промене вредности податка и да се текући елемент избаци из листе (при томе следећи елемент постаје текући). Грешка је ако текући елемент не постоји у моменту покушаја приступања елементу или избацивања елемента.

Ђак је особа која је полагала известан број испита. Ствара се са празном листом испита, после чега се поједини испити додају један по један (djak+=ispit). Може да се одреди средња оцена положених испита. У датотеку се поред општих података пише и средња оцена положених испита.

Школа има једнословну ознаку и садржи листу ђака који похађају школу. Ствара се празна, после чега се ђаци додају један по један (skola+=djak). Може да се дохвати ђак са највећом средњом оценом положених испита без могућности промене података о том ђаку.

Саставити на језику C++ главни програм који направи школу са два ђака са по три полагана испита и испише на главном излазу податке о ђаку са бољим просеком.

9. Написати на језику C++ следеће класе (класе опремити оним конструкторима, деструктором и оператором за доделу вредности, који су потребни за безбедно коришћење класа; грешке пријављивати изузецима типа класа које су оспособљене за исписивање текста поруке):

Боја се задаје помоћу реалних интензитета црвене, зелене и плаве боје у опсегу од 0 до 1 (подразумевано (1,1,1), тј. бела боја). Грешка је ако је вредност интензитета неке од

Page 158: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

157

боја изван наведеног опсега. Боја може да се упише у датотеку (dat<<boja) у облику (c,z,p), где су: c, z и p – интензитети компонентних боја.

Тачка у равни се задаје помоћу реалних координата (подразумевано (0,0)) и могу да јој се дохвате вредности координата.

Апстрактна попуњена фигура у равни има јединствен, аутоматски генерисан идентификациони број и боју. Може да се дохвати њен идентификациони број и боја, да се испита да ли јој припада нека задата тачка (сматра се да тачка припада фигури ако лежи у унутрашњости или на ивици фигуре) и да се сазна које је боје задата тачка која припада фигури (грешка је ако наведена тачка не припада фигури).

Правоугаоник је фигура која има ивице паралелне координатним осама и задаје се помоћу две тачке које чине доње лево и горње десно теме (подразумевано (0,0) и (1,1)).

Круг је фигура која се задаје помоћу полупречника и тачке која представља центар круга (подразумевано полупречника 1 са центром у тачки (1,1)).

Генерички низ се ствара празан задатог капацитета почетног капацитета (подразумевано 10) после чега се елементи додају један по један (niz+=elem). Ако се низ препуни, капацитет му се поваћа за 5 елемената. Може да се дохвати број елемената низа и да се приступа елементу са датим редним бројем (niz[ind]; грешка је ако је индекс изван опсега).

Цртеж је правоугаоник који може да садржи произвољан број фигура у облику генеричког низа. Боја фигуре представља боју подлоге цртежа. Координате садржаних фигура рачунају се у односу на доње лево теме цртежа. У случају преклапања фигура, касније додата фигура прекрива раније додату фигуру (боју тачке у цртежу одређује фигура која последња додата цртежу и садржи ту тачку – ако такве фигуре нема, узима се боја подлоге).

Написати на језику C++ програм који направи један цртеж од неколико фигура константних параметара (не треба ништа учитавати) и после читајући неколико парова координата тачака исписује боју тих тачака у цртежу.

10. Написати на језику C++ следеће класе (класе опремити оним конструкторима, деструктором и оператором за доделу вредности, који су потребни за безбедно коришћење класа; грешке пријављивати изузецима типа једноставних класа које су опремљене писањем текста поруке):

Апстрактним мерљивим појмовима може да се одреди тежина и да се дохвати назив врсте.

Мерљива особа има име и тежину, који могу да се дохвате. Може да се дохвати име и да се упише у излазни ток (it<<osoba) у облику име(тежина).

Мерљив теретни контејнер има јединствен, аутоматски генерисан регистарски број и тежину када је празан. У контејнер је могуће сместити товар задате тежине (kont+=tez) и извадити товар задате тежине (kont-=tez). Може да се дохвати регистарски број и сопствена тежина и да се упише у излазни ток (it<<kont) у облику регБрој(укупнаТежина).

Генерички низ садржи задат број (подразумевано 10) елеменатa типа који је једини параметар шаблона. Приликом стварања сви елементи се поставе на подразумевану (празну) вредност. Може да се дохвати дужина низа и да се приступа елементу са датим редним бројем (niz[ind]). Грешка је ако је индекс изван опсега.

Апстрактан авион има ознаку (низ од 5 знакова), максималну тежину, тежину када је празан и садржи низ од задатог броја показивача на мерљиве појмове. Авион не сме да се копира ни на који начин. Може да се стави неки појам на задато место у низу (avion.stavi(ind,&pojam)), да се уклони појам са задатог места (avion.ukloni(ind)), да се израчуна тренутна тежина авиона и да се упише у излазни ток (it<<avion) у облику

Page 159: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

158

ознака(тренутнаТежина)[појам,…,појам]. Грешка је ако се покуша претоварити авион, ставити нешто на попуњено место или уклањати нешто с празног места.

Путнички авион може да превози само путнике, а треттни авион може да превози само контејнере. Грешка је ако се покуша додати појам неодговарајуће врсте.

Написати на језику C++ програм који направи један путнички авион са три путника и један

теретни авион са два контејнера, све са константним параметрима (не треба ништа учитавати) и

после испише та два авиона на главном излазу.

11. Коришћењем класа из првог дела, написати на језику C++ следеће класе (класе опремити оним конструкторима, деструктором и оператором за доделу вредности, који су потребни за безбедно коришћење класа):

Апстрактно возило има задату сопствену тежину. Може да се дохвати назив врсте возила, да се одреди тежина возила и да се возило упише у излазни ток (it<<v). Пише се назив врсте возила и сопствена тежина возила.

Бицикл је возило. Камион је возило задате сопствене тежине и носивости. Ствара се без товара после чега

може да се дода товар задате тежине (k+=t) и да се скине товар задате тежине (k-=t). Ако се камион претовари, вишак терета се одбацује. Скидањем превише товара тежина товара постане једнака нули. У излазни ток се пише и тренутна тежина товара на камиону.

12. Коришћењем класа из првог дела, саставити на језику C++ следеће класе (класе

опремити оним конструкторима, деструктором и оператором за доделу

вредности, који су потребни за безбедно коришћење класа):

Апстрактни чвор графа има једнословну ознаку. Може да се дохвати ознака

чвора, да се одреди реална величина чвора и да се ознака чвора упише у

датотеку (dat<<cvor).

Географски чвор је чвор који садржи једно географско место. Величина чвора је

обим контуре места. Може да се дохвати центар садржаног места. У датотеку се

пише име места и обим контуре.

Апстрактна грана графа има једнословну ознаку и спаја два чвора графа. Може

да се дохвати ознака гране, да се одреди реална дужина гране и да се грана

упише у датотеку (dat<<grana) у облику ozn(poc,kra), где су ozn – ознака гране

а poc и kra – ознаке почетног и крајњег чвора гране. Грана не сме да се копира.

Географска грана је грана која спаја два географска чвора. Дужина гране је

растојање између центара места на крајевима гране.

13. Написати на језику C++ следеће класе (класе опремити оним конструкторима,

деструктором и оператором за доделу вредности, који су потребни за безбедно

коришћење класа; грешке пријављивати изузецима типа једноставних класа које

су опремљене писањем текста поруке):

Позиција у једнодимензионалном (линијском) простору се дефинише реалним

бројем x који означава растојање од координатног почетка. Може да се дохвати

вредност x и одреди растојање од друге позиције. Позиција може да се упише у

излазни ток (it<<pozicija) у облику (x).

Апстрактна честица поседује јединствен аутоматски генерисан

идентификациони број. Задаје се позицијом у линијском простору. Може да се

дохвати једнословна ознака врсте честице и позиција честице. Честици могу да

се одреде маса и наелектрисање као и да се израчуна сила привлачења са

Page 160: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

159

задатом честицом (негативна вредност означава одбијање). Честица може да се

упише у излазни ток (it<<cestica) у облику

врста:ид[маса,наелектрисање,позиција] .

Е-честица има задато наелектрисање, док је њена маса 0. Сила привлачења се

израчунава по Кулоновом закону: FE = −kc⋅q1⋅q2/r2, kc ≈ 8,99⋅109. Једнословна

ознака врсте је 'Е'.

М-честица има задату масу, док је њено наелектрисање 0. Сила привлачења се

израчунава по закону гравитације: FG = γ⋅m1⋅m2/r2, γ ≈ 6,67⋅10−11. Једнословна

ознака врсте је 'M'.

О-честица има задату масу и наелектрисање. Сила привлачења је збир сила по

Кулоновом закону и закону гравитације. Једнословна ознака врсте је 'О'.

Генеричка листа може да садржи произвољан број елемената одређеног типа.

Може да се дохвати број елемената листе, да се дода елемент на крај листе

(lista+=elem), да се дохвати елемент са задатим редним бројем од почетка

листе (lista[ind]) и да се садржај листе упише у излазни ток (it<<lista) почев

од првог елемента у облику елемент|…|елемент. Грешка је ако не постоји

елемент који одговара задатом индексу приликом дохватања.

Експериментална соба садржи листу честица и задату експерименталну

честицу. Након стварања, честице се додају једна по једна. Грешка је ако се

покуша додавање честице на истој позицији као и експериментална честица. У

излазни ток се уписује експериментална честица и садржај листе у облику

експ_честица{листа}. Резултат експеримента је интензитет силе којом додате

честице делују на експерименталну (позитивна вредност означава силу у правцу

x осе). Интензитет силе се израчунава као збир интензитета сила којом делују

честице из листе.

Написати на језику C++ програм који направи једну експерименталну собу у коју дода

неколико честица а затим испише резултат експеримента на главном излазу. Користити

константне параметре (не треба ништа учитавати).

14. Prodavnica prodaje kompjutere i softver. Kompjuter može biti desktop ili laptop. Date su

klase Proizvod, Kompjuter, Desktop, Laptop i Software.

a. U svaku od klasa dodati metod prikazi() koji kao rezultat daje string sa podacima

o proizvodu.

b. Kreirati formu koja na sebi ima dve liste – listu proizvoda u prodavnici, kao i listu

izabranih proizvoda. Omogućiti izbor označenih proizvoda prebacivanjem u listu

izabranih proizvoda, kao i odustajanje od kupovine određenog proizvoda. Dodati

labelu koja u svakom trenutku pokazuje tačnu ukupnu cenu odabranih proizvoda.

c. Dodati dugme za brisanje postojećeg proizvoda, s’ tim što se proizvod ne može

obrisati ukoliko ga je kupac izabrao.

d. Dodati dugme za dodavanje novog proizvoda. Ovo dugme bi trebalo da prikazuke

novi prozor u kome je padajuća lista iz koje korisnik prvo treba da odabere tip

proizvoda (kompjuter/software). Ukoliko izabere kompjuter, treba mu prikazati još

jednu padajuću listu u okviru koje bira da li se radi o dektop ili laptop kompjuteru.

Posle izabranog tipa treba prikazati polja za unos odgovarajućih podataka o

proizvodu. Ovaj prozor treba da sadrži i dugme za potvrdu, odnosno dugme za

odustajanje od unosa novog proizvoda.

Page 161: Uvod u OOP – vežbenasport.pmf.ni.ac.rs/materijali/2117/vezbe.pdf1 Programski jezik C++ 1. Razlike C i C++-a neobjektne prirode Zadatak 1. 1 Implementirati funkciju max koja daje

160