Amikor egy program több száz sor hosszú, már nehéz követni. Sőt, a valódi mérnöki (vagy akármilyen más) számításoknál sokszor több ezer sorból álló programokat kell alkalmazni. Az egyetlen módja, hogy e hatalmas "kód-zuhatagot" kezelni tudjuk a modulátorok és a programba beágyazott alprogramok használata, amikkel programunk szövegét több kisebb részre bonthatjuk. Az alprogram egy kisebb kódrészlet, ami egy konkrét részfeladatot old meg. Egy nagyobb programban előfordulhat, hogy ugyanazt azt alproblémát kell megoldani többször, de különböző adattokkal. Ilyenkor is alkalmazhatunk alprogramot, a parancsok ismétlése helyett, azaz az egyszer megírt segédprogramot kell előhívni, miután a bemenő adatokat megfelelően módosítottuk.
A FORTRAN program szegmensekből áll, amelyek közül az egyik a főszegmens, a fennmaradók háromfélék lehetnek: függvények (FUNCTION), eljárások (SUBROUTINE), és lehet a programban egy adatszegmens.(BLOCK DATA) A szegmensekben használt azonosítók (kivéve a szegmens nevét és a COMMON adatmezőket) lokálisak. A szegmensek a nyelv fordítási egységei. A nyelv nem tartalmaz elemet a szegmensek közötti kapcsolatok leírására, fordítás közben nincs mód a kapcsolatok helyességének ellenőrzésére.
A szegmensek elején deklarációs sorok állnak, utánuk következik a végrehajtható rész. A deklarációs rész kiértékelése statikus, a változók leképezése a memóriába fordítási időben történik. Sem az eljárások, sem a függvények nem hívhatják meg önmagukat, de az F(F(X)) függvényhívás legális. A fordító az eljárás hívásakor csak a formális paraméterek számának egyezését vizsgálja, a típusukat nem! A paraméterátadás: szám és logikai változókra címszerinti, a kifejezésekre érték szerinti (ekkor a formális paramétert lokális változóként lehet használni), tömbökre szintén címszerinti. A tömbök átadásánál többféle lehetőségünk is lehet:
A SUBROUTINE és a FUNCTION szintaxisa nagyon hasonló. Az előbbi SUBROUTINE S(A1, A2, ..., AN) vagy SUBROUTINE S, az utóbbinak FUNCTION F(A1, A2, ... , AN) vagy t FUNCTION F(A1, A2, ... , AN) . Az S illetve F névnek mindig szerepelnie kell, függvény esetén legalább egy formális paraméterre mindig szükség van. A formális paraméterek és a t visszatérési értékek az alaptípusok lehetnek.
Az alprogram hívására a CALL, a visszatérésre a RETURN utasítás szolgál.
A példából is látható, hogy az elemi matematikai függvények megvalósítását a nyelv tartalmazza. A függvényt mindig valamilyen (aritmetikai vagy logikai) kifejezésbe beleírva lehet meghívni. Függvényeknél a visszatérési értéket úgy állíthatjuk be, ha a függvény nevének értéket adunk. Például:
Habár FORTRAN alprogramokban lehetőség van lokális tömbök definiálásra, de ezt nem szokták használni. Általában a főprogramban deklaráljuk az összes tömböt, és ezekre hívjuk meg az alprogramokat.
A paramétereket a szubrutin nevét követő zárójelben felsorolt belső változónevekkel jelöljük. Ezeket a változókat ugyanúgy deklarálni kell, mint a eljárások saját változóit. A szándék (intent) tulajdonsággal adhatjuk meg, hogy az egyes paraméterek információt adnak át az eljárásnak (intent(in)), vagy információt adnak vissza a meghívó program egységnek (intent(out)), esetleg mindkettőt (intent(inout)). A paraméterek a szokásos változótípusokon kívül lehetnek eljárások, függvények, vagy mutató típusú argumentumok. Ezeknél az intent tulajdonság nem adható meg.
A függvény paraméterei általában mind intent(in) szándékúak, hiszen az eredményt a függvény adja vissza.
A függvények visszatérési érték megadásának módozatai:
A függvényben is szerepelhet return utasítás, de ügyelnünk kell arra, hogy a függvény mindig értéket kapjon.
Mind az eljárások, mind a függvények meghívhatják önmagukat akár közvetlenül, akár közvetett módon más eljárások és függvényeken keresztül. A rekurzív alprogramok esetében a subrutine illetve a function elé kell írni, hogy recursive.
A faktoriális kiszámítása rekurzív módon:
Egy alprogramnak nagyon sok argumentuma lehet. Gyakran ezeknek egy része mindig ugyanolyan értékű, vagy a hívások nagy részében nincsenek befolyással az eredményre. Az ilyen argumentumokat célszerű optional tulajdonsággal deklarálni.
Az eljárást meghívhatjuk egy vagy két paraméterrel.
Az eljáráson belül a present függvény segítségével dönthető el, hogy egy opcionális paraméter szerepelt-e a külső paraméter listában vagy sem.
Ha opcionális paraméterek vannak az argumentumlistában, akkor a külső argumentumok sorrendje nem feltétlenül adja meg, hogy melyik belső argumentumhoz tartoznak. Ilyenkor név szerint lehet hivatkozni az argumentumokra.
A főprogramban deklarált változók értéke nem veszhet el, azonban az eljárásokban deklarált lokális változók értéke nem őrződik meg a vezérlés visszatérése után. Ha a deklarációban szerepel a save tulajdonság, akkor a változó értéke megmarad.
Például írjuk ki, hogy egy eljárást hányszor hívták meg.
Fontos megjegyezni, hogy a kezdeti értékadás csak az első meghívásra vonatkozik.
A belső eljárások általánosításaként itt már nincs megkötve, hogy csak egy soros lehet a definíció. Nézzük a következő példát:
Szabályok a belső eljárások alkalmazásához:
Megjegyzés: A belső eljárások látják a befogadó szegmens változóit, ez azonban visszafelé nem igaz!
Az olyan változók, amelyek már a program megírásánál is ismertek, a data (=adat) utasítással is bevihetők. Formalizmusban nagyon hasonló az elnevezéses utasításokhoz. A metódus a következő:
ahol a három pont azt jelenti, hogy ezen beírás akárhányszor megismételhető, például:
De össze is vonhatók:
A "hagyományos" elnevezéses utasítással a fenti m,n,x,y változókat így írtuk volna:
Ez a data utasítás tömörebb, mint a hagyományos, ezért széles körben elterjedt a használata. Azonban főleg az összevont esetnél, ügyelnünk kell arra, hogy ugyanazon értékeket nem elég egyszer leírni.
A data utasítást elég egyszer, közvetlenül a végrehajtó utasítások előtt, a program elején alkalmaznunk. Ezért ezt a data utasítást általában a főprogramban használják, és nem a subroutinokban.
Természetesen a data utasítással tömböket (vektorokat, mátrixokat) is definiálhatunk. A következő programrészlet biztosítja, hogy a mátrix elemei mind zérusok, mikor a program futtatás megindul.
Néhány fordító automatikusan alkalmazza ezt a tömbökre, de nem mind, ezért ha ragaszkodunk, hogy az elemek mind nullák legyenek, akkor a fenti szintaktikát kell beírnunk. Természetesen zérustól különböző tömb elemeket is megnevezhetünk, akár így:
de akár így is, kilistázva egy kis tömbben:
Többdimenziós esetben oszlopok szerint rendezi és kezeli a tömb elemeit.
A data utasítást nem alkalmazhatjuk egy közös tömb/blokk elemeire. Erre egy speciális "subroutine" áll rendelkezésünkre: a block data utasítás. Igazából ez nem egy segédprogram, de hasonló fogalom, mert egy önálló programrészként jelenik meg. Nézzünk rá egy példát is:
A Fortran 77 fordító a data utasításhoz hasonlóan, a block data-t is program elején hajtja végre, mielőtt még a főprogram futtatása elindulna. A block data elhelyezése a forráskód szempontjából közömbös, persze csak addig, amíg nem beágyazott utasításként szerepel vagy a főprogramban vagy egy segédprogramban. Ezért célszerű mindig ezek elejére írnunk.