Κυριακή 7 Φεβρουαρίου 2016

Προγραμματισμός 0008 - Κλάσεις τι άλλο;

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

\\ Οι μεταβλητές με τις αρχικές τιμές
Κ=0
Λ=0
\\ πρόγραμμα στάδιο 1
\\ Εισάγουμε ένα νούμερο, και αλλάζουμε τη κατάσταση στο Λ
κ=5
Λ=Λ+1 \\Λ++
\\ Εξάγουμε στην οθόνη τη κατάσταση Λ και την τιμή κ
Τύπωσε Λ       '1
Τύπωσε κ       ' 5
\\ πρόγραμμα στάδιο 2
\\ Εισάγουμε ένα νούμερο, και αλλάζουμε τη κατάσταση στο Λ
κ=10
Λ=Λ+1 \\ Λ++
\\ Εξάγουμε στην οθόνη τη κατάσταση Λ και την τιμή κ
Τύπωσε Λ      '2
Τύπωσε κ       '10


Η απόστροφος είναι για σημείωση στη γραμμή όπως και η \ (μία κάνει)

Τρία στάδια (έχει σημασία πώς λέμε τα πράγματα οπότε δώστε βάσει στις λέξεις):
1. Ονομάζουμε τις μεταβλητές και ορίζουμε τις πρώτες τιμές. Το = εδώ δεν κάνει "αντικατάσταση" (άλλη φορά ναι), διότι δεν υπάρχει τιμή. Ο διερμηνευτής δεν αρχικοποιεί δυο φορές τη μεταβλητή. Όταν δει το όνομα κοιτάει αν υπάρχει και αν όχι δημιουργεί πρώτα το χώρο που θα γράψει, εφόσον δει το "=". Αν η έκφραση (η παράσταση μετά το =) δεν δώσει νούμερο διότι ας πούμε έγινε λάθος (π.χ. το 5/0 δίνει λάθος), τότε βγαίνει επίσης λάθος...η "η μεταβλητή κ χωρίς τιμή".  Αν δεν βάζαμε το = τότε θα έψαχνε για τμήμα και αν δεν έβρισκε θα έβγαζε λάθος "Δεν υπάρχει τμήμα κ" (το οποίο εδώ δεν γνωρίζουμε ακόμα τι είναι, και το αφήνουμε). Ουσιαστικά με τη τιμή δίνουμε στο Κ ένα χώρο (ίδιος σε έκταση για κάθε αριθμητική μεταβλητή) με μια τιμή 0.(όλα τα bit 0).

2. Το κ=5 είναι αντικατάσταση, αλλάζει το 0 με το 5 (αντικατάσταση σημαίνει πάρε την τιμή και "πάτησε" πάνω στην παλιά τιμή.(o επεξεργαστής "πατάει", βάζει τον αριθμό, σε όλη την έκταση του χώρου του αριθμού, δηλαδή όλα τα bit, έχουν ή δεν έχουν νούμερο 1 - 0 ή 1 είναι το δυαδικό).

3 Το Λ=Λ+1 είναι επίσης αντικατάσταση. Πρώτα ο διερμηνευτής διαβάζει το Λ και το βρίσκει σαν μεταβλητή, μετά βλέπει ότι έχει το = άρα περιμένει έκφραση και την αναζητεί. Βρίσκει την Λ+1 και την εκτελεί (επειδή πάλι αναζητεί τη Λ, εδώ μπορούμε να βάλουμε το Λ++ που κάνει το ίδιο με μια μόνο αναζήτηση της μεταβλητής). Έτσι βάζει το νέο Λ. Η Λ=Λ+1 (και η Λ++) λέγεται μετρητής Λ κατά 1. Άρα ξέρουμε ότι κάτι σαν Χ=Χ+1 ή Χ++ είναι μετρητής. Κάθε φορά που το πρόγραμμα το εκτελεί αυξάνει την τιμή κατά ένα. Αν δεν υπήρχε η Λ θα έβγαινε λάθος επειδή το Λ = δεν βάζει το Λ στις μεταβλητές, αλλά πρόσκαιρα περιμένει τιμή και μετά το βάζει, άρα το Λ+1 δεν θα εκτελεστεί αφού το Λ δεν θα υπάρχει!

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

Επίσης μάθαμε για τον μετρητή (Χ=Χ+1), για να παίξει πρέπει να έχει προηγηθεί δημιουργία του Χ με αρχική τιμή! Τελική τιμή; Δεν γνωρίζουμε, ουσιαστικά μετράει κάθε φορά που περνάμε από το σημείο που είναι ο κώδικας.

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

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

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

κ=0
Λ=0
ΒάλεΤιμή(5)
Τύπωσε Λ
Τύπωσε κ
ΒάλεΤιμή(10)
Τύπωσε Λ
Τύπωσε κ


Ρουτίνα ΒάλεΤιμή(Χ)
      κ=Χ
      Λ++
Τέλος Ρουτίνας


Δείτε λοιπόν πως η ρουτίνα έχει δυο γραμμές:
1. κ=Χ δίνουμε τιμή στην κ του τμήματος, με την προσωρινή Χ
2. Λ++ είναι ο μετρητής όπως έχει αναφερθεί πιο πάνω
3.Κανονικά η κλήση σε ρουτίνα γίνεται έτσι: Διαμέσου ΒάλεΤιμή(5) αλλά αν δεν έχουμε πίνακα με όνομα ΒάλεΤιμή() τότε μπορεί να κληθεί χωρίς τη Διαμέσου
4. Αν θέλουμε τοπικές μεταβλητές σε ρουτίνα γίνεται με την εντολή Τοπική να ορίσουμε και μάλιστα αν θέλουμε χωρίς δήλωση αρχικής τιμής, γιατί αποδίδει αυτόματα ο διερμηνευτής. Η τοπική θα διαγραφεί στο τέλος της ρουτίνας. Η Χ είναι επίσης τοπική (την λέω προσωρινή γιατί δεν θα υπάρχει στο τέλος της ρουτίνας)


Τώρα μέχρι εδώ είδαμε ότι ένα μέρος του κώδικα μπορεί να ονομαστεί και να παίζει όποτε θέλουμε, δηλαδή ομαδοποιούμε εντολές με ένα όνομα.

Μια σκέψη εδώ είναι ότι αφού μπορώ να ομαδοποιώ εντολές για να εκτελούνται μαζί όσες φορές το ζητήσω, μπορώ να ομαδοποιώ μεταβλητές; Η απάντηση είναι ναι και αυτό γίνεται με ομάδες τις οποίες φτιάχνουμε ή άμεσα ή με χρήση κλάσης. Εδώ θα δούμε την χρήση κλάσης:

Συνάρτηση Αλφα.Τιμή {
           Διάβασε
            Για δ {
                  ++
                  Διάβασε .κ
                  =
            }
}
Κλάση Αλφα {
      Λ=0, κ
}
Κ=Αλφα()
Τύπωσε Αλφα.Τιμή(&Κ, 5) ' 1
Τύπωσε Κ.κ ' 5
Τύπωσε Αλφα.Τιμή(&Κ, 10) '2
Τύπωσε Κ.κ '10



Εδώ θέλει εξήγηση το πράγμα! Έχουμε τρία μέρη:
Δηλώσεις - Δημιουργία αντικειμένου - Επεξεργασία

1. Δηλώσεις: Έχουμε τη δήλωση της συνάρτησης, και τη δήλωση της κλάσης. Στη Μ2000 η δήλωση της κλάσης είναι μια συνάρτηση που επιστρέφει ομάδα (το αντικείμενο της Μ2000). Στη κλάση δώσαμε αρχική τιμή στη Λ αλλά όχι στη κ. Θα δοθεί το 0. Απλά εδώ το έχουμε έτσι για να φανεί κάτι. Ο ορισμός της κλάσης δεν δέχεται εντολές μόνο αναθέσεις τιμών (όπου εκεί παίζουν εντολές έμμεσα, αλλά θα το δούμε άλλη φορά)

2.Δημιουργία  Κ=Αλφα()  εδώ έχουμε δημιουργία μιας ομάδας με όνομα, και ακολουθεί ο διερμηνευτής το ίδιο μοτίβο, πρώτα κοιτάει αν υπάρχει Κ, στη λίστα ονομάτων του τμήματος, αν δεν υπάρχει κάνει χώρο μετά εκτελεί την έκφραση και μετά βάζει στο χώρο αυτό που δίνει η έκφραση. Δεν θα εξετάσουμε εδώ τι γίνεται αν υπάρχει κ και δώσουμε αντικείμενο. Αυτό που θα γίνει στο πρόγραμμα είναι να φτιαχτεί η Κ.κ και η Κ.Λ καθώς και το αντικείμενο Κ (που κρατάει λογαριασμό του τι έχει).
3. Το όνομα Αλφα.Τιμή στη συνάρτηση Αλφα.Τιμή() περιέχει τελεία χωρίς κάποιο ιδιαίτερο λόγο.  Όμως οι τελείες στα .κ και .Λ έχουν ρόλο.
4. Στη Για δ { } του λέμε να δει το ,κ ως δ.κ και το .Λ ως δ.Λ
5. Όταν καλούμε τη συνάρτηση δίνουμε δυο παραμέτρους, το &Κ και έναν αριθμό. Το πρώτο λέει να πάρει ένα δείκτη η Άλφα.Τιμη και στο Διάβασε &δ λέμε να φτιάξει ένα νέο αντικείμενο δ το οποίο θα έχει ότι και το Κ αλλά κάθε τιμή θα δείχνει τις τιμές του Κ. Μιλάμε για πέρασμα με αναφορά ομάδας. Η αύξηση του δ.Λ είναι ταυτόχρονα αύξηση του Κ.Λ διότι έχουν τον ίδιο χώρο μνήμης. Απλά το δ.Λ βρίσκεται στη Συνάρτηση Αλφα.Τιμή() και όταν αυτή τερματίσει, θα χαθεί ως όνομα, αλλά δεν θα σβήσει η μνήμη, που βλέπει και το Κ,Λ.
6. Επιστροφή τιμής. Στη συνάρτηση Αλφα.Τιμή() έχουμε ουσιαστικά δυο επιστροφές (μια πραγματική), απλά η μια αφορά το αντικείμενο που εδώ απλά το έχουμε συνδεδεμένο με αναφορά άρα η επιστροφή δεν λογίζεται. Η άλλη είναι στο = που υπάρχει σε εντολή χωρίς να υπάρχει μεταβλητή (είναι η επιστροφή τιμής σε Συνάρτηση).
7. Ενώ στις ρουτίνες βλέπουμε τις μεταβλητές του τμήματος, στις συναρτήσεις (και στα τμήματα) δεν βλέπουμε τις μεταβλητές εκτός και αν τις έχουμε περάσει με αναφορά.


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

Η επόμενη ιδέα λέει: Αφού είναι δυνατόν να ομαδοποιούμε εντολές και να ομαδοποιούμε μεταβλητές, τότε γίνεται να τα κάνουμε όλα αυτά σε ένα; Η απάντηση είναι απλή: Ναι γίνεται:


Κλάση Αλφα {
      Λ=0, κ
      Τμήμα ΒάλεΤιμή {
            ++
            Διάβασε .κ
      }
      Συνάρτηση Αλφα.Τιμή {
            .ΒάλεΤιμή
            =
      }
}


Κ=Αλφα()
Τύπωσε Κ.Αλφα.Τιμή(5) ' 1
Τύπωσε Κ.κ ' 5
Τύπωσε Κ.Αλφα.Τιμή(10) '2
Τύπωσε Κ.κ '10



1. Δείτε τώρα ότι το Κ έχει αποκτήσει δική του Αλφα.Τιμή(). Επειδή το Κ ανήκει στο τμήμα, ανήκει και σε αυτό το Κ.Αλφα.Τιμη()/
2. Δείτε επίσης ότι η Αλφα.Τιμη ...δεν διαβάζει το νούμερο που δίνουμε, το αφήνει για να το διαβάσει η Βάλε.Τιμή. Αυτό γίνεται γιατί οι παράμετροι στη Μ2000 μπαίνουν σε μια ειδική στοίβα που εδώ λέμε σωρός τιμών του τμήματος/συνάρτησης. Τα τμήματα βλέπουν το σωρό αυτού που τους κάλεσε, οπότε η ΒάλεΤιμή (δείτε ότι την καλούμε με μια τελεία στην αρχή, θα μπορούσαμε να βάλουμε Αυτο.ΒάλεΤιμή απλά βάζοντας μόνο τη τελεία ο διερμηνευτής κοιτάει στη λίστα μεταβλητών και στη λίστα τμημάτων/συναρτήσεων του Κ να το βρει).
3. Η .Λ++ αυξάνει την τιμή στο Κ.Λ.
4. Παρατηρούμε πως ενώ οι συναρτήσεις και τα τμήματα ΔΕΝ βλέπουν μεταβλητές/συναρτήσεις/τμήματα έξω από το χώρο τους (που δεν έχουν δημιουργηθεί στο χώρο τους), βλέπουν όμως τις μεταβλητές του αντικειμένου.
5. Εδώ δεν έτυχε να αλλάξουμε απευθείας τιμή. Αν θέλαμε να αλλάξουμε τιμή στην κ, πχ να δώσουμε το 200, τότε θα έπρεπε να δώσουμε .κ<=200 (δείτε το <=). Αν δίναμε το .κ=200 τότε θα φτιάχναμε τοπική μεταβλητή. Η Μ2000 έχει και γενικές μεταβλητές/συναρτήσεις/τμήματα αλλά εδώ δεν έχουν αναφερθεί. Αν ορίσουμε τοπική με ίδιο όνομα γενικής τότε για όσο ο ορισμός υπάρχει, θα βλέπουμε την τοπική μεταβλητή.

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

Η επόμενη ιδέα λέει: Αν θέλω περισσότερα ασφαλώς μπορώ να ονομάσω και άλλα, αλλά αν θέλω ένα πίνακα τι μπορώ να κάνω:

Κλάση Αλφα {
      Λ=0, κ
      Τμήμα ΒάλεΤιμή {
            ++
            Διάβασε .κ
      }
      Συνάρτηση Αλφα.Τιμή {
            .ΒάλεΤιμή
            =
      }
}
Πίνακας Κ(20)=Αλφα()
Τύπωσε Κ(4).Αλφα.Τιμή(5) ' 1
Τύπωσε Κ(4).κ ' 5
Τύπωσε Κ(4).Αλφα.Τιμή(10) '2
Τύπωσε Κ(4).κ '10


1. Δείτε ότι ορίσαμε ένα πίνακα 20 στοιχείων (από 0 έως 19) και δηλώσαμε ότι θα παίρνει κλάση  Αλφα(). Η Μ2000 δεν έχει τύπους αντικειμένων, εκτός από αυτήν την περίπτωση που ορίζουμε κάποια τμήματα και συναρτήσεις σταθερές για ένα πίνακα αντικειμένων.
2. Μπορώ για οποιοδήποτε Κ() να βάλω τιμή και να μετράω κάθε φορά την νέα εισαγωγή με έναν μετρητή!
3. Η κλάση παραμένει ίδια
4. Τα αντικείμενα στο πίνακα δεν είναι όπως το αντικείμενο Κ που είδαμε σε προηγούμενο θέμα. Η διαφορά τους είναι ότι αυτά δεν έχουν όνομα. Το Κ(4) είναι όνομα με δείκτη. Οι μεταβλητές και τα τμήματα/συναρτήσεις δεν υπάρχουν στη λίστα του τμήματος που τρέχει το πρόγραμμα.
5. Όταν καλώ την Κ(4).Αλφα.Τιμή(5) τότε ο διερμηνευτής επικοινωνεί με το αντικείμενο, πρόσκαιρα το ανοίγει, δημιουργεί ένα αντίγραφο με ένα δικό του όνομα έστω κ12345 και εκτελεί αυτό κ1234.Αλφα.Τιμή(5) και στο πέρας ξανά κλείνει το αντικείμενο
6. Αντί να ανοίξει και να κλείσει τέσσερις φορές το αντικείμενο μπορούμε να το κάνουμε με τη μία;
Για Κ(4) {
      Τύπωσε .Αλφα.Τιμή(5) ' 1
      Τύπωσε .κ ' 5
      Τύπωσε .Αλφα.Τιμή(10) '2
      Τύπωσε .κ '10
}

7. Προσοχή η Για σβήνει ότι νέο δημιουργείται εντός των αγκυλών (εκτός αυτών που θα βάλουμε στο τμήμα, και εκτός από τις αλλαγές που θα κάνουμε σε υπάρχουσες μεταβλητές).
8. Μπορούμε να κάνουμε αυτό ΑΒ=Κ(4) και έτσι δημιουργούμε το ΑΒ με τις τιμές του Κ(4) και τις συναρτήσεις/μεταβλητές. Αν το ΑΒ είναι ήδη αντικείμενο έχουμε ένωση. δηλαδή αν είναι διαφορετικό αντικείμενο τότε τα παντρεύουμε, και σε ότι είναι ίδιο γίνεται αντικατάσταση, ενώ σε ότι είναι νέο για την ΑΒ θα το αποκτήσει!
9. Μπορούμε να κάνουμε αυτό Κ(4)=ΑΒ και εδώ δεν έχουμε ένωση αλλά αντικατάσταση. Το αντικείμενο στο Κ(4) διαγράφεται και μπαίνει ένα αντίγραφο του ΑΒ. Αν θέλουμε ένωσε πρέπει να κάνουμε αυτό: Για Κ(4) { Αυτό=ΑΒ } οπότε κάνουμε ένωση με το ΑΒ (ένωση σημαίνει αντιγραφή τιμών όπου έχουμε ίδιο όνομα  ή προσθήκη αν δεν υπάρχουν).
10. Δεν μπορούμε να περάσουμε με αναφορά ένα κλειστό-χωρίς όνομα- αντικείμενο. Πρέπει να το ανοίξουμε π.χ Για Κ(4) { ΚάνεΚάτι &ΑΥΤΟ }  το ΑΥΤΟ είναι το συνθηματικό για το ανοικτό Κ(4).

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

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

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

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

Συνάρτηση Αλφα.Τιμή {
           Διάβασε δείκτης$
            δείκτης$.Λ++
            Για δείκτης$ {
                  Διάβασε .κ
                  }
            =εκφρ(δείκτης$.Λ)
}
Κλάση Αλφα {
      Λ=0, κ
}
Κ=Αλφα()
Τύπωσε Αλφα.Τιμή(&Κ, 5) ' 1
Τύπωσε Κ.κ ' 5
Τύπωσε Αλφα.Τιμή(&Κ, 10) '2
Τύπωσε Κ.κ '10


1. Την Ισχνή αναφορά την έχω ονομάσει δείκτης$

Συνάρτηση Αλφα.Τιμή {
            Διάβασε δείκτης$
            Για δείκτης$ {
                   ++
                  Διάβασε .κ
                  =
            }
}

2. Άλλος τρόπος είναι να φτιάξω μια πραγματική αναφορά από την ισχνή:
Συνάρτηση Αλφα.Τιμή {
            Διάβασε δείκτης$
            Ένωσε Ισχνή δείκτης$ στο δ
            Για δ {
                   ++
                  Διάβασε .κ
                  =
            }
}


Δείτε τώρα γιατί μας βολεύει η ισχνή αναφορά (στο παραπάνω δεν μας βολεύει αφού ένα Διάβασε &δ φθάνει.)

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

Συνάρτηση Αλφα.Τιμή {
           Διάβασε δείκτης$
            Για δείκτης$ {
                  ++
                  Διάβασε .κ
                  =
                  Αν .Λ=1 τότε=Τυχαίος(100)
            }
}
Κλάση Αλφα {
      Λ=0, κ
      Μ=-10
}
Πίνακας Κ(20)=Αλφα()
Τύπωσε Αλφα.Τιμή(ισχνη$(Κ(4)), 5) ' 1
Τύπωσε Κ(4).κ ' 5
Τύπωσε ">>>>>>>",Κ(4).Μ
Τύπωσε Αλφα.Τιμή(ισχνη$(Κ(4)), 10) '2
Τύπωσε Κ(4).κ '10
Τύπωσε ισχνη$(Κ(4))


1. Έχουμε βγάλει απ΄έξω την συνάρτηση. Δεν μπορούμε να βάλουμε μια Διάβασε &δ γιατί δεν υπάρχει αναφορά σε αντικείμενο αλλά σε στοιχείο πίνακα. Το δείκτη μπορούμε να το δούμε, με την Τύπωσε ισχνη$(Κ(4))
2. Δείτε όμως ότι η Αλφα.Τιμή μπορεί να χρησιμοποιηθεί και με επώνυμη ομάδα (αντικείμενο) π.χ. αν φτιάχναμε αυτό: Β=Κ(3) ή Β=Αλφα() τότε αυτό θα έπαιζε: Αλφα,Τιμή(&Β,5)
3. Στο προηγούμενο το Τύπωσε &Β τυπώνει την ισχνή αναφορά της Β (το πλήρες όνομα).
4. Για να γίνει πιο ενδιαφέρον έβαλα μια ακόμα μεταβλητή η οποία αλλάζει μια φορά! Βλέπουμε πόσο εύκολο είναι να βάλουμε κάτι επιπλέον σε μια κλάση.

Τελικό πρόγραμμα:
Κλάση Αλφα {
      Λ=0, κ
      Μ =-10
      ονομα$="κάτι"
      Συνάρτηση Αλφα.Τιμή {
            Τμήμα ΒάλεΤιμή {
                  Διάβασε δείκτης$
                  Για δείκτης$ {
                        ++
                        Διάβασε .κ
                        Αν .Λ=1 τότε=Τυχαίος(100)
                  }
            }
            ΒάλεΤιμή &Αυτο
            =
      }
}
Πίνακας Κ(20)=Αλφα()
Τμήμα ΚαιΑυτό {
      Διαβασε β$
      Τύπωσε β$
      ΔείξεΜου(β$)
}
ΔείξεΜου(ισχνη$(Κ(4)))
ΚαιΑυτό ισχνη$(Κ(2))
Τύπωσε ισχνη$(Κ(4))
Ρουτίνα ΔείξεΜου(α$)
      Τύπωσε "Τμήμα:";Τμήμα$ ' τυπώνει το όνομα του τμήματος
      Τύπωσε Συνάρτηση(α$.Αλφα.Τιμή(5)) '1
      Τύπωσε εκφρ(α$.κ) ' 5
      Τύπωσε ">>>>>>>",εκφρ(α$.Μ)
      Τύπωσε Συνάρτηση(α$.Αλφα.Τιμή(10)) ' 2
      Τύπωσε εκφρ(α$.κ) '10
      Τύπωσε εκφρ$(α$.ονομα$)+":"+α$
Τέλος Ρουτίνας


1. Όταν ο διερμηνευτής φτάσει στο Ρουτίνα τερματίζει το τμήμα.
2. Το τμήμα ΚαιΑυτό αναζητεί τις ρουτίνες στο δικό του κώδικα ή αν δεν τη βρει εκεί στο κείμενο του κώδικα απ΄όπου φορτώθηκε (κάθε φορά που βρίσκει η Μ2000 ένα τμήμα με ορισμό εντολών τότε μπαίνει σε μια λίστα, δηλαδή φορτώνεται, μία θέση υπάρχει για ένα όνομα, και αυτό σημαίνει ότι αν ήδη υπάρχει...αλλάζει κώδικα). Εδώ έτσι βρίσκει την ΔείξεΜου()
3.Αν αλλάξουμε ένα γράμμα σε μικρά ή μεγάλα με τόνο ή χωρίς στις ρουτίνες δεν θα βρίσκονται και είναι σαν να κάνουμε έξοδο από το τμήμα
4. Στα τμήματα, τις συναρτήσεις και τα ονόματα μεταβλητών και πινάκων, και στις εντολές μπορούμε να βάζουμε τόνους ή να έχουμε μικρά και μεγάλα (όλα γίνονται κεφαλαία χωρίς τόνους κατά την χρήση).
5. Στη Συνάρτηση Άλφα.Τιμή έχουμε ένα δικό της τμήμα το Βάλε.Τιμή. Αυτό το τμήμα δεν είναι τμήμα του αντικειμένου αλλά τοπικό τμήμα (φτιάχνεται άμεσα και διαγράφεται στο πέρας της εκτέλεσης της Αλφα.Τιμή). Για το λόγο αυτό πρέπει να περάσουμε την ισχνή ή κανονική αναφορά για να έχουμε σε αυτήν πρόσβαση στις μεταβλητές του αντικειμένου!

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

Ομάδα αλφα {
      κ=123,μ
}
Τύπωσε αλφα.κ, αλφα.μ,
Ομάδα αλφα {
      ν=10
}
Τύπωσε αλφα.ν
Β=αλφα
Τύπωσε Β.κ,Β.μ, Β.ν
Β.κ+=10
Τύπωσε Β.κ=αλφα.κ+10 ' -1 αληθες
Ενωσε Β.κ στο Μ ' δεύτερη αναφορά δεν μπορώ να βάλω
Μ++
Τύπωσε Β.κ ' 134  (123+10+1)
Τμήμα Αλλαξέμε {
      Διαβασε &αρ
      αρ+=100
}
Αλλαξέμε &αλφα.κ
Αλλαξέμε &Β.κ
Τύπωσε αλφα.κ, β.κ '223, 234
Τύπωσε Μ '234
Αλλαξέμε
Τύπωσε αλφα.κ, β.κ ' 223, 334
Τύπωσε Μ '334


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

Αυτό που δεν είδαμε σε αυτό το "σεντόνι" είναι ότι οι ομάδες μπορούν να έχουν άλλες ομάδες εσωτερικά, να έχουν πίνακες με άλλες ομάδες εσωτερικά.

Υπάρχουν όμως προγράμματα για να τα δει κανείς αυτά όπως εδώ:
Δυαδικό Δένδρο (Διαγραφή στοιχείου)

Ο πίνακας κατακερματισμού 2.0 στα ελληνικά!

Φιδάκι Νο2

Συναρτήσεις που επιστρέφουν αντικείμενα

Συνδεδεμένες Λίστες FIFO και LIFO για αντικείμενα!

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

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

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