Τρίτη, 23 Φεβρουαρίου 2016

Εγχειρίδιο της Μ2000 - Τεύχος 15ο

7. Τιμές και Παράμετροι (δυο διαφορετικές έννοιες).

Σε αυτό το κεφάλαιο θα δούμε κάτι παραπάνω για το τι λέμε τιμή, τι λέμε παράμετρο, τι λέμε παραστάσεις, εκφράσεις. Επίσης θα δούμε το γιατί η Μ2000 δεν δηλώνει στο όνομα τμημάτων και συναρτήσεων τον αριθμό παραμέτρων.

7.1. Περί τιμών

Η Μ2000 χρησιμοποιεί τιμές που γράφουμε στο κώδικα όπως 1234 ή "Γράμματα" με τρεις τρόπους:

  • Απόδοση Ονόματος σε Τιμή
  • Πέρασμα τιμής ως Παράμετρο
  • Άμεση Χρήση  

7.1.1 Απόδοση ονόματος σε Τιμή

Για την απόδοση τιμής με όνομα έχουμε δει τις γενικές/τοπικές μεταβλητές, τους γενικούς/τοπικούς πίνακες, τις μεταβλητές  μέλη γενικών/τοπικών/πτητικών (ανώνυμων) ομάδων, τις στατικές μεταβλητές τμημάτων/συναρτήσεων.
Για το πέρασμα τιμής σε παράμετρο έχουμε δει ότι αυτό γίνεται με πέρασμα της τιμής στο σωρό τιμών και με διάβασμα από το σωρό από την πλευρά αυτού που καλείται και να πώς:

Εδώ θα δούμε μερικές ειδικές περιπτώσεις τιμών.
Οι συνηθισμένες τιμές είναι οι Αριθμοί και τα Γράμματα.
Π.χ  το 1024 είναι αριθμός και το "Γιώργος" αλλά και το "1024" είναι γράμματα γιατί έχουν δυο σύμβολα ένα αρχής και ένα τέλους που λένε "ότι βλέπεις είναι απλά σειρές χαρακτήρων".

Για τα Αλφαριθμητικά, τα  σύμβολα αρχής και τέλους μπορεί να είναι τα διπλά εισαγωγικά ή οι αγκύλες (οι αγκύλες χρησιμοποιούνται και για μπλοκ εντολών, αλλά ο διερμηνευτής τις ξεχωρίζει και για αλφαριθμητικά). Στις αγκύλες μπορούμε να συμπεριλάβουμε κείμενο:
α$= { Αυτή είναι η πρώτη παράγραφος
            αυτή η δεύτερη
            αυτή η τρίτη
            }
Η θέση της αγκύλης στο τέλος καθορίζει πόσα διαστήματα θα αφαιρεθούν από την δεύτερη και μετά παράγραφο. Έτσι όλο το κείμενο μπορούμε να το μεταφέρουμε δεξιά με το Tab στον ενσωματωμένο διορθωτή κάνοντας το κώδικα ευανάγνωστο.

Για τους αριθμούς έχουμε αρκετές μορφές:

  • Ακέραιος: 100  -300 +50650  
  • Δεκαδικός 10.2342     .2442 (χωρίς μηδέν μπροστά) (βάζουμε πρόσημα αν θέλουμε)
  • Επιστημονική μορφή 1.23432e-54 1.23432ε-54 (το e δουλεύει και με το ελληνικό ε)
                                    Α=1.223222ε-45
                                    Τύπωσε Α

  • Δεκαεξαδική μορφή
                                    Α%= 0xFFFFFFFF
                                    Τύπωσε Α% ' 4294967295
                                    Δεκαεξ Α%



  • Χρώμα κατά Html με χρήση του # στην αρχή ενός εξαψήφιου δεκαεξαδικού.
                        Πένα 0x80000012 : Τύπωσε "Χρώμα"    \\ εδικά χρώματα των Windows
                        Πένα #33AADD : Τύπωσε "Χρώμα"  \\ RGB χρώματα
                        Α=#33AADD \\ we can use it like a number – return a negative number
                        Πένα 14 \\ 0 .. 15 τα βασικά των windows
                        Τύπωσε Δεκαεξ$(Α,3)
                        Α=Χρώμα(100,200,30) \\ RGB με τιμές στο δεκαδικό νούμερο

  • Ημερομηνία-Ώρα (δίνονται μέσω συναρτήσεων)
                  Μ=Σήμερα : Χ=Τώρα
                  Τύπωσε Γραφή$(Χ,"hh:mm:ss")
                  Τύπωσε Γραφή$(Μ,"yyyy/mm/dd")
                  Χ1= Υπωρα(Χ,3,30) \\ +3 ώρες και 30 λεπτά
                  Τύπωσε Γραφή$(Χ1,"hh:mm:ss")
                  Μ1=Υπμερ(Μ,0,100) \\100 μήνες από τώρα!
                  Τύπωσε Γραφή$(Μ1,"yyyy/mm/dd")
                  Τύπωσε Ημέρα$(Μ1) \\ κανονική έξοδος
                  Τύπωσε Χρόνος$(Χρόνος("10:20")) \\κανονική έξοδος σε ώρες και λεπτά μόνο!
                  \\ μπορούμε να δώσουμε το μμ γιατί έχουμε ελληνικά σαν γλώσσα.
                  Τύπωσε Κωδ("Γ")=195 ' αν δεν δώσει αληθές δεν έχουμε ελληνικά ως κύρια γλώσσα!
                  Αν Κωδ("Γ")=195 τότε {
                        Χ=Ημέρα("31/12/2000")+Χρόνος("10:30μμ") \\βάζουμε μια ημέρα & ώρα στο Χ
                  } Αλλιώς {
                        Χ=Ημέρα(γραφη$("2000 12, 31", "yyyy/mm/dd"))+Χρόνος("22:30")
                  }
                  Τύπωσε Γραφή$(Χ,"Long Date") \\ πάντα στα Ελληνικά!
                  Τύπωσε Ημέρα$(Χ)
                  Τύπωσε Χρόνος$(Χ) \\ δίνει 22:30
                  Τοπικό 1033
                  Τύπωσε Τοπικό$(55+10) ' October 1033
                  Τοπικό 1049
                  \\ Οκτώβριος επειδή η εφαρμογή έχει εξ ορισμού Ελληνικό Locale Id.
                  Τύπωσε Γραφή$(Ημέρα("2010/10/12"), "mmmm")
                  Τύπωσε Τοπικό$(55+Τιμή(Γραφή$(Ημέρα("2010/10/12"),"m") )) ' Октябрь 1049 Ρώσικα
                  


  • Μακρύς (Long) 32bit ακέραιος 
            Μακρύς Α=-1 \\μπορεί να είναι αρνητικός!
            \\ Μετατροπή τα bits του μακρύ σε δυαδικό χωρίς πρόσημο
            Τύπωσε Δεκαεξ$(Δυαδικό.Ακέραιο(Α),4) \\ FFFFFFFF
            \\ Μετατροπή δυαδικού (unsign) σε ακέραιο 32bit (sign)
            Α=Ακέραιο.Δυαδικό(0χFF00AA00)
            Τύπωσε 0χFF00AA00, Δυαδικό.Ακέραιο(Α)
            Δεκαεξ 0χFF00AA00, Δυαδικό.Ακέραιο(Α)
            Τύπωσε Α




 7.1.2 Περί Αριθμού/Τύπων Παραμέτρων 

Σε μια Συνάρτηση (εδώ σε μορφή μιας γραμμής) έχουμε τις παραμέτρους και τις τιμές σαν κάτι το ξεχωριστό:
Εδώ η τιμή είναι το 10, η παράμετρος είναι το Χ και η επιστροφή της συνάρτησης είναι μια παράσταση με την παράμετρο και διάφορες τιμές που τις λέμε σταθερές επειδή δεν αλλάζουν στη θέση που τις έχουμε στο κώδικα.

Κάνε άλφα(χ)=2*χ*2-5*χ+10
Τύπωσε άλφα(10)


Η εντολή Κάνε απλά φτιάχνει το παρακάτω σε μια γραμμή, παίρνει τις παραμέτρους που έχουμε στην παρένθεση και τις βάζει σε μια διάβασε.

Συνάρτηση άλφα {
      Διάβασε χ
      =2*χ*2-5*χ+10
}
Τύπωσε άλφα(10)

Ας δούμε με ένα απλό παράδειγμα τι κάνει ο διερμηνευτής:

Αν έχουμε κλήση συνάρτησης και περνάμε μια τιμή έστω 1234 τότε ο διερμηνευτής ετοιμάζει ένα αντικείμενο εκτέλεσης με το κώδικα της συνάρτησης, του αποδίδει έναν νέο σωρό τιμών και σε αυτόν βάζει το 1234  (αν είχαμε παράσταση θα έβαζε την τιμή που θα έβρισκε) και μετά ξεκινάει αυτό το αντικείμενο εκτέλεσης!
Η Μ2000 δεν αποτιμά την έκφραση όταν την παραδίδει σε μια παράμετρο, ούτε όταν η παράμετρος χρησιμοποιηθεί, αλλά πιο πριν, δηλαδή πρώτα αποτιμά όλες τις παραμέτρους και σώνει τις τιμές σε ένα σωρό που δίνεται στο αντικείμενο εκτέλεσής της και μετά είναι θέμα της συνάρτησης αν θα πάρει και πότε τις τιμές, Ό,τι δεν πάρει θα χαθεί μαζί με αυτόν τον σωρό. Στην συνάρτηση σε μια γραμμή (με την Κάνε) έχουμε άμεση απόδοση των τιμών στις παραμέτρους, επειδή δεν μπορούμε να βάλουμε κώδικα για να επέμβουμε στο σωρό.
Σε όλες τις περιπτώσεις που χρησιμοποιούμε μια συνάρτηση σε πολλές γραμμές με την Συνάρτηση { } μπορούμε να σκεφτούμε πώς θα "δράσουμε" στην επεξεργασία της εισαγωγής τιμών, πόσες και ποιες παραμέτρους χρειαζόμαστε, αν κάποια πρέπει να προηγηθεί για να προετοιμάσει το χώρο για να τακτοποιηθούν οι άλλες. Υπάρχει τρόπος για οκνηρή αποτίμηση με μεταφορά σε παράμετρο συνάρτηση που όταν θα χρησιμοποιηθεί, τότε θα αποτιμηθεί η παράσταση (έχω δώσει παραδείγματα με την Οκν$() από την λέξη Οκνηρή) και εδώ θα δούμε και άλλα.

Έχουμε δει την εντολή Ταύτιση() όπου  ένα Τάυτιση("ΓΑ") θα δώσει -1 (Αληθές) αν στην κορυφή του σωρού είναι αλφαριθμητικό (Γράμματα) και αμέσως μετά είναι αριθμός.
Επιπλέον μπορούμε να χρησιμοποιήσουμε τιμή από το σωρό για μια φορά χωρίς να την περάσουμε σε μεταβλητή (οι αριθμός και γράμμα$ κάνουν ακριβώς αυτό)

Τρέχουμε το m2000.exe και γράφουμε Σ Α(  και έτσι ανοίγει ο διορθωτής για να γράψουμε συνάρτηση (και έτσι η συνάρτηση γίνεται άμεσα γενική)

Αν ταύτιση("ΑΑ") τότε {
      =Αριθμός>Αριθμός
} Αλλιώς.ΑΝ ταύτιση("ΓΓ") τότε {
      =Γράμμα$>Γράμμα$
}

Δείτε λοιπόν ότι μπορούμε να δώσουμε αυτές τις δυο εντολές

Τύπωσε Α("Αλφα","Βήτα"), Α(1,2)

Δηλαδή καλέσαμε την Α() με δυο διαφορετικές ταυτότητες παραμέτρων,  δίνοντας από την μεριά της κλήσης τιμές και από την μεριά του κώδικα της συνάρτησης (που τρέχει κάθε φορά σε άλλο αντικείμενο εκτέλεσης) ελέγχουμε την ύπαρξη μιας "ταυτότητας" τιμών, και ανάλογα δίνουμε αποτέλεσμα. Σε άλλες γλώσσες αν θέλει κανείς να φτιάξει διαφορετικές Α() βάσει παραμέτρων γράφει ξεχωριστές και ο μεταφραστής βρίσκει από το τι παραμέτρους βάζουμε ποια από τις διαφορετικές Α() χρησιμοποιούμε. Εδώ έχουμε μια συνάρτηση αλλά με δυνατότητα να ελέγχει τι πήρε σε τύπους πριν καν τους αποδώσει σε μεταβλητές. Μια συνάρτηση μπορεί να έχει τμήματα, και επειδή τα τμήματα δέχονται το σωρό του πατρικού, μπορεί η συνάρτηση απλά να δει τι παραμέτρους έχει και να καλέσει ένα τμήμα αφήνοντας τον σωρό ως έχει. Τα τμήματα επιστρέφουν σε σωρό τιμές, ή μπορεί η συνάρτησή μας να δώσει μια μεταβλητή με αναφορά για το αποτέλεσμα. Έτσι παρέχοντας τον σωρό τιμών  και την μεταβλητή για επιστροφή έχουμε τμήματα που με ευκολία προγραμματιστικά θα βάλουμε.

Δυο ακόμα παρατηρήσεις: Μία είναι ότι δεν χρησιμοποιούμε εδώ μεταβλητές που με μια Διάβασε θα έπαιρναν τιμές και μια δεύτερη είναι ότι η επιστροφή τιμής είναι προκαθορισμένη να είναι αριθμητική ή αριθμητικός πίνακας ή αντικείμενο (δεν μπορούμε να το ξέρουμε αυτό αν δεν δούμε το κώδικα, και μπορεί να έχουμε και τα τρία αν θέλουμε, ανάλογα με την είσοδο).
Ας δούμε τον κώδικα με μεταβλητές και να μη γράψουμε τη συνάρτηση απ΄ευθείας στην λίστα τμημάτων/συναρτήσεων "επιπέδου 0",  δηλαδή να ανήκουν σε άλλη συνάρτηση ή άλλο τμήμα:

Συνάρτηση Α {
      Αν ταύτιση("ΑΑ") τότε {
            Διάβασε Α, Β
            =Α>Β
      } Αλλιώς.ΑΝ ταύτιση("ΓΓ") τότε {
            Διάβασε Α$, Β$
            =Α$>Β$
      }
}
Τύπωσε Α("Αλφα","Βήτα"), Α(1,2)

Με την χρήση των Αριθμός και Γράμμα$ "σηκώνουμε" άμεσα τιμές από το σωρό αλλά δεν τις καταχωρούμε. Μπορούμε βέβαια να βγάλουμε αντίγραφα με την εντολή Πάνω.

Άδειασε  ' Αδειάζουμε το σωρό για το παράδειγμα
Σειρά 10, 20 ' χρήση FIFO
\\ μπορούμε να αφαιρέσουμε την επόμενη γραμμή - δεν αλλάζει κάτι στη Τύπωσε
Σειρά 100, 200 ' πάνε στο τέλος του σωρού, το 200 ως τελευταίο στοιχείο
Πάνω 2 : Πάνω 2
Διάβασε Α1, Β1, Α2, Β2
Τύπωσε Α1, Β1, Α2, Β2


Η εντολή Πάνω 2 παίρνει το 20 και το φέρνει στην κορυφή άρα ο σωρός έχει το 20,10,20,100,200
Μετά μια όμοια εντολή παίρνει το 2ο που είναι το 10 και το περνάει "Πάνω" από τη κορυφή και το κάνει κορυφή 10,20,10,20,100,200
Η εντολή Πάνω αντιγράφει οτιδήποτε στοιχείο, πίνακες και αντικείμενα (που μπορούν να έχουν οτιδήποτε, άλλους πίνακες και άλλα αντικείμενα).

Πίνακας Α(20)=10
Βάλε Α()
Πάνω \\ τον διπλασιάζω
Α(3)=100
Διάβασε Γ(),Δ()
Τύπωσε Γ(3), Δ(3) ' 10    100
Α(3)=5000
Τύπωσε Γ(3), Δ(3) ' 10    100


Γιατί συμβαίνει το Γ(3) να έχει 10 και το Δ(3) να έχει 100; Διότι το Βάλε Α() έβαλε ουσιαστικά αναφορά στον Α() ενώ η Πάνω έφτιαξε νέο πίνακα και έβαλε μια νέα σειρά τιμών. Αλλάζοντας το Α(3) σε 100 δεν άλλαξε στο αντίγραφο. Όταν διαβάζω την Γ() τότε διαβάζω το αντίγραφο.
“η Διάβασε διαβάζει πάντα από την κορυφή του σωρού, η Βάλε βάζει πάντα στην κορυφή του σωρού, η Σειρά βάζει πάντα στο τέλος του σωρού.”
Όταν διαβάσω την Δ() τότε βγαίνει ένα αντίγραφο (όπως κάνει η Πάνω) αλλά για την Δ() μόνο. Η απόδειξη είναι στις επόμενες γραμμές. Αλλάζω την Α(3) σε 5000 και η Δ() δεν αλλάζει πια.
Γιατί γίνεται αυτό; Για να αποφεύγεται η διπλή αντιγραφή, μία με την Βάλε και μια με την Διάβασε. Με την Πάνω όμως κάνουμε στην ουσία διπλή αντιγραφή, αλλά αυτό θέλουμε!

Στη κλήση όμως μιας συνάρτησης ο σωρός είναι νέος, άρα δεν θα βρούμε εκεί κάτι που να είχε περάσει σε χρόνο πριν την κλήση. Άρα ουσιαστικά δεν μπορώ να δώσω μια Α(3)=100 πριν την κλήση συνάρτησης και εφόσον περάσω στο σωρό της τον πίνακα!  Αυτά γίνονται μόνο στα τμήματα που θα δούμε αργότερα! Μπορούμε όπου θέλουμε να βάζουμε μια εντολή Σωρός για να μας δείχνει τον τρέχοντα σωρό ή αν θέλουμε ξεκινάμε το πρόγραμμα με τη φόρμα της δοκιμής (γράψτε δοκιμή ή δοκιμή και το όνομα του τμήματος για να ανοίξει η φόρμα). Για την φόρμα αυτή θα δούμε σε επόμενο τεύχος.

7.1.2.1 Προαιρετικές Παράμετροι

Από την 8η έκδοση έχουμε προαιρετικές παραμέτρους:

Συνάρτηση Αλφα {
\\ αρχικές τιμές
      Χ=10
      Υ=5
\\ αν δεν υπάρχει τιμή αφήνει την αρχική
      Διάβασε ? Χ, Υ
      = Χ*Υ
}
Τύπωσε Αλφα() ' 50
Τύπωσε Αλφα(2) ' 10
Τύπωσε Αλφα(,2) ' 20
Τύπωσε Αλφα(2,3) ' 6



Θα μπορούσαμε να έχουμε δυο Διάβασε και η δεύτερη ή η πρώτη να ήταν προαιρετική (με το ?). Δηλαδή δεν μας υποχρεώνει κάτι να χρησιμοποιήσουμε με μια Διάβασε το πέρασμα παραμέτρων, και ούτε όλα να είναι προαιρετικά όπως στο παράδειγμα.

7.1.3 Πολλαπλή Εισαγωγή Τιμών και Εξαγωγή Στοιχείων

Αυτό που επιστρέφει μια συνάρτηση λέγεται στοιχείο, και αυτό το στοιχείο μπορεί να είναι η τιμή για μια παράμετρο σε μια άλλη συνάρτηση. Τα στοιχεία αν δεν περνάνε σε άλλες συναρτήσεις/τμήματα/ρουτίνες τότε αποθηκεύονται προσωρινά ή στο δίσκο σε αρχεία.
Για τα τμήματα αυτή είναι η πιο εύκολη υπόθεση επειδή δέχονται έναν σωρό κάνουν αλλαγές, επεξεργασία και σε αυτόν κάνουν επιστροφές (χώρια σε παραμέτρους που έχουμε περάσει με αναφορά). Ο συναρτήσεις κανονικά γυρνάνε μια τιμή, του τύπου που ορίζει το όνομά τους π.χ. Α() γυρνάει αριθμό, το Α%() γυρνάει ακέραιο (εσωτερικά είναι πραγματικός double), και τέλος το Α$() δίνει αλφαριθμητικό.  Ο διερμηνευτής δίνει προτεραιότητα στους πίνακες με το ίδιο όνομα. Τις συναρτήσεις μπορούμε να τις καλέσουμε με τις δυο συναρτήσεις Συνάρτηση() και Συνάρτηση$(). Η αν ξέρουμε ότι έχουμε πίνακα με το ίδιο όνομα βάζουμε το χαρακτήρα @ μετά την αριστερή παρένθεση:
Πίνακας Α(10)=30
Κάνε Α(χ)=χ**2

Τύπωσε Α(3) \ τυπώνει 30
Τύπωσε Συνάρτηση("Α",3) \\ 9
Τύπωσε Α(@ 3) \\ 9

Στο παρακάτω πρόγραμμα φτιάξαμε μια συνάρτηση που παίρνει από κανένα ως όσα θέλουμε στοιχεία, και τα βάζει σε έναν πίνακα. Επειδή ο πίνακας είναι αριθμητικός (έχουμε δει ότι όλοι οι πίνακες εσωτερικά είναι το ίδιο, έχουν στοιχεία τύπου variant που σημαίνει γίνονται ότι θέλουμε) θα βάλουμε το πρώτο στοιχείο αριθμό, το μηδέν.


Συνάρτηση ΈναςΠίνακας {
      Καθαρό Α$ \\ και έτσι ορίζουμε μια μεταβλητή
      Ενώ όχι κενό {
              Αν εινγρ τότε {
                  Α$=Α$+Παράθεση$(γραμμα$)
            } Αλλιώς {
                  Δες οκ {
                        Α$=Α$+γραφη$(αριθμός," #")
                    }
                  Αν όχι οκ τότε Α$=Α$+γραφη$(0, " #")
            }
      }
      \\ θυσιάζουμε το στοιχείο 0 για να είναι αριθμός πάντα
      \\ αφού η συνάρτηση θέλει το πρώτο στοιχείο αριθμό
      \\ και ίσως να μην έχουμε περάσει τίποτα
      Αν Α$="" τότε {
            Πίνακας Α(1)=0
            =Α()
      } αλλιώς {
            =παραμ(" 0"+Α$)
      }
}
Πίνακας Α(), Α1()
Α()=ΈναςΠίνακας(1,2,"Γεια Χαρά",3)
Ένωσε Α() στο Α$()
Τύπωσε Α(2), Α$(3)
Α1()=ΈναςΠίνακας()
Τύπωσε Α1(0)




Βλέπουμε ότι μια συνάρτηση μάζεψε τιμές και αντί να τις βάλει σε μεταβλητές τις έβαλε με ένα τρόπο σε ένα αλφαριθμητικό και τις πέρασε σαν να τις γράφαμε στο "=" στην επιστροφή της συνάρτησης (έχουμε δει ότι όλες οι συναρτήσεις μπορούν να επιστρέφουν παραπάνω από μια τιμή, και αυτό το κάνουν με πίνακα). Αν δεν δώσουμε τιμές τότε χωρίς το Αν Α$="" θα επέστρεφε μια τιμή, το 0 και όχι πίνακα. θέλουμε όμως να επιστρέφει πίνακα κάθε φορά και το κάνουμε αυτό δίνοντας στη περίπτωση που δεν έχουμε τιμές έναν πίνακα με ένα στοιχείο, με τιμή μηδέν.

Μπορούμε να συνεχίσουμε με αυτές τις εντολές:
Βάλε Α()
\\ χωρίς το παρακάτω θα έχουμε λάθος στην Διάβασε Α()
\\ Ο διερμηνευτής δεν αντιγράφει τον πίνακα Α()...στον εαυτό του, τον πίνακα Α()!
Πάνω : Φέρε 2 : Πέτα
Α()=ΈναςΠίνακας(1000,3452,"Γεια Χαρά και πάλι")
Τύπωσε Α(2), Α$(3)
Διάβασε Α()
Τύπωσε Α(2), Α$(3)


Βάζουμε τον πίνακα Α() στο σωρό. Ζητάμε στο σωρό να φτιάξει ένα αντίγραφο. Ζητάμε να φέρει το δεύτερο στοιχείο στην κορυφή. Ζητάμε να το πετάξει!
Τώρα ο πίνακας Α() θα αλλάξει τιμές αντιγράφοντας τις τιμές του πίνακα. Δεν θα αλλάξει αντικείμενο. Θα δούμε το "Γεια Χαρά και Πάλι". Όμως στην Διάβασε Α() ο πίνακας αλλάζει άμεσα αντικείμενο. Δείτε ότι το Α$() δεν έχασε την αναφορά στο Α$(). Αν δεν είχαμε κάνει την Πάνω/Φέρε/Πέτα τότε η αναφορά του πίνακα στο σωρό θα έδειχνε τον πίνακα στο Α(), που θα έχει αλλάξει με το Α()=ΈναςΠίνακας(...) και στη Διάβασε θα του λέγαμε βάλε στην Α() μια αντιγραφή από τον εαυτό του!
Αυτό που είδαμε είναι στην ουσία αντιγραφή τιμών σε πίνακα από πίνακα η οποία φαίνεται άμεσα και σε όσους πίνακες έχουμε συνδέσει (με την Ένωση)
Είδαμε επίσης ότι μπορούμε να περνάμε τιμές σε συναρτήσεις και να γίνονται παράμετροι με όνομα ή να χρησιμοποιούνται άμεσα, χωρίς όνομα.

7.1.4 Επαγωγικό Πέρασμα Τιμής!

Ο σωρός τιμών σε Συνάρτηση θα διαγραφεί στην επιστροφή από αυτήν, έτσι αν κάποιος περάσει τιμές που δεν θα χρειαστούν τότε θα πεταχτούν, δηλαδή δεν βγαίνει λάθος.
Θα μπορούσε κανείς να εκτελέσει πρόγραμμα πριν κληθεί μια συνάρτηση, και εφόσον έχουν περάσει οι παράμετροι σε αυτήν, και πριν το αντικείμενό της εκτελεστεί.

Αν προσέξει κανείς τον κώδικα,  την εξαγωγή των Α_συν1() και Α_συν2() δεν την χρησιμοποιούμε. Η συνάρτηση "Κάτι" επιστρέφει τιμή πάνω σε μια Α που άλλαξε από μια από αυτές τις δύο, οι οποίες δόθηκαν υποτίθεται για εισαγωγή τιμής! Όμως έγινε αλλά μέσω τις αλλαγής μιας γενικής. Αυτός ο τρόπος, δηλαδή πέρασμα τιμής μέσω γενικής είναι αυτό που λέω εδώ "επαγωγικό πέρασμα τιμής".

Γενική Α=100
Συνάρτηση Α_συν1 {
            Α++
            \\ αν δεν επιστρέψουμε τιμή θα δοθεί το 0
}
Συνάρτηση Α_συν2 {
            Α+=2
}
Συνάρτηση Κάτι {
      =Α**2
}


Τύπωσε Κάτι(Α_συν1()), Α
Τύπωσε Κάτι(Α_συν2()), Α
Τύπωσε Κάτι(Α_συν1()), Α
Τύπωσε Κάτι(Α_συν2()), Α


ή θα μπορούσε να φτιάξει αυτό (η Οκν$()  έχει αναφερθεί στο τεύχος 8, στην παρ. 4.9). Η Α δεν είναι πια γενική, και οι συναρτήσεις που έχουν γίνει ανώνυμες έχουν την ιδιαιτερότητα όταν εκτελεστούν να βλέπουν ονόματα (όχι όμως σωρό) από το τμήμα/συνάρτηση που δημιουργήθηκαν (η Οκν$() το κάνει αυτό). Θα μπορούσαμε να είχαμε μια γενική Α αλλά οι συναρτήσεις αυτές δεν θα την έβλεπαν. Επιπλέον μπορούμε να στείλουμε τα αλφαριθμητικά που κρατάνε τις συναρτήσεις

Α=100
Συνάρτηση Α_συν1 {
            Α++
}
Συνάρτηση Α_συν2 {
            Α+=2
}
Συνάρτηση Κάτι {
      =Α**2
}
Κάτι$=Οκν$(&Κάτι())
Α_συν1$=Οκν$(&Α_συν1())
Α_συν2$=Οκν$(&Α_συν2())
Τύπωσε Συνάρτηση(Κάτι$, Συνάρτηση(Α_συν1$)), Α
Τύπωσε Συνάρτηση(Κάτι$, Συνάρτηση(Α_συν2$)), Α
Τύπωσε Συνάρτηση(Κάτι$, Συνάρτηση(Α_συν1$)), Α
Τύπωσε Συνάρτηση(Κάτι$, Συνάρτηση(Α_συν2$)), Α


Συνεχίζω το παραπάνω:
Α=100
Τμημά ΔοκιμασέΜε {
      Διάβασε &Α(), &Β(), &Γ()
      \\ εδώ η Α είναι άγνωστη
      Τύπωσε Α(Β())
      Τύπωσε Α(Γ())
      Τύπωσε Α(Β())
      Τύπωσε Α(Γ())
      Τύπωσε Έγκυρο(Α) \\0
}
ΔοκιμασέΜε Κάτι$, Α_συν1$, Α_συν2$


Τώρα έστειλα τις ανώνυμες συναρτήσεις στο τμήμα ΔοκιμασέΜε και εκεί τους έδωσα όνομα. Η Α δεν υπάρχει στο τήμα ΔοκιμασέΜε, Όμως και οι τρεις συναρτήσεις βλέπουν την Α (και οι Β και Γ την αλλάζουν) που είναι τοπική στο τμήμα που κάλεσε την ΔοκιμασέΜε()
Αυτό λέγεται κλείσιμο ή Closure, και η Μ2000 μπορεί να το κάνει προς τα κάτω σωστά αλλά όχι προς τα πάνω, δηλαδή να στείλει την Κάτι$ ως επιστροφή από το τμήμα - θα δούμε πώς ένα τμήμα επιστρέφει τιμές παρακάτω-  αλλά όταν θα τρέξει, η Α δεν θα υπάρχει, και θα βγει λάθος.

7.1.5 Παράδειγμα με Ομάδα (Αντικείμενο)


Ομάδα Άλφα {
Ιδιωτικό:
      Α=100
      Συνάρτηση Α_συν1 {
                  ++
      }
      Συνάρτηση Α_συν2 {
                  +=2
      }
      Συνάρτηση Κάτι {
            =**2
      }
Δημόσιο:
      Τμήμα ΠάρεΑ {
            Διάβασε .Α
      }
      Συνάρτηση Κάτι_1 {
            =.Κάτι(.Α_συν1())
      }
      Συνάρτηση Κάτι_2 {
            =.Κάτι(.Α_συν2())
      }
}
Για Άλφα {
      Τύπωσε .Κάτι_1()
      Τύπωσε .Κάτι_2()
      Τύπωσε .Κάτι_1()
      Τύπωσε .Κάτι_2()
}
Άλφα.ΠάρεΑ 100
Τμημά ΔοκιμασέΜε {
      Διάβασε δείκτης$
      Για δείκτης$ {
            Τύπωσε .Κάτι_1()
            Τύπωσε .Κάτι_2()
            Τύπωσε .Κάτι_1()
            Τύπωσε .Κάτι_2()
      }


}
ΔοκιμασέΜε &Άλφα


Εδώ έχουμε ένα αντικείμενο και το περνάμε μόνο με ισχνή αναφορά. Θα ήταν κανονική έτσι:

Τμημά ΔοκιμασέΜε {
      Διάβασε &Βήτα
      Για Βήτα {
            Τύπωσε .Κάτι_1()
            Τύπωσε .Κάτι_2()
            Τύπωσε .Κάτι_1()
            Τύπωσε .Κάτι_2()
      }
}


Δηλαδή με την διάβασε καθορίζουμε αν κάνουμε μια αναφορά κανονική άμεσα ή αν θα την κρατήσουμε ως ισχνή (γράφοντάς την σε ένα αλφαριθμητικό), για μελλοντική χρήση. Αν καλούσαμε μια φορά την Δοκίμασέ με τότε ο δεύτερος τρόπος, της κανονικής αναφοράς θα ήταν οκ, αλλά επειδή με αυτό το τρόπο δημιουργούμε τα στοιχεία της ομάδας μέσα στο τμήμα ΔοκίμασέΜε, σε μια επαναληπτική διαδικασία 100 φορών θα είχαμε 100 δημιουργίες μελών της ομάδας Βήτα, ενώ με το Δείκτης$ θα έχουμε 100 φορές μόνο το Δείκτης$. Μια άλλη διαφορά είναι ότι ο δείκτης βλέπει σαν γενικό αυτό που δείχνει άρα περάσματα τιμών σε απλές μεταβλητές ακολουθούν τους κανόνες των γενικών με "<=" για αντικατάσταση τιμών. Επιπλέον με την χρήση δείκτη μπορούμε να περάσουμε στοιχείο πίνακα που δεν μπορεί να βγει κανονική αναφορά (οι κανονικές έχουν σχέση με τα ονόματα, και τα στοιχεία πίνακα, μόνο στο πίνακα έχουν όνομα). Αν ο δείκτης δείχνει κάτι που δεν υπάρχει θα το καταλάβουμε στο Για ενώ αν δεν υπάρχει στην περίπτωση με τη χρήση της Βήτα θα το καταλάβουμε στην Διάβασε &Βήτα. Ουσιαστικά κάθε φορά που χρησιμοποιούμε την ισχνή αναφορά, γίνεται έλεγχος, και αυτό στην περίπτωση με την Βήτα γίνεται μια φορά. Αυτό δεν σημαίνει ότι χρησιμοποιώντας την Βήτα δεν γίνεται έλεγχος αν υπάρχει η Βήτα! Ο διερμηνευτής δουλεύει με ελέγχους, τόσο στα ονόματα όσο και στους δείκτες πινάκων.

Δεν υπάρχουν σχόλια:

Δημοσίευση σχολίου