Κυριακή 6 Δεκεμβρίου 2015

Επέκταση με Ισχνές Αναφορές Ι (Έκδ.8.Αναθ.104)

Κύριες διορθώσεις:
1. Τονισμένη ελληνική εντολή δεν εμφανίζονταν με ctrl+f1 στη βοήθεια, στο διορθωτή
2. Χρήστης ΈναΌνομα τώρα δουλεύει σωστά!
3. Βελτιώσεις στον χρωματισμό (τώρα στην αντιγραφή τμήματος γραμμής ή της πρώτης γραμμής με αρχή μετά το πρώτο χαρακτήρα βγαίνει σωστά το χρώμα στο στόχο (π,χ, στο word ή στο chrome σε blog ή φόρουμ που υποστηρίζει το html format)
4. Νέες εντολές για ισχνές αναφορές: ισχνή$()  weak$() εκφρ$() eval$()   (παράγουν αναφορές)
Επεκτάθηκαν ένωση, link, συνάρτηση(), function(), συνάρτηση$(), function$() εκφρ(), eval()   (δέχονται ισχνές αναφορές)

Στο πρώτο παράδειγμα κάνουμε μια μέτρηση ταχύτητας (στο παράδειγμα όλες οι μεταβλητές είναι με λατινικούς χαρακτήρες για να ξεχωρίζουν).
Φτιάχνουμε ένα πίνακα 30 στοιχείων από 0 έως 29 με τιμή σε κάθε στοιχείο το 10
Φτιάχνουμε μια ισχνή αναφορά στο στοιχείο 4 (το 4 μένει μέσα στην αναφορά, αν είχαμε μια έκφραση, π.χ. 6-2 θα είχε εκτελεστεί και το 4 θα έπαιρνε τη θέση του). Χρησιμοποιούμε το Ισχνή$()  ή Weak$()
Δείτε τώρα πως μπορώ να χρησιμοποιώ το k1$, την ισχνή αναφορά απευθείας στο δεξιό μέρος μιας εντολής αλλαγής τιμής. Δείτε ότι έχει μια τελεία ακριβώς μετά το $.
Εδώ αυξάνω την τιμή κατά 1
Η Ισχνή αναφορά ουσιαστικά έχει την διεύθυνση του στοιχείου όπως την γνωρίζει ο διερμηνευτής. 
Μια κανονική αναφορά θα ήταν να είχαμε ένα νέο όνομα πίνακα και να δίναμε σε αυτόν το 4 και θα μας έδινε την ίδια τιμή:
            Πίνακας a(30)=10
            Ένωσε a() στο b()
            b(4)++
            Τύπωσε b(4)
            \ η ένωση κάνει αυτό:
            Βάλε &a() : Διάβασε &c()
            Τύπωσε c(4)

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

Στην ισχνή αναφορά οι δείκτες γίνονται ένα με το όνομα. Δεν δημιουργούμε νέα μεταβλητή με αναφορά αλλά κρατάμε μια διεύθυνση που μας αρκεί για να αναφερθούμε σε αυτό που θέλουμε. Π.χ. εδώ κρατάμε το συγκεκριμένο a(4) στο συγκεκριμένο τμήμα. Στην Τύπωσε μας δείχνει ακριβώς τι κρατάμε.

Για να κάνουμε τη μέτρηση έχουμε τον Αναλυτή και το Φόρτο. Η πρώτη εντολή ρυθμίζει το μετρητή και η δεύτερη μεταβλητή μόνο ανάγνωσης (Φόρτος) μας δίνει το χρόνο (είναι σε msec και τα δεκαδικά που παίρνουμε είναι από την διαίρεση της πραγματικής τιμής σε nanosecond με το 1000)

Το έργο (το φορτίο) θα είναι μια επανάληψη 999 φορές μιας αλλαγή τιμών των στοιχείων a(4) και a(6).  Θα γίνει με πέντε τρόπους:

Ο πρώτος τρόπος γίνεται με μια τρίτη μεταβλητή

Ο δεύτερος τρόπος γίνεται με χρήση της ισχνής αναφοράς και μιας τρίτης μεταβλητής . Δείτε το Εκφρ() που χρησιμοποιούμε για να πάρουμε την τιμή. Η έκφρ() παίρνει π,χ, "12+4" και δίνει 16. Η ισχνή αναφορά είναι έκφραση, χωρίς πράξεις και έτσι γίνεται να πάει στην αριστερή πλευρά -(δεξιά λέμε τη πλευρά που διαβάζουμε, αριστερή που βάζουμε κάτι π.χ. το Α=Β, στα αριστερά, στο Α βάζουμε, ενώ στα δεξιά, το Β το διαβάζουμε, και το αντιγράφουμε στο Α, που όπως είδαμε βάζουμε τιμή - γράφω πώς στο μυαλό μας πρέπει να το σκεφτόμαστε)

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

Ο τέταρτος τρόπος σχετίζεται με τον τρίτο. Δηλαδή και εδώ η Άλλαξε (Swap) χρησιμοποιείται, αλλά κατασκευάζουμε την εντολή προσθέτοντας τις δυο ισχνές αναφορές και έτσι έχουμε μια k3$ μεταβλητή και την οποία καλούμε με μια Ένθεση (Inline) που κάνει το αλφαριθμητικό κώδικα που παρεμβάλει και τον τρέχει!

Ο πέμπτος τρόπος έχει την ίδια ταχύτητα με τον δεύτερο. Κάνουμε ότι στο τέταρτο αλλά μέσα στην  k3$ βάζουμε και την δομή Για. Έτσι σε κάθε επανάληψη δεν χρειάζεται να διαβάζει την k3$, τα έχει όλα δηλαδή σαν να είχαμε τον κώδικα χωρίς αναφορές.

Τέλος φτιάχνουμε ένα τμήμα το ΚάτιΆλλο και βλέπουμε πως δουλεύουν οι ισχνές αναφορές. Αυτό που περνάμε είναι τα δυο αλφαριθμητικά. Αντί να τα διαβάσουμε σε δυο μεταβλητές, τα διαβάζουμε άμεσα με την Γράμμα$ (letter$) η οποία σηκώνει από την κορυφή του σωρού παραμέτρων ένα αλφαριθμητικό (αν δεν υπάρχει ή αν δεν είναι αλφαριθμητικό βγαίνει λάθος).
Κανονικά στο τμήμα ΚάτιΆλλο  δεν εμφανίζεται ο πίνακας a(). Όμως οι ισχνές αναφορές χρησιμοποιούν την κανονική ονομασία του πίνακα, με το πρόθεμα του τμήματος ή συνάρτησης που ανήκουν (εδώ να δούμε ότι οι ρουτίνες που μπορούν να υπάρχουν σε ένα τμήμα δεν βάζουν το δικό τους όνομα ως πρόθεμα αλλά το όνομα του τμήματος που ανήκουν, και έτσι μπορούν να βλέπουν τις μεταβλητές του τμήματος ως δικές τους. Όταν δε κάνουμε τοπικές αυτές πάλι έχουν το πρόθεμα του τμήματος αλλά σκιάζουν τυχόν υπάρχουσες με το ίδιο όνομα, επειδή είναι πιο "φρέσκες". Όταν η ρουτίνα τερματίσει ..οι φρέσκες χάνονται και επανέρχονται οι παλιές που γίνονται οι νέες φρέσκες. Να γιατί οι ρουτίνες αν και μοιάζουν με τα τμήματα..δεν είναι τμήματα)

Πίνακας a(30)=10
k1$=Ισχνή$(a(4))
k1$.++
Τύπωσε Έκφρ(k1$)
k2$=Ισχνή$(a(2))
Τύπωσε Έκφρ(k2$)


Αναλυτής
Για i=1 Έως 999 {
      a=a(2):a(2)=a(4):a(4)=a
}
Τύπωσε Φόρτος
Τύπωσε a(2), a(4)


Αναλυτής
Για i=1 Έως 999 {
      a=Έκφρ(k2$) :k2$.=Έκφρ(k1$):k1$.=a
}
Τύπωσε Φόρτος
Τύπωσε a(2), a(4)


Αναλυτής
Για i=1 Έως 999 {
      Άλλαξε a(2),a(4)
}
Τύπωσε Φόρτος
Τύπωσε a(2), a(4)


k3$=μορφη$("Άλλαξε {0},{1}",k1$, k2$)

Αναλυτής
Για i=1 Έως 999 {
      Ένθεση k3$
}
Τύπωσε Φόρτος
Τύπωσε a(2), a(4)


k3$=μορφη$("Για i=1 Έως 999 {Άλλαξε {0},{1}}",k1$, k2$)
Αναλυτής
Ένθεση k3$
Τύπωσε Φόρτος
Τύπωσε a(2), a(4)



Τμημα ΚάτιΆλλο {
      Ένθεση μορφη$("Για i=1 Έως 999 {Άλλαξε {0},{1}}",γράμμα$,γράμμα$)
}
Αναλυτής
ΚάτιΆλλο k1$, k2$
Τύπωσε Φόρτος
Τύπωσε a(2), a(4)


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

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

You can feel free to write any suggestion, or idea on the subject.