Download as pdf or txt
Download as pdf or txt
You are on page 1of 335

Uvod

Literatura
Laslo Kraus: Programski jezik C++ sa reenim zadacima, Akademska misao

Programski jezik C
Jezik opte namene Ima karakteristike
viih programskih jezika
strukturirani tipovi podataka upravljake strukture

niih programskih jezika (simbolikih programskih jezika)


rad sa bitovima korienje procesorskih registara pristup podacima pomou adrese operatore orijentisane ka hardveru raunara

Razvoj programskog jezika C


C je projektaovao Dennis Ritchie
1972 u Bell-ovim laboratorijama

Cilj razvoja novog jezika


jezika nezavisan od raunara karakteristike vieg programskog jezika korienje umesto simbolikih mainskih jezika koji su zavisni od raunara

Standardizovan 1989
standard izdao American National Standards Institute ANSI C

Razvoj programskog jezika C++


1980 su dodate klase, jezik je nazvan C sa klasama Dalja proirenja jezika: virtuelne funkcije (isto to i redefinisanje u Javi, ali nije sasvim isto to i apstraktna funkcija, koja je ista virtuelna funkcija) preklapanje operatora 1983/84 je nazvan C++ ime oznaava da C++ nije novi programski jezik, ve proirenje jezika C preko 95% jezika C je usvojeno bez izmena u C++
promenjeni su neki detalji radi obezbeivanja konzistentnosti novih koncepcija u C++

Autor C++ je Bjarne Stroustrup, njegova knjiga The C++ Programming Language koriena je kao definicija jezika pre nego to je standardizovan
5

Razvoj programskog jezika C++


Dalji razvoj
viestruko nasleivanje apstraktne klase generike klase rukovanje izuzecima

1991 objavljena knjiga The Annotated C++ Reference Manual, autori su Margaret A. Elis i Bjarne Stroustrup, ANSI standard je izdat 1997, jezik je proiren:
provera tipa objekta u toku izvrenja programa razraene generike funkcije i klase definisana biblioteka gotovih klasa i funkcija koje se esto koriste
6

Obrada programa na jeziku C++ pod operativnim sistemom MS Windows


Unoenje izvornog teksta programa u datoteku. Ekstenzije datoteka su:
.c, ako je napisana u jeziku C .cpp, ako je napisana u jeziku C++

Prevoenje izvornog teksta programa


ekstenzija datoteke je .obj

Povezivanje prevedenog oblika programa sa potrebnim korisnikim i sistemskim potprogramima u izvrni oblik
ekstenzija datoteke je .exe

Izvravanje programa

Prikazivanje algoritma
Algoritam je opis koraka koji se izvravaju u toku neke obrade Opis algoritma
govornim jezikom grafiki pomou dijagrama toka pomou pseudojezika pomou programskog jezika

Najjasnije je grafiko predstavljanje Vrste dijagrama toka


standardni dijagram toka strukturirani dijagram toka
8

Standardni dijagram toka


Orijentisani graf koji ima jednu poetnu i jednu zavrnu taku

Strukturirani dijagram toka


Podrava principe strukturiranog programiranja

10

Tipovi podataka

11

Elementi jezika C
Skup znakova Leksiki simboli Beli znaci Naredbe Direktive pretprocesora

12

Skup znakova
Mala i velika slova engleskog alfabeta
razlikuju se mala i velika slova

Deset decimalnih cifara Vei broj znakova interpunkcije

13

Leksiki simboli
Leksiki simboli su nedeljivi nizovi znakova
identifikatori konstante slubene rei operatori separatori

Leksiki simboli se piu spojeno ili razdvojeno belim znacima

14

Beli znaci
Beli znaci su
razmak tabulacija vertikalna tabulacija prelazak u novi red prelazak na novu stranicu

15

Komentari
Komentar u jednom redu
// Proizvoljan tekst do kraja reda

Komentar u proizvoljnom broju redova


/* tekst napisan u proizvoljnom broju redova */ /* moe i unutar jednog reda */

Komentari se mogu smatrati belim znacima

16

Naredbe
Naredbe su nizovi leksikih simbola Vrste naredbi
deklarativne naredbe slue za definisanje podataka, potprograma (funkcija), ... izvrne naredbe izvode elementarne obrade

17

Direktive pretprocesora
Pretprocesor je deo prevodioca koji koji priprema izvorni tekst programa pre samog prevoenja Direktive pretprocesora su uputstva kojima se utie na tok prevoenja programa
Nisu deo programa tj. nisu naredbe Piu se u posebnim redovima, prvi ne-beli znak je # Naredbe se ne piu u istom redu sa direktivom

Primer direktive pretprocesora: #define PI 3.14

18

Identifikatori
Identifikatori slue za oznaavanje
podataka simbolikih konstanti tipova podataka potprograma (funkcija) oznake koje su odredita za naredbe skoka

Identifikatori se sastoje od velikih i malih slova, cifara i znaka donja crta "_" (u Javi moe i "$!)
prvi znak ne moe biti cifra mogu da budu proizvoljno dugaki
po standardu najmanje 31 znak je znaajan

19

Primeri identifikatora
Ispravni identifikatori alfa a b356 c5a ime_i_prezime imeIprezime Neispravni identifikatori 3a // poinje cifrom int // rezervisana re x-z // operator nije dozvoljen
20

Tipovi podataka
Tipovi podataka odreuju osobine podatka:
skup moguih vrednosti podatka operacije koje mogu da se urade sa podatkom

Podaci se predstavljaju
vrednostima (konstantama) identifikatorima

21

Podaci predstavljeni konstantama


Ne mogu da se promene u toku izvravanja programa Konstante predstavljene identifikatorima se nazivaju simbolike konstante Konstante ne zauzimaju prostor u memoriji, ugraene su direktno u naredbe programa Pod terminom "podatak" nee se nadalje podrazumevati konstante

22

Podaci predstavljeni identifikatorima


Zauzimaju prostor u memoriji Vrednost podatka se smeta u prostor u memoriji Vrste podataka na osnovu mogunosti promene
Promenljivi podaci su najei oblik podataka koji se koriste Nepostojani podaci su podaci koji mogu da se menjaju izvan kontrole programa
npr. hardverski registri perifernih ureaja

Nepromenljivi podaci su podaci koji ne mogu da se menjaju


Razlika izmeu #define and const deklaracije kompajler prepoznaje identifikator deklarisan kao const
const int KONST=96;

23

Prosti i sloeni podaci


Prosti (skalarni, nestrukturirani) podaci ne mogu da se dele na manje delove koji mogu nezavisno da se obrauju (nemaju strukturu) Sloeni (strukturirani) podaci se sastoje od vie elemenata koji mogu biti prosti ili sloeni

24

Prosti tipovi podataka


U jeziku C postoje samo numeriki (prosti) tipovi podataka
celobrojni realni

Logiki tip podataka je uveden u C++


spada u grupu celobrojnih tipova

25

Celobrojni tipovi podataka


Celobrojni tipovi su char i int sa svojim varijantama int je osnovni celobrojni tip
oznaen je (ima pozitivne i negativne vrednosti) najbolje odgovara hardveru raunara obino je duine jedne mainske rei raunara

char je mali celobrojni podatak dovoljan da primi jedan znak iz skupa znakova koji se koriste na raunaru
standardom nije precizirano da li je oznaen

Modifikatori pomou kojih se dobijaju varijante tipova su


short long unsigned
26

Varijante tipa char


char tipino ima duinu jednog bajta
tipini opsezi vrednosti su
od 128 do 127 ako je oznaen od 0 do 255 ako je neoznaen

kodovi znakova su pozitivni

unsigned char je neoznaena varijanta tipa char


tipini opseg vrednosti je od 0 do 255

signed char je oznaena varijanta tipa char


tipini opseg vrednosti je od 128 do 127

27

Varijante tipa int


Varijante su oznaene Neoznaene varijante se dobijaju dodavanjem modifikatora unsigned Oznaene varijante
short int, tipina duina je 16 bita int, tipina duina je 16 ili 32 bita long int, tipina duina je 32 bita

Neoznaene varijante
unsigned short int unsigned int unsigned long int
28

Skraeno pisanje varijanti tipa int


U varijantama tipa int sa modifikatorima moe se izostaviti re int Ekvivalentno je korienje
short i short int long i long int unsigned short i unsigned short int unsigned long i unsigned long int

29

Realni tipovi podataka


float je realni podatak u jednostrukoj tanosti
broj tanih decimalnih cifara je 6 do 7

double je realni podatak u dvostrukoj tanosti


broj tanih decimalnih cifara je 15 do 16

long double je realni podatak u viestrukoj tanosti Raunari obino podravaju IEEE standard za brojeve IEEE 754

30

Standard IEEE 754, opsezi brojeva


Sa normalizovanom mantisom (eksponent 0) min float 2126 double 21022 max (2223)2127 (2252)21023 priblini opseg 1,171038 3,401038 2,2210308 1,7910308

Sa denormalizovanom mantisom (eksponent = 0) min float 2149 max (1223)2126 priblini opseg 1,401045 1,751038

double 21074 (1252)21022 4,9410324 2,2210308


31

Logiki tip podataka


Uveden je u C++ Celobrojni tip Tip bool ima dve vrednosti
false je logika neistina true je logika istina

32

Celobrojne konstante
Piu se u numerikim sistemima
decimalnom oktalnom heksadecimalnom

33

Decimalne celobrojne konstante


Prva cifra ne moe da bude 0 Moe se pisati predznak + ili
bez predznaka se podrazumeva +

34

Konstante u oktalnom numerikom sistemu


Osnova sistema je 8 Cifre su od 0 do 7 Prva cifra oktalne konstante mora da bude 0 Znak broja je odreen prvim bitom broja u binarnom numerikom sistemu Primeri 01 0145

35

Konstante u heksadecimalnom numerikom sistemu


Osnova sistema je 16 Cifre su od 0 do 9 i slova A, B, C, D, E, F
mogu se koristiti mala ili velika slova

heksadecimalna konstanta poinje sa 0x ili 0X Znak broja je odreen prvim bitom broja u binarnom numerikom sistemu Primeri 0x1a 0XCF05 0x2F3B 0xFFFFFFFF
36

Konstante varijanti celobrojnih tipova


Konstante su tipa int ako je celobrojna konstanta unutar opsega tipa int, inae je tipa long int Sufiks u ili U slui za neoznaene celobrojne konstante
Primeri: 1u, 06U, 0xFFu

Sufiks l ili L slui za celobrojne konstante tipa long int


Primeri za oznaeni tip long int: 1l, 024L, 0xFFL Primeri za neoznaeni tip long int: 1ul, 024UL, 0xFFUL
37

Realne konstante
Piu se u decimalnom numerikom sistemu Za vrlo velike i vrlo male brojeve koristi se zapis sa mantisom i eksponentom <mantisa>E<eksponent> Mantisa je decimalni broj sa decimalnom takom
mora da ima bar jednu cifru

Moe da se koristi malo ili veliko slovo e ili E Pojedini delovi mogu da nedostaju Da bi se razlikovale od ceolbronih konstanti mora da postoji ili decimalna taka ili E ili e

38

Realne konstante
Podrazumeva se tip double Za tip float dodaje se F ili f na kraju Za tip long double dodaje se L ili l na kraju Primeri: 1.23 1.2E5 1e5 .2e3 0.1F 3.1e3f Primeri neispravnih realnih konstanti: 1,23 1.a2 .1

39

Znakovne konstante
Piu se izmeu jednostrukih navodnika Primeri: 'A' 'a' '3' U jeziku C++ su tipa char, a u jeziku C su tipa int

40

Pridruivanje identifikatora tipovima podataka


Tipovima se mogu dodeliti sopstveni identifikatori naredbom opteg oblika typedef opis_tipa naziv_tipa; opis_tipa je tip kojem se dodeljuje identifikator
moe biti i tip koji je prethodno uveden naredbom typedef

naziv_tipa je identifikator koji se dodeljuje tipu iji je opis naveden Primeri: typedef unsigned int pozitivan; typedef pozitivan neoznacen;
Tipovi pozitivan i neoznacen su nova imena Podaci ovih tipova su u stvari istog tipa unsigned int
41

Definisanje podataka
Promenljivi podaci se definiu deklarativnom naredbom opteg oblika tip podatak = vrednost, podatak, ... ; tip je opis tipa podatak je identifikator podatka Podatku moe da se dodeli poetna vrednost navoenjem = vrednost
ako se ne dodeli poetna vrednost podatak e imati neku sluajnu vrednost zateenu u memoriji! neki podaci dobijaju poetnu vrednost 0

Dodeljivanje poetne vrednosti naziva se inicijalizacija Vrednost koja se dodeljuje naziva se inicijalizator
42

Primeri definisanja podataka


int i=0, pocetak, kraj=10; float duzina = 101.5; typedef unsigned int pozitivan; typedef pozitivan neoznacen; pozitivan alfa=0, beta=100; neoznacen a=alfa+beta;

43

Definisanje nepostojanih podataka


Nepostojani podaci su promenljivi podaci ija vrednost moe da se promeni u toku izvravanja programa izvan kontrole programa Definiu se modifikatorom volatile na poetku naredbe Primer: volatile int znak, v=4;

44

const
U jeziku C sa const se definiu nepromenljivi podaci
nepromenljivi podatak mora da se inicijalizuje ne moe da mu se promeni vrednost u toku izvravanja programa nije konstanta, tj. ne moe da se koristi na mestu gde se zahtevaju konstante

U jeziku C++ sa const se definiu simbolike konstante


mogu da se koriste na mestima gde se oekuju konstante

Primeri const int DIMENZIJA=100; const double e=2.71828182845905; const long dan=24L * 60 * 60;

45

Simbolike konstante u jeziku C


Definiu se direktivom define iji je opti oblik: #define IME_KONSTANTE vrednost_konstante IME_KONSTANTE je identifikator, obino se pie velikim slovima vrednost_konstante je konstanta standardnog tipa U jeziku C++ mogu da se koriste i simbolike konstante definisane direktivom define Primeri #define MIN 0 #define MAX 1000 #define PI 3.14159
46

Nabrojane konstante
Nabrojane konstante su simbolike konstante Dodeljuju im se vrednosti eksplicitno ili implicitno po redosledu Opti oblik naredbe je enum ime_nabrajanja { IME_KONSTANTE=vrednost, ... IME_KONSTANTE=vrednost } Nabrojane simbolike konstante su formalno tipa int

47

Nabrojane konstante
ime_nabrajanja je identifikator nabrajanja koji moe da se izostavi IME_KONSTANTE je identifikator konstante
svi identifikatori moraju biti razliiti

vrednost je vrednost koja se dodeljuje konstanti i moe da se izostavi


konstanta kojoj nije eksplicitno dodeljena vrednost dobija vrednost za jedan veu u odnosu na prethodnu konstantu u nabrajanu ako prvoj konstanti nije dodeljena vrednost ona dobija vrednost 0

48

Nabrojane konstante
Nabrojane konstante mogu da se koriste kao novi tip
u jeziku C mora se pisati i re enum u C++ moe se koristiti ime_nabrajanja bez enum ako ne postoji podatak sa tim imenom, inae se mora pisati i enum

49

Nabrojane konstante
Da ne bi morala da se pie re enum u jeziku C moe se koristiti naredba typedef oblika typedef enum { IME_KONSTANTE = vrednost, IME_KONSTANTE = vrednost, ... } Ime_tipa; ime_nabrajanja koje se pie iza rei enum se u ovom sluaju najee izostavlja, ali moe da se napie

50

Primeri za nabrojane konstante


enum { NE, DA }; enum KONSTANTE { C1=5, C2, C3=10, C4 }; enum meseci { JAN=1,FEB,MAR,APR,MAJ,JUN, JUL,AVG,SEP,OKT,NOV,DEC }; typedef enum { PON=1,UTO,SRE,CET,PET,SUB,NED } Dani; typedef enum meseci Meseci; Dani dan1 = PON;(bez enum) Dani dan2 = PON + 2; enum meseci mesec = JAN;(sa enum) Meseci mesec1 = FEB;
51

Ulaz i izlaz podataka


Preko tastature podaci se unose kao nizovi znakova tj. u tekstualnom obliku Na ekranu se podaci prikazuju u tekstualnom obliku Podaci u memoriji raunara su u binarnom obliku Prilikom unoenja podataka preko tastature tastature radi se ulazna konverzija Prilikom prikazivanja podataka na ekranu radi se izlazna konverzija

52

Ulaz i izlaz podataka u jeziku C


Za ulaz i izlaz podataka postoje biblioteke funkcije (potprogrami) Funkcija scanf se koristi za itanje podataka preko glavnog ulaza (tastature) i ulaznu konverziju podataka Funkcija printf se koristi za pisanje podataka preko glavnog izlaza (ekran) uz primenu izazne konverzije Deklaracije funkcija scanf i printf nalaze se u stdio.h

53

Skretanje glavnog ulaza i glavnog izlaza


Moe da se uradi skretanje glavnog ulaza (tastature) i glavnog izlaza (ekran) i da to postanu datoteke Pokretanje programa, glavni ulaz je tastatura, a glavni izlaz je ekran ime_programa Pokretanje programa sa skretanjem glavnog ulaza i glavnog izlaza ime_programa <glavni_ulaz >glavni_izlaz

54

Ulazna konverzija
Opti oblik funkcije scanf je: scanf(format, &arg1, &arg2, ... , &argN); format je tekstualni podatak oblika "tekst" koji odreuje ulazne konverzije koje se koriste
pojedinane konverzije su oblika %nq
% je oznaka za poetak konverzije n su dopunski parametri konverzije q je oznaka za vrstu konverzije

&arg su adrese promenljivih ije se vrednosti uitavaju


arg su identifikatori podataka koji se uitavaju & je operator za dohvatanje adrese podatka
55

Ulazna konverzija
Ulazni podaci su razdvojeni belim znakom, tj. podatak je niz znakova izmeu dva bela znaka itanje podatka se zaustavlja na prvom znaku iza proitanog podatka Broj znakova u jednom podatku
moe da bude proizvoljan moe da se nevede parametrom n (unutar %nq)
u ovom sluaju ne mora da beli znak izmeu dva podatka

Vrste ulaznih konverzija


za celobrojne podatke za realne brojeve
56

Konverzije za celobrojne podatke


Konverzije za tip int su: i, d, u, o, x
i je decimalna, oktalna ili heksadecimalna konverzija zavisno od oblika podatka na osnovu pravila pisanja d je decimalna konverzija u je decimalna konverzija za tip unsigned int o je oktalna konverzija (bez obzira na vodeu 0) x je heksadecimalna konverzija (bez obzira na 0x)

Za tipove short dodaje se znak h ispred oznake konverzije: hi, hd, hu, ho, hx Za tipove long dodaje se znak l ispred oznake konverzije: li, ld, lu, lo, lx
57

Konverzije za realne podatke


Konverzije za tip float su: f, e, g
ulazne konverzije su iste, izlazne se razlikuju

Za tip double dodaje se znak l ispred oznake konverzije: lf, le, lg Za tip long double dodaje se znak L ispred oznake konverzije: Lf, Le, Lg

58

Tok konverzije
scanf(format, &arg1, &arg2, ... , &argN); Analizira se format sleva udesno, znakovi razmaka i tabulacije se Kad se naie na opis konverzije vri se konverzija i rezultat se dodeljuje sledeem podatku iz liste itanje se zavrava kad se naie na kraj formata ili ako se desi greka Programer obezbeuje da broj opisa konverzije i broj podataka budu isti
ako je broj podataka vei od broja opisa, prekobrojni podaci nee dobiti vrednost ako je broj opisa vei od broja podataka posledice su nepredvidive

59

Dodatni znaci u formatu


U opisu konverzije mogu postojati dodatni znaci ita se po jedan znak za svaki dodatni iz opisa konverzije
moraju da budu isti ne radi se dodela vrednosti

Ako je dodatni znak %, piu se dva znaka %% umesto jednog, jer jedan znak oznaava poetak opisa konverzije

60

Primer uitavanja
int i; float f; double d; scanf("%i%f%lf", &i, &f, &d);

61

Izlazna konverzija
Opti oblik fukncije scanf je: printf(format, izraz1, ... , izrazN); format je tekstualni podatak oblika "tekst" koji odreuje izlazne konverzije koje se koriste
pojedinane konverzije su oblika % -+0#n.kq
prvi znak % je oznaka za poetak konverzije znaci -+0#n.k su dopunski parametri konverzije i ne moraju da postoje poslednji znak q je oznaka za vrstu konverzije

izrazi su numeriki izrazi ije se vrednosti ispisuju

62

Dopunski parametri konverzije -+0 #n.kq


znak n je celobrojna decimalna konstanta
oznaava najmanji broj znakova za ispisivanje ako je potrebno ispisuje se vie znakona od n, inae se sa leve strane dodaju prazni znaci

znak k razdvojen takom oznaava tanost prikazivanja podataka koja zavisi od vrste konverzije znak - oznaava poravnanje uz levu stranu znak + oznaava da treba da se ispie znak + ispred pozitivnog broja znak razmaka oznaava da treba da se ostavi jedno prazno mesto umesto znaka + znak 0 oznaava da se u sluaju ravnanja na desnu ivicu sa leve strane umesto praznih znakova ispisuju nule znak # oznaava alternativni nain ispisivanja koji zavisi od vrste konverzije 63

Parametar konverzije *
Umesto dopunskih parametara n i k moe da se stavi znak *
kao irina polja za ispisivanje uzima se vrednost sledeeg celobrojnog izraza meu argumentima funkcije printf

64

Konverzije za celobrojne podatke


Konverzije za tip int su: i, d, u, o, x, X Sve konverziju osim u se primenjuju za tipove int i unsigned int, a u se primenjuju za unsigned int
i, d oznaavaju decimalnu konverziju o oznaava oktalnu konverziju
vodea 0 se ispisuje ako postoji znak # u opisu konverzije

x, X oznaavaju heksadecimalnu konverziju, pri emu se cifre oznaene slovima se ispisuju malim ili velikim slovima
vodei 0x se ispisuje ako postoji znak # u opisu konverzije

Za tipove short dodaje se znak h, a za long znak l ispred oznake konverzije: hi, hd, hu, ho, hx, hX, odnosno li, ld, lu, lo, lx, lX Tanost k oznaava najmanj broj cifara
dodaju se vodee nule ako je potrebno
65

Konverzije za realne podatke


Konverzije za tip double su: f, e, E, g, G
f oznaava konverzije oblika ccc.cccccc
k oznaava broj decimalnih mesta, podrazumevano je 6, a za k=0 se ne ispisuje ni decimalna taka # oznaava obavezno ispisivanje decimalne take

e, E oznaavaju konverziju u eksponencijalni oblik c.ccccccexx ili c.ccccccExx


k oznaava ukupan broj cifara, podrazumeva se 6, a jedna nenulta cifra je uvek ispred decimalne take # oznaava obavezno ispisivanje decimalne take

konverzije g, G su iste kao e, E ako je eksponent vei od 4 ili vei ili jednak od tanosti, inae su iste kao f

Za tip long double dodaje se znak L ispred oznake konverzije: Lf, Le, LE, Lg, LG Konverzije za tip float su iste kao za double 66
tanost k treba da je primerena tipu float

Tok konverzije
printf(format, izraz1, ... , izrazN); Analizira se format sleva udesno, znakovi koji nisu deo opisa konverzije ispisuju se kako su navedeni Kad se naie na opis konverzije vri se konverzija sledeeg izraza i rezultat se ispisuje Ispisivanje se zavrava kad se doe do kraja formata Programer obezbeuje da broj opisa konverzije i broj podataka budu isti
ako je broj podataka vei od broja opisa, prekobrojni podaci se nee ispisati ako je broj opisa vei od broja podataka posledice su nepredvidive

Posledice su nepredvidive ako se ne slau vrsta konverzije i tip podatka

67

Znaci u formatu
Znak \n oznaava prelazak u novi red Ako je potrebno ispisati dodatni znak %, piu se dva znaka %% umesto jednog, jer jedan znak oznaava poetak opisa konverzije

68

Primeri ispisivanja
printf("Dobar dan!\n"); printf("Zapremina lopte poluprecnika %7.3f je %g\n", r, v); printf("Zbir brojeva %d i %d je %d\n", m, n, m+n); printf("Srednja vrednost je %*.*f\n", m, n, s);

69

Primer programa
Program ispisuje: Pozdrav svima! #include <stdio.h> main() { printf("Pozdrav svima!"); }

70

Primer programa
Primer programa koji uitava dva cela broja, sabira ih i ispisuje rezultat #include <stdio.h> main() { int a, b; printf("unesite dva cela broja: "); scanf("%d%d", &a, &b); int c = a + b; printf("Zbir unetih brojeva: %d\n", c); }
71

Operatori

72

Operatori i izrazi
Operator je radnja koja se izvrava nad operandima i daje rezultat Izraz je proizvoljno sloeni sastav operanada i operatora Izrazi su:
konstanta podatak operator izraz izraz operator izraz operator izraz izraz ? izraz : izraz ( izraz )
73

Tipovi operatora na osnovu broja operanada


Unarni Binarni Ternarni

74

Vrste operatora
Adresni operatori Aritmetiki operatori Relacijski operatori Operatori nad bitima Logiki operatori Operatori za dodelu vrednosti Operator zarez izraunava prvi operand i odbacuje rezultat, a zatim izraunava drugi operandi vraa tu vrednost. Poeljno kada su potrebni boni efekti. Primer:
int a = 1, b=2; i = a += 2, a + b; // increases a by 2, then stores a = 5 into i
75

Operatori
Prioritet 19 18 17 Broj Smer operanada grupisanja 1, 2 2 1 :: [] () . -> Operatori

a++ a-static_cast const_cast dynamic_cast reinterpret_cast typeid ! ~ ++a --a + - * & (tip) sizeof new delete .* * + << ->* / >>
76

16 15 14 13 12

1 2 2 2 2

Operatori
Prioritet 11 10 9 8 7 6 5 4 3 2 1 Broj operanada 2 2 2 2 2 2 2 3 2 1 2 Smer grupisanja < == & ^ | && || ?: = &= , += ^= -= |= *= /= %= <<= >>= <= != Operatori > >=

throw
77

Unarni aritmetiki operatori + i + vrednost operanda bez promenene znaka vrednost operanda sa promenjenim znakom

Prefiksni operatori Prioritet je 16 Grupisanje je zdesna ulevo

78

Unarni aritmetiki operatori ++ i -++ uveavanje za jedan umanjivanje za jedan

Operatori mogu biti prefiksni i postfiksni Za postfiksne operatore


prioritet je 17 smer grupisanja nije definisan

Za prefiksne operatore
prioritet je 16 smer grupisanja je zdesna ulevo
++k k++ j = --k j = k-// // // // k=k+1 k=k+1 k=k1, j=k j=k, k=k-1

79

Binarni aritmetiki operatori


+ * / % zbir razlika proizvod kolinik ostatak deljenja dva broja

Grupisanje je sleva udesno Prioritet je:


14 za *, /, % 13 za +, -

80

Primeri osnovnih operacija


int int int int int int a b c g d e = = = = = = 1 + a * b / b % c -d; = = = g = = 1; 3; 4; 4; a; // // // // // // 1; 3; 4; % 4; a; a b c g d e = = = = = = 2 6 1 2 -1 1

double a double b double c //double double d double e

1 + a * b / = b c -d;

// a = 2 // b = 6 // c = 1.5 //greka, definisan za celobrojne tipove // d = -1 // e = 1


81

Boni efekat
Boni efekat je promena vrednosti nekog operanda operatora u toku izvravanja operatora Primer j = --k; --k;

// k = k - 1, j = k // k = k - 1

82

Aritmetiki operatori dodeljivanja


izraz1 = izraz2; izraz1 operator= izraz2; //izraz1 = izraz1 operator izraz2; Operatori su += -= *= /= %= Prioritet je 3 Grupisanje zdesna ulevo
83

Primeri aritmetikih operatora za dodeljivanje


a = b = c = d + 5; b = b % c; b %= c; d = d + e * f; d += e * f; a = b++ + 3*(c=d-3); //a = b++ + 3*c=d-3;// greka

84

Lvrednost
Lvrednost je vrednost koja oznaava podatak u memoriji, odnosno moe da se nalazi na levoj strani operatora za dodelu vrednosti Neki operatori se primenjuju samo na lvrednosti
operandi operatora ++, --, & operandi na levoj strani operatora za dodelu vrednosti

Rezultat nekih operatora je lvrednost


operatora za posredni pristup * i indeksiranje [ ] prefiksnih operatora ++ i svih operatora za dodelu vrednosti rezultat ternarnog operatora ?: je lvrednost ako su drugi i trei operand isttog tipa i ako su oba lvrednosti
85

Primeri za lvrednosti
++ ++k; // ++(++k) ili k=k+2 --k*=5; // (--k)*=5 ili k=(k-1)*5 k++ ++; // greka d*=e+=f; // e=e+f, d=d*e (d*=e)+=f; // d=d*e, d=d+f ili d=d*e+f x=y=5; // x=(y=5) ili y=5, x=y ++(p/=q); // p=p/q, p=p+1 ili p=p/q+1 ++p/=q; // p=p+1, p=p/q ili p=(p+1)/q long x=5; int a,b; x ? a : b = 1; // x ? a=1 : b=1 x ? x : b = 1; // greka x ? 2 : b = 1; // greka
86

Konverzija tipa
Binarni operatori se izvravaju nad operandima istih tipova Za operande razliitih tipova radi se automatska konverzija
Oprez: kompajler ne upozorava tako striktno kao kod Jave mogue nenamerne greke.

Pravilo za automatska konverziju tipa: tip operanda jednostavnijeg tipa se pretvori u tip operanda sloenijeg tipa i posle toga se izraunava rezultat operatora Neoznaena varijanta istog tipa je sloenija od oznaene varijante

87

Automatska konverzija tipa


ako je jedan operand tipa long double, i drugi se pretvori u tip long double; inae, ako je jedan operand tipa double, i drugi se pretvori u tip double; inae, ako je jedan operand tipa float, i drugi se pretvori u tip float; inae, ako je bilo koji od operanada tipa char ili short pretvori se u tip int, ili ako je jedan operand tipa unsigned char ili unsigned short pretvori se u tip unsigned, (po potrebi se oba pretvore u tip int ili unsigned;

88

Automatska konverzija tipa - nastavak


posle, ako je jedan operand tipa unsigned long, i drugi se pretvori u tip unsigned long; inae, ako je jedan operand tipa long, i drugi se pretvori u tip long; inae, ako je jedan operand tipa unsigned, i drugi se pretvori u tip unsigned Tip rezultata je uvek bar tip int ili unsigned Primeri
5/4*3. 3.*5/4 // (5/4)*3.= 1*3. = 1.*3. = 3. // (3.*5)/4= (3.*5.)/4= 15./4= 15./4.= 3.75

89

Automatska konverzija tipa kod dodele vrednosti


Tip operanda sa desne strane se pretvara u tip operanda sa leve strane oprez! Realni podatak se konvertuje u celobrojni odsecanjem razlomljenog dela Pretvaranje kraeg celobrojnog podatka u dui
za oznaene tipove proiruje se predznak za neoznaene tipove dodaju se nule sa leve strane

90

Konverzija logikog tipa u C++


Automatska konverzija u izrazima iz tipa bool u numeriki tip (ne moe u Javi!)
false se konvertuje u celobrojnu vrednost 0 true se konvertuje u celobrojnu vrednost 1

Dodela vrednosti numerikog podatka promenljivoj tipa bool


vrednost 0 se pretvara u false vrednost razliita od 0 se pretvara u true

Na mestima gde se oekuju logike vrednosti mogu da se piu numeriki podaci Primer: int i; if( i ) ...

91

Eksplicitna konverzija tipa


Pretvaranje u eljeni tip se radi unarnim prefiksnim cast operatorom (unutar zagrada se napie ime tipa u koji se pretvara) ( ime_tipa ) Primeri: (double)a (unsigned int) a+b //((unsigned int)a)+b

92

Relacijski operatori (operatori poreenja)


> < >= <= == != Vee Manje Vee ili jednako Manje ili jednako Jednako Razliito

Operandi su numerikog tipa, rezultat je logikog tipa Operatori >, <, >=, <= imaju prioritet 11 Operatori == i != imaju prioritet 10 Grupisanje je sleva udesno
93

Primeri za operatore poreenja


int a=1, b=4; bool c = a < b; // c ima vrednost true 8 == 13>5; // 8==(13>5), 8==1, false a < b < 5; // (a<b)<5, (true ili false)<5, true Primeri za operande razliitih tipova
-1L < 1U // // // // -1L < 1UL 0xFFFFFFFFL < 0x00000001U 0xFFFFFFFFL < 0x00000001L rezultat je true, long je sloeniji tip od unsigned (tj. nema konverzije)

// 0xFFFFFFFFL < 0x00000001UL // 0xFFFFFFFFUL < 0x00000001UL // rezultat je false, unsigned long je sloeniji tip od long (tj //dolazi do konverzije prvog operanda)

94

Logiki operatori
! Logika negacija Prefiksni unarni operator Prioritet je 16 Grupisanje zdesna ulevo && || Logiko i Logiko ili

Binarni operator Prioritet operatora && je 6, a operatora || je 5 Grupisanje je sleva udesna


95

Tabela logikih operatora

false true

true false

&& false true

false false false

true false true

|| false true

false false true

true true true

96

Uslovni izraz ?:
Opti oblik je uslov ? izraz1 : izraz2 Primeri (a > b) ? a : b // max(a, b) (x<=y && y<=z) ? y : (x+z)/2 a<b ? -1 : a>b ? 1 : 0 a<b ? -1 : (a>b ? 1 : 0)

97

Operatori po bitima
Operacije se izvode nad bitima unutar podataka celobrojnih tipova i rezultat je celobrojnog tipa Vrste operatora po bitima
logike operacije nad bitima odgovarajuih pozicija pomeranje bita

98

Logike operacije po bitima


Prefiksni unarni operator ~ komplementiranje po bitima (prioritet 16) Binarni operatori & logika "i" operacija nad bitima (prioritet 9) | logika "ili" operacija nad bitima (prioritet 8) ^ logika "iskljuivo ili" operacija nad bitima (prioritet 7)

99

Logike operacije po bitima

0 1

1 0

| 0 1

0 0 1

1 1 1

& 0 1

0 0 0

1 0 1

^ 0 1

0 0 1

1 1 0

100

Primeri za operatore nad bitima


~ 00101010 11010101 00101010 & 00001111 00001010 42 43 42 15 10 00101010 | 00001111 00101111 00101010 ^ 00001111 00100101 42 15 47 42 15 37

101

Operatori za pomeranje po bitima


Binarni operatori za pomeranje levog operanda za onoliko bita koliko iznosi desni operand << pomeranje ulevo >> pomeranje udesno nema >>> kao u Javi jer postoje oznaeni i neoznaeni tipovi Prioritet je 11 Grupisanje je sleva udesno Rezultat je nedefinisan ako je desni operand negativan ili je vei od broja bita u levom operandu
102

Operatori za pomeranje po bitima


Pri pomeranju ulevo sa desne strane se dodaju nule Pri pomeranju udesno sa leve strane se dodaju
za neoznaene (unsigned) tipove dodaju se nule (logiko pomeranje) za oznaene tipove dodaju se biti koji su jednaki predznaku opearnda (aritmetiko pomeranje)

103

Operatori po bitima i dodela vrednosti


Za binarne operatore za rad po bitima postoje i operatori za dodelu vrednosti &= ^= |= <<= >>= Prioritet je 3 Grupisanje zdesna ulevo

104

Primeri za pomeranje ulevo


vrednost << broj_bita_za_koliko_se_pomera; Sa desne strane se dodaju nule Biti sa leve strane se gube Primer:
int i int p p = p p =<< = 1 << 3; = 0x7FFFFFFF; << 1; 1; // // // // i p p p dobija vrednost 8 ima vrednost najveeg int je 0xFFFFFFFE tj. -2 je 0xFFFFFFFC tj. -4

Pomeranje ulevo za N bita odgovara mnoenju sa 2N, pod uslovom da ne doe do promene znaka broja
105

Pomeranje udesno za oznaene tipove


vrednost >> broj_bita_za_koliko_se_pomera;

Pri pomeranju se uva znak, tj. sa leve strane se dodaje bit jednak bitu koji je prethodno bio na poziciji 31 Biti sa desne strane se gube Primer:
int a a = a a >>= int b b = b b >>= b >>= = 35; >> 2; 4; = -8; >> 2; 1; // 1; // // a = 0...0 00100011 // a = 0...0 00001000 (tj. a=8) // a = 0...0 00000000 (tj. a=0) // b = 1...1 11111000 // b = 1...1 11111110 (tj. b=-2) b = 1...1 11111111 (tj. b=-1) b = 1...1 11111111 (b ostaje -1)
106

Pomeranje udesno za neoznaene tipove


vrednost >> broj_bita_za_koliko_se_pomera;

Sa leve strane se dodaju nule Biti sa desne strane se gube Primer:


unsigned k = 0xFFFFFFFF; // k je najvei unsigned k = k >> 1; // 0x7FFFFFFF k >>= 23; // 0x000000FF (k je 255)

107

Primeri za operacije nad bitima


022222 & 055555 // =000000, operator po bitima 022222 && 055555 // =true, logiki operator

108

Niz izraza
Izrazi mogu da se sastave u niz izraza pomou binarnog operatora zarez (,), pri emu se niz izraza ponaa kao jedan izraz Binarni operator zarez (,) je prioriteta 1 i grupie se sleva udesno Primer a=5, b+=13, c++ x=3, y*=x+3, x--, z-=x*3- --y Zbog smera grupisanja i izrazi se izraunavaju sleva udesno u sluaju da ima vie uzastopnih operatora zarez Rezultat koji vraa niza izraza je vrednost poslednjeg izraza (krajnji desni koji se poslednji izraunava)
109

Korienje zagrada
Zagrade slue za definisanje redosleda izraunavanja (prioriteta) i za pisanje jasnijih izraza
a >> b + 3; // prvo se b uveava za 3, // zatim se sadraj a pomera udesno // ("+" ima vei prioritet od ">>") a >> (b + 3); // ekvivalentno gornjem (a >> b) + 3; // prvo se sadraj a pomera udesno, // zatim se uveava za 3

110

Veliina podataka
Operator sizeof je prefiksni unarni operator koji izraunava veliinu memorije, izraenu u bajtovima, koja je potrebna za smetanje podatka nekog tipa Operand je izraz ili identifikator tipa Ako je operand identifikator tipa stavlja se u zagradama Primeri sizeof(char) sizeof(long double) Tip rezultata je size_t koji je celobrojni tip definisan naredbom typedef u fajlu <stddef.h> Standardom nije precizirano kojeg celobrojnog tipa je size_t
111

Biblioteke funkcije
Funkcije na osnovu svojih argumenata daju rezultate Funkcije mogu da imaju neogranien broj argumenata Opti oblik pozivanja funkcije je
identifikator_funkcije(argument, ... , argument)

Ako su argumenti izrazi, izraunavaju se pre pozivanja funkcije po proizvoljnom redosledu U sastavu jezika je standardna biblioteka sa velikim brojem standardnih funkcija Funkcije su deklarisane u datotekama zaglavlja (header), i imaju ekstenziju *.h

112

Korienje bibliotekih funkcija


Na poetku datoteke sa izvornim kodom se napie direktiva include sa imenom *.h datoteke koja e se koristiti Opti oblik je #include <naziv_datoteke>

113

Biblioteka matematikih funkcija


Matematike funkcije su deklarisane u datoteci <math.h>

114

Naredbe

115

Naredbe
Naredba je osnovna jedinica obrade u programu Proste naredbe ne mogu da se podele na manje delove koji su takoe naredbe Sloene naredbe su strukture narebi (upravljake strukture) koje odreuju redosled izvravanja naredbi u strukturi. Dele se na:
sekvence selekcije cikluse (petlje)

Upravljake naredbe ne vre obradu, ve prenose tok upravljanja na neko drugo mesto (skokovi)
116

Naredbe
Deklarativne naredbe deklarisanje tipova podataka Izvrne naredbe

117

Prosta naredba
Opti oblik je izraz; Prazna naredba se koristi kada sintaksa jezika zahteva naredbu, a nije potrebna nikakva obrada ;

118

Sekvenca (blok)
Niz naredbi koje se izvravaju jedna za drugom Opti oblik sekvence je { naredba1 naredba2 ... naredbaN } Moe da se pie i u jednom redu { naredba1 naredba2 ... naredbaN } Moe da bude prazna { }
119

Primer sekvence
int a, b; ... { int t; t = a; a = b; b = t; } ili u jednom redu { t=a; a=b; b=t; }
120

Doseg identifikatora (oblast vaenja)


Oblast vaenja je deo programa u kojem identifikator moe da se koristi Blokovski doseg za identifikatore deklarisane unutar bloka: identifikator moe da se koristi od mesta gde je deklarisan do kraja bloka u kojem je deklarisan Primer
{ int x = 5; double y = x / 2.; printf("x=%d, y=%f\n", x, y); }

121

Uklapanje dosega
Unutar jednog bloka (spoljanji) moe da se nalazi drugi blok (unutranji) U unutranjem bloku mogu da se koriste identifikatori definisani u spoljanjem bloku, oni su globalni za unutranji blok Identifikatori definisani u unutranjem bloku su lokalni za taj blok, i ne mogu da se koriste izvan njega U unutranjem bloku se moe definisati identifikator koji ima isto ime kao i identifikator iz spoljanjeg bloka, i na taj nain identifikator iz spoljanjeg bloka postaje nevidljiv u unutranjem bloku

122

Primer uklapanja dosega


{ double x = 0.5; printf("x=%f\n", x); { int x=0; { int a=1, b=2; x = a * b; } printf("x=%d\n", x); } printf("x=%f\n", x); } x=0.500000 x=2 x=0.500000

123

Selekcije
if-else switch

124

Osnovna selekcija if-else


Uslovno izvravanje jedne od dve mogue naredbe Opti oblik if(uslov) naredba1 else naredba2 uslov je izraz logikog tipa naredba je jedna naredba ili blok naredbi deo else nije obavezan Izvravanje
ako uslov vrati vrednost true izvrava se naredba1 inae se izvrava naredba2 (ako else deo postoji) 125

Primeri za if
if(a < b) a = 0; else b = 0; if(a > b) { t=c; c=a; a=t; } else { t=c; c=b; b=t; } if(a > b) { t=a; a=b; b=t; }
126

Uklapanje selekcije if-else


if(uslov1) if(uslov2) naredba1 else naredba2 Deo else se uvek odnosi na poslednji if ispred njega

127

Primer za uklapanje selekcije if-else


if(i == 10) { if(j < 20) a = b; if(k > 100) c = d; else a = c; // ovaj else se odnosi na uslov if(k > 100) } else a = d; // ovaj else se odnosi na uslov if(i == 10)

128

if else if
if(uslov1) naredba1; else if(uslov2) naredba2; else if(uslov3) naredba3; else if(uslov4) naredba4; else naredba5; if(uslov1) naredba1; else if(uslov2) naredba2; else if(uslov3) naredba3; else if(uslov4) naredba4; else naredba5;
129

Naredba switch
Grananje u vie putanja zavisno od vrednosti izraza Opti oblik
switch(izraz) { case vrednost1: niz_naredbi1 case vrednost2: niz_naredbi2 ... default: niz_naredbiD ... case vrednostN: niz_naredbiN }
130

Naredba switch
izraz je celobrojni izraz Svaka od vrednosti je celobrojna konstanta Ne sme se ponoviti ista vrednost u istom switch Sa break se zavrava switch Ako ne postoji break nastavlja se izvravanje sledeeg case Deo default je opcioni i oznaava mesto na koje se skae ako vrednost izraza nije jednaka nijednoj od vrednosti u oznakama case

131

Prekidanje naredbe switch


Naredba switch se moe prekinuti naredbom break, i taj oblik naredbe switch se ee koristi
switch(izraz) { case vrednost1: case vrednost2: niz_naredbi1; break; niz_naredbi2; break; ... niz_naredbiN; break; ... niz_naredbiN; break;
132

default:

case vrednostN: }

Primer za switch
switch(i + j * k) { case 0: printf("Unseite 3 cela broja:"); scanf("%d%d%d", &i, &j, &k); case 7: case 3: case 5: a = i + j * k; b = i j / k; default: c = a * b; case 12: printf("Rezultati su: %d %d %d", a, b, c ); }

133

Uklopljena naredba switch


switch (izraz_spoljasnjeg_switch) { case 1: switch (izraz_unutrasnjeg_switch) { case 0: a=0; break; case 1: b=0; break; } break; case 2: ... }

134

Poreenje if i switch
switch proverava samo jednakost, a if proizvoljan logiki izraz switch je efikasniji od ugnjedenih if else if

135

Ciklusi (petlje)
Izvravanje (ponavljanje) jedne naredbe ili bloka naredbi potreban broj puta, zavisno od uslova Naredbe ciklusa (petlje)
while do while for

136

Petlja while
Opti oblik while petlje while(uslov) telo_petlje uslov je proizvoljan logiki izraz telo_petlje je jedna naredba (moe biti i prazna naredba) ili blok naredbi telo_petlje se ponavlja sve dok uslov ima vrednost true while petlja je sa izlazom na vrhu, ako uslov ima vrednost false pri prvoj proveri, ne ulazi se u petlju, tj. telo_petlje se ne izvrava nijednom
137

Primer za while petlju


int n = 5; // Za n=0 petlja se ne bi izvrila nijednom while(n > 0) { printf("Vrednost n je %d\n", n); n--; }

Vrednost n je 5 Vrednost n je 4 Vrednost n je 3 Vrednost n je 2 Vrednost n je 1


138

Primeri za while petlju: zbir n brojeva


int s=0, i=1; while(i<n) { s += i; i++; } int s=0, i=1; int s=0, i=1; int s=0, i=1; int s=0, i=1;

while(i<n) { s += i; i++; } while(i<n) { s += i++; } while(s+=i++, i<=n) ; // Nije lepo while(++i<n) { s += i; }

139

Petlja do while
Opti oblik do while petlje do telo_petlje while(uslov); uslov je proizvoljan logiki izraz telo_petlje je jedna naredba ili blok naredbi do while petlja je sa izlazom na dnu:
telo_petlje se izvrava jednom a posle toga se proverava uslov ako uslov ima vrednost true, telo_petlje se izvrava ponovo, a ako je vrednost false izlazi se iz petlje

140

Primer za do while
int n = 5; // Za n=0 petlja bi se izvrila jednom do { printf("Vrednost n je %d\n", n); n--; } while(n > 0); Vrednost n je 5 Vrednost n je 4 Vrednost n je 3 Vrednost n je 2 Vrednost n je 1 Za n=0 rezultat bi bio Vrednost n je 0

141

Krae napisan primer za do while


int n = 5; do printf("Vrednost n je %d\n", n); while(--n > 0); Vrednost n je 5 Vrednost n je 4 Vrednost n je 3 Vrednost n je 2 Vrednost n je 1

142

do while petlja: zbir kvadrata n brojeva


int s=0, i=1; do { s += i * i; i++; } while(i<n); int s=0, i=1; do { s+=i*i; i++; } while(i<n); int s=0, i=1; do s+=i*i; while(++i<n); int s=0, i=1; do ; while (s+=i*i, i++<=n); //Loe

143

Generalizovani ciklus sa izlazom na vrhu: for


U praksi su este petlje sa sledeom strukturom
postavljanje poetne vrednosti jedne ili vie promenljivih pre ulaska u petlju ispitivanje da li treba izvravati sadraj petlje pre svakog prolaska kroz petlju menjanje vrednosti jedne ili vie promenljivih na kraju svakog prolaska kroz petlju

144

Petlja for
inicijalizacija je izraz
izvrava se samo jednom na poetku pre ulaska u petlju obino inicijalizuje jednu ili vie promenljivih petlje

uslov je logiki izraz, proverava se pre izvravanja tela petlje


ako je vrednost true izvrava se telo petlje ako je false ne izvrava se telo petlje i izlazi se iz petlje obino zavisi od upravljake promenljive petlje

telo_petlje je jedna naredba ili blok naredbi iteracija je izraz


izvrava se posle tela petlje obino menja jednu ili vie upravljakih promenljivih petlje

Petlja se nastavlja proverom uslova i izvravanjem tela petlje i iteracije sve dok je uslov taan 145

Naini pisanja for petlje


for(inicijalizacija; uslov; iteracija) naredba for(inicijalizacija; uslov; iteracija) naredba for(inicijalizacija; uslov; iteracija) { naredba1 ... naredbaN } for(inicijalizacija; uslov; iteracija) { naredba1 ... naredbaN }
146

Nain pisanja
Smatra se loim programerskim stilom ako se u jedan ili vie delova petlje: inicijalizacija, uslov, iteracija, stavljaju radnje koje se ne odnose na opsluivanje petlje

147

Primeri za for
for(i=pocetak; i<kraj; i+=korak) {...} for(i=pocetak; i<kraj; i++) {...} for(i=pocetak; i>=kraj; i--) {...} for(s=0, i=1; i<=n; i++) s+=i*i; for(s=0, i=1; i<=n; s+=i*i, i++) ; // Loe for(s=0, i=1; i<=n; i++) s+=i; for(s=0, i=1; i<=n; s+=i++) ;

// Moe

148

Primer za for
int n; for(n=5; n>0; n--) printf("Vrednost n je %d\n", n); Vrednost n je 5 Vrednost n je 4 Vrednost n je 3 Vrednost n je 2 Vrednost n je 1

149

Deklaracija promenljive unutar for petlje


Upravljaka promenljiva petlje se esto deklarie unutar petlje u delu inicijalizacija Takva promenljiva postoji samo unutar petlje for(int n=5; n>0; n--) printf("Vrednost n je %d\n", n);

150

Vie upravljakih promenljivih for petlje


U inicijalizaciji se moe deklarisati i inicijalizovati vie upravljakih promenljivih petlje U iteraciji se moe menjati vie promenljivih Izrazi u inicijalizaciji i iteraciji se razdvajaju zarezima for(int a=1, b=4; a<b; a++, b--) printf("a = %d\nb = %d", a, b);
a=1 b=4 a=2 b=3
151

Uslov ne zavisi od upravljake promenljive for petlje


bool kraj = false; for(int i=0; !kraj; i++) { printf("i je %d", i); if(i == 5) kraj = true; } i je 0 i je 1 i je 2 i je 3 i je 4 i je 5
152

for petlja bez inicijalizacije i iteracije


Delovi for petlje inicijalizacija ili iteracija, ili oba dela, mogu da se izostave boolean kraj = false; int i = 0; for( ; !kraj; ) { printf("i je %d", i); if(i == 5) kraj = true; i++; }
153

Beskonana for petlja


for( ; ; ) { // ... if(uslov) break; // ... }

154

Ugnedene for petlje


for(int i=0; i<5; i++) { for(int j=i; j<5; j++) printf("%d", i); printf("\n"); } 00000 1111 222 33 4
155

Trajnost podataka
Prema intervalu vremena u kojem podaci postoje u toku izvravanja programa podaci mogu biti:
prolazni trajni privremeni

156

Prolazni podaci
Stvaraju se naredbom za definisanje
dodeljuje im se prostor u memoriji inicijalizator se svaki put izvrava imaju sluajnu vrednost ako nisu inicijalizovani unitavaju se pri naputanju dosega njihovog identifikatora

Primer { int t=0; int a; ... }


157

Modifikatori za prolazne podatke


Dodaju se na poetku naredbe za definisanje auto
moe se dodati da bi se naglasila prolaznost podataka, i zato se prolazni podaci nazivaju i automatski podaci

register
sugerie prevodiocu da se podaci smeste u brze procesorske registre koriste se npr. za promeljive koje se koriste u najdubljoj petlji kad postoji nekoliko uklopljenih petlji nije sigurno da e prevodilac to i uraditi

158

Primeri korienja modifikatora


{ register int t=0; auto int a; ... }

159

Trajni podaci (static)


Stvaraju se prilikom prvog pozivanja naredbe za definisanje Inicijalizatori se izvravaju samo jednom Ako inicijalizatori ne postoje promenljive imaju poetnu vrednost nula Unitavaju se pri zavravanju programa Da bi podatak postao trajni, na poetak naredbe za definisanje dodaje se modifikator static Ovi podaci se zovu i statiki podaci

160

Primer definisanja statikih podataka


{ static int t=0; // Inicijalizacija je suvina static int a; ... }

161

Privremeni podaci
Slue za odlaganje meurezultata sloenih izraza Stvara ih prevodilac tako da programer ne zna za njihovo postojanje Unitavaju se automatski kad vie nisu potrebni

162

Razlika dosega i trajnosti podatka


Doseg odreuje deo programa u kojem podatak moe da se koristi Trajnost odreuje vreme koliko dugo podatak postoji Trajni podaci postoje i kad se izvravaju delovi programa izvan njihovog dosega, ali u tim delovima programer ne moe da ih koristi Za privremene podatke doseg i trajnost se u izvesnom smislu poklapaju

163

Mesto definisanja podataka


Podatke je najbolje definisati najblie mestu gde se koriste
npr. unutar najmanjeg bloka koji obuhvata sva mesta na kojima se podatak koristi

Tipovi podataka, npr. definisani sa typedef, obino se koriste u veem delu programa
definiu se u *.h fajlu ili na poetku fajla

164

Naredbe skoka
Slue za prekidanje izvravanja redosleda naredbi i nastavljanje na definisanom mestu, tj. slue za preskakanje naredbi
break continue return

Naredbe skoka nemaju strukturu, pa nisu upravljake strukture Naredbe skoka ne vre nikakvu obradu pa nisu proste naredbe

165

Naredba break
Slui za iskakanje iz upravljake strukture
preskakanje preostalih naredbi unutar naredbe switch i skakanje na prvu naredbu iza naredbe switch prevremeni zavretak petlje (for, while, do) i skakanje na prvu naredbu iza naredbe
uobiajeno je da se iz petlje izlazi na osnovu uslova

Prekida samo jednu upravljaku strukturu

166

Selekcija alternativnih grana


int godina, mesec, broj_dana; ... switch(mesec) { case 1: case 3: case 5: case 7: case 8: case 10: case 12: broj_dana = 31; break; case 4: case 6: case 9: case 11: broj_dana = 30; break; case 2: broj_dana = 28 + (godina%4==0 && godina%100!=0 || godina%400==0); break; default: broj_dana = -1; break; }
167

Izlazak iz for petlje sa break


for(int i=0; i<100; i++) { if(i == 5) break; // prekidanje petlje kad je i=5 printf("i: %d\n", i); } printf("Petlja je zavrena.\n"); i: 0 i: 1 i: 2 i: 3 i: 4 Petlja je zavrena.
168

Izlazak iz while petlje sa break


int i=0; while(i<100) { if(i == 5) break; // prekidanje petlje kad je i=5 printf("i: %d\n", i); i++; } printf("Petlja je zavrena.\n");
i: 0 i: 1 i: 2 i: 3 i: 4 Petlja je zavrena
169

break u uklopljenim strukturama


for(int i=0; i<9; i++) { switch(i) { case 0: printf("i = 0\n"); case 1: case 2: printf("i < 3\n"); break; case 3: case 4: printf("i < 5\n"); break; default: printf("i >= 5\n"); } int n = 0; ... }

170

break u uklopljenim strukturama


break prekida samo najdublje ugnjedenu petlju u kojoj se nalazi
for(int i=0; i<3; i++) { printf("i = %d; j:", i); for(int j=0; j<100; j++) { if(j == 10) break; // prekida unutranju petlju za j=10 printf(" %d", j); } printf("\n"); } printf("Petlja je zavrena.\n");
i = 0; j: 0 1 2 3 4 5 6 7 8 9 i = 1; j: 0 1 2 3 4 5 6 7 8 9 i = 2; j: 0 1 2 3 4 5 6 7 8 9 Petlja je zavrena.

171

Naredba continue
Opti oblik petlja { ... continue; ... } Slui za preskakanje naredbi do kraja tela petlje i na prelazak na naredbe za opsluivanje tela petlje
u while i do while petljama posle continue se prelazi na proveru uslova u for petlji posle continue se prelazi na iteraciju
172

Naredba continue
Naredba continue se obino nalazi unutar naredbe if ili switch, inae se naredbe iza continue nikad ne bi izvravale
Primer petlja { ... if(uslov) continue; ... }

173

Primer za continue
for(int i=0; i<10; i++) { printf("%d ", i); if(i%2 == 0) continue; printf("\n"); }

01 23 45 67 89
174

Skok sa proizvoljnim odreditem


Opti oblik naredbe goto je: goto oznaka; Oznaka je odredite skoka
pie se po pravilima pisanja za identifikator oznaka ima funkcijski doseg

Naredba na koji se skae obeleava se oznakom koja se pie ispred naredbe oznaka: naredba Odredite skoka moe biti na bilo kojem mestu
uskakanje u blok nije zabranjeno, ali treba smatrati kao da jeste naredba goto se moe koristiti npr. da se prekine vie uklopljenih struktura 175

Primer za goto
for(...){ for(...){ for(...){ ... if(propast) goto greska; ... } } } greska: // obrada greke
176

Naredba return
Opti oblik tip ime_metode(lista_parametara) { ... if(uslov) return [vrednost]; ... } Slui za izlazak iz metode Posle naredbe return kontrola se vraa pozivaocu metode Naredba if je se najee pie ako naredba return nije poslednja naredba u metodi, inae se naredbe iza naredbe return nikad ne bi izvravale vrednost ne postoji ako je tip metode void, inae postoji
177

Nizovi

178

Nizovi
Sloeni (strukturirani) tipovi podataka Slue za predstavljanje vektora, matrica, viedimenzionalnih nizova Predstavljaju niz podataka istog tipa koji se nazivaju elementi niza Elementi niza se identifikuju pomou rednog broja unutar niza koji se naziva indeks Indeksiranje uvek poinje od nule, tj. prvi element niza uvek ima indeks 0

179

Nizovi
Imaju jednu ili vie dimenzija Jednodimenzionalni niz (vektor) ima skalarne elemente Dvodimenzionalni niz (matrica) je niz iji su elementi jednodimenzionalni nizovi

180

Definisanje nizova
Opti oblik je:
tip identifikator_niza [duina1][duina2]...[duinaN]

Duina mora da bude konstantan izraz Primer float vektor[50], matrica[10][20], x; Elemenit niza vektor imaju indekse od 0 do 49 Dvodimenzionalni niz matrica ima 10 vrsta i 20 kolona, indeksi vrsta su od 0 do 9, a kolona od 0 do 19

181

Inicijalizacija niza
Pri definisanju niza mogu da se navedu poetne vrednosti tj. inicijalizatori Nizovi sa inicijalizatorima su uvek trajni Inicijalizator niza je oblika: { vrednost1, vrednost2, ... vrednostN } Primeri:
int dani[12] = {31,28,31,30,31,30,31,31,30,31,30,31}; int dani[] = {31,28,31,30,31,30,31,31,30,31,30,31}; long a1[5] = { 1, 2, 3 }; long a2[5] = { 1, 2, 3, 0, 0 }; // iste vrednosti ima i niz a1 long a3[5] = { 1, 2, 3, 4, 5, 6 }; // greka const int tablica[] = { 1, 5, 3, 4, 2 };
182

Inicijalizacija dvodimenzionalnih nizova


int tab_dan[2][12] = { {31,28,31,30,31,30,31,31,30,31,30,31}, {31,29,31,30,31,30,31,31,30,31,30,31}, }; int tab_dan[2][13] = { {0,31,28,31,30,31,30,31,31,30,31,30,31}, {0,31,29,31,30,31,30,31,31,30,31,30,31}, };

183

Inicijalizacija dvodimenzionalnih nizova


short kvadrat1[4][4] = { {0,1,2}, {3,4}, {5,6,7,8}, {9} }; short kvadrat2[4][4] = { {0,1,2,0}, {3,4,0,0}, {5,6,7,8}, {9,0,0,0} }; short kvadrat3[4][4] = { 0,1,2,3,4,5,6,7,8,9 }; short kvadrat4[4][4] = { {0,1,2,3}, {4,5,6,7}, {8,9,0,0}, {0,0,0,0} };

184

Predstavljanje dvodimenzionalnog niza


int matrica[3][4]; Prvi indeks odreuje vrstu a drugi kolonu

[0][0] [1][0] [2][0]

[0][1] [1][1] [2][1]

[0][2] [1][2] [2][2]

[0][3] [1][3] [2][3]

185

Pristupanje elementima niza


Elementu se pristupa pomou indeksa tj. rednog broja unutar niza Pristup elementima niza naziva se indeksiranje Koristi se binarni operator [] Prvi operand je niz i pie se ispred operatora, a drugi je indeks i pie se "unutar" operatora [] niz[indeks] indeks moe da bude proizvoljan celobrojni izraz Operator za indeksiranje je prioriteta 18 i grupie se sleva udesno

186

Pristupanje elementima niza


Skalarni element niza je lvrednost Operatorom za dodelu vrednosti = ne moe se sadraj jednog niza preneti u drugi niz Niz moe da se koristi kao operand operatora [] i sizeof Primeri vektor[1] = 155; vektor[i+(j-1)*n] = a+b*c; matrica[i][j] = vektor[i+j];

187

Identifikatori nizovnih tipova


Opti oblik je typedef tip identifikator_tipa [d1]...[dN]; Primer typedef double Niz[10]; Niz p, q[3]; p[7] = q[0][9]; double p[10];

188

Veliina niza
Veliina memorije koju zauzima neki niz dobija se unarnim operatorom sizeof Primeri: typedef double Niz p, q[3]; p[7] = q[0][9]; sizeof(double) sizeof(Niz) sizeof(q) sizeof(q[1]) sizeof(q[2][7]) Niz[10];

// // // // //

8 10 x 8 = 80 3 x 10 x 8 = 240 10 x 8 = 80 8
189

Pokazivai (pointeri) i reference

190

Pokazivai
Operativna memorija je niz adresnih lokacija koje su numerisane celim brojevima 0, 1, 2, ... , m-1, gde je m kapacitet memorije Brojevi pridrueni memorijskim lokacijama nazivaju se adrese Najmanja memorijska lokacija koja moe da se adresira je obino jedan bajt Pokaziva je prost podatak u koji moe da se smesti adresa neke lokacije u memoriji Pokaziva obino zauzima 2 ili 4 bajta

191

Operator za dohvatanje adrese & (upuiva)


Adresa nekog podatka u memoriji moe da se dobije pomou prefiksnog unarnog operatora & Operator je prioriteta 16 i grupie se zdesna ulevo Operand operatora & mora da bude lvrednost, tj. podatak koji se nalazi u memoriji

192

Operator za dohvatanje podatka * (pokaziva)


Podatak u memoriji se moe dohvatiti na osnovu njegove adrese primenom prefiksnog unarnog operatora * Operator je prioriteta 16 i grupie se zdesna ulevo Operand operatora * mora da bude adresa nekog podatka u memoriji i ne mora da bude lvrednost Rezultat je podatak sa navedenom adresom i predstavlja lvrednost Dohvatanje podatka posredno, pomou adrese, naziva se indirektno adresiranje.

193

Definisanje pokazivaa
Opti oblik je: tip * identifikator_pokazivaa Tip je standardni tip ili tip definisan sa typedef Primer: int *p; int* p; Jedno tumaenje: poto je *p tipa int, p je pokaziva na int Definisanje vie pokazivaa istom naredbom short *p1, *p2;
194

Generiki pokaziva
Generiki pokaziva je pokaziva kod kojeg nije odreen tip pokazivanog podatka Definie se stavljanjem slubene rei void umesto tipa Primer: void* p;

195

Primeri
double a, *pa=&a; double b, *pb; pb = &b; Nije bitno to a i b nisu dobili vrednosti

196

Primeri
int x=1, y=2, z[7]; int *pi; // pi je pokaziva na int void *pj; // pj je generiki pokaziva pi = &x; // pi pokazuje na x y = *pi; // y je sada 1 pj = pi; // pj pokazuje na x *pi = 0; // x je sada 0 *pj = 3; // greka, pj je generiki pok. *(int*)pj = 3; // x je sada 3 pi = &z[0]; // pi sada pokazuje na z[0] pj = &z[5]; // pj sada pokazuje na z[5]
197

Primeri
int x=1; int *pi; void *pj; pi = &x; pj = pi; *pj = 3; *(int*)pj = 3; *(double*)pj = *(double*)pi = // pi je pokaziva na int // pj je generiki pokaziva // pi pokazuje na x // pj pokazuje na x // greka u prevodjenju // x je sada 3 1.5; // prevodi se 2.5; // prevodi se

U zadnja dva primera pokaziva pokazuje na tip podatka koji zauzima 4 bajta u memoriji, a upisuje se podatak koji zauzima 8 bajtova

198

Nepromenljivi podaci i promenljivi pokazivai


Dosad su korieni promenljivi pokazivai na promenljive podatke Definisanje promenljivog pokazivaa na nepromenljive podatke const tip *p; Tumaenje: p je pokaziva (*) na nepromenljive (const) podatke tipa tip Vrednost pokazivaa se moe promeniti Pomou pokazivaa se ne moe promeniti vrednost podatka na koji pokazuje

199

Promenljivi podaci i nepromenljivi pokazivai


Definisanje nepromenljivog pokazivaa na promenljive podatke tip *const p = &k; Tumaenje: p je nepromenljivi (const) pokaziva (*) na podatke tipa tip Vrednost pokazivaa se ne moe promeniti Pomou pokazivaa se moe promeniti vrednost podatka na koji pokazuje

200

Nepromenljivi podaci i nepromenljivi pokazivai


Definisanje nepromenljivog pokazivaa na nepromenljive podatke const tip *const p = &k; Tumaenje: p je nepromenljivi (const) pokaziva (*) na nepromenljive (const) podatke tipa tip Vrednost pokazivaa se ne moe promeniti Pomou pokazivaa se ne moe promeniti vrednost podatka na koji pokazuje

201

Pokazivai sa modifikatorom volatile (nepostojani podaci)


Mogunosti su: volatile tip* (objekat je volatile) tip *volatile (pointer je volatile) volatile tip *volatile (oba volatile) volatile tip *const (volatile objekat, const pokaziva) const tip *volatile

202

Dodele vrednosti pokazivaima


Pokazivau na promenljive podatke mogu da se dodele samo adrese promenljivih podataka Pokazivau na nepromenljive podatke mogu da se dodele adrese nepromenljivih i promenljivih podataka Pokazivau na nepostojane podatke mogu da se dodele adrese nepostojanih i promenljivih podataka Eksplicitnom konverzijom mogu da se prekre ova pravila, ali je u tom sluaju odgovoran programer

203

Primeri
int a=2,*pa=&a, *const kpa=&a;//pok.je const const int b=5, *pkb=&b, *const kpkb=&b; pkb = pa; *pkb = 4; // greka kpa = pa; // greka // greka pravilo 1 sa pa = kpkb; // prethodne strane pa = (int*)kpkb; // Ne preporuuje se *pa = 4; // Menja se nepromenljivi // podatak b int c=1, *const kpc=&c; pa = kpc;
204

Prikazivanje vrednosti pokazivaa


Zavisi od jezika C na datom raunaru U scanf i printf se koristi vrsta konverzije %p Primer:
#include <stdio.h> main () { int x, *px; px = &x; printf("%p\n", px); } Rezultat je npr: 0x07ff35cd

205

Identifikatori pokazivakih tipova


Opti oblik je: typedef tip * identifikator_tipa Primer:
typedef double* Pdouble; double a, b; Pdouble pa, pb, pc; pa = &a; pb = &b; scanf("%lf%lf", pa, pb) pc = (*pa < *pb) ? pa : pb; printf("%g", *pc);
206

Adresna aritmetika
Dozvoljene su operacije
dodela vrednosti jednog pokazivaa drugom dodavanje celobrojnog podatka na vrednost pokazivaa i oduzimanje celobrojnog podatka od vrednosti pokazivaa oduzimanje i uporeivanje dva pokazivaa uporeivanje pokazivaa i nule

207

Dodela vrednosti
Ako su razliiti tipovi pokazivaa obavezno je kastovanje Kastovanje nije obavezno ako se dodeljuje vrednost pokazivau generikog tipa (void*) Primer: int a; void* gp = &a; int* pi = gp; // greka int* pj = (int*)gp;

208

Dodavanje celobrojnog podatka


Mogu se primeniti operatori: +, ++, +=, -, --, -= Ne mogu se primeniti gornji operatori na pokaziva generikog tipa (void*) Jedinica mere pri sabiranju i oduzimanju je veliina pokazivanih podataka Ako pokaziva p pokazuje na neki element niza, tada:
posle p+1 ili p++ pokaziva pokazuje na naredni element niza posle p-1 ili p-- pokaziva pokazuje na prethodni element niza

209

Operacije izmeu dva pokazivaa


Za dva pokazivaa istog tipa (razliitog od void*) koji pokazuju na elemente istog niza, dozvoljeno je:
oduzimanje operatorom uporeivanje relacijskim operatorima <, <=, >, >=

Dozvoljeno je uporeivanje dva pokazivaa istog tipa (ukljuujui i void*) relacijskim operatorima ==, !=
rezultat je da li pokazivai pokazuju na isti podatak

Dozvoljeno je uporeivanje dva pokazivaa istog tipa (ukljuujui i void*) sa nulom


rezultat je da li pokaziva pokazuju na neki podatak moe se umesto nule koristiti simbolika konstanta NULL, definisana u <stdio.h> i <stdlib.h>
210

Pokazivai i nizovi
Identifikator niza predstavlja poetnu adresu niza Identifikator niza je nepromenljivi pokaziva na podatke iji je tip jednak tipu elementa niza Primer: int a[10]; Moe se smatrati da je identifikator a tipa int* const, i da je inicijalizovan poetnom adresom bloka memorije veliine 10 podataka tipa int

211

Pokazivai i nizovi
Ako su: a identifikator niza, i indeks, prema adresnoj aritmetici, tj. na osnovu sabiranja pokazivaa i celih brojeva, sledee je ekvivalentno: &a[i] a + i i + a a[i] *(a + i) *(i + a) i[a] Izraz i[a] treba izbegavati

212

Primer za pokazivae i nizove


int a[10], *pa, *pb, x, y; pa = &a[4]; // pa pokazuje na a[4] x = *(pa + 3); // x = a[7] *pa++; // *(pa++), poveava se pokaziva, pokazuje na a[5] pa++; // poveava se pokaziva, pokazuje na a[6] (*pa)++; // poveava se pokazivani podatak pb = &a[2]; // pb pokazuje na a[2] if (pb < pa) // uporeivanje pokazivaa, rezultat je "tano" { ... }

213

Primer: izraunavanje skalarnog proizvoda


double a[10], b[10], s=0; ... // Prvi nain, pomou indeksa for (int i=0; i<10; i++) s += a[i] * b[i]; // Drugi nain, pomou pokazivaa for(int *pa=a, *pb=b; pa<a+10; pa++, pb++) s += *pa * *pb; // Alternativni nain pisanja za drugi nain for(int *pa=a, *pb=b; pa<a+10; s+= *pa++ * *pb++);

214

Smetanje dvodimenzionalnih nizova u memoriju


Operativna memorija je jednodimenzionalna
enum { m=3, n=4 }; int b[m][n]; [0][0] [1][0] [2][0] [0][1] [1][1] [2][1] [0][2] [1][2] [2][2] [0][3] [1][3] [2][3]

Gornja matrica se u memoriju smeta na sledei nain


0,0 0,1 0,2 0,3 1,0 1,1 1,2 1,3 2,0 2,1 2,2 2,3

215

Adresna aritmetika za dvodimenzionalni niz


enum { m=3, n=4 }; int b[m][n];
0,0 0,1 0,2 0,3 1,0 1,1 1,2 1,3 2,0 2,1 2,2 2,3

Tip identifikatora b je pokaziva na niz od etiri integer-a b &b[0] je adresa poetka prve vrste matrice b+1 &b[1] je adresa poetka druge vrste matrice Pristupanje elementu dvodimenzionalnog niza b[i][j] *((int*)b + n*i + j) b[i][j] *((int*)(b+i) + j) U izraunavanju indeksa ne uestvuje prva dimenzija niza m 216

Smetanje viedimenzionalnih nizova u memoriju


enum { p=2, q=2, r=3 }; int c[p][q][r];
[1][0][0] [1][0][1] [1][0][2] [0][0][0] [0][0][1] [0][0][2] [1][1][0] [1][1][1] [1][1][2] [0][1][0] [0][1][1] [0][1][2]

Gornji trodimenzionalni niz se u memoriju smeta na sledei nain


0,0,0 0,0,1 0,0,2 0,1,0 0,1,1 0,1,2 1,0,0 1,0,1 1,0,2 1,1,0 1,1,1 1,1,2

217

Adresna aritmetika za trodimenzionalni niz


enum { p=2, q=2, r=3 }; int c[p][q][r];
0,0,0 0,0,1 0,0,2 0,1,0 0,1,1 0,1,2 1,0,0 1,0,1 1,0,2 1,1,0 1,1,1 1,1,2

Tip identifikatora c je pokaziva na matricu od dve vrste i tri kolone iji su elementi integer-i c &c[0] je adresa poetka prve matrice c+1 &c[1] je adresa poetka druge matrice Pristupanje elementu trodimenzionalnog niza c[i][j][k] *((int*)c + q*r*i + r*j + k) U izraunavanju indeksa ne uestvuje prva dimenzija niza p
218

Tipovi identifikatora nizova


// Definisane su konstante k, m, n, p, q, r int a[k]; // a je tipa int* int b[m][n]; int c[p][q][r]; // b je tipa int** // c je tipa int***

219

Statika dodela memorije


Statika dodela memorije nizu const int m = 100; int a[m]; Deo memorije u koji se smetaju statiki definisani podaci naziva se statika zona memorije Za nizove se mora znati veliina niza Ako se ne zna veliina niza mora se definisati niz sa najveom oekivanom duinom Moe doi do nepotrebne potronje memorije

220

Dinamika dodela memorije


Memorijski prostor se moe traiti od operativnog sistema u vreme izvravanja programa Dinamika zona memorije je deo memorije koji se dinamiki dodeljuje u vreme izvravanja programa Podaci u dinamikoj zoni memorije nemaju identifikatore, pristupa im se preko pokazivaa Podaci u dinamikoj zoni memorije postoje sve dok ih programer ne uniti, ili se ne zavri program Podaci u dinamikoj zoni memorije se nazivaju dinamiki podaci

221

Dodela memorije u dinamikoj zoni: operator new


Operator new slui za dodelu memorije u dinamikoj zoni memorije, opti oblik je new naziv_tipa ( poetna_vrednost ) naziv_tipa je identifikator osnovnog ili izvedenog tipa
moe imati modifikator * ili [duina] Za nizove prva dimenzija moe biti promenljiva, a sve ostale moraju biti konstantni izrazi

poetna_vrednost je proizvoljan izraz odgovarajueg tipa


inicijalizuju se samo pojedinani podaci, ne mogu nizovi

Operator new kao rezultat vraa pokaziva na dodeljeni memorijski prostor


222

Oslobaanje memorije u dinamikoj zoni: operator delete


Opti oblik za pojedinane podatke je: delete izraz Opti oblik za nizove bez obzira na dimenziju je: delete [] izraz izraz je adresni izraz koji pokazuje na podatak u dinamikoj zoni memorije kome je memorija dodeljena pomou operatora new, inae su posledice nepredvidive Ako izraz ime vrednost nula (NULL) ne deava se nita Operator delete ne vraa rezultat (tip void)

223

Primeri
double* pd = new double(5.2); delete pd; int n = 10; float* a = new float[n]; for(int i=0; i<n; i++) a[i] = ...; delete[] a; float* b = a; delete[] b;
224

Alociranje dinamike memorije u jeziku C


Biblioteke funkcije iz <stdlib.h> malloc(veliina) // tip void* calloc(n, veliina) // tip void* realloc(p, veliina) // tip void* free(p) Ne treba koristiti ove funkcije, treba uvek koristiti operatore new i delete

225

Reference (upuivai)
Referenca je alternativno ime za podatak Ne zauzimaju prostor u memoriji Ne postoje pokazivai na reference Ne postoje nizovi referenci Moraju da se inicijalizuju prilikom definisanja Ne mogu da im se promene vrednosti (tj. adresa na koju ukazuju, za razliku od pokazivaa)

226

Definisanje reference
Dodaje se modifikator & ispred identifikatora reference Primeri:
int k = 1; int& r = k; // int x = r; // r = 2; // r++; // int* p = &r; // int* p1 = &k;// int y = *p; // *p = 5; // p = 0; // r i k predstavljaju isti int x = 1 k = 2 poveava se k, k = 3 p pokazuje na k p1 pokazuje na k y = 3 k = 5 p ne pokazuje na podatak
227

Reference i modifikatori const i volatile


Reference mogu da upuuju na
promenljive podatke nepromenljive podatke (const) nepostojane podatke (volatile)

Primer
int k = 1; int& r = k; // r i k predstavljaju isti int r = 2; // k = 2, pomou r se moe menjati k const int& rc = k; // rc i k predstavljaju isti int rc = 5; // greka, pomou rc ne moe se menjati k

228

Definisanje tipova
Sa typedef se moe dodeliti ime tipu podatka koji je referenca na neki tip Primer typedef double& Rdouble; double a, b; Rdouble ra = a, rb = b; ra = rb = 5; // a = b = 5 Ekvivalentno sa: double &ra = a, &rb = b;
229

Funkcije

230

Funkcije
Rastavljanje sloenijih problema na vie jednostavnijih problema Funkcije su potprogrami koji na osnovu argumenata daju rezultat koji se naziva vrednost funkcije Funkcija moe da daje i druge rezultate koji se nazivaju boni efekti Funkcija ne mora da vraa kao rezultat vrednost funkcije, moe da ima samo bone efekte

231

Definisanje funkcija
Naredba za definisanje funkcije ima opti oblik: tip naziv (niz_argumenata) telo_funkcije tip je tip rezultata koji vraa funkcija, tj. tip vrednosti funkcije naziv je identifikator funkcije niz_argumenata predstavlja argumente funkcije pomou kojih se unose poetne vrednosti telo_funkcije je po formi blok

232

Primer funkcije
long faktorijel(int n) { long rezultat = 1; for(int i=n; i>1; i--) rezultat *= i; return rezultat; }

233

Vrednost funkcije
Tip vrednosti funkcije je tip rezultata koji vraa funkcija Ako funkcija ne vraa vrednost (ima samo bone efekte) tip vrednosti funkcije je void Ako se izostavi tip vrednosti funkcije u definiciji funkcije podrazumeva se tip int Tip vrednosti funkcije moe da bude pokaziva na neki tip (modifikator *), a takoe i referenca (modifikator &) Vrednost funkcije moe biti proizvoljnog skalarnog tipa
moe da bude jedan podatak ne moe da bude niz moe da bude pokaziva na element niza
234

Argumenti funkcije
tip naziv (niz_argumenata) telo_funkcije niz_argumenata ima oblik: argument, argument, ... , argument Pojedinani argument se definie kao podatak: tip naziv_argumenta tip argumenta je proizvoljan standardni tip ili identifikator tipa definisan naredbom typedef
moe da bude i pokaziva na neki tip ili referenca moe da bude i niz oznaka tipa mora da se navede uz svaki argument

Argumentima se unose poetne vrednosti podataka u funkciju

235

Niz argument funkcije


Za jednodimenzionalne nizove ne mora da se navodi dimenzija niza Primer:
double srednjaVrednost(int niz[], int duzina_niza) {...}

Za viedimenzionalne nizove ne mora da se navodi prva dimenzija, ostale moraju Primer:


int naziv_funkcije (int matrica[][10], int n) {...}

Viedimenzionalni nizovi se retko koriste kao argumenti


esto se smetaju u jednodimenzionalne, a u funkciji se koristi adresna aritmetika za pristupanje elementima niza
236

Niz - argument funkcije


Za jednodimenzionalni niz argument moe da bude niz ili pokaziva na poetak niza Primer:
double srednjaVrednost(int niz[], int duzina_niza) {...}

ili:
double srednjaVrednost(int *niz, int duzina_niza) {...}

237

Formalni i stvarni argumenti


Formalni argumenti su argumenti koji se navode u definisanju funkcije Stvarni argumenti su argumenti koji se navode prilikom pozivanja funkcije Formalni argumenti prilikom pozivanja funkcije dobijaju vrednosti od stvarnih argumenata

238

Primer
long faktorijel(int n) { long rezultat = 1; for(int i=n; i>1; i--) rezultat *= i; return rezultat; } void prikazFaktorijel(int a) { printf("faktorijel je %d\n", faktorijel(a)); }

239

Telo funkcije
Po formi je blok Moe da sadri deklarativne i izvrne naredbe Podaci definisani u telu funkcije su lokalni za tu funkciju Formalni argumenti su lokalni za funkciju
moe se smatrati kao da su definisani na poetku bloka pre prve naredbe bloka inicijalizovani su vrednostima stvarnih argumenata

240

Telo funkcije
Povratak iz funkcije u pozivajuu funkciju radi se naredbom return Opti oblik je: return izraz; // Kad funkcija vraa rezultat return; // Kad je tip vrednosti funkcije void Izraz predstavlja vrednost funkcije (vraeni rezultat)
mora po tipu da se slae sa predvienim tipom vrednosti funkcije za numerike tipova radi se automatska konverzija u predvieni tip rezultata

Naredba return moe da se izostavi ako je to poslednja nareba u funkciji iji je rezultat tipa void
241

Naredba return
Unutar tela funkcije moe biti vie naredbi return u razliitim selekcijama Funkcija se zavrava kad se izvri prva naredba return Primer:
long faktorijel(int n) { if(n < 2) return 1; long rezultat = 1; for(int i=n; i>1; i--) rezultat *= i; return rezultat; }
242

Vrednost funkcije je pokaziva ili referenca


Vrednost funkcije ne sme da bude pokaziva ili referenca na lokalni prolazni podatak funkcije Prolazni lokalni podatak se unitava pre nego to pozivajua funkcija moe da mu pristupi Moe da bude pokaziva ili referenca na lokalni trajni podatak Moe da bude pokaziva na dinamiki podatak napravljen u funkciji

243

Primer
Moe (vraanje vrednosti):
int DoubleValue(int nX) { int nValue = nX * 2; return nValue; // Ovde se vraa kopija od nValue } // nValue izlazi iz dosega

Ne moe (vraanje reference):


int& DoubleValue(int nX) { int nValue = nX * 2; return nValue; // Ovde se vraa refer. od nValue } // nValue izlazi iz dosega
244

Primer
Ne moe (vraanje adrese):
int* DoubleValue(int nX) { int nValue = nX * 2; return &nValue; // Ovde se vraa adresa nValue } // nValue izlazi iz dosega

245

Biblioteke funkcije
U sastavu jezika je standardna biblioteka sa velikim brojem standardnih funkcija
biblioteke funkcije su podeljene u nekoliko grupa na osnovu slinosti deklaracije funkcija navedene su u *.h datotekama (datoteke zaglavlja)

Da bi se koristile standardne funkcije, na poetku programa (tj. datoteke u kojoj se koriste funkcije) dodaje se zaglavlje fajla u kojem su deklarisane standardne funkcije: #include <naziv_datoteke>

246

Matematike funkcije, <math.h>


Rezultat, x i y su tipa double, n je tipa int sin(x) cos(x) tan(x) asin(x) acos(x) atan(x) atan2(x,y) sinh(x) cosh(x) tanh(x) sin x cos x tg x arcsin x, arccos x, arctg x, arctg x/y, sh x ch x th x
247

x[-1, 1] x[-1, 1] rezultat [-/2, /2] rezultat [-, ], mora x ili y da bude 0

Matematike funkcije, <math.h>


Rezultat, x i y su tipa double, n je tipa int exp(x) log(x) log10(x) pow(x,y) sqrt(x) ceil(x) floor(x) fabs(x) ldexp(x,n) ex logex, log10x, xy, x1/2, x>0 x>0 x0

za x=0 mora y>0; za x<0, mora y da bude ceo broj

najmanji ceo broj x najvei ceo broj x |x| x2n

248

Matematike funkcije, <math.h>


Rezultat, x i y su tipa double, n je tipa int vrednost funkcije je normalizovana mantisa realnog frexp(x,&n) broja x u opsegu [-1/2, 1] n je eksponent (boni efekat) modf(x,&y) vrednost funkcije je razlomljeni deo realnog broja x sa predznakom tog broja y je celobrojni deo broja x sa predznakom tog broja (boni efekat) ostatak realnog deljanja x/y sa predznakom od x standard ne precizira rezultat za y=0

fmod(x,y)

249

Matematike funkcije, <math.h>


Funkcije za celobrojne tipove abs(n) labs(n) |n|, |n|, n je tipa int, rezultat je tipa int n je tipa long int, rezultat je tipa long int

rand()

Pseudosluajan broj tipa int sa uniformnom raspodelom u opsegu [0, RAND_MAX]. RAND_MAX je simbolika konstanta zavisna od raunara, RAND_MAX 32767 Postavljanje poetne vrednosti sekvence pseudosluajnih brojeva koju daje funkcija rand() na n. Podrazumevana poetna vrednost sekvence je 1. n je tipa unsigned int

srand(n)

250

Funkcije za rad sa znakovima, <stdio.h>


getchar() putchar(c) gets(s) puts(s) ita sledei znak sa glavnog ulaza raunara (tastature), ukljuujui bele znaka (Ctrl-Z za kraj) Ispisuje znak c na glavnom izlazu raunara (ekranu) ita jedan red teksta sa glavnog ulaza raunara, do znaka '\n' koji se zamnenjuje '\0'. Rezultat je znakovni niz s tipa char[] ili char* Ispisuje sadraj znakovnog niza s (tipa char[] ili char*) do zavrnog znaka '\0', dodajui znak '\n'

251

Funkcije za ispitivanje znakova, <ctype.h>


isalnum(c) isalpha(c) islower(c) isupper(c) isdigit(c) isspace(c) isgraph(c) isprint(c) ispunct(c) iscntrl(c) tolower(c) toupper(c) Da li je c slovo ili cifra Da li je c slovo Da li je c malo slovo Da li je c veliko slovo Da li je c decimalna cifra Da li je c beli znak Da li je c tampajui znak, ali nije razmak Da li je c tampajui znak, ukljuujui i razmak Da li je c specijalni znak, tampajui nije slovo ni cifra Da li je c upravljaki znak Kod odgovarajueg velikog slova, inae c Kod odgovarajueg malog slova, inae c
252

isxdigit(c) Da li je c heksadecimalna cifra

Funkcije za rad sa stringovima, <string.h>


strcpy(t,s) kopiranje s -> t strncpy(t,s,n) kopiranje s -> t, najvie n znakova strcat(t,s) dopisivanje s na kraj t strncat(t,s,n) dopisivanje s na kraj t, najvie n znakova strcmp(u,s) poreenje u i s strlen(s) strchr(u,c) strrchr(u,c) strstr(u,s) strcspn(u,s) strspn(u,s) broj ynakova bez '\0' pokaziva na prvi element niza u koji sadri znak c pokaziva na zadnji element niza u koji sadri znak c pokaziva na prvi element niza u od kojeg poinje podniz s indeks prvog elementa niza u koji sadri bilo koji znak iz niza s indeks prvog elementa niza u koji sadri bilo koji znak koji se ne pojavljuje u nizu s
253

Konverzija u numerike tipove, <stdlib.h>


atof(s) atoi(s) atol(s) Konverzija realnog broja iz stringa oblika ccc.cccEee u binarni ekvivalent, rezultat je tipa double Konverzija celog broja iz stringa oblika cccc u binarni ekvivalent, rezultat je tipa int Konverzija celog broja iz stringa oblika cccc u binarni ekvivalent, rezultat je tipa long int

254

Pozivanje funkcije
Binarni operator sa operandima
prvi operand je funkcija koja se poziva drugi operand je niz stvarnih argumenata operator je prioriteta 18, grupie se sleva udesno

Opti oblik pozivanja funkcije je: funkcija ( izraz, izraz, ... , izraz) funkcija je funkcija koja se poziva i moe biti
identifikator funkcije adresni izraz ija je vrednost adresa eljene funkcije

izrazi su stvarni argumenti kojim se inicijalizuju formalni argumenti pre izvravanja tela funkcije
255

Stvarni argumenti
Treba da se slau po broju i tipu sa formalnim argumentima Radi se automatska konverzija tipa ako je mogua Mogu da budu adresni izrazi Ako je jedan argument niz izraza stavlja se u zagrade
f(a,b) f(a,(b,c))

Izraunavaju se po proizvoljnom redosledu


ne smeju da zavise od redosleda izraunavanja

Ako je stvarni argument poziv druge funkcije, ona se izrauna i koristi se vrednost
ne sme da bude tipa void
256

Stvarni argumenti
Imena stvarnih argumenata mogu da budu proizvoljna, ali se u praksi najee poklapaju sa imenima formalnih argumenata

257

Primer
#include <stdio.h> long faktorijel(int n) { long rezultat = 1; for(int i=n; i>1; i--) rezultat *= i; return rezultat; } main() { int n; printf("Unesite broj %d\n", &n); printf("faktorijel je %d\n", faktorijel(n)); }

258

Boni efekti funkcija


Skalarni podaci se uvek prenose po vrednosti Promena formalnog argumenta unutar funkcije ne odraava se na vrednost stvarnog argumenta Iznoenje vrednosti iz funkcije preko argumenta mogue je ako je formalni argument
pokaziva preko kojeg se modifikuje podatak indirektnim adresiranjem referenca

259

Primer: nema bonih efekata


int izracunaj(int a, int b) { a *= 2; int c = a + b; return c; } void f() { int m=1, n=3; int p=izracunaj(m, n); int q=m; // q=1 }

// p=5

260

Argument funkcije pokazivakog tipa


Nizovi se u funkciju prenose pomou adrese Promenom podatka indirektnim adresiranjem (pristupanjem preko pokazivaa koji je formalni argument) pravi se boni efekat funkcije

261

Primer: funkcija sa bonim efektom


int izracunaj(int *a) { *a *= 2; // menja se podatak iji pokaziva je stvarni argument int c = *a + 3; return c; } void f() { int m=1; int p=izracunaj(&m); int q=m; // q=2 }

// p=5

262

Primer: funkcija sa bonim efektom


int izracunaj(int *a, int b) { *a *= 2; // menja se podatak iji pokaziva je stvarni argument int c = *a; a = &b; // a je lokalni prolazni podatak, sad pokazuje na b *a += 1; // menja se lokalni prolazni podatak b c += *a; return c; } void f() { int m=1, n=3; int p=izracunaj(&m, n); // p=6 int q=m; // q=2, promenjeno je ono to je bilo //na adresi &m, posle toga adrese a i m nisu vie //iste. 263 }

Primer: pretvaranje Dekartovih u polarne koordinate


#include <math.h> void polar(double x, double y, double *r, double *fi) { *r = sqrt(x*x + y*y); *fi = (x==0 && y==0) ? 0 : atan2(y, x); }
void f() { double x=1, y=1, r, fi; ... polar(x, y, &r, &fi); ... }
264

Nepromenljivi formalni argumenti pokazivakog tipa


Modifikator const ispred oznake tipa pokazivakog formalnog argumenta oznaava da funkcija nee da promeni vrednost podatka na koji ukazuje taj pokaziva
stvarni argument moe biti promenljivi ili nepromenljivi podatak

265

Primer: pretvaranje Dekartovih u polarne koordinate


#include <math.h> void polar(const double *x, const double *y, double *r, double *fi) { *r = sqrt((*x)*(*x) + (*y)*(*y)); *fi = (*x==0 && *y==0) ? 0 : atan2(*y, *x); } void f() { double x=1, y=1, r, fi; ... polar(&x, &y, &r, &fi); ... }

266

Nepromenljivi formalni argumenti pokazivakog tipa


Odsustvo modifikatora const ispred oznake tipa pokazivakog formalnog argumenta oznaava da funkcija moe, ali ne mora, da promeni vrednost podatka na koji ukazuje taj pokaziva Napomena: identifikator niza je pokaziva na prvi element niza Preporuuje se upotreba modifikatora const uz identifikatore pokazivakog ili nizovnog tipa kad funkcija ne menja podatak na koji ukazuje pokaziva

267

Primer: izraunavanje skalarnog proizvoda


double skalarniProizvod(double a[], double b[], int n) { double s=0; for (int i=0; i<n; i++) s += a[i] * b[i]; return s; } double skalarniProizvod(const double a[], const double b[], int n) { double s=0; for (int i=0; i<n; i++) s += a[i] * b[i]; return s; }
268

Nepostojani formalni argumenti pokazivakog tipa


Modifikator volatile ispred oznake tipa pokazivakog formalnog argumenta oznaava da je funkcija spremna na neoekivane promene podatka na koji ukazuje taj pokaziva

269

Reference i funkcije
Reference mogu da budu formalni argumenti i vrednosti funkcija

270

Argument funkcije tipa reference


Kad je formalni argument referenca stvarni argument mora biti podatak (lvrednost) istog tipa kao i referenca
nije mogua automatska konverzija tipa (rezultat konverzije nije lvrednost)

Formalni argument se inicijalizuje podatkom koji je stvarni argument Formalni argument postaje alternativno ime za podatak Promenom vrednosti formalnog argumenta menja se stvarni argument (podatak) Ne kopira se vrednost stvarnog argumenta u formalni argument
uteda prostora i vremena za argumente sloenih tipova
271

Primer: argument funkcije je referenca


void povecaj(int& a) { a++; } int x = 1; povecaj(x); povecaj(x+1);

// greka, x+1 nije lvrednost

Realizacija pomou pokazivaa


void povecaj(int* a) { (*a)++; } int x = 1; povecaj(&x);

272

Vrednost funkcije je tipa reference


Referenca moe da bude vrednost funkcije, i tada je vrednost funkcije podatak odgovarajueg tipa (lvrednost) Vrednost funkcije ne sme da bude referenca na lokalni prolazni podatak funkcije Kada vrednost funkcije nije referenca tada vrednost funkcije nije lvrednost
naredba return vraa kopiju vrednosti izraza a ne podatak

273

Primer: vrednost funkcije je referenca


int& max(int& p, int& q) { return p>q ? p : q; } int a = 2, b = 5; max(a, b) ++; // b se poveava za 1, b=6 !!!

Primer kad vrednost funkcije nije referenca


int max(int& p, int& q) { return p>q ? p : q; } int a = 2, b = 5; max(a, b) ++; // greka, rezultat nije lvrednost
274

Modifikator const i argument funkcije tipa reference


Ako je argument funkcije sloenog tipa dobro je da bude tipa reference
ne kopira se sloeni objekat

Ako se argument tipa reference ne menja u funkciji treba da se deklarie kao referenca na nepromenljive podatke
dodaje se modifikator const stvarni argument moe biri promenljivi ili nepromenljivi podatak

275

Primer: nepromenljivi argument funkcije


int max(const int& p, const int& q) { return p>q ? p : q; // rezultat nije lvrednost }

Rezultat funkcije je nepromenljivi podatak


const int& max(const int& p, const int& q) { return p>q ? p : q; } int a = 2, b = 5; max(a, b) ++; // greka, rezultat je nepromenljiv

276

Primer: nepromenljivi argument funkcije (2)


int& max(const int& p, const int& q) { return p>q ? p : q; // greka, rezultat nije konstantan podatak } const int& max(int& p, int& q) { return p>q ? p : q; // u redu, ali nije najlepe napisano }

Poto se p i q ne menjaju unutar funkcije bilo bi bolje kao to je na prethodnoj stranici, tj.
const int& max(const int& p, const int& q)

277

Primer: vrednost funkcije je pokaziva


int* max(int* p, int* q) { return (*p)>(*q) ? p : q; } int a = 2, b = 5; (*max(&a, &b)) ++;

// b se poveava za 1, b=6

Primer kad vrednost funkcije nije pokaziva


int max(int* p, int* q) { return (*p)>(*q) ? (*p) : (*q); }

278

Primer: pretvaranje Dekartovih u polarne koordinate


#include <math.h> void polar(double x, double y, double &r, double &fi) { r = sqrt(x*x + y*y); fi = (x==0 && y==0) ? 0 : atan2(y, x); }

Sa pokazivaima je
void polar(double x, double y, double *r, double *fi) { *r = sqrt(x*x + y*y); *fi = (x==0 && y==0) ? 0 : atan2(y, x); }

279

Lokalni identifikatori funkcija


Identifikatori definisani unutar funkcija imaju blokovski doseg i lokalni su za tu funkciju Isti identifikatori se mogu koristiti u razliitim funkcijama Vrednost funkcije ne sme biti referenca ili pokaziva na lokalni prolazni podatak

280

Primer: vrednost funkcije je referenca


int& max(int& p, int& q) { int a, &ra = a; ra = p>q ? p : q; return ra; // greka, ra je referenca na lokalni podatak }

Drugaije napisano
int max(int& p, int& q) { int a, &ra = a; if (p>q) ra = p; else ra = q; return ra; // greka, ra je referenca na lokalni podatak }

281

Primer: vrednost funkcije je pokaziva


int* max(int p, int q) { return p>q ? &p : &q; // greka, p i q su lokalni podaci }

Drugaije napisano
int* max(int p, int q) { int a; if (p>q) a = p; else a = q; return &a; // greka, a je lokalni podatak }
282

Globalni identifikatori
Definiu se naredbama koje se piu izvan tela funkcije Zajedniki su za vei broj funkcija Doseg je od mesta na kojem su deklarisani do kraja datoteke (kae se i datoteki doseg) Podaci sa globalnim identifikatorima se nazivaju globalni podaci

283

Primer
#include <math.h> double x, y, r, fi; void polar() { r = sqrt(x*x + y*y); fi = (x==0 && y==0) ? 0 : atan2(y, x); }

Funkcija ima boni efekat, menja globalne podatke

284

Globalni podaci
Globalni podaci su uvek trajni
znaenje modifikatora static kod globalnih podataka se razlikuje, oznaava unutranje povezivanje a ne trajnost podatka (spoljanje povezivanje - extern)

Imaju nulte poetne vrednosti ako nisu inicijalizovani Stvaraju se pre pozivanja bilo koje funkcije ili podatka iz datoteke u kojoj su definisani Postoje do zavretka programa U jeziku C++ treba izbegavati korienje globalnih podataka

285

Doseg identifikatora funkcija


Identifikatori funkcija su globalni sa datotekim dosegom
funkcije ne mogu biti lokalne tj. ne mogu biti definisane unutar druge funkcije

Doseg formalnih argumenata funkcije je blok tela funkcije

286

Deklaracija i definicija
Termini deklaracija i definicija se odnose na podatke i funkcije Deklaracija je odreivanje identifikatora i opisivanje podataka ili funkcija bez dodeljivanja memorijskog prostora za smetanje podataka ili funkcija Definicija sadri deklaraciju i dodelu memorijskog prostora za smetanje podataka ili funkcija
prilikom definisanja podatak moe i da se inicijalizuje prilikom definisanja funkcije mora da se navede telo funkcije prevoenjem funkcije dodeljuje joj se memorijski prostror

287

Definisanje tipova
Za identifikatore tipova koji su uvedeni naredbom typedef ne razlikuje se deklaracija i definicija
ne smetaju se u memoriju moe se smatrati da postoji samo definicija

Isto je i za simbolike konstante uvedene naredbom enum ili direktivom define

288

Deklarisanje globalnih podataka


Globalni podaci se deklariu dodavanjem modifikatora extern na poetku naredbe za deklarisanje Ne sme da postoji inicijalizator u naredbi za deklarisanje globalnog podatka Podatak sme da se deklarie vie puta, ali mora da se definie tano jednom Moe da se uradi izvan ili unutar funkcija
deklaracija globalnog podatka unutar funkcija ima blokovski doseg i to se retko koristi

Ako nije definisan, globalni podatak mora bar da se deklarie pre korienja
289

Primer deklaracije globalnog podatka


int x = 5; // File 1 extern int x; // File 2 int funkcija() { return x; }

//extern int y=1; // greka, nema inicijalizacije u deklaraciji

290

Deklarisanje funkcije
Funkcije se deklariu navoenjem prazne naredbe ; umesto tela funkcije tip naziv_funkcije ( argumenti ) ; Deklaracija funkcije se naziva i prototip ili potpis (signature) (kao kod apstraktne funkcije u Javi) Prototip funkcije treba da bude naveden u sluajevima kada se neke funkcija poziva na mestu na kojem definicija funkcije nije dostupna prevodiocu. Prototip navodi ime funkcije, tip vrednosti funkcije i broj i tipove argumenata Doseg identifikatora je unutar deklaracije, naziva se prototipski doseg
291

Deklarisanje funkcije
Funkcije mogu da se deklariu vie puta, ali moraju da se definiu tano jednom Deklaracija funkcije sadri sve podatke koji su potrebni za ispravno pozivanje funkcije Identifikatori argumenata u prototipu mogu da se izostave
prevodilac ne koristi identifikatore iz prototipa

Primer double funkcija(double a, int b, short c); double funkcija(double, int, short);

292

Potpuni prototip
Prototip je potpun ako sadri sve informacije, tj. tip vrednosti funkcije i tipove i broj argumenata tip naziv_funkcije ( argumenti ) ; Nepotpuni prototip ima samo tip vrednosti funkcije, a argumenti se ne navode Nepotpuni prototip treba izbegavati

293

Primer sa globalnim podacima


#include <stdio.h> #include <math.h> main() { extern double x, y, r, fi; // da bi se mogli koristiti pre definisanja void polar(void); // deklarisanje funkcije while(printf("x,y? "), scanf("%lf%lf",&x,&y), x!=1E38) { polar(); printf("r, fi = %g %g\n", r, fi); } } void polar() // definisanje funkcije { extern double x, y, r, fi; // deklarisanje podataka r = sqrt(x*x + y*y); fi = (x==0 && y==0) ? 0 : atan2(y, x); } double x, y, r, fi; // definisanje podataka
294

Povezivanje identifikatora
Izvorni tekst program se najee stavlja u vie datoteka U jednu datoteku se stavljaju srodne funkcije, ili jedna klasa Datoteke se prevode nezavisno Posle prevoenja povezuju se u izvrni oblik programa esto se prave biblioteke koje sadre prevedeni oblik koda koji se moe koristiti u vie programa

295

Globalni podaci u razliitim datotekama


Mogu biti deklarisani u vie datoteka u kojima se koriste Definiu se samo u jednoj datoteci, tj. moraju se definisati tano jednom Ako podatak nije deklarisan javlja se greka u prevoenju Ako podatak nije definisan ili je definisan vie puta, greka se javlja u toku povezivanja (link-ovanja) u izvodljivi oblik programa
ne javlja se greka u toku prevoenja

296

Globalni podaci u razliitim datotekama


Imaju spoljanje povezivanje, tj. oznaavaju jedan isti podatak iako su deklarisani u vie datoteka Ako se globalnom podatku doda modifikator static, podatak je lokalni za datoteku unutar koje je naveden (unutar te datoteke je globalni), tj. ima unutranje povezivanje Podaci sa modifikatorom const imaju unutranje povezivanje, osim ako se ne doda modifikator extern Identifikatori definisani naredbama typedef i enum ili direktivom define imaju unutranje povezivanje
definicija se mora pisati u svakoj datoteci u kojoj se koristi, ili se pie u *.h datoteci koja se ukljuuje u vie datoteka
297

Globalni podaci u razliitim datotekama


// Datoteka sa deklaracijom globalih podataka double x, y, r, fi;

// Datoteka sa definicijom funkcije #include <math.h> extern double x, y, r, fi; // deklarisanje globalnih podataka void polar() { r = sqrt(x*x + y*y); fi = (x==0 && y==0) ? 0 : atan2(y, x); }
298

Globalni podaci u razliitim datotekama


// Datoteka sa glavnim programom #include <stdio.h> extern double x, y, r, fi; // deklarisanje globalnih podataka void polar(void); // deklarisanje funkcije main() { while(printf("x,y? "), scanf("%lf%lf",&x,&y), x!=1E38) { polar(); printf("r, fi = %g %g\n", r, fi); } }
299

Glavni program u jeziku C


Glavni program je specijalna funkcija koju poziva operativni sistem raunara Ima jedan od sledea etiri prototipa void main(void); int main(void); void main(int bpar, const char *vpar[]); int main(int bpar, const char *vpar[]); Ako se ne navede tip rezultata podrazumeva se tip int

300

Glavni program u jeziku C


Vrednost funkcije tipa int vraa se operativnom sistemu kao zavrni status programa
vrednost nula oznaava uspean zavretak programa nenulta vrednost predstavlja ifru greke pri neuspenom zavravanju programa

Glavni program tipa void, ili tipa int ali bez naredbe return, ima sluajnu vrednost kao zavrni status

301

Razlika u glavnom programu u jezicima C i C++


Glavni program u jeziku C++ je tipa int Ako glavni program nema naredbu return, zavrni status je 0

302

Zavravanje glavnog programa


Program se zavrava na jedan od sledeih naina:
izvravanjem poslednje linije programa naredbom return pozivanjem biblioteke funkcije exit koja se nalazi u zaglavlju <stdlib.h> i iji je prototip int exit(int status);

Pozivanje funkcije exit moe se uraditi iz bilo koje funkcije unutar programa (nestrukturirani pristup!), a glavni program treba da bude tipa int

303

Argumenti glavnog programa


Glavni program moe da bude bez argumenata, ili da ima dva argumenta Argumentima se prenose parametri koji se zadaju u sastavu komande operativnog sistema int main(int bpar, const char *vpar[]); bpar je broj parametara (rei) u komandi operativnog sistema kojom se pokree program, ukljuujui i samu komandu operativnog sistema tj. ime izvrnog oblika programa vpar je niz pokazivaa na znakovne nizove (rei) u komandi operativnog sistema kojom se pokree program
304

Detaljnije objanjenje argumenta vpar


vpar je niz pokazivaa na znakovne nizove (rei) u komandi operativnog sistema kojom se pokree program Znakovnih nizova (pokazivaa) ima bpar+1 Svaki znakovni niz sadri jednu re iz komande operativnog sistema, a razdvojeni su belim znacima Prvi pokaziva vpar[0] pokazuje na ime datoteke koja sadri izvrnu verziju programa, zajedno sa celom putanjom u sistemu direktorijuma ako se navodi
ako putanja sadri beli znak, mora da se napie unutar navodnika, npr: C:\"Program Files\proba.exe" arg1 ... argN

Poslednji pokaziva vpar[bpar] ima vrednost NULL


305

Komanda echo
Na operativnim sistemima UNIX i MS-DOS komanda echo ispisuje tekst koji je sastavni deo komande: % echo Pozdrav svima! Operativni sistem stvara sledeu struktura koju prosleuje programu bpar vpar P NULL s o v z i d m r a a ! v \0
306

3 e c h o \0 \0

Primer programa koji radi isto to i naredba echo


#include <stdio.h> void main(int bpar, const char *vpar[]) { for(int i=1; i<bpar; i++) printf("%s%c", vpar[i], (i<bpar-1)?' ':'\n')); }

307

Rekurzivni problemi
Neki problemi su po prirodi rekurzivni Fibonacci-jevi brojevi: f0 = 0 f1 = 1 fn = f n 1 + f n 2 , n > 1 Niz je: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ... Rekurvno reavanje faktorijela 0! = 1 n! = n (n1)! , n > 0

308

Rekurzivni problemi
Rekurzivne funkcije su funkcije koje neposredno ili posredno pozivaju same sebe Prirodno se koriste za reavanje rekurzivnih problema Da bi se rekurzija zavrila mora postojati specijalna vrednost argumenta za koju vrednost funkcije nije definisana rekurzivno

309

Rekurzivne funkcije
Rekurzivno reavanje faktorijela
int faktorijel(int n) { return (n>0) ? (n * faktorijel(n-1)) : 1; }

Iterativno reavanje faktorijela


int faktorijel(int n) { int rezultat = 1; for(int i=n; i>1; i--) rezultat *= i; return rezultat; }
310

Rekurzivne funkcije
Rekurzivno reavanje problema je sporije nego iterativno, ako postoji jednostavan nacin da se rekurzivni problem svede na iterativni, kao u sluaju faktorijela
u rekurzivnom reenju faktorijela najvie vremena se gubi na pozivanja funkcije

Otkrivanje greaka u rekurzivnim funkcijama je tee nego u iterativnim

311

Rekurzivno reenje Fibonacci-jevih brojeva


int fibonacci(int n) { return (n>1) ? (fibonacci(n-1)+fibonacci(n-2)) : ( (n==1) ? 1 : 0 ); }

312

Iterativno reenje Fibonacci-jevih brojeva


int fibonacci(int n) { if(n==0) return 0; int s = 1, sp = 0; for(int i=1; i<=n; i++) { int t = s; s += sp; sp = t; } return s; }

313

Pokazivai na funkcije
Moe se definisati pokaziva na funkciju Pokazivai na funkcije mogu da se:
meusobno dodeljuju prenose kao argumenti drugim funkcijama da budu rezultati funkcija da se smetaju u nizove

Pokaziva na funkciju moe da pokazuje na bilo koju funkciju pod uslovom da se slae po tipu sa funkcijom, tj. da su im jednaki:
tip vrednosti funkcije broj i tipovi argumenata
314

Tip pokaziva na funkciju


Naredba za definisanje pokazivaa na funkciju ima oblik: tip (*identifikator)(niz_tipova_argumenata) tip je tip vrednosti funkcije, moe biti bilo koji skalarni tip identifikator je oznaka (ime) pokazivaa niz_tipova_argumenata odreuje broj i tipove formalnih argumenata funkcije Tip pokazivaa na funkciju odreen je tipom vrednosti funkcije i brojem i tipovima argumenata funkcije

315

Primer
Definisanje pokazivaa na funkciju double (*pfun) (float, int); pfun je pokaziva na funkciju ija je vrednost tipa double i koja ima dva argumenta, prvi je tipa float a drugi je tipa int Sledei primer ne predstavlja pokaziva na funkciju, ve funkciju iji je rezultat pokaziva na tip double double *fun (float, int);

316

Korienje pokazivaa na funkciju


Identifikator funkcije predstavlja pokaziva na funkciju, slino kao kod nizova Funkcija je deklarisana na sledei nain double fun(float, int);
fun je identifikator funkcije, tj. pokaziva na funkciju

Definisanje pokazivaa na funkciju double (*pfun)(float, int); Dodela vrednosti pokazivau na funkciju pfun = fun; Pozivanje funkcije preko pokazivaa (*pfun)(x, n); // *pfun(x, n); // greka

317

Primer korienja pokazivaa na funkciju


int faktorijel(int n) { return (n>0) ? (n * faktorijel(n-1)) : 1; } int fibonacci(int n) { return (n>1) ? (fibonacci(n-1)+fibonacci(n-2)) : ( (n==1) ? 1 : 0 ); }

318

Primer korienja pokazivaa na funkciju


#include <stdio.h> int main() { while(true) { printf("n? "); int n; scanf("%d",&n); if(n<0) return; int(*pfun)(int); pfun = faktorijel; int r1 = (*pfun)(n); // faktorijel od n pfun = fibonacci; int r2 = (*pfun)(n); // n-ti lan fibonacci-jevog niza printf("%d %d\n", r1, r2); } return 0; }

319

Definisanje tipa pokazivaa na funkciju


Koristi se naredba typedef Primer typedef double (*Tpfun)(float, int); Tpfun je identifikator novog tipa: tip pokazivaa na funkcije tipa double koje imaju dva argumenta, prvi tipa float i drugi tipa int

320

Korienje identifikatora tipa pokaziva na funkciju


typedef int (*TpFun)(int); TpFun je identifikator tipa: pokaziva na funkciju tipa int koja ima jedan argument tipa int Definisanje pokazivaa na funkciju TpFun pfun = faktorijel; int n = (*pfun)(5);

321

Funkcije sa promenljivim brojem argumenata


Pored obaveznih u funkciji mogu da postoje i neobavezni argumenti U deklarisanju i definisanju se oznaavaju sa tri take: tip naziv (niz_argumenata, ... ); Mora se obezbediti nain da se utvrdi koliko ima argumenata, npr.
obavezni argument oznaava koliko ima argumenata poslednji argument ima neku specijalnu vrednost

Funkcije iz standardne biblioteke scanf i printf imaju promenljiv broj argumenata, npr. printf("%s%d%lf", str, i, x); Prevodilac ne moe da proveri tip i broj argumenata, pa su greke u sluaju neslaganja nepredvidive 322 Treba izbegavati pisanje ovakvih funkcija

Neposredno ugraivanje funkcije u kod u C++


Za kratke funkcije je efikasnije da se telo ugradi u kod na svakom mestu pozivanja, nego da se poziva funkcija Modifikator inline na poetku definisanja funkcije sugerie prevodiocu da se telo funkcije ugrauje u kod
nije sigurno da e prevodilac uvaiti sugestiju

Poto prevodilac mora imati telo funkcije da bi ga ugradio u kod, funkcija se mora navesti:
u svakoj *.cpp datoteci gde se koristi ili u *.h datoteci koja se ukljuuje u *.cpp datoteke
nije pogodno zbog izlaganja tela funkcije javnosti

Neposredno ugraivanje u kod se moe postii korienjem makroa (nain iz jezika C)


323

Primer za inline
Funkcija inline int max(int i, int j) { return i>j ? i : j; } Makro #define max(i,j) ((i) > (j) ? (i) : (j)); Makro nije pogodan zbog viestrukog izraunavanja izraza, (npr. kad ima bonih efekata, tj. pravi greku): max(k++, n++) ((k++) > (n++) ? (k++) : (n++)) // k ili n ce 2 puta biti inkrementirano
324

Podrazumevane vrednosti argumenata funkcija


Za formalne argumente funkcija mogu da se navedu podrazumevane vrednosti Podrazumevane vrednosti se navode kao poetne vrednosti u naredbama za definisanje podataka Argumenti koji imaju podrazumevane vrednosti
moraju da se navedu kao poslednji po redosledu mogu da se izostave prilikom pozivanja funkcije

Mogu i svi argumenti da imaju podrazumevane vrednosti

325

Primer za podrazumevani argument


struct Tacka { double x, y; }; const Tacka ORG = { 0, 0 }; #include <math.h> double rastojanje(Tacka a, Tacka b = ORG ) { return sqrt(pow(a.x-b.x,2) + pow(a.y-b.y,2)); } ... Tacka p={1,1}, q={-1,-1}; double d1 = rastojanje(p, q); double d2 = rastojanje(p);

326

Primeri za podrazumevani argument


int int int int f1(int f2(int f3(int f4(int a, a=0, a=0, a, int int int int b=0) b) b=0) b=0, { ... }; { ... }; // Greka { ... }; int c=1) { ... };

U pozivu funkcije f4 mogue je sledee


da se navede samo argument a da se navedu argumenti a i b da se navedu argumenti a, b i c

Nije mogue da se u pozivu funkcije f4 navede argument c, a da se izostavi argument b


327

Preklapanje imena funkcija


Preklapanje imena funkcija je definisanje vie funkcija koje imaju isto ime tj. identifikator Preklopljene funkcije moraju da se razlikuju
ili po broju argumenata ili po tipovima argumenata ili po broju i po tipovima argumenata

Tip vrednosti funkcije nije bitan, moe da bude isti ili razliit Razlike u preklopljenim funkcijama moraju biti takve da prevodilac na osnovu argumenata moe jednoznano da odredi funkciju koja treba da se pozove
328

Pravila za izbor preklopljenih funkcija


Trai se potpuno slaganje po tipovima argumenata (char i short se potpuno slau sa int, a float sa double) inae, trai se slaganje korienjem standardnih konverzija za osnovne tipove podataka (v. slajd 87) inae. trai se slaganje korienjem nestandardnih konverzija koje je definisao programer

329

Primeri preklapanja funkcija


int max(int x, int y) { return x>y ? x : y; } double max(double x, double y) { return x>y ? x : y; } char max(char x, char y) { return x>y ? x : y; } int double char double int a b c d e = = = = = max(1, max(1.0, max('a', max(1, max(1, 2); 2.0); '3'); 2.0); '3'); // // // // // max(int,int) max(double,double) max(char,char) max(double,double) max(int,int)

330

Primeri preklapanja funkcija


void alfa(char x, int y=0); void alfa(char x, float y=0); alfa('5', 77); alfa('5', 77.0f); alfa('5'); // alfa(char,int) // alfa(char,float) // Greka

331

Pretprocesor

332

Pretprocesor
Pretprocesor je deo prevodioca koji obrauje izvorni tekst programa i stvara konani oblik teksta koji se prevodi Pretprocesor radi sledee
umetanje sadraja tekstualne datoteke na odreeno mesto u izvornom tekstu zamene leksikih simbola novim nizovima simbola uslovno ukljuivanje ili izostavljanje delova teksta

333

Direktive pretprocesora
Radom pretprocesora upravlja se specijalnim naredbama koje se nazivaju direktivama pretprocesora Pisanje direktiva
svaka direktiva je u posebnom redu poinje znakom # ispred kojeg mogu biti samo beli znaci nastavljanje direktive u narednom redu oznaava se znakom \ koji je poslednji znak koji nije beli u redu koji se nastavlja

334

Umetanje sadraja datoteke


Koristi se direktiva include iji je opti oblik # include " naziv_datoteke " # include < naziv_datoteke > Najee slui za umetanje *.h datoteka Kod direktive sa znakovima "...", datoteka se prvo trai u direktorijumu u kojem je izvorni tekst programa, a ako se ne pronae trai se u sistemskim direktorijumima
najee slui za umetanje fajlova koje pie programer

Ako se direktiva navede sa znakovima <...>, datoteka se trai u sistemskim direktorijumima


najee slui za umetanje zaglavlja fajlova standardnih biblioteka ili fajlova okruenja u kojem se radi
335

Zaglavlja standardnih biblioteka


Primeri zaglavlja standardnih biblioteka:
<stdio.h> <math.h> <string.h> <vector> <set>

Zaglavlja standardnih biblioteka se uvek nalaze u sistemskim direktorijumima

336

Primeri umetanja datoteke


# include <stdio.h> #include <set> #include "proba.h"

337

Zamena leksikih simbola


Zamena pojavljivanja jednog identifikatora nizom leksikih simbola radi se direktivom define za definisanje makroa Opti oblik makroa bez argumenata je # define IDENTIFIKATOR simbol simbol ... simbol IDENTIFIKATOR se uobiajeno pie velikim slovima Leksiki simboli mogu biti proizvoljni: identifikatori, slubene rei, konstante, operatori, separatori, a moe i ceo niz leksikih simbola da bude prazan

338

Zamena leksikih simbola


Opti oblik makroa sa argumentima je
# define IDENTIFIKATOR(niz_argumenata) simbol ... simbol

Izmeu identifikatora, zagrada i niza argumenata ne sme biti belih znakova Argumenti su formalni argumenti makroa Formalni argumenti makroa nemaju tipove U tekstu iza identifikatora mora da bude napisan niz stvarnih argumenata makroa unutar zagrada

339

Ukidanje zamene leksikih simbola


Radi se direktivom # undef IDENTIFIKATOR Identifikatori makroa nisu sastavni deo programa, ne postoje u vreme prevoenja Identifikatori makroa ne smeju da se poklapaju sa identifikatorima koji se koriste u programu

340

Primeri definisanja makroa


#define MAX_DUZ 100 #define ZAUVEK for( ; ; ) #define MAX(A,B) ((A) > (B) ? (A) : (B)) ... ZAUVEK { ... if (kraj) break; ... } int x = MAX(p+q, r+s); // x = ((p+q) > (r+s) ? (p+q) : (r+s)) int y = MAX(i++, j++); // y = ((i++) > (j++) ? (i++) : (j++))
341

Unapred definisani identifikatori


Identifikatori koji postoje u toku prevoenja datoteke:
decimalna konstanta __LINE__ sadri redni broj tekueg reda izvornog koda koji se prevodi konstantni znakovni niz __FILE__ sadri ime datoteke koja se prevodi konstantni znakovni niz __DATE__ sadri datum prevoenja u formatu "Mmm dd GGGG" konstantni znakovni niz __TIME__ sadri vreme prevoenja u formatu "hh:mm:ss"

Postoje i drugi identifikatori koji zavise od prevodioca

342

Uslovno prevoenje
U toku prevoenja delovi programa se mogu izbaciti (nee se prevoditi) Osnovna direktiva za uslovno prevoenje je # if uslov ... # endif uslov je celobrojni konstantni izraz
operandi su konstante ili identifikatori definisani sa define mogu se koristiti operatori za skalarne numerike podatke moe se koristiti specijalni unarni operator defined ako je uslov ispunjen (0) prevodi se deo programa izmeu #if i #endif, inae (=0) se ne prevodi
343

Operator defined
Unarnim operatorom defined se utvruje da li je neki identifikator definisan direktivom define bez obzira da li taj identifikator ima neku vrednost ili ne Izraz je oblika defined identifikator defined (identifikator) Izraz ima vrednost 1 ako je identifikator definisan sa define i jo nije uniten sa undef, inae je vrednost 0
#if i #endif, inae (=0) se ne prevodi

344

Uslovno prevoenje sa operatorom defined


Uslovno prevoenje najee poinje jednom od direktiva # ifdef identifikator # ifndef identifikator Sa prvom direktivom je uslov ispunjen ako je identifikator definisan, a sa drugom ako nije definisan Grananje uslovnog prevoenja postie se direktivom koja se moe ponoviti vie puta u jednom uslovnom prevoenju # elif uslov U jednom uslovno prevoenju moe se najvie jednom pojaviti direktiva # else Uslovno prevoenje se uvek zavrava direktivom # endif
345

Primer uslovnog prevoenja


#ifdef VERZIJA1 char ver[20]="Verzija #elif defined VERZIJA2 char ver[20]="Verzija #elif defined VERZIJA3 char ver[20]="Verzija #else char ver[20]="Verzija #endif 1"; 2"; 3"; 4";

346

Izbegavanje viestrukog prevoenja datoteke


Pomou direktive include moe se desiti da se jedna datoteka vie puta ukljuiti, to moe dovesti do greke
npr. ne sme se jedan tip vie puta definisati sa typedef

Viestruko prevoenje spreava se uslovnim prevoenjem Preporuuje se da sve *.h datoteke imaju oblik
// ImeDatoteke.h #ifndef _imedatoteke_h_ #define _imedatoteke_h_ // Definicije #endif

Imena svih datoteka jednog programa moraju biti razliita Mogu se koristiti i drugi oblici identifikatora umesto _imedatoteke_h_, uobiajeno je da sadre ime datoteke
347

Greka zbog viestrukog prevoenja *.h datoteka


// Sadrzaj dat1.h typedef double RCoordinate // Sadrzaj dat2.h #include "dat1.h" bool f2(RCoordinate& r); // Sadrzaj dat3.h #include "dat1.h" void f3(RCoordinate& r); // Sadrzaj dat4.h #include "dat2.h" #include "dat3.h" // ...
348

Datoteka dat4.h ukljuuje datoteke dat2.h i dat3.h Obe datoteke dat2.h i dat3.h ukljuuju dat1.h Datoteka dat1.h je dva puta ukljuena u datoteku dat4.h, jednom preko dat2.h i drugi put preko dat2.h Pri prevoenju datoteke dat4.h javlja se greka, tip RCoordinate je definisan vie puta

Primer: nema viestrukog prevoenja *.h datoteka


// Sadrzaj dat1.h #ifndef _dat1_h_ #define _dat1_h_ typedef double RCoordinate #endif // Sadrzaj dat2.h #ifndef _dat2_h_ #define _dat2_h_ #include "dat1.h" bool f2(RCoordinate& r); #endif // Sadrzaj dat3.h #ifndef _dat3_h_ #define _dat3_h_ #include "dat1.h" void f3(RCoordinate& r); #endif // Sadrzaj dat4.h #ifndef _dat4_h_ #include "dat2.h" #include "dat3.h" // ... #endif

Datoteka dat1.h ukljuuje se u dat4.h preko dat2.h U trenutku ukljuivanja datoteke dat3.h u dat4.h, identifikator _dat1_h_ je definisan, pa se sadraj koji je unutar uslovnog prevoenja iz datoteke dat1.h nee ponovo ukljuiti u dat4.h

349

Razne direktive
Redefinisanje identifikatora __LINE__ # line konstanta # line konstanta datoteka Direktiva za prekidanje prevoenja i ispisivanje poruke # error poruka Direktiva za podeavanje parametara prevoenja # pragma simbol simbol ... simbol

350

351

Datoteke u jeziku C

352

Komunikacija programa sa okolinom


Program mora da komunicira sa spoljanjim svetom
dobija ulazne podatke sa ulaznih ureaja
tastatura datoteka sa jedinice masovne memorije (hard disk, CD, ...) ureaj prikljuen na neki port (serijski, paralelni, USB, ...) ... prikazuje na ekranu upisuje u datoteku alje ureaju prikljuenom na neki port (tampa, modem, ...) ...

vraa rezultate obrade

353

Vrste datoteka
Prema nainu smetanja podataka datoteke mogu biti
tekstualne binarne

354

Tekstualne datoteke
Sadre nizove znakova grupisane u redove Znak za prelazak u novi red je '\n' Znakovi u tekstualnim datotekama mogu biti
znakovi koji se ispisuju na ekranu upravljaki znakovi
prelazak u novi red prelazak na novu stranicu tabulacija ...

Numeriki podaci su u memoriji raunara upisani u binarnom obliku


prilikom itanja ili upisivanja u tekstualnu datoteku radi se konverzija
355

Binarne datoteke
Sastoje se od niza bajtova iji je sadraj verna slika naina predstavljanja podatka u memoriji Podaci se itaju i upisuju u binarne datoteke bajt po bajt bez konverzije Mogu postojati samo na jedinicama masovne memorije Program mora da zna kako su podaci zapisani u binarnom fajlu, npr. 8 bajtova mogu da predstavljaju
jedan podatak tipa double dva podatka tipa float dva podatka tipa int etiri podatka tipa short
356

...

Zapis
Sadraj datoteke se moe podeliti na manje logike celine koje se nazivaju zapisi

357

Vrste datoteka prema organizaciji


Sekvencijalne datoteke
pristup zapisima mogu je samo po redosledu smetanja u datoteku (sekvencijalni pristup)

Relativne datoteke
moe se pristupati zapisima po proizvoljnom redosledu na osnovu rednog broja zapisa (direktni pristup)

Indeksne datoteke
moe se pristupati zapisima po proizvoljnom redosledu na osnovu sadraja dela zapisa koji se naziva klju (pristup pomou kljua)

358

Pristup datoteci u C i C++


Postoji samo sekvencijalni pristup Postoji mogunost pozicioniranja na neki bajt unutar datoteke Parcelisanje datoteke moe da uradi programer i da o tome vodi rauna

359

Radnje u radu sa datotekama


Otvaranje datoteke
uspostavljanje veze sa fizikom datotekom u memoriji se pravi struktura pomou koje se brzo pristupa datoteci

Pristup datoteci
itanje ili upisivanje sa ili bez konverzije

Ispitivanje stanja datoteke


da li je dolo do greke pri itanju ili upisivanju

Zatvaranje datoteke
raskidanje veze sa fizikom datotekom unitavanje strukture u memoriji napravljenje pri otvaranju
360

Pokaziva na datoteku
Datoteka je podatak tipa FILE Pokaziva na datoteku je tipa FILE* FILE je strukturirani tip definisan naredbom typedef u fajlu <stdio.h> Definisanje pokazivaa na datoteku FILE* datoteka;

361

Globalni identifikatori
Tri standardne tekstualne datoteke se otvaraju na poetku izvravanja programa Definisana su tri globalna identifikatora za ove datoteke u zaglavlju <stdio.h>
stdin - glavni (standardni) ulaz, predstavlja tastaturu dok se komandom operativnog sistema ne skrene glavni ulaz stdout - glavni (standardni) izlaz, predstavlja ekran dok se komandom operativnog sistema ne skrene glavni izlaz stderr - standardni izlaz za poruke o grekama, predstavlja ekran i ne moe da se skrene na datoteku

362

Deklaracije funkcija za rad sa fajlovima


Sve funkcije u ovom poglavlju deklarisane su u zaglavlju <stdio.h>

363

Otvaranje datoteke
FILE* fopen(const char* ime, const char* reim);

ime je naziv datoteke prema sintaksi operativnog sistema i moe biti cela putanja zajedno sa imenom drajva reim je znakovni niz koji oznaava nain korienja datoteke Podrazumeva se tekstualna datoteka, a osnovni rezimi su
"r" za itanje iz postojee datoteke (read) "w" za upisivanje u novu datoteku (write) "a" za dodavanje na kraj nove ili postojee datototeke (append)

364

Reimi za otvaranje datoteke


Oznake osnovnih reima za rad sa tekstualnim datotekama su "r", "w", "a" Za auriranje sadraja tj. naizmenino itanje i upisivanje dodaje se znak "+", pa su oznake "r+", "w+", "a+" Za rad sa binarnim datotekama dodaje se znak "b", pa su oznake "rb", "wb", "ab", "r+b", "w+b", "a+b" (ili "rb+", "wb+", "ab+" umesto poslednje tri)

365

Rezultat funkcije fopen


Vrednost funkcije fopen je
pokaziva na strukturu pridruenu datoteci u sluaju uspenog otvaranja NULL u sluaju greke

Ako datoteka ne postoji ne moe se otvoriti u reimu "r" Ako datoteka postoji i otvori se u reimu "w", bie unitena prethodna Primeri otvaranja datoteke
FILE* file = fopen("proba.txt", "r"); bool greska = file==NULL; FILE* f = fopen("C:\Demo\binarna.proba.b", "wb");

366

Zatvaranje datoteke
int fclose(FILE* datoteka); datoteka je pokaziva na strukturu datoteke koja se zatvara Rezultat zatvaranja datoteke je
nula u sluaju uspenog zatvaranja simbolika konstanta EOF u sluaju neuspenog zatvaranja

Primer zatvaranja datoteke


bool greska = fclose(file)!=NULL;

367

itanje jednog znaka iz tekstualne datoteke


int fgetc(FILE* datoteka); // funkcija int getc(FILE* datoteka); // makro int getchar(void); // itanje preko glavnog ulaza

Rezultat svake funkcije je:


kod proitanog znaka u sluaju uspeha simbolika konstanta EOF u sluaju nailaska na kraj datoteke ili u sluaju greke

Upravljaki znak za kraj datoteke preko tastature je


<Ctrl>Z pod operativnim sistemom MS-DOS <Ctrl>D pod operativnim sistemom UNIX (Linux)

368

Primer itanja znakova iz datoteke


... FILE* file = fopen("proba.txt", "r"); if(!file) // kod za obradu greke char znak; while((znak = fgetc(file)) != EOF) { // obrada unutar petlje } if(fclose(file)) // kod za obradu greke
369

Upisivanje jednog znaka u tekstualnu datoteku


int fputc(int znak, FILE* datoteka); // funkcija int putc(int znak, FILE* datoteka); // makro int putchar(int znak); // ispisivanje preko glavnog izlaza

Rezultat svake funkcije je:


kod ispisanog znaka u sluaju uspeha simbolika konstanta EOF u sluaju greke u toku pisanja

370

Primer upisivanja znakova u datoteku


// primer upisuje velika slova u fajl, jedno slovo u svakom redu FILE* file = fopen("proba.txt", "w"); if(!file) // kod za obradu greke char c = 'A'; for(int i=0; i<26; i++) { if((fputc(c,file)==EOF) || fputc('\n',file)==EOF) // kod za obradu greke c++; } if(fclose(file)) // kod za obradu greke
371

itanje jednog reda teksta iz datoteke


char* fgets(char* tekst, int n, FILE* datoteka); char* gets(char* tekst); // itanje preko glavnog ulaza

fgets zavrava itanje kad proita n-1 znakova ili znak za kraj reda '\n' i na kraj dodaje znak '\0' gets ita sve znakove do znaka za kraj reda '\n' umesto kojeg u niz tekst dodaje znak '\0' tekst je pokaziva na znakovni niz u koji se upisuje proitani red teksta Vrednost obe funkcije je
pokaziva tekst u sluaju uspenog itanja NULL u sluaju nailaska na kraj datoteke ili u sluaju greke
372

Upisivanje znakovnog niza u jedan red datoteke


int fputs(const char* tekst, FILE* datoteka); int puts(const char* tekst); // preko glavnog izlaza

tekst je pokaziva na znakovni koji se ispisuje Vrednost obe funkcije je


nenegativan broj u sluaju uspenog ispisivanja simbolika konstanta EOF u sluaju u sluaju greke

373

Prenos podataka sa konverzijom - ispisivanje


int fprintf(FILE* datoteka, const char* format, arg1,arg2, ...); int printf( const char* format, arg1,arg2, ...); int sprintf(char* niz, const char* format, arg1,arg2, ...);

Izlazna konverzija argumenta zadata je nizom format Odredite je:


datoteka u sluaju funkcije fprintf glavni izlaz u sluaju funkcije printf znakovni niz u memoriji raunara u sluaju funkcije fprintf, dovoljno dugaak da primi sve argumente i dodatno znak \0

Vrednost sve tri funkcije je broj znakova u sluaju uspeha, ili negativna vrednost u sluaju greke

374

Prenos podataka sa konverzijom - uitavanje


int fscanf(FILE* datoteka, const char* format, arg1, arg2, ...); int scanf( const char* format, arg1, arg2, ...); int sscanf(char* niz, const char* format, arg1, arg2, ...);

Ulazna konverzija argumenta zadata je nizom format Argumenti su adrese podataka ili znakovnih nizova Izvorite je:
datoteka u sluaju funkcije fscanf glavni ulaz u sluaju funkcije scanf znakovni niz u memoriji raunara u sluaju funkcije sscanf, dovoljno dugaak da primi sve argumente i dodatno znak \0

Vrednost sve tri funkcije je broj konvertovanih podataka u sluaju uspeha, ili simbolika konstanta EOF u sluaju greke
375

itanje iz binarne datoteke


int fread(void* niz, int veliina, int broj, FILE* datoteka);

Funkcija ita iz datoteke datoteka najvie broj podataka veliine veliina u memoriju poevi od adrese niz itanje poinje na mestu gde je zavren prethodni pristup datoteci Programer mora da vodi rauna o logikoj strukturi datoteke, veliini podataka, broju i redosledu Vrednost funkcije je broj proitanih podataka Ako u datoteci nema dovoljno podataka bie proitano manje od broj podataka Za ispitivanje greaka koriste se funkcije feof i ferror
376

Primer itanja podataka iz binarnog fajla


const int n_max = 10; int* niz = new int[n_max]; FILE* file = fopen("Proba.bin", "rb"); if(!file) // u sluaju da nije uspelo otvaranje fajla int n = fread(niz, sizeof(int), n_max, file); if(n<n_max) // u sluaju da je proitan manji broj podataka od zahtevanog if(feof(file)) // u sluaju da je itanje dolo do kraja datoteke

377

Upisivanje u binarnu datoteku


int fwrite(const void* niz, int veliina, int broj, FILE* datoteka);

Funkcija upisuje broj podataka veliine veliina iz memorije poevi od adrese niz u datoteku datoteka Pisanje poinje na mestu gde je zavren prethodni pristup datoteci Programer mora da vodi rauna o logikoj strukturi datoteke, veliini podataka, broju i redosledu Vrednost funkcije je broj upisanih podataka U sluaju greke vrednost funkcije je manja od broj podataka
378

Primer prepisivanja podataka iz binarnog fajla


FILE* file_r = fopen("Proba.bin", "rb"); FILE* file_w = fopen("Novi.bin", "wb"); if(!file_r || !file_w) // u sluaju da nije uspelo otvaranje bar jedne datoteke char c; while(!feof(file_r)) { if(fread(&c, 1, 1, file_r) == 1) // ita se 1 bajt fwrite(&c, 1, 1, file_w); // upisuje se 1 bajt } fclose(file_r); fclose(file_w);

379

Nalaenje trenutne pozicije unutar datoteke


long ftell(FILE* datoteka);

Funkcija nalazi trenutnu poziciju u datoteci datoteka Vrednost funkcije je trenutna pozicija u bajtovima u odnosu na poetak datoteke, a u sluaju greke -1L

380

Pozicioniranje unutar datoteke


void rewind(FILE* datoteka); Funkcija radi pozicioniranje na poetak u datoteci datoteka

381

Pozicioniranje unutar datoteke


int fseek(FILE* datoteka, long pomeraj, int reper);

Funkcija radi pozicioniranje na mesto u datoteci datoteka koje je na udaljenosti pomeraj bajtova od oznaene reperne take Reperne take se obeleavaju simbolikim konstantama:
poetak datoteke SEEK_SET trenutna pozicija u datoteci SEEK_CUR kraj datoteke SEEK_END

Sledee pristupanje datoteci (itanje ili pisanje) zapoee na poziciji podeenoj funkcijom fseek Vrednost funkcije je nula u sluaju uspeha, a razliita od nule u sluaju greke
382

Signalizacija greaka
Svaka datoteka ima dva logika identifikatora
indikator kraja datoteke indikator greke

Boni efekat veine funkcija iz <stdio.h> je podeavanje ovih indikatora

383

Signalizacija greaka
void clearerr(FILE* datoteka); Funkcija brie indikatore kraja datoteke i greke int feof(FILE* datoteka); Funkcija ispituje indikator kraja datoteke, ukljuen je ako je vrednost funkcije razliita od nule int ferror(FILE* datoteka); Funkcija ispituje indikator greke datoteke, ukljuen je ako je vrednost funkcije razliita od nule Globalna promenljiva errno, deklarisana u zaglavlju <errno.h>, moe da sadri ifru greke koja nije precizirana standardom
384

385

386

387

Znakovi

388

Znakovni nizovi
Tip za znakovni niz je char[] Na kraju znakovnog niza se dodaje jedan element ija je vrednost jednaka nuli Uvek treba predvideti niz ija je duina za jedan vea od broja elemenata koje treba da sadri niz Primer: da bi sadraj znakovnog niza bio "tri", duina znakovnog niza mora da bude najmanje etiri t r i \0

389

Kodovi znakova
Najee se koristi ASCII kod Znakovi koji se prikazuju na ekranu i koji se tampaju nazivaju se tampajui znakovi
imaju kodove od 32 do 126
slova cifre specijalni znaci

Upravljaki znakovi imaju upravljake efekte


ne prikazuju se na ekranu i ne tampaju se

390

Beli znakovi
Beli znakovi ostavljaju belinu izmeu znakova koji se tampaju
razmak skok na novi list (ff form feed) skok u novi red (lf line feed) povratak na poetak reda (cr carriage return) tabulacija (ht horizontal tab) vertikalna tabulacija (vt vertical tab)

391

Znakovne konstante
Znakovne konstante se piu izmeu para apostrofa Konstanta 'A' je:
tipa int u jeziku C, ima vrednost koda navedenog znaka tipa char u jeziku C++

392

Znakovne konstante
Za tampajue znakove navodi se sam znak, npr. 'a' Upravljaki znakovi navode se sa kosom crtom unazad, npr:
'\r' '\n' '\h' '\t' '\v' za povratak na poetak tekueg reda za skok na poetak novog reda za skok na poetak novog lista za horizontalnu tabulaciju za vertikalnu tabulaciju

393

Znakovne konstante
Mogu da se piu navoenjem oktalne vrednosti sa jednim do tri oktalne cifre iza kose crte unazad
primer: '\7' '\15'

Mogu da se piu navoenjem heksadecimalne vrednosti sa dve cifre iza kose crte unazad i znaka x
primer: '\x07' '\X15'

Obeleavanje zankovnih konstanti oktalnim i heksadecimalnim ciframa treba izbegavati


nije prenosiv program izmeu dva raunara koji koriste razliite kodove

394

Operacije sa znakovima
Ne postoje posebni operatori za obradu znakova Moru se raditi aritmetike operacije sa znakovima
numerika vrednost koda se koristi u izraunavanjima

Primeri:
int i = 'a' 'A'; // i = 32 za ASCII kod char z = 'A' + 32; // z = 'a' za ASCII kod char c = 'G' - 'A' + 'a'; // c='g' za ASCII i EBCIDIC

395

Konstante znakovnog niza


Opti oblik znakovnog niza:
"tekst" belina "tekst" belina ... belina "tekst"

Primeri: "Pozdrav svima!" "Pozdrav " "svima!"

// Identian prethodnom

Prevodilac za svaki znak iz konstantnog znakovnog niza generie po jedan znak i na kraju dodaje znak sa vrednou nula "Pozdrav" je isto to i 'P' 'o' 'z' 'd' 'r' 'a' 'v' '\0'

396

Inicijalizacija znakovnih nizova


Mogu se inicijalizovati konstantama tipa znakovnog niza
duina niza mora da bude bar za jedan vea od broja znakova u konstanti tipa znakovnog niza

Primer dva niza koji se inicijalizuju istim elementima: const char niz1[] = "Dva"; const char niz2[] = {'D', 'v', 'a', '\0'}; Primer inicijalizacije znakovnog niza: char poruka[] = "Pozdrav"; Primer inicijalizacije pokazivaa ija je poetna vrednost adresa konstante tipa znakovnog niza: char* p_poruka = "Pozdrav";
397

Niz pokazivaa na znakovne nizove


char *dani[7] = {"ponedeljak", "utorak", "sreda", "cetvrtak", "petak", "subota", "nedelja" }; dani

p u s c p s n

o t r e e u e

n o e t t b d

e r d v a o e

d a a r k t l

e k \0 t \0 a j

l \0

\0

\0

\0 a \0
398

Ulazna konverzija za znakovne podatke u jeziku C


Za znakovne podatke slue konverzije s i c itanje pomou scanf
konverzijom %s uitava se znakovni niz (tip char[]) izmeu dva bela znaka konverzijom %ns uitava se znakovni niz izmeu dva bela znaka, ali se uitava najvie n znakova konverzijom %c uitava se jedan znak moe da bude i beli znak konverzijom %nc uitava se tano n znakova bez obira da li su beli ili ne

Za s konverziju se dodaje \0 na kraj uitanog niza


niz mora da bude bar za 1 dui od broja uitanih znakova

Za c konverziju se ne dodaje \0
399

Primeri za ulaznu konverziju


char niz1[256], niz2[2]; scanf("%s%1s", niz1, niz2); char z; scanf("%c", &z); char pz = &z; scanf("%c", pz); Ako je promenljiva tipa char mora se koristiti operator za dohvatanje adrese &

400

Izlazna konverzija za znakovne podatke u jeziku C


Pisanje pomou printf
konverzijom %s ispisuje se znakovni niz do znaka \0
ispisuju se i beli znakovi iz znakovnog niza u %n.ks konverziji n je najmanja a k najvea irina polja

konverzijom %c ispisuje se jedan znak bez obzira na irinu polja tj. n


podatak moe da bude izraz bilo kojeg celobrojnog tipa, pri emu se radi automatska konverzija u tip char, tj. koristi se vrednost najnieg bajta

Primer
char ime[32], prezime[32]; ... printf("Ime i prezime: %s %1s", ime, prezime);
401

Biblioteke funkcije
Postoje posebne biblioteke funkcije za rad sa znakovnim podacima koje slue za:
itanje i pisanje znakova bez konverzije ispitivanje znakova rad sa znakovnim nizovima konverziju u numerike tipove podataka

402

itanje i pisanje znakovnih podataka bez konverzije


Biblioteke funkcije za itanje i pisanje bez konverzije deklarisane su u standardnom zaglavlju <stdio.h>
itanje jednog znaka preko glavnog ulaza, ukljuujui i bele znakove int getchar() ispisivanje jednog znaka preko glavnog izlaza int putchar(int c) itanje jednog reda teksta (do znaka \n) preko glavnog ulaza char* gets(char* tekst) ispisivanje ynakovnog niza do znaka \n preko glavnog izlaza int puts(const char* tekst)
403

Ispitivanje znakova
Ispituje se da li je znak slovo, cifra, beli znak, ... Funkcije su u standardnom zaglavlju <ctype.h>
int int int int int int int int int int int int int isalnum(int c) // da li je c alfanumeriki znak isalpha(int c) // da li je c slovo islower(int c) // da li je c malo slovo isupper(int c) // da li je c veliko slovo isdigit(int c) // da li je c decimalna cifra isxdigit(int c) // da li je c heksadecimalna cifra isspace(int c) // da li je c beli znak isgraph(int c) // da li je c tampajui znak ali ne razmak isprint(int c) // da li je c tampajui znak ukljuujui razmak ispunct(int c) // da li je c tampajui znak ali ne slovo ili cifra iscntrl(int c) // da li je c upravljaki znak tolower(int c) // konverzija c u malo slovo toupper(int c) // konverzija c u veliko slovo 404

Rad sa znakovnim nizovima


Funkcije su u standardnom zaglavlju <string.h>
char* strcpy(char* t, const char* t); char* strncpy(char* t, const char* t, size_t n); char* strcat(char* t, const char* t); char* strncat(char* t, const char* t, size_t n); size_t strlen(const char* s); char* strchr(const char* u, int c); char* strrchr(const char* u, int c); char* strstr(const char* u, const char* s); char* strcspn(const char* u, const char* s); char* strspn(const char* u, const char* s);

405

Konverzija u numerike tipove


Funkcije su u standardnom zaglavlju <stdlib.h> Beli znakovi na poetku se preskau Konverzija se zavrava kod prvog znaka koji ne moe da se konvertuje
double atof(const char* s); int atoi(const char* s); long atol(const char* s);

406

407

Strukture u jeziku C

408

Strukture u jeziku C
Strukture su sloeni tipovi podataka koji se sastoje od elemenata proizvoljnog prostog ili sloenog tipa Elementi strukture se nazivaju i polja strukture Polja stukture mogu da budu razliitih tipova
prosti tipovi nizovi strukture

Mogu da se prave nizovi iji su elementi strukture Mogu da postoje pokazivai na strukture

409

Primer definisanja strukture


Struktura za take u ravni struct tacka { double x, y; };

410

Definisanje struktura
Opti oblik je: struct ime_strukture { niz_deklaracija } ime_strukture je identifikator strukture
nije identifikator tipa mora da se navodi sa struct ime_strukture

niz_deklaracija je niz deklaracija polja strukture Svaka deklaracija ima oblik naredbe za definisanje podataka: tip polje, polje, ... polje; tip je osnovni tip polja u strukturi polje je idenfikator polja
moe imati modifikator ako je polje niz ili pokaziva
411

Polja strukture
Doseg identifikatora polja je unutar strukture (strukturni doseg) Polja u razliitim strukturama mogu da imaju iste identifikatore

412

Podaci strukturnog tipa


Mogu da se navedu odmah iza definicije strukture struct tacka { int x, y; } a, b, c; ee se jednom naredbom definie struktura, a u posebnim naredbama se definiu podaci: struct tacka { int x, y; }; struct tacka a, b, c; Definicija strukture se najee pie u jednoj *.h datoteci, a koristi se u vie datoteka

413

Dodela identifikatora strukturnom tipu


Opti oblik je: typedef struct ime_strukture { niz_deklaracija } Ime_tipa; Ime strukture moe da se izostavi: typedef struct { niz_deklaracija } Ime_tipa; Primeri: typedef struct tacka { int x, y; } Tacka; typedef struct { int x, y; } Tacka; Primer definisanja podatka: struct tacka a, b; // ako je definisano ime strukture Tacka c, d; // ako je definisan tip strukture
414

Poetne vrednosti polja strukture


Opti oblici su: { vrednost, vrednost, ... vrednost } izraz izraz je izraz ili poziv funkcije, iji rezultat mora biti istog strukturiranog tipa kao i podatak kojem se dodeljuje vrednost Primer za prvi sluaj: typedef struct tacka { int x, y; } Tacka; Tacka a = { -5, 8 };

415

Pristupanje poljima strukture


Poljima strukture se pristupa preko imena polja, ali se mora navesti i stukrura ijem se polju pristupa Za pristupanje polju strukture koristi se binarni operator taka .
prvi operand je identifikator strukture drugi operand je identifikator polja strukture prioritet je 18 i grupisanje je sleva udesno

Primer:
typedef struct tacka { int x, y; } Tacka; Tacka a, b; a.x = 5; a.y = 6; b.x = a.x; b.y = a.x;

416

Pristupanje polju strukture preko pokazivaa


Za pristupanje polju strukture preko pokazivaa na strukturu koristi se binarni operator ->
prvi operand je pokaziva na strukturu drugi operand je identifikator polja strukture prioritet je 18 i grupisanje je sleva udesno

Primer:
typedef struct tacka { int x, y; } Tacka; Tacka a, b; Tacka* pt = &a; // pt pokazuje na taku a (*pt).x = 5; // a.x = 5 pt->y = 6; // a.y = 6 pt = &b; // pt pokazuje na taku b pt->y = a.x; // b.y = 5
417

Primer definisanja pravougaonika


typedef struct tacka { int x, y; } Tacka; typedef struct pravougaonik { Tacka dole_levo, gore_desno; } Pravougaonik; Pravougaonik w, x = { {0, 0}, {1, 1} }; w.dole_levo.x = x.gore_desno.x; w.dole_levo.y = x.gore_desno.y; Tacka* pt = &w.gore_desno; pt->x = 10; pt->y = 5;
418

419

Imenski prostori

420

Imenski prostori
U velikim programima mogu se pojaviti ista globalna imena u razliitim datotekama Imenski prostor slui za grupisanje globalnih imena u vie dosega Svaki imenski prostor ini poseban doseg (prostorni doseg)

421

Definisanje imenskog prostora


Opti oblik za definisanje imenskog prostora u datotekom dosegu je: namespace Identifikator { // Sadraj imenskog prostora } Identifikator je ime imenskog prostora mora biti jedinstveno u svom dosegu Sadraj imenskog prostora je uobiajeni tekst programa Ne prenosi se iz datoteke u datoteku. Ako su delovi sadraja imenskog prostora potrebni u vie datoteka, treba ih ponoviti u svakoj od tih datoteka. Koristiti zaglavlje (.h) datoteke. Globalni identifikatori (van dosega funkcija) mogu da se koriste samo unutar imenskog prostora
422

Primer definisanja imenskog prostora


namespace Alfa { int a = 55; // Definicija globalne promenljive float f() { return 5; } extern char b; // Deklarisanje double g(double); // Deklarisanje } namespace Beta { double a = 99; } namespace extern double char b Alfa { int x; f(int); = '!';

// // // double g(double x)

Preklapanje Definisanje ranije deklarisane promenljive { return x / 2; }


423

Upotreba identifikatora u imenskom prostoru


Unutar imenskog prostora globalni identifikatori se koriste tako to se navodi samo identifikator Identifikatori iz nekog imenskog prostora mogu da se dohvate pomou operatora za razreenje dosega :: Imenski_prostor :: identifikator Imenski_prostor je identifikator imenskog prostora identifikator je globalni identifikator iz navedenog imenskog prostora Operator za razreenje dosega :: je prioriteta 19 (najvii) i grupie se sleva udesno

424

Uvoenje identifikatora iz imenskog prostora


Identifikatori iz nekog imenskog prostora mogu da se uvezu i da se nadalje koriste bez navoenja identifikatora imenskog prostora iz kojeg se uvoze Koristi se naredba using Ako je potreban pojedinani identifikator: using Imenski_prostor :: identifikator Ako se uvozi seo imenski prostor: using namespace Imenski_prostor

425

Uvoenje identifikatora iz imenskog prostora


Ako su lokalni identifikator i identifikator iz uvezenog imenskog prostora jednaki:
navoenje identifikatora odnosi se na lokalni identifikator za identifikator iz uvezenog imenskog prostora mora se koristiti operator ::

426

Primer korienja identifikatora iz imenskih prostora


int p = Alfa::a; double q = Beta::a; using Alfa::x; int r = x; using namespace Alfa; a = 99; double s = f(x); using namespace Beta; int t = a; int u = Alfa::a; double v = Beta::a; using Alfa::a; int w = a;

// r = Alfa::x; // Alfa::a = 99; // Alfa::f(int) // Greka: Alfa::a, Beta::a;

// Koristi se Alfa::a

427

Definisanje funkcija iz imenskog prostora


Funkcije deklarisane u imenskom prostoru mogu da se definiu i izvan imenskog prostora kojem pripadaju
ispred imena funkcije mora da se navede imenski prostor sa operatorom za razreenje imenskog prostora doseg imenskog prostora se odnosi na celo telo funkcije

428

Primer
namespace Alfa { int a = 55; double f(int); extern int x; double g(double); } Podatak i funkcija deklarisani u imenskom prostoru definiu se izvan imenskog prostora: int Alfa::x = 22; double Alfa::f(int x) { return x + a; }
429

Bezimeni imenski prostor


Dobija se izostavljanjem identifikatora u definiciji imenskog prostora: namespace { // Sadraj imenskog prostora }

430

Bezimeni imenski prostor


Ne stvara novi doseg imena, uklapa se u okruujui datoteki doseg. Identifikatori su obini globalni identifikatori
mogu da se koriste se bez navoenja operatora :: ako su pokriveni moraju da se dohvate operatorom :: ako se uveze isti identifikator iz nekog drugog imenskog prostora, identifikator it bezimenog imenskog prostora vie ne moe da se dohvati ni na koji nain

431

Razlika izmeu globalnih identifikatora


Obini globalni identifikatori imaju spoljanje povezivanje Globalni identifikatori iz bezimenog imenskog prostora imaju unutranje povezivanje (unutar datoteke, lokalni)
ovo ne moe da se promeni ni korienjem modifikatora extern

Preporuka:
za definisanje globalnih podataka i funkcija sa unutranjim povezivanjem treba koristiti bezimeni imenski prostor, a ne modifikator static kao to se radi u jeziku C

432

Primer za bezimeni imenski prostor


namespace { int a = 1; } int b = 2; namespace Alfa { int a = 3; int b = 4; } void f() { int p = a; int q = b; int r = Alfa::a; using namespace Alfa; int s = a; int t = Alfa::a; int u = b; int v = ::b; int w = Alfa::b; int b = 5; int x = b; int y = ::b; int z = Alfa::b; } // Unutranje povezivanje za "a" // Spoljanje povezivanje za "b"

// p = ::a // q = ::b // Greka, ::a ili Alfa::a // Greka, b ili Alfa::b // Lokalno "b" unutar funkcije // Lokalno "b" // Globalno "b"

433

Uklapanje imenskih prostora


Unutar jednog imenskog prostora, izvan funkcija, moe da se definie drugi imenski prostor (koji je uklopljen) Identifikator (ime) uklopljenog imenskog prostora
unutar spoljanjeg imenskog prostora koristi se samostalno izvan spoljanjeg imenskog prostora mora da se navede i identifikator spoljanjeg imenskog prostora

Primer:
namespace Alfa { // ... namespace Beta { int x = 1; } } int y = Alfa::Beta::x;
434

Doseg uklopljenih imenskih prostora


Doseg spoljanjeg imenskog prostora je globalan u odnosu na unutranji imenski prostor
identifikatori promenljivih definisanih u spoljanjem imenskom prostoru mogu da se dohvate iz unutranjeg imenskog prostora i bez korienja operatora ::

Doseg unutranjeg imenskog prostora je lokalan u odnosu na spoljanji imenski prostor


identifikatori promenljivih definisanih u unutranjem imenskom prostoru mogu da se dohvate iz spoljanjeg imenskog prostora samo pomou operatora ::

435

Primer uklapanja imenskih prostora


namespace Alfa { // Spoljanji imenski prostor int a = 1; int f() { return 2; } extern int b; //definisano negde drugde u Alfa int g(); namespace Beta { // Unutranji imenski prostor extern int a; //definisano negde drugde u Beta int f(); int g() { return b; } // Alfa::b } int c = a + Beta::a; //Alfa::a + Beta::a }

436

Primer uklapanja imenskih prostora nastavak


void h() int p int q int r int s using int t int u int v int w { = = = = Alfa::a; Alfa::f(); Alfa::Beta::a; Alfa::Beta::f(); t u v w = = = = Alfa::a Alfa::f() Alfa::Beta::a Alfa::Beta::f()

namespace Alfa; = a; // = f(); // = Beta::a; // = Beta::f(); //

} // Deklarisanje promenljivih i funkcija izvan // prostora imena (v. slajdove 428 i 429) int Alfa::b = 3; // Deklarisano sa extern u Alfa int Alfa::g() { return 4; } // Deklaracija u Alfa int Alfa::Beta::a = 5; // Deklarisano sa extern u Beta int Alfa::Beta::f() { return b; } // Alfa::b;
437

Imenski prostor std


Svi globalni identifikatori predvieni standardom su u imenskom prostoru std Da bi globalni identifikatori predvieni standardom bili u imenskom prostoru std treba koristiti sistemska zaglavlja bez ekstenzije .h, npr. zaglavlje <iostream> Postoje i varijante zaglavlja koje globalne identifikatore predviene standardom ne stavljaju u imenski prostor std, i te varijante sistemskih zaglavlja imaju ekstenziju .h, npr. zaglavlje <iostream.h>

438

Globalni identifikator u imenskom prostoru std


Primer:
#include <iostream> int main() { int n; std::cout << "n? "; std::cin >> n; std::cout << "n^2= " << n*n << std::endl; using namespace std; cout << "n? "; cin >> n; cout << "n^2= " << n*n << endl; }

439

Globalni identifikator nije u imenskom prostoru std


Primer:
#include <iostream.h> int main() { int n; cout << "n? "; cin >> n; cout << "n^2= " << n*n << endl; }

440

Biblioteke funkcije nasleene iz jezika C


Zaglavlja koja koriste imenski prostor std nemaju ekstenziju *.h i imaju dodato slovo "c" ispred imena koje je korieno u jeziku C I dalje se mogu koristiti stara zaglavlja iz jezika C koja ne stavljaju imena u imenski prostor Primeri novih i starih zaglavlja <cstdlib> <stdlib.h> <cstdio> <stdio.h> <cmath> <math.h> <cctype> <ctype.h> <cstring> <string.h>
441

Primer za matematike funkcije


#include <iostream> using namespace std; // pozicija komande using!! #include <cmath> int main() { double x=2, y=5; cout << "x^y= " << std::pow(x,y) << endl; using namespace std; cout << "x^y= " << pow(x,y) << endl; }

Bolje je da se prvo navedu direktive include za sva standardna zaglavlja i da iza njih stavi jedna naredba using namespace std;
442

443

Ulaz i izlaz podataka u jeziku C++

444

Ulaz i izlaz
Ulaz i izlaz nisu deo jezika C++
ostvaruju se pomou bibliotekih klasa

Datoteke u C i C++ su dugaki nizovi bajtova koji se nazivaju tokovi (stream)


ulazni tokovi mogu biti tastatura, memorija, hard disk, ...

445

Klase za tokove
Klase za rad sa tokovima na hard disku (datotekama):
ofstream samo za izlazne datoteke ifstream samo za ulazne datoteke fstream za ulazno-izlazne datoteke klase su opisane u zaglavlju <fstream> ostringstream samo za smetanje podataka u tokove istringstream samo za uzimanje podataka iz tokova stringstream za uzimanje i smetanje podataka klase su opisane u zaglavlju <sstream>

Klase za rad sa tokovima u operativnoj memoriji:

446

Klasni dijagram

447

Klase za tokove
Klasa ios sadri
zajednike funkcije za sve vrste tokova simbolike konstante
pri korienju se pie npr. ios::in, ios::binary

Klase ostream i istream slue za prenos podataka sa ili bez konverzije


ostream sadri sve radnje za izlazne tokove istream sadri sve radnje za ulazne tokove klase su opisane u zaglavlju <iostream>

Klasa iostream slui za objedinjavanje ulaznih i izlaznih radnji u jednu klasu


448

Klase za elementarne radnje sa tokovima

Osnovna klasa za elementarne radnje sa fizikim ureajima je streambuf Klase slue za rukovanje ulazno-izlaznim baferima Ne pripadaju hijerarhiji izvoenja klasa koja poinje klasom ios

449

Standardni tokovi
Na poetku izvravanja programa automatski se stvaraju sledee dve globalne promenljive tipa tokova: cin glavni (standardni) ulaz, tip istream
tastatura dok se glavni ulaz ne skrene u programu ili operativnom sistemu

cout glavni (standardni) izlaz, tip ostream


ekran dok se ne izvri skretanje

450

Standardni tokovi
cerr (standardni) izlaz za poruke, tip ostream
ekran dok se ne izvri skretanje koristi se za poruke o grekama

clog (standardni) izlaz za zabeleke, tip ostream


ekran dok se ne izvri skretanje koristi se za voenje evidencije o toku izvravanja prgrama

451

Primer
Primer programa koji uitava dva broja i ispisuje zbir: #include <iostream> using namespace std; void main() { cout << "a,b? "; int a,b; cin >> a >> b; int c = a + b; cout << "a+b= " << c << \n; }

452

453

Klase

Klase
Klase su sloeni tipovi podataka Obezbeuju kapsulaciju i nasleivanje Sastoje se od ureenih nizova elemenata koji mogu da budu meusobno razliitih tipova i koji se nazivaju lanovi klase Podaci klasnih tipova su primerci klase i nazivaju se objekti Pojam podatak obuhvata i vrednosti standardnih tipova i objekte klasnih tipova Skalarni podaci, pokazivai, strukture i objekti su pojedinani podaci Nizovi
2

Klase
lanovi klase
podaci funkcije

Vrednosti podataka lanova ine stanje (vrednost) objekta, i nazivaju se i atributi ili polja klase ili objekta Funkcije lanovi izvode operacije nad podacima lanovima i mogu da menjaju stanje objekta Funkcije lanovi se nazivaju metodi

Klase
Klase su pravi tipovi:
odreuju mogue vrednosti objekata odreuju mogue operacije nad objektima spreavaju izvravanje bilo koje druge operacije nad objektima obezbeuju obaveznu inicijalizaciju objekata obezbeuju unitavanje objekata

Pristup lanovima klase


lanovi klase mogu da budu
privatni javni zatieni (u vezi s izvedenim klasama)

Privatnim lanovima moe da se pristupa samo unutar klase Javnim lanovima moe da se pristupa unutar klase i iz delova programa izvan klase U veini sluajeva
podaci lanovi su privatni neki metodi su privatni, a neki javni
5

Definisanje klase
U definiciji klase se navode svi lanovi klase Na osnovu definicije zna se potreban prostor za smetanje objekta te klase u memoriju Klasa se definie opisom class iji je oblik: class Identifikator { lan lan ... public: lan lan ... private: lan lan ... };

Definisanje klase
Identifikator u definiciji klase je identifikator tipa klase
moe da se koristi na svim mestima gde se oekuje identifikator tipa

Javne i privatne delove klase odreuju modifikatori:


public za javni pristup private za privatni pristup

lanovi pre prvog modifikatora za pristup su privatni

Definisanje klase
lan u definiciji klase moe da bude
definicija podatka lana klase definicija metoda deklaracija metoda naredba typedef ili enum
uvode indentifikator tipa ili simbolikih konstanti

Definicija podatka lana klase


Ima opti oblik naredbe za definisanje podatka Podatak lan moe da bude i
pokaziva referenca niz

Ne mogu da se navode inicijalizatori Ne mogu da budu nepostojani (volatile) Ne mogu da budu istog tipa kao klasa kojoj pripadaju, ali mogu da budu pokazivai ili reference na klasu kojoj pripadaju

Definicija metoda
Ima isti oblik kao i definisanje obinih (globalnih) funkcija Podrazumeva se modifikator inline Vrednost metoda moe da bude istog tipa kao i klasa kojoj metod pripada Argumenti metoda mogu da budu istog tipa kao i klasa kojoj metod pripada

10

Deklaracija metoda
Ima isti oblik kao i deklaracija obinih (globalnih) funkcija Metodi koji se samo deklariu u klasi moraju da se definiu izvan klase Za metode definisane izvan klase ne podrazumeva se modifikator inline, ali moe da se doda u definiciji

11

Naredba typedef ili enum u definiciji klase


Uvode indentifikator tipa ili simbolikih konstanti Ne stvaraju nove lanove klase Primer
class Predmet { ... public: enum Boja{ CRVENA, ZELENA, PLAVA }; ... } Predmet::Boja boja = Predmet::CRVENA; if(boja != Predmet::ZELENA) { ... }
12

Doseg identifikatora
Identifikatori definisani unutar klase imaju doseg do kraja definicije klase Kae se da lanovi klase imaju klasni doseg

13

Deklarisanje klase
Opti oblik deklaracije klase je class Identifikator; Posle deklaracije
mogu da se definiu pokazivai i reference na objekte klase ne mogu da se definiu objekti klase i da se pristupa lanovima klase

14

Pisanje definicije klase


Definicija klase se najee pie u *.h datoteci Metodi se najee samo deklariu unutar definicije klase, a definiu se u *.cpp datoteci Jedna klasa se najee pise u dve datoteke, jedna *.h i jedna *.cpp, i te dve datoteke najee imaju isto ime Primer
Proba.h sadri definiciju klase Proba Proba.cpp sadri definiciju metoda klase Proba

15

Primer definisanja klase


class Nesto { int a, b; int f(int); private: Nesto n; // Greka Nesto* pn; Nesto& rn; public: int c; int g(int); Nesto u (Nesto); Nesto* v (Nesto*); Nesto w (Nesto&); };

16

Radnje sa objektima posle definisanja klase


Definisanje (stvaranje) objekata i nizova objekata ([]) Definisanje pokazivaa (*) i referenci (&) na objekte Dodeljivanje vrednosti (=) jednog objekta drugom (kopiranje polje po polje, ali samo za jednostavne objekte. Za polja koji su pokazivai na delove memorije u dinamikoj zoni, mora preklopljeni operator.) Dohvatanje adrese objekta (&), pristup objektima na osnovu adrese (*) i indeksiranjem ([]) Pristup lanovima objekta neposredno tj. preko imena objekta (.) ili posredno tj. preko pokazivaa na objekat (->)
17

Objekti
Definiu se naredbama za definisanje
tip je identifikator klase

Svaki objekat sadri zaseban komplet svih podataka lanova klase Metodi se u memoriju smetaju samo jednom Metodi se pozivaju za konkretne objekte
metod pozvan za konkretan objekat obrauje podatke lanove iz tog objekta

18

Primer korienja klase Nesto


Nesto n, *pn, &rn=n; n.c = 55; // c je javni lan int i = n.g(12); // poziv javnog metoda n.a = 0; // greka, privatni lan int j = n.f(2); // greka, privatni metod pn = new Nesto; // stvaranje dinamikog objekta *pn = rn; // kopiranje objekta int k = pn->g(3); // pristupanje preko pokazivaa rn = n.u(*pn); // argument i rezultat su tipa Nesto delete pn; // unitavanje dinamikog objekta
19

Dodela vrednosti jednog objekta drugom


Kopiraju se sva polja iz jednog objekta u drugi Ako je polje pokaziva kopira se njegova vrednost, a ne pravi se novi podatak na koji pokazuje pokaziva
class Alfa { public: int i; double* pd; }; ... Alfa a, b; a.i = 10; a.pd = new double[5]; b = a; //b.i=10; b.pd i a.pd pokazuju na isti niz
20

Objekti argumenti funkcija


Objekat argument funkcije se prenosi po vrednosti
kopiraju se svi lanovi podaci iz objekta koji je stvarni argument u formalni argument funkcije koji je lokalni podatak unutar funkcije

Da se ne bi kopirao objektat treba kao argumente funkcija koristiti pokazivae ili reference

21

Metodi
Pored formalnih argumenata metodi klasa imaju jedan skriveni argument i to je objekat za koji se poziva metod Unutar metoda se pristupa lanovima skrivenog argumenta navoenjem njihovog imena Adresa skrivenog argumenta nalazi se u pokazivau sa imenom this Skriveni argument moe da bude nepromenljiv (const) ili nepostojan (volatile)

22

Pokaziva this
Koristi se unutar metoda za pristupanje objektu za koji je pozvan metod Tip skrivenog parametra je u svakoj klasi je nepromenljiv pokaziva na tu klasu (za klasu T to je T* const) Prema tome, unutar svake klase pokaziva this je tipa te klase

23

Preklapanje metoda
Metodi mogu da se preklapaju Preklopljeni metodi moraju da se razlikuju po broju i / ili tipu arumenata Koji od preklopljenih metoda se poziva odreuje se na osnovu broja i tipa argumenata u trenutku prevoenja

24

Modifikatori za skriveni argument


Skriveni argument moe da bude nepromenljiv (const) ili nepostojan (volatile) Modifikator const oznaava da metoda nee promeniti vrednost nijednog polja u objektu za koji je pozvana (tj. tekuem objektu). Deklaracija metoda iji skriveni argument ima modifikator: tip metod (argumenti) modifikator; Definicija metoda iji skriveni argument ima modifikator tip metod (argumenti) modifikator { // Telo metoda } Primer int dohvatiA() const { return a; }
25

Vraanje pokazivaa ili reference na polje objekta


Ne preporuuje se: tip& metod (argumenti) const; tip* metod (argumenti) const;
preko pokazivaa ili reference se moe promeniti polje nepromenljivog objekta

Preporuuju se dva metoda: tip& metod (argumenti) ; const tip& metod (argumenti) const; tip* metod (argumenti) ; const tip* metod (argumenti) const;
jedan metod e se pozivati za promenljivi, a drugi za nepromenljivi objekat
26

Primer
int Nesto::f(int x) { int z=x+a; // z = x + this->a return z/b; // z / this->b; } Nesto Nesto::h(Nesto x) { Nesto y; y.a = x.a + this->a; y.b = x.b * a; return y; }
27

Primer definisanja klase


Klasa Tacka za rad sa takama u ravni U datoteci Tacka.h je definisana klasa
neki jednostavni metodi su definisani unutar definicije klase ostali metodi su samo deklarisani unutar definicije klase

U datoteci Tacka.cpp su definisani ostali metodi


ovi metodi su definisani izvan definicije klase da bi se znalo da metod pripada klasi Tacka, ispred imena metoda se dodaje ime klase sa operatorom :: za razreenje dosega

28

Sadraj datoteke Tacka.h


class Tacka { private: double m_x; double m_y; public: void koordinate(int x, int y){ m_x = x; m_y = y; } double apcisa() const { return m_x; } double ordinata() const { return m_y; } double poteg() const; double rastojanje(Tacka) const; Tacka najbliza(const Tacka*, int) const; void citaj(); void pisi() const; };

29

Sadraj datoteke Tacka.cpp


#include <cmath> #include <iostream> using namespace std; #include "Tacka.h" double Tacka::poteg() const { return sqrt(m_x * m_x + m_y * m_y); } double Tacka::rastojanje(Tacka t) const { return sqrt(pow(m_x-t.m_x,2)+pow(m_y-t.m_y,2)); }
30

Sadraj datoteke Tacka.cpp nastavak


Tacka Tacka::najbliza(const* Tacka niz, int n) const { if(!niz || n < 1) throw "greska"; Tacka t = niz[0]; double minr = rastojanje(t); for(int i=1; i<n; i++) { double tmp = this->rastojanje(niz[i]); if(minr > tmp) { minr = tmp; //zapamti trenutno min rast. t = niz[i]; //zapamti tekuu najbliu taku } } return t; } 31

Sadraj datoteke Tacka.cpp nastavak


void Tacka::citaj() { cin >> m_x >> m_y; } double Tacka::pisi() const { cout << '(' << m_x << ',' << m_y << ')'; }

32

Primer korienja klase Tacka


#include <iostream> using namespace std; #include "Tacka.h" int main() { cout << "\nUnesite broj tacaka u nizu: "; int n; cin >> n; if(n<1) return 1; Tacka* niz = new Tacka[n]; // Unosenje niza tacaka cout << "\nUnesite niz XY tacaka"; for(int i=0; i<n; i++) niz[i].citaj();

33

Primer korienja klase Tacka nastavak


cout << "\nUnesite referentnu tacku"; double x, y; cin >> x >> y; Tacka t; t.koordinate(x, y); cout << "\nReferentna tacka: "; t.pisi(); cout << endl; cout << "Udaljenost od koordinatnog pocetka je:" << t.poteg() << endl; Tacka w = t.najbliza(niz, n); cout << "Najbliza tacka referentnoj je:" w.pisi(); cout<<"\nRastojanje:" << t.rastojanje(w) << endl; delete[] niz; //return 0; // Suvino u C++ }
34

Prijateljske funkcije klase


Funkcije koje nisu lanovi te klase ali imaju pravo da pristupaju privatnim lanovima te klase U definiciji klase se mora navesti deklaracija ili definicija prijateljske funkcije sa modifikatorom friend friend tip funkcija (argumenti) ; friend tip funkcija (argumenti) { telo } Svejedno je da li se navodi u javnom ili privatnom delu, poto nije lan klase Za prijateljske funkcije definisane unutar definicije klase podrazumeva se modifikator inline Prijateljske funkcije mogu da budu obine (globalne) funkcije ili da budu metode drugih klasa. Globalne funkcije imaju datoteki doseg

35

Prijateljske funkcije lanovi druge klase


Funkcija lan jedne klase moe da bude prijateljska funkcija druge klase Ako su sve funkcije lanovi jedne klase prijateljske funkcije druge klase, to se oznaava u drugoj klasi sa: friend Identifikator_klase ; Ili ako prva klasa jo nije definisana: friend class Identifikator_klase ;

36

Primer prijateljske funkcije lanice druge klase


class B { private: int _b; friend int A::Func1( B& ); }; int A::Func1( B& b ) { return b._b; } // OK int

37

Razlika metoda i prijateljskih funkcija


Pozivanje
metodi se pozivaju za objekat prijateljske funkcije imaju po jedan parametar vie kod prijateljskih funkcija nego kod metoda objekat kao argument (nemaju pokaziva this za prijateljsku klasu)

Prijateljska funkcija moe da bude prijatelj vie klasa istovremeno Primer korienja prijateljske funkcije: kada neka funkcija trba da pristupa lanovima vie klasa, npr. ako elimo da realizujemo mnoenje matrice sa vektorom (klase Matrica, Vektor) Poziv: f(x) umesto x.f()
38

Primer za prijateljske funkcije


class Alfa { int m_x; public: void postaviX(int x) { m_x = int dohvatiX() { return m_x; friend void postaviXf(int x, friend int dohvatiXf(Alfa a) }; void main() { Alfa a; a.postaviX(5); int i = a.dohvatiX(); postaviXf(3, a); int j = dohvatiXf(a); }

x; } } Alfa& a) { a.m_x=x; } { return a.m_x; }

// // // //

metod metod prijateljska funkcija prijateljska funkcija


39

Alternativa za funkciju postaviXf


Mogue je izostaviti parametar koji predstavlja objekat u prijateljskoj funkciji: friend Alfa postaviXf(int n) { Alfa w; w.x=n; return w} Poziv: Alfa a = postaviXf(55); Sada je to neka vrsta funkcije za konverziju iz tipa int u tip Alfa.
40

Primer za objekte
Statiki objekti Tacka obj1; obj1.koordinate(0,1); Tacka obj2; obj2.koordinate(4,4); Dinamiki objekat Tacka* pObj = new Tacka; pObj->koordinate(5,5); delete pObj; Svaki objekat ima svoje kopije svih podataka lanova
41

obj1 m_x m_y obj2 m_x m_y

0 1 4 4

pObj

m_x m_y

5 5

Primer za dinamike objekte


Pravljenje dinamikih objekata Tacka* pt1 = new Tacka; pt1->koordinate(5,5); Tacka* pt2 = new Tacka; pt2->koordinate(0,0); Tacka* pt3; Tacka* pt4 = pt2; Oslobaanje memorije delete pt4; delete pt1; pt1 m_x m_y pt2 pt3 pt4 m_x m_y 5 5 0 0

42

Zajedniki lanovi klasa


Zajedniki lanovi se dobijaju stavljanjem modifikatora static na poetku definicije ili deklaracije lana lanovi koji nisu zajedniki su pojedinani (koji nemaju modifikator static)

43

Podaci zajedniki lanovi klasa (zajednika polja)


Postoji samo jedan primerak lana koji je zajedniki za sve objekte te klase bez obzira na broj objekata, menjanjem vrednosti zajednikog polja menja se stanje svih objekata te klase. Zajednika polja su specijalni globalni podaci

trajni spoljanje povezivanje


Ako su zajednika polja privatna mogu se menjati samo metodima klase Opis polja unutar klase je samo deklaracija polja (ne dodeljuje se memorija) Definicija polja mora da se navede izvan definicije klase

mora da se koristi operator za razreenje dosega :: prilikom definisanja mogu da se inicijalizuju, ako ne, podrazumevaju se nule inicijalizacija se obavlja pre pozivanja funkcije main
44

Primer za zajednike podatke


class Alfa { public: static int a; int b, c; }; int Alfa::a = 10; Alfa obj1; Alfa obj2; Alfa obj3; Svaki objekat ima svoje kopije podataka lanova koji nisu zajedniki Postoji samo jedna kopija zajednikog podatka a 10 obj1 b c obj2 b c obj3 b c 0 0 0 0 0 0

45

Zajedniki metodi
Ne pozivaju se za objekat, tj. nemaju skriveni argument Nemaju pokaziva this Preko identifikatora lana mogu da pristupaju samo zajednikim lanovima (poljima i metodima) Pojedinanim lanovima mogu da pristupaju samo za konkretne objekte koji mogu biti
argumenti zajednikih metoda lokalni podaci zajednikih metoda globalni podaci (static)

46

Pristupanje zajednikim lanovima


Preko objekta ( objekat.lan ) Preko pokazivaa ( pokaziva->lan )
objekat i pokaziva mogu biti izrazi

Preko imena klase ( Klasa::lan ) Izriito se preporuuje korienje obilka Klasa::lan


naglaava se da se pristupa celoj klasi a ne nekom objektu eventualne promene se odnose na celu klasu

Zajednikim lanovima se moe pristupati i kad nije napravljen nijedan objekat klase
pristupa im se Klasa::lan
47

Primer za statike lanove


class Abc { static int a; int b; public: static int f(); static void g(Abc, Abc*, Abc&); int h(int); }; int Abc::a = 10; int Abc::f() { int i = a; int j = b; return i + j; }

// Greka: zajedniki metod, pojedinani lan // (this->b, a this ne postoji)


48

Primer za statike lanove nastavak


// Zajedniki metod koji pristupa pojedinanim lanovima objekata void Abc::g(Abc o, Abc* p, Abc& r) { // Pristup pojedinacnim clanovima objekata koji // su parametri funkcije (vrednost, *, &) int i = o.b; int j = p->b; r.b = i + j; }
// Pojedinani metod moe da pristupa pojedinanim i zajednikim lanovima, // ima this

int Abc::h(int x) { return (a + b) * x; }


49

Primer za statike lanove nastavak


void main() { int i = Abc::f(); int j = Abc::h(5); Abc obj; int k = obj.h(5);

// zajedniki metod // greka, mora se pozvati za objekat // objekat // sve tri metode mogu da se pozivaju // za objekat int m = obj.f(); // nain pozivanja koji treba izbegavati int s = obj.h(7) // mora konkretan objekat Abc::g(obj, &obj, obj);

50

Pokazivai na polja klasa


Definie se naredbom: tip Klasa::* identifikator tip je tip polja kojima se moe pristupiti preko pokazivaa Klasa je identifikator klase ijim se poljima pristupa Pokaziva na polje kome je dodeljena vrednost samo oznaava polje kojem e se pristupati Polju se moe pristupiti tako to se navede objekat ijem polju se pristupa

51

Pristupanje polju preko pokazivaa na polja klasa


Koriste se binarni operatori .* i ->* iji je prioritet 14, a grupisanje sleva udesno
za operator .* prvi operand je objekat za operator ->* prvi operand je pokaziva na objekat drugi operand je u oba sluaja pokaziva na polje klase

52

Primer za definisanje i korienje pokazivaa na polja klasa


class Alfa { ... public: int a, b; } int Alfa::* pc; Alfa obj; Alfa* pObj = &obj; pc = &Alfa::a; obj.*pc = 1; pObj->*pc = 2; pc = &Alfa::b; obj.*pc = 3; pObj->*pc = 4;

// pc je pokaziva na int polja klase Alfa // obj je objekat klase Alfa // pObj je pokaziva na objekte klase Alfa // pc pokazuje na polje a objekata klase Alfa // obj.a = 1 // pObj->a = 2 // pc pokazuje na polje b objekata klase Alfa // obj.b = 3 // pObj->b = 4
53

Unutranje klase
Klase mogu da se definiu unutar druge klase Koristi se relativno retko i pri tome su unutranje klase vrlo male i najee imaju samo javna polja Dosezi su nezavisni moraju da se koriste operatori ., ->, ili :: Privatni lanovi nisu uzajamno dostupni, osim ako nije re o prijateljskim klasama.

54

Primer za unutranje klase


class Spolja { static int x; int y; ... class Unutra { // Definisanje unutranje klase public: static int a; int b; }; ... }; int Spolja::x = 1; int Spolja::Unutra::a = 10;
55

Lokalne klase
Klase mogu da se definiu unutar funkcija Lokalne klase imaju blokovski doseg Lokalne klase ne mogu da imaju zajednike lanove (static) Unutar lokalne klase dozvoljeno korienje:
identifikatora tipova trajnih podataka spoljanjih podataka i funkcija nabrojanih konstanti

iz okruujeeg dosega.

56

Primer
int x; void f(){ static int s; int x; extern int g(); class Lok { ... public: int h(){return x} // GREKA: x nije trajan //podatak int j(){return s} // Moe static int k(){return ::x} // Globalan podatak int l(){return g()} // Spoljanja funkcija g() static int a; // GREKA: ne moe static int b; // OK } Lok *p = 0; // Greka: nije u dosegu
57

Strukture
Strukture u jeziku C++ su klase iji su podaci podrazumevano javni Mogu se koristiti modifikatori private i public Nema drugih razlika izmeu struktura i klasa

58

Unije
Sva polja imaju iste poetne adrese u datom trenutku samo jedno moe da ima definisanu vrednost Imalo znaaja u vreme jezika C, kad su hardverske utede u memoriji neto znaile

59

60

Konstruktori

61

Stvaranje objekata
Novi objekti (primerci klasa) mogu da se stvaraju naredbama za definisanje podataka (stalni i prolazni objekti) kao lokalni podaci koji su formalni argumenti funkcija (prolazni objekti) u toku izvravanja sloenih izraza za odlaganje meurezultata (privremeni objekti) izvravanjem operatora new (dinamiki objekti) Stvaranjem objekata: dodeljuje se memorijski prostor moe da se uradi inicijalizacija Polja: inicijalizaciju radi programer. Samo za static polja su podrazumevane vrednosti nula. Konstruktori su specijalni metodi koji rade inicijalizaciju objekata Automatski se pozivaju pri stvaranju objekta
62

Argumenti konstruktora
Mogu da imaju proizvoljan broj argumenata Argumenti ne mogu da budu objekti tipa svoje klase Argumenti mogu da budu pokazivai ili reference na objekte svoje klase Mogu da imaju podrazumevane argumente Ne vraaju nikakvu vrednost, ne koristi se ni void

63

Primer definicije klase sa konstruktorima


class Alfa { char m_a; int m_b; public: Alfa(); // Podrazumevani konstruktor Alfa(int); // Konstruktor konverzije Alfa(char, int=0); Alfa(Alfa); // Greka Alfa(Alfa*); Alfa(Alfa&); // Konstruktor kopije };

64

Automatsko pozivanje konstruktora


Radi se u naredbi za definisanje podataka i iza identifikatora objekta navodi se inicijalizator oblika ( izraz, izraz, ... ) = izraz = { konstanta, konstanta, ... } Prvi oblik inicijalizatora je za pozivanje konstruktora, argumenti su izrazi Drugi oblik inicijalizatora je za pozivanje konstruktora koji ima samo jedan argument (ee se koristi prvi oblik) Trei oblik moe da se koristi samo ako klasa nema konstruktor, a sva pojedinana polja su javna Za stvaranje objekta operatorom new koristi se prvi 65 oblik inicijalizatora

Primer pozivanja konstruktora


Alfa a; Alfa Alfa Alfa Alfa Alfa Alfa Alfa b = 15; c('0'); c('0', 3); e(&a); f(a); g = a; h = {'0', 3}; // poziva se Alfa(), bila bi greka da nije // napisan podrazumevani konstruktor // poziva se Alfa(int) // poziva se Alfa(char, int) // poziva se Alfa(char, int) // poziva se Alfa(Alfa*) // poziva se Alfa(Alfa&) // poziva se Alfa(Alfa&) // greka, treba koristiti konstruktor

Alfa* p1 = new Alfa(a); // poziva se Alfa(Alfa&) Alfa* p2 = new Alfa('c'); // poziva se Alfa(char)

66

Eksplicitno pozivanje konstruktora


Moe se pozvati eksplicitno, kao i svaka druga metoda, u okviru sloenijeg izraza Rezultat je bezimeni privremeni objekat Primer: Alfa a; a = Alfa('c', 6);

67

Definisanje konstruktora
Definiu se kao i druge metode Razlika je to mogu da se navedu inicijalizatori Opti oblik je: Klasa ( argumenti ) : inicijalizator, ... , inicijalizator { Telo } Argumenti, inicijalizatori i telo mogu da se izostave (ali moraju zagrade,() i {} )

68

Inicijalizator u definiciji konstruktora


Opti oblik inicijalizatora je: polje ( izraz, izraz, ... ) polje je lan klase izrazi su argumenti konstruktora iz klase iji je polje primerak Ako je polje prostog tipa navodi se samo jedan izraz, tj. oblik inicijalizatora za prost tip je polje ( izraz )

69

Definisanje konstruktora izvan klase


Mora da se navede operator :: za razreenje dosega, da se doseg klase proiri na definiciju konstruktora Primer sa korienjem inicijalizatora Alfa::Alfa(char a, int b) : m_a(a), m_b(b) {} Primer bez korienja inicijalizatora Alfa::Alfa(char a, int b) { m_a = a; m_b = b; } Primer inicijalizacije konstantama: T::T () : a(0), b(1) {}, ekv. sa: T::T () {a=0; b=1;}
70

Primeri konstruktora
Alfa::Alfa() : m_a('d'), m_b(1) { } Alfa::Alfa(int i) : m_a(i), m_b(2*i) {} Alfa::Alfa(int i) : m_b(2*i), m_a(i) {} Alfa::Alfa(int i) { m_a = i; m_b = 2*i; }
71

Zajednika polja u konstruktorima


Ne moe da se navede inicijalizator za zajedniko polje (ono postoji pre stvaranja prvog objekta) Vrednost zajednikog polja se moe menjati u telu konstruktora

72

Podrazumevani konstruktor
Podrazumevani konstruktor je konstruktor bez argumenata ili konstruktor iji svi argumenti imaju podrazumevane vrednosti Ako se u klasi ne napie konstruktor, automatski se generie javni podrazumevani konstruktor sa praznim telom Obavezno treba definisati podrazumevani konstruktor u klasi koja ima polja pokazivakog tipa Ako treba spreiti pravljenje objekta neke klase, npr. klase iji su svi lanovi zajedniki, treba napraviti privatni podrazumevani konstruktor sa praznim telom

73

Primer: klasa ima polje pokazivakog tipa


class Niz { double* m_niz; int m_n; public: Niz() : m_niz(0), m_n(0) { } ; ... };

74

Konstruktor kopije
Konstruktor kopije ima jedan argument tipa reference na svoju klasu (ako postoje, ostali argumenti moraju imati podrazumevane vrednosti) Slui za inicijalizaciju objekta kopiranjem drugog objekta iste klase Koristi se
u naredbi za definisanje objekta prilikom pozivanja operatora new za inicijalizaciju formalnog argumenta funkcije klasnog tipa

Da bi se spreilo stvaranje kopija objekata, konstruktor kopije treba uiniti privatnim lanom klase
75

Automatski generisani konstruktor kopije


Ako se ne napie, automatski se generie javni konstruktor kopije koji kopira sva polja objekta Za polja koja su tipa drugih klasa pozivaju se konstruktori kopija tih klasa Ako je polje pokaziva, kopira se vrednost pokazivaa, a ne stvara se novi objekat na koji pokazuje pokaziva Klasa, koja ima pokazivae kao polja, trebalo bi da ima i konstruktor kopije koji bi kopirao objekte na koje ukazuju ti pokazivai

76

Primer: klasa ima polje pokazivakog tipa


class Niz { double* m_niz; int m_n; public: ... Niz(const Niz& arg) { m_n = arg.m_n; if(m_n) { m_niz = new double[m_n]; for(int i=0; i<m_n; i++) m_niz[i] = arg.m_niz[i]; } else m_niz = 0; } };

77

Primer za objekte
Niz obj1; ... Niz obj2(obj1);

obj1 m_niz m_n obj2 m_niz m_n 5 5

e
78

Primer za objekte
Da nije definisan konstruktor kopije bio bi pozvan podrazumevani konstruktor kopije Niz obj1; ... Niz obj2(obj1);
obj1 m_niz m_n obj2 m_niz m_n 5
79

a 5

Konstruktor konverzije
Konstruktor konverzije ima jedan argument Argument moe biti bilo kog tipa osim tipa te klase, moe biti i upuiva Moe se pozvati eksplicitno ili prilikom automatske konverzije Ne moe se spreiti automatska konverzija ako postoji konstruktor konverzije Konstruktorom konverzije se moe definisati konverzija iz nekog drugog tipa u tip klase za koju se taj konstruktor definie

80

Konstruktor konverzije - primer


class Alfa { char m_a; int m_b; public: Alfa(int i) : m_a(i), m_b(2 * i) {} }; int x = 2; Alfa a = x; Alfa b(6); Alfa c = (Alfa)8;
81

Tok izvravanja konstruktora


Neinicijalizovani objekat je samo rezervisano pare memorije Prvo se inicijalizuju polja klasnih tipova po redosledu navoenja u definiciji klase pozivanjem odgovarajuih konstruktora Zatim se inicijalizuju polja standardnih tipova po redosledu navoenja u definiciji klase Na kraju se izvrava telo konstruktora. Menjanje vrednosti polja unutar tela konstruktora je dodela vrednosti, a ne inicijalizacija Nepromenljiva (const) i upuivaka polja se moraju inicijalizovati
82

Inicijalizacija nizova objekata


Prilikom definisanja nizova objekata klasnih tipova, mogu se navesti inicijalizatori u obliku niza konstantnih izraza unutar para vitiastih zagrada Ti izrazi mogu biti i pozivi konstruktora sa konstantnim argumentima Alfa alfa[] = {3, Alfa('d', 'e'), Alfa())}; Redosled inicijalizacije je po rastuim vrednostima indeksa Ako se ne koriste inicijalizatori, poziva se podrazumevani konstruktor ako postoji Kada se koristi operator new, inicijalizatori ne smeju da se navode
83

Destruktori

84

Unitavanje objekta
Unitavanje objekata se radi:
za stalne objekte: automatski na kraju programa za prolazne objekte: automatski u trenutku naputanja dosega njihovih identifikatora za privremene objekte (meurezultate): automatski im je to mogue za dinamike objekte: na zahtev programera pomou operatora delete ili automatski na kraju programa

Oslobaanje prostora
prostor dodeljen poljima oslobaa se automatski oslobaanje prostora u dinamikoj zoni memorije mora da uradi programer

Destruktori su specijalni metodi koji unitavaju objekat 85 Ako postoje, pozivaju se automatski pri unitavanju objekta

Destruktori
Imaju isto ime kao klasa, sa prefiksom ~: ~Alfa() Klasa moe da ima samo jedan destruktor Destruktor nema parametre Ako u klasi nije definisan destruktor, automatski se definie javni destruktor s praznim telom

class Niz { double* a; int n; public: ... ~Niz () {delete [] a;} ... }
86

Redosled izvravanja destruktora


Ako objekat koji se unitava ima polja tipa klasa s destruktorima prvo se izvrava telo destruktora posmatranog objekta, pa tek onda destruktori klasa tih polja. Poja se unitavaju po suprotnom redosledu od njihovog navoenja u definiciji klase. Kod unitavanja nizova, destruktor se poziva za svaki element niza, a oni se unitavaju po obrnutom redosledu.

87

Eksplicitni poziv destruktora


Destruktor se moe pozivati i eksplicitno. ,,Prazni polja, ali ostavlja objekat, tj. ne unitava ga. Mora da ga ostavi u ispravnom praznom stanju. Zato treba izbegavati eksplicitno pozivanje destruktora.

88

UML

89

Preklapanje operatora

90

Preklapanje operatora
Za operande klasnih tipova mogu da se definiu tumaenja standardnih operatora Primeri
A = (B + C) * D, gde su A, B, C, D matrice A = (B + C) * d, gde su A, B, C nizovi, d je numeriki tip

Za klasne tipove mogu biti definisani svi operatori osim operatora za


pristup lanu klase . i .* razreenje dosega :: uslovni izraz ?: veliinu objekta sizeof prijavljivanje (bacanje) izuzetka throw
91

Ogranienja za preklapanje operatora


Ne mogu da se promene tumaenja operatora za standardne tipove podataka (numerike i pokazivake) Ne mogu da se uvedu novi simboli za operatore Ne mogu da se promene prioriteti i smer grupisanja operatora

92

Automatski definisani operatori


Za nove tipove automatski postoje operatori za
dodelu vrednosti jednog objekta drugom = obrazovanje adrese objekta & obrazovanje niza izraza ,

93

Operatorske funkcije
Operatori se ostvaruju operatorskim funkcijama iji je opti oblik: operator op op je simbol operatora Primeri: operator+ operator -operator new // Moe se pisati spojeno // ili odvojeno // Mora se pisati odvojeno

94

Operatorske funkcije
Mogu biti
metodi zajedniki metodi (static) globalne funkcije (najee prijateljske)

Mogu da imaju podrazumevane argumente Mogu se preklapati Vrednost operatorskih funkcija moe biti proizvoljnog tipa, ukljuujui i void

95

Unarni operatori
Operatorska funkcija mora imati jedan operand Moe biti:
metod bez argumenata (ima skriveni argument) globalna funkcija sa jednim argumentom tipa klase za koju se pravi operatorska funkcija

96

Binarni operatori
Operatorska funkcija mora imati dva operanda Moe biti:
metod sa jednim argumentom (drugi je skriveni argument) globalna funkcija sa dva argumenta
bar jedan mora biti tipa klase za koju se pravi operatorska funkcija drugi moe biti proizvoljnog tipa

97

Pozivanje operatorskih funkcija


Mogu se pozivati na dva naina
kao to se pozivaju operatori
a+b

kao to se pozivaju funkcije (metodi)


a.operator+(b)

98

Primer klase sa preklopljenim operatorima


#include <iostream> using namespace std; class Complex { private: double re, im; public: Complex( double r, double i ) : re(r), im(i) {} Complex operator+( Complex &other ); Complex Complex:: operator!(); void pisi( ) { cout << re << ", " << im << endl; } }; // Binarni operator korienjem funkcije lana Complex Complex::operator+( Complex &other ) { // dva argumenta, // jedan je skriveni return Complex( re + other.re, im + other.im ); } // Unarni operator korienjem funkcije lana Complex Complex:: operator!() {return Complex(re, -im);} int main() { Complex a = Complex( 1.2, 3.4 ); Complex b = Complex( 5.6, 7.8 ); Complex c = Complex( 0.0, 0.0 ); c = a + b; //ekv. a.operator+(b) ili operator+(a,b) Complex d = !c; // ekv. c.operator!() ili operator!(c) c.pisi(); }

99

Boni efekti preklopljenih operatora


Operatori sa bonim efektima (++, --, dodela vrednosti, =, +=, *=, ... ) mogu se preklopiti operatorskim funkcijama koje nemaju bone efekte Operatori koji nemaju bone efekte mogu se preklopiti operatorskim funkcijama koje imaju bone efekte Ako operator ima boni efekat, odgovarajui operand mora biti lvrednost, tj. referenca odgovarajueg tipa Preporuuje se da se ouvaju boni efekti pri preklapanju operatora

100

Izbor: metodi ili globalne funkcije


Operatori bez bonih efekata mogu da budu globalne funkcije jer nema razloga da se operandi tretiraju razliito
kod metoda se skriveni i pravi argument tretiraju razliito, jer se za skriveni argument ne radi automatska konverzija pri pozivanju funkcije

Operand koji podlee bonom efektu moe da bude skriveni argument prirodno da funkcija za preklapanje bude lan klase.

101

Preklapanje operatora
Operatori se preklapaju nezavisno, npr. +, ++, +=, tj. ako preklopimo +, ne znai i da smo automatski preklopili ++ i += Treba izbegavati neoekivana tumaenja operatora, npr. da se sabiranje matrica ili nizova napravi preklapanjem operatora -

102

Preklapanje operatora ++ i - Imaju prefiksni i postfiksni oblik oba operatora su unarna Prefiksni operatori se obino preklapaju kao metodi bez argumenata kao prijateljske funkcije sa jednim argumentom Postfiksni operatori se obino preklapaju kao metodi sa jednim argumentom tipa int
svrha argumenta tipa int nije da se koristi, ve slui da razlikujemo dve preklopljene funkcije (prefiksnu i postfiksnu verziju)

kao prijateljske funkcije sa dva argumenta


prvi je tipa klase za koju se radi preklapanje operatora drugi je tipa int

vrednost argumenata tipa int je nula kad se operatorska funkcija poziva kao operator, a ako se poziva kao funkcija ili metod vrednost se prenosi u funkciju
103

Primer preklapanja operatora ++ i -class Kompl { double re, im; public: Kompl(double r, double i) { re = r; im = i; } Kompl& operator++() { ++re; return *this; } // prefiksni

Kompl operator++(int i) // postfiksni { Kompl z = *this; re++; im+=i; return z; } friend Kompl& operator--(Kompl& z) { --z.re; return z; } // prefiksni

friend Kompl operator--(Kompl& z, int i) // postfiksni { Kompl x = z; z.re--; z.im-=i; return x; } };


104

Primer preklapanja operatora ++ i -Kompl x(1,3); Kompl a = ++x; Kompl b = x++; // x = (1,3) // x = (2,3), a = (2,3) // Posto je postfiksni // oblik, gleda funkciju // b = (2,3), x = (3,3) x.operator++(2) // c = (3,3), x = --x; // x = (3,5), d = x--; // e = (3,5), x = operator--(x,2) // f = (2,5), x =

sa int: (4,5) (3,5) (2,5) (1,3)

Kompl Kompl Kompl Kompl

c d e f

= = = =

105

Preklapanje unarnog operatora (tip)


Slui za konverziju tipa iz klase kojoj operator pripada u bilo koji drugi standardni tip, klasni tip, ili pokazivaki tip Oblik je operator T() Tip T je tip u koji se radi konverzija Operatorska funkcija mora da bude lan klase iz koje se radi konverzija Konstruktor konverzije slui za konverziju iz bilo kog tipa u tip klase kojoj konstruktor pripada

106

Preklapanje unarnog operatora (tip)


Drugi oblik (prvi je preko konstruktora) operatorske funkcije za konverziju iz tipa T u tip U je T::operator U() Pozivanje
kao funkcija lan klase t.operator U() kao operator za kastovanje (U)t kao obina funkcija U(t)

Pozivanje je isto kao i pozivanje konstruktora konverzije

107

Automatska konverzija tipa


Ako se u pozivima funkcija tipovi argumenata ne slau s tipovima odgovarajuih parametara, obavlja se automatska konverzija. Automatska konverzija izmeu standardnih tipova je deo jezika C++. Konverziju izmeu tipova, od kojih je bar jedan klasa, mora da definie programer pomou konstruktora konverzije ili preklapanjem operatora. Automatska konverzija se koristi i u izrazima kada su operandi nekog operatora razliitih tipova.

108

Primer konverzija
class Kompl { double re, im; public: Kompl (double r=0, double i=0) { re=r; im=i; } operator double(){ return sqrt(re*re+im*im); } friend double real (Kompl z) { return z.re; } friend double imag (Kompl z) { return z.im; } Kompl operator+ (Kompl z) { z.re += re; z.im += im; return z; } friend ostream& operator<< (ostream& it, const { return it << '(' << z.re << ',' << z.im << }; int main () { Kompl a (1, 2); Kompl b = a; Kompl c = 5;

// // // // //

Inic. ili konverzija. Konverzija u double. Realni deo. Imaginarni deo. Sabiranje.

Kompl& z) ')'; }

cout cout cout cout cout cout cout cout double d=Kompl(3,4); cout

<< << << << << << << << <<

"a "b "c "a+b "a+3 ? "|a|+3 "a+(3,4) "dble(a) "d

= = = =

" << a " << b " << c " << a + b = " << a + (Kompl)3 = " << (double)a + 3 = " << a + Kompl (3,4) = " << (double)a = " << d

<< endl; << endl; << endl; << endl; << endl; << endl; << endl; << endl; << endl; 109

Preklapanje operatora =
Operator = ima automatsko tumaenje za sve nove klase: kopira sva polja izvorinog objekta u polja odredinog objekta Ako klasa ima polje koje je pokaziva na deo u dinamikoj zoni memorije:
ne kopira se deo iz dinamike zone memorije ako je to potrebno treba preklopiti operator =

Operator = moe da se preklopi samo pojedinanim (koji nije static) metodom


ne moe biti globalna funkcija

Ako se ne preklopi operator =, koristi se automatski generisani operator


110

Vrednost preklopljenog operatora =


Vrednost operatora = za standardne tipove je lvrednost Preklopljeni metod najee ima vrednost koja je referenca na objekat svoje klase Ako klasa ima polje koje je pokaziva na deo u dinamikoj zoni memorije:
ne kopira se deo iz dinamike zone memorije ako je to potrebno treba preklopiti operator =

111

Napomene u vezi preklapanja operatora =


U izrazu a = b objekat a ve postoji
treba osloboditi dinamike delove memorije koje koristi objekat a pre kopiranja objekta b u objekat a alternativa: ne moraju se osloboditi dinamiki delovi memorije ako su njihove veliine jednake za objekte a i b, ali to komplikuje reenje

Zbog mogunosti pisanja izrazu a = a


pre oslobaanja dinamikih delova memorije koje koristi levi operand mora se proveriti da li levi i desni operand predstavljaju isti objekat treba proveriti da li objekti zauzimaju isti prostor u memoriji tj. da li su jednaki
pokaziva odredinog objekta (this skrivenog argumenta) pokaziva izvorinog objekta (argumenta metoda) 112

Inicijalizacija i dodela vrednosti


Inicijalizacija i dodela vrednosti su dve razliite radnje, mada se sa obe dodeljuje vrednost jednog objekta drugom. Inicijalizacija se vri prilikom stvaranja novih objekata. Rezultat treba da bude ispravan objekat koji poseduje sve osobine svoje klase. Inicijalizacija se obavlja automatskim pozivanjem odgovarajueg konstruktora. Dodela vrednosti se vri prilikom izvravanja operatora = pozivanjem operatorske funkcije operator=(). Podrazumeva se da je objekat s leve strane operatora inicijalizovan.
113

Primer preklapanja operatora = (Tekst.h)


class Tekst { char* m_txt; public: Tekst(const char* niz); // Konstruktor konverzije Tekst(const Tekst& tekst); // Konstruktor kopije ~Tekst(); Tekst& operator=(const Tekst& tekst); };

114

Primer preklapanja operatora = (Tekst.cpp)


#inslude <cstring> using namespace std; Tekst::Tekst(const char* niz) // Konstruktor konverzije { m_txt = new char [strlen(niz) + 1]; strcpy(m_txt, niz);

}
Tekst::Tekst(const Tekst& tekst) // Konstruktor kopije { m_txt = new char [strlen(tekst.m_txt) + 1]; strcpy(m_txt, tekst.m_txt);

}
115

Primer preklapanja operatora = (Tekst.cpp)


Tekst::~Tekst() { delete[] m_txt; //m_txt = 0; // Za eksplicitno pozivanje destruktora, } // ali bi bilo bolje da se napravi metod clear() Tekst::Tekst& operator=(const Tekst& tekst) { if(&tekst != this) { delete[] m_txt; m_txt = new char [strlen(tekst.m_txt) + 1]; strcpy(m_txt, niz); } return *this; }
116

Primer preklapanja operatora = (Main.cpp)


#inslude "Tekst.h" int main() { Tekst a("Dobar dan."); // Konstruktor konverzije // Konstruktori konverzije i kopije, prvo se konstruktorom konverzije // stvara privremeni objekat koji se konstruktorom kopije kopira u b Tekst b = Tekst("Zdravo."); Tekst c(a); // Konstruktor kopije Tekst d = b; // Konstruktor kopije a = b; // Dodela vrednosti

117

Preklapanje operatora za pozivanje funkcija ()


Operator za pozivanje funkcija moe da se preklopi samo pojedinanim (ne static) metodama klasa. Prototip funkcija:
tip_rezultata operator() (arg1, ..., argN);

Preklapanja operatora () u nekoj klasi omoguava korienje objekata u izazima oblika obj(arg1, ..., argN). Na primer, ako se radi o klasi polinoma ovo omoguava da se vrednost polinoma izraunava izrazom oblika p(x) umesto p.izracunaj(x).

118

Preklapanje operatora za posredni pristup ->


Operator za posredan pristup lanovima klase moe da se preklopi samo pojedinanim (ne static) metodama klasa. Prototip funkcija:
tip_rezultata operator-> ();

Preklapanje operatora -> omoguava obrazovanje klasa iji se objekti ponaaju kao pametni pokazivai, koji pored pristupanja objektu urade i neki dodatni posao, na primer broje pristupe objektima ili proveravaju ispravnost pokazivaa.

119

Primer
// Preklapanje operatora -> #include <iostream> using namespace std; struct Obj { double x, y; }; // Korisceni objekat.

class PokObj { // Klasa "pametnih" pokazivaca. Obj* p; // Pokazivac na pridruzeni objekat. int n; // Broj pristupa pridruzenom objektu. public: PokObj (Obj* obj) { n = 0; p = obj; } // Inicijalizacija. Obj* operator-> () { n++; return p; } // Pristup clanu. Obj& operator* () { n++; return *p; } // Pristup objektu. int operator+ () const { return n; } // Broj pristupa. } ;

120

Primer - nastavak
int main () { Obj a; PokObj pa = &a; pa->x = pa->y = 0; cout << +pa << endl; Obj b = *pa; cout << +pa << endl; Obj* pb = &b; pb->x = pb->y = 5; *pa = *pb; cout << +pa << endl; }

// "Pametan" pokazivac. // Pise se: 2 // Pise se: 3 // "Obican" pokazivac.

// Pise se: 4

121

Operatori za ulaz >> i izlazi <<


U jeziku C++ ne postoje naredbe za ulaz i izlaz podataka Pristup datotekama ostvaruje se pomou klasa
svakoj datoteci dodeljuje se po jedan objekat tih klasa pristup datoteci obavlja se metodima ili prijateljskim funkcijama tih klasa

Deklaracije vezane za ulaz i izlaz su u zaglavljima <iostream> i <iostream.h>


klasa za ulaz podataka zove se istream klasa za izlaz podataka zove se ostream

Objekti za pristup glavnom ulazu i izlazu


cin je objekat klase istream za pristup glavnom ulazu cout je objekat klase ostream za pristup glavnom izlazu
122

Deklaracije operatora za ulaz >> i izlazi <<


Deklaracije operatorskih funkcija su istream& operator>>(istream& dat, T& t); ostream& operator<<(ostream& dat, const T& t); Objekat dat je objekat
ulazne datoteke iz koje se ita (npr. cin) izlazne datoteke u koju se upisuje (npr. cout)

Objakat t je
odredite podataka proitanih iz ulazne datoteke izvorite podataka za pisanje u izlazne datoteke

Vrednost obe funkcije je referenca na datoteku koja je prvi operand, to omoguava ulanavanje operatora >> i <<
123

Preklapanje operatora za ulaz >> i izlazi <<


Preklapanjem se mogu napraviti operatori za ulaz i izlaz klasnih tipova koje pie programer Ove operatorske funkcije moraju biti globalne
najee su prijateljske funkcije ne mogu biti lanovi klase jer prvi operand nije tipa klase za koji se preklapa operator

Operatori >> i << mogu da se preklapaju i na druge naine koji nisu povezani sa ulazom i izlazom

124

Primer preklapanja operatora <<


#include <iostream.h> class Kompl { double re, im; public: Kompl(double r, double i) { re = r; im = i; } friend ostream& operator<<(ostream& dat, const Kompl& z) { dat << '(' << z.re << ',' << z.im << ')'; return dat; } }; int main() { Kompl z(1,0); cout << "z = " << z << endl; }
125

Izvedene klase

126

Izvedene klase
Sline pojave se grupiu na osnovu zajednikih osobina Unutar grupe postoje podgrupe koje imaju sve osobine grupe i jo neke dodatne Primer:
geometrijske slike u ravni imaju
poloaj orijentaciju povrinu obim

krugovi su geometrijske slike koje imaju poluprenik kvadrati su geometrijske slike koje imaju duinu stranice trouglovi su geometrijske slike koje imaju tri stranice
127

Primer klasifikovanja prevoznih sredstava


Prevozno sredstvo slui za prevoz (moe da se kree)
letelice su prevozna sredstva koja lete
avioni su letelice helikopteri su letelice vasionski brodovi su letelice

plovila su prevozna sredstva koja plove po vodi


amci su plovila jedrenjaci su plovila brodovi su plovila

vozila su prevozna sredstva koja se kreu po zemlji


automobili su vozila teretna vozila su vozila autobusi su vozila
128

Osnovne i izvedene klase


Klasa opisuje grupu objekata (apstrakcija) sa istim osobinama Osnovna klasa opisuje optiju grupu objekata (apstrakcija)
natklasa klasa predak klasa roditelj

Izvedena klasa opisuje podgrupu objekata (apstrakcija) koja ima neke specifine osobine
potklasa klasa potomak klasa dete

Moe postojati vie nivoa (koraka) izvoenja

129

Definisanje izvedene klase


Opti oblik je:
class Identifikator : nain_izvoenja osnovna_klasa, ... , nain_izvoenja osnovna_klasa { lan, lan, ... public: lan, lan, ... protected: lan, lan, ... private: lan, lan, ... };
130

Definisanje izvedene klase


Identifikator je ime izvedene klase osnovna_klasa je ime osnovne klase iz koje se izvodi izvedena klase
izvedena klasa se moe izvesti iz vie osnovnih klasa

nain_izvoenja moe biti neki od modifikatora


public za javno izvoenje protected za zatieno izvoenje private za privatno izvoenje

Za osnovnu klasu se kae da je javna, zatiena ili privatna osnovna klasa date izvedene klase

131

Nasleivanje
Izvedena klasa nasleuje sve lanove osnovne klase Viestruko nasleivanje je kad se izvedena klasa izvodi iz vie osnovnih klasa Ne nasleuju se
konstruktori destruktor operator=()

Ako se ne napiu, u izvedenoj klasi se automatski generiu


podrazumevani konstruktor konstruktor kopije destruktor operator=()

132

Kontrola pristupa lanovima klase


Kontrola pristupa lanovima klase ostvaruje se modifikatorima Modifikator public oznaava javne delove klase
nema ogranienja pristupa, moe im se pristupati iz klase i izvan klase (ukljuujui i izvedene klase)

Modifikator protected oznaava zatiene delove klase


zatienim lanovima se moe pristupati iz klase u kojoj su definisani i iz svih klasa koje su izvedene iz te klase

Modifikator private oznaava privatne delove klase


privatnim lanovima se moe pristupati samo iz klase u kojoj su definisani, ne moe im se pristupati ak ni iz izvedenih klasa
133

Prijateljske funkcije
Izvedene klase ne nasleuju prijateljske funkcije i klase od osnovne klase Prijatelji osnovne klase se mogu proglasiti prijateljima i u izvedenoj klasi Izvedena klasa moe imati i nove prijatelje

134

Nain izvoenja
Nain izvoenja odreuje kontrolu pristupa lanovima osnovne klase preko primeraka izvedene klase Izvoenje moe biti
javno (public) zatieno (protected) privatno (private)

Ako se ne navede podrazumeva se privatno izvoenje

135

Nain izvoenja
Javno izvoenje
javni lanovi osnovne klase su javni u izvedenoj klasi zatieni lanovi osnovne klase su zatieni u izvedenoj klasi privatni lanovi osnovne klase su privatni u izvedenoj klasi

Zatieno izvoenje
javni i zatieni lanovi osnovne klase su zatieni u izvedenoj klasi privatni lanovi osnovne klase su privatni u izvedenoj klasi

Privatno izvoenje
javni, zatieni i privatni lanovi osnovne klase su privatni u izvedenoj klasi

Najee se koristi javno izvoenje

136

Nain izvoenja

izvoenje javan javno zatieno privatno javan zatien privatan

lan osnovne klase zatien zatien zatien privatan privatan privatan privatan privatan

137

Izvoenje struktura
Strukture (struct) su ravnopravne sa klasama Struktura moe da se izvede iz klase ili strukture Klasa moe da se izvede iz strukture Kod izvedenih struktura podrazumeva se javno izvoenje

Iz unija (union) ne mogu da se izvedu drugi tipovi podataka Unije ne mogu da se izvedu iz drugih tipova podataka

138

Klasni dijagrami za izvedene klase


Linija je orijentisana od izvedene klase ka osnovnoj
izvedena klasa zna za osnovnu klasu osnovna klasa ne zna za izvedenu klasu

Uobiajeno se osnovne klase crtaju na vrhu a izvedene ispod


OsnovnaKlasa OsnovnaKlasa OsnovnaKlasa

IzvedenaKlasa
javno izvo enje

IzvedenaKlasa
zatieno izvoenje

IzvedenaKlasa
privatno izvo enje

139

Primer za klasne dijagrame izvedenih klasa


class class class class class A B C D E { { : : : int a; int b; public public public }; }; A { int c; }; A, public B { int d; }; D { int e; };

A a

B b

C c

D d

E e 140

Pristupanje lanovima izvedenih klasa


lanovima osnovne klase se u izvedenoj klasi pristupa na isti nain kao i u osnovnoj klasi, bez identifikatora klase Smatra se da izvedena klasa ima kao podobjekat jedan bezimeni primerak svoje osnovne klase
nasleeni su svi lanovi osnovne klase

Klasa moe imati polje koje je objekat druge klase


lanovima ovog objekta se pristupa preko imena objekta

Razlikovati polje druge klase od podobjekta osnovne klase, kojem se ne moe pristupiti kao celini, ve samo lanovima pojedinano
141

Primer pristupanja lanovima


class T { public: int a, b; }; T t; class U : public T { public: int c, d; }; U u; class V { //ima polje public: //druge klase T m_t; int c, d; }; V v; t: a b u: a b c d v: m_t c d t.a t.b u.a u.b u.c u.d a v.m_t.a b v.m_t.b v.c v.d
142

Pokrivanje lanova u izvedenoj klasi


U izvedenoj klasi se moe definisati lan sa identifikatorom koji ve postoji u osnovnoj klasi
izvedena klasa ima dva lana sa istim imenom lan iz osnovne klase je pokriven (postao je nevidljiv) po imenu se pristupa sopstvenom lanu nevidljivom lanu se moe pristupiti preko imena osnovne klase osnovna_klasa::lan

Mogu se pokrivati i polja i metodi

143

Primer za izvedene klase


class Alfa { int a; public: int b; void stavi(int _a){ a = _a; } }; class Beta : public Alfa { // Javno izvoenje int c; public: void smesti(int _a, int _b, int _c){ c = _c; // Beta::c, dodela vrednosti b = _b; // Alfa::b, dodela vrednosti a = _a; // Alfa::a, Greka, privatni lan klase Alfa stavi(_a); // Alfa::a, dodela vrednosti } };
144

Primer za izvedene klase nastavak


class Gama : Alfa int b, c; public: void smesti(int c = _c; b = _b; Alfa::b = _b; stavi(_a); } }; { // Privatno izvoenje

_a, int _b, int _c){ // Gama::c, dodela vrednosti // Gama::b, dodela vrednosti // Alfa::b, pokriveno polje, dodela vrednosti // Alfa::a, dodela vrednosti

145

Primer za izvedene klase nastavak


void main() { Alfa alfa; Beta beta; Gama gama; alfa.b = 5; // javno polje klase Alfa beta.b = 5; // javno polje klase Beta (nasleeno od Alfa) gama.b = 5; // greka, privatno polje klase Gama gama.Alfa::b = 5;// greka, privatno polje klase Gama // (nasleeno od Alfa privatno izvoenje) alfa.stavi(2); // javni metod klase Alfa beta.stavi(2); // javni metod klase Beta (nasleen od Alfa) gama.stavi(2); // greka, privatni metod klase Gama // (nasleen od Alfa privatno izvoenje) gama.smesti(5,2,1); // javni metod klase Gama 146 }

Redefinisanje metoda
Redefinisanje metoda u izvedenoj klasi ne smatra se preklapanjem imena funkcija. Sve metode osnovne klase koje imaju isto ime kao i metoda izvedene klase postae nevidljive, bez obzira na broj i tipove parametara. Te metode se pozivaju sa ::

147

Primer
class Osn { ... public: void m(); void m(int); }; class Izv: public Osn{ ... public: void m(int); // Pokriva i Osn::m() i Osn::m(int) }; int main() { Izv izv; izv.m(); // Greka: ne vidi se Osn::m() izv.Osn::m() // Moe izv.m(5); // Poziva se Izv::m() izv.Osn::m(5);// poziva se Osn::m(int)
148

Virtuelne osnovne klase


Primer
osnovna klasa A dve klase B i C se izvode iz iste osnovne klase A klasa D se izvodi iz dve klase B i C i nasleuje sve njihove lanove
klasa D dva puta nasleuje polja iz klase A
nasleuje ih od klase B nasleuje ih od klase C

U viestrukom izvoenju najee treba izbei viestruko ugraivanje lanova jedne klase u izvedenu klasu Osnovna klasa (A) treba da bude virtuelna za klase koje se neposredno izvode iz nje (B i C) virtuelno izvoenje
dodaje de modifikator virtual prilikom izvoenja
149

Primer za virtuelne osnovne klase


class class class class A B : public A C : public A D : public B, public C { { { { public: public: public: public: int int int int a; b; c; d; }; }; }; };

D d; D.B::a = 1; D.b = 2; D.C::a = 3; D.c = 4; D.d = 5;

// Objekat klase D ima 5 polja // Polje klase D nasleeno od klase A preko klase B // Polje klase D nasleeno od klase B // Polje klase D nasleeno od klase A preko klase C // Polje klase D nasleeno od klase C // Polje klase D

150

Primer za virtuelne osnovne klase


class class class class D d; D.a = D.b = D.c = D.d = A B : virtual public A C : virtual public A D : public B, public C { { { { public: public: public: public: int int int int a; b; c; d; }; }; }; };

1; 2; 3; 4;

// Objekat klase D ima 4 polja // Polje klase D nasleeno od klase A preko B i C // Polje klase D nasleeno od klase B // Polje klase D nasleeno od klase C // Polje klase D

151

Virtuelne osnovne klase


U viestrukom izvoenju se nasleuje
po jedan podobjekat osnovne klase od svih meuklasa za koje osnovna klasa nije virtuelna jedan podobjekat osnovne klase preko svih meuklasa za koje je osnovna klasa virtuelna
A a A a A a

B b

C c

B b

C c

D d

D d

152

Primer za virtuelne osnovne klase


class A { public: int a; }; class B : virtual public A { public: int b; }; class C : virtual public A { public: int c; }; class D : public B, public C { public: int d; }; class E : public A { public: int e; }; class F : public E, public D { public: int f; }; F d; // Objekat klase F ima 7 polja F.E::a = 1; // Polje klase F nasleeno od klase A preko E F.e = 2; // Polje klase F nasleeno od klase E F.D::a = 3; // Polje klase F nasleeno od klase A preko D (B i C) F.b = 4; // Polje klase F nasleeno od klase B F.c = 5; // Polje klase F nasleeno od klase C F.d = 6; // Polje klase F nasleeno od klase D F.f = 7; // Polje klase F

153

Stvaranje objekta izvedene klase


U listi inicijalizatora konstruktora izvedene klase moe se navesti inicijalizator osnovne klase Polja nasleena iz osnovne klase
ne mogu se navesti inicijalizatori polja se mogu inicijalizovati samo u klasama kojima direktno pripadaju (osnovnim klasama) moe se koristiti ceo objekat osnovne klase za inicijalizaciju mogu se koristiti u telu konstruktora, ali je to dodela vrednosti a ne inicijalizacija

154

Redosled pri stvaranju objekta izvedene klase


Izvravaju se konstruktori osnovnih klasa po redosledu navoenja osnovnih klasa u definiciji izvedene klase Izvravaju se konstruktori polja klasnih tipova po redosledu navoenja polja u definiciji izvedene klase Inicijalizuju se polja standardnih tipova koja postoje, po redosledu navoenja u definiciji klase Redosled navoenja inicijalizatora u konstruktoru nije bitan Posle inicijalizatora, izvrava se telo konstruktora izvedene klase

155

Primer za redosled pri stvaranju objekta


class Osnovna1 { int* a; public: Osnovna1() : a(0) { } }; class Osnovna2 { char* b; double c; public: Osnovna2() { b = 0; c = 5; } Osnovna2(char* _b, double _c) : c(_c) { b = _b; } }; 156

Primer za redosled pri stvaranju objekta


class Izvedena : public Osnovna2, public Osnovna1 { int p, q; Osnovna1 r; Osnovna2 s, t; double u, v; public: Izvedena(int, char*, double); }; Izvedena::Izvedena(int _p, char* _b, double _q) : p(_p+2), Osnovna2(_b, _q), s("ne", _p) { q = p + _q; }

157

Primer za redosled pri stvaranju objekta


void main() { Izvedena obj(1, "Zdravo", 2); }

Redosled izvravanja inicijalizacije objekta obj je:


Osnovna2("Zdravo", 2.0) Osnovna1() r.Osnovna1() s.Osnovna2("ne", 1.0) t.Osnovna2() //podrazum. p(3) q = 3 + 2.0 Ne inicijalizuju se: obj.u, obj.v obj.b = obj.c = obj.a = obj.r.a obj.s.c obj.s.b obj.t.b obj.t.c obj.p = obj.q = "Zdravo" 2.0 0 = 0 = 1.0 = "ne" = 0 = 5.0 3 //=_p+2 5
158

Redosled pri unitavanju objekta izvedene klase


Redosled je obrnut od redosleda pri stvaranju objekta Izvrava se telo destruktora izvedene klase Izvravaju se destruktori polja klasnih tipova po suprotnom redosledu u odnosu na redosled navoenja polja u definiciji izvedene klase Izvravaju se destruktori osnovnih klasa po suprotnom redosledu u odnosu na redosled navoenja osnovnih klasa u definiciji izvedene klase

159

Konverzija tipa osnovnih i izvedenih klasa


Objekat osnovne klase moe da se inicijalizuje objektom javno izvedene klase Tom prilikom e konstruktor kopije osnovne klase prekopirati samo polja izvedene klase koja su nasleena Objektu osnovne klase moe da se dodeljuje vrednost objekta javno izvedene klase U sluaju privatnog ili zatienog izvoenja izvedena klasa se ne ponaa istovetno svojoj osnovnoj klasi, pa nije dozvolejna automatska inicijalizacija i dodela vrednosti objekta izvedene klase objektu osnovne klase neophodno je obezbediti konverziju tipa preklapanjem operatora za konverziju tipa.
160

Konverzija tipa osnovnih i izvedenih klasa


Inicijalizacija objekata izvedene klase objektom osnovne klase nikada nije automatski dozvoljena. Potrebno je da postoji definisana konverzija tipa iz osnovne klase u izvedenu klasu. Ta konverzija treba da odredi vrednosti specifinih polja u izvedenoj klasi koja ne postoje u osnovnoj klasi.

161

Primer
class Osn { ... }; class Izv : public Osn { ... }; void f (Osn); int main() { Izv izv; Osn osn; osn = izv; // Dodela vrednosti izv = osn; // Greka: ta dodeliti //specifinim poljima? f(izv); // Inicijalizacija
162

Pokazivai na objekte
Dodela vrednosti pokazivaa na objekte tipa izvedene klase pokazivau na objekte tipa osnovne klase:
za javnu osnovnu klasu radi se automatska konverzija tipa pokazivaa
operacija je bezopasna izvedena klasa ima sve to ima i osnovna klasa, sa istim pravom pristupa

za privatnu ili zatienu osnovnu klasu mogua je dodela samo uz eksplicitnu konverziju tipa, kojom programer saoptava prevodiocu da zna ta radi
pristup u izvedenoj klasi je restriktivniji nego u osnovnoj preko pokazivaa na tip osnovne klase se moe pristupiti lanovima kojima se ne moe pristupiti preko pokazivaa tipa izvedene klase 163 ovaj sluaj treba izbegavati

Pokazivai na objekte
Dodela vrednosti pokazivaa na objekte tipa osnovne klase pokazivau na objekte tipa izvedene klase mogua je samo uz eksplicitnu konverziju tipa
preko pokazivaa na tip izvedene klase se moe pristupiti lanovima koji ne postoje u osnovnoj klasi (moe se pristupiti delu memorije koji ne pripada objektu!) operacija je veoma opasna i treba je maksimalno izbegavati eksplicitnom konverzijom programer saoptava prevodiocu da zna ta radi

164

Reference na objekte
Koriste se kao i pokazivai, s tom razlikom to se referenca mora inicijalizovati Inicijalizacije reference tipa osnovne klase referencom tipa izvedene klase:
za javnu osnovnu klasu radi se automatska konverzija za privatnu ili zatienu osnovnu klasu obavezna je eksplicitna konverzija tipa

Inicijalizacije reference tipa izvedene klase referencom tipa osnovne klase mogua je samo uz eksplicitnu konverziju tipa

165

Reference na objekte
Najei sluajevi inicijalizacije reference su pozivanja funkcija Ako je formalni argument funkcije referenca na osnovnu klasu, moe se kao stvarni argument proslediti objekat ili referenca na izvedenu klasu
uslov je da je izvoenje javno

166

Primer: pokazivai i reference na osnovnu klasu


class Osnovna { ... }; class Izvedena : public Osnovna { ... }; Izvedena izv; Izvedena* pi = &izv; Osnovna* po = pi; // Automatska konverzija, po=(Osnovna*)pi void fun(Osnovna&); fun(izv); // Automatska konverzija, fun((Osnovna&)izv) pi = (Izvedena*)po; // Eksplicitna konverzija, opasna operacija

167

Konverzije nadole i nagore


S obzirom na vizualizaciju u dijagramima klasa (osnovna klasa iznad izvedenih klasa):
Konverzija nagore je konverzija pokazivaa (ili reference) tipa izvedene klase u pokaziva (ili referencu) tipa osnovne klase Konverzija nadole je konverzija u suprotnom smeru

168

Virtuelni metodi
Polimorfizam je mogunost razliitog ponaanja programa u zavisnosti od tipa objekata koji se obrauju Polimorfizam se ostvaruje se pomou virtuelnih metoda Virtuelni metod je metod osnovne klase koji moe da se redefinie u izvedenoj klasi Virtuelni metodi se deklariu dodavanjem modifikatora virtual na poetku deklaracije metoda u osnovnoj klasi Za virtuelne metode se u izvedenim klasama podrazumeva modifikator virtual
moe da se navede, ali ne mora
169

Virtuelni metodi
Deklaracija virtuelnog metoda u osnovnoj i izvedenoj klasi mora da bude ista
ista su imena metoda isti su broj i tipovi argumenata isti je tip vrednosti metoda
izuzetak: ako je vrednost metoda u osnovnoj klasi pokaziva ili referenca na osnovnu klasu, u javno izvedenoj klasi vrednost metoda moe da bude pokaziva ili referenca na tu izvedenu klasu

Razlikuje se samo tip skrivenog argumenta (tekueg objekta)

170

Virtuelni metodi u izvedenoj klasi


Virtuelni metod ne mora da se definie u svakoj izvedenoj klasi Ako virtuelni metod nije definisan u izvedenoj klasi, koristi se metod iz osnovne klase iz koje je izvreno izvoenje

171

Ostvarivanje polimorfizma
Prilikom pozivanja metoda pomou pokazivaa ili reference tipa osnovne klase poziva se istoimeni metod one izvedene klase iji primerak u tom trenutku predstavlja dati pokaziva ili referenca Polimorfne klase su klase koje imaju bar jedan virtuelan metod

172

Preklopljeni i redefinisani (virtuelni) metodi


Preklopljeni metodi
razlikuju se na osnovu broja i tipa argumenata tip vrednosti metoda (vraenog rezultata) nije bitan metod bira prevodilac u vreme prevoenja programa metodi pripadaju istoj klasi bez obzira da li su dobijeni nasleivanjem ili definisanjem u toj klasi

Redefinisani (virtuelni) metodi


svi argumenti su istih tipova, isti je i tip vrednosti metoda metod se bira dinamiki u trenutku pozivanja (izvravanja) naizgled se pozivaju za istu vrstu objekta (pozivaju se preko pokazivaa ili reference na osnovnu klasu) metod se bira na osnovu tipa objekta na koji pokazuje identifikator, a ne na osnovu tipa identifikatora
173

Preklopljeni i redefinisani (virtuelni) metodi


Metod u izvedenoj klasi ima isto ime kao i virtuelni metod iz osnovne klase
ako se razlikuje po tipu ili broju argumenata to je preklopljen metod (nije redefinisan tj. virtuelan metod) greka je ako se metod razlikuje samo po tipu vrednosti
mogu se razlikovati samo po tipu vrednosti ako je:
tip vrednosti u osnovnoj klasi pokaziva ili referenca na osnovnu klasu tip vrednosti u izvedenoj klasi pokaziva ili referenca na izvedenu klasu izvoenje je javno

u ovom sluaju metod je redefinisan (virtuelan)

174

Konstruktori i destruktori
Konstruktori ne mogu da budu virtuelni metodi Destruktori mogu da budu virtuelni metodi i to se preporuuje, jer onda unitava i lanove koji ne pripadaju osnovnoj klasi. Ako je destruktor osnovne klase virtuelni metod
objektu izvedene klase se pristupa preko pokazivaa na osnovnu klasu poziva se destruktor osnovne klase izvrie se destruktor izvedene klase
kao i u ostalim sluajevima, posle izvravanja destruktora izvedene klase pozvae se i destruktor osnovne klase

175

Primer za virtuelne metode


class Osn { int k, *a; public: Osn();

// // virtual void vm1();// virtual void vm2(); virtual void vm3(); void m(); // ~Osn();

Konstruktor, ne moe da bude virtuelan Tri virtuelne metode.

Obicna metoda

} class Izv: public Osn { int n, *b; public: Izv(); void vm1(); // void vm2(int); // char vm3(); // void m(); // ~Izv(); }

Virtuelna metoda Nije virt. metoda, pokrivanje imena Greka, return tip Obi na metoda
176

Primer za virtuelne metode, nastavak


int main() { Osn* po = new Izv; // Inicijalizacija pomou // Izv::Izv() plus konverzija po-vm1(); // Izv::vm1() po->vm2(); // Osn::vm2()(ne postoji Izv) po->m(); // Osn ::m() delete po; // Problem: poziva se Osn::~Osn() Izv* pi = new Izv; pi->vm2(); // Greka: ne vidi se Osn::vm2() pi->Osn::vm2() // Moe, nije polimorfizam pi->vm2(5); // Izv::vm2(int) delete pi; }

177

Apstraktne klase
Virtuelni metod koji nije definisan u osnovnoj klasi naziva se apstraktni metod ili ist virtuelni metod Apstraktni metod se oznaava tako to se u definiciji klase umesto tela metoda stavi =0; Primer deklarisanja apstraktnog metoda int imeMetoda(argumenti)=0; Klasa koja ima bar jedan apstraktni metod je apstraktna klasa U apstraktnoj klasi nema ogranienja za ostale lanove

178

Apstraktne klase
Ne mogu da se naprave objekti apstraktne klase Mogu da se definiu pokazivai i reference tipa apstraktne klase
pokaziva apstraktne klase moe da pokazuje samo na objekte izvedenih klasa (poto objekata osnovne klase nema) isto je i za reference

179

Izvoenje iz apstraktnih klasa


Apstraktne klase slue da se iz njih izvode druge klase Klasa izvedena iz apstraktne klase je apstraktna sve dok ne redefinie sve apstraktne metode osnovne klase Apstraktni metodi osnovne klase slue da propiu koje metode moraju da redefiniu izvedene klase
ovi metodi e se pozivati preko pokazivaa ili reference tipa osnovne apstraktne klase

180

Primer apstraktne klase


class GeometrijskaSlika { public: virtual double obim()=0; virtual double povrsina()=0; ... } class Krug : public GeometrijskaSlika { double r; public: ... double obim() { return 2 * 3.14 * r; } double povrsina() { return 3.14 * r * r; } }

181

Primer apstraktne klase nastavak


class Pravougaonik : public GeometrijskaSlika { double a, b; public: ... double obim() { return 2 * a * b; } double povrsina() { return a * b; } }

182

Primer apstraktne klase nastavak


int main() { ... GeometrijskaSlika* slike[n]; slike[0] = new Krug; slike[1] = new Pravougaonik; ... double obim = slike[0]->obim(); // Obim kruga ... obim = slike[1]->obim(); // Obim pravougaonika ... Krug k = *slike[0]; // Objekat tipa Krug GeometrijskaSlika& ref = k; double povrsina = ref.povrsina(); // Povrsina kruga }

183

Dinamika konverzija tipa podataka


U sluaju polimorfnih klasa moe se desiti da pokaziva tipa osnovne klase na odreenom mestu u programu u razliitim trenucima pokazuje na objekte razliitih (srodnih) tipova. Potrebna je dinamika konverzija tipa pokazivaa ili reference polimorfne osnovne klase u pokaziva ili referencu izvedene klase, koja proverava ispravnost konverzije Dinamika konverzija tipa pokazivaa ili reference polimorfne osnovne klase u pokaziva ili referencu izvedene klase radi se operatorom dynamic_cast.

184

Dinamika konverzija pokazivakog tipa


Izraz za konverziju ima opti oblik dynamic_cast<Izv*>(po) po je pokaziva tipa osnovne klase Rezultat je pokaziva tipa Izv* koji pokazuje na isti objekat kao i pokaziva osnovne klase, ako pokaziva osnovne klase pokazuje na:
objekat tipa IzvedenaKlasa ili objekat neke klase koja je dobijena daljim izvoenjem iz klase IzvedenaKlasa

Inae rezultat je nula

185

Dinamika konverzija reference


Izraz za konverziju ima opti oblik dynamic_cast<IzvedenaKlasa&>(refo) refo je referenca tipa osnovne klase Rezultat je referenca na isti objekat na koji ukazuje refo ako je taj objekat:
tipa IzvedenaKlasa ili tipa neke klase koja je dobijena daljim izvoenjem iz klase IzvedenaKlasa

Inae se prijavljuje izuzetak tipa bad_cast definisanog u zaglavlju <typeinfo>

186

Primer za dynamic_cast
class A // Polimorfna osnovna klasa {virtual void vm() {} }; class B: public A // Prva javno izvedena klasa {public: int b; B(int x):b(x) {}}; class C: public A // Duga javno izvedena klasa {public: int c; C(int x):c(x) {}}; int main (){ A* pa = new B(5); //Da li pa pokazuje na B? da if (B* pb = dynamic_cast<B*>(pa)) cout<<pc->b<<endl; //Da li pa pokazuje na C? ne if (C* pb = dynamic_cast<C*>(pa)) cout<<pc->c<<endl; B& ub = dynamic_cast<B&>(pa) // *pa je objekat tipa B cout<<ub.b<<endl; C& uc = dynamic_cast<C&>(pa) // GR: *pa nije tipa B, runtime cout<<uc.c<<endl; // error

187

188

Izuzeci

189

Obrada greaka u programu


Ako programski jezik nema podrku za obradu greaka, greke se obrauju na sledei nain
u nekoj funkciji f1 se pojavi greka
funkcija f1 postavlja vrednost nekog argumenta (kod greke) funkcija f1 se prekida

funkcija f2 koja je pozvala funkciju f1 mora da ispituje


da li je bila greka i koja funkcija f2 postavlja vrednost nekog argumenta (kod greke) funkcija f2 se prekida

funkcija f3 koja je pozvala funkciju f2 mora da ispituje ...

Loe je to je veina funkcija optereena ispitivanjem ta se desilo u pozvanim funkcijama, umesto da to ini samo jedna funkcija
kod postaje veoma komplikovan i teak za odravanje
190

Obrada greaka pomou izuzetaka


Kad se na nekom mestu otkrije greka prijavi se izuzetak koji nosi informaciji o vrsti greke Program se prekida na tom mestu i nastavlja se tako to nadleni rukovalac izuzecima obrauje izuzetak Izuzeci su podaci standardnih ili klasnih tipova Rukovalac izuzecima obrauje izuzetke na osnovu tipa izuzetka

191

Rukovanje izuzecima
Rukovanje izuzecima definie se naredbom try iji je opti oblik
try { // Naredbe u kojima mogu da se pojave izuzeci } catch(tip identifikator) { // Telo: obrada izuzetka ovog tipa } ... catch(tip identifikator) { // Telo: obrada izuzetka ovog tipa } catch(...) { // Univerzalni rukovalac // obrauje izuzetke svih preostalih tipova }

192

Rukovanje izuzecima: naredba try


Naredba try obuhvata blok unutar kojeg mogu da se pojave izuzeci Blok je proizvoljne sloenosti, ukljuujui pozivanje funkcija do proizvoljne dubine
izuzetak moe da se pojavi u bloku ili u pozvanoj funkciji

Izvravanje bloka obuhvaenog naredbom try:


ako se ne pojavi izuzetak do kraja bloka, preskau se svi catch delovi ako se pojavi izuzetak u bloku, prekida se njegovo izvravanje i odabere se jedan rukovalac (jedan catch deo) koji se izvrava
izbor se radi na osnovu tipa izuzetka
193

Rukovanje izuzecima: catch deo


Deo catch lii na funkciju sa jednim argumentom Ako se argument ne koristi moe da se izostavi, tj. moe da se navede samo tip izuzetka Jedan catch deo obrauje izuzetak navedenog tipa
ako je navedeni tip klasni catch deo obrauje i sve klasne tipove izuzetaka izvedene iz navedenog tipa

Univerzalni rukovalac koji obrauje sve tipove izuzetaka navodi se sa tri take umesto tipa izuzetka
ako se navodi treba da bude poslednji rukovalac koji se navodi u jednoj try naredbi

194

Primer
try { ... radi(); ... } catch(const char* str) { ... // Obrada izuzetka tipa const char* } catch(int i) { ... // Obrada izuzetka tipa int } catch(...) { ... // Obrada izuzetka proizvoljnog tipa }

195

Prijavljivanje izuzetaka
Prijavljivanje (bacanje) izuzetka radi se izrazom oblika throw izraz; Operator throw je unarni prefiksni operator prioriteta 2
nema rezultat, tj. tip rezultata je void

Vrednost izraza dostavlja se rukovaocu izuzetka Tip izraza je tip izuzetka


na osnovu tipa izuzetka odreuje se rukovalac koji e obraditi izuzetak tip moe biti standardni tip, ali se mnogo ee koriste klasni tipovi izuzetaka

196

Prijavljivanje izuzetaka
Izuzetak moe da se prijavi u bilo kojem delu bloka unutar naredbe try ukljuujui funkcije, metode, konstruktore, destruktore, operatorske funkcije

197

Deklaracija funkcije koja baca izuzetka


U deklaraciji funkcije mogu (ne moraju) da se navedu tipovi izuzetaka koje funkcija moe da prijavi Opti oblik je tip imeFun(argumenti) throw(niz_tipova); tip imeFun(argumenti) throw(niz_tipova){...} niz_tipova je niz tipova izuzetaka razdvojenih zarezima Ako je niz_tipova prazan funkcija ne moe da prijavi izuzetak

198

Deklaracija funkcije koja baca izuzetka


Ako se navode izuzeci koje funkcija moe da prijavi moraju se navesti svi
greka je ako se prijavi tip izuzetka koji nije naveden

Ako se ne navode tipovi izuzetaka koje funkcija moe da prijavi moe se prijaviti bilo koji izuzetak (tj. ako nema throw operatora)

199

Primer
class Izuzetak : public exception { ... }; void radi() throw (char*, int) { ... if(...) throw "greska"; // tip char* ... if(...) throw 5; // tip int ... if(...) throw Izuzetak(); // greka, tip Izuzetak ... }

200

Izuzeci u virtuelnim metodima


Ako su u deklaraciji virtuelnog metoda osnovne klase navedeni izuzeci koje metod moe da prijavi:
redefinisani metod izvedene klase ne sme da prijavi izuzetak koji nije naveden u deklaraciji osnovne klase moe da bude manji broj tipova izuzetaka u redefinisanom metodu izvedene klase

Ako u deklaraciji virtuelnog metoda osnovne klase nisu navedeni izuzeci koje metod moe da prijavi, mogu se navesti izuzeci koje moe da prijavi redefinisani metod izvedene klase

201

Primer
class A { public: virtual void f() throw (int, char); }; class B : public A{ public: void f() throw (int) { } }; /* Sledece nije dozvoljeno */ /* class C : public A { public: void f() { } }; class D : public A { public: void f() throw (int, char, double) { } };*/
202

Uklopljene naredbe try


Naredbe try mogu biti uklopljene na dva naina
neposredno: jedna (unutranja) naredba try je unutar bloka druge (spoljanje) naredbe try posredno: u bloku (spoljanje) naredbe try se poziva funkcija unutar koje je druga (unutranja) naredba try

Ako se u catch delu unutranje naredbe try prijavi izuzetak, on se obrauje u spoljanjoj naredbi try
moe se napisati samo throw; (bez izraza) i u tom sluaju se izuzetak koji se obrauje prosledi spoljanoj naredbi try, tip izraza je isti kao u obuhvatajuoj catch naredbi

Ako u unutranoj naredbi try ne postoji rukovalac za tip izuzetka koji je nastao, i ne postoji univerzalni rukovalac, izuzetak e obraditi spoljanja naredba try
203

Prihvatanje izuzetaka
Rukovalac tipa R moe da prihvati izuzetak tipa I ako:
R i I su isti tipovi R je javna osnovna klasa za klasu I (klasa I je javno izvedena iz klase R) R i I su tipa pokazivaa ili reference i R moe standardnim konverzijama da se pretvori u tip I

204

Redosled navoenja rukovaoca


Rukovaoci tipa izvedene klase stavljaju se ispred rukovaoca tipa njihove osnovne klase u jednoj try naredbi
rukovaoc tipa osnovne klase obrauje izuzetke tipova javno izvedenih klasa za koje ne postoje zasebni rukovaoci

Ako se navodi, univerzalni rukovaoc catch(...) se navodi kao poslednji u jednoj try naredbi

205

Stvaranje izuzetka
Na mestu prijavljivanja stvara se kopija podatka (objekta) koji je rezultat izraza throw izraz Kopija podatka je privremeni podatak
za izuzetke klasnih tipova u klasi mora da postoji konstruktor kopije

Kopija podatka se prosleuje najbliem rukovaocu koji moe da obradi tip izuzetka (podatka)
ako ne moe da ga obradi nijedan rukovalac try naredbe u kojoj je nastastao prosleuje se spoljanjoj try naredbi i tako redom ako ga nijedna naredba try ne obradi program se prekida
206

Unitavanje podataka (objekata)


Pojavom izuzetka prekida se jedan ili vie uklopljenih blokova Naputanjem jednog bloka unitavaju se svi lokalni podaci tog bloka
redosled je od najdubljeg bloka ka spoljanjim blokovima

Ako se izuzetak pojavi u konstruktoru, unitavaju se samo podaci stvoreni do tog trenutka

207

Unitavanje podataka (objekata) izuzetka


Podatak iz naredbe trow izraz je najee lokalni i bie odmah uniten Zato se privremeni podatak koji je njegova kopija prosleuje rukovaocu i bie uniten tek pri naputanju bloka rukovaoca Ako se u bloku rukovaoca koji obrauje izuzetak prosledi izuzetak spljanjoj naredbi try, odlae se unitavanje privremenog podatka dok ga ne obradi neki rukovaoc Operand operatora trow ne sme da bude pokaziva ili referenca na lokalni (prolazni) podatak koji e biti uniten pre nego to izuzetak bude obraen!

208

Neprihvaeni i izuzeci
Ako se za izuzetak ne pronae rukovalac izvrava se sistemska funkcija iji je prototip void terminate(); Funkcija terminate() poziva funkciju abort() koja prekida program Moe se zadati da funkcija terminate() poziva drugu funkciju a ne abort()

209

Zamena funkcije koju poziva terminate


Postavljanje nove funkcija koju poziva terminate radi se pozivanjem sistemske funkcije set_terminate iji je prototip: typedef void (*PF)(); PF set_terminate(PF pf);
pf je pokaziva na funkciju koja se poziva umesto abort() i koja
mora zavriti program pozivanjem funkcije exit(int) ili abort(), ako to ne uradi pozvae se abort() ne sme prijaviti izuzetak

vrednost funkcije set_terminate je pokaziva na prethodnu funkciju koju je pozivala funkcija terminate()
210

Neoekivani izuzeci
Ako funkcija prijavi izuzetak koji nije na spisku izuzetaka predvienih za tu funkciju izvrava se sistemska funkcija iji je prototip: void unexpected(); Funkcija unexpected() poziva funkciju terminate() Moe se zadati da funkcija unexpected() pozove drugu funkciju a ne terminate()

211

Zamena funkcije koju poziva unexpected


Postavljanje nove funkcija koju poziva unexpected radi se pozivanjem sistemske funkcije set_unexpected iji je prototip: typedef void (*PF)(); PF set_unexpected(PF pf);
pf je pokaziva na funkciju koja se poziva umesto terminate(), koja moa da uradi sledee
prijavi izuzetak sa spiska dozvoljenih za datu funkciju prijavi objekat izuzetka tipa bad_exception zavri program pozivanjem funkcije exit(int), terminate() ili abort() ako to ne uradi pozvae se abort()

vrednost funkcije set_unexpected je pokaziva na prethodnu funkciju koju je pozivala funkcija unexpected() 212

Zaglavlje <exception>
U zaglavlju <exception> opisana je klasa bad_exception i funkcije: terminate(); set_terminate(); unexpected(); set_unexpected(); Funkcija abort() opisana je u zaglavljima <cstdlib> i <stdlib.h>

213

Standardni izuzeci
Izuzetke mogu da prijave neki operatori jezika C++ i metodi standardnih klasa Svi izuzeci koje oni prijavljuju izvedeni su iz osnovne klase exception koja je definisana u zaglavlju <exception>

214

Definicija klase exception


class exception { public: exception() throw(); exception(const exception&) throw(); exception& operator=(const exception&) throw(); virtual ~exception() throw(); virtual const char* what() const throw(); private: ... };

215

Klasa exception
Ima sve metode koji se smatraju obaveznim:
podrazumevani konstruktor konstruktor kopije operator za dodelu vrednosti virtuelni destruktor

Virtuelni metod what vraa pokaziva na tekstualni opis izuzetka Nijedan metod ne prijavljuje nijedan izuzetak Preporuuje se da se za prijavljivanje svojih izuzetaka piu klase koje se izvode iz klase exception

216

You might also like