Κυριακή 9 Αυγούστου 2015

Copy In - Copy Out

Διαβάζω για την ΓΛΩΣΣΑ του Λυκείου ότι έχει χρησιμοποιηθεί η τεχνική του Copy in - copy out στις διαδικασίες. Ουσιαστικά αυτή η τεχνική έχει νόημα όταν μιλάμε για πέρασμα τιμής σε καταχωρητή (ίσως και αλλού αλλά εδώ θα το προσπεράσω). Δηλαδή όταν ο μεταφραστής πρέπει να χρησιμοποιήσει μια παράμετρο τύπου μεταβλητής και μπορεί να τον μεταφέρει σε ένα εσωτερικό καταχωρητή που δουλεύει πολύ πιο γρήγορα από την μνήμη τότε κάνει ένα αντίγραφο στο καταχωρητή και όταν τελειώσει την διαδικασία ότι τιμή έχει ο καταχωρητής σώνεται ξανά στη μεταβλητή. Αν κάποιος περάσει με αναφορά την ίδια μεταβλητή δυο φορές και εφόσον ο μεταφραστής βρει δυο καταχωρητές, τότε μπορεί να βάλει την ίδια τιμή και ότι αλλαγές γίνουν η μεταβλητή θα πάρει την τελευταία από το σώσιμο του τελευταίου καταχωρητή! Γιατί να το κάνει κάποιος αυτό; Η ιδέα που διαβάζω (άλλων) είναι ότι στην πολυεπεξεργασία (η ΓΛΩΣΣΑ δεν έχει τέτοιο πράγμα), ενδέχεται να αλλάξει κάποιος τιμή σε μια μεταβλητή ενώ αυτή "δουλεύει" σε μια διαδικασία, περασμένη με αναφορά. Τα συστήματα πολυεπεξεργασίας δεν δουλεύουν έτσι ατάκτως ριγμένα, κοινές αποθήκες (πίνακες ας πούμε) δεν διαβάζονται από όλους αλλά με αιτήματα, κάνεις αίτημα, και περιμένεις τη σειρά σου για να πάρεις τιμές. Η Μ2000 χρησιμοποιεί κάτι ανάλογο με τα semaphores δηλαδή έχει μπλοκ εντολών που μπορούν να τρέξουν όταν μια μεταβλητή λέει "οκ", και την ώρα που τρέχουν αυτή η μεταβλητή λέει "οχι οκ" δηλαδή οποιοδήποτε άλλο μπλοκ εντολών με την ίδια μεταβλητή χειρισμού δεν μπορεί να τρέξει.
To Κ εδώ το φτιάχνει η Μερος {} ως μεταβλητή
\\ semaphore Κ
Μερος {
      τυπωσε Κ
      τυπωσε "εδώ τυπώνει"
      μερος {
            τυπωσε "δεν τυπώνει ποτέ"
      } ως Κ
} ως Κ

Όμως σαν άσκηση ας δούμε πως γίνεται στην Μ2000 η Copy-in Copy-out. Βάζω στα αγγλικά τα ονόματα των τμημάτων για να δείξω το πέρασμα όπως λέγεται (By Value με τιμή, By Reference με αναφορά). χρησιμοποιώ την αύξηση με το ++   (ίδιο με το +=1). Στην πρώτη περίπτωση περνάμε με τιμή άρα η α παραμένει ως έχει με τιμή μηδέν. Στη δεύτερη περίπτωση περνάμε με το τρόπο της ΓΛΩΣΣΑΣ δηλαδή με αντιγραφή στην είσοδο (copy in) και στην έξοδο (copy out). Εδώ βλέπουμε ότι η α πήρε την τελευταία τιμή που αλλάξαμε, το 1. Στην τελευταία περίπτωση, την κανονική για πέρασμα με αναφορά, έχουμε τιμή στο α το 2 γιατί δυο φορές αλλάξαμε την α, επειδή έχουμε δυο μεταβλητές που αναφέρονται στην α, άρα δυο ενέργειες ++ έδωσαν λογικά το 2.

τμημα ByValue {
       διάβασε α, β
      α++
       β++
}
τμημα ByReference {
       διάβασε,
      α++
       β++
}
τμημα CopyInCopyOut {
       Διάβασε,
      Στη α1=α, β1=β \\ copy in
       α1++
       β1++
       Στη α=α1, β=β1 \\ copy out
}
α=0
ByValue α, α
Τύπωσε α \\ 0
α=0
CopyInCopyOut &α,
Τύπωσε α \\ 1
α=0
ByReference &α,
Τύπωσε α \\ 2


Και επειδή είναι ωραίο να βλέπουμε και μια άλλη εικόνα στο πρόγραμμα, να μαθαίνουμε και κάτι, θα μπορούσε κανείς να φτιάξει μια συνάρτηση (φεύγουμε από τις διαδικασίες ή τμήματα στην Μ2000) που να αλλάζει την συμπεριφορά μιας συνάρτησης που την καλούμε ως τμήμα (γίνονται αυτά στην Μ2000).
Εδώ λοιπόν έχουμε δυο συναρτήσεις που παίρνουν τιμές με αναφορά, την Πρόσθεσε1 και την Πρόσθεσε2. Μπορούμε να τις καλέσουμε απευθείας, ώστε να αλλάζουν τιμές "κανονικά" ή να τις καλέσουμε μέσω μιας άλλης συνάρτησης που αλλάζει το πέρασμα με αναφορά σε πέρασμα CopyInCopyOut. Εδώ χρησιμοποιούμε την αναφορά σε συνάρτηση (δεν υπάρχει στη ΓΛΩΣΣΑ).
Η αναφορά σε συνάρτηση είναι μια αντιγραφή συνάρτησης οπότε στην Διάβασε &Συν2() φτιάχνεται μια νέα συνάρτηση με τον ορισμό που βρίσκει στο σωρό! Πραγματικά εδώ είναι μια copy in διαδικασία (χωρίς να έχει έννοια η copy out αφού δεν αλλάζουμε τον ορισμό της συνάρτησης που περνάμε με αναφορά). Στη βιβλιογραφία το πέρασμα με αναφορά πολλές φορές μπορεί να είναι πέρασμα με τιμή...απλά και μόνο επειδή οι έννοιες μπορούν κάλλιστα να επικαλύπτονται, όπως εδώ με την "αναφορά" στην συνάρτηση που είναι αντιγραφή ορισμού (άρα πραγματικά μια αναφορά, αφού ο ορισμός είναι η συνάρτηση).

Συνάρτηση ΣυνΣτηΣυν {
     Διάβασε &Συν2(),,
     στη α1=α, β1=β
     καλεσε Συν2(&α1, &β1)
      στη α=α1, β=β1
}
Συνάρτηση Προσθεσε1 {
       Διάβασε,
      α++
       β++
}
Συνάρτηση Προσθεσε2 {
       Διάβασε,
      α+=2
       β+=2
}
α=0
καλεσε ΣυνΣτηΣυν(&Προσθεσε1(), , &α)
Τυπωσε α \\1
α=0
καλεσε Προσθεσε1( &α, &α)
Τυπωσε α \\2
α=0
καλεσε ΣυνΣτηΣυν(&Προσθεσε2(), , &α)
Τυπωσε α \\ 2
α=0
καλεσε Προσθεσε2( &α, &α)
Τυπωσε α \\ 4




Για να φτιάξουμε μια συνάρτηση χωρίς όνομα:
Βάλε "{Διάβασε Χ : =Χ**2}" : Διάβασε &Κ() : Τυπωσε Κ(2) \\ 4
Βάλε "{Διάβασε Χ : =Χ**2+10}" : Διάβασε &Κ() : Τυπωσε Κ(2) \\14

Κανονικά δεν μπορούμε να αλλάξουμε αναφορά σε μια μεταβλητή που έχουμε δώσει αναφορά σε άλλη μεταβλητή. Στη αναφορά συνάρτησης μπορούμε γιατί έχουμε ουσιαστικά αντιγραφή ορισμού.

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

Πινακας Κ(20)=2, Ν(30)=3
Βαλε &Κ() : Διάβασε &Λ()
Βαλε &Κ() : Διάβασε &Μ() \\ αυτό γίνεται, να έχουμε διπλή αναφορά
Λ(10)+=10 \\ και το Μ(10) θα γίνει 12
για αυτό { \\ το μπλοκ για αυτο {} σβήνει κάθε νέο στο πέρας του
Δες ενταξει {
       Βαλε &Κ() : Διάβασε &Μ() \\ αυτό δεν γίνεται διότι ήδη υπάρχει...και βγάζει λάθος.
}
αν οχι εντάξει τότε Τύπωσε "Αυτό δεν γίνεται"
Βαλε &Ν() : Διάβασε &Μ() \\ αυτό θα φτιάξει μια νέα Μ() ενώ θα υπάρχει ήδη μια.
Τυπωσε Μ(10), Διάσταση(Μ(),1) \\ η νέα Μ() επισκιάζει την προηγούμενη
Βαλε &Μ() : Διάβασε &Κ() \\ εδώ φτιάχνουμε μια νέα Κ() που επισκιάζει την προηγούμενη Κ()
}
\\ τώρα τα νέα Μ() και Κ() δεν υπάρχουν και έχουν δώσει τη θέση τους στα παλιά
\\ λιστα   \\ με την εντολή λίστα βλέπουμε τι έχουμε σε μεταβλητές και πίνακες.
Τυπωσε Μ(10), Διάσταση(Μ(),1)

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

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

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