Szubrutin ( eng. szubrutin ) - egy számítógépes program elnevezett vagy más módon azonosított része, amely egy adott műveletsor leírását tartalmazza. Egy szubrutin többször is meghívható a program különböző részeiből. A programozási nyelvekben speciális szintaktikai eszközök vannak az alprogramok tervezésére és használatára.
A szubrutinok eredetileg a programok optimalizálásának eszközeként jelentek meg az elfoglalt memória mennyisége szempontjából - lehetővé tették, hogy a programban ne ismételjék meg az azonos kódblokkokat, hanem egyszer leírják és szükség szerint hívják. A szubrutinoknak ez a funkciója mára kisegítővé vált, fő céljuk a program felépítése a könnyebb érthetőség és karbantartás érdekében.
A programok szubrutinokra bontásának előnyei a következők:
A legegyszerűbb esetben (az assemblereknél ) az alprogram a program fő részétől elkülönülő parancsok (operátorok) sorozata, amelyeknek a végén egy speciális paranccsal lehet kilépni a szubrutinból. Általában egy szubrutinnak van neve is, amelyen hívható, bár számos programozási nyelv lehetővé teszi a névtelen szubrutinok használatát is. A magas szintű nyelvekben egy szubrutin leírása általában legalább két részből áll: egy "fejlécből" és egy "törzsből". A szubrutin fejléce leírja a nevét és esetleg a paramétereit, azaz tartalmazza a szubrutin hívásához szükséges információkat. A törzs olyan utasítások halmaza, amelyek a szubrutin meghívásakor végrehajtódnak.
Egy szubrutin hívása az alprogram nevét tartalmazó hívási utasítással történik. A legtöbb modern programozási nyelvben az invocation parancs egyszerűen a meghívott szubrutin neve, amelyet opcionálisan tényleges paraméterek követnek (lásd alább ).
A következő Pascal példában a subprog háromszor kerül meghívásra a főprogramból:
program SubProgExample ; // Az alprogram leírása subprog eljárás subprog ; // A szubrutin nevét tartalmazó fejléc begin // a szubrutin törzsének kezdete WriteLn ( 'Bye' ) ; vége ; // szubrutin törzs vége begin WriteLn ( 'Hello' ) ; subprog ; // Alprogram 1. hívása ; // 2nd call subprog ; // 3. hívás vége .Egy ilyen program végrehajtásának eredménye a "Hello" karakterlánc és a három "Bye" karakterlánc kimenete lesz.
A hívási eljárás végrehajtási környezetének mentésére és visszaállítására, a használt gépi regiszterek esetleges nemkívánatos változásaival kapcsolatos mellékhatások kiküszöbölésére a fordító minden egyes eljáráshoz speciális parancssorozatokat generál, amelyeket az eljárás prológjának és epilógusának neveznek .
Egyes programozási nyelvek (például Pascal, Ada, Modula-2) lehetővé teszik a beágyazott szubrutinok alkalmazását, vagyis szubrutinok elhelyezését más alprogramok belsejében. Az ilyen beágyazott szubrutinok csak abban az alprogramban használhatók, amelyben deklarálva vannak. Más esetekben (például a C nyelvben) az alprogramok egymásba ágyazása nem megengedett. A szubrutinok egymásba ágyazása alapvető előnyökkel nem jár, de a program logikusabb felépítéséhez kényelmes lehet (ha valamelyik szubrutin csak valamelyik másik szubrutinban kerül felhasználásra, logikus az elsőt a másodikba helyezni).
Az alprogramokat gyakran használják sztereotip műveletek ismételt végrehajtására különböző adatokon. Az alprogram általában hozzáfér a főprogramban leírt adatobjektumokhoz (legalábbis ezek egy részéhez), így a feldolgozott adatok szubrutinba való átviteléhez elegendő, ha például globális változókhoz rendeljük őket. De ez a módszer nem különösebben kényelmes, és tele van hibákkal.
A paraméterek szubrutinba való ellenőrzött átvitelének és az onnan származó eredmények visszaadásának biztosítására a paramétermechanizmust használják . A paraméterek leírása az alprogram leírásában (a fejlécében) található, és az eljáráson belül ugyanúgy használhatók, mint az abban leírt változók . Egy eljárás meghívásakor az egyes paraméterek értékei a hívó parancsban vannak megadva (általában a hívott szubrutin neve után).
program SubProgExample2 ; // Az alprogram leírása subprog eljárás subprog ( Line : String ) ; // Fejléc, amely tartalmazza a szubrutin nevét begin // szubrutin törzsének kezdete WriteLn ( Line ) ; vége ; // szubrutin törzs vége begin WriteLn ( 'Hello' ) ; subprog ( 'Viszlát,' ) ; // 1st call to subprog ( 'szerelmem,' ) ; // 2nd call to subprog ( 'good bye!' ) ; // 3. hívás vége .A fenti példában az alprog szubrutin Line paramétere minden hívásban más értékre van beállítva, így ugyanazok helyett más vonalak jelennek meg.
Egy szubrutin fejlécében és törzsében leírt paramétereinek megkülönböztetésére a szubrutin meghívásakor megadott paraméterektől formális és tényleges paramétereket használunk. A formális paraméterek egy szubrutin deklarálásakor vagy definiálásakor adhatók meg, a tényleges paraméterek pedig közvetlenül a meghívásakor. Tehát az utolsó példában a Line paraméter a subprog fejlécében és törzsében a formális paraméter, és az alprogram első hívásakor használt "Good bye" karakterlánc a tényleges paraméter. Egy szubrutin meghívásakor a hívási parancsban megadott aktuális paraméterek a megfelelő formális paraméterek értékeivé válnak, ami biztosítja az adatok átvitelét az alprogramba.
Számos módja van a paraméterek átadásának egy szubrutinnak.
A programozási nyelv lehetővé teheti, hogy paramétereket adjon át a szubrutinoknak akár csak érték, akár érték és hivatkozás alapján, akár név és érték alapján. Az utóbbi két esetben külön szintaktikai konstrukciókat használnak a paraméterek átadásának megkülönböztetésére (Pascalban ez a var kulcsszó a paraméter leírásánál). Valójában, ha a nyelv tartalmazza a hivatkozás (mutató) fogalmát, akkor megteheti anélkül, hogy hivatkozással átadna egy paramétert (ez mindig modellezhető egy "referencia" típusú paraméter leírásával), de ez a funkció kényelmes, mivel lehetővé teszi, hogy formális paraméter-hivatkozással dolgozzon hivatkozás nélkül , valamint növeli a program megbízhatóságát és biztonságát.
A hivatkozással átadott paraméterekre természetes korlátozások vonatkoznak: az ilyen paramétert híváskor helyettesítő tényleges paraméternek változónak kell lennie (vagyis címmel kell rendelkeznie), és az erősen tipizált nyelvekben is pontosan azonos adattípussal kell rendelkeznie.
A magas szintű programozási nyelvekben kétféle szubrutin létezik: eljárások és függvények .
A C - szerű nyelvekben egy szubrutint mindig függvényként írnak le. Az eljárás a void típus függvényében valósul meg , azaz "üres" típussal rendelkezik, és ennek megfelelően nem ad vissza értéket.
Az objektumprogramozási nyelvekben osztályok részét képező szubrutinokat általában metódusoknak nevezik . Ez a kifejezés egy osztály bármely tag-alprogramjára vonatkozik, mind a függvényekre, mind az eljárásokra; ha pontosításra van szükség, akkor módszerekről-eljárásokról vagy módszer-funkciókról beszélünk .