<?php

require_once($_SERVER["DOCUMENT_ROOT"] . "/common/common.INC.PHP");         

print_page_header();

?>
<p>Fortran Überblick</p>
<h2>Dateinamen</h2>
<p>Die Namen der Quellcode-Dateien sollten in <em>.f90</em> enden.</p>
<h2>Programmskelett</h2>
<pre>
PROGRAM xyz
  IMPLICIT NONE
  ...
END
... hier kann was stehen, dass NICHT ignoriert wird O_o
</pre>
<h2>Kommentare</h2>
<pre>
! Bis zum Ende der Zeile ignoriert
</pre>
<h2>Kompilation</h2>
<pre>
gfortran -o thing thing.f90
</pre>
<pre>
gfortran -o thing thing.f90 -lkernlib -lmathlib
</pre>
<h2>Intrinsische Datentypen</h2>
<pre>
REAL
DOUBLE PRECISION
INTEGER
CHARACTER
LOGICAL
</pre>
<h2>Intrinsische Konstanten</h2>
<pre>
.TRUE.
.FALSE.
</pre>
<h2>Intrinsische Operatoren</h2>
<pre>
+
-
*
/
**
<span title="==">.EQ.</span>
<span title="/=">.NE.</span>
<span title="&lt;">.LT.</span>
<span title="&lt;=">.LE.</span>
<span title="&gt;">.GT.</span>
<span title="&gt;=">.GE.</span>
.EQV.
.NEQV.
.OR.
.AND.
.NOT.
</pre>
<h2>Intrinsische Funktionen</h2>
<p>
ABS, IABS, SIN, COS, TAN, EXP, LOG, ASIN, ACOS, ATAN, SQRT, NINT, MIN, MAX, AMAX1, AMAX0, MAX0, MAX1, AMIN1, AMIN0, MIN0, MIN1 
</p>
<h2>Eigene Konstanten definieren</h2>
<pre>
PARAMETER (PI=3.141592d0)
</pre>
<h2>Konditional</h2>
<pre>
IF (2 .EQ. 3) THEN
  PRINT *, "the world is ending"
ELSE IF (3 .EQ. 3) THEN
  PRINT *, "everything alright"
ELSE
  PRINT *, "what did you expect?"
END IF
</pre>
<pre>
SELECT CASE (i)
  CASE default
    ...
  CASE (1:5)
    ...
  CASE (7)
    ...
END SELECT
</pre>
<h2>Assignabledefinition</h2>
<pre>
INTEGER x
INTEGER :: x
</pre>
<h2>Assigning</h2>
<pre>
x = 5
x = 3
x = 42
</pre>
<p>Die Schachtel x enthält am Ende 42.</p>
<h2>Funktionen</h2>
<pre>
PURE FUNCTION f(x) RESULT (result)
  IMPLICIT NONE
  DOUBLE PRECISION, INTENT(in) :: x
  DOUBLE PRECISION :: result
  result = 42d0
END
</pre>
<h2>Rekursion</h2>
<pre>
RECURSIVE PURE FUNCTION fac(n) RESULT (result)
  IMPLICIT NONE
  INTEGER, INTENT(in) :: n
  INTEGER :: result
  IF (n .EQ. 0) THEN
     result = 1
  ELSE
     result = n*fac(n - 1)
  END IF
END
PROGRAM f
  INTEGER r
  INTEGER fac
  r = fac(10)
  WRITE(*,*) r
END
</pre>
<h2>Subroutinen</h2>
<pre>
SUBROUTINE doStuff(x, y, z)
  IMPLICIT NONE
  REAL x
  REAL y
  REAL z
  READ(*,*) x, y, z
  RETURN
END
PROGRAM f
  REAL a
  REAL b
  REAL c
  CALL doStuff(a, b, c)
END
</pre>
<h2>Funktionale</h2>
<pre>
PROGRAM a
  IMPLICIT NONE
  EXTERNAL f
  EXTERNAL g
  DOUBLE PRECISION f
  DOUBLE PRECISION g
  DOUBLE PRECISION b
  ! Funktional g bekommt f übergeben.
  b = g(f)
  WRITE(*,*) b
END
FUNCTION f(x) RESULT (result)
  IMPLICIT NONE
  DOUBLE PRECISION :: x
  DOUBLE PRECISION :: result
  result = 2.4d0
END
FUNCTION g(callback) RESULT (result)
  IMPLICIT NONE
  DOUBLE PRECISION result
  ! gibt die Schnittstelle (den Prototyp) für callback an:
  INTERFACE
    FUNCTION callback(x)
      DOUBLE PRECISION :: callback
      DOUBLE PRECISION :: x
    END
  END INTERFACE
  result = callback(2.0d0)
END
</pre>
<h2>I/O</h2>
<p>Spezielle Nummern, genannt I/O-Channels, repräsentieren die Verbindung zum Zielgerät</p>
<p>* ist der Default Channel</p>
<pre>
WRITE(*,*) "hello", 42
PRINT *, 42, 43
OPEN(11, FILE="bli", STATUS='<span title="OLD|NEW|SCRATCH|REPLACE|UNKNOWN">REPLACE</span>')
WRITE(11,*) 42
CLOSE(11)
READ(*,*) v
</pre>
<p>FORMAT existiert.</p>
<h2>Operator Precedence</h2>
<ol>
<li>()</li>
<li>**</li>
<li>* /</li>
<li>+ -</li>
<li>.EQ. .NE. .LT. .LE. .GT. .GE.</li>
<li>.NOT.</li>
<li>.AND.</li>
<li>.OR.</li>
<li>.EQV. .NEQV.</li>
</ol>
<h2>Arrays</h2>
<pre>
INTEGER values(5) ! Index fängt bei 1 an
INTEGER values(0:10) ! Endindex INKLUSIVE
DATA values/5,4,3,2,1/
</pre>
<h2>Arrayfilter</h2>
<pre>
SUM(c, mask=c .GT. 0)
</pre>
<h2>Fixgröße-Datentypen</h2>
<p>INTEGER*8 ist ein Integer, der 8 Byte groß ist (wenn möglich).</p>
<h2>Records</h2>
<pre>
type Student
   character*20 last_name
   character*16 first_name
   character*6 comp_id
   integer id
   real score
   character*2 grade
end type
type (Student) cs(100)
cs(55) = Student('a', 'b', 'c', 2, 1.2, 'A')
cs(i)%score
</pre>
<h2>Modulsystem</h2>
<pre>
MODULE 
END MODULE
</pre>
<pre>
USE things
</pre>
<h2>Typkonversion</h2>
<pre>
INT(x)
REAL(x)
DBLE(x)
CMPLX(x,y)
</pre>
<!--<h2>Grafisches Darstellen gnuplot, graphviz -->
<h2>Schleifen</h2>
<pre>
DO WHILE (i .LE. 10)
  ...
END DO
</pre>
<pre>
DO i=0,10,1 ! der Endindex 10 ist komischerweise INKLUSIVE.
  ...
  EXIT
  ...
  CYCLE
END DO
</pre>
