E
ro
n
kt
sk
o
d
iz
an
je
(2
01
5)
le
E
ro
n
kt
sk
o
d
iz
an
je
(2
01
5)
Predrag Janii
(2
01
5)
Filip Mari
je
PROGRAMIRANJE 1
le
kt
ro
n
sk
o
iz
an
Beograd
2015.
Autori:
dr Filip Mari, docent na Matematikom fakultetu u Beogradu
dr Predrag Janii, redovni profesor na Matematikom fakultetu u Beogradu
PROGRAMIRANJE 1
Izdava: Matematiki fakultet Univerziteta u Beogradu
(2
01
5)
kt
ro
n
sk
o
iz
an
je
le
ISBN 978-86-7589-100-0
c 2015.
Ovo delo zatieno je licencom Creative Commons CC BY-NC-ND 4.0 (AttributionNonCommercial-NoDerivatives 4.0 International License).
videti na veb-adresi
http://creativecommons.org/licenses/by-nc-nd/4.0/.
Do-
(2
01
5)
je
Sadraj
an
Sadraj
10
11
iz
12
1.2
16
1.3
21
1.4
22
1.5
26
sk
o
1.1
38
ro
n
38
2.2
Zapis brojeva . . . . . . . . . . . . . . . . . . . . . . . . . . . .
40
2.3
Zapis teksta . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
48
2.4
55
kt
2.1
. . . . . . . . . . . . . . . . . .
61
le
3 Algoritmi i izraunljivost
Formalizacije pojma algoritma
. . . . . . . . . . . . . . . . . .
61
3.2
er-Tjuringova teza . . . . . . . . . . . . . . . . . . . . . . . .
63
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
64
3.1
3.3
ur maine
3.4
Enumeracija
3.5
Neizraunljivost i neodluivost
3.6
urm programa
. . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . .
. . . . . . . . .
69
71
73
78
4.1
. . . . . . . . . . . .
79
4.2
80
4.3
80
4.4
. . . . . . . . . . . . . . . . . .
II Jezik C
83
90
91
Standardizacija jezika
. . . . . . . . . . . . . . . . . . . . . . .
91
5.2
Prvi programi . . . . . . . . . . . . . . . . . . . . . . . . . . . .
93
(2
01
5)
5.1
101
6.1
Promenljive i deklaracije . . . . . . . . . . . . . . . . . . . . . .
101
6.2
104
6.3
109
6.4
Operatori i izrazi . . . . . . . . . . . . . . . . . . . . . . . . . .
112
6.5
Konverzije tipova . . . . . . . . . . . . . . . . . . . . . . . . . .
126
6.6
Nizovi i niske
. . . . . . . . . . . . . . . . . . . . . . . . . . . .
132
6.7
140
an
je
. . . . . . . . . . . . . . . . . . .
7.2
7.3
Naredbe grananja . . . . . . . . . . . . . . . . . . . . . . . . . .
152
7.4
Petlje
156
. . . . . . . . . . . . . . . . . . . . . . . . . . .
151
7.1
iz
. . . . . . . . . . . . . . . . . . . . .
8 Funkcije
sk
o
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
151
152
168
168
8.2
170
8.3
Parametri funkcije
. . . . . . . . . . . . . . . . . . . . . . . . .
171
8.4
Prenos argumenata . . . . . . . . . . . . . . . . . . . . . . . . .
172
8.5
174
8.6
ro
n
8.1
. . . . . . . . . . . . . . . . . .
175
8.7
Nizovi i funkcije . . . . . . . . . . . . . . . . . . . . . . . . . . .
175
8.8
178
8.9
Rekurzija
kt
. . . . . . . . . . . . . . . . . . . .
179
179
le
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
186
9.1
9.2
193
9.3
219
187
234
. . . . . . . . . . . . . . . . . . . . . . . . .
234
239
. . . . . . . . . . . . . . . . . . . . . . . . .
241
244
247
251
. . . . . . . . . . . . . . . . . . . . . . .
254
. . . . . . . . . . . . . . . . . . . . . . .
255
258
string.h
stdlib.h
ctype.h
math.h .
assert.h
269
. . . . . . . . . . . . . . . . . . . . . . . . .
269
. . . . . . . . . . . . . . . . . . . . . . . . .
272
. . . . . . . . . . . . . . . . . . . . . . . . .
274
(2
01
5)
11.1 Zaglavlje
. . . . . . . . . . . . . . . . . . . . . . . . .
275
. . . . . . . . . . . . . . . . . . . . . . . . .
276
277
. . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
an
le
kt
ro
n
sk
o
Indeks
iz
B Reenja zadataka
je
. . . . . . . . . . . . . .
277
285
286
294
300
301
373
(2
01
5)
Predgovor
je
an
knjizi, centralno mesto ima programski jezik C, ali predmet i knjiga nisu samo
kurs ovog jezika, ve pokuavaju da dju ire osnove programiranja, ilustrovane
iz
predmetu drali od 2005. godine. Ipak, vremenom je materijal proiren i delovima koji se u okviru tog predmeta ne predaju ili se predaju u vrlo ogranie-
sk
o
ro
n
kt
samo drugog dela knjige (Jezik C). Za kurs Programiranje 1 na smeru Informatika preporuujemo samo ubrzano upoznavanje sa glavama 1 i 2 (jer se ti
Za ovaj kurs
le
koja su zadata na testovima i ispitima iz predmeta Programiranje 1 u periodu od pet godina. Odgovori na pitanja nisu eksplicitno navoeni, jer su ve
implicitno sadrani u osnovnom tekstu knjige.
(2
01
5)
viu. Na brojnim sugestijama i ispravkama zahvalni smo i nastavnicima Matematikog fakulteta Mileni Vujoevi-Janii, Nenadu Mitiu i Mladenu Nikoliu,
Jani Proti, Ljubici Peleksi, Ivanu Baleviu, Danielu Doi, Milou Samardiji,
Stefanu Saviu, Petru Kovrliji i Tomislavu Milovanoviu.
je
Be-
an
sk
o
iz
le
kt
ro
n
Autori
(2
01
5)
Deo I
le
kt
ro
n
sk
o
iz
an
je
10
(2
01
5)
Glava 1
je
Raunarstvo i informatika predstavljaju jednu od najatraktivnijih i najivot u savremenom drutvu ne moe se zamis-
an
iz
Brojevi
sk
o
ro
n
razliitih vrednosti.
28 ,
kt
le
mehanike i elektromehanike naprave koje su mogle da reavaju neke numerike zadatke. Dananji raunari su programabilni, tj. mogu da se isprogrami-
Za funkcionisanje
1 Koliina
iskazuje u bajtovima ili izvedenim jedinicama. Obino se smatra da je jedan kilobajt (KB)
jednak 1024 bajtova (mada neke organizacije podrazumevaju da je jedan KB jednak 1000
bajtova). Slino, jedan megabajt (MB) je jednak 1024 KB ili
10242
2 esto
teleskopima, a biologija mikroskopima. Raunari nisu sami po sebi svrha i samo su sredstvo
koje treba da pomogne u ostvarivanju razliitih zadataka.
11
12
rija, matina ploa, hard disk, DVD ureaj, itd. Softver (programski sistem
raunara) ine raunarski programi i pratei podaci koji odreuju izraunavanja koja vri raunar. Raunarstvo je danas veoma iroka i dobro utemeljena
nauna disciplina sa mnotvom podoblasti.
(2
01
5)
Prvi pre-
matematikih operacija koriene su raunaljke zvane abakus . U IX veku persijski matematiar Al Horezmi
je
an
analognih spravama (npr. klizni lenjir iber ) . Prve mehanike sprave koje
iz
6 kon-
7 konstruisao je
sk
o
1672. godine mainu koja je mogla da izvrava sve etiri osnovne aritmetike
operacije (sabiranje, oduzimanje, mnoenje i deljenje) nad celim brojevima.
Ova maina bila je zasnovana na dekadnom brojevnom sistemu, ali Lajbnic je
le
kt
ro
n
na Mesec,
6 Blaise
7 Gottfried
13
Mehanike maine.
programabilnu mainu mehaniki tkaki razboj koji je koristio buene kartice kao svojevrsne programe za generisanje kompleksnih ara na tkanini. Svaka
rupa na kartici odreivala je jedan pokret maine, a svaki red na kartici odgovarao je jednom redu are.
U prvoj polovini XIX veka, arls Bebid
(2
01
5)
funkcija (i eliminie este ljudske greke u tom poslu) u cilju izrade to preciznijih logaritamskih tablica. Ime je dobila zbog toga to je koristila tzv. metod
Maina je trebalo da ima oko 25000 delova i da se pokree runo, ali nije
nikada zavrena
je
Osnovna razlika u odnosu na sve prethodne maine, koje su imale svoje specifine namene, bila je u tome to je analitika maina zamiljena kao raun-
an
Program zapisan na
iz
Ada Bajron
11 zajedno
sk
o
ro
n
programerom u istoriji (i njoj u ast jedan programski jezik nosi ime Ada ).
Ona je bila i prva koja je uvidela da se raunske maine mogu upotrebiti i za
nematematike namene, ime je na neki nain anticipirala dananje namene
kt
digitalnih raunara.
Elektromehanike maine.
le
Herman Holerit
uspeno
11 Augusta
12 Herman
(2
01
5)
14
je
an
iz
sk
o
raunarom
ro
n
kt
Aikena
instrukcije sa buene papirne trake, imala je preko 760000 delova, duinu 17m,
le
Sabiranje i
Elektronski raunari.
danas.
Jedan od prvih elektronskih raunara ABC (specijalne namene reavanje
Slika 1.3:
Holeritova maina.
je
(2
01
5)
15
an
ranja).
16 i Beri 17 .
iz
sk
o
jantama koristi i danas u okviru tzv. DRAM memorije. Maina nije bila proKrajem Drugog svetskog rada, u Engleskoj, u Bleli parku (engl. Bletchley Park) u kojem je radio i Alan Tjuring
ro
n
kt
le
16
(2
01
5)
rani.
Potpuna konceptualna promena dola je kasnih 1940-ih, sa pojavom raunara koji programe na osnovu kojih rade uvaju u memoriji zajedno sa podacima
Iako ideje
je
an
21 . Fon Nojman se u
iz
Rau-
sk
o
raunara koji su mogli da uitaju programe u memoriju. Iako je dizajn raunara EDVAC bio prvi opis fon Nojmanove arhitekture, pre 1951. godine - kada
je EDVAC puten u rad, ve je nekoliko raunara sline arhitekture bilo kon-
ro
n
kt
rija , koji su meusobno povezani. Ostale komponente raunara (npr. ulaznoizlazne jedinice, spoljanje memorije, . . . ) smatraju se pomonim i povezuju
le
se na centralni deo raunara koji ine procesor i glavna memorija. Sva obrada
podataka vri se u procesoru. U memoriju se skladite podaci koji se obrauju,
ali i programi, predstavljeni nizom elementarnih instrukcija (kojima se procesoru zadaje koju akciju ili operaciju da izvri). I podaci i programi se zapisuju
obino kao binarni sadraj i nema nikakve sutinske razlike izmeu zapisa programa i zapisa podataka. Tokom rada, podaci i programi se prenose izmeu
procesora i memorije. S obzirom na to da i skoro svi dananji raunari imaju
fon Nojmanovu arhitekturu, nain funkcionisanja ovakvih raunara bie opisan
detaljnije u poglavlju o savremenim raunarskim sistemima.
Moderni programabilni raunari se, po pitanju tehnologije koju su koristili,
mogu grupisati u etiri generacije, sve zasnovane na fon Nojmanovoj arhitek-
21 John
17
Slika 1.4:
(2
01
5)
turi.
I generacija raunara
an
memoriju.
je
umske cevi kao logika kola i magnetne doboe (a delom i magnetne trake) za
veinu nije postojala serijska proizvodnja). Prvi realizovani raunari fon Nojmanove arhitekture bili su Manesterska Beba (engl. Manchester Baby)
iz
sk
o
ro
n
II generacija raunara
kt
tranzistore umesto vakuumskih cevi. Iako je tranzistor otkriven jo 1947. godine, tek sredinom pedesetih poinje da se koristi umesto vakuumskih cevi kao
osnovna elektronska komponenta u okviru raunara. Tranzistori su izgraeni
le
poreenju sa vakuumskih cevima, tranzistori su manji, zahtevaju manje energije te se manje i greju. Tranzistori su unapredili ne samo procesore i memoriju ve i spoljanje ureaje. Poeli su da se iroko koriste magnetni diskovi
i trake, zapoelo je umreavanja raunara i ak korienje raunara u zabavne
svrhe (implementirana je prva raunarska igra Spacewar za raunar PDP-1 ).
U ovo vreme razvijeni su i prvi jezici vieg nivoa (FORTRAN, LISP, ALGOL,
COBOL). U to vreme kompanija IBM dominirala je tritem samo raunar
IBM 1401, prodat u vie od deset hiljada primeraka, pokrivao je oko treinu
tada postojeeg trita.
18
Prvi raunar koji je koristio ovu tehnologiju bio je IBM 360, napravljen 1964. go-
Slika 1.5:
(2
01
5)
dine.
je
Nova tehnologija omoguila je poslovnu primenu raunara u mnogim oblastima. U ovoj eri dominirali su mejnfrejm (engl. mainframe)mejnfrejm raunari
an
raunari koji su bili izrazito moni za to doba, ija se brzina merila milionima
instrukcija u sekundi (engl. MIPS; na primer, neki podmodeli raunara IBM
iz
racija za popise, statistike obrade i slino. Kod raunara ove generacije uveden je sistem deljenja vremena (engl. timesharing) koji dragoceno procesorsko
sk
o
ro
n
kompanije IBM. Sa udelom od 90%, kompanija IBM je imala apsolutnu dominaciju na tritu ovih raunara.
Pored mejnfrejm raunara, u ovom periodu iroko su korieni i mini rau-
kt
nari (engl. minicomputers) koji se mogu smatrati prvim oblikom linih (personalnih) raunara. Procesor je, uglavnom, bio na raspolaganju iskljuivo jednom
korisniku.
le
poput PDP-8 i VAX. Za ove raunare, obino se vezuje operativni sistem Unix
i programski jezik C razvijeni u Belovim laboratorijama (engl. Bell Laborato-
IV generacija raunara
grisanim kolima kod kojih je na hiljade kola smeeno na jedan silikonski ip.
22 Termin
(2
01
5)
19
Slika 1.6: Mejnfrejm raunar: IBM 7094. Mini raunar: DEC PDP 7
je
an
In-
iz
raunara.
sk
o
proizvodnje softvera. Naime, prvi proizvod kompanije Microsoft bio je interpretator za programski jezik BASIC za Altair 8800.
Nakon Altaira pojavljuje se jo nekoliko raunarskih kompleta na skla-
ro
n
kt
za jednostavnije obrade podataka, uenje programiranja i igranje raunarskih igara. Kompanija Commodore je 1977. godine predstavila svoj rau-
le
narom Commodore PET koji je zabeleio veliki uspeh. Commodore 64, jedan
od najuspenijih raunara za kunu upotrebu, pojavio se 1982. godine.
Iz
Zasnovan na In-
telovom mikroprocesoru Intel 8088, ovaj raunar veoma brzo je zauzeo trite
raunara za linu poslovnu upotrebu (obrada teksta, tabelarna izraunavanja,
. . . ). Pratei veliki uspeh IBM PC raunara, pojavio se odreen broj klonova
je
(2
01
5)
20
Slika 1.7: Prvi mikroprocesor: Intel 4004. Naslovna strana asopisa Popular
an
raunara koji nisu proizvedeni u okviru kompanije IBM, ali koji su kompat-
iz
sk
o
ro
n
x86 seriji (Intel 80286, 80386, 80486) i zatim na seriji Intel Pentium. Operativni sistem koji se tradicionalno vezuju uz PC raunare dolaze iz kompanije
kt
le
godina, pojavom interneta (engl. internet) i veba (engl. World Wide Web
WWW), veina raunara postaje meusobno povezana sredinom 1990-ih godina. Danas se veliki obim poslovanja izvrava u internet okruenju, a domen
korienja raunara je veoma irok. Dolo je do svojevrsne informatike revolucije koja je promenila savremeno drutvo i svakodnevni ivot. Na primer, tokom
prve decenije XXI veka dolo je do pojave drutvenih mrea (engl. social net-
je
(2
01
5)
21
Tablet: Apple
an
iz
se trend tehnoloke konvergencije koja podrazumeva stapanje razliitih ureaja u jedinstvene celine, kao to su tableti (engl. tablet) i pametni telefoni
sk
o
ro
n
23
kt
le
jskih. Zbog njihove isprepletenosti nije jednostavno sve te oblasti sistematizoU nastavku je dat spisak nekih od oblasti savremenog
vati i klasifikovati.
23 Flops
vima u pokretnom zarezu (i pogodnija nego generika mera koja se odnosi na broj instrukcija
u sekundi). Broj flopsa govori koliko operacija nad brojevima u pokretnom zarezu moe da
izvri raunar u jednoj sekundi. Brzina dananjih raunara se obino izraava u gigaflopsima
(109 flopsa), teraflopsima (1012 flopsa) i petaflopsima (1015 flopsa).
22
(2
01
5)
grama);
je
nara);
an
iz
povima podataka);
ro
n
sk
o
Teorijsko raunarstvo (teorijske osnove izraunavanja, raunarska matematika, verifikacija softvera, itd).
kt
le
menih raunarskih sistema i dalje fon Nojmanova maina (procesor i memorija), oni se danas ne mogu zamisliti bez niza hardverskih komponenti koje
olakavaju rad sa raunarom.
Iako na prvi pogled deluje da se jedan uobiajeni stoni raunar sastoji od
kuita, monitora, tastature i mia, ova podela je veoma povrna, podlona
promenama (ve kod prenosnih raunara, stvari izgledaju znatno drugaije) i
nikako ne ilustruje koncepte bitne za funkcionisanje raunara. Mnogo znaajnija je podela na osnovu koje raunar ine:
23
(2
01
5)
Magistrala
obuhvata provodnike koji povezuju ureaje, ali i ipove koji kontroliu protok
podataka. Svi periferijski ureaji se sa memorijom, procesorom i magistralama
povezuju hardverskim sklopovima koji se nazivaju kontroleri .
Matina ploa
je
(engl. motherboard) je tampana ploa na koju se prikljuuju procesor, memorijski ipovi i svi periferijski ureaji. Na njoj se nalaze ipovi magistrale, a
Osnovu hardvera savremenih
an
iz
Procesori.
sk
o
ro
n
kt
vrila iskljuivo preko specijalizovanog registra koji se nazivao akumulator. Aritmetiko logika jedinica sprovodi operacije nad podacima koji su smeteni u
le
odreuje sledeu akciju sistema (na primer, izvri prenos podataka iz procesora na odreenu memorijsku adresu, izvri odreenu aritmetiku operaciju
nad sadrajem u registrima procesora, uporedi sadraje dva registra i ukoliko
su jednaki izvri instrukciju koja se nalazi na zadatoj memorijskoj adresi i
slino). Brzina procesora meri se u milionima operacija u sekundi (engl. Million Instructions Per Second, MIPS) tj. poto su operacije u pokretnom zarezu
najzahtevnije, u broju operacija u pokretnom zarezu u sekundi (engl. FLoating Point Operations per Second, FLOPS). Dananji standardni procesori rade
oko 10 GFLOPS (deset milijardi operacija u pokretnom zarezu po sekundi).
Dananji procesori mogu da imaju i nekoliko jezgara (engl. core) koja istovremeno izvravaju instrukcije i time omoguuju tzv. paralelno izvravanje.
24
CPU
Kontrolna
Aritmetiko
jedinica
logika jedinica
registri
Memorija
(2
01
5)
magistrala
Ulazni
Izlazni
ureaji
ureaji
an
je
sk
o
Memorijska hijerarhija.
iz
(GHz)) vei radni takt obino omoguava izvravanje veeg broja operacija
ro
n
kt
le
25
CPU
pod napajanjem
registri
Ke memorija
(2
01
5)
RAM
ROM/BIOS
bez napajanja
USB diskovi
je
hard diskovi
an
iz
sk
o
ro
n
kt
traeni podatak tamo postoji, u pitanju je tzv. pogodak kea (engl. cache hit) i
podatak se dostavlja procesoru. Ako se podatak ne nalazi u keu, u pitanju je
tzv. promaaj kea (engl. cache miss) i podatake se iz glavne memorije prenosi
le
Glavna memorija uva sve podatke i programe koje procesor izvrava. Mali
deo glavne memorije ini ROM (engl. read only memory) nepromenljiva memorija koja sadri osnovne programe koji slue za kontrolu odreenih komponenata raunara (na primer, osnovni ulazno-izlazni sistem BIOS). Znatno vei
deo glavne memorije ini RAM privremena promenljiva memorija sa slobodnim pristupom.
26
(2
01
5)
tavnija, ali zato sporija od statike memorije od koje se obino gradi ke.
Spoljne memorije uvaju podatke trajno, i kada raunar ostane bez elektrinog napajanja. Kao centralna spoljna skladita podataka uglavnom se ko-
riste hard diskovi (engl. hard disk) koji uvaju podatke korienjem magnetne
tehnologije, a u novije vreme se sve vie koriste i SSD ureaji (engl. solid state
drive) koji uvaju podatke korienjem elektronskih tzv. fle memorija (engl.
flash memory). Kao prenosne spoljne memorije koriste se uglavnom USB fle-
je
memorije (izraene u slinoj tehnologiji kao i SSD) i optiki diskovi (CD, DVD,
Ulazni ureaji.
an
Blu-ray).
koristiti tzv.
taped (engl.
iz
povezuju ili kablom (preko PS/2 ili USB prikljuaka) ili beino (najee korienjem BlueTooth veze). Ovo su uglavnom standardizovani ureaji i nema
sk
o
velikih razlika meu njima. Skeneri sliku sa papira prenose u raunar. Princip
rada je slian digitalnom fotografisanju, ali prilagoen slikanju papira.
Izlazni ureaji.
ro
n
Danas dominiraju monitori tankog i ravnog ekrana (engl. flat panel display),
zasnovani obino na tehnologiji tenih kristala (engl. liquid crystal display,
LCD) koji su osvetljeni pozadinskim LED osvetljenjem.
Ipak, jo uvek su
kt
ponegde u upotrebi i monitori sa katodnom cevi (engl. cathode ray tube, CRT).
Grafiki kontroleri koji slue za kontrolu slike koja se prikazuje na monitoru
le
27
1.5.1
(2
01
5)
je
programskim jezicima.
2 + 3
za datu vred-
an
nost
promenljivama. Meutim, promenljive u programiranju (za razliku od matematike) vremenom mogu da menjaju svoju vrednost (tada kaemo da im se
iz
sk
o
a promen-
onda se pomenuto
Simbol
ro
n
y := 2*x + 3
kt
Kao naredni primer, razmotrimo odreivanje veeg od dva data broja. Raunari (tj. njihovi procesori) obino imaju instrukcije za poreenje brojeva, ali
le
treba da
opisom.
Sloenije
28
pen broja
(tj. vrednost
Na primer,
-ti
ste-
rezultat
0,
zatim se, prilikom svakog mnoenja, uveava sve dok ne dostigne vrednost
(2
01
5)
s := 1, i := 0
dok je i < n radi sledee:
s := sx, i := i+1
Kada se ovaj postupak primeni na vrednosti
i := 0,
n(=2),
poto je
i := i+1 = 1+1 = 2,
n(=2),
i(=0)
manje od
racije
an
i := i+1 = 0+1 = 1,
i(=1)
manje od
racije
sk
o
iz
s := sx = 33 = 9,
poto je
s := sx = 13 = 3,
1.5.2
= 3 i = 2, izvodi se naredni
je
niz koraka.
s := 1,
Mainski programi
ro
n
kt
Primitivne instrukcije koje podrava procesor su veoma malobrojne i jednostavne (na primer, postoje samo instrukcije za sabiranje dva broja, kon-
le
Asemblerski jezici.
bliski mainskom jeziku raunara, ali se, umesto korienja binarnog sadraja
za zapisivanje instrukcija koriste (mnemotehnike, lako pamtljive) simbolike
oznake instrukcija (tj. programi se unose kao tekst). Ovim se, tehniki, olakava
unos programa i programiranje (programer ne mora da direktno manipulie binarnim sadrajem), pri emu su sve mane mainski zavisnog programiranja i
dalje prisutne. Kako bi ovako napisan program mogao da se izvrava, neophodno je izvriti njegovo prevoenje na mainski jezik (tj. zapisati instrukcije
binarnom azbukom) i uneti na odgovarajue mesto u memoriji. Ovo prevoenje
29
bleri .
Sva izraunavanja u primerima iz poglavlja 1.5.1 su opisana neformalno,
kao uputstva oveku a ne raunaru.
(2
01
5)
instruie procesor da izvri odreenu operaciju. Svaki procesor podrava unapred fiksiran, konaan skup instrukcija (engl. instruction set). Svaki program
ax, bx i cx
je
an
add ax, bx
Operacija
mul ax, bx
ax.
Instrukcija
sk
o
u registar
Instrukcija
iz
Operacija
cmp ax, bx
Instrukcija
ro
n
ax.
kt
u procesoru. Operacija
le
Instrukcija
jmp label,
gde je
label
Uslovni skokovi prouzrokuju nastavak izvravanja programa od instrukcije oznaene navedenom labelom, ali samo ako je neki uslov ispunjen.
Ukoliko uslov nije ispunjen, izvrava se naredna instrukcija.
tavku e se razmatrati samo instrukcija
U nas-
30
label
(2
01
5)
Instrukcija
mov
tra prvi odreuje gde se podaci prenose, a drugi koji odreuje koji
se podaci prenose.
se pristupa podacima u odreenom registru), broj u zagradama (to oznaava da se pristupa podacima u memoriji i to na adresi odreenoj
je
an
iz
registra
2 + 3
sk
o
ax, [10]
bx, 2
ax, bx
bx, 3
ax, bx
[11], ax
le
kt
mov
mov
mul
mov
add
mov
ro
n
adrese
10)
u registar
Odreivanje veeg od dva broja moe se ostvariti na sledei nain. Pretpostavimo da se ulazni podaci nalaze u glavnoj memoriji i to broj
na adresi
31
10,
broj
na adresi
11,
dok rezultat
12.
Program
(2
01
5)
iz
an
je
11,
12.
sk
o
na adresi
ro
n
kt
mov ax, 1
mov bx, 0
petlja:
mov cx, [11]
cmp bx, cx
jge kraj
mov cx, [10]
mul ax, cx
mov cx, 1
add bx, cx
jmp petlja
kraj:
mov [12], ax
u registru
i , kao i konstanta
le
a broj
koje se koriste u
10,
32
11
vrednost
= 2.
ax: ?
bx: ?
cx: ?
ax: 1
bx: 0
cx: ?
ax: 1
bx: 0
cx: 2
10: 3
11: 2
12: ?
an
cx:
iz
tar
je
10: 3
11: 2
12: ?
ax i bx
(2
01
5)
10: 3
11: 2
12: ?
bx
ax: 3
bx: 0
cx: 3
kt
10: 3
11: 2
12: ?
ro
n
sk
o
Nakon toga, u
le
vrednosti registara
istru
bx
10: 3
11: 2
12: ?
uveava
ax: 3
bx: 1
cx: 1
cx
petlja)
nakon ega se u
33
10: 3
11: 2
12: ?
ax: 9
bx: 2
cx: 1
je
10: 3
11: 2
12: 9
(2
01
5)
Mainski jezik.
an
Na primer,
sk
o
iz
001
010
011
100
101
110
ro
n
mov
add
mul
cmp
jge
jmp
kt
neposredno
registarsko
le
apsolutno
00
01
10
Pretpostavimo da registar
registar
cx oznaku 10.
ax
ima oznaku
00,
registar
bx
ima oznaku
01,
mov,
zatim slede
(10)16
binarno kodirana sa
00010000
i na kraju oznaka
00
registra
ax.
001 01 10 00 00010000
001 01 00 01 00000010
011 00 01
2 + 3
34
001 01 00 01 00000011
010 00 01
001 10 01 00010001 00
// mov bx, 3
// add ax, bx
// mov [11], ax
Izmeu prikazanog asemblerskog i mainskog programa postoji veoma direktna i jednoznana korespondencija (u oba smera) tj. na osnovu datog mainskog
kda mogue je jednoznano rekonstruisati asemblerski kd.
(2
01
5)
an
1.5.3
je
cijama.
iz
Napredak
sk
o
grameri naredbe raunaru mogu zadavati na to apstraktnijem nivou. Raunarski sistemi i softver se grade slojevito i svaki naredni sloj oslanja se na
funkcionalnost koju mu nudi sloj ispod njega. U skladu sa tim, softver savre-
ro
n
Osnovni zadatak
vera nije kruta i postoje programi za koje se moe smatrati da pripadaju obema
kt
le
Aplikativni softver.
Sistemski softver.
prisutan na skoro svim raunarima, ini operativni sistem (OS). Pored OS,
sistemski softver sainjavaju i razliiti usluni programi : editori teksta, alat za
programiranje (prevodioci, dibageri, profajleri, integrisana okruenja) i slino.
35
Meutim,
ovaj deo sistema koji se naziva korisniki interfejs (engl. user interface UI)
ili koljka (engl. shell) samo je tanak sloj na vrhu operativnog sistema i OS je
mnogo vie od onoga to krajnji korisnici vide. Najvei i najznaajni deo OS
naziva se jezgro (engl. kernel). Osim to kontrolie i apstrahuje hardver, operativni sistem tj. njegovo jezgro sinhronizuje rad vie programa, rasporeuje
orijama itd.
(2
01
5)
procesorsko vreme i memoriju, brine o sistemu datoteka na spoljanjim memNajznaanjni operativni sistemi danas su Microsoft Windows,
sistemi zasnovani na Linux jezgru (na primer, Ubuntu, RedHat, Fedora, Suse)
i Mac OS X.
je
an
iz
nije ako programer umesto da mora da kae Neka se zavrti ploa diska, neka
se glava pozicionira na odreenu poziciju, neka se zatim tu upie odreeni bajt
itd. moe da kae Neka se u datu datoteku na disku upie odreeni tekst.
sk
o
ro
n
kt
le
zadatak).
Izvrni
24 Ovaj
da oznai skup funkcija kroz koji jedan programski sistem koristi drugi programski sistem.
36
Pitanja za vebu
Pitanje 1.1.
Pitanje 1.2.
Pitanje 1.3.
(2
01
5)
Pitanje 1.4.
veka?
Pitanje 1.5.
je
ranja?
an
programerom?
Kako se one
Ko se smatra prvim
Pitanje 1.6.
Koja
iz
Pitanje 1.7.
Pitanje 1.8.
Nabrojati nekoliko
sk
o
najznaajnijih.
ro
n
EDVAC?
Pitanje 1.9.
kt
le
Pitanje 1.10.
ver a ta softver?
Pitanje 1.11.
Pitanje 1.12.
Pitanje 1.13.
eracije raunara savremenih elektronskih raunara? ta su bile osnovne elektronske komponente prve generacije elektronskih raunara? Od koje generacije
raunara se koriste mikroprocesori? Koji tipovi raunara se koriste u okviru
III generacije?
37
Pitanje 1.14.
Koji je najprodavaniji model kompanije Commodore? Da li je IBM proizvodio raunare za kunu upotrebu? Koji komercijalni kuni raunar prvi uvodi
grafiki korisniki interfejs i mia?
Pitanje 1.15.
Pitanje 1.16.
ta je to tehnoloka konvergencija?
pametni telefoni?
Pitanje 1.17.
(2
01
5)
ta je
memorijska hijerarhija? Zato se uvodi ke-memorija? Koje su danas najkorienije spoljne memorije?
Pitanje 1.19.
je
Pitanje 1.18.
Pitanje 1.20.
an
Ukoliko je
iz
raspoloiv mainski kd nekog programa, da li je mogue jednoznano konstruisati odgovarajui asemblerski kd?
Zadatak 1.1.
x := x*y + y + 3.
sk
o
nosti izraza
gram.
Zadatak 1.2.
ro
n
kt
ako je (x < 0)
y := 3*x;
inace
x := 3*y;
Zadatak 1.3.
le
Zadatak 1.4.
Na
se izraunava
[ ],
pri emu se
adresu 200.
Pitanje 1.21.
Pitanje 1.22.
(2
01
5)
Glava 2
an
je
Reprezentacija podataka u
raunarima
iz
sk
o
zapis podataka daje azbuku od samo dva razliita simbola. Tako, na primer,
ukoliko izmeu dve take postoji napon vii od odreenog praga, onda se smatra
da tom paru taaka odgovara vrednost
1,
ro
n
Takoe, polje hard diska moe biti ili namagnetisano to odgovara vrednosti
ili razmagnetisano to odgovara vrednosti
0.
0.
1
kompakt diska bui rupice kojim je odreen zapis podataka pa polje koje
nije izbueno predstavlja vrednost
1.
0,
kt
vrednost
le
38
39
Analogni zapis.
Dakle,
(2
01
5)
je
napraviti veran zapis signala koji se zapisuje i izrazito je teko napraviti dva
identina zapisa istog signala. Takoe, problem predstavlja i inherentna nestal-
an
iz
Digitalni zapis.
sk
o
ro
n
nosti. Ovim je svaki digitalno zapisani signal predstavljen nizom brojeva koji
se nazivaju odbirci ili semplovi (engl. sample) .
kt
le
pitanje je koliko esto je potrebno vriti merenje da bi se polazni kontinualni signal mogao verno rekonstruisati.
Na primer, poto
sokog kvaliteta zapisa potrebno imati medijume visokog kvaliteta, kvalitet reprodukcije digitalnog zapisa ne zavisi od toga kakav je kvalitet medija na kome
su podaci zapisani, sve dok je medijum dovoljnog kvaliteta da se zapisani brojevi mogu razaznati.
(2
01
5)
40
je
an
pis brojeva koji predstavljaju vrednosti boja u takama digitalno zapisane fotografije, injenica da papir uti ne bi predstavljala problem dok god se brojevi
mogu razaznati.
iz
omoguava prenos podataka na daljinu. Na primer, ukoliko izvrimo fotokopiranje fotografije, napravljena fotokopija je daleko loijeg kvaliteta od originala.
Meutim, ukoliko umnoimo CD na kojem su zapisani brojevi koji ine za-
sk
o
pis neke fotografije, kvalitet slike ostaje apsolutno isti. Ukoliko bi se dva CD-a
pregledala pod mikroskopom, oni bi izgledali delimino razliito, ali to ne predstavlja problem sve dok se brojevi koji su na njima zapisani mogu razaznati.
ro
n
kt
le
Jedna
41
(2
01
5)
prirodna broja je uvek jedan isti prirodni broj, bez obzira na to u kom sistemu
su ova tri broja zapisana.
ori samo celi brojevi, dok su ispravnija imena oznaeni celi brojevi (engl. signed
je
an
iz
njima sprovedenih u raunaru, nee uvek odgovarati rezultatima koji bi se dobili bez tih ogranienja (zbog takozvanih prekoraenja ).
Naglasimo jo i da,
sk
o
2.2.1
ro
n
Neoznaeni brojevi
kt
le
gde je
Pretpostavimo da je dat
cifara
( 1 . . . 1 0 ) =
= + 1 1 + . . . 1 + 0
=0
Na primer:
(101101)2 = 1 25 + 0 24 + 1 23 + 1 22 + 0 2 + 1 = 32 + 8 + 4 + 1 = 45,
(3245)8 = 383 +282 +48+5 = 3512+264+48+5 = 1536+128+32+5 =
1701.
1 Ako
10.
42
:= 0
za svako od 0 do
:= +
(2
01
5)
:= 0
za svako od 1 do
:= +
an
je
iz
ro
n
sk
o
:= 0
:= 1
za svako od 1 do
:=
:= +
sheme:
kt
( 1 . . . 1 0 ) = (. . . (( + 1 ) + 2 ) . . . + 1 ) + 0
le
:= 0
za svako od unazad do 0
:= +
Naredni primer ilustruje primenu Hornerovog postupka na zapis
3
9
0 10 + 9 = 9
2
8
9 10 + 8 = 98
1
7
98 10 + 7 = 987
(9876)10 .
0
6
987 10 + 6 = 9876
43
Meurezultati dobijeni u ovom raunu direktno odgovaraju prefiksima zapisa ija se vrednost odreuje, a rezultat u poslednjoj koloni je traeni broj.
Navedeni postupak moe se primeniti na proizvoljnu brojevnu osnovu. Sledei
primer ilustruje primenu postupka na zapis
3
3
08+3=3
2
2
3 8 + 2 = 26
1
4
26 8 + 4 = 212
0
5
212 8 + 5 = 1701
(2
01
5)
(3245)8 .
3
3
2
26
4
212
5
1701
je
+1
mnoenja).
+1
an
svakom koraku dovoljno izvriti samo jedno mnoenje i jedno sabiranje (ukupno
u
osnovom ,
ostatak je 0 a celobrojni kolinik je broj iji je zapis ( 1 . . . 1 ) . Dakle,
izraunavanjem celobrojnog kolinika i ostatka pri deljenju sa , odreena je
poslednja cifra broja i broj koji se dobija uklanjanjem poslednje cifre iz zapisa.
vai da je
0 < .
Za svaku cifru
u zapisu broja
iz
sk
o
osnovi
ro
n
mod,
a celobrojnog kolinika sa
div,
kt
u datoj osnovi
le
:= 0
dok je razliito od 0
:= mod
:= div
:= + 1
Na primer, 1701 = (3245)8 jer je 1701 = 212 8 + 5 = (26 8 + 4) 8 + 5 =
((3 8 + 2) 8 + 4) 8 + 5 = (((0 8 + 3) 8 + 2) 8 + 4) 8 + 5. Ovaj postupak se
1701
1701
1
1701 div 8 = 212
1701 mod 8 = 5
2
212 div 8 = 26
212 mod 8 = 4
3
26 div 8 = 3
26 mod 8 = 2
3 div 8 = 0
3 mod 8 = 3
44
1701
5
212
4
26
2
3
3
Druga vrsta tabele sadri celobrojne kolinike, a trea ostatke pri deljenju
sa osnovom
(2
01
5)
itaju unatrag.
je mogunost jednostavnog
je
sadekadni sistem omoguava da se binarni sadraj memorije zapie kompaktnije (uz korienje manjeg broja cifara). Prevoenje se moe izvriti tako to
an
heksa
binarno
0000
0100
heksa
binarno
heksa
binarno
1000
0001
1100
0101
1001
0010
1101
0110
1010
0011
1110
0111
1011
1111
sk
o
iz
heksa
ro
n
heksadekadnih cifara:
(1011 0110 0111 1100 0010 1001 1111 0001)2 = (6729 1)16
kt
(. . .) ,
ako se koristi
cifara.
le
potrebnih za zapis broja krai od zadate duine zapisa, onda se broj proiruje
vodeim nulama. Na primer,
55 = (0011 0111)82 .
do
2 1.
raspon
od 0 do 255
16
od 0 do 65535
32
od 0 do 4294967295
45
2.2.2
Oznaeni brojevi
Oznaeni brojevi su celi brojevi iji zapis ukljuuje i zapis znaka broja
).
(+ ili
(2
01
5)
simbolom
1.
1),
konvencija je da se znak
zapisuje simbolom
0,
+100 = (0 1100100)82 ,
8
100 = (1 1100100)2 .
Osnovni problem zapisa u obliku oznaene apsolutne vrednosti je injenica
je
an
Potpuni komplement.
iz
sk
o
neoznaeni brojevi, pri emu u njihovom zapisu prva cifra mora da bude
0.
ro
n
kt
Na primer, broj
le
binarno
1
dekadno
????????
-100
01100100
+100
00000000
da se
100
(10011100)82 .
46
01100100
+100
10011011
komplementiranje
1
10011100
21
1,
(100 . . . 00)2
(2
01
5)
Broj
1.
komplementu:
raspon
128
od 32768
2147483648
od
16
32
od
do
do
do
+127
+32767
+2147483647
je
an
broj bita
iz
21
sk
o
ro
n
2.2.3
kt
le
zapis.
Svakoj
kombinaciji nula i jedinica pridruuje se neki realan broj. Kod celih brojeva
odluivano je da li e se takvim kombinacijama pridruivati samo pozitivni ili
i pozitivni i negativni brojevi i kada je to odlueno, u principu je jasno koji
skup celih brojeva moe biti zapisan (taj skup vrednosti je uvek neki povezan
raspon celih brojeva).
47
(nju obino doivljavamo kao broj decimala, mada to tumaenje, kao to emo
uskoro videti, nije uvek u potpunosti tano).
Osnovni naini zapisivanja realnih brojeva su zapis u fiksnom zarezu i zapis
u pokretnom zarezu . Zapis u fiksnom zarezu podrazumeva da se posebno zapisuje znak broja, zatim ceo deo broja i zatim njegov razlomljeni deo (njegove
decimale). Broj cifara za zapis celog dela i za zapis realnog dela je fiksiran i
jednak je za sve brojeve u okviru istog tipa koji koristi zapis u fiksnom zarezu.
Vrednost
je osnova
(2
01
5)
naziva
zapis eksponenta je fiksiran i jednak je za sve brojeve u okviru istog tipa koji
koristi zapis u pokretnom zarezu. Zapisivanje brojeva u pokretnom zarezu pro-
je
an
iz
nenegativnih realnih brojeva (kao to smo rekli, u raunaru se ovakav zapis interno ne koristi, ve se koristi binarni zapis). Zamislimo da imamo tri dekadne
cifre koje moemo iskoristiti za zapis. Dakle, imamo 1000 brojeva koji se mogu
sk
o
ro
n
00,0, 00,1,
...,
99,8
99,9.
9,99.
Ako se se za deci-
0,00, 0,01,
...,
9,98
Ovim smo dobili bolju preciznost (svaki broj je zapisan sa dve, umesto
sa jednom decimalom), ali smo to platili mnogo uim rasponom brojeva koje
kt
moemo zapisati (umesto irine oko 100, dobili smo raspono irine oko 10). U
raunaru se fiksni zarez esto ostvaruje binarno (odreeni broj bitova kodira
le
ceo, a odreeni broj bitova kodira razlomljeni deo), pri emu se uvek jedan bit
ostavlja za predstavljanje znaka broja ime se omoguava zapis i pozitivnih i
negativnih vrednosti.
Umesto fiksnog zareza, u raunarima se mnogo ee koristi pokretni zarez.
U takvom zapisu, nae tri dekadne cifre podeliemo tako da dve odlaze za zapis
mantise, a jednu za zapis eksponenta (pa e zapis biti oblika
prve dve cifre
u zapisu
1 i 2 ,
tumaiemo da je mantisa
0, 1 2 .
1 2 3 ).
Ako su
48
zapis
vrednost
010
020
980
990
0,01 104
0,02 104
0,98 104
0,99 104
= 0,000001
= 0,000002
= 0,000098
= 0,000099
zapis
vrednost
011
021
981
991
0,01 103
0,02 103
0,98 103
0,99 103
10
= 0,00001
= 0,00002
= 0,00098
= 0,00099
...
zapis
vrednost
...
018
028
988
998
0,01 104
0,02 104
0,98 104
0,99 104
do
99 000, 0
...
...
...
0, 000001
= 100,0
= 200, 0
= 9800,0
= 9900,0
zapis
vrednost
019
029
989
999
0,01 105
0,02 105
0,98 105
0,99 105
tj. od oko
= 1 000,0
= 2 000,0
= 98 000,0
= 99 000,0
106
do oko
) i mnogo iri nego to je to bilo kod fiksnog zareza, ali gustina zapisa je
neravnomerno rasporeena, to nije bio sluaj kod fiksnog zareza. Kod malih
(2
01
5)
brojeva preciznost zapisa je mnogo vea nego kod velikih. Na primer, kod malih
brojeva moemo zapisivati veliki broj decimala, ali nijedan broj izmeu
i
99 000
98 000
neki od ova dva broja). Ovo nije preveliki problem, jer nam obino kod velikih
brojeva preciznost nije toliko bitna koliko kod malih (matematiki gledano,
relativna greka koja nastaje usled zaokruivanja se ne menja puno kroz ceo
raspon).
oko
106
do oko
je
an
broj dekadnih znaajnih cifara (u naem primer, imamo dve dekadne znaajne
cifre) i on je skoro potpuno odreeno irinom mantise.
iz
sk
o
ro
n
se tekst obino zamilja kao dvodimenzioni objekat, u raunarima se tekst predstavlja kao jednodimenzioni (linearni) niz karaktera koji pripadaju odreenom
unapred fiksiranom skupu karaktera.
kt
karakteri koji oznaavaju prelazak u novi red, tabulator, kraj teksta i slino.
Osnovna ideja koja omoguava zapis teksta u raunarima je da se svakom
karakteru pridrui odreen (neoznaeni) ceo broj (a koji se interno u rau-
le
Ovi brojevi se
Tehnika ogranienja
ranih raunara kao i neravnomeran razvoj raunarstva izmeu razliitih zemalja, doveli su do toga da postoji vie razliitih standardnih tabela koje dodeljuju numerike kdove karakterima. U zavisnosti od broja bitova potrebnih
za kodiranje karaktera, razlikuju se 7-bitni kdovi, 8-bitni kdovi, 16-bitni kdovi, 32-bitni kdovi, kao i kodiranja promenljive duine koja razliitim karakterima dodeljuju kdove razliite duine. Tabele koje sadre karaktere i njima
pridruene kdove obino se nazivaju kdne strane (engl. code page).
Postoji veoma jasna razlika izmeu karaktera i njihove grafike reprezentacije.
Elementi pisanog teksta koji najee predstavljaju grafike reprezentacije pojedinih karaktera nazivaju se glifovi (engl. glyph), a skupovi glifova nazivaju
se fontovi (engl. font).
49
biti jednoznana. Naime, softver koji prikazuje tekst moe vie karaktera predstaviti jednim glifom (to su takozvane ligature, kao na primer glif za karaktere
f i i:
fi), dok jedan isti karakter moe biti predstavljen razliitim glifovima
(2
01
5)
WGL4 listi (Windows Glyph List 4 ) koja sadri uglavnom karaktere koriene
koje je bilo poeljno kodirati je postajao sve vei. Poto je raunarstvo u ranim
an
je
a, b, ... , z
Cifre
Interpunkcijske znake:
A, B, ... , Z
iz
0, 1, ..., 9
...
sk
o
, . : ; + * - _ ( ) [ ] { }
ro
n
kt
zapis karaktera.
le
ASCII.
Prva 32 karaktera od
50
NUL
STX
SOT
ETX
EOT
ENQ
ACK
BEL
BS
HT
LF
VT
FF
CR
SO
SI
DLE
DC1
DC2
DC3
DC4
NAK
SYN
ETB
CAN
EM
SUB
ESC
FS
GS
RS
US
"
&
'
2
0
<
>
DEL
(30)16
do
(2
01
5)
je
rni zapis.
kodira brojem
an
reprezentaciji. Na primer,
dok se
iz
sk
o
u novi red.
(0)16 i
(0)16 ,
operativni
ro
n
kt
le
ASCII
kd
YUSCII
ASCII
kd
@
[
\
]
^
(40)16
(5)16
(5)16
(5)16
(5)16
{
|
}
~
(60)16
(7)16
(7)16
(7)16
(7)16
51
( )16
nisu iskorieni.
1,
tj. raspon od
(80)16
(2
01
5)
Microsoft.
ISO je definisao familiju 8-bitnih kdnih strana koje nose zajedniku oznaku
(00)16
do
(1 )16 , (7 )16
i od
(80)16
do
(9 )16
ostali
je
kontrolnim karakterima):
Latin 1
ISO-8859-2
Latin 2
ISO-8859-3
Latin 3
juno-evropski jezici
ISO-8859-4
Latin 4
severno-evropski jezici
ISO-8859-5
Latin/Cyrillic
ISO-8859-6
Latin/Arabic
ISO-8859-7
Latin/Greek
ISO-8859-8
Latin/Hebrew
an
ISO-8859-1
iz
sk
o
ro
n
Windows-1250
Windows-1251
Windows-1252
kt
evropski jezici
le
NBSP
SHY
Unicode.
52
NBSP
SHY
(2
01
5)
iz
an
je
NBSP
sk
o
SHY
le
kt
ro
n
irilicu i latinicu.
svih karaktera.
53
0
8
(2
01
5)
tera koristi se kao osnovni viejezini skup karaktera, dok je preostali prostor
ostavljen kao proirenje za drevne jezike, naunu notaciju i slino.
je
an
iz
ne jezici;
sk
o
216 = 65536
menom se shvatilo da dva bajta nee biti dovoljno za zapis svih karaktera
ro
n
koji se koriste na planeti, pa je odlueno da se skup karaktera proiri i Unicode danas dodeljuje kdove od
je osnovna viejezina ravan (engl. basic multilingual plane) koja sadri veinu
kt
(0000)16 i ( )16 .
le
viejezikoj ravni:
54
0020-007E
ASCII printable
00A0-00FF
Latin-1
0100-017F
0180-027F
Latin extended B
grki alfabet
0400-04FF
irilica
(2
01
5)
...
0370-03FF
...
2000-2FFF
specijalni karakteri
3000-3FFF
...
an
UCS-2.
je
iz
UTF-8.
sk
o
Unicode Transformation Format (UTF-8) je algoritam koji svakom dvobajtnom Unicode karakteru dodeljuje odreeni niz bajtova ija duina varira od 1
do najvie 3. UTF je ASCII kompatibilan, to znai da se ASCII karakteri za-
ro
n
kt
sledeih pravila:
raspon
00000000 0xxxxxxx
0xxxxxxx
00000yyy yyxxxxxx
110yyyyy 10xxxxxx
0800-FFFF
zzzzyyyy yyxxxxxx
le
0000-007F
0080-07FF
Unicode kd
55
(2
01
5)
koje su za-
Zapis slika
je
2.4.1
an
Slike se u raunaru zapisuju koristei vektorski zapis, rasterski zapis ili kom-
binovani zapis..
jskih figura (taaka, linija, krivih, poligona), pri emu se svaka figura pred-
iz
sk
o
le
kt
ro
n
uklanjati.
U rasterskom zapisu, slika je predstavljena pravougaonom matricom komponenti koje se nazivaju pikseli (engl. pixel - PICture ELement). Svaki piksel je
individualan i opisan jednom bojom. Raster nastaje kao rezultat digitalizacije
slike. Rasterska grafika se jo naziva i bitmapirana grafika. Ureaji za prikaz
(monitori, projektori), kao i ureaji za digitalno snimanje slika (fotoaparati,
skeneri) koriste rasterski zapis.
56
Modeli boja.
U sluaju da se slika
predstavlja sa ukupno dve boje (na primer, crna i bela, kao kod skeniranog
predstavlja jednim bitom.
(2
01
5)
teksta nekog dokumenta) koristi se model pod nazivom Duotone i boja se tada
U RGB modelu boja, kombinovanjem crvene (R), zelene (G) i plave (B)
komponente svetlosti reprezentuju se ostale boje. Tako se, na primer, kombi-
novanjem crvene i zelene boje reprezentuje uta boja. Bela boja se reprezentuje
maksimalnim vrednosti sve tri osnovne komponente, dok se crna boja reprezentuje minimalnim vrednostima osnovnih komponenti.
RGB
je
model boja se koristi kod ureaja koji boje prikazuju kombinovanjem svetlosti
(monitori, projektori, . . . ). Ukoliko se za informaciju o svakoj komponenti komogue koristiti
224 = 16777216
an
Za razliku od aditivnog RGB modela boja, kod kojeg se bela boja dobija
iz
kombinovanjem svetlosti tri osnovne komponente, u tampi se koristi subtraktivni CMY (Cyan-Magenta-Yellow) model boje kod kojeg se boje dobijaju kombinovanjem obojenih pigmenata na belom papiru. Kako se potpuno crna teko
sk
o
ro
n
Za obradu slika pogodni su HSL ili HSV (poznat i kao HSB) model boja.
U ovom modelu, svaka boja se reprezentuje Hue (H) komponentom (koja predstavlja ton boje), Saturation (S) komponentom (koja predstavlja zasienost
boje odnosno njenu jarkost) i Lightness (L), Value (V) ili Brightness (B)
kt
le
tricom piksela, pri emu se za svaki piksel uva informacija o njegovoj boji.
Dimenzije ove matrice predstavljaju tzv. apsolutnu rezoluciju slike. Apsolutna
rezolucija i model boja koji se koristi odreuju broj bajtova potrebnih za zapis slike. Na primer, ukoliko je apsolutna rezolucija slike 800x600 piksela, pri
emu se koristi RGB model boje sa 3 bajta po pikselu, potrebno je ukupno
informacija potrebnih za zapis slike, koriste se tehnike kompresije i to (i) kompresije bez gubitka (engl. lossless), i (ii) kompresije sa gubitkom (engl. lossy).
Najee korieni formati u kojima se koristi tehnike kompresije bez gubitka
danas su GIF i PNG (koji se koriste za zapis dijagrama i slinih raunarski
generisanih slika), dok je najee korieni format sa gubitkom JPEG (koji se
obino koristi za fotografije).
57
2.4.2
Zapis zvuka
Zvuni talas predstavlja oscilaciju pritiska koja se prenosi kroz vazduh ili
neki drugi medijum (tenost, vrsto telo). Digitalizacija zvuka se vri merenjem i zapisivanjem vazdunog pritiska u kratkim vremenskim intervalima. Osnovni parametri koji opisuju zvuni signal su njegova amplituda (koja odgovara
glasnoi) i frekvencija (koja odgovara visini). Poto ljudsko uho obino uje
(2
01
5)
ranja 40KHz, tj. dovoljno je izvriti odabiranje oko 40 000 puta u sekundi.
Na primer, AudioCD standard koji se koristi prilikom snimanja obinih audio
manje. Drugi vaan parametar digitalizacije je broj bita kojim se zapisuje svaki
dobija mogunost zapisa
216 = 65536
je
snimanja zvuka.
an
iz
vie od dva kanala (od 3 pa ak i do 10), pri emu se esto jedan poseban kanal
izdvaja za specijalno snimanje niskofrekvencijskih komponenti zvuka (tzv. bas).
sk
o
Najpoznatiji takvi sistemi su 5+1 gde se koristi 5 regularnih i jedan bas kanal.
Kao i slika, nekomprimovan zvuk zauzima puno prostora. Na primer, jedan
minut stereo zvuka snimljenog u AudioCD formatu zauzima
60 2
= 10584000 10.1 .
2 44100
ro
n
kt
le
Pitanja i zadaci
Pitanje 2.1.
Pitanje 2.2.
Pitanje 2.3.
ta je Hornerova shema?
kdom.
Pitanje 2.4.
Pitanje 2.5.
ta je to IEEE 754?
58
Pitanje 2.6.
ta je to glif, a ta font?
Pitanje 2.7.
ASCII tabele? Kako se odreuje binarni zapis karaktera koji predstavljaju cifre?
Pitanje 2.8.
Pitanje 2.9.
(2
01
5)
karaktere.
Nabrojati bar tri kdne sheme u kojima moe da se zapie re
raunarstvo.
Pitanje 2.10.
je
Pitanje 2.11.
tog dokumenta eli zapisivanje teksta koji sadri jedan pasus na srpskom (pisan
an
Pitanje 2.13.
"raunari e biti...".
iz
Pitanje 2.12.
ta je to piksel? ta je to sempl?
Zadatak 2.1.
sk
o
Pitanje 2.14.
(b) (34)16
(c) (734)8
Zadatak uraditi klasinim postupkom, a zatim i korienjem Hornerove sheme.
(10111001)2
ro
n
(a)
254
u osnovama
2, 8
16.
kt
Zadatak 2.2.
Zadatak 2.3.
(a)
le
1010101101001000111101010101011001101011101010101110001010010011.
3 46189237.
narnom sistemu.
Zadatak 2.4.
nim kdovima u RGB sistemu: prve dve cifre odgovaraju koliini crvene boje,
naredne dve koliini zelene i poslednje dve koliini plave. Koja je koliina RGB
komponenti (na skali od 0-255) za boju
#35A7DC?
ista uta boja ako se zna da se dobija meanjem crvene i zelene? Kako izgledaju kdovi za nijanse sive boje?
59
Zadatak 2.5.
bita
(b)
Zadatak 2.6.
bita
(c)
16
bita
(d)
24
bita
32
(e)
12
(b)
Zadatak 2.7.
123
(c)
255
(d)
300
bita
(b)
Zadatak 2.8.
mentu irine
(a)
12
(2
01
5)
(a)
bita
bita
(c)
16
bita
(d)
24
bita
32
(e)
bita
bita:
(b)
Zadatak 2.9.
123
(c)
18
(d)
(e)
128
(f )
200
je
an
Zadatak 2.10.
(a)
(e)
11011010
01111111
(b)
(f )
01010011
00000000
(c)
10000000
iz
irine
(d)
11111111
tera.
ro
n
Zadatak 2.11.
sk
o
brojeva?
Zadatak 2.12.
rani zapis rei
Dekodirati
45.
kt
le
Zadatak 2.13.
tekst:
"Programiranje 1".
Zadatak 2.14.
Za rei
Matematiki fakultet?
(b) Windows-1250
(c) ISO-8859-5
(d) ISO-8859-2
(f ) UTF-8
Zadatak 2.15.
pisuje tekst
60
Zadatak 2.16.
Zadatak 2.17.
liko editor nema traene mogunosti) kreirati datoteku koja sadri listu imena
tika). Datoteka treba da bude kodirana kodiranjem:
(a) Windows-1250
(b) ISO-8859-2
(2
01
5)
10 vaih najomiljenijih filmova (pisano latinicom uz ispravno korienje dijakri(c) Unicode (UCS-2)
(d) UTF-8
View->Character encoding).
je
Zadatak 2.18.
iconv)
rekodirati
Zadatak 2.19.
an
le
kt
ro
n
sk
o
iz
HSB modelima.
#B58A34
predstavlja u CMY i
(2
01
5)
Glava 3
an
je
Algoritmi i izraunljivost
i za mnoenje prirodnih brojeva. U raunarstvu, postoje algoritmi za odreivanje najmanjeg elementa niza, ureivanje elemenata po veliini i slino. Da bi
iz
sk
o
ro
n
starogrkih matematiara (na primer, Euklidov algoritam za odreivanje najveeg zajednikog delioca dva broja), pa i pre toga.
kt
goritma. Tada je, u jeku reforme i novog utemeljivanja matematike, postavljeno pitanje da li postoji algoritam kojim se (pojednostavljeno reeno) mogu
le
1 Re
(engl. Muhammad ibn Musa al-Khwarizmi). On je 825. godine napisao knjigu, u meuvremenu nesauvanu u originalu, verovatno pod naslovom O raunanju sa indijskim brojevima.
Ona je u dvanaestom veku prevedena na latinski, bez naslova, ali se na nju obino pozivalo
njenim poetnim reima Algoritmi de numero Indorum, to je trebalo da znai Al-Horezmi
o indijskim brojevima (pri emu je ime autora latinizovano u Algoritmi). Meutim, veina
italaca je re Algoritmi shvatala kao mnoinu od nove, nepoznate rei algoritam koja se
vremenom odomaila sa znaenjem metod za izraunavanje.
2 Ovaj
1928.
godine.
mainu za raunanje, verovao da e biti mogue napraviti mainski postupak koji e, manipulisanjem simbolima, biti u stanju da d odgovor na sva matematika pitanja. Ipak, 1930-ih,
rezultatima era, Tjuringa i Gedela pokazano je da ovakav postupak ne moe da postoji.
61
62
3. Algoritmi i izraunljivost
(2
01
5)
3 i Klini4 ),
-raun
(er ),
Najznaajniji
je
urm)8 .
chines
an
iz
Navedeni sistemi nastali su pre savremenih raunara i veina njih podrazumeva odreene apstraktne maine. I u to vreme bilo je jasno da je opis postupka
dovoljno precizan ukoliko je mogue njime instruisati neku mainu koja e taj
sk
o
postupak izvriti. U tom duhu, i savremeni programski jezici predstavljaju precizne opise algoritama i mogue ih je pridruiti gore navedenoj listi. Znaajna
razlika je u tome to nabrojani formalizmi tee da budu to jednostavniji tj. da
ro
n
koriste to manji broj operacija i to jednostavije modele maina, dok savremeni programski jezici tee da budu to udobniji za programiranje te ukljuuju
veliki broj operacija (koje, sa teorijskog stanovita, nisu neophodne jer se mogu
definisati preko malog broja osnovnih operacija).
kt
le
ovu mainu i tako da izvri sva izraunavanja koja moe da izvri Tjuringova
urm
radovima eperdsona i Sturdisa (engl. Sheperdson and Sturgis), dok je opis koji e biti dat
u nastavku preuzet od Katlanda (engl. Nigel Cutland).
63
3. Algoritmi i izraunljivost
maina kae se da je Tjuring potpun (engl. Turing complete). Za sistem izraunavanja koji izraunava identinu klasu funkcija kao Tjuringova maina kaemo
da je Tjuring ekvivalentan (engl. Turing equivalent).
Ako se neka funkcija moe izraunati u nekom od navednih formalizama,
onda kaemo da je ona izraunljiva u tom formalizmu.
(2
01
5)
urm-
je
vivalentan formalizam.
an
jeziku, moe se opisati i kao program za Tjuringovu mainu ili neki drugi ek-
iz
sk
o
ro
n
9 tvrdi da je
kt
er-Tjuringova teza:
le
Naime, ono govori o intuitivnom pojmu algoritma, ija svojstva ne mogu biti
formalno, matematiki ispitana. Ipak, u korist ove teze govori injenica da je
dokazano da su sve navedene formalne definicije algoritama meusobno ekvivalentne, kao i da do sada nije pronaen nijedan primer intuitivno, efektivno
izvodivog postupka koji nije mogue formalizovati u okviru nabrojanih formalnih sistema izraunavanja.
9 Ovu
64
3. Algoritmi i izraunljivost
3.3 ur maine
ur
urm). Iako su po skupu izraunljivih funkcija nabrojani formalizacije
pojma algoritma jednake, oni se meusobno razlikuju po svom duhu, a ur
maina je verovatno najblia savremenom stilu programiranja: ur maina ima
U daljem tekstu, pojam izraunljivosti bie uveden i izuavan na bazi
maina (
(2
01
5)
ur
kao primitivnu operaciju ima mnoenje prirodnih brojeva, jer se ono moe
je
svesti na sabiranje.
1).
Zaista, defini-
10 i
an
brojeve itaju i upisuju ih na polja ili registre beskonane trake koja slui kao
su sa
iz
prostor za uvanje podataka, tj. kao memorija maine. Registri trake oznaeni
1 , 2 , 3 , . . ..
slici:
2
2
3
3
-tog
...
...
ro
n
1
1
oznaava se sa
sk
o
registra (registra
le
kt
tabeli, na primer,
1 , 2 , . . . koji su upisani
(1 , 2 , . . . , ),
1 , 2 , . . . , redom smetene u prvih
1 , 2 , . . ..
10 Skup
prirodnih brojeva se definie induktivno, kao najmanji skup koji sadri nulu i
11 Oznake
urm
65
3. Algoritmi i izraunljivost
oznaka
naziv
efekat
()
()
(, )
(, , )
nulainstrukcija
0 (tj. := 0)
+ 1 (tj. := + 1)
(tj. := )
ako je = , idi na -tu;
instrukcija sledbenik
instrukcija prenosa
instrukcija skoka
urm instrukcija
(2
01
5)
registara.
urm
program
Neka je funkcija
Vrednost funkcije
Primer 3.1.
iz
an
je
doda vrednost
1,
sk
o
(, ) = + .
i ur
je da se vrednosti
ro
n
+ = + 1 + 1 + ... + 1
Odgovarajui
3 . . .
... ...
kt
le
gde je
1
+
...
...
{0, 1, . . . , }.
12 Neki opisi
urm programa
su svi registri (sem poetnih koji sadre argumente programa) inicijalizovani na nulu. U ovom
tekstu se to nee podrazumevati, delom i zbog toga to promenljive u jeziku C nemaju nulu
kao podrazumevanu vrednost.
66
3. Algoritmi i izraunljivost
:= 0
(2
01
5)
:= + 1
:= + 1
2.
3.
4.
13 .
an
5.
je
(3)
(3, 2, 100)
(1)
(3)
(1, 1, 2)
1.
Neka je funkcija
iz
Primer 3.2.
sk
o
(, ) =
0
1
, ako
, inae
...
...
kt
ro
n
izraunata vrednost je
ili
1.
100 je odabran proizvoljno kao broj sigurno vei od broja instrukcija u programu.
le
13 Broj
I u programima koji slede, uniformnosti radi, za prekid programa e se takoe koristiti skok
na instrukciju 100.
67
3. Algoritmi i izraunljivost
:= 0
0 1
>
1 1
:= + 1
(2
01
5)
5.
6.
7.
8.
9.
Primer 3.3.
Napisati
=0
= ?
= ?
:= + 1
0 1
kraj
an
3.
4.
(3)
(1, 3, 6)
(2, 3, 8)
(3)
(1, 1, 2)
(1)
(1, 1, 100)
(1)
(1)
2.
1 1
iz
1.
je
sk
o
() = [ ]
ro
n
= [ ] 2 < ( + 1)2
kt
Odgovarajui
2 . . .
... ...
le
3
1 = 2
4
2 = ( + 1)2
...
...
za 1 i odgovarajuih vrednosti
1 i 2 postave
1 se postepeno
uveava za 1 i proverava se da li je jednak broju . Ukoliko se ne naie na ,
a 1 dostigne vrednost 2 , onda se uveava za 1 i tada oba broja 1 i 2
2
imaju vrednost (naravno, za uveano ). Tada je potrebno 2 postaviti na
2
2
2
vrednost ( + 1) , tj. potrebno je uveati 2 za ( + 1) = 2 + 1. Ovo
se postie tako to se 2 najpre uvea za 1, a zatim puta uvea za 2. Nakon
Osnovna ideja algoritma je uveavanje broja
2 ,
68
3. Algoritmi i izraunljivost
:= 0
2 := 1
= 1
1 := 1 + 1
je
1 = 2
an
:= + 1
2 := 2 + 1
iz
:= 0
sk
o
2 := 2 + 2
:= + 1
(2)
(3)
(4)
(4)
ro
n
1.
3.
kt
4.
le
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
2.
(2
01
5)
1 := 0
:= 0
1 := 0
2 := 1
(1, 3, 17)
(3)
(3, 4, 9)
(1, 1, 5)
= 1 ?
1 := 1 + 1
1 = 2 ?
(2)
(4)
(5)
(4)
(4)
(5)
(5, 2, 5)
(1, 1, 12)
(2, 1)
:= + 1
2 := 2 + 1
:= 0
2 := 2 + 1
2 := 2 + 1
:= + 1
= ?
1
69
3. Algoritmi i izraunljivost
Primer 3.4.
Neka je funkcija
{
() =
, ako je
=0
, inae
(1, 2, 100)
(1, 1, 1)
0:
(2
01
5)
1.
Za skupove
koji imaju istu kardinalnost kao skup prirodnih brojeva kae se da su prebro-
je
jivi . Dakle, neki skup je prebrojiv ako i samo ako je njegove elemente mogue
an
iz
Primer 3.5.
() = + 1.
Ono to
sk
o
() = 2
ro
n
brojeva).
Lema 3.1.
kt
Dokaz: Razmotrimo beskonanu tabelu elemenata koja odgovara svim ureenim parovima prirodnih brojeva. Mogue je izvriti cik-cak obilazak
le
3.1.
Korienjem slinih ideja, mogu se dokazati i sledea tvrenja.
Lema 3.2.
Lema 3.3.
14 Georg
70
3. Algoritmi i izraunljivost
1
1 1
2
2
3
6
2 3
3 4
4
7
7
...
6
7
.
.
.
je
an
(2
01
5)
iz
Lema 3.4.
brojivo mnogo.
sk
o
urm instrukcija.
Slino je i
ro
n
pa ih (na osnovu leme 3.2) ima prebrojivo mnogo. Skup svih instrukcija
je unija ova etiri prebrojiva skupa, pa je na osnovu leme 3.3 i ovaj skup
le
kt
prebrojiv.
Teorema 3.1.
Razliitih
grama koji imaju jednu instrukciju, skupa programa koji imaju dve instrukcije i tako dalje. Svaki od ovih skupova je prebrojiv (na osnovu leme
3.2) kao konaan Dekartov stepen prebrojivog skupa instrukcija. Dakle,
skup svih
71
3. Algoritmi i izraunljivost
fiksirano dodeljivanje brojeva programima, moemo da govorimo o prvom, drugom, treem, . . . , stotom
(2
01
5)
{, , } i {, , },
= . Za skupove {, } i
{, }
je
an
(1 , . . . , ) = 0,
gde je
polinom
iz
sa celobrojnim koeficijentima.
15
16
sk
o
17
ro
n
4. Zadatak je utvrditi da li postoji opti algoritam koji za proizvoljni zadati skup aksioma i zadato tvrenje proverava da li je tvrnje posledica
18
aksioma.
kt
19 , ve samo da ne postoji
le
15 Ovaj
16 Ovaj
problem je 10. Hilbertov problem izloen 1900. godine kao deo skupa problema
Problem je
19 Instanca
ili primerak problema je jedan konkretan zadatak koji ima isti oblik kao i
opti problem. Na primer, za prvi u navedenom spisku problema, jedna instanca je zadatak
ispitivanja da li je mogue nadovezati nekoliko rei skupa
skupa
{, }
{, }
72
3. Algoritmi i izraunljivost
ur
Pi-
(2
01
5)
raunarstva i programiranja. esto je veoma vano da li se neki program zaustavlja za neku ulaznu vrednost, da li se zaustavlja za ijednu ulaznu vrednost
i slino.
nosti, na ovo pitanje moe se odgovoriti. No, nije oigledno da li postoji opti
postupak kojim se za proizvoljni dati program i proizvoljne vrednosti ulaznih
argumenata moe proveriti da li se program zaustavlja ako se pokrene sa tim
argumentima.
je
urm programe:
Da li postoji urm program koji na ulazu dobija drugi urm program i neki
broj
i ispituje da li se program
an
halting problema za
iz
nemogue, s obzirom na to da
urm programu
sk
o
to je svakom
urm.
ro
n
o halting problemu za
Teorema 3.2
Neka je funkcija
definisana
kt
na sledei nain:
le
(, ) =
1,
0,
ako se program
zadate vrednosti
argument
zaustavlja za ulaz
inae.
zaustavlja za ulazni
Onda
sa jednim argumentom
73
3. Algoritmi i izraunljivost
() 0
()
Ako postoji takav program
ako je
()
() 0
()
()
ako je
ako je
()
(2
01
5)
()
ako je
()
()
ako je
an
() 0
je
programa
ako je
()
iz
karakteristina funkcija
sk
o
ro
n
funkcija jedne promenljive koje za ulazni prirodni broj vraaju iskljuivo 0 ili
1 (tj. funkcija iz
{0, 1})
kt
le
(tj. napisati neki program) je da li je ta funkcija izraunljiva (tj. da li uopte postoji neki program koji je izraunava). Ukoliko takav program postoji, sledee
pitanje je koliko izvravanje tog program zahteva vremena i prostora (memorije). U kontekstu
strukcije, ali se one mogu ponavljati (za neke ulazne vrednosti). Jednostavno
+ 1 puta, a preostale
puta. Dakle, ukupan broj izvrenih instrukcija za ulazne vrednosti i
je jednak 4 + 1. Ako se razmatra samo takozvani red algoritma, onda se zane-
74
3. Algoritmi i izraunljivost
(i to se zapisuje
()).
(1)).
se zapisuje
(2
01
5)
Pitanje 3.2.
je
Pitanje 3.3.
an
dokazati?
iz
Pitanje 3.4.
Da li je svaka
sk
o
ro
n
raunara?
urm naredbe (, , ).
Da li se nekim urm programom moe izraunati hiljadita cifra
Pitanje 3.6.
Opisati efekat
Pitanje 3.7.
21000
kt
broja
Pitanje 3.8.
Da li postoji
le
2,
2?
Da li postoji
gde je
zadati
prirodan broj?
Pitanje 3.9.
Da li se nekim
Pitanje 3.10.
jeva? Koliko ima razliitih programa za Tjuringovu mainu? Koliko ima razliitih programa u programskom jeziku C?
Pitanje 3.11.
Koliko elemenata ima unija prebrojivo mnogo konanih skupova? Koliko elemenata ima unija konano mnogo prebrojivih skupova? Koliko elemenata ima
unija prebrojivo mnogo prebrojivih skupova?
75
3. Algoritmi i izraunljivost
Pitanje 3.12.
skupa
Pitanje 3.13.
Da li se svakom
(2
01
5)
Pitanje 3.15.
je
Pitanje 3.16.
an
iz
3. Da li je mogue napisati
urm program
sk
o
4. Da li je mogue napisati
ro
n
5. Da li je mogue napisati
(0) = 0?
kt
6. Da li je mogue napisati
le
Pitanje 3.17.
2012
i zato?
Zadatak
3.1.
Napisati
Zadatak 3.2.
Napisati
Zadatak 3.3.
Napisati
Zadatak 3.4.
Napisati
1
0
, ako
, inae
76
3. Algoritmi i izraunljivost
Zadatak 3.5.
Napisati
(, ) =
, ako
, inae
Napisati
() =
/3
, ako
(2
01
5)
Zadatak 3.6.
3|
, inae
an
je
Zadatak 3.7.
(, ),
urm
Napisati
odnosno:
iz
Zadatak 3.12.
2(+)
urm
Napisati
Napisati
le
Zadatak 3.15.
Zadatak 3.16.
Napisati
1
0
, ako
, ako
= 0
, inae
(, ) =
Napisati
(, ) =
, inae
{ [ ]
(, ) =
Napisati
, inae
Zadatak 3.17.
, ako
(, ) =
kt
Zadatak 3.14.
ro
n
Zadatak 3.13.
sk
o
(, ) =
(, ) =
, <
,
/3
2
, 3|
,
77
3. Algoritmi i izraunljivost
Napisati
Napisati
++
Zadatak 3.19.
(, , ).
Zadatak 3.20.
Napisati
(, , ) =
Zadatak 3.21.
Napisati
+1
, ako
2|
, inae
(2
01
5)
Zadatak 3.18.
1,
2,
ako je
+ >
inae
le
kt
ro
n
sk
o
iz
an
je
(, , ) =
(2
01
5)
Glava 4
je
an
Na prvim raunarima
iz
sk
o
Prvi programski jezici zahtevali su od programera da bude upoznat sa najfinijim detaljima raunara koji se programira. Problemi ovakvog naina programiranja su viestruki. Naime, ukoliko je eleo da programira na novom rau-
ro
n
naru, programer je morao da izui sve detalje njegove arhitekture (na primer,
skup instrukcija procesora, broj registara, organizaciju memorije).
Programi
kt
Vii programski jezici namenjeni su ljudima a ne mainama i sakrivaju detalje konkretnih raunara od programera. Specijalizovani programi (tzv. jeziki
le
procesori, programski prevodioci, kompilatori ili interpretatori ) na osnovu specifikacije zadate na viem (apstraktnijem) nivou mogu automatski da proizvedu
78
79
(2
01
5)
nastao u periodu 1953-1957 godine. Njegov glavni autor je Don Bakus , koji
je
an
mena omogui unoenje matematikih formula, dok je sistem taj koji bi unete
matematike formule prevodio u niz instrukcija koje raunar moe da izvrava.
2 je dizajnirao programski
-raunu.
iz
sk
o
ro
n
ih godina (period kada zbog loe prakse programiranja softver nije mogao da
kt
le
programa.
1 John
nagrade.
2 John
McCarthy (19272011),
Dobitnik
80
Kao odgovor na jo jednu softversku krizu prelazi se na korienje tzv. objektno-orijentisanih jezika koji olakavaju izradu velikih programa i podelu posla
u velikim programerskim timovima. Tokom 1980-ih se pojavljuje jezik C++
koji nadograuje jezik C objektno-orijentisanim konceptima, a tokom 1990-ih,
pod uticajem interneta, i jezik Java, ija je jedna od osnovnih ideja prenosivost
izvrnog kda izmeu heterogenih raunarskih sistema. Microsoft, je krajem
1990-ih zapoeo razvoj jezika C# koji se danas esto koristi za programiranje
(2
01
5)
Windows aplikacija.
je
paradigme.
an
gramskih jezika. Kako u ovu grupu spada i programski jezik C (ali i programski jezik Pascal, Fortran, Basic itd.), u nastavku e biti najvie rei upravo o
ovakvim jezicima.
iz
sk
o
spadaju Lisp, Haskell, ML, itd.), logika (u nju spada, na primer, Prolog). U
savremenim jezicima meaju se karakteristike razliitih programskih paradigmi
tako da je podela sve manje striktna.
Veina programskih jezika danas je proceduralna to znai da je zadatak
ro
n
kt
le
korieni.
na mainskom jeziku nekog konkretnog raunara, neophodno je precizno definisati ta su ispravni programi nekog programskog jezika, kao i precizno definisati koja izraunavanja odgovaraju naredbama programskog jezika. Pitanjima
ispravnosti programa bavi se sintaksa programskih jezika (i njena podoblast
81
Leksika.
likuje nekoliko razliitih vrsta rei (imenice, glagoli, pridevi, . . . ) i rei imaju
razliite oblike (padei, vremena, . . . ).
(2
01
5)
if (a < 3)
x1 = 3+4*a;
an
zagrada
identifikator
operator
celobrojni literal
iz
zagrada
identifikator
operator
operator
sk
o
celobrojni literal
celobrojni literal
operator
ro
n
if
(
a
<
3
)
x1
=
3
+
4
*
a
;
je
(kategorije).
celobrojni literal
interpunkcija
kt
le
Sintaksa.
ur
Na primer,
(broj, broj).
Sintaksa definie
formalne relacije izmeu elemenata jezika, time pruajui strukturne opise ispravnih niski jezika.
82
<
+
*
(2
01
5)
3
4
i proizvoda konstante
i vrednosti promenljive
a.
jezika.
an
Semantika.
je
iz
if (a < 3) x1 = 3+4*a;
x1
manja od 3,
sk
o
tada promenljiva
a.
ro
n
kt
le
int x = 0;
int y = 1/x;
Dok veina savremenih jezika ima precizno i formalno definisanu leksiku
i sintaksu, formalna definicija semantike postoji samo za neke programske
jezike .
3 Leksika
matikama, dok se semantika formalno zadaje ili aksiomatski (npr. u obliku Horove logike) ili
83
aspekti semantike ostaju nedefinisani standardom jezika i preputa se implementacijama kompilatora da samostalno odrede potpunu semantiku. Tako, na
primer, programski jezik C ne definie kojim se redom vri izraunavanje vrednosti izraza, to u nekim sluajevima moe da dovede do razliitih rezultata
istog programa prilikom prevoenja i izvravanja na razliitim sistemima (na
primer, nije definisano da li se za izraunavanje vrednosti izraza
ili funkcija
g).
f() + g()
(2
01
5)
je
an
iz
sk
o
programskih jezika.
ro
n
tim, programski jezici uobiajeno, kroz koncept promenljivih, nude programerima apstraktniji pogled na podatke. Promenljive omoguavaju programeru da
imenuje podatke i da im pristupa na osnovu imena, a ne na osnovu memorijskih
kt
adresa (kao to je to sluaj kod asemblerskih jezika). Svakoj promenljivoj dodeljen je odreen broj bajtova u memoriji (ili, eventualno, u registrima procesora)
kojima se predstavljaju odgovarajui podaci. Pravila ivotnog veka (engl. life-
le
b, 0, ,, !,
. . . ), niske
84
("zdravo"), . . . Pored ovoga, programski jezici obino nude i mogunost korienja sloenih tipova (na primer, nizovi, strukture tj. slogovi koji mogu da
objedinjavaju nekoliko promenjivih istog ili razliitog tipa).
Svaki tip podataka karakterie:
vrsta podataka koje opisuje (na primer, celi brojevi),
skup operacija koje se mogu primeniti nad podacima tog tipa (na primer,
(2
01
5)
nain reprezentacije i detalji implementacije (na primer, zapis u obliku binarnog potpunog komplementa irine 8 bita, odakle sledi opseg vrednosti
od -128 do 127).
x, y i z celobrojnog
int), a da z nakon izvravanja ovog fragmenta ima vrednost jednaku
promenljivih x i y.
je
tipa (tipa
iz
an
int x, y;
...
int z = x + y;
sk
o
ro
n
x , y i z,
celobrojnog tipa,
kt
float,
najverovatnije bi
bi se prevela u
le
int x = 3.1;
promenljiva
3.
3.1
85
a = 1; b = "2"; a = a + b;.
(2
01
5)
konvertuje.
x1 = 3 + 4*a;.
je
druge.
an
puta i slino.
iz
(goto). Za naredbu skoka (goto) je pokazano da nije neophodna, tj. svaki program se moe zameniti programom koji daje iste rezultate a pri tome koristi
samo sekvencijalno nizanje naredbi, naredbu izbora (if-then-else) i jednu
do-while).4
sk
o
ro
n
Potprogrami.
kt
vrste potprograma, ali nazivi potprograma se razlikuju (najee se koriste termini funkcije, procedure, sabrutine ili metode ). Potprogrami izoluju odreena
le
izraunavanja koja se kasnije mogu pozivati tj. koristiti na vie razliitih mesta
u razliitim kontekstima.
86
nosti ) funkcija dobija svoju kopiju parametra navedenog u pozivu i sve vreme
barata kopijom, ostavljajui originalni parametar nepromenjen. U nekim sluajevima (tzv. prenos po adresi ), parametar se ne kopira ve se u funkciju prenosi
samo memorijska adresa na kojoj se parametar nalazi i funkcija sve vreme
(2
01
5)
vaocu. Neki jezici (npr. Pascal) sutinski razlikuju funkcije koje izraunavaju
(i kae se vraaju ) neku vrednost i procedure iji je zadatak samo da proizvedu
odreeni sporedni efekat (npr. da ispiu neto na ekran ili da promene vrednost
promenljive).
je
Modularnost.
visne celine. Celine, koje sadre definicije srodnih podataka i funkcija, obino
an
upotrebe pojedinih modula u okviru razliitih programa. Celine se obino zasebno prevode i kasnije povezuju u jedinstven program.
iz
sk
o
ro
n
kt
le
Upravljanje memorijom.
htevaju od programera da eksplicitno rukuje memorijom tj. da od sistema zahteva memoriju u trenutku kada je ona potrebna i da tu memoriju eksplicitno
oslobaa, tj. vraa sistemu kada ona programu vie nije potrebna. Drugi programski jezici (na primer, Java, C#, Haskell, ML) oslobaaju programera ove
dunosti time to koriste tzv. sakupljae otpada (engl. garbage collector) iji je
zadatak da detektuju memoriju koju program ne koristi i da je oslobaaju. Iako
je programiranje u jezicima sa sakljupljaima otpada jednostavnije, programi
su obino sporiji (jer odreeno vreme odlazi na rad sakupljaa otpada).
U cilju obezbeivanja pogodnog naina da se hardverom upravlja, neki
programski jezici doputaju programeru da pristupi proizvoljnoj memorijskoj
adresi (npr. u jeziku C, to se moe raditi korienjem pokazivaa), ime se dobija
87
vea sloboda, ali i mnogo vea mogunost pravljenja greaka. Sa druge strane,
neki programski jezici imaju za cilj skrivanje svojstava hardvera od programera, tite memoriju od direktnog pristupa programera i doputaju korienje
podataka samo u okviru memorije zauzete promenljivim programa.
Jeziki procesori
(2
01
5)
4.4.1
cizan opis leksike i sintakse, ali i to precizniji opis semantike vieg programskog
je
jezika.
an
iz
Kompilatori.
sk
o
ro
n
prevoenjem.
izvrni mainski kd .
kt
le
Interpretatori.
prevoenja i faza izvravanja programa isprepletane. Interpretatori analiziraju deo po deo (najee naredbu po naredbu) izvornog kda programa
i odmah nakon analize vre i njegovo izvravanje. Rezultat prevoenja
se ne smeta u izvrne datoteke, ve je prilikom svakog izvravanja neophodno iznova vriti analizu izvornog kda. Zbog ovoga, programi koji
se interpretiraju se obino izvravaju znatno sporije nego u sluaju kompilacije. S druge strane, razvojni ciklus programa je eto krai ukoliko
5 Ipak,
izvrni distribuira i izvorni kd programa (tzv. softver otvorenog kda, engl. open source) da
bi korisnici mogli da vre modifikacije i prilagoavanja programa za svoje potrebe.
88
se koriste interpretatori.
(2
01
5)
definisan meujezik niskog nivoa (ovo je obino jezik neke apstraktne virtuelne
maine), a zatim se vri interpretacija ovog meujezika i njegovo izvravanje
an
Pitanje 4.1.
je
gramskom jeziku (na primer, na jeziku C), da li je mogue jednoznano konstruisati odgovarajui mainski kd? Ukoliko je raspoloiv mainski kd nekog
Pitanje 4.2.
iz
C?
sk
o
ro
n
Pitanje 4.3.
Pitanje 4.4.
kt
dobija kao svoj ulaz, a ta vraa kao rezultat svog rada? ta je zadatak sintaksike analize programa? ta sintaksiki analizator dobija kao svoj ulaz, a ta
le
Pitanje 4.5.
Pitanje 4.6.
ta je to konverzija tipova?
ta znai da je
Pitanje 4.7.
ta je to
89
Pitanje 4.8.
Pitanje 4.9.
Pitanje 4.11.
(2
01
5)
Pitanje 4.10.
Pitanje 4.12.
je
le
kt
ro
n
sk
o
iz
an
grama?
le
E
ro
n
kt
sk
o
d
iz
an
Jezik C
90
je
(2
01
5)
Deo II
(2
01
5)
Glava 5
je
an
iz
sk
o
ro
n
kt
le
1 Dennis
Ritchie
(19412011),
ameriki
informatiar,
1983. godine.
91
dobitnik
Tjuringove
nagrade
92
K&R C.
Brajan Kerningen
ak i posle pojave
ANSI C i ISO C.
(2
01
5)
erogenih platformi i time se javila potreba za zvaninom standardizacijom jezika. Godine 1989. ameriki nacionalni institut za standardizaciju
je
naziva ANSI C ili C89. Godine 1990. Meunarodna organizacija za standardizaciju (ISO) usvojila je ovaj dokument (uz sitnije izmene) pod oz-
an
naziva i C90, pa C89 i C90 predstavljaju isti jezik. Ovaj jezik predstavlja
C99.
iz
sk
o
ro
n
kt
le
uvedeni i neki konstrukti jezika C99 i C11 (uz jasnu naznaku da se radi o
dopunama).
Pitanja za vebu
Pitanje 5.1.1.
Pitanje 5.1.2.
2 Brian
93
Pitanje 5.1.3.
standarde jezika C.
(2
01
5)
Program Zdravo!
Zdravo!.
an
Program 5.1.
je
poruku
#include <stdio.h>
sk
o
iz
int main() {
printf("Zdravo!\n"); /* ispisuje tekst */
return 0;
}
Navedeni program sastoji se iz definicije jedne funkcije i ona se zove
main
ro
n
(od engleskog main glavna, glavno). Program moe da sadri vie funkcija,
ali obavezno mora da sadri funkciju koja se zove
main
i izvravanje programa
kt
naava da ova funkcija, kao rezultat, vraa celobrojnu vrednost (engl. integer),
tj. vrednost tipa
int.
main
le
Naredbe funkcije
{i}
(koji oznaavaju
;.
Funkcije
koje se pozivaju mogu da budu korisniki definisane (tj. napisane od strane istog programera koji pie program) ili biblioteke (tj. napisane od strane nekog
drugog tima programera). Odreene funkcije ine takozvanu standardnu bib-
funkcije
94
kd poziva funkcije
printf,
stdio.h
je pretprocesorska
stdio.h.
return 0; prekida izvravanje funkcije main i, kao njen rezultat,
vrednost 0. Vrednost funkcije vraa se u okruenje iz kojeg je ona poz-
(2
01
5)
stavlja nultu fazu kompilacije i koji pre kompilacije program priprema tako to
main
vraa vrednost
da ukae na to da je
/*
i simbola
je
*/
an
su korisni samo programerima, doprinose itljivosti i razumljivosti samog programa. Njih C prevodilac ignorie i oni ne utiu na izvrnu verziju programa.
Primetimo da je svaka naredba u prikazanom programu pisana u zaseb-
nom redu, pri emu su neki redovi uvueni u odnosu na druge. Naglasimo da
iz
sa stanovita C prevodioca ovo nije neophodno (u ekstremnom sluaju, doputeno bi bilo da je ceo kd osim prve linije naveden u istoj liniji). Ipak, smatra
se da je nazubljivanje (engl. indentation) kda u skladu sa njegovom sintak-
sk
o
ro
n
kt
le
Zdravo!
Tokom prevoenja, prevodilac moe da detektuje greke (engl. error) u
izvornom programu. Tada prevodilac ne generie izvrni program nego izve-
3 Razlog za ovo je istorijski a.out je skraeno za assembler output jer je izvrni program
obino bio izlaz nakon faze asembliranja.
95
tava programera o vrsti tih greaka i brojevima linija u kojima se nalaze. Programer, na osnovu tog izvetaja, treba da ispravi greke u svom programu i
ponovi proces prevoenja.
(2
01
5)
Prethodni program nije uzimao u obzir nikakve podatke koje bi uneo korisnik, ve je prilikom svakog pokretanja davao isti izlaz.
Naredni program
oekuje od korisnika da unese jedan ceo broj i onda ispisuje kvadrat tog broja.
je
Program 5.2.
an
#include <stdio.h>
sk
o
iz
int main() {
int a;
printf("Unesite ceo broj: ");
scanf("%i", &a);
printf("Kvadrat unetog broja je: %i", a*a);
return 0;
}
main je takozvana deklaracija promenljive. Ovom deklaa celobrojnog tipa tipa int. Naredna naredba
(poziv funkcije printf) na standardni izlaz ispisuje tekst Unesite ceo broj:,
a naredba nakon nje (poziv funkcije scanf) omoguava uitavanje vrednosti
ro
n
kt
scanf
le
%i.
U okviru poziva
promenljive ili izraza. U formatu ispisa, na mestu u tekstu gde treba ispisati
vrednost izraza zapisuje se format tog ispisa u ovom sluaju
%i4 ,
jer e biti
ispisana celobrojna vrednost. Nakon niske koja opisuje format, navodi se izraz
koji treba ispisati u ovom sluaju vrednost
4 Umesto %i,
podatak tipa
a*a,
int,
%d
%d. %i
dolazi od toga to je
96
(2
01
5)
Sledei primer prikazuje program koji rauna rastojanje izmeu dve take
int
double,
%lf
sqrt
%i.
deklarisana u zaglavlju
math.h.
an
Program 5.3.
je
umesto niske
iz
#include <stdio.h>
#include <math.h>
kt
ro
n
sk
o
int main() {
double x1, y1, x2, y2;
printf("Unesi koordinate prve tacke: ");
scanf("%lf%lf", &x1, &y1);
printf("Unesi koordinate druge tacke: ");
scanf("%lf%lf", &x2, &y2);
printf("Rastojanje je: %lf\n",
sqrt((x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1)));
return 0;
}
le
teoreme
(2 1 )2 + (2 1 )2 .
-lm
gument). Na primer,
97
Program 5.4.
#include <stdio.h>
an
je
(2
01
5)
int main() {
int a;
printf("Unesi broj: ");
scanf("%d", &a);
if (a % 2 == 0)
printf("Broj %d je paran\n", a);
else
printf("Broj %d je neparan\n", a);
return 0;
}
Ceo broj je paran ako i samo ako je ostatak pri deljenju sa dva jednak nuli.
==.
%,
if
iz
vri operatorom
a % 2 == 0) ispunjen usmerava
() iza kojih ne sledi simbol
;.
sk
o
uslova (takozvana
ro
n
then i else grana mogu da sadre samo jednu naredbu ili vie naredbi.
Ukoliko
sadre vie naredbi, onda te naredbe ine blok iji se poetak i kraj moraju
{ i }.
Grana
else
ne mora da postoji.
kt
oznaiti zagradama
le
Program 5.5.
#include <stdio.h>
#include <math.h>
#define N 100
int main() {
int i;
for (i = 1; i <= N; i++)
printf("%3d %5d %7.4f\n", i, i*i, sqrt(i));
98
return 0;
for
koja slui
da se odreene naredbe ponove vie puta (obino uz razliite vrednosti promenljivih). Petlja se izvrava tako to se prvo izvri inicijalizacija promenljive
na vrednost 1 (zahvaljujui kdu
promenljive
i=1),
vrednost promenljive
i++)
i <= N). Pre preN menja se brojem 100 i to zahvaljujui tzv. pret#define N 100 koja se esto koristi za definisanje konne postane
(zahvaljujui uslovu
(2
01
5)
O petljama e biti
printf.
je
%d,
koristi
%3d,
ime se
%7.4f,
an
postie da se broj uvek ispisuje u polju irine 3 karaktera. Slino se, korienjem
postie da se vrednost korena ispisuje na 4 decimale u polju ukupne
iz
irine 7 karaktera.
sk
o
Naredni program ispisuje prvi prirodni broj za koji je zbir svih prirodnih
brojeva do tog broja vei od 100.
Program 5.6.
ro
n
#include <stdio.h>
kt
#define N 100
le
int main() {
int i = 1;
int s = 1;
while(s <= N) {
i++;
s = s+i;
}
printf("%d\n", i);
return 0;
}
while koja se
int i = 1; je deklaracija
sa inicijalizacijom njom se promenljvoj i dodeljuje inicijalna vrednost 1. Kao
Novina u ovom programu, u odnosu na prethodne, je petlja
99
100 u
N uvedeno pretprocesorskom direktivom.
(2
01
5)
Program 5.7.
sk
o
iz
an
je
#include <stdio.h>
#include <ctype.h>
int main() {
int c;
printf("Otkucaj recenicu (zavrsi je znakom .): ");
do {
c = getchar();
putchar(toupper(c));
} while (c != .);
putchar(\n);
return 0;
}
Kada se pokrene program, dobija se ovakav rezultat.
ro
n
le
kt
Telo petlje se
unetni tekst (sa velikim slovima umesto malim) se ispisuje uvek kada se pritisne
taster za unos (enter ). Kada se unese i prepie taka, tada se petlja zavrava.
100
Pitanje 5.2.2.
ta su to pretprocesorske direktive? Da li je
#include<stdio.h>
Pitanje 5.2.4.
Pitanje 5.2.5.
je ona pozvana?
Zadatak 5.2.1.
Zadatak 5.2.2.
koristiti konstantu
M_PI
sin()
i . Napomena: koristiti
cos() iz zaglavlja math.h
.
Zadatak 5.2.4.
iz
varajuu brzinu u .
Zadatak 5.2.5.
ispisuje odgo
0 , ubrzanje
tela koje se kree
sk
o
i preeni put
ravnomerno ubrzano.
ro
n
2
5
8
1 , 2 , . . . , 9
izrau-
3
6
9
le
kt
nava determinantu:
Zadatak 5.2.8.
Zadatak 5.2.7.
an
( > 0
Zadatak 5.2.6.
je
math.h).
( > 0, > 0)
i vreme
izraunava obim
Zadatak 5.2.3.
iz zaglavlja
(2
01
5)
Pitanje 5.2.3.
i i zatim ispisuje
(2
01
5)
Glava 6
an
je
Predstavljanje podataka i
operacije nad njima
u programu.
Tipovi promenljivih,
iz
Promenljive i konstante,
sk
o
ro
n
Deklaracije,
Operatori,
kt
vrste.
Izrazi,
le
nove vrednosti.
6.1.1
101
102
a,
i, x1, x2 itd. Generalno, identifikator moe da sadri slova i cifre, kao i simbol
_ (koji je pogodan za duga imena), ali identifikator ne moe poinjati cifrom.
Dodatno, kljune rei jezika C (na primer, if, for, while) ne mogu se koristiti
torima . U prethodnim programima koriene su promenljive ija su imena
kao identifikatori.
U identifikatorima, velika i mala slova se razlikuju. Na primer, promenljive
esta praksa je
(2
01
5)
sa imenima
da malim slovima poinju imena promenljivih i funkcija, a velikim imena simbolikih konstanti (vidi poglavlja o nabrojivim tipovima 6.7.4 i pretprocesoru
9.2.1), vrednosti koje se ne menjaju u toku programa.
i).
je
ljive sadri vie rei, onda se, radi bolje itljivosti, te rei razdvajaju sim-
an
bolom
iBrojStudenata).1
_,
iz
sk
o
promenljive smatra znaajnom, dok standard C99 poveava taj broj na 63.
Ukoliko dve promenljive imaju vie od 63 poetna znaka ista, onda se ne garan-
6.1.2
ro
n
Deklaracije
3 sadri
kt
tip i listu od jedne ili vie promenljivih tog tipa, razdvojenih zarezima.
le
int broj;
int a, b;
nakon to je deklarisana . Prilikom deklaracije moe se izvriti poetna inicijalizacija. Mogue je kombinovati deklaracije sa i bez inicijalizacije.
1 Postoje
(C99).
deklaracija i
4 Samo
drazumevana vrednost je 0.
103
int vrednost = 5;
/* deklaracija sa inicijalizacijom */
int a = 3, b, c = 5; /* deklaracije sa inicijalizacijom */
Izraz kojim se promenljiva inicijalizuje zvaemo inicijalizator.
const
Kvalifikator
Kvalifikator
(2
01
5)
je
Izmeu ova dva naina navoenja kvalifikatora razlike postoje samo kod
glavama.
an
sloenijih tipova (pre svega pokazivaa) i o tome e biti vie rei u narednim
const T moe biti dodeljena promenljivoj tipa T, ali proconst T ne moe biti dodeljena vrednost (osim prilikom inici-
Vrednost tipa
menljivoj tipa
iz
sk
o
gramu. Najee se navode na poetku funkcije (u dosada navedenim primerima to je bila funkcija
main).
ro
n
mogu da je koriste.
imena. Promenljive deklarisane van svih funkcija su globalne i mogu se koristiti u vie funkcija. Vidljivost tj. oblast vaenja identifikatora (i njima uvedenih
promenljivih) odreena je pravilima dosega identifikatora o emu e vie rei
kt
le
Pitanje 6.1.2.
Pitanje 6.1.1.
grama?
Pitanje 6.1.3.
_?
Da li se
Pitanje 6.1.4.
Pitanje 6.1.5.
104
Pitanje 6.1.6.
Pitanje 6.1.7.
ta je uloga kvalifikatora
const?
(2
01
5)
brojeve ili brojeve u pokretnom zarezu). Jedan tip karakterie: vrsta podataka
koje opisuje, nain reprezentacije, skup operacija koje se mogu primeniti nad
podacima tog tipa, kao i broj bitova koji se koriste za reprezentaciju (odakle
Tip
int
an
6.2.1
je
int
iz
koristei potpuni komplement. Nad podacima ovog tipa mogu se koristiti arit-
+, -, *, /, %),
sk
o
le
kt
Tipu
ro
n
signed
ni kvalifikator
oznaen broj.
5 Kaemo
105
Podaci o opsegu ovih (i drugih tipova) za konkretan raunar i C prevodilac sadrani su u standardnoj datoteci zaglavlja
<limits.h>.
Pregled danas
neoznaeni (unsigned)
karakteri
1B = 8b
1B = 8b
(char)
[-2 ,
27 -1]
[0,
28 -1]
[0, 255]
kratki
2B = 16b
2B = 16b
(short int)
[-32K, 32K-1] =
15
[-2
215 -1]
(2
01
5)
[-128, 127]
[0, 64K-1] =
[0,
216 -1]
[-32768, 32767]
[0, 65535]
dugi
4B = 32b
4B = 32b
(long int)
[-2G, 2G-1] =
,
231 -1]
[0, 4G-1] =
[0,
232 -1]
je
31
[-2
[0, 4294967295]
veoma dugi
8B = 64b
8B = 64b
[-2
263 -1] =
18
18
[-9.210 , 9.210 ]
,
[0,
[0,
264 -1] =
19
1.8410 ]
iz
od C99
63
an
[-2147483648,2147483647]
sk
o
funkcije
(npr.
%u
za
ro
n
Konaan opseg tipova treba uvek imati u vidu jer iz ovog razloga neke
matematike operacije nee dati oekivane vrednosti (kaemo da dolazi do
prekoraenja .
kt
Program 6.1.
le
#include <stdio.h>
int main() {
int a = 2000000000, b = 2000000000;
printf("Zbir brojeva %d i %d je: %d\n", a + b);
return 0;
}
Zbir brojeva 2000000000 i 2000000000 je: -294967296
Da su promenljive bile deklarisane kao promenljive tipa
%u,
unsigned int
106
Program 6.2.
#include <stdio.h>
(2
01
5)
int main() {
unsigned int a = 2000000000, b = 2000000000;
printf("Zbir brojeva %u i %u je: %u\n", a, b, a + b);
return 0;
}
char
char
simbol, znak).
an
Tip
iz
operacije i relacije.
6.2.2
je
bajt.
Standard
ili neoznaenim
char mogu se
unsigned obezbeuje
unsigned i signed.
sk
o
primeniti kvalifikatori
da se vrednost tretira
signed
ro
n
Kvalifikator
0 do 255 i
28 = 256.
char
128
do
127.
kt
Iako je
janje vrednosti malih celih brojeva, u jeziku C se ovaj tip obino koristi za
le
char).
Standard ne
c),
<ctype.h>. Najkorienije
isalpha, isdigit i sline kojima se proverava da li je karakter slovo abecede
107
toupper, tolower
6.2.3
Tipovi
(2
01
5)
float, double i (od standarda C99) long double . Tip float opisuje brojeve
u pokretnom zarezu osnovne tanosti, tip double opisuje brojeve u pokretnom zarezu dvostruke tanosti, a tip long double brojeve u pokretnom zarezu
proirene tanosti. Nije propisano koliko ovi tipovi zauzimaju bitova, ali propisano je da
long double
double
double.
float,
a da
Podaci o opsegu
<float.h>.
je
I nad podacima ovih tipova mogu se koristiti uobiajene aritmetike operacije (osim operacije raunanja ostatka pri deljenju
%)
i relacije.
an
iz
sk
o
0.0/0.0
je
ili koren
ro
n
1.0/ + jednaka je
ponovo imaju
printf, vrednost se tampa
. Ako se koristi
kao nan.
kt
0.0.
+,
inf,
GCC i funkcija
le
%lf.
double
formate (npr.
%f
za
float
108
6.2.4
true
false
Pitanje 6.2.2.
je
char?
an
Pitanje 6.2.3.
i konstante
bool
(2
01
5)
Pitanje 6.2.4.
signed char?
Koja je
unsigned char?
Koja je
Pitanje 6.2.5.
iz
sk
o
Pitanje 6.2.6.
Pitanje 6.2.7.
ro
n
Pitanje 6.2.8.
short int,
int,
da li se podrazumeva da je
kt
Pitanje 6.2.9.
le
Pitanje 6.2.10.
(a)
char
(b)
int
(c)
short int
(d)
unsigned long
Pitanje 6.2.11.
Pitanje 6.2.12.
double?
float
109
ili
a.
razliitim konstantama. Za sve konstante i za sve izraze, pravilima jezika jednoznano su odreeni njihovi tipovi.
(2
01
5)
vano jer od tih tipova moe zavisiti vrednost sloenog izraza u kojem figurie
konstanta ili neki podizraz. Od tipova konstanti i izraza zavisi i koje operacije
je mogue primeniti nad njima. Tipovi konstanti i izraza su neophodni i da bi
6.3.1
Celobrojne konstante
je
an
su tipa
iz
sk
o
jer se
ro
n
2147483647 -2147483648
2147483647
unsigned long,
int,
dok se
2147483648
%d.
tumai
to ne odgovara formatu
kt
unsigned,
ili
U.
le
stante bi
long, onda se na
long, 12345 je
je tipa
int,
12345ul
je
0,
primer, broj
zapis),
31
0x ili 0X. Na
31 (dekadni
-123
110
123).
6.3.2
+123
je isto
123.4)
(2
01
5)
Karakterske konstante
Iako se tip
char
an
6.3.3
je
iz
ruljivo. Umesto toga, preporuuje se korienje karakterskih konstanti. Karakterske konstante u programskom jeziku C se navode izmeu
navodnika.
terska konstanta
vrednou 0),
sk
o
ro
n
le
kt
char c = a;
char c = 97; /* ekvivalentno prethodnom (na ASCII masinama),
ali se ne preporucuje zbog toga sto smanjuje
citljivost i prenosivost programa */
tipa
char
ab),
Jezik C razlikuje
111
(2
01
5)
\a
\b
\f
\n
\r
\t
\v
\\
\?
\
\"
\ooo
\xhh
question mark
single quote
(npr.
(npr.
\012)
\x12)
double quote
octal number
hexadecimal number
Karakterska konstanta
Ovaj
je
karakter ima specijalnu ulogu u programskom jeziku C jer se koristi za oznaavanje kraja niske karaktera (o emu e vie biti rei u nastavku).
Iako je
an
\0
iz
Konstantni izrazi
ro
n
6.3.4
sk
o
karakterska promenljiva
4 + 3*5).
kt
le
Pitanje 6.3.1.
Pitanje 6.3.2.
Pitanje 6.3.3.
Y.
;.
x, tako da ima
Pitanje 6.3.4.
FFFFFFFF.
101110101101010011100110?
112
Pitanje 6.3.5.
3.4 i 3.4f?
Pitanje 6.3.6.
Pitanje 6.3.7.
0123,
a koja izmeu
1234 (b) .
3u (i) 0
(a)
(h)
123
(c)
6423ul
(d)
12.3e-2
(e)
3.74e+2f
0x47
(g)
0543
0x20 + 020 + 2 - 0
Pitanje 6.3.8.
(f )
(2
01
5)
konstanti
sledei C kd:
je
an
Izrazi se u programskom jeziku C grade od konstanti i promenjivih primenom irokog spektra operatora. Osim od konstanti i promenljivih, elemen-
tarni izrazi se mogu dobiti i kao rezultat poziva funkcija, operacija pristupa
elementima nizova, struktura i slino.
iz
sk
o
ro
n
kada se navode pre operanda i postfiksni kada se navode nakon svog operanda.
Binarni operatori imaju dva operanda i obino su infiksni tj. navode se izmeu
svojih operanda. U jeziku C postoji jedan ternarni operator koji se primenjuje
kt
na tri operanda.
le
+ pre njihovog sabiranja, pa nije prof i g e biti prva pozvana prilikom izraunavanja izraza
f() + g().
6.4.1
se koriste da bi
odredile kojim redosledom ih treba primenjivati. Ipak, slino kao i u matematici, postoje konvencije koje omoguavaju izostavljanje zagrada. Jedna od osnovnih takvih konvencija je prioritet operatora koji definie kojim redosledom
113
23,
bie
jer operator
+.
3 + 4 * 5
Semantika jezika
(2
01
5)
iteta:
1. Unarni operatori imaju vei prioritet u odnosu na binarne.
je
an
Obino se razlikuju
leva asocijativnost, kada se izraz izraunava sleva na desno i desna asocijativnost, kada se izraz izraunava zdesna na levo. Neki jezici razlikuju i neaso-
iz
sk
o
+ ( + ) = ( + ) + .
Zbog naina
+) nisu uvek
(INT_MIN + INT_MAX) + 1 ima vrednost 0 bez
izraz INT_MIN + (INT_MAX + 1) ima vrednost 0,
ro
n
- ima
1 - 2 - 3 je -4 (a ne 2, to bi
ega je jasno da - nije asocijativan
kt
le
u tabeli u dodatku A.
6.4.2
Operator dodele
Operatorom dodele se neka vrednost pridruuje datoj promenljivoj. Operator dodele se zapisuje
7 INT_MIN
=.
datoteci zaglavlja
int
Na primer,
na konkretnom sistemu.
114
broj_studenata = 80;
broj_grupa
= 2;
U dodeljivanju vrednosti, sa leve strane operatora dodele moe da se nalazi
promenljiva, a bie diskutovano kasnije, i element niza ili memorijska lokacija.
Ti objekti, objekti kojima moe biti dodeljena vrednost nazivaju se l-vrednosti
(2
01
5)
Tip izraza dodele je tip leve strane, a vrednost izraza dodele je vrednost koja
e biti dodeljena levoj strani (to nije uvek vrednost koju ima desna strana).
Promena vrednosti objekta na levoj strani je propratni (boni, sporedni) efekat
(engl. side effect) do kojeg dolazi prilikom izraunavanja vrednosti izraza. Na
je
an
izraza
sk
o
x = y = z = 0;
6.4.3
0:
x, y i z
iz
tri promenljive
Aritmetiki operatori
ro
n
le
kt
unarni operator.
Operator
operanada.
8 Na
mentirane nezavisno i u izvrnom programu koristi se jedna od njih, izabrana u fazi prevoenja u zavisnosti od tipova operanada. Informacije o tipovima iz izvornog programa su
115
Na primer, izraz
9.0/5.0 ima vrednost 1.8 (jer se koristi deljenje brojeva u pokretnom zarezu).
U sluaju da je jedan od operanada ceo broj, a drugi broj u pokretnom zarezu,
vri se implicitna konverzija celobrojnog operanda u broj u pokretnom zarezu
bie u poglavlju 6.5).
Prefiksni unarni operatori
od svih binarnih operatora.
prioriteta binarnih operatora
Operatori
+ i -.
(2
01
5)
*, /
asocijativnost.
Inkrementiranje i dekrementiranje.
je
U programi-
++,
(uveavanja za 1) zapisuje se sa
--:
za 1) zapisuje se sa
an
dekrementiranjem umanjivanje za 1.
--
sk
o
iz
++
5++
ro
n
izraz
le
kt
primer,
5,
n.
ima vrednost
onda
x = n++;
dodeljuje promenljivoj
vrednost
5,
x = ++n;
na ovaj, ali i na druge sline naine, upotrebljene tokom prevoenja i one se ne uvaju u
izvrnom programu.
116
dodeljuje promenljivoj
6.
nost
vrednost
6.
Promenljiva
Slino, kd
(2
01
5)
a = 4, b = 4, x = 3, y = 4
Ukoliko ne postoji iri kontekst, tj. ako inkrementiranje ini itavu naredbu,
vrednost izraza se i ne koristi i onda nema razlike izmeu naredbe
an
int a = 3, b = 3;
a++; ++b;
printf("a = %d, b = %d\n", a, b);
n++; i ++n;.
je
Na primer,
prethodni kd ispisuje
iz
a = 4, b = 4
sk
o
,)
bolom
;),
dok operator
+ to
ro
n
sa
take, ali za to ne postoji garancija, tako neto zavisi od konkretne implementacije (od kompilatora) i na to se ne treba oslanjati. Na primer, naredni
kd
le
kt
ispisuje
a = 5, x = 3, y = 4,
b = 5, z = 6
Zaista,
9 Precizan
(vrednost
3).
Poto je zarez
prima uveanu
117
a (vrednost 4). Drugo uveanje promenljive a (na vred5 vri se na kraju deklaracije sa inicijalizacijama, tj. na mestu oznaenom
vrednost promenljive
nost
sa
;).
(vrednost
3),
jer
ne oz-
(2
01
5)
6.4.4
Relacijski operatori.
jednako;
!=
razliito.
>
an
==
je
<
iz
>=
vee;
manje;
manje ili jednako;
sk
o
<=
<, <=, > i >= imaju isti prioritet i to vii od op!= i svi imaju levu asocijativnost. Rezultat
relacionog operatora primenjenog nad dva broja je vrednost 0 (koja odgovara
istinitosnoj vrednosti netano) ili vrednost 1 (koja odgovara istinitosnoj vrednosti netano). Na primer, izraz 3 > 5 ima vrednost 0, a izraz 7 < 5 != 1
je isto to i (7 < 5) != 1 i ima vrednost 1 jer izraz 7 < 5 ima vrednost 0,
to je razliito od 1. Ako promenljiva x ima vrednost 2, izraz 3 < x < 5 ima
vrednost 1 (tano) to je razliito od moda oekivane vrednosti 0 (netano) jer
2 nije izmeu 3 i 5. Naime, izraz se izraunava sleva na desno, podizraz 3 < x
ima vrednost 0, a zatim izraz 0 < 5 ima vrednost 1. Kako u ovakvim sluaRelacijski operatori poretka
==
i razliitosti
le
kt
ro
n
eratora jednakosti
&&.
==
118
Logiki operatori.
int.
0, onda je njegova
0 (netano), a inae je njegova logika vrednost 1 (tano). Iako
su sve vrednosti operanada koje su razliite od 0 doputene i tumae se kao
tano, rezultat izraunavanja tano nije proizvoljna vrednost razliita od 0, ve
iskljuivo vrednost 1.
(2
01
5)
&&
logika konjunkcija i;
||
Operator
&&
||,
a oba su levo
je
an
vrednost izraza
5 && 4.3
vrednost izraza
10.2 || 0
vrednost izraza
0 && 5
vrednost izraza
!1
vrednost izraza
!9.2
vrednost izraza
!0
vrednost izraza
!(2>3)
irazom
d
1;
iz
jednaka je
sk
o
jednaka je
jednaka je
0;
1;
jednaka je
0;
0;
1;
kt
izraz
1;
jednaka je
jednaka je
ro
n
izmeu
jednaka je
ekvivalentan je izrazu
le
izrazom
proverava se
da li je godina
Lenjo izraunavanje.
Osnovna karakteris-
119
nakon izraunavanja vrednosti navedenog izraza. S druge strane, nakon izraunavanja vrednosti izraza
(2
01
5)
1<2 || a++_
a,
a nakon
an
2<1 || a++
iz
Bitovski operatori
a.
6.4.5
je
sk
o
&
bitovska konjunkcija;
bitovska disjunkcija;
kt
le
ro
n
tivan.
&
|.
levu asocijativnost.
& bitovsko
-tih
bitova argumenata).
tipa
x1
x2
unsigned char i ukoliko je vrednost promenljive x1 jednaka 74, a promenljive x2 jednaka 87, vrednost izraza x1 & x2 jednaka je 66. Naime,
120
broj
74
01001010,
66.
| bitovsko
(2
01
5)
x2
bitovsko
x1 | x2
je
01011111,
0x5F.
jedinini komplement
x1 ^ x2
je
00011101,
Za brojeve iz tekueg
0x1D.
je
u tekuem primeru je
10110101,
tj.
B5,
tj.
181.
~x1
an
iz
argumenta se pomeraju u levo za broj pozicija naveden kao drugi argument. Poetni bitovi prvog argumenta se zanemaruju, dok se na zavrna
mesta rezultata upisuju nule.
x ima tip
unsigned char i vrednost 0x95, tj. 10010101, vrednost izraza x << 1 je
00101010, tj. 0x2A.
Na primer, ukoliko promenljiva
sk
o
ro
n
kt
le
pomeranje ).
Ukoliko je ar-
a &= 1
a = a & 1.
121
vrednost izraza
1 & 2
jednaka
Na primer,
je vrednost izraza
Vie rei o upotrebi bitovskih operatora kao i primeri programa bie dati u
drugom tomu ove knjige.
(2
01
5)
6.4.6
i = i + 2; moe se zapisati
x = x * (y+1); ima isto dejstvo kao i
x *= y+1;.
i += 2;.
Slino, naredba
tori dodele:
je
Operatori dodele imaju nii prioritet od svih ostalih operatora i desnu aso-
an
cijativnost.
Izraunavanje vrednosti izraza
iz
gde je
op
sk
o
ro
n
kt
obliku).
le
Program 6.3.
#include <stdio.h>
int main() {
unsigned char c = 254;
10 Na
promenljiva
a[i++] += 1 (a[i]
oznaava
poziva vraa razliite vrednosti. Funkcije i nizovi su detaljnije opisani u narednim glavama.
122
Izlaz programa:
6.4.7
(2
01
5)
c = 255
c = 0
Operator uslova
?:
je
izraz1
,.
an
dodela i operatora
izraz2
izraz3
i to je
i to je
iz
sk
o
m = (a > b) ? a : b
vrednost promenljive
b,
ro
n
m = (a < 0) ? -a : a
vrednost promenljive
a.
kt
le
n = 0;
x = (2 > 3) ? n++ : 9;
promenljiva
imae vrednost
9,
a promenljiva
e zadrati vrednost
jer se
6.4.8
Operator zarez
Binarni operator zarez (,) je operator kao i svaki drugi (najnieg je prioriteta od svih operatora u C-u) i prilikom izraunavanja vrednosti izraza
izgraenog njegovom primenom, izraunavaju se oba operanda, pri emu se
vrednost celokupnog izraza definie kao vrednost desnog operanda (ta vred-
123
nost se esto zanemaruje). Ovaj operator se esto koristi samo da spoji dva
izraza u jedinstveni (da bi se takav sloeni izraz mogao upotrebiti na mestima
gde sintaksa zahteva navoenje jednog izraza). To je najee u inicijalizaciji i
koraku
Jo jedna od estih
(2
01
5)
x = 3, y = 5; /* ekivalentno bi bilo i x = 3; y = 5; */
, od zareza koji razdvajaju promenljive prilikom
elementu na poziciji
6.4.9
(1, 2)
je
je
Operator sizeof
an
A[2],
Veliinu u bajtovima koju zauzima neki tip ili neka promenljiva mogue
je odrediti korienjem operatora
int
sizeof.
Tako,
sizeof(int)
predstavlja
veliinu tipa
iz
najee 4.
sizeof
ima tip
size_t.
Ovo je neoznaen
size_t
sk
o
Tip
unsigned int
(standard C99
ro
n
Pitanje 6.4.2.
kt
Pitanje 6.4.1.
operatore.
Pitanje 6.4.4.
le
Pitanje 6.4.3.
Pitanje 6.4.5.
Pitanje 6.4.6.
operatora?
Pitanje 6.4.7.
tora?
Pitanje 6.4.8.
eratora?
124
Pitanje 6.4.9.
Pitanje 6.4.10.
izvravanja kda:
Pitanje 6.4.11.
(2
01
5)
je
3+4*5+7 (3+(4*5))+7).
(a) a = b = 4 (b) a = 3 == 5 (c) c = 3 == 5 + 7 <= 4
(d) 3 - 4 / 2 < 3 && 4 + 5 * 6 <= 3 % 7 * 2
(e) a = b < c ? 3 * 5 : 4 < 7, 2 (f ) a = b + c && d != e
Pitanje 6.4.12.
an
iz
3
(e) 3
(k) 3
(j) 3
(a)
Pitanje 6.4.13.
Da li su definisana deljenja
Pitanje 6.4.14.
(a)
2++ (b) a++ (c) 2** (d) a** (e) 2>>2 (f ) a>>2 (g) a &&= 0 (e) a ||= -7
naredbi:
ro
n
Pitanje 6.4.15.
a promenljiva
a promenljiva
kt
1.
ima vrednost
1,
le
2.
sk
o
nost:
1/0 i 1.0/0.0?
3.
4.
5.
6.
7.
Pitanje 6.4.16.
Navesti primere.
ta znai to da se operatori
&&, ||
?:
izraunavaju lenjo?
125
Pitanje 6.4.17.
int a = 3, b = 0, c, d;
c = a % 2 || b++;
d = a % 3 || b++;
printf("%d %d %d %d", a, b, c, d);
(2
01
5)
Pitanje 6.4.18.
prestupna.
a i b.
samoglasnik.
je
a.
c malo
p q.
c malo slovo ima vrednost odgovarajueg velikog
vrednost c.
Zadatak 6.4.1.
an
iz
sk
o
Zadatak 6.4.2.
Zadatak 6.4.3.
ro
n
cifrenog broja.
Zadatak 6.4.4.
kt
1234
1243.
Napisati program koji ciklino u levo rotira poslednje tri cifre unetog prirodnog
le
Zadatak 6.4.5.
12345
12453.
nava koji je po redu taj par u cik-cak nabrajanju datom na slici 3.1. Napisati i
program koji za dati redni broj u cik-cak nabrajanju odreuje odgovarajui par
prirodnih brojeva.
Zadatak 6.4.6.
reenje jednaine
+ = 0.
Zadatak 6.4.7.
2
izraunava
1 , 1 , 1 , 2 , 2
1 + 1 = 1 , 2 + 2 = 2 .
Program treba da prijavi ukoliko sistem nema reenja ili ima vie od jednog
reenja.
126
Zadatak 6.4.8.
( =
0)
2
jednaine + + = 0.
Napisati program koji ispisuje sve delioce unetog neoznaenog
24).
Zadatak 6.4.10.
24
treeni delioci su
1, 2, 3, 4, 6, 8, 12i
(2
01
5)
Zadatak 6.4.9.
getchar,
putchar)
je
a za ispis funkciju
Konverzija tipova predstavlja pretvaranje vrednosti jednog tipa u vredJezik C je veoma fleksibilan po pitanju konverzije tipova
an
iz
programa i omoguilo meanje podataka razliitih tipova u okviru istog programa, konverzije mogu dovesti i do gubitka podataka ili njihove loe inter-
sk
o
pretacije. Jezik C je statiki tipiziran, pa, iako se prilikom konverzija konvertuju vrednosti izraza, promenljive sve vreme ostaju da budu onog tipa koji im
6.5.1
ro
n
je pridruen deklaracijom.
Vrste konverzija
kt
le
11
float a=4;
11 C
127
float f = 16777217;
printf("%f\n", f);
obino (tj. na velikom broju konkretnih sistema) ispisuje
16777216.00000
16777217.0 ne moe da se zapie u okviru tipa float ako on koristi
float za zapis mantise koristi
(2
01
5)
jer vrednost
tri bajta, tj. dvadeset etiri binarne cifre i moe da reprezentuje sve pozitivne
celobrojne vrednosti do
je
24
+1
224
konverzije u
float
long
short, double
int).
je
an
sk
o
iz
ro
n
7.7f
konvertovano u
7,
a ne u
kt
8).
le
tip oznaen, konverzija u iri tip se vri proirivanjem vodeeg bita (engl. sign
tom prilikom takoe dolazi do implicitne konverzije. S obzirom na to da standard ne definie da li je tip
char
128
char
(2
01
5)
6.5.2
Eksplicitne konverzije
je
Operator eksplicitne konverzije tipa ili operator kastovanja (engl. type cast
operator) se navodi tako to se ime rezultujueg tipa navodi u malim zagradama
an
(tip)izraz
iz
sk
o
Na
ro
n
pokretnom zarezu:
3.250000
le
kt
int a = 13, b = 4;
printf("%d\t", a/b);
printf("%f\n", (double)a/(double)b);
to je izraz
a/b
printf
upotrebljen je format
%f
umesto
%d,
%d,
zbog toga
naravno, ne utie
double
i u tom sluaju bi se
6.5.3
Implicitne konverzije
129
int a;
double b = (a = 3.5);
a, vri se konverzija
int, a zatim se, prilikom dodele prou double vrednost 3.0.
menljivoj
b,
(2
01
5)
double
-, *, /)
i relacijskih binarnih
je
operatora (<,
?:.
char
short
an
12 .
int.
Ovo se naziva
iz
ro
n
sk
o
le
kt
pravila konverzije:
1. Ako je bar jedan od operanada tipa
tuje u
long double;
long double,
double;
12 Celobrojna
double,
int
vrednosti vri jednostavnim upisivanjem u registre. Procesori obino nemaju mainske instrukcije za rad sa kraim tipovima podataka i operacije nad kraim tipovima podataka
(sluaj u kojem se ne bi vrila celobrojna promocija) zapravo bi bilo tee ostvariti.
130
float,
float;
char i short
long long;
promoviu se u
int.
long long,
long,
(2
01
5)
long.
U sluaju korienja neoznaenih operanada (tj. meanja oznaenih i neoznaenih operanada), pravila konverzije su neto komplikovanija:
je
2. inae, ako je tip oznaenog operanda takav da moe da predstavi sve vrednosti neoznaenog tipa, tada se neoznaeni tip prevodi u iri, oznaeni.
an
enom tipu.
int
zauzima 16 bitova, a
iz
Na primer, ako
signed long
sk
o
ro
n
vai da je
kt
le
signed
si = /* neka vrednost */;
unsigned ui = /* neka vrednost */;
/* if (si < ui) - ne daje uvek korektan rezultat */
if (si < 0 || (unsigned)si < ui) {
...
}
13 Preciznije,
131
Na koji
celobrojnu vrednost?
Pitanje 6.5.2.
(2
01
5)
verzija su promocije, a koje democije: (a) int u short, (b) char u float, (c)
double u long, (d) long u int?
Pitanje 6.5.3.
operatora.
Pitanje 6.5.4.
Pitanje 6.5.5.
konvertuju
iz
nije ni tipa
an
je
Pitanje 6.5.6.
sk
o
tipa
float
nakon naredbe
x = (x = 3/2);?
2. Ako promenljiva
ima tip
ro
n
c = 1.5 * c;?
char,
x tipa float
x = 3/2 + (double)3/2 + 3.0/2;?
kt
4. Ako je promenljiva
nakon naredbe:
le
ima
tipa
iic
koju vrednost
nakon naredbi
Pitanje 6.5.7.
nakon naredbe
Pitanje 6.5.8.
Da li nakon naredbe
tip
tip
char,
tip
tip
int,
tip
tip
float?
132
6.6.1
(2
01
5)
je
Program 6.4.
an
#include <stdio.h>
sk
o
iz
int main() {
int b0, b1, b2, b3, b4, b5, b6, b7, b8, b9;
scanf("%d%d%d%d%d%d%d%d%d%d",
&b0, &b1, &b2, &b3, &b4, &b5, &b6, &b7, &b8, &b9);
printf("%d %d %d %d %d %d %d %d %d %d",
b9, b8, b7, b6, b5, b4, b3, b2, b1, b0);
}
ro
n
1 2 3 4 5 6 7 8 9 10
10 9 8 7 6 5 4 3 2 1
kt
Program 6.5.
le
#include <stdio.h>
int main() {
int b[10], i;
for (i = 0; i < 10; i++)
scanf("%d", &b[i]);
for (i = 9; i >= 0; i--)
printf("%d ", b[i]);
return 0;
}
133
6.6.2
Deklaracija niza
tip ime_niza[dimenzija];
Dimenzija predstavlja broj elemenata niza. Na primer, deklaracija
uvodi niz
a od 10 celih brojeva.
(2
01
5)
int a[10];
niza:
a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9]
Indeksi niza su obino nenegativni celi brojevi (mada je u nekim prilikama kada
je
an
int a[5] = { 1, 2, 3, 4, 5 };
jednak je:
iz
sk
o
Veliina memorijskog prostora potrebnog za niz odreuje se u fazi prevoenja programa, pa broj elemenata niza (koji se navodi u deklaraciji) mora
ro
n
bic
neispravne
14 :
a je ispravna, dok
le
kt
int x;
char a[100+10];
int b[];
float c[x];
14 Standardi
nakon C99 uvode pojam niza promenljive duine (engl. variable length array,
134
int b[] = { 1, 2, 3 };
sadraj niza
jednak je:
sizeof
(2
01
5)
Kada se operator
bajtovima.
an
je
a[2*2+1]
a[i+2]
iz
a[-1]
a[13], pa
sk
o
ro
n
vrednosti). Meutim, nizovi nisu l-vrednosti i nije im mogue dodeljivati vrednosti niti ih menjati. To ilustruje sledei primer:
le
kt
6.6.3
Niske
Posebno mesto u programskom jeziku C zauzimaju nizovi koji sadre karaktere niske karaktera ili krae niske (engl. strings ). Konstantne niske navode
se izmeu dvostrukih navodnika (na primer,
U okviru niski,
15 U
fazi izvravanja, operativni sistem obino proverava da li se pokuava upis van memo-
rije koja je dodeljena programu i ako je to sluaj, obino nasilno prekida izvravanje programa
(npr. uz poruku
segmentation fault).
135
nulom (engl.
\0,
16 .
(2
01
5)
a sadraj nizova
0
r a v
s2 i s3 jednak je:
je
jednak je:
an
s1
Z d r a v o \0
Niz s1 sadri 6 karaktera (i zauzima 6 bajtova).
Deklaracije za
s2
s3
iz
x)
"x" koja sadri
sk
o
x i \0).
ro
n
kt
je ekvivaletno sa
le
printf("Zdravo, svima");
strlen
string.h.
Na primer, funkcija
16 Neki
Na primer,
u Pascal-u se pre samog sadraja niske zapisuju broj koji predstavlja njenu duinu (tzv. Pniske).
136
int i = 0;
while (s[i] != \0)
i++;
Kd koji obrauju niske obino ih obrauje karakter po karakter i obino
sadri petlju oblika:
(2
01
5)
je
an
iz
strlen
za izrauna-
sk
o
u nisku
ro
n
strcpy
velika da primi nisku koja se dodeljuje. Ako to nije ispunjeno, vri se promena
kt
le
po karakter niske
src
int i = 0;
while ((dest[i] = src[i]) != \0)
i++;
for
petlja:
int i;
for (i = 0; dest[i] = src[i]; i++)
;
/* prazno telo petlje */
137
6.6.4
Viedimenzioni nizovi
tip ime_niza[dimenzija_1]...[dimenzija_2];
(2
01
5)
ime_niza[vrsta][kolona]
a ne sa
ime_niza[vrsta, kolona]
je
an
iz
sk
o
char a[2][3] = {
{1, 2, 3},
{4, 5, 6}
};
ro
n
le
kt
char a[][3] = {
{1, 2, 3},
{4, 5, 6}
};
17
Razmotrimo, kao dodatni primer, dvodimenzioni niz koji sadri broj dana
za svaki mesec, pri emu su u prvoj vrsti vrednosti za obine, a u drugoj vrsti
za prestupne godine:
17 Nekada
smeste u jednodimenzioni niz, ali, poto jezik doputa korienje viedimenzionih nizova, za
ovim nema potrebe.
138
char broj_dana[][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}
};
Za skladitenje malih prirodnih brojeva koristi se tip
(2
01
5)
je
prestupna
an
vrednost
iz
Pitanje 6.6.1.
tipa
int
koji za
bude
zdravo
i to:
sk
o
Pitanje 6.6.2.
izraza
Ukoliko je niz
ro
n
Pitanje 6.6.3.
sizeof(a)?
Pitanje 6.6.4.
Ako je niz
float
kt
le
Pitanje 6.6.5.
ziju?
Pitanje 6.6.6.
int a[];
int b[] = {1, 2, 3};
int c[5] = {1, 2, 3};
int d[2] = {1, 2, 3};
c = b;
b++;
139
Pitanje 6.6.7.
tricu
Pitanje 6.6.8.
1
4
2
5
1
3
5
Zadatak 6.6.1.
2
4 .
6
(2
01
5)
tricu
zatim i
3
6
an
.).
Zadatak 6.6.2.
iz
(tj. karakter
je
( < 1000),
Zadatak 6.6.3.
sk
o
ro
n
Zadatak 6.6.4.
redova trougla (
< 100).
()
. Napisati
Na primer, za = 6
1
2
3
4
5
le
1
1
1
1
1
1
kt
ispisuje se:
1
3 1
6 4 1
10 10 5 1
0 = = 1, kao da se svaki
unutranji lan trougla moe dobiti kao zbir odgovarajua dva lana prethodne
() (1) (1)
Zadatak 6.6.5.
ziju matrice (
()
( )
< 10)
140
4
1
5
9
4
2
6
1
5
3
7
2
6
4
8
3
7
Program izraunava i ispisuje sumu elemenata glavne dijagonale i sumu elematrice navedene u primeru je
je
1 + 6 + 2 + 7 = 16,
(2
01
5)
1 + 2 + 3 + 5 + 6 + 9 = 26
Zadatak 6.6.6.
ziju matrice (
< 100)
0
6
1
5
0
0
2
6
0
0
0
7
1
5
9
4
an
je
iz
sk
o
Programski jezik C ima svega nekoliko ugraenih osnovnih tipova. Ve nizovi i niske predstavljaju sloene tipove podataka.
ro
n
nekoliko naina izgradnje sloenih tipova podataka. Promenljive se mogu organizovati u strukture (tj. slogove ), pogodne za specifine potrebe.
Na taj
nain se povezane vrednosti (ne nuno istog tipa) tretiraju kao jedna celina
kt
i za razliku od nizova gde se pristup pojedinanim vrednostima vri na osnovu brojevnog indeksa, pristup pojedinanim vrednostima vri se na osnovu
imena polja strukture. Pored struktura, mogu se koristiti unije, koje su sline
le
strukturama, ali kod kojih se jedan isti memorijski prostor koristi za vie pro-
6.7.1
Strukture
Osnovni tipovi jezika C esto nisu dovoljni za pogodno opisivanje svih podataka u programu. Ukoliko je neki podatak sloene prirode tj. sastoji se od
vie delova, ti njegovi pojedinani delovi mogu se uvati nezavisno (u zasebnim
promenljivama), ali to esto vodi programima koji su nejasni i teki za odravanje. Umesto toga, pogodnije je koristiti strukture. Za razliku od nizova koji
objedinjuju jednu ili vie promenljivh istog tipa, struktura objedinjuje jednu ili
141
brojilac, a
razlomak moe se
imenilac.
Struktura
(2
01
5)
struct razlomak {
int brojilac;
int imenilac;
};
struct zapoinje definiciju strukture.
je
Kljuna re
an
strukture, a zatim, izmeu vitiastih zagrada, opis njenih lanova (ili polja).
Imena lanova strukture se ne mogu koristiti kao samostalne promenljive, one
postoje samo kao deo sloenijeg objekta.
struct razlomak,
ali ne i promenljive
iz
tog tipa.
ro
n
sk
o
struct student {
char ime[50];
float prosek;
};
Strukture mogu biti ugnjedene, tj. lanovi struktura mogu biti druge struk-
kt
ture. Na primer:
le
struct dvojni_razlomak {
struct razlomak gore;
struct razlomak dole;
};
Definicija strukture uvodi novi tip i nakon nje se ovaj tip moe koristiti
kao i bilo koji drugi. Definicija strukture se obino navodi van svih funkcija.
Ukoliko je navedena u okviru funkcije, onda se moe koristiti samo u okviru
te funkcije. Prilikom deklarisanja promenljivih ovog tipa, kao deo imena tipa,
neophodno je korienje kljune rei
struct razlomak a, b, c;
struct,
na primer:
142
Definicijom strukture je opisano da se razlomci sastoje od brojioca i imenioca, dok se navedenom deklaracijom uvode tri konkretna razlomka koja se
nazivaju
a, b i c.
(2
01
5)
struct razlomak a = { 1, 2 };
Redosled navoenja inicijalizatora odgovara redosledu navoenja lanova
strukture. Dakle, navedenom deklaracijom je uveden razlomak
1,
a imenilac
2.
a iji je brojilac
an
je
struct razlomak {
int brojilac;
int imenilac;
} a = {1, 2}, b, c;
iz
sk
o
a.imenilac
ro
n
.,
kt
le
pa je naredni kd korektan.
Od ranije prikazanih operacija, nad promenljivama tipa strukture dozvoljene su operacije dodele a nisu dozvoljeni aritmetiki i relacijski operatori.
Operator
sizeof
ljive tog tipa i u oba sluaja dobija se broj bajtova koje struktura zauzima u
memoriji. Napomenimo da taj broj moe nekada biti i vei od zbira veliina
pojedinanih polja, jer se zbog uslova poravnanja (engl. alignment), o kojem e
vie biti rei u glavi 10, ponekad izmeu dva uzastopna polja strukture ostavlja
prazan prostor.
143
Nizovi struktura
esto postoji povezana skupina sloenih podataka. Umesto da se oni uvaju
u nezavisnim nizovima (to bi vodilo programima tekim za odravanje) bolje je
koristiti nizove struktura. Na primer, ako je potrebno imati podatke o imenima
i broju dana meseci u godini, mogue je te podatke uvati u nizu sa brojevima
dana i u (nezavisnom) nizu imena meseci. Bolje je, meutim, opisati strukturu
(2
01
5)
struct opis_meseca {
char ime[10];
int broj_dana;
};
i koristiti niz ovakvih struktura:
13
an
je
iz
18 :
kt
ro
n
sk
o
le
meseci[1].ime,
18 U
meseci[1].broj_dana
itd.
144
sizeof(meseci)/sizeof(struct opis_meseca)
Unije
(2
01
5)
6.7.2
odgovara zbiru veliina njenih polja, dok veliina unije odgovara veliini njenog
najveeg polja. Osnovna svrha unija je uteda memorije.
struct
je
koristi kljuna re
an
union).
iz
sk
o
union vreme {
int obicno;
float precizno;
};
ro
n
kt
union vreme a;
a.obicno = 17;
Unije se esto koriste i kao lanovi struktura. Neka se, na primer, u pro-
le
gramu uvaju i obrauju informacije o studetima i zaposlenima na nekom fakultetu. Za svakoga se uva ime, prezime i matini broj, za zaposlene se jo uva
struct akademac {
char ime_i_prezime[50];
char jmbg[14];
char vrsta;
union {
double plata;
char indeks[7];
} dodatno;
};
145
vrsta
lan strukture
tipa
s).
Promenljive
plata
indeks
(2
01
5)
int main() {
struct akademac pera = {"Pera Peric", "0101970810001", z};
pera.dodatno.plata = 56789.5;
printf("%f\n", pera.dodatno.plata);
struct akademac ana = {"Ana Anic", "1212992750501", s};
strcpy(ana.dodatno.indeks, "12/123");
printf("%s\n", ana.dodatno.indeks);
je
an
iz
6.7.3
ro
n
sk
o
Polja bitova
kt
char
koji za-
le
struct osobine_pravougaonika {
unsigned char popunjen
unsigned char boja
: 1;
: 3;
146
};
: 2;
sizeof(struct osobine_pravougaonika))
samo 6 bitova, svaki podatak mora da zauzima ceo broj bajtova, tako da je
(2
01
5)
odvojen 1 bit vie nego sto je potrebno). Da je u pitanju bila obina struktura,
zauzimala bi 3 bajta.
...
#define ZELENA
...
#define PUN 00
02
6.7.4
iz
an
je
sk
o
U nekim sluajevima korisno je definisati tip podataka koji ima mali skup
doputenih vrednosti. Ovakvi tipovi se nazivaju nabrojivi tipovi . U jeziku C
nabrojivi tipove se definiu korienjem kljune rei
enum.
Na primer:
le
kt
ro
n
enum znak_karte {
KARO,
PIK,
HERC,
TREF
};
PIK
vrednost 1,
HERC
U navedenom primeru,
vrednost 2 i
TREF
vrednost 3.
enum znak_karte {
KARO = 1,
PIK = 2,
HERC = 4,
KARO
ima vrednost 0,
Mogue je i eksplicitno
147
};
TREF = 8
#define
enum).
(2
01
5)
ali u tom sluaju ta imena ne ine jedan tip (kao u sluaju da se koristi
Slino kao i kod struktura i unija, uz definiciju tipa mogue je odmah deklarisati i promenljive.
enum).
Na primer,
je
iz
struct karta {
unsigned char broj;
enum znak_karte znak;
} mala_dvojka = {2, TREF};
an
sk
o
programa, ukoliko funkcije vraaju (razliite) vrednosti koje su opisane nabrojivim tipom (i imenima koja odgovaraju pojedinim povratnim vrednostim) nego
ro
n
konkretne brojeve. Tako, na primer, tip povratne vrednosti neke funkcije moe
da bude nabrojiv tip definisan na sledei nain:
le
kt
enum return_type {
OK,
FileError,
MemoryError,
TimeOut
};
6.7.5
Typedef
typedef.
Na primer, deklaracija
148
Length
uvodi ime
int.
Ime tipa
Length
se onda moe
int:
to se koristi ime
typedef.
(2
01
5)
typedef
typedef
struct
an
d
struct point {
int x, y;
};
typedef struct point Point;
je
iz
Point a, b;
sk
o
ro
n
kt
Point a, b;
Deklaracija
typedef
#define
(videti
le
uvodi ime
i vraa
149
Osim estetskih razloga, postoje dve osnovne svrhe za korienje kljune rei
typedef
typedef
koristi za uvoenje
short, int
long
typedef
typedef
deklaracije. Jedan od
u zavisnosti od maine.
Point
Definisati strukturu
Pitanje 6.7.2.
Definisati strukturu
typedef
complex
se jednostavnije
(2
01
5)
primera je korienje
student
double.
je
Pitanje 6.7.3.
an
Pitanje 6.7.4.
iz
datum.
Pitanje 6.7.5.
sk
o
Data je struktura:
ro
n
struct tacka {
int a, b;
char naziv[5];
}
naziv.
kt
jeno ime
le
Pitanje 6.7.7.
Pitanje 6.7.6.
C-u?
NoviTip?
Pitanje 6.7.8.
Pitanje 6.7.9.
jedan lan tipa
int
Zadatak 6.7.1.
real
za tip
novitip
float.
double.
koji odgovara strukturi koji ima
complex
.
150
Zadatak 6.7.2.
le
kt
ro
n
sk
o
iz
an
je
(2
01
5)
(2
01
5)
Glava 7
je
an
naredbe grananja i petlje. Iako u jeziku C postoji i naredba skoka (goto), ona
nee biti opisivana, jer esto dovodi do loe strukturiranih programa, neitljivih
se napisati i bez nje.
iz
goto moe
if) i jedna
while), ali se u programima esto koriste i druge
sk
o
naredbe za kontrolu toka radi bolje itljivosti kda. Iako mogu da postoje opte
preporuke za pisanje kda jednostavnog za razumevanje i odravanje, izbor
ro
n
kt
le
izraza (ova vrsta naredbi obuhvata i naredbu dodele i naredbu poziva funkcije).
Naime, svaki izraz zavren karakterom
; je naredba.
=, ++, +=
3 + 4*5;
n = 3;
c++;
f();
151
152
Iako su sve etiri navedene naredbe ispravne i sve predstavljaju naredbe izraza,
prva naredba ne proizvodi nikakav efekat i nema semantiko opravdanje pa se
retko sree u stvarnim programima. etvrta naredba predstavlja poziv funkcije
telo
for
; (na primer,
(2
01
5)
{i}
sloene naredbe tj. blokove i takvi blokovi se mogu koristiti na svim mestima
;.
je
jedan primer njihove upotrebe, ali one se, za grupisanje naredbi, koriste i u
drugim kontekstima. Doputeno je i da blok sadri samo jednu naredbu, ali
an
tada nema potrebe koristiti blok (izuzetak je definicija funkcije koja ne moe da
bude pojedinana naredba ve mora biti blok i telo naredbe
mora biti navedeno izmeu vitiastih zagrada). Svaki blok, na poetku moe
da sadri (mogue praznu) listu deklaracija promeljivih (koje se mogu koristiti
iz
samo u tom bloku). Vidljivost tj. oblast vaenja imena promenljivih odreena je
pravilima dosega (o emu e vie rei biti u poglavlju 9.2.2). Nakon deklaracija,
sk
o
navode se naredbe (elementarne ili sloene, tj. novi blokovi). Postoje razliite
konvencije za nazubljivanje vitiastih zagrada prilikom unosa izvornog kda.
ro
n
kt
Naredba
if-else
le
7.3.1
Naredba uslova
if
if (izraz)
naredba1
else
naredba2
naredba1 i naredba2 su ili pojedinane naredbe (kada se za;) ili blokovi naredbi zapisani izmeu vitiastih zagrada
(iza kojih se ne pie simbol ;).
Deo naredbe else je opcioni, tj. moe da postoji samo if grana. Izraz izraz
Naredba
vravaju simbolom
predstavlja logiki uslov i najee je u pitanju celobrojni izraz (ali moe biti i
izraz ija je vrednost broj u pokretnom zarezu) za koji se smatra, kao i uvek, da
153
je taan (tj. da je uslov ispunjen) ako ima ne-nula vrednost, a inae se smatra
da je netaan. Na primer, nakon naredbe
promenljiva
e imati vrednost
2,
e imati vrednost
1.
a nakon naredbe
promenljiva
je
if (7)
a = 1;
else
a = 2;
(2
01
5)
if (5 > 7)
a = 1;
else
a = 2;
Kako se ispituje istinitosna vrednost izraza koji je naveden kao uslov, ponekad
if (n != 0) je ekvivalentno sa
an
if (n).
iz
ro
n
sk
o
a = 3;
if (a = 0)
printf("a je nula\n");
else
printf("a nije nula\n");
a na nulu
a jednako 0), a zatim ispisuje tekst a nije nula, jer
je vrednost izraza a = 0 nula, to se smatra netanim. Zamena operatora ==
operatorom = u naredbi if je esta greka.
Naime, efekat ovog kda je da postavlja vrednost promenljive
kt
(a ne da ispita da li je
le
if-else vieznanost.
if.
if
else
if (izraz1)
if (izraz2)
naredba1
else
naredba2
se odnosi na drugo a ne
154
U narednom primeru,
else
if
7.3.2
Konstrukcija
(2
01
5)
if (izraz1) {
if (izraz2)
naredba1
} else
naredba2
else-if
iz
an
je
if (izraz1)
naredba1
else if (izraz2)
naredba2
else if (izraz3)
naredba3
else
naredba4
sk
o
ro
n
izraz3.
le
kt
if (a > 0)
printf("A je veci od nule\n");
else if (a < 0)
printf("A je manji od nule\n");
else /* if (a == 0) */
printf("A je nula\n");
7.3.3
Naredba
if-else
Naredna naredba
if (a > b)
x = a;
else
x = b;
i operator uslova
155
veu od vrednosti
a i b.
Naredba ovakvog
?:
(koji
x = (a > b) ? a : b;
Naredba
switch
(2
01
5)
Naredba
an
switch (izraz) {
case konstantan_izraz1: naredbe1
case konstantan_izraz2: naredbe2
...
default:
naredbe_n
}
je
7.3.4
izraz.
izraz
iz
sk
o
koje odgovaraju sledeim sluajevima iako izraz nije imao njihovu vrednost,
sve dok se ne naie na kraj ili naredbu
ako vrednost izraza
izraz
break.
Na sluaj
default se prelazi
default je
opcioni i ukoliko nije naveden, a nijedan postojei sluaj nije ispunjen, onda se
ro
n
default
default
izraz nije navedena ni uz jedan
kt
le
default.
U okviru naredbe
na naredbu
break,
break,
break
156
switch.
cenjem naredbe
Program 7.1.
#include <stdio.h>
(2
01
5)
int main() {
int n;
scanf("%i",&n);
an
je
switch (n % 3) {
case 1:
case 2:
printf("Uneti broj nije deljiv sa 3");
break;
default: printf("Uneti broj je deljiv sa 3");
}
return 0;
n % 3 jednaka 1 ili 2,
Uneti broj nije deljiv sa 3, a inae e biti ispisan tekst
Uneti broj je deljiv sa 3. Da u nije navedena naredba break, onda bi u
sluaju da je vrednost izraza n % 3 jednaka 1 (ili 2), nakon teksta Uneti broj
nije deljiv sa 3, bio ispisan i tekst Uneti broj je deljiv sa 3 (jer bi
iz
sk
o
ro
n
7.4 Petlje
kt
le
grupa naredbi) izvrava vie puta (sve dok je neki logiki uslov ispunjen).
7.4.1
Petlja
Petlja
while
while
while(izraz)
naredba
U petlji
while
izraz
naredba
izraz iznova
157
Ukoliko iza
while
while (i < j)
i++;
while
(2
01
5)
Sledea
while (1)
i++;
Petlja
Petlja
for
for
je
7.4.2
Komponente
an
izraz2
iz
petlje.
sk
o
izraz1)
izraz2)
ima ne-nula
ro
n
izraz3)
telo, korak, uslov, pri emu je uslov ispunjen svaki, osim poslednji put. Dakle,
kt
while:
for
le
izraz1;
while (izraz2) {
naredba
izraz3;
}
Petlja
for
dodeljivanje vrednosti promenljivama i jednostavno ih menjati sve dok je ispunjen zadati uslov (pri emu su i poetno dodeljivanje i uslov i izmene lako
vidljivi u definiciji petlje). To ilustruje sledea tipina forma
for
petlje:
158
break
ili
return):
for (;;)
...
Ako je potrebno da neki od izraza
izraza, moe se koristiti operator
,.
an
i=2, j=8
i=3, j=7
i=1, j=9
iz
i=0, j=10
objedini vie
je
(2
01
5)
beskonano (ako u bloku naredbi koji ovde nije naveden nema neke naredbe
i=4, j=6
Program 7.2.
sk
o
petlje:
ro
n
#include<stdio.h>
le
kt
int main() {
int i, j, n=3;
for(i = 1; i <= n; i++) {
for(j = 1; j <= n; j++)
printf("%i * %i = %i\t", i, j, i*j);
printf("\n");
}
return 0;
}
1 * 1 = 1
2 * 1 = 2
3 * 1 = 3
1 * 2 = 2
2 * 2 = 4
3 * 2 = 6
1 * 3 = 3
2 * 3 = 6
3 * 3 = 9
for
159
7.4.3
Petlja
Petlja
do-while
do-while
do {
naredbe
} while(izraz)
naredbe) naveden izmeu vitiastih zagrada se izvrava
izraz). Ako je on taan, telo se izvrava
nastavlja sve dok izraz izraz nema vrednost nula (tj. sve dok
(2
01
5)
while,
barem jednom.
je
ro
n
sk
o
iz
#include <stdio.h>
int main() {
unsigned n;
printf("Unesi broj: ");
scanf("%u", &n);
do {
printf("%u ", n % 10);
n /= 10;
} while (n > 0);
return 0;
}
an
Program 7.3.
le
kt
broj
7.4.4
while,
a ne
do-while
petlja, za
Naredbe
break i continue
U nekim situacijama pogodno je napustiti petlju ne zbog toga to nije ispunjen uslov petlje, ve iz nekog drugog razloga. To je mogue postii naredbom
break
1 Naredbom break
switch)1
Na primer:
160
(2
01
5)
Korienjem naredbe
otea njegovu analizu (na primer, analizu ispravnosti ili analizu sloenosti).
U nekim situacijama, korienje naredbe
ali kd koji koristi naredbu
break
break
Naredbom
continue
je
iz
an
korienjem naredbe
sk
o
continue
se naruava
continue
ro
n
kt
le
ispisuje
0 0
0 1 0 2
1 0
1 1
2 0
161
if (!x)
x += 2;
x *= 2;
Pitanje 7.2.
0,
int x = 0;
if (x > 3);
x++;
Navesti primer naredbe u kojoj se javlja
Pitanje 7.4.
ro
n
sk
o
iz
naredbi:
i=2; j=5;
switch(j/i)
{
case 1: i++;
break;
case 2: i += ++j;
default: j += ++i;
}
an
Ako su promenljive
switch,
vieznanost.
Pitanje 7.5.
if-else
je
Pitanje 7.3.
5?
(2
01
5)
Ako su promenljive
kt
Pitanje 7.6.
naredbi:
le
Pitanje 7.7.
int i = 2; int j = 2;
while(i + 2*j <= 15) {
i++;
162
Pitanje 7.8.
(2
01
5)
if (i % 3 == 0)
j--;
else {
i+=2; j++;
}
printf("%d %d\n", i, j);
ta se ispisuje prilikom izvravanja narednog kda?
Pitanje 7.9.
je
sk
o
Pitanje 7.10.
iz
an
ro
n
Pitanje 7.11.
Ukoliko se u naredbi
izostavi izraz
e2,
kt
Pitanje 7.12.
Da li je u naredbi
mogue da su izrazi
le
e1 i e3
povezani ti podizrazi?
Pitanje 7.13.
while
i (ii) petljom
for
while
i (ii) petljom
do-while
do {
naredbe
} while(izraz)
Pitanje 7.14.
Pitanje 7.15.
for
i (ii) petljom
do-while
163
while (izraz)
naredba
Pitanje 7.16.
Pitanje 7.17.
(2
01
5)
while(A) {
if(B) break;
C;
}
continue:
je
for(;A;) {
if(B) continue;
C;
}
tako da ne sadri
break:
while
petlje
an
Pitanje 7.18.
break:
2.
3.
4.
Pitanje 7.19.
sk
o
iz
1.
break.
for
petlje sa
2.
ro
n
1.
Pitanje 7.20.
le
kt
Zadatak 7.1.
Zadatak 7.2.
sin()
broj
Zadatak 7.3.
dimenzija
[0, 2]
na jednakim rastojanjima.
i izraunava
Zadatak 7.4.
n.
i neoznaeni ceo
164
a) **** b) ****
****
***
****
**
****
*
c) *
**
***
****
d) ****
***
**
*
e)
*
**
***
****
f) * * * * g)
* * *
* *
*
*
* *
* * *
* * * *
Zadatak 7.5.
Zadatak 7.6.
(2
01
5)
prost.
Zadatak 7.7.
Zadatak 7.8.
a onda ispisuje:
an
0,
je
iz
sk
o
1 +...+
);
ro
n
1
1
1 . . . );
);
+...+ 1
kt
Zadatak 7.9.
le
Zadatak 7.10.
Zadatak 7.11.
izrau-
0 = 1,
+1 =
2
2
vrednost
. Iterativni postupak zaustaviti kada je |+1 | < 0.0001.
tei ka
165
Zadatak 7.12.
1, 1, 2, 3, 5, 8, 13, 21, . . .
je definisan
uslovima
0 = 1,
1 = 1,
+2 = +1 + .
lanova ovog niza (koristiti ideju da se
Zadatak 7.13.
celog broja
n,
Zadatak 7.14.
(2
01
5)
niza).
n.
Ako je jedan od
iz
246).
Zadatak 7.17.
4321).
Zadatak 7.16.
1234
an
Zadatak 7.15.
unsigned.
je
123456
= 5, = 2, = 1234,
program ispisuje
na datu poziciju
sk
o
12534.
ro
n
Zadatak 7.18.
program ispisuje
1. Napisati program koji razmenjuje prvu i poslednju cifru unetog neoznaenog celog broja (na primer, za unos
1234
program ispisuje
4231).
kt
le
1234
program ispisuje
2341).
Zadatak 7.19.
1234
program ispisuje
4123).
Zadatak 7.20.
switch
osnovu prosene ocene i broja jedinica uenika odrediti kolski uspeh. Nakon
toga, upotrebom naredbe
switch
166
Zadatak 7.21.
Zadatak 7.22.
0112122312232334...
Zadatak 7.23.
1,
tj.
(2
01
5)
najvie 100 elemenata). Napisati program koji odreuje njihov presek, uniju i
razliku (redosled prikaza elemenata nije bitan, i u ulaznim nizovima se elementi
an
Zadatak 7.24.
je
ne ponavljaju).
anavolimilovana).
Prilagoditi program
je palindrom).
(na primer,
Zadatak 7.26.
sk
o
iju matrice (
iz
Zadatak 7.25.
< 100)
3 1 2 3 4 5 6 7 8 9
kt
ro
n
opisuje matricu
1
4
7
2
5
8
3
6
9
le
1
2 4
3 5 7
6 8
9
Zadatak 7.27.
menzije matrice (
167
1
0
1
0
1
8
1
3
2
1
1
0
1
9
0
2
3
0
0
2
[1][1], [3][1], i [3][4]
le
kt
ro
n
sk
o
iz
an
je
(2
01
5)
polja na pozicijama
(2
01
5)
Glava 8
je
Funkcije
Svaki C program sainjen je od funkcija.
Funkcija
main
mora da postoji
main (ali i
printf),
an
iz
navanje, neka obrada koja predstavlja celinu za sebe i koristi se vie puta u
sk
o
ro
n
kt
movi koji su u okviru ovog primera samo ukratko objanjeni bie detaljnije
le
Program 8.1.
#include <stdio.h>
int kvadrat(int n);
int main() {
printf("Kvadrat broja %i je %i\n", 5, kvadrat(5));
1U
2 Iz
i generalno se ne preporuuje.
168
main,
main,
kao i da se odreeni
169
8. Funkcije
int kvadrat(int n) {
return n*n;
}
(2
01
5)
moe ravnopravno dalje uestvovati u irim izrazima) iji je tip povratni tip
funkcije, a vrednost povratna vrednost funkcije. Na mestu poziva, tok izvra-
je
return
kvadrat
an
cija funkcije
iz
sk
o
Program 8.2.
#include <stdio.h>
ro
n
le
kt
int main() {
unsigned i;
for(i = 0; i < max; i++)
printf("%d %f %f\n", i, stepen(2.0f,i), stepen(3.0f,i));
return 0;
}
float stepen(float x, unsigned n) {
unsigned i;
float s = 1.0f;
for(i = 1; i<=n; i++)
s *= x;
3 Za
170
8. Funkcije
return s;
}
i
Primetimo da je promenljiva
deklarisana je u funkciji
(2
01
5)
dok promenljive deklarisana van svih funkcija nazivamo obino globalne proO ovoj temi bie vie rei u
poglavlju 9.2.2.
an
je
tip ime_funkcije(niz_deklaracija_parametara);
iz
tip ime_funkcije(niz_deklaracija_parametara) {
deklaracije
naredbe
}
sk
o
ro
n
kt
le
int kvadrat(int n) {
return n*n;
}
Definicija funkcija mora da bude u skladu sa navedenim prototipom, tj. mo-
raju da se podudaraju tipovi povratne vrednosti i tipovi parametara. Deklaracija ukazuje prevodiocu da e u programu biti koriena funkcija sa odreenim
tipom povratne vrednosti i parametrima odreenog tipa. Zahvaljujui tome,
kada prevodilac (na primer, u okviru funkcije
kvadrat,
main),
funkcije nepoznata u trenutku te provere). Poto prototip slui samo za proveravanje tipova u pozivima, nije neophodno navoditi imena parametara, ve je
171
8. Funkcije
dovoljno navesti njihove tipove. U navedenom primeru, dakle, prototip je mogao da bude i
int kvadrat(int);
Nije neophodno za svaku funkciju navoditi najpre njen prototip, pa onda
definiciju.
(2
01
5)
titi u nastavku programa i bez navoenja prototipa (jer prevodilac iz definiMeutim, kada postoji
je
int
i ne
an
vri nikakvu provera ispravnosti argumenata u pozivima funkcije. Ovakvo ponaanje je predvieno jedino zbog kompatibilnosti sa starim verzijama jezika C,
te je opta preporuka da se svakako pre prvog poziva funkcije navede njena
iz
Definicije funkcija mogu se navesti u proizvoljnom poretku i mogu se nalaziti u jednoj ili u vie datoteka.
sk
o
Postojanje dve deklaracije iste funkcije u okviru jednog programa je dozvoljeno, ali postojanje dve deklaracije funkcije istog imena, a razliitih lista paramPostojanje dve definicije funkcije
ro
n
istog imena u jednom programu dovodi do greke tokom prevoenja ili povezivanja (ak i ako su liste parametara razliite).
Prototipovi funkcija iz standardne biblioteke dati su u datotekama zaglavlja
kt
le
172
8. Funkcije
tra funkcije.
etar funkcije
n je param-
(2
01
5)
void.
void,
je
funkcija moe da koristi isto ime za neki svoj parametar ili za neku svoju
Kvalifikatorom
const
an
lokalnu promenljivu.
funkcije ime se obezbeuje da neki parametar ili sadraj na koji ukazuje neki
main
iz
sk
o
ro
n
kt
moe navesti promenljiva, ali i bilo koji izraz istog tipa (ili izraz ija vrednost
moe da se konvertuje u taj tip). Na primer, funkcija
poglavlja 8.1 moe biti pozvana sa
kvadrat(5),
ali i sa
kvadrat iz primera
kvadrat(2+3).
iz
le
koja se koristi kao argument funkcije kopira kada pone izvravanje funkcije i
onda funkcija radi samo sa tom kopijom, ne menjajui original.
Na primer,
Program 8.3.
swap
173
8. Funkcije
#include <stdio.h>
(2
01
5)
argumenti
an
xiy
je
U funkciji
x = 3, y = 5
iz
Program 8.4.
sk
o
#include <stdio.h>
kt
ro
n
void f(int a) {
a = 3;
printf("f: a = %d\n", a);
}
le
int main() {
int a = 5;
f(a);
printf("main: a = %d\n", a);
}
f: a = 3
main: a = 5
Ukoliko je potrebno promeniti neku promenljivu unutar funkcije, onda se
kao argument ne alje vrednost te promenljive nego njena adresa (i ta adresa
174
8. Funkcije
(2
01
5)
return
naredbe) vri se
f vri
3:
je
Program 8.5.
an
#include <stdio.h>
sk
o
iz
void f(int a) {
printf("%d\n", a);
}
int main() {
f(3.5);
}
double
se konverzija
ro
n
kt
short
se promoviu u
int),
i promociju tipa
float
u tip
double.
char
U ovom
sluaju (da deklaracija ni definicija nisu navedene pre poziva funkcije), uko-
le
koja je sprovedena na opisani nain, izvrni program moe da bude generisan, ali njegovo ponaanje moe da bude neoekivano. Ako je u navedenom
primeru definicija funkcije
prevoenja funkcije
main
3.5
main,
prilikom
i kao parametar u
vrednost tipa
double).
(a ne
3.5,
175
8. Funkcije
tip
return r;
r izraz
return r; ne
gde je
zadatog tipa ili tipa koji se moe konvertovati u taj tip. Naredba
(2
01
5)
return
return;).
void
tavie, u
u funkciji.
const
je
an
sk
o
iz
kao argument navesti ime niza. Tokom kompilacije, imenu niza pridruena je
niza.
ro
n
(iji je tip odgovarajueg parametra pokazivaki tip, o emu e biti vie rei u
glavi 10) stie informacija o adresi poetka niza i o tipu elemenata (ali ne i o
kt
imenu niza niti o broju elemenata niza). Poto funkcija koja je pozvana dobija
informaciju o adresi poetka originalnog niza, ona moe da neposredno menja
le
176
8. Funkcije
(2
01
5)
an
je
iz
#include <stdio.h>
Program 8.6.
sk
o
le
kt
ro
n
int main() {
int a[] = {1, 2, 3, 4, 5};
printf("main: %d\n", sizeof(a));
f(a);
return 0;
}
main: 20
f: 4
Prilikom prenosa niza (tj. adrese njegovog poetka) u funkciju, pored imena
niza, korisnik obino treba da eksplicitno prosledi i broj elemenata niza kao
dodatni argument (da bi pozvana funkcija imala tu informaciju).
Povratni tip funkcije ne moe da bude niz. Funkcija ne moe da kreira niz
koji bi bio vraen kao rezultat, a rezultat moe da vrati popunjavanjem niza
koji joj je prosleen kao argument.
4 sizeof
sizeof(a) nema
a.
prenosa argume-
177
8. Funkcije
niza
x,
dok funkcija
Program 8.7.
#include <stdio.h>
je
an
(2
01
5)
void ucitaj_broj(int a) {
printf("Ucitaj broj: ");
scanf("%d", &a);
}
ro
n
sk
o
iz
int main() {
int x = 0;
int y[3] = {0, 0, 0};
ucitaj_broj(x);
ucitaj_niz(y, 3);
printf("x = %d\n", x);
printf("y = %d %d %d\n", y[0], y[1], y[2]);
}
le
kt
Unesi broj: 5
Unesi niz: 1 2 3
x = 0
y = 1, 2, 3
Prenos niski u funkciju se vri kao i prenos bilo kog drugog niza. Jedina
razlika je to nije neophodno funkciji prosleivati duinu niske, jer se ona moe
5 Na primer,
strchr
karakter.
5 Naravno,
178
8. Funkcije
(2
01
5)
return -1;
const),
c,
strchr.
Kljuna re
const
je
funkcije.
an
iz
sk
o
Funkcija kreiraj_razlomak
struct razlomak:
kt
ro
n
le
rezultat).
179
8. Funkcije
(2
01
5)
ostaje jednak
2/4
8.9 Rekurzija
an
razlomak
je
iz
Na primer,
sk
o
funkcija
kt
ro
n
le
izraunava vrednost
uzimaju mnogo prostora na steku poziva), ali zato esto daju krai i razumljiviji
izvorni kd. Rekurzija je veoma vana programerska tehnika i o njenoj upotrebi
e vie rei biti u drugom delu ove knjige.
printf
va_list
scanf
a takve
<stdarg.h>
i tip po-
180
8. Funkcije
makro
(2
01
5)
iz
an
je
#include <stdio.h>
#include <stdarg.h>
ro
n
sk
o
int main() {
printf("%d\n", sumof(5, 1, 2, 3, 4, 5));
return 0;
}
kt
Pitanje 8.2.
Pitanje 8.3.
le
Pitanje 8.4.
vraa rezultat?
return
return?
return?
Da li
naredbe?
Pitanje 8.5.
Da li se u nekoj
181
8. Funkcije
Pitanje 8.6.
int f(int x) {
x = x+2;
return x+4;
}
Pitanje 8.7.
an
d
iz
sk
o
int main() {
int n = 4, k = 5;
f(n, k);
printf("%d %d\n", n, k);
}
je
Pitanje 8.8.
(2
01
5)
int main() {
int x = 1, y = 2;
x = f(x+y);
printf("%d\n", x);
}
le
kt
ro
n
void f(int x) {
x += (++x) + (x++);
}
int main() {
int x = 2;
f(x); f(x);
printf("%d\n", x);
}
Pitanje 8.9.
1. Koje su informacije od navedenih, tokom kompilacije, pridruene imenu
niza: (i) adresa poetka niza; (ii) tip elemenata niza; (iii) broj elemenata
niza; (iv) adresa kraja niza?
2. Koje se od ovih informacija uvaju u memoriji tokom izvravanja programa?
3. ta se sve od navedenog prenosi kada se ime niza navede kao argument
funkcije: (i) adresa poetka niza; (ii) elementi niza; (iii) podatak o broju
elemenata niza; (iv) adresa kraja niza.
182
8. Funkcije
Pitanje 8.10.
Pitanje 8.11.
je
int main() {
int i;
int a[] = {1, 2, 3, 4};
f(a);
for(i = 0; i < sizeof(a)/sizeof(int); i++)
printf("%d ", a[i]);
}
(2
01
5)
an
Pitanje 8.12.
emu je jednako
Pitanje 8.13.
Pitanje 8.14.
iz
a emu
sk
o
funkcije
sizeof("abc"),
strlen.
double
void
vrednost.
ro
n
int main() {
f(2);
return 0;
}
strlen("abc")?
kt
Pitanje 8.15.
Zadatak 8.1.
prost i program koji je testira. Uporediti sa reenjem koje sadri samo funkciju
le
main.
Zadatak 8.2.
double)
(koristiti
Heronov obrazac, na osnovu kojeg je povrina trougla jednaka vrednosti
( )( )( ),
gde su
, i
duine stranica, a
njegov poluo-
bim; napisati i koristiti funkciju koja rauna rastojanje izmeu dve take Dekar-
tove ravni).
Zadatak 8.3.
1,
183
8. Funkcije
Zadatak 8.4.
Zadatak 8.5.
(2
01
5)
3. pronalazi indeks poslednje pozicije na kojoj se u nizu nalazi dati broj (-1
ako niz ne sadri broj).
je
an
iz
Zadatak 8.6.
sk
o
ro
n
k;
kt
na datu poziciju
k;
x
iz niza.
le
Napomena: funkcija kao argument prima niz i broj njegovih trenutno popun-
operacije.
Zadatak 8.7.
184
8. Funkcije
k
k
pozicija ulevo;
pozicija udesno;
(2
01
5)
Zadatak 8.8.
je
Zadatak 8.9.
an
prvoj.
iz
pozicijama u drugoj).
sk
o
1.
ro
n
Zadatak 8.10.
permutacija druge (niska je permutacija druge ako se od nje dobija samo pre-
kt
"abc"
"cba"
jesu, a da niske
nisu permutacija.
le
"ab"
Zadatak 8.11.
"aab"i
( < 10)
Napisati program
i zatim elemente
kvadratne matrice, proverava da li je ona magini kvadrat i ispisuje odgovarajuu poruku na standardni izlaz. Koristiti pomone funkcije za izraunavanje
zbira elemenata vrsta, kolona i dijagonala matrice.
Primer, matrica:
7 12
2 13
16 3
9
6
je magini kvadrat.
1 14
8 11
10 5
15 4
185
8. Funkcije
Zadatak 8.12.
zija najvie
i dimenzije).
1. Napisati funkciju koja uitava matricu sa standardnog ulaza.
2. Napisati funkciju koja ispisuje matricu na standardni izlaz.
(2
01
5)
Zadatak 8.13.
unsigned long).
1000
je
le
kt
ro
n
sk
o
iz
an
cifara.
(2
01
5)
Glava 9
an
je
na viim programskim jezicima i predstavlja sredstvo komunikacije izmeu programera i raunara, ali i izmeu programera smih. Specijalizovani programi,
iz
prevodioci (kompilatori), prevode izvorni u izvrni program , napisan na mainskom jeziku raunara, tj. na jeziku neposredno podranom arhitekturom pro-
sk
o
cesora.
Postoji mnotvo pisanih pravila (tj. pravila koja proistiu iz standarda
jezika koji se koristi) i nepisanih pravila (razne konvencije i obiaji) za organizovanje kda izvornog programa.
ro
n
kt
vanje kodeksa postaje kljuno jer u protivnom pisanje i odravanje kda postaje
le
1 Postoji
nego pamet.
186
187
sistem nasilno prekida njegovo izvravanje), ali mogu da budu takve da se program nesmetano izvrava, ali da su rezultati koje prikazuje pogreni. Dakle, to
to ne postoje greke u fazi prevoenja i to to se program nesmetano izvrava,
jo uvek ne znai da je program ispravan, tj. da zadovoljava svoju specifikaciju
i daje tane rezultate za sve vrednosti ulaznih parametara.
Ispravnost pro-
(2
01
5)
je
an
sk
o
Pretprocesiranje.
iz
omoguava da se izvre neke jednostavne transformacije izvornog teksta programa pre nego to on bude prosleen kompilatoru kompilator, dakle, ne
obrauje tekst programa koji je programer napisao, ve samo tekst koji je nas-
ro
n
kt
Na primer, u
.c
.h
koje sadre
le
.c
datoteke.
-E
(na primer,
gcc -E program.c).
Kompilacija.
188
(2
01
5)
u objektne module.
-c
(na primer,
gcc -c program.c).
program.o
je
cije
an
and Linkable Format), formatu u kome je i izvrna datoteka, pri emu objektni modul nije izvran (kae se da je relokatibilan jer je u njemu tek potrebno
razreiti memorijske adrese) i mora se povezati da bi se dobila izvrna datoteka.
vri se najopsenija optimizacija kda to uzrokuje da
iz
gcc -O3,
-Wall
Povezivanje.
sk
o
od jednog ili vie objektnih modula koji su nastali ili kompilacijom izvornog
ro
n
kda programa ili su objektni moduli koji sadre mainski kd i podatke stan-
dardne ili neke nestandardne biblioteke . Program koji vri povezivanje zove
se poveziva , linker (engl. linker) ili ureiva veza.
Nakon kompilacije, u objektnim modulima adrese mainskog kda funkcija
kt
le
modul sadri sve promenljive i funkcije koje se koriste u programu (to najee
nije sluaj jer se koriste funkcije standardne biblioteke iji se izvrni kd ne
nalazi u objektnim modulima nastalim kompilacijom izvornog kda).
Kao to je ve reeno, pored objektnih modula nastalih kompilacijom izvornog kda koje je programer napisao, izvrnom programu se moe dodati unapred pripremljen mainski kd nekih biblioteka.
2 Objektni
.obj.
3 Biblioteke
nekoliko
.o
.a
.o,
a na sistemu Windows
.lib.
189
(2
01
5)
printf).
Deo stan-
je
an
namiko povezivanje , koje se vri tokom izvravanja programa (zapravo na njegovom poetku). Naime, statiko povezivanje u izvrnu datoteku umee main-
iz
namic link library) . Izvrne datoteke sadre nerazreene pozive funkcija koje
sk
o
ro
n
kt
le
koristi.
Na primer, ako se koristi GCC prevodilac, prevoenje programa od jedne datoteke i povezivanje sa objektnim modulima standardne biblioteke se postie
na sledei nain:
program
(u ELF formatu).
4 Ekstenzija
Windows
.dll.
190
libm
(2
01
5)
program.o),
je
gcc -c program.c
gcc -o program program.o
an
povezivanje ve samo kompilaciju i da rezultat eksplicitno sauva kao objekpoziv vri povezivanje tog objektnog
program.o. Drugi
program.
iz
Na primer, ako
program1.c i program2.c,
sk
o
ro
n
kt
gcc -c program1.c
gcc -c program2.c
gcc -o program program1.o program2.o
le
uli koji se ne menjaju ne prevode iznova svaki put kada je potrebno napraviti
novu verziju izvrnog program (kada se promeni neka izvorna datoteka). Na
primer, ako je promena izvrena samo u datoteci
ponovo prevoditi datoteku
Program make.
program2.c.
Program
make
program1.c,
nije potrebno
make
najee se koristi na
make
su
savremena integrisana razvojna okruenja (engl. integrated development environment, IDE) u kojima programer na interaktivni nain specifikuje proces
kompilacije.
191
Makefile
ime
make,
Speci-
make,
(2
01
5)
Makefile
an
je
kae da datoteka
ro
n
sk
o
iz
Izvravanje programa.
izvravanja programa.
kt
le
e vie biti rei u poglavlju 12.4) u odgovarajui deo memorije programa koji
se pokree, da inicijalizuju odreene registre u procesoru i na kraju da pozovu
poetnu funkciju programa.
funkcija
_start
main,
main,
ve
Ukoliko se otkrije da
postoji greka tokom izvravanja (tzv. bag od engl. bug), vri se pronalaenje
uzroka greke u izvornom programu (tzv. debagovanje ) i njeno ispravljanje. U
pronalaenju greke mogu pomoi programi koji se nazivaju debageri i koji
192
-g.
(2
01
5)
programa.
Pitanje 9.1.3.
an
Pitanje 9.1.4.
je
Pitanje 9.1.2.
iz
Pitanje 9.1.5.
Pitanje 9.1.6.
sk
o
ro
n
Pitanje 9.1.7.
kt
korektno razreene?
Pitanje 9.1.8.
le
sistemima?
Pitanje 9.1.9.
Pitanje 9.1.10.
greaka?
Pitanje 9.1.11.
Pitanje 9.1.12.
Pitanje 9.1.13.
p1.c i p2.c.
make?
193
(2
01
5)
Osnovni koraci u organizovanju sloenijih programa obino su podela sloenih zadataka na jednostavnije poslove i njihovo izdvajanje u zasebne funkcije
je
an
datoteka tj. modula koji sadre podatke i funkcije koji objedinjavaju odreenu
iz
sk
o
ro
n
Pretprocesor sa linkerom
kt
le
otni vek promenljivih (engl. lifetime) odreuje da li je neka promenljiva dostupna tokom itavog izvravanja programa ili samo tokom nekog njegovog dela.
Postojanje promenljivih koje traju samo pojedinano izvravanje neke funkcije
znatno tedi memoriju, dok postojanje promenljivih koje traju itavo izvravanje programa omoguava da se preko njih vri komunikacija izmeu razliitih
funkcija modula. Povezanost identifikatora (engl. linkage) u vezi je sa deljenjem podataka izmeu razliitih jedinica prevoenja i daje mogunost korienja
zajednikih promenljivih i funkcija u razliitim jedinicama prevoenja (modulima), ali i mogunost sakrivanja nekih promenljivih tako da im se ne moe
pristupiti iz drugih jedinica prevoenja. Odnos izmeu dosega, ivotnog veka
i povezanosti je veoma suptilan i sva ova tri aspekta objekata odreuju se na
194
osnovu mesta i naina deklarisanja tj. definisanja objekata, ali i primenom kvalifikatora
ovog poglavlja.
Sva ova sredstva donose potencijalna olakanja u proces programiranja, ali
sva stvaraju i mogunosti raznih greaka ukoliko se ne koriste na ispravan nain.
Pretprocesor
(2
01
5)
9.2.1
kompilacije. Sutinski, pretprocesor vri samo jednostavne operacije nad tekstualnim sadrajem programa i ne koristi nikakvo znanje o jeziku C. Pretpro-
je
an
grama.
\. Dve najee
#include (za ukljuivanje sadraja neke
#define
druge datoteke) i
iz
sk
o
ro
n
kt
5 promenljivih, funkcija
le
i tipova podataka koji se u njoj koriste. ak i kada programer pie samo jednu
datoteku, program po pravilu koristi i funkcionalnost koju mu prua stan-
printf),
5 Podsetimo,
odreenu datoteku i tako generie objektni modul (npr. prototip funkcije je deklaracija),
dok definicije sadre mnogo vie informacija informacije koje su dovoljne da nakon faze
povezivanja nastane izvrni program (npr. ceo kd funkcije predstavlja njenu definiciju).
Kompilator ne mora da poznaje definiciju funkcije da bi generisao njen poziv, ali linker
mora, da bi mogao da taj poziv razrei.
195
datoteke koje se onda ukljuuju gde god je potrebno. Takve datoteke zovu se
datoteke zaglavlja (engl. header files). Osnovni primer datoteka zaglavlja su zaglavlja standardne biblioteke. Primer kreiranja korisniki definisanih datoteka
zaglavlja bie naveden u poglavlju 9.2.6. U datoteku koja se prevodi, sadraj
neke druge datoteke ukljuuje se direktivom
#include.
Linija oblika:
i linija oblika
#include <ime_datoteke>
zamenjuju se sadrajem datoteke
ime_datoteke.
(2
01
5)
#include "ime_datoteke"
-I)
je
an
< i >,
koji se koristi.
#include.
#include
sk
o
Poto, zahvaljujui
iz
moraju biti iznova prevedene. Datoteka koja se ukljuuje i sama moe sadrati
ro
n
kt
Makro zamene
Pretprocesorska direktiva
le
u datoteci, makroa (engl. macro) drugim nizom karaktera pre samog pre-
#define MAX_LEN 80
Ovakva definicija se koristi da bi se izbeglo navoenje iste konstantne vrednosti na puno mesta u programu.
U nave-
196
const).
Naime, za ime
MAX_LEN
MAX_LEN
\ na kraju svakog
(2
01
5)
prethode.
max(A, B)
an
#define
je
iz
sk
o
ro
n
kt
le
primeni na
kvadrat(a+2),
a+2*a+2,
a ne
(a+2)*(a+2),
eljeno.
zamenjen izrazom
a/(b*b)).
a/(b)*(b),
a/kvadrat(b), on e biti
(a/b)*b (a ne sa sa
to je ekvivalentno sa
6 Zato je neophodno da pretprocesor tokom svog rada izvri jednostavniju leksiku analizu.
197
#,
Celobrojnim pro-
Ukoliko se u direktivi
navede simbol
t.
(2
01
5)
#define,
denog izmeu dvostrukih navodnika. Ovo moe da se kombinuje sa nadovezivanjem niski. Na primer, naredni makro moe da poslui za otkrivanje greaka:
je
dprint(expr)
an
#define
Tako e tekst:
dprint(x/y);
iz
sk
o
Poto se niske automatski nadovezuju, efekat ove naredbe je isti kao efekat
naredbe:
ro
n
##.
kt
Na primer,
le
dodaj_u_niz(a, 3);
se tada zamenjuje naredbom
niz_a[brojac_a++] = 3;
Dejstvo primene direktive zamene je od mesta na kojem se nalazi do kraja
datoteke ili do reda oblika:
198
#undef originalni_tekst
Kao to je reeno, makro zamene i funkcije se, iako mogu izgledati slino,
sutinski razlikuju. Kod makro zamena nema provere tipova argumenata niti
implicitnih konverzija to moe da dovodi do greaka u kompilaciji ili do neoekivanog rada programa. Argument makroa u zamenjenoj verziji moe biti nave-
(2
01
5)
strane, kod poziva makroa nema prenosa argumenata te se oni izvravaju bre
nego odgovarajue funkcije. Ipak, moderni kompilatori kratke funkcije obino
umeu (engl. inline) itavo telo funkcije na mesto poziva, starajui se o argu-
je
getc, printf
fprintf,
itd.).
an
funkciju
Uslovno prevoenje
iz
#if
sk
o
#define).
kt
direktive
ro
n
le
Program 9.1.
#define SRPSKI
#include <stdio.h>
int main()
{
#ifdef SRPSKI
printf("Zdravo, svete");
#else
printf("Hello, world");
#endif
199
return 0;
ispisuje tekst na srpskom jeziku, a izostavljanjem direktive iz prvog reda ispisivao bi tekst na engleskom jeziku.
grananja zasnovanog na C naredbi
if.
se samo jedna od dve verzije programa i dobijeni izvrni program nema nikakvu
(2
01
5)
9.2.2
Doseg identifikatora
Jedna od glavnih karakteristika dobrih programa je da se promenljive veinom definiu u funkcijama (ili ak nekim uim blokovima) i upotreba promen-
je
an
iz
sk
o
ristiti odreeni identifikator i u kojem taj identifikator identifikuje odreeni objekat (na primer, promenljivu ili funkciju). Svaki identifikator ima neki doseg.
Jezik C spada u grupu jezika sa statikim pravilima dosega to znai da se doseg
svakog identifikatora moe jednoznano utvrditi analizom izvornog kda (bez
ro
n
vrste dosega:
doseg nivoa datoteke (engl. file level scope) koji podrazumeva da ime vai
kt
doseg nivoa bloka (engl. block level scope) koji podrazumeva da ime vai
le
doseg nivoa funkcije (engl. function level scope) koji podrazumeva da ime
vai u celoj funkciji u kojoj je uvedeno; ovaj doseg imaju jedino labele
koje se koriste uz
goto
naredbu;
doseg nivoa prototipa funkcije (engl. function prototype scope) koji podrazumeva da ime vai u okviru prototipa (deklaracije) funkcije; ovaj
doseg imaju samo imena parametara u okviru prototipova funkcije; on
omoguava da se u prototipovima funkcija navode i imena (a ne samo
tipovi) argumenata, to nije obavezno, ali moe da olaka razumevanje i
dokumentovanje kda.
7 Za
200
Najznaajni nivoi dosega su doseg nivoa datoteke i doseg nivoa bloka. Identifikatori koji imaju doseg nivoa datoteke najee se nazivaju spoljanji ili glob-
alni , dok se identifikatori koji imaju ostale nivoe dosega (najee doseg nivoa
(2
01
5)
je
int a;
/* a je globalna promenljiva - doseg nivoa datoteke */
sk
o
iz
an
ro
n
le
kt
201
inicijalizovanu na vrednost
inicijalizovana na vrednost
3.
(2
01
5)
void f() {
int a = 3, i;
for (i = 0; i < 4; i++) {
int a = 5;
printf("%d ", a);
}
}
je
5 5 5 5
an
iz
9.2.3
static i auto
sk
o
ro
n
statiki (engl. static) ivotni vek koji znai da je objekat dostupan tokom
celog izvravanja programa;
kt
le
static
auto
202
deklaracije do kraja bloka i nije ih mogue koristiti van bloka u kojem su deklarisane. Ne postoji nikakva veza izmeu promenljivih istog imena deklarisanih u
razliitim blokovima.
Lokalne promenljive podrazumevano su automatskog ivotnog veka (sem
ako je na njih primenjen kvalifikator
static
ili kvalifikator
extern
o emu
(2
01
5)
aktivnim instancama jedne funkcije (jer svaka instanca funkcije ima svoj stek
je
an
iz
register
sk
o
ro
n
kt
le
static,
203
(2
01
5)
promenljivih koje bi bile statikog ivotnog veka (da bi uvale vrednost tokom
itavog izvravanja programa), ali lokalnog dosega (da bi se mogle koristiti i
menjati samo u jednoj funkciji).
static
je
u tom sluaju ona ima statiki ivotni vek kreira se na poetku izvravanja programa i oslobaa prilikom zavretka rada programa.
Tako modifiko-
an
vana promenljiva ne uva se u stek okviru svoje funkcije, ve u segmentu podataka (videti poglavlje 9.3.3). Ukoliko se vrednost statike lokalne promenljive
promeni tokom izvravanja funkcije, ta vrednost ostaje sauvana i za sledei
Ukoliko inicijalna vrednost statike promenljive nije nave-
0.
iz
poziv te funkcije.
sk
o
u funkciji
ro
n
Program 9.2.
kt
#include <stdio.h>
le
void f() {
int a = 0;
printf("f: %d ", a);
a = a + 1;
}
void g() {
static int a = 0;
printf("g: %d ", a);
a = a + 1;
}
9 Ovakvo
204
int main() {
f(); f();
g(); g();
return 0;
}
f: 0 f: 0 g: 0 g: 1
9.2.4
(2
01
5)
static i extern
vidljivo samo u jednoj ili u vie funkcija definisanih u jednoj jedinici prevoenja.
voljan i potrebna je malo finija kontrola.
je
Meutim, kada se program sastoji od vie jedinica prevoenja, doseg nije doPoeljno je da postoji mogunost
an
definisanja: (i) objekata (promenljivih ili funkcija) koji se mogu koristiti samo
u pojedinanim funkcijama, (ii) objekata koji se mogu koristiti u vie funkcija
neke jedinice prevoenja, ali ne i van te jedinice prevoenja i (iii) objekata koji
iz
jedinicama prevoenja.
ta e biti sluaj,
sk
o
ro
n
kt
taj identifikator
le
Ne treba meati spoljanju i unutranju povezanost sa spoljanjim i unutranjim dosegom (otuda i korienje alternativnih termina globalni i lokalni
za doseg) povezanost (i unutranja i spoljanja) se odnosi iskljuivo na globalne objekte (tj. objekte spoljanjeg dosega), dok su lokalni objekti (tj. objekti
unutranjeg dosega) najee bez povezanosti (osim ako im se povezanost ne
promeni kvalifikatorom
extern
205
void f();).
f,
Deklaraciju moemo
(2
01
5)
shvatiti kao deo koda kojim kompilatoru kaemo negde u programu postoji
objekat tog i tog tipa. Definicijom se taj objekat zaista implementira tj. in-
f implementira
tu funkciju tj. uvodi njen kod i svaki poziv te funkije se onda razreava tako
to se poziva upravo taj kd. Definicija globalne promenljive
int a = 3; kae
je
an
tekstu programa u stvari odnosne na taj podatak. Objekti mogu da imaju vei
broj (istovetnih) deklaracija, ali mogu da imaju samo jednu definiciju. Ako su
iz
sk
o
promenljive koja je do sada prikazana bila je ujedno i njena definicija. Meutim, to je neto drugaije kod globalnih promenljivih. Naime, ako deklaraciju
prati inicijalizacija, ona se uvek ujedno smatra i definicijom. Ali, ako je globalna
int a;),
ro
n
Takav kod se
kt
le
tj. ponaanje je isto kao da pored naelne definicije postoji stvarna definicija
sa inicijalizatorom 0. Takoe, ako se pri deklaraciji promenljive (bilo lokalne,
extern
206
imena
f,
funkcije
g1
g2
promenljive i tipove.
int g1(int i) {
static int j;
}
int g2() {
static int i, j;
...
}
je
struct i { int a; }
(2
01
5)
int f() {
int i;
...
}
an
nou u skupu jedinica prevoenja odreuju jedan isti objekat (tj. sve pojave
ovakvog identifikatora u razliitim jedinicama prevoenja odnose se na jedan
iz
isti objekat), dok u celom programu mora da postoji tano jedna definicija tog
objekta. Tako se jedan identifikator koristi za isti objekat u okviru vie jedinica
Kvalifikator
extern
sk
o
prevoenja.
extern.
ro
n
torom
inicijalizaciju promenljivih niti telo funkcije (to ima smisla samo prilikom
definisanja). Slino, za niz u
Poto
extern
kt
ziju.
extern
le
extern
extern
deklaraciju.
static
int x;),
definicije, tj. ako negde postoji stvarna definicija objekta sa tim imenom, one
nisu definicije ve samo deklaracije.
extern
nije
207
static). Zato je kod lokalnih promenljivih neophodno koristiti kvaliextern kada se eli naglasiti da je u pitanju deklaracija (a ne defini-
(2
01
5)
fikator
je
Program 9.3.
#include <stdio.h>
extern int a;
void f();
void f() {
printf("a=%d\n", a);
}
int g() {
extern int b;
printf("b=%d\n", b);
f();
}
int main() {
a = 1;
/* b = 2; */
g();
return 0;
}
le
kt
ro
n
sk
o
iz
an
#include <stdio.h>
int a;
int b = 3;
b=3
a=0
f.
a i b kao i globalna
povezanost. Linija
int b = 3;
int a;
f.
U sluaju promenljive
208
bi radio identino (obe definicije bile bi naelne i tek tokom povezivanja bio
bi napravljen jedinstven objekat statikog ivotnog veka inicijalizovan na nulu
(2
01
5)
neophodno navoditi
je
static.10
an
torom
static
iz
mora postojati tano jedna definicija u toj jedinici prevoenja. S druge strane,
onemoguava korienje promenljive ili funkcije u drugim
sk
o
ro
n
kt
le
Program 9.4.
10 Kvalifikator static
209
#include <stdio.h>
static int a = 3;
int b = 5;
#include <stdio.h>
int g(); /* int f(); */
int a, b;
(2
01
5)
int main() {
printf("main: a=%d, b=%d\n",
a, b);
g(); /* f() */
return 0;
}
int g() {
f();
}
Program ispisuje
an
je
i funkcija
i funkcija
imaju unutranju
a, b
i funkcije
g i main
iz
sk
o
ro
n
kt
int b;
b,
u dru-
le
a,
onda se
int a;
nost 0).
9.2.5
stderr
(videti poglavlje
12.1). ak i u veoma kratkim programima, za svaku od ovih faza moe da postoji greka koja tada moe biti otkrivena. Razmotrimo jednostavan (vetaki,
bez konkretne svrhe) program naveden u nastavku i greke do kojih moe doi
210
malim izmenama:
Program 9.5.
Pretprocesiranje.
(2
01
5)
#include<stdio.h>
int main() {
int a = 9;
if (a == 9)
printf("9");
return 0;
}
je
#include, u programu navedeno #Include, bie prijavljena greka (jer ne postoji direktiva #Include):
an
iz
Kompilacija
int a = 9;,
09
sk
o
pravna leksema
ro
n
if a == 9 ...,
if (a == 9) ...,
kt
le
Semantika analiza:
if (a == 9) ...,
postoji naredba
211
Povezivanje.
naredba
funkcije
print(...);,
print):
printf(...);, postoji
(2
01
5)
je
an
iz
if (a == 9) ...
sadri naredbu
if (a = 9) ...,
prevodilac moe
sk
o
izdati upozorenje:
ro
n
if (9 == 9) ...,
kt
le
if (a / 0) ...,
212
-Wall.
9.2.6
(2
01
5)
Kao primer programa sastavljenog iz vie datoteka i vie jedinica prevoenja, razmotrimo definisanje jednostavne korisnike biblioteke za rad sa
pozitivnim razlomcima.
je
OK
IMENILAC_0
nabrojivog
an
RAZLOMAK_GRESKA.
tipa
iz
sk
o
#ifndef __RAZLOMAK_H_
#define __RAZLOMAK_H_
kt
ro
n
le
kvalifikator
213
Datoteka zaglavlja
razlomak.h
(2
01
5)
#ifndef IME
#define IME
je
...
gde je tekst
IME
an
#endif
IME
iz
datoteke) ignoriu celokupan njen sadraj. Ovaj mehanizam olakava odravanje datoteka zaglavlja i primenjen je i u navedenom primeru.
sk
o
razlomak.c.
#include "razlomak.h"
kt
ro
n
char* razlomak_poruka[] = {
"Operacija uspesno sprovedena",
"Greska: imenilac je nula!"
};
le
214
razlomak_greska = OK;
return r;
(2
01
5)
iz
an
je
sk
o
razlomak.h.
Iako
ovaj korak nije uvek neophodan (ukoliko se pre svakog poziva funkcije javlja
njena definicija), svakako se preporuuje pre definicija ukljuiti deklaracije da
bi se tokom kompilacije proverilo da li su deklaracije i definicije uparene.
ro
n
razlomak_poruka.
Elementi niza
le
kt
menljive
broja.
static.
program.c.
Program 9.6.
#include <stdio.h>
#include "razlomak.h"
215
int main() {
unsigned a, b;
RAZLOMAK r1, r2, r;
(2
01
5)
an
je
iz
r = saberi_razlomke(r1, r2);
if (razlomak_greska != OK)
printf("%s\n", razlomak_poruka[razlomak_greska]);
sk
o
razlomak_greska.
U sluaju
Datoteka
ro
n
razlomak.h
kt
Odgovarajua
Makefile
le
#include?
216
Pitanje 9.2.2.
Pitanje 9.2.3.
Pitanje 9.2.4.
(2
01
5)
cesorske direktive
Pitanje 9.2.5.
je
Pitanje 9.2.6.
an
Pitanje 9.2.8.
#include?
iz
Pitanje 9.2.7.
#define,
Pitanje 9.2.9.
sk
o
#include <stdio.h>
#define x(y) y*y+y
int main() { printf("%d", x(3 + 5)); /* ispis */ }
2.
#include <stdio.h>
#define A(x,y) (x > 2) ? x*y : x-y
int main() { printf("%d %d", A(4,3+2), A(4,3*2); }
le
kt
ro
n
1.
#include <stdio.h>
#define A(x,y) (y>=0) ? x+y : x-y
int main() {
if (b<=0) c = A(a+b,b); else c = A(a-b,b);
printf("%d\n", c);
}
4.
#include <stdio.h>
#define proizvod(x,y) x*y
int main() { printf("%d\n", proizvod(2*3+4, 2+4*5)); }
3.
217
5.
#include <stdio.h>
#define A(x,y) (x > 2) ? x*y : x-y
int main() { printf("%d %d\n", A(4,3+2), A(4,3*2)); }
Pitanje 9.2.10.
1. Navesti primer poziva makroa
definiciji
dvostruko
(2
01
5)
kvadrat
Pitanje 9.2.11.
je
an
iz
Pitanje 9.2.13.
sk
o
Pitanje 9.2.12.
jeziku C, koja faza prethodi kompilaciji, a koja sledi nakon faze kompilacije?
Kako se zove faza prevoenja programa u kojoj se od objektnih
ro
n
Pitanje 9.2.14.
Pitanje 9.2.15.
datoteka
kt
prva.c,
program?
druga.c
i na kraju povezati
le
Pitanje 9.2.17.
Pitanje 9.2.16.
neke datoteke?
globalnih promenljivih?
Pitanje 9.2.18.
Pitanje 9.2.19.
Pitanje 9.2.20.
218
Pitanje 9.2.21.
Pitanje 9.2.22.
extern,
static
u kojoj
Pitanje 9.2.23.
(2
01
5)
alocirano:
1.
2.
3.
Pitanje 9.2.24.
je
Pitanje 9.2.25.
static,
static)?
an
statika promenljiva
sk
o
Pitanje 9.2.26.
iz
kojoj je deklarisana?
Pitanje 9.2.27.
a,
a koja
le
kt
ro
n
int i = 2;
int f() { static int i; return ++i; }
int g() { return ++i; }
int main() {
int i;
for(i=0; i<3; i++)
printf("%d", f()+g());
}
int i=2;
void f() { static int i; i++; printf("%d",i); }
void g() { i++; printf("%d",i); }
void h() { int i = 0; i++; printf("%d",i); }
int main() {
f(); g(); h(); f(); g(); h();
}
Pitanje 9.2.28.
static,
219
(2
01
5)
laganje, vri se dinamiko povezivanje poziva rutina niskog nivoa rantajm bibliotekom, vre se potrebne inicijalizacije i onda izvravanje moe da pone. U
fazi izvravanja mogue je da doe do greaka koje nije bilo mogue detektovati
u fazi prevoenja i povezivanja.
je
sistem, ali ima arhitekturu koja ne odgovara generisanoj aplikaciji (na primer,
9.3.1
an
iz
sk
o
biblioteke (engl. runtime library). Funkcije rantajm biblioteke obino su realizovane kao niz zahteva operativnom sistemu (najee zahteva koji se odnose
na ulaz/izlaz i na memoriju).
ro
n
kt
le
isanim od strane kompilatora ali obino nisu neposredno raspoloive aplikativnom programeru. Ako se izvrava vie programa kompiliranih istim kompilatorom, svi oni koriste funkcije iste rantajm biblioteke.
Opisani pristup primenjuje se, ne samo na C, ve i na druge programske
jezike. Biblioteka za C ima i svoje specifinosti. U operativnom sistemu Linux,
funkcije C rantajm biblioteke smatraju se i delom operativnog sistema i moraju
da budu podrane. Nasuprot tome, operativni sistem Windows ne sadri nuno
podrku za C bibliteku i ona se isporuuje uz kompilatore. Zbog toga se i delovi
rantajm biblioteke mogu statiki ugraditi u izvrni program (da se ne bi zavisilo
od njenog postojanja na ciljnom sistemu).
Osnovni skup rantajm funkcija koju jezik C koristi je sadran u modulu
220
crt0
main,
9.3.2
main
i slino.
(2
01
5)
poziv funkcije
Isto se
je
informacija o tipovima. Sve informacije o tipovima se razreavaju u fazi prevoenja i u mainskom kdu se koriste instrukcije za konkretne vrste oper-
an
iz
izvravati.
sk
o
ili 32-bitni ili 64-bitni tj. obino registri procesora, magistrale i podaci tipa
int
ro
n
i 32-bitni softver, ali ne i obratno. Pod 32-bitnim softverom se najee podrazumeva softver koji koristi 32-bitni adresni prostor tj. moe da adresira
232
kt
le
programi.
11 Sistem
na kome se vri prevoenje ne mora biti isti kao onaj na kome e se vriti izvra-
221
char
short
int
long
long long
pointer
32
ILP64
LP64
LLP64
8
16
16
16
16
32
64
32
32
32
64
64
32
64
64
64
64
32
64
64
(2
01
5)
tip
64
<stdint.h>.
Kada se koristi kompilator GCC, podrazumevani broj bitova odgovara sistemu na kojem se vri prevoenje. Ovo se moe promeniti opcijama
-m32 i -m64
je
9.3.3
an
Organizacija memorije
iz
odnosi se, ako to nije drugaije naglaeno, na irok spektar platformi, pa su,
zbog toga, nainjena i neka pojednostavljivanja.
sk
o
Kada se izvrni program uita u radnu memoriju raunara, biva mu dodeljena odreena memorija i zapoinje njegovo izvravanje. Dodeljena memorija
organizovana je u nekoliko delova koje zovemo segmenti ili zone:
kt
ro
n
le
U nastavku e biti opisana prva tri, dok e o hip segmentu biti vie rei u
Segment kda
Fon Nojmanova arhitektura raunara predvia da se u memoriji uvaju podaci i programi. Dok su ostala tri segmenta predviena za uvanje podataka,
u segmentu kda se nalazi sm izvrni kd programa njegov mainski kd
222
koji ukljuuje mainski kd svih funkcija programa (ukljuujui kd svih korienih funkcija koje su povezane statiki). Na nekim operativnim sistemima,
ukoliko je pokrenuto vie instanci istog programa, onda sve te instance dele isti
prostor za izvrni kd, tj. u memoriji postoji samo jedan primerak kda.
tom sluaju, za svaku instancu se, naravno, zasebno uva informacija o tome
do koje naredbe je stiglo izraunavanje.
(2
01
5)
Segment podataka
U segmentu podataka uvaju se odreene vrste promenljivih koje su zajednike za ceo program (one koje imaju statiki ivotni vek, najee globalne
promenljive), kao i konstantni podaci (najee konstantne niske).
Ukoliko
se istovremeno izvrava vie instanci istog programa, svaka instanca ima svoj
zaseban segment podataka. Na primer, u programu
an
d
iz
sk
o
#include <stdio.h>
int a;
int main() {
int b;
static double c;
printf("Zdravo\n");
return 0;
}
je
Program 9.7.
c,
ro
n
"Zdravo\n"
je lokalna
kt
le
Stek segment
U stek segmentu (koji se naziva i stek poziva (engl. call stack) ili programski
stek ) uvaju se svi podaci koji karakteriu izvravanje funkcija. Podaci koji
odgovaraju jednoj funkciji (ili, preciznije, jednoj instance jedne funkcije jer,
na primer, rekurzivna funkcija moe da poziva samu sebe i da tako u jednom
trenutku bude aktivno vie njenih instanci) organizovani su u takozvani stek
okvir (engl. stack frame). Stek okvir jedne instance funkcije obino, izmeu
ostalog, sadri:
argumente funkcije;
meurezultate izraunavanja;
223
12 . To znai da
se stek okvir moe dodati samo na vrh steka i da se sa steka moe ukloniti
(2
01
5)
samo okvir koji je na vrhu. Stek okvir za instancu funkcije se kreira onda kada
funkcija treba da se izvri i taj stek okvir se oslobaa (preciznije, smatra se
nepostojeim) onda kada se zavri izvravanje funkcije.
Ako funkcija
main,
main
main,
prvi stek
Ukoliko funkcija
funkciju, onda e za nju biti kreiran stek okvir na novom vrhu steka.
f,
Kada
an
je
f,
iz
zaista obrisan).
sk
o
Vrh steka
f(),
njeni argumenti,
Vrh steka
ro
n
main(),
lokalne promenljive,
Vrh steka
...
main(),
main(),
njeni argumenti,
njeni argumenti,
lokalne promenljive,
lokalne promenljive,
...
...
...
le
kt
njeni argumenti,
lokalne promenljive,
Levo: tokom
izvravanja
funkcije
main().
f()
nazad u funkciju
main().
Sredina:
main().
tokom
Desno:
izvravanja
f()
Veliina stek segmenta obino je ograniena. Zbog toga je poeljno izbegavati smetanje jako velikih podataka na segment steka. Na primer, sasvim
je mogue da u programu u nastavku, sa leve strane, niz
12 Ime
pristupa.
224
sa desne strane niz biti smeten u segment podataka i sve e tei oekivano.
Predefinisana veliina steka C prevodioca se moe promeniti zadavanjem odgovarajue opcije.
int a[1000000];
int main() {
...
}
(2
01
5)
int main() {
int a[1000000];
...
}
je
Program 9.8.
iz
an
kt
ro
n
sk
o
int main() {
int a[] = {1, 2, 3};
int s;
s = f(a, sizeof(a)/sizeof(int));
printf("s = %d, a = {%d, %d, %d}\n",
s, a[0], a[1], a[2]);
return 0;
}
le
U funkciji
main
sledeeg oblika
main:
13 :
114:
112:
108:
104:
100:
...
?
3
2
1
13 U
f.
a i ceo broj s.
main na steku se nalazi samo jedan stek okvir
<- s
<- a
f,
main
postavlja se stek
225
argumenta).
likom poziva.
Argumenti se inicijalizuju na vrednosti koje su prosleene priPrimetimo da je umesto niza preneta samo adresa njegovog
je
(2
01
5)
<- s
f:
kt
le
main:
<- a
main:
f:
s
i
n
a
<<<<-
iz
...
2
0
3
100
...
?
3
2
2
ro
n
main:
134:
130:
126:
122:
118:
114:
112:
108:
104:
100:
sk
o
f:
an
134:
130:
126:
122:
118:
114:
112:
108:
104:
100:
...
9
2
3
100
...
?
4
3
2
134:
130:
126:
122:
118:
114:
112:
108:
104:
100:
<<<<-
...
5
1
3
100
...
?
3
3
2
<<<<-
<- s
<- a
s
i
n
a
<- s
<- a
s
i
n
a
226
f:
134:
130:
126:
122:
118:
...
9
3
3
100
<<<<-
s
i
n
a
je
(2
01
5)
an
main. Nakon
main, poto se
printf,
a zatim i funkcije
Implementacija rekurzije.
iz
funkcije
Razmotrimo, kao
14
Program 9.9.
sk
o
ro
n
#include <stdio.h>
le
kt
int faktorijel(int n) {
if (n <= 0)
return 1;
else
return n*faktorijel(n-1);
}
int main() {
int n;
while(scanf("%d",&n) == 1)
printf("%d! = %d\n", n, faktorijel(n));
return 0;
}
Ukoliko je funkcija
faktorijel
pozvana za argument
5,
onda e na steku
poziva da se formira isto toliko stek okvira, za pet nezavisnih instanci funkcije.
14 Vrednost
227
jedan primerak izvrnog kda ove funkcije (u kd segmentu), a svaki stek okvir
pamti za svoju instancu dokle je stiglo izvravanje funkcije, tj. koja je naredba
u kd segmentu tekua.
(2
01
5)
9.3.4
je
vanja C programa.
an
Program 9.10.
#include <stdio.h>
int n = 10, sum;
ro
n
sk
o
iz
int main() {
int i;
for (i = 0; i < n; i++)
sum += i;
printf("sum = %d\n", sum);
return 0;
}
kt
dobijanje izvrnog kda potrebno prevesti tu jedinicu i povezati nastali objektni modul sa potrebnim delovima (objektnim modulima) unapred kompilirane
standardne biblioteke.
le
Nakon kompilacije sa
program.o
objdump.
ula
Na primer,
Name
Value
Class
main
|00000000|
T
n
|00000000| D
printf |
| U
sum
|00000004|
C
15 Primer
|
|
|
|
Type
FUNC
OBJECT
NOTYPE
OBJECT
Size
|00000050|
|00000004|
|
|
|00000004|
daje rezultat
Section
.text
.data
*UND*
*COM*
228
(2
01
5)
Simbol
.bss segment).
je
podataka koji moraju biti upisani u izvrnu datoteku, kod neinicijalizovanih podataka, umesto da se nule upisuju u izvrnu datoteku, u njoj se samo naglaava
vanja funkcije
main
an
njegova veliina. Prilikom uitavanja programa u glavnu memoriju, pre pozivri se inicijalizacija ovog segmenta na nulu. Primetimo
ebp
ebp,esp
esp,0xfffffff0
esp,0x20
DWORD PTR [esp+0x1c],0x0
16
15
44
d0
00
44
00
44
df
00
44
04
fc
00
29 <main+0x29>
edx,DWORD PTR ds:0x0
eax,DWORD PTR [esp+0x1c]
eax,edx
ds:0x0,eax
DWORD PTR [esp+0x1c],0x1
eax,ds:0x0
DWORD PTR [esp+0x1c],eax
13 <main+0x13>
eax,ds:0x0
DWORD PTR [esp+0x4],eax
DWORD PTR [esp],0x0
45 <main+0x45>
eax,0x0
ro
n
push
e5
mov
e4 f0
and
ec 20
sub
44 24 1c 00 00 00 mov
le
E
sk
o
<main>:
jmp
mov
mov
add
00 00
mov
1c 01
add
00 00
mov
1c
cmp
jl
00 00
mov
04
mov
00 00 00 00 mov
ff ff
call
00 00
mov
leave
ret
00 00 00 00
24 1c
kt
00000000
0: 55
1: 89
3: 83
6: 83
9: c7
10: 00
11: eb
13: 8b
19: 8b
1d: 01
1f: a3
24: 83
29: a1
2e: 39
32: 7c
34: a1
39: 89
3d: c7
44: e8
49: b8
4e: c9
4f: c3
main
iz
Mainski kd funkcije
objdump -d program.o.
00
24
00
24
00
24
24
ff
00
229
main)
Na primer, u instrukciji
Zadatak linkera je da na
printf
prepie u registar
eax).
Slino
(2
01
5)
ds),
44).
Zadatak linkera je da
ovaj poziv korektno razrei. Spisak stavki koje linker treba da razrei mogu da
se vide komandom
objdump -r program.o
nikakvo smisleno znaenje dok se u obzir ne uzme tabela relokacije i dok se sve
an
d
sk
o
iz
je
ro
n
poziv funkcije
na adresu
promenljive
45
kt
printf umetne
printf postati
2a
u segmentu
le
20
35)
sum
i adresu poetka
segmenta
ebp
230
strukcije predstavljaju tzv. prolog tekue funkcije i slue da pripreme novi stek
okvir (uva se adresa poetka starog stek okvira i to opet na steku, adresa
poetka novog stek okvira postaje adresa tekueg vrha steka, a vrh steka se
podie (ka manjim adresama) da bi se napravio prostor za uvanje lokalnih
promenljivih i slinih podataka na steku). Prevedeni kd podrazumeva da se
eax,
esp+0x1c
29.
eax.
u registar
(smetene u steku na
esp+0x1c)
(2
01
5)
promenljiva
Ukoliko je
je
poziv funkcije
an
jedan. Po zavretku petlje, kada uslov petlje vie nije ispunjen prelazi se na
iz
i zatim adresa format niske (iako je u trenutnom kdu za obe adrese upisana
to e biti promenjeno tokom povezivanja). Poziv
call
main
sk
o
leave i ret
ro
n
Instrukcije
ret
kt
le
poziva funkcija ili koristi promenljiva koja nije u njoj definisana (ve samo
deklarisana, kao to je sluaj sa funkcijom
printf
u prethodnom primeru),
kreiranje objektnog modula bie uspeno, ali samo od tog objektnog modula
nije mogue kreirati izvrni program (jer postoje pozivi funkcije iji mainski kd nije poznat usled nedostatka definicije ili postoje promenljive za koju
nije odvojena memorija, tako da referisanje na njih u objekntim modulima nisu
ispravna). U fazi povezivanja, linker razreava pozive funkcija i adrese promenljivih i konstanti traei u svim navedenim objektnim modulima (ukljuujui i
objektne module standardne biblioteke) odgovarajuu definiciju (maniski kd)
takve funkcije tj. definiciju (dodeljenu adresu) takve promenljive.
231
Ukoliko su svi takvi zahtevi uspeni, linker za sve pozive funkcija upisuje
adrese konkretne funkcije koje treba koristiti, za sva korienja promenljivih
ukazuje na odgovarajue konkretne promenljive i povezuje sve objektne module
u jedan izvrni program.
Kd dobijen povezivanjem obino i dalje nije u stanju da se autonomno
izvrava.
koriste odreen broj rutina niskog nivoa, ali se sve te rutine ne ugrauju u
Umesto da se te rutine ugrauju u
(2
01
5)
an
je
9.3.5
iz
sk
o
mogue predvideti neke greke koje se mogu javiti u fazi izvravanja programa.
Osim to je mogue da daje pogrean rezultat (emu je najei razlog pogrean
algoritam ili njegova implementacija), mogue je i da uspeno kompiliran provanja.
ro
n
gram prouzrokuje greke tokom rada koje uzrokuju prekid njegovog izvraTe greke mogu biti posledica greke programera koji nije predvideo
neku moguu situaciju a mogu biti i greke koje zavise od okruenja u kojem
kt
se program izvrava.
Jedna od najeih greaka u fazi izvravanja je nedozvoljeni pristup memoriji. Ona se, na primer, javlja ako se pokua pristup memoriji koja nije dodel-
le
jena programu ili ako se pokua izmena memorije koja je dodeljena programu,
ali samo za itanje (engl. read only).
Segmentation fault
Najei uzrok nastanka ovakve greke je pristup neadekvatno alociranom bloku
memorije (npr. ako je niz definisan sa
ementu
a[1000]
int a[10];,
NULL
232
(2
01
5)
toru programa jer je prevideo da moe doi do deljenja nulom i nije u programu
predvideo akciju koja to spreava.
Pitanje 9.3.1.
je
an
Pitanje 9.3.2.
Pitanje 9.3.3.
iz
Pitanje 9.3.4.
sk
o
u stek segmentu?
okviru.
Pitanje 9.3.5.
ro
n
Pitanje 9.3.6.
f,
kt
funkcije
le
Pitanje 9.3.7.
f?
u kd segmentu?
Pitanje 9.3.8.
Pitanje 9.3.9.
Pitanje 9.3.10.
233
segmentu memorije se uvaju automatske promenljive, u kom statike promenljive, a u kom dinamike?
Pitanje 9.3.11.
kakav im je ivotni vek? U kom segmentu memorije se uvaju mainske instrukcije prevedenog C programa?
Za svaku promenljivu u narednom kdu rei koji joj je nivo
(2
01
5)
Pitanje 9.3.12.
le
kt
ro
n
sk
o
iz
an
je
int a;
int f() {
double b; static float c;
}
(2
01
5)
Glava 10
an
je
Programer, u radu sa
iz
To otvara i
sk
o
Uzastopni
ro
n
bajtovi mogu se tretirati kao jedinstven podatak. Na primer, dva (ili etiri, u
zavisnosti od sistema) uzastopna bajta mogu se tretirati kao jedinstven podatak
celobrojnog tipa. Pokazivai (engl. pointer) predstavljaju tip podataka u C-u
kt
Iako
le
Jezik C razlikuje
1 Jedino
pokaziva tipa
void*
234
235
int
zapisuje se
int *.
Slino
int
dok je
p4
tipa
int:
(2
01
5)
int *p1;
int* p2;
int* p3, p4;
p1, p2 i p3 su pokazi-
niza
adresni operator vraa adresu svog operanda. On moe biti primenjen samo na
an
je
a i p rezervie prostor
10, a u prostor za p
da pokazuje na a.
Unarni operator
se upisuje vrednost
iz
adresa promenljive
sk
o
ro
n
kt
le
5.
*p = *p+a+3;.
Tako
ove mogunosti treba veoma oprezno koristiti i iskljuivo sa jasnim ciljem (koji
2 Postoje
adresu funkcije u segmentu koda, u emu e vie rei biti u poglavlju 10.8.
3 Simbol *
236
mogue je dodeliti
0 ne smatra se moguom).
0 obino
<stdio.h>, kao
se ko-
jasniji
NULL,
definisana u zaglavlju
(2
01
5)
Na primer
ili ak
je
an
na funkcije (o kojima e vie biti rei u poglavlju 10.8) nisu doputene (dovode
U nekim sluajevima, poeljno je imati mogunost opteg pokazivaa,
void*.
Za to
iz
se koristi tip
sk
o
void*
jer nije
mogue odrediti tip takvog izraza kao ni broj bajtova u memoriji koji predstavljaju njegovu vrednost.
ro
n
Takoe,
void*
nije
mogue vriti aritmetike operacije (o kojima e vie rei biti u poglavlju 10.4).
le
kt
Tako bi
int,
pokaziva, a ne
int),
int
koji je konstantan
(konstantna su oba).
Vrednost pokazivaa moe se dodeliti pokazivau istog tipa.
vrednost pokazivaa
dodeli pokazivau
Ukoliko se
vrednost promenljive
q,
237
pokaziva
p.
sadraja (slika 10.1). Plitko kopiranje je est uzrok greaka jer nakon plitkog
kopiranja oba pokazivaa ukazuju isti sadraj i izmenom sadraja preko jednog
pokazivaa, moda neoekivano, biva izmenjen sadraj na koji ukazuje i drugi
originalni pokaziva
(2
01
5)
pokaziva.
sadraj
originalni pokaziva
sadraj
novi pokaziva
kopija sadraja
an
je
kopija pokazivaa
iz
nati (engl. aligned), to znai, na primer, da svaki podatak koji zauzima etiri
bajta u memoriji mora poinjati na memorijskoj adresi koja je deljiva sa etiri
sk
o
char*
char zauzima
ro
n
int
le
kt
primer, tip
void*
char*
238
dobija
float
(2
01
5)
float f = 3.5f;
printf("%x\n", *( ( unsigned* )&f ));
Pravi nain da se ovaj zadatak rei je korienje unije, koja vri alijasovanje
ganizovanja unije vodi rauna o pitanjima koja mogu naruiti ispravnost rada
an
je
iz
ro
n
sk
o
int a;
void f(double *p) {
a = 1;
*p = 1.234;
g(a);
}
kt
le
Koje od ovih
239
Pitanje 10.1.2.
Pitanje 10.1.3.
unsigned char*?
unsigned char?
t:
Koliko
8 bajtova,
double *
na konkretnom sistemu
(2
01
5)
Pitanje 10.1.4.
unsigned char *?
Pitanje 10.1.5.
Pitanje 10.1.6.
an
umesto
je
koristiti izraz
Pitanje 10.1.7.
Za ta se on
Pitanje 10.1.8.
sk
o
celobrojna vrednost?
Pitanje 10.1.9.
deklaracije
ro
n
naredbi
iz
kt
le
4 Kao
promenljive tipa
int),
swap(x, y)
swap,
njegovog poetka.
240
xiy
ostaju nepromenjene.
swap
int, ve su
int*. Zato se kao argumenti ne mogu koristiti vrednosti x i y
ve njihove adrese &x i &y. Nakon poziva swap(&x, &y), kreira se stek okvir
za swap, obezbeuje se prostor za argumente pokazivakog tipa pa i pb i zatim
se vrednosti &x i &y kopiraju u taj prostor. Time se prenos argumenata vri po
swap(x, y).
(2
01
5)
an
je
pokazivakog tipa
iz
xiy
xiy
i razmenjuje im
su razmenjene. Na ovaj
scanf
koja je ve koriena.
sk
o
ro
n
Program 10.1.
#include <stdio.h>
le
kt
/ i %):
241
Objasniti na primeru.
Pitanje 10.2.2.
int a = 1, b = 2;
void f(int* p) {
p = &b;
}
int main() {
int *p = &a
f(p);
printf("%d\n", *p);
}
2.
#include<stdio.h>
void f(int* p) { p++; p += 2; p--; p = p + 1; }
an
je
(2
01
5)
1.
Pitanje 10.2.3.
sk
o
iz
int main() {
int a[] = {1, 2, 3, 4, 5}, *p = a, *q = a;
f(p); printf("%d\n", *p);
q++; q += 2; q--; q = q + 1; printf("%d\n", *q);
}
Ukoliko je potrebno da funkcija vrati vie od jedne vrednosti,
ro
n
Pitanje 10.2.4.
samo
kt
Napisati
argu-
le
void
Zadatak 10.2.1.
< 86400)
proteklih od prethodne ponoi izraunava trenutno vreme tj. broj sati, minuta i
sekundi.
sizeof(a)
int a[10];
10*sizeof(int).
int.
Izraz
Poetni element
242
niza je
a[0],
a deseti element je
elementa niza, o tipu elemenata niza, kao i o broju elemenata niza. Poslednje
dve informacije koriste se samo tokom kompilacije i ne zauzimaju memorijski
prostor u fazi izvravanja.
Za razliku od pokazivaa koji jesu l-vrednosti, imena nizova (u navedenom
a)
to nisu (jer
je
(2
01
5)
an
kao i obino, nema provere granica niza, pa je dozvoljeno pisati (tj. prolazi
iz
int* p)
p[3]).
sk
o
(bez obzira to
100
ro
n
na sistemu na kojem je
na kojoj poinje
smeten u memoriji
*(p+3)
tj.
kt
x+n
isto je to i
&x[n].
x[n]
isto je to i
*(x+n),
le
prednosti (na primer, iako funkcije ne primaju niz ve samo pokaziva na prvi
element, implementacija tih funkcija moe to da zanemari i sve vreme da koristi
int a[10];
int *b;
a[3] = 5; b[3] = 8;
a je ispravno deklarisan i mogue je pristupiti njegovom elementu na poziciji
b nije izvrena alokacija elemenata na koje se
pokazuje i, iako se pristup b[3] ispravno prevodi, on bi najverovatnije doveo do
niz
3,
243
greke prilikom izvravanja programa. Zato, svaki put kada se koristi operator
indeksnog pristupa, potrebno je osigurati ili proveriti da je memorija alocirana
na odgovarajui nain (jer kompilator ne vri takve provere).
Kao to je reeno, izraz
int [10]
a,
int *.
c:
int a[10];
int *b[10];
int (*c)[10];
U navedenom primeru, promenljiva
ima 10 bajtova. Promenljiva
je niz
int.
(2
01
5)
Izraz
10
pokazivaa na
char
char
i zauz-
i zauzima prostor
je
c je (jedan) pokaziva na
10 elemenata tipa char i zauzima onoliko prostora koliko i bilo koji drugi
pokaziva. Vrednost se promenljivoj c moe pridruiti, na primer, naredbom
c=&a;. Tada je (*c)[0] isto to i a[0]. Ukoliko je promenljiva c deklarisana, na primer, sa char (*c)[5];, u dodeli c=&a; e biti izvrena implicitna
an
niz od
iz
sk
o
funkcije. Umesto toga, kao argument funkcije se moe navesti ime niza i time
se prenosi samo pokaziva koji ukazuje na poetak niza. Funkcija koja prihvata
takav argument za njegov tip moe da ima
char a[]
ili
char *a.
Ovim se u
ro
n
funkciju kao argument prenosi (kao i uvek po vrednosti) samo adresa poetka
niza, ali ne i informacija o duini niza.
Kako se kao argument nikada ne prenosi itav niz, ve samo adresa poetka,
mogue je umesto adrese poetka proslediti i pokaziva na bilo koji element
kt
niza, kao i bilo koji drugi pokaziva odgovarajueg tipa. Na primer, ukoliko je
le
nema informaciju o tome koliko elemenata niza ima nakon prosleene adrese.
Pitanje 10.3.2.
a?
a+9?
ta je vrednost izraza
a + 3?
int a[10];,
ta je vrednost izraza
char a[10];
na
ta je vrednost izraza
*(a+3)?
244
Pitanje 10.3.3.
Da li se komanda
ip = *a[0]?
Pitanje 10.3.4.
za svaku pojedi-
float* x[10],
Da li je vrednost
a[0]+i;
nano) (a)
Pitanje 10.3.5.
(b)
a+i;
(c)
Pitanje 10.3.6.
tipa
int*.
Neka je niz
Da li je naredba
Pitanje 10.3.7.
Niz je deklarisan sa
an
Pitanje 10.3.8.
Da li mu je
je
(2
01
5)
(d)
*d = b + 2; *c = d[-1];
iz
sk
o
Pitanje 10.3.9.
ro
n
prenosi u funkciju: (i) adresa poetka niza; (ii) elementi niza; (iii) podatak o
broju elemenata niza; (iv) adresa kraja niza?
kt
Pitanje 10.3.10.
le
pravne?
p+1
sizeof(int)
bajtova).
int
(tj. vrednosti
Na primer, ako je
p+1
pokaziva na
p se razlikuju
int koji sadri
245
adresu
adresa
vrednost
p+3
e biti
++
--,
sa slinom
I u tom sluaju se ne
(2
01
5)
p1
&i*
p2.
*p+1
p+1).
Unarni operatori
Postfiksni operator
an
p.
&, *,
i prefiksni
pi
++
je
p1 < p2
primenjuju sleva na desno, imaju vii prioritet od unarnih operatora koji se priinkrementira.
*p++
p,
iz
Program 10.2.
sk
o
tavni primer.
kt
ro
n
#include <stdio.h>
int main() {
int a[] = {8, 7, 6, 5, 4, 3, 2, 1};
int *p1, *p2, *p3;
/* Ispis elemenata niza */
printf("%d %d %d\n", a[0], a[3], a[5]);
le
246
8
8
7
7
6
5
5
3
6
5
3
3
4
1 6
6
(2
01
5)
Ako je
p += 5;?
Pitanje 10.4.2.
int*,
Ako su promenljive
zlikovati vrednosti
ta je efekat naredbe
nakon komande
*p += 5;
q tipa double *, za
p = q+n (pri emu
a ta
koliko e se raje
celobrojna
iz
promenljiva)?
Pitanje 10.4.3.
tipa
efekat naredbe
an
Pitanje 10.4.1.
je
ro
n
Pitanje 10.4.4.
sk
o
Pitanje 10.4.5.
p1 i p2
kt
tipa
int*)?
tipa
int)?
Pitanje 10.4.6.
le
E
vrednosti:
Pitanje 10.4.7.
Ako su
konstrucija ispravna:
p=NULL;
p1=p1+10;
(7) p1=(p1-p1)+0;
(10) p1=p1-(p2+10);
(13) p1=p1+(p2-p3);
(16) p1=p1+(p2+p3);
(1)
(4)
Pitanje 10.4.8.
p1, p2, p3
p=10;
p1=(p1+p1)+0;
(8) p1=(p1-p1)+10;
(11) p1=p1+(p1-p2);
(14) p1=(p1+p2)-p3;
(2)
(5)
p1=p1+0;
p1=(p1+p1)+10;
(9) p1=(p1-p2)+10;
(12) p1=p1-(p1-p2);
(15) p1=(p1+p2)+p3;
(3)
(6)
247
p += 2;?
2. Ako je
tipa
float*,
4. Ako je
pokaziva tipa
T,
p += 2;?
emu je jednako
Pitanje 10.4.10.
b nakon
a+b i a-b?
Da li nakon
Da li su
int* a, b;?
Da li su
(b)
deklaracije
iz
*(p++);
neki
deklaracije
a kog tipa
dozvoljene operacije
an
a,
2. Kog je tipa
y nakon
x+y i x-y?
a kog tipa
(gde je
je
x,
dozvoljene operacije
T *
p + 3?
Pitanje 10.4.9.
1. Kog je tipa
tipa
(2
01
5)
p+5 i p?
"informatika",
sk
o
u memoriji su realizovane slino kao nizovi karaktera: karakteri su poreani redom na uzastopnim memorijskim lokacijama i iza njih se nalazi zavrna nula
(\0) koja oznaava kraj niske. Konstantne niske se u memoriji uvek uvaju
u segmentu podataka.
printf("%d", x);),
ro
n
char *p = "informatika";.
Uko-
kt
liko je takva deklaracija navedena u okviru neke funkcije, onda se u njenom stek
le
"informatika"
i, p[1]
je jednako
"informatika" i p[0]
je
(na primer,
p[0]=x;
p[1]=x;)
ili
prolazi fazu
(na primer,
Na primer, deklaracijom
248
a duine 12 i
"informatika". U
ovoj situaciji, dozvoljeno je menjanje vrednosti a[0], a[1], ..., a[9], ali nije
dozvoljeno menjanje vrednosti a. Dakle, a nije l-vrednost, ali, na primer, a[0]
sa inicijalizacijom
kreira se niz
jeste.
Razmotrimo kao ilustraciju rada sa pokazivaima na karaktere nekoliko
(2
01
5)
argument
an
je
iz
*s != \0,
*s):
ro
n
sk
o
kt
le
strcpy koja prihvata dva karakterska pokazivaa (ili dve niske) i sadraj druge
kopira u prvu. Da bi jedna niska bila iskopirana u drugu nije, naravno, dovoljno
prekopirati pokaziva, ve je neophodno prekopirati svaki karakter druge niske
pojedinano.
samo pokaziva
je plitko kopiranje i to esto nije ono to programer eli (npr. bilo kakva izmena
sadraja putem pokazivaa
s).
249
(2
01
5)
s dodeli niski t
strcpy, iju emo jednu moguu implementaciju
je
opisati.
iz
an
sk
o
se moe
le
kt
ro
n
while
petlje:
250
}
U navedenoj implementaciji funkcije
je da se sadraj lokacija na koje ukazuje
Pitanje 10.5.1.
(2
01
5)
Pitanje 10.5.2.
Nakon koda
an
je
void f() {
char* a = "Zdravo";
char b[] = "Zdravo";
...
}
Pitanje 10.5.3.
aib
a?
b?
p?
iz
Da li se vrednosti
a?
na ta pokazuje promenljiva
a,
a koliko
nakon naredbi:
Razmotriti funkciju:
ro
n
Pitanje 10.5.4.
sk
o
int i;
char a[] = "informatika";
i = strlen(a+2) ? strlen(a+4) : strlen(a+6);
le
kt
char *dan(int n) {
static char *ime[] = {
"neispravna vrednost", "ponedeljak", "utorak", "sreda",
"cetvrtak", "petak","subota", "nedelja"
};
return (n < 1 || n > 7) ? ime[0] : ime[n];
}
ta se postie navedenim kvalifikatorom
Koliko bajtova zauzima niz
ime
static?
static?
Zadatak 10.5.1.
ime
ime[0]?
strcmp.
strcpy.
strlen.
Navesti
251
strrev.
strstr.
strchr.
Navesti jednu
vaku sintaksu.
(2
01
5)
je
int a[10][20];
an
Svaki od izraza
iz
te ima tip
ima tip
sk
o
int (*)[20],
a drugi tip
int*.
a[0]+i
je jednako
ro
n
a[i],
&a[0][i].
a+i
jednako
Ako
su date deklaracije
kt
int a[10][20];
int *b[10];
le
252
ovi pokazivai mogu biti razliite duine. Tako, svaki element niza
ne mora
Razmotrimo primer niza koji treba da sadri imena meseci. Jedno reenje
je zasnovano na dvodimenzionom nizu (u koji se, prilikom inicijalizacije upisuju
imena meseci):
(2
01
5)
char meseci[][10] = {
"Greska", "Januar", "Februar", "Mart", "April",
"Maj", "Jun", "Jul", "Avgust", "Septembar",
"Oktobar", "Novembar", "Decembar"};
Poto meseci imaju imena razliite duine, bolje reenje je napraviti niz
pokazivaa na karaktere i inicijalizovati ga da pokazuje na konstantne niske
menata niza poto je izvrena inicijalizacija):
je
iz
an
char *meseci[] = {
"Greska", "Januar", "Februar", "Mart", "April",
"Maj", "Jun", "Jul", "Avgust", "Septembar",
"Oktobar", "Novembar", "Decembar"};
Slika 10.2 ilustruje slian primer memoriju koja odgovara nizovima
aib
sk
o
ro
n
le
tipa
kt
Pitanje 10.6.1.
Pitanje 10.6.2.
Da li se matrica
a[3][3];
(e)
Pitanje 10.6.3.
deklaracije
a[3*3]?
Nakon deklaracije
int b[10][20];
dimenzije
float.
Pitanje 10.6.4.
Pitanje 10.6.5.
dimenzija 10, 9, 8?
253
Segment podataka
a b c d
0
g h i
(2
01
5)
e f
Stek segment
b
[0] [1] [2]
a a b c d
e f
g h i
an
je
[0][0] [0][1] [0][2] [0][3] [0][4] [1][0] [1][1] [1][2] [1][3] [1][4] [2][0] [2][1] [2][2] [2][3] [2][4]
iz
Pitanje 10.6.6.
sk
o
Pitanje 10.6.7.
ro
n
1. Da li je nakon deklaracije
char a[3][3],
naredba
a[0][0] = a;
(a)
a[0][0] = a;
(a)
char* a[3];,
naredba
kt
le
Pitanje 10.6.8.
Pitanje 10.6.9.
(a)
(c)
char* a[10];
int a[][2]=(1,2,3,4);
int a[][2]={1,2,3,4};
Pitanje 10.6.10.
(b)
(d)
int a[2][]=(1,2,3,4);
int a[2][]={1,2,3,4};
sizeof(a) i sizeof(b)
nakon deklaracija
Pitanje 10.6.11.
narednih deklaracija:
Pitanje 10.6.12.
temu.
254
Pitanje 10.6.13.
a emu
sizeof(b)?
void f() {
char* a = "Zdravo";
char b[] = "Zdravo";
...
}
U kom segmentu memorije se nalazi promenljiva
je ono na ta pokazuje promenljiva
ta pokazuje promenljiva
a?
je
Pitanje 10.6.14.
b?
a?
(2
01
5)
emu je jednako
an
iz
* i ., mogue
->. I operator -> je operator najvieg prioriteta. Na
(*pa).imenilac moe se pisati pa->imenilac:
sk
o
je koristiti operator
ro
n
p.
a,
Dodelom
kt
vakog tipa
a=b;
b.p.
p,
le
je ukazivao pokaziva
b.p).
ukazivae na
koristi (pre svega zbog utede memorije), ono je est uzrok greaka i pokazivae sadrane u strukturama esto je poeljnije duboko kopirati (to zahteva
dodatan trud programera).
Strukture se kao argumenti u funkciju prenose po vrednosti.
S obzirom
na to da strukture esto zauzimaju vie prostora od elementarnih tipova podataka, est je obiaj da se umesto struktura u funkcije proslede njihove adrese,
tj. pokazivai na strukture. Na primer,
255
pa->imenilac*pb->brojilac;
pc->imenilac = pa->imenilac*pb->imenilac;
(2
01
5)
Program 10.3.
an
je
#include <stdio.h>
sk
o
iz
le
kt
ro
n
print(b, N);
256
mul2(a, N, b);
even0(a, N, b);
print(b, N);
print(b, N);
return 0;
u niz
b,
(2
01
5)
a:
#include <stdio.h>
an
je
iz
ro
n
sk
o
le
kt
#define N 8
int main() {
int a[N] = {1, 2, 3, 4, 5, 6, 7, 8}, b[N];
map(a, N, b, &inc1);
ispisi(b, N);
map(a, N, b, &mul2);
ispisi(b, N);
map(a, N, b, &parni0); ispisi(b, N);
return 0;
Funkcija
map
int.
257
*double, a prima
double i int, dok promenljiva b oznaava pokaziva na funkciju
rezultat tipa double, a prima argumente tipa double i int.
promenljiva
(2
01
5)
argumente tipa
koja vraa
je
an
a predstavlja niz od 3 pokazivaa na funkcije koje vraaju int, i primaju arguint. Funkcije ije se adrese nalaze u nizu se mogu direktno i pozvati.
Na primer, naredni kd ispisuje vrednost 4:
iz
ment tipa
sk
o
printf("%d", (*a[0])(3));
ro
n
Deklarisati funkciju
float.
kt
argument tipa
Pitanje 10.8.2.
strcmp
le
gde je
Pitanje 10.8.3.
moe da bude
f(strcmp),
Ako se funkcija
Pitanje 10.8.4.
f iji poziv
string.h.
Deklarisati funkciju
funkcija deklarisana u
int
char i
povratnog tipa
tipa
kao
5 Iako
int
int
int
int
samo ime pokazivaa (na primer, u prethodnom programu je bilo mogue navesti
map(a, N,
258
Pitanje 10.8.5.
Obrazloiti odgovor.
Pitanje 10.8.6.
Date su deklaracije:
a kog
Pitanje 10.8.7.
a2?
Kog je tipa
deklarisano sa:
double (*x[3])(int);
2.
3.
int *x (double);
4.
5.
iz
Zadatak 10.8.1.
1.
je
a1,
an
Kog je tipa
(2
01
5)
sk
o
ro
n
kt
le
259
10.9.1
<stdlib.h>).
Prostor za
malloc
(2
01
5)
(engl. heap).
n bajtova i
void*). U
malloc
NULL. Memorija
je
na koju funkcija
u principu, nedefinisan (tj. zavisi od podataka koji su ranije bili uvani u tom
Funkcija
an
delu memorije).
ativni celobrojni tip za ije vrednosti je rezervisano najmanje dva bajta. Ovaj
sk
o
iz
ro
n
kt
le
void*
dereferenciranja
malloc()
(ili
utvrdi da je funkcija
se prijaviti korisniku
odgovarajua poruka ili pokuati neki metod oporavka od greke. Dakle, najei scenario upotrebe funkcije
malloc
je sledei:
260
assert
(2
01
5)
se
raunanje izraza
vrednosti
calloc).
U trenutku kada dinamiki alociran blok memorije vie nije potreban, poeljno
je osloboditi ga. To se postie funkcijom
free:
an
je
free(p) oslobaa memoriju na koju ukazuje pokaziva p (a ne memp), pri emu je neophodno da p
pokazuje na blok memorije koji je alociran pozivom funkcije malloc ili calloc.
Poziv
iz
sk
o
Re-
ro
n
kt
le
Program 10.4.
#include <stdio.h>
#include <stdlib.h>
int main() {
int n, i, *a;
/* Unos broja elemenata */
scanf("%d", &n);
/* Alocira se memorija */
if ((a = (int*)malloc(n*sizeof(int))) == NULL) {
261
return 0;
(2
01
5)
}
/* Unos elemenata */
for (i = 0; i < n; i++) scanf("%d",&a[i]);
/* Ispis elemenata u obrnutom poretku */
for (i = n-1; i >= 0; i--) printf("%d ",a[i]);
/* Oslobadjanje memorije */
free(a);
realloc,
iji je prototip:
an
je
Parametar
parametar
iz
sk
o
ro
n
kopira na to novo mesto i zatim se stari blok memorije oslobaa. Ova operacija
moe biti vremenski zahtevna.
Upotreba funkcije
kt
Kako esta
le
desetog elementa.
Program 10.5.
#include <stdio.h>
#include <stdlib.h>
#define KORAK 256
int main() {
int* a = NULL;
262
int duzina = 0;
/* broj popunjenih elemenata niza */
int alocirano = 0; /* broj elemenata koji mogu biti smesteni */
int i;
do {
printf("Unesi ceo broj (-1 za kraj): ");
scanf("%d", &i);
je
(2
01
5)
iz
an
/* Ispis elemenata */
printf("Uneto je %d brojeva. Alocirano je %d bajtova\n",
duzina, alocirano*sizeof(int));
printf("Brojevi su : ");
for (i = 0; i<duzina; i++)
printf("%d ", a[i]);
return 0;
ro
n
sk
o
/* Oslobadjanje memorije */
free(a);
realloc
main
bi
le
kt
if (duzina == alocirano) {
/* Kreira se novi niz */
int* new_a;
alocirano += KORAK;
new_a = malloc(alocirano*sizeof(int));
/* Kopira se sadrzaj starog niza u novi */
for (i = 0; i < duzina; i++) new_a[i] = a[i];
/* Oslobadja se stari niz */
free(a);
/* a ukazuje na novi niz */
a = new_a;
}
U ovoj implementaciji, prilikom svake realokacije vri se premetanje mem-
realloc.
263
a = realloc(a, alocirano*sizeof(int));
U nekim sluajevima ova konstrukcija moe da bude neadekvatna ili opasna.
Naime, ukoliko zahtev za proirenje memorijskog bloka ne uspe, vraa se vred-
NULL,
nost
upisuje u promenljivu
10.9.2
(2
01
5)
Curenje memorije.
je
an
program vie nema mogunost da oslobodi taj blok memorije i on biva zauvek
(zapravo do kraja izvravanja programa) izgubljen (rezervisan za korienje
iz
sk
o
char* p;
p = (char*) malloc(1000);
....
p = (char*) malloc(5000);
ro
n
Inicijalno je 1000 bajtova dinamiki alocirano i adresa poetka ovog bloka memorije smetena je u pokazivaku promenljivu
p.
rano 5000 bajtova i adresa poetka tog bloka memorije je opet smetena u
promenljivu
p.
kt
rienjem funkcije
free,
p,
le
U takvim situacijama moe da se gubi malo po malo memorije, ali tokom dugtrajnog izvravanja programa, pa ukupna koliina izgubljene memorije moe
da bude veoma velika.
ulazima. Meutim, kada se program pusti u rad i kada pone da radi dui vre-
264
menski period (moda i bez prestanka) i da obrauje vee koliine ulaza, curenje
memorije postaje vidljivo, ini program neupotrebljivim i moe da uzrokuje velike tete.
Veina programa za otkrivanje greaka (debagera) detektuje da u programu
postoji curenje memorije, ali ne moe da pomogne u lociranju odgovarajue
greke u kdu.
rije (engl.
(2
01
5)
memorije.
pokazuje pokaziva
free(p),
odmah
p,
mogue je da
postavi na
NULL.
an
je
pristupa osloboenoj memoriji biti odmah prepoznat tokom izvravanja programa i operativni sistem e zaustaviti izvravanje programa sa porukom o
segmentation fault).
iz
greci (najee
Nakon poziva
sk
o
poziv
ro
n
bezbednosnih problema.
Funkciji
kt
le
Kao i u
265
koji slobodni. Zato, i malo prekoraenje granice bloka prilikom upisa moe da
promeni te dodatne informacije i da uzrokuje pad sistema za dinamiko upravljanje memorijom. Postoje i mnogi drugi sluajevi u kojima prekoraenje i
potkoraenje bafera mogu da narue ispravno izvravanje programa ili dovedu
do njegovog pada.
Fragmentisanje memorije
(2
01
5)
10.9.3
koje esto vre dinamiku alokaciju i dealokacije memorije) tokom dugog rada
pokazuju degradaciju u performansama i na kraju prekidaju svoj rad na nepredvieni nain.
U sluaju
je
jaturizovan) primer.
100101011000011101010110,
postoji
an
111111111111111100000000
ima samo 8 slobodnih bajtova, ali jeste u stanju da izvri alokaciju 5 traenih
iz
bajtova. Memoriju na hipu dodeljenu programu nije mogue automatski reorganizovati u fazi izvravanja, jer nije mogue u toj fazi aurirati sve pokazivae
sk
o
ro
n
kt
rati prostor za nekoliko njih odjednom (kao to je to, na primer, bilo raeno
u primeru datom prilikom opisa funkcije
realloc).
le
10.9.4
U poglavlju 9.3.3, reeno je da je memorija dodeljena programu organizovana u segment kda, segment podataka, stek segment i hip segment.
Hip
vraaju adresu u hip segmentu. Objekti koji su alocirani u slobodnom memorijskom prostoru nisu imenovani, ve im se pristupa iskljuivo preko adresa.
Poto ovi objekti nisu imenovani, oni nemaju definisan doseg (a doseg pokazi-
266
vaa putem kojih se pristupa dinamikim objektima podlee standardnim pravilima). Svi objekti koji su dinamiki alocirani imaju dinamiki ivotni vek. Ovo
znai da se memorija i alocira i oslobaa iskljuivo na eksplicitni zahtev i to
tokom rada programa.
Hip segment obino poinje neposredno nakon segmenta podataka, a na
suprotnom kraju memorije od stek segmenta. Obino se podaci na hipu slau
od manjih ka veim adresama (engl. upward growing), dok se na steku slau
(2
01
5)
trenutku kada se iscrpi memorijski prostor dodeljen programu, hip i stek po-
je
Pitanje 10.9.1.
an
malloc;
calloc;
iz
realloc;
sk
o
free.
Pitanje 10.9.2.
realloc
free
ako je:
ro
n
Fukcija
kt
le
Pitanje 10.9.3.
char *p;
p = (char*)malloc(n);
komanda
strcpy(p,"test");
Pitanje 10.9.4.
bezbedna?
Pitanje 10.9.5.
vaa na neki dinamiki alocirani blok memorije? Zato je ova pojava opasna?
267
Pitanje 10.9.6.
p = (int*)malloc(sizeof(int)*5)
slede komanda/komande:
q = (int*)malloc(sizeof(int)*5);
p = (int*)malloc(sizeof(int)*5);
(2
01
5)
free(p); free(p);
free(p+1);
Pitanje 10.9.7.
an
Pitanje 10.9.8.
je
int *f = malloc(4*sizeof(int));
int* g = f;
free(g);
free(f);
f=g;
*p?
Pitanje 10.9.10.
free(p);?
free(p),vrednost
iz
vrednost
pokazivaa
p,
a ta
sk
o
Pitanje 10.9.9.
ta se time postie?
ro
n
Pitanje 10.9.11.
Pitanje 10.9.12.
kt
le
Pitanje 10.9.13.
Pitanje 10.9.14.
free
malloc, calloc i realloc?
proslediti
Pitanje 10.9.15.
ne koristi rekurzija?
268
Zadatak 10.9.1.
,
sa standardnog ulaza.
Program treba da vrati indeks broja u nizu (ako se nalazi u ) ili indeks
od
Zadatak 10.9.2.
pojave brojevi:
5.
2 5 12 4 5 2 3 12 15 5 6 6 5
(2
01
5)
broj se pojavio najvie puta meu tim brojevima. Na primer, ako se na ulazu
program treba da vrati broj
Zadatak 10.9.3.
dimenzije matrice ( i
je
Zadatak 10.9.4.
an
1. Napisati funkciju
= (1 , . . . , ) i = (1 , . . . , )
)
je suma
2. Napisati funkciju
= 1 1 + 2 2 + . . . +
iz
tora
sk
o
ro
n
n, a
le
kt
(2
01
5)
Glava 11
je
an
iz
sk
o
konkretnog sistema.
ro
n
kt
pregled svih dvadeset devet zaglavlja. Ove datoteke, zajedno sa izvornim kdom programa bivaju ukljuene u proces kompilacije (korienjem pretproce-
le
#include).
Najkompleksnije zaglavlje
269
stdio.h
bie opisano u
270
Datoteka zaglavlja
Od
<assert.h>
<complex.h>
<ctype.h>
C89
Makro
C99
C89
(2
01
5)
assert.
<errno.h>
C89
<fenv.h>
C99
<float.h>
C89
<inttypes.h>
<iso646.h>
<limits.h>
C99
NA1
C89
<locale.h>
<math.h>
<setjmp.h>
<signal.h>
<stdalign.h>
<stdarg.h>
C89
Funkcije za lokalizaciju.
C89
C89
Makroi
C89
C11
C89
<stdatomic.h>
C11
lioteke funkcije.
<stdnoreturn.h>
<string.h>
<tgmath.h>
<threads.h>
<time.h>
<uchar.h>
<wchar.h>
<wctype.h>
je
an
isna od implementacije.
iz
setjmp i longjmp.
etara
sk
o
bool.
C99
Tip
C89
ro
n
kt
<stdint.h>
<stdio.h>
<stdlib.h>
le
<stdbool.h>
<stddef.h>
NULL i
size_t).
C99
C89
C89
C11
C89
C99
C11
C89
C11
NA1
NA1
271
size_t strlen
(char* str);
char*
char*
char*
char*
strcpy
strncpy
strcat
strncat
(char*
(char*
(char*
(char*
int
int
char*
char*
char*
char*
char*
char*
char*
source);
source, size_t num);
source);
source, size_t num);
(2
01
5)
destination,
destination,
destination,
destination,
strtok
strlen
Funkcija
sk
o
strcpy
iz
char*
an
je
strcpy
Funkcija
strncpy takoe vri kopiranje, ali se dodatn kontrolie najvei broj karaktera koji moe biti kopiran (u sluaju da je niska koja se kopira kraa od broja n ostatak se popunjava nulama, a ukoliko je dua od broja n terminalna nula se ne dodaje
automatski na kraj). Korienje funkcije strncpy smatra se bezbednijim
od strcpy jer je mogue kontrolisati mogunost prekoraenja bafera.
ro
n
kt
nim parameterom
Funkcija
le
strcat
jajui da prva niska ima dovoljno prostora da smesti i sve karaktere druge,
ukljuujui i njenu terminalnu nulu (terminalna nula prve niske se brie).
Funkcija
strncat
dodatnim parametrom
strchr
Funkcija
strpbrk
Funkcija
272
strstr
strstr
Funkcija
strspn
Funkcija
strspn
NULL.
strtok
(2
01
5)
U prvom pozivu funkcije kao prvi argument navodi se niska koja se deli,
a u drugom navodi se
NULL.
Na primer, kd
iz
an
je
ro
n
Ovo
je
jedna
niska
sk
o
ispisuje
kt
le
void
void
void
void
int rand(void);
void srand(unsigned int);
int system(char* command);
void exit(int);
Ve smo naveli da se u zaglavlju
273
rand
int rand(void); generie pseudo-sluajne cele brojeve u interRAND_MAX (koja je takoe definisana u zaglavlju
<stdlib.h>). Termin pseudo-sluajni se koristi da se naglasi da ovako
Funkcija
valu od 0 do vrednosti
dobijeni brojevi nisu zaista sluajni, ve su dobijeni specifinim izraunavanjima koja proizvode nizove brojeva nalik na sluajne. Funkcija
rand()
[0, 1)
nain:
(2
01
5)
an
je
n+rand()%(m-n+1)
sledei nain:
iz
sk
o
srand
ro
n
kt
funkcije
le
vreme (npr.
system("date");
aktivira se program
date
koji
274
system
system
nije vrednost
NULL,
onda funkcija
1 vraa se u sluaju
(2
01
5)
exit
Funkcija
void exit(int);
funkcije je pozvana) i vraa svoj argument kao povratnu vrednost programa. Obino povratna vrednost nula oznaava uspeno izvrenje pro-
EXIT_SUCCESS EXIT_FAILURE za
exit(e); u okviru funkcije main ekvivanaredbi return e;. Funkcija exit automatski poziva fclose
datoteku otvorenu u okviru programa (vie o funkciji fclose
je
an
c);
c);
c);
c);
int
int
int
int
isdigit(int
isspace(int
islower(int
tolower(int
sk
o
isalpha(int
isalnum(int
isupper(int
toupper(int
c);
c);
c);
c);
ro
n
int
int
int
int
iz
Zaglavlje
ctype.h
int
kt
int
isupper(c)
islower(c)
isdigit(c)
isalnum(c)
isspace(c)
le
isalpha(c)
toupper(c)
vraa karakter
sm karakter
c;
275
tolower(c)
vraa karakter
sm karakter
c;
Zaglavlje
double
double
double
double
double
asin(double);
acos(double);
atan(double); double atan2(double);
log10(double); double log2(double);
exp(double); double sqrt(double);
(2
01
5)
double
double
double
double
double
atikih funkcija. Svaka od njih ima jedan ili dva argumenta tipa
kao tip povratne vrednosti.
sin(x)
sin(),
smatra se da je
cos(x)
cos(),
smatra se da je
koordinatni poetak.
an
zadato u radijanima;
zadato u radijanima;
-osu take , .
sk
o
vraa vrednost
(, ].
iz
exp(x)
atan2(y, x)
je
double
log10(x)
log2(x)
ro
n
log(x) vraa vrednost ln (mora da vai > 0); logaritam log (za , > 0,
= 1) moe se izraunati kao log(b)/log(a).
vraa vrednost
vraa vrednost
pow(x,y)
log10
log12
(mora da vai
(mora da vai
kt
> 0);
vraa vrednost
le
E
fabs(x)
> 0);
da vai
> 0);
vrednost
moe se
itd.
M_PI
, M_E
broja
, M_SQRT2
broja
276
(2
01
5)
je
ime
an
iz
assert
sk
o
grama koje nisu logike (na primer, neka datoteka ne moe da se otvori)
ve samo na one logike greke koje ne smeju da se dogode. U zavrnoj
verziji programa, pozivi funkcije
assert
ro
n
kt
le
Pitanje 11.5.2.
cos?
Kako
strcpy.
Navesti i
Pitanje 11.5.3.
rand?
nim
Pitanje 11.5.4.
Pitanje 11.5.5.
efekat makroa
n<m)?
ta je efekat funkcije
exit?
assert
assert?
Kakav je
(2
01
5)
Glava 12
je
an
podrane samim jezikom, ve specijalizovanim funkcijama iz standardne biblioteke jezika (koja je prisutna u svakom C okruenju). Poto su ove funkcije
deo standarda jezika C, mogu se koristiti u programima uz garantovanu prenosivost programa izmeu razliitih sistema.
iz
<stdio.h>.
sk
o
ro
n
izlaza. Ulaz i izlaz se modeluju tzv. tokovima (engl. stream) podataka (obino
pojedinanih bajtova ili karaktera).
se unose sa tastature.
kt
prikazuju na ekranu.
greke na koji se obino upuuju poruke o grekama nastalim tokom rada pro-
le
onda program
prog
infile,
umesto sa tastature.
Takoe, mnoga okruenja omoguavaju da se izvri preusmeravanje (redirekcija) standardnog izlaza u neku datoteku. Na primer, ukoliko se program
pokrene sa
277
278
onda program
prog
outfile,
umesto na ekran.
(2
01
5)
12.1.1
getchar:
je
an
int getchar(void);
getchar vraa sledei karakter sa ulaza, svaki put kada se pozove, ili
EOF kada doe do kraja toka. Simbolika konstanta EOF je definisana u zaglavlju
<stdio.h>. Njena vrednost je obino -1, ali umesto ove konkretne vrednosti
ipak treba koristiti ime EOF. Funkcija getchar (kao i jo neke srodne funkcije)
umesto tipa char koristi tip int koji je dovoljno irok da u njega mogu da se
smeste kako ASCII vrednosti od 0 do 127, tako i specijalna vrednost EOF, tj. -1.
Ako bi povratni tip funkcije getchar bio char, a povratna vrednost u nekom
konkretnom sluaju jednaka EOF (tj. konstantna vrednost -1), na sistemima na
kojima je tip char podrazumevano neoznaen, vrednost EOF bi se konvertovala
u 255, pa bi poreenje getchar() == EOF bilo netano (jer bi sa leve strane
bila vrednost 255 koja bi pre poreenja sa -1 bila promovisana u tip int).
Funkcija getchar() najee se realizuje tako to karaktere uzima iz privre-
ro
n
sk
o
iz
Funkcija
kt
menog bafera koji se puni itanjem jedne po jedne linije ulaza. Dakle, u interaktivnom radu sa programom,
getchar()
le
putchar:
int putchar(int);
Funkcija
putchar(c)
EOF
tampa karakter
1U
standardnoj biblioteci ne postoji funkcija koja ita samo jedan karakter, ne cekajuci
kraj ulaza.
279
mala slova.
Program 12.1.
#include <stdio.h>
#include <ctype.h>
je
Funkcija
(2
01
5)
int main()
{
int c;
while ((c = getchar()) != EOF)
putchar(tolower(c));
return 0;
}
velikih slova u karaktere malih slova, ne menjajui pri tom ostale karaktere.
getchar i putchar
iz
<stdio.h> i tolower
an
Funkcije poput
iz
<ctype.h>
gets:
sk
o
12.1.2
iz
Biblioteka funkcija
ro
n
ita karaktere sa standardnog ulaza do kraja tekue linije ili do kraja datoteke
i karaktere smeta u nisku s. Oznaka kraja reda se ne smeta u nisku, a niska
s sadri
gets ini veoma
proitan, gets vraa s, a
kt
le
inae vraa
NULL
pokaziva.
fputs:
Biblioteka funkcija
puts
vraa
EOF
u sluaju
280
12.1.3
Formatirani izlaz
printf
Funkcija
printf
Funkcija
(2
01
5)
putchar
printf
mogu biti
printf
Funkcija
dardni izlaz pod kontrolom date format niske . Format niska sadri dve vrste
objekata:
printf.
je
iz
menta.
Izmeu % i karaktera
an
Konvertovani argument se
sk
o
.,
Taka
Broj za preciznost, koji specifikuje najvei broj karaktera koje treba tam-
ro
n
pati iz niske u sluaju tampanja niske ili broj taaka iza decimalne take
u sluaju broja u pokretnom zarezu ili najmanji broj cifara u sluaju
kt
celog broja.
Karakter
le
h, ako ceo broj treba da se tampa kao short, ili l ako ceo broj
long.
Konverzioni karakteri
Konverzioni karakteri su prikazani u narednoj tabeli. Ukoliko se nakon %
navede pogrean konverzioni karakter, ponaanje je nedefinisano.
2 Funkcija printf
argumenata (tj. broj argumenata u pozivima ne mora uvek da bude isti). Programer moe
stdarg.h.
281
Karakter
Tip
d,i
o
x,X
int
int
int
tampa se kao
dekadni broj
neoznaeni oktalni broj (bez vodeeg simbola 0)
neoznaeni heksadekadni broj (bez vodeih 0x ili 0X),
korienjem abcdef ili ABCDEF za 10, ...,15
int
int
char *
(2
01
5)
u
c
s
\0
ili broja
double
e,E
double
g,G
double
je
void *
an
h (za
short), l (za celobrojne tipove, za long), L (za brojeve
u pokretnom zarezu, za long double). Tako, na primer, sekvenca hd moe se
koristiti za ispisivanje podatka tipa short int, sekvenca ld moe se koristiti
za ispisivanje podatka tipa long int, a sekvenca Lf za ispisivanje podatka tipa
long double.
Primetimo da za format float ne postoji zaseban konverzioni karakter. To
je zbog toga to se svi argumenti tipa float implicitno konvertuju u tip double
prilikom poziva funkcije printf (jer je printf funkcija sa promenljivim brojem
iz
ro
n
sk
o
celobrojne tipove, za
kt
le
to i zahteva za tip
printf(s);
printf("%s", s);
282
(2
01
5)
int
count = -9234;
printf("Celobrojni formati:\n"
"\tDekadni: %d Poravnat: %.6d Neoznacen: %u\n",
count, count, count);
printf("Broj %d prikazan kao:\n\tHex: %Xh C hex: 0x%x Oct: %o\n",
count, count, count, count );
je
Celobrojni formati:
Dekadni: -9234 Poravnat: -009234 Neoznacen: 4294958062
Broj -9234 prikazan kao:
Hex: FFFFDBEEh C hex: 0xffffdbee Oct: 37777755756
iz
an
sk
o
Cifre 10 predstavljaju:
Hex: 16 Octal: 8 Decimal: 10
ro
n
kt
char ch = h;
printf("Karakteri u polju date sirine:\n%10c%c\n", ch, ch);
le
283
"hello, world"
Formatirani ulaz
Funkcija
scanf
(2
01
5)
scanf
an
12.1.4
:hello, world:
:hello, world:
:hello, wor:
:hello, world:
:hello, world:
:hello, world
:
:
hello, wor:
:hello, wor
:
je
:%s:
:%10s:
:%.10s:
:%-10s:
:%.15s:
:%-15s:
:%15.10s:
:%-15.10s:
printf.
Funkcija
scanf
ita
iz
sk
o
Opis format niske dat je u nastavku. Ostali argumenti moraju biti pokazivai i odreuju lokacije na koje se smeta konvertovani ulaz. Kao i u sluaju
funkcije
printf,
scanf
ro
n
funkcije. Funkcija
kada neki deo ulaza ne moe da se uklopi u shemu navedenu format niskom.
Funkcija vraa broj uspeno uklopljenih i dodeljenih izlaznih podataka.
sluaju kraja datoteke, funkcija vraa
EOF.
kt
scanf
le
284
*,
konvertovana vrednost
se preskae i nigde ne dodeljuje. Ulazno polje se definie kao niska karaktera koji nisu beline.
ili do irine polja, ako je ona eksplicitno zadana. Ovo znai da funkcija
(2
01
5)
Tip
Ulazni podatak
int*
int*
d
i
x
c
je
an
int*
unsigned*
int*
char*
iz
char*
%1s
\0
sk
o
nalnu
double*
e,f,g
ro
n
tom
le
kt
scanf("%d", n);
umesto
scanf("%d", &n);
3 Pod
285
scanf
Pozivi funkcije
Takoe, preskau
scanf
mogu biti
Naredni
poziv bilo koje ulazne funkcije e proitati prvi karakter koji nije proitan
scanf.
Primeri
U narednom primeru, korienjem funkcije
scanf
implementiran je jednos-
tavni kalkulator:
Program 12.2.
#include <stdio.h>
an
je
int main()
{
double sum, v;
(2
01
5)
iz
sum = 0.0;
while (scanf("%f", &v) == 1)
printf("\t%.2f\n", sum += v);
return 0;
sk
o
ro
n
jem:
kt
le
Ispred
va. Doslovni karakteri se mogu pojaviti u okviru format niske i u tom sluaju
se oni oekuju i na ulazu. Tako, za itanje datuma sa ulaza koji su u formatu
12/25/1988,
mogue je koristiti:
printf
sprintf
286
funkciji
printf,
arg1, arg2,
sprintf
(2
01
5)
a rezultat smeta u nisku karaktera prosleenu kao prvi argument, podrazumekoja vri ispis u nisku karaktera umesto na stan-
scanf,
sscanf
koja je
standardnog ulaza.
je
sscanf.
an
korienjem
ro
n
sk
o
iz
kt
le
<stdio.h>.
287
12.3.1
Iako se svaka datoteka moe razmatrati kao niz bajtova, obino razlikujemo
datoteke koje sadre tekstualni sadraj od datoteka koje sadre binarni sadraj.
U zavisnosti od toga da li se u datoteci nalazi tekstualni ili binarni sadraj,
razlikuju se dva razliita naina pristupa.
Prvi nain je prilagoen tekstualnim datotekama iji sadraj u principu
(2
01
5)
ine vidljivi karakteri, sa dodatkom oznake kraja reda i horizontalnog tabulatora. Ovakve datoteke se obino obrauju liniju po liniju, to je karakteristino
za tekst.
isuje linija po linija. Oigledno, u ovom sluaju oznaka za kraj linije je veoma
relevantna i znaajna. Meutim, na razliitim sistemima tekst se kodira na ra-
\r\n
\n
na sistemu Linux).
Da bi se
je
an
Ukoliko se datoteka otvori u tekstualnom modu, prilikom svakog itanja i upisa u datoteku vri se konverzija iz podrazumevanog formata oznaavanja kraja
\n.
iz
upisuje
\n
\r\n
sk
o
ro
n
jpg
ili
kt
(na primer,
zip
le
podravaju Unicode, jer se u tom sluaju vie bajtova ita i konvertuje u jedan
karakter.
12.3.2
Pristupanje datoteci
fopen:
Za ovo se koristi
288
Funkcija
fopen dobija nisku koja sadri ime datoteke (na primer, datoteka.txt)
i uz pomo usluga operativnog sistema (koje nee na ovom mestu biti detaljnije opisane) vraa pokaziva na strukturu (najee dinamiki alociranu)
koja predstavlja sponu izmeu lokalne datoteke i programa i koja sadri informacije o datoteci koje e biti koriene prilikom svakog pristupa datoteci. Ove
informacije mogu da ukljue adresu poetka bafera (prihvatnik, eng. buffer)
kroz koji se vri komunikacija sa datotekom, tekuu poziciju u okviru bafera,
(2
01
5)
fopen
Drugi argument je niska karaktera koja predstavlja nain (mod) otvaranja daukljuuju itanje (read,
"r"),
pisanje (write,
Dozvoljeni modovi
je
"w")
i dopisivanje (append,
"a").
an
dopisivanje stari sadraj zadrava, a novi sadraj upisuje nakon njega. Ukoliko
iz
fopen
vraa
NULL.
Modovi
sk
o
r+, w+ i a+
"b"
(na primer,
. . . ).
ro
n
kt
nazivaju:
le
FILE* stdin;
FILE* stdout;
FILE* stderr;
Funkcija
fclose
fopen
ostvarila.
Takoe,
S obzirom
289
12.3.3
To
Funkcija
FILE
getc
(2
01
5)
pokazivaem ili
EOF
FILE
je
greke prilikom izlaza retke, one se nekada javljaju (na primer, ako se prepuni
Slino kao i
an
iz
a ne funkcije.
Program 12.3.
sk
o
ro
n
#include <stdio.h>
le
kt
290
if(izlaz == NULL)
return -1;
filecopy(ulaz,izlaz);
Funkcija
(2
01
5)
fclose(ulaz);
fclose(izlaz);
return 0;
ungetc:
je
naredni poziv operacije itanja nad ovom datotekom vrati upravo vraeni karakter. Ovaj karakter moe, ali ne mora biti jednak poslednjem proitanom karak-
an
teru datoteke. Iako ova funkcije utie na naredne operacije itanja datoteke,
ona ne menja fiziki sadraj same datoteke (naime vraeni karakteri se najee
smetaju u memorijski bafer odakle se dalje itaju, a ne u datoteku na disku).
Funkcija
iz
Naredni primer ita karaktere iz datoteke dok su u pitanju cifre i pri tom
gradi dekadni ceo broj. Poto poslednji karakter koji je proitan nije cifra, on
sk
o
#include <stdio.h>
le
kt
ro
n
12.3.4
Funkcija
datoteke.
ferror
u radu sa datotekom.
291
12.3.5
fgets
(2
01
5)
liniju po liniju.
an
je
reda) iz datoteke
u datoteku:
EOF
Za razliku od funkcija
puts
fgets i fputs,
funkcija
gets
brie zavrni
\n,
ga dodaje.
sk
o
funkcija
iz
Ona vraa
fgets i fputs,
ro
n
le
kt
cs = s;
while (--n > 0 && (c = getc(iop)) != EOF)
if ((*cs++ = c) == \n)
break;
*cs = \0;
return (c == EOF && cs == s) ? NULL : s;
292
register int c;
while (c = *s++)
putc(c, iop);
return ferror(iop) ? EOF : 0;
Korienjem funkcije
(2
01
5)
iz
12.3.6
an
je
scanf i printf,
sk
o
fscanf
fprintf.
FILE
kt
ro
n
le
12.3.7
u binarne datoteke. Progameru su na raspolaganju i funkcije za pozicioniranje u okviru datoteka, pa se binarne datoteke mogu koristiti i kao neke vrste
memorije sa slobodnim pristupom.
Funkcija
funkcija
datoteke, a
293
fseek
Funkcija
ftell
vraa
(2
01
5)
je
an
dozvoljene vrednosti
odnosu
na kraj datoteke.
odnosu
odnosu
iz
Program 12.4.
sk
o
#include <stdio.h>
kt
ro
n
int main() {
struct S {
int broj;
int kvadrat;
} s;
le
FILE* f;
int i;
294
(2
01
5)
fclose(f);
argc,
main.
je
Prvi argument
pokretanja programa.
an
argv,
od en-
gleskog argument vector ) je niz niski karaktera koje sadre argumente svaka
Ako je
argc
iz
argv[0].
na sledei nain:
sk
o
ro
n
kt
Program 12.5.
le
#include <stdio.h>
int main(int argc, char* argv[]) {
int i;
printf("argc = %d\n", argc);
i pozove sa
295
./echoargs
-U
zdravo
svima
dobar dan
(2
01
5)
argc = 5
argv[0] =
argv[1] =
argv[2] =
argv[3] =
argv[4] =
a, b, c, d e i f
134 i zdravo.
je
an
Program 12.6.
iz
#include <stdio.h>
le
kt
ro
n
sk
o
Program 12.7.
#include <stdio.h>
int main(int argc, char* argv[]) {
char c;
296
(2
01
5)
stderr?
Pitanje 12.2.
printf?
an
Pitanje 12.3.
je
scanf?
Pitanje 12.4.
printf, specifikuje
primer:
iz
opcioni broj koji se navodi iza opcione take za argument koji je niska (na
printf("%.2s", "zdravo");)?
ta specifikuje opcioni broj koji se navodi iza opcione take za argument koji
Pitanje 12.5.
printf("%.2f", 3.2453);)?
sk
o
printf("#%6.*f#", 2, 3.14159);?
printf("%6.1f",1/7);?
ta je rezultat poziva
ro
n
ta je rezultat poziva
Pitanje 12.6.
kt
Pitanje 12.7.
le
upisati vrednosti
1/7 i 2/7
razmakom.
Pitanje 12.8.
Pitanje 12.9.
puts i fputs?
Pitanje 12.10.
Pitanje 12.11.
fopen.
297
Pitanje 12.12.
datoteke. Koju vrednost ona vraa? Navesti bar dva razloga zbog kojih je preporuljivo zatvoriti datoteku im se zavri njeno korienje.
Pitanje 12.13.
Pitanje 12.14.
(2
01
5)
fprintf
p?
Pitanje 12.15.
Pitanje 12.16.
fseek i fsetpos?
Pitanje 12.17.
je
an
lnu datoteku?
Pitanje 12.18.
Pitanje 12.19.
main
sa argumentima.
main,
iz
koji se izvrava?
Zadatak 12.1.
funkcije
tekstua-
Napisati funkciju
main
sk
o
Zadatak 12.2.
int).
a za-
ro
n
kt
le
3
1 2 3
7 3 4
5 3 1
0 (jer je
2 + 3 + 3 = 8, u
1 + 7 + 5 = 13,
Zadatak 12.3.
u prvoj
Data je datoteka
apsolventi.txt.
3 + 4 + 1 = 8).
nalaze se podaci o apsolventu: ime (ne vee od 20 karaktera), prezime (ne vee
od 20 karaktera), broj preostalih ispita. Datoteka je dobro formatirana i broj
redova datoteke nije poznat. Potrebno je uitati podatke iz datoteke, odrediti
prosean broj zaostalih ispita i potom ispisati imena i prezimena studenta koji
imaju vei broj zaostalih ispita od prosenog u datoteku ije ime je zadato kao
argument komadne linije. NAPOMENA: koristiti strukturu
298
typedef struct {
char ime[20];
char prezime[20];
unsigned br_ispita;
} APSOLVENT;
Zadatak 12.4.
Napisati funkciju
(2
01
5)
u datoj osnovi
b.
Na-
u nisku
s.
Napisati zatim program koji ita liniju po liniju datoteke koja se zadaje kao
je
prvi argument komandne linije i obrauje ih sve dok ne naie na praznu liniju.
Svaka linija sadri jedan dekadni, oktalni ili heksadekadni broj (zapisan kako
an
le
kt
ro
n
sk
o
iz
unsigned
.
(2
01
5)
Dodatak A
le
kt
ro
n
sk
o
iz
an
je
299
300
Opis
Asocijativnost
poziv funkcije
sleva na desno
an
iz
bitska konjunkcija
sleva na desno
je
sleva na desno
sleva na desno
sleva na desno
sleva na desno
sleva na desno
bitska disjunkcija
sleva na desno
logika konjunkcija
sleva na desno
logika disjunkcija
sleva na desno
ternarni uslovni
zdesna na levo
dodele
zdesna na levo
kt
le
E
zdesna na levo
unarni plus/minus
(2
01
5)
prefiksni inkrement/dekrement
ro
n
()
[]
.
->
++ -++ -+ ! ~
(type)
*
&
sizeof
* / %
+ << >>
< <=
> >=
== !=
&
^
|
&&
||
?:
=
+= -=
*= /= %=
&= ^= |=
<<= >>=
,
sk
o
Operator
sleva na desno
(2
01
5)
Dodatak B
je
Reenja zadataka
an
le
kt
ro
n
sk
o
Na raspolaganju
iz
301
302
B. Reenja zadataka
(b) 964
(c) 476
(2
01
5)
(48 5566293)16 .
je
(1010 0011 1011 1111 0100 0110 0001 1100 1000 1001 1011 1110 0010 0011 1101 0111)2
an
(a) rgb(53, 167, 220) (b) #FFFF00 (c) Svaki par heksadekadnih cifara je isti
iz
sk
o
(a)
ro
n
(b)
01111011,
(c)
11111111,
kt
21 (10 . . . 00),
a najvei je
21 1 (011 . . . 11).
Dakle,
le
Najmanji broj je
(a)
00001100,
(b)
10000101,
(c)
00000000,
(d)
11101110,
(e)
10000000
(f ) ne
moe da se zapie
Broj
kao
kao
000101,
broj
kao
111011,
zbir kao
000000,
a proizvod
303
B. Reenja zadataka
38,
(b)
83,
(c)
128,
(d)
1,
(e)
127,
(f )
(2
01
5)
Sa
je
Heksadekadno: 22 50 72 6f 67 72 61 6d 69 72 61 6e 6a 65 20 31 22,
an
00110001 00100010
Oktalno: 042 120 162 157 147 162 141 115 151 162 141 156 152 145 040 061
iz
042
Dekadno: 34 80 114 111 103 114 97 109 105 114 97 110 106 101 32 49 34
sk
o
Windows-1250
ISO-8859-5
ISO-8859-2
Unicode (UCS-2)
11
11
22
12
informatika
11
11
11
11
22
11
ro
n
ASCII
raunarstvo
UTF-8
kt
UCS-2 : 006b 0072 0075 017e 0069 0107 UTF-8 : 6b 72 75 c5be 69 c487
le
Izraunljivost
= + (1 + . . . + 1) + . . . + (1 + . . . + 1)
Odgovarajui
304
B. Reenja zadataka
redom vrednosti
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
0, 1, . . . , .
(4)
(1, 10, 100)
(2, 10, 14)
(1, 3)
(4)
(4, 2, 12)
(5)
(5)
(3)
(5, 1, 5)
(1, 1, 8)
(3, 1)
(1, 1, 100)
(1)
...
...
0, 1, . . . , ,
= 0,
= 0?
:=
:= + 1
= ?
:= 0
:= + 1
:= + 1
1
0 1
0 1
le
kt
:=
:= + 1
=
ro
n
=0
:= 0
:= + 1
:= + 1
dobija
onda kraj
iz
sk
o
=0
=0
ako je
:= 0
(2
01
5)
je
an
gde
305
B. Reenja zadataka
= =+
Odgovarajui
...
...
(2
01
5)
:= 0
je
:= 0
:= + 1
>
:= + 1
:= + 1
iz
ro
n
sk
o
1.
2.
kt
3.
le
4.
5.
6.
7.
8.
9.
10.
11.
(3)
(4)
(1, 3, 11)
(2, 3, 7)
(3)
(1, 1, 3)
(3)
(4)
(3, 1, 11)
(1, 1, 7)
(4, 1)
Jezik C - uvod
Reenje zadatka 5.2.1:
an
=0
=0
= ?
= ?
:= + 1
:= + 1
:= + 1
= ?
1
306
B. Reenja zadataka
int main() {
double r;
printf("Unesi poluprecnik kruga: ");
scanf("%lf", &r);
assert(r > 0);
printf("Obim kruga je: %lf\n", 2*r*M_PI);
printf("Povrsina kruga je: %lf\n", r*r*M_PI);
return 0;
}
je
(2
01
5)
#include <stdio.h>
#include <math.h>
#include <assert.h>
an
#include <stdio.h>
#include <math.h>
sk
o
iz
int main() {
/* Koordinate tacaka A, B, C */
double xa, ya, xb, yb, xc, yc;
/* Duzine stranica BC, AC, AB */
double a, b, c;
/* Poluobim i povrsina trougla ABC */
double s, P;
le
kt
ro
n
return 0;
i
yc));
yc));
yb));
307
B. Reenja zadataka
int main() {
/* Duzine stranica trougla */
double a, b, c;
/* Velicine uglova trougla */
double alpha, beta, gamma;
an
je
(2
01
5)
#include <stdio.h>
#include <math.h>
#include <assert.h>
sk
o
iz
ro
n
return 0;
le
kt
#include <stdio.h>
int main() {
double kmh;
printf("Unesi brzinu u km/h: ");
scanf("%lf", &kmh);
printf("Brzina u ms/s je: %lf\n", kmh * 1000.0 / 3600.0);
return 0;
}
308
B. Reenja zadataka
je
(2
01
5)
int main() {
/* Pocetna brzina u m/s, ubrzanje u m/s^2 i vreme u s*/
double v0, a, t;
ro
n
#include <stdio.h>
sk
o
iz
an
le
kt
int main() {
double a1, a2, a3, a4, a5, a6, a7, a8, a9;
scanf("%lf%lf%lf", &a1, &a2, &a3);
scanf("%lf%lf%lf", &a4, &a5, &a6);
scanf("%lf%lf%lf", &a7, &a8, &a9);
/* Determinantu ra\v cunamo primenom Sarusovog pravila:
a1 a2 a3 a1 a2
a4 a5 a6 a4 a5
a7 a8 a9 a7 a8
- glavne dijagonale pozitivno, sporedne negativno
*/
printf("%lf\n", a1*a5*a9 + a2*a6*a7 + a3*a4*a8
- a3*a5*a7 - a1*a6*a8 - a2*a4*a9);
return 0;
}
309
B. Reenja zadataka
#include <stdio.h>
je
(2
01
5)
int main() {
int a1, a2, a3; /* brojevi */
int m; /* maksimum brojeva */
printf("Unesi tri broja: ");
scanf("%d %d %d", &a1, &a2, &a3);
m = a1;
if (a2 > m)
m = a2;
if (a3 > m)
m = a3;
printf("Maksimum je: %d\n", m);
return 0;
}
an
iz
ro
n
sk
o
int main() {
int a, b, i;
scanf("%d%d", &a, &b);
for (i = a; i <= b; i++)
printf("%d\n", i*i*i);
return 0;
}
#include <stdio.h>
kt
Jezik C - izrazi
le
#include <stdio.h>
int main() {
int h, m, s, h1, m1, s1;
scanf("%d:%d:%d", &h, &m, &s);
if (h < 0 || h > 23) {
printf("Neispravno unet sat\n");
return 1;
}
if (m < 0 || m > 59) {
printf("Neispravno unet minut\n");
return 2;
310
B. Reenja zadataka
}
if (s < 0 || s > 59) {
printf("Neispravno unet sekund\n");
return 3;
}
= 60 = 59 = 23 (s1 ==
s1 = 0;
m1++;
s;
m;
h;
60) {
(2
01
5)
s1
m1
h1
if
#include <stdio.h>
an
sk
o
iz
je
}
if (m1 == 60) {
m1 = 0;
h1++;
}
le
kt
ro
n
int main() {
double x, y, z;
scanf("%lf%lf%lf", &x, &y, &z);
if (x > 0 && y > 0 && z > 0 &&
x + y > z && x + z > y && y + z > x)
printf("Trougao postoji\n");
else
printf("Trougao ne postoji\n");
return 0;
}
311
B. Reenja zadataka
c0
c1
c2
c3
n % 10;
(n / 10) % 10;
(n / 100) % 10;
(n / 1000) % 10;
je
an
=
=
=
=
(2
01
5)
iz
#include <stdio.h>
le
kt
ro
n
sk
o
int main() {
unsigned n, c0, c1; /* broj, poslednja i pretposlednja cifra */
printf("Unesi broj: ");
scanf("%d", &n);
c0 = n % 10;
c1 = (n / 10) % 10;
printf("Zamenjene poslednje dve cifre: %u\n",
(n / 100)*100 + c0*10 + c1);
return 0;
}
#include <stdio.h>
int main() {
/*
(0, 0) -> 1
(0, 1) -> 2
(2, 0) -> 4
(0, 3) -> 7
...
*/
(1, 0) -> 3
(1, 1) -> 5 (0, 2) -> 6
(1, 2) -> 8 (2, 1) -> 9 (3, 0) -> 10
312
unsigned x, y; /* koordinate */
unsigned z;
/* pomocna promenljiva */
unsigned n;
/* redni broj u cik-cak nabrajanju */
printf("Unesi x i y koordinatu: ");
scanf("%d%d", &x, &y);
z = x + y;
if (z % 2)
n = z*(z + 1)/2 + x + 1;
else
n = z*(z + 1)/2 + y + 1;
printf("Redni broj u cik-cak nabrajanju je: %u\n", n);
return 0;
(2
01
5)
B. Reenja zadataka
je
an
#include <stdio.h>
kt
ro
n
sk
o
iz
int main() {
double A, B;
printf("Unesi koeficijente A i B jednacine A*X + B = 0: ");
scanf("%lf%lf", &A, &B);
if (A != 0)
printf("Jednacina ima jedinstveno resenje: %lf\n", -B/A);
else if (B == 0)
printf("Svaki realan broj zadovoljava jednacinu\n");
else
printf("Jednacina nema resenja\n");
return 0;
}
le
#include <stdio.h>
int main() {
double a1, b1, c1, a2, b2, c2; /* koeficijenti sistema */
double Dx, Dy, D; /* determinante */
scanf("%lf%lf%lf", &a1, &b1, &c1);
scanf("%lf%lf%lf", &a2, &b2, &c2);
/* Sistem resavamo primenom Kramerovog pravila */
/* Determinanta sistema:
a1 b1
a2 b2
*/
313
B. Reenja zadataka
an
return 0;
iz
je
(2
01
5)
D = a1*b2 - b1*a2;
/* Determinanta promenljive x:
c1 b1
c2 b2
*/
Dx = c1*b2 - b1*c2;
/* Determinanta promenljive y:
a1 c1
a2 c2
*/
Dy = a1*c2 - c1*a2;
if (D != 0)
printf("x = %lf\ny = %lf\n", Dx / D, Dy / D);
else if (Dx == 0 && Dy == 0)
printf("Sistem ima beskonacno mnogo resenja\n");
else
printf("Sistem nema resenja\n");
sk
o
#include <stdio.h>
#include <math.h>
#include <assert.h>
le
kt
ro
n
int main() {
float a, b, c; /* koeficijenti */
float D;
/* diskriminanta */
printf("Unesi koeficijente a, b, c"
" kvadratne jednacine ax^2 + bx + c = 0: ");
scanf("%f%f%f", &a, &b, &c);
assert(a != 0);
D = b*b - 4*a*c;
if (D > 0) {
float sqrtD = sqrt(D);
printf("Realna resenja su: %f i %f\n",
(-b + sqrtD) / (2*a), (-b - sqrtD) / (2*a));
} else if (D == 0) {
printf("Jedinstveno realno resenje je: %f\n",
-b/(2*a));
} else {
printf("Jednacina nema realnih resenja\n");
}
return 0;
}
314
B. Reenja zadataka
je
(2
01
5)
int main() {
unsigned n; /* broj koji se ispituje */
unsigned d; /* kandidat za delioca */
scanf("%u", &n);
for (d = 1; d <= n; d++)
if (n % d == 0)
printf("%u\n", d);
return 0;
}
an
iz
#include <stdio.h>
#include <ctype.h>
ro
n
sk
o
int main() {
int c;
while ((c = getchar()) != . && c != , && c != EOF)
putchar(toupper(c));
}
Jezik C - nizovi
le
kt
#include <stdio.h>
#define MAX 1000
int main() {
int a[MAX];
int n, i, max, zbir;
scanf("%d", &n);
if (n >= MAX) {
printf("Previse elemenata\n");
return 1;
}
/* Ucitavanje niza */
315
B. Reenja zadataka
(2
01
5)
return 0;
iz
an
ro
n
sk
o
le
kt
je
return 0;
316
B. Reenja zadataka
#include <stdio.h>
#include <assert.h>
(2
01
5)
ro
n
sk
o
iz
an
je
int main() {
int d, m, g, b, M;
/* Broj dana po mesecima. Niz je napravljen tako da se broj dana za
mesec m moze ocitati sa br_dana[m].
*/
int br_dana[] = {-1, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
printf("Unesi datum u formatu d/m/g: ");
assert(scanf("%d/%d/%d", &d, &m, &g) == 3);
/* Provera ispravnosti datuma */
if (g < 0) {
printf("Pogresna godina\n");
return 1;
}
if (m < 1 || m > 12) {
printf("Pogresan mesec\n");
return 1;
}
if (d < 1 || d > (m == 2 && prestupna(g) ? 29 : br_dana[m])) {
printf("Pogresan dan\n");
return 1;
}
le
kt
b = 0;
/* Broj dana u prethodnim mesecima */
for (M = 1; M < m; M++)
b += br_dana[M];
/* Broj dana u tekucem mesecu */
b += d;
/* Eventualno dodati i 29. 2. */
if (prestupna(g) && m > 2)
b++;
printf("%d\n", b);
return 0;
317
B. Reenja zadataka
#include <ctype.h>
je
an
iz
return 0;
sk
o
(2
01
5)
int main() {
int a[100], n, k, m;
/* Ucitavamo broj redova trougla */
scanf("%d", &m);
for (n = 0; n < m; n++) {
/* Azuriramo tekuci red trougla */
/* (n n) = 1 */
a[n] = 1;
for (k = n-1; k > 0; k--)
/* (n k) = (n-1 k) + (n-1 k-1) */
a[k] = a[k] + a[k-1];
/* (n 0) = 1 */
/* a[0] = 1; -- ovo vec vazi */
ro
n
#include <stdio.h>
#include <assert.h>
le
kt
int main() {
int n, A[10][10], i, j, s;
/* ucitavamo matricu */
scanf("%d", &n); assert(0 < n && n <= 10);
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
scanf("%d", &A[i][j]);
/* sumiramo elemente glavne dijagonale */
s = 0;
for (i = 0; i < n; i++)
s += A[i][i];
printf("Suma elemenata glavne dijagonale je: %d\n", s);
/* sumiramo elemente iznad sporedne dijagonale */
s = 0;
for (i = 0; i < n; i++)
318
B. Reenja zadataka
return 0;
(2
01
5)
ro
n
sk
o
iz
an
je
int main() {
int n, A[100][100], i, j, dt;
/* ucitavamo matricu */
scanf("%d", &n); assert(0 < n && n <= 100);
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
scanf("%d", &A[i][j]);
/* proveravamo da li je matrica donjetrougaona */
dt = 1;
for (i = 0; i < n && dt; i++)
for (j = i+1; j < n && dt; j++)
if (A[i][j] != 0)
dt = 0;
printf("Matrica %s donjetrougaona\n", dt ? "je" : "nije");
return 0;
}
kt
le
#include <stdio.h>
#include <math.h>
/* Struktura za reprezentovanje kompleksnog broja */
typedef struct complex {
double Re, Im;
} COMPLEX;
int main() {
/* Najveci broj */
COMPLEX max_z;
319
B. Reenja zadataka
sk
o
iz
an
je
int i;
for (i = 0; i < 10; i++) {
/* Tekuci broj */
COMPLEX z;
/* Moduo tekuceg broja */
double z_m;
/* Ucitavanje */
scanf("%lf%lf", &z.Re, &z.Im);
/* Racunanje modula */
z_m = sqrt(z.Re*z.Re + z.Im*z.Im);
/* Azuriranje najveceg */
if (z_m > max_m) {
max_z = z;
max_m = z_m;
}
}
printf("%lf + i*%lf\n", max_z.Re, max_z.Im);
return 0;
(2
01
5)
/* Najveci moduo */
double max_m = 0.0;
ro
n
#include <stdio.h>
#include <assert.h>
le
kt
int main() {
enum dani {PON = 1, UTO, SRE, CET, PET, SUB, NED};
int dan;
scanf("%d", &dan);
assert(1 <= dan && dan <= 7);
if (dan == SUB || dan == NED)
printf("Vikend\n");
else
printf("Radni dan\n");
return 0;
}
Jezik C - naredbe
Reenje zadatka 7.1:
#include <stdio.h>
320
B. Reenja zadataka
(2
01
5)
int main() {
int n, i;
printf("Unesi gornju granicu: ");
scanf("%d", &n);
for (i = 1; i < n; i += 2)
printf("%d ", i);
printf("\n");
return 0;
}
#include <stdio.h>
#include <math.h>
ro
n
sk
o
iz
an
int main() {
int N = 100;
double l = 0.0, d = 2*M_PI;
double h = (d - l) / (N - 1);
double x;
printf(" x
sin(x)\n");
for (x = l; x <= d; x += h)
printf("%4.2lf %7.4lf\n", x, sin(x));
return 0;
}
je
kt
#include <stdio.h>
le
int main() {
double x, s;
unsigned n, i;
printf("Unesi broj x: ");
scanf("%lf", &x);
printf("Unesi izlozilac n: ");
scanf("%d", &n);
for (s = 1.0, i = 0; i < n; i++)
s *= x;
printf("x^n = %lf\n", s);
return 0;
}
321
B. Reenja zadataka
(2
01
5)
#define N 4
int main() {
int i, j;
/* Deo (a): */
printf("--------------\n");
sk
o
iz
/* Deo (b): */
for (i = 0; i < N; i++) {
for (j = 0; j < N - i; j++)
putchar(*);
putchar(\n);
}
an
je
ro
n
printf("--------------\n");
le
kt
/* Deo (c): */
for (i = 0; i < N; i++) {
for (j = 0; j < i + 1; j++)
putchar(*);
putchar(\n);
}
printf("--------------\n");
/* Deo (d): */
for (i = 0; i < N; i++) {
for (j = 0; j < i; j++)
putchar( );
for (j = 0; j < N - i; j++)
putchar(*);
putchar(\n);
}
printf("--------------\n");
322
B. Reenja zadataka
(2
01
5)
/* Deo (e): */
for (i = 0; i < N; i++) {
for (j = 0; j < N - i - 1; j++)
putchar( );
for (j = 0; j < i + 1; j++)
putchar(*);
putchar(\n);
}
printf("--------------\n");
an
iz
/* Deo (f): */
for (i = 0; i < N; i++) {
for (j = 0; j < i; j++)
putchar( );
for (j = 0; j < N - i - 1; j++) {
putchar(*); putchar( );
}
putchar(*);
putchar(\n);
}
je
printf("--------------\n");
le
kt
ro
n
sk
o
/* Deo (g): */
for (i = 0; i < N; i++) {
for (j = 0; j < N - i - 1; j++)
putchar( );
for (j = 0; j < i; j++) {
putchar(*); putchar( );
}
putchar(*);
putchar(\n);
}
return 0;
323
B. Reenja zadataka
an
je
(2
01
5)
*/
int main() {
unsigned n; /* broj koji se ispituje */
unsigned s; /* suma delioca */
unsigned d; /* kandidat za delioca */
scanf("%u", &n);
for (s = 0, d = 1; d*d < n; d++)
if (n % d == 0)
s += d + n / d;
if (d * d == n)
s += d;
printf("Suma: %u\n", s);
return 0;
}
#include <stdio.h>
#include <assert.h>
le
kt
ro
n
sk
o
iz
324
B. Reenja zadataka
int main() {
unsigned n, d;
/* Ucitavamo broj */
scanf("%u", &n);
sk
o
iz
an
je
(2
01
5)
ro
n
le
kt
#include <stdio.h>
#include <limits.h>
#include <math.h>
int main() {
int a; /* broj koji se unosi */
int n = 0; /* broj unetih brojeva */
int s = 0; /* zbir unetih brojeva */
int p = 1; /* proizvod unetih brojeva */
int min = INT_MAX; /* minimum unetih brojeva */
int max = INT_MIN; /* maksimum unetih brojeva */
double sr = 0; /* zbir reciprocnih vrednosti */
while (1) {
scanf("%d", &a);
if (a == 0) break;
n++;
s += a;
325
B. Reenja zadataka
p *= a;
if (a < min) min = a;
if (a > max) max = a;
sr += 1.0/a;
#include <stdio.h>
sk
o
an
return 0;
iz
je
(2
01
5)
}
if (n == 0) {
printf("Nije unet nijedan broj\n");
return 1;
}
printf("broj: %d\n", n);
printf("zbir: %d\n", s);
printf("proizvod: %d\n", p);
printf("minimum: %d\n", min);
printf("maksimum: %d\n", max);
printf("aritmeticka sredina: %f\n", (double)s / (double)n);
printf("geometrijska sredina: %f\n", pow(p, 1.0/n));
printf("harmonijska sredina: %f\n", n / sr);
ro
n
int main() {
int ts = 0; /* Tekuca serija */
int ns = 0; /* Najduza serija */
int pb, tb; /* Prethodni i tekuci broj */
le
kt
scanf("%d", &pb);
if (pb != 0) {
ts = ns = 1;
while(1) {
scanf("%d", &tb);
if (tb == 0) break; /* Prekidamo kada je uneta 0 */
/* Da li je tekuci broj jednak prethodnom? */
if (tb == pb)
/* Ako jeste, nastavlja se tekuca serija */
ts++;
else
/* Inace, krenula je nova serija */
ts = 1;
/* Azuriranje najduze serije */
if (ts > ns)
326
B. Reenja zadataka
ns = ts;
/* Azuriranje prethodnog broja */
pb = tb;
(2
01
5)
}
}
/* Ispis rezultata */
printf("%d\n", ns);
return 0;
je
#include <stdio.h>
iz
an
int main() {
/* Izracunava se ceo deo korena unetog broja x. Trazi se interval
oblika [n^2, (n+1)^2] = [N1, N2] tako da mu x pripada i tada je n
ceo deo korena iz x.
*/
unsigned x;
unsigned N1, N2, n;
sk
o
/* Ucitava se broj x */
scanf("%d", &x);
le
kt
ro
n
327
B. Reenja zadataka
#include <stdio.h>
sk
o
iz
je
an
(2
01
5)
#include <stdio.h>
#include <math.h>
le
kt
ro
n
int main() {
unsigned fpp = 1, fp = 1, k;
scanf("%d", &k);
if (k == 0) return 0;
printf("%d\n", fpp);
if (k == 1) return 0;
printf("%d\n", fp);
k -= 2;
while (k > 0) {
unsigned f = fpp + fp;
printf("%d\n", f);
fpp = fp; fp = f;
k--;
}
return 0;
}
328
B. Reenja zadataka
#include <stdio.h>
(2
01
5)
int main() {
unsigned n;
printf("Unesi broj: ");
scanf("%u", &n);
do {
/* Poslednja cifra broja */
printf("%u\n", n % 10);
/* Brisemo poslednju cifru broja */
n /= 10;
} while (n > 0);
return 0;
}
je
#include <stdio.h>
ro
n
sk
o
iz
an
int main() {
unsigned n, suma = 0;
printf("Unesi broj: ");
scanf("%u", &n);
do {
suma += n % 10;
n /= 10;
} while (n > 0);
printf("Suma cifara broja je: %u\n", suma);
return 0;
}
kt
le
int main() {
unsigned n1, n2, tmp;
scanf("%d", &n1);
scanf("%d", &n2);
/* Da bi se izvrsilo nadovezivanje, n1 se mnozi sa 10^k,
gde je k broj cifara broja n2 i zatim se dodaje n2 */
/* posto ce nam n2 kasnije trebati, kopiramo ga u pomocnu promenljivu */
tmp = n2;
/* Dok ima cifara broja tmp */
while (tmp > 0) {
/* Mnozimo n1 sa 10 */
n1 *= 10;
329
B. Reenja zadataka
(2
01
5)
}
/* Uvecavamo n1 za n2 */
n1 += n2;
printf("%d\n", n1);
return 0;
ro
n
sk
o
iz
an
je
int main() {
unsigned n;
/* polazni broj */
unsigned o = 0; /* obrnuti broj */
scanf("%d", &n);
do {
/* poslednja cifra broja n se uklanja iz broja n i
dodaje na kraj broja o */
o = 10*o + n % 10;
n /= 10;
} while (n > 0);
printf("%d\n", o);
return 0;
}
kt
#include <stdio.h>
le
int main() {
/* Broj koji se obradjuje */
unsigned n;
/* Rezultat i 10^k gde je k broj cifara rezultata (ovaj stepen je
potreban zbog dodavanja cifara na pocetak rezutlata) */
unsigned r = 0, s = 1;
/* Ucitavamo broj */
scanf("%u", &n);
while (n > 0) {
/* Uklanjamo mu poslednju cifru */
unsigned c = n % 10;
n /= 10;
if (c % 2 == 0) {
/* Ako je parna, dodajemo je kao prvu cifru rezultata */
330
B. Reenja zadataka
r = c * s + r;
s *= 10;
(2
01
5)
}
}
/* Ispis rezultata */
printf("%u\n", r);
return 0;
an
je
#include <stdio.h>
int main() {
unsigned n, s = 1;
unsigned char p, c;
scanf("%u%hhu%hhu", &n, &p, &c);
iz
/* s = 10^p */
while (p > 0) {
s *= 10;
p--;
}
ro
n
sk
o
le
kt
331
B. Reenja zadataka
(2
01
5)
an
je
/* Prva cifra */
poc = n / s;
/* Cifre izmedju prve i poslednje */
sred = (n % s) / 10;
/* Poslednja cifra */
kraj = n % 10;
return 0;
sk
o
/* Rotiranje ulevo */
#include <stdio.h>
iz
ro
n
int main() {
unsigned n, tmp, s;
scanf("%u", &n);
le
kt
return 0;
/* Rotiranje udesno */
#include <stdio.h>
332
B. Reenja zadataka
int main() {
unsigned n, tmp, s;
scanf("%u", &n);
(2
01
5)
return 0;
an
je
iz
ro
n
int main() {
int d, m, g, dm;
sk
o
#include <stdio.h>
#include <assert.h>
kt
le
333
printf("Pogresan mesec\n");
return 1;
je
(2
01
5)
/* Provera dana */
if (d < 1 || d > dm) {
printf("Pogresan dan\n");
return 1;
}
/* Provera godine */
if (g < 0) {
printf("Pogresna godina\n");
return 1;
}
printf("Uneti datum je korektan\n");
return 0;
an
B. Reenja zadataka
iz
#include <stdio.h>
#define BROJ_PREDMETA 12
sk
o
int main() {
/* Nabrojivi tip */
enum Uspeh {NEDOVOLJAN, DOVOLJAN, DOBAR, VRLO_DOBAR, ODLICAN, GRESKA};
ro
n
le
kt
/* Unos podataka */
printf("Unesi broj jedinica: ");
scanf("%d", &broj_jedinica);
printf("Unesi prosek: ");
scanf("%f", &prosek);
/* Odredjivanje uspeha */
if (broj_jedinica > BROJ_PREDMETA || prosek < 2.0 || prosek > 5.0)
uspeh = GRESKA;
else if (broj_jedinica > 0)
uspeh = NEDOVOLJAN;
else if (prosek < 2.5)
334
B. Reenja zadataka
= DOVOLJAN;
(prosek < 3.5)
= DOBAR;
(prosek < 4.5)
= VRLO_DOBAR;
= ODLICAN;
return 0;
kt
ro
n
sk
o
iz
an
je
/* Prijavljivanje rezultata */
switch(uspeh) {
case NEDOVOLJAN:
printf("Nedovoljan uspeh\n");
break;
case DOVOLJAN:
printf("Dovoljan uspeh\n");
break;
case DOBAR:
printf("Dobar uspeh\n");
break;
case VRLO_DOBAR:
printf("Vrlo dobar uspeh\n");
break;
case ODLICAN:
printf("Odlican uspeh. Cestitamo!\n");
break;
case GRESKA:
printf("Deluje da su podaci neispravni\n");
break;
}
(2
01
5)
uspeh
else if
uspeh
else if
uspeh
else
uspeh
le
#include <stdio.h>
#include <limits.h>
int main() {
int x; /* tekuci broj */
int m; /* najmanji prethodno unet broj */
int n; /* broj unetih brojeva */
int s; /* suma unetih brojeva */
/* Prvi uneti broj mora biti specificno obradjen jer nema
prethodnih brojeva kako bi se odredio njihov minimum. Po uslovu
B. Reenja zadataka
(2
01
5)
335
return 0;
sk
o
iz
an
je
ro
n
kt
#include <stdio.h>
le
int main() {
unsigned a[1000], n, i, j;
scanf("%d", &n);
/* Gradimo niz sve do pozicije n */
a[0] = 0;
for (i = 1; i < n; i = j)
/* Kopiramo prefiks uvecavajuci elemente za 1, vodeci racuna da ne
predjemo granicu */
for (j = i; j < i+i && j < n; j++)
a[j] = a[j - i] + 1;
/* Stampamo niz */
for (i = 0; i < n; i++)
336
B. Reenja zadataka
return 0;
(2
01
5)
an
je
int main() {
int a[100], b[100]; /* Ulazni nizovi */
int na, nb; /* Njihov broj elemenata */
int p[100], u[200], r[100]; /* Presek, unija, razlika */
int np, nu, nr; /* Njihov broj elemenata */
int i, j, k; /* Pomocne promenljive */
sk
o
iz
le
kt
ro
n
337
B. Reenja zadataka
(2
01
5)
}
/* Ispisujemo elemente preseka */
printf("Presek: ");
for (i = 0; i < np; i++)
printf("%d ", p[i]);
printf("\n");
kt
ro
n
sk
o
iz
an
je
/* ------------------------------------------------------- */
/* unija - u niz u kopiramo sve elemente niza a i za njima sve
elemente niza b koji se ne javljaju u a */
/* Kopiramo niz a u niz u */
nu = 0;
for (i = 0; i < na; i++)
u[nu++] = a[i];
for (i = 0; i < nb; i++) {
/* Trazimo b[i] u nizu a */
for (j = 0; j < na; j++)
if (b[i] == a[j])
break;
/* Ako je petlja stigla do kraja, znaci da niz a ne sadrzi b[i] pa
ga dodajemo u uniju u */
if (j == na)
u[nu++] = b[i];
}
/* Ispisujemo elemente unije */
printf("Unija: ");
for (i = 0; i < nu; i++)
printf("%d ", u[i]);
printf("\n");
le
/* ------------------------------------------------------- */
/* razlika - u niz r kopiramo sve elemente niza a koji se ne
javljaju u nizu b */
nr = 0;
for (i = 0; i < na; i++) {
/* Trazimo a[i] u nizu b */
for (j = 0; j < nb; j++)
if (a[i] == b[j])
break;
/* Ako je petlja stigla do kraja, znaci da niz b ne sadrzi a[i] pa
ga dodajemo u razliku r */
if (j == nb)
r[nr++] = a[i];
}
/* Ispisujemo elemente razlike */
338
B. Reenja zadataka
printf("Razlika: ");
for (i = 0; i < nr; i++)
printf("%d ", r[i]);
printf("\n");
return 0;
an
je
int main() {
/* Rec koja se proverava */
char s[] = "anavolimilovana";
/* Bulovska promenljiva koja cuva rezultat */
int palindrom = 1;
(2
01
5)
sk
o
iz
ro
n
kt
le
/* Ispisujemo rezultat */
if (palindrom)
printf("Rec %s je palindrom\n", s);
else
printf("Rec %s nije palindrom\n", s);
#include <stdio.h>
#include <string.h>
int main() {
/* Niska koja se obrce */
char s[] = "Zdravo";
/* Nisku obilazimo paralelno sa dva kraja sve dok se pozicije ne
susretnu, razmenjujuci karaktere */
int i, j;
339
B. Reenja zadataka
(2
01
5)
je
#include <stdio.h>
#include <assert.h>
an
ro
n
iz
sk
o
/* Ucitavanje matrice */
scanf("%u", &n);
assert(n < MAX);
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
scanf("%d", &m[i][j]);
int main() {
unsigned n, i, j, k;
int m[MAX][MAX];
le
kt
return 0;
340
B. Reenja zadataka
int main() {
unsigned m, n, i, j;
int a[MAX][MAX];
(2
01
5)
/* Ucitavamo matricu */
scanf("%d%d", &m, &n);
assert(m < MAX && n < MAX);
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
scanf("%d", &a[i][j]);
iz
an
je
sk
o
return 0;
kt
ro
n
le
Jezik C - funkcije
#include <stdio.h>
int prost(unsigned n) {
unsigned d;
if (n <= 1) return 0; /* najmanji prost broj je 2 */
/* Proveravaju se delioci do korena i prekida se ako se
pronadje delioc (moze da prekoraci za jako veliko n) */
for (d = 2; d * d <= n; d++)
if (n % d == 0)
341
return 0;
/* Ako delioc nije pronadjen, broj je prost */
return 1;
int main() {
/* Ucitava se broj i proverava da li je prost */
unsigned n;
scanf("%u", &n);
printf(prost(n) ? "Prost\n" : "Nije prost\n");
}
an
je
#include <stdio.h>
#include <math.h>
(2
01
5)
B. Reenja zadataka
iz
le
kt
ro
n
sk
o
int main() {
double xa, ya, xb, yb, xc, yc;
scanf("%lf%lf", &xa, &ya);
scanf("%lf%lf", &xb, &yb);
scanf("%lf%lf", &xc, &yc);
double a = rastojanje(xb, yb, xc, yc);
double b = rastojanje(xa, ya, xc, yc);
double c = rastojanje(xa, ya, xb, yb);
double s = (a + b + c) / 2.0;
double P = sqrt(s * (s - a) * (s - b) * (s - c));
printf("%lf\n", P);
return 0;
}
#include <stdio.h>
unsigned suma_delilaca(unsigned n) {
unsigned s = 1, d;
for (d = 2; d*d < n; d++)
if (n % d == 0)
s += d + n / d;
342
B. Reenja zadataka
if (d * d == n)
s += d;
return s;
(2
01
5)
int savrsen(unsigned n) {
return n == suma_delilaca(n);
}
je
int main() {
unsigned n;
for (n = 1; n <= 10000; n++)
if (savrsen(n))
printf("%u\n", n);
return 0;
}
sk
o
/* Struktura razlomak */
struct razlomak {
int brojilac, imenilac;
};
iz
#include <stdio.h>
#include <assert.h>
an
le
kt
ro
n
343
B. Reenja zadataka
(2
01
5)
an
iz
je
#include <stdio.h>
ro
n
sk
o
le
kt
344
B. Reenja zadataka
int i;
int s = 0;
for (i = 0; i < n; i++)
s += a[i];
return (double)s / (double)n;
je
sk
o
iz
an
(2
01
5)
kt
ro
n
le
int main() {
int a[] = {3, 2, 5, 4, 1, 3, 8, 7, 5, 6};
int n = sizeof(a) / sizeof(int);
printf("Sadrzi: %d\n", sadrzi(a, n, 3));
printf("Prva pozicija: %d\n", prva_poz(a, n, 3));
printf("Poslednja pozicija: %d\n", poslednja_poz(a, n, 3));
printf("Suma: %d\n", suma(a, n));
printf("Prosek: %lf\n", prosek(a, n));
printf("Minimum: %d\n", min(a, n));
printf("Pozicija maksimuma: %d\n", max_poz(a, n));
printf("Sortiran: %d\n", sortiran(a, n));
return 0;
}
345
B. Reenja zadataka
iz
an
je
(2
01
5)
kt
ro
n
sk
o
le
346
B. Reenja zadataka
a[i] = a[i-1];
a[0] = x;
return n + 1;
(2
01
5)
iz
an
je
sk
o
le
kt
ro
n
347
n = izbaci_poslednji(a, n);
ispisi(a, n);
n = ubaci_na_poz_k(a, n, 2, 4);
ispisi(a, n);
n = ubaci_na_kraj(a, n, 1);
ispisi(a, n);
n = izbaci_sve(a, n, 1);
ispisi(a, n);
return 0;
(2
01
5)
B. Reenja zadataka
je
#include <stdio.h>
d
iz
sk
o
an
le
kt
ro
n
348
B. Reenja zadataka
an
je
(2
01
5)
le
kt
ro
n
sk
o
iz
349
B. Reenja zadataka
return j == m;
je
(2
01
5)
ro
n
sk
o
iz
an
le
kt
350
(2
01
5)
B. Reenja zadataka
sk
o
iz
an
je
le
kt
ro
n
351
B. Reenja zadataka
return 0;
(2
01
5)
#include <stdio.h>
je
an
d
iz
sk
o
int main() {
printf("%d\n", poredi("zdravo", "svima"));
return 0;
}
ro
n
kt
#include <stdio.h>
le
352
B. Reenja zadataka
iz
an
je
(2
01
5)
ro
n
sk
o
int main() {
printf("%d\n", podniz("banana", "ann"));
printf("%d\n", podniska("banana", "anan"));
return 0;
}
kt
le
#include <stdio.h>
353
B. Reenja zadataka
(2
01
5)
iz
an
je
/* Provera funkcije */
int main() {
char s[] = "tom marvolo riddle ", t[] = "i am lord voldemort";
printf("%d\n", permutacija(s, t));
return 0;
}
sk
o
#include <stdio.h>
#include <assert.h>
le
kt
ro
n
354
B. Reenja zadataka
iz
je
an
(2
01
5)
le
kt
ro
n
sk
o
355
B. Reenja zadataka
(2
01
5)
sk
o
iz
an
je
le
kt
ro
n
356
B. Reenja zadataka
return m;
je
an
sk
o
iz
int main() {
MATRICA m1, m2, m;
m1 = ucitaj(); m2 = ucitaj();
if (m1.m == m2.m && m1.n == m2.n) {
m = saberi(m1, m2);
ispisi(m);
}
if (m1.n = m2.m) {
m = pomnozi(m1, m2);
ispisi(m);
}
return 0;
}
(2
01
5)
void ispisi(MATRICA m) {
unsigned i, j;
for (i = 0; i < m.m; i++) {
for (j = 0; j < m.n; j++)
printf("%g ", m.a[i][j]);
putchar(\n);
}
}
ro
n
kt
le
B. Reenja zadataka
}
/* Obrcemo zapis */
for (i = 0, j = rez.n-1; i < j; i++, j--) {
unsigned char tmp = rez.c[i];
rez.c[i] = rez.c[j];
rez.c[j] = tmp;
}
return rez;
void ispisi(BROJ b) {
int i;
for (i = b.n-1; i >= 0; i--)
putchar(0 + b.c[i]);
}
(2
01
5)
357
le
kt
ro
n
sk
o
iz
an
je
B. Reenja zadataka
(2
01
5)
358
iz
an
je
/* Normalizujemo rezultat */
p = 0;
for (i = 0; i < rez.n; i++) {
unsigned char c = rez.c[i] + p;
rez.c[i] = c % 10;
p = c / 10;
}
/* Ako je prva cifra 0, smanjujemo broj cifara */
if (rez.c[rez.n-1] == 0)
rez.n--;
return rez;
kt
ro
n
sk
o
int main() {
BROJ a = ucitaj(), b = ucitaj(), c;
c = saberi(a, b);
ispisi(c);
putchar(\n);
c = pomnozi(a, b);
ispisi(c);
putchar(\n);
}
le
Jezik C - pokazivai
#include <stdio.h>
#include <assert.h>
/* Funkcija vraca 3 vrednosti preko pokazivaca */
void od_ponoci(unsigned n, unsigned* h, unsigned *m, unsigned *s) {
*h = n / 3600;
n %= 3600;
*m = n / 60;
359
B. Reenja zadataka
n %= 60;
*s = n;
(2
01
5)
int main() {
unsigned n, h, m, s;
scanf("%d", &n); assert(n < 60*60*24);
od_ponoci(n, &h, &m, &s);
printf("%d:%d:%d\n", h, m, s);
return 0;
}
je
#include <stdio.h>
d
iz
sk
o
int pozitivan(int x) {
return x > 0;
}
an
int paran(int x) {
return x % 2 == 0;
}
le
kt
ro
n
360
B. Reenja zadataka
(2
01
5)
an
d
je
#include <stdio.h>
sk
o
iz
ro
n
le
kt
void my_strrev(char* s) {
char *t = s;
/* Dovodimo s ispred terminalne nule */
while(*s)
s++;
s--;
/* Obrcemo karaktere */
for (; t < s; t++, s--) {
char tmp = *s; *s = *t; *t = tmp;
}
}
const char* my_strchr(char x, const char* s) {
while(*s) {
if (*s == x) return s;
s++;
361
B. Reenja zadataka
}
return NULL;
}
return NULL;
je
(2
01
5)
ro
n
sk
o
iz
an
int main() {
char s[] = "abc", t[] = "def", r[4];
printf("%lu %lu\n", my_strlen(s), my_strlen(t));
my_strcpy(r, s);
printf("%s\n", r);
my_strrev(s);
printf("%s\n", s);
printf("%d\n", my_strcmp(s, t));
printf("%c\n", *my_strchr(x, "abcxyz"));
printf("%s\n", my_strstr("abcdefghi", "def"));
return 0;
}
kt
le
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
int main() {
unsigned n, i, min;
int *a, x;
/* Ucitavamo niz */
scanf("%u", &n);
assert(n > 0);
a = malloc(n*sizeof(int)); /* Dinamicka alokacija */
assert(a != NULL);
for (i = 0; i < n; i++)
362
B. Reenja zadataka
scanf("%d", &a[i]);
je
an
/* Oslobadjamo niz */
free(a);
return 0;
(2
01
5)
#define KORAK 32
sk
o
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
iz
ro
n
int main() {
unsigned n = 0, aloc = 0, i, m, nm;
int *a = NULL;
le
kt
363
B. Reenja zadataka
(2
01
5)
je
return 0;
sk
o
iz
an
/* Oslobadjamo niz */
free(a);
ro
n
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
int main() {
int n, i, j, lx, ux, ly, uy, **A;
le
kt
364
B. Reenja zadataka
(2
01
5)
an
sk
o
return 0;
iz
je
/* Oslobadjamo matricu */
for (i = 0; i < n; i++)
free(A[i]);
free(A);
ro
n
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
le
kt
365
B. Reenja zadataka
int main() {
int n, i, j, **A;
/* Ucitavamo dimenziju matrice */
scanf("%d", &n);
(2
01
5)
an
je
return 0;
iz
ro
n
sk
o
/* Oslobadjamo matricu */
for (i = 0; i < n; i++)
free(A[i]);
free(A);
kt
Jezik C - ulaz/izlaz
le
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* argv[]) {
int zbir = 0;
for (i = 0; i < argc; i++)
zbir += atoi(argv[i]);
printf("%d\n", zbir);
return 0;
}
366
B. Reenja zadataka
(2
01
5)
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
/* Racuna se zbir kolone j matrice A dimenzije n */
int zbir_kolone(int** A, unsigned n, unsigned j) {
int i, zbir = 0;
for (i = 0; i < n; i++)
zbir += A[i][j];
return zbir;
}
an
je
sk
o
iz
if (argc < 2) {
fprintf(stderr, "Greska: nedostaje ime ulazne datoteke\n");
return -1;
}
kt
ro
n
le
367
B. Reenja zadataka
/* Odredjujemo maksimum */
max_j = 0; max = zbir_kolone(A, n, 0);
for (j = 1; j < n; j++) {
int m = zbir_kolone(A, n, j);
if (m > max) {
max_j = j;
max = m;
}
}
/* Prijavljujemo rezultat */
printf("Kolona: %u Zbir: %d\n", max_j, max);
an
je
/* Oslobadjamo matricu */
for (i = 0; i < n; i++)
free(A[i]);
free(A);
iz
/* Zatvaramo datoteku */
fclose(dat);
return 0;
sk
o
(2
01
5)
ro
n
kt
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
le
#define KORAK 64
typedef struct {
char ime[20];
char prezime[20];
unsigned br_ispita;
} APSOLVENT;
int main() {
FILE* dat;
APSOLVENT* apsolventi = NULL, apsolvent;
unsigned aloc = 0, n = 0, i, zbir;
float prosek;
dat = fopen("apsolventi.txt", "r");
368
B. Reenja zadataka
if (dat == NULL) {
fprintf(stderr,
"Greska pri otvaranju datoteke apsolventi.txt\n");
return 1;
}
an
je
(2
01
5)
/* Zatvaramo datoteku */
fclose(dat);
sk
o
iz
kt
ro
n
le
/* Oslobadjamo memoriju */
free(apsolventi);
return 0;
369
B. Reenja zadataka
je
(2
01
5)
ro
n
sk
o
iz
an
le
kt
370
n /= b;
} while (n > 0);
s[i] = \0;
/* Obrce se niz cifara */
for (j = 0, --i; j < i; j++, i--) {
char tmp = s[i];
s[i] = s[j];
s[j] = tmp;
}
(2
01
5)
B. Reenja zadataka
an
je
le
kt
ro
n
sk
o
iz
/* Otvaranje datoteka */
if (argc < 3) {
fprintf(stderr, "Upotreba: %s <ulaz> <izlaz>\n", argv[0]);
return 1;
}
ulaz = fopen(argv[1], "r");
if (ulaz == NULL) {
fprintf(stderr, "Greska prilikom otvaranja %s\n", argv[1]);
return 1;
}
izlaz = fopen(argv[2], "w");
if (izlaz == NULL) {
fprintf(stderr, "Greska prilikom otvaranja %s\n", argv[2]);
return 1;
}
iz
an
/* Zatvaramo datoteke */
fclose(ulaz);
fclose(izlaz);
return 0;
le
kt
ro
n
sk
o
itob(n, 2, bs);
fputs(bs, izlaz); fputc(\n, izlaz);
} else {
/* Oktalni broj pocinje sa 0 */
n = btoi(t, 8);
printf("%u\n", n);
itob(n, 2, bs);
fputs(bs, izlaz); fputc(\n, izlaz);
}
} else {
/* Dekadni broj */
n = btoi(t, 10);
printf("%u\n", n);
itob(n, 2, bs);
fputs(bs, izlaz); fputc(\n, izlaz);
}
je
B. Reenja zadataka
(2
01
5)
371
le
E
ro
n
kt
sk
o
d
iz
an
je
(2
01
5)
372
B. Reenja zadataka
(2
01
5)
Indeks
abakus, 12
an
ABC (raunar), 15
algoritam, 61
analitika maina, 13
API, 35, 269
argument funkcije, 86
iz
analogni zapis, 39
294
sk
o
getc, 289
getchar, 278
gets, 279
isalnum, 274
isalpha, 107, 274
isdigit, 107
isdigit, 274
islower, 274
isupper, 274
malloc, 258, 272
matematika (sin, cos, log2,
exp, . . . ), 275
printf, 93, 280
putc, 289
putchar, 278
rand, 272
realloc, 260, 272
scanf, 95, 283
sprintf, 285
sqrt, 96, 275
srand, 272
sscanf, 286
strcat, 269
strchr, 269
strcmp, 269
strcpy, 136, 248, 269
strlen, 135, 247, 269
strstr, 269
system, 272
tolower, 107, 274
toupper, 107, 274
je
ro
n
biblioteka funkcija
le
kt
assert, 276
calloc, 258, 272
exit, 272
fclose, 288
feof, 290
ferror, 290
fgets, 291
fopen, 287
fprintf, 292
fputs, 279, 291
fread, 292
free, 259, 272
fscanf, 292
fseek, 293
ftell, 293
fwrite, 292
373
374
B. Reenja zadataka
ungetc,
290
nara, 16
font, 48
blok dijagram, 62
brojevni sistem, 40
main,
(2
01
5)
parametar, 170
C (programski jezik), 18
poziv, 168
ANSI/ISO C, 92
C11, 92
C99, 92
je
239
an
171
er-Tjuringova teza, 63
datoteka, 286
tekstualna, 287
iz
binarna, 287
datoteka zaglavlja, 94, 186, 194, 269
ro
n
sk
o
<assert.h>, 276
<ctype.h>, 106, 274
<math.h>, 96, 275
<stdio.h>, 94, 277
<stdlib.h>, 258, 272
<string.h>, 269
debager, 190
kt
le
stvarna, 204
deljenje vremena, 18
diferencijska maina, 13
void,
171
halting problem, 72
hard disk, 26
198
EDVAC raunar, 16
elektromehanike maine, 13
ENIAC (raunar), 15
enigma maina, 15
375
B. Reenja zadataka
integrisano kolo, 17
democija, 127
interpretator, 78, 87
eksplicitna, 126
izraunljiva funkcija, 63
promocija, 126
kvalifikator
(2
01
5)
192
izvrni program, 79, 87, 94, 185,
218
jedinica prevoenja, 186, 192, 194,
203
jeziki procesor, vidi programski pre-
je
vodilac
kardinalnost, 69
kastovanje, vidi konverzija tipova (eksplicitna)
iz
kodiranje karaktera, 48
sk
o
ISO-8859, 51
klizni lenjir, 12
ISO-10646, 52
an
karakter, 48
UCS-2, 54
ro
n
kdna strana, 48
Unicode, 52
UTF-8, 54
windows-125x/ANSI, 51
kt
YUSCII, 50
magistrala, 23
magnetni dobo, 17
komentar, 94
kompilacija, 186
le
Kolos (raunar), 15
odvojena, 189
tiva
define
Mark I (raunar)
harvardski, 14
manesterski, 17
karakterska, 110
matina ploa, 23
memorija
kontroler, 23
ke, 25
126, 173
RAM, 24, 26
376
B. Reenja zadataka
ROM, 25
arnost, 112
asocijativnost, 113
mikroip, 17
bitovski, 119
mikroprocesor, 19
dekrementiranje, 115
mini raunari, 18
model boja, 55
inkrementiranje, 115
logiki, 117
RGB, 55
(2
01
5)
CMYK, 56
prioritet, 113
sizeof,
je
uslovni, 122
zarez, 122
174
nazubljivanje koda, 94
neodluiv problem, 71
parametar funkcije, 86
prenos po adresi, 86
sk
o
prenos po vrednosti, 86
Paskalina, 12
iz
niska, 134
an
izraza, 151
pokaziva, 233
na funkciju, 254
ro
n
niz, 132
poluprovodniki elementi, 17
potprogram, 85
poveziva, 187
kt
deklaracija, 133
le
NULL,
235
objektno-orijentisano programiranje,
79
odbirak, 39, 57
->,
253
adresni, 234
aritmetiki, 104, 107, 114
377
B. Reenja zadataka
undef,
196
procesorska instrukcija, 29
sintaksiko stablo, 81
programiranje, 11
sloenost izraunavanja, 73
programska paradigma, 80
programski jezik
(2
01
5)
aplikativni, 34
asemblerski, 28
sistemski, 34, 91
mainski zavisan, 26
je
an
struktura, 140
punilac, 190
raunar, 11
elektromehaniki, 14
elektronski, 14
iz
definicija, 141
78
sk
o
inicijalizacija, 142
prenos u funkciju, 177
bool, 108
char, 106
double, 96, 107
float, 107
int, 93, 104
rasterska grafika, 55
logiki, 108
lini, 19
ro
n
sa skladitenim programom, 16
raunarstvo i informatika, 11
kt
oblasti, 21
le
rezolucija, 56
sakuplja otpada, 86
pokazivaki, 233
size_t,
123
typedef, 147
unija (union),
void*, 235
140, 144
semantiki analizator, 87
Tjuringova maina, 62
tok, 277
82
146
opseg, 105
token, 81
378
B. Reenja zadataka
tranzistor, 17
ulazno-izlazni ureaji, 16, 23, 26
unija, 144
Unix (operativni sistem), 18, 91
upozorenje prevodioca, 95, 210
(2
01
5)
UR maina, 62, 64
vakuumska cev, 17
vektorska grafika, 55
Z3 (raunar), 14
zapis
fiksni zarez, 47
neoznaeni brojevi, 41
je
an
oznaeni brojevi, 45
pokretni zarez, 47, 107
potpuni komplement, 45
realni brojevi, 46
iz
slika, 55
tekst, 48
akardov razboj, 13
sk
o
zvuk, 56
le
kt
ro
n