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

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

7.2. Κλήσεις Τμημάτων/Συναρτήσεων

Είδαμε ότι μπορούμε να περάσουμε τιμές σε παραμέτρους, ενός τμήματος ή μιας συνάρτησης, και είδαμε ότι η ιδέα "αλλάζω τιμή παραμέτρου" δεν δηλώνει μόνο την αλλαγή αυτή ως κάτι άμεσο όπως στο f(3) στο f(x)=x^2, αλλά και ως κάτι που γίνεται εκτός του κώδικα της συνάρτησης, και αυτό μπορεί να είναι σε μια γενική μεταβλητή ή αντικείμενο ή να έχουμε περάσει το περιβάλλον με "επαγωγικό" τρόπο (η αλλαγή προκαλείται έμμεσα, σε άλλο χώρο).
Στο παράδειγμα η συνάρτηση Ψ μπορεί να αλλαχτεί (να τροποποιήσουμε το κώδικα για να πετύχουμε κάτι καλύτερο), αλλά ο κώδικας των Κάτι$() και Κάτι2$() δεν χρειάζεται να πειραχτεί. Οι δυο συναρτήσεις παίρνουν συνάρτηση για τιμή παραμέτρου. Η Οκν$() τις έχει μετατρέψει έτσι ώστε το περιβάλλον που θα τρέξουν να είναι αυτό του αρχικού τμήματος σε ότι έχει να κάνει με τα ονόματα, ενώ ο σωρός τιμών είναι ξεχωριστός. Έχει γίνει αναφορά σε αυτό που αναφέρω ως επαγωγικό πέρασμα, αλλά εδώ η διαφορά είναι ότι η παράμετρος Α δεν βρίσκεται και στις δυο πλευρές, σε αυτόν που καλεί και σε αυτόν που καλείται, αλλά μόνο σε αυτόν που καλεί, και αυτός που καλείται μπορεί να περάσει πίσω μια τιμή σε μια παράμετρο (εδώ φάκελο$) και να πάρει βάσει αυτής ένα αποτέλεσμα.

Α=0
Συνάρτηση Ψ$ {
      Α++
      Αν Ταύτιση("Γ") τότε {
            Διάβασε Φάκελο$
            =Μορφή$("{0} Αρ. Εγγραφής {1}", Φάκελο$, Α)
      } Αλλιώς {
            =Μορφή$("Αρ. Εγγραφής {0}",Α)
      }
}
Συνάρτηση Κάτι$ {
      Διάβασε α$
      ="Κάτι γίνεται εδώ:"+Συνάρτηση$(α$)
}
Συνάρτηση Κάτι2$ {
      Διάβασε α$
      ="Κάτι γίνεται εδώ:"+Συνάρτηση$(α$, "Τομέας1")
}
Τύπωσε Κάτι$(Οκν$(&Ψ$()))
Τύπωσε Κάτι2$(Οκν$(&Ψ$()))

7.2.1 Αντικείμενο Εκτέλεσης

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

Έτσι ό,τι φτιάξουμε σε παράμετρο, εκεί που καταχωρούμε τιμές που δίνουμε κατά τη κλήση, ανήκουν πια στο αντικείμενο εκτέλεσης. Ο πηγαίος κώδικας ΔΕΝ έχει δεδομένα! Αν το αντικείμενο καλέσει ένα τμήμα τότε δημιουργείται άλλο αντικείμενο εκτέλεσης.

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

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

Τα νήματα υλοποιούνται με αντικείμενα εκτέλεσης, που καλούνται στον διερμηνευτή από μια εξωτερική πηγή κλήσεων (ένα χρονιστή όπως λέμε, που καλεί τακτικά ένα άλλο σημείο εισόδου στον διερμηνευτή). Ο διερμηνευτής της Μ2000 όταν εκτελείται είναι ένα αντικείμενο εκτέλεσης. ενώ το αρχείο στο δίσκο καλούμε για να τρέξει είναι η πηγή (ο κώδικας για να τρέξει).

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

7.2.2 Γραμμή Εκτέλεσης Αντικειμένων Εκτέλεσης.

Πρώτα ας κατανοήσουμε πως οι ρουτίνες δεν είναι αντικείμενα εκτέλεσης. Έχουν ένα "παράθυρο" για προσωρινές μεταβλητές όπως εδώ η X, και το παράθυρο αυτό κλείνει όταν τερματίσουν (και διαγράφονται ότι προσωρινό όνομα δημιουργήσαμε). Το αντικείμενο εκτέλεσης εδώ είναι αυτό που φτιάχτηκε στην κλήση του Άλφα (ακριβώς μετά την εντολή Αλφα 10 και πριν ξεκινήσουμε την Διάβασε Α. Αν αντί για 10 είχαμε μια κλήση σε συνάρτηση τότε πριν την κλήση του Άλφα γίνεται η κλήση της συνάρτησης σε άλλο αντικείμενο εκτέλεσης. Όπως έχουμε γράψει το πρόγραμμα φαίνεται ότι ανήκει σε ένα άλλο τμήμα (έστω το Α), άρα το Αλφα 10 καλέστηκε από το αντικείμενο του Α. Στο επίπεδο 0, δηλαδή στην γραμμή εντολών όπου γράψαμε το Α για να το καλέσουμε έχουμε επίσης το αρχικό αντικείμενο εκτέλεσης. 
Άρα όταν τρέχει το Άλφα έχουμε:

Βασικό Αντικείμενο -> Αντικείμενο Α και -> Αντικείμενο Άλφα
Όταν καλούμε τη ρουτίνα  κ()  τότε ακόμα είμαστε στο Άλφα. Αυτό που αλλάζει είναι ότι το αντικείμενο γράφει το σημείο επιστροφής στο κώδικα και τις επιστροφές τις κρατάει σε ένα δικό του σωρό επιστροφών. Η Μ2000 έχει σωρό (στοίβα την λένε άλλοι) επιστροφών από ρουτίνες ανά αντικείμενο εκτέλεσης. Αν μια ρουτίνα καλέσει τον εαυτό της απλά θα χρησιμοποιηθεί αυτός ο σωρός. Τα αντικείμενα εκτέλεσης έχουν δικό τους σωρό (στοίβα ή Stack) επιστροφών, που έχει να κάνει με το βασικό return/parameter stack του exe αρχείου. Είναι δηλαδή πιο "σοβαρά" αλλά περιορίζονται (μέχρι 3350κλήσεις, είναι το όριο της εκδοσης 8.5 - κατέβηκε γιατί υπήρχε πρόβλημα με το άνοιγμα ιστοσελίδων...δεν μπορούσαν να ανοίξουν με μεγάλο σωρό επιστροφών, δεν ξέρω το γιατί αλλά έτσι συμβαίνει). Ρουτίνες μπορούμε να βάλουμε ανά τμήμα/συνάρτηση, και μπορούμε στον ίδιο πηγαίο κώδικα να βρίσκονται ως κώδικας σε άλλο τμήμα και πάλι θα την βρει από εκεί το σύστημα (δηλαδή οι ρουτίνες δεν ανήκουν στο σύστημα που δεσμεύει τα ονόματα με το όνομα του τμήματος, σε αυτό που λέμε όνομα χώρου ή name space). Οι ρουτίνες βλέπουν κανονικά τμήματα/συναρτήσεις/ μεταβλητές/ αντικείμενα , όπως οι άλλες εντολές στο τμήμα που κλήθηκαν. Στην έκδοση 8.6 οι ρουτίνες αναζητούνται μια φορά και καταγράφεται η εύρεσή τους, ώστε κάθε άλλη φορά να γνωρίζει ο διερμηνευτής τι θα πάρει χωρίς αναζήτηση. Σε περίπτωση που ανοίξουμε για διόρθωση το τμήμα απ΄όπου έχει καταγράψει τις θέσεις στις ήδη ζητημένες ρουτίνες (μπορεί να γίνει και σε φάση εκτέλεσης αυτό), τότε σβήνεται ο κατάλογος και δημιούργειται κατά την αναζήτηση άλλος. Επίσης ισχύει το Τμήμα Αλφα (Α) { } ισοδύναμο με το Τμήμα Αλφα { Διάβασε Α }, την αλλαγή την κάνει κατά τη δημιουργία ο διερμηνευτής (διαβάζει το (Α) που είναι ξεχωριστό από το όνομα Άλφα και βάζει μια νέα γραμμή Διάβασε Α. Αυτό ισχύει και για τις Συναρτήσεις, τους τελεστές και τις ειδικές Θέσε και Αξία για που δίνουν στις Ομάδες τιμές.


Τμήμα Αλφα {
      Διάβασε Α
      κ(&Α)
      Τύπωσε Α
      λ()
      Τύπωσε Α
      \\ εδώ γίνεται έξοδος
      \\ αν βρεθεί η εντολή Ρουτίνα στη ροή...
      \\ ...λειτουργεί ως Έξοδος
      Ρουτίνα κ(&Χ)
            Χ+=100
      Τέλος Ρουτίνας
      Ρουτίνα λ()
            Α+=100
      Τέλος Ρουτίνας
}


Άλφα 10


Έχουμε δει την Για αντικείμενο { } και την χρήση της με πολλές φωλιασμένες και την χρήση των τελειών στην αρχή των ονομάτων. Η χρήση ρουτίνας δεν "μηδενίζει" την σειρά των τελειών, οπότε αν χρησιμοποιηθεί αυτό το χαρακτηριστικό σε μια ρουτίνα που καλεί τον εαυτό της θα βγει λάθος αν μέσα στην ρουτίνα έχουμε μια Για {} Ή θα βγει λάθος αν καλούμε από διαφορετικά επίπεδα φωλιασμένων για μια ρουτίνα όπου έχουμε καθορίσει το επίπεδο με τον αριθμό των τελειών που χρησιμοποιούμε:

Τμήμα Άλφα {
      Ομάδα Α {
            Α$="οκ"
            Ομάδα Β {
                  Κ=1, Λ=3, Μ=2
            }
      }
      Μ=Α \\ φτιάχνω ένα αντίγραφο του Α
      Για Μ.Β {
            =300
            =100
            =50
      }
      Για Μ {
            Τ(.Β)
            Για .Β {
                  Τ1()
                  Τ(.Β)
            }
      }
      Για Α, { Τ1() }
      Δες οκ {
            Για Α.Β { Τ1() } \\ λάθος γιατί η Τ1() περιμένει σε 2ο Επίπεδο
      }
      Αν Λάθος τότε Τύπωσε Λάθος$ \\ Άγνωστη μεταβλητή Κ
      Τ(Α.Β)
      Ρουτίνα Τ(Χ)
            \\ χωρίς χρήση των επιπέδων με τις πολλαπλές τελείες.
            Τύπωσε Χ.Κ, Χ.Λ, Χ.Μ
      Τέλος Ρουτίνας
      Ρουτίνα Τ1()
            \\ περιμένει σε 2ο επίπεδο
            \\ τα επίπεδα σχετίζονται με το αντικείμενο εκτέλεσης!
            Τύπωσε ., ..Λ, ..Μ
      Τέλος Ρουτίνας
}
Άλφα


Η  χρήση χαρακτηριστικών που σχετίζονται με το αντικείμενο εκτέλεσης μας δίνει πλεονεκτήματα αλλά μπορεί να μας οδηγήσει σε λάθη αν δεν ξέρουμε  τι γίνεται με αυτά!

7.2.3 Όνομα Τμήματος και εντολή Κάλεσε

Τα τμήματα (κάποιοι θα τα έλεγαν διαδικασίες, αλλά αυτό μάλλον ως μια γενική θεώρηση) στην Μ2000 έχουν δυο ιδιαιτερότητες:

  • Το όνομα ενός τμήματος κατά την εκτέλεση μπορεί να αλλάξει.
  • Ο σωρός τιμών μεταβιβάζεται από το τμήμα που καλεί στο τμήμα που καλείται και επιστρέφεται σε αυτόν που καλεί.

Παράδειγμα αλλαγής ονόματος, έστω το τμήμα λέγεται Α:
Στατική Α$="Πέτρος", Β$="Μήτσος"
Τμήμα Α$
Στη Α=1000, Β=2345, Γ$="Γεια χαρά"
Τύπωσε Α, Β, Γ$
Τμήμα Β$
Στη Α=1050, Β=125, Γ$="Γεια χαρά πάλι"
Τύπωσε Α, Β, Γ$
Τμήμα Α$
Τύπωσε Α, Β, Γ$


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

Μπορούμε να δούμε το όνομα του τμήματος (ισχύει και σε συνάρτηση αυτό)
Έστω ότι το παρακάτω είναι γραμμένο στο τμήμα Β
Τμήμα Α {
      Τύπωσε Τμήμα$
}
Α
Κάλεσε Α \\ εδώ θα μας δείξει άλλο όνομα


Θα πάρουμε δυο ονόματα
Στην απλή κλήση θα πάρουμε το Α
Στην ειδική κλήση με την Κάλεσε θα πάρουμε το Β[1]

Παρατηρούμε ότι με το δεύτερο τρόπο δεν υπάρχει το Α, ως όνομα αντικειμένου (το αντικείμενο καταγράφει χωριστά το αρχικό όνομα και που είναι ο πηγαίος κώδικας). Ο δεύτερος τρόπος δίνει το πλεονέκτημα της κλήσης στον εαυτό (αναδρομή). Κανονικά μέσα από το Α  μια  κλήση στο Α θα βγάλει λάθος, γιατί το Α δεν φαίνεται στο Α...είναι έξω από τους ορισμούς του, είναι εκτός χώρου ονομάτων του (name space). (Οι συναρτήσεις έχουν εξ ορισμού την αναδρομή, χωρίς ειδικό τρόπο)

Σε ένα τμήμα Α γράφουμε το παρακάτω. Κάνουμε μια κανονική κλήση στο Β και δυο ειδικές μετά.

Τμήμα Β {
Τμήμα ΚΛΜ {
      Τμήμα Α {
            Τύπωσε Τμήμα$
      }
      Α
      Κάλεσε Α \\ εδώ θα μας δείξει άλλο όνομα
}
Κάλεσε ΚΛΜ
}
Β


Θα πάρουμε:
Στην απλή κλήση θα πάρουμε το Α
Στην ειδική κλήση με την Κάλεσε θα πάρουμε το Β[2]
Το Β[1] είναι η ΚΛΜ και το Β[2] είναι Α στο Β[1]. Οι μεταβλητές που θα δημιουργήσουμε μέσα στα τμήματα θα έχουν πρόθεμα ένα όνομα τμήματος, Υπάρχει περίπτωση κάποιος να κάνει αυτό, σε ένα τμήμα Α:

ΑΛΦΑ=100
Τμήμα Β {
      Τμήμα Α {
            Τμήμα Β {
                  Τμήμα Α {
                      ? ΑΛΦΑ 
                  }
                  Α
            }
            Β 
      }
      Α
}
Β


Η εσωτερική Α είναι η Α.ΑΛΦΑ και υπάρχει Α.ΑΛΦΑ πιο πριν! Αν την καλέσουμε ως Α αλλά αν την καλέσουμε με Κάλεσε Α τότε το όνομα της Α γίνεται Α[1] και η εσωτερική Α ψάχνει για Α.ΑΛΦΑ, δεν βρίσκει και βγάζει λάθος. Θα έλεγε κανείς εδώ ότι η γλώσσα έχει θέμα. Όμως αυτό που συμβαίνει είναι ότι δεν έχουμε χρησιμοποιήσει όλα τα όπλα της Μ2000 γιατί μας βόλευε, ενώ τώρα δεν μας βολεύει, άρα:

ΑΛΦΑ=100
Τμήμα Β {
      Τμήμα Α {
            Τμήμα Β {
                  Τμήμα Α {
                      Τοπική ΑΛΦΑ=12345
                      Τύπωσε ΑΛΦΑ 
                  }
                  Α
            }
            Β
      }
      Α
}
Β
Τύπωσε ΑΛΦΑ


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

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

Τμήμα Δ {
      Τμήμα Α {
           ΑΛΦΑ=100
            Τμήμα Β {
                  Τμήμα Α {
                     Τοπική ΑΛΦΑ
                      Διαβασε ΑΛΦΑ
                      Τύπωσε ΑΛΦΑ
                  }
                  Α 12345
            }
            Β
            Τύπωσε ΑΛΦΑ
      }
      Α
}
Δ

Αν αφαιρέσουμε το Τοπική ΑΛΦΑ θα έχουμε αλλαγή στην πιο εξωτερική ΑΛΦΑ (αφού και οι δύο θα είναι οι Α.ΑΛΦΑ).

7.2.4 Κλήση τμήματος στο ίδιο τμήμα (Αναδρομή)Γίνεται να καλέσει ένα τμήμα τον εαυτό του! Με τη κλήση με το όνομα δεν γίνεται. Πρέπει να γίνει με την Κάλεσε επειδή αυτή αλλάζει όνομα σε αυτό που καλεί!

Τμήμα κλμ {
      Διάβασε Ν
      Αν Ν>1 Τότε κάλεσε κλμ, Ν-1
      Τύπωσε Ν
}

κλμ 10

Συνάρτηση κλμ {
      Διάβασε Ν
      Αν Ν>1 Τότε κάλεσε κλμ(Ν-1)
      Τύπωσε Ν
}

Κάλεσε κλμ(10)

7.2.5 Κλήση με την Κάλεσε Τμημάτων στην ίδια σειρά εκτέλεσης.

Η εντολή κάλεσε κάνει μερικά ωραία πράγματα, αν χρησιμοποιείται διαδοχικά, σε μια σειρά εκτέλεσης. Δεν βάζει μαζί το χώρο μεταβλητών και τις συναρτήσεις, αλλά δίνει τρόπο να βρούμε ένα τμήμα αν δεν υπάρχει ήδη στο "χώρο" μας, και αυτό που βρίσκει είναι ο πηγαίος κώδικας για να φτιάξει νέο αντικείμενο εκτέλεσης.

Τμήμα λλ {
            Τύπωσε "λλ", αριθμός
      }
Τμήμα κάτιακόμη {
      Τμήμα γγ {
            Τύπωσε "γγ"
      }
      Συνάρτηση λα {
            Τύπωσε "λα"
            Κάλεσε λλ, 2
            Κάλεσε γγ
      }
      Συνάρτηση ββ {
            Τύπωσε "ββ"
            Κάλεσε λλ, 1
            Κάλεσε γγ
      }
      Κάλεσε ββ() 
      Κάλεσε λα()
}
Κάλεσε κάτιακόμη


Αν δεν είχε μπει το Κάλεσε στο κάτιακόμη το τμήμα λλ δεν θα φαινόταν με Κάλεσε μέσα στο τμήμα κάτιακόμη (αυτό γίνεται γιατί η κάλεσε αλλάζει το όνομα του τμήματος). Μια κλήση στη λλ μέσα από την κάτιακόμη χωρίς την Κάλεσε θα δώσει λάθος Μπορούμε να καλέσουμε και συναρτήσεις. Αλλά δεν μπορούμε να καλέσουμε μέσα από συνάρτηση άλλη συνάρτηση! Μόνο τμήμα!

Το ίδιο πρόγραμμα χωρίς τις Κάλεσε θα έπρεπε για να δουλέψει να έχει Γενικά τμήματα το λλ και το γγ.

Τμήμα Γενικό λλ {
            Τύπωσε "λλ", αριθμός
      }
Τμήμα κάτιακόμη {
      Τμήμα Γενικό γγ {
            Τύπωσε "γγ"
      }
      Συνάρτηση λα {
            Τύπωσε "λα"
            λλ 2
            γγ
      }
      Συνάρτηση ββ {
            Τύπωσε "ββ"
            λλ 1
            γγ
      }
      Α=ββ() 
      Β=λα()
}
κάτιακόμη


7.2.6 Κλήση συναρτήσεων με τη Κάλεσε

Και οι συναρτήσεις καλούνται με Κάλεσε Συνάρτηση (ή με τις παρενθέσεις όπως στο παράδειγμα πάνω). Όμως όχι όπως τα τμήματα (δηλαδή όχι όπως στο 7.2.5)

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

Συνάρτηση γ {
      Τύπωσε "..από τη γ"
      =100
}
Κάλεσε κενή συνάρτηση γ
\\ δεν δίνει λάθος
Δες {
Κάλεσε συνάρτηση γ
\\ δίνει λάθος 100
}
Επίλεξε Με Λάθος
Με 100 
      Τύπωσε "Έχουμε Λάθος"
Αλλιώς
      Τύπωσε "Όλα Καλά"  \\ μόνο μια εντολή αλλιώς για πολλές βάζουμε μπλοκ
Τέλος Επιλογής
Τύπωσε Λάθος \\ είναι μηδέν, η μεταβλητή σβήνει αν διαβαστεί!


Δείτε εδώ το παράδειγμα και τις εναλλακτικές εκδοχές του (αφαιρέστε τις σημειώσει, μια φορά την 1 και μια άλλη την 2)


Άδειασε
Συνάρτηση Κ {
      Διάβασε Ν
      \\ μεταβιβάζουμε το σωρό στην Κ
      Αν Ν>1 Τότε Κάλεσε Συνάρτηση Κ, Ν-1
Σημ 1 : Αν Ν>-1 Τότε Κάλεσε Συνάρτηση Κ, Ν-1
      \\ μη μηδενικός αριθμός σημαίνει λάθος σε κλήση συνάρτησης με Κάλεσε.
      Αν Ν<1 τότε =1035 
Σημ 2 : Αν Ν>1 Τότε =Κ(Ν-1)
      Βάλε Ν
      Τύπωσε Ν, 
}
\\ Αντί για Κάλεσε Συνάρτηση μπορούμε να δίνουμε και αυτό
\\ Κάλεσε Κ(5)
Δες οκ {
      Κάλεσε Συνάρτηση Κ, 5
}
\\ η Δες πιάνει λάθη μέσα στη Δες Οκ { }
\\ η οκ γίνεται ψευδές αν το λάθος είναι στο μπλοκ και όχι σε κάτι που κάλεσε το μπλοκ
\\ Για να το δούμε αυτό πρέπει να εξετάτουμε την Λάθος.


Αν Λάθος Τότε Τύπωσε Λάθος$

Ενώ Όχι Κενό { Τύπωσε Αριθμός, }
Τύπωσε
Δες Οκ {
      Κάλεσε Συνάρτηση Κ, 0
}
Αν Λάθος Τότε Τύπωσε Λάθος$


7.2.7 Ορισμός Στατικής Μεταβλητής με το "@" (παλιός τρόπος για στατικές)

Σε παλαιότερες εκδόσεις της Μ2000 υπήρχε ένας τρόπος να ορίσουμε μια μεταβλητή που θα δημιουργηθεί και θα φαίνεται σαν μεταβλητή τμήματος. Αυτό γίνεται και στην 8 (έχει κρατηθεί για λόγους συμβατότητας). Στηρίζεται στην ιδέα ότι η μεταβλητή έχει το όνομα του τμήματος. Εφόσον όμως δεν έχει κληθεί το τμήμα Λ με μια Κάλεσε

Λ@Β=5
Τμήμα Λ {
      Τύπωσε Β
}
Λ

ή

Τμήμα ΜΜ {
      Λ@Β=5
      Τμήμα Λ {
            Τύπωσε Β
      }
      Λ
}
Κάλεσε ΜΜ

Το διαφορετικό με αυτή την Β είναι ότι το όνομά της ανήκει στο όνομα χώρου της Λ όχι στο αντικείμενο εκτέλεσης (όπως στις στατικές μεταβλητές). Και εδώ δεν μπορούμε να ορίσουμε πίνακες!

Δείτε εδώ ένα παλιό πρόγραμμα (από εκεί σκέφτηκα να φτιάξω αντικείμενα για τη Μ2000)

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

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