Oppgåve 5

Oppgåve 5

Variable med indekser. Løkker.

FORTRAN-variable med indekser

En FORTRAN-variabel kan ha opptil 7 indekser. Hver indeks kan anta et angitt antall heltallsverdier bestemt ved en nedre og øvre grense. En slik variabel defineres ved deklarasjon, for eksempel slik:
      REAL A(1:13,0:6,8,2)
Hvis den nedre grensen for indeksen ikke oppgis ved deklarasjon er den implisitt 1. De to siste dimensjonene i eksempelet er derfor her implisitt definert som 1:8 og 1:2. Gitt verdier på hver indeks, peker man på en lagerplass, for eksempel:
      X = A(7,3,5,1)
I et program kan verdien av indeks angis som en FORTRAN-variabel (INTEGER, heltall) med en verdi som kan redefineres ved utføring av programmet. Dette er spesielt nyttig i løkker, for eksempel i en DO-løkke. Slike variabler med indeks brukes naturlig til å lagre vektorer og matriser.

Legg merke til at matriser er lagret med første indeks varierende 'hurtigst', noe som betyr at i løkker som gjentas mange ganger bør man prøve å bruke og endre fortrinnsvis de første indeksene først:

*
*-- Definer A og X.
*
      REAL A(100,100), X(100,100)
*
*-- En uheldig kopieringsmetode.
*
      DO 20 I=1,100
        DO 10 J=1,100
          X(I,J) = A(I,J)
   10   CONTINUE
   20 CONTINUE
*
*-- En bedre kopieringsmetode.
*
      DO 40 J=1,100
        DO 30 I=1,100
          X(I,J) = A(I,J)
   30   CONTINUE
   40 CONTINUE
For små matriser betyr ikke dette så mye, men med store matriser, vil dette kunne ha meget sterk innvirkning på kjøre-tiden til programmet.

I READ og WRITE kan benyttes såkalt implisitt DO-løkke, for eksempel slik:

      WRITE(7) (I,(A(I,J,K,L),K=1,6),I=4,13,3)
Legg merke til at dersom en hel vektor skal skrives ut vil de fleste kompilatorer lage mer effektive programmer dersom en skriver ut vektoren uten indeksen(e) eksplisitt oppgitt:
      WRITE(7) A
Dette gir bedre resultat enn
      WRITE(7) (A(I),I=1,IMAX)

Syntaksen for vektorer med tegnstrenger er litt mer komplisert enn for vektorer med tall dersom man ønsker å få tilgang til tegn inne i tegnstrengene. Her er et eksempel:

      CHARACTER*80 LINES(24)
...
      DO 10 J=1,24
        WRITE(*,'(1X,80A1)') (LINES(J)(I:I),I=1,80)
   10 CONTINUE
Med dette vil man (meget ineffektivt!) skrive ut et og et tegn langs en linje på 80 kolonner, for hver av 24 linjer med tegn.

Oppgaver:

  1. På filen ~/fil5.dat er skrevet ut data fra et FORTRAN-program med linjen:
          WRITE(7,*) N,(Q(J),J=1,N)
    
    Lag og utfør et FORTRAN-program som leser denne filen og lager en tabell over de 20 første verdier på hver av de 30 første linjer, utskrevet med et hensiktsmessig format på en fil.
  2. Lag og utfør et FORTRAN-program som regner ut verdiene av A(I,J,K,L) etter algoritmen
          B=(I*J+K)
          C=L
          A=B/C
    
    Skriv ut verdiene pent formattert på en fil eller på terminal.
  3. Lag en mer effektiv versjon av eksemplet med en vektor av strenger i denne oppgaven. Test at dette kompilerer og kjører. Skriv så ut hele strengvektoren uten bruk av ekstern løkke omkring WRITE.
  4. Lag og utfør et FORTRAN-program som sorterer verdiene i tabellen fra punkt 1 i økende rekkefølge. Programmet skal så lese inn et sekvensnummer i den opprinnelige tabellen og skrive ut den tilhørende tabellverdi og -plass etter sortering. Obs: Du må ha for hånden en passende algoritme før du skriver dette programmet! Denne oppgaven gir vanligvis problemer ellers...

Attende til startsida vår.

Oppdatert 2. mars 1995 av Erling Andersen