149

Click here to load reader

Programski Jezici i Strukture Podataka

Embed Size (px)

DESCRIPTION

sadasdasdasdasdasdasdascxzczdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdadasdasdasdasdasd

Citation preview

Page 1: Programski Jezici i Strukture Podataka

FAKULTET TEHNIČKIH NAUKA

UNIVERZITETA U NOVOM SADUElektrotehnika i računarstvoOdsek za računarstvo i automatiku

prof. dr Dušan Malbaški 02 ESE2 501

Programski jezici i

Semestar

1

Page 2: Programski Jezici i Strukture Podataka

strukture podataka

1

Page 3: Programski Jezici i Strukture Podataka

PROF. DR DUŠAN MALBAŠKI , TMD 145

Programski jezici i strukture podataka

UNIVERZITET U NOVOM SADUFakultet tehničkih nauka

Elektrotehnika i računarstvoOdsek za računarstvo i automatiku

Šifra predmeta: 02 ESE2 501Semestar: I

Predavanja u semestru/u nedelji: 60 / 4Vežbi u semestru/u nedelji: 10N+50C / 4Asistenti: mr Branko Markoski, TMD 9A

Žarko Ivanov, TMD 15A

LITERATURA:O'Brian S.: Turbo Pascal 6.0, Mikro Knjiga, Beograd, 1991. (ili ekvivalent)

Malbaški D., Obradović D.: Osnovne strukture podataka, UNS, 1995.Hotomski P., Malbaški D.: Matematička logika i principi programiranja, UNS, 2000.

Malbaški D.: Odabrana poglavlja metoda programiranja, UNS, 2002.

Page 4: Programski Jezici i Strukture Podataka

Sadržaj

Page 5: Programski Jezici i Strukture Podataka

U V O D

Uvod Error! Bookmark not defined.

Alfabet Pascala 2

T I P O V I P O D A T A K A

Tipovi podataka 4

Hijerarhija operatora 5

Logički tip 5

Celobrojni tip 6

Realni tip 7

Znakovni tip 8

String 8

Enumeracija 9

Intervalni tip 9

Nizovi 10

Skupovi 11

Slog 12

Datoteke 13

Primer 18

S T R U K T U R A P R O G R A M A

Opšta struktura programa 22

Zaglavlje 22

Deklaracije 23

Algoritamski deo 24

N A R E D B E

Naredba dodele 26

Složena naredba (sekvenca) 26

Naredbe selekcije 26

Petlje 28

Naredbe skoka 29

Elementarni ulaz/izlaz 30

M O D U L I

Potprogrami 31

Moduli 35

Šta se nalazi u modulu 37

Jedinice u Turbo Pascalu 37

Pascalovi gotovi uniti 39

Page 6: Programski Jezici i Strukture Podataka

Primer 39

Page 7: Programski Jezici i Strukture Podataka

1

Tema

1

Page 8: Programski Jezici i Strukture Podataka

D E S I G N C U S T O M I Z A T I O N

Programski jezik Pascal

U ovom delu ćemo obraditi osnove programskog jezika Pascal, sa posebnom pažnjom na Turbo Pascal. Bavićemo se tipovima podataka u Turbo Pascalu, a spomenućemo i opštu strukturu pascalskih programa, neke osnovne naredbe i rad sa potprogramima.

askal se pojavio 1969. Njegov autor je Švajcarac Niklaus Wirth, a ime je dobio po Francuzu Blezu Pascalu, izumitelju prve mašine za računanje.

Nastao je posle prve velike softverske krize koja je nastala zbog toga što tadašnji softver nije mogao da zadovolji potrebe korisnika i iskoristi mogućnosti hardvera. Pascal je nastao na bazi programskog jezika ALGOL (ALGOrhitmic Language) tako što je preuzeta većina komandi (neke su odbačene), a uvedene su nove strukture podataka. Inače, Pascal nije prvobitno pisan za izvršavanje na računaru, već za prikazivanje programa, tj. imao je edukativnu ulogu.

P

Pascal je standardizovan programski jezik što znači da postoji neka osnovna struktura koja je ista za sve verzije ovog programskog jezika i stoga se program pisan za jednu verziju uz manje izmene može izvršavati na računaru sa nekom drugom verzijom Pascala. Zbog toga, osnovna svrha Pascala kakav je on sad je pisanje čitljivih i razumljivih programa. Takav program se lako ispravlja i modifikuje, a takođe ga nije potrebno posebno dokumentovati, jer je sam program prilično razumljiv. Pascal je prvi programski jezik koji ima takvu strukturu da je omogućio pisanje programa bez upotrebe

skokova.

Četiri aspekta koje treba razjasniti prilikom programiranja

1. Kakvim tipovima podataka raspolažemo?

2. Kakvim upravljačkim strukturama raspolažemo?

Page 9: Programski Jezici i Strukture Podataka

P R O G R A M S K I J E Z I K P A S C A L

3. Kako se organizuje ulaz i izlaz?

4. Kako se vrši modularizacija (upotreba procedura, funkcija i modula)?

3

Page 10: Programski Jezici i Strukture Podataka

P R O G R A M S K I J E Z I K P A S C A L

Alfabet Pascala

Skup simbola koji se koriste u programskom jeziku naziva se alfabet programskog jezika.

Pascal je veštački jezik i stoga poseduje strogo definisan skup simobla koji se smeju koristiti.

U alfabet Pascala spadaju:

slova engleske abecede (karakteri), bez razlike velikih i malih slova i donja crta _

cifre od 0 do 9

specijalni znaci (+, =, :, -, *, :=, <= itd.)

Skup simbola koji se koriste u programskom jeziku naziva se alfabet programskog jezika.

Pascal program ima slobodan format, što znači da ne postoje striktna pravila o rasporedu komandi u tekstu programa. Ali zbog toga mora da postoji rečnik programskog

jezika (sadrži rezervisane reči).

U programu se indikatorima jednoznačno identifikuju promenljive, konstante, tipovi i potprogrami. Identifikatori se izgrađuju poštujući sledeća pravila:

u identifikator mogu samo da uđu slova, cifre i donja crta;

identifikator mora da počne slovom;

postoji maksimalna dužina identifikatora koja zavisi od programskog jezika.

Identifikatori koji imaju semantiku treba da imaju mnemoniku.

4

Page 11: Programski Jezici i Strukture Podataka

P R O G R A M S K I J E Z I K P A S C A L

To znači da ako identifikator predstavlja npr. neku realnu veličinu, njegovo ime treba da asocira na tu veličinu (npr. sila, masa itd.). Postavlja se pitanje da li treba koristiti englesku mnemoniku ili mnemoniku maternjeg jezika. Engleski jezik ima drugačiju strukturu od srpskog, tako da je engleska mnemonika kraća. Takođe, naredbne programskog jezika su na engleskom, ali postoji ograničenje u vidu dovoljnog poznavanja stranog jezika.

Naredbe se uvek razdvajaju separatorom. U Pascalu to je tačkazarez:

naredba1; naredba2;

Komentar je slobodni tekst čija je svrha da razjasni potencijalno nejasne delove koda. U Pascalu, se komentari umeću između vitičastih zagrada:

{ovo je komentar}

Dobra upotreba identifikatora eliminiše najveći deo potrebe za komentarima.

5

Page 12: Programski Jezici i Strukture Podataka

Tipovi podataka

Kad je Pascal nastao, prava inovacija koju je on doneo bila je u domenu tipova podataka. Ranije je postojao mali broj tipova i nije bilo moguće da programer kreira svoj sopstveni.

U Pascalu postoji određeni broj ugrađenih tipova na osnovu kojih gradimo sopstvene tipove. Treba voditi računa da izgrađeni tip što vernije i jasnije odražava ono na šta se odnosi.

Tipovi podataka

enumeracija

interval

tipovi podataka

osnovni (skalarni)izvedeni (strukturirani)

standardnideo su programskog

jezika, na njih programer nema uticaja

nestandardnikoje programer sam

pravi

logički (Bulov)

celobrojni

realni

znakovni

string

niz

skup

slog

datoteka

pokazivač

Page 13: Programski Jezici i Strukture Podataka

P R O G R A M S K I J E Z I K P A S C A L

Svi osnovni tipovi u Pascalu imaju identifikator. A u sastav tipa ulaze vrednosti i operacije.

Hijerarhija operatoraPošto u izrazu figurišu promenljive, konstante, operatori i funkcije, mora postojati redosled izvođenja operacija. Postoje određene razlike u odnosu na ovu hijerarhiju u matematici.

Redosled je sledeći:

zagrade: ( i );funkcije;operator not;operatori: *, /, div, mod i and;operatori +, -, or irelacioni operatori: =, <>, >, >=, <, <= i operator in

Ukoliko se desi da su operatori na istom nivou prioriteta, onda se primenjuje pravilo „s leva na desno“.

Logički tipNjegov identifikator je: Boolean. Zbog nemogućnosti da se u Pascalu koriste matematičke oznake za tačno i netačno (T i ), uvedene su logičke konstante koje su dobile posebna imena. To su true i false.

Logičke operacije

Postoje tri osnovne logičke operacije u Pascalu. To su konjunkcija, disjunkcija i neegacija. U tabeli su upoređene matematičke i Pascalove oznake tih funkcija.

operacija u matematici u Pascalukonjunkcija and

disjunkcija or

negacija not

Relacioni operatori

U Pascalu ne postoje relacije kao u matematici. Postoje relacioni operatori, pa se relacije u stvari tretiraju kao operacije koje imaju rezultat.

Ovaj tip ima dve logičke vrednosti: tačno i netačno.

7

Page 14: Programski Jezici i Strukture Podataka

P R O G R A M S K I J E Z I K P A S C A L

Uz podatke logičkog tipa mogu se koristiti sledeći relacioni operatori:

operator značenje= jednako

<> nije jednako> veće

>= veće ili jednako< manje

<= manje ili jednako

Upotrebom relacionih operatora mogu se iskazati i sledeće složene matematičke relacije:

operacija u matematici u Pascaluimplikacija p<=q

ekvivalencija p=qekskluzivna disjunkcija

p<>q

Celobrojni tipOvaj tip obuhvata familiju tipova, ali osnovni je integer. U Pascalu se tip promenljive određuje zavisno od toga koji raspon promenljiva zauzima u modelu.

tip opseginteger od -32 768 do 32 767 2Bshortint od -128 do 127 1Blongint od oko -2,14∙109 do 2,14∙109 4B

byte od 0 do 255 1Bword od 0 do 65 535 2B

Operacije

Operacije koje možemo vršiti sa podacima celobrojnog tipa su: sabiranje (+), oduzimanje (-), množenje (*), deljenje (/), celobrojno deljenje (div) i ostatak pri deljenju (mod). Rezultat deljenja je uvek realan broj bez obzira što delimo cele brojeve, a ako želimo da deljenjem dobijemo ceo broj, koristićemo operator div. Treba voditi računa da operator div samo odbaci brojeve iza decimalne tačke i na taj način formira ceo broj. Tako dobijamo da je 9 div 10 = 0 iako bi matematičkim zaokruživanjem dobili 1.

Važno!false < true

8

Page 15: Programski Jezici i Strukture Podataka

P R O G R A M S K I J E Z I K P A S C A L

Funkcije

Funkcije kojima raspolažemo kada obrađujemo podatke celobrojnog tipa su: apsolutna vrednost (abs), kvadrat broja (sqr), neparnost (odd), sledbenik (succ) i prethodnik (pred).

Tipovi byte i word

Ovi tipovi nemaju ulogu da modeliraju cele brojeve. Naime, u njihovom registru ne postoji mesto za predznak, pa se zbog toga svi bitovi jednako tretiraju. Ovi tipovi prvenstveno služe za operacije nad bitovima ćelije.

Da bi sadržaj ćelije po bitovima bio vidljiv programeru, cele brojeve možemo lakše prikazati u obliku heksadecimalnog zapisa, tako što ćemo ispred zapisa staviti znak $ koji prevodiocu označava da je u pitanju heksadecimalni podatak. Na primer:

$7A2C

Nepisano je pravilo da se koriste velika slova za brojeve od A do F.

U heksadecimalnom zapisu, raspon koji može uzeti byte podatak je od $00 do $FF, a word od $0000 do $FFFF.

Bit operacije

Na tipove byte i word su primenljive još neke operacije. To su tzv. bit operacije. To mogu biti logičke operacije and, or, not i xor. N.b. označavaju se isto kao Bulove operacije. Ove operacije obrađuju svaki bit posebno. Tako:

Not $000F = $FFF0

Naravno, ove operacije su primenljive i na ostale celobrojne tipove, ali njihov rezultat ne može biti neposredno jasan.

Pored ovih za rad sa bitovima standardne su još i shl i shr, koje služe za pomeranje (šift) bitova u levo i u desno.

9

Page 16: Programski Jezici i Strukture Podataka

P R O G R A M S K I J E Z I K P A S C A L

Realni tipI ovaj tip obuhvata familiju tipova, gde je osnovni tip real. Ovo je podskup skupa realnih brojeva. Dok je u matematici skup celih brojeva podskup skupa realnih brojeva (Z R), u programiranju to ne važi. Celobrojni tip nije podskup realnog tipa.

Podaci realnog tipa se prikazuju u obliku decimalnog zapisa

(5,6) ili eksponencijalno (56E-1). Mantisa eksponencijalnog zapisa može biti realan broj, dok je eksponent uvek ceo broj. Zavisno od veličine broja koristićemo određenu notaciju. Eksponencijalna notacija se koristi za zapis mnogo velikih i mnogo malih brojeva.

tip opsegsingle od 1,5∙10-45 do 3,4∙1038 4B

real od 2,9∙10-39 do 1,7∙1038 6Bdouble od 5∙10-324 do 1,7∙10308 8Bcomp od -9,2∙1018 do 9,2∙1018 8B

extended 3,4∙10-4932 do 1,1∙104932

10B

Tip comp modelira celobrojni tip. On ne posduje razlomljeni deo.

Operacije

Operacije koje možemo vršiti sa podacima realnog tipa su: sabiranje (+), oduzimanje (-), množenje (*) i deljenje (/).

Funkcije

Funkcije koje možemo koristiti sa podacima realnog tipa su: apsolutna vrednost (abs), kvadrat broja (sqr), kvadratni koren (sqrt), sinus (sin), kosinus (cos), arkus tangengs (arctan), prirodni logaritam (ln), eksponent (exp). Pored ovih postoje i dve funkcije koje povezuju realni tip sa celobrojnim. To su odsecanje decimala (trunc) i zaokruživanje (round).

Znakovni tipNjegov identifikator je char. Skup svih znakova se zove karakter set (character set). Pascalov karakter set obuhvata 255 znakova ASCII kôda gde spadaju prazno mesto, brojevi, velika i mala slova engleske abecede, interpunkcijski i specijalni znaci i simboli.

10

Page 17: Programski Jezici i Strukture Podataka

P R O G R A M S K I J E Z I K P A S C A L

Podatke znakovnog tipa označavamo tako što ih stavljamo među jednostruke znake navoda:

'L'

Znakove možemo dodeljivati konstantama takođe navodeći njihov ASCII kod iza prefiksa #. Na primer:

#76 = 'L'

Relacioni operatori

Sa podacima znakovnog tipa takođe možemo koristiti relacione operatore. Prilikom upoređivanja, upoređuju se ordinalni brojevi karakterâ. U Pascalu, ordinalni broj nekog karaktera odgovara ordinalnom broju tog karaktera u ASCII kôdu.

Funkcije

Od funkcija možemo koristiti: prethodnik (pred), sledbenik (succ), određivanje ordinalnog broja ASCII kôda (ord) i određivanje karaktera definisanog ordinalnim brojem ASCII kôda (chr).

StringOvo je tekstualni tip, tj. njegove promenljive su tekstovi.

Mora se voditi računa da tip string i char ne mogu biti ekvivalentni, jer se operacije nad njima razlikuju. Takođe, prazan string postoji, dok prazan znak ne može da postoji. Na kraju, podatak tipa char ima dužinu jedan znak, dok podatak tipa string može da ima dužinu do 255 znakova.

Naime, kod stringa, prvi bajt se ne koristi za smeštaj podatka, već za čuvanje dužine stringa. Pošto bajt ima raspon vrednosti od 0 do 255, time je i dužina stringa ograničena na maksimalno 255 znakova.

Podatke string tipa označavamo isto kao i char, tj. stavljanjem među apostrofe:

'Luka'

Dužina stringa se može unapred zadati ako ga deklarišemo pomoću:

string[duzina]

11

Page 18: Programski Jezici i Strukture Podataka

P R O G R A M S K I J E Z I K P A S C A L

Operacije

Operacija sa stringovima ima nekoliko desetina, ali jedna od najvažnijih je konkatenacija, tj. spajanje stringa. Ona se vrši pomoću operatora +:

'Luka' + ' Ranisavljević' = 'Luka Ranisavljević'

Pored ove, dosta se koristi i funkcija za određivanje aktuelen dužine stringa length.

EnumeracijaOvo je nestandardni skalarni tip. Razlikuje se od svih ostalih do sada spomenutih, zato što je njegov domet uvek program u kojem je definisan. Ovaj tip ne postoji u Pascalu, pa ga programer definiše u svom programu. Drugi nazivi za ovaj tip su i nabrojivi tip, nabrojani tip itd.

Enumeracija ima unapred zadate vrednosti koje zadaje programer u programu gde je potrebna enumeracija. Vrednosti su konstante i imaju sintaksu identifikatora. Promenljiva tipa enumeracije može da uzme samo jednu od nabrojanih vrednosti.

Opšti obliktype ImeTipa = (sve_konstante_tipa);

Primer:

type Dani = (pon, uto, sre, cet, pet, sub, ned);

Operacije

Operacije sa ovim tipom su dosta jednostavne. To su sledbenik (succ) i prethodnik (pred). Takođe se mogu koristiti svih šest relacionih operatora (=, <>, >, >=, <, <=) i funkcija ord koja određuje redni broj.

Sve ove operacije možemo koristiti, jer redosled vrednosti

nije proizvoljan. Stoga svaka vrednost u enumeraciji ima svoj redni broj i to: prva je 0, druga je 1 itd.

Ulaz i izlaz za ovaj tip nisu definisani, pa se vrednosti promenljivima ovog tipa ne mogu zadavati pomoću procedura read i readln, niti se one mogu štampati pomoću write i writeln.

Enumeracija se koristi da bi se izbeglo šifriranje podataka.

12

Page 19: Programski Jezici i Strukture Podataka

P R O G R A M S K I J E Z I K P A S C A L

Intervalni tipOvo je izvedeni tip, jer se oslanja na neki od osnovnih tipova. Intervalni tip se izvodi iz nekog drugog tipa i to onih za koje postoji preslikavanje na skup prirodnih brojeva

(celobrojni i znakovni, ali ne real i string). Ovaj tip u stvari „iseca“ jedan segment iz osnovnog tipa.

Opšti obliktype ImeTipa = dg..gg

Gde je dg donja granica, a gg gornja granica.

Primer:

type RadniDani = pon..pet;type NulaDoSest = 0..6;

Ako je osnovni tip od kojeg se uzima interval neki izvedeni tip, prvo moramo definisati taj izvedeni tip. U gornjem primeru prvo moramo definisati tip Dani (enumeraciju), pa tek onda RadniDani.

Promenljive intervalnog tipa nasleđuju osobine osnovnog tipa, ali im je opseg određen donjom i gornjom granicom. Funkcije i operatori su definisani za ovaj tip kao i za osnovni.

Intervalni tip se koristi za definisanje drugih tipova kod kojih je bitno da se zada opseg (npr. definisanje opsega nizova) i ako je u domenu problema potrebno koristiti ovakav tip. Ako je potrebno strogo voditi računa da promenljiva ne izađe iz željenog opsega, koristićemo intervalni tip. Jer ako promenljiva izađe iz opsega, dobija se poruka o grešci.

NizoviOvo je izvedeni, struktuirani tip. Bez obzira na broj dimenzija, Pascal sve nizove tretira jednako. Niz obuhvata sekvencu određenih vrednosti, obavezno istog tipa. Njihov broj se zadaje u programu.

Opšti obliktype ImeTipa = array[opseg1, opseg2, ..., opsegN] of tip;

Opseg je integralnog tipa, cela enumeracija ili logički tip. Ne može biti real i integer. To znači da opseg može biti samo izvedeni celobrojni tip, kod kojeg je definisana donja i gornja granica. Vrednost opsega može biti i

13

Page 20: Programski Jezici i Strukture Podataka

P R O G R A M S K I J E Z I K P A S C A L

negativan po potebi ili izveden iz znakovnog tipa. U praksi se opseg najčešće zadaje kao 1 do n i ima ih jedan ili dva. Broj opsega određuje broj dimenzija niza.

Dvoindeksni nizovi skalara se zovu matrice.

Primeri:

type TNiz = array[1..5] of real;type TMatrica = array[1..4, 1..10] of integer;

Svaki element navedenog realnog niza se ponaša kao realna skalarana promenljiva, odnosno svaki element navedene celobrojne matrice se ponaša kao celobrojna skalarna promenljiva. Sve što možemo da radimo sa realnom (tj. celobrojnom) promenljivom možemo i sa članom odgovarajućeg niza.

Članovima niza pristupamo tako što navodimo njihov(e) indeks(e). Indeksi su konstante, promenljive i izrazi.

niz[i];matr[i,j];

U suštini Pascal ne poznaje tip matrice, samo tip niza (zbog uniformnosti), pa se matrica tretira kao niz nizova. Stoga TMatricu možemo definisati i na sledeći način:

type TMatrica = array[1..4] of array[1..10] of integer;

Prvi način je skraćeni zapis niza nizova. Slično, i članu matrice se može pristupiti na sledeći način:

matr[i][j];

Čitamo: j-ti element niza koji je i-ti element niza matr.

Isto tako se na sledeći način može pristupati vrstama matrice:

matr[i]

14

Page 21: Programski Jezici i Strukture Podataka

P R O G R A M S K I J E Z I K P A S C A L

SkupoviOvaj tip predstavlja metematičke skupove.

Opšti obliktype ImeTipa = set of tip_elemenata;

Elementi skupa moraju biti istog tipa i to mogu mogu biti sledeći tipovi: logički, znakovni, enumeracija i intervalni tip.

U Turbo Pascalu tip elementa može da ima najviše 256

različitih elemenata. To je posledica memorisanja skupa. Skup se čuva kao podatak od 32 bajta, što je 256 bita i to tako što se svakom potencijalnom elementu dodeli 1 bit. Ako element pripada skupu, njegov bit ima vrednost 1, u suprotnom 0.

Kao i u matematici i ovde važi da je redosled navođenja elemenata proizvoljan i nema uticaja na vrednost skupa. Takođe, udvojeni elementi se ne uzimaju u obzir.

Primeri:

type TMalaSlova = set of 'a'..'z';TOsnovneBoje = (crvena, zuta, plava);TSkupOsnovnihBoja = set of TOsnovneBoje;

Konstante ovog tipa su svi skupovi koji se mogu formirati od elemenata, s tim što je [ ] prazan skup.

Konstante od TSkupOsnovnihBoja bi bile sledeće:

[] [crvena] [zuta] [plava] [crvena, zuta] [crvena, plava] [zuta, plava] [crvena, zuta, plava]

Inače konstante možemo zadati i kao promenljive, izraze, imenovane konstante i opsege:

[i, i * j - 1, 3, 11..20]

15

Page 22: Programski Jezici i Strukture Podataka

P R O G R A M S K I J E Z I K P A S C A L

Operacije

Tu pre svega spada dodela vrednosti, kada vrednosti elemenata jednog skupa dodeljujemo elementima drugog skupa. Na primer:

type TSkup = set of 1..50;var s1, s1: TSkup;s1 := s2;

Zatim, tu spadaju još i unija, presek i razlika:

operacija u matematici u Pascaluunija A B a + b

presek A B a * b

razlika A \ B a - b

Relacioni operatori imaju posebna značenja kad se primenjuju na skupove:

operacija u matematici u Pascalupodskup A B a <= b

nadskup A B a >= b

jednakost A = B a = b

nejednakost A B a <> b

pripadnost a B a in b

Ranije su se skupovi najviše koristili za proveru da li se vrednost neke promenljive nalazi u odgovarajućem opsegu. Na primer, da li je neko slovo malo ili veliko. Pa da ne bismo pisali:

if (slovo = 'A' or slovo = 'B' or ...) then

koristimo skupove i pišemo kraće:

if slovo in [A..Z] then

SlogSlog se drugačije naziva zapis. Ovaj tip je izveden kao i niz, iz nekog osnovnog tipa, ali za razliku od elemenata niza, elementi sloga ne moraju biti istog tipa. Znači da tip sloga može biti izveden iz više različitih osnovnih tipova.

Slog nam omogućuje da u programu modeliramo određeni tzv. realni entitet čije osobine opisuju elementi tog sloga.

16

Page 23: Programski Jezici i Strukture Podataka

P R O G R A M S K I J E Z I K P A S C A L

Opšti obliktype ImeTipa = record

e1: tip1;e2: tip2;...eN: tipN;end;

Pri čemu je ei element sloga koji zovemo polje. Svako ei

može imati više identifikatora, u slučaju da više polja u jednom slogu ima isti tip. Tipovi polja su proizvoljni. Svako polje se ponaša kao samostalna promenljiva tog tipa.

Primer:

type Stanovnik = recordjmbg: string[13];ime: string[15];prezime: string[30];end;

U semantičkom smislu, elementi niza su samostalni, tj. svaki za sebe ima značenje. Ovo ne važi za elemente sloga. Elementi sloga zajedno opisuju entitet, pa svaki za sebe nema značenje.

Dodela vrednosti

Ako dodeljujemo vrednost jedne promenljive tipa sloga drugoj promenljivoj tipa sloga, vrednost svakog polja iz prve se kopira u odgovrajuće polje ove druge.

Zbog toga, slogu možemo pristupati u celini, ali i njegovim delovima (poljima). Određenom polju u slogu pristupamo ako imeđu imena sloga i polja stavimo tačku:

Stanovnik.jmbg := '1906983800052';

Iterator with

Naredbu with koristimo za pristup poljima sloga, s tim što nam ona omogućava da ne moramo svaki put navesti ime sloga kad pristupamo nekom polju. Njen cilj nije skraćivanje kôda, već preglednost i zadovoljavanje principa jedan posao – jedna naredba.

with a beginjmbg := '1906983800052';ime := 'Luka';prezime := 'Ranisavljevic'

end;

17

Page 24: Programski Jezici i Strukture Podataka

P R O G R A M S K I J E Z I K P A S C A L

Iteratori omogućavaju da se pristupi svakom elementu neke složene strukture.

DatotekeSvrha postojanja datoteke u svim programskim jezicima je permanentno čuvanje podataka. Podaci se u memoriji čuvaju najduže dok traje program. Dok se, na primer, lokalne promenljive čuvaju još kraće.

Izlaz iz programa nam je često potreban i posle završetka programa, pa ga zbog toga memorišemo. Ulaz iole obimnijih informacija je besmisleno raditi sa tastature. Inače se najveći deo informacija potrebnih za izvršavanje programa priprema iz datoteke, gde se oni provere, a potom ih program obradi. Zavisno od konkretne situacije izlaz ide na ekran ili u datoteku ili oboje.

Datoteka sa svojim sadržajem je fizički smeštena van

programa i nalazi se na permanentom mediju. Dakle, datoteke mogu da služe za komunikaciju između programa, što je standardni vid komunikacije.

Sa stanovišta Pascala, datoteka se sastoji od sekvencijalno

poređanih elemenata. Izrazito karakteristično je da je u svakom trenutku jedan elemenat markiran i zove se tekući elemenat. Tekući element može biti jedan od postojećih ili novi (tj. jedan iz poslednjeg postojećeg u sekvenci). Zbog toga i prazna datoteka ima tekući element. Procedure i funkcije se izvršavaju implicitno nad tekućim elementom, npr. prilikom čitanja ili pisanja, uvek se pristupa tekućem elementu.

Turbo Pascal ima dobro rešen datotečki sistem, tj. mehanizmi za korišćenje datoteka su jednostavni. Turbo Pascal raspoznaje tri različita tipa datoteka, od kojih standardnu primenu imaju prve dve. To su:

tipizirana datoteka;

tekstualna datoteka;

netipizirana datoteka.

Datoteke se čuvaju takve kakve jesu dok se eksplicitno ne promene.

Tekući elemenat je onaj na kojim se izršavaju procedure i funkcije.

18

Page 25: Programski Jezici i Strukture Podataka

P R O G R A M S K I J E Z I K P A S C A L

Tipizirana datoteka

Deklarišemo je naredbom type. Alternativni način (koji se često koristi) je direktno zadavanje tipa uz naziv promenljive. Na primer:

type TSlog = record{opis}end;

var f: file of TSlog;

Ne postoje naredbe za komunikaciju sa datotekama, već se koriste posebne procedure i funkcije. Za tipizirane datoteke postoje desetine procedura i funkcija, a najvažnije delimo u dve grupe.

1. U ovu grupu spadaju univerzalne procedure i funkcije, tj. one koje su iste u svim verzijama Pascala. To su četiri procedure i jedna funkcija. Prve dve procedure služe za pripremu datoteke, a druge dve za ulaz i izlaz.

a) rewrite(f) formira datoteku na spoljašnjem mediju ako ona još ne postoji. Ako postoji, briše sav njen sadržaj. Posle izvršavanja ove procedure, datoteka se sastoji od jedne prazne lokacije koja je tekuća.

b) reset(f) se koristi pod pretpostavkom da datoteka već postoji nezavisno od toga da li sadrži neke podatke ili je prazna. U svakom slučaju ona (potencijalne) podatke ne dira i postavlja prvi element da bude tekući. Pre korišćenja datoteke u programu mora se izvršiti rewrite ili reset.

c) read(f, elem) se koristi za čitanje podataka (tj. elemenata) iz datoteke. Parametar elem dobija vrednost tekućeg elementa, a marker tekuće lokacije se premešta na sledeću. Elem je bafer promenljiva.

d) write(f, elem) se koristi za upisivanje parametra elem u tekuću lokaciju. Isto se marker tekuće

19

Page 26: Programski Jezici i Strukture Podataka

P R O G R A M S K I J E Z I K P A S C A L

pomera na sledeću lokaciju. Za razliku od read, procedura write može da se izvede i nad praznom lokacijom. U tom slučaju ona dobija vrednost parametra elem i kreira se nova prazna lokacija koja postaje tekuća. Zbog toga datoteka može da se proširuje u memoriji.

Element datoteke se ne može eksplicitno obrisati.

e) eof(f) (End Of File) je ugrađena funkcija koja vraća promenljivu Bulovog tipa. Vrednost vraćene promenljive je true, ako je kao tekući označen element iza poslednjeg nepraznog (tj. novi). U suprotnom, ova funkcija vraća false.

2. U ovoj grupi su procedure i funkcije koje postoje u svim verzijama, ali im sintaksa varira od verzije Pascala. Ove su nam (kao i one iz prve grupe) neophodne za rad sa datotekama.

a) Assign(f, putanja) – za ovu proceduru se može reći da je osnovna u radu sa datotekama. Spoljnjo ime datoteke je njeno pravo ime i u skladu je sa pravilima imenovanja operativnog sistema. U programu ne koristimo to ime, već neku promenljivu (npr. f). Da bi napravili asocijaciju između internog i eksternog imena datoteke koristimo Assign. Parametar f je interno ime datoteke, a putanja je tipa string i predstavlja apsolutnu ili relativnu putanju do fajla na mediju.

Kad koristimo neku datoteku u programu, prvo ćemo izvršiti proceduru Assign, da bi računar znao sa kojom datotekom radi.

b) Close(f) je procedura koja se koristi da zatvorimo datoteku kad nam više nije potrebna. Posle zatvaranja datoteka nam više nije na raspolaganju dok ponovo ne izvršimo Assign.

U Turbo Pascalu se sve preostale otvorene datoteke (koje nismo eksplicitno zatvorili) automatski zatvaraju pre završetka programa. U praksi se pribegava tome da se

20

Page 27: Programski Jezici i Strukture Podataka

P R O G R A M S K I J E Z I K P A S C A L

eksplicitno otvorena datoteka eksplicitno i zatvori.

Nije običaj da se sve datoteke eksplicitno zatvaraju na samom kraju programa, već onda kad nam više nisu potrebne.

c) Seek(f, pozicija) je procedura koja dejstvuje na oznaku tekućeg elementa i to tako što za tekući element postavlja onaj čiju smo poziciju naveli. Mora se voditi računa da se elementi obeležavaju počev od 0 ne do 1. Parametar pozicija je tipa longint.

d) FilePos(f) je funkcija tipa longint koja nam saopštava veličinu datoteke izraženu brojem elemenata. Vrednost koju vraća ova funkcija jednaka je broju zauzetih lokacija plus 1. Ako želimo da marker tekuće lokacije postavimo na kraj datoteke (tj. na novu praznu lokaciju) to ćemo učiniti komandom:

Seek(f, FilePos(f));

U toku izrade programa može se desiti da ne znamo da li neka datoteka koja nam treba postoji u spoljašnjoj memoriji, pa da npr. koristimo reset na nepostojećoj datoteci kada dolazi do greške.

Da bismo rešili ovaj problem koristićemo funkciju IOResult koja nam može poslužiti da testiramo uspešnost bilo koje funkcije za rad sa datotekama. Funkcija vraća vrednost 0 ako nije nastala nikakva greška u operaciji sa datotekom. U suprotnom vraća nam odgovarajući kôd

koji predstavlja šifru nastale greške i na osnovu kojeg možemo predvideti da se u programu izvrše odgovarajući koraci koji saniraju grešku.

Tekstualna datoteka

Ovaj tip datoteke se intenzivno koristi. U originalnom Pascalu su tekstualne datoteke predstavljale vrstu tipiziranih datoteka – tipizirane datoteke čiji su elementi znakovi. Kasnije je ovaj način definisanja tekstualnih datoteka eliminisan. Drugačije se tekstualne datoteke zovu i tekst fajlovi.

Tekstualna datoteka predstavlja poseban tip podataka i postoji posebno rezervisano ime za ovaj tip: text. Osnovni

21

Page 28: Programski Jezici i Strukture Podataka

P R O G R A M S K I J E Z I K P A S C A L

element ove datoteke jeste znak. Pošto ovakva datoteka sadrži tekst (ne formalne podatke), u nju se piše i iz nje se čita pomoću stringova.

Opšti oblik za definisanje promenljivih ovog tipa je sledeći:

var t: text;

I datoteke ove vrste postoje nezavisno od programa, imaju spoljnje identifikatore i u programu se moraju povezati sa spoljnjim imenom koje je nezavisno od programa. Kao i kod tipiziranih datoteka i ovde se to postiže procedurom Assign.

Tekstualne datoteke se otvaraju za pisanje i čitanje istim procedurama kao i tipizirane, i one imaju iste osobine, ali postoje dve razlike. I kod tekstualnih datoteka tekući element postoji, ali programer na njega nema nikakvog uticaja. Druga razlika se tiče režima rada

tekstualne datoteke. Ako je otvaramo procedurom rewrite, datoteka je u tzv. „write-only“ režimu, kad je u nju moguće samo upisivati podatke. A ako je otvorimo sa reset, onda je ona u tzv. „read-only“ režimu kad se iz nje može samo čitati.

Postoji i treći način otvaranja, pomoću procedure append.

Datoteka se otvara kao da smo izvršili reset, ali se marker tekućeg elementa postavlja na kraj datoteke i u nju možemo upisati nove podatke koji će se naći iza već postojećih.

Na disku se tekstualna datoteka čuva kao niz znakova od kojih su neki specijalni (npr. eoln označava kraj linije, a eof kraj fajla).

Način rukovanja ovom datotekom je identičan elementarom ulazu i izlazu, tj. podatke upisujemo i čitamo pomoću procedura write, writeln, read i readln. Drugačije rečeno, datoteka se ponaša kao ekran kad se u nju upisuje, a kao tastatura kad se iz nje čita. To je zbog toga što se ekran i tastatura u stvari tretiraju kao posebna vrsta tekstualne datoteke.

U procedurama za ulaz i izlaz se kao prvi parametar

obavezno navodi promenljiva koja se odnosi na datoteku iz koje želimo da učitamo podatke, tj. da ih upišemo. Input i output su dve standardne datoteke automatski

22

Page 29: Programski Jezici i Strukture Podataka

P R O G R A M S K I J E Z I K P A S C A L

pridružene tastaturi i ekranu (printeru), pa ako ih ne navedemo kao parametre procedura za elementarni ulaz i izlaz, podrazumevaju se.

Od ostalih procedura i funkcija bitnih za upravljanje tekstualnim datotekama, spomenućemo još neke. Close se koristi za zatvaranje datoteke. Funkcija eof pokazuje kada naiđemo na kraj datoteke, a eoln kada naiđemo na kraj reda. Eoln je u Turbo Pascalu izgubila značaj, jer postoji readln koja učitava ceo red odjednom. Naravno, writeln koja kao parametar ima samo ime datoteke upisuje u nju prazan red.

Netipizirana datoteka

Ovo je uobičajen naziv za ovaj tip datoteke, ali nije dovoljno precizan kada se govori o Turbo Pascalu. Jedno od osnovnih načela ovog programskog jezika jeste da sve ima svoje ime, tako da je nepravilno govoriti o netipiziranim podacima.

Ovaj naziv se koristi upravo zbog toga što se netipiziranoj datoteci pristupa na nivou bajta, tj. njeni osnovni elementi se tretiraju kao bajtovi. Sadržaj datoteke se sastoji od niza bajtova bez ikakve semantike. Nju obezbeđuje programer u svom programu. Ovo je dosta važan tip datoteke.

Opšti oblik za definisanje promenljivih ovog tipa je:

var b: file;

Vidimo da se u deklaraciji promenljive navodi samo da je u pitanju datoteka, ali ne i o kakvom tipu datoteke se radi.

I za ove datoteke se koriste: assign, reset i rewrite, ali reset i rewrite imaju drugačiju sintaksu, jer se navodi i veličina jednog elementa u bajtovima. Mogu se koristiti i close, seek, filepos i filesize. Filesize ne vraća veličinu datoteke u bajtovima, veću u elementima. Npr. ako jedan element ima 10 bajtova, filesize će vratiti broj desetobajtnih elemenata u datoteci. Za rukovanje sadržajem datoteke se koriste posebne procedure: blockread i blockwrite.

23

Page 30: Programski Jezici i Strukture Podataka

P R O G R A M S K I J E Z I K P A S C A L

PokazivačiPokazivači predstavljaju jedan od najvažnijih tipova u Pascalu i predstavljaju najveći konkretni doprinos Pascala uopšte. Omogućili su da program u toku rada zahteva dodatnu memoriju od sistema i oslobađa tu naknadno zahtevanu memoriju.

Postoje dve međusobno srodne vrste pokazivača: skalarni

(osnovni) i izvedeni. Među njima postoje razlike, ali oni mogu međusobno razmenjivati vrednosti. Inače, pokazivače uopšteno zovemo pointeri bez obzira koje su vrste.

Vrednost jednog pokazivača je adresa. Adresa je zajednička karakteristika svih tipova podataka i kategorija u programu.

Kad tražimo dodatnu memoriju od sistema, mi njenu adresu unapred ne znamo. Dodatnu memoriju naš program traži od jednog drugog programa čija je uloga da obezbedi onoliko memorije koliko smo tražili i onda nam prosledi adresu te novozauzete memorije. Adresu ćemo čuvati u promenljivoj tipa pokazivača.

Važno!

Pokazivači nam omogućavaju dinamičku dodelu

memorije i pristup toj dinamički dodeljenoj memoriji preko njene adrese.

Netipizirani pokazivači

Ovo je jedan od osnovnih skalarnih tipova. Vrednosti promenljivih ovog tipa se razlikuju od drugih vrednosti osnovnih tipova koliko se i oni među sobom razlikuju. Drugačije se ovaj tip naziva i adresni tip ili generički

pokazivač. Nešto malo manje se koriste od tipiziranih pokazivača.

Promenljivu deklarišemo na sledeći način:

var adr: pointer;

Nekoj adresi se ne može pristupiti direktno preko goredeklarisane promenljive adr, jer mi ne znamo šta se na toj adresi nalazi. Zbog toga je namena generičkih pokazivača čuvanje vrednosti tipiziranog pokazivača.

24

Page 31: Programski Jezici i Strukture Podataka

P R O G R A M S K I J E Z I K P A S C A L

Tipizirani pokazivači

Pokazivači ovog tipa su od primarnog značaja, jer gotovo da nema programa koji ih ne koristi. Nisu postojali u originalnom Pascalu.

Tipizirani pokazivač je izvedeni tip i njegova vrednost jeste adresa, ali se prilikom definisanje promenljive ovog tipa daje i informacija o tome šta se nalazi na toj adresi. Ako se zna šta stoji na određenoj adresi, onda je moguć pristup toj adresi. Dakle, osnovna namena tipiziranog pokazivača jeste dinamička promena memorije.

Ovaj tip se mora eksplicitno deklarisati i to na sledeći način:

type ImeTipa = ^tip_podatka;

Naravno, možemo ga deklarisati i direktno u deklaraciji promenljive:

var pok: ^tip_podatka;

Nepisano je pravilo da se kod imenovanja pokazivačkih tipova na početak imena stavi veliko slovo P, kako bismo kasnije u programu znali da je reč o pokazivaču. Kod promenljivih, stavljamo malo slovo p. Ovo je tzv. mađarska notacija. Na primer:

type PInt = ^integer;var pI : PInt;

Tipizirane pokazivače koristimo na dva načina: možemo manipulisati vrednošću pokazivača (tj. adresom na koju pokazuje) ili podatkom na koji pokazuje (sadržajem memorijske adrese). Sadržaj adrese pokazivača (podatak) ima sve osobine promenljive koja se nalazi na toj adresi i njemu pristupamo pomoću: pI^.

Postoje dva načina za povezivanje pokazivača i lokacije čiju adresu sadrži pokazivač. U prvom slučaju, sve promenljive su deo statičke memorije programa. Na primer:

var i: integer;p: ^integer;t, w: pointer;

U Pascalu se za označavanje pokazivača koristio simbol , a u Turbo Pascalu se koristi ^.

25

Page 32: Programski Jezici i Strukture Podataka

P R O G R A M S K I J E Z I K P A S C A L

i := 5;p := @i;p^ := -7;t := @i;w := p;

U ovom primeru, i je celobrojna promenljiva, p je tipizirani, a t i w su generički pokazivači. Dodelićmo vrednost 5 promenljivoj i, a zatim njenu adresu promenljivoj p. To radimo pomoću adresnog operatora @. Potom smo upisali vrednost -7 na lokaciju p^, tj. promenili smo vrednost i. Adresama t i w ne možemo da pristupamo, jer su t i w generički pokazivači. Oni čuvaju samo adresu i, tj. vrednost p.

Drugi način povezivanja je važniji, jer omogućava dinamičku dodelu memorije. Dinamička memorija se zove i heap. Pokazivač (koji je deo statičke memorije programa) nam omogućava da u određenom trenutku zahtevamo od sistema da nam dodeli lokaciju iz ostatka memorije, ali pri tome se mora znati koliko memorije i za šta. Pascal program se u tom slučaju obraća tzv. upravljaču

heapa koji pronalazi gde postoji slobodna memorija koja se traži, označava tu lokaciju kao zauzetu i upisuje njenu adresu u pointer.

Sa upravljačem heapa se komunicira uz pomoć procedura. Procedura new(pI), gde je pI tipizirani pokazivač. Posle izvršavanja procedure new, možemo da koristimo promenljivu pI^. Kad nam ova lokacija više nije potrebna, javljamo da se označi kao slobodna procedurom dispose(pI). Posle njenog izvršavanja nam pI^ više nije na raspolaganju, tj. sadržaj pokazivača je nil.

Pokazivačka konstanta nil

Pokazivač bilo koje vrste može da uzme njenu vrednost. U tom slučaju pokazivač ne pokazuje ni na šta.

Posle izvršavanja procedure new(pI), ne smemo

promenljivoj pI dodeliti vrednost nil mi sami. Desiće se da će se prekinuti veza između pokazivača i lokacije, ali da će lokacija ostati označena kao zauzeta. Zbog toga moramo izvršiti i proceduru dispose, da bi se lokacija korektno oslobodila.

26

Page 33: Programski Jezici i Strukture Podataka

P R O G R A M S K I J E Z I K P A S C A L

PrimerU ovom primeru ilustrovaćemo rad sa datotekom i korišćenje unita u Turbo Pascalu (strana 47). Program koristi unit MPoint koji je dat na strani 50.

Smatra se da već postoji formirana datoteka koja sadrži neke elemente (podatke) tipa TPoint. Program će pročitati podatke iz cele datoteke i odrediti (štampati) apscisu i ordinatu tačke najudaljenije od koordinatnog početka.

program NajdaljaTacka;

uses MPoint;var DatTacka: file of TPoint;

Nula, tacka, najdalja: TPoint;maxrast, pom: real;

beginAssign(DatTacaka, 'c:\mydir\tacke.dat');reset(DatTacaka);Create(Nula, 0, 0);maxrast := 0;

while not eof(DatTacaka) do beginread(DatTacaka, tacka);pom := distance(tacka, Nula);if maxrast < pom then begin

maxrast := pom;Copy(tacka, najdalja); end

end;

Close(DatTacaka);writeln('Najdalja tačka ima apscisu ',

GetX(najdalja), ' i ordinatu ', GetY(najdalja))

end.

27

Page 34: Programski Jezici i Strukture Podataka

P R O G R A M S K I J E Z I K P A S C A L

Opšta struktura programa

Pascal programi imaju čvrsto definisanu strukturu. Tačno se zna gde se koji deo kôda piše. Time se smanjuje verovatnoća da se napravi greška.

Strukturu Pascal programa čini sam program, njegovi potprogrami i moduli.

Pošto je struktura gotovo uniformna, možemo govoriti o globalnoj strukturi programa. Takođe, bez obzira koji prevodilac prevodi kôd, vrlo je moguće da će on uvek raditi jednako.

Globalna struktura programa

zaglavlje

blo

k

deklaracije

labelekonstantetipovipromenljivepotprogrami

algoritamski deo

ZaglavljeU zaglavlju se identifikuje program. Ova linija kôda u turbo Pascalu nije obavezna.

program ime_programa;

28

Page 35: Programski Jezici i Strukture Podataka

P R O G R A M S K I J E Z I K P A S C A L

DeklaracijeOdmah na početku teksta o deklaracijama treba napomenuti dve stvari. Prvo: redosled kategorija koje se deklarišu nije dat po važnosti. Drugo: odnos važnosti deklaracija i algoritamskog dela se u toku vremena menjao. Ranije su programeri veliku pažnju obraćali da algoritamski deo, dok deklaracije nisu bile mnogo bitne. To je bilo zbog toga što su tadašnji programi imali male mogućnost, pa samim tim tipova, promenljivih itd. nije bilo mnogo. Kasnije je delu sa deklaracijama posvećena veća pažnja (tako je i u Pascalu), jer vrlo se lako može desiti da pogrešno deklarisana promenljiva utiče da se javlja greška u programu ili da ozbiljno ugrozi performanse programa. Danas, pošto se koristi objektni model programiranja, obrisana je granica između deklaracija i algoritamskog dela i ta dva su dela postali ravnopravni.

Labele

Labele su oznake naredbi u programu. Ranije su mnogo korišćene, dok se danas teži da se upotreba labela i skokova u programu maksimalno izbegne. U Pascalu se one skoro uopšte ne koriste osim u slučaju komande goto. Treba voditi računa da se program tako piše da ova komanda postane izlišna.

Sintaksa:

label identifikator1, identifikator2, ..., identifikatorN;

Označavanje naredbi se vrši na sledeći način:

oznaka: naredba;

Primer:

label kraj;...kraj: writeln;

Konstante

Deklarišemo samo imenovane konstante.

29

Page 36: Programski Jezici i Strukture Podataka

P R O G R A M S K I J E Z I K P A S C A L

Sintaksa:

const ime1 = vrednost1, ime2 = vrednost2, ..., imeN = vrednostN;

Primer:

const pi = 3.14;

Tipovi

Tipovi koje deklarišemo su u stvari sopstveni tipovi koje definiše programer. Takođe, ime tipa treba da bude smisleno. Nepisano pravilo je da ime tipa počinje velikim slovom. Pošto identifikator ne može sadržati razmake, onda ako ime tipa sadrži više reči, sve ih pišemo zajedno, ali svaku počinjemo velikim slovom.

Sintaksa:

type ImeTipa1 = opis_tipa1;ImeTipa2 = opis_tipa2;...ImeTipaN = opis_tipaN;

Primer:

type Visina = real;

Promenljive

Svaka promenljiva ima ime i tip i zauzima memoriju u kojoj se čuva njena vrednost. U Pascalu je eksplicitno deklarisanje promenljivih obavezno. Na taj način, između ostalog, se smanjuje mogućnost greške.

Promenljive deklarišemo na sledeći način:

var ime1_1, ime1_2, ime1_3 : tip1;ime2_1, ime2_2 : tip2;

Direktno zadavanje tipa

Kod deklaracije promenljivih dajemo njeno ime i njen tip. Ako je tip izveden, možemo mu prvo dati ime u deklaraciji tipova pa ga onda koristiti. Ali ga možemo zadati i direktno, tj. u deklaraciji promenljive. Na primer:

var dani: (pon, uto, sre, cet, pet, sub, ned);

Konstante koje u programu imaju određeno značenje bi trebalo da budu imenovane.

30

Page 37: Programski Jezici i Strukture Podataka

P R O G R A M S K I J E Z I K P A S C A L

Ovo se u glavnom ne radi, jer na ovaj način ne možemo kasnije definisati još jednu promenljivu istog tipa. Takođe ovo nije u duhu Pascala, jer bi sve trebalo da ima svoje ime.

Potprogrami

Potprogrami u Pascalu su u stvari procedure i funkcije. Prilikom njihovog deklarisanja one se navode u celini. Kao što program može da ima svoj potprogram, tako i potprogram može da ima svoj potprogram. Broj nivoa potprograma nije ograničen, ali je u praksi potrebno najviše dva nivoa, a veoma retko se koriste i tri. Velik broj podnivoa čini program teškim za razumevanje, a ranije je rečeno da je osnovna svrha Pascala pisanje čitljivih i razumljivih programa.

O procedurama i funkcijama će više reči biti kasnije.

Algoritamski deoAlgoritamski deo se sastoji od naredbi. Da bi prevodiocu označili algoritamski deo, stavljamo ga među tzv. programske zagrade:

beginnaredba;

end.

Obavezno se iza ovog end stavlja tačka, ne tačka-zarez.

Programski jezik Pascal sadrži samo najbitnije naredbe. ALGOL je sadržao jedan broj naredbi koje su se jako retko koristile. Pascal ih nema.

31

Page 38: Programski Jezici i Strukture Podataka

P R O G R A M S K I J E Z I K P A S C A L

Naredbe

Naredba dodeleOva naredba je osnovna naredba svakog proceduralnog programskog jezika. Njena sintaksa u Pascalu je sledeća:

promenljiva := izraz;

Ova se naredba izvršava u dva koraka:

izračunava se vrednost izraza;

dodela vrednosti izraza promenljivoj sa leve strane.

Mora se voditi računa da promenljiva i izraz imaju isti tip.

Jedini izuzetak je da je promenljiva tipa real, a izraz integer.

Složena naredba (sekvenca)Složena naredba predstavlja vrlo jednostavan i delotvoran način da se više nezavisnih naredbi tretira kao jedna složena.

Sekvencu nezavisnih naredbi stavljamo među programske

zagrade. U Pascalu su to begin i end, kako je objašnjeno na strani 31.

Kada pišem program u Pascalu, koristimo se principom: jedan posao – jedna naredba. Samim tim, ceo naš program možemo posmatrati kao jednu složenu naredbu.

Naredbe selekcijeDrugačije se nazivaju uslovne naredbe.

Naredba dodele je dvoznak.

32

Page 39: Programski Jezici i Strukture Podataka

P R O G R A M S K I J E Z I K P A S C A L

If then i if then else

Ove dve naredbe su potpuno ravnopravne. Neki autori naredbu if then smatraju specijalnim slučajem ove druge, što nije opravdano.

Sintaksa:

if logicki_izraz then naredba1;else naredba2;

if logicki_izraz then naredba;

Kod komande if then else, zavisno od toga je li logički izraz tačan ili ne izvršava se prva, odnosno druga naredba. Kod komande if then, pak, naredba se izvršava ako je izraz tačan, ako nije, ne izvršava se.

Primer:

if x > 3,5 then g := sin(x)else if x = 3,5 then g:= 0.0else g := cos(x)

Case

Naredba case predstavlja naredbu višestruke selekcije. To je izvedena naredba. Koristimo je kada treba da uporedimo vrednost nekog izraza sa unapred zadatim vrednostima. Mora se voditi računa da izraz ne sme biti tipa real i string.

Sintaksa:

case izraz ofvrednost1_1, vrednost1_2: naredba1;vrednost2_1: naredba2;...vrednostN: naredbaN;

end;

logički izraz

naredba

true

false

logički izraz

naredba 1

naredba 2

true

false

33

Page 40: Programski Jezici i Strukture Podataka

P R O G R A M S K I J E Z I K P A S C A L

Primer:

case i + s of1, 4: y := sin(z);0: begin y := 0; j := 1 end;-10: x := x + 1

end;

PetljePetlje predstavljaju jednu od najosnovnijih struktura u programiranju. Pomoću njih se fizički ograničenim brojem naredbi računaru može zadati proizvoljno veliki psao. U Pascalu postoje tri naredbe ciklusa: for, while i repeat. Svaki ciklus predstavlja jedinstvenu naredbu.

For

For je brojački ciklus. For petlja ima upravljačku promenljivu čija vrednost upravlja ponavljanjem ciklusa. Njena vrednost se menja i proverava automatski, stoga kod ove petlje postoji određena automatizacija.

Sintaksa:

for kp := pv {to|downto} kv do naredba;

Gde je kp ime kontrolne promenljive, pv je početna vrednost, a kv krajnja vrednost. Koristimo to ili downto zavisno od toga želimo li da se prilikom izvršenja petlje vrednost kontrolne promenljive odbrojava unapred ili unazad od početne do krajnje vrednosti (npr. od 1 do 10 ili od 10 do 1).

Ova petlja ne mora da se izvrši ni jednom. Koristimo je kada je u trenutku otpočinjanja ciklusa poznato koliko će biti ponavljanja.

While

Ovo je osnovna vrsta ciklusa, pošto se njim može rešiti bilo koje ponavljanje.

Sintaksa:

while logicki_izraz do naredba;

Upravljačka promenljiva se zove i kontrolna promenljiva.

34

Page 41: Programski Jezici i Strukture Podataka

P R O G R A M S K I J E Z I K P A S C A L

Na BDA naredbe while se vidi da se prvo proverava vrednost logičkog izraza, pa ako je izraz tačan, izvršava se naredba. Zbog toga se ova petlja ne mora izvršiti ni

jednom. Naravno, broj ponavljanja ne mora biti unapred poznat, ali

je bitno da naredba utiče na vrednost logičkog izraza. U suprotnom se petlja ili uopšte neće izvršiti (ako je izraz netačan pre ulaska u petlju) ili će se izvršavati beskonačno (pošto je izraz uvek tačan).

Repeat

Sintaksa:

repeatnaredba_1;naredba_2;...;naredba_nuntil logicki_izraz;

Repeat naredba je slična naredbi while. Doduše, mnogo manje se koristi. Za

razliku od while, pošto se uslov proverava na kraju, repeat se izvršava makar jednom. Ako je naredba sekvenca, ne koriste se programske zagrade begin i end, jer se ponavlja sve što je između repeat i until.

Najvažnija razlika između while i repeat je što se while ponavlja dok iskaz jeste tačan, a repeat dok iskaz ne postane tačan.

Naredbe skokaU Pascalu postoji pet naredbi skoka. Kao što je iznešeno ranije, Pascal je tako koncipiran da je potreba za skokom skoro eliminisana.

Osnovna naredba skoka je goto. Njena sintaksa je:

goto labela;

Labela je mnemonički identifikator.

Pored ove postoje i naredbe skoka koje se koriste u ciklusima i potprogramima:

break – momentalni izlazak iz ciklusa;

Naredbe skoka treba izbegavati.

35

logički izraz

naredba

true

false

logički izraz

true

false

bloknaredbi

Page 42: Programski Jezici i Strukture Podataka

P R O G R A M S K I J E Z I K P A S C A L

continue – momentalni skok na početak ciklusa;

exit – momentalno završavanje potprograma;

halt – momentalno zaustavljanje programa. Ova naredba je najčešće propraćena porukom za korisnika.

36

Page 43: Programski Jezici i Strukture Podataka

P R O G R A M S K I J E Z I K P A S C A L

Elementarni ulaz/izlaz

Elementarni ulaz jeste ulaz sa tastature, a elementarni izlaz jeste izlaz na ekran.

U Pascalu se ovo obavlja pomoću dva potprograma (dve procedure) čiji je broj parametara promenljiv.

Za izlaz na ekran u tekstualnom režimu se koristi:

write(p1, p2, ..., pN);writeln(p1, p2, ..., pN);writeln;

Gde je pi konstruktor sastavljen na sledeći način:

pI = e1 : e2 : e3

e1, e2 i e3 su izrazi i to: e1 je izraz čija se vrednost prikazuje, e2 određuje broj pozicija koju zauzima e1 na ekranu, a e3 je broj decimalnih mesta. e2 i e3 su najčešće konstantne vrednosti.

Pažnja

Treba voditi računa o tome da kad write završi ispis, ekranski kurzor ostaje odmah iza poslednjeg ispisa, dok ga writeln premešta na početak novog reda. Samim tim, writeln bez parametara samo premešta kurzor na početak sledećeg reda.

Za ulaz sa tastature koristimo:

read(v1, v2, ..., vN);readln(v1, v2, ..., vN);readln;

Gde je vi ime promenljive čiju vrednost tražimo od korisnika.

37

Page 44: Programski Jezici i Strukture Podataka

P R O G R A M S K I J E Z I K P A S C A L

Ako unosimo više promenljivih odjednom, njihove vrednosti prilikom unosa razdvajamo tako što među njima napravimo jedno ili više praznih mesta.

38

Page 45: Programski Jezici i Strukture Podataka

P R O G R A M S K I J E Z I K P A S C A L

Potprogrami

Prvobitna namena potprograma je bilo skraćivanje izvornog koda, ali je ovo brzo zanemareno. Osnovni razlog upotrebe potprograma je što oni predstavljaju logičku celinu i time sam program postaje pregledniji i lakši za razumevanje. Potprogrami predstavljaju jedan od nivoa modularizacije.

Postoje dve vrste potprograma: funkcije i procedure. One imaju istu strukturu koja je gotovo identična opštoj strukturi programa.

Zaglavlje potprograma predstavlja mehanizam koji se razmenjuju parametri između glavnog programa i potprograma. Oblik zaglavlja zavisi od vrste potprograma.

function ime(formalni_parametri): tipfunction ime: tip

procedure ime(formalni_parametri)procedure ime

Namena formalnih parametara je prenos ulaznih vrednosti klijenta i prihvatanje eventualnih vrednosti funkcije, odnosno vrednosti koje vraća procedura. Formalni parametri mogu biti promenljive svih osnovnih tipova ili druge procedure.

Primeri:

function Proizvod(n: integer): longint;var p: longint; i: integer;beginp := 1;

for i := 1 to n do p := p * i;Proizvod := p;

end;

39

Page 46: Programski Jezici i Strukture Podataka

P R O G R A M S K I J E Z I K P A S C A L

procedure MinMax(x, y, z: real; var min, max : real);begin

if (x < y) and (x < z) then min := xelse if (y < x) and (y < z) then min := yelse min := z;if (x > y) and (x > z) then max := xelse if (y > x) and (y > z) then max := yelse max := z;

end;

Da bi pozvali neku funkciju, njeno ime ćemo uvrstiti u neki izraz. Proceduru pozivamo samo navođenjem njenog imena u kôdu programa.

Svaka funkcija vraća jednu vrednost, tako što njenom imenu dodelimo vrednost u kôdu funkcije. (U primeru funkcije Prozivod, pretposlednja linija kôda dodeljuje vrednost p funkciji.) Pri tome treba voditi računa da se ime funkcije ne sme koristiti u njoj samoj, osim u slučaju dodele konačne vrednosti koju funkcija vraća. Funkcije vraćaju samo skalarne vrednosti.

Procedura, s druge strane, ne vraća nikakvu vrednost svojim imenom. Njih koristimo za izmenu stanja programa koje je opisano vrednostima nekih promenljivih, jer će procedura promeniti vrednosti tih promenljivih. Ako je potrebno da je izlazna vrednost potprograma takva da ne može da je vrati funkcija (nije jedna ili nije skalarna) koristićemo proceduru.

Deklaracija unapred

Da bi jedan potprogram mogao pozvati drugi, onaj koji je pozvan mora biti deklarisan pre ovog koji poziva. Tj. ako P koristi Q, Q mora biti deklarisano pre P. U slučaju da P poziva Q, ali i Q poziva P nije moguće oba programa smestiti jedan pre drugog, pa koristimo deklaraciju unapred. U zaglavlje jedan potprogram postavljamo prvi i koristimo ključnu reč forward koja prevodiocu označava da će potprogram biti opisan kasnije.

Primer:

procedure Q(...); forward;procedure P(...);begin

...Q...

end;

40

Page 47: Programski Jezici i Strukture Podataka

P R O G R A M S K I J E Z I K P A S C A L

Lokalne i globalne promenljive

Pošto se često javlja potreba da u potprogramu postoje neke promenljive koje van njega nemaju značenje, uvodimo lokalne promenljive. Formalni parametri potprograma su lokalne promenljive. Za razliku od ovih postoje i globalne promenljive, koje su definisane u glavnom programu i važe za ceo program.

Ako se dogodi da se poklope imena lokalne i globalne promenljive, lokalna promenljiva ima prednost, tj. u potprogramu će važiti lokalna promenljiva, a van njega globalna.

Pažnja

Treba voditi računa da lokalna i globalna promenljiva istog imena nikako ne utiču jedna na drugu.

Formalni i stvarni parametri

Formalni parametri su oni koji se pojavljuju u zaglavlju

potprograma. Pri pozivu tog potprograma njihove vrednosti se zamenjuju vrednostima stvarnih parametara.

Stvarni parametri su oni koji se nalaze u pozivu

potprograma i to mogu biti promenljive ili izrazi.

Stvarni i formalni parametri se moraju poklapati po tipu

i po redosledu kako se navode u pozivu potprograma, odnosno u njegovom zaglavlju.

Parametri vrednosti i parametri imena

Prenos parametara između glavnog programa i potprograma se izvršava preko steka i može biti prenos po vrednosti, kad se prenosi samo vrednost tog parametra, ili po imenu, kad se prenosi adresa

parametra.

Prenos po vrednosti se koristi za čisto ulazne parametre čiju vrednost u glavnom programu potprogram ne treba da menja. Zbog toga na mestu poziva parametra po vrednosti može da stoji i neki izraz.

Prenos po imenu se koristi za ulazno/izlazne parametre. Pošto se u steku nalazi stvarna adresa parametra,

41

Page 48: Programski Jezici i Strukture Podataka

P R O G R A M S K I J E Z I K P A S C A L

potprogram može da menja vrednost parametra u glavnom programu.

Da bi prevodilac znao da li se neki parametar prenosi po vrednosti ili imenu, dodajemo rezervisanu reč var u zaglavlje potprograma. Tako u primeru procedure MinMax x, y i z se prenose po vrednosti, jer ispred njih ne stoji var, a min i max po imenu, jer ispred njih stoji var.

Nizovi kao parametri potprograma

Nizove prosleđujemo potprogramu na sledeći način: prvo deklarišemo tip, a zatim u potprogramu navedemo formalni parametar tog tipa. Na primer:

type TNiz: array[1..10000] of integer;...function f(n: integer; Niz: TNiz): integer;

begin...

end;

Ovde postoje dva problema:

niz se prenosi kao parametar vrednosti;

funkcija će prihvatiti samo nizove koji su identičnog tipa kao formalni parametar.

Prvi problem nastaje zbog toga što ako se niz prenosi kao parametar vrednosti, svih n elemenata se prenosi na stek bez obzira koliko nam zaista treba. Ovo zauzima nepotrebne resurse, ali i oduzima vreme pogotovo ako niz ima velik broj članova. Zbog toga možemo dodati var

u deklaraciju parametra, da bi se niz preneo po imenu. Tad će potprogram raditi sa stvarnim elementima niza, ali se mora voditi računa ako je niz čisto ulazni da potprogram ne menja vrednost članova.

U Turbo Pascalu 7.0 je dozvoljeno da se stvarni parametri prenose na tri načina. Pored prenosa po vrednosti i imenu, uveden je i prenos parametra kao konstante. U tom slučaju se takođe prenosi adresa stvarnog parametra, ali prevodilac vodi računa da potprogram ne menja njegovu vrednost.

42

Page 49: Programski Jezici i Strukture Podataka

P R O G R A M S K I J E Z I K P A S C A L

U gornjem primeru bismo to rešili na sledeći način:

type TNiz: array[1..10000] of integer;...function f(n: integer; const Niz: TNiz): integer;

begin...

end;

Što se tiče drugog problema, on se ogleda u sledećem. Kokretno, u navedenom primeru, funkcija f će prihvatiti kao ulazni parametar neku celobrojnu vrednost n i isključivo celobrojni niz od 10 000 elemenata čiji je opseg od 1 do 10 000. U slučaju da želimo da napišemo neki uopšteni potprogram (npr. za sabiranje n članova niza), za svaki niz koji je drugačiji od ovog bi morali pisati novi potprogram.

Ovaj problem je sintaksno rešen tek u Turbo Pascalu 7.0, ali samo za jednodimenzionalne nizove. Kod deklaracije tog niza nećemo navesti njegov opseg. Na primer, procedura P će prihvatiti sve nizove koji su realnog tipa.

procedure P(RNiz: array of real);

Low() i High()

Ove dve funkcije su uvedene za rad sa otvorenim parametrima. Low nam daje donju granicu niza (najmanji indeks, indeks prvog elementa), a High gornju granicu (tj. najveći indeks, indeks poslednjeg elementa).

Primer:

function Suma(const X: array of real; n: integer): real;var s: real; i: integer;

begins := 0;for i := 1 to n do

s := s + x[Low(x) + i – 1];Suma := s

end;

Potprogrami kao parametri drugih potprograma

Potprogramu možemo proslediti neki drugi potprogram kao parametar, tako što ćemo parametru pridružiti odgovarajući tip.

Da bi mogli koristiti Low() i High() prevodiocu moramo zadati direktivu {&P+}.

43

Page 50: Programski Jezici i Strukture Podataka

P R O G R A M S K I J E Z I K P A S C A L

U sledećem primeru smo definisali tip TFunc koji odgovara funkciji g. U deklaraciji funkcije Integral, kao jedan od parametara navodimo f koji je tipa TFunc.

type TFunc = function(x: real): real;function Integral(a, b: real; f: TFunc): real;

var t: real;begin

...f(t);...

end;function g(x: real): real;begin

g := 2 * exp(x) – sin(x)end;...y := Integral(1.2, g)...

Rekurzivni potprogrami

Rekurzivni potprogram je onaj koji poziva samoga sebe, tj. koristi sopstvene usluge. Prvi put su se rekurzivni potprogrami pojavili u Algolu, jer je tad uveden stek koji je omogućio rekurzivno pozivanje potprograma. Primer rekurzivne funkcije je faktorijel.

Rekurzivni programi su najčešće kratki ali nejasni i često utiču na brzinu izvršavanja programa. Treba ih izbegavati, jer uz korišćenje lokalnih promenljivih lako mogu prepuniti stek.

Koriste se za rešavanje rekurzivnih problema, npr. prolazak kroz stablo i sl.

Primer:

function Faktorijel(n: integer): longint;begin

if n := 0 then Faktorijel := 1else Faktorijel := n * Faktorijel(n-1)

end;

Moduli

44

Page 51: Programski Jezici i Strukture Podataka

P R O G R A M S K I J E Z I K P A S C A L

Moduli predstavljaju vrstu autonomnih softverskih jedinica. Da bismo lakše realizovali neki kompleksni program, razbijamo ga na delove od kojih svaki predstavljaja logičku celinu, pa onda te delove zasebno realizujemo i na kraju ih spajamo.

Moduli su se pojavili 60-ih godina kao rezultat povećanih zahteva korisnika. Prvi moduli su bili vrlo jednostavni i osnovna namena im je bila da se jednom napisan kôd može više puta upotrebiti.

Da ne bismo svaki put kopirali deo kôda koji izvršava isti posao, pojavile su se biblioteke gotovih programa. U početku su bile štampane na papiru, pa se proces njihove implementacije svodio na prepisivanje kôda sa papira. Kasnije je pronađen mehanizam da se ove biblioteke prenose u prevedenom obliku.

Pojavom strukturnih programskih jezika, biblioteke modula više nisu predstavljale skupove programa opšte namene koji rešavaju neki problem, već su dobile odgovarajuću organizaciju, tj. strukturu.

Važno je napomenuti da Wirthov Pascal nije poznavao

module. Ceo program (sa svim potprogramima) je predstavljao čvrsto vezanu celinu. Prepisivanje kôda je bio jedini način da se izvede da se neki potprogram jednog programa izvršava i u nekom drugom programu.

Za pisanje modula koristimo uobičajene komande

programskog jezika. Moduli se koriste isključivo u prevedenom obliku i prevedeni modul u Pascalu nema ekstenziju EXE, jer nije izvršni. Najčešće ima ekstenziju TPU ili TPP.

Šta je modul?

Modul je softverska komponenta koja se realizuje (tj. projektuje, kôdira, testira i modifikuje) autonomno, bez potrebe da se taj kôd meša sa nekim drugim kôdom.

U početku biblioteke nisu imale strukturu, predstavljale su skup neuređenih programa koji se koriste po potrebi.

Bez modula nema profesionalne izrade programa ni na jednom proceduralnom programskom jeziku.

45

Page 52: Programski Jezici i Strukture Podataka

P R O G R A M S K I J E Z I K P A S C A L

Modul može biti izvršni, a ne mora. U Pascalu postoje obe vrste modula. Naime, kod Pascala glavni program je takođe modul (izvršni). Ostale strukture po pravilu nisu izvršni moduli.

Opšta struktura modulaZbog postojanja modula, glavni program pokazuje tendenciju smanjenja. U normalnim okolnostima, sve što se dešava u programu se dešava u modulima. U jedan modul smestićemo srodne funkcije. Ako je već napisan neki modul koji zadovoljava naše potrebe, nikada nećemo pisati neki svoj koji radi isti posao.

Opšta struktura modula je saobrazna principu skrivanja

informacija koji je formulisao Parnas početkom 70-ih. Ovaj princip nalaže da detalji realizacije modula treba da budu skriveni od klijenta. U ovom slučaju klijent je drugi program, ne programer.

Na primer, za realizaciju tačke u Dekartovom koordinatnom sistemu postoje dva načina: pomoću vektora sa dve komponente (jedna predstavlja apscisu, druga ordinatu) i pomoću tipa sloga (gde jedno polje predstavlja apscisu, a drugo ordinatu).. Ova dva načina su potpuno različita, jer svaki način zahteva drugi kôd i sl. ali su ravnopravni – ni jedan nije bolji od drugog.

Po principi skrivanja informacija klijent ne sme znati je li ovaj problem rešen korišćenjem dvokomponentnog vektora ili sloga. Detalji realizacije su nedostupni klijentu, čak ako se i promene, klijent to ne sme da primeti. Problem će biti tako rešen da modul ima isto ime u oba slučaja, iste ulazne i iste izlazne parametre.

U svojoj strukturi moduli moraju imati dva dela:

interfejs modula: klijent ga vidi, to je deo kroz koji se vrši interakcija između klijenta i modula, pa je ovo u stvari deo za spregu sa klijentom.U idealnom slučaju (a skoro uvek je i stvarno tako) interfejs se nikad ne menja, eventualno se dopunjava, jer bilo kakva izmena interfejsa povlači promenu svih poziva klijenata tom modulu;telo modula: ovo je obavezan deo i u Pascalu se zove implementacija. Ovaj deo sadrži pomenute skrivene delove modula.

Information Hiding Principle

Šta se dešava sa ulazom i kako se transformiše u izlaz, klijenta se ne tiče.

46

Page 53: Programski Jezici i Strukture Podataka

P R O G R A M S K I J E Z I K P A S C A L

U modulu se u principu mogu pojaviti sve komponente programskog jezika. U Pascalu se pojavljuju potprogrami, tipovi, imenovane konstante, a malo ređe i promenljive.

U Turbo Pascalu postoje dve vrste modula, svaki sa svojom strukturom:

glavni program (autonomno realizovan);

modul u užem smislu reči, koji nije izvršni kao glavni program i nudi svoje usluge klijentima.

Šta se nalazi u modulu

Modul pre svega mora predstavljati logički zaokruženu celinu. Njega odlikuju jaka logička kohezija i slaba logička

adhezija. Pod prvim terminom podrazumevamo da modul sadrži logički povezane delove. Drugi termin se odnosi na slabu logičku zavisnost jednog modula od nekog drugog (loose coupling). Oba termina proističu iz zahteva da je modul autonoman.

Uniti u Turbo PascaluModul u užem smislu reči u Turbo Pascalu se zove jedinica ili unit. Njena struktura nije identična strukturi glavnog programa zbog svrhe modula i zbog toga što je prilikom pisanja modula najvažnije poštovati princip skrivanja informacija.

Unit se u opštem slučaju sastoji od tri (odnosno četiri) dela. To su:

zaglavlje (jednostavno je kao i zaglavlje glavnog programa);interfejs;implementacija i inicijalizacija (ovaj deo je opcioni).

Zaglavlje unita

Zaglavlje ima jednostavan oblik: sastoji se od službene reči unit i imena jedinice:

unit ime_jedinice;

Potprogram nije modul, jer nije autonomno realizovan, već kao deo modula (tj. glavnog programa).

47

Page 54: Programski Jezici i Strukture Podataka

P R O G R A M S K I J E Z I K P A S C A L

Izbor imena zavisi od verzije Pascala. U Turbo Pascalu ime jedinice mora da se poklopi sa imenom datoteke u kojoj se na disku čuva kôd te jedinice.

Interfejs

Označavamo ga službenom reči interface iza koje ne stoji tačka-zarez. Ako naš unit koristi usluge nekog drugog, onda u interfejs stavljamo referencu na drugi unit. To se radi pomoću:

uses ime_jedinice1, ime_jedinice2, ..., ime_jediniceN;

Inače, kad god koristimo procedure i funkcije nekog unita, moramo navesti njegovu referencu, da bi prevodilac znao da na raspolaganju ima još neke potprograme.

U interfejsu se takođe mogu naći deklaracije tipova, konstanti, promenljivih i potprograma.

Ako je neka procedura ili funkcija iz unita javno dostupna,

onda se njeno zaglavlje navodi u zaglavlje unita. Inače, zaglavlja potprograma u interfejsu imaju osobinu deklaracije unapred i zbog toga je redosled deklarisanja potprograma provizoran. Takođe je sve jedno kojim ih redom navodimo u telu jedinice.

Implementacija

Označavamo je službenom reči implementation iza koje ne stoji tačka-zarez. U ovom delu se nalazi realizacija procedura i funkcija deklarisanih u interfejsu (njihov kompletan tekst uključujući i zaglavlje).

Pošto su zaglavlja potprograma zajedno sa formalnim parametrima navedena u interfejsu, u implementaciji nije obavezno da se ponovo deklarišu formalni parametri. Doduše, ovo se uglavnom radi, jer je programeru dok piše potprogram lakše da vidi kako je nazvao parametre potprograma i koliko ih ima ako još jednom ponovi celo zaglavlje u implementaciji.

Kao što je već rečeno, redosled navođenja procedura i funkcija je irelevantan. Takođe svaki potprogram može koristiti neki drugi u okviru unita. Ako su nam potrebni

Ukoliko se desi da deklarišemo neki potprogram u interfejsu, a ne realizujemo ga u implementaciji, prevodilac će nam prijaviti grešku.

48

Page 55: Programski Jezici i Strukture Podataka

P R O G R A M S K I J E Z I K P A S C A L

i potprogrami drugih unita, koristimo službenu reč uses.

Deo za implementaciju unita podseća na deklaracioni deo glavnog programa i fizički je najveći deo unita. Takođe može da sadrži i lokalne promenljive koje se ne vide van unita. To su interne promenljive koje služe kao pomoć u implementaciji potprograma i imaju osobine globalnih promenljivih za taj unit. Unit takođe sadrži i lokalne procedure i funkcije (isto nedostupne van njega), a ređe i lokalne tipove i konstante.

Kao u interfejsu tako i u implementaciji se mogu naći reference na druge unite i to onda kad se njihove usluge koriste samo interno. Treba voditi računa da kružne reference nisu moguće, jedino u slučaju da se jedan unit referencira u interfejsu drugog, a drugi u implementaciji

prvog. Ovo se retko koristi.

Inicijalizacija

Inicijalizacija služi za postavljanje nekih početnih stanja u modulu i izvršava se samo jedanput i to kada se u zaglalvju klijenta naiđe na uses. Inicijalizacija se najčešće koristi za postavljanje vrednosti nekih promenljivih i ovo je jedini izvršni deo unita.

Inicijalizacija se prepoznaje po tome što počinje službenom reči begin, iza koje slede naredbe.

Bez obzira da li unit ima inicijalizaciju ili ne, uvek se završava sa end iza kojeg sledi tačka.

Pascalovi gotovi unitiU Pascalu postoji velik broj gotovih unita. Od njih je najvažniji system koji sadrži sve osnovne funkcije i procedure Pascala. Ovo je jedini unit koji se automatski

uključuje u program i ne treba se posebno navoditi.

Pored ovog, za rad u tekstualnom režimu u Pascalu bitni su i:

crt (služi za neposredno rukovanje tastaturom i ekranom);

Ovog dela obično nema, jer ima vrlo specifičnu namenu.

49

Page 56: Programski Jezici i Strukture Podataka

P R O G R A M S K I J E Z I K P A S C A L

DOS (malo raznovrsniji unit, sadrži potprograme za upravljanje datotekama, direktorijumima itd.);

graph (koristi se za rad sa grafičkim elemenatima);

printer (komunikacija sa lokalnim štampačem).

PrimerSledeći program predstavlja unit koji sadrži neke procedure i funkcije potrebne za realizaciju tačke u Dekartovom koordinatnom sistemu. Čuvamo ga u MPOINT.PAS datoteci.

UNIT MPOINT;

INTERFACE

type TPoint = recordx, y: realend;

procedure Create(var p: TPoint; xx, yy: real);function GetX(p: TPoint): real;function GetY(p: TPoint): real;procedure Copy(from: TPoint; to: TPoint);function Distance(p1, p2: TPoint): real;

IMPLEMENTATION

procedure Create(var p: TPoint; xx, yy: real);begin

with p do begin x:= xx; y:= yy; endend;

function GetX(p: TPoint): real;begin

GetX := p.xend;

function GetY(p: TPoint): real;begin

GetY := p.yend;

50

Page 57: Programski Jezici i Strukture Podataka

P R O G R A M S K I J E Z I K P A S C A L

procedure Copy(from: TPoint; to: TPoint);begin

to.x := from.x;to.y := from.y

end;

function Distance(p1, p2: TPoint): real;begin

Distance := sqrt(sqr(p1.x – p2.x) + sqr(p1.y – p2.y))end;

END.

51

Page 58: Programski Jezici i Strukture Podataka

Tema

2

52

Page 59: Programski Jezici i Strukture Podataka

Sintaksa programskih jezika

Ovde ćemo ukratko izložiti osnovne činjenice o sintaksi prograsmskih jezika i reći nešto o tri najšire korišćena sistem meta-jezika.

Aspekti svakog programskog jezika su:

sintaksa,

semantika i

pragmatika.

Sintaksa sadrži pravila za građenje konstrukcija datog programskog jezika. Čvrsto je vezana za kompajler čiji je osnovni zadatak (pored prevođenja programa na mašinski jezik) da proveri da li je program napisan u skladu sa sintaksnim pravilima. Drugačije rečeno, kompajler proverava da li je neka struktura pravilno napisana i na taj način proverava da li je ta struktura uopšte deo programskog jezika. Sintaksa programskih jezika je po pravilu mnogo jednostavnija od sintakse govornog jezika, ali je zato krajnje stroga.

Semantika se bavi značenjem onog što je napisano. To je interpretacija sintaksno pravilno napisane strukture.

Pragmatika predstavlja način korišćenja jezičkih konstrukcija da bi se rešio zadati problem.

Pošto je sintaksa programskih jezika strogo formalna, već krajem 50ih se javila ideja da se formalno i prikaže.

Prvi formalni sistem za opis sintakse se pojavio 1960. i opisivao je sintaksu ALGOLa.

Za formalni prikaz sintakse se koristi meta-jezik. Meta-jezik je, dakle, jezik za opis programskog jezika. Isto je formalan i postoji mnogo različitih varijanti meta-jezika. Tri su najpoznatija: BNF, EBNF i sintaksni dijagram. Prva dva se koriste više u svrhu formalnog

53

Page 60: Programski Jezici i Strukture Podataka

S I N T A K S A P R O G R A M S K I H J E Z I K A

zadavanja sintakse, a treći je pogodan za njeno prezentovanje.

Takođe, prva dva predstavljaju linearnu formu, dok se treći prikazuje dvodimenzionalno.

Način za opis sintakse nekog programskog jezika postavlja pred nas jedan osnovni problem: kako predstaviti terminale, a kako neterminale. Terminali su samoobjašnjavajuće konstrukcije nekog programskog jezika. Neterminali su one konstrukcije koje treba dalje razjašnjavati. Na primer, ako posmatramo sledeću naredbu Pascala:

while logicki_izraz do naredba;

while i do su terminali, dok su logicki_izraz i naredba neterminali (treba ih definisati). Njih jednim imenom zovemo simboli.

Ova tri sistema meta-jezika se bave načinima za zadavanje terminala i neterminala. Pošto kompajleri rade na meta-jezicima, treba obezbediti da formalni sistem predstavi sve moguće oblike neterminala.

Kompajler generator

Ulaz za kompajler generator jeste sintaksa novog programskog jezika koja se saopštava odgovarajućim meta-jezikom. Semantiku zadajemo na osnovu nekog već postojećeg programskog jezika (najčešće je to C). Kompajler generator nam onda generiše kompajler tog našeg novog programskog jezika.

Bekus-Naurova forma – BNFJohn Backus (tvorac Fortrana) i Peter Naur su napravili ovaj, prvi meta-jezik, kojeg definišu sedam stavki.

1. neterminale prikazujemo između kao: <neterminal>;

2. terminali se prikazuju bez ikakvih dodatnih znakova, onako kako se pišu u programskom jeziku;

3. simbol ::= znači jednakost po definiciji, gde se sa leve strane nalazi terminal, a sa desne opis tog terminala u vidu kombinacije neterminala i terminala. Ako se sa desne strane nalazi

54

Page 61: Programski Jezici i Strukture Podataka

S I N T A K S A P R O G R A M S K I H J E Z I K A

neterminal, onda njega objašnjavamo na isti način;

4. simbol | označava isključivo ili eksplicitno navedenih elemenata. Na primer: cifra ::= 0|1|2|3|4|5|6|7|8|9. Ili: slovo ::= A|B|C|D|E|...|Z|a|b|c|d...|z, s tim što se u zadavanju sintakse svi elementi moraju eksplicitno navesti. Ovde to nije slučaj zbog preglednosti;

5. ako lančamo simbole, pišemo ih jedan za drugim, npr: <dvoznačni naziv> ::= <slovo><slovo>|<slovo>cifra>;

6. ako konstrukti ne moraju uvek imati istu dužinu koristimo rekurziju, npr: <kard broj> ::= <cifra>|<kard broj><cifra>;

7. postoji i mogućnost ponavljanja nekog simbola jednom ili više puta: {<x>} ili ograničenog ponavljanja {<x>}n

m gde je m najmanji mogući broj, a n najveći mogući broj ponavljanja.

Poboljšana Bekus-Naurova forma – EBNFViše se upotrebljava od BNF i posebno je pogodna za kompajler generatore. Postoje određene razlike u odnosu na BNF.

1. neterminali se prikazuju bez ikakvih dodatnih simbola. Ako se neterminal sastoji od više reči, između njih se stavlja crtica ili donja crta, npr: kard-broj ili kard_broj;

2. terminali se stavljaju pod navodnike, npr: "while";

3. simbol = predstavlja jednakost po definiciji;

4. isključivo ili se predstavlja istim simbolom |;

5. lančanje se vrši na isti način kao kod BNF;

6. rekurzija je identična;

55

Page 62: Programski Jezici i Strukture Podataka

S I N T A K S A P R O G R A M S K I H J E Z I K A

7. ponavljanje može biti nula ili više puta (kod BNF je jednom ili više puta). Ograničeno ponavljanje je isto kao za BNF.

8. simbolima srednjih zagrada [ i ] se označava opcija;

9. simbolima malih zagrada ( i ) se označava objedinjavanje izraza;

10. na kraju svakog meta-izraza se stavlja tačka . koja označava njegov kraj.

Na primer:

"FOR" kont_prom ":=" pv ("TO"|"DOWNTO") kv "DO" naredba ";".

Sintaksni dijagramKao što je već rečeno, najviše se koristi za prezentaciju

sintakse forme i to u glavnom čitaocu u knjigama. Sintaksni dijagram je čitljiviji od BFN i EBNF. Sredstva za prikazivanje sintaksnog dijagrama su grafička.

Sintaksni dijagram kao celina ima jednu ulaznu granu na kojoj piše naziv konstrukcije koju definišemo. Terminale

prikazujemo krugovima ili zaobljenim pravougaonicima, neterminale pravougaonicima i međusobno ih povezujemo

usmerenim granama, pa se lančanje postiže upravo na taj način. Ekskluzivno ili ne postoji. Ponavljanje se postiže isto upotrebom usmerenih grana.

Svaka konstrukcija dobijena prolaskom kroz dijagram je pravilna.

Primeri

0 91 82 73 4 5 6

cifra

cifrakard_broj

56

Page 63: Programski Jezici i Strukture Podataka

S I N T A K S A P R O G R A M S K I H J E Z I K A

57

Page 64: Programski Jezici i Strukture Podataka

Tema

3

58

Page 65: Programski Jezici i Strukture Podataka

Osnovi teorije algoritama

Ovde ćemo videti kako se definiše algoritam i biće dat kraći prikaz tri najpoznatija algoritamska sistema: rekurzivne funkcije, Tjuringove mašine i normalne algoritme Markova.

Šta je to algoritam?lgoritam je vrlo star pojam i ne podleže strogom

definisanju (kao i neki pojmovi iz geometrije, npr. tačka, prava i ravan). Dakle, ne postoji stroga

definicija algoritma, već se on intuitivno definiše. Reč algoritam potiče od imena arapskog matematičara iz IX veka, a njegovo ime je Abu Jaffar Mohammed ibn Musa al Khowarizmi. Izgovor poslednje dve reči podseća na izgovor reči algoritam.

A

Emiprijska definicija algortima

Algoritam je pravilo formulisano na nekom jeziku koje jednoznačno definiše redosled operacija neophodan za transformaciju dozvoljenih ulaznih podataka u traženi rezultat.

Druga definicija je sintetička i formalnija je od ove empirijske. Oslanja se na alfabet (W, skup simbola bez semantike) u okviru kojeg se definiše skup W* – skup reči

(nizovi simbola) u kojem se nalazi i prazna reč.

Posmatraćemo dva alfabeta: X i Y, gde je X ulazni alfabet (sadrži dozvoljene ulazne podatke), a Y izlazni alfabet (sadrži izlazne rezultate). X i Y su najčešće isti. Nad skupovima reči X* i Y* se definiše alfabetski operator G, tako da je G X* Y*, pri čemu G nije funkcija. G vrši transformacije reči iz X* u reć iz Y*. Uvešćemo i pojam kodeksa Z koji predstavlja skup zakona koji bliže određuju

59

Page 66: Programski Jezici i Strukture Podataka

O S N O V I T E O R I J E A L G O R I T A M A

kako G vrši transformaciju ulazne u izlaznu reč. Odavde sledi sintetička definicija algoritma.

Sintetička definicija algortima

Algoritam je uređena četvortka (X*, Y*, G, Z).

Iako su X*, Y* i G strogo definisani, Z je definisan intuitivno, pa je i ova definicija intuitivna.

Dva algoritma mogu biti ekvivalentni na dva načina: po izvršavanju ili funkcionalno. Ako su isti po izvršavanju, isti ulazni podaci daju iste rezultate. Ako su dva algoritma funkcionalno ekvivalentni, onda im se i kodeksi poklapaju (na primer, ekvivalentni algoritmi imaju isti BDA, ali drugačije nazvane promenljive).

Algoritmi su deterministički (za isti ulaz daju isti izlaz) ili sholastički.

Algoritamski sistemiAlgoritamski sistem je sredstvo za zadavanje algoritma. Postoji čitav niz poznatih algoritamskih sistema (npr. opšti BDA koji nije do kraja precizno definisan ili oni vezani za konkretne probeleme, koji opet nisu dovoljno opšti).

Tri algoritamska sistema su najpoznatiji i sva tri su ekvivalentna, tj. mogu se svesti jedan na drugi. To su rekurzivne funkcije, Tjuringove mašine i Markovljevi normalni algoritmi.

Rekurzivne funkcijeOvo su najstariji algoritamski sistemi. Vrednost funkcije za neki argument računa se poznatim postupkom na bazi vrednosti funkcije za prethodne vrednosti argumenta. Na primer, ako računamo faktorijel broja n (n!) imamo za f(0) = 1, a dalje f(i) = i f(i-1), i = 1, 2, ..., n.

60

Page 67: Programski Jezici i Strukture Podataka

O S N O V I T E O R I J E A L G O R I T A M A

Churchova teza kaže: klasa izračunljivih funkcija poklapa se sa klasom rekurzivnih funkcija i od najvećeg je značaja za aritmetičke funkcije definisane na skupu

celih nenegativnih brojeva, tj f : Nk N. (Aritmetičke funkcije su diskretne.)

Služeći se aritmetičkim funkcijama, možemo napraviti bijektivno preslikavanje skupa reči nekog alfabeta (T*) na skup prirodnih brojeva (N). Znači, sve reči iz skupa T* možemo kôdirati elementima iz N.

Osnovna teza teorije algoritama sa stanovišta rekurzivnih funkcija kaže da za svaki algoritam koji obrađuje skupove celih nenegativnih brojeva postoji (funkcionalno) ekvivalentan algoritam koji odgovara nekog rekurzivnoj funkciji.

Rekurziju ostvarujemo pomoću šest sredstava, podeljenih u dve grupe: tri bazne funkcije (od kojih moramo poći) i tri osnovne operacije. To su:

1. nula funkcija: preslikava sve argumente u 0, tj. 0n(x1, x2, ..., xn) = 0;

2. funkcija naslednik: vrednost funkcije je jednaka vrednosti funkcije argumenata uvećanog za jedan, tj. S(x) = x', x' = x + 1 ;

3. projekcijska funkcija: Inj(x1, x2, ..., xj, ..., xn) = xj ;

4. operacija supstitucije: supstitucija funkcija h1, h2, ..., hm u funkciju g na sledeći način: f(x1, x2, ..., xn) = g(h1(x1, x2, ..., xn), h2(x1, x2, ..., xn), ..., hm(x1, x2, ..., xn)) ;

5. operacija proste rekurzije: kada iz dve funkcije dobijamo treću, npr. rekurzija po y: f(x1, x2, ..., xn, 0) = g(x1, x2, ..., xn, y + 1) i f(x1, x2, ..., xn) = h(x1, x2, ..., xn, y, f(x1, x2, ..., xn, y)). U prostom obliku pišemo: f(0) = a, f(y+1) = h(y, f(y)) ; i

6. operacija minimizacije: izvodi se iz neke aritmetičke funkcije g(x1, x2, ..., xn, y). Ciljna funkcija f(x1, x2, ..., xn) se dobij minimizacijom g, tako što za vrednost f usvajamo najmanje celo nenegativno rešenje jednačine g(x1, x2, ..., xn, y) = 0. Ako takvo

Izračunljive funkcije su one čija se vrednost može izračunati algoritmom.

61

Page 68: Programski Jezici i Strukture Podataka

O S N O V I T E O R I J E A L G O R I T A M A

rešenje ne postoji, onda funkcija nije definisana za te vrednosti argumenata.

Definicija rekurzivne funkcije glasi: za funkciju f : Nk N, k N {0} kaže se da je rekurzivna ako postoji bar jedan konačan niz funkcija f1, f2, ..., ft gde je ft f takav da svaka funkcija fi iz tog niza zadovoljava sledeća dva uslova:

fi je bazna funkcija i

fi se dobija od prethodnih funkcija u nizu supstitucijom, prostom rekurzijom ili minimizacijom.

Primer

Sabiranje celih nenegativnih brojeva kao rekurzivna funkcija:

f1(x) = I1(x)

f2(x) = S(x)

f3(x, 0) = I1'(x)

f3(x, y + 1) = S(f3(x, y)) = f2(f3(x, y))

f3 f = x + y.

62

Page 69: Programski Jezici i Strukture Podataka

O S N O V I T E O R I J E A L G O R I T A M A

Tjuringove mašine

Pod Tjuringovim mašinama podrazumevamo familiju

matematičkih apstrakcija koje predstavljaju jednu apstraktnu mašinu. Ovde posmatramo algoritam sa stanovišta onoga ko ga izvršava, tj. Tjuringove mašine prikazuju apstraktnog izvršioca algoritma i njegovo ponašanje kojim se strogo definisan ulaz transformiše u strogo definisan izlaz.

Definisao ih je Alan Turing 1936. godine. Svaki današnji računar predstavlja Tjuringovu mašinu. Kad je 1943. napravljen ENIAC (John von Neumann) on je u suštini predstavljao Tjuringovu mašinu.

Zadatak Tjuringove mašine je da reč iz nekog ulaznog alfabeta transformiše u reč nekog izlaznog alfabeta. Zbog toga je glavni problem način zadavanja alfabetskog operatora.

Postoje dve grupe Tjuringovih mašina i to su specijalne i univerzalne Tjuringove mašine. Današnji računar je po svojoj prirodi jedna univerzalna Tjuringova mašina.

Specijalne Tjuringove mašine

Imaju tri funkcionalne celine i to su: beskonačna traka, upisno-čitajuća glava i upravljački blok.

Beskonačna traka igra ulogu memorije i može ih biti jedna ili više, ali su sve ekvivalentne. Na beskonačnoj traci se nalazi ulazna reč i na njoj se izvode sve transformacije. Na početku rada se na beskonačnoj traci nalazi neka ulazna reč od slova, a levo i desno od te reči su prazne ćelije (označavamo ih sa B).

Upisno-čitajuća glava izvršava operaciju učitavanja

nekog slova sa ili upisivanja nekog slova na trenutnu

poziciju. Ima mogućnost da se pomeri za jedno

UTM se može svesti na specijalnu.

63

Page 70: Programski Jezici i Strukture Podataka

O S N O V I T E O R I J E A L G O R I T A M A

mesto u levo ili desno U početnom trenutku se nalazi iznad prvog slova ulazne reči.

Upravljački blok upravlja radom Tjuringove mašine i uvek se nalazi u nekom stanju. Skup stanja upravljačkog bloka nazivamo unutrašnji alfabet

Tjuringove mašine i u njemu mora da se nađe tačno jedno početno stanje i jedno ili više završnih stanja.

Kad se upravljački blok nađe u jednom od završnih stanja, sesija je završena. Na početku rada je upravljački blok u početnom stanju.

Rad Tjuringove mašine se odvija po koracima (pokretima) u tri razdela. Prvo se menja stanje upravljačkog bloka. Zatim se vrši upis slova koje nije B na poziciju iznad koje je upisno-čitajuća glava. Glava se pomera za jednom mesto u levo ili desno. Ovaj postupak se ponavlja dok se upravljački blok ne nađe u nekom završnom stanju. Rezultat rada će biti reč koja se nalazi između dve prazne ćelije.

Među simbolima neke reči može se pojaviti i prazan simbol

koji ne utiče na reč i označavamo ga sa . Treba voditi računa da prazna ćelija (B) ne sadrži nikakav podatak. Samim tim ako sadrži prazno slovo (), ona nije prazna.

Ne postoji način da se unapred zna da će za neku ulaznu reč Tjuringova mašina posle konačnog broja koraka doći u jedno od završnih stanja, tj. ne postoji način da unapred znamo hoće li algoritam dati rezultate ili ne.

Formalna definicija Tjuringovih mašina

Formalno se Tjuringove mašine definišu kao uređena šestorka (, , , , q0, F), gde je:

– unutrašnji alfabet;

– spoljašnji alfabet (skup svih simbola koji se mogu naći na beskonačnoj traci uključujući i B i );

64

Page 71: Programski Jezici i Strukture Podataka

O S N O V I T E O R I J E A L G O R I T A M A

– skup ulaznih slova (podskup skupa , u opštem slučaju: \ {B}, tj. sigurno B , ali možda i neki drugi element iz takođe ne pripada );

– funkcija prelaza (obavlja pokrete, a odluka o pokretu se donosi na osnovu stanja upravljačkog bloka i simbola iznad kojeg se trenutno nalazi upisno-čitajuća glava, tj. : ( ) ( \ {B}) {L, R};

q0 – početno stanje;

F – skup završnih stanja.

Konfiguracija Tjuringove mašine

Konfiguracija Tjuringove mašine je uređena trojka (q, , i) i ona određuje njeno ukupno stanje.

Ukupno stanje Tjuringove mašine je određeno stanjem upravljačkog bloka (q), aktuelnom reči na beskonačnoj traci () i položajem upisno-čitajuće glave (i), tj. njenim rastojanjem od početka aktuelne reči (redni broj slova iznad kojeg se glava nalazi).

Funkcije prelaza

Funkcija prelaza se zadaje u vidu pesudnonaredbe, npr: qa q'a'.

Drugi način za njihovo zadavanje (ne isključuje prvi) je u vidu funkcionalne sheme. To je matrica koja po jednoj dimenziji ima oznake stanja, a po kolonama oznake iz spoljašnjeg alfabeta. Na preseku se nalaze urđene trojke (q', a, P).

Osnovna teza teorije algoritama sa stanovišta Tjuringovih mašina kaže da se svaki algoritam može zadati u obliku funkcionalne sheme specijalne Tjuringove mašine, tj. svaki algoritam je jedna Tjuringova mašina.

Univerzalne Tjuringove mašine

Postavlja se pitanje možemo li definisati Tjuringovu mašinu koja bi mogla predstavljati svaki algoritam. To je univerzalna Tjuringova mašina. Ima tu osobinu da ne služi za izvršavanje jednog algoritma, već svakog algoritma.

Funkcionalna shema se kodira, tako da i ona postaje deo ulaza.

65

Page 72: Programski Jezici i Strukture Podataka

O S N O V I T E O R I J E A L G O R I T A M A

Univerzalne Tjuringove mašine na ulazu imaju reč koju treba obraditi zajedno sa uputstvom za njenu obradu.

U savremenim računarima, ova uputstva zovemo programima.

Primer

T = (, , , , q0, F)

= {S1, S2, S3}

= {0, 1, , B}

= {0, 1}

q0 = S1

F = {S3}

funkcionalna shema ove Tjuringove mašine je:

0 1 BS1 (S2, 0, R) (S2, 1, R) - -S2 (S2, 1, R) (S2, 0, R) - (S3, , R)S3 - - - -

66

Page 73: Programski Jezici i Strukture Podataka

O S N O V I T E O R I J E A L G O R I T A M A

Normalni algoritmi Markova

Ovo je najnoviji algoritamski sistem, izveden je 1954. iz BDA. Posmatraju algoritam sa stanovišta izvršavanja.

Osnovni problem kojim se bave NAM je kako prikazati alfabetski operator G na neki standardni način.

Kod zadavanja alfabetskog operatora (transformacije ulazne reči) Markov je uočivo da postoje svega dve osnovne operacije: operacija obrade i operacija odluke. Tako da se Markovljevi algoritmi prikazuju primenom ove dve operacije:

Postoji i treća operacija, to je smena nad tzv. tekućom reči: .

Na početku algoritma se poijavljuje početna vrednost tekuće reči na kojoj se izvršava strogo definisana sekvenca smena na sledeći način: u tekućoj reči se locira prva s leva pojava podreči i zatim se ona zameni sa .

Na primer: tekuća reč je 9215125415181512, je 151, a je 0. Posle smene dobijamo: 92025415181512.

Naravno, ako smena ima više, mora se voditi računa o redosledu njihovog izvršavanja. Tako intuitivno podrazumevamo strogo uređen niz smena koje se primenjuju u tekućoj reči.

Ako podreči nema, ništa se neće dogoditi.

U svakom slučaju, mora postojati posebna vrsta nula ili više završnih smena koje se izvršavaju ako ni jedna druga

i

67

Page 74: Programski Jezici i Strukture Podataka

O S N O V I T E O R I J E A L G O R I T A M A

više ne može da se izvrši. Njih označavamo tako što stavimo tačku iza strelice, npr. . .

Uobičajena oznaka za prazno slovo je . Proširivanje reči radimo na sledeći način: , tj. ispred tekuće dodajemo .

Definicija normalnih algoritama Markova

MNA definišemo koristeći sledeće definicije:

i je smena;

x je reč;

P(i, x) je predikat, tj. x = i(x)

K(i) pokazuje T ako je i završna smena, tj. ako nije.

68

Page 75: Programski Jezici i Strukture Podataka

O S N O V I T E O R I J E A L G O R I T A M A

Opšti oblik Markovljevih normalnih algoritama

Opšti oblik Markovljevih normalnih algoritama prikazan je sledećom šemom:

DA NE

početak

ulaz:X

P(1, x) x = 1(x) K(1)

1DANE

DA NEP(2, x) x = 2(x) K(2)

1DANE

DA NEP(i, x) x = i(x) K(i)

1DANE

1

kraj

izlaz:X

69

Page 76: Programski Jezici i Strukture Podataka

O S N O V I T E O R I J E A L G O R I T A M A

Fundamentalne osobine algoritama

To su diskretnost, primenljivost, determinisanost i masovnost.

Diskretnost je definiciona osobina, jer kontinualni algoritmi ne postoje

Algoritam je primenljiv na date ulazne podatke ako nakon konačnog broja koraka daje rezultate.

Detereminisanost znači da algoritam za iste ulazne podatke daje isti rezultat. To važi samo za determinističke algoritme. Pored njih postoje i sholastički koji nemaju ovu osobinu, pa ovo nije esencijalna osobina algoritama.

Masovnost znači da je algoritam primenljiv na veliki broj ulaznih podataka. Tu postoje određeni problemi. Prvo, ne znamo šta znači veliki broj ulaznih podataka Dalje, postoje algoritmi koji nemaju ulazne podatke. Treće, neki algoritmi se pišu za samo jedan tačno određeni ulazni podatak.

70

Page 77: Programski Jezici i Strukture Podataka

Tema

4

71

Page 78: Programski Jezici i Strukture Podataka

Strukturirano programiranje

subtitle

trukturirano programiranje predstavlja tehnologiju za sistematsku izradu softvera. Definisano je kao paradigma 70-ih godina koja je kasnije

dopunjena sistem analizom. Tada je konačno postalo moguće pratiti ceo životni ciklus softvera.

SMetodologija koja je prethodila strukturiranom programiranju je kompozitno programiranje. Korišćeno je od pojave viših programskih jezika, pa do kraja 60ih, kad je nastala prva velika softverska kriza.

Prva velika softverska kriza je bila uzrokovana činjenicom da nije postojao softver koji bi mogao iskoristiti novonastale velike mogućnosti hardvera. Zbog toga su organizovani stručnjaci koji su dijagnostifikovali da je problem u tome što se u to vreme kompleksan softver nije mogao pisati bez grešaka.

1968. holandski hemičar E. W. Dijkstra piše čuveni kontroverzni članak: „Goto Statement Considered Harmful“ u kojem izlaže rezultate istraživanja po kojima je broj grešaka u softveru proporcionalan broju upotreba goto naredbe.

Konačno je 1969. definisan programski jezik koji je omogućio pisanje programa bez upotrebe goto naredbe. U pitanju je Pascal Niklausa Wirtha.

1972. Dijkstra, Hoare i Dahl su napisali knjigu „Structured Programming“ po kojoj je cela ova oblast i dobila ime. U toj knjizi se nalaze tri članka koji se između ostalog bave rešavanjem problema bez upotrebe goto i strukturama podataka.

Tih godina je razrađena i teorija modula. Najveću zaslugu za to ima Parnas koji je definisano čuveni Princip skrivanja informacija (IHP).

72

Page 79: Programski Jezici i Strukture Podataka

S T R U K T U R I R A N O P R O G R A M I R A N J E

Ovde je bitno pomenuti i sukcesivnu (hijerarhijsku) dekompoziciju

programa. Znači, od najkompleksnijeg načina zadavanja problema njegovim rastavljanjem na jednostavnije celine dolazimo do određene proizvoljne dubine.

Pod strukturiranim programiranjem podrazumevamo skup tehnika za razvijanje programskih modela koji koriste strogo definisane upravljačke strukture i strukture podataka.

Sredstva za analizu algoritama

Osnovno sredstvo za analizu algoritma jeste graf toka

programa. To je digraf (orjentisani graf) koji pokazuje redosled izvršavanja operacija u programu. Graf toka programa možemo definisati i kao BDA redukovan na najosnovnije elemente.

Graf toka programa se sastoji od tri elementa:

1. funkcionalni čvor (proces) transformiše neke

informacije. Ima jedan ulaz i jedan izlaz;

2. predikat ima jedan ulaz i dva izlaza;

3. kolektor ima dva ulaza i jedan izlaz.

73

Page 80: Programski Jezici i Strukture Podataka

S T R U K T U R I R A N O P R O G R A M I R A N J E

Primer

Na gornjem dijagramu možemo uočiti jedan od podgrafova. Njega možemo prikazati posebnim simbolom obrade ako želimo da uprostimo glavni graf.

Pravilni programiKlasa programa koja se razmatra kao ciljna klasa se zove pravilni program. Pravilni program zadovoljava tri uslova:

1. ima tačno jednu ulaznu granu

2. ima jednu izlaznu granu

3. kroz svaki čvor prolazi se bar jednom od ulaza do izlaza

Prva dva uslova nalažu da ceo pravilni program možemo zameniti tačno jednim čvorom, a treći uslov eliminiše mogućnost beskonačnih ciklusa i izolovanih (nedostupnih) delova programa.

Pravilni potprogram

Pravilni potprogram je sastavni deo nekog programa koji je takođe pravilan. Na datom primeru grafa toka programa zaokružen je jedan podgraf koji je takođe i pravilan program.

T

T

74

Page 81: Programski Jezici i Strukture Podataka

S T R U K T U R I R A N O P R O G R A M I R A N J E

Potprograme uvodimo zbog načina uočavanja dekompozicije programa na prostije delove. Dekompoziciju vršimo dokle je god moguće poštovati pravilnost potprograma. Dakle, pronalazimo potprograme koji ne mogu da se dekomponuju na pravilne potprograme. Takvi potprogrami su prosti potprogrami.

Prost program je pravilan program čiji svaki pravilan potprogram ima tačno jedan čvor. Dakle, prost program može da sadrži druge pravilne programe, ali to su samo procesi i ništa više.

Odavde vidimo da prosti programi predstavljaju neke od osnovnih naredbi jednog programskog jezika.

Analiza algoritamaAnaliza algoritama se direktno bavi problemom koji iskazi treba da postoje u nekom programskom jeziku. Izgrađena je oko dva centralna pojma: pojma pravilnog programa i pojma prostog programa.

Kao i dva algoritma isto i dva programa mogu biti funkcionalno ekvivalentni (za isti ulaz generišu isti izlaz) i ekvivalentni po izvršavanju (ako ulazne podatke obrađuju na isti način do izlaznih).

Analiza i odnos prostih programa nas navode na određivanje pojma baze strukturiranih programa. To je skup prostih programa čijom se superpozicijom (kombinovanjem) može realizovati svaki pravilan program. Treba skrenuti pažnju da baza strukturnih programa po definiciji nije minimalna, tj. ona može da sadrži i „višak“ prostih programa. Dakle, baza je redundantna.

Strukturirani program je program sastavljen od prostih programa iz zadate baze. Dakle sledi da je strukturiran program pravilan program, ali to ne znači da u njemu po definiciji nema skokova.

Pojam strukturiranog progama je relativan, jer se definiše u odnosu na zadatu bazu. Tako je jedan program u odnosu na jednu bazu strukturiran, ali ne mora biti strukturiran u odnosu i na neku drugu bazu.

75

Page 82: Programski Jezici i Strukture Podataka

S T R U K T U R I R A N O P R O G R A M I R A N J E

Kao kandidati za sastavljanje baze razmatraju se programi sa jednim, dva, tri i četiri čvora, ali naravno ne svi koji zadovoljavaju ovaj kriterijum (npr. oni koji nemaju funkcionalne čvorove nisu od interesa za bazu, jer „ne rade ništa“).

Ovakvih programa ima sedam:

1.funkcionalni čvor

2.sekvenca

3.

IF-THEN

4.

WHILE-DO

5.

REPEAT-UNTIL

6.

IF-THEN-ELSE

7.

DO-WHILE-DO

Programi 3 i 6 su programi selekcije, a 4, 5 i 7 iteracije. Ovi prosti programi predstavljaju osnovne naredbe svih strukturnih programskih jezika, tj. preslikavaju se u naredbe tih programskih jezika. Odavde vidimo da je skup naredbi u Pascalu teorijski zasnovan.

Primetimo da među ovih sedam prostih programa ne postoji ekvivalent pascalske naredbe case. To je zbog toga što case nije prost program, jer ga možemo

f

f g

P

ST

S

PT

PT

S

f

g

P

T

P

T

f

g

76

Page 83: Programski Jezici i Strukture Podataka

S T R U K T U R I R A N O P R O G R A M I R A N J E

zameniti pomoću if-then-else strukture. Razlog za uvođenje case naredbe je taj što nam je tako programiranje olakšano.

Takođe primetimo da u realizaciji ovih sedam struktura ne postoje skokovi.

Strukturna teorema i programiranje bez gotoIzdvaja se jedna posebna baza strukturnih programa. Nju čine sekvenca, iteracija tipa while-do i selekcija tipa if-then-else. Pomoću ove baze se može izvesti svaki program i na osnovu nje pravimo druge baze koje su nam potrebne.

1966. C. Boehm i G. Jacopini su izveli strukturnu teoremu

koja pokazuje da se svaki pravilan program može ostvariti superpozicijom ove tri strukture, tj. da se može ostvariti bez upotrebe skokova, što je bilo ključno za rešavanje problema koji su tražili uvođenje strukturiranih programa.

Za dokaz teoreme uzećemo jedan pravilan program prikazan sledećim grafom toka programa:

Naš cilj je da definišemo program funkcionalno ekvivalentan ovom koji se može sastaviti upotrebom samo pomenute tri strukture.

Uočićemo redosled izvršavanja čvorova sa GTP i pokazaćemo da se može obezbediti mehanizam za određivanje sledećeg čvora koji će biti izvršen, a da taj mehanizam

sadrži samo tri date strukture.

Da bismo to postigli, prvo ćemo na GTP proizvoljnim simbolima obeležiti čvorove (na primeru, uzeti su celi nenegativni brojevi). Okolinu (ono što se na grafu nalazi pre ulaza i pre izlaza) isto obeležavamo proizvoljnim simbolom (uzeta je 0). Kolektore ne označavamo, jer su to pomoćni simboli GTP. Označavanjem čvorova se u stvari omogućava da svaka ta oznaka bude argument pomenutog mehanizma čiji je rezultat takođe oznaka čvora.

A

P BT

0

1

32

77

Page 84: Programski Jezici i Strukture Podataka

S T R U K T U R I R A N O P R O G R A M I R A N J E

Zatim, definišemo matricu prelaza koja čini osnovu za određivanje koji će se čvor sledeći izvršiti. To je kvadratna matrica koja ima onoliko vrsta i kolona koliko ima oznaka čvorova uključujući i oznaku okoline. Realizujemo je kao logičku matricu, tako što je popunjavamo po vrstama. Za svaki čvor u nekoj vrsti upisujemo T i . T upisujemo u onoj koloni koja odgovara čvoru koji neposredno sledi čvoru iz date vrste. Zbog toga u svakoj vrsti postoji samo jedno T.

Pošto dva čvora mogu da slede neki predikat (ili jedan ili drugi, ne oba) u odgovarajuće kolone nećemo staviti oznake T i , već stavljamo P i , od kojih opet samo jedna može biti tačna i ona nam pokazuje koji se čvor sledeći izvršava.

Matrica prelaza za gornji graf toka programa izgleda ovako:

0 1 2 30 T 1 T 2 P P3 T

Sada, definišemo funkciju next koja preslikava skup oznaka čvorova na samog sebe:

function next(n: integer): integer;begin

j := 0;while not L[n, j] do j := j + 1;next := j;

end;

Sad možemo napraviti prelaznu strukturu koja vodi krajnjoj strukturi. Koristićemo još jednu teoremu, to je teorema o kanoničkoj formi. Ona kaže: za svaki pravilan program postoji ekvivalentan program koji se sastoji od jedne iteracije while-do unutar koje se nalazi struktura case sa onoliko paralelnih grana koliko ima procesa i predikata u grafu toka programa.

Dakle, kanonička forma za naš primer je:

78

Page 85: Programski Jezici i Strukture Podataka

S T R U K T U R I R A N O P R O G R A M I R A N J E

beginn := 1; {oznaka prvog čvora koji se izvršava}while n <> 0 do {0 je oznaka okoline}

case n of1: begin {obraditi n}; n := next(n) end;2: begin {obraditi n}; n := next(n) end;...k: begin {obraditi n}; n := next(n) end;

endend;

Sada možemo formulisati strukturnu teoremu: svaki pravilan program može se transformisati u ekvivalentan formalno strukturiran program uz korišćenje tri osnovne upravljačke strukture: sekvence, iteracije tipa while-do i selekcije tipa if-then-else. Primetimo da se case ne uklapa u ovu teoremu, ali tu strukturu vrlo lako zamenjujemo ugnežđenom strukturom if-then-else.

Minimalna baza strukturiranih programa

Baza koja se sastoji od sekvence, iteracije while-do i selekcije if-then-else nije minimalna. Možemo isključiti strukturu if-then-else (tj. zameniti je strukturom while-do) i onda opet prikazati pravilne programe pomoću struktura iz ove (sada minimalne) baze.

If-then-else možemo zameniti sa while-do na sledeći način:

if p then A else B

79

Page 86: Programski Jezici i Strukture Podataka

S T R U K T U R I R A N O P R O G R A M I R A N J E

Uzroci nestrukturiranosti programa

Strukturiran program je relativan pojam, jer se odnosi na bazu. Ukoliko ne postoji referenca na neku bazu, pojam strukturiranog programa se odnosi na programe koji su pisani bez upotrebe skokova ili uopšte koji se odnose na bazu izgrađenu od sekvence, iteracije tipa while-do i selekcije tipa if-then-else.

Postoji pet uzroka za nestrukturiranost programa, tj. postoji pet struktura koje ako se neka od njih pojavi kao podgraf GTP onda je program nestrukturiran i mora se koristiti goto.

To su sledeće strukture:

nepravilan put iza selekcije

T

T

80

Page 87: Programski Jezici i Strukture Podataka

S T R U K T U R I R A N O P R O G R A M I R A N J E

repeticija sa više izlaza

repeticija sa više ulaza

T

T

T

T

81

Page 88: Programski Jezici i Strukture Podataka

S T R U K T U R I R A N O P R O G R A M I R A N J E

repeticije koje se preklapaju

paralelne repeticije (ovo je inače i nepravilan program)

T

T

T

T

82

Page 89: Programski Jezici i Strukture Podataka

S T R U K T U R I R A N O P R O G R A M I R A N J E

Strukturiranje programa

Strukturiranje programa se bavi problemom eliminisanja skokova. Oni ostaju kao opcija jedino za eventualno iskakanje iz nekog ciklusa. Skokove eliminišemo transformacijom programa koji ih koristi u funkcionalno ekvivalentni koji ih nema.

Postoje dva načina za ovu transformaciju: možemo napisati program iz početka izbegavajući skokove ili koristiti neku od metoda za transformaciju. Ovaj drugi metod je više korišćen. Najpoznatija metoda je Aschroft-Manna i bazira se na dokazu strukturnih teorema.

Metoda Aschroft-MannaPrimer

Transformisaćemo program dat sledećim GTP u funkcionalno ekvivalentan program.

To se radi na sledeći način:

prvo označimo čvorove i okolinu;

uvodimo jednu upravljačku promenljivu, sukcesivnim proveravanjem njene vrednosti izvršiće se odgovarajući čvor;

zbog ubrzanja procesa, vrednost idućeg čvora nećemo tražiti u matrici prelaza, već se ta vrednost zadaje eksplicitno.

Ova metoda je izuzetno pogodna za automatizaciju.

Bazira se na transformaciji nestrukturiranog programa (sa goto skokovima) u program bez goto naredbi.

Q

A

T

PT

B

1

2

3

0

4

83

Page 90: Programski Jezici i Strukture Podataka

S T R U K T U R I R A N O P R O G R A M I R A N J E

Evo kako izgleda algoritam tog programa:

Pisanje programa bez upotrebe skokovaOvo ostvarujemo hijerarhijskom (ili sukcesivnom) dekompozicijom programa. Najčešće se koristi top-down razvoj programa koji predstavlja vrlo prirodan

n 1

n = 1T

A

n 2

n 3

n = 3

Bn 4

n 0

n = 0

n = 2 P n 1

n = 4 Q n 2

T

T

T

T

T

T

84

Page 91: Programski Jezici i Strukture Podataka

S T R U K T U R I R A N O P R O G R A M I R A N J E

način za pisanje programa uopšte rešavanje kompleksnih problema. Program razbijamo na jednostavnija rešenja koja se sukcesivno izvršavaju.

Primer

Rešiti sistem linearnih jednačina Ax = b reda n, Ax = b, n.

Sa teorijskog aspekta, jasno je da problem rastavljamo na problem unosa podataka, određivanja rešenja i izdavanja rezultata. Naravno, svaki od ovih problema se može dekomponovati na još jednostavnije probleme. Tako da dekompoziciju problema vršimo do nivoa naredbe programskog jezika.

Svaki od ovih nivoa dok ne stignemo do naredbe u stvari predstavlja komentar u programu koji opisuje postupak rešavanja problema.

Rešavanje sistema linearnih jednačina Ax = b, n.

U praksi, ulaz i izlaz nećemo dekomponovati na jednostavnije probleme, jer su jasni sami po sebi. Doduše, problem određivanja rešenja dekomponujemo na neke podkorake čiji broj zavisi od toga kako rešavamo sistem. Na slici je dat jedan primer. Ispod ovog nivoa nećemo ići kad je u pitanju ovaj zadatak, jer su dalji postupci jednostavni.

Ovakav način rešavanja problema otvara mogućnost paralelnog timskog rada, zbog toga što su poslovi algoritamski nezavisni. Druga mogućnost koja nam se otvara jeste korišćenje gotovog softvera.

Ova metoda više nije toliko popularna, njen osnovni nedostatak je taj što je algoritamski orijentisana.

REŠITIAx = b, n

ulaz:n, A, b

odreditirešenja

izlaz:x

odreditiA-1

odreditix = A-1b

85

Page 92: Programski Jezici i Strukture Podataka

Tema

5

86

Page 93: Programski Jezici i Strukture Podataka

Strukture podataka

U dosadašnjem izlaganju najviše reči je bilo o algoritmima. Ovde ćemo se baviti jednom podjednako bitnom komponentom svakog programa – strukturama podataka.

Pojam podatkaajosnovniji pojam u računarstvu uopšte jeste pojam podatka. U memoriji računara se ne nalazi ništa osim podataka (Van Neumannova

koncepcija). Tu se misli na podatke u užem smislu reči (vrednosti nekih promenljivih) i uputstva kako se ti podaci obrađuju (programi). Pre konstruisanja ENIAC-a, program je bio realizovan mehanički.

N

Podaci odgovaraju diskretnim, zapisanim činjenicama o fenomenima iz kojih se izvlače informacije. Informacija je svako povećanje znanja.

Jedinice posmatranja zovemo entiteti. Entitet predstavlja stvar, subjekt, pojam ili događaj. Svaki podatak se vezuje za neki entitet, pa podatak definišemo kao uređenu četvorku: (naziv entiteta, naziv osobine, vrednost osobine, vreme). Na primer: (Petar, težina u kg, 70, decembar 2002.).

Da bi mogli manipulisati podacima, oni moraju biti uređeni. Podatke možemo definisati kao skupove. Na primer, treba proveriti da li je data ulazna vrednost (10) elemenat skupa S = {-5, 10, 11, 12, 25}. Znači, treba kreirati odgovarajući algoritam koji će porediti datu vrednost sa elementima skupa, tj. sa njegovim prvim, drugim itd. elementom. Postavlja se pitanje kako odrediti redosled elemenata, ako znamo da je skup neuređena struktura.

87

Page 94: Programski Jezici i Strukture Podataka

S T R U K T U R E P O D A T A K A

Dakle, mora postojati bar jedno uređenje podataka. Tako da, ako skup S snabdemo uređenjem, to više neće biti skup. Uređen skup se zove struktura.

Bez strukture podataka nema programa.

Prvi programski jezici (Fortran, BASIC, Cobol) su bili prilično siromašni strukturama podataka.

Strukture podataka i tipovi podataka su vrlo bliski pojmovi.

U Pascalu, Wirth je izjednačio po značaju algoritamski i deklarativni deo (u kojem su date strukture podataka). On je pokazao da je struktura podataka potpuno ravnopravna u odnosu na algoritam i da je to stabilniji deo programa.

Odnos algoritma i strukture podataka

Ako posmatramo gornju šemu gde su prikazani algoritmi A1, A2, ..., An koji svi pristupaju nekoj strukturi podataka S, jasno je da izmena nekog od algoritama Ai

verovatno neće imati uticaj na drugih n-1 algoritama. Ali svaka izmena strukture S će gotovo sigurno izazvati izmene u skoro svim algoritmima.

Značaj struktura podatakaZnačaj struktura podataka ilustrovaćemo na primeru. Tu se jasno vidi koliki je uticaj struktura podataka na algoritam.

S

A1 A2 Ai An

88

Page 95: Programski Jezici i Strukture Podataka

S T R U K T U R E P O D A T A K A

Treba napisati Pascal program za manipulaciju sa matricama. Program treba da omogući pristup elementima matrice, obradu tih elemenata, brisanje, dodavanje novih itd.

Postavlja se pitanje koju strukturu podataka će koristiti naš program. Uzećemo da je matrica definisana kao izvedeni pascalski tip array:

var A: array[1..m, 1..n] of <tip>;

U ovom slučaju, pristup elementima rešen je na nivou programskog jezika:

A[i, j] := t;m := A[k, l];

A takođe i obrada elemenata:

for i := 1 to m do for j := 1 to n do Obradi(A[i,j]);

Postavlja se pitanje, kako manipulisati matricom ako su m i n veliki brojevi. Npr, ako su m i n 1000, naša matrica ima milion elemenata, što traži prilično velik memorijski prostor za smeštanje tih elemenata. Takođe, pristup i obrada elemenata može trajati prilično dugo. Dakle, učinićemo znatno ozbiljniji zahvat i razmotrićemo druge načine za realizaciju strukture podataka.

U inženjeriji je vrlo čest slučaj da u matricama sa velikim brojem elemenata, vrednost najvećeg broja tih elemenata je nula. Takve matrice se zovu retke matrice. Zašto onda ne bismo obratili pažnju samo na one elemente čija je vrednost različita od nule?

Prvo, memorisaćemo samo one čija je vrednost različita od nule. Time smo matricu pretvorili u niz slogova (p je mnogo manje od m i n.):

var B: array[1..p] of recordvrednost: T;vrsta, kolona: integerend;

Sada obrađujemo samo elemente od B:

for k := 1 to p do obradi(B[k].vrednost);

89

Page 96: Programski Jezici i Strukture Podataka

S T R U K T U R E P O D A T A K A

Ovim smo smanjili troškove memorije i vreme obrade, ali sada pristup elementima A više nije jednostavan. Pristup elementu A[i,j] možemo rešiti na primer na sledeći način:

k := 1; nadjen := false;while (k <= p) and (not nadjen) do

if (B[k].vrsta = i) and (B[k].kolona = j) thennadjen := true

else k := k + 1;if nadjen then x := B[k].vrednost else x := 0;

Još je komplikovaniji postupak za dodavanje novog elementa u A.

Definicija strukture podatakaPostoji mnogo definicija strukture podataka: od onih intuitivnih do složenih, strogo matematičkih definicija (npr. uređen skup podataka, strana 88).

Elemente jedne strukture čine:

pre svega, skalari;

neke druge strukture podataka;

relacije kojima su povezani elementi date strukture.

Uređeni par (p, ) jeste skalar, gde je p podatak, a relacija. Pošto je p izolovan podatak, ova relacija jeste prazna relacija.

Relacije kojima su međusobno povezani elementi strukture mogu biti sasvim jednostavne ili pak vrlo složene. Na primer, niz je uređen relacijom susedstva definisanom između dva elementa na sledeći način {(xi, xi+1) | i = 1, 2, ..., n -1}. Složena relacija je na primer relacija predmet-nastavnik, gde jedan predmet može da predaje više različitih nastavnika, a sa druge strane svaki nastavnik može da predaje više različitih predmeta.

U daljem razmatranju posmatraćemo relaciju elemenata nekog niza. Uzećemo da je ova relacija netranzitivna. Definisaćemo neposredno susedstvo kao (xi, xi+1) ili posredno kada je xi prethodnik xi+1 i xi+1 je sledbenik xi.

90

Page 97: Programski Jezici i Strukture Podataka

S T R U K T U R E P O D A T A K A

Skalar je struktura podataka. Ako su S1, S2, ..., Sk strukture podataka i ako je S = {S1, S2, ..., Sk} tada je uređena n+1-orka (S, r1, r2, ..., rn) struktura podataka, gde su r1, r2, ..., rn relacije reda dva ili većeg u skupu S. U opštem slučaju ova n+1-orka je promenljiva u vremenu.

GrafoviZa grafičko prikazivanje struktura podataka se koriste grafovi. Graf je skup snabdeven jednom binanom relacijom, tj. uređeni par (S, r). Sastoji se od čvorova (elementi skupa S). Relacije među tim čvorovima se prikazuju tako što ih povezujemo granama koje ne moraju biti orjentisane. Orjentisan graf se zove digraf (directed graph).

Digrafi su modeli jedne velike klase struktura podataka. Ne svih, jer se ne mogu sve strukture prikazati na ovaj način. U matematici, čvorove grafa označavamo kružićima, dok je kod struktura podataka uobičajeno da se za oznake koriste pravougaonici.

Graf niza

Za svaki čvor na digrafu se definiše ulazni stepen čvora, a to je broj grana koje ulaze u čvor, i izlazni stepen čvora, tj. broj grana koje izlaze iz njega.

Operacije nad strukturama podatakaDefinicije ovih operacija nisu obuhvaćene definicijom strukture podataka, jer ih intuitivno pridružujemo toj definiciji. Razlog zbog čega podatke stavljamo u strukturu (strukturiramo ih, uređujemo) je da bismo nad njima vršili neke operacije.

X1 X2 X3 XnXn-1...

a1 a2

a3 a4

Digraf

91

Page 98: Programski Jezici i Strukture Podataka

S T R U K T U R E P O D A T A K A

Postoje tri grupe operacija:

1. primitivne operacije su sasvim proste operacije i uglavnom se pojavljuju u sastavu drugih operacija, tj. retko se pojavljuju kao izolovane. Treba spomenuti operaciju Empty, koja je logička operacija i vraća vrednost true ako je struktura podataka prazna, tj. nema elemenata. Druga bitna je operacija Full, takođe logička koja pokazuje da li je memorijski prostor namenjen čuvanju neke strukture podataka popunjen.

Treba primetiti da ove dve operacije nisu dualne, jer je Empty vezana za definiciju neke strukture podataka, a Full sa neposrednom realizacijom te strukture u memoriji. Pošto se jedna struktura može realizovati na više načina, Full u jednom slučaju može da ima smisla, a u drugom ne;

2. osnovne operacije su najbitnije i služe za međusobno razlikovanje struktura podataka koje imaju isti digraf. Postoje tri grupe ovih operacija: operacije pristupa, uklanjanja i dodavanja. Ove operacije ulaze u definiciju strukture podataka.

Osnovne operacije su:

a) pristup – to su semantički jednostavne operacije. Svode se na uočavanje (izdvajanje) nekog elementa iz strukture podataka radi čitanja ili izmene podatka (informacionog dela, tj. sadržaja elementa). Izdvojeni element se zove tekući element i postoji mehanizam za izmenu tekućeg elementa.

Treba definisati kriterijum pristupa nekom podatku. To je predikat koji daje T za tačno jedan element iz strukture. Ako se takav element može naći u datoj strukturi, pristup je uspešan. U suprotnom, traženog elementa nema.

Postoje tri načina pristupa u okviru strukture podataka od kojih su svi ravnopravni, ali nejednako zastupljeni. Kod pojedinih struktura podataka neki od ovih

92

Page 99: Programski Jezici i Strukture Podataka

S T R U K T U R E P O D A T A K A

načina nisu mogući ili jednostavno nemaju upotrebni značaj. Način pristupa može biti:

I prema poziciji: kriterijum je mesto elementa, može se dati i implicitno, koristi se kod nizova;

II prema informacionom sadržaju (asocijativni pristup, traženje): kao argument traženja se daje deo informacionog sadržaja elementa i to takav deo da potpuno definiše dati element. Tada se algoritamski proverava da li takvog elementa ima u datoj strukturi. Ako on postoji, traženje je uspešno i na raspolaganje se stavlja ostatak informativnog sadržaja elementa. Deo informativnog sadržaja koji jednoznačno definiše svaki element se naziva ključ;

III navigacija – ovaj način pretraživanja izgrađen je oko pojma tekućeg elementa. Tekući element uvek postoji i njemu se implicitno pristupa;

b) uklanjanje se vrši na sledeći način: izvuče se traženi element iz strukture i potom se ažuriraju veze, kako bi se uklonile sve prema sada nepostojećem elementu;

c) dodavanje se izvodi slično kao uklanjanje, jedina razlika je što se novi element umeće u strukturu, a veze se ažuriraju kako bi se i novi element našao raspoređen na pravo mesto.

Sve tri osnovne operacije mogu biti definisane sa određenim ograničenjima, a uklanjanje i dodavanje uopšte ne moraju biti definisane za neku strukturu.

3. složene operacije su:

a) pretraživanje – razlika između ove i operacije traženja je u tome što rezultat ove operacije može biti više od jednog elementa;

b) sortiranje – to je uređivanje (po pravilu) linijske strukture podataka po nekom kriterijumu

93

Page 100: Programski Jezici i Strukture Podataka

S T R U K T U R E P O D A T A K A

c) kopiranje;

d) spajanje dve ili više struktura u jednu;

e) razlaganje jedne strukture podataka na dve ili više.

Klasifikacija struktura podatakaKlasifikacija struktura podataka vrši se na tri osnovna načina:

1. prema nivou apstrakcije;

2. prema mestu memorisanja;

3. prema tipu relacije.

Klasifikacija struktura podataka prema nivou apstrakcije

Postoji izuzetno velika i bitna razlika između logičkih i fizičkih struktura podataka. Nije isto kako logički definišemo neku strukturu i kako je posle realizujemo u memoriji računara.

Logička struktura je ona koja se pojavljuje u modelu i nezavisna je od računara, programa i memorije. Data rekurzivna definicija strukture podataka se odnosi upravo na ovu logičku strukturu.

Fizička struktura podataka (tj. fizička realizacija) predstavlja strukturu onako kako je implementirana u računaru.

Jasno je da za jednu logičku strukturu može da postoji više načina njene fizičke realizacije.

Primer

Uzećemo primer strukture matrice. Njena logička struktura se sastoji od vrsta i kolona. Sa druge strane, memorija računara je po svojoj prirodi jednodimenzionalna (linijska) struktura. Zbog toga moramo smisliti određeni način kako da dvodimenzionalnu strukturu transformišemo u jednodimenzionalnu i kasnije tu jednodimenzionalnu opet u dvodimenzionalnu. U Fortranu, na primer, to je bilo rešeno tako što se matrica razdvajala na kolone i onda su one upisivane sekvencijalno jedna iza druge u memoriju.

94

Page 101: Programski Jezici i Strukture Podataka

S T R U K T U R E P O D A T A K A

a b c d

e f g h a b c d e f g h i j k l

i j k l

Primer logičke i fizičke strukture matrice

Klasifikacija struktura podataka prema mestu memorisanja

Prema mestu memorisanja strukture podataka delimo na operativne i masovne.

Operativne su one koje se čuvaju u operativnoj memoriji računara (npr. RAM), a masovne se čuvaju u masovnoj memoriji (npr. tvrdi disk).

Razlike između ove dve kategorije su i kvalitativne i kvantitativne. Operativne strukture su manjeg kapaciteta, ali im se brže pristupa. Obrnuto je kod masovnih. Takođe, masovne su permanentne, dok je život operativnih samo dok traje program.

Klasifikacija struktura podataka prema tipu relacije

Ova klasifikacija je karakteristična samo za strukure podataka tipa (S, r), tj. za one čiji je skup snabdeven samo jednom binarnom relacijom. Ovakvih struktura ima mnogo i za sve se može konstruisati odgovarajući digraf.

Postoje tri vrste struktura i to su:

1. linearne strukture – imaju digraf koji zadovoljava dva uslova: svi čvorovi osim tačno jednog imaju ulazni stepen jedan i svi osim tačno jednog imaju izlazni stepen jedan. Drugačije rečeno, svaki element osim jednog ima tačno jednog prethodnika i svaki element osim jednog ima tačno jednog sledbenika. Ovaj odnos prethodnik-sledbenik je fundamentalan za linearne strukture podataka.

Posebna varijanta linearnih struktura su tzv. cirkularne strukture, gde svi čvorovi imaju ulazni stepen jedan i izlazni stepen jedan.

2. strukture tipa stabla – njihov digraf se zove stablo. U stablu postoji tačno jedan čvor s ulaznim stepenom nula. U sve ostale čvorove ulazi tačno jedna grana. Takođe, ovaj digraf je slabo povezan, što znači da su svaka dva čvora povezana nekim putem bez obzira na orjentaciju grana. Bitna

95

Page 102: Programski Jezici i Strukture Podataka

S T R U K T U R E P O D A T A K A

karakteristika je da svaki element strukture osim jednog ima tačno jednog prethodnika, a svaki ima jednog ili više sledbenika. Dakle, prethodnik jeste funkcija, dok sledbenik nije.

3. mrežne strukture podataka – svaki element ima proizvoljan broj prethodnika i sledbenika. Bitno je samo da su svi čvorovi slabo povezani.

Klasifikacija operativnih strukturaPojedine strukture podataka ne omogućavaju neke ili sve osnovne operacije (uklanjanje, dodavanje, pristup). Prema ovim ograničenjima strukture podataka mogu biti:

statičke– ne postoji uklanjanje i dodavanje;

poludinamičke– definisane su sve osnovne operacije, uz specifičan pristup; i

dinamičke– definisane su sve osnovne operacije, ali na račun brzine i fleksibilnosti.

96

Page 103: Programski Jezici i Strukture Podataka

S T R U K T U R E P O D A T A K A

Statičke strukture podataka

Kod ovih struktura nije moguće uklanjanje i dodavanje elemenata, ali je pristup veoma fleksibilan i obavlja se velikom brzinom.

Osnovni pristup je pristup po poziciji. Kod statičkih struktura je ovaj tip pristupa unapred određen. Ovaj tip struktura se karakteriše pozicijom kao osnovnim identifikacionim svojstvom, a svaka pozicija određena je oznakom pozicije kojih može biti više različitih. Oznake pozicije mogu da budu u uređenom ili neuređenom skupu.

Postoje dve osnovne vrste statičkih struktura podataka i to su:

indeksne strukture (nizovi), koje imaju uređene oznake pozicija;

slogovi, koji nemaju uređene oznake pozicija i

tabele koje su nizovi slogova.

NizoviNizovi spadaju u najznačajnije i najstarije strukture podataka. Zovu se i višedimenzionalne strukture. Kod Pascala, nizovi se odnose na vektore, na matrice i na višedimenzionalne nizove, što nije bio slučaj i sa starijim programskim jezicima.

Nizovi su jedinstvene linearne strukture. Označavamo ih kao uređenu dvojku A = (S(A), r(A)), gde je S(A) skup, a r(A) relacija definisana nad tim skupom.

97

Page 104: Programski Jezici i Strukture Podataka

S T R U K T U R E P O D A T A K A

Pristup je dozvoljen svakom elementu niza, a uklanjanje i dodavanje nisu definisani. Pristup elementima statičkog niza je fleksibilan i brz, jer je pozicija elementa unapred poznata. Moguće su sve tri vrste pristupa (prema poziciji, prema informacionom sadržaju i navigacijom). Pristup prema poziciji je najznačajniji i ostvaruje se prema indeksu pozicije.

Kod nizova postoji podgrupa koja se naziva multiindeksna

struktura i nju definišemo rekurzivno na sledeći način.

Vektor je multiindeksna struktura reda jedan. Multiindeksna struktura reda k je niz Nk = (S(Nk), r(Nk)) u kojem su elementi skupa S(Nk) multiindeksne strukture reda k-1.

Fizička realizacija

Neposredna fizička realizacija jedne strukture podataka može biti:

sekvencijalna i

spregnuta.

Kod sekvencijalne realizacije neke strukture, zauzima se kompaktan memorijski prostor u koji se smeštaju elementi strukture. Spregnuta realizacija neke strukture podataka se izvodi tako što se sprega između elementa te strukture i mesta njihovog smeštanja u memoriji ostvaruje pokazivačima. Dakle elementi jedne strukture se mogu smestiti na različitim lokacijama u memoriji.

Jasno je da je kod sekvencijalne realizacije neke strukture maksimalni broj elemenata te strukture ograničen, dok kod spregnute ista struktura teoretski može imati neograničen broj elemenata. (U stvarnosti nas ograničava samo količina raspoložive memorije.) Sa druge strane, osnovne operacije se obavljaju mnogo brže na strukturama koje su realizovane sekvencijalno, nego na onim realizovanim spregnuto.

Svaka struktura podataka je snabdevena jednom dopunskom strukturom koja sadrži podatke o toj

Nizovi mogu biti statički i dinamički. Ovde ćemo se baviti statičkim nizovima.

Niz čiji su elementi skalari jeste vektor, a niz vektora je matrica.

Deskriptor je obavezan!

98

Page 105: Programski Jezici i Strukture Podataka

S T R U K T U R E P O D A T A K A

osnovnoj strukturi i naziva se deskriptor. Deskriptore najčešće kreira kompajler, a ako oni ne postoje u programskom jeziku, kreira ih sâm programer.

Niz se u programskim jezicima realizuje sekvencijalno. Deskriptor niza može da sadrži ime tog niza (X), vrstu podataka (V) i oznaku tipa (char). A mora da sadrži adresu početka niza (adr(X[-5])), opseg indeksâ (-5 do 4) i veličinu jednog elementa u osnovnoj adresnoj jedinici (na današnjim računarima to je bajt - u primeru 1 bajt).

X: array[-5..4] of char;

x[-5] x[-4] ... x[3] x[4]Realizacija niza u memoriji

V Xadr(X[-5])-5 4

char 1Deskriptor niza

Ako pretpostavimo da je p najmanja i k najveća vrednost indeksa i da su p i k celi brojevi, onda pristup u opštem slučaju adresa elementa kojem pristupamo se određuje tako što se sabere adresa početka niza sa proizvodom rastojanja tekućeg elementa od početka niza i veličine jednog elementa. Dakle: adr(B[i]) = adr(B[p]) + adr(i-p) * l(T). Vidi se da u ovom postupku dimenzije niza ne igraju ulogu, pa se samim tim opseg nigde ne prenosi u potprogram.

Kad su u pitanju multiindeksne strukture, pristup se može ubrzati ako je adresa unapred poznata. Na primer, BASIC i Fortran koriste metod linearizacije koji se svodi na „sečenje“ matrice na vrste ili kolone. Ovaj metod predviđa da se primeni jedna formula koja nam odmah daje adresu elementa. Npr. ako je M niz definisan na sledeći način:

M: array[p1..k1, p2..k2, ..., pn..kn] of T;

onda bi se adresa niza računala na sledeći način:

Prvi način za izračunavanje Dm je ako sečemo matricu na vrste: Dm = (km + 1 - pm + 1 + 1) Dm + 1, Dn = n, m = n - 1, n - 2, ..., 1 i ovo je rekurzija unazad. Drugi način je ako matricu sečemo na kolone i tada je Dm =

99

Page 106: Programski Jezici i Strukture Podataka

S T R U K T U R E P O D A T A K A

(km - 1 - pm - 1 + 1) Dm - 1, D1 = 1, m = 2, 3, ..., n i ovo je rekurzija unapred.

Iliffeovi vektori

Illifeovi vektori se primenjuju ako želimo veliku brzinu obrade, a pri tom to što ova struktura traži nešto više memorije nije problem. Ovu strukturu mora programer sâm da realizuje, jer nije sastavni deo ni jednog programskog jezika. Na primer:

X: array[2..3, -1..1, -2..-1] of T;

Illifeovi vektori se retko programiraju na Pascalu, već na nekom drugom programskom jeziku tipa Assemblera. To se radi, na primer, na C-u koji ima brzinu približnu brzini Assemblera. C nudi i tu prednost što se za donji indeks niza podrazumeva 0, a ne 1 kao kod Pascala.

Kao i nizovi, Iliffeovi vektori najčešće imaju dve dimenzije, a retko kad više od tri. Jedina razlika u odnosu na strukturu niza je u tome što Iliffeovi vektori ne sadrže adrese, već samo vrednosti elemenata.

Za svaki nivo indeksâ se odvaja jedan Iliffeov vektor koji se svaki stvara na bazi raspona indeksâ. Ako nivo indeksâ ne obuhvata nulu, stvaraju se pseudoelementi u kojima ne postoji ništa. Za svaki sledeći nivo indeksa formiramo skup Iliffeovih vektora. Za poslednji nivo, ovaj se skup opet dopunjava do nule.

Shema Illifeovog vektora

a1

2-1-2

2-1-1

20-2

20-1

21-2

21-1

3-1-2

3-1-1

30-2

30-1

31-2

31-1

0123

-101

-101

deskriptor

a2 = a1 + 3l(T)

a3 = a2 + 1l(T)

x[3, 1, -2]

x[2, -1, -2]

100

Page 107: Programski Jezici i Strukture Podataka

S T R U K T U R E P O D A T A K A

SlogoviFormalno gledano, slogovi podsećaju na nizove. Svaki skalar možemo shvatiti kao trivijalni slog sa jednim elementom.

Ovo je još jedna statička struktura koja se ne može proširivati, a ne mogu se ni uklanjati neki elementi. S druge strane, pristup je omogućen svakom elementu.

Semantička konvergencija se odnosi na interpretaciju informacionog sadržaja sloga. Element sloga sâm za sebe nema semantiku, tj. postoji takva međuzavisnost elemenata sloga da oni samo zajedno imaju značenje. Zbog te međuzavisnosti, elemente sloga drugačije zovemo polja.

Pitanje relacije se postavlja u vezi sa definisanjem odgovarajuće relacije među elementima sloga kako bi on oslikavao realni model. Na primer, ako relaciju definišemo kao binarnu, a uzmemo da slog opisuje tačku u Dekartovom koordinatnom sistemu dolazi do neslaganja sa modelom. Ime tačke je u relaciji sa apscisom, ali ne i sa ordinatom (ili obrnuto). Zbog toga se relacija drugačije uređuje.

Slog R je uređeni par (S(R), r(R)), gde je S(R) skup poljâ, a r(R) relacija koja se sastoji od jedne uređene n-torke u koju ulaze svi elemenit iz S(R). r(R) = {(x1, ..., xn), n = |S(R)| i (xi, xj S(R)) i j xi xj.

Za slogove važi da se vrlo retko pojavljuju izolovani. Najčešće su elementi neke druge složenije strukture podataka. Jedan od specijalnih slučajeva je deskriptor.

U programskim jezicima, tip sloga karakteriše da su njegova polja u opštem slučaju nejednakog tipa. Pristup poljima je definisan kao pristup po poziciji, dok navigacije i pristupa po sadržaju nema. Pristup po poziciji se obavlja putem oznake pozicije i bitno je da u

Dve bitne osobine slogova su semantička konvergencija i pitanje relacije.

'A' x y

101

Page 108: Programski Jezici i Strukture Podataka

S T R U K T U R E P O D A T A K A

skupu pozicija ne postoji uređenje, tj. ne zna se da li postoji i šta je sledbenik, odnosno prethodnik. Pristup po poziciji ostvarujemo bijektivnim preslikavanjem naziva polja nekog sloga na poziciju.

Fizička realizacija

Teorijski, fizička realizacija sloga je dvojaka: i sekvencijalna i spregnuta. U praksi je ovo retko, jer je osnovna (koja je i gotovo uvek zastupljena) sekvencijalna

realizacija. Može se pojaviti i kombinacija ove dve.

U programskim jezicima opšte namene slog je isključivo sekvencijalno realizovan, a ukoliko se nađe potreba za spregnutom realizacijom, ostavljeno je prostora da je program sâm kreira. Dakle, jedina fizička realizacija podržana direktno od strane programskog jezika jeste sekvencijalna. Tipičan primer izolovanog sloga, a dakle i spregnuto realizovanog, jeste deskriptor.

Za sekvencijalnu realizaciju vezuje se problem različitih vrsta polja u jednom slogu, pa na primer polja mogu da imaju različite dužine. Dakle svako polje se opisuje na različit način i stoga se svako opisuje posebno. Zbog ovoga je deskriptor sloga znatno složeniji od deskriptora bilo koje druge strukture podataka. Programski jezici po pravilu direktno podržavaju strukturu sloga, tako da programer najčešće ne dolazi u dodir sa deskriptorom.

A0 A0 + 30 A0 + 40 A0 + 42 A0 + 44

prezime ime indeks

god_upisa god_studija

Kompaktan memorijski prostor odvojen za skladištenje sloga

Tipičan deskriptor sadrži podatke na nivou celog sloga. Na primer, može da sadrži indikator tipa (koji pokazuje da se radi o slogu), naziv sloga, adresu početka memorijskog prostora rezervisanog za skladištenje sloga, može da sadrži ukupnu dužinu sloga, ali mora da sadrži broj polja u slogu.

Informacije o svakom polju se memorišu posebno i to: indikator tipa, dužina u osnovnim adresabilnim jedinicama, naziv i adresa polja. Adresa se može dati relativno (u odnosu na početak memorijskog prostora odvojenog Primer deskriptora sloga sa

deskriptorom polja

R STUDENT 5 A0

S 30 prezime 0S 10 ime 30I 2 indeks 40I 2 god_upisa 42I 2 god_studija 44

102

Page 109: Programski Jezici i Strukture Podataka

S T R U K T U R E P O D A T A K A

za slog) ili apsolutno. Ako je tip nekog od polja slog onda se ceo deskriptor tog sloga smešta u opis datog polja. Ovo važi za svako polje.

Kod spregnute realizacije, u opisu poljâ ne stoje adrese tih polja u memoriji, već pokazivači na dinamičku memoriju.

Kad se u programu traži pristup polju, prevodilac za dato ime polja pregleda deskriptor, traži opis odgovarajućeg polja, i tu pročita njegovu adresu. Ako je ona data apsolutno vraća njenu vrednost ili računa početnu adresu polja, ako je adresa data relativno.

Primena sloga je kranje široka i teško je izdvojiti neku za koju se može reći da preovladava. Karakteristično je da se svaka baza podataka sastoji upravo od slogova.

TabeleStruktura tabele predstavlja niz čiji su elementi slogovi. Ova struktura ima posebne primene, jer objedinjuje slogove.

Zavisno od tipa niza, tabela može biti statička ili dinamička.

Tipične obrade su sortiranje i traženje na osnovu zadatog ključa (dakle pristup je po informacionom sadržaju). Traženje može biti od prvog na dalje ili neka specifična vrsta traženja.

103

Page 110: Programski Jezici i Strukture Podataka

S T R U K T U R E P O D A T A K A

Poludinamičke strukture podataka

Za ove strukture podataka uz određena ograničenja definisane su sve tri osnovne operacije. Ova ograničenja nisu iznuđena, već su posledica posebnih namena ovih struktura podataka. Dinamičke strukture podataka promenljive su u vremenu.

Uvešćemo jednu primitivnu funkciju koja će nam pokazivati je li neka struktura prazna i nazvaćemo je Empty(F), gde je F neka poludinamička struktura podataka. Drugačije rečeno, ova funkcija nam pokazuje da li data struktura F ima elemenata. Treba napomenuti da je stanje prazne strukture specijalno stanje.

U poludinamičke strukture podataka spadaju stek, red, dek

i sekvenca. Zajednička osobina im je da su linearne i da je pomenuta funkcija Empty(F) definisana za svaku od njih.

Stek (stack)Ovo je najvažnija od poludinamičkih struktura s obzirom na svoju ulogu, ima je svaki program (makar i implicitno). Teorijski, ova struktura je najjednostavnija od svih.

Stek je uređeni par L = (S(L), r(L)), gde je r(L) binarna relacija definisana nad skupom S(L).

S(L) = {x1, x2, ..., xn} i

U prevodu, stack znači „naređana gomila“.

104

Page 111: Programski Jezici i Strukture Podataka

S T R U K T U R E P O D A T A K A

Element koji je bez prethodnika (u

smislu relacije - prvi) se zove vrh steka. Element koji je bez sledbenika (u smislu relacije - poslednji) se zove apsolutno dno steka. Vrh steka je od najvećeg interesa.

Pored spomenute primitivne funkcije Empty(L), za stek je definisana i funkcija Prvi(L), koja očitava prvi element strukture.

Sve tri osnovne operacije se vrše isključivo na vrhu: pristupa se implicitno vrhu, vrh se uklanja, a novi element se dodaje „ispred“ vrha steka. Tj. pristup je omogućen samo poslednje upisanom elementu, a takođe se uklanja poslednji upisan elemenat. Odavde je stek dobio drugačiji naziv LIFO red (Last In First Out).

Pristup se izvršava operacijom Top, koja ne mora biti izvršena kad se pozove. Da li će se Top izvršiti ili ne, zaviis od toga da li je stek prazan. Uklanjanje se vrši operacijom Pop, a dodavanje operacijom Push. U praksi su Top i Pop najčešće kombinovani, pa se kaže da je očitavanje destruktivno.

Od složenih operacija tu je operacija pražnjenja steka (uklanjanje svih elemenata dok Empty ne pokaže true). Ova operacije je više teorijske prirode, jer je osnovna osobina steka velika brzina, a ovom operacijom usporavamo obradu.

Fizička realizacija

Fizička realizacija steka obavlja se na oba standardna načina: i sekvencijalno i spregnuto. Osnovni način realizacije je sekvencijalni, jer je brži što se i najviše očekuje od steka. Ovaj način uvodi ograničenje maksimalnog broja elemenata na steku. Podrazumeva se deskriptor koji se ne vidi. Važno je napomenuti da programski jezici nemaju ugrađen stek kao tip podatka, ali ga svi programi imaju implicitno.

Amin vrh

Ama

x

Realizacija steka u memoriji

L STAmax Amin

vrhopis

elemenataDeskriptor steka

Xn Xn-1 X1...

105

Page 112: Programski Jezici i Strukture Podataka

S1

S2

S3

S1

S2

S3

stek

S T R U K T U R E P O D A T A K A

Stek se proteže od minimalne adrese do aktuelnog vrha. Vidimo da funkcija Prvi(L) u stvari očitava adresu vrha iz deksriptora steka.

Procedura Top se izvršava na sledećin način: prvo se proverava je li stek prazan (tj. da li je vrh < Amin). Ako nije, putem primitivne funkcije Prvi(L) se pristupi elementu na vrhu i on se očita. Uklanjanje se slično izvršava: isto se proveri je li stek prazan, pa ako nije vrh se umanji za vrednost veličine jednog elementa steka. Dodavanje se izvršava tako što se vrh pomeri na sledeće mesto i upiše novi sadržaj.

Kod sekvencijalne realizacije postoji i ograničenje kada je vrh = Amax i tada dodavanje više ne može da se izvrši, dok se ne ukloni neki element. Kao posledica ovoga uvodi se operacija Full(F) koja proverava je li stek prepunjen.

Ukoliko se pokuša upis u prepunjen stek dolazi to tzv. overflow stanja. U terminologiji je poznato i tzv. underflow

stanje koje nastaje kad se očitava ili uklanja element iz praznog steka. Ove dva stanja nisu dualana, jer je underflow posledica logičkih karakteristika steka, a overflow isključivo njegove sekvencijalne realizacije.

Nestandardna realizacija steka jeste spregnuta fizička realizacija koja postoji samo ako je bezuslovno neophodno da se izbegne oveflow stanje. Deskriptor tad mora da sadrži adresu vrha, a elementi su pokazivačima spregnuti po adresi. Ovakva realizacja steka se zove i fizička lista.

Ako stek realizujemo sekvencijalno, sve tri osnovne operacije su sporije. Kao što je rečeno, od steka se najpre očekuje brzina, pa se onda on gotovo uvek realizuje sekvencijalno. A da bi se makar donekle izbegao problem prepunjenosti steka, za smeštaj elemenata ove strukture odvaja se prilično velik memorijski prostor.

Primena

Stek se primenjuje gde god se pojavljuje neka vrsta rekurzije. Na primer kod prevođenja izraza na mašinski jezik, izrazi se

106

Page 113: Programski Jezici i Strukture Podataka

S T R U K T U R E P O D A T A K A

prvo prevode iz infiksne (a+b) u postfiksnu (ab+) ili prefiksnu (+ab) notaciju (najčešće u postfiksnu, jer je taj zapis izraza najsličiniji onom na mašinskom jeziku). Kod poslednje dve za naznačavanje redosleda izvršavanja operacija nisu potrebne zagrade. Standardni algoritam za prevođenje izraza iz jedne u drugu notaciju ne može da funkcioniše bez steka.

Prilikom rekurzije, potprogramu se mora proslediti tzv. adresa povratka (na koju se upisuje rezultat tog potprograma). Bez obzira koliko se duboko zalazi u rekurziju, da bi se vratili na prethodni nivo uvek se koristi poslednja upisana adresa koja se potom ukloni. Zbog toga se koristi stek.

Dakle, druga veoma važna primena steka jeste razmena

podataka među programima i potprogramima. Skup podataka koji sadrži stvarne parametre i adresa povratka se smeštaju na stek, odakle ih čita potprogram. On rezultate obrade upisuje na stek, a povratni parametar na datu adresu.

Pascalski i fortranski način razmene podataka između programa i potprograma

Ranije se postupak razmene podataka odvijao u zaglavlju potprograma. Standardni fortranski način razmene parametara jeste da se adresa na kojoj se nastavlja izvršavanje glavnog programa posle završetka potprograma upiše na nultu relativnu adresu memorijskog prostora predviđenog za potprogram. Iza tog podatka bi se nalazili stvarni parametri, a tek potom instrukcije potprograma.

Ovaj način razmene parametara bio je nefleksibilan i narušavao je princip da program i potprogram budu relativno nezavisne celine. Takođe, rekurzija nije bila moguća, jer se nije moglo upisati više povratnih adresa.

AA'

A'param.

P

program

stek

potprogramAA'

program

A'param.

kôd

potprogram

107

Page 114: Programski Jezici i Strukture Podataka

S T R U K T U R E P O D A T A K A

Sada svi programski jezici predviđaju isključivo stek za prenos parametara i zbog toga je stek jedna od najvažnijih struktura podataka.

Red (queue)Red se drugačije zove red čekanja ili FIFO red (First In First Out). Ovo je takođe jedna od vrlo važnih struktura podataka . Formalno, red veoma liči na stek, ali je područje primene reda sasvim drugačije.

Red je uređeni par F = (S(F), r(F)) gde je S(F) skup, a r(F) binarna linearna relacija definisana nad tim skupom.

S(F) = {x1, x2, ..., xn},

108

Page 115: Programski Jezici i Strukture Podataka

S T R U K T U R E P O D A T A K A

Iz definicije reda vidimo da ima isti digraf kao i stek.

Digraf reda

Osobine reda su da je relacija r linearna, pristup je dozvoljen samo prvom elementu, uklanja se takođe prvi element, a razlika u odnosu na stek je da se dodavanje uvek izvršava iza poslednjeg elementa.

Za red su definisane dve primitivne funkcije: Prvi(F) (vidi stranu 105) i Poslednji(F) koja vraća adresu poslednjeg elementa reda. Ova adresa se čuva u deskriptoru. Funkcija Prvi(F) potrebna je zbog pristupa i uklanjanja, a Poslednji(F) zbog dodavanja elemenata.

Primitivna funkcija za pristup prvom elementu reda jeste Front(F), za uklanjanje se koristi Pop, za dodavanje Push. (Ovo su uobičajeni nazivi funkcija). Ako uvedemo operaciju Rear(F) za pristup poslednjem elementu reda, red gubi definicione osobine, ali se i ova struktura svrstava u redove i nema posebno ime.

Od izvedenih funkcija bitna je Empty(F), a od izvedenih operacija to su operacija pražnjenja reda i određivanje tzv. „dužine“ reda (broj elemenata u redu).

Fizička realizacija

Postoje dva načina fizičke realizacije reda: sekvencijalna i spregnuta. Od reda se, kao i od steka, očekuje brzina, pa je osnovni način sekvencijalna fizička realizacija. Kao i kod steka, ovakvom realizacijom se izdvaja kompaktan memorijski prostor koji će služiti za smeštanje elemenata reda.

Amin poslednji prvi

Ama

x

Realizacija reda u memoriji

RD FAmax Amin

prviposlednji

opis elemenata

Deskriptor reda

Red se nalazi između adrese prvog i poslednjeg elementa. Uklanjanje elemenata se obavlja ne jednom kraju, a dodavanje na drugom. Tako da su oba kraja reda pokretna i nastaje problem lažne prepunjenosti reda.

Xn Xn-1 X1...

109

Page 116: Programski Jezici i Strukture Podataka

S T R U K T U R E P O D A T A K A

x

Uzećemo za primer red sa prethodne slike koji sadrži jedan element x. Posle izvršavanja operacije umetanja Push(F,a) red sadrži dva elementa, i novi element a se nalazi „levo“ od elementa x. Izvršićemo Pop(F) čime smo uklonili element x. Izvršićemo Push(F,b), pa Pop(F) i ako bismo sad hteli da izvršimo Push(F,c) pošto se nalazimo na poslednjoj raspoloživoj adresi element c ne može da se upiše u red. Ispada da je red popunjen, a očigledno da sadrži samo jedan element.

b

Zbog toga pribegavamo rešenju da novi element upišemo na početak reda. Ovo je tzv. cirkularna realizacija

reda. Na ovaj način smo rešili problem lažne prepunjenosti, ali se pojavio novi problem.

Za njegovo ilustrovanje, definisaćemo funkciju Prethodni(x,F) na sledeći način:

Počnimo da sukcesivno uklanjamo elemente iz reda sve dok ne bude Prvi(F) = Poslednji(F). Sada red sadrži jedan element i ako još jednom izvršimo Pop(F) red će postati prazan. Sada je Prethodni(Poslednji(F), F) = Prvi(F).

Ukoliko uradimo suprotno, tj. u red upisujemo nove elemente jedan za drugim dok ga ne popunimo, opet ćemo dobiti da je Prethodni(Poslednji(F), F) = Prvi(F), ali u ovom slučaju to znači da je red pun.

Dakle sada postoji nemogućnost razlikovanja potpuno praznog od potpuno punog reda. Postoji nekoliko načina da se reši ovaj problem.

1. U deskriptoru ćemo u svakom momentu memorisati aktuelni broj elemenata. Ovaj način usporava operacije, jer je posle svakog upisa ili brisanja elementa potrebno pristupiti deskriptoru i ažurirati broj elemenata. Doduše ova operacija nam omogućava da nam je u svakom momentu na raspolaganju informacija o aktuelnoj dužini reda.

110

Page 117: Programski Jezici i Strukture Podataka

S T R U K T U R E P O D A T A K A

2. U deskriptor se smešta statusno polje S koje može da ima dve vrednosti: 0 i 1. Ako je S = 0 red je prazan, u suprotnom red nije prazan. Tako da statusno polje i funkcija Prethodni(x,F) zajedno daju informaciju o tome je li red prazan ili ne. Ovaj način takođe usporava obradu reda, jer se polje S mora ažurirati posle svakog upisa i/ili brisanja.

3. Ovaj način predviđa da se upis onemogući na jednu memorijsku lokaciju koja se uvek nalazi iza lokacije Poslednji(F). Ako se ta lokacija zove Prazna, onda je Prethodni(Poslednji(F), F) = Prazna.

Ukoliko sada želimo da ispraznimo niz, elemente brišemo dokle god se Prethodni(Poslednji(F), F) ne poklopi sa lokacijom Prvi(F). U red možemo dodavati elemente sve dok Prethodni(Prazna, F) nije Prvi(F), tj. Prethodni(Prethodni(Poslednji(F), F), F) nijr prvi. Ovo znači da je red pun.

Kod spregnute realizacije ne postoji problem prepunjenosti reda. Red se spregnuto realizuje u deskriptoru i elementi reda su slobodno distribuirani po memoriji. Međusobno su povezani pokazivačima.

Primena

Primena redova je vrlo široka. Prilikom prenosa poruka na daljinu veoma je bitno da one stižu istim redom kojim su poslate. Na računaru redovi postoje kod ulaznih uređaja (npr. bafer tastature i miša). Drugi primer reda kod računara je red čekanja za štampač.

Dek (deque)Dek je red sa dva kraja. Odatle i engleski naziv (Double Ended QUEue). Ova struktura ima više teorijsku primenu.

Dek objedinjava osobine steka, reda i svih sličnih struktura podataka. Karakteriše se linearnom strukturom s tim da su sve tri osnovne operacije definisane na oba kraja. Dakle, krajevi su ravnopravni. Označavamo ih kao levi i desni kraj.

Dek se može realizovati i spregnuto i sekvencijalno. Ako ga realizujemo sekvencijalno, nastaju svi problemi kao i

111

Page 118: Programski Jezici i Strukture Podataka

S T R U K T U R E P O D A T A K A

kod sekvencijalno realizovanih redova. Dok red cirkuliše u jednom, dek cirkuliše u oba smisla.

Dek se češće realizuje spregnuto, jer prilikom fizičke realizacije dolazi do toga da krajevi nisu ravnopravni, jer se kretanje vrši u jednom smeru. Za spregnutu realizaciju je vezan problem uklanjanja krajnjeg elementa. Dok je levi lako ukloniti, moramo proći kroz celu strukturu da bismo došli do desnog elementa.

Logička struktura deka je strogo simetrična, dok fizička nije. Kretanje se vrši pomoću dva pokazivača, a u sprezi su po dva susedna elementa.

SekvencaSekvenca je linijska struktura kod koje je pristup dozvoljen svakom elementu, a uklanjaju se samo svi elementi odjednom. Postoji i varijanta uklanjanja gde se uklanjaju svi elementi počev od zadate pozicije. Dodavanje novih elemenata se uvek vrši iza poslednjeg elementa.

Sekvenca je uređeni par D = (S(d), r(D)), gde je S skup, a r binarna relacija.

Za sekvencu su definisane sve tri vrste pristupa, ali se najviše koristi navigacija. Za sekvencu je karakteristično da uvek ima definisan tekući element. Pristupa se tekućeme elementu, pa sledećem iza njega itd.

Definisana je i jedna primitivna operacija koju ćemo nazvati Prvi(D). Ova operacija kao tekući označava prvi element iz strukture. Pristup se odvija tako što se proveri je li markiran tekući element i potom se njemu pristupa. Zatim se pomera marker na sledeći element, pa se njemu pristupi i tako dalje. Stoga je operacija Prvi(D) izolovana (izvršava se samo jednom na početku pristupa elementima strukture).

Sekvencu karakteriše i njeno stanje koje je određeno ne samo rasporedom elemenata već i vrednošću tekućeg elementa.

112

Page 119: Programski Jezici i Strukture Podataka

S T R U K T U R E P O D A T A K A

Posle dodavanja elementa, po pravilu taj novododati se označava kao tekući. Pošto je pristup omogućen bilo kom elementu strukture (koji se onda označi kao tekući), može se i ukloniti bilo koji element strukture. Posle uklanjanja, kao tekući se može označiti prethodni ili sledeći iza tog elementa.

Za sekvencu je karakteristična redosledna obrada. Ako procedura PostaviPrvi(D) označava tekući element, posle njenog izvršavanja doveli smo sekvencu u početno stanje. Zatim se pristupa redom svakom elementu i svaki taj element se obradi na neki način (zapamtimo da i nemenjanje elementa spada u trivijalne obrade).

Postoji veći broj operacija za rad sa tekućim elementom. Na primer, postavljanje za tekući nekog n-tog elementa kada se počev od prvog redom pristupa elementima dok se ne dođe do tog n-tog elementa. Treba napomenuti da je ovim postupkom sekvenca promenila stanje iako su svi elementi zadržali svoj informacioni sadržaj. To je zbog toga što je promenjen tekući element.

Tipična sekvenca se ne nalazi u operativnoj, već u permanentnoj memoriji i to je datoteka.

Fizička realizacija

Imajući u vidu da je glavni predstavnik sekvence datoteka, ova se struktura realizuje sekvencijalno-spregnutom realizacijom, tj. mešavinom ove dve. Ovo je jedina strukutra koja se ovako organizuje.

Ovakav način realizacije podrazumeva da se elementi sekvence nalaze u blokovima koji mogu biti elementi i sami sebi. Ti blokovi su spregnuto realizovani, tj. ne moraju biti susedni u memoriji, već su međusobno povezani pokazivačima. Doduše, elementi unutar blokova su obavezno raspoređeni sekvencijalno.

Deskriptor sekvence sadrži adresu prvog, kao i adresu tekućeg elementa. Adresa tekućeg elementa sastoji se obavezno od oznake bloka u kom se nalazi taj tekući i oznake samog elementa unutar datog bloka.

113

Page 120: Programski Jezici i Strukture Podataka

S T R U K T U R E P O D A T A K A

Dinamičke strukture podataka

Glavna karakteristika ovih struktura je da osnovne operacije nemaju nikakvih ograničenja osim definicionih. Neke od ovih struktura su linearne, ali postoji čitava grupa dinamičkih struktura koje su nelinearne. Dinamičke strukture podataka su znatno fleksibilnije od statičkih i poludinamičkih.

Pristup je uvek omogućen svakom elementu. Kod nekih dinamičkih struktura pristup se vrši po poziciji, a kod nekih ne. Pristup po informacionom sadržaju je najizraženiji. Navigacija je takođe moguća.

Određene strukture iz ove grupe postavljaju određena ograničenja prilikom uklanjanja elemenata. Takva ograničenja postoje i kod dodavanja elemenata i usmerena su praktičnoj upotrebi te strukture. Jedino ograničenje koje sigurno postoji je da struktura po uklanjanju i/ili dodavanju elementa ne sme promeniti svoje definicione osobine. Uklanjanje se ograničava na račun brzine pristupa.

Postoje tri grupe dinamičkih struktura podataka. To su:

1. liste sa dinamičkim nizovima, najjednostavnije dinamičke strukture;

2. stabla, veoma važna klasa dinamičkih strukura podataka i

3. mreže (vidi stranu 96).

Liste i dinamički nizoviU okviru ove grupe, izdvajaju se četiri strukture:

1. jednostruko spregnuta lista;

2. dinamički niz;114

Page 121: Programski Jezici i Strukture Podataka

S T R U K T U R E P O D A T A K A

3. dvostruko spregnuta lista i

4. višestruko spregnuta lista.

Jednostruko spregnuta lista je najvažniji predstavnike ove grupe, a drugačije se zove i linearna lista ili lanac. Ova struktura je krajnje fleksibilna.

Jednostruko spregnuta lista je uređeni par P = (S(P), r(P)), gde je r(P) linearna relacija definisana na skupu S(P).

Ono što karakteriše ovu strukture je, prvo, da je pristup dozvoljen svakom elementu, zatim ukloniti se može bilo koji element, a dodati se isto može bilo gde. Jedino ograničenje postavlja činjenica da je ova struktura linearna.

Definisane su sve tri vrste pristupa. Pristup po poziciji je nešto sporiji, jer se ne može unapred izračunati adresa elementa. Dakle, za pristup nekom k-tom elementu mora se pristupiti redom svakom do tog k-tog. U ovome se ogleda razlika između statičkog niza i liste. Pristup prema informacionom sadržaju isto zahteva da se pođe od prvog elementa dok se ne nađe traženi. U svakom slučaju, listu možemo snabdeti mehanizmom za navigaciju i tad će u svakom trenutku postojati jedan tekući element.

Zbog ovoga listu možemo realizovati na više načina. Svakako, postoji primitivna funkcija Prvi(P). Ukoliko se očekuje da će biti mnogo dodavanja na kraju liste, snabdećemo je i primitivnom funkcijom Poslednji(P). Od liste se takođe može očekivati da bude sortirana. Tada su elementi uređeni u rastućem ili opadajućem redosledu po vrednosti ključa.

Zbog ovoga svega se jednostruka lista mora projektovati. Moramo imati u vidu za čega će se koristiti. Ako napravimo jednu listu za više namena, lista će sigurno biti sporija (npr. mehanizam za navigaciju će postojati samo ako nam je potreban).

Kao što je već rečeno, ukloniti se može svaki element, ali ovaj postupak nikako nije trivijalan. Na primer, mora se voditi računa o specijalnim slučajevima. Ako je lista

115

Page 122: Programski Jezici i Strukture Podataka

S T R U K T U R E P O D A T A K A

prazna, neće doći do uklanjanja. Ako se uklanja prvi ili poslednji element, uz njega se uklanja samo jedna veza.

Opšti slučaj uklanjanja je kad se ne uklanja ni prvi ni poslednji element i tada se posle uklanjanja elementa, mora ubaciti nova veza kako bi očuvali linearnost strukture. Takođe se moraju ažurirati veze za Prvi(P) i (ako postoji) za Poslednji(P).

Ako je definisana navigacija, prilikom uklanjanja, prvo se pronađe element koji treba ukloniti i označi se kao tekući. Posle obavljenog uklanjanja, tekući više ne postoji i mora se voditi računa koji će element biti novi tekući.

Svi ovi problemi su posledica velike fleksibilnosti liste.

Slični problemi nastaju i prilikom dodavanja elemenata. To može biti dodavanje u praznu listu (kad se ne ažurira ni jedna veza) ili dodavanje ispred prvog ili iza poslednjeg elementa. U opštem slučaju dodavanje se izvrši između dva elementa, raskine se stara veza i dodaju dve nove. Ako postoji mehanizam navigacije, treba voditi računa o tekućem elementu. Po pravilu, novododati element postaje tekući element.

Takođe, postavlja se pitanje pozicije novog elementa. U listama gde redosled elemenata nije bitan, uvek dodajemo ispred prvog da ne bismo prolazili kroz celu listu tražeći poslednji. Ukoliko je redosled bitan, možemo zadati poziciju novog elementa, ali se postavlja pitanje da li element koji se trenutno nalazi na toj poziciji treba pomeriti ispred ili iza novog elementa. (Ovaj problem se najčešće rešava pomoću dve procedure za dodavanje, gde jedna dodaje ispred, a druga iza datog elementa.)

Ako je lista sortirana, pozicija dodavanja je unapred poznata. Nađu se dva susedna elementa takva da je ključ jednog „manji“ od ključa novog, a ključ ovog manji od ključa drugog elementa. Novi element se ubaci između ta dva elementa. U sortiranu listu element se najčešće ovako dodaje, tj. lista ostaje sortirana u svakom trenutku. U nekim specijalnim situacijama element se dodaje bilo gde, pa se sortiranje vrši naknadno, što je sporije.

116

Page 123: Programski Jezici i Strukture Podataka

S T R U K T U R E P O D A T A K A

Logička struktura jednostruko spregnute liste liste

Fizička realizacija liste je isključivo spregnuta. Liste primenjujemo gde god je potrebna fleksibilna struktura. Mnogi redovi čekanja operativnog sistema imaju strukturu liste.

Dinamički nizovi su na prvi pogled veoma fleksibilne strukture. Imaju sve osobine statičkih nizova, ali su uklanjanje i dodavanje definisani za bilo koji element. Dakle, dinamički nizovi imaju sve osobine liste, s tim što je pristup po poziciji znatno brži, jer se (kao kod statičkih nizova) pozicija može lako izračunati unapred. Doduše, zbog operacija uklanjanja i dodavanja dinamički nizovi su znatno specifičnija struktura nego liste.

Ako želimo da pristup po poziciji bude definisan kao i kod statičkog niza, posle svakog uklanjanja i dodavanja moramo ažurirati pozicije elemenata. Zbog ovoga su operacije spore, pa dinamički nizovi nemaju praktične osobine liste. Takođe, fizička realizacija mora biti sekvencijalna, pa može doći do prepunjenosti.

Primena dinamičkih nizova nije široka, ali se oni vrlo često koriste. To zbog toga što tip podataka string ima osobine dinamičkog niza.

Dvostruko spregnute liste dosta podsećaju na jednostruko spregnute. Koriste se mnogo više. Ova strukutra nije linearna i omogućene su veze u oba smera. Ove liste se zovu i simetrične liste.

Dvostruko spregnuta lista je uređeni par: DP = (S(DP), r(DP)), gde r nije linearna relacija, r = r1  r2, r1  r2 =  i (a,b)  r 1 (b,a)  r2. Vidimo da su (S, r1) i (S, r2) jednostruko spregnute liste.

Logička struktura dovstruko spregnute liste

...

...

117

Page 124: Programski Jezici i Strukture Podataka

S T R U K T U R E P O D A T A K A

Fizička realizacija je isključivo spregnuta, pa se dakle svaki element proširuje sa dva pokazivača.

Treba voditi računa da dvostruka lista (tj. lista sa dve relacije) nije isto što i dvostruko spregnuta lista. Pošto se relacija uspostavlja na bazi nekog kriterijuma, kod ovih drugih, jedna relacija je taj kriterijum, a druga suprotan kriterijum. Kod dvostruke liste, jedan i drugi kriterijum ne moraju imati nikakve veze.

Višestruko spregnute liste karakteriše da postoji više različitih relacija među elementima. Ni jedna od ovih relacija ne mora da uključuje sve elemente.

Višestruko spregnuta lista je uređena n+1-orka VP = (S(VP), r1, r2, ..., rn) gde je svaki uređeni par (S, ri) jednostruko spregnuta lista i Si  S(VP).

Logička struktura višestruko spregnute liste

StablaStablo (zove se još i drvo) je izuzetno važna struktura podataka. Modelira više fundamentalnih odnosa iz realnog svega (hijerarhijski odnosi, odnos opšte-pojedinačno, postupak dekompozicije itd.).

Osnovna osobina stabla je da ono nije linearno. Stablo kao digraf zadovoljava sledeće osobine:

postoji tačno jedan čvor ulaznog stepena nula;

u svaki čvor osim jednog ulazi po jedna grana (svaki ima tačno jednog prethodnika) i

stablo je slabo povezano.

Element u stablu ulaznog stepena nula se zove koren

stabla. Čvorovi digrafa iz kojih ne izlazi ni jedna grana 118

Page 125: Programski Jezici i Strukture Podataka

S T R U K T U R E P O D A T A K A

se zovu listovi. Put u stablu je uređena n-torka (x1, x2, ..., xn), gde su xi čvorovi. Dužina puta jednaka je broju grana (n-1). Visina stabla odgovara broju čvorova na najdužem putu (n). Dakle, visina stabla je dužina najdužeg puta uvećana za jedan. U stablu postoji tačno jedan put od korena do bilo kog čvora, tj. koren je povezan sa svim čvorovima tačno jednim putem. Najduži put u stablu uvek počinje od korena i završava se u listu. Nivo čvora jeste udaljenje čvora od korena. Za stabla se ne koriste termini prethodnik i sledbenik, već nadređeni i podređeni. Red stabla odgovara najvećem proju podređenih u stablu. Podstablo čini čvor sa svim svojim podređenim čvorovima.

Za ovo stablo koren je element 1, a listovi su elementi 5, 6 i 7. Jedan od puteva čine elementi 1, 2 i 5, dužina ovog puta je 2 i ovo je jedan od najdužih puteva. Visina stabla je 3. Nivo korena je

0, nivo elemenata 2, 3 i 4 je 1, a nivo elemenata 5, 6 i 7 je 3. Red ovog stabla je 3.

Postoje dva specijalna stabla, to su: puno i kompletno stablo. Kompletno stablo reda n je takvo da svi čvorovi stabla (osim listova) imaju izlazni stepen n. Kod punog stabla su svi putevi od korena do nekog lista iste dužine. Ove dve osobine niti uključuju niti isključuju jedna drugu, tj. nisu ni u kakvoj korelaciji. Najbolje je da je stablo tako konstruisano da je što bliže punom i kompletnom stablu. Tada je operacija pristupa najbrža.

Stablo koje pokazuje dobre osobine (tj. približno je puno i kompletno) zove se balansirano stablo. Za bilo koja dva čvora istog nivoa balansiranog stabla važi da se broj elemenata u njihovim podstablima razlikuje najviše za jedan element. Postoje algoritmi za balansiranje stabla i oni zavise od konkretnog stabla. Primenom ovih algoritama ubrzavamo pristup elementima stabla.

Stablo kao struktura podataka

Stablo ne možemo odmah precizno definisati, jer se među stablima nalaze raznorodne strukture. Jedina zajednička osobina im je da imaju digraf tipa stabla. Dodavanja i uklanjanje su u načelu svuda dozvoljeni, ali ipak postoje ograničenja koja zavise od slučaja do slučaja. Npr. postoji ograničenje reda iznad kojeg se ne može ići.

1

5 6 7

432

119

Page 126: Programski Jezici i Strukture Podataka

S T R U K T U R E P O D A T A K A

Karakteristike stabla su:

1. digraf je tipa stabla;

2. dozvoljen je pristup svakom elementu i

3. dodavanje i uklanjanje su definisani u skladu sa specifičnim osobinama datog stabla.

Teorijski, pristup stablu je moguć na sva tri načina. Međutim, pristup po poziciji je specifičan i redak, jer stablo nije linearna struktura. Zbog toga se koristi pristup po informacionom sadržaju ili navigacija.

Najčešće se elementima stabla pristupa po informacionom sadržaju i ovaj se pristup obavlja po ključu. Počinje se od korena i na bazi argumenta traženja (ključa) i informacionog sadržaja elementa se odlučuje kojem se sledećem elementu pristupa. Suštinski problem koji se ovde javlja je taj da podređeni elementi istog nivoa čine skup koji nije uređen i ne možemo odrediti prvi, drugi itd. element. Dakle, ne može se formirati algoritam koji bi proverio da li se u tom skupu nalazi dati ključ.

Zbog toga u strukturi podataka mora postojati uređenje skupa podređenih nekog elementa. Ovo uređenje može biti eksplicitno i tada je definisano na nivou logičke strukture podataka i može biti implicitno kada se definiše na nivou fizičke realizacije. Na osnovu ove osobine stabala, vrši se njihova osnovna podela. Eksplicitno uređenje imaju tzv. n-arna stabla, a implicitno tzv. generalisana (uopštena) stabla. Jedina zajednička osobina za ove dve vrste je već pomenuti digraf tipa stabla.

N-arna stabla

N-arna stabla reda n su ona gde svaki element ima tačno nula ili n podređenih. U svakom trenutku, postoji n mesta rezervisanih za smeštanje podređenih elemenata nekog elementa, ali ta mesta ne moraju biti uvek popunjena (mogu biti nezauzeta). Zbog toga skup podređenih nivoa n ima osobine statičkog niza.

120

Page 127: Programski Jezici i Strukture Podataka

S T R U K T U R E P O D A T A K A

Prva dva stabla su binarana i razlikuju se po rasporedu elemenata, a treće je ternarno, ali pozicija c nije zauzeta

Iz ovih definicionih osobina sledi definicija n-arnog stabla.

N-arno stablo je uređena n+1-orka Tn = (S(Tn), r1, r2, ..., rn) sledećih karakteristika: (S(Tn), r1 r2 ... rn) ima osobine digrafa stabla i [(a,b)  ri (a,c)  ri] (b = c), i = 1, 2, ..., n.

Ova druga osobina n-arnih stabala govori da različiti podređeni ne mogu biti u istoj relaciji sa jednim nadređenim, tj. sve relacija n-arnog stabla su funkcije. Tako je samim zadavanjem relacije za svaki element oređen njegov podređeni.

Binarna stabla

Binarna stabla su posebna vrsta n-arnih, to su n-arna stabla reda dva. Za ova stabla postoji jedna vrlo karakteristična izvedena operacija. To je obilazak binarnog stabla.

Logička struktura jednog binarnog stabla

Obilazak binarnog stabla

Prilikom obilaska stabla pristupa se svakom njegovom elementu u cilju obrade. Postoji više načina da se to uradi.

Može se pristupati redom elementima na svakom nivou. Npr, za dato stablo redosled bi bio ABCDEFGHI. Ovakav način pristupa nije čest, jer je prilično komplikovan za izvođenje.

X

BA

X

B A

X

A CB

A

CB

FD E

IHG

121

Page 128: Programski Jezici i Strukture Podataka

S T R U K T U R E P O D A T A K A

Za obilazak, u principu, postoji šest algoritama od kojih su po dva dualna. Svaka od ovih metoda jeste rekurzivna i svaka se rekurzija bazira na tri stavke:

1. prisup datom elementu;

2. njegovom levom podstablu i

3. njegovom desnom podstablu.

Pošto je redosled stavki proizvoljan, dobijamo šest algoritama.

Obilazak s leva u desno se izvodi tako što se prvo pristupa levom podstablu (2), zatim elementu (1), pa desnom podstablu (3). Proces uvek počinje od korena. Dakle, pristupa se korenu, ali se ovaj element ne obrađuje, već se memoriše u neku strukturu L (za naše stablo, memoriše se A). Zatim se prelazi u levo podstablo i opet se izvršavaju koraci 2, 1 i 3. (Sada se memoriše B, a u sledećem koraku D). Kada smo stigli do elementa koji nema levo podstablo (G), obrađujemo ga. Zatim obrađujemo element koji je poslednji memorisan u strukturi L (to je D za naš primer). Obrađujemo desno podstablo tog elementa. (Posle ovog koraka potpuno je obrađeno podstablo D.) Nastavimo li ovim algoritmom, potpuno ćemo obraditi celo stablo. Dakle, redosled obrade je sledeći: GDHBAECIF.

Očigledno je da je pomenuta struktura L LIFO red, tj. stek. Njega možemo kreirati sami (sporiji način) ili se ono kreira implicitno, zbog rekurzija.

Obilazak s vrha ka dnu pretpostavlja da je redosled obrade: element, levo podstablo, desno podstablo. Za naš primer, elemente obrađujemo sledećim redosledom: ABDGHCEFI.

Obilazak sa dna ka vrhu se vrši na sledeći način: levo podstablo, desno podstablo, element. Na primeru, redosled je: GHDBEIFCA.

Fizička struktura

Pošto je logička struktura stabla data na bazi fizičke, fizička struktura stabla je određena definicijom.

N-arna stabla realizujemo isključivo spregnuto. Svi elementi imaju isti oblik i svaki od njih proširujemo sa

122

Page 129: Programski Jezici i Strukture Podataka

S T R U K T U R E P O D A T A K A

tačno n pokazivača. Deksriptor stabla, između ostalog, mora sadržati adresu korena.

Fizička struktura binarnog stabla sa prethodne slike

U specijalnom slučaju, stablo možemo realizovati sekvencijalno. Takvo stablo mora biti binarno i ne sme biti veliko. Inače se za realizacuju binarnog stabla koristi specijalna tehnika niti ili prošivki.

Tehnika niti

Pretpostavka je da imamo binarno stablo i da se očekuje intenzivan obilazak. Svrha upotrebe niti je da se eliminiše stek i još više ubrza obilazak. Postoje dve varijante ove tehnike, tj. prošivke mogu biti jednostruke ili dvostruke.

Kod jednostrukih niti bira se jedan od pokazivača pridruženih elementu (npr. desni). Ako taj pokazivač ima vrednost (pokazuje na neki podređeni element), ostavlja se kakav jeste. Ako je njegova vrednost nil (ne pokazuje „ni na šta“, na slici označeno *) onda se koristi za obilazak i u njega se upiše adresa sledećeg kojem treba pristupiti. Dakle, prilikom obilaska prate se pokazivači i prošivke.

Stablo sa pokazivačima i jednostrukim nitima

Da nam prošivke ne bi pravile probleme prilikom obrade (tada se mora znati koji je element nadređeni, a koji podređeni i to nam govore isključivo pokazivači),

A

B C

E F

I

D

HG

A

*B C

* *E *F

* *I

D

* *H* *G

123

Page 130: Programski Jezici i Strukture Podataka

S T R U K T U R E P O D A T A K A

svaki element proširujemo statusnom bajtom. On pokazuje da li je u pitanju pokazivač ili prošivka.

Kod tehnike dvostrukih niti koriste se oba pokazivača (ako su slobodni). Ovaj drugi se koristi za obilazak u obrnutom smeru, tj. pokazuje na prethodni. Dvostruke prošivke koristimo samo pod pretpostavkom da se koriste oba smera obilaska, tj. da algoritam obilazu strukturu stabla u oba smera.

Sekvencijalna fizička realizacija

Kao što je već rečeno, ovako se realizuju isključivo binarna stabla koja nisu velika i to u izuzetnim slučajevima.

Kao i za druge sekvencijalno realizovane strukture, odvaja se određen memorijski prostor sa relativnim adresama. Koren se smešta u relativnu adresu jedan. Za ostale elemente važi da ako je taj element na relativnoj adresi k, njegov levi podređeni se smešta na adresu 2k, a desni na 2k+1.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18

A B C D E F G H ISekvencijalna realizacija stabla iz primera

Prednost ovakve realizacije je u tome što se adresa elementa može izračunati unapred, pa je pristup direktan.

Ovakav način realizacije se koristi za statična stabla ili za ona koja se vrlo malo proširuju (zbog vrlo lakog prepunjavanja memorije).

Binarna stabla se retko realizuju samostalno, već kao pomoćna struktura nekih algoritama (npr. algoritma sortiranja).

124