08. Alprogramok

7. Alprogramok


Az alprogram olyan utasítások csoport, amelyet a program bizonyos pontjairól aktivizálhatunk. Az alprogramokat a deklarációs részben kell megírnunk (procedure, function kulcsszavak után). Az alprogramok tartalmazhatnak újabb alprogramokat (egymásba ágyazás).
Akkor használjuk oket, ha
- bizonyos tevékenység többször elofordul a programban,
- egy nagy programot tagolni, strukturálni szeretnénk.
Két fajtája van:
- eljárás (procedure): egy tevékenységcsoportot hajt végre, utasításszeruen hívjuk (ld. standard eljárások),
- függvény (function): feladata egy érték eloállítása, hívásakor neve operandusként egy kifejezésben szerepelhet (ld. standard eljárások).
Már eddig is sok szabványos eljárást és függvényt használtunk, melyeket a különbözo egységekben deklaráltak. Nézzük, hogyan készíthetünk saját alprogramokat!

7.1 Eljárás - Procedure

a, Szerkezete:
Hasonló a programéhoz.
Eljárás fej: PROCEDURE azonosító [ ( formális paraméter lista ) ];
Deklarációs rész:


Label...
Const...
Type...
Var...
Procedure...
Function...
Végrehajtandó rész: Begin
utasítások
End;
ahol, formális paraméter lista:
[Var] azonosító [, azonosító...] : típusazonosító [; [Var] azonosító [, azonosító...] : típusazonosító...]

Például:

procedure Teglalap(a, b: integer; var t, k: integer);
begin
t := a * b;
k := 2 * (a + b)
end;
b, Az eljárás hívása:
azonosító [ (aktuális paraméter lista)]

ahol az aktuális paraméter lista elemei kifejezések vagy változók lehetnek (ld. paraméterátadás) egymástól vesszovel elválasztva.

Pl. Teglalap(5, 4, Ter, Ker)

c, Az eljárások hatásköre:

A Pascal nyelv befelé struktúrált, az alprogramokat egymásba ágyazhatjuk (az alprogram deklarációs részében is lehet alprogram). Ezért fontos tisztán látnunk, hogy hogy a foprogramból illetve egy alprogramból mely eljárásokat hívhatjuk meg:
- A program illetve egy eljárás meghívhatja (ismeri) azokat az alprogramokat, melyeket a program vagy az adott alprogram deklarációs részében deklaráltunk, de azok alprogramjait már nem.
- Egy alprogram meghívhatja az ugyanazon deklarációs részben (, ahol ot deklaráltuk) korábban deklarált alprogramokat.
- Egy alprogram meghívhatja az ot tartalmazó eljárásokat.
- Egy alprogram meghívhatja saját magát.

Nézzük a fenti eseteket egy példán keresztül.

d, Paraméterek:

A paraméterek az eljárás és az ot hívó programrész közötti adatcserét, kommunikációt szolgálják. A formális paraméterekkel írjuk le az alprogram tevékenységét. Híváskor ezek helyére konkrét objektumokat, aktuális paramétereket írunk.
Az aktuális és a formális paramétereknek meg kell egyezniük számban, sorrendben és típusban.
Vigyázzunk, hogy a formális paraméterek típusának megadásakor csak típusazonosítót használhatunk, így pl. a következo eljárásfej hibás: procedure elj (t: array[1..10] of real);

A paraméterátadás két féle módon történhet:

- Érték szerinti paraméter átadás (a deklarációban a formális paraméter elott nincs Var)

Ekkor az aktuális paraméter értéke kerül át a formális paraméterbe. Az eljárás minden egyes hívásakor a rendszer tárterületet rendel a verem memóriában a formális paraméterekhez, és ide másolja be az aktuális paraméterek értékeit. Az eljárás végeztével ez a terület felszabadul. Az aktuális paraméter értékét az eljárás nem változtathatja meg, így ez csak bemeno paraméter.
Az aktuális paraméter kifejezés lehet.

- Cím szerinti paraméter átadás (a deklarációban a formális paraméter elé Var -t írunk)

Az aktuális paraméter címe kerül át a formális paraméterhez, ha változik a formális paraméter, akkor változik az aktuális is. Ezáltal egyaránt használhatjuk be- és kimeno paraméterként is.
Az aktuális paraméter csak változó lehet.

e, Lokális és globális változók

Egy eljárásban deklarált változókat ezen eljárás lokális változóinak nevezzük. Ezek a program más részein nem ismertek. (Így különbozo eljárásokban elofordulhatnak azonos nevu változók, amelyeknek azonban semmi közük egymáshoz.) A lokális változókhoz (az eljárás paramétereihez hasonlóan) a rendszer a veremben rendel tárterületet, dinamikus módon, azaz csak akkor van címe a változóknak, ha az eljáráson van a vezérlés. A lokális változók értéke az eljárás két hívása között elvész.

Egy eljárásra nézve globális változó egy ot tartalmazó eljárásban vagy a foprogramban deklarált változó. Ezt az eljárás ismeri, hacsak nem deklaráltunk egy vele azonos nevu lokális változót vagy az eljárásnak nincs egy vele azonos nevu paramétere. Ekkor a lokális változó "eltakarja" a globálisat. A globális változó értéke természetesen nem vész el. (Abban az esetben használhatunk egy a lokálissal azonos nevu globális változót, ha az a foprogram változója. Ekkor a program nevével kell minosítenünk a globális változót: programnév.változónév.)

Egy példa a lokális és globális változók értelmezésére.

f, Információ csere

Összefoglalva elmonhatjuk, hogy egy alprogram kétféle módon kommunikálhat az ot hívó programegységgel,
- a paramétereken keresztül,
- a globális változók segítségével.

Példák a kétféle adatcserére.

7.2 Függvény - Function


A függvény feladata egy érték eloállítása. Ezt az értéket a függvény nevéhez rendeljük, a függvény törzsében kell szerepelni legalább egy értékadó utasításnak, amelyben a függvény neve a baloldalon áll. (Vigyázzunk, ha a jobboldalon szerepeltetjük a függvény nevét, akkor az már rekurziót jelent. Példa egy ilyen hibára.)
A függvényt egy kifejezésben hívhatjuk meg, pl. egy értékadó utasítás jobboldalán.
Szerkezete megegyezik az eljáráséval azzal a különbséggel, hogy még meg kell határoznunk a viszatérési érték típusát is. Így a függvény feje:
FUNCTION azonosító [ ( formális paraméter lista ) ]: típusazonosító;

ahol a típusazonosító csak csak sorszámozott, valós, karakterlánc vagy mutató lehet.

Pl.

function Tangens(Alfa: real): real;
begin
if cos(Alfa) <> 0 then
Tangens := Sin(Alfa) / Cos(Alfa)
end;


7.3 Rekurzió

Ha egy alprogram saját magát meghívja, akkor rekurzióról beszélünk. Megkülönböztethetünk közvetlen és közvetetten rekurziót.
A rekurzió alkalmazásának egyik területe, amikor úgy oldunk meg egy problémát, hogy visszavezetjük egy egyszerubb esetre, majd ezt addig folytatjuk, míg el nem jutunk a triviális esetig. A módszer a matematikai indukción alapszik.
A megoldás lépései:
1. Megkeressük azt a legegyszerubb esetet, ahol a megoldás már magától értetodo - triviális eset. Ekkor áll le a rekurzív hívások sorozata.
2. Megvizsgáljuk, hogy ismételt egyszrusítésekkel hogyan juthatunk el a triviális esethez. (Az általános esetet visszavezetjük az eggyel egyszerubbre.)

Példák:
1. Faktoriális számítás
- Triviális eset: 1! = 1
- Egyszerusítés: N! = N*(N-1)!
Ezzel a problémát megoldottuk, már csak kódolnunk kell.
Megoldás
Megj.: Bár a feladat kituno példa a rekurzív algoritmusra, az iterációs (ciklussal történo) megodás jobb, mivel az ismételt függvényhívások idoigényesek.
2. Fibonacci sorozat (1, 1, 2, 3, 5, 8, 13...) N. eleme
- Triviális eset: az elso és a második elem értéke 1.
- Egyszerusítés: az N. elem az N-1 - edik és az N-2 - dik elemek összege.
Megoldás





A cikk tulajdonosa: RedQueen
http://RedQueen.uw.hu

A cikk webcíme:
http://RedQueen.uw.hu/modules.php?name=Sections&op=viewarticle&artid=52