Fortran | tulajdonságai

Tulajdonságai

Habár általános célú nyelvként tartják számon, a Fortrant a numerikus számításokra optimalizálták. Jellegzetes a hatványozás jele a **, és a komplex számok adattípusa (COMPLEX). Szembeszökő, hogy az utasításokat csupa nagybetűvel szokás megadni, bár a legtöbb fordító már kisbetűvel írva is képes megérteni őket. Az már csak kevésbé látható, hogy a szóközök csak a program olvashatóságát, tagoltságát javítják; a szóközök nélkül írt Fortran program ugyanúgy lefordul, és ugyanazt csinálja, mint szóközöket tartalmazó példánya. Így lehet a GO TO GOTO, az ELSE IF ELSEIF, az END DO ENDDO. A Fortran 90-ben standardizálták a vektor- és a mátrixműveleteket. Ezt segítik a MATLAB segítségével készült BLAS és LAPACK csomagok. Emellett léteznek még más csomagok is, mint például a LINPACK és EISPACK. [1] Számos csomag áll rendelkezésre a különféle tudományos és numerikus számításokhoz. A csomagokat nem kell importálni a programba, csak fordításkor kell kapcsolókat megadni.

A Fortran90 lehetőségei többek között a mutatók kezelésében, a saját típusok és a modulok használatának lehetővé tételében nyilvánulnak meg. A Fortran2003 már lehetővé teszi az objektumorientált, a Fortran2008 a párhuzamos programozást.

Formátum

A régebbi Fortran programokat kötött formátumban írták, ahol is:

  • az első oszlopot a megjegyzés jelének tartották fenn (c, C)
  • a második-ötödik oszlopokba kerültek a címkék
  • a hatodik oszlop a folytatás jelzésére szolgált
  • a hetedik-hetvenkettedik oszlopba kerültek az utasítások

A lyukkártya-korszakból fennmaradt kötött formátumot a Fortran 90 tette opcionálissá. Egy hasonló megkötés volt, hogy a nevek legfeljebb hat betűsek lehettek. A Fortran 90-ben és 95-ben ez a határ 31; a Fortran 2003-as kiadása 63-ra növelte ezt a hosszt, és azt is lehetővé tette, hogy egy utasítást akár 255 sorba is tördelhessenek. Szabad formátumban a sorvégi & jel jelzi a folytatást. Eredetileg mindent nagybetűkkel írtak; ma a nyelv nagybetűérzéketlen.

Deklaráció

Ugyanebből a korszakból maradt fenn az implicit deklaráció is, ahol az I-N betűvel kezdődő változók egészeket jelölnek a matematikában szokásos módon (INTEGER). A többi betűvel kezdődő név lebegőpontos számot jelent (REAL). Ez a viselkedés azonban felülbírálható:

! Minden nem deklarált változó komplex, aminek c-vel vagy z-vel kezdődik a neve
IMPLICIT COMPLEX (c, z)

vagy letiltható:

IMPLICIT NONE

Ezután a nem deklarált változók fordítás idejű hibát adnak, ami megkönnyíti a hibakeresést.

Típusok

A Fortran alaptípusai:

  • INTEGER egész számok
  • REAL lebegőpontos szám
  • DOUBLE PRECISION dupla pontosságú lebegőpontos szám
  • COMPLEX komplex szám, két REAL-t tartalmaz
  • LOGICAL, logikai érték (.TRUE. vagy .FALSE.)
  • CHARACTER, szöveg típus, alapértelmezetten egy hosszúságú

Konstansok deklarálására a PARAMETER kulcsszó szolgál. A szöveges típus hosszát meg kell adni:

Fortran77-ben:

       CHARACTER*12 :: USERNAME
C USERNAME legfeljebb 12 karakter hosszú lehet

Fortran90-ben:

CHARACTER(LEN=12) :: USERNAME !USERNAME legfeljebb 12 karakter hosszú lehet

Szöveg értékét aposztrófok között kell megadni. A konkatenáció jele a //.

Szükség lehet arra, hogy egy program mindenütt azonos pontosságú számokat használjon. Ehhez vezették be a KIND-eket. A Fortran77 egyes változataiban, ha egy típus nevét egy csillag és egy szám követte, akkor az a tároláshoz használt bájtok számát jelezte. A Fortran90-be már szabványosítva került be:

INTEGER(KIND=2) !Ez -32768 és 32767 közötti értékek tárolására alkalmas.

ahol is a KIND a 2 hatványa kell, hogy legyen.

A kevésbé pontos KIND-ek a műveletek közben automatikusan konvertálódnak pontosabb KIND-ekké. Ez azonban csalóka lehet, mert ez pontosabb értéket sejtet a megadottnál, ezért az ilyen műveletek kerülendők.

Szöveges értékekre a KIND a karakterkészlet megválasztását jelenti:

CHARACTER(KIND=character_set, LEN=10) :: greek

A logikai változókhoz is definiálható KIND, de ez azt jelenti, hogy a két logikai érték egyike tárolódik a megadott számú bájton.

Alprogramok

Egy Fortran program lehet főprogram, függvény vagy szubrutin. Főprogram a PROGRAM, függvény a FUNCTION, szubrutin a SUBROUTINE kulcsszóval írható. Mindegyik futása leállítható a STOP utasítással. Végüket END jelzi. A függvénynek egy, a szubrutinnak több visszatérési értéke lehet. A visszatérési értékek megadásához kötelező a RETURN. Érdemes megadni a függvények és a szubrutinok típusát, mert a kikövetkeztetett típus hibaforrás lehet. A paraméterek típusát a deklarációban kell jelezni. Opcionális paraméterek a Fortran90 óta az OPTIONAL kulcsszóval deklarálhatók. Ha az opcionális argumentumokat nem adjuk meg, akkor létre sem jönnek; ez egy újabb hibaforrás. Paraméter-átadáskor a fordítók nem ellenőrzik a paraméterek típusát, ezért ez szintén hibákhoz vezethet. Szubrutin a neve előtti CALL utasítással hívható. A Fortran hagyományosan cím szerint adja át a paramétereket, vagyis nem másolatokat, hanem címeket ad át. A Fortran90-től kezdve lehetővé vált a név szerinti paraméter-átadás, a rekurzió és a modulok használata. A modulok MODULE kulcsszóval deklarálhatók, és deklarációkat, függvényeket, szubrutinokat, vagy interfészeket tartalmazhatnak. Egy modul használatát USE vezeti be. A név szerinti paraméter-átadást interfészek teszik lehetővé, ahol azt is jelezni kell, hogy a változó bemenő (INTENT IN), kimenő (INTENT OUT), vagy mindkettő (INTENT INOUT). Rekurzív függvények a RECURSIVE kulcsszóval és segédfüggvénnyel (RESULT) írhatók. A rekurzív szubrutinokat elég RECURSIVE-nak deklarálni.

Beágyazott eljárások

Beágyazott eljárások a Fortran90 óta készíthetők. A gazda programtól CONTAINS kulcsszó választja el, és csak a gazda programból hívhatók. Hozzáférnek a gazda összes változójához; felülírhatják, sőt felüldeklarálhatják őket. A modulokon kívül nem ágyazhatók egymásba; a modulokban a Fortran90-ben egy szintű, a Fortran95-ben és az újabb változatokban tetszőleges szintű beágyazás lehetséges. A beágyazott eljárások az implicit deklaráció megváltoztatását, illetve tiltását is öröklik.

Beágyazott eljárásokkal típuskonstruktorok és generikus eljárások: függvények, szubrutinok is készíthetők.

Logikai kifejezések és feltételes utasítások

A két logikai értéket .TRUE. és .FALSE. jelöli. A két pont is a név része, ami segíti a szabadabb névválasztást. Logikai változók a LOGICAL megjelöléssel deklarálhatók. A logikai műveleteket a .NOT. (nem), az .AND. (és) és az .OR. (vagy) valósítja meg. Precedenciájuk szerint a .NOT. a legerősebb, ezt követi az .AND., és végül az .OR. Az összehasonlító operátorok:

  • .EQ. egyenlő
  • .NE. nem egyenlő
  • .LT. kisebb
  • .LE. kisebb-egyenlő
  • .GT. nagyobb
  • .GE. nagyobb-egyenlő

A Fortran90 óta használhatók a más programnyelvekben megszokott összehasonlító szimbólumok is.

A feltételes utasításokat IF kezdi és END IF zárja. Lehet egy ELSE és több ELSE IF ága. Ha az utasítások nem a feltétel sorában kezdődnek, akkor kötelező a THEN az IF és az ELSE IF ágakban. A feltétel kiválasztása fentről lefelé halad, így a speciálisabb feltételeket előre kell venni. A feltételes szerkezetek egymásba ágyazhatók, de ha túl mély lenne a beágyazás, vagy túl bonyolultak a feltételek, akkor inkább szubrutint kell használni.

Ciklusok

A Fortran 77-es verzió szabványában csak egyféle ciklus, a DO ciklus érhető el, ami megfelel a más programnyelvek által használt for ciklusnak. A while és az until ciklusok szervezéséhez a GO TO utasítás megkerülhetetlen. Sok implementáció azonban már tartalmazta ezeket a ciklusokat is. Ezen úgy segítettek, hogy betették a 90-es szabványba az EXIT utasítást, amivel már nem lehet bárhova elugrani. Ez az utasítás arra szolgál, hogy a vezérlés elhagyja a ciklust, és az az utáni első sorra lépjen. A ciklus belsejében a C-től eltérően nem lehet megváltoztatni a ciklusváltozót, ezért a futtatások száma ránézésre megállapítható.

Fortran77-ben:

c Legyen iFunc() egész értékkel visszatérő függvény .
c A fordítónak csak egyszer kell iFunc-ra hivatkoznia.
DO 100 i = 1, iFunc(4711)
   c.. valami értelmes művelet
   c Nem lehet megváltoztatni i értékét
100 CONTINUE

Ugyanez Fortran90-ben:

! Legyen iFunc() egész értékkel visszatérő függvény .
! A fordítónak csak egyszer kell iFunc-ra hivatkoznia.
DO i = 1, iFunc(4711)
   !.. valami értelmes művelet
   ! Nem lehet megváltoztatni i értékét
ENDDO

Ugyanez az iteráció C-ben:

 for (i = 1; i <= iFunc(4711); i++) {
    /* valami értelmes művelet */
    /* i megváltoztatható */
 }

C-ben a ciklust egy logikai kifejezés határozza meg. Az iteráció addig megy, amíg ez a kifejezés igaz. A ciklus törzsében hívott függvények mellékhatásai megváltoztathatják az i változót, ezért nem biztos, hogy annyiszor fut le a ciklus, ahányszor akarjuk. A Fortran 95 óta lehet egy függvényt vagy szubrutint PURE-nak deklarálni, ami megköveteli a mellékhatásoktól való mentességet. Eszerint a bemenő argumentumok nem módosíthatók. Emellett a PURE-nak deklarált függvény vagy szubrutin nem tartalmazhat I/O utasításokat, és a globális változókart sem módosíthatja. Ha ez mégis megtörténne, akkor fordítási hibát kapunk.

Tömbök

A Fortranban a tömbök indexelése alapértelmezésben 1-től kezdődik. Egy tömb megadható elemeinek típusával, a nevével és kerek zárójelbe tett hosszával, vagy indexhatáraival. A túlindexelést a fordítók nem figyelik, így ez gyakori hiba. Magasabb dimenziós tömbök is megadhatók, a lehetséges legnagyobb dimenziószám a 7. Az egydimenziós tömbök kezelhetők vektorként, a kétdimenziósak mátrixként. Teljesen kitöltött mátrixok kezelhetők vektorként is, vagyis lehet őket skálázni, skaláris szorzatukat venni. Függvényekben és szubrutinokban a tömbök méreteinek meghatározása a főprogramra hagyható. Résztömbök indextartományokkal hivatkozhatók. Paraméterként a tömbök helyettesíthetők annyi megfelelő típusú változóval, ahány eleme a tömbnek van. A típusokat a fordítók nem ellenőrzik. A Fortran90 óta lépésköz is használható, tehát lehet például minden második sorra vagy oszlopra hivatkozni.

A Fortran90 óta különféle függvények léteznek a tömbök különböző méreteinek lekérdezésére. A Fortran90 előtt a tömbelemek egymás után oszlopfolytonosan tárolódtak a memóriában, a Fortran90 óta ez nincs meghatározva, akár különböző memóriákba is kerülhetnek az elemek. A tömböket a Fortran nem inicializálja, a frissen létrehozott tömb elemei határozatlanok. Teljes tömbök ciklusokkal tölthetők fel. Régebben szokás volt nagy méretű tömböket deklarálni, és csak részben feltölteni, mivel nem volt dinamikus allokáció. Ez a lehetőség a Fortran90-ben jelent meg először, a deklarációban ALLOCATABLE kulcsszóval, a tulajdonképpeni programban ALLOCATE, illetve DEALLOCATE utasításokkal. Dinamikus tömb csak allokált állapotban használható argumentumként. A tömbelemek feltételes megválasztásához a Fortran90-től kezdve maszkok is készíthetők WHERE feltétel END WHERE blokkal. A blokk egy másik formájában a maszk feltételének nem megfelelő elemekkel is lehet csinálni valamit a blokkban kiadott ELSEWHERE utasítással.

Stringek

A stringek a CHARACTER kulcsszóval és hosszukkal deklarálhatók. Ez tulajdonképpen a maximális hosszuk. A stringek nem tömbök, ezért nem allokálhatók, de lehet részstringjeikre indexekkel hivatkozni. A stringek indexelése is 1-től kezdődik. Az üres string és az üres részstring nem megengedett; az egy karakteres részstringre úgy lehet hivatkozni, hogy a kezdetét és a végét ugyanaz a szám jelöli. A stringekben a Fortran megkülönbözteti a kis- és a nagybetűket.

Globális változók

A Fortran hagyományosan nem ismeri a globális változókat. Ehelyett közös blokkokat kell létrehozni a COMMON kulcsszóval, két / közé tett névvel és magukkal a blokkba tartozó, előzetesen deklarált változókkal. A közös tömböket minden olyan részprogramba be kell tenni, ahol hivatkoznak rájuk. A névegyezés nem kötelező, a részprogramok csak a sorrendből tudják, hogy melyik változó melyik. Típusellenőrzés nincs, ezért a közös blokkokat hibaforrásnak tekintik, és lehetőleg mellőzik. Ha mégis használni kell, akkor külön fájlba teszik, és INCLUDE-olják mindenhová. A névtelen közös blokk speciális.

Előre ismert adatok

Az előre ismert értékű változók a DATA kulcsszóval, névvel és két / jel közé tett értékükkel deklarálhatók. Tömbök is deklarálhatók így. A DATA-ban megadott változók nem kerülhetnek be úgy közös blokkokba, mint a közönséges változók; ezen a BLOCK DATA és egy END közé zárt programrészlet segít. Csak itt lehet őket deklarálni és közös blokkba tenni.

I/O

Változók beolvasására a READ, kiíratásra a WRITE utasítás szolgál. A standard be- és kimenet használatához egy csillagot kell utánuk írni, vagy egy zárójelbe két, vesszővel elválasztott csillagot. Az első csillagot helyettesítheti egy I/O egység száma, a másodikat egy FORMAT utasítás kóddal. Ha a FORMAT utasítás helyett csak egy csillag van, akkor az listavezérelt kiíratás, amit fájlba íráskor kerülni kell. Az egységszámok 1 és 99, egyes rendszereken 1 és 255 közé eshetnek. Az előre megnyitott standard bemenet egységszáma az 5, a standard kimeneté a 6. Egy egységen egy időben legfeljebb egy fájl lehet megnyitva, és a Fortran programban összesen legfeljebb 32 fájl lehet egyszerre megnyitva.

A FORMAT utasítás a kiírandó szöveg formázására szolgál. A formátumban használt leggyakoribb kódok:

  • A - szöveg
  • D - pontosabb valós szám, exponenciális alak (normálalak)
  • E - valós szám, exponenciális alak (normálalak)
  • F - valós szám, fixpontos formátum
  • I - egész
  • X - horizontális ugrás olvasáskor, szóköz íráskor
  • / - vertikális ugrás (új sor)

Az E, a D és az F általános formája w.d alakú, ahol w a szám egészrésze, és d a törtrésze. Az egészet jelentő kód után is meg kell adni, hogy milyen hosszú lesz a szám. A szöveget jelentő kódnál is megadható hossz, de nem kötelező. A FORMAT utasítás paramétereként egy ilyen elemekből építkező kódot kell megadni, vagy egy címkét, amivel a kódot tartalmazó sorra mutatunk.

Ha a kiírandó adat túl rövid, akkor a fordítók szóközökkel pótolják ki. Ha az adat törtrésze túl hosszú, akkor kerekíti. Ha az adat egészrésze, vagy a szöveges adat túl hosszú, akkor figyelmeztetésként csillagokat ír ki.

Csak megnyitott fájlba lehet írni, vagy onnan olvasni. Egyes egységekre megnyitás nélkül írni, illetve a leírtakat kiolvasni nem fordítási hiba, de nem oda kerülnek az információk, ahova akartuk; ilyen például a 39-es egység, ami a szalagos tárhoz volt rendelve. Ma egy új fájlt hoz létre TAPE39 vagy FTN039.DAT névvel. Ez a szalagos egységek használatának idejéből maradt fenn, és elavultnak tekintik. Az OPEN() utasításban nagyon sok opció adható meg. A FILE = fájlnévben a fájl elérési útját kell megadni. Az UNIT = egységszám megadása is kötelező. A fájl elérése lehet SEQUENTIAL (=szekvenciális, közvetett) vagy DIRECT (=direkt, közvetlen); alapértelmezésben SEQUENTIAL. A fájl formátuma lehet FORMATTED (=formázott) vagy UNFORMATTED (=formázatlan); alapértelmezésben UNFORMATTED. Formázott esetben meg kell adni a rekordhosszt is, erre a RECL = rekordhossz szolgál. A rekordhossz többnyire megfeleltethető a fájl sorainak hosszával. Használat után a fájlt be kell zárni a CLOSE (egységszám) utasítással. További opciók az ERR=címke az I/O hiba kezelésének címkéje, STA= a fájl állapota: NEW, ha új, OLD, ha régi, és SCRATCH, ha átmeneti. Bezáráskor a fájl törölhető a CLOSE utasítás a STATUS='DELETE' paraméterrel.

A szekvenciális fájlok rekordonként olvashatók a fájl elejétől a fájl végéig. A Fortran77 nem specifikálta a mutató helyét, ezért megnyitás után az olvasáshoz ki kellett adni a REWIND utasítást, amivel a fájl elejére lehet ugrani. A Fortran90 óta az írásra vagy csak olvasásra megnyitott fájl elejére, a hozzáfűzésre megnyitott fájl végére mozog.

Minden olvasás alapértelmezetten új rekordot olvas be, egészen addig, amíg el nem ér a fájl végéig. Visszafelé a BACKSPACE utasítással lehet mozogni. Új rekordokat csak a fájl végére lehet fűzni; REWIND után írni a fájl tartalmának megsemmisülésével jár. A direkt hozzáférésű fájlokban lehet sorszámmal hivatkozni a rekordokra, de ehhez meg kell adni a rekordhosszt, ami a fájl egész életében állandó marad. A formázott fájlok szövegként írhatók-olvashatók, míg a nem formázottak bináris gépi kódot tartalmaztak, és nem hordozhatók, gyakran még azonos típusú gépek és operációs rendszerek között sem.

A szövegfájlok rendszerint formázott szekvenciális fájlok. A nem formázott szekvenciális fájlok az egyes programegységek közötti kommunikációra valók. Egy rekord akár több ezer mezőt is tartalmazhat; ennek csak az operációs rendszer szab határt. A nem formázott direkt elérésű fájlok használata hatékonyabbá teheti a programot, de használatához tudni kell, hogy az adott rendszer milyen mértékegységben méri a rekordhosszt, és hogy egy számot hány bájton tárol. A formázott direkt elérésű fájlok rekordhosszát mindenütt karakterben mérik.

A Fortran90 újabb utasításokkal és paraméterekkel bővítette a fájlkezelés képességeit. Így például APPEND-re megnyitva a mutató eleve a fájl végére van pozicionálva, és különféle tulajdonságok kérdezhetők le a fájl megnyitása után.

Felhasználói típusok

Felhasználói típusok a Fortran90 óta TYPE kulcsszóval hozhatók létre:

TYPE PONT
REAL x, y, z
END TYPE PONT

Ez az adatszerkezet inkább a Pascal rekordjaira és a C nyelv struct-jaira hasonlít, mint osztályokra. Az objektumorientált programozást a Fortran2003 vezette be.

A típusba a % jellel lehet lefúrni:

P%x=4.0
P%y=4.0
P%z=5.0

Az egyes felhasználói típusok egymásba ágyazhatók. Mélyebbre is le lehet fúrni:

golyo%kozeppont%x

Az összetett típusok lehetnek tömbelemek, paraméterek vagy visszatérési értékek. Az egyes adatmezők értékei tömbök is lehetnek, kivéve a dinamikus tömböket.

Pointerek

A pointereket a Fortran90 vezette be. A pointerek POINTER kulcsszóval és céljuk típusával deklarálandók. A pointerek lehetséges célját TARGET jelöli a deklarációban. Az így megjelölt célra => jellel állítható pointer; ezután a cél hivatkozható a pointer nevével is, de tényleges másolás nem történik. A pointerek hivatkozásait a fordítók automatikusan feloldják. A pointer átállítható egy másik célra, vagy a Null értékre a NULLIFY utasítással.

A pointerek is allokálhatók; ekkor a NULLIFY utasítás memóriaszemetet hagy maga után; helyette deallokálni kell. A pointerek mutathatnak dinamikus tömbökre is. A dinamikus tömbök hatékonyabbak, de a dinamikus pointerek flexibilisebbek.

A pointerek lehetnek argumentumok, de csak INTENT deklaráció nélkül. Használatuk interfészt igényel. Lehetnek visszatérési értékek is. Lehetnek tömbök elemei, mezőértékek is.

Más nyelveken
English: Fortran
العربية: فورتران
azərbaycanca: Fortran
беларуская: Fortran
български: FORTRAN
বাংলা: ফোরট্রান
bosanski: FORTRAN
català: Fortran
کوردی: فۆرتران
čeština: Fortran
Чӑвашла: Фортран
dansk: Fortran
Deutsch: Fortran
Ελληνικά: Fortran
español: Fortran
eesti: Fortran
euskara: FORTRAN
فارسی: فورترن
suomi: Fortran
français: Fortran
Gaeilge: FORTRAN
עברית: Fortran
हिन्दी: फ़ोरट्रान
hrvatski: Fortran
interlingua: FORTRAN
Bahasa Indonesia: Fortran
italiano: Fortran
日本語: FORTRAN
Taqbaylit: Fortran
қазақша: Фортран
한국어: 포트란
Kurdî: Fortran
Latina: FORTRAN
lietuvių: Fortran
latviešu: Fortran
മലയാളം: ഫോർട്രാൻ
монгол: Фортран
Bahasa Melayu: Fortran
Mirandés: FORTRAN
မြန်မာဘာသာ: Fortran
Nederlands: Fortran
norsk nynorsk: Fortran
norsk: Fortran
occitan: Fortran
polski: Fortran
português: Fortran
română: Fortran
русский: Фортран
саха тыла: Fortran
Scots: Fortran
srpskohrvatski / српскохрватски: Fortran
Simple English: Fortran
slovenčina: Fortran
slovenščina: Fortran
shqip: Fortran
српски / srpski: Фортран
svenska: Fortran
తెలుగు: ఫోర్ట్రాన్
тоҷикӣ: Фортран
Türkçe: Fortran
українська: Фортран
Tiếng Việt: Fortran
中文: Fortran