UVOD U PROGRAMSKI JEZIK PASCAL

PROMJENLJIVE I ARITMETIKA
1. Promjenljive i pridruživanje
1.1. Promjenljive
Podaci koji se drže u glavnoj memoriji čuvaju se u promjenljivim (engl. variables) koje imaju imena: A Starost Slovo 5 21 A

Promjenljive moraju biti deklarirane prije nego što se upotrebe u programu, na primjer: Broj : integer; Ovo deklarira promjenljivu nazvanu "Broj" koja moze sadržavati cjelobrojnu (engl. integer) vrijednost. Imena promjenljivih moraju slijediti pravila za Pascal identifikatore (promjenljive su specijalan slučaj tzv. identifikatora), tj. ona moraju sadržavati samo alfanumeričke znakove (tj. slova i brojke), i moraju početi sa alfabetskim znakom (tj. slovom), pri čemu naša slova (Č, Ć itd.) nisu dozvoljena.

1.2. Primjer programa
program PonoviBroj(input, output); var Broj : integer; begin read(Broj); write(Broj) end. deklaracijski dio izjavni (izvršni) dio

Program počinje naredbom “program” iza koje slijedi ime programa, kao i riječi “input” ukoliko program čita ulazne podatke, odnosno “output”, ukoliko program saopštava izlazne podatke korisniku. One se obavezno pišu u zagradama, i predstavljaju parametre programa. Radi jasnoće, u svim primjerima će ključne riječi Pascal jezika biti pisane masnim slovima, ostali ugrađeni elementi Pascal-a običnim slovima, dok će se imena koja definira korisnik pisati nakošenim slovima. Deklaracije promjenljivih sadržane su u deklaracijskom dijelu programa, prije izjavnog odnosno izvršnog dijela (engl. statement part), i prethodi im rezervirana (ključna, službena) riječ "var". Izjavni dio uvijek započinje sa “begin”, a završava sa “end”. Na kraju programa nalazi se tačka.

Izjava odnosno naredba (engl. statement) "read" čeka na unos sa tastature, i smješta unesenu vrijednost u promjenljivu koja je zadana kao argument. Naredba “write” ispisuje vrijednost argumenta na izlazni uređaj (najčešće ekran). Naredbe se međusobno razdvajaju znakom “;”, pri čemu on nije neophodan ispred oznake kraja bloka “end”. Pri tome bitan stil pisanja programa ne utiče na njegovo izvršavanje, novi red ne označava kraj naredbe, nego isključivo tačkazarez. Tako, isti rezultat bi proizveo i program: program PonoviBroj(input, output); : integer; var Broj

begin read (Broj ); write(Broj ) end. Naravno, radi čitljivosti programa treba paziti na stil pisanja.

1.3. Pridruživanje
Promjenljivima se može dodijeliti vrijednost upotrebom naredbe pridruživanja (engl. assignment statement): Broj := 5; ":=" predstavlja operator dodjele (engl. assignment operator). Čita se kao "postaje", npr. "Broj postaje pet".

2. Tipovi
U Pascal-u, svaka promjenljiva ima tip. Deklaracija Broj : integer; označava da je promjenljiva "Broj" tipa cijeli broj (engl. integer). Tip promjenljive određuje: • • vrstu vrijednosti koja može biti dodijeljena promjenljivoj; vrste operacija koje se na nju mogu primjenjivati.

Za promjenljivu "Broj" iz gornjeg primjera to znači: • • mogu se dodjeljivati samo cijeli brojevi; mogu se primjenjivati aritmetičke operacije definirane za cijele brojeve.

3. Cjelobrojni izrazi
Izraz (engl. expression) je formula koja ima neku vrijednost. Cjelobrojni izrazi su sačinjeni od: a) cijelih brojeva, npr. 5 999 +999 -42

b) slijedećih aritmetičkih operatora: + * div mod sabiranje oduzimanje množenje cjelobrojno dijeljenje ostatak dijeljenja

c) ugrađenih (engl. built-in) funkcija, od kojih su neke: abs sqr apsolutna vrijednost kvadrat

Primjeri cjelobrojnih izraza: 2 + 2 33 * -6 48 div 5 7 mod 3 (5 + 2) * 7 + sqr(4) 5 + abs(-5) Cjelobrojni izrazi mogu sadržavati i cjelobrojne promjenjive, kao u slijedećem demonstracionom programu: program Aritmetika(input, output); var a, b, c : integer; begin a := 5; b := 3; c := a * 2; b := (c + 3) div a; a := a + 5; writeln(a); writeln(b); writeln(c) end. Naredba “writeln” je slična naredbi “write”, samo što se nakon nje ispis nastavlja u novom redu, što nije slučaj sa naredbom “write”. Naredba “writeln” bez argumenata samo ispisuje jedan prazan red.

begin read(Prihod.LicnaNaknada – NaknadaZaDjecu * BrojDjece. Podrazumijeva se da se porez računa kao jedna trećina prihoda umanjenog za poresku naknadu. } const LicnaNaknada = 5000. OporezovaniPrihod : integer. SedmicaUGodini = 52. na primjer. Uočite upotrebu znaka “=” a ne “:=” u definiciji konstanti. pri cemu se naknada sastoji od lične naknade od 5000 funti. 4. var BrojDjece : integer. Porez : integer. ukoliko se promijeni kurs dinara i marke na primjer na 150. uvećava promjenljivu a za 5. One se definiraju pomoću definicija konstanti: const DinaraZaMarku = 100. const RadnihDana = 5. Konstante povećavaju čitljivost programa i olakšavaju njegovu izmjenu. Tako će rezultat izvršavanje ovog programa biti ispis brojeva 10. output). plus naknada za djecu od 1000 funti po svakom djetetu. NaknadaZaDjecu = 1000. BrojDjece). Prihod : integer. drugim riječima. .Na prvi pogled čudna konstrukcija “a := a + 5” ima značenje “nova vrijednost promjenljive a postaje stara vrijednost promjenljive a plus 5”. { Ovaj program računa iznos godišnjeg poreza poreskog obveznika. 5. Tako. OporezovaniPrihod := Prihod . Primjer programa program RacunanjePoreza(input. izmjenu je dovoljno napraviti samo u definiciji konstante “DinaraZaMarku”. a ne na svakom mjestu u programu gdje je upotrebljena ta konstanta (što bi inače morali uraditi da smo umjesto imena “DinaraZaMarku” u programu upotrebljavali broj 100 za kurs dinara). 2 i 10 (svaki u novom redu). Konstante Konstante se koriste za podatke koji se nikada ne mijenjaju u programu. pri čemu se kao ulaz zadaje obveznikov godišnji prihod i broj njegove djece.

Formatirani ispis Naredba: write('Poreska dadžbina iznosi: '. Tekst koji se nalazi unutar vitičastih zagrada { } predstavlja samo komentar koji povećava čitljivost programa. Porez. Prihod .Porez) dakle.{ Oporezovani prihod je prihod umanjen za iznos naknada } Porez := OporezovaniPrihod div 3. ispisaće: Poreska dadžbina iznosi: 666 Dakle. kao što je vidljivo iz gornjeg programa. ali se tako povećava čitljivost). Primijetimo da imena promjenljivih ne smiju sadržavati razmake. Porez:8). Porez). eksplicitnim ispisom jednog razmaka između rezultata. Porez. Ako se zadaju ulazni podaci: 11000 4 tada će izlazni podaci biti: 11000 2000 666 10334 iako će ispis izgledati kao: 11000200066610334 jer nigdje nismo naglasili u programu da izlazne rezultate treba razdvojiti (računar nikad ništa ne podrazumijeva dok mu se eksplicitno ne naglasi). problem sljepljenog ispisa rezultata u prethodnom programu možemo riješiti pisanjem naredbe: writeln(Prihod. Dalje je moguće zadati i širinu polja predviđenu za ispis cijelog broja: write('Poreska dadžbina iznosi: '. U nastavku ćemo vidjeti kako se ovaj problem rješava. Prema tome. tekst koji se nalazi između apostrofa u naredbi “write” samo se doslovno prenosi na ekran prilikom izvršavanja programa. Prihod . ' '. i da se mogu koristiti velika i mala slova (mada računar ne pravi razliku između njih.Porez) end. OporezovaniPrihod. { Porez se računa kao cijeli broj funti } writeln(Prihod. ' '. ali se računar na njega ne obazire prilikom izvršavanja programa. . Naredbe “read” i “write” mogu sadržavati i više argumenata razdvojenih zarezom. 6. OporezovaniPrihod. ' '.

'. write('Čisti prihod: što će proizvesti slijedeći ispis: Prihod: 11000 '.će ispisati: Poreska dadžbina iznosi: 666 “8” nije broj razmaka. Kako u našem slučaju broj “666” ima 3 cifre. OporezovaniPrihod:5). (Prihod .Porez):5). on se dopunjuje sa 5 dodatnih razmaka ispred. Oporezovani prihod: 2000 Poreska dadžbina: 666 Čisti prihod: 10334 . da uljepšamo izlaz iz prethodnog programa možemo pisati: write('Prihod: writeln. writeln. Prihod:5). Porez:5). Tako. '. '. write('Oporezovani prihod: writeln. write('Poreska dadžbina: writeln. nego broj mjesta koje će zauzeti broj.

Realni izraz može sadržavati cjelobrojne operande (koji se automatski konvertuju u realne).0. opcionalno. Cijeli broj može biti dodijeljen realnoj promjenljivoj: Poluprecnik := 3.1234 55E6 -3.0e-3 (Ovo znači 55∙106) 2. i definiciju konstante Pi = 3. Promjenljive tipa "real" Promjenljive realnog tipa koriste se za smještanje realnih brojeva. i. Primjeri: 5. Sirina. Realni izrazi mogu sadržavati realne konstante. eksponent. koje imaju decimalnu tačku. Povrsina : real.0. ili dodijeliti realnu vrijednost cjelobrojnoj promjenljivoj: Brojac := 100.8E3 12.4 3. Poluprecnik : real. prividno realne vrijednosti. Ne smijete koristiti realnu vrijednost u cjelobrojnim izrazima. Pravila za realni tip Pretpostavimo da imamo deklaraciju promjenljivih: Brojac : integer. Duzina. { POGREŠNO!!! } . jer je njihov opseg i broj decimala koje se pamte ograničen).0 -0. kada se izračunava izraz 2 * Pi * Poluprecnik cijeli broj 2 se automatski konvertuje u realnu vrijednost 2. Ovdje se ponovo dešava automatska konverzija tipa.REALNI TIP 1. Primjeri ovakvih deklaracija su: Temperatura : real. Ovim promjenljivim mogu biti pridružene realne vrijednosti (preciznije.14159. Na primjer.

000000000E+00 1. Ispis realnih vrijednosti Kada se ispisuju realne vrijednosti pomocu naredbi "write" i "writeln" možemo pored širine polja zadati i broj decimalnih mjesta.827433388E+01 Drugim riječima.884955592E01 2. Povrsina := Pi * sqr(Poluprecnik).141592654. Obim := 2 * Pi * Poluprecnik. i izračunava njegov obim i površinu. Povrsina). Povrsina) end. Povrsina : real. output). } const Pi = 3.0 naredba writeln(Poluprecnik. pri ispisu realnih brojeva podrazumijeva se eksponencijalna notacija. ako drugačije ne naglasimo. Realna aritmetika Realni izrazi mogu se slagati na sličan način kao i cjelobrojni izrazi. begin read(Poluprecnik). Naredba . Obim. var Poluprecnik. koristeći aritmetičke operatore. Obim. ispisaće nešto poput: 3. writeln(Poluprecnik. Operatori za realnu aritmetiku su: + * / sabiranje oduzimanje množenje dijeljenje Slijedi primjer programa koji ilustrira realnu aritmetiku: program Krug(input. 4. Ako se u program "Krug" unese ulazna vrijednost 3. Obim. { Ovaj program traži od korisnika poluprečnik kruga.3.

27 Ako želimo da zadamo samo broj decimala a ne i širinu polja.88 28. .0 18. Ovo doduše nije predviđeno standardom Pascal-a. Obim:10.writeln(Poluprecnik:8.885E+01 2. Povrsina:10:2) ispisaće: 3. Povrsina:10).827E+01 Naredba writeln(Poluprecnik:8:1. ali sve poznate implementacije podržavaju ovu konvenciju. ispisaće: 3. Obim:10:2.0E+00 1. za širinu polja stavljamo 0.

ch2 := '*'. on mora biti udvojen (peti primjer). read(treci). Unos i ispis znakovnih vrijednosti Znakovi se mogu unositi sa ulaznog uređaja koristeći naredbe "read" ili "readln". Inicijal. treci) end. drugi. npr. output). read(drugi). begin read(prvi). Znakovna konstanta se označava uokviravanjem znaka između jednostrukih znakova navoda (apostrofa). treci : char. Znakovne promjenljive Promjenljive tipa "char" mogu sadržavati samo jednu znakovnu (engl.ZNAKOVNI TIP 1. ch1 := ch2. a ispisivati pomoću "write" ili "writeln". drugi. 'A' '7' '+' ' ' '''' '?' Primijetite da kada je potrebno napisati apostrof između apostrofa. writeln(prvi. . ch2 : char. Ovim promjenljivim može se dodijeliti vrijednost pomocu pridruživanja poput: ch1 := 'a'. Primjeri znakovnih deklaracija su: Slovo : char. character) vrijednost. Nije moguće niti ima smisla vršiti aritmetiku poput ove: ch1 := ch2 + '3'. var prvi. kao u slijedećem primjeru: program DemonstracijaZnakova(input. { POGREŠNO!!! } 2. ch1.

a u suprotnom ne radimo ništa: ako pada kiša onda uzmi kišobran ako je danas radni dan onda ustani idi na posao Takođe je moguće navesti alternativni tok akcija koje slijede ako uvjet nije ispunjen: ako je danas radni dan onda ustani idi na posao inače isključi zvono na budilniku nastavi spavati 2. false). if Starost > 18 then write('Punoljetan'). condition). if StanjeKase < 0 then write('Nema više novca') else begin StanjeKase := StanjeKase . Ovdje su dati neki primjeri: if StanjeKase < 0 then write('Nema više novca'). then) i "inače" (engl. if). Uvjet je izjava koja moze biti tačna (engl. Algoritmi sa strukturama izbora Pored prostog niza (sekvence) instrukcija. U bosanskom jeziku izbor se izrazava pomocu specijalnih rijeci "ako" (engl. .Zaduzenje.Zaduženje. if StanjeKase > 0 then begin StanjeKase := StanjeKase . selection) izmedju dvije mogućnosti. "onda" (engl. izbor se izvodi upotrebom naredbe "if". Izbor u Pascal-u: naredba “if” U Pascal-u.NAREDBE IZBORA 1. true) ili netačna (engl. else). write('Trgovina obavljena') end. zavisno od vrijednosti nekog uvjeta (engl. mogu se pisati i algoritmi koji sadrže izbor (engl. Najjednostavniji slučaj izbora je kada vršimo neku akciju samo ako je uvjet tačan. write('Trgovina obavljena') end.

To su: = <> < > <= >= jednako nije jednako manje od veće od manje od ili jednako vece od ili jednako Tako.”end”. podrazumijevajući da su deklarirane slijedeće promjenjive: StanjeKase.Sintaksni dijagram za "if" naredbu izgleda ovako: NAREDBA “IF”: if NAREDBA: uvjet then naredba else naredba prosta naredba složena naredba SLOŽENA NAREDBA: begin naredba . Uvjeti u Pascal-u 3. Tako. 3. U principu.”. Broj : real. dozvoljene su sve sintaksne varijante do kojih se može doći u pravcu strelice. Porez : integer. one moraju biti uokvirene parom “begin”. dok su sve ostale nedozvoljene. formirana korištenjem relacionalnih operatora. . Inicijal : char. Takođe slijedi da ako se iza “if” želi navesti više naredbi koje se izvršavaju ako je uvjet ispunjen. iz sintaksnog dijagrama slijedi da se ispred “else” nikada ne smije staviti znak “..1 Relacionalni operatori Najjednostavnija vrsta uvjeta su poređenja dvije vrijednosti. npr. end Sintaksni dijagrami su jedan od najpreciznijih načina da se izrazi sintaksa nekog jezika iako su početnicima malo teži za čitanje.

output). Ugniježdene (engl.2 Logički operatori Složeniji izrazi mogu se formirati korištenjem logičkih operatora: and or not logičko "i" logičko "ili" logička negacija Oni se mogu koristiti za kombiniranje ili negiranje uvjeta: if (Starost >= 16) and (Starost < 65) then write('Možete se zaposliti'). if not (Starost > 65) then write('Ne možete imati penziju'). Primjer programa program Rezultati(input. { Ovaj program kao ulaz traži ocjenu sa ispita.možemo formirati slijedeće Pascal uvjete: StanjeKase = 100 Porez < 1000 Broj > 5. 4. Obratite pažnju na neophodne zagrade. if (Starost < 16) or (Starost > 65) then write('Ne možete se zaposliti').2 Inicijal = 'P' Obratite pažnju na razliku između operatora “=” sa značenjem “da li je jednako” i “:=” sa značenjem “postaje”. nested) naredbe "if" Naredbe unutar "if" naredbe (pogledajte sintaksni dijagram) mogu i same biti takodje "if" naredbe. 5. Na primjer: if Starost <= 16 then write('Dijete') else if Starost < 65 then write('Zrela osoba') else write('Penzioner'). i daje studentu komentar podrške } . 3.

. writeln('. . begin write('Unesi svoju ocjenu sa ispita: '). read(Ocjena).ali možda trebate više raditi!') end else writeln('Više sreće slijedeći put!') end.. if Ocjena >= 9 then writeln('Odlično!') else if Ocjena >=7 then writeln('Dobro') else if Ocjena >= 6 then begin writeln('Nije tako loše').var Ocjena : integer.

. tj. Boolean) je jos jedan ugrađeni (engl. Bulovi izrazi Bulovim promjenljivim mogu biti dodijeljene vrijednosti Bulovih izraza (oni su zapravo ekvivalentni logičkim izrazima)."until" petljom) o kojima će biti kasnije riječi. Promjenljive Bulovog tipa mogu imati samo dvije vrijednosti: "true" (tačno) i "false" (netačno). Pošto su Bulove promjenljive ujedno i Bulovi izrazi. IspravnaOcjena : Boolean. 2. izraza koji imaju vrijednost "true" ili "false". kao i unutar "if" naredbe: if UDugovima then writeln('Račun u dugovanju') else writeln('Račun u primanju'). Slijede neke deklaracije Bulovog tipa: UDugovima : Boolean. Ugrađene konstante "true" i "false" mogu se koristiti u Bulovim izrazima: Nastavak := true. predefined = unaprijed definiran) jednostavni (skalarni) tip. one se mogu koristiti za upravljanje "while" petljom (kao i "repeat". Nastavak : Boolean. Primjer programa . Bulovi izrazi mogu se kombinirati koristenjem logičkih operatora "and". npr. Deklaracija promjenljivih Bulovog tipa Bulov tip (engl. "or" i "not": IspravnaOcjena := (Ocjena >= 5) and (Ocjena <= 10). while Nastavak do begin { naredbe u petlji } end.LOGIČKI (BULOV) TIP 1. if Penzioner or Dijete then writeln('Platite pola karte za prevoz'). 3. UDugovima := (StanjeKase < 0). Punoljetan : Boolean. Punoljetan := (Starost >= 18).

Plemic := (Odgovor = 'D') or (Odgovor = 'd'). Neuracunljiv : Boolean. writeln. { Određuje ima li neko pravo glasa } var PravoGlasa. write('Da li ste trenutno neuračunljivi? (D/N): '). writeln. Neuracunljiv := (Odgovor = 'D') or (Odgovor = 'd'). i nakon toga saopštava imate li pravo glasa. program Glasac(input. . ili posjedujete titulu kao "vojvoda" ili "lord". begin writeln('Molim Vas. Zatvorenik := (Odgovor = 'D') or (Odgovor = 'd'). Morate imati 18 godina ili više. ili ako ste "plemenite krvi". writeln. readln(Odgovor). readln(Odgovor). unesite svoju starost: '). readln(Odgovor). Plemic. Odgovor : char. tj. write('Da li ste plemenite krvi? (D/N): '). readln(Starost). output). if PravoGlasa then writeln('Imate pravo glasa') else writeln('Nemate pravo glasa') end. write('Da li ste zatvoreni u nekom od zatvora? (D/N): '). PravoGlasa := (Starost >= 18) and not (Plemic or Zatvorenik or Neuracunljiv). Starost : integer. ili ste proglašeni neuračunljivim. Slijedeći program postavlja korisniku nekoliko pitanja.Velika Britanija ima slijedeće pravilo za određivanje da li neko ima pravo da glasa na izborima. Ne možete glasati ako ste u zatvoru. ako ste član kraljevske porodice na primjer. Zatvorenik. writeln.

Naredba "for" u Pascal-u U Pascal-u. algoritmi poput ovog izvode se pomoću "for" naredbe. Na primjer. naredba writeln('Here we go') biće ponovljena 11 puta. 4. const BrojLinija = 11. 2. for) upotrebljena u koraku 2. begin for Brojac := 1 to BrojLinija do writeln('Here we go') end. Ponavljanje pomoću naredbe "for" Ponavljanje (engl. Sintaksni dijagram za naredbu "for" izgleda ovako: . repetition) je upravljačka struktura koja nam omogućava da kreiramo algoritme koji uključuju ponavljanje neke akcije (ili skupine akcija). itd. 2. Drugi put "Brojac" će biti postavljen na 2. var Brojac : integer.2) ponavljaju zadani broj puta. promjenljiva "Brojac" će imati vrijednost 1. Najjednostavniji algoritmi koji koriste ponavljanje su oni gdje želimo da ponovimo neku akciju zadani broj puta.1 i 2. Na primjer.2 3.NAREDBE PONAVLJANJA 1. postavi ukupnu količinu padavina na 0 za mjesece od 1 do 12 radi slijedeće: unesi količinu padavina u toku mjeseca dodaj uneseni broj na ukupnu količinu podijeli ukupnu količinu sa 12 prikaži rezultat Specijalna riječ "za" (engl. Prvi put kada se izvrši. Kada promjenljiva "Brojac" dostigne graničnu vrijednost 11. označava da se slijedeće akcije (2. 2. U ovom programu. Algoritam za ovaj zadatak može izgledati ovako: Računanje prosječne količine padavina 1. iteration.1 2. i da izračunamo prosječnu količinu padavina u toku jednog mjeseca. Naredba "for" uvećava cjelobrojnu promjenljivu za 1 svaki put kada se naredba ponovi. naredba writeln će se ponoviti zadnji put. i izvršavanje naredbe "for" će biti završeno. zamislimo da želimo da unesemo ukupnu količinu padavina u toku svakog mjeseca u godini. slijedeći program ispisuje riječi pjesme popularne među engleskim nogometnim navijačima: program NogometnaPjesma(output).

U tim slučajevima u opisu algoritma koristimo specijalnu rijec "dok" (engl. uzmi cipelu . iz sintaksnog dijagrama se vidi da pored varijante sa “to” postoji i varijanta “for” petlje sa “downto” (o tome će biti riječi kasnije). mjeseca: '). Program za računanje prosječnih količina padavina u Pascal-u bi izgledao ovako: program KolicinaPadavina(input. readln(Padavine). Prosjek := Ukupno / 12. real.0. output). Ukupno := Ukupno + Padavine end. while).for promjenljiva := izraz to downto izraz do naredba Prema tome. Ponavljanje pomoću naredbe "while" Ponekad ne znamo unaprijed koliko puta se neka akcija treba ponoviti. for Mjesec := 1 to 0 do { radi nešto } petlja se neće izvrišiti niti jedamput. Mjesec:2. { { { { Ukupna godišnja kolicina padavina } Količina padavina za svaki mjesec } Prosječna mjesečna količina padavina } Redni broj mjeseca (1 . 3. i ponavljamo akciju sve dok je neki uvjet ispunjen (tačan). Ovo je algoritam koji princ koristi da nađe Pepeljugu: Traženje Pepeljuge 1. integer. writeln('Prosječna mjesečna količina padavina je: '.12) } begin Ukupno := 0. Prosjek:3:1) end. { Ovaj program očekuje unos količine padavina za svaki mjesec u godini. real. Ako je u “for” petlji krajnja vrijednost veća od početne. i računa prosječnu količinu padavina u toku jednog mjeseca } var Ukupno Padavine Prosjek Mjesec : : : : real. '. for Mjesec := 1 to 12 do begin write('Unesi kolicinu padavina u toku '. npr.

writeln(' .1 2. Kada se unese negativan broj. read(Broj) end. Broj : integer. naredbe unutar petlje se ponavljaju. while Broj >= 0 do begin Suma := Suma + Broj.negativan broj označava prekid. naredbe unutar petlje (prikazane uvučeno) se izvršavaju. writeln. } var Suma : integer. Ukoliko je uvjet ispunjen. ispituje se tačnost uvjeta. i ako je još ispunjen. write('Unesi broj: ').2 2. read(Broj). Kada pri izvršavanju ovog algoritma naiđemo na specijalnu riječ "dok". Uvjet se tada ispituje ponovo. Suma) .1 3. sve dok Pepeljuga nije nađena radi slijedeće potraži prvu slijedeću djevojku probaj može li obući cipelu ako cipela odgovara onda Pepeljuga je nađena oženi se Princ ovdje ne može koristiti algoritam sa "for". output). program ispisuje izračunatu sumu i završava sa radom: program SumaBrojeva(input.3. writeln. write('Unesi broj: '). { Suma unesenih brojeva } { Broj unijet od strane korisnika } begin Suma := 0. write('Unesi brojeve koji ce se sabirati '). { Ovaj program računa sumu brojeva unesenih sa tastature. jer ne zna unaprijed koliko će djevojaka morati da ispita prije nego sto nađe pravu. 2.2. pri čemu završava sa radom kada se unese negativan broj. Naredba "while" u Pascal-u U Pascal-u odgovarajuća upravljačka struktura koja vrši ponavljanje naredbi sve dok je neki uvjet ispunjen predstavlja naredbu "while".'). i sve tako dok uvjet ne prestane biti tačan. Sintaksni dijagram naredbe "while" izgleda ovako: while uvjet do naredba Slijedeći program omogućava korisniku da unosi nenegativne brojeve i pamti ukupnu sumu unesenih brojeva. 4.3 2. writeln('Suma unesenih brojeva je: '.

Brisanje" piši "K .Kraj" piši "Unesi opciju" učitaj znak dok ne bude znak jednak 'E'. jer će računar smatrati da je tijelo petlje prazno (dakle petlja u kojoj se ne izvršava ništa). sve "do" (engl. Ovo se naprimjer dešava kada tražimo neki unos od korisnika. a nakon toga se ispituje uvjet naveden iza "dok ne bude" (engl."until" u Pascal-u U Pascal-u.3 1. ovaj tip ponavljanja se realizira pomoću "repeat" naredbe. 6.1 1. until = do. Naredba "repeat". Ponavljanje pomoću strukture "repeat".6 {1} ponavljaj piši "E . i da ih želimo ponavljati sve do ispunjenja nekog uvjeta.4 1.5 1.1 do 1.. Česta greška prilikom korištenja naredbi “for” i “while” je stavljanje tačka-zareza iza riječi “do”. Njen sintaksni dijagram izgleda ovako: repeat naredba . 'B' ili 'K' Naredbe koje slijede iza "ponavljaj" (engl. i traži unos od korisnika sve dok korisnik ne da korektan odgovor: Prikaži meni 1. i ponavljamo zahtjev sve dok unos ne bude ispravan. od 1. ali neispravno. Na primjer."until" Slijedeća vrsta ponavljanja je moguća kada znamo da želimo da preduzmemo neke akcije barem jedamput.. repeat) se izvršavaju. until uvjet Podrazumjevajući da imamo deklaraciju promjenljive: var Opcija : char. dok ne bude). gornji algoritam u Pascal-u realizirao bi se ovako: repeat . Ako on nije tačan (tj.6) se ponavljaju. a naredbe koje smo željeli da budu u petlji izvršiće se izvan nje! 5.Snimanje" piši "B . naredbe unutar petlje (tj. ako je korisnik unijeo pogrešan znak). ovdje je dat algoritam koji prikazuje na ekranu izbor opcija (meni). until) ispunjenja zadanog uvjeta. nego će program raditi.end. Najgore je što u tom slučaju prevodilac neće prijaviti grešku. itd.2 1. 'S'. 1. uvjet se testira ponovo.Editor" piši "S .

. i "repeat" i "for" naredbe su.until } var Suma : integer. Suma) end. Broj : integer. Zapravo. .Editor').Kraj'). write('Unesi broj: '). Ipak. dok je “repeat”. writeln.negativan broj označava prekid. read(Broj) until Broj < 0.'). writeln('Unesi opciju: '). write('Unesi brojeve koji će se sabirati '). output). read(Opcija) until (Opcija = 'E') or (Opcija = 'S') or (Opcija = 'B') or (Opcija = 'K'). koristeći naredbe "for" i "repeat" program se često može jednostavnije napisati i uciniti čitljivijim.. writeln.writeln('E . writeln('B . može se napisati pomoću naredbe "repeat" umjesto naredbe "while": program SumaBrojeva2(input. naredba “for” je pogodnija od “while” ako unaprijed znamo broj ponavljanja. Napomena: mi smo već vidjeli program koji obavlja isti zadatak koristeći "while" naredbu.Brisanje').Snimanje'). writeln. Broj := 0. Program za računanje sume unesenih brojeva iz odjeljka 4. jer se svi ponavljajući algoritmi mogu napisati koristeći samo naredbu "while". repeat Suma := Suma + Broj. writeln('Suma unesenih brojeva je: '. strogo uzevsi suvišne. Na primjer. writeln(' . { Ovaj program računa sumu brojeva unesenih sa tastature: verzija sa repeat. { Suma unesenih brojeva } { Broj unijet od strane korisnika } begin Suma := 0. writeln('S . writeln('K .”until” petlja pogodna u slučajevima kada znamo da će se petlja izvršiti barem jedamput.

određena svojim indeksom. Ocjene svih učenika u razredu. Slovo : char. array) koji može čuvati 12 vrijednosti. Temperatura : real. može se vršiti i nad invididualnim elementima niza.. Brojac Temperatura Slovo Često pri rješavanju problema iz stvarnog svijeta trebamo predstaviti skupinu vrijednosti koje su sve istog tipa. Nizovni tipovi: predstavljanje skupine vrijednosti Tipovi "integer".12] of real. "real" i "char" dozvoljavaju nam predstavljanje pojedinačnih vrijednosti: Brojac : integer. array types). mi predstavljamo takve skupine vrijednosti pomocu nizovnih tipova (engl. Indeks se navodi nakon imena niza. Dakle.0. . na primjer: • • • Prosječne količine padavina za svaki mjesec.NIZOVI 1. ne kreirajući pri tome ni jedan primjerak promjenljive tog tipa (to moramo sami eksplicitno definirati). pri čemu je svaka tipa "real": ProsjecnePadavine 1 2 3 4 5 6 7 8 9 10 11 12 Svaki element niza je takođe za sebe promjenljiva. Ova deklaracija promjenljive kreiraće niz (engl. ovako definirani nizovni tip možemo koristiti u deklaracijama promjenljivih: var ProsjecnePadavine : Padavine. itd. U Pascal-u. Bilo koja operacija koja se može vršiti nad promjenljivima običnog tipa. u uglastim zagradama: ProsjecnePadavine[4] := 20. Možemo kreirati nizovni tip pomoću definicije tipa poput: type Padavine = array [1. Definicija tipa samo definira novi tip. Stanje prodaje za svaki dan u sedmici.

5] of real. writeln('Stavka Cijena'). { Ovaj program traži unos spiska od 5 cijena. '. podrazumijevajući da je deklarisana cjelobrojna promjenljiva "Mjesec". Često želimo da izvršimo istu operaciju nad svakim elementom niza. writeln. output).. writeln('-------------').0. ProsjecnePadavine := 20. i ispisuje ih kao spisak sa naslovom } type PetBrojeva = array [1. nemaju smisla u Pascal-u. for i := 1 to 5 do begin writeln(i:2. postaviće svaki element niza na 0. Nizovi su složeni tipovi (engl. Slijedeća 3 primjera koriste nizove i naredbu "for": program SpisakCijena(input.0. write(ProsjecnePadavine). var i : integer. writeln('Spisak cijena'). begin writeln('Unesi pet cijena:'). writeln.write(ProsjecnePadavine[7]:2:1). . To se najlakše može uraditi korištenjem "for" petlje. Na primjer. Cijene : PetBrojeva. slijedeća "for" naredba for Mjesec := 1 to 12 do ProsjecnePadavine[Mjesec] := 0. for i:=1 to 5 do read(Cijene[i]). non-scalar types) pa izjave poput: read(ProsjecnePadavine). Cijene[i]:6:2). ' writeln end end.

i : integer. { downto označava brojanje unazad } var Dan. for Dan := 1 to 5 do read(BrojPolaznika[Dan]).program Izvrtanje(input. { Ovaj program zahtijeva unos broja studenata koji prisustvuju petodnevnom kursu za svaki dan pojedinačno. i prikazuje linijski dijagram prisustva } type PetDana = array [1.5] of char. i ispisuje unesenu riječ u obrnutom poretku slova } type TipRijec = array [1. writeln('Dijagram prisustva za kratki kurs'). for i:= 5 downto 1 do write(Rijec[i]). for i := 1 to 5 do read(Rijec[i]). output). writeln. write('Riječ izgovorena natraške je: ').5] of integer. writeln end.. . writeln('Dan'). begin write('Unesi riječ od 5 slova: '). output). program Prisustvo(input. var Rijec : TipRijec.. Zvjezdica : integer. writeln('---------------------------------'). begin writeln('Unesi broj polaznika u toku svakog od 5 dana: '). { Ovaj program traži unos petoslovne riječi. BrojPolaznika : PetDana.

5..' '). neka imamo slijedeće deklaracije: type Matrica = array [1. 1. npr.for Dan := 1 to 5 do begin write(Dan:2. . writeln end end. Na primjer. Dvodimenzionalni nizovi se nazivaju matrice. postoje i višedimenzionalni nizovi.3]. var M : Matrica.5] of integer. Pored jednodimenzionalnih nizova koji su gore opisani. M[2. Ovim je definiran tip "Matrica" koji predstavlja matricu formata 5x5. for Zvjezdica := 1 to BrojPolaznika[Dan] do write('*'). i promjenljiva "M" koja je tipa "Matrica". O višedimenzionalnim nizovima biće više riječi kasnije.. Na sličan način se deklariraju i koriste nizovi sa više od dvije dimenzije. Elementima matrice "M" pristupa se preko dva indeksa.

. ili rezultati nogometne utakmice. BrojPolaznika : PetDana. Pobrojani tipovi Pobrojani i poddomenski tipovi su prosti tipovi definirani od strane korisnika. Danas. Rezultat = (Poraz. Cetvrtak.POBROJANI I PODDOMENSKI TIPOVI 1. Imena u pobrojanim tipovima mogu se koristiti za definiciju nizovnog tipa. Na primjer: type Dan = (Ponedjeljak. var Dan : RadniDan.. BrojPolaznika[Ponedjeljak]. Cetvrtak. kao što su dani u sedmici. Pobjeda). Pobrojani (engl. Nedjelja). . Petak). PetDana = array [RadniDan] of integer. Srijeda. Srijeda. Program koji prati pohađanje petodnevnog kursa.. Petak. Promjenljive pobrojanog tipa možemo deklarirati na uobičajeni način: var DanasnjiRezultat : Rezultat. BrojPolaznika[Petak]. Deklaracija promjenljive BrojPolaznika : PetDana. Sutra : Dan. output). Cetvrtak. kreiraće niz sastavljen od 5 cjelobrojnih elemenata: BrojPolaznika[Utorak]. Utorak. koji je bio napisan u poglavlju o nizovima. neka imamo slijedeće definicije tipova: type RadniDan = (Ponedjeljak. može se preglednije napisati ovako: program Prisustvo(input. pružajući mnogo prirodniji model za predstavljanje pojmova iz stvarnog života. enumerated) tip je skup vrijednosti koji su nazvane i uređene (stavljene u poredak) od strane programera. i prikazuje linijski dijagram prisustva } type RadniDan = (Ponedjeljak. Utorak. Petak). Nerijeseno. { Ovaj program zahtijeva unos broja studenata koji prisustvuju petodnevnom kursu za svaki dan pojedinačno. Utorak. Zvjezdica : integer. Subota. PetDana = array [RadniDan] of integer. Na primjer. Srijeda. Upotreba pobrojanih tipova čini program lakšim za razumijevanje.

koji je interno deklariran kao: type Boolean = (false. writeln(Dan). tako da nije moguće nešto poput: Dan := Ponedjeljak. tako je na primjer: Succ(Poraz) = Nerijeseno Pred(Petak) = Cetvrtak Tako je na primjer moguće koristiti naredbu: Dan := Succ(Dan). Deklaracijom pobrojanog tipa definiran je i poredak pojedinih elemenata. Tako je na primjer: Ord(Srijeda) = 2 Funkcije “Succ“ i “Pred” daju respektivno slijedeći odnosno prethodni element iz liste. for Dan := Ponedjeljak to Petak do read(BrojPolaznika[Dan]). writeln('---------------------------------'). writeln('Dijagram prisustva za kratki kurs'). writeln. . writeln end end. Tip "Boolean" je specijalni slučaj pobrojanog tipa. for Dan := Ponedjeljak to Petak do begin for Zvjezdica := 1 to BrojPolaznika[Dan] do write('*'). Važno je naglasiti da se promjenljive pobrojanog tipa ne mogu čitati ili pisati. true). tako je na primjer: Ponedjeljak < Utorak Pobjeda > Nerijeseno Funkcija “Ord“ daje redni broj pobrojane promjenljive pri čemu prvi element iz spiska ima redni broj 0.begin writeln('Unesi broj polaznika u toku svakog od 5 dana: ').

366. PC) taj broj manji. na primjer: type Mjeseci = 1. dok je tip "RadniDan" podskup korisnički definiranog pobrojanog tipa "Dan"... 2. Pobrojani tipovi su uvedeni samo za povećanje čitljivosti programa. Dobra je praksa koristiti poddomenske promjenljive gdje je god to moguće. tada su vrijednosti tih promjenljivih ograničene na definirane opsege: tako se promjenljivoj "PlaceniDan" ne može na primjer pridružiti vrijednost "Nedjelja". Konstanta "MaxInt" koja je korištena u deklaraciji tipa "Stanovnistvo" označava najveći cijeli broj koji se može predstaviti na korištenom računaru. Na većim računarima (npr. DanUGodini = 0. Danas : DanUGodini. RadniDan = Ponedjeljak..12] of real. da omogućimo provjeru vrijednosti koje su izvan opsega. Sat = 0. Neki Pascal prevodioci za manje računare (npr. VAX) to je uglavnom 2147483647. MjesecnePlate = array[Mjeseci] of real.MaxInt. Na primjer: type Dan = (Ponedjeljak.. obično 32767. a promjenljivima "London" i "Tokio" ne mogu se dodijeliti negativne vrijednosti. dok je na manjim računarima (npr. Petak.Petak.. Subota. Cetvrtak. Poddomenski tipovi Poddomenski (engl. Tokio : Stanovnistvo. Ovdje su tipovi "Sat". . osim po tome što ima širi opseg dozvoljenih vrijednosti. Nedjelja).. "DanUGodini" i "Stanovnistvo" podskupovi tipa "integer". subrange) tipovi dozvoljavaju programeru da ograniči skup vrijednosti predstavljen tipom. Poddomenske tipove možemo koristiti u deklaraciji nizova. U kasnijim poglavljima biće prikazani neki načini da se riješi ovaj problem. Utorak.niti read(Dan).23. London. Srijeda. Stanovnistvo = 0. Ako deklariramo slijedeće promjenljive poddomenskog tipa: var PlaceniDan : RadniDan.12. Turbo Pascal za PC) podržavaju tip "longint" koji se ne razlikuje od tipa "integer". ima isto dejstvo kao: type MjesecnePlate = array [1.

'E' : writeln('manje od 40%') end. 'D' : writeln('40% . Izborni izraz moze biti bilo kojeg rednog (engl. Naredba "case" Naredba "case" omogućava izbor izvršavanja jedne od nekoliko mogućih alternativa. 8. Nekada želimo da izvršimo istu akciju za više različitih vrijednosti izbornog izraza.2. 6 : writeln('Slabo'). Isto važi i za sve ostale konstante u popisu konstanti (koje se sve moraju međusobno razlikovati). 'B' : writeln('65% . Naredba "case" izabira konstantu čija je vrijednost jednaka vrijednosti izbornog izraza. ali ne i tip "real" koji je prividno kontinualan).VIŠESTRUKI IZBOR 1. Izbor je zasnovan na vrijednosti jednog izraza koji se naziva izborni izraz (engl. izvršavanje "case" naredbe nije definirano (bar ne u standardnom Pascal-u). i izvršava naredbu koja slijedi iza te konstante. To se postiže pisanjem niza konstanti razdvojenih zarezom umjesto jedne konstante. case expression). možemo napisati ovakvu "case" naredbu: case Stupanj of 'A' : writeln('75% ili vise'). ako pretpostavimo da je "Stupanj" promjenljiva tipa "char".64%'). zasnovan na pojmovima “slijedeći” i “prethodni” kao npr. 9 : writeln('Dobro'). tada će biti izvršena naredba koja slijedi iza konstante 'A'. Na primjer. ordinal) tipa (to su svi tipovi između kojih je moguće uspostaviti diskretni poredak. Sintaksni dijagram naredbe "case" izgleda ovako: case izraz of konstanta .1 : writeln('Veoma slabo') end.74%').3. . 5. ako je "Ocjena" promjenljiva tipa "integer".54%'). tip "integer" i "char". Ako se ni jedna konstanta ne slaže sa vrijednošću izbornog izraza.4.7 : writeln('Prosječno'). Ako izborni izraz (u ovom slučaju to je promjenljiva "Stupanj") ima vrijednost 'A'. možemo pisati: case Ocjena of 10 : writeln('Odlično'). Na primjer. što znači da morate uvijek navesti sve moguće vrijednosti izbornog izraza u popisu konstanti (kasniji Pascal standardi predviđaju i “else” varijantu u slučaju da se nijedna konstanta ne slaže sa vrijednošću izbornog izrata. ali time se ovdje nećemo baviti). : naredba end . 'C' : writeln('55% .

case Operator of '+' : writeln((Prvi '-' : writeln((Prvi '*' : writeln((Prvi '/' : writeln((Prvi end end. Program tada štampa rezultat tražene operacije: program Kalkulator(input. . operator +. Ovo je jedna od nestandardnih osobina (i jedna od rijetkih loših osobina) Turbo Pascal-a. Ako zamijenimo gornju "read" naredbu sa slijedećom naredbom: read(Prvi. begin read(Prvi. Drugi : real. Operator. * i /. koji omogućava korisniku da unese broj. { Program koji simulira prosti kalkulator } var Prvi. Drugi). Razmak. 2+3). program će proraditi. ali tada moramo obavezno prije operatora unijeti tačno jedan razmak (npr. 2 + 3). Drugi):5:2). + * / Drugi):5:2). 2.Poredak konstanti razdvojenih zarezom nije bitan. Operator. -. Drugi):5:2). Operator : char. i drugi broj (npr. output). i deklariramo promjenljivu "Razmak" tipa "char". Drugi):5:2) Napomena: Ovaj program ne radi u Turbo Pascal-u zbog nekih specifičnosti njegove "read" naredbe. Drugi). Primjer programa Slijedeći program simulira najprostiji kalkulator.

Pri unosu narudžbe program će neprekidno tražiti unos šifre naručenog proizvoda i naručenu količinu (u tonama). Kompanija trenutno ima 5 proizvoda na lageru. Program treba na osnovu toga izračunati ukupnu cijenu narudžbe tako da se ta informacija može odmah dati kupcu. i broj naručenih tona. Pošto ne postoji proizvod čija je šifra 0. Farmeri mogu telefonom naručiti porudžbinu i podići je slijedeći dan. program treba da prikaže sumarni izvještaj koji prikazuje ukupan broj naručenih tona za svaki proizvod. Napravićemo jednostavan program koji će nakon svake narudžbe pitati da li operator želi unijeti novu narudžbu. to se unos šifre 0 može koristiti kao signal da je narudžba gotova. Opis problema Neka kompanija prodaje vise razlicitih vrsta hrane za životinje. Na kraju dana. U svakom narednom koraku. Razvoj programa 2. on će prikazati sumarni izvještaj. detaljnije se razrađuju pojedini dijelovi algoritma: . 2. a cijene su slijedeće: Šifra proizvoda 1 2 3 4 5 Cijena (u funtama po toni) 150 200 400 325 250 Potreban im je kompjuterski program koji će operateru omogućiti da unese podatke o svakoj narudžbi: šifru svakog proizvoda kojeg farmer želi kupiti. Drugi niz će biti korišten za čuvanje ukupne količine naručene za svaki proizvod.2 Razvoj algoritma Algoritam ćemo razviti korak po korak. program će čekati unos slijedeće narudžbe.1 Strukture podataka Koristićemo niz da smjestimo popis cijena. 2. kada nema vise narudžbi. U prvom koraku algoritam se grubo skicira. a ako je odgovor "N".PRIMJER RAZVOJA PROGRAMA KORAK PO KORAK 1. tako da na kraju možemo prikazati sumarni izvještaj. Ako je odgovor "D".

1 {2.4 Postavi ukupnu cijenu porudžbine na 0 Učitaj šifru proizvoda sve dok je šifra proizvoda <> 0 radi slijedeće Učitaj zahtijevanu količinu Dodaj zahtijevanu količinu na ukupnu količinu za taj proizvod Prikaži zahtijevanu količinu pomnoženu sa cijenom po toni Dodaj zahtijevanu količinu pomnoženu sa cijenom po toni na ukupnu cijenu porudžbine Učitaj šifru proizvoda kraj petlje Ispiši ukupnu cijenu porudžbine 3.1.3. Obradi narudžbe 2.1 {3.1.3.3.3} 2.1.1.1.3.1 2.1} za proizvode od 1 do 5 radi slijedeće Postavi ukupnu količinu za taj proizvod na 0 kraj petlje za proizvode od 1 do 5 radi slijedeće Ispiši ukupnu količinu naručenu za taj proizvod kraj petlje 2.3. Inicijaliziraj listu cijena 2. Program u Pascal-u .1 2.3.3.1.3. Prikaži izvjestaj Korak 2 2.1.1 Postavi ukupne količine na 0 2.1.1.3} Postavi ukupne količine na 0 Postavi korisnikovu komandu na 'D' sve dok je korisnikova komanda = 'D' radi slijedeće Obradi jednu narudžbu Čekaj na unos korisnikove komande kraj petlje 3.1 3.1.3.2 2.5 {2.1 2.2 2.2 2.3 2.3.1.4 2.1.2 {2.3 2. Prikaži izvještaj 3.1 2.3.3.Korak 1 Program za obradu narudžbi 1.3.3.3.1.3. Obradi narudžbe 3.1 Obradi jednu narudžbu 2.3 2.1 2.1} Korak 3 2.3.1.1.3.

{ Omogućava unos kupčevih narudžbi sa terminala. možemo skicirati slijedeći kostur programa (engl.'D' znači "nastavljam" } . UkupnaNarudzba : integer.BrojProizvoda] of integer. računa vrijednost svake narudžbe koristeći spisak cijena. i prikazuje sumarni izvještaj } const BrojProizvoda = 5. begin { Inicijaliziraj listu cijena } { Obradi narudžbe } { Prikaži izvjestaj } end. Kolicina : integer. SifraProizvoda : integer. Cijene[3] := 400...BrojProizvoda] of integer. program skeleton): program Narudzbe(input. var Cijene : PopisCijena. potrebno je samo dodijeliti ispravne vrijednosti svakom elementu niza. Nastavak : char. type PopisCijena = array [1.Nakon razmišljanja o strukturi podataka. u razvoju algoritma. Nakon koraka 2 (razrada dijelova algoritma "Obradi narudžbe" i "Prikaži izvještaj" izvršni dio programa izgleda ovako: begin { Inicijalizacija liste cijena } Cijene[1] := 150. i nakon izvršenog koraka 1. Inicijalizacija liste cijena je trivijalna. { Obrada narudžbi } { Postavljanje ukupnih količina na 0 } { Popis tekućih cijena } { Ukupna narucena količina naručena za svaki proizvod } { Šifra koja odredjuje proizvod } { Broj naručenih tona } { Ukupna vrijednost narudžbe } { Korisnikova komanda . Kolicine : PopisKolicina. Cijene[4] := 325. PopisKolicina = array [1. output). Cijene[2] := 200. Cijene[5] := 250.

Nastavak := 'D'. while Nastavak = 'D' do begin { Obrada jedne narudžbe } UkupnaNarudzba := 0. Cijene[2] := 200. { Obrada narudžbi } { Postavljanje ukupnih količina na 0 } for SifraProizvoda := 1 to BrojProizvoda do Kolicine[SifraProizvoda] := 0. Nastavak := 'D'. Cijene[4] := 325. Još je jedino preostalo da dodamo kod za "Obradi jednu narudžbu" koji je razvijen u koraku 3: begin { Inicijalizacija liste cijena } Cijene[1] := 150. writeln(Kolicina * Cijene[SifraProizvoda]). read(Nastavak) end. Cijene[3] := 400. Cijene[5] := 250. Kolicine[SifraProizvoda] := Kolicine[SifraProizvoda] + Kolicina. while SifraProizvoda <> 0 do begin read(Kolicina). UkupnaNarudzba := UkupnaNarudzba + . while Nastavak = 'D' do begin { Obradi jednu narudžbu } writeln(UkupnaNarudzba). Kolicine[SifraProizvoda]) end. readln. read(SifraProizvoda). { Prikaz izvještaja } for SifraProizvoda := 1 to BrojProizvoda do writeln(SifraProizvoda.for SifraProizvoda := 1 to BrojProizvoda do Kolicine[SifraProizvoda] := 0.

UkupnaNarudzba : integer. output). { Obrada narudžbi } { Popis tekućih cijena } { Ukupna naručena količina naručena za svaki proizvod } { Šifra koja određuje proizvod } { Broj naručenih tona } { Ukupna vrijednost narudžbe } { Korisnikova komanda . { Omogucava unos kupčevih narudžbi sa terminala.'D' znači "nastavljam" } . PopisKolicina = array [1. { Prikaz izvještaja } for SifraProizvoda := 1 to BrojProizvoda do writeln(SifraProizvoda. readln. moramo učiniti program "ljubaznim" (engl. Kolicine[SifraProizvoda]) end. ispisom zaglavlja u izvještajima.. Cijene[3] := 400. type PopisCijena = array [1.Kolicina * Cijene[SifraProizvoda]. itd. writeln(UkupnaNarudzba). Slijedi konačni program: program Narudzbe(input. read(Nastavak) end. Cijene[5] := 250. računa vrijednost svake narudžbe koristeći spisak cijena. Nastavak : char. begin { Inicijalizacija liste cijena } Cijene[1] := 150.BrojProizvoda] of integer.. Kolicine : PopisKolicina. i prikazuje sumarni izvještaj } const BrojProizvoda = 5.BrojProizvoda] of integer. Cijene[2] := 200. var Cijene : PopisCijena. sa postavljanjem pitanja korisniku. read(SifraProizvoda) end. Cijene[4] := 325. Konačno. user-friendly). Kolicina : integer. SifraProizvoda : integer.

read(SifraProizvoda) end. for SifraProizvoda := 1 to BrojProizvoda do writeln(SifraProizvoda:8. ' funti'). ' tona proizvoda br. { Prikaz izvještaja } writeln('Proizvod Prodata količina (tona)').{ Postavljanje ukupnih količina na 0 } for SifraProizvoda := 1 to BrojProizvoda do Kolicine[SifraProizvoda] := 0. read(SifraProizvoda). ' = '). read(Kolicina). UkupnaNarudzba := UkupnaNarudzba + Kolicina * Cijene[SifraProizvoda]. while SifraProizvoda <> 0 do begin write('Unesi željenu količinu: '). writeln. . '. write('Unesi šifru proizvoda: '). writeln. while Nastavak = 'D' do begin { Obrada jedne narudžbe } UkupnaNarudzba := 0. readln. SifraProizvoda:1. Kolicine[SifraProizvoda]:28) end. writeln(Kolicina * Cijene[SifraProizvoda]. writeln end. write('Da li zelite jos narudžbi (D/N): '). Kolicine[SifraProizvoda] := Kolicine[SifraProizvoda] + Kolicina. write('Unesi šifru proizvoda: '). UkupnaNarudzba:3. ' funti'). Nastavak := 'D'. read(Nastavak). writeln('------------------------------'). writeln('Ukupna cijena narudžbe = '. write(Kolicina:2.

3. read(Drugi). { Čita dva broja i ispisuje njihov zbir } var Prvi. da se može izostaviti). Ova naredba će uzrokovati da se kod sadržan u proceduri izvrši. Procedure se koriste da struktuiraju programe tako da oni budu modularni.PROCEDURE 1. Primijetićete sličnost između strukture procedure i strukture programa. Često se procedura koja je definirana i koristena u jednom programu može upotrebiti u drugom programu. procedure body) sadrži skupinu naredbi omeđenih sa "begin" i "end". Drugi : integer. Na primjer. tj. procedure heading) sadrži ime procedure. Razvoj korak po korak zasniva se na procedurama koje obavljaju svaku etapu u procesu razrađivanja. Format deklaracije procedure Slijedi opis formata deklaracije procedure (uglaste zagrade [] označavaju da je nešto unutar njih opcionalno. Procedura se može smatrati kao mali program . Zaglavlje procedure (engl. jednostavniji za izmjene. Definiranje i poziv procedure Svakoj proceduri se daje ime. Pozivanje procedure po njenom imenu daje nalog proceduri da obavi svoj zadatak. writeln(Prvi + Drugi) end. tj. da budu načinjeni od manjih jedinica koje su neovisne jedna od druge koliko god je to moguće. Da pozovemo proceduru. 2. Modularnost Procedura je samostalan dio koda koji izvršava određeni zadatak. i opcionalno popis parametara. tipova i promjenljivih. Modularni programi su: jednostavniji za pisanje. ovdje je data jednostavna procedura koja čita dva broja i ispisuje njihov zbir: procedure SaberiUlaze. što štedi vrijeme i trud. dok tijelo procedure (engl. Blok procedure sadrži deklaracije konstanti. begin read(Prvi). jednostavniji za čitanje i razumijevanje. kao i tijelo procedure. koje treba da predstavlja zadatak koji ona izvršava. o kojima ćemo govoriti nešto kasnije. koristimo naredbu koja se sastoji samo od imena procedure: SaberiUlaze.

On štampa dvije strofe pjesme (tekst nije preveden sa engleskog jezika. output). . jer u prevodu postaje rogobatan). Napomenimo ipak da se deklaracija procedure završava sa tačka-zarezom. I wanna go back where the roses grow'). sa refrenom nakon svake strofe. writeln('Gee Mom. Ona čak može imati i svoje “privatne” pod-procedure. I don''t care too much for Army life!'). sa refrenom nakon svake strofe } procedure Refren. procedure <ime> [(<spisak parametara>)]. [const <definicije konstanti>] [type <definicije tipova>] [var <definicije promjenljivih>] [<deklaracije procedura>] begin <naredbe> end. tijelo procedure blok procedure zaglavlje procedure 4. program Pjesma(input. Primjer programa Ovdje je dat jednostavan primjer programa koji koristi procedure. a ne sa tačkom.') end.unutar drugog programa. writeln('But they won''t let me go home. { Štampa refren } begin writeln('Oh. { Štampa dvije strofe pjesme.

Procedure i razvoj korak po korak . write('One rolled off a table. Nasuprot tome. It's good for cuts and bruises. the biscuits are real fine. begin PrvaStrofa. '). DrugaStrofa. poredak u kojem se procedure deklariraju nije bitan. Ovaj primjer ilustrira jednu potencijalnu korist od procedura. '). I don't care too much for Army life! Gee Mom. { Glavni program } Rezultat izvršavanja ovog programa je slijedeći ispis: They say that in the Army. što je vidljivo iz gornjeg primjera.problem šahovske table 5. Refren. Oh. { Štampa drugu strofu } begin write('They say that in the Army.') end. and killed a pal of mine. One rolled off a table. They say that in the Army.'). I wanna go back where the roses grow But they won't let me go home. 5. Umjesto da 2 puta pišemo tekst refrena pjesme. jer rezultat izvršavanja programa zavisi od redoslijeda kojim se procedure pozivaju. Procedure moraju biti deklarirane prije nego što se pozovu.procedure PrvaStrofa. writeln('and tastes like iodine.'). Oh. writeln('the coffee''s mighty fine. the coffee's mighty fine. mi smo 2 puta pozvali proceduru “refren”. procedure DrugaStrofa. I wanna go back where the roses grow But they won't let me go home. I don't care too much for Army life! Gee Mom. što dovodi do kraćeg i jasnijeg programa. writeln. and tastes like iodine. writeln('the biscuits are real fine. { Štampa prvu strofu } begin write('They say that in the Army. writeln('and killed a pal of mine.1 Opis problema .') end. '). a ne od poretka u kojem su deklarirane. '). write('It''s good for cuts and bruises. Refren end.

2 Razvoj Korak 1 Program za štampanje šahovske table Učitaj širinu polja (u znacima) Učitaj visinu polja (u redovima) Štampaj tablu Korak 2 Štampaj tablu za par redova od 1 do 4 radi slijedeće Štampaj neparni red Štampaj parni red kraj petlje Korak 3 .Da pokažemo kako se procedure mogu iskoristiti za izvođenje etapa u razvoju korak po korak. koristeći praznine i zvjezdice. poput ovoga: ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** 5. riješićemo slijedeći problem: Napraviti program koji štampa lik šahovske table.

output).3 Program u Pascal-u program StampanjeSahovskeTable(input. { Širina kvadratnog polja } . { Program koji štampa lik sahovske table } var SirinaPolja : integer.Štampaj neparni red za linije od 1 do visine polja radi slijedeće Štampaj liniju neparnog reda kraj petlje Štampaj parni red za linije od 1 do visine polja radi slijedeće Štampaj liniju parnog reda kraj petlje Korak 4 Štampaj liniju neparnog reda za par kvadrata od 1 do 4 radi slijedeće Štampaj razmake Štampaj zvjezdice kraj petlje Štampaj liniju parnog reda za par kvadrata od 1 do 4 radi slijedeće Štampaj zvjezdice Štampaj razmake kraj petlje Korak 5 Štampaj razmake za znakove od 1 do širine polja radi slijedeće Štampaj razmak kraj petlje Štampaj zvjezdice za znakove od 1 do širine polja radi slijedeće Štampaj zvjezdicu kraj petlje 5.

begin for i := 1 to SirinaPolja do write(' ') end. procedure LinijaParnogReda.VisinaPolja : integer. StampajZvjezdice end. { Štampa "SirinaPolja" razmaka } var i : integer. procedure StampajZvjezdice. { Štampa liniju neparnog reda } var i : integer. { Štampa liniju parnog reda } var i : integer. procedure LinijaNeparnogReda. begin for i := 1 to 4 do begin StampajZvjezdice. { Stampa "SirinaPolja" zvjezdica } var i : integer. begin for i := 1 to 4 do begin StampajRazmake. . begin for i := 1 to SirinaPolja do write('*') end. writeln end. { Visina kvadratnog polja } procedure StampajRazmake.

read(SirinaPolja). procedure SahovskaTabla. SahovskaTabla . writeln. { Štampa neparni red } var i : integer. begin for i := 1 to VisinaPolja do LinijaNeparnogReda end.'). write('Unesi širinu svakog kvadrata. u linijama: '). writeln end. writeln. write('Unesi visinu svakog kvadrata. begin { Glavni program } writeln('Ovaj program prikazuje šahovsku tablu. procedure NeparniRed. { Štampa šahovsku tablu } var i : integer. u znakovima: '). begin for i := 1 to VisinaPolja do LinijaParnogReda end. writeln. begin for i := 1 to 4 do begin NeparniRed. ParniRed end end. read(VisinaPolja). { Štampa parni red } var i : integer. procedure ParniRed.StampajRazmake end.

Vidokrug identifikatora Promjenljive deklarirane unutar programskog bloka su globalne: one se mogu koristiti bilo gdje u programu (isto važi i za ostale identifikatore. scope). Dio programa u kojem se ime promjenljive (ili neki drugi identifikator) može legalno koristiti naziva se njen vidokrug (engl. međutim ona je neovisna od promjenljive "i" u proceduri "StampajRazmake": njen vidokrug je blok procedure "StampajZvjezdice". tipova i procedura). promjenljive deklarirane unutar bloka procedure su lokalne: one se mogu koristiti samo unutar procedure unutar koje su deklarirane. Slijedi još jedan primjer: . promjenljive "SirinaPolja" i "VisinaPolja" su globalne.end. S druge strane. 6. Promjenljiva sa imenom "i" takodje postoji i u proceduri "StampajZvjezdice" na primjer. U prethodnom primjeru. njen vidokrug je blok procedure u kojoj je definirana. dok je promjenljiva "i" deklarirana u proceduri "StampajRazmake" lokalna. tj. te dvije promjenljive su 2 potpuno različita objekta iako su im imena ista. za deklaracije konstanti.

ali lokalna promjenljiva "d". e := c. writeln(f) end. Proc1. ne može se koristiti unutar tijela procedure "Proc2". U slijedećem primjeru. Vidokrug od f Vidokrug od d i e Vidokrug od a. writeln(d. begin a := 1. e : integer. c : integer. b := 2. procedure Proc2. "b" i "c" mogu se koristiti unutar tijela procedura “Proc1" i "Proc2". begin d := a + 1. b. hidden) lokalnom promjenljivom “b” unutar bloka procedure "Proc2" (ponovo se radi o 2 potpuno različita objekta): . var d. Krajnji rezultat ovog programa je ispis brojeva 2. Proc2 end. 3 i 2.program DemonstracijaVidokruga1(input. begin f := b. globalna promjenljiva “b” je skrivena (engl. b i c { Glavni program } Globalne promjenljive "a". ili unutar glavnog programa. procedure Proc1. e) end. var f : integer. na primjer. c := 3. output). var a.

output). begin a := 1. b. Proc1. writeln(d) end. begin b := a + c. begin d := b. writeln(b) end. b := 2. Vidokrug od (lokalne) b Na ovom mjestu lokalna promjenljiva b skriva globalnu promjenljivu b prekidajući njen vidokrug Vidokrug od d Vidokrug od (globalne) b Vidokrug od a i c { Glavni program } Promjenljiva "b" koja se koristi u tijelu promjenljive "Proc1" je globalna promjenljiva. Promjenljiva "b" kojoj je pridružena vrijednost u proceduri "Proc2" i koja je prenesena kao argument naredbi "writeln" predstavlja lokalnu promjenljivu. procedure Proc2. var d : integer. Proc2 end. ali globalna promjenljiva "b" i dalje zadržava vrijednost 2.procedure DemonstracijaVidokruga2(input. var b : integer. Rezultat poziva ove procedure u glavnom programu biće ispis broja 4. var a. Rezultat poziva procedure "Proc1" u glavnom programu biće ispis broja 2. Sve lokalne promjenljive se “gube” (nestaju) po završetku procedure u kojoj su korištene. . c := 3. procedure Proc1. c : integer.

{ Glavni program } Iako ovaj program radi.PROCEDURE SA VRIJEDNOSNIM PARAMETRIMA 1. var Poluprecnik : real. writeln('Povrsina: '. neovisna od ostatka programa koliko god je to moguće. Zašto su potrebni parametri? Pogledajte slijedeći program: program Primjer1(input. Trebali bismo biti veoma pažljivi. Pi * Poluprecnik * Poluprecnik) end. U tom smislu oni su slični lokalnim promjenljivim. output). Ako se ime globalne promjenljive "Poluprecnik" promijeni. kada bi željeli da proceduru "Krug" upotrebimo u drugom programu. i da prenosimo željenu vrijednost kao parametar prilikom poziva procedure. Parametri su vrijednosti koje se koriste za inicijalizaciju nekih promjenljivih koje se koriste u proceduri prije nego što se naredbe unutar procedure počnu izvršavati. od kojih se razlikuju time što vrijednost lokalnih promjenjivih nije definirana u trenutku poziva procedure sve dok im eksplicitno ne dodijelimo neku vrijednost. begin read(Poluprecnik).procedura bi trebala biti neovisna jedinica koda. procedura će imati grešku. { Računa i štampa obim i površinu kruga sa poluprečnikom "Poluprecnik" } const Pi = 3. i možda bismo morali izmijeniti dio koda. Rješenje ovih problema je da dozvolimo proceduri "Krug" da koristi svoje lokalno ime za poluprečnik kruga. procedure Krug. 2 * Pi * Poluprecnik). postoje i neki problemi. Slijedi bolja verzija prethodnog programa koja koristi ovu ideju: . begin writeln('Obim: '. Krug end. ili će davati pogrešan rezultat.141592654. To nije ono sto želimo .

Broj stvarnih parametara koji se prenose u proceduru mora biti jednak broju formalnih parametara (u našem primjeru jedan). ako i formalni i stvarni parametar imaju isto ime (npr.program Primjer2(input. { Glavni program } Ovdje procedura "Krug" koristi svoje lokalno ime. njeni formalni parametri se deklariraju u popisu parametara: popis parametara procedure Krug(r : real). begin read(Poluprecnik). writeln('Površina: '.141592654. stvarni parametri (engl. 2 * Pi * r). var Poluprecnik : real. tako da "r" dobija vrijednost promjenljive "Poluprecnik". Formalni i stvarni parametar u principu mogu imati ista imena. "r". tekuća vrijednost promjenljive "Poluprecnik" prenosi se u proceduru. To je njen parametar. Krug(Poluprecnik) end. i ta vrijednost postaje početna vrijednost parametra "r". za poluprečnik. ali treba voditi računa da se i u tom slučaju radi o različitim objektima. stvarni parametar Vrijednost stvarnog parametra se prenosi u formalni parametar. output). 2. procedure Krug(r : real). Dakle. begin writeln('Obim: '. . formalni parametar Kada se procedura pozove. Formalni i stvarni parametri Kada se deklarira procedura. Kada se procedura pozove iz glavnog programa. actual parameters) se moraju proslijediti proceduri da inicijaliziraju svaki formalni parametar: Krug(Poluprecnik). { Računa i štampa obim i povrsinu kruga sa poluprečnikom koji se zadaje kao parametar } const Pi = 3. Pi * r * r) end.

Krug(Precnik / 2. prvo uvodeći parametar tako da procedura "StampajZvjezdice" ne mora ništa "znati" o globalnim promjenljivim: procedure StampajZvjezdice(BrojZvjezdica : integer). gdje je "SirinaPolja" globalna promjenljiva: procedure StampajZvjezdice.0). Korištenje vrijednosnih parametara Vrsta parametra koji je korišten u prethodnom primjeru. 3.0). . naziva se vrijednosni parametar (engl. Ova procedura može biti poboljšana. { Štampa "BrojZvjezdica" zvjezdica } var i : integer. Svaki stvarni parametar mora odgovarati po tipu odgovarajućem formalnom parametru. tako da su svi slijedeći pozivi dozvoljeni (ako pretpostavimo da postoji i promjenljiva "Precnik" tipa "real"): Krug(Poluprecnik). konstanta ili izraz. Krug(3. begin for i := 1 to SirinaPolja do write('*') end. Vrijednosni parametar se može upotrebiti da učini proceduru generalnijom. formalni parametar “X” je neovisan od stvarnog parametra “X”. i "Poluprecnik" je tipa "real". "r" je tipa "real". Stvarni parametar može biti bilo koja vrijednost ispavnog tipa: promjenljiva. U programu za ispis šahovske table imali smo proceduru nazvanu "StampajZvjezdice" koja je štampala "SirinaPolja" zvjezdica na ekranu. value parametar).“X”). begin for i := 1 to BrojZvjezdica do write('*') end. { Štampa "SirinaPolja" zvjezdica } var i : integer. mada se pri pozivu procedure “X” stvarni parametar “X” kopira u formalni parametar “X”. Iz izloženog je jasno da formalni parametar može biti samo ime. gdje se vrijednost stvarnog parametra kopira u formalni parametar. tako da se lakše može ponovo iskoristiti u drugim programima. a ne konstanta ili izraz.

Ovo je još generalnija procedura. odštampaće četiri slova "A". '*').Ovo je generalnija korisna procedura koja štampa onoliko zvjezdica koliko želimo. Znak : char). Ipak. StampajZnakove(SirinaPolja. begin for i := 1 to BrojZnakova do write(Znak) end. izuzev sto naredba "write" štampa razmak a ne zvjezdicu. koja štampa proizvoljan broj bilo kojeg znaka koji želimo: StampajZnakove(4. postoji takođe i procedura nazvana "StampajRazmake" koja štampa nekoliko razmaka. { Štampa "BrojZnakova" znakova "Znak" } var i : integer. Njen kod identičan je kao u proceduri "StampajZvjezdice". 'A'). odštampaće "SirinaPolja" zvjezdica. Dodajući još jedan parametar. . možemo postići da ista procedura radi oba posla (i isto tako dobro mnoge druge): procedure StampajZnakove(BrojZnakova : integer. kada god to zatražimo.

flowchart). Strukturni dijagram može takođe prikazivati prenos parametara: Glavni program Poluprecnik Krug Ovo pokazuje da glavni program poziva proceduru "Krug" i da joj prenosi "Poluprecnik" kao parametar. Primjer programa Slijedeći program predstavlja novu verziju programa za prikaz šahovske table. on im samo predaje ispravne parametre i prepušta im da odrade svoj posao. Procedure trebaju djelovati kao "crna kutija" sa gledišta glavnog programa. jer strukturni dijagram prikazuje samo hijerarhiju procedura. 6. Strukturni dijagrami Strukturni dijagram prikazuje strukturu programa: procedure koje on sadrži i pozivnu hijerarhiju (tj. To znači da pojedini dijelovi programa ne trebaju imati pristup onim promjenljivim koje ne trebaju da koriste. koji koristi vrijednosne parametre: . ni jedna procedura ne treba da radi više različitih poslova (svakom poslu treba dodijeliti posebnu proceduru). dijagrama toka (engl. i ne tiče ih se šta radi ostatak programa. information hiding) je jedan od principa dobrog modularnog dizajna. Sakrivanje informacija Sakrivanje informacija (engl. U slijedecem dijagramu procedura "A" poziva procedure "B" i "C": A B C Strukturni dijagram treba razlikovati od dijagrama toka (engl. 5. Algoritmi za svaku proceduru prikazanu na strukturnom dijagramu moraju biti opisani korištenjem pseudo-koda (način koji smo koristili kada smo opisivali razvoj korak po korak) ili korištenjem tzv. jer se smatra da podstiču nemodularno programiranje. koje procedure zovu koje procedure). Da se izbjegne upotreba globalnih promjenljivih u procedurama. Takođe. u dobro napisanom modularnom programu. flowcharts) koji se u posljednje vrijeme izbjegavaju. Primijetimo da strukturni dijagram ne opisuje korišteni algoritam. Procedure s druge strane samo primaju parametre od glavnog programa.4. U Pascal-u to zapravo znači da svaka promjenljiva treba imati vidokrug što je god moguće manji. ne ulazeći u to kako će one to uraditi. one se brinu samo kako da obave zadatak koji im je povjeren. a ne i algoritam kako pojedine procedure djeluju. treba intenzivno koristiti parametre.

output). begin for i := 1 to 4 do begin StampajZnakove(SirinaKvadrata. writeln . var m : integer.program StampanjeSahovskeTable(input. Zvjezdica) end. procedure LinijaParnogReda(SirinaKvadrata : integer). StampajZnakove(SirinaKvadrata. begin for i := 1 to 4 do begin StampajZnakove(SirinaKvadrata. Razmak). begin for i := 1 to BrojZnakova do write(Znak) end. { Štampa liniju parnog reda } var i : integer. StampajZnakove(SirinaKvadrata. Razmak) end. { Štampa liniju neparnog reda } var i : integer. Zvjezdica). Znak : char). { Program koji štampa lik šahovske table } const Razmak = ' '. n : integer. { Štampa niz znakova } var i : integer. Zvjezdica = '*'. { Širina kvadratnog polja } { Visina kvadratnog polja } procedure StampajZnakove(BrojZnakova : integer. procedure LinijaNeparnogReda(SirinaKvadrata : integer). writeln end.

{ Štampa parni red } var i : integer. m) . Sirina : integer). write('Unesi visinu svakog kvadrata. writeln. { Štampa neparni red } var i : integer. begin for i := 1 to Visina do LinijaNeparnogReda(Sirina) end. Sirina) end end. writeln. u znakovima: '). writeln. procedure ParniRed(Visina.'). begin for i := 1 to 4 do begin NeparniRed(Visina. procedure SahovskaTabla(Visina. SahovskaTabla(n. Sirina : integer). write('Unesi širinu svakog kvadrata. begin for i := 1 to Visina do LinijaParnogReda(Sirina) end. ParniRed(Visina. { Štampa šahovsku tablu } var i:integer. read(m). procedure NeparniRed(Visina. begin { Glavni program } writeln('Ovaj program prikazuje šahovsku tablu. Sirina). read(n). u linijama: '). Sirina : integer).end.

end. Slijedi i kompletan strukturni dijagram za ovaj program: .

Glavni program Visina Sirina SahovskaTabla Visina Sirina ParniRed Visina LinijaParnogReda Visina Znak StampajZnakove Znak Visina Sirina NeparniRed Visina LinijaNeparnogReda Visina .

40 + 2 * Povrsina. B then := A := B. var Min : integer). Nije dozvoljen ovakav poziv: NadjiMinimum(200. Kada se ova procedura izvrši. ovdje je prikazana deklaracija procedure koja nalazi najmanji od 3 broja koji su preneseni kroz vrijednosne parametre "A". Na primjer. Dok se kod vrijednosnih parametara odgovarajući formalni parametar “gubi” nakon završetka procedure ne ostavljajući nikakav “trag” na stvarnom parametru. C : integer. NajnizaCijena). i vraća rezultat kroz promjenljivi parametar "Min": procedure NadjiMinimum(A. Mi naznačavamo da je neki parametar promjenljivi parametar tako što stavljamo riječ "var" ispred deklaracije formalnog parametra u zaglavlju procedure. Promjenljivi ili varijabilni parametri dozvoljavaju da se podaci prenesu nazad iz procedure u blok koji je pozvao proceduru. pa odgovarajući stvarni parametar mora biti promjenljiva. jer je "Min" promjenljivi formalni parametar. promjenljivi parametar dozvoljava proceduri da promijeni vrijednost odgovarajućeg stvarnog parametra. Mehanizam prenosa parametara . "B" i "C" i smješta rezultat u "Min" } begin if A < Min else Min if C < Min end. 2. stvarni parametar ne smije biti konstanta ili izraz). 5 * Povrsina.PROCEDURE SA PROMJENLJIVIM PARAMETRIMA 1. NajnizaCijena : integer. B. "B" i "C". 40 + 2 * Povrsina. Primjer poziva procedure "NadjiMinimum" moze izgledati ovako: NadjiMinimum(200. Zato u tom slučaju stvarni parametar mora biti promjenljiva (kod promjenljivih formalnih parametara za razliku od vrijednosnih formalnih parametara. Oni su prenosili neku vrijednost u proceduru. Min then := C Pretpostavimo da imamo slijedeću deklaraciju promjenljivih: Povrsina. Promjenljivi parametri Parametri koje smo do sada koristili bili su vrijednosni parametri. 5 * Povrsina. vrijednost dodijeljena promjenljivom parametru "Min" postaje nova vrijednost promjenljive "NajnizaCijena". { Nalazi minimum od "A". 1000).

Prvi način je kopiranje vrijednosti u neku od lokalnih promjenljivih procedure. formalni i stvarni parametar predstavljaju različite objekte čak i kada imaju isto ime. procedure StopeIInci(Metri : real. BrojStopa. Ove (i druge podjednako nestandardne jedinice za težinu i zapreminu) poznate su kao "kraljevske" jedinice (zato što su bile nametnute u cijeloj britanskoj kraljevini!). jer je ona jedan od najčešćih uzročnika grešaka u programima koje koriste procedure! 3. ona može da izmijeni njen sadržaj. i vraca ih kroz parametre "Stope" i "Inci" } const StopaPoMetru = 3. { Na ulazu traži broj koji predstavlja dužinu u metrima. U suštini. var Pomocna : real. dok u prenosu po imenu formalni i stvarni parametar predstavljaju iste objekte čak i kada imaju različito ime. u Pascal-u. { Pretvara broj metara predstavljen parametrom "Metri" u broj stopa i inča. Inci := (Pomocna . Ovdje je dat program koji pretvara dužinu u metrima u stope i inče. Na ovu činjenicu (koja u početku može djelovati zbunjujuće) treba dobro obratiti pažnju. by reference ili by name). Primjer programa U Britanjiji i Sjevernoj Americi stare jedinice za dužinu. ali "ne zna" gdje se nalazio stvarni parametar. vrijednosni parametri se prenose po vrijednosti. read(BrojMetara).Stope) * 12.280839895 stopa } { 1 stopa = 12 inča } begin write('Unesi dužinu u metrima: '). StopeIInci(BrojMetara. pa ga zato ne može ni promijeniti.Postoje dva načina na koji se parametri prenose u proceduru. i pretvara ga u dužinu predstavljenu u stopama i inčima. Ovaj mehanizam se naziva prenos po referenci ili prenos po imenu (engl. { Kraj procedure "StopeIInci" } { 1 m = 3. output).0 end. Ovaj mehanizam se naziva prenos po vrijednosti (engl. stope i inči se još uvijek mnogo koriste (1 stopa = 12 inča). BrojInca : real. Zbog toga. zaokruženo na najbliži cijeli broj inča } var BrojMetara. kod prenosa po vrijednosti. program Konverzija(input. Inci : real). write('Dužina u kraljevskim jedinicama je: '). Pošto u ovom drugom slučaju procedura "zna" gdje se odgovarajuća promjenljiva nalazi. Stope := trunc(Pomocna). Drugi način je da se proceduri saopšti mjesto u memoriji računara gdje se odgovarajuća vrijednost čuva. var Stope. by value). . BrojStopa. što nije slučaj u prvom načinu. a promjenljivi parametri po imenu (referenci). U prvom načinu procedura samo dobija vrijednost. BrojInca). begin Pomocna := Metri * StopaPoMetru.280839895.

predstavljenu sa jednim znakom "T" ili "F" (što predstavlja true odnosno false). a druga zaokružuje realni broj na najbliži cijeli broj. Procedura treba da preskoči eventualne razmake koji prethode znaku "T" ili "F". Napišite proceduru koja ispisuje N praznih linija. Zadaća 1. Napišite proceduru koja razmjenjuje vrijednosti dva cjelobrojna parametra. round(BrojInca):2. tada naredba readb(DaLiPadaKisa). i vraća učitanu vrijednost kroz parametar. Ove funkcije su dosta slične međusobno.3 napišite i testni program kojim ćete testirati napisane procedure.writeln(round(BrojStopa):2. ' stopa '. gdje je N formalni parametar. Prva vrši odsjecanje decimala realnog broja (bez zaokruživanja). Obratimo pažnju na korištene funkcije "trunc" i "round". ako imamo slijedeću deklaraciju: DaLiPadaKisa : Boolean. 4. treba da u promjenljivu "DaLiPadaKisa" smjesti vrijednost "true" ili "false". Na primjer. 2. u zavisnosti da li je korisnik unijeo "T" ili "F". Za svaki od zadataka 1 . Napišite proceduru nazvanu "readb" koja učitava Bulovu vrijednost. Naredba "read" u Pascal-u ne moze se koristiti za učitavanje promjenljivih tipa "Boolean". . 3. ' inča') end.

procedure su objekti koji nemaju nikakvu vrijednost. 2. writeln(SahovskaTabla(m. besmislena. Za razliku od funkcija. n)). sqr(Broj). BrojStopa. ili iskoristiti unutar aritmetičkog izraza. sama za sebe nema nikakvog smisla. writeln(round(BrojInca)). koristili smo naredbe poput: Kvadrat := sqr(Broj). od kojih smo neke već koristili. BrojInca). Ove naredbe pokazuju da je poziv funkcije. . Deklaracija funkcije Deklaracija funkcije je slična deklaraciji procedure. Slijedeća deklaracija govori da je vrijednost koju vraća funkcija "Povrsina" tipa "real": function Povrsina(Poluprecnik : real) : real. kao sto su "sqr". izraz koji ima vrijednost (za razliku od poziva procedure. već upoznali. osim što se mora zadati i tip vrijednosti (rezultata) koji procedura vraća.FUNKCIJE 1. Drugi tip Pascal potprograma su funkcije.141592654. Vrijednost funkcije se mora dodijeliti nečemu. "sin". Slijedeći primjer ilustrira upotrebu funkcija u aritmetičkim izrazima (pri čemu je upotrebljena i funkcija “sqrt” koja računa kvadratni korijen): Hipotenuza := sqrt(sqr(Kateta1) + sqr(Kateta2)). Postoje mnoge već ugrađene funkcije. Funkcija je potprogram koji vraća neku vrijednost. tako da je upotreba naredbi poput: Rezultat := StopeIInci(BrojMetara. Na primjer. "round". Funkcije u Pascal-u Programske jedinice koje nam dozvoljavaju razvoj modularnih programa nazivaju se potprogrami. procedure. begin Povrsina := Pi * Poluprecnik * Poluprecnik { ili Pi * sqr(Poluprecnik) } end. koji ne predstavlja izraz). tako da naredba poput: sqr(Broj). U Pascalu postoje dva tipa potprograma. od kojih smo jedan tip. kao npr. "cos" itd. { Vraća površinu kruga čiji je poluprečnik dat kao parametar } const Pi = 3.

i vraća rezultat kroz četvrti (promjenljivi) parametar.0 + Kub(3. Poziv funkcija Kao što smo već rekli.5). Ovdje su neka tipična zaglavlja funkcija: function Kub(Broj : real) : real. begin if A < B then Najmanji := A else Najmanji := B. Pošto ta procedura računa samo jednu vrijednost (minimum). Oni se mogu koristiti bilo gdje gdje je dozvoljeno koristiti izraz onog tipa kojeg vraća funkcija. function PrestupnaGodina(Godina : TipGodine) : Boolean. B. Minimum := Najmanji end. za razliku od poziva procedura. Kao i kod procedura. stvarni parametri se moraju slagati sa formalnim parametrima i po broju i po tipu. Napomenimo da se parametri funkcija prenose po imenu (oni su vrijednosni parametri). 40 + 12 * Povrsina). Ranije smo napisali proceduru "NadjiMinimum". koji je složeni tip). writeln(5. na primjer: NajnizaCijena := Minimum(200. Upotreba funkcija Funkcije se mogu koristiti kada trebamo da izračunamo jednu vrijednost iz skupa parametara. rednog ili realnog (rezultat funkcije ne može biti niz. KljucZaDesifrovanje : integer) : char. { Vraća najmanji od cijelih brojeva A. C : integer) : integer. podesnije je koristiti funkciju: function Minimum(A. if PrestupnaGodina(OvaGodina) then BrojDana[Februar] := 29. pozivi funkcija su izrazi.0) / 2. Principijelno je . Funkcija može vratiti rezultat bilo kojeg prostog tipa. B i C kao rezultat } var Najmanji : integer. 3. if C < Najmanji then Najmanji := C. koja nalazi najmanji od prva tri njena cjelobrojna parametra. 5 * Povrsina. function Desifruj(Znak : char. 4.Barem jedna naredba (tipično zadnja) mora biti dodjeljivanje koje funkciji dodjeljuje vrijednost.

Napišite program koji će testirati funkciju. Napišite funkciju koja računa radnikovu sedmičnu platu. 5. i nije dobra programerska praksa. predviđeni broj radnih sati u jednoj sedmici i ostvareni broj radnih sati u sedmici. Pogotovo u funkcijama treba izbjegavati upotrebu globalnih promjenljivih (koje dovode do pojave tzv. broj ostvarenih radnih sati iznad predviđenog broja) treba da se plati 1.5 puta više u odnosu na normalnu satnicu. Prekovremeni rad (tj. Parametri treba da budu satnica (cijena jednog sata rada). . 2. Napišite program koji će testirati funkciju. ali je to zbunjujuće. Funkcija treba da vraća kao rezultat iznos isplate. Zadaća 1.moguće i unutar funkcija koristiti promjenljive parametre. Napište funkciju koja pretvara temperaturu u Celzijevim stepenima u arenhajtove stepene koristeći formulu F = C * 9 / 5 + 32. bočnih efekata).

3.1 {1.3.2 1.1 2. januara unijete godine Odrediti ostatak dijeljenja sa 7 broja proteklih dana u slučaju da je ostatak 0 : Početni dan je ponedjeljak (ovo se oslanja na činjenicu da je 1. godine) do 1.1. bio ponedjeljak) 1 : Početni dan je utorak 2 : Početni dan je srijeda 3 : Početni dan je cetvrtak 4 : Početni dan je petak 5 : Početni dan je subota 6 : Početni dan je nedjelja kraj izbora 3.3.2.1 Postavka problema Potrebno je sastaviti program koji će na ekranu odštampati kalendar za proizvoljnu unesenu godinu u opsegu 1997 – 3000.2 2.PRIMJERI MODULARNIH PROGRAMA 1.1 1.2 2. 1.1.1. 2.2} 1.3.3} Odrediti broj proteklih dana od nekog poznatog datuma (npr. 1. a koje nisu djeljive sa 400 (pravilo tzv. Određivanje početnog dana 2.2 Razvoj korak po korak Korak 1 Program za štampanje kalendara za godinu u opsegu 1997-3000 1. Pri tome treba voditi računa da su prestupne godine sve one djeljive sa 4.3 2. 1. gregorijanskog kalendara koji je danas u upotrebi).6 2. Korak 2 1.3 ponavljaj Učitati godinu sa tastature ako godina nije u opsegu (1997-3000) onda Ispiši upozorenje kraj uvjeta dok ne bude godina u opsegu Unijeti godinu Odrediti početni dan unijete godine Štampati kalendar 2.1 1.3.3. Štampanje kalendara . 3.1 2. 1996. januara 1996.3 2. Unos godine 1.7 {2.1.3. Kalendar 1. osim u slučaju godina kojima počinju vijekovi.1.4 2.5 2.

2.1601) div 400) Broj prestupnih godina je broj godina djeljivih sa 4 umanjen za broj godina djeljivih sa 100 koje nisu djeljive sa 400 (jer nije uvijek svaka četvrta godina prestupna.2 3.1 Određivanje broja proteklih dana 2.2.2 Izračunaj broj proteklih godina (Godina-1996) i pomnoži ga sa 365 Na rezultat dodaj broj prestupnih godina od godine 1996.1.1.1 Odredi broj godina djeljivih sa 4 od godine 1996.5.1.1.2 3.4 3.1 3.1 2.2.2.1.5} Korak 4 2.5. Određivanje broja prestupnih godina 2. tj.1.1.1.1.1.1.2 2.2.1.1.1.1.5 3.1.5.3.1.1 {3.1.1. do zadane godine uključivo godinu 1996.1.5.3 3.1.1.1 {3.1.2} 3.5.2.1 3.4 .) 3.1.3 {3. one djeljive sa 100 su prestupne samo ako su im zadnje dvije cifre dijeljive sa 4.2. tj. (uz malo elementarne matematike lako se dolazi do formule 1 + (Godina .1. godine kojima počinju vijekovi.1. do zadane godine (uključivo godinu 1996.1997) div 4) Odredi broj godina djeljivih sa 100 u istom razmaku (to daje formulu (Godina .1 Štampanje kalendara za jedan mjesec 3.1.1.1.ovo je pravilo gregorijanskog Ispiši ime mjeseca Ispiši zaglavlje kalendara Ispiši prazna polja čiji broj zavisi od početnog dana Odredi broj dana u mjesecu za brojač od 1 do broja dana u mjesecu radi slijedeće Ispiši brojač ako tekući dan nije nedjelja onda Pređi na slijedeći dan inače Proglasi ponedjeljak za slijedeći dan Prebaci ispis u novi red na ekranu kraj uvjeta kraj petlje 2.1.5.1.2.1.1 3.1.1.3 2.2} {3.1.2 3.1901) div 100) Odredi broj godina djeljivih sa 400 u istom razmaku (to daje formulu (Godina .1} Korak 3 za mjesece od januara do decembra radi slijedeće Štampaj kalendar za tekući mjesec kraj petlje 2. ako je sama godina djeljiva sa 400 .5.

3 Ispis praznih polja 3.4.4.1.1.1.1.1.4.4.1.3.1.1.3.1.1.1. Oktobar.1.4 Određivanje broja dana u mjesecu 3. August.1.4.1.1. i . Decembar : Broj dana u mjesecu je 31 April.1.3} 3.3 Ispitivanje da li je godina prestupna 3.2 {3. Juli.2 3.1.1.1 3.4.kalendara) 3.1 3.1.3 3.1.1.1.1 3.1.3.1.1.1.1.1} Korak 5 3.1 Godina je prestupna (u skladu sa rečenim u 2.3.1.2.Godina nije početna godina vijeka (tj.1.1.1 {3.1.4. Maj.4) ako je .1. Mart.4.1.4.1.1. Septembar.Godina djeljiva sa 4.4.1.4.3.1} za brojač od 1 do rednog broja početnog dana radi slijedeće Ispiši jedno prazno polje kraj petlje 3.1.3.1.1 {3. nije djeljiva sa 100) ili je godina djeljiva sa 400) za slučaj da je mjesec Januar.1.1.3} {3. Juni.1. Novembar : Broj dana u mjesecu je 30 Februar : ako je godina prestupna onda Broj dana u mjesecu je 29 inače Broj dana u mjesecu je 28 kraj uvjeta kraj izbora .1.1.

{ Godina za koju se traži kalendar } { Početni dan godine odnosno tekućeg mjeseca } { Tekući mjesec za koji se stampa kalendar } procedure UnosGodine(var Godina : integer). if not GodinaJeDobra(Godina) then writeln('Unijeli ste godinu izvan predvidjenog opsega!') until GodinaJeDobra(Godina) end.3. Cetvrtak. { UnosGodine } function OdrediPocetniDanGodine(Godina : integer) : Dani. Novembar. { Program koji formira kalendar za unesenu godinu u opsegu od 1997 do 3000 } type integer = longint. Petak. { Ova deklaracija u verziji Turbo Pascal proširuje opseg dozvoljenih cijelih brojeva izvan opsega -32768. Oktobar. Septembar. April. Utorak. Srijeda. Juni. Mjeseci = (Januar. Mart. Februar. Program u Pascal-u program Kalendar(input. var Godina : integer. { Određuje početni dan zadane godine } var . Maj.. Juli. { Unosi sa tastature željenu godinu vodeci racuna o ograničenju na dozvoljeni opseg godina } function GodinaJeDobra(Godina : integer) : Boolean. Subota. { Provjerava da li se godina nalazi u zadanom opsegu } begin GodinaJeDobra := (Godina >= 1997) and (Godina <= 3000) end. Nedjelja). Decembar). PocetniDan : Dani.2. read(Godina).32767. dok je u drugim verzijama Pascala suvišna i moze se izostaviti } Dani = (Ponedjeljak. August. output). { GodinaJeDobra } begin { UnosGodine } repeat write('Unesi godinu u opsegu od 1997 do 3000: '). Mjesec : Mjeseci.

do zadane godine } begin BrojGodinaDjeljivihSa4 := 1 + (Godina . { Broj godina djeljivih sa BrojGodinaDjeljivihSa100 : integer. BrojGodinaDjeljivihSa400 := (Godina . { iskorištena } 2 : OdrediPocetniDanGodine := Srijeda.1901) div 100. Mjesec : Mjeseci.1996) * 365 + BrojPrestupnihGodina(Godina). BrojGodinaDjeljivihSa100 := (Godina . var TekuciDan : Dani). { Ovdje je } 1 : OdrediPocetniDanGodine := Utorak. godinu } var BrojGodinaDjeljivihSa4 : integer. { Broj dana od 1. { 4. { bio ponedjeljak } 5 : OdrediPocetniDanGodine := Subota.1601) div 400. { OdrediPocetniDanGodine } procedure KalendarZaJedanMjesec(Godina : integer. januara zadane godine } Ostatak : integer. { 4 razmaka čine jedno prazno polje u kalendaru } { Razmak između polja u kalendaru } { Brojač dana u mjesecu } .1996 godine } 4 : OdrediPocetniDanGodine := Petak. var Brojac : integer.BrojGodinaDjeljivihSa400) end. { Određuje koliko je prestupnih godina bilo od 1996. case Ostatak of 0 : OdrediPocetniDanGodine := Ponedjeljak. i usput ažurira parametar "TekuciDan" tako da na izlazu sadrži početni dan narednog mjeseca } const PraznoPolje = ' Razmak = ' '.BrojProteklihDana : integer.1997) div 4. { u intervalu od godine 1996. godine do zadane godine uključivo 1996. { Ostatak dijeljena broja dana sa 7 } function BrojPrestupnihGodina(Godina : integer) : integer. 100 i 400 respektivno BrojGodinaDjeljivihSa400 : integer.1. 6 : OdrediPocetniDanGodine := Nedjelja end end. { BrojPrestupnihGodina } begin { OdrediPocetniDanGodine } BrojProteklihDana := (Godina . do 1. { Štampa kalendar za zadani mjesec zadane godine. Ostatak := BrojProteklihDana mod 7. BrojPrestupnihGodina := BrojGodinaDjeljivihSa4 (BrojGodinaDjeljivihSa100 . januara 1996. { činjenica da je } 3 : OdrediPocetniDanGodine := Cetvrtak. { 1. '.

{ IspisiImeMjeseca } Nažalost. { Ispisuje ime mjeseca } begin case Mjesec of Januar : writeln('Januar'). { Mart : writeln('Mart'). Septembar. August : writeln('August'). Decembar : writeln('Decembar') end end. { Maj : writeln('Maj'). Maj. { GodinaJePrestupna } begin { BrojDanaUMjesecu } case Mjesec of Januar. August. Juli. { BrojDanaUMjesecu } . Mart. Septembar : writeln('Septembar'). { Juli : writeln('Juli'). promjenljive } pobrojanog tipa ne mogu } se ispisivati sa "write" } i ”writeln”. { Određuje da li je godina prestupna } begin GodinaJePrestupna := (Godina mod 4 = 0) and ((Godina mod 100 <> 0) or (Godina mod 400 = 0)) end. inače bi } bilo dovoljno samo } napisati writeln(Mjesec) } function BrojDanaUMjesecu(Godina : integer. { Određuje broj dana u zadanom mjesecu zadane godine } function GodinaJePrestupna(Godina : integer) : Boolean. Juni. { April : writeln('April'). Oktobar. April. Mjesec : Mjeseci) : integer.procedure IspisiImeMjeseca(Mjesec : Mjeseci). Novembar : writeln('Novembar'). Oktobar : writeln('Oktobar'). Novembar : BrojDanaUMjesecu := 30. { Februar : writeln('Februar'). Decembar : BrojDanaUMjesecu := 31. Februar : if GodinaJePrestupna(Godina) then BrojDanaUMjesecu := 29 else BrojDanaUMjesecu := 28 end end. { Juni : writeln('Juni').

begin { KalendarZaJedanMjesec } IspisiImeMjeseca(Mjesec). for Brojac := 1 to Ord(TekuciDan) do write(PraznoPolje)... i to je pravi end { trenutak da se ispise novi end. { KalendarZaJedanMjesec } { kad mjesec završava } { ponedjeljkom (tada je on } begin { Glavni program } { već ispisan) } UnosGodine(Godina). writeln. { još jedan prazan red. PocetniDan). Razmak). writeln('Pon Uto Sri Čet Pet Sub Ned'). if TekuciDan <> Nedjelja then { succ(X) vraća kao } TekuciDan := succ(TekuciDan) { rezultat sljedbenika od X else begin TekuciDan := Ponedjeljak. PocetniDan := OdrediPocetniDanGodine(Godina). for Brojac := 1 to BrojDanaUMjesecu(Godina. Mjesec. end. } } } } . } writeln. osim end. treba ispisati } writeln. for Mjesec := Januar to Decembar do KalendarZaJedanMjesec(Godina. if TekuciDan <> Ponedjeljak then { Na kraju. Mjesec) do begin write(Brojac:3. { red. { Iza nedjelje slijedi } writeln { ponedjeljak.

1. Poređenja radi. Brojac. type integer = longint. for Mjesec := 1 to 12 do begin case Mjesec of 1 : writeln('Januar'). Mjesec. if (Mjesec = 4) or (Mjesec = 6) or (Mjesec = 9) or (Mjesec = 11) then BrojDana := 30. begin repeat write('Unesi godinu u opsegu od 1997 do 3000: '). 8 : writeln('August').1997) div 4 (Godina . i znatno teži za izmjene. ovdje je dat i primjer istog programa napisanog nemodularno. 11 : writeln('Novembar'). znatno teži za razumijevanje. 2 : writeln('Februar'). writeln. output). 3 : writeln('Mart'). 6 : writeln('Juni'). BrojDana : integer. writeln('Pon Uto Sri Čet Pet Sub Ned'). for Brojac := 1 to Dan do write(' '). 9 : writeln('Septembar'). 7 : writeln('Juli').4 Nemodularno rješenje Ono što je bitno da se uoči da modularno rješenje nije i najkraće rješenje.1901) div 100 + (Godina .1996) * 365 + 1 + (Godina . 12 : writeln('Decembar') end. Ostatak. program Kalendar(input. if Mjesec = 2 then .1601) div 400) mod 7. if (Godina < 1997) or (Godina > 3000) then writeln('Unijeli ste godinu izvan predvidjenog opsega!') until (Godina >= 1997) and (Godina <= 3000). jer ne prati prirodan tok misli. 4 : writeln('April'). Ostatak := ((Godina . { Samo za Turbo Pascal } var Godina. Prikazani program je znatno kraći. read(Godina). BrojDana := 31. 5 : writeln('Maj'). 10 : writeln('Oktobar').

BrojDana := 28 + .Ord((Godina mod 4 = 0) and ((Godina mod 100 <> 0) or (Godina mod 400 = 0))). Dan := (Dan + 1) mod 7. if Dan = 0 then writeln end. if Dan <> 0 then writeln end end. writeln. for Brojac := 1 to BrojDana do begin write(Brojac:3. ' ').

Šta su stringovi? String je niz znakova. Mnogi podaci koje zelimo da čuvamo u elektronskoj formi sastoje se od stringova. Dugi = packed array [1.6] of char. telefonski broj (niz cifara i razmaka) itd. 2. stringovi su predstavljeni kao nizovi (arrays) koji se pokoravaju slijedećim pravilima: 1. Stringovi u Pascal-u Za razliku od nekih drugih jezika. tako da mnoge izvedbe Pascal-a (prevodioci koje prodaju razni proizvođači) uvode tip string i funkcije za obradu stringova kao proširenje jezika. Zbog toga ćemo se ograničiti na standardni Pascal. 2.STRINGOVI 1. razmaka i interpunkcijskih znakova). U standardnom Pascal-u. i obrnuto.. Takođe.' 'Ja sam drugi string!' 'string sa nekoliko razmaka na kraju '+387 71 654-321' ' ' ' . Rijec2 : Kratki. Važno je moći napisati program za računar koji obrađuje stringove. Problem je što ta proširenja nisu standardizirana: ono što radi u VAX Pascal-u ne radi u Turbo Pascal-u na PC-u. Donji indeks niza mora biti 1. Upotreba stringova u programima 3. riječ (niz slova).1 Pridruživanje stringova String konstante mogu se pridružiti string promjenljivim.20] of char. Kada se definira tip niza. Slijede primjeri definicija stringovnog tipa: type Kratki = packed array [1. rečenica (niz slova. { String } { promjenljive } 3. 3. ispred riječi "array" mora se dodati riječ "packed". Tip elemenata niza mora biti char. jezik poznat kao standardni Pascal ne uključuje tip string kao ugrađeni tip. na primjer imena i adrese ljudi. Programeri u Pascal-u su shvatili da je to problem. ove bilješke su pripremljene pomoću programa za obradu teksta koji manipulira sa stringovima.. { Tipovi stringovnih } { nizova } Sa ovako definiranim tipovima možemo deklarirati string promjenljive: var Rijec1. na primjer: 'mačka' 'Ovo je string. Fraza : Dugi. String konstante su ograničene jednostrukim znakom navoda (apostrofom). To može biti npr.

To se može učiniti koristeći naredbu "read" unutar "for" petlje. Fraza := 'Previše kratko '. kao što pokazuje slijedeći primjer: .Ako string mora da sadrži apostrof kao svoj sastavni dio. { Uočite 6 dodatnih razmaka } Sadržaj jedne string promjenljive može biti dodijeljen drugoj samo ukoliko su tipovi dvije promjenljive identični (nizovi iste dužine). kao u primjeru: 'I''m English string!' Dužina string konstante mora odgovarati tipu string promjenljive kojoj se pridružuje.znakovi se moraju čitati jedan po jedan. taj apostrof se mora pisati dvostruko. jer su "Rijec1" i "Rijec2" oba string nizovi sa 6 elemenata.2 Ispis stringova Već smo upoznali upotrebu string konstanti kao parametara u naredbama "write" i "writeln": writeln('Pozdrav svijetu'). 3. writeln(Fraza). u raznim proširenjima to je moguće) .3 Upis stringova Naredbe "read" i "readln" ne mogu se koristiti za upis cijelog niza odjedamput (bar ne u standardnom Pascal-u. 3. Tako su ispravna slijedeća string pridruživanja: Rijec1 := 'Pjevaj'. Tako možemo pisati: Rijec2 := Rijec1. Rijec2). Naredbe "write" i "writeln" mogu se takođe koristiti za ispis sadržaja string promjenljivih: write(Rijec1.

ima značenje "dolazi prije po abecedi od". Rijec) end. { Ovaj program traži od korisnika da unese desetoslovnu riječ. na primjer: if Rijec1 = 'Pjevaj' then writeln('Moraš pjevati pjesmu'). Testiranje jednakosti je takođe uobičajeno. liniju po liniju } const MaksimalnaDuzinaLinije = 79. writeln('Unijeli ste '. { Ovaj program ponavlja unos. begin writeln('Molim unesite desetoslovnu riječ').4 Poređenje stringova Stringovi se mogu porediti koristeći relacione operatore: <. 3. i : integer. { Broj linija koje će se ponavljati } . Tako sva velika slova dolaze ispred malih slova po poretku (naša slova su tu poseban problem. Program "KopirajLinije" omogućava korisniku da neprestano unosi liniju teksta (neodređene dužine). dužina unesene linije } BrojLinija = 10. jer čak i ako su uključena u skup slova. kada se primijeni na stringove.10] of char. var Rijec : TipRijec. Ugrađena Bulova funkcija "eoln" detektuje kada je korisnik završio unos sa RETURN odnosno ENTER karakterom (ako se čitanje vrši sa tastature. njihova pozicija je nestandardna). funkciji "eoln" se daje ime "input" kao parametar). output).program UnosStringova(input. koja se nakon unosa ispisuje na ekran. Tako oba izraza 'mačka' < 'pas ' 'Damir' > 'Dalen' imaju vrijednost "true". } type TipRijec = packed array [1. i ispisuje je na ekran. for i := 1 to 10 do read(Rijec[i]). { Maks.. 4. > itd. Primjeri programa Slijedeći primjeri prikazuju neke tehnike obrade stringova. program KopirajLinije(input. output). Prilikom poređenja se pravi razlika između malih i velikih slova. Operator "<".

MaksimalnaDuzinaLinije] of char. do pozicije "MaksimalnaDuzina". begin for i := 1 to MaksimalnaDuzina do if eoln(input) then OvaLinija[i] := ' ' else read(OvaLinija[i]) end. { Čita znakove sa ulaza u string "OvaLinija". Za tu svrhu moramo koristiti niz čiji je svaki element string.. } var i : integer. writeln(SlijedecaLinija). Program "SmjestiImena" koristi niz koji može smjestiti do 100 desetoslovnih imena. SpisakImena = array [1.. { tip stringovnog niza } { niz stringova } . na primjer imena svih učenika u razredu. readln end end. ili sve dok se ne pročita “MaksimalnaDuzina” znakova. Ona je kod rada sa stringovima uvijek neophodna kao priprema za unos novog stringa. MaksimalnaDuzinaLinije).type Linija = packed array [1. popunjavaju se sa razmacima. Često je potrebno smještanje skupine stringova. MaksimalnaDuzina : integer). { Niz koji čuva svaku unesenu liniju } i : integer. itd.10] of char. Primijetimo upotrebu naredbe “readln” bez parametara nakon obrade jedne linije.. Neiskorištene pozicije u stringu.100] of Ime. To je postignuto definicijom tipova: type Ime = packed array [1. imena svih mjeseci u godini. sve dok se ne dostigne kraj linije. { CitajLiniju } begin { Glavni program } for i := 1 to BrojLinija do begin CitajLiniju(SlijedecaLinija. procedure CitajLiniju(var OvaLinija : Linija. var SlijedecaLinija : Linija. i deklaracijom promjenljive var CijeliSpisak : SpisakImena.

i : integer.100] of Ime.Kao ilustracija kako raditi sa nizom stringova.100. { CitajIme } begin { Glavni program } Inicijalizacija(CijeliSpisak. SpisakImena = array [1. Broj : 1. SaImenom : Ime). output).. { Inicijalizira sva imena u spisku "Spisak" sa imenom navedenim u parametru "SaImenom" } var i : integer. { 10 razmaka } procedure Inicijalizacija(var Spisak : SpisakImena.10] of char. ovaj program omogućava korisniku da unese spisak imena.. i omogućava korisniku da izabere dio koji će biti prikazan } type Ime = packed array [1.. begin for i := 1 to 10 do read(NekoIme[i]) end. readln(Broj). begin for i := 1 to 100 do Spisak[i] := SaImenom end. Pocetak. program SmjestiImena(input. { Inicijalizacija } procedure CitajIme(var NekoIme : Ime). . write('Koliko desetoslovnih imena želite da unesete? '). { Čita znakove jednog imena } var i : integer. Razmaci). { { { { cijeli spisak imena } broj imena koji će biti unesena } granice za ispis imena } brojač petlje } '. Kraj : 1. { Čita spisak imena.100.. const Razmaci = ' var CijeliSpisak : SpisakImena. i tada da izabere podspisak (na primjer imena sa rednim brojevima od 10 do 20) koji će biti ispisan.

Zadaća 1. writeln('kojeg zelite:'). Ako je ime kraće od 10 znakova. writeln. svako u novoj liniji:'). Kraj). 2. (Pogledajte program "KopirajLinije" za objašnjenje kako to uraditi). moraju se unositi dodatni razmaci da se popuni string. Napišite program koji čita spisak od 10 riječi i zatim ga štampa: (a) u obrnutom poretku. write('Unesite redni broj prvog i zadnjeg imena '). ali bez ispisa duplih riječi koje su se već jednom pojavile u spisku. Izmjenite program tako da se string automatski popunjava potrebnim prazninama ako se unese kraće ime.writeln('Unesite imena. Program "SmjestiImena" ima nedostatak što primorava korisnika da unosi tačno deset znakova za svako ime. { SmjestiImena } 5. . (b) u normalnom poretku. for i := Pocetak to Kraj do writeln(CijeliSpisak[i]) end. readln end. for i := 1 to Broj do begin CitajIme(CijeliSpisak[i]). readln(Pocetak.

. To se postiže definicijom poput: type TipTabela = array [1.. 2 3 4 5 Razlika između dva načina definiranja je što niz tipa kao sto je "TipTabela". Ako se . Deklaracija višedimenzionalnih nizova Pascal dozvoljava da elementi nizova budu bilo kojeg tipa. Deklaracija var Matrica : TipMatrica.. ili matrica. iako je drugi način prirodniji kada se dvodimenzionalni niz definira kao jedan tip. na primjer dvostruko osjenčeni element na slici. ne može biti rastavljen na redove sa kojima se može neovisno manipulirati. konstrukcijom poput: Matrica[3][2] ili Matrica[3. kreira dvodimenzionalni niz sa četiri reda i pet kolona: 1 1 2 3 4 Matrica Izraz Matrica[3] predstavlja jedan red niza (osjenčen na slici).5] of real..2] gdje oba načina pisanja označavaju drugi element u trećem redu. uključujući i same nizove. var Tabela : TipTabela. koji se često koriste za predstavljanje tabela podataka. 1.4] of TipRed. definiran pomoću oba skupa indeksa u istoj definiciji. Posebno uobičajeni su dvodimenzionalni nizovi. TipMatrica = array [1. Definicija tipa za dvodimenzionalni niz koji smješta realne vrijednosti može biti poput slijedeće: type TipRed = array [1.4.VIŠEDIMENZIONALNI NIZOVI 1. To nam omogućava da kreiramo višedimenzionalne nizove. Ova dva oblika su ekvivalentna. bez prethodnog definiranja tipa za red.5] of real. Može se izabrati i samo jedan element.

Unutrašnja petlja broji kolone niza. BrojIspita = 5. Matrica[4] := Red. i ispisivati ukupnu prosječnu ocjenu za svakog studenta.100. i njoj se mogu direktno pridružiti redovi niza. { Tabela ocjena } { Brojac petlje } .. output).BrojStudenata. program Ispiti(input. } const BrojStudenata = 10. Matrica[1] := Matrica[4]. { Ocjena je data u procentima } OpsegStudenata = 1. var Ocjene : TabelaOcjena. Tako da zamijenimo prvi i posljednji red matrice "Matrica" možemo pisati: Red := Matrica[1]. TabelaOcjena = array [OpsegStudenata] of OcjeneStudenata. 2. najprirodnije je definirati tip koji će predstavljati taj skup. { Čita skup ocjena za svakog studenta u grupi.. Zahtijeva se program koji će tražiti sve ocjene.BrojIspita. Kako nas zanima skup ocjena za svakog studenta. koristeći ugnježdene "for" petlje. type Ocjena = 1. OcjeneStudenata = array [OpsegIspita] of Ocjena.. OpsegIspita = 1. i ispisuje ukupne prosjecne ocjene. Student : OpsegStudenata.koristi definicija tipa u dvije etape (kao "TipMatrica" u prvom primjeru). a vanjska petlja broji redove. Procedura "CitajOcjene" prikazuje uobičajen način manipulacije sa dvodimenzionalnim nizovima. može se definirati promjenjiva koja predstavlja neki red kao var Red : TipRed. Primjer programa Svi studenti u grupi polažu nekoliko ispita.

BrojIspita):20:1) end. writeln end end. { CitajOcjene } function Prosjek(OcjeneJednogStudenta : OcjeneStudenata. Ispit : OpsegIspita. writeln('Broj studenta writeln('------------- Prosječna ocjena'). Ispit : OpsegIspita.0. Prosjek := Suma / N end. for Ispit := 1 to N do Suma := Suma + OcjeneJednogStudenta[Ispit]. 3. N: OpsegIspita) : real. Ispit:1. Prosjek(Ocjene[Student]. { Brojači } { petlji } begin for Student := 1 to BrojStudenata do begin writeln('Unesi ocjene za studenta '. { Čita podatke u tabelu ocjena } var Student : OpsegStudenata. ': '). readln(Tabela[Student][Ispit]) end. for Student := 1 to BrojStudenata do writeln(Student:8.procedure CitajOcjene(var Tabela : TabelaOcjena). Zadaća 1. . Napišite program koji čita vrijednosti dvije matrice A i B. ----------------'). { Prosjek } begin { Glavni program } CitajOcjene(Ocjene). { Suma ocjena } { Brojač petlje } begin Suma := 0. i računa i štampa njihovu sumu S. Student:2). writeln. { Vraća aritmetičku sredinu prvih "N" ocjena u nizu "OcjeneStudenta" } var Suma : real. for Ispit := 1 to BrojIspita do begin write('Ispit '.

.2. Napišite program koji određuje da li je data matrica: (a) gornja trougaona matrica. Napišite i program koji testira napisanu funkciju. (b) simetrična oko glavne dijagonale.

kurs koji pohađa student.30] of char.. ime. na primjer. Na primjer. odjeljenje. platni broj i iznos plate nekog radnika. 2.. ocjena svih studenata u grupi. ImaginarniDio : real end. i radnika u preduzeću: type Kompleksni = record RealniDio : real. itd. padavina u toku svakog mjeseca u godini. Plata : real end. Odjeljenje : packed array [1. Slogovi kao struktura podataka Nizovi se koriste za smještanje skupine povezanih objekata istog tipa. prvo je potrebno da definiramo odgovarajući slogovni tip. fields) sloga. Kurs = record BrojSatiUSedmici : integer. Struktura podataka koja moze čuvati takvu skupinu raznovrsnih podataka naziva se slog ili zapis (engl. "Odjeljenje". Promjenljive "Ime". npr. . slijedeće definicije tipova uvode slogovne tipove koji predstavljaju kompleksni broj. Definiranje slogovnog tipa Kada želimo da koristimo slogove u Pascal programu. Često je ipak potrebno čuvati skupinu povezanih objekata različitog tipa. "PlatniBroj" i "Plata" zovu se polja (engl. PlatniBroj : integer. Stupanj : char.10] of char.SLOGOVI 1. Prolaz : Boolean end. Radnik = record Ime : packed array [1. record).

if Programiranje. c.Prolaz then write('Bravo!').Dan. Slogovi se mogu prenositi kao parametri u funkcije i procedure. NekaUplata. npr. kao što je prikazano u slijedećem programu. Pojedinačnim poljima u slogu pristupa se po nazivu.Mjesec. koja postavlja vrijednosti u sva njena polja. Naime. Ovdje je napisan jednostavan primjer. c. 23/07/1997). zbog specifičnosti (moglo bi se reći i greške) “read” naredbe Turbo Pascal-a. NekaUplata. Jedan cijeli slog može se dodijeliti drugoj slogovnoj promjenljivoj istog tipa: Hodzic := Kovacevic. i iznos uplate. koji koristi slog za čuvanje podataka o uplati. Turbo Pascal ne dopušta da se pri unosu broja naredbom “read” neposredno iza broja nađe išta što nije razmak! program StampacUplata(input. Da bi se program koristio u Turbo Pascal-u. Slogovne promjenljive Kada smo uveli definicije tipova. NekaUplata. 23 /07/ 1997 umjesto 23/07/1997. Nakon toga. ovaj program ne radi ispravno u Turbo Pascal-u. Slogovna promjenljiva "NovaUplata" se prvo prenosi kao promjenljivi parametar u proceduru "CitajUplatu". 4. c.): Kovacevic.0. za platne spiskove ili za kontrolu u samoposluzi. . Primjer programa (1) Često se zahtijeva program koji štampa detalje o uplatama na predračunskom izvještaju. c. možemo deklarirati slogovne promjenljive: var Hodzic. c. ali u tom slučaju ispred znaka ‘/’ pri unosu datuma moramo unijeti tačno jedan razmak (npr. a zatim ime uplatitelja. koristeći tačku (.Godina).Mjesec. NekaUplata. output). Programiranje : Kurs.Godina). NAPOMENA: Ponovo. treba zamijeniti sa: read(NekaUplata. ona se prenosi kao vrijednosni parametar u proceduru "StampajUplatu" koja ispisuje detalje o uplati u zahtijevanom obliku. Kovacevic : Radnik.Dan.3. c. naredbu read(NekaUplata.Plata := 12000. Program prvo traži da se unese datum uplate u obliku DD/MM/GGGG (npr.

readln.Uplatitelj[i] := ' '.12. writeln. { Maksimalna dužina imena uplatitelja } type Uplata = record Dan : 1. for i := 1 to MaksIme do if not eoln(input) then read(NekaUplata.. i štampa ih u pogodnom obliku } const MaksIme = 30.{ Ovaj program unosi detalje o uplati. NekaUplata. c. { Štampa uplatu u željenom obliku } begin writeln. NekaUplata.. { Brojač slova u uplatiteljevom imenu } { Služi za preskakanje znaka '/' u datumu unesenom u obliku DD/MM/GGGG } begin read(NekaUplata. writeln(NekaUplata. { Čita detalje o uplati } var i : integer. NekaUplata.Mjesec:2. Iznos : real end.Iznos) end.31.2100. NekaUplata. c. Uplatitelj : packed array [1. Nastavak : char. var NovaUplata : Uplata. NekaUplata.Dan:2.MaksIme] of char. Mjesec : 1. writeln(' ':20.Mjesec. readln.Godina).Godina:4). c : char.Uplatitelj).. '/'. '/'.. { Uplata koja ce se štampati } { Korisnikova komanda } procedure CitajUplatu(var NekaUplata : Uplata). . Godina : 1997.Uplatitelj[i]) else NekaUplata. readln(NekaUplata. { CitajUplatu } procedure StampajUplatu(NekaUplata : Uplata).Dan.

na primjer sve uplate uplaćene u proteklom mjesecu.Iznos:4:2). readln(Nastavak) until Nastavak <> 'd' end.30] of char. u slogu. Za modeliranje podataka iz takvih sistema iz realnog svijeta možemo koristiti nizove slogova: nizove čiji je svaki element tipa slog. Ipak ova situacija nije uobičajena u stvarnom životu. StampajUplatu(NovaUplata).. type Radnik = record Ime : packed array [1. polje "Ime" trećeg elementa promjenljive "PlatniSpisak" je PlatniSpisak[3]. SpisakRadnika = array [1. 5.Plata:4:2). slijedeće definicije tipa i deklaracije promjenljivih omogućavaju nam da predstavimo skupinu radnika: const MaksimalniBrojRadnika = 1000. Plata : real end. write('Želite li još uplata (d/n)? '). Svaki element predstavlja slog. Elementima se pristupa na uobičajeni način. Nizovi slogova U prethodnom primjeru zaista nije bilo neophodno čuvati promjenljive koje sadrže ime uplatitelja. PlatniSpisak[i]. writeln end. iznos uplate itd.Ime Tako. NekaUplata. PlatniBroj : integer.. ako su "i" i "DuzinaPlatnogSpiska" cjelobrojne promjenljive. preko indeksa. Mnogo česće želimo da obrađujemo skupinu slogova. var PlatniSpisak : SpisakRadnika.10] of char. { StampajUplatu } begin { Glavni program } repeat writeln('Unesi detalje o uplati: ').Ime. Na primjer. CitajUplatu(NovaUplata). možemo pisati: for i := 1 to DuzinaPlatnogSpiska do writeln(PlatniSpisak[i]. . jer smo mi u jednom trenutku radili samo sa jednom uplatom (iako je upotreba tipa sloga omogućila da prenosimo u procedure sve podatke za obradu koristeci samo jedan parametar).. tako na primjer. Odjeljenje : packed array [1.writeln(' ':20.MaksimalniBrojRadnika] of Radnik. ili podatke o svim radnicima u preduzeću.

Prolaz : Boolean end..2000 end. VrijemePregleda : Vrijeme. Mjesec : 1..30] of char.Dan predstavlja dan slijedećeg zakazanog pregleda. Ocjene : array [1. Datum = record Dan : 1. kao u slijedećem primjeru tipa koji predstavlja podatke o studentu: type PodaciOStudentu = record Ime : packed array [1... ili slogovi. DatumPregleda : Datum end.31. tada pojedinačnim dijelovima (slogovnim poljima) promjenljive "SlijedeciPregled" pristupamo pomoću operatora tačka.DatumPregleda. ZakazaniPregled = record ImePacijenta : packed array [1. na primjer tip "ZakazaniPregled" koji se može koristiti za evidenciju zakazivanja pregleda kod ljekara: type Vrijeme = record Sati : 0. Struktuirana polja Polja slogova mogu i sama biti struktuiranog (složenog) tipa. Ako imamo promjenljivu takvog tipa: var SlijedeciPregled : ZakazaniPregled. Tako SlijedeciPregled.23.da odštampamo ime i platu za svakog radnika u preduzeću. Minute : 0. Ona mogu biti nizovi.20] of char.59 end. 6.12... . Prosjek : real..5] of integer.. Godina : 1990.

7. Dizajniranje podataka
Koristeci Pascal-ove struktuirane tipove, nizove i slogove, možemo sagraditi složene strukture podataka koje susrećemo u sistemima u realnom životu. Na primjer u evidentiranju zakazivanja pregleda kod ljekara potrebno je čuvati detalje o mnogo naručenih pregleda, tako da možemo koristiti niz (ovdje podrazumijevamo da je negdje ranije definirana konstanta pod imenom "MaksimalniBrojPacijenata"): type SpisakZakazanihPregleda = array [1..MaksimalniBrojPacijenata] of ZakazaniPregled; var Pregledi : SpisakZakazanihPregleda; Pojedinačnim dijelovima pristupamo pomoću indeksiranja i operatora tačka. Na primjer, dan i-tog zakazanog pregleda u spisku je: Pregledi[i].DatumPregleda.Dan Dizajniranje podataka podrazumijeva dizajniranje takvih struktura podataka koji modeliraju područje problema na način koji se može lako obrađivati u programu. Ako se to ispravno učini, većina složenih situacija u realnom svijetu može se predstaviti pomoću struktura podataka u programu, što čini razvoj algoritama jednostavnijim.

8. Primjer programa (2)
Ovaj poduži program čita imena i ocjene sa ispita za jednu grupu studenata. Da bi se uštedilo na unosu sa tastature, podaci će biti pročitani iz datoteke na disku (detalji o tome kako se to radi biće dati u slijedećem poglavlju). Program zatim obrađuje sve studentske slogove, racunajuci prosječnu ocjenu i donoseći odluku prošao/pao za svakog studenta. Na kraju, program štampa tabelu rezultata. Slogovi se koriste za smještanje imena, ocjena, prosjeka i odluke za svakog studenta. Program koristi niz slogova, da predstavi cijelu grupu. Iza programa je prikazan i njegov strukturni dijagram. program IspitniSlogovi(Podaci, output); { Ovaj program obrađuje ispitne ocjene za grupu studenata, da odredi spisak studenata koji su položili ili pali. Svaki student ima ocjenu za svaki od skupine ispita. Prolaz se postiže ako je prosječna ocjena veća ili jednaka od prolazne ocjene } const MaksimalnaDuzinaImena = 20; BrojIspita = 5; ProlaznaOcjena = 50; type OpsegGrupe = 1..50; { Maksimalna dužina imena } { Broj ispita } { Najmanja prolazna ocjena } { Opseg grupe, }

OpsegDuzineImena = 1..MaksimalnaDuzinaImena; { dužine imena, } OpsegIspita = 1..BrojIspita; { broja ispita i } OpsegOcjena = 1..100; { mogućih ocjena } ImeStudenta = packed array [OpsegDuzineImena] of char; OcjeneStudenta = array [OpsegIspita] of OpsegOcjena; PodaciOStudentu = record Ime : ImeStudenta; Ocjene : OcjeneStudenta; Prosjek : real; Prolaz : Boolean end; SpisakGrupe = array [OpsegGrupe] of PodaciOStudentu; var Podaci : text; Grupa : SpisakGrupe; BrojStudenata : OpsegGrupe; { Ulazna datoteka } { Niz slogova o studentima }

procedure CitajStudente(var Spisak : SpisakGrupe; DuzinaSpiska : OpsegGrupe); { Čita podatke o svim studentima u spisku } var Student : OpsegGrupe; procedure CitajJednogStudenta(var Student: PodaciOStudentu); { Čita ime i ocjene za jednog studenta } var i : OpsegDuzineImena; Ispit : OpsegIspita; { Brojač slova u imenu } { Brojač ispita }

begin for i := 1 to MaksimalnaDuzinaImena do read(Podaci, Student.Ime[i]); for Ispit := 1 to BrojIspita do read(Podaci, Student.Ocjene[Ispit]); readln(Podaci) end; { CitajJednogStudenta } begin { CitajStudente } for Student := 1 to DuzinaSpiska do CitajJednogStudenta(Spisak[Student]) end; { CitajStudente } procedure ObradiRezultate(var Spisak : SpisakGrupe; DuzinaSpiska : OpsegGrupe;

ProlaznaOcjena : OpsegOcjena); { Računa prosjek i indikator prolaznosti za svakog studenta u spisku } var Student : OpsegGrupe; { Brojač studenata } function SrednjaVrijednost(Ocjene : OcjeneStudenta; N : OpsegIspita) : real; { Vraća srednju vrijednost prvih "N" ocjena u nizu "Ocjene" } var Suma : real; Ispit : OpsegIspita; { Zbir ocjena } { Brojač petlje }

begin Suma := 0.0; for Ispit := 1 to N do Suma := Suma + Ocjene[Ispit]; SrednjaVrijednost := Suma / N end; { SrednjaVrijednost } begin { ObradiRezultate } for Student := 1 to DuzinaSpiska do begin Spisak[Student].Prosjek := SrednjaVrijednost(Spisak[Student].Ocjene, BrojIspita); if Spisak[Student].Prosjek >= ProlaznaOcjena then Spisak[Student].Prolaz := true else Spisak[Student].Prolaz := False end end; { ObradiRezultate } procedure StampajRezultate(Spisak : SpisakGrupe; DuzinaSpiska : OpsegGrupe); { Štampa spisak rezultata } var Student : OpsegGrupe; { Brojač studenata } procedure StampajJedanRezultat(Student : PodaciOStudentu); { Štampa rezultate ispita za jednog studenta } var Ispit : OpsegIspita; { Brojač ocjena ispita }

begin { StampajJedanRezultat }

write(Student.Ime, ' '); for Ispit := 1 to BrojIspita do write(Student.Ocjene[Ispit]:8); write(Student.Prosjek:10:1); if Student.Prolaz then writeln(' PROSAO') else writeln(' PAO') end; { StampajJedanRezultat }

begin { StampajRezultate } writeln; for Student := 1 to DuzinaSpiska do StampajJedanRezultat(Spisak[Student]) end; { StampajRezultate } begin { Glavni program } assign(Podaci, 'OCJENE.DAT'); { U VAX Pascal-u naredbu assign(Podaci, 'OCJENE.DAT') treba } { zamijeniti sa open(Podaci, 'OCJENE.DAT') } reset(Podaci); readln(Podaci, BrojStudenata); CitajStudente(Grupa, BrojStudenata); ObradiRezultate(Grupa, BrojStudenata, ProlaznaOcjena); StampajRezultate(Grupa, BrojStudenata) end. Slijedi primjer datoteke podataka koja se može koristiti za demonstraciju rada programa: 12 Medvjed Jogi Dusko Dugousko Kojot Vili Paja Patak Fred Kremenko Vilma Kremenko Miki Maus Mini Maus Oliva Mornar Popaj Barni Kamenko Beti Kamenko 52 25 38 48 25 27 58 53 73 20 27 70 79 32 37 62 62 56 47 68 54 45 56 72 36 15 62 59 24 23 47 43 30 36 23 55 54 22 84 75 59 40 67 54 70 25 40 48 75 29 80 72 38 52 55 65 55 40 52 52

Primijetimo da se u ovom programu konstrukcija if Spisak[Student].Prosjek >= ProlaznaOcjena then

jediničnu cijenu robe. to znači da treba pozvati dobavljača da se obezbijede efikasne zalihe robe).Prolaz := true else Spisak[Student]. Napišite definicije slogovnog tipa koje predstavljaju slijedeće objekte: Fudbalski tim (za program koji odrzava tablicu lige). minimalnu količinu (ako je količina robe jednaka ili manja od minimalne količine. i ime dobavljača.Prolaz := Spisak[Student]. (c) Dnevni meteorološki izvjestaj za neki grad. količinu u skladištu.Spisak[Student]. Obrada i štampanje rezultata ispita IspitniSlogovi Broj učenika Broj učenika Prolazna Spisak ocjena grupa Čitanje spiska podataka o studentima CitajStudente Podaci o studentu Čitanje podataka o jednom studentu CitajJednogStudenta Obrađeni Obrađeni spisak spisak grupe grupe Broj učenika Štampanje spiska rezultata StampajRezultate Potpuni podaci o studentu Štampaj rezultat za jednog studenta StampajJedanRezultat Obrada spiska rezultata ObradiRezultate Ocjene jednog studenta Prosječna ocjena Računa prosječnu ocjenu SrednjaVrijednost 9. (a) . Zadaća 1. (b) Robu u skladistu za svrhe inventure. Potrebno je čuvati naziv robe. broj skladišta.Prosjek >= ProlaznaOcjena Na slijedećoj slici je prikazan strukturni dijagram programa (obratite pažnju da strukturni dijagram ne mora da odražava stvarna imena parametara upotrebljenih u programu).Prolaz := False mogla zamijeniti jednostavnijom ali manje očiglednom konstrukcijom: Spisak[Student].

Napišite program koji čita spisak podataka o robama u skladištu (kao što je opisano gore). i ime dobavljača za one artikle čija je količina u skladištu manja od dozvoljene količine. i štampa izvještaj koji prikazuje naziv robe.2. količinu u skladištu. broj skladišta. Umjesto unosa podataka o svim artiklima sa tastature. oni se mogu pročitati iz tekstualne datoteke kreirane pomoću editora. . na način opisan u slijedećem poglavlju.

vanjskim datotekama (engl. output. program KontrolaSkladista(input. U Pascal programima. files) omogućavaju trajan smještaj informacija na vanjskom mediju za smještanje. otvoriti taj dokument koji je bio sačuvan kao datoteka. i nastaviti raditi sa njim. Poredak datotečnih parametara nije bitan. datotečne promjenljive se koriste za kreiranje i pristup datotekama na disku. Sve primjene računara gdje podaci moraju biti sačuvani izmedju dva pokretanja programa zahtijevaju upotrebu datoteka. DatotekaSkladista. external files). vanjske datoteke moraju biti pobrojane u zaglavlju programa kao datotečni parametri (verzija Turbo Pascal ovo ne zahtijeva. definiraju promjenljivu "Brojevi" koja predstavlja vanjsku datoteku čije su komponente tipa "integer" (cijeli brojevi). Datotečni parametri Datotečne promjenljive koje predstavljaju trajne. od programa za obradu teksta može se zahtijevati da sačuva na disk dokument sa kojim radimo. tako da u budućnosti bilo kada možemo ponovo pokrenuti program. program GovorGreteGarbo(Garbo). tzv. 2. . definicija tipa type DatotekaCijelihBrojeva = file of integer. Na primjer. Imena "input" i "output" su datotečni parametri koji predstavljaju standardne ulazne i izlazne tokove za program (danas uglavnom tastatura i ekran monitora). i deklaracija promjenljive var Brojevi : DatotekaCijelihBrojeva. Datotečne promjenljive čuvaju slijed koji se sastoji od proizvoljnog broja komponenti (taj slijed obično odgovara vanjskoj datoteci na disku). obično disku. Sintaksa definicije tipa datoteke data je slijedećim dijagramom: type ime = file of naziv tipa komponenti Na primjer. ali je dobra praksa uvijek navoditi datotečne parametre radi konzistentnosti sa drugim izvedbama Pascal-a). Narudzbe).DATOTEKE 1. Datotečne promjenljive Datoteke (engl. output). Slijedeći primjeri prikazuju zaglavlja programa sa datotecnim parametrima: program StampacUplata(input. Vrijednosti pojedinačnih komponenti mogu biti bilo kojeg tipa (izuzetak je da komponenta neke datoteke ne može biti druga datoteka).

Sve ostale datotečne promjenljive moraju se deklarirati prije upotrebe. Na žalost. To znači da programi koji koriste vanjske datoteke nisu "prenosivi" sa jedne izvedbe Pascal-a na drugu. poput: open(Brojevi. Na primjer. Mi još moramo "povezati" te promjenljive sa stvarnim vanjskim datotekama čija stvarna imena (fizička imena) odgovaraju pravilima za davanje imena datoteka na odgovarajućem operativnom sistemu. osim tamo gdje je eksplicitno naglašeno. new). U Turbo Pascal-u na PC-u umjesto naredbe "open" koristimo naredbu "assign" koja ima tačno dva parametra: assign(Brojevi. ali je dobra praksa da se one zatvore eksplicitno.DAT').oni su već unaprijed definirani (ugradjeni u svaki program). razlike nisu prevelike. standardni Pascal ne propisuje nikakav poseban način da se to uradi.DAT". upravo kao i sve ostale promjenljive.DAT'. Ipak. npr. ili "old" ako želimo da koristimo datoteku koja vec postoji. i obratno. tako da razne Pascal izvedbe imaju svoje načine. Prvi parametar procedure "open" predstavlja datotečnu promjenljivu. Na sreću. Treći parametar je parametar "istorije datoteke" koji treba da ima vrijednost "new" ako želimo da kreiramo novu datoteku. dok je drugi parametar string (konstanta ili promjenljiva) koja sadrži fizičko ime vanjske datoteke. 'BROJEVI. programi napisani u VAX Pascal-u neće se moći prevesti i izvršavati sa Turbo Pascal-om na PC-u. ove naredbe se moraju uključiti u program. Na primjer. moramo u u program dodati naredbu "open". 3. bez ikakvog značenja izvan programa u kojem su deklarirani. ako želimo da povežemo promjenljivu "Brojevi" sa datotekom na disku čije je fizicko ime "BROJEVI. ako želite da on radi! . Povezivanje datotečnih promjenljivih sa vanjskim datotekama Naše datotečne promjenljive su samo logička imena u Pascal programu. VAX Pascal i Turbo Pascal posjeduju i naredbu "close".Programi ne zahtijevaju deklaraciju promjenljivih "input" i "output" kao datotečnih promjenljivih . koja zatvara datoteku kada ona više nije potrebna. U narednim primjerima ove "nestandardne" naredbe biće izostavljene. 'BROJEVI. close(Brojevi). Sve datoteke se automatski zatvaraju po završetku programa. u VAX Pascal-u.

NekaPromjenljiva. 4. Vrijednosti bilo kojih prostih ugrađenih tipova. tako da nema potrebe da ovo pišete! } Može se napisati deklaracija promjenljive koja predstavlja tekstualnu datoteku: var MojaDatoteka : text. možemo pisati: writeln(MojaDatoteka. i koji se može prikazati na ekran koristeći DOS (ili VMS) komandu TYPE (npr. i to prilično suštinske na implementacionom nivou. 6:2). Kada se datotečna promjenljiva zada kao prvi parametar neke od ovih procedura.1 Deklaracija tekstualnih datotečnih promjenljivih Tekstualne datoteke su datoteke čije su komponente tipa "char".2 Upis u tekstualne datoteke Prije upisa podataka u tekstualnu datoteku. jer je u njima svaki znak predstavljen svojom ASCII šifrom (engl. { Ugrađeno. naredba rewrite(MojaDatoteka). Ako datoteka već postoji. svi podaci koji su postojali u njoj biće uništeni. One se ponekad zovu i "ASCII datoteke".4. Naredni primjer kreira tekstualnu datoteku koja sadrzi prvu rečenicu koju je glumica Greta Garbo izgovorila u filmu (rečenica je ostavljena u originalu na engleskom jeziku. Na primjer. ili stringova (pakovanih nizova znakova) mogu se upisivati u tekstualnu datoteku. datoteka mora biti pripremljena za upis korištenjem procedure "rewrite". biće kreirana. 'neki tekst'. U Turbo Pascal-u izmedju tipova "text" i "file of char" ipak postoje razlike. To je tip datoteka koji se tipično kreira pomoću editora (poput DOS-ovog ili VMS-ovog programa EDIT ili Windows-ovog NOTEPAD-a).DAT). jer se radi o žargonu. i teško je napraviti prevod koji će vjerno oslikati žargon): program GovorGreteGarbo(Garbo). . Ako datoteka ne postoji. Na primjer. To je kao da svaki program automatski uključuje definiciju: type text = file of char. ispis se usmjerava u tu datoteku. i nova prazna datoteka će biti kreirana. ali su sa korisničkog aspekta razlike samo u detaljima koji izlaze izvan okvira ovog kursa. Tip "text" je ugrađen u Pascal. Tekstualne datoteke 4. ima za posljedicu kreiranje prazne datoteke. TYPE PODACI. Procedure "write" i "writeln" mogu se koristiti za upis podataka u tekstualnu datoteku. ASCII code).

. Ova funkcija se veoma često koristi za upravljanje petljom koja neprekdno čita podatke iz datoteke sve dok se kraj datoteke ne dostigne: . Vrijednost bilo kojeg ugrađenog prostog tipa moze se čitati iz tekstualne datoteke. 'Gimme a viskey. Funkcija eof(f) vraća "true" ako je pokazivač datoteke "f" na kraju datoteke. writeln(Garbo... Oni se koriste prilikom čitanja iz datoteka za određivanje da li je kraj datoteke ili kraj linije dostignut.. u suprotnom vraća "false". RESET postavlja pokazivač na početak datoteke Komponente datoteke (u tekstualnim datotekama su to znakovi) . čitanje se vrši iz te datoteke. 4. v2).var Garbo : text. readln(MojaDatoteka. koji označava mjesto u datoteci gdje će se izvršiti slijedeća operacija čitanja ili pisanja.4 Funkcije "eof" i "eoln" Funkcije "eof" i "eoln" su ugrađene funkcije koje vraćaju rezultat tipa "Boolean". Procedura "reset" postavlja pokazivač nazad na početak datoteke (pogledajte sliku). Na primjer možemo pisati: read(MojaDatoteka. Pokazivač nakon nekoliko operacija čitanja Podaci se mogu čitati iz tekstualne datoteke koristeći procedure "read" i "readln".3 Čitanje iz tekstualnih datoteka Procedura "reset" se koristi za pripremu datoteke za čitanje. Datoteka . 4. Kada se datotečna promjenljiva zada kao prvi parametar ovih procedura. NekaPromjenljiva). Korisno je da zamislimo da uvijek imamo "pokazivač" pridružen svakoj datoteci. begin rewrite(Garbo). Njen parametar je datotečna promjenljiva: reset(MojaDatoteka). v1. baby!') end. an don'' be stingy.

Brojac : integer. var Podaci : text. Znak : char. Podaci). Brojac := Brojac + 1 end. Parametar funkcije "eoln" mora biti tekstualna datoteka. slično kao program WC (word counter) na UNIX operativnom sistemu. writeln('Broj znakova = '. zarezom itd. Znak). tj. . Zadaća 1. Brojac) end. To smo već koristili da čitamo znakove sa tastature sve dok korisnik ne pritisne taster "RETURN" (ili "ENTER"): while not eoln(input) do { Čitaj slijedeći znak } Parametar funkcije "eof" može biti datoteka proizvoljnog tipa. 5. Podrazumijevajte da je datoteka ispravna. Napravite izmjene u tom programu tako da on čita podatke o studentima iz ulazne datoteke sve dok se ne dostigne kraj datoteke. 2.while not eof(MojaDatoteka) do { Čitanje iz datoteke "MojaDatoteka" } Funkcija eoln(f) vraća "true" ako je slijedeći znak u datoteci "f" oznaka kraja reda (engl. Riječ se definira kao bilo koji niz znakova bez razmaka koji završavaju razmakom. u suprotnom vraća "false". riječi i linije u tekstualnoj datoteci. Brojac := 0. U programu "IspitniSlogovi" (u poglavlju posvećenom slogovima). program BrojacZnakova(output. while not eof(Podaci) do begin read(Podaci. Primjer programa Ovdje je dat jednostavan program koji broji znakove u tekstualnoj datoteci. begin reset(Podaci). newline character). prva linija u ulaznoj datoteci morala je sadržavati broj studenata u grupi (u navedenom primjeru to je broj 12). da svaka linija zaista sadrži ime studenta i potpun skup ocjena. pomoću koje je program saznavao koliko ima studenata za koje treba učitati podatke. ili znakom interpunkcije (tačkom. 6. Proširite program "BrojacZnakova" tako da broji znakove. novom linijom. bez potrebe da se unaprijed navodi koliko ih ima. i ispisuje ta tri rezultata.).

.

Ocjene : OcjeneStudenta. dodaje sadržaj promjenljive "X" u datoteku "MojaDatoteka". Pojam binarne datoteke Tekstualne datoteke su datoteke cije su komponente tipa "char". Boje = (Crvena. 2. Zelena. X). Slijedi nekoliko primjera: type Student = record Ime : ImeStudenta. zbog toga što podaci u njima nisu smješteni u obliku ASCII šifrovanih znakova. čita slijedeću komponentu iz datoteke "MojaDatoteka" i smjesta je u promjenljivu "X". . Međutim. write(MojaDatoteka. X). niti prikazivati pomocu DOS ili VMS komande TYPE. mi možemo definirati tipove i deklarirati datotecne promjenljive koje čuvaju vrijednosti bilo kojeg struktuiranog ili prostog tipa. Čitanje i upis u binarne datoteke Za pripremu binarnih datoteka za čitanje i upis koriste se procedure "reset" i "rewrite". i pomjera "pokazivač datoteke" na slijedeću komponentu. DatotekaStudenata = file of Student. Prvi parametar mora biti datotečna promjenljiva. Tako npr. Plava. Mjerenja : DatotekaBrojeva. Zuta). Boje : DatotekaBoja. Takve datoteke ne mogu se kreirati ili pregledati pomocu editora. Ponovo je prvi parametar datotečna promjenljiva. Tako npr. DatotekaBoja = file of Boja. dok je drugi parametar promjenljiva koja smješta pročitanu komponentu. DatotekaBrojeva = file of real. Prolaz : Boolean end. Datoteke koje nisu tekstualne datoteke često se nazivaju binarne datoteke. Procedura "read" čita jednu komponentu datoteke iz datoteke. read(MojaDatoteka. kao za tekstualne datoteke.BINARNE DATOTEKE 1. a drugi promjenljiva koja sadrži komponentu koja će biti smještena u datoteku. Procedura "write" dodaje novu komponentu u datoteku. var Grupa : DatotekaStudenata. Prosjek : real.

i : integer. output). X. for i := 1 to 1000 do write(Brojevi. ne smijemo pisati: write(MojaDatoteka. program CitajCijeleBrojeve(Brojevi. podrazumijevajući da je "X" promjenljiva tipa "integer". već: X := 5. tj. ovdje su data dva programa koji koriste datoteku cijelih brojeva. već: write(MojaDatoteka. a ne konstanta ili izraz.I za čitanje i za pisanje važi slijedeće: ako datotečna promjenljiva nije tipa "text". var Brojevi : DatotekaCijelihBrojeva. drugi parametar u proceduri "write" mora biti promjenljiva. Y). { Čita sve vrijednosti iz datoteke ”Brojevi” i ispisuje ih } type DatotekaCijelihBrojeva = file of integer. Kao jednostavan primjer. X). kod binarnih datoteka. Y). samo jedna komponenta se smije zadati u procedurama "read" ili "write". ne smijemo pisati: write(MojaDatoteka. program PisiCijeleBrojeve(Brojevi). Prvi kreira datoteku koja sadrži cijele brojeve od 1 do 1000. Tako ako je "MojaDatoteka" datoteka cijelih brojeva (tipa "file of integer"). write(MojaDatoteka. Takođe. i) end. . Procedure "readln" i "writeln" ne mogu se koristiti sa binarnim datotekama. dok drugi čita sve vrijednosti iz tako kreirane datoteke i ispisuje ih. 5). X). write(MojaDatoteka. { Kreira datoteku koja sadrži cijele brojeve od 1 do 1000 } type DatotekaCijelihBrojeva = file of integer. begin rewrite(Brojevi).

Datoteke slogova U mnogim primjenama potrebno je koristiti datoteke čije su komponente slogovi. writeln end. Uočite da su procedure "CitajJednogStudenta" (koja čita ime i ocjene za jednog studenta u slogovnu promjenljivu) i "StampajJedanRezultat" (koja prikazuje jedan red tabele rezultata) prosto prepisane u ovaj program iz programa "IspitniSlogovi" bez ikakve izmjene. prosječna ocjena i indikator prolaza) u nizu koji se nalazio u memoriji (to je bio niz "SpisakGrupe"). Jedina razlika je sto je proceduri "CitajJednogStudenta" dodan još jedan parametar . ili podatke o zalihama robe u skladištu nekog preduzeća. čuvali smo podatke o svakom studentu (ime.var Brojevi : DatotekaCijelihBrojeva.. Slijedeci). DatotekaGrupe = file of PodaciOStudentu.5] of integer. i koristi podatke iz nje da prikaže spisak rezultata. osim što umjesto definiranja tipa niza mi definiramo tip koji predstavlja datoteku slogova o studentima: type PodaciOStudentu = record Ime : packed array [1. Slijedeci : integer. var Grupa : DatotekaGrupe. Na primjer.30] of char. i čitaćemo slogove iz te datoteke sa ciljem da prikažemo tabelu rezultata. U slijedećem primjeru ćemo kreirati datoteku slogova o studentima. while not eof(Brojevi) do begin read(Brojevi. Program "CitajGrupu" čita svaki slog iz te datoteke. tada bi trebali imati slog za svakog studenta ili robu. ocjene sa ispita. Program "NapraviGrupu" čita podatke o svakom studentu iz tekstualne datoteke. begin reset(Brojevi). Prolaz : Boolean end. Prosjek : real. Ocjene : array [1.. U programu "IspitniSlogovi" (u poglavlju o slogovima). write(Slijedeci:5) end. Definicije tipova koristene u ovim programima su uglavnom iste kao one korištene u programu "IspitniSlogovi". i čuvati te slogove trajno u datoteci na disku. 3. računa prosječnu ocjenu i indikator prolaza. U tome i jeste svrha dobro napisanih procedura. i zapisuje obrađeni slog u datoteku. ako želimo da čuvamo podatke o svim studentima na fakultetu. Data su dva programa.

{ Opseg ispitnih ocjena } ImeStudenta = packed array [OpsegDuzineImena] of char. Parametri datotečnog tipa moraju uvijek biti promjenljivi parametri. OcjeneStudenta = array [OpsegIspita] of OpsegOcjena.. i ta promjena mora da “preživi” kraj procedure! program NapraviGrupu(Podaci. i kreira datoteku koja sadrži detaljne podatke o studentima.. var Ulaz : text). { Opseg broja ispita } OpsegOcjena = 1. Grupa).. { Pomoćna promjenljiva koja smješta slijedeću skupinu podataka o studentima koji se obrađuju } procedure CitajJednogStudenta(var Student : PodaciOStudentu. { Opseg dužine imena studenta } OpsegIspita = 1. { Maksimalna dužina imena } { Broj ispita } { Najmanja prolazna ocjena } type OpsegGrupe = 1.nazvan "Ulaz" tipa "text" čime je izbjegnuta upotreba globalne datotečne promjenljive "Podaci" u proceduri (ista stvar se mogla uraditi i u programu "IspitniSlogovi"). što je uvijek slučaj kada se radi sa datotekama. ProlaznaOcjena = 50.50.BrojIspita. DatotekaGrupe = file of PodaciOStudentu. { Ulazna datoteka sa imenima i ocjenama } Grupa : DatotekaGrupe. { Izlazna datoteka } SlijedeciStudent : PodaciOStudentu. Ocjene : OcjeneStudenta. računa prosječnu ocjenu i indikator prolaznosti ”prošao/pao”. { Ovaj program čita ispitne ocjene za grupu studenata. { Čita ime i ocjene za jednog studenta } var .MaksimalnaDuzinaImena. } const MaksimalnaDuzinaImena = 20. BrojIspita = 5. Prosjek : real.100. Primijetite da je parametar "Ulaz" datotečnog tipa "text" deklariran kao promjenljivi parametar (sa "var" konstrukcijom). PodaciOStudentu = record Ime : ImeStudenta. Razlog za to je slijedeći: iako procedura “CitajJednogStudenta” prividno ne mijenja datoteku koja joj se prenosi kao parametar. Prolaz : Boolean end. var Podaci : text. { Opseg veličine jedne grupe } OpsegDuzineImena = 1.. ona ipak mijenja jednu njenu komponentu (pokazivač na tekući element u datoteci).

{ Zbir ocjena } { Brojač petlje } begin Suma := 0.Prolaz := true else Student. { Priprema tekstualnu datoteku za čitanje } rewrite(Grupa). write(Grupa. { Brojač slova u imenu } { Brojač ispita } begin for i := 1 to MaksimalnaDuzinaImena do read(Ulaz.Ocjene.Prosjek >= ProlaznaOcjena then Student.Prolaz := false end. { Dopisuje novi slog u izlaznu datoteku } end end. Ispit : OpsegIspita. { SrednjaVrijednost } begin { ObradiJednogStudenta } Student.0. for Ispit := 1 to BrojIspita do read(Ulaz.Ime[i]). if Student. SlijedeciStudent). { CitajJednogStudenta } procedure ObradiJednogStudenta(var Student : PodaciOStudentu. { Vraća srednju vrijednost prvih "N" ocjena u nizu "Ocjene" } var Suma : real. for Ispit := 1 to N do Suma := Suma + Ocjene[Ispit]. { Računa prosjek i indikator prolaza za jednog studenta } function SrednjaVrijednost(Ocjene : OcjeneStudenta. { ObradiRezultate } begin { Glavni program } reset(Podaci).Ocjene[Ispit]). Student.Prosjek := SrednjaVrijednost(Student. Student. . ProlaznaOcjena : OpsegOcjena). { Kreira izlaznu datoteku } while not eof(Podaci) do begin CitajJednogStudenta(SlijedeciStudent.i : OpsegDuzineImena. SrednjaVrijednost := Suma / N end. Podaci). N : OpsegIspita) : real. readln(Ulaz) end. ProlaznaOcjena). Ispit : OpsegIspita. BrojIspita). ObradiJednogStudenta(SlijedeciStudent.

if Student. ' ').Ocjene[Ispit]:8). output). procedure StampajJedanRezultat(Student : PodaciOStudentu).. DatotekaGrupe = file of PodaciOStudentu.program CitajGrupu(Grupa. { Opseg veličine jedne grupe } OpsegDuzineImena = 1. { Opseg broja ispita } OpsegOcjena = 1.Prolaz then writeln(' PROŠAO') else writeln(' PAO') end.BrojIspita.100. { Čita datoteku slogova o studentima i ispisuje spisak rezultata } const MaksimalnaDuzinaImena = 20.50. for Ispit := 1 to BrojIspita do write(Student. Prolaz : Boolean end. Prosjek : real.MaksimalnaDuzinaImena. BrojIspita = 5.. var Grupa : DatotekaGrupe. OcjeneStudenta = array [OpsegIspita] of OpsegOcjena.Ime.Prosjek:10:1). write(Student.. { Brojač ocjena ispita } begin { StampajJedanRezultat } write(Student. { Opseg dužine imena studenta } OpsegIspita = 1. Ocjene : OcjeneStudenta. SlijedeciStudent : PodaciOStudentu. { StampajJedanRezultat } begin { Glavni program } reset(Grupa). PodaciOStudentu = record Ime : ImeStudenta. { Maksimalna dužina imena } { Broj ispita } type OpsegGrupe = 1.. { Pripremi ulaznu datoteku za čitanje } while not eof(Grupa) do . { Štampa rezultate ispita za jednog studenta } var Ispit : OpsegIspita. { Opseg ispitnih ocjena } ImeStudenta = packed array [OpsegDuzineImena] of char.

.begin read(Grupa. SlijedeciStudent). StampajJedanRezultat(SlijedeciStudent) end end.

SKUPOVI
1. Skupovni literali
Pascal dopušta definiranje skupova (engl. set), koji predstavljaju skupinu elemenata kod kojih poredak nije bitan. Pascal skupovi posjeduju većinu svojstava i operacija koje posjeduju skupovi u matematici. Skupovi sa konstantnim članovima, nazvani skupovni literali, mogu se formirati pomoću spiska elemenata ili opsega elemenata, uokvirenih unutar uglastih zagrada. Na primjer, tipični skupovi su: ['A', 'E', 'I', 'O', 'U'] ['0'..'9'] [Apr, Jun, Sep, Nov] [0..100] { { { { Skup Skup Skup Skup samoglasnika } znakova za cifre } mjeseci sa 30 dana } mogućih bodova na ispitu }

Nažalost, u standardnom Pascal-u ovi skupovni literali ne mogu se dodijeliti imenima konstanti u "const" sekciji, npr. nije moguće napisati: const SkupCifara = ['0'..'9']; Takođe, za razliku od skupova u matematici, svi skupovi u Pascal-u moraju se sastojati od elemenata istog tipa. Tako slijedeći skup nije dozvoljen: [3,'a',Apr]

2. Operator "in"
Operator "in" u Pascal-u je operator pripadnosti. Izrazi poput Znak in ['0'..'9'] su Bulovi izrazi. Tako mozemo napisati naredbe poput: DaLiJeCifra := Znak in ['0'..'9']; if Mjesec in [Apr, Jun, Sep, Nov] then BrojDana := 30; Testiranje pripadnosti je ubjedljivo najčešća skupovna operacija u Pascal programima.

3. Skupovni tipovi
Ako se skup koristi više nego jedamput, ili ako nam je potreban skup čiji se članovi mogu mijenjati, tada je potrebno definirati skupovni tip, zajedno sa skupovnim promjenljivim tog tipa. Skupovni tip se definira od baznog tipa (to je tip elemenata skupa), koji može biti pobrojani tip, tip "char", tip "Boolean", manji poddomenski tip tipa "integer", ili bilo koji poddomenski tip od gore definiranih tipova. Primjeri baznih tipova su: type

Mjeseci = (Jan, Feb, Mar, Apr, Maj, Jun, Jul, Aug , Sep, Okt, Nov, Dec); Bodovi = 0..100; VelikaSlova = 'A'..'Z'; MalaSlova = 'a'..'z'; Sintaksa za definiranje skupovnog tipa je: type ime = set of ime baznog tipa

Primjeri skupovnih definicija su: type SkupMjeseci = set of Mjeseci; SkupBodova = set of Bodovi; SkupZnakova = set of char; SkupVelikihSlova = set of VelikaSlova; SkupMalihSlova = set of MalaSlova; Sada možemo definirati promjenljive skupovnih tipova: var SviMjeseci, MjeseciSa30Dana : SkupMjeseci; GranicniBodovi : SkupBodova; SvaMalaSlova : SkupMalihSlova; Slova, Cifre : SkupZnakova; Ovim promjenljivim mogu se dodijeliti skupovne vrijednosti prikladnih tipova: SviMjeseci := [Jan..Dec]; MjeseciSa30Dana := [Apr, Jun, Sep, Nov]; GranicniBodovi := [50, 60, 70, 80, 90]; Cifre := ['0'..'9']; Slova := []; { Ovo je primjer kako se zadaje prazan skup } SvaMalaSlova := ['a'..'z']; Zbog načina kako se skupovi realiziraju interno u prevedenom Pascal programu, obično postoji ograničenje na maksimalan broj različitih vrijednosti koje smije poprimiti bazni tip. U Turbo Pascal-u, na primjer, gornja granica je 255. Tako definicija poput: type Brojevi = set of integer; neće biti prihvaćena. { NEISPRAVNO!!! }

4. Skupovni operatori
Već smo se upoznali sa "in" operatorom, a postoji još operatora koji su primjenljivi na skupove. Postoji pet relacionih operatora, koji se mogu koristiti za konstrukciju Bulovih izraza:

in = <=

<> >=

pripadnost skupu jednakost i nejednakost skupova podskup i nadskup

i tri operatora koji daju izraze čiji je tip vrijednosti skup: + * unija skupova presjek skupova razlika skupova

5. Operacije nad skupovima
Skupovnim promjenljivim se mogu dodijeliti skupovni izrazi, korištenjem gore navedenih skupovnih izraza. Na primjer, nakon deklaracije var MjeseciSa31Dan : SkupMjeseci; možemo pisati: MjeseciSa31Dan := SviMjeseci - MjeseciSa30Dana - [Feb]; Nažalost, ne postoji ugrađena (predefinisana) procedura za unos skupova (sa tastature). Za unos vrijednosti sa ulaza i njihovo dodavanje u skup, moramo prvo inicijalizirati skup na vrijednost prazan skup, i koristiti operaciju unija za pojedinačno dodavanje svake pročitane vrijednosti. Slijedeći isječak programa konstruira skup koji sadrži znakove koji su uneseni u ulaznoj liniji: var Znakovi : SkupZnakova; Znak : char; { Prazan skup }

begin Znakovi := [];

while not eoln(input) do begin read(Znak); Znakovi := Znakovi + [Znak] end end; Slično, ne postoji ugrađena funkcija za ispis skupova. Da odštampamo sve elemente iz skupa, moramo imati petlju koja obuhvata cijeli bazni tip, i koristiti test pripadnosti skupu. Na primjer, slijedeći primjer ispisuje sve elemente skupa “GranicniBodovi”: for Bodovi := 0 to 100 do if Bodovi in GranicniBodovi then write(Bodovi);

Na kraju se štampa skup svih brojeva koji su izdvojeni iz "sita" (to su upravo prosti brojevi). i njegovi umnošci se uklanjaju. počev od najmanjeg prostog broja 2. morale bi biti zamijenjene odgovarajućim tipovima i konstantama.Jednostavniji način ne postoji. var Brojevi : SkupBrojeva. Primjer programa Slijedeći primjer koristi algoritam poznat pod nazivom "Erastotenovo sito" za nalaženje svih prostih brojeva u određenom opsegu brojeva. { Gornja granica opsega u kojem će se tražiti prosti brojevi } BrojNadjenih : BazniOpseg. program ErastotenovoSito(input. Broj 2 se izdvaja iz skupa i prebacuje u drugi skup. i tako dalje sve dok se "sito" ne isprazni. . SkupBrojeva = set of BazniOpseg. Kao primjer dat je prototip funkcije koja računa kardinalni broj skupa (tj. Slijedeći broj 3 se izdvaja. Prvo se formira skup čiji su elementi svi brojevi u datom opsegu. output). potrebna je slična kombinacija "for" i "if" naredbe. { Skup brojeva iz kojeg će se izdvajati prosti brojevi } Prosti : SkupBrojeva. a svi umnošci od 2 se uklanjaju. 6. Tekuci : NekiOpseg.MaksimalniSkup. Naravno. KardinalniBroj := Brojac end. da obavimo bilo koju operaciju nad svim članovima skupa. { Nalazi proste brojeve u zadanom opsegu } const MaksimalniSkup = 255. for Tekuci := najnizi to najvisi do if Slijedeci in Skup then Brojac := Brojac + 1. "Najnizi" itd. { Najveća veličina skupa u većini Pascal implementacija } type BazniOpseg = 0. { Broj nađenih prostih brojeva } Slijedeci : BazniOpseg. begin Brojac := 0. Zapravo. u konkretnom slučaju konstrukcije poput "NekiSkupovniTip". { Brojac za štampanje skupa } procedure Sito(var OvoSito : SkupBrojeva. broj njegovih elemenata): function KardinalniBroj(Skup : NekiSkupovniTip) : NekiOpseg. { Vraća kardinalni broj skupa } var Brojac : integer. { Skup pronađenih prostih brojeva } Granica : BazniOpseg..

writeln(BrojNadjenih:1. ' '). "Brojac" vraća broj nađenih prostih brojeva } var Slijedeci : BazniOpseg.. Sito(Brojevi. ' su:'). var Brojac : BazniOpseg). for Slijedeci := 2 to Granica do if Slijedeci in Prosti then write(Slijedeci:1. MaksimalniSkup:1. ' prostih brojeva do '. ')? '). { Slijedeći prosti broj koji se uklanja } { Slijedeći umnožak koji se uklanja } begin NadjeniProsti := []. writeln end. BrojNadjenih). Brojac := 0. Umnozak : BazniOpseg. Umnozak + Slijedeci + 1 begin write('Do koje vrijednosti želite stampanje prostih brojeva '). Najvisi do OvoSito . Slijedeci := 2. repeat readln(Granica) until (Granica >= 2) and (Granica <= MaksimalniSkup). Slijedeci := Slijedeci until OvoSito = [] end. Umnozak := Slijedeci. while Umnozak <= begin OvoSito := Umnozak := end end.[Umnozak].Granica]. Prosti. Granica. write('(maksimum '. { Nalazi proste brojeve u skupu "NekoSito" (zaključno do broja "Najvisi") i dodaje ih u skup "Nadjeni Prosti". Brojevi := [2. . repeat if Slijedeci in OvoSito then begin NadjeniProsti := NadjeniProsti + [Slijedeci]. Granica:1.Najvisi : BazniOpseg. Brojac := Brojac + 1. var NadjeniProsti : SkupBrojeva.

i njihov opis se može naći u brojnim knjigama o računarskim naukama i metodama programiranja. Mi ćemo ovdje analizirati jedan jednostavan algoritam. “Bubble Sort”. Cijeli niz različitih algoritama za sortiranje je razvijen za tu svrhu. Algoritmi za sortiranje U računarskim primjenama često je potrebno smjestiti listu elemenata u nekom unaprijed određenom poretku. Postupak se ponavlja sve dok se čitav niz ne sortira. “Bubble Sort”. Oni su poznati pod nazivima “Selection Sort”. Prvi prolaz kroz niz generira: 12 0 0 0 0 . “Shell Sort”. spisak računa poredan po datumu plaćanja. Uobičajeni korak u obradi podataka je čitanje neuređenog spiska i njegovo sortiranje u željeni poredak. “Insertion Sort”. i zamjenjujući ih ukoliko su u pogrešnom poretku. Slijedi opis algoritma: Postavi dužinu na broj elemenata u nizu ponavljaj postavi indikator sortiranosti na "Tačno" za elemente od 1 do (dužina-1) radi slijedeće ako taj element i slijedeći nisu u ispravnom poretku onda postavi indikator sortiranosti na "Netačno" razmijeni ta dva elementa kraj uvjeta kraj petlje umanji dužinu za 1 dok ne bude indikator sortiranosti tačan ili dužina = 1 Da ilustriramo kako ovo radi. abecedni spisak imena u telefonskom imeniku. “Bubble sort” radi poredeći svaki par elemenata niza u jednom potezu.SORTIRANJE 1. tabela liga nogometnih klubova poredana u opadajućem poretku bodova (!) itd. Algoritam "Bubble Sort" Pretpostavimo da su elementi koji se sortiraju smješteni u niz. “Quick Sort” itd. pretpostavimo da je niz: 12 0 3 2 8 i neka želimo da sortiramo vrijednosti u nizu u rastući poredak. npr. 2.

MaksimalnaDuzinaImena] of char. To znači da je on pogodan samo za sortiranje manjih nizova (maksimalno 50 – 100 elemenata). Ime = packed array [1.output). koji sortira spisak imena u abecedni poredak } const MaksimalnaDuzinaImena = 10. 3. ali pošto je izvršena jedna razmjena. dužina imena } { Maks. i proces sortiranja se završava. MaksimalanBrojElemenata = 10.MaksimalanBrojElemenata. 0 3 2 8 12 0 3 2 8 12 0 2 3 8 12 0 2 3 8 12 U ovom stadiju niz je sortiran. Međutim.0 3 2 8 12 3 2 8 3 12 2 8 3 2 12 8 3 2 8 12 Pošto su izvrsene zamjene (indikator sortiranosti je netačan). program SortiranjeImena(input. Kako ni jedna razmjena neće biti napravljena za vrijeme tog prolaza. Zapravo. indikator sortiranosti će ponovo biti netačan. broj imena u spisku } type OpsegSpiska = 1. Dužina se ponovo umanjuje za 1 i započinje novi prolaz. Bubble Sort u Pascal-u Slijedeći program sadrzi proceduru "Sort" koja koristi “Bubble Sort” algoritam za sortiranje niza stringova u abecedni poredak. dužina se smanjuje za 1... { Program za demonstraciju algoritma za sortiranje. pošto je nakon prvog prolaza najveći element sigurno na ispravnoj poziciji. . indikator sortiranosti ce biti tačan. { Maks. moramo napraviti novi prolaz kroz niz. može se pokazati da je u prosjeku vrijeme potrebno za sortiranje grubo proporcionalno sa N2. Iako je “Bubble Sort” veoma jednostavan za razumijevanje i izvedbu. gdje je N veličina niza. on nije naročito efikasan algoritam za sortiranje.

var Imena : SpisakImena. begin Imena[1] := 'Miki Maus '. Duzina : OpsegSpiska). { Brojač u petlji } begin repeat { Pretpostavi da je niz sortiran } Sortirano := true. Imena[2] := 'Pluton '. { dva elementa. niz nije } Sortirano := false. begin for i := 1 to Duzina do writeln(Spisak[i]) end. { Štampa imena u spisku } var i : OpsegSpiska. { dok se ne dokaže suprotno } for i := 1 to (Duzina . { Spisak imena koja će se sortirati } { Broj imena u spisku } procedure Sortiranje(var Spisak : SpisakImena.SpisakImena = array [OpsegSpiska] of Ime.1 { Umanji dužinu za novi prolaz } until Sortirano or (Duzina = 1) end.. Duzina := Duzina . procedure StampajImena(Spisak : SpisakImena. { sortiran. } Spisak[i+1] := Privremena end. { izvršiti razmjenu } Spisak[i] := Spisak[i+1]. i moramo } Privremena := Spisak[i]. { Brojač u petlji } .. Duzina : OpsegSpiska). { Privremena promjenljiva za razmjenu } Sortirano : Boolean. BrojImena : OpsegSpiska. { Sortira "Duzina" imena u spisku "Spisak" u abecedni poredak koristeći "Bubble Sort" algoritam } var Privremena : Ime.1) do if Spisak[i] > Spisak[i+1] then { Ako je poredak } begin { pogrešan. { Indikator da li je niz sortiran } i : OpsegSpiska.

BrojImena). writeln('Nakon sortiranja. Imena[9] := 'Paja Patak'. Juric Z. Preduzeće održava interni telefonski imenik. Sortiranje(Imena. Imena[5] := 'Tom '. writeln('Nesortirani spisak je:'). BrojImena). StampajImena(Imena. ucitajte elemente niza iz datoteke. Napišite program koj čita nesortirani spisak imena i lokalnih brojeva iz tekstualne datoteke. writeln. Imena[4] := 'Vilma '.) . StampajImena(Imena. BrojImena) end. 2134 2545 2244 2768 (Uputa: kreirajte niz slogova. koji sadrži ime radnika i lokalni telefonski broj (4 cifre). writeln. 4. BrojImena := 10. spisak je:'). Prvih nekoliko linija ulazne datoteke mogu izgledati poput: Protic D. Imena[7] := 'Dzeri '. Imena[10] := 'Oliva '. spreman za štampanje.Imena[3] := 'Jogi '. Imena[8] := 'Popaj '. writeln. Koristite slogovni tip da predstavite svaku jedinku u imeniku (ime + lokalni broj). Allen P. itd. i prebacite sortirane podatke u izlaznu datoteku. sortirajte niz. Zadaća 1. i kreira drugu datoteku koja sadrži spisak sortiran abecedno po imenima. Imena[6] := 'Fred '. Jamak H.

koji je na granici komercijalne upotrebljivosti. ili po gol razlici za slučaj da više timova ima isti broj bodova.1 {1.3 1.1.1 1.1. broj datih i primljenih golova.1.3 Korak 2 1.2 1.2 1.2.1.1.1 Izaberi opciju 1. Nakon ažuriranja tabela se sortira po broju bodova.1 1.4 ponavljaj Ispiši instrukcije korisniku Unesi opciju ako je opcija neispravna (izvan opsega 0-3) onda Ispiši upozorenje kraj uvjeta dok ne bude opcija ispravna (u opsegu 0-3) ponavljaj Izaberi opciju za slučaj da je opcija 1 : Postavi novu ligu 2 : Unesi i obradi rezultate 3 : Prikazi tabelu kraj izbora dok ne bude opcija = 0 (kraj) 1. na kraju je dat jedan složeniji program.) Unos rezultata odigranih utakmica jednog kola.1.1. broj pobjeda. Priloženi program služi za administraciju nogometne lige.2.2.) Prikaz sortirane tabele. Postavka problema Kao ilustracija svega izloženog.2} 1.1. pri čemu se vrši automatsko ažuriranje tabele koja sadrži broj odigranih utakmica.1. te broj bodova (3 boda za svaku pobjedu.2.1 1. 1 za neriješeni rezultat i 0 za poraz).1. 2.1.) Zadavanje nove nogometne lige (unos imena klubova).1. 1.2.2 1.1.1 1. Korak 1 Program za administraciju nogometnih takmičenja 1.1. 2.2. Razrada algoritma Prije samog programa.3. 3.1 1.1.2.1 1.1.1 Postavi novu ligu 1.2 1.PRIMJER SLOŽENIJEG PROGRAMA 1. čime se ranije uneseni podaci brišu. poraza i neriješenih rezultata.2.2 Upozori korisnika na moguće posljedice ako je upozorenje prihvaćeno onda Pripremi praznu datoteku ponavljaj .3 {1.1.2.3} 1. Program ima 3 opcije: 1. prvo će biti izložena razrada problema korak po korak.2.

2.2.2.3.2.2.2.2.3} Korak 3 Ispiši zaglavlje tabele Premotaj datoteku na pocetak sve dok se ne dostigne kraj datoteke radi slijedeće Učitaj jedan klub iz datoteke Prikaži rezultate za jedan klub kraj petlje 1.1.2 1.3 {1.3 1.1.2.2.1.1.2 1.9 Postavi Postavi Postavi Postavi Postavi Postavi Postavi Postavi Postavi ime kluba na unijeto ime broj odigranih utakmica na 0 broj pobjeda na 0 broj neriješenih utakmica na 0 broj poraza na 0 broj datih golova na 0 broj primljenih golova na 0 broj poena na 0 gol razliku na 0 1.4 Učitaj ligu iz datoteke u niz u memoriji ponavljaj Unesi rezultate za jednu utakmicu Postavi pitanje treba li unijeti još rezultata dok ne bude odgovor ne različit od "d" i "D" Sortiraj tabelu Snimi tabelu u datoteku na disk 1.1.2.1.1 1.1.2 1.2.3.1.2.1.2.2.2.2 Postavi broj klubova na 0 Premotaj datoteku na početak .2.2.2.2.2.2.2.1.2.8 1.2 {1.2.1 1.2.2.2.3.5 1.2.1.2.2 {1.2.3.2.2.4 1.2.2.1.1.2} Unesi jedno ime ako ime nije prazno onda Postavi pocetne podatke za jedan klub Upiši postavljene podatke u datoteku kraj uvjeta dok ne bude ime prazno kraj uvjeta 1.1.1.2.2.1.2.2.6 1.3.3 1.2.1 1.1.2.2.1.3.2.1.1 1.1.2.2.1.2.1 Postavi početne podatke za jedan klub 1.3 Prikaži tabelu 1.2.2.1.1.2.1 Upozori korisnika na moguće posljedice 1.2.1.1 1.7 1.2.2.3 Ispiši korisniku upozorenje Unesi odgovor korisnika Upozorenje je prihvaćeno ako je odgovor "d" ili "D" 1.2.1 1.2.2 1.2.3 1.2.1.2.2.1.2.1 1.2.1.2.2.2.2.1.2.1.2.2.2.2.2 1.1.2 1.2.2.2.2.3.3.2.2.1.2.2.2.1.2.1 Učitaj ligu iz datoteke u niz u memoriji 1.2 Unos i obrada rezultata 1.1 1.2.2.2.2.2.2.3 1.2.1.2.2.2.2.2.2.2.1.2} 1.2.2.2.1.1.1 1.2.

2.2.3.2.3.3.3.2.2.2.1 1.3.1.2.2.1 1.3.4 1.2.3 1.3.3.3.5 Unesi ime prvog tima i odredi njegov indeks u tabeli Unesi ime drugog tima i odredi njegov indeks u tabeli Unesi broj golova prvog tima Unesi broj golova drugog tima Obradi unesene rezultate 1.2.1.2.3.2.3} 1.2.3.2.2.3.2.2.2.3.2.1 1.2.3} sve dok se ne dostigne kraj datoteke radi slijedeće Povećaj broj klubova za 1 Učitaj slijedeci element iz datoteke u tekući element tabele (određen brojem klubova) kraj petlje 1.2.2.1 1.2.4 1.3 1.2.2.1 1.2 1.3 1.1.2.3.3.2.1.2. ili dok indikator izvršene razmjene ne bude netačan Uvećaj brojac prolaza za 1 dok ne bude brojač prolaza veći od broja klubova umanjenog za dužinu bloka kraj petlje .3.1.2.2.2.1.2.3.2.2. brzi i bolji od uobičajenog i najjednostavnijeg Bubble Sort algoritma) 1.1.2.1.2.3.2.2.2.2.2.2.3.2.2.4 {1.2.3.2.2.2.3.2.2.2.2.2} ako su elementi u pogrešnom poretku onda Razmijeni elemente Umanji drugi indeks za dužinu bloka Postavi indikator izvršene razmjene na tačno kraj uvjeta dok ne bude prvi indeks manji ili jednak nuli.3.2.3.2.2.3 1.3.2.2 Postavi dužinu bloka na ukupan broj klubova sve dok je dužina bloka razlicita od 1 radi slijedeće Prepolovi dužinu bloka na 1 Postavi brojač prolaza na 1 ponavljaj Postavi prvi indeks na brojač prolaza ponavljaj Postavi drugi indeks na prvi indeks uvećan za dužinu bloka Postavi indikator izvršene razmjene na netačno 1.2.1.3.3.2.3.2.3.1.2.2.2.3.2 1.3.1 1.3 1.2.2.2.3.2.2.2.3.2.2 1.1 1.2.2.3 {1.2.2.2.2.2.2 1.2 1.2.2.2 {1.3.2.2.2.3.2.2.2.1 Unos rezultata za jednu utakmicu 1.2.2.3.2.3 Sortiranje tabele (Shell-ov algoritam.

5 1.3.3.2.3.8 1.1.2.2.2.3.2.2.2.2.4 Snimanje tabelu u datoteku na disk 1.2.2.2 1.3.2.2.2.2} Pripremi praznu datoteku za brojač od 1 do ukupnog broja klubova radi slijedeće Upiši tekući element tabele (određen brojačem) u tabelu kraj petlje 1.3.2.4 1.2.9 Ispiši ime kluba Ispiši broj odigranih utakmica Ispiši broj pobjeda Ispiši broj neriješenih utakmica Ispiši broj poraza Ispiši broj datih golova Ispiši broj primljenih golova Ispiši broj poena Pređi u novi red .3.2.3.1 1.3.2.2.2 Prikaz rezultata za jedan klub 1.2.2.3.3.2.2.4.3.1 1.2.2 1.4.3.2.2.3.3.3.2.4.4.2.3 1.1 {1.2.2.3.3.3.7 1.3.2.6 1.

9} Povećaj broj odigranih utakmica prvog kluba Povecaj broj odigranih utakmica drugog kluba Povećaj broj datih golova prvog kluba za broj golova koje je dao prvi klub Povećaj broj datih golova drugog kluba za broj golova koje je dao drugi klub Povećaj broj primljenih golova prvog kluba za broj golova koje je dao drugi klub Povećaj broj primljenuh golova drugog kluba za broj golova koje je dao prvi klub Izračunaj gol razliku za prvi klub kao broj njegovih datih golova umanjeno za broj primljenih golova Izracunaj gol razliku za drugi klub kao broj njegovih datih golova umanjeno za broj primljenih golova ako je broj golova koje je dao prvi klub veći od broja golova koje je dao drugi klub onda Postavi pobjedu prvog kluba Postavi poraz drugog kluba inače ako je broj golova koje je dao prvi klub jednak broju golova koje je dao drugi klub onda Postavi neriješen ishod za prvi klub Postavi nerijesen ishod za drugi klub inače Postavi poraz prvog kluba Postavi pobjedu drugog kluba kraj uvjeta kraj uvjeta 1.2.1.1.2.9.2.2.5.1.2.3.2.1.2.2.9} 1.5.2.2.2.1.2.1.2.2.2.9.1 {1.2.1.1.5.2.5 Obrada unesenih rezultata 1.2.1.2.2.2.4 1.2.1 1.2.2.3} {1.2.9 1.3} 1.3 1.1.2.2.2.9.2.5 1.2.5.2.5.2.1.2.3 1.2.2.3 Ispitivanje da li je poredak elemenata u tabeli pogrešan 1.1.6 1.2.2.2.1.2.5.3.2.2.2.5.5.3} 1.2.1.7 1.2.2.2.1.2.1 1.2.2.2.2.2.2.9.5.1.3.2.2 1.1 1.1.2.1 1.3 1.2.3.2.1.2.2.5.5.2.2.3.2.3.Broj poena prvog kluba manji od broja .1 Poredak je pogrešan ako je: .2.1.1.1.1.2.2.1.2.5.9.2.2.5.2 {1.2.2.2.5.3.1.1.1.1.5.2.5.3 !.1.2.2 {1.4 {1.1.3.2.2.5.2.1.2.2.2.2.2.Korak 4 1.2.9.1 1.2.2.1.2.2.1.5.8 1.9.5.1.2.2.1.2.2.3 ponavljaj Unesi ime sa tastature Pronađi indeks pretragom tabele ako indeks nije nađen onda Ispiši da nema tima sa takvim imenom kraj uvjeta dok ne bude indeks nađen 1.1.3.2.1.1.2 1.2.9.1 Unos imena tima i odredjivanje njegovog indeksa 1.1.5.3.1.2.2.1.1.9.2.1.

2.2.1.5.4} 1.2.2.2.2.2.2.5.1. ili .1.2.1.1.1.1.9.2.2.1.9.2.2. Program u Pascal-u Konačno.3.2.2 {1.3.1 1. slijedi i sam listing programa.1.2.1.2.2.2.2.1.1.1. 1.1.2 1.1 Povećaj broj poraza tog kluba za 1 1.2.2.2.1.9.1.2.1.1.2.1 1.2.2 1.2.2.3.2 {1.2.3.1.2.5.1 1.5.1.4} Postavi indikator pronalaska na netačno Postavi indeks na 0 sve dok je indeks manji od broja klubova i dok klub nije nađen radi slijedeće Uvećaj indeks za 1 Indiciraj da je element nađen ako je tekući element u tabeli (određen indeksom) jednak zadanom imenu kraj petlje ako je element nađen onda Vrati kao rezultat tekući indeks inače Signaliziraj da element nije nađen kraj uvjeta Prebaci prvi klub u pomoćnu promjenljivu Prebaci drugi klub u prvi klub Prebaci pomoćnu promjenljivu u drugi klub 1.2.2.1.1.1.2.2.2.2.1.2.1 {1.2.2.5.2.1 1.3.1.1.2.1 Razmjena elementa (klubova) u tabeli 1.9.2 Pronalaženje indeksa u tabeli pretragom tabele 1.2.2.1.3.3.2.1.5.3.1.2.9.3.1.1.3 1.2.3.1.1 Postavljanje pobjede nekog kluba 1.2 Povećaj broj pobjeda tog kluba za 1 Povećaj broj poena tog kluba za 3 1.2.2.2.2.2.2.2.2.2.3} 1.3.1. .2.2.3 Korak 5 1.2 Povećaj broj nerijesenih utakmica tog kluba za 1 Povećaj broj poena tog kluba za 1 3.2.2.2.1.2.1.2.2.2.9.1.1.1.2.4 1.2.3.1.2.3.2.1.2.2.4.2.2.1.1.2.4.2.3.2.1.1.1.2.2.1.1 1.1.1.2.9.2.3.1 Postavljanje neriješenog ishoda za neki klub 1.3.3.1.1.2.5.2.2 Postavljanje poraza nekog kluba 1.2.2.2.Broj poena prvog kluba jednak broju poena drugog kluba i gol razlika prvog kluba manja od gol razlike drugog kluba.2.9.2.5.1.2.2.2.poena drugog kluba.

BrojPrimljenihGolova. BrojPobjeda. BrojDatihGolova. BrojUtakmica. Liga). var Opcija : char. output. { Prazno ime } { Čuva klub koji se trenutno unosi } { Ime koje se unosi } function Upozorenje : Boolean. . { Maksimalna dužina imena } type OpsegImena = 1.. { Brojač znakova u imenu } begin for Brojac := 1 to MaxIme do if eoln(input) then Ime[Brojac] := ' ' else read(Ime[Brojac]). Ime : TipIme. { CitajIme } procedure PostaviLigu(var Liga : TipLiga). { Korisnička komanda } { Datoteka sa podacima } procedure CitajIme(var Ime : TipIme).MaxIme. BrojPoena. BrojNerijesenih. GolRazlika : integer end. { Tip za definiranje imena } Klub = record Ime : TipIme. { Postavlja novu nogometnu ligu } const PraznoIme = ' var NoviKlub : Klub. { Program za administraciju nogometnih natjecanja } const MaxIme = 20. { Opseg dužine imena } TipIme = packed array [OpsegImena] of char. readln end. TipLiga = file of Klub.program AdministracijaLige(input. BrojPoraza. '. Liga : TipLiga. { Procedura za unos imena sa tastature } var Brojac : OpsegImena.

NekiKlub. readln(Opcija). ').').GolRazlika := 0 end. Upozorenje := (Opcija = 'd') or (Opcija = 'D') end. write(Liga. rewrite(Liga). NoviKlub). write('Unos završite pritiskom na ENTER.BrojPrimljenihGolova := 0. writeln. Ime : TipIme). { Upozorenje } procedure PostaviJedanKlub(var NekiKlub : Klub. writeln('bez unosa imena. { PostaviJedanKlub } begin { PostaviLigu } if Upozorenje then begin writeln. NekiKlub. NekiKlub. writeln('Unesite imena klubova. { Korisnička komanda } begin write('OPREZ! Ova opcija će izbrisati ').BrojPobjeda := 0. if Ime <> PraznoIme then begin PostaviJedanKlub(NoviKlub. { Postavlja početne vrijednosti za jedan klub } begin NekiKlub. NekiKlub.Brojutakmica := 0.') end . writeln('Liga postavljena.BrojPoraza := 0.'). NekiKlub. NekiKlub.Ime := Ime. NekiKlub. repeat CitajIme(Ime).BrojNerijesenih := 0.{ Upozorava korisnika na moguće posljedice i pita ga da li želi da nastavi sa radom } var Opcija : char.BrojDatihGolova := 0. write('Da li želite da nastavite: '). writeln('postojeće rezultate!'). jedno po jedno. Ime). NekiKlub. end until Ime = PraznoIme.BrojPoena := 0.

{ PostaviLigu } procedure UnosRezultata(var Liga : TipLiga). { Tabela za privremeni rad u memoriji BrojKlubova : OpsegKlubova. { UcitajLigu } procedure UnosJedneUtakmice(var Tabela : TipTabela. { Unosi podatke o jednoj utakmici i ažurira tabelu } const MaxGolova = 99. { Učitava tabelu iz datoteke u memoriju i vraća broj klubova u ligi } begin BrojKlubova := 0. { Tabela lige u memoriji } var Tabela : TipTabela. var Indeks1. var BrojKlubova : OpsegKlubova). reset(Liga). { Unosi rezultate odigranih utakmica } const NijeNadjeno = 0. { Opseg broja klubova TipTabela = array [OpsegKlubova] of Klub. .. { Maksimalni broj golova } { Opseg broja golova } { Indeks timova u tabeli } { Broj golova koje su postigli timovi } procedure UnosImenaTima(var Tabela : TipTabela. var Tabela : TipTabela. while not eof(Liga) do begin BrojKlubova := BrojKlubova + 1..MaxKlubova. Indeks2 : OpsegKlubova. { Broj klubova u ligi Opcija : char. BrojKlubova : OpsegKlubova. read(Liga. var Indeks : OpsegKlubova). MaxKlubova = 50. type OpsegGolova = 0. Golovi1.end. BrojKlubova : OpsegKlubova). { Konstanta koja oznacava da tim nije nađen } { Maksimalni broj klubova } } type OpsegKlubova = 0. Tabela[BrojKlubova]) end end.MaxGolova. { Korisnička komanda } } } procedure UcitajLigu(var Liga : TipLiga. Golovi2 : OpsegGolova.

{ Trazi } begin { UnosImenaTima } repeat CitajIme(Ime). Ime : TipIme.Ime = Ime end. BrojKlubova : OpsegKlubova) : OpsegKlubova. BrojKlubova). Nasao := Tabela[Indeks]. Ime. Klub2 : Klub. { Vraća indeks traženog kluba u tabeli ili "NijeNadjeno" ako tim sa zadanim imenom ne postoji u tabeli } var Indeks : integer. Golovi2 : OpsegGolova). Golovi1. Indeks := 0. writeln. Nasao : Boolean. { Vrši obradu rezultata } .{ Unosi ime tima sve dok se ne unese ispravno ime i vraća njegov indeks kao rezultat } var Ime : TipIme. { Ime tima koji se unosi } function Trazi(var Tabela : TipTabela. { Indeks u tabeli } { Indikator da li je klub pronađen } while (Indeks < BrojKlubova) and not Nasao do begin Indeks := Indeks + 1. begin Nasao := false. if Nasao then Trazi := Indeks else Trazi := NijeNadjeno end. if Indeks = NijeNadjeno then begin writeln. Indeks := Trazi(Tabela. { UnosImenaTima } procedure ObradiRezultate(var Klub1. write('Unesite ime tima ponovo: ') end until Indeks <> NijeNadjeno end. writeln('Nema tima sa takvim imenom!').

{ Označava da je tim poražen } begin NekiKlub. if Golovi1 > Golovi2 then begin PostaviPobjedu(Klub1).BrojDatihGolova .BrojPoena := NekiKlub. { PostaviPobjedu } procedure PostaviPoraz(var NekiKlub : Klub).BrojPrimljenihGolova + Golovi1. Klub1.BrojPoraza + 1.BrojPrimljenihGolova. PostaviPoraz(Klub2) end else if Golovi1 = Golovi2 then begin . Klub1.BrojPrimljenihGolova := Klub2.Klub1.BrojDatihGolova := Klub1. NekiKlub.BrojDatihGolova + Golovi2.BrojNerijesenih := NekiKlub.BrojUtakmica := Klub1.BrojUtakmica + 1.BrojDatihGolova + Golovi1. { Označava da je tim pobijedio } begin NekiKlub.BrojPoena + 1 end. Klub2.BrojPoraza := NekiKlub.BrojPobjeda := NekiKlub. Klub2. Klub1. end.BrojUtakmica + 1.BrojPrimljenihGolova := Klub1.BrojDatihGolova .procedure PostaviPobjedu(var NekiKlub : Klub). NekiKlub.BrojUtakmica := Klub2.Klub2.GolRazlika := Klub1. Klub2. Klub2.BrojPrimljenihGolova.BrojPrimljenihGolova + Golovi2.BrojPoena := NekiKlub. { PostaviPoraz } procedure PostaviNerijesenIshod(var NekiKlub : Klub).BrojPobjeda + 1.BrojNerijesenih + 1.BrojPoena + 3 end.BrojDatihGolova := Klub2.GolRazlika := Klub2. { PostaviNerijeseno } begin { ObradiRezultate } Klub1. { Označava da je tim igrao neriješeno } begin NekiKlub.

write('Broj golova prvog tima: '). Prolaz : integer. Indeks2). BrojKlubova : integer). BrojKlubova. Indeks2.GolRazlika)) end. PostaviPobjedu(Klub2) end end. { PogresanPoredak } procedure Razmijeni(var Klub1. PostaviNerijesenIshod(Klub2) end else begin PostaviPoraz(Klub1). ObradiRezultate(Tabela[Indeks1].GolRazlika < Klub2. write('Ime drugog tima: '). procedure SortirajTabelu(var Tabela : TipTabela. readln(Golovi2). { Određuje da li su klubovi u pogrešnom poretku } begin PogresanPoredak := (Klub1. { Vrši razmjenu dva sloga } var . function PogresanPoredak(Klub1. write('Broj golova drugog tima: '). Klub2 : Klub).BrojPoena) and (Klub1.BrojPoena = Klub2. writeln end.BrojPoena) or ((Klub1. BrojKlubova. Indeks1). DuzinaBloka. { ObradiRezultate } begin { UnosJedneUtakmice } writeln('Unesite rezultate utakmice:'). Tabela[Indeks2]. Klub2 : Klub) : Boolean. writeln. Razmijenjen : Boolean. writeln. Golovi1. write('Ime prvog tima: '). readln(Golovi1).BrojPoena < Klub2.PostaviNerijesenIshod(Klub1). UnosImenaTima(Tabela. Golovi2). { Sortira tabelu Shell-ovim postupkom u skladu sa datim kriterijem } var Indeks1. UnosImenaTima(Tabela.

Klub2 := Pomocni end. { Razmijeni } begin { SortirajTabelu } DuzinaBloka := BrojKlubova. if PogresanPoredak(Tabela[Indeks1]. repeat Indeks2 := Indeks1 + DuzinaBloka. begin Pomocni := Klub1. while DuzinaBloka <> 1 do begin DuzinaBloka := DuzinaBloka div 2. { Snima sadržaj tabele u memoriji u datoteku } var Brojac : OpsegKlubova. Prolaz := 1. { Brojač slogova } begin rewrite(Liga). BrojKlubova). writeln('Rezultati uneseni.DuzinaBloka. Tabela[Indeks2]) then begin Razmijeni(Tabela[Indeks1]. write('Da li želite unijeti jos rezultata (D/N)? '). BrojKlubova : OpsegKlubova). Tabela[Brojac]) end. for Brojac := 1 to BrojKlubova do write(Liga. Klub1 := Klub2. var Tabela : TipTabela. Tabela[Indeks2]). Indeks1 := Indeks1 . repeat Indeks1 := Prolaz. Razmijenjen := true end until (Indeks1 <= 0) or not Razmijenjen.'). Prolaz := Prolaz + 1 until Prolaz > BrojKlubova . Razmijenjen := false. { SnimiLigu } begin { UnosRezultata } UcitajLigu(Liga. Tabela. BrojKlubova). { SortirajTabelu } procedure SnimiLigu(var Liga : TipLiga. readln(Opcija).Pomocni : Klub. .DuzinaBloka end end. repeat UnosJedneUtakmice(Tabela.

write(NekiKlub.BrojUtakmica:4. write(NekiKlub. write(NekiKlub.BrojPoena:4) end. NoviKlub). readln end. SnimiLigu(Liga.. begin write(NekiKlub. Razmak). PrikazJednogRezultata(NoviKlub) end. Razmak). SortirajTabelu(Tabela. write(NekiKlub. write(NekiKlub. { Prikazuje sortiranu tabelu } var NoviKlub : Klub. BrojKlubova). writeln ('-------------------------------------------------------'). Tabela. { UnosRezultata } procedure PrikazTabele(var Liga : TipLiga).Ime. Razmak).writeln. BrojKlubova) end. until (Opcija <> 'd') and (Opcija <> 'D').BrojPoraza:4. procedure PrikazJednogRezultata(NekiKlub : Klub). { Prikazuje jedan red tabele } const Razmak = ' '. '). writeln.BrojNerijesenih:4. { PrikazJednogRezultata } begin { PrikazTabele } writeln ('Ime kluba P W D L F A Pts').BrojDatihGolova:4. Razmak). writeln(NekiKlub. Razmak). Razmak). { Nudi izbor mogućih opcija programa } . Razmak). Reset(Liga).BrojPrimljenihGolova:4. write('Pritisni ENTER za nastavak . { PrikazTabele } procedure IzborOpcija(var Opcija : char).. write(NekiKlub. while not eof(Liga) do begin read(Liga.BrojPobjeda:4.

{ Turbo Pascal varijanta } repeat writeln. write('Unesi opciju: ').DAT'). Prikaz tabele'). if (Opcija < '0') or (Opcija > '3') then writeln('Pogrešna opcija!'). until Opcija = '0' end. writeln. IzborOpcija(Opcija). Kraj programa'). '2' : UnosRezultata(Liga). writeln. writeln('3. begin { Glavni program } assign(Liga. '3' : PrikazTabele(Liga) end. Unos rezultata odigrane utakmice'). . writeln('1. until (Opcija >= '0') and (Opcija <= '3') end. 'LIGA. writeln('0. writeln('2.begin repeat writeln. writeln. writeln('-----------------------------------------------'). writeln('PROGRAM ZA ADMINISTRACIJU NOGOMETNIH TAKMIČENJA'). Postavljanje nove nogometne lige'). readln(Opcija). case Opcija of '1' : PostaviLigu(Liga).

Sign up to vote on this title
UsefulNot useful