10. Eljárások és függvények

Eljárások és paraméterek

Nagyobb feladatot célszerû (már algoritmus-szinten is) lépésekre bontani. Továbbá, vannak olyan tevékenységek, melyeket a programban több helyen is el kell végezni. Ilyen lehet a figyelmeztetõ sípolás:

sound(880); delay(50); nosound;

Az ilyen rész-tevékenységeket külön egységbe foglalhatjuk, ezek neve alprogram (subroutine) avagy eljárás (procedure). Az eljárásoknak azonosítójuk van, és a deklarációs részben adjuk meg õket a következõképpen:

Mint látható, a saját deklarációs rész miatt az eljárás valóban önálló programként viselkedhet. A saját deklarációs részben nem szerepelhet a Program és a Uses utasítás. Példa a sípoló eljárásra:

Procedure Beep; {ennek az eljárásnak nincsenek paraméterei}
 Begin {sem deklarációs része}
    sound(880); delay(50); nosound;
 End;

Az eljárásokat a nevükkel indíthatjuk el a fõprogramból vagy más eljárásokból (természetesen csak akkor, ha az eljárás deklarációja megelõzte az eljárásra való hivatkozást). Ez az eljáráshívás:

VAR a:integer;
BEGIN
 Repeat
    readln(a);
    if a=0 then beep;
{eljáráshívás}
 Until a<>0;
 Writeln(1/a); beep; beep;
END.

Így az eljárások pontosan úgy mûködnek, mint a Pascal saját utasításai. Ha úgy tetszik, a Pascal utasításkészletét bõvítettük, amikor egy azonosítóhoz hozzárendeltünk egy tevékenységet.

Ha azután az egyszerû sípszót bonyolultabb dallamra akarjuk átírni, csak a Beep eljárásban kell elvégezni a változtatásokat. Például füttyszóhoz:

Procedure Beep;
 var i:integer;
 Begin
    for i:=300 to 500 do begin
       sound(i); delay(5); nosound;
    end;
 End;

Ez az eljárás használ egy saját változót is. Miután az eljárást megírtuk, nem foglalkozunk többet vele, hanem a program más részeire összpontosítjuk figyelmünket. Éppen így segítenek az eljárások a programozásban: a feladatot részekre (a programot eljárásokra) bontva mindig csak egy részfeladattal foglalkozunk. De mi történik, ha a fõprogramban máshol is használunk egy i változót?

Az eljárás belsejében deklarált saját, avagy lokális változók kívülrõl, vagyis az eljárást hívó programból láthatatlanok: az eljárás hívásakor keletkeznek, és az alprogram lefutása után megszûnnek. Ha a fõprogramnak van azonos nevû változója, azt a Pascal az eljárás mûködésének idejére elraktározza.

Az eljárás tudja használni mindazokat a saját változóitól eltérõ nevû változókat, melyeket az eljáráson kívül, elõtte deklaráltunk. Ezek az eljárás szempontjából külsõ, azaz globális változók. Példa:

VAR a,b:integer;

Procedure Valami;
 Var a:integer;
 Begin
    a:=5;
{lokális változó}
    b:=7; {a fõprogram globális változója}
 End;

BEGIN
 a:=1;
 b:=2;
 Valami;
 Writeln(a,b);
END.

A program 1-et ír ki (mert a fõprogram globális a változóját nem zavarta az eljárás azonos nevû lokális a változója), és 7-et (mert a b az eljárásban is globális változó volt).

A Pascal legtöbb utasítása paramétert is kap híváskor. Hasonlóképpen az eljárást is lehet paraméterezni. A paraméterlista a változódeklarációhoz hasonlóan a paraméterek azonosítóját és típusát tartalmazza. Példa egy karaktert adott helyre kiíró eljárásra:

Procedure Kiirxy(x,y:integer;c:char);
 Begin
    gotoxy(x,y); write(c);
 End;

A paraméterek az eljárásban lokális változókként viselkednek, azzal a különbséggel, hogy nem az eljáráson belül kapnak értéket, hanem az eljárás hívásakor, kívülrõl:

VAR i:integer;
BEGIN
 For i:=1 to 10 do
    Kiirxy(10,i,'*');
END.

Például amikor az i értéke 3, az eljárás hívásakor az egyes paraméterek értéke: x=10, y=3, c='*' lesz. Vagyis, eljáráshíváskor a hívó utasításban lévõ értékeket veszik fel az eljárás paraméterei. Ez az érték szerinti paraméterátadás.

Elõfordul, hogy az eljárásnak változókat szeretnénk átadni, és ezekkel kell valamilyen mûveletet végezni, tehát a hívó program változóit kell változtatni. Ezt megoldhatjuk úgy is, hogy globális változókat használunk, melyeket tud kezelni az eljárás, de akkor a program áttekinthetetlenebb lesz, mert az eljárás önállósága megszûnik. Erre a célra használható a cím szerint paraméterátadás, más néven a változóparaméterek. Ekkor paraméterként nem értéket adunk át, hanem változót, és ezt a paraméterlistában Var szóval jelöljük:

Procedure Csere(Var a,b:integer);
 Var m:integer;
 Begin
    m:=a; a:=b; b:=m;
 End;

VAR p,q:integer;
BEGIN
 p:=8;
 q:=4;
 Csere(p,q);
 Writeln(p,q);
END.

Ez a program a 4,8 számokat írja ki. Ha a var szócskát nem írtuk volna a paraméterlista elejére, a fõprogram változóival semmi nem történt volna, csak az eljárás lokális változóiban cseréltük volna fel az értékeket. A var szó hatására a következõ történik: eljáráshíváskor létrejön az eljárás lokális a és b változója, de ezek a változók ugyanarra a memóriacímre mutatnak, mint a fõprogram p és q változói. Tehát akármilyen mûveleteket végzünk az a és b változókkal, ugyanaz fog történi a fõprogram p és q változóival. Így a Csere eljárást nem is lehet számokkal meghívni, csak integer típusú változókkal.

Használhatunk változó- és közönséges paramétereket egyszerre is: a

procedure valami(s:string;var c:integer)

deklarációnál s közönséges, c pedig változóparaméter. A Pascal több utasítása is használ változóparamétert, pl. az Initgraph.

Függvények

A függvények pontosan úgy mûködnek, mint az eljárások, azzal a különbséggel, hogy visszatérési értéket is szolgáltatnak. A visszatérési értéket a függvény törzsében a függvénynév:=érték utasítással állíthatjuk be. A függvény deklarálásakor jelezni kell a visszatérési érték típusát, mely csak elemi típus lehet.

Function Kob(a:real):real;
 Begin
    Kob:=a*a*a;
 End;

BEGIN
 writeln(Kob(65));
END;

A függvény ezeken kívül ugyanúgy mûködik, mint egy eljárás. Nem elegáns azonban, ha a függvény a visszatérési érték kiszámításán kívül mást is csinál (mellékhatások). Ilyen esetekben inkább használjunk eljárást, és a visszatérési értéket változóparaméterrel adjuk vissza a hívó programnak.

A Pascalban megfelelõ beállítás esetén a függvényeket eljárásként is meghívhatjuk: ekkor csak a függvény mellékhatása jelentkezik. Például a Readkey függvényt utasításként használva a program egy billentyû lenyomásáig várakozik.

Még egy példa:

Function maxi(a,b:integer):integer;
 Begin
    if a>=b then Maxi:=a else Maxi:=b;
 End;

A Pascal kiegészítésként felsorolt néhány szövegkezelõ eljárása és függvénye jó példát ad a változóparaméterek használatára. Láthatjuk: vagy függvényt, vagy változóparaméteres eljárást használunk a visszatérési érték megkapásához.

Elõzõ fejezet
Tartalomjegyzék
Honlap