9. A tömbök

A tudományos számításoknál elõfordulhatnak vektorok és mátrixok. Ezen adattípusokat a Fortran tömbökként kezeli. Az egydimenziós tömb a vektorral ekvivalens, míg a kétdimenziós tömb a mátrixot jelöli. A tömbök fortranos kezeléséhez azonban nemcsak a szintaxisát használát, hanem ezen objektumok memóriában való tárolását is meg kell ismernünk.

Egydimenziós tömbök

A legegyszerübb tömbtípus, az egydimenziós, elemek egymásutáni sorozatából áll, melyek folyamatosan tárolódnak a memóriában. Például, a
      real a(20)
deklarációval, megneveztünk egy a 20 hosszúságú valós egydimenziós tömböt, ami 20 valós számból áll, melyek folyamatosan tárolódnak a gép memóriájában. A konvenció alapján a Fortranban az elemek indexelését 1-tõl kezdjük felfelé. Tehát az elsõ elemét a tömbünknek az a(1)jelöli, míg az utolsót az a(20). Ettõl függetlenül mi is definiálhatunk egyéni indexezést saját tömbünkre, az alábbi módon:
      real b(0:19), weird(-162:237)
Itt a b teljesen megegyezik az elõzõ példabeli a -val, kivéve hogy itt az index 0-tól fut 19-ig. A weird a tömb hossza, ebben a példában 237-(-162)+1 = 400.

A tömb elemének típusa bármilyen alaptípus lehet. Például:

      integer i(10)
      logical aa(0:1)
      double precision x(100)
Minden egyes elem felfogható akár egy-egy különálló változóként is. Az i-edik elemre az a(i)-vel hivatkozhatunk. A következõ kis programszegmens az elsõ 10 négyzetszámot tárolja egy sq tömbben:
      integer i, sq(10)

      do 100 i = 1, 10
         sq(i) = i**2
  100 continue
Gyakori hiba, hogy a program olyan tömbelemre is hivatkozik, ami nem definiált vagy kivülesik a definiált tömbön. Ezért fontos a programozó figyelmessége, mert ezen hibatípust a Fortran-fordítók nem ismerik fel!

Kétdimenziós tömbök

A lineáris algebrában alapvetõ a mátrixok használata. A mátrixokat általában kétdimenziós tömbök formájában jelenítjük meg. Például a
      real A(3,5)
deklaráció, definiál nekünk egy 2 dimenziós tömböt, mely 3*5=15 valós számból áll. Hasznos tudni, hogy az elsõ index a sorindex, a második pedig az oszlop index. Így az alábbi grafikus képet kapjuk:
   (1,1)  (1,2)  (1,3)  (1,4)  (1,5)
   (2,1)  (2,2)  (2,3)  (2,4)  (2,5)
   (3,1)  (3,2)  (3,3)  (3,4)  (3,5)
Kétdimenziós tömböknél is definiálhatunk egyéni indexezést. Az általános formalizmus az alábbi:
     név (low_index1 : hi_index1, low_index2 : hi_index2)

A tömb teljes mérete tehát :

     méret = (hi_index1-low_index1+1)*(hi_index2-low_index2+1)

(low=kezdõindex, hi=legmagasabb index)

A Fortranban gyakran szoktak nagyobb tömböt deklarálni, mint amekkora mátrixra a számításhoz és tároláshoz szükség lenne. (Oka: a Fortran nem rendelkezik rugalmas és dinamikus tárolási funkcióval) Ez teljesen elfogadott eljárás. Például:

      real A(3,5)
      integer i,j
c
c     Mi csak a felso 3 * 3 -ast részét hasznoljuk a tombnek 
c
      do 20 j = 1, 3
         do 10 i = 1, 3
            a(i,j) = real(i)/real(j)
   10    continue
   20 continue
A részmátrix elemei, A(1:3,4:5), pontosan definiáltak

A kétdimenziós tömbök tárolási formája

A Fortran a magasabb dimenziojú tömböket is elemek folyamatos sorozataként tárolja. Fontos tudni, hogy a kétdimenziós tömböket oszlop szerint tárolja. Tehát a fenti példát nézve, a tömb (2,1)-vel jelzett elemét (3,1) elem követi. Majd ezután végighalad a kettes, majd a többi oszlopon is.

Térjünk kicsit vissza ahhoz a példához, mikor csak a felsõ 3*3 részmátrixot használtuk, a 3*5-ös A(3,5)tömbbõl. A kilenc számunkra fontos elem a memória elsõ 9 helyén fog tárolódni, míg a következõ hat helyet nem használjuk fel. Ez kicsit talán fura, hiszen a fõdimenziója mindkét mátrixnak (az eredeteinek és a tároltnak) ugyanaz. Azonban gyakran a fõdimenziója a használt tömbnek nagyobb lesz, mint a definiáltnak. Tehát a mátrix nem folyamatosan fog tárolódni, habár maga a tömb folytonos. Például a fenti példánkban, ahol A(5,3)volt, lesz két "kihasználatlan" cellánk (az elsõ oszlop alja és a második eleje között (ismét a 3*3 mátrix példáját nézve) .

Ez most talán bonyolultnak tûnik, de a használat során majd megtapasztaljuk, hogy nem az. Probléma esetén, nem árt megnézni, az egyes elemekre való memória-hivatkozást (azaz memória címét). Minden egyes tömbhöz hozzárendelõdik egy, a tömb elsõ eleme (1,1) alapján kiosztott memória cím. Az (i,j)-edik elem memóriacíme:

      cím[A(i,j)] = cím[A(1,1)] + (j-1)*lda + (i-1)
ahol lda a fõ (többnyire sor) dimenziója A-nak. Fontos, hogy az lda nem azonos az aktuális mátrix dimenziójával. Ezek keverésébõl sok programhiba származhat!

Három- vagy még több dimenziós tömbök

A Fortran 77-ban maximum hétdimenziós tömböt használhatunk. A kezelés szintaxisa és formalizmusa teljesen analóg a kétdimenzióséval, ezért erre nem vesztegetjük az idõt.

A dimension utasítás

Más úton is definiálhatunk egy tömböt a Fortran 77-ben:
      real A, x
      dimension x(50)
      dimension A(10,20)
ami ekvivalens ezzel:
      real A(10,20), x(50)
A dimension utasítás használata manapság már egyre kevésbé jellemzõ.

 

Copyright © 1995-7 by Stanford University. All rights reserved.

Fordították: Seres András Tamás és Szalai Szilvia (ELTE-TTK)


[Tovább] [Tartalomjegyzék]