Δευτέρα, 26 Φεβρουαρίου 2018

Εκτέλεση Παραστάσεων και Κλήση συνάρτησης.

Ακολουθεί ένα παράδειγμα που σχετίζεται με την εκτέλεση παραστάσεων, με το σωρό τιμών στο πρώτο μέρος, και στο δεύτερο καθαρά σε σχέση με τις προτεραιότητες τελεστών. Η εντολή Διακόπτες λειτουργεί στη κονσόλα, αλλά μπορούμε να την καλέσουμε με την Θέσε Διακόπτες και σε τμήμα (πρόγραμμα της Μ2000). Εδώ την χρησιμοποιούμε για να αλλάξουμε το εξ ορισμού τρόπο χρήσης των Διά και Υπόλ ή Υπόλοιπο (και των Δια# και Υπόλ# ή Υπόλοιπο#, για ευκλείδια διαίρεση και υπόλοιπο). Ο εξ ορισμού διακόπτης είναι ο -DIV. O +DIV κάνει την Μ2000 να λειτουργε όπως η Python και το Excel.
Η χρήση προσήμου είναι ίδια όπως στο Excel, δηλαδή το -3^2 δίνει 9 (ενώ η VB6 δίνει -9)


\\ Μέρος Πρώτο
\\ Κατανόηση του σωρού τιμών κατά την κλήση
\\ Σκοπός είναι να αντιληφθεί ο αναγνώστης ότι αυτός που καλεί διαβάζει τον τρέχον σωρό

\\ Η συνάρτηση που καλείται έχει δικό της τρέχον σωρό.
\\ Θέλουμε να εκτελέσουμε αυτό Κύβος(1+Κύβος(2)+Κύβος(3))
\\ αλλά τα 1,2,3 θα τα πάρουμε από το σωρό τιμών, απευθείας με την Αριθμός
\\ η Αριθμός σηκώνει την κορυφή του σωρού, αν είναι αριθμός αλλιώς βγάζει λάθος.
\\ "σηκώνει" σημαίνει εδώ ότι επιστρέφει την τιμή ενώ αυτή δεν υπάρχει πια στο σωρό
\\ ο σωρός θα δείχνει την επόμενη, ως νέα κορυφή, αν υπάρχει αλλιώς θα είναι κενός.
Άδειασε
Συνάρτηση Κύβος(κ) {
      Σειρά 1,2,3
      =κ**Μέγεθος.Σωρού
      \\ τα επιπλέον νούμερα θα χαθούν με την επιστροφή από τη συνάρτηση
}
Σειρά 1,2,3
\\ η αριθμός διαβάζει από τη κορυφή του σωρού
\\ η κορυφή εδώ είναι το 1
Σωρός  ' μας δείχνει το σωρό
\\ Ο διερμηνευτής πάντα εκτελεί από αριστερά προς τα δεξιά,
\\ ενώ κρατάει τις προτεραιότητες όπως πρέπει
\\ εδώ θα καλέσει την Κύβος αλλά δεν θα την εκτελέσει αν δε δώσει το αποτέλεσμα της έκφρασης
\\ η έκφραση διαβάζει πρώτα την κορυφή του σωρού (της εντολής όχι της Κύβος())
\\ μετά εκτελεί την πρόσθεση στέλνοντας την υπόλοιπη έκφραση για εκτέλεση
\\ έτσι ξεκινάει η εκτέλεση του Κύβος(Αριθμός)+Κύβος(Αριθμός), με το τρέχον σωρό
\\ βρίσκει πάλι την Κύβος() και ξεκινάει να εκτελέσει την έκφραση που βρίσκει,
\\ και εδώ είναι μόνο η αριθμός, άρα διαβάζει το 2 και εκτελεί την Κύβος()
\\ μετά βλέπει το + και ξεκινάει να εκτελεί την υπόλοιπη έκφραση Κύβος(Αριθμός)
\\ Πάλι εδώ βρίσκει την Κύβος() και εκτελεί την έκφραση εντός των παρενθέσεων,
\\ δηλαδή την Αριθμός και τραβάει το 3 από το σωρό.
\\ Τώρα το αποτέλεσμα της Κύβος(3) θα επιστραφεί και θα προστεθεί στο
\\ αποτέλεσμα της Κύβος(2) και αυτό θα επιστραφεί και θα προστεθεί στο 1
\\ το αποτέλεσμα αυτό θα γινει ο αριθμο που θα μπει στη Κύβος(),
\\ και θα μας δώσει το αποτέλεσμα 46656
Τύπωσε Κύβος(Αριθμός+Κύβος(Αριθμός)+Κύβος(Αριθμός)) ' 46656
Τύπωσε Κύβος(1+Κύβος(2)+Κύβος(3))
Τύπωσε (1+2**3+3**3)**3
Τύπωσε (1+2^3+3^3)^3 ' η δύναμη γράφεται και με ^
Σειρά 1,2,3
Τύπωσε (Αριθμός+Αριθμός^3+Αριθμός^3)^3
\\ πρώτα εκτελείται η παρένθεση και μετά η ύψωση σε δύναμη
\\ και η συνάρτηση το ίδιο κάνει αλλά την "γνωρίζει" ο διερμηνευτής,
\\ πριν εκτελέσει τα περιεχόμενα στις παρενθέσεις, και την εκτελεί αφού μαζέψει τις τιμές
\\ και τις βάλει σε ένα σωρό μόνο γι' αυτήν.
\\ Εδώ με χρήση της Βάλε, οπότε η κάθε τιμή πάει στη κορυφή
\\ άρα πάνε "ανάποδα", το 3 στη κορυφή, αμέσως μετά το 2 και τελευταίο το 1
\\ δηλαδή το πρώτο που θα μπει θα βγει τελευταίο.
Βάλε 1, 2, 3
\\ η κορυφή εδώ είναι το 3
Σωρός
Τύπωσε Κύβος(Αριθμος+Κύβος(Αριθμός)+Κύβος(Αριθμός)) ' 1728
Τύπωσε Κύβος(3+Κύβος(2)+Κύβος(1)) ' 1728

\\ Εσκεμμένο λογικό λάθος
\\ εξ ορισμού δεν γίνεται έλεγχος για τον αριθμό και τον τύπο των τιμών που δίνουμε στις κλήσεις
\\ στην συνάρτηση όμως αν η Διάβασε περιμένει αριθμό και διαβάσει αλφαριθμητικό θα βγάλει λάθος
\\ όμως αν δώσουμε και άλλες παραμέτρους και δεν τις διαβάσει ο κώδικας ...
\\ θα μείνουν εκεί μέχρι να καταργηθεί ο σωρός (καταργείται στην επιστροφή από τη συνάρτηση),
\\ η αν σβηστούν πιο πριν με μια άδειασε
Τύπωσε Κύβος(3,0)
\\ Δίνει 81 γιατί εξαρτιέται η δύναμη από το μήκος του σωρού.
\\ Εδώ βάλαμε μια παράμετρο παραπάνω, άρα έχουμε τέσσερις όταν διαβάζουμε το μέγεθος του σωρού
\\ και ισοδυναμεί με αυτό
Τύπωσε 3*3*3*3=81 ' δίνει -1 δηλαδή αληθές
\\ Μέρος Δεύτερο
\\ Σκοπός είναι να αντιληφθεί ο αναγνώστης ότι το διάβασμα του κώδικα, γίνεται από αριστερά προς τα δεξιά, ενώ η εκτέλεση των παραστάσεων γίνεται μετά το διάβασμα την ώρα που πρέπει!
\\ Ο διερμηνευτής:
\\ 1. Κάνει πρώτα ένα γρήγορο πέρασμα από αριστερά προς τα δεξιά, χωρίς να εκτελέσει κώδικα,
\\ ούτε να δει αν τα αναγνωριστικά είναι σωστά, απλά για να διαπιστώσει τι παράσταση υπάρχει: αριθμητική ή αλφαριθμητική,
\\ και που τελειώνει.
\\ 2. Περνάει την παράσταση για εκτέλεση στον εκτελεστή παραστάσεων ανάλογα, για αριθμούς ή για αλφαριθμητικά.
\\ Αυτοί εκτελούν με ένα πέρασμα, και ενδέχεται να καλέσουν και άλλες φορές τον ένα ή τον άλλο
\\ Γίνεται χρήση της Reentrant ή Επανεισόδου, που σημαίνει ότι πριν τελειώσει η συνάρτηση εκτέλεσης παραστάσεων μπορεί να κληθεί ξανά,
\\ και θα λειτουργήσει με άλλες τοπικές μεταβλητές. Μεταβλητές τοπικές δηλαδή που κρατάει λογαριασμό για τις μέχρι εκείνη τη στιγμή εκτελέσεις πράξεων.
\\ Ο διερμηνευτής εκτελεί σωστά τις εκφράσεις, βάσει προτεραιοτήτων, τις οποίες δεν τις υπολογίζει προκαταβολικά, αλλά είναι ο κώδικας έτσι γραμμένος που βγαίνουν!
\\ Πάντα διαβάζει το κώδικα από αριστερά προς τα δεξιά, παρόλο που στην επιστροφή κάνει τα απαραίτητα
\\ για να διατηρεί τις προτεραιότητες, αποθηκεύοντας τιμές σε τοπικές μεταβλητές μια συνάρτησης εκτέλεσης.
\\ εδώ θέλουμε το 2^2 να εκτελεστεί ως 4 και μετά το 10*4 να δώσει 40,
\\ επειδή η δύναμη έχει μεγαλύτερη προτεραιότητα από το γινόμενο
\\ Πάλι ο διερμηνευτής εκτελεί από αριστερά προς δεξιά, δείτε πώς:
\\ Πρώτα βρίσκει το 10 και το βάζει στην άκρη. Μετά βρίσκει το "*" που δηλώνει γινόμενο και το βάζει και αυτό στην άκρη
\\ μετά βρίσκει το 2 και το βάζει και αυτό στην άκρη. Αν δεν έχει τίποτα άλλο θα δώσει το 10*2
\\ βλέπει όμως ότι έχει την ύψωση σε δύναμη. Θα δει αν μετά το σύμβολο έχει παρένθεση,
\\ αν ναι τότε θα εκτελέσει την έκφραση στη παρένθεση και το αποτέλεσμα θα είναι η δύναμη που θα υψώσει το 2,
\\ θα βρει το αποτέλεσμα και θα εκτελέσει το γινόμενο με το 10, και τώρα πάει για το επόμενο,
\\ θα βρει το + και θα εκτελέσει την έκφραση (4*4). Θα βρει την παρένθεση, και θα εκτελέσει την έκφραση 4*4
\\ θα βρει το 4 και θα το βάλει στην άκρη, θα βρει το * και θα το βάλει στην άκρη, θα βρει το 4 και θα εκτελέσει τον πολλαπλασιασμό,
\\ με αποτέλεσμα 16, θα πετάξει το κλείσιμο παρένθεσης ")", και το νούμερο θα επιστραφεί,
\\ έτσι θα προστεθεί στο προηγούμενο 40 και θα δώσει 56.
Τύπωσε 10*2^2+4*4 ' 56
Τύπωσε 10*(2^2)+(4*4) '56
Τύπωσε (10*2)^2, 10*2^2, 10*(2^2) ' 400 40 40
\\ Οι συγκρίσεις έχουν μεγαλύτερη προτεραιότητα από τις πράξεις
\\ και εδώ η εκτέλεση θα γίνει από αριστερά προς τα δεξιά
\\ και πάλι όμως θα κρατηθούν μερικά αποτελέσματα για να βγουν οι προτεραιότητες
Τύπωσε 2*-3*2+100=2*(-(3*2))+100
Τύπωσε 2*+3*2+100=2*(+(3*2))+100
Τύπωσε 2*--3*2+100=2*(--(3*2))+100
Τύπωσε 2*--3*2+100=2*(-(-(3*2)))+100
Τύπωσε 2+3*2+100=2+(3*2)+100
Τύπωσε 2+3*-2+100=2+(3*(-2))+100
\\ Οι λογικοί τελεστές έχουν μεγαλύτερη προτεραιότητα από τις πράξεις και από τις συγκρίσεις
Τύπωσε 2+3*-2+100=2+(3*(-2))+100 Και Ψευδές ' δίνει 0
\\ Ο διερμηνευτής της Μ2000 δεν χρειάζεται πολλές παρενθέσεις
\\ Επειδή πάντα εκτελεί με τον ίδιο τρόπο, από αριστερά προς τα δεξιά, δεν υπάρχει μπέρδεμα.
Τύπωσε 2+3*-2+100=2+3*-2+100 Και 1000-900-50=1000-900-50 ' δίνει -1
Τύπωσε 2+3*-2+100=2+(3*(-2))+100 Και 10*5=1000-900-50 ' δίνει -1
Τύπωσε (2+3*-2+100=2+(3*(-2))+100) Και ((10*5)=(1000+(-900)+(-50))) ' δίνει -1
Τύπωσε "Α"<"α" ' Δίνει αληθές  -1
Τύπωσε "Α"<"α" Ή 5>100 ' Δίνει αληθές -1 γιατί το πρώτο είναι αληθές
\\ Αφού εκτελεστεί η πρώτη παράσταση, η Τύπωσε βρίσκει το κόμμα και κοιτάει αν υπάρχει άλλη
\\ το κόμμα στην Τύπωσε δεν λέει υποχρεωτικά πάρε άλλη τιμή, απλά μεταθέτει σε νέα στήλη...
\\ το δρομέα της οθόνης ή της σελίδας του εκτυπωτή, ή σε ένα επίπεδο που το χρησιμοποιούμε για εξαγωγή.
\\ Κάθε παράθυρο χρήστη έχει ένα επίπεδο και η Κονσόλα έχει 32 ακόμα, συν το περιθώριο και τη σελίδα του εκτυπωτή 34.
Τύπωσε "Α"<"α" Ή 5>100, "Α">"α" Ή 5<100 ' δίνει και τα δύο αληθές
\\ Εξ ορισμού ο διακόπτης DIV είναι στο -DIV
\\ Αν τον αλλάξουμε σε +DIV τότε το Υπολ και το Δια έχουν την ίδια προτεραιότητα με το / και το *
\\ Οπότε θα πάρουμε διαφορετικά αποτελέσματα!
Θέσε Διακόπτες "-DIV"
\\ Το Υπόλοιπο διαίρεσης έχει μεγαλύτερη προτεραιότητα από το / και το *
\\ Το Υπολοιπο επιστρέφει τιμές όπως στην Visual Basic 6 αν δουλεύει με ακέραιες τιμές
\\ (στη Μ2000 δουλεύει και με πραγματικούς)
Τύπωσε 103 Υπολ 8/2 = 103 Υπόλοιπο 4 ' δίνει -1, Υπολ και Υπόλοιπο και Υπολοιπο είναι το ίδιο
Τύπωσε 103 Υπολ 8=103 Υπόλοιπο (10-2) ' δίνει -1

Τύπωσε 103 Υπολ 8=103 Υπόλοιπο 10-2 ' δίνει 0
\\ Η δύναμη συνεχίζει να έχει μεγαλύτερη προτεραιότητα
Τύπωσε 103 Υπολ 2**2=103 Υπόλ 16/2**2 ' δίνει -1
Τύπωσε (103 Υπολ (2**2))=(103 Υπόλ (16/(2**2))) ' δίνει -1
Τύπωσε 103 Υπολ 2**3=103 Υπόλ 16/2 ' δίνει -1
Τύπωσε 103 Υπολ 16/2=7 ' -1
Τύπωσε 3 Υπολ 2, -3 Υπολ 2, 3 Υπολ -2, -3 Υπολ -2
Τύπωσε 3 Υπολ# 2, -3 Υπολ# 2, 3 Υπολ# -2, -3 Υπολ# -2 ' Ευκλείδιο υπόλοιπο, είναι πάντα θετικό
Θέσε Διακόπτες "+DIV"
\\ Δουλεύει όπως στην Python, το * και / έχουν ίδια προτεραιότητα με το Υπόλοιπο
\\ Το Υπόλοιπο ή Υπολ δουλεύει όπως του Excel η συνάρτηση Mod()  (με +DIV στην Μ2000)
Τύπωσε 103 Υπολ 16/2=3.5 ' -1
Τύπωσε 3 Υπολ 2, -3 Υπολ 2, 3 Υπολ -2, -3 Υπολ -2
Τύπωσε 3 Υπολ# 2, -3 Υπολ# 2, 3 Υπολ# -2, -3 Υπολ# -2 ' Ευκλείδιο υπόλοιπο, είναι πάντα θετικό

Θέσε Διακόπτες "-DIV"  ' το επαναφέρουμε
\\ Περί προσήμων η Μ2000 ακολουθεί το σύστημα του Excel και όχι της VB6
Τύπωσε -3^2 ' δίνει 9 και όχι -9 γιατί το - είναι το πρόσημο του 3
Τύπωσε 0-3^2 ' δίνει -9 και όχι 9 γιατί το - είναι η αφαίρεση
Τύπωσε 0-++++-3^2=0-++++(-3^2) ' -1 αληθές
Τύπωσε 0-++++-3^2=0-+--+(-3^2) ' -1 αληθές
Τύπωσε ---2, --2, -2 ' -2 2 -2
Τύπωσε 0---2, 0--2, 0-2 ' -2 2 -2
Τύπωσε 0-3^2, 0-(--3^2), 0-(---3^2) ' -9 -9 -9
Τύπωσε 0-3^2, 0---3^2, 0----3^2 ' -9 -9 -9
Τύπωσε 0+3^2, 0+--3^2, 0+---3^2 ' 9 9 9  ' ο πρώτος τελεστής είναι η πράξη, οι άλλοι δίνουν το πρόσημο
Τύπωσε 0+3^3, 0+--3^3, 0+---3^3 ' 27 27 -27  ' ο πρώτος τελεστής είναι η πράξη, οι άλλοι δίνουν το πρόσημο
Τύπωσε 10-3^2 ' δίνει 1  το - είναι η αφαίρεση
Τύπωσε 10+-3^2 ' δίνει 19  το - είναι το πρόσημο του 3
Τύπωσε --(25)=-5*-5 ' -1