You are on page 1of 7

Potprogrami Najjednostavnije, potprogrami su djelii programa koji se koriste na vie mjesta u programu, pa su zato radi praktinosti zapisani samo

na jednom mjestu i to jedanput, no onda se mogu pozvati beskonano puta u programu. U Pascalu ih dijelimo na procedure i funkcije. Bitno je znati praktinu razliku izmeu njih. U samom Pascalu obje varijante zapravo itavo vrijeme ve i koristimo. Uzmimo na primjer funkciju length(s) i proceduru writeln(s). Obje naredbe neto rade sa stringom s. Funkcija length e poprimiti vrijednost broja znakova u stringu, a procedura writeln e string ispisati i prebaciti kursor u novi red. Razlika je to e se length ponaati kao integer, a writeln ni sluajno ne. To je i razlika izmeu funkcija i procedura.
//npr. a := 1 + length('1234'); // potpuno normalno radi b := 1 + writeln('1234');// syntax error!

Funkcije same poprimaju neku vrijednost, a procedure su posrednici koji neto naprave. Funkcije isto tako koristimo stalno u matematici. Sinus, kosinus, apsolutna vrijednost, su sve funkcije, i koristimo ih kao brojeve. Osim toga funkciju moemo vraati u samu sebe, to se naziva rekurzijom, no o tome malo kasnije.
program //naziv programa uses //moduli programa var //varijable programa //funkcije i procedure, ako ih ima! begin //glavni program end.

Evo sad za primjer jedan jednostavan program koji e dva broja zbrojiti, i to prvo procedurom.
program zbrajanje; var a,b:integer; procedure zbroj(a1,b1:integer); var zbr:integer; //lokalne varijable, dakle one koje koristi samo //potprogram, se ovdje definiraju begin //naredbe potprograma se nalaze u begin .. end; zbr:=a1+b1; write(zbr); end; //sve osim same najave je isto kao u glavnom programu begin write('a... ');readln(a);

write('b... ');readln(b); zbroj(a,b); readln; end.

Vidimo da se procedura definira kao


procedura(ulazna varijabla1, ulazna varijabla2, ... , ulazna varijabla n:tip podataka)

Ovime hou pokazati da se u proceduru moe unijeti koliko god podataka koliko nam se htjedne! No, ako imamo samo dvije varijable kao unos u proceduru(ili funkciju), a mi unesemo sedam, javit e se syntax error, to ima smisla! Za funkciju vrijedi ista stvar, jedino to na kraju definicije moramo odrediti koji e biti tip podataka kojeg e funkcija poprimiti:
funkcija(varijabla:tip):tip;

U onom potprogramu sam varijable a i b nazvao kao varijable a1 i b1. To je isto zato da se ne zbunim kad ja radim s potprogramom: da sam im ostavio imena, raunalo bi te varijable tretiralo kao nove, lokalne varijable! Slijedi ista stvar, samo sa funkcijom:
program zbrajanje; var a,b:integer; function zbroj(a1,b1:integer):integer; begin zbroj:=a1+b1; //sama funkcija zbroj poprima neku vrijednost! //na kraju svake funkcije se imenu funkcije dodjeljuje neka vrijednost //u suprotnom funkcija ne radi! end; begin write('a... ');readln(a); write('b... ');readln(b); writeln( zbroj(a,b) ); //sad taj zbroj treba ispisati! readln; end.

Okej, ajmo sad rijeit Vuletov zadatak sa potprogramom pa onda na rekurziju! 9. Potprogramski obrii velika slova poruke.
program devet; var s:string; function brisanje(s:string):string; var i:integer; begin for i:=1 to length(s) do case s[i] of

'A'..'Z': delete(s,i,1); end; brisanje:=s; end; begin write('s... ');readln(s); writeln( brisanje(s) ); readln; end.

Za kraj bih jo htio rei jednu stvar u vezi procedura. U najavi procedure moe stajati ovako neto:
procedure abc(a,b:integer; var zbroj, umnozak:integer);

Sve je nadam se jasno, osim ovog dijela sa var. Otkud to najednom? To je tos kako moemo unutar procedure najaviti varijable koje emo koristiti drugim imenima izvan nje. Recimo da imam ovu proceduru koja e dati neke vrijednosti zbroju i umnoku, vjerojatno zbrojiti i pomnoiti brojeve a i b.
//ja cu onda u programu prvo pozvati proceduru abc(1,2,zbr,umn); //sad, broj 1 se dodijelio varijabli a u proceduri, broj 2 varijabli b //a zbr i umn su se svaki dodijelili varijablama zbroj i umnozak. //stos je sad u tome kako ja zbr i umn mogu koristiti! writeln('zbroj je ',zbr); writeln('umnozak je ', umn);

Vidite, ja kasnije zbr i umn koristim kao varijable u glavnom programu, bez da sam ih najavio u glavnom programu. Da sam htio napisati writeln(a), to nebi ilo jer a postoji samo u potprogramu. zbr postoji i u glavnom programu, a definiran je u proceduri. Zato je to zgodna stvar? Jer ista procedura moe napraviti vie stvari, ali i zato jer ovog puta procedura zapravo vraa neku vrijednost! Funkcija sama poprima vrijednost, i to samo jednu, a procedura moe vratiti hrpu vrijednosti. Moduli Modul je mjesto gdje moemo pospremiti nae potprograme a da se ne nalaze u samom programu. Prije smo imali ovo:
program //naziv programa var //varijable programa //funkcije i procedure begin //glavni program end.

A sad imamo ovo:


program //naziv programa

uses //moduli programa, gdje su funkcije i procedure var //varijable programa begin //glavni program end.

Razlika je u preglednosti, a i isti modul moe koristiti vie programa. Tako ako imamo istu funkciju za vie programa, definiramo ju u posebnom modulu i onda samo koristimo modul. Ve redovito koristimo modul crt u kojem ive procedura clrscr i funkcija gotoxy(x,y), na primjer. Da svaki put moramo ponovno definirati clrscr recimo, Pascal bi bio jo gori.
unit ime_modula; interface //samo deklaracije potprograma, dakle samo function x(nesto):tip, ne ostatak implementation //sve, citavi potprogrami kao i inace end.

Bitno je to da je interface samo suelje u kojem nam pie koji potprogrami tu ive. To je isto radi preglednosti! Ako ih imamo 50, tu emo imati u biti 50 imena, a tek kasnije u implementationu moemo raditi na svakoj. To je dakle da se lake snaemo. Zamislite modul crt koliko tamo ima funkcija!
unit modul1; interface function zbroj(a,b:integer):integer; procedure ispis(s:string); implementation function zbroj(a,b:integer):integer; //ostatak funkcije procedure ispis(s:string); //ostatak procedure end.

Dakle, u interface copy-pasteamo definiciju. Ovaj modul, modul1, emo pospremiti pod nazivom modul1, pa ga onda moemo koristiti u drugim programima.
program asdf; var //varijable uses modul1; begin //svasta ispis(a); //svasta zbroj(3,6); //svasta end.

Otprilike tako.

Rekurzija Uzmimo da imamo 2 potprograma, potprogram a i potprogram b. Nije toliko bitno to oni rade. Jasno, potprogrami a i b imaju nekakav unos s kojim neto naprave. Recimo da je taj unos nekakav broj x. Kad potprogram a radi neto na tom x-u, napisat emo ovako: a(x). Isto tako za potprogram b: b(x). Ti potprogrami su u biti funkcije, pa poprimaju neku novu vrijednost, dakle a(x) i b(x) su neki brojevi, isto kao to je sinus nekog kuta opet broj. Mi moemo napraviti da unos u jednu funkciju bude druga funkcija, odnosno a(b(x)) i b(a(x)), isto kao log(sin(x)). Ako napravimo ovo: a(a(x)), pribliili smo se ideji rekurzije. Rekurzija je funkcija koja zove samu sebe. Zna biti komplicirano za pojmiti, no evo zasad jedan primjer. Treba nai zbroj prirodnih brojeva do n. Dakle, funkcija f(n) = 1 + 2 + 3 + + n-1 + n. Jedan nain na koji bi to mogli rijeiti je iteracijom, odnosno ponavljanjem. Dakle jedna for petlja gdje i ide od 1 do n i zbraja. Sad emo to rijeiti rekurzijom. Da bude lake emo se vratiti definiciji, koja kae da funkcija zove samu sebe. To znai da e i s lijeve i s desne strane znaka jednakosti( = ) stajati funkcija f(x). Opet moemo vidjeti da taj unos x ne smije biti isti jer emo s obje strane imati isti f(x) koji e se, jasno, pokratiti. f(n) = 1 + 2 + 3 + + n-1 + n emo grupirati malo drugaije: f(n) = (1 + 2 + 3 + + n-1) + n. Ovo u zagradi je zbroj svih brojeva do n-1. Funkcija f(x) zbraja sve brojeve do odreenog broja. Dakle, ovo u zagradi je f(n-1). Tada f(n) = (1 + 2 + 3 + + n1) + n = f(n-1) + n, odnosno: f(n) = f( n-1 ) + n Jo jedino fali uvjet da je f(1) = 1, jer bi se inae ponavljalo u beskonanost. Rekurziji je svojstveno grananje, jer funkcija koja radi pozove novu funkciju koja pozove novu funkciju itd. Za n = 4 bi se to grananje moglo prikazati ovako:

4 +

f(4-1)

Odnosno, dobili smo 4 + 3 + 2 + 1, to je toan rezultat.

U Pascalu bismo to napravili ovako:


var n:integer; function zbroj(n:integer):integer; begin if n=1 then zbroj:=1 else zbroj:=zbroj(n-1)+n; end; begin write('n... ');readln(n); writeln(zbroj(n)); readln; end.

(ovi zapisi koji slijede nisu ispravni matematiki, nego sam samo ovo ponavljanje izrazio uz pomo i ) 1. 3 +

1 2 3 i 1 + + + = 3 + + , s time da ako je i = 1 je funkcija jednaka 3. 2 3 4 i

if i=1 then zbroj:=3 else zbroj:=zbroj(i-1)+(i-1)/i;

4. 2

1 2 3 i 1 + + = 2 , s time da je razlomak negativan ako je i paran broj. 2 3 4 i

if i=1 then zbroj:=2 else if i mod 2=0 then zbroj:=zbroj(i-1)-(i-1)/i else zbroj:=zbroj(i-1)+(i-1)/i;

7. 1 +

2 4 6 2i 2 + + + = 1+ 1 3 5 2i 3

if i=1 then zbroj:=1 else zbroj:=zbroj(i-1)+(2*i-2)/(2*i-3);

10. 5 +

1* 2 2 * 4 3 * 6 (i 1)(2i 2) + + + = 5 + 1 3 5 2i 3

if i=1 then zbroj:=5 else zbroj:=zbroj(i-1)+(i-1)(2*i-2)/(2*i-3);

13. 6 +

1 3 5 2i 3 + + + = 6 + 2 4 6 2i 2

if i=1 then zbroj:=5 else zbroj:=zbroj(i-1)+(2*i-3)/(2*i-2);

16. 5

1 2 3 i 1 + + = 5 3 5 7 2i 3

if i=1 then zbroj:=2 else if i mod 2=0 then zbroj:=zbroj(i-1)-(i-1)/(2*i-1) else zbroj:=zbroj(i-1)+(i-1)/(2*i-1);

to se tie ovih ostalih zadataka s rekurzijom, oni trae da se neto napravi sa nekim stringom. To onda nisu rekurzivne funkcije, nego rekurzivne procedure, i koristit emo onaj var u zagradi! 5. Upii poruku. Rekurzivno izdvoji znamenke iz poruke(modul).
//ne pisem modul ni nista, samo rekurzivni dio koji nas zanima! //dio u glavnom programu: s:='abc123'; znamenke(s,length(s),s2); //unosi se string i njegova duzina. //ovaj case uvijek radi, i za taj char na kojem je provjeri je li broj //ako da, ga doda nekom novom stringu s2 koji je globalna varijabla jer je //najavljen sa var. //konstanto se provjerava zadnja znamenka stringa, no ta duzina se stalno smanjuje //dok se ne dodje do 1, i tad su sve znamenke provjerene! procedure znamenke( s1:string; duzina:integer; var s2:string ); begin if duzina > 1 then znamenke( s1, duzina-1, s2 ); case s1[duzina] of '0'..'9': s2 := s2 + s1[duzina]; end;

Na istu foru su svi takvi zadaci koje nam je Vule dao. Vidim da nema zadataka sa rekurzivnim sortom(ima sa obinim potprogramom to nije problem), to mi je i drago jer ima puno posla za to. Neu vas tupit sad time.

Sretno na testu!

You might also like