Függvény (programozás)

A Wikipédiából, a szabad enciklopédiából

A számítógép-programozásban a függvény és az eljárás egy nagyobb program forráskódjának része, amely egy adott feladatot hajt végre, a kód többi részétől viszonylag független egység, és többször felhasználható anélkül, hogy a program kódjának több példányban is tartalmaznia kellene. Hasonló fogalmat jelölnek a szubrutin, metódus, procedúra vagy alprogram nevek is.

A szubrutin[szerkesztés | forrásszöveg szerkesztése]

A kék szubrutin három helyről van meghívva, és mindig a hívás helyéhez tér vissza

Ha egy adott műveletsorra egy programban több helyen is szükség van, az elemi megoldás az, hogy az adott kódrészletet mindenhol elhelyezzük, beillesztve a környezetébe. Ha újabb helyen merül fel rá igény, akkor a kódrészletet átmásoljuk a következő helyre is és így tovább. Ez terjengős és nehezen elemezhető forráskódot eredményezne, valamint nagyon sok fölösleges munkát. Ezért minden már a legkorábbi számítógépek kódkészlete is tartalmazott vezérlés átadó utasítást (Pl:Minszk–22), amelyet oda kell elhelyezni, ahol az adott kódrészletnek szerepelnie kellene, maga a kódrészlet (rutin) pedig a programban tetszőleges, külön helyen lehet. A rutint helyettesítő utasítás végrehajtásakor a számítógép odaugrik a rutin kezdőpontjára, végrehajtja a benne levő utasításokat, majd amikor egy utasítás jelzi, hogy ez a rutin véget ért, automatikusan visszatér az előző helyre, és onnan folytatódik a program végrehajtása, ahonnan a külön rutinra való átirányítás volt. A rutint elindító utasítás szakkifejezéssel meghívta a külön programrészletet, amelyet, mivel logikailag alárendelt része lett az egész programnak, valójában a szubrutin (al-rutin) névvel illetnek. A módszer előnye az, hogy ha egy másik helyen van szükség ugyanerre a szubrutinra, oda is csak a meghívó utasítás kerül, és amikor a szubrutin véget ért, a program automatikusan onnan folytatódik, ahonnan most a szubrutint meghívták. Tehát a visszatérés mindig az éppen aktuális meghívás helyére történik. Ebből eredően a szubrutin tetszőleges helyről tetszőleges alkalommal használatba vehető, és a kódját csak egyszer kellett megírni. (A szubrutin kódja egyenértékű a többi kóddal, ezért a szubrutinból is meghívhatók újabb szubrutinok is.) Ha pedig a szubrutinban levő műveletsoron változtatni kellett, így egyetlen helyen is elég volt a változást elvégezni.

Ez a megoldás annyira alapvetővé vált a számítógépes programokban, hogy a legalacsonyabb szinten, magában a gépi kódban is megvan a hívó és visszatérési utasítások megfelelője.

A szubrutin egy viszonylag rugalmas eszköz, olyannyira, hogy a visszatérési utasításnak nem is kötelező a szubrutin utolsó sorában lennie, sőt a szubrutinban több helyen is szerepelhet.

A szubrutinban is adatokkal kell dolgozni, ezért a munkához szükséges adatokat, paramétereket a program először a szokott módon (a változókban) eltárolja, majd a szubrutin ezekhez hozzáférve dolgozza fel azokat.

Az eljárás[szerkesztés | forrásszöveg szerkesztése]

A félreértés elkerülésére jelezzük, hogy az eljárás szó a szócikkben mindig a programkód egy részét jelenti, szemben a szó általános jelentésével.

Az eljárás (procedure) nagyon hasonlít a szubrutinhoz, de van közöttük egy lényeges eltérés. A szubrutinnak csak a kezdőpontja volt megjelölve azért, hogy a programkódban utalni is lehessen rá. Az eljárásnak meg van jelölve a végpontja is, tehát a forráskódban jól láthatóan elkülönült egységet alkot. Az eljárásból való visszatérésre így nincs is külön utasítás, hanem a visszatérés akkor történik meg, amikor az eljárás utolsó sora is végrehajtódott.

A korlátozás előnye az, hogy a fordítóprogram ellenőrizni tudja, hogy nincs-e logikai elcsúszás a programrészletek nyitó és zárópontjai között, tehát nincs-e olyan eljárás, amelynek lemaradt a végét jelölő kódszó, ez ugyanis a program teljesen rossz működéséhez vezetne.

Még egy előny, hogy az eljárás meghívásakor a hívó utasításban egyből át is adhatjuk a szubrutinnak, eljárásnak azokat a paramétereket, amelyekkel dolgoznia kell, és ha az eljárás ezeken a saját feladata érdekében változtat, a program többi részére ez a változás nem terjed ki.

A függvény és az eljárás különbsége[szerkesztés | forrásszöveg szerkesztése]

Az eljárás a végrehajtása során keletkező új adatokat a program egy közös tárhelyen helyezi el, amelyeket a program többi része az egyéb esetekben szokásos módon használ fel. A programokban kényelmesebb nem minden egyes elemi lépésre önálló utasítást adni, hanem ezekből néhányat egyszerűsítve összevonni is lehet, a programnyelvek ehhez különböző mértékű és fajtájú segítséget adnak. Az összevonások egyik fő fajtája a kifejezések használata. Ha például egy adott számot meg akarunk szorozni 2-vel, majd hozzáadni 3-at, a két lépés egyben írható le az X×2+3 alakkal. Ez már egy kifejezés, amelynek van egy végső értéke, eredménye. Ha a 2 helyén egy olyan számértéknek kellene állnia, amelyet egy eljárás számít ki, akkor megtehetjük, hogy az eljárás az eredményt először egy Y nevű tárolóelembe teszi, majd a program kiszámítja az X×Y+3 kifejezés értékét. Kimondottan kényelmi okokból viszont a programozók megtehetik azt is, hogy a kifejezésbe beleteszik az eljárást meghívó utasítást, ez esetben az Y helyére, és az eljárás neve itt helyettesíteni fogja azt a számértéket, amelyet az eljárás egy kiemelt eredményként előállít. Ha az eljárás egy téglalap területét számolja ki, máshol közölt adatok alapján, és a neve TERÜLET, akkor megoldható az, hogy az eljárás neve a területszámítás értékét helyettesítheti, így: X×TERÜLET+3. Ez esetben egy egész programrészlet által kiszámított érték lett belefoglalva egy kifejezésbe. Ilyen esetben, tehát amikor az eljárás (procedure) nem egyszerűen elvégez valami feladatot, hanem végül egy számítási értéket eredményez, amelyen önmaga megtestesít, az eljárást függvénynek (function) hívjuk. Szakkifejezéssel élve a függvény értéket ad vissza.

A matematikai függvények elvi jellegzetessége az, hogy a számítási képlet – amelynek a programban a számítást elvégző programrész felel meg – értéke egy vagy több megadott függvényváltozó értékétől függ. A programokban is megengedett ez; ha a területszámításhoz meg kell adni a téglalap A és B oldalait, akkor az eljárást elindító utasítás nézhet ki így:

HÍV TERÜLET(A,B)

Ha a TERÜLET nem csak eljárás, hanem függvény, tehát önmaga helyettesíti az eredményt, értéket ad vissza, akkor a függvény így, paraméterekkel együtt szerepelhet a kifejezésben is:

X×TERÜLET(A,B)+3

Abból a szempontból tehát, hogy az eljárás meghívásakor megadhatunk-e paramétereket is, az eljárás és a függvény között nincs különbség. Ám az eljárás egyes régebbi programnyelvekből hiányzott, emiatt a szubrutin és a függvény volt a két összehasonlítható eszköz, és a függvény ekkor kapta a nevét a matematikai függvény formai analógiája alapján.

Nyelvi alkalmazások[szerkesztés | forrásszöveg szerkesztése]

Hangsúlyozzuk, hogy a szubrutin, eljárás és függvény közötti technikai különbségtétel kizárólag kényelmi célokat szolgál, a programozó munkájának megkönnyítésére alakultak ki, mivel valójában minden program megírható ezek használata nélkül is.

Több nyelvben, mint például a Pascal, a modern BASIC, a FORTRAN és az Ada különbséget tesznek a függvények és az eljárások között. Más nyelvekben, mint a C és a LISP, nincs meg ez a különbségtétel és ezeket a fogalmakat szinonimaként használják, itt a függvény kódjában (például a VOID kódszóval) jelzik, ha a függvény nem ad vissza értéket, csak eljárás szerepében kerül használatba.

A metódus (method) kifejezést gyakran használják az objektumorientált programozással kapcsolatban, különösen olyan szubrutinokra, amelyek objektum részei. Ezen kívül még a típusosztályokkal kapcsolatban is használják.

A számítógép programozásban a szubrutin mint fogalom Maurice Wilkes, Stanley Gill és David Wheeler 1951-ben kiadott könyvében jelent meg. Ők „closed subroutine”-nak (zárt szubrutin) hívták, utalva a szubrutinok formailag is láthatóvá tett lezárására. Az 1960-as években gyártott számítógépek utasításkészlete általában tartalmazott szubrutinhívást lehetővé tevő utasítást vagy utasításokat!

A függvények és eljárások használatnak előnyei

  • csökkenthető a kódismétlődés
  • ugyanaz a függvény más programban is használható
  • összetett problémák egyszerűbb részekre bonthatók, ami könnyebbé teszi a kód frissítését és bővítését
  • javítható a program olvashatósága
  • elrejthetők és szabályozhatók a program egyes részei

Összetevőik lehetnek

  • a kód törzse, amely a híváskor végrehajtódik
  • paraméterek, melyeket a függvény híváskor megkap
  • visszatérési érték, amely a hívás helyére adódik vissza

Példa az eljárások és a függvények közti különbségre[szerkesztés | forrásszöveg szerkesztése]

Legyen a feladat a megadandó középpontú és sugarú kör rajzolása. Az erre megírt Pascal nyelvű eljárás első, ún. deklarációs sora így nézhet ki:

PROCEDURE rajzolKor(origox, origoy : Integer; r : Real);

amely tartalmazza az eljárásnak a programozó általá választott nevét (rajzolKor), továbbá azt, hogy a középpont koordinátájának két átadandó számértékét egy origox és origoy nevű tárelem fogja tárolni, amelyek csak egész számok lehetnek, a kör sugara pedig egy r nevű tárolóelemben lesz található, ez lehet törtszám is. Ez után a sor után következik a feladat megoldására szolgáló utasítássorozat.

Egy másik feledat legyen a megadandó sugarú kör területének a kiszámolása egy függvénnyel, vagyis a függvény neve logikailag szimbolizálni fogja a számtás végeredményét. Látható lesz, hogy a függvény programkódjának egyértelműen jelölve van a kezdete és vége is, így elkülönül a program többi részétől.

FUNCTION szamolKorKerulet(r : Real) : Real;
BEGIN
   szamolKorKerület := (r + r) * pi;
END;

Kirajzolhatunk egy 50 képpont átméréjű kört a (100,100)-as pontba, majd kiírathatjuk ugyanennek a körnek a kerületét a következőképpen:

...
rajzolKor(100,100,50);
WriteLn(szamolKorKerulet(50));
...

Ugyanez a különbség C nyelven a void visszatérési típusnév használatával érhető el:

void RajzolKor(int x, int y, double r);
double SzamolKorKerulet(double r);
 
...
 
int x = 100; int y = 100; double r = 50;
RajzolKor(x, y, r);
std::cout << SzamolKorKerulet(r) << std::endl;

Források[szerkesztés | forrásszöveg szerkesztése]

  • dr. Úry László: Commodore 64 I-II. (LSI Alkalmazástechnikai Tanácsadó Szolgálat, Budapest, 1985)
  • Kaszanyiczki László: Visual Basic 5.0 felhasználóknak (LSI Oktatóközpont, 1998) - Eljárások és függvények
  • Programozás – Pascal II. (prog.ide.sk)