Procedúry a funkcie
Procedúry a funkcie sú základom hierarchickej štruktúry programu.
Hierarchická štruktúra programu úzko súvisí s postupným návrhom programu metódou zhora nadol.
Táto metóda spočíva v opakovanom rozklade zložitejších problémov na menšie podproblémy pričom sa tiež prihliada na to, aby abstraktné príkazy (ktoré riešia zložitejšie problémy) boli postupne pretransformované na problémy menej abstraktné (ktoré riešia menšie podproblémy).
Týmto spôsobom prechádzame od globálneho návrhu algoritmu riešenia daného problému postupným rozpracovávaním abstraktných príkazov až k zápisu algoritmu v programovacom jazyku. Abstraktné príkazy, o ktorých tu hovoríme, môžu byť zrealizované práve pomocou procedúr a funkcií.
Príklad: Študent si vyberie predmety, ktoré by chcel absolvovať počas štúdia a je potrebné vytvoriť preň usporiadanie predmetov podľa prerekvizít tak, aby si ich mohol podľa tohto usporiadania zapísať v jednotlivých rokoch štúdia. |
Problém sa rozpadne na niekoľko podproblémov. Budeme hovoriť najprv o abstraktných príkazoch a hlavne, čo od nich očakávame. Podproblémy:
|
napr. |
Typezaznam = record meno:array[1..10] of char; { 10 bajtov} rocnik:1..5; { 1 bajt} priemer:real; { 8 bajtov} end; |
meno |
rocnik |
priemer |
a pracujeme s nimi takto: |
Var z:zaznam; begin ... z.meno:='Jan Hrasko'; z.rocnik:=1; z.priemer:=1.33; ... end; |
Pomocou záznamu reprezentujeme bod ako dvojicu čísel (súradníc): |
Typebod=record x,y:real end; |
Príklad: Procedúra vypočíta koeficienty A, B, C rovnice priamky prechádzajúcej dvoma rôznymi bodmi B1, B2. V prípade chybného zadania bodov, t.j. ak sú body totožné procedúra vypíše o tom správu a všetky tri koeficienty A, B, C sa rovnajú 0. |
procedure priamka (B1, B2: BOD; var A, B, C: real);begin if (B1.X=B2.X) and (B1.Y=B2.Y) then begin writeln(' Zadane body su totozne '); A:=0; B:=0; C:=0; end else begin {Vypocet koeficientov priamky } A:=B2.y-B1.y; B:=B1.X-B2.X; C:=-A*B1.X-B*B1.Y end end; {priamka} |
V príklade si všimnime, že špecifikácie formálnych parametrov sú oddelené bodkočiarkou.
Vo všeobecnosti môže byť špecifikovaných viacej premenných toho istého typu (prípadne bez typu) sú oddelené čiarkami.
Môže byť viacej špecifikácií formálnych parametrov, ktoré sú oddelené bodkočiarkami.
Každá špecifikácia predstavuje skupinu parametrov (aspoň jedného) určitého druhu.
Podľa druhu rozlišujeme
Procedúrové a funkcionálne typy
Tieto typy sú rozšírením štandardnej definície jazyka Pascal. Ich zavedením sa zjednodušilo používanie procedúr a funkcií ako formálnych parametrov v definíciách iných procedúr a funkcií. Dôvodom pre zavedenie bola myšlienka zaviesť typ, ktorý umožní kontrolu parametrov, resp. typu funkcie.
Deklarácia procedúrového typu má syntax podobnú ako deklarácia procedúry alebo funkcie s tým rozdielom, že je vynechané meno (identifikátor) procedúry alebo funkcie.
Príklad:
type
Proc = procedure;
Sproc = procedure ( var X, Y: integer);
Strproc = procedure (s: string);
Mfun = function (X: real): integer;
máme procedúru, ktorá vráti pomocou parametra minimum z dvoch čísel: |
proceduremin(a,b:integer; var m:integer); begin if a<b then m:=a else m:=b; end; |
Podprogram môžeme definovať v tvare funkcie:
a teraz min ako funkcia v Turbo pascale: |
functionmin(a,b:integer):integer; begin if a<b then min:=a else min:=b; end; |
a teraz min ako funkciav objektovom pascale: |
functionmin(a,b:integer):integer; begin if a<b then Result:=a else Result:=b; { v Turbo pascale bolo min:=a} end; |
Logická funkcia, ktorá vracia true, ak je vstupný parameter písmenom: |
functionpismeno(z:char):boolean; begin Result:=(z>='a') and (z<='z') or (z>='A') and (z<='Z'); end; |
Logická funkcia jecifra, ktorá vracia true, ak je vstupný parameter cifrou: |
functionjecifra(z:char):boolean; begin Result:=(z>='0') and (z<='9'); end; |
Celočíselná funkcia, ktorá vracia hodnotu načítanej cifry (inak -1): |
functioncifra(z:char):integer; begin if jecifra(z) then Result:=ord(z)-ord('0') else Result:=-1 end; |
funkcia zistí, či je číslo nepárne: |
functionodd1(x:integer):boolean; begin Result:= x mod 2 = 1; end; |
celočíselná funkcia, ktorá vracia súčet prvých N celých čísel: |
functionsuma(N:integer):integer; begin Result:=0; while N>0 do begin Result:=Result+N; dec(N); end; end; |
funkcia spracuje jeden znak zo vstupu: |
var z:char; function znak(var t:TextFile):char; begin if eof(t) then z:='#' else if eoln(t) then begin z:=' '; readln(t) end else read(t,z); Result:=z; end; |
všimnite si použitie textového súboru ako formálneho parametra - zapamätajte si, že textový súbor ako parameter musí byť vždy typu
var-parameter!
Preskakovanie medzier |
while znak(t)=' ' do; |
Príklad pre počítanie mocniny čísla:
funkcia počíta mocninu čísla: |
functionmocnina(x,K:integer; var ok:boolean):integer; var hranica:integer; begin Result:=1; hranica:=maxint div x; while (K>0) and (Result<=hranica) do begin Result:=Result*x; dec(K); end; ok:=K=0; end; |
Programové jednotky -- UNITY
Štruktúra programových jednotiek
unit identifikátor;interface uses Zoznam programových jednotiek; {nepovinné} Verejné deklarácie a definície; implementation uses Zoznam programových jednotiek; {nepovinné} Interné deklarácie a definície; Procedúry a funkcie; begin Inicializačné príkazy; end. |
Programová jednotka mat_unit obsahuje procedúry pre prácu s maticami: na čítanie matice, výpis matice a súčet dvoch matíc rovnakého typu. |
Unit mat_unit;Interface const nmax=20; mmax=20; type matica=array[1..mmax,1..nmax] of real; procedure nacit_mat(var Ma:matica; m,n:integer; var f:text); {Procedura nacita maticu s m riadkami a n stlpcami z textoveho suboru f} procedure vypis_mat(Ma:matica; m,n:integer; var f:text); {Procedura vypise maticu s m riadkami a n stlpcami do textoveho suboru f} procedure sucet_mat(Ma, Mb: matica; m,n: integer; var Mc:matica); {Procedura vypocita sucet dvoch matic rovnakeho typu} Implementation procedure nacit_mat(var Ma:matica; m,n:integer; var f:text); var i, j:integer; begin for i:=1 to m do begin for j:=1 to n do read(f, Ma[i,j]); readln(f); end; end;{nacit_mat} procedure vypis_mat(Ma:matica; m,n:integer; var f:text);var i, j:integer; begin writeln(f,'Vypis matice'); writeln(f); for i:=1 to m do begin for j:=1 to n do write(f, Ma[i,j]:10:2); writeln(f); end; end;{vypis_mat} procedure sucet_mat(Ma, Mb: matica; m,n: integer; var Mc:matica); var i, j:integer; begin for i:= 1 to m do for j:= 1 to n do Mc[i,j]:=Ma[i,j]+Mb[i,j]; end; {sucet_mat} begin end. |
Použitie programových jednotiek
Program, ktorý testuje použiti e programovej jednotky mat_unit. |
program Matica_prog; uses mat_unit; var m,n:integer; fvst, fvyst: text; MM: matica; begin Assign(fvst,'mat.dat'); Assign(fvyst,'matv.dat'); reset(fvst); rewrite(fvyst); writeln('Zadajte pocet riadkov a pocet stlpcov'); readln(m,n); nacit_mat(MM,m,n,fvst); vypis_mat(MM,m,n,fvyst); vypis_mat(MM,M,n,output); readln end. |