Appendix 3. Informell sammanställning över de nya satserna i Fortran 90

A 3.0 Inledning

Detta appendix innehåller en kort sammanfattning av de nytillkomna satserna i den nya standarden, och är främst avsett för den som redan kan Fortran 77. En systematisk genomgång av det fullständiga språket Fortran 90 sker i Appendix 4.

A 3.1 Källkoden

INCLUDE kan användas för att inkludera källkod från en extern fil. Konstruktionen är att på en rad finns INCLUDE samt en textsträng samt eventuellt avslutande kommentar, men satsnummer är ej tillåtet. Tolkningen är implementationsberoende, normalt tolkas textsträngen som namnet på den fil som skall inkluderas på det ställe i källkoden där satsen INCLUDE finns. Kapsling är tillåten (antalet nivåer är implementationsberoende), men däremot ej rekursion. Se vidare avsnitt 14.6.

Om man vill använda Algol-principen att deklarera samtliga variabler underlättas detta av att kommandot IMPLICIT NONE slår av de implicita typ-reglerna. Notera att denna sats måste finnas först i varje programenhet, om den skall ha verkan i hela programmet.

Liksom i de flesta Algol-språk kan nu END kompletteras med namnet på rutinen eller funktionen, som END PROGRAM ALPHA och END FUNCTION GAMMA.

A 3.2 Alternativa representationer

Olikhetstecknen < och > kan användas enligt
        <   .LT.          >   .GT.
        <=  .LE.          >=  .GE.
        ==  .EQ.          /=  .NE.
Detta innebär att man inte behöver så många punktsymboler som tidigare. Det är dock inga fler punktsymboler som fått ny representation i och med Fortran 90. Notera att vid felaktig användning av exempelvis <= kan kompilatorn komma att klaga på .LE. i stället.

A 3.3 Specifikationer

Dessa kan nu skrivas på en rad utnyttjande dubelkolon ::
     REAL, DIMENSION(2), PARAMETER :: a =  (/ 1.0, 7.0 /) 

     COMPLEX, DIMENSION(10) :: kurre
där variablerna a blir en konstant vektor med två element och flyttalsvärdena 1.0 respektive 7.0, medan kurre blir en komplex vektor med 10 (komplexa) element, vilka ej initierats.

Dubbel precision har kompletterats med en mer generell metod att ange önskad precision, nämligen parametern KIND för vilken precision som önskas, användbar på alla variabeltyper.

      INTEGER, PARAMETER :: LP = SELECTED_REAL_KIND(20)
      REAL (KIND = LP)   :: X, Y, Z
Ovanstående båda satser deklarerar således variablerna X, Y och Z att vara reella flyttalsvariabler med (minst) 20 decimala siffrors noggrannhet, av en datatyp som här kallas LP (står för lång precision).

A 3.4 Villkorssatser

Ett nytt kommando är
        SELECT CASE (uttryck)
          CASE block-väljare
               block
          CASE block-väljare
               block
          CASE DEFAULT
               defaultblock
        END SELECT
Typisk konstruktion:
   SELECT CASE(3*i-j)  !  väljarvariabeln är 3*i-j
          CASE(0)      !  för väljarvariabeln noll
           ...         !  exekverbar kod
          CASE(2,4:7)  !  för väljarvariabeln 2,4,5,6,7
           ...         !  exekverbar kod
          CASE DEFAULT !  för andra värden på 
                       !  väljarvariabeln
                ...    !  exekverbar kod
   END SELECT
Om CASE DEFAULT saknas och inget av alternativen gäller så fortsätter exekveringen med nästa sats, utan felutskrift.

Annat exempel:

      INTEGER FUNCTION SIGNUM(N)
      SELECT CASE (N)
        CASE (:-1)
          SIGNUM = -1
        CASE (0)
          SIGNUM =  0
        CASE (1:)
          SIGNUM =  1
      END SELECT
      END

A 3.5 DO-slinga

Tre nya varianter införes. Den första ger i princip en oändlig slinga, som dock kan avslutas med till exempel en villkorlig hoppsats.
        namn:   DO 
                  exekverbara satser
                END DO namn
Den gamla vanliga DO-slingan har nu följande utseende,
        namn:   DO i = heltalsuttr_1, heltalsuttr_2, heltalsuttr_3
                  exekverbara satser
                END DO namn
där i kallas kontrollvariabel eller styrvariabel, och där heltalsuttr_3 markerar ej nödvändig del. Slutligen finns även den nya DO WHILE-slingan
        namn:   DO WHILE (logiskt_uttryck)
                  exekverbara satser
                END DO namn
Namnet behöver ej anges men kan utnyttjas för kapslade slingor för att ange vilken som skall itereras på nytt med CYCLE eller avslutas med EXIT.
        S1:   DO
                 IF ( X > Y ) THEN
                    Z = X
                    EXIT S1
                 END IF
                 CALL NEW(X)
              END DO S1

              N = 0
   SLINGA1:   DO I = 1, 10
                 J = I
   SLINGA2:      DO K = 1, 5
                    L = K
                    N = N + 1
                 END DO SLINGA2
              END DO SLINGA1
I det senare fallet blir slutvärdena I = 11, J = 10, K = 6, L = 5 och N = 50 i enlighet med vad standarden föreskriver.

Namnsättning av slingorna är helt frivillig. Notera att denna typ av namn är begränsad till DO-slingor, CASE och IF...THEN...ELSE...ENDIF. Den gamla möjligheten med satsnummer (utan kolon) att hoppa till finns kvar även i fri form.

A 3.6 Programenheter

Rutiner kan anropas med nyckelordsargument och kan utnyttja underförstådda argument.
      SUBROUTINE solve (a,b,n)
      REAL, OPTIONAL, INTENT (IN) :: b
kan anropas med
      CALL solve ( n = i, a = x)
där två av argumenten ges med nyckelord i stället för med position, och där det tredje är ett standardvärde. Om solve är en extern rutin fordras ett INTERFACE block i det anropande programmet. Se vidare avsnitt 5.2.1.6.

Rutiner kan specificeras att vara rekursiva

      RECURSIVE FUNCTION fakultet(n) RESULT (fak)
men måste då ha ett särskilt RESULT namn för att föra tillbaks resultatet. Se vidare avsnitt 5.2.1.3.

A 3.7 Textsträngsvariabler

CHARACTER har utvidgats till att även innefatta en tom sträng
     a = ''
och tilldelning av överlappande strängar
     a(:5) = a(3:7) 
samt ett antal nya inbyggda funktioner som TRIM, vilken tar bort avslutande blanka. Vidare så kan vi nu valfritt använda apostrof ' eller citattecken " för att innesluta texten. Detta kan bland annat utnyttjas om man vill skriva en apostrof inuti en text, då omsluter man det hela med citattecken, och tvärtom om man vill ha ett citattecken inuti en text. Variabel längd på en textsträng finns bara under vissa restriktioner. Längden ges då antingen via en variabel vars värde bestäms vid anropet av programenheten, eller med en asterisk som kopplar textsträngen till ett verkligt argument av typ textsträng eller till en konstant textsträng. I ett tillägg till standarden behandlas textsträngar med variabel längd.

A 3.8 Inmatning

Slutligen kommer NAMELIST in i standarden! Den satsen måste dock finnas bland specifikationerna. I exemplet nedan anger list2 listans namn medan a och x är flyttalsvariabler och i en heltalsvariabel.
                NAMELIST / list2 / a, i, x
                ...
                READ(enhet, NML = list2)
önskar indata av formen (ej samtliga variabler behöver vara med, godtycklig ordning)
                &list2 x = 4.3, a = 1.E20, i = -4 /
Jag anser dock att NAMELIST kom in för sent i standarden, det är inte längre något användbart begrepp vid nutidens interaktiva program. Det är ett gammalt IBM påfund från 1960-talet.

A 3.9 Vektor- och matrishantering

Detta är en av de viktigaste aspekterna på den nya standarden. Ett fält eller en "array" definieras att ha ett mönster eller en "shape" given av dess antal dimensioner (kallat rang eller "rank") och omfång eller "extent" för var och en av dessa. Två fält överensstämmer om de har samma mönster. Operationer sker normalt på element för element bas! Observera att rangen för ett fält är antalet dimensioner och inte har något att göra med den matematiska rangen för en matris!
                REAL, DIMENSION(5,20)    :: x, y
                REAL, DIMENSION(-2:2,20) :: z
                :
                z = 4.0*y*SQRT(x)
Vi kanske här vill skydda oss för negativa element i x. Detta sker genom
                WHERE ( x >= 0.0 )
                        z = 4.0*y*SQRT(x)
                ELSEWHERE
                        z = 0.0
                END WHERE
Notera att ELSEWHERE måste vara i ett ord! Jämför även funktionen SUM som diskuteras sist i nästa avsnitt.

Med deklarationen

                REAL, DIMENSION(-4:0,7) :: a
väljer a(-3,:) ut hela den andra raden, medan a(0:-4:-2, 1:7:2) väljer i omvänd ordning ut vartannat element i varannan kolumn.

Liksom variabler kan bilda fält, så kan även konstanter det.

        REAL, DIMENSION(6)   :: B
        REAL, DIMENSION(2,3) :: C

        B = (/ 1, 1, 2, 3, 5, 8 /)
        C = RESHAPE( B, (/ 2,3 /) )
där det första argumentet till den inbyggda funktionen RESHAPE ger värdena och det andra argumentet ger det nya mönstret. Ytterligare två argument finns som möjliga till denna funktion.

Några kommandon för verklig parallell databehandling finns ej, kommittén bedömde att ytterligare erfarenhet krävs före standardisering. Se därför Appendix 9 om HPF.

A 3.10 Dynamisk minneshantering

Fortran 90 innehåller fyra olika sätt att göra dynamisk åtkomst av minne. Den första är att använda sig av pekare, och diskuteras i avsnitt 4.3.2.

Det andra är att använda ett allokerbart fält, "allocatable array", dvs att med de båda satserna ALLOCATE och DEALLOCATE erhålla respektive återlämna lagringsutrymme för ett fält vars typ, rang och namn (och andra attribut) tidigare har deklarerats

        REAL, DIMENSION(:), ALLOCATABLE :: x
        ...
        ALLOCATE(x(n:m))  ! n och m är heltalsuttryck
                          ! Ge båda gränserna eller bara
                          ! den övre och då utan kolon!
        ...
        x(j) = q
        CALL sub(x)
        ...
        DEALLOCATE (x)
        ...
Deallokering förekommer automatiskt (om ej attributet SAVE getts) när man i proceduren når RETURN eller END i samma procedur.

Den tredje varianten är ett automatiskt fält, "automatic array". Detta fanns nästan men inte riktigt i gamla Fortran, där X då måste vara med i argumentlistan.

                SUBROUTINE sub (i, j, k)
                REAL, DIMENSION (i, j, k) :: x
Dimensioneringen för X hämtas från heltalen i det anropande programmet.

Slutligen finns antaget mönster, "assumed-shape array", vars lagring definieras i den anropande proceduren, och för vilken endast typ, rang och namn ges.

                SUBROUTINE sub (a)
                REAL, DIMENSION(:, :, :) :: a
Här krävs ett explicit gränssnitt i den anropande programenheten för att överföra dimensioneringsinformationen. Detta skall se ut som följer:
        INTERFACE
                SUBROUTINE SUB(A)
                REAL, DIMENSION (:,:,:) :: A
                END SUBROUTINE SUB
        END INTERFACE
Om man glömmer INTERFACE eller har ett felaktigt sådant erhålles ofta felet "Segmentation error". Se vidare avsnitt 11.2.

A 3.11 Inbyggda funktioner

Fortran 90 definierar omkring 100 inbyggda funktioner. Många av dessa används för fält, exempelvis för reducering (SUM), konstruktion (SPREAD) och manipulering (TRANSPOSE). Andra tillåter attribut i programmeringsmiljön att bestämmas, som största positiva flyttalet och heltalet, liksom tillgång till systemets klocka. En slumptalsgenerator ingår. Slutligen tillåter funktionen TRANSFER att innehållet i en viss fysisk area överföres till en annan area utan typkonvertering.

Vissa inbyggda funktioner finns för att bestämma de verkliga dimensioneringsgränserna

        DO (i = LBOUND(a,1), UBOUND(a,1))
                DO (j = LBOUND(a,2), UBOUND(a,2))
                        DO (k = LBOUND(a,3), UBOUND(a,3))
där LBOUND ger den lägre dimensioneringsgränsen för den specificerade dimensioneringen, och UBOUND den övre.

Summan av de positiva värdena av ett antal tal i ett fält kan skrivas

        SUM ( X, MASK = X > 0.0 )
Samtliga inbyggda funktioner presenteras utförligt i Appendix 5.

A 3.12 Egna datatyper

Fortran har tidigare inte tillåtet användardefinierade datatyper. Detta blir nu möjligt med hjälp av satsen TYPE. Se avsnitt 10.5

För att kunna använda användardefinierade datatyper i exempelvis COMMON eller för att se till att två likadana datatyper betraktas som samma datatyp använder man kommandot SEQUENCE, i det senare fallet får dessutom ingen variabel vara deklarerad PRIVATE.

A 3.13 Moduler

Moduler är samlingar av data, typ-definitioner och procedur-definitioner, vilka ger en säkrare och allmängiltigare ersättning för COMMON. Se avsnitt 14.4

A 3.14 Datatypen "bit"

Datatypen "bit" finns ej, men väl bit-operationer på heltal enligt en tidigare standard MIL-STD-1753. Dessutom har binära, oktala och hexadecimala konstanter införts, liksom möjligheter att inkludera dessa storheter i in/utmatning genom införande av erforderliga format-bokstäver. I en DATA sats använder man då tilldelning enligt
     B'01010101010101010101010101010101' 
för binära,
     O'01234567'
för oktala och
     Z'ABCDEF' 
för hexadecimala tal.

A 3.15 Pekare

Pekare har införts, men inte på det vanliga sättet som en egen datatyp utan som attribut till de andra datatyperna. En variabel med pekarattribut kan användas dels som en vanlig variabel, dels på ett antal nya sätt. Pekare i Fortran 90 är inte minnesadresser som i flera andra programspråk eller i vissa Fortran-varianter, utan är mer ett extra namn (alias). Se kapitel 12.

A 3.16 Egna utvidgningar

Det nya språket innebär en möjlighet för användaren att utvidga det med egna begrepp, till exempel intervallaritmetik, rationell aritmetik eller dynamiska textsträngar. Genom att definiera nya datatyper och operatorer, samt överlagra operatorer och procedurer (så att man till exempel kan använda + som symbol även för addition av intervall och inte bara av vanliga tal) kan man bygga upp kompletterande paket (moduler), utan att gå omvägen via preprocessorer. Vi har redan sett ett antal utvidgningar för olika tillämpningar i form av moduler från programvaruleverantörer.

Sammanställning över Fortran 77 Satser Innehåll Genomgång av hela språket Fortran 90


Senast modifierad: 3 maj 1999
boein@nsc.liu.se