ΚΕΝΤΡΟ ΠΛΗ.ΝΕ.Τ. Ν. ΦΛΩΡΙΝΑΣ
Η Γλώσσα Προγραμματισμού Fortran 90/95
Τι Είναι η Fortran
Η Fortran (FORmula TRANslation) είναι μια επιστημονική γλώσσα προγραμματισμού, όπως είναι οι Cobol, Algol, Ada, PL1, APL, Pascal κ.ά., η παλαιότερη απ’ όλες. Ένας πολύ μεγάλος όγκος από επιστημονικές εφαρμογές έχει αναπτυχθεί με τη γλώσσα αυτή και έτσι είναι αναγκαία και χρήσιμη η εκμάθηση και η υποστήριξή της. Η Fortran είναι εξαιρετικά κατάλληλη για πολύπλοκες αριθμητικές εργασίες.
Δημιουργήθηκε το 1955 στα εργαστήρια της ΙΒΜ από μια ομάδα επιστημόνων με επικεφαλής τον John Backus. Μέχρι σήμερα έχουν εμφανισθεί διάφορες παραλλαγές και βελτιώσεις της, όπως οι Fortran ΙΙ, Fortran IV, Fortran V, Fortran 66 και Fortran 77.
Η Fortran 90 είναι η πιο τελευταία έκδοση της γλώσσας και με την επερχόμενη Fortran 95 τοποθετείται πλέον στον όμιλο των μοντέρνων γλωσσών προγραμματισμού. Υπάρχει και η έκδοση Visual Fortran, η οποία βασίζεται στην Fortran 90 με στοιχεία της Fortran 95 και χρησιμοποιεί ένα γραφικό, παραθυρικό περιβάλλον.
Για μια πρώτη γνωριμία με την Fortran, θα δούμε ένα απλό πρόγραμμα που υπολογίζει και εκτυπώνει την τρίτη δύναμη των ακεραίων από το 2 έως και το 100.
PROGRAM FIRST
! ΤΟ ΠΡΩΤΟ ΜΑΣ ΠΡΟΓΡΑΜΜΑ ΣΕ FORTRAN
! ΥΠΟΛΟΓΙΖΕΙ ΤΗΝ ΤΡΙΤΗ ΔΥΝΑΜΗ ΤΩΝ ΑΚΕΡΑΙΩΝ &
&! ΑΡΙΘΜΩΝ ΑΠΟ ΤΟ 2 ΕΩΣ ΚΑΙ ΤΟ 100
X=2 ! ΑΡΧΙΚΗ ΤΙΜΗ
100 Y=X**3
PRINT *, X, Y
X=X+1
IF(X<=100) GO TO 100
STOP
END PROGRAM FIRST
Μερικές πρώτες παρατηρήσεις που μπορούμε να κάνουμε είναι οι εξής :
Το σύμβολο ! χρησιμοποιείται για να ορίζουμε σχόλια (comments) και μπορούμε να το χρησιμοποιήσουμε στην αρχή μιας εντολής αλλά και πιο μέσα.
Μπορούμε να χρησιμοποιήσουμε αριθμούς για τις εντολές του προγράμματος, όπου η αρίθμησή τους δεν είναι υποχρεωτικό να είναι αύξουσα.
Το * στην εντολή εκτύπωσης προσδιορίζει ελεύθερη μορφή εκτύπωσης.
Για να συνεχίσουμε μια μεγάλη εντολή στην επόμενη σειρά, θα πρέπει να γράψουμε το σύμβολο & στο τέλος της γραμμής και να συνεχίσουμε στην επόμενη γραμμή με το ίδιο σύμβολο &, αν και αυτό δεν είναι απαραίτητο.
Για να γράψουμε περισσότερες από μία εντολές στην ίδια γραμμή, θα πρέπει να χρησιμοποιήσουμε τον χαρακτήρα ;.
Η τελευταία εντολή κάθε προγράμματος πρέπει να είναι η END.
Η πρώτη εντολή κάθε προγράμματος είναι πολύ χρήσιμο, αν και όχι υποχρεωτικό, να είναι η PROGRAM ακολουθούμενη από το όνομα του προγράμματος.
Μετά από την εντολή END είναι πολύ χρήσιμο, αν και όχι υποχρεωτικό, να γράψουμε και πάλι το όνομα του προγράμματος.
Γνωριμία με το Περιβάλλον της Visual Fortran
Το περιβάλλον της Visual Fortran είναι οργανωμένο σε projects και η ανάπτυξη των προγραμμάτων γίνεται δια μέσου των projects. Μέσα σε κάθε project δημιουργούνται τα αρχεία με τα πηγαία προγράμματα (source programs).
Τα projects είναι διαφόρων τύπων και περιέχονται μέσα σε workspaces, όπου ένα workspace μπορεί να περιέχει περισσότερα από ένα projects. Η Visual Fortran έχει ενσωματωμένο έναν δικό της text editor για να μπορούμε να γράφουμε τα προγράμματά μας και χρησιμοποιεί βιβλιοθήκες, που είναι πολύ χρήσιμες στους προγραμματιστές.
Για να ξεκινήσουμε την Visual Fortran, επιλέγουμε Developer Studio από το υπομενού Visual Fortran του αρχικού μενού Έναρξη. Για να δημιουργήσουμε ένα καινούργιο πρόγραμμα, επιλέγουμε New… από το μενού File ή πατάμε τα πλήκτρα Control+N.
Στο πλαίσιο διαλόγου New και στην καρτέλα Projects επιλέγουμε Fortran Console Application. Στο πλαίσιο κειμένου Project name γράφουμε το όνομα του project, π.χ. Project1. Στη θέση Location μπορούμε να αφήσουμε την προεπιλεγμένη θέση της Visual Fortran για τη δημιουργία του project, δηλ. την C:\Program Files\Microsoft Visual Studio\MyProjects\Project1, ή να κάνουμε κλικ στο διπλανό πλήκτρο με τις τρεις τελείες (…) και να επιλέξουμε μια άλλη δική μας θέση. Η Visual Fortran θα δημιουργήσει έναν φάκελο (directory) με το όνομα του καινούργιου project και στη θέση που επιλέξαμε.
Κάνουμε κλικ στο ΟΚ και στο επόμενο πλαίσιο διαλόγου επιλέγουμε το πλήκτρο επιλογής An empty project και κάνουμε κλικ στο πλήκτρο Finish. Στο νέο περιβάλλον που θα εμφανισθεί επιλέγουμε New… από το μενού File ή πατάμε τα πλήκτρα Control+N. Στο πλαίσιο διαλόγου New και στην καρτέλα Files επιλέγουμε Fortran Free Format Source File και στο πλαίσιο κειμένου File name γράφουμε το όνομα του προγράμματος, π.χ. Program1.
Στη θέση Location μπορούμε να επιλέξουμε τον φάκελο όπου θα δημιουργηθεί το πρόγραμμα ή αφήνουμε τον φάκελο που προτείνει η Visual Fortran. Κάνουμε κλικ στο ΟΚ και είμαστε έτοιμοι να ξεκινήσουμε να γράφουμε το πρόγραμμά μας.
Παρατηρούμε ότι καθώς πληκτρολογούμε τις εντολές του προγράμματος, αυτόματα η Visual Fortran χρωματίζει με πράσινο χρώμα τα σχόλια, με μπλε χρώμα τις εντολές της γλώσσας (δεσμευμένες λέξεις) και αφήνει όλα τα άλλα με το κανονικό μαύρο χρώμα. Αποθηκεύουμε το πρόγραμμά μας και βλέπουμε ότι προστίθεται αυτόματα η επέκταση .f90.
Για παράδειγμα, έστω ότι δημιουργούμε ένα πολύ απλό πρόγραμμα που θα προσθέτει δύο αριθμούς και θα εμφανίζει το άθροισμά τους :
! Πρόσθεση δύο αριθμών
program program1
real::a, b, c
read *, a, b
c =a + b
print *, a, b, c
stop
end program program1
Για να εκτελέσουμε το παραπάνω πρόγραμμα, θα πρέπει να πάμε με τη σειρά στις εξής επιλογές του μενού Build :
Compile Program1.f90 (Control+F7), για να γίνει η μεταγλώττιση (compilation) του προγράμματος και να εντοπιστούν τα τυχόν συντακτικά λάθη. Τα λάθη (errors) ή οι προειδοποιήσεις (warnings) θα εμφανισθούν στο κάτω παραθυράκι της Visual Fortran. Αν υπάρχουν λάθη, θα πρέπει να τα διορθώσουμε πριν προχωρήσουμε στο επόμενο βήμα.
Build Project1.exe (F7), για να γίνει η διασύνδεση των απαραίτητων βιβλιοθηκών και να δημιουργηθεί η εκτελέσιμη μορφή του προγράμματος.
! Execute Project1.exe (Control+F5), για να εκτελεσθεί το πρόγραμμα. Θα εμφανισθεί ένα άλλο παράθυρο όπου θα πρέπει να δώσουμε δύο αριθμητικές τιμές και να πατήσουμε το πλήκτρο enter για να δούμε το αποτέλεσμα.
Για να ανοίξουμε τώρα ένα υπάρχον πρόγραμμα και να το επεξεργαστούμε, επιλέγουμε Open Workspace… από το μενού File και αναζητούμε το αρχείο με όνομα Program1 αλλά με επέκταση .dsw.
Οι σταθερές (constants) στη Fortran είναι έξι ειδών και είναι οι εξής :
Ακέραιες σταθερές (integer ή fixed point constants). Είναι όλοι οι ακέραιοι αριθμοί από –231-1 έως και +231-1 και δεν χρησιμοποιούμε υποδιαστολή.
Πραγματικές σταθερές (real ή floating point constants). Είναι αριθμοί που περιέχουν οπωσδήποτε υποδιαστολή και παίρνουν τιμές από –1038 έως και +1038. Μπορούν να παρασταθούν και με εκθετική μορφή, όπως για παράδειγμα 29.32Ε3 = 29.32 Χ 103.
Σταθερές διπλής ακρίβειας (double precision constants). Είναι αριθμοί που περιέχουν οπωσδήποτε υποδιαστολή και παίρνουν τιμές από –10308 έως και +10308. Μπορούν να παρασταθούν και με εκθετική μορφή, όπως για παράδειγμα 29.32D3 = 29.32 Χ 103.
Μιγαδικές σταθερές (complex constants). Στη Fortran μια μιγαδική σταθερά παριστάνεται με δύο πραγματικές σταθερές, μια για το πραγματικό και μια για το φανταστικό μέρος, που χωρίζονται με κόμμα και περικλείονται σε παρενθέσεις. Για παράδειγμα (2.1, –5.6) = 2.1 – 5.6i.
Λογικές σταθερές (logical constants). Όπως σ’ όλες τις γνωστές γλώσσες προγραμματισμού, έτσι και στη Fortran, οι λογικές σταθερές είναι δύο : .TRUE. και .FALSE.
Αλφαριθμητικές σταθερές (alphanumeric constants). Αποτελούνται από ένα πλήθος συμβόλων, κενών αλφαβητικών ή και αριθμητικών χαρακτήρων που περικλείονται σε μονές ή διπλές αποστρόφους. Για να κάνουμε μια αλφαριθμητική σταθερά να περιέχει η ίδια απόστροφο, γράφουμε δύο συνεχόμενες αποστρόφους χωρίς κενό ανάμεσά τους.
Οι μεταβλητές (variables) στη Fortran είναι κι αυτές έξι ειδών και είναι οι εξής :
Ακέραιες μεταβλητές (integer variables). Παίρνουν ως τιμές μόνο ακέραιες σταθερές και ο πρώτος χαρακτήρας τους πρέπει να είναι ένα από τα γράμματα I, J, K, L, M και N. Αν θέλουμε μια ακέραια μεταβλητή να αρχίζει από διαφορετικό γράμμα, θα πρέπει να το δηλώσουμε στην αρχή του προγράμματος με την εντολή δήλωσης INTEGER, ως εξής :
INTEGER::A, FLORINA
Πραγματικές μεταβλητές (real variables). Παίρνουν ως τιμές μόνο πραγματικές σταθερές και ο πρώτος χαρακτήρας τους πρέπει να είναι ένα από τα γράμματα του λατινικού αλφαβήτου εκτός από τα I, J, K, L, M και N. Για να χρησιμοποιήσουμε ένα από τα γράμματα αυτά σαν τον πρώτο χαρακτήρα μιας πραγματικής μεταβλητής, θα πρέπει να το δηλώσουμε στην αρχή του προγράμματος με την εντολή δήλωσης REAL, ως εξής :
REAL::K1, M5
Μεταβλητές διπλής ακρίβειας (double precision variables). Παίρνουν ως τιμές πραγματικές σταθερές διπλής ακρίβειας. Μπορούν να αρχίζουν από οποιοδήποτε γράμμα του λατινικού αλφαβήτου αλλά θα πρέπει να δηλώνονται στην αρχή του προγράμματος με την εντολή δήλωσης DOUBLE PRECISION ή την REAL(8), ως εξής :
DOUBLE PRECISION::MEAN, A ή REAL(8)::K1, M5
Μιγαδικές μεταβλητές (complex variables). Παίρνουν ως τιμές μιγαδικές σταθερές. Μπορούν να αρχίζουν από οποιοδήποτε γράμμα του λατινικού αλφαβήτου αλλά θα πρέπει να δηλώνονται στην αρχή του προγράμματος με την εντολή δήλωσης COMPLEX, ως εξής :
COMPLEX::A20, C
Λογικές μεταβλητές (logical variables). Παίρνουν ως τιμές λογικές σταθερές. Μπορούν να αρχίζουν από οποιοδήποτε γράμμα του λατινικού αλφαβήτου αλλά θα πρέπει να δηλώνονται στην αρχή του προγράμματος με την εντολή δήλωσης LOGICAL, ως εξής :
LOGICAL::RESULT, PASS
Αλφαριθμητικές μεταβλητές (alphanumeric variables). Παίρνουν ως τιμές αλφαριθμητικές σταθερές και ορίζονται με μια εντολή CHARACTER της εξής μορφής :
CHARACTER(LEN=μήκος)::A1, A2, A3, …
ή
CHARACTER(μήκος)::A1, A2, A3, …
ή
CHARACTER*μήκος::A1, A2, A3, …
Όλες οι παραπάνω εντολές ορίζουν ότι οι μεταβλητές Α1, Α2 και Α3 είναι αλφαριθμητικές και παίρνουν τιμές έως και μήκος όση είναι η τιμή του προσδιοριστικού μήκος. Αν παραλείψουμε την τιμή για το προσδιοριστικό, τότε οι μεταβλητές θα μπορούν να πάρουν τιμή ενός μόνο χαρακτήρα.
CHARACTER(LEN=8)::A1, A2*3, A3, Α4*5
που ορίζει ότι οι μεταβλητές Α1 και Α3 θα έχουν μήκος 8 χαρακτήρων, αλλά η μεταβλητή Α2 θα έχει μήκος 3 χαρακτήρων και η μεταβλητή Α4 θα έχει μήκος 5 χαρακτήρων.
Προσέξτε και τα εξής :
CHARACTER A1(10)
CHARACTER *(*)B
CHARACTER(LEN=*)NAME
PARAMETER (NAME=’ΦΛΩΡΙΝΑ’)
Η μεταβλητή Α1 είναι ένας αλφαριθμητικός πίνακας μίας διάστασης που περιέχει 10 στοιχεία μήκους ενός χαρακτήρα το καθένα, το μήκος της μεταβλητής Β δεν προσδιορίζεται ενώ το μήκος της μεταβλητής NAME καθορίζεται στην επόμενη εντολή PARAMETER από την τιμή που της δίνουμε (μήκος = 7).
Το όνομα μιας μεταβλητής στη Fortran μπορεί να περιέχει γράμματα, ψηφία και τον χαρακτήρα υπογράμμισης _. Μπορεί να έχει έως και 31 χαρακτήρες αλλά ο πρώτος χαρακτήρας δεν πρέπει να είναι ψηφίο.
Είδαμε στην προηγούμενη παράγραφο ότι μια σύμβαση που έχει παραμείνει από τις παλαιότερες εκδόσεις της Fortran είναι ότι όλες οι μεταβλητές που αρχίζουν από τα γράμματα Ι – Ν είναι ακέραιες ενώ όλες οι υπόλοιπες είναι πραγματικές.
Αυτή η σύμβαση παύει να ισχύει αν χρησιμοποιήσουμε εντολές δήλωσης, όπως είναι οι INTEGER, REAL, LOGICAL, COMPLEX κ.ά. Στην Fortran 90 μπορούμε να ακυρώσουμε την παραπάνω σύμβαση αν χρησιμοποιήσουμε την εντολή IMPLICIT NONE και ανάλογες εντολές δήλωσης, όπως παρακάτω :
IMPLICIT NONE
INTEGER::A=0
REAL::I, J
REAL::A1=1.5, A2 = 3.4
Βλέπουμε ότι παράλληλα με τη δήλωση του τύπου μιας μεταβλητής μπορούμε να της δώσουμε και αρχική τιμή.
Οι Αριθμητικές Παραστάσεις στη Fortran
Οι αριθμητικές παραστάσεις στην Fortran μπορούν να αποτελούνται από μια απλή μεταβλητή ή και από μια πολύπλοκη αλγεβρική παράσταση. Τα σύμβολα που χρησιμοποιούμε και οι πράξεις που μπορούμε να κάνουμε μέσα στις αριθμητικές παραστάσεις είναι τα εξής :
+, πρόσθεση
–, αφαίρεση
*, πολλαπλασιασμός
/, διαίρεση
**, ύψωση σε δύναμη
Η ιεραρχία των αριθμητικών πράξεων μέσα σε μια αριθμητική παράσταση είναι η εξής : πρώτα υπολογίζονται οι δυνάμεις, μετά οι πολλαπλασιασμοί και οι διαιρέσεις και τέλος οι προσθέσεις και οι αφαιρέσεις. Για τις ισοδύναμες αριθμητικές πράξεις, η ιεραρχία είναι από αριστερά προς τα δεξιά. Βέβαια, αν χρησιμοποιηθούν παρενθέσεις, θα γίνουν πρώτα οι πράξεις μέσα στις παρενθέσεις.
Όταν γίνεται διαίρεση δύο ακεραίων αριθμών, τότε στην ουσία παίρνουμε το πηλίκο της ακέραιης διαίρεσης. Για παράδειγμα, το αποτέλεσμα της διαίρεσης 5/3 είναι 1 και το αποτέλεσμα της διαίρεσης 18/4 είναι 4.
Οι Ενσωματωμένες Συναρτήσεις της Fortran
Η Fortran είναι εφοδιασμένη με πάρα πολλές έτοιμες (ενσωματωμένες) συναρτήσεις, τις οποίες μπορούμε να καλούμε όποτε θέλουμε στα προγράμματά μας. Οι πιο χρήσιμες από τις συναρτήσεις αυτές είναι οι εξής :
Συνάρτηση |
Αντίστοιχη Μαθηματική |
Τύπος των Ορισμάτων |
Τύπος του Αποτελέσματος |
Παρατηρήσεις |
SIN(X) |
ημ(Χ) |
R |
R |
Το Χ σε ακτίνια |
COS(X) |
συν(Χ) |
R |
R |
Το Χ σε ακτίνια |
TAN(X) |
εφ(Χ) |
R |
R |
Το Χ σε ακτίνια |
COTAN(X) |
σφ(Χ) |
R |
R |
Το Χ σε ακτίνια |
ASIN(X) |
τοξημ(Χ) |
R |
R |
<= 1 |
ACOS(X) |
τοξσυν(Χ) |
R |
R |
<= 1 |
ATAN(X) |
τοξεφ(Χ) |
R |
R |
|
SQRT(X) |
|
R |
R |
|
EXP(X) |
eX |
R |
R |
|
ALOG10(X) |
log(X) |
R |
R |
Δεκαδικός λογάριθμος |
LOG(X) |
ln(X) |
R |
R |
Νεπέρειος λογάριθμος |
CEILING(X) |
Ο μικρότερος ακέραιος που είναι >= Χ |
R |
I |
|
FLOOR(X) |
Ο μεγαλύτερος ακέραιος που είναι <= Χ |
R |
I |
|
ABS(X) IABS(X) |
|
R I |
R I |
|
FLOAT(X) |
Μετατροπή ακεραίου σε πραγματικό |
I |
R |
|
IFIX(X) |
Μετατροπή πραγματικού σε ακέραιο |
R |
I |
|
DBLE(X) |
Μετατροπή αριθμού σε διπλής ακρίβειας |
R, I, C |
D |
|
SNGL(X) |
Μετατροπή διπλής ακρίβειας σε πραγματικό |
D |
R |
|
SIGN(X1, X2) ISIGN(X1, X2) |
Συνάρτηση πρόσημο |
R I |
R I |
Απόλυτη τιμή του Χ1 επί πρόσημο του Χ2 |
DIM(X1, X2) IDIM(X1, X2) |
Θετική διαφορά |
R I |
R I |
Ίσο με Χ1-Χ2 αν Χ1>Χ2 και ίσο με 0 αν Χ1<=Χ2 |
REAL(X) |
Μετατροπή ακεραίου σε πραγματικό ή το πραγματικό μέρος μιγαδικού |
C, I |
R |
|
AIMAG(X) |
Φανταστικό μέρος μιγαδικού |
C |
R |
|
CONJG(X) |
Συζυγής μιγαδικού |
C |
C |
|
CMPLX(X1, X2) |
Μετατροπή ακεραίων ή πραγματικών σε μιγαδικό |
R, I |
C |
=X1+jX2 |
MAX(X1, X2 …) |
Μέγιστος |
R |
R |
|
MIN(X1, X2 …) |
Ελάχιστος |
R |
R |
|
MOD(X1, X2) |
Υπόλοιπο διαίρεσης |
I |
I |
|
AINT(X) INT(X) |
Αποκοπή δεκαδικού μέρους |
R R |
R I |
|
ANINT(X) NINT(X) |
Στρογγυλοποίηση |
R R |
R I |
|
CHAR(X) |
Χαρακτήρας ASCII |
I |
CHAR |
|
ICHAR(X) |
Θέση χαρακτήρα στον κώδικα ASCII |
CHAR |
I |
|
LEN(X) |
Πλήθος χαρακτήρων |
CHAR |
I |
|
INDEX(X1, X2) |
Θέση αλφαριθμητικού μέσα σε άλλο |
CHAR |
I |
Θέση όπου ξεκινάει το Χ2 μέσα στο Χ1 |
LLT(X1, X2) |
Σύγκριση αλφαριθμητικών (<) |
CHAR |
L |
|
LGT(X1, X2) |
Σύγκριση αλφαριθμητικών (>) |
CHAR |
L |
|
LLE(X1, X2) |
Σύγκριση αλφαριθμητικών (<=) |
CHAR |
L |
|
LGE(X1, X2) |
Σύγκριση αλφαριθμητικών (>=) |
CHAR |
L |
|
Ακολουθούν παραδείγματα :
FLOAT(12) = 12. ! Μετατροπή ακεραίου αριθμού σε πραγματικό
IFIX(16.87) = 16 ! Μετατροπή πραγματικού αριθμού σε ακέραιο
DBLE(13.14) = 13.14D1 ! Μετατροπή αριθμού σε διπλής ακρίβειας
SNGL(9.14D2) = 9.14E2 ! Μετατροπή διπλής ακρίβειας σε πραγματικό
SIGN(10, -5) = -10 ! Χρήση της συνάρτησης πρόσημο
IDIM(10, 15) = 0 ! Θετική διαφορά
REAL(10.3+3.4i) = 10.3 ! Πραγματικό μέρος μιγαδικού αριθμού
AIMAG(10.3+3.4i) = 3.4 ! Φανταστικό μέρος μιγαδικού αριθμού
CONJG(10.3+3.4i) = 10.3–3.4i ! Συζυγής μιγαδικού αριθμού
CMPLX(-9.1, 35.34) = -9.1+35.34i ! Δημιουργία μιγαδικού αριθμού
AINT(7.4) = 7.0 ! Αποκοπή δεκαδικού μέρους
INT(7.4) = 7 ! Αποκοπή δεκαδικού μέρους
ANINT(7.8) = 8.0 ! Στρογγυλοποίηση αριθμού
NINT(7.8) = 8 ! Στρογγυλοποίηση αριθμού
MAX(10.3, 31.4, 15.7) = 31.4 ! Υπολογισμός μεγίστου
MIN(10.3, 31.4, 15.7) = 10.3 ! Υπολογισμός ελαχίστου
MOD(18, 4) = 2 ! Υπόλοιπο ακέραιης διαίρεσης
CHAR(65) =’A’ ! Επιστροφή χαρακτήρα από τον κωδικό ASCII
ICHAR(‘A’) = 65 ! Επιστροφή κωδικού ASCII από τον χαρακτήρα
LEN(‘FLORINA’) = 8 ! Πλήθος χαρακτήρων αλφαριθμητικού
INDEX(‘FLORINA’, ‘O’) = 3 ! Θέση του 2ου ορίσματος
LLT(‘A’, ‘B’) = .TRUE.
LGT(‘C’, ‘D’) = .FALSE.
LLE(‘A’, ‘B’) = .TRUE.
LGE(‘C’, ‘D’) = .FALSE.
Πράξεις με Αλφαριθμητικές Μεταβλητές
Ο τελεστής // ενώνει τα περιεχόμενα δύο αλφαριθμητικών μεταβλητών. Ακολουθούν παραδείγματα :
CHARACTER*15::A, B*8, C*7
B = ’ΦΛΩΡΙΝΑ’
C = ‘ΚΟΖΑΝΗ’
A = B // C
A = B // ‘KAI ’ // C
Η μεταβλητή Α θα περιέχει αρχικά την τιμή ‘ΦΛΩΡΙΝΑ ΚΟΖΑΝΗ ’ και μετά την τιμή ‘ΦΛΩΡΙΝΑ ΚΑΙ ΚΟΖ’.
Μπορούμε να αποσπάσουμε χαρακτήρες από μια αλφαριθμητική μεταβλητή, ορίζοντας μέσα σε παρενθέσεις το κατώτερο και το ανώτερο όριο και χωρίζοντάς τα με τον χαρακτήρα :.
Για παράδειγμα, ο συμβολισμός Α(3:5) ορίζει ένα υποσύνολο της αλφαριθμητικής μεταβλητής Α που αποτελείται από τον τρίτο μέχρι και τον πέμπτο χαρακτήρα της.
Μπορούμε να παραλείψουμε το 1 σαν κατώτερο όριο. Για παράδειγμα, ο συμβολισμός Α(:5) είναι ίδιος με τον Α(1:5). Μπορούμε να παραλείψουμε και το ανώτερο όριο αν είναι ίσο με το πλήθος των χαρακτήρων της αλφαριθμητικής μεταβλητής. Για παράδειγμα, ο συμβολισμός Α(4:) είναι ίδιος με τον Α(4:10), αν φυσικά η αλφαριθμητική μεταβλητή Α αποτελείται από 10 χαρακτήρες.
Ο παραπάνω συμβολισμός μπορεί να χρησιμοποιηθεί και σε εντολές αντικατάστασης. Για παράδειγμα, η παρακάτω έκφραση :
A(2:5) = B(4:7)
αντικαθιστά 3 χαρακτήρες της μεταβλητής Α με άλλους τρεις χαρακτήρες της μεταβλητής Β ενώ οι υπόλοιποι χαρακτήρες της μεταβλητής Α δεν επηρεάζονται.
Με την εντολή PARAMETER μπορούμε να δώσουμε τιμές σε κάποιες μεταβλητές ταυτόχρονα με τον ορισμό τους, οι οποίες όμως δεν θα μπορούν να αλλαχθούν στη συνέχεια. Πρόκειται στην ουσία για σταθερές με όνομα.
Για παράδειγμα, η επόμενη εντολή :
REAL, PARAMETER::PI=3.1415926
ορίζει μια πραγματική μεταβλητή με όνομα PI και με τιμή 3.1415926, η οποία δεν θα μπορεί να μεταβληθεί κατά την εκτέλεση του προγράμματος.
Μπορούμε να χρησιμοποιήσουμε και μόνη της την εντολή PARAMETER και με διάφορες μορφές, ως εξής :
REAL(4)::PI, PI1
CHARACTER::A*10, B*10
PARAMETER(PI=3.1415926, PI1=PI/2)
PARAMETER(A=’FLORINA’, B=’PER SEMPRE’)
Τα δεδομένα εισόδου σ’ ένα πρόγραμμα μπορούν να δοθούν από το πληκτρολόγιο με καταχωρήσεις του χρήστη ή και να διαβασθούν από ένα αρχείο. Η εντολή που χρησιμοποιούμε για να διαβάσουμε δεδομένα είναι η READ, η οποία έχει δύο μορφές σύνταξης :
READ(u, f) list
ή
READ f, list
Το u (unit) είναι ο κωδικός που χαρακτηρίζει τη μονάδα εισόδου. Μπορεί να συσχετιστεί με κάποιο αρχείο μέσω της εντολής OPEN, που θα την δούμε αργότερα, και η τιμή του πρέπει να είναι ακέραιη και μεταξύ των –32767 και 32767.
Για το πληκτρολόγιο χρησιμοποιούμε τις τιμές 0, 5 και το *, ενώ αν παραλείψουμε την τιμή του u, όπως στον δεύτερο τρόπο σύνταξης, τότε ως μονάδα εισόδου θεωρείται το πληκτρολόγιο.
Το f είναι ο αριθμός μιας εντολής FORMAT, η οποία καθορίζει τη μορφοποίηση των δεδομένων εισόδου και θα πρέπει να βρίσκεται κάπου μέσα στο πρόγραμμα. Αν στη θέση του f υπάρχει ο χαρακτήρας *, τότε μιλάμε για ελεύθερο FORMAT, δηλ. θα πρέπει οι τιμές των δεδομένων εισόδου να διαχωρίζονται μεταξύ τους με κόμμα ή με κενό.
Το list είναι μια σειρά μεταβλητών που διαχωρίζονται μεταξύ τους με κόμματα.
Σε γενικές γραμμές, η εντολή READ διαβάζει τις μεταβλητές που υπάρχουν στη list από τη μονάδα εισόδου που αντιστοιχεί στον αριθμό u και σύμφωνα με τις προδιαγραφές που υπάρχουν στην εντολή FORMAT στον αριθμό εντολής f.
Ακολουθούν παραδείγματα :
READ(5, *) A, B
READ(*, *) I, BATHMOS
READ *, C
READ(5, 10) A, B
10 FORMAT(2F8.2)
Στα παραδείγματα αυτά η είσοδος των τιμών των μεταβλητών γίνεται από το πληκτρολόγιο με καταχώρηση των τιμών από τον χρήστη κατά τη διάρκεια της εκτέλεσης του προγράμματος.
Μπορεί, όμως, οι τιμές των μεταβλητών να υπάρχουν ήδη αποθηκευμένες σε κάποιο αρχείο και να τις διαβάσουμε από εκεί όταν εκτελεσθεί το πρόγραμμα.
Ακολουθούν παραδείγματα :
OPEN(UNIT=10, FILE=’DATA’)
READ(10, *) A1, A2
Η εντολή OPEN ανοίγει ένα αρχείο με όνομα DATA, το οποίο συσχετίζεται με τον αριθμό μονάδας 10, από το οποίο αρχείο γίνεται και το διάβασμα των τιμών των μεταβλητών Α1 και Α2 με ελεύθερο FORMAT.
OPEN(UNIT=10, FILE=’DATA1’)
READ(10, 20) A1, A2
20 FORMAT (F5.2, F6.3)
Στο παράδειγμα αυτό δεν έχουμε ελεύθερο FORMAT.
Οι Εντολές Εξόδου WRITE και PRINT
Τα δεδομένα εξόδου σ’ ένα πρόγραμμα μπορούν να σταλούν απευθείας στην οθόνη ή και να γραφούν σ’ ένα αρχείο. Οι εντολές που χρησιμοποιούμε για να γράψουμε δεδομένα είναι η WRITE και η PRINT, οι οποίες έχουν την εξής σύνταξη :
WRITE(u, f) list
και
PRINT f, list
Το u (unit) είναι ο κωδικός που χαρακτηρίζει τη μονάδα εξόδου. Μπορεί να συσχετιστεί με κάποιο αρχείο μέσω της εντολής OPEN και η τιμή του πρέπει να είναι ακέραιη και μεταξύ των –32767 και 32767.
Για την οθόνη χρησιμοποιούμε τις τιμές 0, 6 και το *, ενώ αν παραλείψουμε την τιμή του u, όπως στον δεύτερο τρόπο σύνταξης, τότε ως μονάδα εξόδου θεωρείται η οθόνη.
Το f είναι ο αριθμός μιας εντολής FORMAT, η οποία καθορίζει τη μορφοποίηση των δεδομένων εξόδου και θα πρέπει να βρίσκεται κάπου μέσα στο πρόγραμμα. Αν στη θέση του f υπάρχει ο χαρακτήρας *, τότε μιλάμε για ελεύθερο FORMAT, δηλ. η μορφή εμφάνισης θα είναι η προκαθορισμένη από τον Η/Υ.
Το list είναι μια σειρά μεταβλητών που διαχωρίζονται μεταξύ τους με κόμματα.
Σε γενικές γραμμές, η εντολή εξόδου εμφανίζει (εξάγει) τις μεταβλητές που υπάρχουν στη list προς τη μονάδα εξόδου που αντιστοιχεί στον αριθμό u και σύμφωνα με τις προδιαγραφές που υπάρχουν στην εντολή FORMAT στον αριθμό εντολής f.
Ακολουθούν παραδείγματα :
WRITE(*, *) A, B
WRITE(6, *) I, BATHMOS
PRINT *, A, B
WRITE(*, *) ‘Η Α ΕΧΕΙ ΤΙΜΗ : ‘, A
PRINT *, ‘Η Β ΕΧΕΙ ΤΙΜΗ : ‘, B
Στα παραδείγματα αυτά η έξοδος των τιμών των μεταβλητών γίνεται προς την οθόνη κατά τη διάρκεια της εκτέλεσης του προγράμματος.
Μπορεί, όμως, να θέλουμε οι τιμές των μεταβλητών να αποθηκευθούν σε κάποιο αρχείο για να μπορούμε να τις διαβάσουμε από εκεί αργότερα ή και με κάποιο άλλο πρόγραμμα.
Ακολουθούν παραδείγματα :
OPEN(UNIT=11, FILE=’OUT’)
WRITE(11, *) A1, A2
Η εντολή OPEN ανοίγει (δημιουργεί) ένα αρχείο με όνομα OUT, το οποίο συσχετίζεται με τον αριθμό μονάδας 11, στο οποίο αρχείο γίνεται και η εγγραφή των τιμών των μεταβλητών Α1 και Α2 με ελεύθερο FORMAT.
OPEN(UNIT=11, FILE=’OUT1’)
WRITE(11, 20) A1, A2
20 FORMAT (F5.2, F6.3)
Στο παράδειγμα αυτό δεν έχουμε ελεύθερο FORMAT. Την εντολή WRITE μπορούμε να την χρησιμοποιήσουμε και για να εμφανίσουμε ένα περιγραφικό μήνυμα όταν πρόκειται να διαβάσουμε κάτι με την εντολή READ, όπως :
WRITE(*, *) ‘ΔΩΣΤΕ ΤΟΝ ΒΑΘΜΟ : ‘
READ(*, *) BATHMOS
Η Εντολή Εισόδου για Σειριακά Αρχεία
Η εντολή εισόδου δεδομένων για σειριακά αρχεία που χρησιμοποιεί η Fortran έχει την εξής γενική μορφή :
READ([UNIT=]u, [FMT=f][,END=e][,ERR=er][,IOSTAT=int][,ADVANCE=C-expr][,EOR=eor]) list
Οι παράμετροι που είναι μέσα σε αγκύλες [ ] είναι προαιρετικές και η επεξήγησή τους έχει ως εξής :
UNIT=u, είναι ο κωδικός αριθμός της μονάδας εισόδου που θα χρησιμοποιήσουμε και είναι η μόνη υποχρεωτική παράμετρος.
FMT=f, είναι ο αριθμός μιας εντολής FORMAT, η οποία καθορίζει τη μορφή καταχώρησης των δεδομένων.
END=e, καθορίζει ότι αν έχουν τελειώσει τα δεδομένα του αρχείου εισόδου (end-of-file), τότε η εκτέλεση του προγράμματος θα συνεχισθεί στην εντολή με αριθμό e. Αν δεν χρησιμοποιήσουμε αυτή την παράμετρο και έχουμε φθάσει στο τέλος του αρχείου εισόδου, θα εμφανισθεί ένα μήνυμα λάθους.
ERR=er, καθορίζει ότι αν συμβεί κάποιο λάθος κατά την είσοδο των δεδομένων, τότε η εκτέλεση του προγράμματος θα συνεχισθεί στην εντολή με αριθμό er.
IOSTAT=int, χρησιμοποιείται για να μάθουμε αν η εκτέλεση της εντολής READ ήταν επιτυχής ή όχι. Η int είναι μια ακέραια μεταβλητή που μπορεί να πάρει αρνητική, μηδέν ή θετική τιμή, που σημαίνει ότι είχαμε ελλειπή δεδομένα (end-of-file), επιτυχή εκτέλεση ή κάποιο λάθος στα δεδομένα, αντίστοιχα.
ADVANCE=C-expr, η παράμετρος C-expr μπορεί να πάρει μια από τις τιμές ‘yes’ (εξ ορισμού) ή ‘no’, που σημαίνει ότι η εντολή READ διαβάζει μια καινούργια εγγραφή (record) ή ότι παραμένει στην ίδια εγγραφή και συνεχίζει από εκεί που τελείωσε η προηγούμενη εντολή READ.
EOR=eor, καθορίζει ότι αν έχουν τελειώσει τα δεδομένα μιας εγγραφής (end-of-record) χωρίς να έχουν πάρει τιμή όλες οι μεταβλητές της list, τότε η εκτέλεση του προγράμματος θα συνεχισθεί στην εντολή με αριθμό e.
list, είναι μια σειρά από μεταβλητές που χωρίζονται μεταξύ τους με κόμματα.
Ακολουθούν παραδείγματα :
READ(UNIT=10, FMT=*, END=100, ERR=200, IOSTAT=I) A
READ(9, 10) B
READ(7, 20, ADVANCE=’NO’, EOR=100) C
Η Εντολή Εισόδου για Αρχεία Άμεσης Προσπέλασης
Η γενική μορφή της εντολής εισόδου για την ανάγνωση ενός αρχείου άμεσης προσπέλασης, η εύρεση δηλαδή μιας συγκεκριμένης εγγραφής (record), είναι η εξής :
READ([UNIT=]u,[FMT=]f[, ERR=er][, IOSTAT=int][, REC=rc]) list
Η παράμετρος REC=rc είναι ο αύξων αριθμός της εγγραφής μέσα στο αρχείο. Η rc μπορεί να έχει μια σταθερή τιμή ή μια μεταβλητή ή και μια έκφραση, αλλά πάντα ακέραιη και θετική.
Ακολουθούν παραδείγματα :
READ(10, 100, REC=25) A, B
READ(10, *, REC=I) A
Η Εντολή Εξόδου για Σειριακά Αρχεία
Η εντολή εξόδου δεδομένων που χρησιμοποιεί η Fortran για σειριακά αρχεία έχει την εξής γενική μορφή :
WRITE([UNIT=] u, [FMT=] f [, ERR=er][, IOSTAT=int] [, ADVANCE=C-expr]) list
Οι παράμετροι που χρησιμοποιούντα είναι ίδιες μ’ αυτές της εντολής εισόδου, ενώ οι παράμετροι END και EOR δεν έχουν νόημα εδώ.
Ακολουθούν παραδείγματα :
WRITE(UNIT=10, FMT=30, ERR=200, IOSTAT=I) A, B
WRITE(10, 30) A
Η Εντολή Εξόδου για Αρχεία Άμεσης Προσπέλασης
Η γενική μορφή της εντολής εξόδου για τα αρχεία άμεσης προσπέλασης είναι η εξής :
WRITE([UNIT=]u,[FMT=]f[, ERR=er][, IOSTAT=int], REC=rc) list
Η παράμετρος REC=rc είναι ο αύξων αριθμός της εγγραφής μέσα το αρχείο. Η rc μπορεί να έχει μια σταθερή τιμή ή μια μεταβλητή ή και μια έκφραση, αλλά πάντα ακέραιη και θετική. Ακολουθούν παραδείγματα :
WRITE(11, 80, ERR=100, REC=32) A, B
READ(*, *) A
WRITE(20, *, ERR=90, REC=I) A
I = I + 1
Με την εντολή OPEN μπορούμε να ανοίξουμε ένα αρχείο για επεξεργασία (διάβασμα ή εγγραφή δεδομένων) και να το συνδέσουμε μ’ έναν ακέραιο αριθμό μονάδας.
Η γενική μορφή της εντολής OPEN είναι η εξής :
OPEN([UNIT=]u[,ACCESS=acc][,BLANK=bl][,ERR=er] [,FILE=fi][,FORM=fo][,IOSTAT=int][,RECL=rl][,STATUS=st])
Όπου οι παράμετροι σημαίνουν τα εξής :
UNIT=u, καθορίζει τον κωδικό αριθμό που συνδέεται με το αρχείο και μπορεί να είναι μια ακέραιη σταθερά ή μια ακέραιη μεταβλητή ή και μια ακέραιη έκφραση. Συνήθως ο αριθμός 5 αναφέρεται στο πληκτρολόγιο για είσοδο δεδομένων και ο αριθμός 6 στην οθόνη για έξοδο δεδομένων, ενώ τα * και 0 είναι προκαθορισμένες επιλογές για το πληκτρολόγιο σαν μονάδα εισόδου και για την οθόνη σαν μονάδα εξόδου.
ACCESS=acc, το acc είναι μια αλφαριθμητική μεταβλητή που μπορεί να πάρει μια από τις τιμές ‘DIRECT’ ή SEQUENTIAL’ (προκαθορισμένη), για να καθορίσουμε ότι το αρχείο είναι άμεσης ή σειριακής προσπέλασης αντίστοιχα.
BLANK=bl, το bl είναι μια αλφαριθμητική μεταβλητή που καθορίζει αν τα κενά διαστήματα σ’ ένα αριθμητικό πεδίο θα ληφθούν ως μηδενικά ή θα αγνοηθούν όταν θα διαβασθούν από μια εντολή εισόδου. Αν η μεταβλητή bl έχει την τιμή ‘NULL’ (προκαθορισμένη), τα κενά θα αγνοηθούν, ενώ αν έχει την τιμή ‘ZERO’, τα κενά θα ληφθούν ως μηδενικά.
ERR=er, καθορίζει τον αριθμό μιας εκτελέσιμης εντολής του προγράμματος στην οποία θα μεταφερθεί ο έλεγχος αν συμβεί κάποιο λάθος εισόδου/εξόδου κατά την εκτέλεση του προγράμματος.
FILE=fi, το fi είναι μια αλφαριθμητική έκφραση (σταθερά ή μεταβλητή) που καθορίζει το όνομα του αρχείου που συνδέεται με τη μονάδα που καθορίζει ο αριθμός u. Μπορεί να αποτελείται από 7 το πολύ χαρακτήρες με τον πρώτο χαρακτήρα οπωσδήποτε αλφαβητικό. Αν δεν προσδιορίσουμε όνομα αρχείου με την παράμετρο αυτή, τότε θα δημιουργηθεί ένα προσωρινό αρχείο που θα χαθεί με το κλείσιμο του αρχείου και η παράμετρος STATUS θα λάβει την τιμή SCRATCH.
FORM=fo, το fo είναι μια αλφαριθμητική μεταβλητή που μπορεί να πάρει μια από τις τιμές ‘FORMATTED’ (προκαθορισμένη για τα σειριακά αρχεία) ή ‘UNFORMATTED’ (προκαθορισμένη για τα αρχεία άμεσης προσπέλασης) ανάλογα με το αν οι εντολές εισόδου/εξόδου που αναφέρονται στο αρχείο είναι με FORMAT (και ελεύθερο FORMAT) ή όχι.
IOSTAT=int, το int είναι μια ακέραιη μεταβλητή που παίρνει αρνητική τιμή αν συμβεί κάποιο λάθος τύπου end-of-file κατά το άνοιγμα του αρχείου ή μηδενική τιμή αν δεν συμβεί κανένα λάθος ή θετική τιμή αν συμβεί κάποιο άλλο λάθος.
RECL=rl, το rl είναι μια ακέραιη θετική αριθμητική έκφραση (σταθερά ή μεταβλητή) που είναι υποχρεωτική στα αρχεία άμεσης προσπέλασης και που καθορίζει το μήκος σε bytes της κάθε εγγραφής (record).
STATUS=st, το fi είναι μια αλφαριθμητική έκφραση (σταθερά ή μεταβλητή) που καθορίζει το status (κατάσταση) του αρχείου και μπορεί να πάρει τις εξής τιμές :
‘NEW’, αρχείο που δημιουργείται για πρώτη φορά.
‘OLD’, αρχείο που υπάρχει ήδη.
‘SCRATCH’, αρχείο που είναι προσωρινό και που δημιουργείται και χρησιμοποιείται μόνο κατά τη διάρκεια της εκτέλεσης του προγράμματος και μετά διαγράφεται.
‘UNKNOWN’, είναι η προκαθορισμένη τιμή και αναφέρεται σ’ ένα αρχείο η κατάσταση του οποίου είναι άγνωστη στο πρόγραμμα.
Ακολουθούν παραδείγματα :
OPEN(UNIT=10, FILE=’DATA01’, ACCESS=’SEQUENTIAL’,
BLANK=’NULL’, ERR=100, FORM=’FORMATTED’,
IOSTAT=I, STATUS=’UNKNOWN’)
OPEN(20, ACCESS=’DIRECT’, STATUS=’NEW’, RECL=70)
Τα αρχεία που έχουμε ανοίξει με την εντολή OPEN, θα κλείσουν αυτόματα με το τέλος της εκτέλεσης του προγράμματος. Αν, όμως, θέλουμε να κλείσουμε κάποιο ανοικτό αρχείο κατά τη διάρκεια της εκτέλεσης του προγράμματος, θα πρέπει να χρησιμοποιήσουμε την εντολή CLOSE, η οποία έχει την εξής σύνταξη :
CLOSE([UNIT=]u[,ERR=er][,IOSTAT=int][,STATUS=st])
Όπου οι παράμετροι σημαίνουν τα εξής :
UNIT=u, καθορίζει τον κωδικό αριθμό μονάδας που χρησιμοποιήσαμε κατά το άνοιγμα του αρχείου.
ERR=er, καθορίζει τον αριθμό μιας εκτελέσιμης εντολής του προγράμματος στην οποία θα μεταφερθεί ο έλεγχος αν συμβεί κάποιο λάθος εισόδου/εξόδου κατά την εκτέλεση του προγράμματος.
IOSTAT=int, το int είναι μια ακέραιη μεταβλητή που παίρνει αρνητική τιμή αν συμβεί κάποιο λάθος τύπου end-of-file κατά το κλείσιμο του αρχείου ή μηδενική τιμή αν δεν συμβεί κανένα λάθος ή θετική τιμή αν συμβεί κάποιο άλλο λάθος.
STATUS=st, το fi είναι μια αλφαριθμητική έκφραση (σταθερά ή μεταβλητή) που παίρνει μια από τις τιμές ‘KEEP’ (προκαθορισμένη) ή ‘DELETE’ ανάλογα με το αν το αρχείο πρέπει να διατηρηθεί στο τέλος του προγράμματος ή να διαγραφεί.
Ακολουθούν παραδείγματα :
CLOSE(10)
CLOSE(20, ERR=100)
CLOSE(10, ERR=200, IOSTAT=I, STATUS=’DELETE’)
Με την εντολή REWIND επαναφέρουμε την κεφαλή του δίσκου στην πρώτη εγγραφή ενός σειριακού αρχείου και έχει την εξής σύνταξη :
REWIND([UNIT=]u[, ERR=er][, IOSTAT=int])
Ακολουθούν παραδείγματα :
REWIND(10)
REWIND 20
REWIND A
REWIND(20, ERR=100)
REWIND(UNIT=10, ERR=200, IOSTAT=I)
Με την εντολή BACKSPACE επαναφέρουμε την κεφαλή του δίσκου στην προηγούμενη εγγραφή ενός σειριακού αρχείου και έχει την εξής σύνταξη :
BACKSPACE([UNIT=]u[, ERR=er][, IOSTAT=int])
Ακολουθούν παραδείγματα :
BACKSPACE(10)
BACKSPACE 20
BACKSPACE A
BACKSPACE(20, ERR=100)
BACKSPACE(UNIT=10, ERR=200, IOSTAT=I)
Όπως ήδη γνωρίζουμε, όταν τελειώνει η προσπέλαση σε κάποιο αρχείο, το πρόγραμμα τοποθετεί στο τέλος του αρχείου μια ειδική εγγραφή (end-of-file), η οποία δηλώνει το τέλος του αρχείου. Για να τοποθετήσουμε εμείς μια τέτοια εγγραφή και όχι αυτόματα το πρόγραμμα, πρέπει να χρησιμοποιήσουμε την εντολή ENDFILE, η οποία έχει την εξής σύνταξη :
ENDFILE([UNIT=]u[, ERR=er][, IOSTAT=int])
Ακολουθούν παραδείγματα :
ENDFILE(10)
ENDFILE 20
ENDFILE A
ENDFILE (20, ERR=100)
ENDFILE (UNIT=10, ERR=200, IOSTAT=I)
Η εντολή GO TO είναι η πρώτη από τις εντολές ελέγχου (control statements) που θα μελετήσουμε και η μορφή της εντολής χωρίς όρους (unconditional) μεταφέρει τον έλεγχο (τη ροή) του προγράμματος σε μια συγκεκριμένη εντολή. Η σύνταξή της είναι ως εξής :
GO TO n
όπου το n είναι ο αριθμός μιας άλλης εντολής του προγράμματος.
Ακολουθεί ένα παράδειγμα χρήσης της εντολής :
! Η ΕΝΤΟΛΗ GO TO ΧΩΡΙΣ ΟΡΟΥΣ
I = 1
SUM = 0
10 SUM = SUM + A
I = I + 1
IF (I > 100) GO TO 20
GO TO 10
20 PRINT *, ‘ΑΘΡΟΙΣΜΑ=’, SUM
STOP
END
Η εντολή αυτή (computed GO TO), όπως και η προηγούμενη, είναι απομεινάρια από τις παλιές εκδόσεις της Fortran και εξακολουθούν να ισχύουν και να χρησιμοποιούνται ακόμα αν και η χρήση τους έχει ατονήσει με τις νέες σύγχρονες τεχνικές των νεώτερων εκδόσεων της Fortran, η οποία συμπορεύεται πλέον με τις άλλες, δομημένες γλώσσες προγραμματισμού.
Η σύνταξή της είναι ως εξής :
GO TO (n1, n2, …, nm)[,]I
όπου τα n1, n2, … και nm είναι αριθμοί εντολών του προγράμματος και το Ι είναι μια ακέραιη σταθερή ή μεταβλητή με τιμές 1, 2, …, m, ώστε ανάλογα με την τιμή της να εκτελεσθεί αμέσως μετά η αντίστοιχη εντολή n1, n2, …, nm. Αν η τιμή του Ι είναι μεγαλύτερη από το m ή μικρότερη από το 1, τότε θα εκτελεσθεί η εντολή που ακολουθεί την GO TO.
Ακολουθεί ένα παράδειγμα χρήσης της εντολής :
A1 = 10
A2 = 20
GO TO (10, 20, 30, 40) I
10 S = A1 + A2
GO TO 50
20 S = A1 – A2
GO TO 50
30 S = A1 * A2
GO TO 50
40 S = A1 / A2
50 …
Η προηγούμενη εντολή θεωρείται κάπως ξεπερασμένη και στη θέση της χρησιμοποιείται πλέον η δομή CASE, η οποία έχει την εξής σύνταξη :
[name:] SELECT CASE (expr)
CASE (A1 [, A2] … ])[name]
Block εντολών1
CASE (B1 [, B2] … ])[name]
Block εντολών2
…
[CASE DEFAULT [name]
Block εντολών3]
END SELECT [name]
Όπου έχουμε τα εξής :
name, είναι το όνομα που δίνουμε στη δομή.
expr, είναι μια έκφραση που μπορεί να πάρει ακέραιη, λογική ή αλφαριθμητική τιμή.
A1, A2, … B1, B2, …, είναι ακέραιες, λογικές ή αλφαριθμητικές τιμές, που συσχετίζονται με την έκφραση expr.
Η δομή δουλεύει ως εξής : αν η τιμή της έκφρασης expr είναι μεταξύ των τιμών Α1, Α2 κοκ, θα εκτελεσθεί το block εντολών1, αν η τιμή της έκφρασης expr είναι μεταξύ των τιμών Β1, Β2 κοκ, θα εκτελεσθεί το block εντολών2, ενώ αν η τιμή της έκφρασης expr δεν βρεθεί πουθενά ανάμεσα στις προαναφερόμενες τιμές, τότε θα εκτελεσθεί το block εντολών3.
Οι εκφράσεις που μπορούμε να χρησιμοποιήσουμε μέσα σε μια εντολή CASE είναι οι εξής :
CASE(1,4,6:8,10), καλύπτει τις τιμές 1, 4, 6, 7, 8 και 10.
CASE(:–2), καλύπτει όλες τις τιμές που είναι μικρότερες από –2.
CASE(4), καλύπτει μόνο την τιμή 4.
CASE(2:), καλύπτει όλες τις τιμές που είναι μεγαλύτερες από 2.
Ακολουθούν παραδείγματα :
NAME1: SELECT CASE(I)
CASE(:– 4)
A=1
CASE(2)
A=2
CASE(–2:3)
A=3
CASE DEFAULT
A=4
END SELECT NAME1
Το παρακάτω παράδειγμα υπολογίζει τις ημέρες ενός μήνα αν δώσουμε σαν δεδομένα την αρίθμηση του μήνα στην αριθμητική μεταβλητή MONTH καθώς και το αν το έτος είναι δίσεκτο ή όχι στη λογική μεταβλητή DISEKTO.
SELECT CASE(MONTH)
CASE(4, 6, 9, 11)
IMERES=30
CASE(1, 3, 5, 7:8, 10, 12)
IMERES=31
CASE(2)
SELECT CASE(DISEKTO)
CASE(.TRUE.)
IMERES=29
CASE(.FALSE.)
IMERES=28
END SELECT
END SELECT
Παρατηρούμε ότι έχουμε μια δομή CASE ένθετη μέσα σε μια άλλη δομή CASE καθώς και το ότι δεν χρησιμοποιήσαμε ονόματα για τις δομές.
Η εντολή ASSIGN ανήκει στις παλιές εντολές της Fortran και τελεί υπό κατάργηση στις καινούργιες εκδόσεις της γλώσσας. Μας δίνει τη δυνατότητα να αντιστοιχίσουμε μια ακέραιη μεταβλητή με τον αριθμό κάποιας εντολής του προγράμματος ή τον αριθμό κάποιας εντολής FORMAT.
Η σύνταξή της είναι ως εξής :
ASSIGN αριθμός_εντολής TO ακέραιη_μεταβλητή
Για παράδειγμα, με την εντολή :
ASSIGN 100 TO I
η ακέραιη μεταβλητή I έχει τιμή 100 και μέσα στο πρόγραμμα θα πρέπει να υπάρχει κάποια εντολή με αριθμό 100. Την μεταβλητή I δεν θα μπορούμε να την χρησιμοποιήσουμε σε μια εντολή αντικατάστασης.
Ακολουθεί ένα παράδειγμα :
…
ASSIGN 10 TO I
IF (K==1) GO TO I
…
10 WRITE(*, *) ‘…’
…
20 WRITE(*, *) ‘…’
STOP
END
Η γενική μορφή της εντολής IF είναι η εξής :
IF(λογική_έκφραση) εκτελέσιμη_εντολή
Η εκτελέσιμη_εντολή δεν πρέπει να είναι μια εντολή DO ή ένα άλλο λογικό IF.
Ακολουθούν μερικά χαρακτηριστικά παραδείγματα :
IF(A>B) GO TO 100
IF(C<D) DA = B * 10
IF(X>0.) S = S + BATHMOS
IF(A==B) GO TO 200
IF(X/=Y) GO TO 300
IF(A<=B) WRITE(6, 10) A
Οι τελεστές σύγκρισης των εκδόσεων 77 και 90 της Fortran είναι οι εξής :
Fortran 77 |
Fortran 90 |
Ερμηνεία |
.GT. |
> |
Μεγαλύτερο |
.LT. |
< |
Μικρότερο |
.GE. |
>= |
Μεγαλύτερο ή ίσο |
.EQ. |
== |
Ίσο |
.NE. |
/= |
Όχι ίσο |
.LE. |
<= |
Μικρότερο ή ίσο |
Η Fortran χρησιμοποιεί και τους τρεις γνωστούς λογικούς τελεστές .AND., .OR. και .NOT.
Ακολουθούν παραδείγματα :
IF(A>B .AND. A>C) GO TO 100
IF(I==1 .OR. J<10) GO TO 200
IF(.NOT.(A>B)) A = A + 1
Και η εντολή αυτή αποτελεί μια ανάμνηση από τις παλιές εκδόσεις της Fortran και τελεί υπό κατάργηση. Η γενική μορφή της είναι η εξής :
IF(αριθμητική_έκφραση) εντολή1, εντολή2, εντολή3
Η εντολή δουλεύει ως εξής : αν το αποτέλεσμα της αριθμητικής_έκφρασης είναι αρνητικό θα εκτελεσθεί η εντολή1, αν είναι μηδέν θα εκτελεσθεί η εντολή2 και αν είναι θετικό θα εκτελεσθεί η εντολή3.
Ακολουθούν παραδείγματα :
IF(X) 10, 20, 30
IF(A–B) 15, 15, 25
SUM = 0
10 READ(%, *) X
IF(X) 10, 30, 20
20 SUM = SUM + X**2
GO TO 10
30 WRITE(6, *) SUM
END
Η Εντολή IF-THEN-ELSE
Η εντολή IF που είδαμε σε προηγούμενη παράγραφο αποτελεί την πιο απλή μορφή της δημοφιλούς αυτής εντολής. Έχει το βασικό μειονέκτημα ότι μας επιτρέπει να εκτελέσουμε μία μόνο εντολή αν κάποια λογική έκφραση είναι αληθής (TRUE).
Για να μπορέσουμε να εκτελέσουμε περισσότερες από μία εντολές ανάλογα με το αποτέλεσμα μιας λογικής έκφρασης, μπορούμε να χρησιμοποιήσουμε την εξής μορφή της εντολής IF :
IF (λογική_έκφραση) THEN
… εντολές …
ENDIF
Αν η λογική_έκφραση είναι αληθής (TRUE) θα εκτελεσθούν οι εντολές που βρίσκονται μέσα στο μπλοκ IF … ENDIF, ενώ αν η λογική_έκφραση είναι ψευδής (FALSE) ο έλεγχος θα μεταφερθεί στην εντολή που βρίσκεται αμέσως μετά την εντολή ENDIF.
Ακολουθεί ένα παράδειγμα :
IF(A>B) THEN
SUM = SUM + A
P = P * B
ENDIF
Μπορούμε να έχουμε και ένθεση των εντολών IF, ως εξής :
IF(A>10) THEN
IF(A>20) THEN
SUM = SUM + A
P = P * A
ENDIF
IF(A==20) THEN
…
ENDIF
IF(A<20) THEN
…
ENDIF
ENDIF
Μπορούμε να βγούμε από την περιοχή των εντολών ενός IF πριν να εκτελεσθούν όλες οι εντολές του, με χρήση της εντολής GO TO, αλλά μπορούμε να στείλουμε τον έλεγχο του προγράμματος μόνο στην πρώτη εντολή του IF.
Ακολουθεί ένα παράδειγμα :
10 IF(A>B) THEN
READ(6, *) C
IF(C<0) GO TO 50
F = SQRT(C)
ENDIF
…
50 …
…
GO TO 10
Για να μπορέσουμε να εκτελέσουμε κάποιες εντολές αν το αποτέλεσμα μιας λογικής έκφρασης είναι αληθές (TRUE) και κάποιες άλλες εντολές αν το αποτέλεσμα της ίδιας λογικής έκφρασης είναι ψευδές (FALSE), μπορούμε να χρησιμοποιήσουμε και την εντολή ELSE, ως εξής :
IF (λογική_έκφραση) THEN
… εντολές αν η λογική_έκφραση είναι TRUE …
… εντολές αν η λογική_έκφραση είναι FALSE …
ENDIF
Αν η λογική_έκφραση είναι αληθής (TRUE) θα εκτελεσθούν οι εντολές που βρίσκονται αμέσως μετά την εντολή IF … THEN, ενώ αν η λογική_έκφραση είναι ψευδής (FALSE) θα εκτελεσθούν οι εντολές που βρίσκονται αμέσως μετά την εντολή ELSE.
Ακολουθεί ένα παράδειγμα :
IF(A>0) THEN
SUM = SUM + A
ELSE
P = P * A
Υπάρχει η δυνατότητα να χρησιμοποιήσουμε και την εντολή ELSEIF για επιπλέον επιλογές, ως εξής :
IF (λογική_έκφραση1) THEN
… εντολές αν η λογική_έκφραση1 είναι TRUE …
… εντολές αν η λογική_έκφραση1 είναι FALSE
και η λογική_έκφραση2 είναι TRUE …
… εντολές αν η λογική_έκφραση1 και η λογική_έκφραση2
είναι FALSE …
ENDIF
Η εντολή END αποτελεί την τελευταία εντολή κάθε προγράμματος και τερματίζει την εκτέλεσή του. Αν χρησιμοποιηθεί στα υποπρογράμματα θα έχει το ίδιο αποτέλεσμα με την εντολή RETURN. Είναι καλό, αν και είναι προαιρετικό, να γράφουμε τη δεσμευμένη λέξη PROGRAM και το όνομα του προγράμματος μετά από την εντολή END.
Η σύνταξη της εντολής END είναι η εξής :
END [PROGRAM [όνομα_προγράμματος]]
END [FUNCTION [όνομα_υποπρογράμματος]]
END [SUBROUTINE [όνομα_υποπρογράμματος]]
END [MODULE [όνομα_MODULE]]
END [BLOCK DATA [όνομα_BLOCK DATA]]
Ενώ χρησιμοποιούμε μία φορά την εντολή END για να τερματίσουμε ένα πρόγραμμα όταν αυτό φθάσει στο τέλος του, μπορούμε να χρησιμοποιήσουμε πολλές φορές μέσα σ’ ένα πρόγραμμα την εντολή STOP για να διακόψουμε εσκεμμένα την εκτέλεση ενός προγράμματος, εμφανίζοντας ταυτόχρονα κι ένα προαιρετικό μήνυμα.
Η σύνταξη της εντολής STOP είναι η εξής :
STOP [μήνυμα] | [ακέραιη_τιμή]
Το μήνυμα είναι μια αλφαριθμητική σταθερά και η ακέραια τιμή είναι ένας ακέραιος αριθμός μεγαλύτερος του 0. Το μήνυμα χρησιμοποιείται για να μπορέσουμε να καταλάβουμε σε ποιο σημείο του προγράμματος διακόπηκε η εκτέλεσή του και να μπορέσουμε έτσι να διερευνήσουμε τι δεν πήγε καλά.
Ακολουθούν παραδείγματα :
READ(*, *) A
IF(A<0) STOP ‘ΟΧΙ ΑΡΝΗΤΙΚΕΣ ΤΙΜΕΣ’
C = SQRT(A)
IF(C==2) STOP ‘ΟΧΙ ΤΟΣΟ ΕΥΚΟΛΕΣ ΤΙΜΕΣ’
STOP ‘ΕΔΩ ΤΕΛΕΙΩΝΕΙ ΚΑΝΟΝΙΚΑ ΤΟ ΠΡΟΓΡΑΜΜΑ’
END
Είναι από τις παλιές εντολές της Fortran που τελούν υπό κατάργηση. Σ’ αντίθεση με την εντολή STOP, η οποία προκαλεί τερματισμό της εκτέλεσης του προγράμματος, η εντολή PAUSE προκαλεί μια προσωρινή διακοπή, εμφανίζει ένα προαιρετικό μήνυμα και περιμένει μια ενέργεια του χρήστη για να συνεχίσει την εκτέλεση του προγράμματος.
Η σύνταξη της εντολής PAUSE είναι η εξής :
PAUSE [μήνυμα] | [ακέραιη_τιμή]
Το μήνυμα είναι μια αλφαριθμητική σταθερά και η ακέραια τιμή είναι ένας ακέραιος αριθμός μεγαλύτερος του 0. Το μήνυμα χρησιμοποιείται για να κάνει κάποια απαραίτητη ενέργεια ο χρήστης πριν συνεχισθεί η εκτέλεση του προγράμματος. Συνήθως πρέπει να πατήσουμε το πλήκτρο enter για να συνεχισθεί η εκτέλεση του προγράμματος.
Ακολουθούν παραδείγματα :
PAUSE
PAUSE ‘ΠΡΕΠΕΙ ΝΑ ΑΛΛΑΞΕΤΕ ΧΑΡΤΙ ΣΤΟΝ ΕΚΤΥΠΩΤΗ’
PAUSE ‘ΤΟΠΟΘΕΤΗΣΤΕ ΜΙΑ ΔΙΣΚΕΤΑ ΣΤΟ DRIVE’
Η εντολή DO της Fortran αποτελεί την αντίστοιχη πολύ δημοφιλή εντολή FOR, γνωστή από άλλες γλώσσες προγραμματισμού.
Η σύνταξη της εντολής είναι ως εξής :
[ΟΝΟΜΑ:] DO [n][,][var=start, stop, inc]
… εντολές …
END DO
Όπου έχουμε τα εξής :
ONOMA, είναι το προαιρετικό όνομα που μπορούμε να δώσουμε σ’ έναν βρόχο DO.
n, είναι αριθμός εντολής του προγράμματος.
var, είναι το όνομα μιας μεταβλητής, συνήθως ακέραιης.
start, είναι μια αριθμητική έκφραση που δηλώνει την αρχική τιμή της μεταβλητής var.
stop, είναι μια αριθμητική έκφραση που δηλώνει την τελική τιμή της μεταβλητής var.
inc, είναι μια αριθμητική έκφραση που δηλώνει την τιμή της μεταβολής της μεταβλητής var και όταν δεν υπάρχει θεωρείται ότι είναι ίση με 1.
Η εντολή n αποκαλείται τελική εντολή, η μεταβλητή var αποκαλείται δείκτης της DO, η start αποκαλείται αρχική τιμή, η stop αποκαλείται τελική τιμή και η inc αποκαλείται βήμα ή αύξηση.
Ο βρόχος της εντολής DO τελειώνει με την εντολή END DO, αλλά αν στην εντολή DO υπάρχει ο αριθμός μιας εντολής n, τότε η τελευταία εντολή του βρόχου θα πρέπει να έχει τον αριθμό n ή να είναι μια εντολή CONTINUE με τον αριθμό n. Αν στην εντολή DO έχουμε δώσει και όνομα, τότε το ίδιο όνομα θα πρέπει να υπάρχει και στην εντολή END DO.
Συνεπώς, οι μορφές που μπορεί να πάρει η εντολή DO είναι οι εξής τρεις :
[ΟΝΟΜΑ:] DO var=start, stop, inc
… εντολές …
END DO [ONOMA]
ή
[ΟΝΟΜΑ:] DO
… εντολές …
END DO [ONOMA]
ή
DO n var=start, stop, inc
… εντολές …
n τελική_εντολή
ή
n CONTINUE
Αναφορικά με την πρώτη μορφή της εντολής DO, η όλη διαδικασία θυμίζει πολύ την γνωστή εντολή FOR από άλλες γλώσσες προγραμματισμού. Δηλαδή, η μεταβλητή var ξεκινά με την τιμή start και εκτελούνται όλες οι εντολές που βρίσκονται ανάμεσα στις εντολές DO και END DO.
Μετά, η μεταβλητή var αυξάνεται κατά την τιμή της inc και εκτελούνται ξανά οι ίδιες εντολές κοκ. Μόλις η τιμή της var ξεπεράσει την τιμή της stop, η εκτέλεση του προγράμματος συνεχίζεται με την εντολή που βρίσκεται αμέσως μετά την εντολή END DO.
Όταν το βήμα έχει την τιμή 1 και η var είναι ακέραιη μεταβλητή, τότε μπορεί να παραληφθεί.
Ακολουθούν παραδείγματα :
DO I=1, 100, 1
DO I=6, 80, 2
DO I=3.1, 97.3, 0.6
DO J=–10, 60, 2
DO J=100, 10, –2
SUM = 0
DO I=1, 100, 1
SUM = SUM + I
END DO
ή
SUM = 0
P1:DO I=1, 100, 1
SUM = SUM + I
END DO P1
Σύμφωνα με τη δεύτερη μορφή της εντολής DO, οι εντολές του βρόχου εκτελούνται συνέχεια μέχρι κάποια εντολή του βρόχου να στείλει τη ροή του προγράμματος έξω από τον βρόχο.
Ακολουθεί ένα παράδειγμα :
I = 1
SUM = 0
DO
SUM = SUM + I
IF(SUM>1000) THEN
WRITE(*, *) ‘I = ‘, I
STOP
END IF
I = I + 1
END DO
Χρήσιμες στη δεύτερη μορφή της εντολής DO είναι οι εντολές EXIT και CYCLE. Η πρώτη προκαλεί έξοδο από τον βρόχο, ενώ η δεύτερη στέλνει τη ροή του προγράμματος στην αρχή του βρόχου.
Αν η εντολή EXIT ακολουθείται από το όνομα ενός βρόχου DO, τότε προκαλείται έξοδος από τον βρόχο αυτό και απ’ όλους τους βρόχους που περιέχει.
Η εντολή CYCLE διακόπτει την τρέχουσα επανάληψη του βρόχου, η μεταβλητή var αυξάνει σύμφωνα με το βήμα και ξεκινάει μια καινούργια επανάληψη. Αν η εντολή CYCLE ακολουθείται από το όνομα ενός βρόχου DO, τότε προκαλείται έξοδος απ’ όλους τους βρόχους που περιέχει ο τρέχον βρόχος και η ροή του προγράμματος πηγαίνει στον βρόχο που έχουμε καθορίσει με το όνομά του.
Ακολουθούν παραδείγματα :
LOOP1:DO I=1, 50
A=A+2
IF(A>20) EXIT LOOP1
END DO LOOP1
SUM = 0
M = 0
DO
READ(*, *) A
IF(A<0) EXIT
SUM = SUM + A
M= M + 1
END DO
WRITE(*, *) SUM/M
I = 0
DO
READ(*, *) A
IF(A<0) THEN
EXIT
ELSEIF(MOD(A, 2)==1) THEN
CYCLE
ELSE
I = I + 1
END IF
END DO
WRITE(*, *) ‘ΠΛΗΘΟΣ ΑΡΤΙΩΝ ΑΡΙΘΜΩΝ : ‘, I
Η τρίτη μορφή της εντολής DO τελεί υπό κατάργηση αλλά γίνεται ακόμα αποδεκτή. Χαρακτηριστικό παράδειγμα είναι το εξής :
DO 10 I=1, 10
K = I * I
10 WRITE(*, *) I, K
Σαν τελευταία εντολή ενός DO μπορούμε να χρησιμοποιήσουμε και την εντολή CONTINUE, ως εξής :
DO 10 I=1, 10
…
DO 10 J=I, 20
…
10 CONTINUE
ή και ως εξής :
DO 10 I=1, 10
…
DO 20 J=I, 20
…
20 CONTINUE
…
10 CONTINUE
Με την εντολή FORMAT μπορούμε να ορίσουμε με ακρίβεια τη μορφή των δεδομένων του προγράμματος για είσοδο αλλά και για έξοδο.
Η γενική μορφή της εντολής είναι η εξής :
f FORMAT(K1, K2, … Km)
όπου f είναι ο αριθμός της εντολής και τα Κ1, Κ2, … Km είναι ειδικές κωδικοποιήσεις της εντολής που θα δούμε αναλυτικά παρακάτω.
Μια εντολή FORMAT δεν είναι εκτελέσιμη εντολή και έτσι δεν έχει καμία σημασία σε ποια θέση θα την τοποθετήσουμε στο πρόγραμμα. Το πιο σωστό είναι να την τοποθετούμε μετά από την αντίστοιχη εντολή εισόδου ή εξόδου που αναφέρεται σ’ αυτήν αλλά μπορούμε και να τοποθετήσουμε όλες μαζί τις εντολές FORMAT ενός προγράμματος στην αρχή ή και στο τέλος του προγράμματος.
Πρέπει να έχουμε υπόψη μας ότι αν χρησιμοποιήσουμε μια εντολή FORMAT για να στείλουμε αποτελέσματα στον εκτυπωτή, τότε ο πρώτος χαρακτήρας θεωρείται χαρακτήρας ελέγχου και δεν εκτυπώνεται αλλά χρησιμοποιείται ως εξής :
‘ ‘, ορίζει ότι η εκτύπωση θα γίνει από την αρχή της επόμενης γραμμής.
‘0’, ορίζει ότι η εκτύπωση θα γίνει από την αρχή της επόμενης γραμμής αφού αφήσει μια κενή γραμμή.
‘1’, ορίζει ότι η εκτύπωση θα γίνει από την αρχή της επόμενης σελίδας.
‘+’, ορίζει ότι η εκτύπωση θα γίνει πάνω στην ήδη υπάρχουσα γραμμή.
Η Εντολή FORMAT με Πραγματικούς Αριθμούς
Για τη μορφοποίηση της εισόδου και της εξόδου των πραγματικών αριθμών με την εντολή FORMAT χρησιμοποιούμε τους κώδικες F και E.
Η σύνταξη του κώδικα F είναι η εξής :
Fw.d
όπου το w είναι ένας ακέραιος αριθμός που καθορίζει το συνολικό πλάτος του πεδίου, δηλ. το πλήθος των ψηφίων συν την υποδιαστολή, και το d είναι ένας ακέραιος αριθμός που καθορίζει το πλήθος των δεκαδικών ψηφίων του αριθμού.
Ακολουθούν παραδείγματα :
READ(5, 10) A1, A2, A3
10 FORMAT(F8.3, F7.4, F10.2)
WRITE(6, 20) A1, A2, A3
20 FORMAT(F10.4, F8.3, F5.2)
Ο κώδικας Ε χρησιμοποιείται για την είσοδο και έξοδο πραγματικών αριθμών σε εκθετική μορφή και η σύνταξή του είναι ως εξής :
Ew.d[Ee]
όπου το w είναι ένας ακέραιος αριθμός που καθορίζει το συνολικό πλάτος του πεδίου, δηλ. το πλήθος των ψηφίων συν την υποδιαστολή, και το d είναι ένας ακέραιος αριθμός που καθορίζει το πλήθος των δεκαδικών ψηφίων του αριθμού.
Το e που υπάρχει μέσα στην αγκύλη είναι προαιρετικό και καθορίζει μόνο κατά την έξοδο το πλήθος των ψηφίων του εκθετικού μέρους του αριθμού.
Ακολουθεί ένα παράδειγμα :
WRITE(6, 30) A1, A2, A3
30 FORMAT(Ε13.4E3, Ε11.3, Ε12.2)
Η Εντολή FORMAT με Ακέραιους Αριθμούς
Για τη μορφοποίηση της εισόδου και της εξόδου των ακέραιων αριθμών με την εντολή FORMAT χρησιμοποιούμε τον κώδικα Ι, με την εξής σύνταξη :
Iw[.m]
όπου το w είναι ένας ακέραιος αριθμός που καθορίζει το πλάτος του πεδίου και το m είναι ένας ακέραιος αριθμός που είναι προαιρετικός και καθορίζει μόνο κατά την έξοδο το μέγιστο πλήθος των μηδενικών μπροστά από τον αριθμό, αν χρειαστεί φυσικά να εμφανιστούν μηδενικά.
Ακολουθούν παραδείγματα :
READ(5, 10) I1, I2, I3
10 FORMAT(I8, I7, I5)
WRITE(6, 20) I1, I2, I3
20 FORMAT(I5, I6, I8.3)
Η Εντολή FORMAT με Αριθμούς Διπλής Ακρίβειας
Για τη μορφοποίηση της εισόδου και της εξόδου των αριθμών διπλής ακρίβειας με την εντολή FORMAT χρησιμοποιούμε τον κώδικα D, με την εξής σύνταξη :
Dw.d
όπου το w είναι ένας ακέραιος αριθμός που καθορίζει το συνολικό πλάτος του πεδίου και το d είναι ένας ακέραιος αριθμός που καθορίζει τον αριθμό των δεκαδικών ψηφίων του αριθμού.
Ακολουθεί ένα παράδειγμα :
WRITE(6, 30) A1, A2, A3
30 FORMAT(D13.4, D11.3, D12.2)
Η Εντολή FORMAT με Λογικές Τιμές
Για τη μορφοποίηση της εισόδου και της εξόδου των τιμών των λογικών μεταβλητών με την εντολή FORMAT χρησιμοποιούμε τον κώδικα L, με την εξής σύνταξη :
Lw
όπου το w είναι ένας ακέραιος αριθμός που καθορίζει το συνολικό πλάτος του πεδίου.
Κατά την είσοδο λογικών τιμών θα πρέπει να γράφουμε τα γράμματα T ή F ή ολόκληρα σαν .TRUE. και .FALSE. αντίστοιχα, ενώ κατά την έξοδο εμφανίζεται το γράμμα T ή F στη δεξιότερη θέση του πεδίου και οι υπόλοιπες θέσεις του πεδίου είναι κενές.
Ακολουθούν παραδείγματα :
LOGICAL L1, L2, L3
READ(5, 10) L1, L2, L3
10 FORMAT(L1, L2, L5)
WRITE(6, 20) L1, L2, L3
20 FORMAT(L3, L1, L2)
Η Εντολή FORMAT με Αλφαριθμητικές Τιμές
Για τη μορφοποίηση της εισόδου και της εξόδου των τιμών των αλφαριθμητικών μεταβλητών με την εντολή FORMAT χρησιμοποιούμε τον κώδικα Α, με την εξής σύνταξη :
Αw
όπου το w είναι ένας ακέραιος αριθμός που καθορίζει το συνολικό πλάτος του πεδίου.
Αν οι χαρακτήρες της αλφαριθμητικής μεταβλητής που θα γράψουμε κατά την είσοδο είναι περισσότεροι από το μήκος της αλφαριθμητικής μεταβλητής όπως αυτό έχει ορισθεί με μια εντολή CHARACTER, τότε θα γίνει αποκοπή από τα αριστερά.
Ακολουθεί ένα παράδειγμα :
CHARACTER A*5
READ(5, 10) A
10 FORMAT(A7)
Αν σύμφωνα με τις παραπάνω εντολές γράψουμε το κείμενο ‘FLORINA’, τότε στη μεταβλητή Α θα καταχωρηθούν οι χαρακτήρες ‘ORINA’.
Αν οι χαρακτήρες της αλφαριθμητικής μεταβλητής που θα γράψουμε κατά την είσοδο είναι λιγότεροι από το μήκος της αλφαριθμητικής μεταβλητής όπως αυτό έχει ορισθεί με μια εντολή CHARACTER, τότε θα προστεθούν κενά στα δεξιά της μεταβλητής.
Ακολουθεί ένα παράδειγμα :
CHARACTER A*10
READ(5, 10) A
10 FORMAT(A7)
Αν σύμφωνα με τις παραπάνω εντολές γράψουμε το κείμενο ‘FLORINA’, τότε στη μεταβλητή Α θα καταχωρηθούν οι χαρακτήρες ‘FLORINAbbb’.
Κατά την έξοδο αλφαριθμητικών τιμών, αν το πλάτος του πεδίου είναι μεγαλύτερο από το μήκος της αλφαριθμητικής μεταβλητής, το κείμενο θα εμφανισθεί στοιχισμένο δεξιά μέσα στο οριζόμενο πεδίο, ενώ αν το πλάτος του πεδίου είναι μικρότερο από το μήκος της αλφαριθμητικής μεταβλητής θα αποκοπούν οι δεξιότεροι χαρακτήρες της αλφαριθμητικής μεταβλητής.
Ακολουθεί ένα παράδειγμα :
CHARACTER A*7
A = ‘FLORINA’
WRITE(6, 10) A
10 FORMAT(A5)
Σύμφωνα με τις παραπάνω εντολές, θα εκτυπωθεί το κείμενο ‘FLORI’.
Ο Κώδικας Η της Εντολής FORMAT
Με τον κώδικα Η, που το όνομά του προέρχεται από τον γνωστό κατασκευαστή μηχανών υπολογισμού στα τέλη του 19ου αιώνα Hollerith, μπορούμε να εμφανίσουμε στην έξοδο μαζί με τα αποτελέσματα κάποια επιπλέον δικά μας μηνύματα.
Η μορφή του κώδικα Η είναι η εξής :
nH
όπου n το είναι το πλήθος των χαρακτήρων που θα αποτελούν το μήνυμα.
Ακολουθεί ένα παράδειγμα :
A1 = 10.41
A2 = 5.32
WRITE(6, 10) A1, A2
10 FORMAT(3HA1=, F5.2, 3HA2=, F4.2)
Το αποτέλεσμα θα είναι :
A1=10.41A2=5.32
Μπορούμε αντί να χρησιμοποιούμε τον κώδικα Η και να αναγκαζόμαστε να μετράμε τους χαρακτήρες που θέλουμε να εμφανισθούν στην έξοδο, να χρησιμοποιήσουμε μονές αποστρόφους, ως εξής :
A1 = 10.41
A2 = 5.32
WRITE(6, 10) A1, A2
10 FORMAT(‘ ‘, ‘A1=’, F5.2, ‘A2=’, F4.2)
Το αποτέλεσμα θα είναι :
A1=10.41A2=5.32
WRITE(6, 10)
20 FORMAT(‘ ‘, ‘ ΦΛΩΡΙΝΑ ‘)
Το αποτέλεσμα θα είναι :
‘ ΦΛΩΡΙΝΑ ‘
Ο Κώδικας Χ της Εντολής FORMAT
Με τον κώδικα Χ μπορούμε να πληροφορήσουμε τον Η/Υ κατά τη είσοδο δεδομένων να αγνοήσει κάποιους χαρακτήρες, ενώ κατά την έξοδο να εκτυπώσει κενούς χαρακτήρες.
Η μορφή του κώδικα Χ είναι η εξής :
nΧ
όπου n το είναι το πλήθος των χαρακτήρων που θα αγνοηθούν κατά την είσοδο ή το πλήθος των κενών θέσεων κατά την έξοδο.
Ακολουθούν παραδείγματα :
READ(5, 10) A1, A2
10 FORMAT(F5.2, 5X, F4.2)
WRITE(6, 20) A1, A2
20 FORMAT(3X, F5.2, 5X, F4.2)
Ο Κώδικας / της Εντολής FORMAT
Με τον κώδικα / μπορούμε να διακόψουμε κατά την είσοδο δεδομένων την προσπέλαση σε μια εγγραφή (record) και να πάμε στην επόμενη εγγραφή, ενώ κατά την έξοδο μπορούμε να διακόψουμε το γράψιμο σε μια εγγραφή και να πάμε στην επόμενη εγγραφή.
Η μορφή του κώδικα / είναι η εξής :
n(/) ή //…/
όπου n το είναι το πλήθος των χαρακτήρων /.
Ακολουθούν παραδείγματα :
READ(5, 10) A1, A2
10 FORMAT(F5.2//F4.2)
WRITE(6, 20) A1, A2
20 FORMAT(5X, ‘ΑΠΟΤΕΛΕΣΜΑΤΑ = ‘/3Χ, ‘Α1=’, F5.2/3Χ,’Α2=’, F4.2)
Θα πρέπει να έχουμε υπόψη μας ότι κατά την εκτύπωση των αποτελεσμάτων, το πρώτο κενό από τους χαρακτήρες Χ χρησιμοποιείται σαν χαρακτήρας ελέγχου και έτσι τα κενά που θα εκτυπωθούν με βάση την παραπάνω εντολή θα είναι 4, 2 και 2 και όχι 5, 3 και 3.
Ο Κώδικας \ της Εντολής FORMAT
Με τον κώδικα \ (backslash) μπορούμε να ορίσουμε την παραμονή του δρομέα (cursor) στην ίδια εγγραφή με το τέλος μιας εντολής READ ή WRITE και να μην αλλάζει έτσι εγγραφή.
Ακολουθεί ένα παράδειγμα :
WRITE(*, 10)
READ(*, *) I
10 FORMAT(10X, ‘ΔΩΣΕ ΤΗΝ ΤΙΜΗ ΤΟΥ I : ‘\)
Οι Κώδικες SP, SS και S της Εντολής FORMAT
Οι κώδικες αυτοί χρησιμοποιούνται για να ορίζουμε την εμφάνιση ή όχι του θετικού πρόσημου +, καθώς το αρνητικό πρόσημο – εμφανίζεται έτσι κι αλλιώς πάντοτε.
Ο κώδικας SP ορίζει την εμφάνιση του πρόσημου + μέχρι να συναντήσουμε έναν άλλον κώδικα, ο κώδικας SS καταργεί την εμφάνιση του πρόσημου + και ο κώδικας S επαναφέρει την προκαθορισμένη κατάσταση που ισχύει για το πρόσημο + των θετικών αριθμητικών τιμών.
Ακολουθεί ένα παράδειγμα :
A = 100
WRITE(*, 10) A, A, A, A, A
10 FORMAT(10X, SP, I5, I5, SS, I5, SP, I5, S, I5)
Γενικοί Κανόνες για την Εντολή FORMAT
Σε περίπτωση που θέλουμε να χρησιμοποιήσουμε την ίδια ακριβώς μορφοποίηση για πολλές μεταβλητές, μπορούμε να χρησιμοποιήσουμε έναν αριθμό επανάληψης, ως εξής :
READ(5, 10) A1, A2, A3, A4, A5
10 FORMAT(3F5.2, 2F4.2)
Σύμφωνα με την παραπάνω εντολή FORMAT, οι τρεις πρώτες μεταβλητές θα διαβασθούν με τον κώδικα F5.2 και οι δύο επόμενες θα διαβασθούν με τον κώδικα F4.2.
Μπορούμε να χρησιμοποιήσουμε και παρενθέσεις για να επαναλάβουμε συνδυασμούς από κώδικες FORMAT, ως εξής :
READ(5, 10) A1, A2, Ι1, Α3, Ι2
10 FORMAT(F5.2, 2(F4.2, I5))
Μπορούμε να εκτυπώσουμε πολλούς ίδιους συνεχόμενους χαρακτήρες χρησιμοποιώντας έναν ακέραιο αριθμό και τους χαρακτήρες μέσα σε παρενθέσεις, ως εξής :
WRITE(6, 20)
20 FORMAT(5X, ‘ΑΠΟΤΕΛΕΣΜΑΤΑ = ‘/5Χ, 12(‘-‘))
Σαν μια σύνοψη των κανόνων που ισχύουν για τις εντολές FORMAT, έχουμε τα εξής :
Οι εντολές FORMAT είναι μη-εκτελέσιμες εντολές και συνοδεύουν τις εντολές εισόδου/εξόδου.
Δεν μπορούμε να χρησιμοποιήσουμε μια εντολή GO TO για να μεταφέρουμε τον έλεγχο του προγράμματος σε μια εντολή FORMAT.
Οι εντολές FORMAT μπορούν να τοποθετηθούν οπουδήποτε μέσα στο πρόγραμμα, όλες μαζί στην αρχή του προγράμματος ή όλες μαζί στο τέλος του προγράμματος, αλλά το σωστό είναι η κάθε εντολή FORMAT να ακολουθεί την εντολή εισόδου/εξόδου με την οποία συνεργάζεται.
Η ίδια εντολή FORMAT μπορεί να χρησιμοποιηθεί από περισσότερες από μία εντολές εισόδου/εξόδου.
Αν υπάρχουν περισσότεροι κώδικες FORMAT απ’ όσους χρειάζεται μια εντολή εισόδου/εξόδου, αυτοί θα αγνοηθούν.
Οι Πίνακες (Arrays) στη Fortran
Οι πίνακες (arrays) ή μητρώα ή διατάξεις ή μεταβλητές με δείκτες είναι γνωστοί από άλλες γλώσσες προγραμματισμού για το πόσο χρήσιμοι είναι και το πόσο μεγάλη ευελιξία προσφέρουν στη συγγραφή των προγραμμάτων.
Για να μπούμε κατευθείαν στην έννοια των πινάκων στη Fortran, θα ξεκινήσουμε μ’ ένα απλό παράδειγμα ενός μονοδιάστατου πίνακα. Έστω ότι πρέπει να διαβάσουμε τις ποσότητες και τις τιμές από 10 προϊόντα και να υπολογίσουμε την αξία του κάθε προϊόντος καθώς και τη συνολική αξία όλων των προϊόντων.
Γράφουμε το εξής πρόγραμμα :
DIMENSION POSO(10), TIMH(10), AXIA(10)
SYNOLO = 0
DO I=1, 10
READ(*, *) POSO(I), TIMH(I)
AXIA(I) = POSO(I) * TIMH(I)
WRITE(*, *) AXIA(I)
SYNOLO = SYNOLO + AXIA(I)
END DO
WRITE(*, *) SYNOLO
END
Ακολουθεί ένα παράδειγμα μ’ έναν πίνακα δύο διαστάσεων, με 20 γραμμές και 30 στήλες, όπου διαβάζουμε όλα τα στοιχεία (αριθμούς) του πίνακα και μετά υπολογίζουμε το άθροισμά τους καθώς και τον μέσο όρο τους.
DIMENSION A(20, 30)
SYNOLO = 0
DO I = 1, 20
DO J = 1, 30
READ(*, *) A(I, J)
SYNOLO = SYNOLO + A(I, J)
END DO
END DO
MO = SYNOLO/600
Οι κανόνες που ισχύουν για τις μεταβλητές της Fortran ισχύουν και για τους πίνακες. Αυτό σημαίνει ότι αν το όνομα ενός πίνακα ξεκινάει μ’ έναν από τους χαρακτήρες I, J, K, L, M ή N, τότε όλα τα στοιχεία του πίνακα είναι ακέραιοι αριθμοί, αλλιώς είναι πραγματικοί αριθμοί.
Με τις κατάλληλες εντολές τύπου μπορεί ένας πίνακας να περιέχει διπλής ακρίβειας ή μιγαδικούς αριθμούς ή λογικές ή αλφαριθμητικές τιμές.
Με την εντολή DIMENSION δηλώνουμε τους πίνακες σ’ ένα πρόγραμμα Fortran και πιο συγκεκριμένα δηλώνουμε τα ονόματα των πινάκων που πρόκειται να χρησιμοποιήσουμε στο πρόγραμμα, τις διαστάσεις τους καθώς και τον συνολικό αριθμό των στοιχείων που θα περιέχει ο κάθε πίνακας.
Η γενική μορφή της εντολής DIMENSION είναι η εξής :
DIMENSION[::]A1(l:m), A2(l :m), …, AN(l :m)
όπου έχουμε τα εξής :
Τα Α1, Α2, …, ΑΝ είναι τα ονόματα των πινάκων.
Το l είναι η ελάχιστη δυνατή τιμή του δείκτη ενός πίνακα που μπορεί να είναι θετική, αρνητική ή και μηδέν. Προκαθορισμένη τιμή είναι το 1.
Το m είναι η μέγιστη δυνατή τιμή του δείκτη ενός πίνακα που μπορεί να είναι θετική, αρνητική, μηδέν ή και *, αλλά πάντα >=l. Το * χρησιμοποιείται για να δηλώσει έναν πίνακα μεταβλητού μήκους και μόνο σε υποπρογράμματα.
Ακολουθούν παραδείγματα :
DIMENSION::A(10, 20), B(100), IPOLISEIS(10, 15, 20)
Τα σύμβολα :: μπορούν να παραλειφθούν.
DIMENSION::A(5:50, -10:20), K(-4:20, 100), M(19:36)
Στο παραπάνω παράδειγμα, οι τιμές των δεικτών των πινάκων δεν ξεκινούν από το 1, ως συνήθως, αλλά από άλλες τιμές, ακόμα και αρνητικές.
Μια άλλη πιο γενική μορφή της εντολής DIMENSION είναι η εξής :
Type, DIMENSION(διαστάσεις)[::]A1[διαστάσεις] [, A2[διαστάσεις]]…
όπου έχουμε τα εξής :
Το Type είναι ο τύπος των δεδομένων που περιέχει ο πίνακας, δηλ. κάτι από τα REAL, INTEGER, DOUBLE PRECISION, COMPLEX, LOGICAL, CHARACTER.
Τα Α1, Α2, … είναι ονόματα πινάκων, όπου μπορούμε να ορίσουμε άλλες διαστάσεις σε κάποιον πίνακα ή να μην ορίσουμε διαστάσεις και να θεωρηθούν έτσι δεδομένες οι διαστάσεις που έχουν δηλωθεί στην εντολή DIMENSION.
Ακολουθούν παραδείγματα :
REAL, DIMENSION(100)::A, B, C(50)
INTEGER, DIMENSION(10, 10)::A1, A2, A3(20, 20)
CHARACTER(LEN=20), DIMENSION(50)::NAMES
Στο τελευταίο παράδειγμα ορίζουμε έναν μονοδιάστατο αλφαριθμητικό πίνακα που περιέχει 50 στοιχεία και με μέγιστο αριθμό χαρακτήρων 20 για το κάθε στοιχείο.
Πρέπει να έχουμε υπόψη μας ότι η εντολή DIMENSION είναι μη-εκτελέσιμη εντολή και πρέπει να την γράφουμε στην αρχή του προγράμματος. Ακόμη, όταν εκτελείται το πρόγραμμα θα πρέπει να έχουμε προνοήσει ώστε οι δείκτες των πινάκων που έχουμε ορίσει μέσα στο πρόγραμμα να μην ξεπερνάνε τα όρια που έχουμε καθορίσει.
Εκτός από την κλασική εντολή DO που έχουμε χρησιμοποιήσει μέχρι τώρα για την καταχώρηση τιμών σ’ έναν πίνακα, υπάρχει και ένας πιο γρήγορος τρόπος καταχώρησης στοιχείων σε πίνακα με την εντολή READ, η λεγόμενη έμμεση εντολή DO (implied DO), που γράφεται ως εξής :
READ(5, 10) (A(I), I=1, 10)
10 FORMAT(10F5.2)
READ(*, *) (A(I), I=1, 20)
READ(5, *) (A(I), I=1, 30, 2)
READ(5, 20) ((A(I, J), J=1, 20), I=1, 10)
20 FORMAT(200F5.2)
WRITE(6, 10) (A(I), I=1, 10)
10 FORMAT(10F5.2)
WRITE(6, 20) ((A(I, J), J=1, 20), I=1, 10)
20 FORMAT(200F5.2)
WRITE(*, *) (A(I), I=1, 30, 2)
Μπορούμε να χρησιμοποιήσουμε και μόνο το όνομα ενός πίνακα, αφού τον έχουμε ορίσει πρώτα με την εντολή DIMENSION, για να καταχωρήσουμε τιμές σ’ αυτόν, ως εξής :
DIMENSION A(10)
READ(5, 10) A
10 FORMAT(10F5.2)
Με τον παραπάνω τρόπο καταχώρησης τιμών σ’ έναν πίνακα, είμαστε υποχρεωμένοι να δώσουμε τιμές γι’ όλα τα στοιχεία του πίνακα, άρα θα πρέπει να γνωρίζουμε εκ των προτέρων το δηλωμένο μέγεθος του πίνακα.
Στη Fortran 90 μπορούμε να κάνουμε ορισμένες πράξεις με τους πίνακες πολύ εύκολα, ενώ σε παλιότερες εκδόσεις της γλώσσας θα έπρεπε να γράψουμε αρκετές γραμμές κώδικα.
Για παράδειγμα :
DIMENSION (20)::A1, A2, A3, A4
…
A1 = A2
! ολόκληρος ο πίνακας Α2 καταχωρείται στον πίνακα Α1
Α3 = Α1 + Α2
! το άθροισμα των πινάκων Α1 και Α2 καταχωρείται στον πίνακα Α3
Α4 = Α1 * 10
! ο πίνακας Α4 είναι ίσος με τον πίνακα Α1, όπου όμως όλα τα
! στοιχεία του έχουν πολλαπλασιασθεί με το 10
Ακολουθεί άλλο ένα παράδειγμα :
INTEGER, DIMENSION (5)::A, B, C(15)
…
A = (/1, 2, 3, 4, 5/)
B = (/10, 20, 30, 40, 50/)
C = (/B, A, B/)
Οι πίνακες Α και Β θα πάρουν κάποιες αρχικές ακέραιες τιμές, ενώ ο πίνακας C θα πάρει τις 5 τιμές του πίνακα Β, μετά τις 5 τιμές του πίνακα Α και τέλος ξανά τις 5 τιμές του πίνακα Β.
Κι άλλο ένα παράδειγμα :
INTEGER::C(5)
REAL::A(10), B(5)
SUB = (/1, 3, 5, 7, 9/)
A = (/0.2, 1.2, 2.2, 3.2, 4.2, 5.2, 6.2, 7.2, 8.2, 9.2/)
B = A(C)
Σύμφωνα με τις παραπάνω εντολές, ο πίνακας Β θα πάρει τιμές από τον πίνακα Α, αλλά μόνο για τις θέσεις 1, 3, 5, 7 και 9, όπως δηλαδή ορίζεται από τις τιμές που περιέχει ο ενδιάμεσος πίνακας C.
Μπορούμε πολύ εύκολα να προσδιορίσουμε τμήματα ενός πίνακα, ως εξής :
A(2:5, 2)
! δηλώνει το κομμάτι της 2ης στήλης του πίνακα Α που περιέχει
! τα στοιχεία από την 2η έως και την 5η γραμμή
A(5, :)
! δηλώνει ολόκληρη την 5η γραμμή του πίνακα Α
A(2:3, 1:4)
! δηλώνει το κομμάτι που ορίζουν η 2η και η 3η γραμμή με την 1η
! και την 4η στήλη του πίνακα Α
Με την εντολή ALLOCATE μπορούμε να ορίσουμε δυναμικούς πίνακες στην Fortran 90, δηλ. πίνακες που δεν γνωρίζουμε από την αρχή τις πραγματικές τους διαστάσεις, αλλά μπορούμε να τις δηλώσουμε κατά τη διάρκεια της εκτέλεσης του προγράμματος.
Ακολουθεί ένα κατατοπιστικό παράδειγμα :
REAL, DIMENSION(:,:), ALLOCATABLE::A
…
READ(5, *) I1, I2
ALLOCATE (A(I1, I2))
READ(5, *) ((A(I, J), J=1, I2), I=1, I1)
Η εντολή WHERE χρησιμοποιείται για να μπορούμε να επιλέγουμε στοιχεία από πίνακες και έχει ανάλογο αποτέλεσμα με την εντολή IF.
Ακολουθούν παραδείγματα :
WHERE (B>0) B = B + 10
! μόνο για τα θετικά στοιχεία του πίνακα Β έχουμε αύξηση κατά 10
REAL, DIMENSION(10)::A, B
READ(*, *) A
READ(*, *) B
WHERE(A>0)
B=100
END WHERE
Αφού καταχωρήσουμε όλες τις τιμές στους πίνακες Α και Β, με την εντολή WHERE ελέγχουμε τις θετικές τιμές του πίνακα Α και καταχωρούμε την τιμή 100 στις αντίστοιχες θέσεις του πίνακα Β.
Υπάρχει και η εξής μορφή της εντολής WHERE :
WHERE(A>0)
… εντολές …
ELSE WHERE
… εντολές …
END WHERE
Οι Υπορουτίνες (Subroutines) στη Fortran
Όπως όλες οι γνωστές γλώσσες προγραμματισμού, έτσι και η Fortran, διακρίνει τα υποπρογράμματα (subprograms) σε δύο κατηγορίες, τις υπορουτίνες (subroutines) και τις συναρτήσεις (functions).
Θα δούμε ένα αρχικό παράδειγμα υπορουτίνας που υπολογίζει τον μέσο όρο των αριθμών ενός πίνακα.
SUBROUTINE MO(N, A, MESOS)
DIMENSION A(100)
SUM = 0
DO I=1, N
SUM = SUM + A(I)
END DO
MESOS = SUM/N
RETURN
END SUBROUTINE MO
Οι μεταβλητές Ν (πλήθος των στοιχείων για τα οποία θέλουμε να υπολογίσουμε τον μέσο όρο) και Α (όνομα πίνακα) είναι οι παράμετροι εισόδου της υπορουτίνας και η μεταβλητή MESOS είναι η παράμετρος εξόδου της υπορουτίνας. Μόλις συναντηθεί η εντολή RETURN, η υπορουτίνα τελειώνει τη δουλειά της και επιστρέφει τον έλεγχο στο κυρίως πρόγραμμα.
Δεν υπάρχει κάποιος τρόπος για να καταλάβουμε με μια πρώτη ματιά ποιες είναι οι παράμετροι εισόδου και ποιες είναι οι παράμετροι εξόδου μιας υπορουτίνας^ είναι όμως σωστό να γράφουμε μέσα στις παρενθέσεις πρώτα τις παραμέτρους εισόδου και μετά τις παραμέτρους εξόδου.
Το κυρίως πρόγραμμα που καλεί την παραπάνω υπορουτίνα με την εντολή CALL μπορεί να έχει την εξής μορφή :
DIMENSION A(100)
READ(*, *) N
READ(*, *) (A(I), I=1, N)
CALL MO(N, A, MESOS)
WRITE(*, *) ‘ΜΕΣΟΣ ΟΡΟΣ = ‘, MESOS
Πρέπει να έχουμε υπόψη μας ότι τα ονόματα των παραμέτρων στην εντολή CALL δεν είναι ανάγκη να είναι τα ίδια μ’ αυτά που υπάρχουν στην υπορουτίνα, αλλά πρέπει οπωσδήποτε να αντιστοιχούν σε πλήθος, σειρά και τύπο δεδομένων.
Μπορούμε με την εντολή RETURN να επιστρέψουμε τον έλεγχο όχι στην εντολή που ακολουθεί αμέσως μετά την εντολή CALL αλλά σε κάποια άλλη εντολή του κυρίως προγράμματος.
Ακολουθεί ένα παράδειγμα :
! ΤΟ ΚΥΡΙΩΣ ΠΡΟΓΡΑΜΜΑ
…
CALL SUB1(I, *10, J, *20, *30)
WRITE(*, *) ‘ΕΔΩ ΕΙΝΑΙ ΤΟ ΚΑΝΟΝΙΚΟ RETURN’
…
10 WRITE(*, *) ‘RETURN1’
…
20 WRITE(*, *) ‘RETURN2’
…
30 WRITE(*, *) ‘RETURN3’
…
END
! Η ΥΠΟΡΟΥΤΙΝΑ
SUBROUTINE SUB1(I, *, J, *, *)
…
IF (I==1) RETURN 1
IF (I==2) RETURN 2
IF (I > 2) RETURN 3
…
RETURN
END
Στην εντολή CALL χρησιμοποιούμε * για να δηλώσουμε τους αριθμούς των εντολών του κυρίως προγράμματος όπου θα γίνει η επιστροφή από την υπορουτίνα και στις αντίστοιχες θέσεις στην εντολή SUBROUTINE γράφουμε απλά *.
Αν, μέσα στην υπορουτίνα, συναντήσουμε την εντολή RETURN 1, τότε στο κυρίως πρόγραμμα η επιστροφή θα γίνει στον αριθμό εντολής που αντιστοιχεί στο πρώτο * κοκ.
Χρησιμοποιούμε την εντολή CONTAINS στην περίπτωση που το κυρίως πρόγραμμα και μια υπορουτίνα που καλεί περιέχονται μαζί στο ίδιο αρχείο. Το κυρίως πρόγραμμα μπορεί να περιέχεται σε ξεχωριστό αρχείο από μια υπορουτίνα που καλεί, οπότε θα πρέπει να γίνει ξέχωρα η μεταγλώττιση (compilation) των δύο αρχείων και στη συνέχεια με τη σύνδεση (linking) θα γίνει η ένωσή τους σ’ ένα ενιαίο εκτελέσιμο αρχείο.
Στην περίπτωση λοιπόν που το κυρίως πρόγραμμα και μια υπορουτίνα που καλεί περιέχονται μαζί στο ίδιο αρχείο, θα πρέπει να χρησιμοποιήσουμε την εντολή CONTAINS ως εξής :
PROGRAM KYRIO
…
CALL MO(A, B)
…
CONTAINS
SUBROUTINE MO(A, B)
…
RETURN
END SUBROUTINE MO
END PROGRAM KYRIO
Οι Συναρτήσεις (Functions) στη Fortran
Οι συναρτήσεις στη Fortran είναι υποπρογράμματα που μπορούν να δεχθούν μία ή και περισσότερες παραμέτρους εισόδου αλλά επιστρέφουν μία και μόνο μία παράμετρο εξόδου και μάλιστα με το ίδιο όνομα της συνάρτησης.
Η άλλη μεγάλη διαφορά των συναρτήσεων από τις υπορουτίνες είναι ότι οι συναρτήσεις δεν καλούνται με κάποια εντολή CALL αλλά με χρήση του ονόματός τους, όπως ακριβώς καλούνται οι έτοιμες συναρτήσεις των βιβλιοθηκών.
Η σύνταξη μιας συνάρτησης στη Fortran έχει την εξής μορφή :
[Τύπος] FUNCTION NAME(παρ1, παρ2, …, παρn)
[RESULT (NAME1)]
… εντολές …
RETURN
END FUNCTION NAME
όπου έχουμε τα εξής :
Τύπος, δηλώνουμε προαιρετικά τον τύπο δεδομένων της τιμής επιστροφής της συνάρτησης.
NAME, είναι το όνομα της συνάρτησης και είναι ίδιο με το όνομα της μεταβλητής που υπολογίζεται μέσα στη συνάρτηση και επιστρέφεται στην εντολή από την οποία έχει κληθεί. Αυτά ισχύουν βέβαια στην περίπτωση που δεν χρησιμοποιηθεί η προαιρετική παράμετρος RESULT.
NAME1, αν χρησιμοποιηθεί η προαιρετική παράμετρος RESULT, εδώ δηλώνουμε το όνομα της μεταβλητής που επιστρέφει την τιμή υπολογισμού της συνάρτησης και στην περίπτωση αυτή δεν μπορούμε να χρησιμοποιήσουμε καθόλου μέσα στη συνάρτηση το όνομα της ίδιας συνάρτησης σαν μεταβλητή.
παρ1, παρ2, …, παρn, είναι ονόματα μεταβλητών που αποτελούν τις παραμέτρους της συνάρτησης και είναι όλες παράμετροι εισόδου.
Το πρόβλημα της εύρεσης του μέσου όρου των Ν στοιχείων ενός πίνακα Α μπορεί να λυθεί και με τη βοήθεια μιας συνάρτησης ως εξής :
PROGRAM MAIN
DIMENSION A(100)
READ(*, *) N
READ(*, *) (A(I), I=1, N)
MESOS_OROS = SUM(N, A)/FLOAT(N)
WRITE(*, *) ‘ΜΕΣΟΣ ΟΡΟΣ = ‘, MESOS_OROS
CONTAINS
FUNCTION SUM(N, A)
DIMENSION A(100)
SUM = 0.
DO I=1, N
SUM = SUM + A(I)
END DO
END FUNCTION SUM
END PROGRAM MAIN
Ακολουθεί το ίδιο πρόγραμμα αλλά με τη χρήση της εντολής RESULT, όπου ο μέσος όρος υπολογίζεται μέσα στη συνάρτηση και η τιμή επιστρέφεται στο κυρίως πρόγραμμα με το όνομα της μεταβλητής που δηλώνεται στην εντολή RESULT ενώ δεν μπορούμε να χρησιμοποιήσουμε πουθενά μέσα στην ίδια τη συνάρτηση το όνομά της σαν μεταβλητή.
PROGRAM MAIN
DIMENSION A(100)
READ(*, *) N
READ(*, *) (A(I), I=1, N)
MESOS_OROS = MO(N, A)
WRITE(*, *) ‘ΜΕΣΟΣ ΟΡΟΣ = ‘, MESOS_OROS
CONTAINS
FUNCTION MO(N, A) RESULT(MESOS)
DIMENSION A(100)
SUM = 0.
DO I=1, N
SUM = SUM + A(I)
END DO
MESOS = SUM/FLOAT(N)
END FUNCTION MO
END PROGRAM MAIN
Η εντολή συνάρτηση (statement function) αποτελεί μια πολύ απλουστευμένη μορφή της συνάρτηση FUNCTION που γνωρίσαμε στην προηγούμενη παράγραφο αλλά που είναι πολύ βολική και χρήσιμη όταν θέλουμε να χρησιμοποιήσουμε έναν απλό τύπο υπολογισμού και δεν θέλουμε να μπούμε στον κόπο να δημιουργήσουμε ένα ολόκληρο υποπρόγραμμα.
Για να δημιουργήσουμε μια εντολή συνάρτηση, γράφουμε το όνομα της εντολής συνάρτηση, μετά μέσα σε παρενθέσεις τις απαιτούμενες παραμέτρους, το σύμβολο = και τέλος τις πράξεις που πρέπει να γίνουν με τις παραμέτρους.
Για παράδειγμα, ας υποθέσουμε ότι θέλουμε να δημιουργήσουμε μια εντολή συνάρτηση που να υπολογίζει το άθροισμα των τετραγώνων δύο αριθμών και να την ενσωματώσουμε σ’ ένα πρόγραμμα. Γράφουμε τα εξής :
! ΟΡΙΣΜΟΣ ΤΗΣ ΕΝΤΟΛΗΣ ΣΥΝΑΡΤΗΣΗ
F(A, B) = A**2 + B**2
…
READ(*, *) X, Y
Z = F(X, Y)
WRITE(*, *) ‘ΑΠΟΤΕΛΕΣΜΑ = ‘, Z
Οι Α και Β αποκαλούνται ψευδομεταβλητές της εντολής συνάρτηση και τα ίδια ονόματα μπορούμε να τα χρησιμοποιήσουμε ξανά μέσα στο πρόγραμμα. Η εντολή συνάρτηση θα πρέπει να γράφεται πριν από την πρώτη εκτελέσιμη εντολή του προγράμματος και δεν μπορεί να χρησιμοποιηθεί σ’ ένα υποπρόγραμμα που καλείται από το κυρίως πρόγραμμα.
Με την εντολή COMMON μπορούμε να δώσουμε τη δυνατότητα σε μια ή περισσότερες μεταβλητές να καταλαμβάνουν την ίδια θέση μνήμης.
Η σύνταξή της είναι ως εξής :
COMMON A1, A2, …, An
όπου τα A1, A2, …, An είναι ονόματα μεταβλητών.
Για παράδειγμα, αν γράψουμε τις παρακάτω εντολές, στο κυρίως πρόγραμμα την πρώτη και σ’ ένα υποπρόγραμμα τη δεύτερη, στην ουσία θα δημιουργηθούν τέσσερις διαφορετικές θέσεις μνήμης (μεταβλητές) όπου οι Α1 και Β1 θα έχουν ίδια τιμή (ίδια θέση μνήμης), όπως και η Β1 με την Β2 κοκ.
COMMON A1, A2, A3, A4
COMMON B1, B2, B3, B4
Αν χρησιμοποιήσουμε την εντολή COMMON σ’ ένα πρόγραμμα, τότε μπορούμε να παραλείψουμε την αναγραφή των μεταβλητών στις εντολές CALL και SUBROUTINE και αυτό γιατί η μεταφορά των τιμών των μεταβλητών γίνεται με την εντολή COMMON.
Το γνωστό παράδειγμα με τον υπολογισμό του μέσου όρου μπορεί να γραφεί με τη χρήση της εντολής COMMON και ως εξής :
PROGRAM MAIN
DIMENSION A(100)
COMMON N, A, MESOS
READ(*, *) N
READ(*, *) (A(I), I=1, N)
CALL MO
WRITE(*, *) ‘ΜΕΣΟΣ ΟΡΟΣ = ‘, MESOS
CONTAINS
SUBROUTINE MO
DIMENSION A1(100)
COMMON N1, A1, MESOS1
SUM = 0
DO I=1, N1
SUM = SUM + A1(I)
END DO
MESOS1 = SUM/N
RETURN
END SUBROUTINE MO
END PROGRAM MAIN
Στην εντολή COMMON μπορούμε να ορίσουμε τις διαστάσεις και το μέγεθος ενός πίνακα και να μην χρειασθεί να γράψουμε έτσι την εντολή DIMENSION.
COMMON I, A(100)
Με την εντολή INTENT μπορούμε να καθορίσουμε ποιες παράμετροι θα είναι εισόδου σ’ ένα υποπρόγραμμα και ποιες θα είναι εξόδου. Η γενική μορφή της εντολής μπορεί να είναι μια από τις εξής :
[TYPE,] INTENT (IN)::λίστα_παραμέτρων
ή
[TYPE,] INTENT (OUT)::λίστα_παραμέτρων
ή
[TYPE,] INTENT (INOUT) ::λίστα_παραμέτρων
Με την πρώτη μορφή της εντολής ορίζουμε ότι οι παράμετροι είναι εισόδου και άρα δεν μπορούν να τροποποιηθούν από το υποπρόγραμμα, με τη δεύτερη μορφή ορίζουμε ότι οι παράμετροι είναι εξόδου και άρα θα πρέπει να λάβουν κάποια τιμή μέσα στο υποπρόγραμμα και με την τρίτη μορφή ορίζουμε ότι οι παράμετροι είναι και εισόδου και εξόδου.
Ακολουθεί ένα παράδειγμα :
PROGRAM PROG1
IMPLICIT NONE
INTEGER::A, B, C
CALL SUB1(A, B, C)
WRITE(*, *) A, B, C
END PROGRAM PROG1
SUBROUTINE SUB1(A1, A2, A3)
IMPLICIT NONE
INTEGER, INTENT(IN)::A1, A2
INTEGER, INTENT(OUT)::A3
A3 = A1 * A2
END SUBROUTINE SUB1
Με τις εντολές USE και MODULE μπορούμε να χρησιμοποιήσουμε ένα κομμάτι προγράμματος της Fortran πολλές φορές μέσα στο ίδιο πρόγραμμα αλλά και σε διαφορετικά προγράμματα. Η εντολή USE πρέπει να είναι η πρώτη εντολή στο τμήμα του προγράμματος όπου χρησιμοποιείται.
Ακολουθεί ένα παράδειγμα :
MODULE FIRST
INTEGER::A1, A2, I
REAL::A(100)
END MODULE FIRST
Αν θέλουμε τώρα να χρησιμοποιήσουμε το παραπάνω κομμάτι προγράμματος σ’ ένα κυρίως πρόγραμμα ή σ’ ένα υποπρόγραμμα, θα πρέπει να γράψουμε πριν από τις εκτελέσιμε εντολές, την εντολή USE ως εξής :
USE FIRST
Αν θελήσουμε να χρησιμοποιήσουμε μερικά μόνο από τα στοιχεία του MODULE FIRST, γράφουμε το εξής :
USE FIRST, ONLY::A1, A2
Αν θελήσουμε, μπορούμε να αλλάξουμε το όνομα κάποιας μεταβλητής, ως εξής :
USE FIRST, ONLY::B1=>A1
Έτοιμες Συναρτήσεις Χειρισμού Πινάκων
Η Fortran περιέχει πολλές συναρτήσεις FUNCTION που μπορούμε να χρησιμοποιήσουμε για να κάνουμε πράξεις με πίνακες, που διαφορετικά θα ήμασταν αναγκασμένοι να γράψουμε πολύπλοκο κώδικα. Οι σημαντικότερες από τις συναρτήσεις αυτές είναι οι εξής :
MATMUL(A, B), επιστρέφει το γινόμενο δύο πινάκων σ’ έναν τρίτο πίνακα, αν φυσικά υπάρχουν οι προϋποθέσεις για να μπορεί να υπολογισθεί το γινόμενό τους.
TRANSPOSE(A), επιστρέφει τον ανάστροφο ενός πίνακα σ’ έναν άλλον πίνακα.
MAXVAL(A), επιστρέφει το μέγιστο στοιχείο ενός πίνακα.
MINVAL(A), επιστρέφει το ελάχιστο στοιχείο ενός πίνακα.
MAXLOC(A), επιστρέφει τη θέση του μέγιστου στοιχείου ενός πίνακα.
MINLOC(A), επιστρέφει τη θέση του ελάχιστου στοιχείου ενός πίνακα.
SUM(A), επιστρέφει το άθροισμα των στοιχείων ενός πίνακα.
Με την παράμετρο KIND μπορούμε να επιλέξουμε εμείς την ακρίβεια που θέλουμε να έχουν τα δεδομένα μας, έτσι ώστε τα αποτελέσματα να είναι τα ίδια σε διαφορετικά συστήματα υπολογιστών. Στην ουσία επιλέγουμε το πλήθος των bytes που απαιτούνται για την αποθήκευση μιας μεταβλητής.
Η παράμετρος KIND είναι ένας ακέραιος αριθμός που μπορεί να πάρει μια από τις τιμές 4, 8 ή 16 για απλή, διπλή ή και τετραπλή ακρίβεια αντίστοιχα, ενώ σε μερικούς υπολογιστές η ακρίβεια αυτή δηλώνεται με τους αριθμούς 1, 2 και 3 αντίστοιχα.
Αν την χρησιμοποιήσουμε με πραγματικούς αριθμούς, μπορούμε να δηλώσουμε κάποιες πραγματικές μεταβλητές σαν διπλής ακρίβειας ως εξής :
REAL(KIND=8)::A1, A2, A3
ή
REAL(8)::A1, A2, A3
Για τις ακέραιες μεταβλητές μπορούμε να χρησιμοποιήσουμε τις τιμές 1, 2 και 4 για ακεραίους με μέγιστες τιμές 127, 32.767 και 2.147.483.647 αντίστοιχα. Η προκαθορισμένη τιμή για τις ακέραιες μεταβλητές είναι η 4.
INTEGER(KIND=2)::A
ή
INTEGER(2)::A
Υπάρχουν οι έμμεσες εντολές τύπου (implicit type statements) και οι άμεσες εντολές τύπου (explicit type statements). Με τις πρώτες μπορούμε να καθορίσουμε μόνο τον τύπο των δεδομένων των μεταβλητών, των πινάκων και των συναρτήσεων βάσει του αρχικού γράμματος του ονόματός τους, ενώ με τις δεύτερες πρώτες μπορούμε να καθορίσουμε τον τύπο των δεδομένων για ορισμένες μεταβλητές, πίνακες και συναρτήσεις αλλά και τις αρχικές τιμές τους καθώς και τις διαστάσεις των πινάκων.
Οι έμμεσες εντολές τύπου δηλώνονται με την εντολή IMPLICIT, η γενική μορφή της οποίας είναι η εξής :
IMPLICIT Type(A1, A2, …), …
όπου έχουμε τα εξής :
Type, είναι ο τύπος δεδομένων των μεταβλητών, δηλ. κάτι από τα INTEGER, REAL, DOUBLE PRECISION, COMPLEX, LOGICAL και CHARACTER.
A1, A2, …, είναι γράμματα ή και περιοχές γραμμάτων.
Ακολουθούν παραδείγματα :
IMPLICIT INTEGER(A-D, R-U), REAL(I, L)
Η παραπάνω εντολή δηλώνει ότι όλες οι μεταβλητές που ξεκινούν μ’ ένα από τα γράμματα A έως D και R έως U είναι ακέραιες, ενώ όλες οι μεταβλητές που ξεκινούν μ’ ένα από τα γράμματα I ή L είναι ακέραιες.
IMPLICIT REAL(I, L), LOGICAL(A-C, Y), COMPLEX(D-F)
IMPLICIT CHARACTER*10 (A, F)
IMPLICIT CHARACTER*15 FLORINA
Οι παραπάνω εντολές ορίζουν ότι όλες οι μεταβλητές που ξεκινούν μ’ ένα από τα γράμματα A και F είναι αλφαριθμητικές με μήκος χαρακτήρων 10, με εξαίρεση την αλφαριθμητική μεταβλητή FLORINA, η οποία θα έχει μήκος 15 χαρακτήρων.
Οι άμεσες εντολές τύπου είναι πιο περίπλοκες στη σύνταξή τους και θα φανούν καλύτερα με παραδείγματα :
INTEGER::A, DEIKTIS
Οι μεταβλητές A και DEIKTIS είναι ακέραιες.
INTEGER A/100/, I
Οι μεταβλητές A και I είναι ακέραιες και η Α έχει αρχική τιμή 100.
INTEGER A(10), B(5)/1, 3, 3*10/
Οι μεταβλητές Α και Β είναι πίνακες με 10 και 5 στοιχεία αντίστοιχα και ο Β έχει αρχικές τιμές : Β(1)=1, Β(2)=3 και Β(3)=Β(4)=Β(5)=10.
INTEGER A(4)/10, 20, 30, 40/, B(2, 2)/1, 2, 3, 4/
Οι μεταβλητές Α και Β είναι πίνακες, όπου ο Α είναι μονοδιάστατος με 4 στοιχεία και αρχικές τιμές : 10, 20, 30 και 40, ενώ ο Β είναι δισδιάστατος (2 Χ 2) με 4 στοιχεία και αρχικές τιμές : Β(1, 1)=1, Β(2, 1)=2, Β(1, 2)=3 και Β(2, 2)=4. Θα πρέπει να έχουμε υπόψη μας ότι στους δισδιάστατους πίνακες οι τιμές δίνονται κατά στήλες.
REAL A1/7.2/, A2/3.4/, A3/20.5/
Ορίζουμε τρεις πραγματικές μεταβλητές και δίνουμε αρχικές τιμές.
COMPLEX A, B(20)
COMPLEX A1/3, 2/, A2/-4, 15/
Ορίζουμε μιγαδικές μεταβλητές, όπου στο δεύτερο παράδειγμα έχουμε και απόδοση αρχικών τιμών, δηλ, τις 3+2i και –4+15i.
LOGICAL D, PASS/.TRUE./, SUCCESS/.FALSE./
DOUBLE PRECISION A, B(10, 20), C/10.15D2/
CHARACTER(LEN=10)::NAME
Με την εντολή EQUIVALENCE μπορούμε να ορίσουμε τις μεταβλητές που θέλουμε να καταλαμβάνουν τις ίδιες ακριβώς θέσεις στη μνήμη του υπολογιστή. Η γενική μορφή της εντολής είναι η εξής :
EQUIVALENCE (A1, A2, …, An), (B1, B2, …, Bn)
Όπου οι μεταβλητές Α1, Α2, …, Αn καταλαμβάνουν την ίδια ακριβώς θέση στη μνήμη και άρα είναι ισοδύναμες και το ίδιο ισχύει για τις μεταβλητές Β1, Β2, …, Βn, οι οποίες καταλαμβάνουν κάποια άλλη θέση μνήμης.
Ακολουθούν παραδείγματα :
EQUIVALENCE (A1, A2, A3)
A1 = 10
Σύμφωνα με τις παραπάνω εντολές, και οι τρεις μεταβλητές A1, A2, A3 θα έχουν πάρει την τιμή 10.
DIMENSION A(10), B(10)
EQUIVALENCE (A(1), B(1))
Οι δύο πίνακες καταλαμβάνουν την ίδια θέση μνήμης, δηλ. ισχύει η αντιστοιχία Α(1)=Β(1), Α(2)=Β(2) κοκ. Αναφέρουμε μόνο τα πρώτα στοιχεία των πινάκων και η ισοδυναμία γίνεται αυτόματα και για τα υπόλοιπα στοιχεία.
Με την εντολή DATA μπορούμε να αποδώσουμε αρχικές τιμές στις μεταβλητές ενός προγράμματος. Αν στις σταθερές τιμές υπάρχει το σύμβολο *, τότε η σταθερή τιμή που ακολουθεί το * θα επαναλαμβάνεται όσες φορές δηλώνει ο αριθμός που βρίσκεται μπροστά από το *.
Ακολουθούν παραδείγματα :
DATA A/10.1/, I/5/, B/13.6/
Η μεταβλητή Α παίρνει την τιμή 10.1, η Ι την τιμή 5 και η Β την τιμή 13.6.
DATA A, B/15.7, 4.8/
Η μεταβλητή Α παίρνει την τιμή 15.7 και η Β την τιμή 4.8.
DATA K1, K2, K3/2*10, 20/
Οι μεταβλητές Κ1 και Κ2 παίρνουν την τιμή 10 και η Κ3 την τιμή 20.
CHARACTER*7, NAME
DATA NAME/’FLORINA’/
Η αλφαριθμητική μεταβλητή ΝΑΜΕ παίρνει την τιμή ’FLORINA’.
DIMENSION I(20)
DATA I/15*5, 5*50/
Τα 15 πρώτα στοιχεία του πίνακα Ι θα πάρουν την τιμή 5 και τα υπόλοιπα 5 στοιχεία την τιμή 50.
CHARACTER*18, A
DATA A(1:7), A(8:12), A(13:18)/’FLORINA’, ‘ PER ‘, ‘SEMPRE’/
Η αλφαριθμητική μεταβλητή Α παίρνει σταδιακά την τιμή ’FLORINA PER SEMPRE’.
DIMENSION A(10, 10)
DATA ((A(I, J), J=1, 10), I=1, 10)/100*0./
Ο δισδιάστατος πίνακας Α μηδενίζεται κατά σειρές.
Με την εντολή SAVE μπορούμε να αποθηκεύουμε τις τιμές των τοπικών μεταβλητών των υποπρογραμμάτων ανάμεσα στις διαδοχικές κλήσεις τους.
Η σύνταξή της είναι ως εξής :
SAVE [A1, A2, …, An]
όπου τα Α1, Α2, …, An είναι ονόματα τοπικών μεταβλητών ή πινάκων και αν δεν υπάρχουν καθόλου ονόματα μεταβλητών, τότε αποθηκεύονται οι τιμές όλων των τοπικών μεταβλητών του υποπρογράμματος.
Ακολουθεί ένα παράδειγμα χρήσης της εντολής :
PROGRAM MAIN
…
DO I=1, 10
CALL SUB1(I)
END DO
END PROGRAM MAIN
SUBROUTINE SUB1(I)
SAVE A
IF (I==1) THEN
A=1
ELSE
A=A+1
END IF
WRITE(*, *) A
RETURN
END SUBROUTINE SUB1
Θα εκτυπωθούν οι τιμές 1 έως 10 για τη μεταβλητή Α, ενώ αν δεν υπήρχε η εντολή SAVE A, η τιμή της Α θα ήταν 0 κάθε φορά που Ι>1 και έτσι η μεταβλητή Α θα ήταν πάντα ίση με 1, γιατί 0+1=1.