1. ΟΡΓΑΝΩΣΗ ΑΦΗΡΗΜΕΝΩΝ ΤΥΠΩΝ ΔΕΔΟΜΕΝΩΝ ΚΑΙ ΒΑΣΙΚΟΙ ΤΡΟΠΟΙ ΠΡΟΣΒΑΣΗΣ ΣΕ ΔΟΜΕΣ 1.1 Οργάνωση Αφηρημένων τύπων δεδομένων Θα αναλυθεί το πρότυπο οργάνωσης των αφηρημένων τύπων δεδομένων (ΑΤΔ) που παρουσιάζονται στην εργασία. Οι υλοποίησεις έχουν υλοποιηθεί και ελεγχθεί με χρήση του προγράμματος dev-c++. Να διευκρινιστεί ακόμη πως καθώς δοκιμάζονταν αυτές οι υλοποιήσεις και εφαρμογές, υπήρξε εξ αρχής ένας από τους βασικούς σκοπούς να γίνει μια κατάλληλη οργάνωση αρχείων ώστε να ακολουθηθεί και ένα μοντέλο κατάλληλο σε αφαιρετικό επίπεδο για κάθε ΑΤΔ με βάση ας το πούμε την έννοια του modularity. Ο κώδικας έχει επίσης ελεγχθεί και σε linux περιβάλλον (terminal) για ελέγχους απώλειας μνήμης σε περιπτώσεις κυρίως δυναμικής δέσμευσης όπου χρειάστηκε στον εκάστοτε κώδικα (αυτό επετεύχθη με χρήση της εντολής valgrind). Ξεκινώντας λοιπόν με την οργάνωση προφανώς το μοντέλο οργάνωσης σε επίπεδο αρχείων-κώδικα είναι ταυτόσημο με τις ενότητες παρουσίασης κάθε ΑΤΔ. Πιο συγκεκριμένα κάθε ΑΤΔ έχει οργανωθεί σε πρώτο στάδιο με το εξής σκεπτικό: α) επιμέρους υλοποίησεις, β) αρχεία υλοποίησης-διεπαφής τύπου στοιχείου. Για παράδειγμα για τον ΑΤΔ Στοίβα υπάρχει ο εξής διαχωρισμός (όπως θα φανεί εκτενέστερα και στο επόμενο κεφάλαιο που τον αφορά): α) επιμέρους υλοποιήσεις: Μερική απόκρυψη, Ολική απόκρυψη, β) αρχεία υλοποίησηςδιεπαφής τύπου στοιχείου. Με βάση το γενικό μοντέλο οργάνωσης κάποια από τις επιμέρους υλοποιήσεις αναλύεται και σε άλλες επιμέρους και αυτές οι άλλες και σε άλλες επιμέρους κτλ. Για παράδειγμα ο ΑΤΔ Δένδρο αναλύεται αρχικά σε 2 επιμέρους υλοποιήσεις : α) δυαδικό δένδρο αναζήτησης και β) AVL δένδρο, αλλά το δυαδικό δένδρο αναζήτησης αναλύεται σε 3 νέες υπο-επιμέρους υλοποιήσεις: α) με ακολουθιακό πίνακα, β) με δείκτες, γ) με απλό πίνακα, καθεμία εκ των οποίων σε 2 άλλες υπο-επιμέρους υλοποιήσεις, α) με αναδρομή, β) με επανάληψη. Όταν δεν υπάρχει άλλη πλέον διάσπαση τότε η υλοποίηση ή επί μέρους υλοποίηση αναλύεται ως εξής: α) Αρχεία Υλοποίηση-Διεπαφής, β) Αρχεία Υλοποίησης, γ) Εφαρμογές. Ο φάκελος-κατηγορία Εφαρμογές όμως δεν υπάρχει για κάθε υλοποίηση καθώς δεν έχουν υλοποιηθεί για κάθε επί μέρους υλοποίηση ενός ΑΤΔ εφαρμογές είτε επειδή δεν θεωρήθηκε απαραίτητο είτε επειδή κάποιες που πιθανότατα υπάρχουν σε άλλη κατηγορία να εννοείται οτί μπορούν να
υλοποιηθούν για αυτή την κατηγορία αλλά δεν επαναλαμβάνονται. Για παράδειγμα οι εφαρμογές της επιμέρους υλοποίησης μερική απόκρυψη στον ΑΤΔ Στοίβα προφανώς μπορούν να υλοποιηθούν και για την ολική απόκρυψη. Στα αρχεία Υλοποίησης-Διεπαφής περιλαμβάνονται τα πρότυπα αρχεία. Ως πρότυπο αρχείο, μια ορολογία που χρησιμοποιείται στα πλαίσια μόνο της αυτής εργασίας, ορίζεται ένα αρχείο που μεν περιλαμβάνει τις υλοποιήσεις συναρτήσεων-πράξεων μιας δομής (αρχείο Υλοποίησης) ή τις δηλώσεις τους (αρχείο Διεπαφής) αλλά δεν μπορεί να χρησιμοποιηθεί έτσι όπως είναι σε εφαρμογή καθώς δεν έχει δοθεί υπαρκτό μονοπάτι του αρχείου Διεπαφής του τύπου στοιχείου που χρησιμοποιεί η εκάστοτε εφαρμογή. Έτσι στα πρότυπα αρχεία και συγκεκριμένα στο αρχείο Διεπαφής κυρίως εντοπίζεται το include του τύπου στοιχείου το οποίο δεν περιλαμβάνει συγκεκριμένο μονοπάτι που να προσδιορίζει το αρχείο του τύπου στοιχείου αλλά περιγράφει τον ρόλο του συγκεκριμένου include.η όλη αυτή γενίκευση αποσκοπεί στην έννοια της αφαιρετικότητας, για να μπορεί ανα πάσα στιγμή αν θέλει ο χρήστης μιας εφαρμογής να εκτελέσει την εφαρμογή του με τα αρχεία Υλοποίησης-Διεπαφής μιας άλλης επί μέρους υλοποίησης τοποθετώντας το αντίστοιχο μονοπάτι αρχείου Διεπαφής του τύπου στοιχείου που χρησιμοποιεί η συγκεκριμένη εφαρμογή. Για παράδειγμα στον ΑΤΔ Δένδρο στην επί μέρους υλοποίηση του δέντρου με δείκτες υπάρχουν πολλές επί μέρους διαφορετικές υλοποιήσεις για τις οποίες υπάρχουν 3 εφαρμογές που μπορούν να θεωρηθούν κοινές, παρ ότι και στις 3 χρησιμοποιείται η υλοποίηση της απλής μονής λίστας με δείκτες. Όμως μπορούν αυτές οι εφαρμογές να δοκιμασθούν με οποιαδήποτε από αυτές τις επί μέρους υλοποιήσεις. Στα αρχεία Δοκιμής τώρα περιλαμβάνονται πάντα το αρχείο δοκιμής-main που λειτουργεί ως test αρχείο (εμφανίζει στον χρήστη μενού με επιλογή να διαλέξει πράξεις πάνω στην ανάλογη δομή), τα αρχεία Διεπαφής-Υλοποίησης της δομής, μόνο που δεν είναι τα πρότυπα, δηλαδή υποδεικνύουν συγκεκριμένο μονοπάτι-path για τα αρχεία Διεπαφής-Υλοποίησης του τύπου στοιχείου του εκάστοτε ΑΤΔ. Εκτός αυτών εννοείται οτί σε αυτόν τον φάκελο, άμα το δούμε καθαρά οργανωτικά για τους φακέλους των αρχείων, υπάρχει και το project της δοκιμής (δημιουργημένο και εκτελεσμένο στο dev-c++) ενώ τα αρχεία τύπου στοιχείου δεν βρίσκονται σε αυτό τον φάκελο αλλά έξω από τις υλοποιήσεις όπως προτοείπαμε στο αρχικό επίπεδο εκτός του φακέλουενότητας των υλοποίησεων, δηλαδή το path στο αρχείο Διεπαφής της δομής είναι πάντα σύνθετο. Πέραν όμως αυτών στα αρχεία δοκιμής μπορεί να υπάρχουν και αρχεία Διεπαφής-Υλοποιήσης από άλλη υλοποίηση που να εξυπηρετούν την συγκεκριμένη Δοκιμή. Για παράδειγμα στις υλοποιήσεις στον ΑΤΔ Δένδρο που χρησιμοποιούν αναδρομή στα αρχεία τους περιλαμβάνονται και τα αρχεία Διεπαφής- Υλοποίησης της Στοίβας με ολική απόκρυψη γιατί οι Δοκιμές αυτές χρησιμοποιούν Στοίβα. Τέλος όσον αφορά το πεδίο οργάνωσης των υλοποιήσεων υπάρχουν και τα αρχεία των Εφαρμογών. Για κάθε εφαρμογή μέσα στον φάκελο της υπάρχουν
τα εξής αρχεία: βασικό αρχείο εφαρμογής (συνήθως ονοματίζεται ως main), αρχεία Διεπαφής-Υλοποίησης, το project της εφαρμογής αλλά και τα αρχεία τύπου στοιχείου της δομής καθώς σε πολλές από αυτές τις εφαρμογές οι βασικές πράξεις του τύπου στοιχείου επεκτείνονται και έτσι διαφοροποιούνται αυτά τα αρχεία από τα βασικά που βρίσκονται έξω από τα πλαίσια των υλοποιήσεων. Πέραν όμως αυτών όπως και στα αρχεία δοκιμής μπορεί να υπάρχουν και αρχεία Διεπαφής-Υλοποιήσης από άλλη υλοποίηση που να εξυπηρετούν την συγκεκριμένη Δοκιμή. Επιστρέφοντας τώρα στο αρχικό επίπεδο οργάνωσης πάλι και αφού έχουμε αναλύσει σε βάθος την οργάνωση των επιμέρους υλοποιήσεων σε έναν ΑΤΔ απομένει η ανάλυση των αρχείων υλοποίησης-διεπαφής του τύπου στοιχείου. Στον φάκελο αυτό υπάρχουν μέσα οι εξής φάκελοι: α) φάκελος αρχείων Υλοποίησης-Διεπαφής τύπου στοιχείου ορισμένου ως ακεραίου-int, β) φάκελος αρχείων Υλοποίησης-Διεπαφής τύπου στοιχείου ως πίνακα-string και γ) φάκελος αρχείων Υλοποίησης-Διεπαφής τύπου στοιχείου ως struct που περιέχει έναν ακέραιο και μια συμβολοσειρά. Έξω από τους υποφακέλους αυτούς και χωρίς να εντάσσονται σε κάποιο φάκελο υπάρχουν τα αρχεία Υλοποίησης-Διεπαφής του τύπου στοιχείου ορισμένου ως ακεραίου ως «default» αρχεία που χρησιμοποιούν όλες οι δοκιμές του εκάστοτε ΑΤΔ. Αυτή η επιλογή έχει γίνει έτσι ώστε αν ο χρήστης θέλει να χρησιμοποιήσει κάποια άλλη υλοποίηση του τύπου στοιχείου από τις προτεινόμενες να αντιγράψει τα αρχεία που θέλει σε αυτή την θέση ώστε να καλύπτονται όλες οι υλοποιήσεις έτσι με την νέα υλοποίηση και να διατηρείται η αποσύνδεση που είναι επιθυμητή μεταξύ των τύπων στοιχείων με τις υλοποιήσεις των δομών. Βεβαίως να διευκρινιστεί σε αυτό το σημείο ότι μπορεί κάποια από αυτές τις προτεινόμενες υλοποιήσεις τύπου στοιχείου να μην καλύπτει μια συγκεκριμένη εφαρμογή ή να απαιτεί παραπάνω βασικές πράξεις όπως γίνεται για παράδειγμα στην εφαρμογή της υλοποίησης στοίβας με Μερική Απόκρυψη για τον υπολογισμό της τιμής μιας μεταθεματικής παράστασης αλλά και στην εφαρμογή της ίδιας υλοποίησης για μετασχηματισμό μιας μεταθεματικής παράστασης σε ενδοθεματική. Ενώ στις 3 υλοποιήσεις που θέλουμε να μελετήσουμε σε αυτή την ενότητα υπάρχουν 3 σταθερά υλοποιημένες πράξεις (TSstoiva_setValue, TSstoiva_writeValue, TSstoiva_readValue) για τον τύπο στοιχείου στοίβας σε αυτές τις εφαρμογές, οι υλοποίησεις του τύπου στοιχείου για αυτές τις εφαρμογές περιλαμβάνει μια extra συνάρτηση (την TSstoiva_Iso). Aκόμη ο τύπος στοιχείου έχει οριστεί ειδικά σε αυτές καθώς δεν ακολουθούν καμία από τις υπάρχουσες επιλογές που αναλύονται σε αυτή την ενότητα. Συγκεκριμένα στην εφαρμογή για τον υπολογισμό της τιμής μιας μεταθεματικής παράστασης το στοιχείο στοίβας ορίζεται (typedef ) ως float αλλά και στην εφαρμογή της ίδιας υλοποίησης για μετασχηματισμό μιας μεταθεματικής παράστασης σε ενδοθεματική ως char.
Γενικά θα δούμε αυτές τις μικροδιαφοροποιήσεις ως προς τις πράξεις και τον ορισμό του τύπου στοιχείου και σε εφαρμογές άλλων δομών. Tονίζεται όπως και στην αρχή αυτής της ενότητας πως η οργάνωση που έγινε τηρείται στην εργασία αυτή τόσο σε επίπεδο οργάνωσης αρχείων όσο και στην σειρά και δομή παρουσίασης των ΑΤΔ. 1.2 Μερική και Ολική Απόκρυψη Σε αυτή την ενότητα αναλύονται και θίγονται οι έννοιες μερική και ολική απόκρυψη. Πρόκειται για έννοιες που πιθανότατα δεν είναι ευρέως γνωστές στο επιστημονικό πεδίο των δομών δεδομένων καθώς είναι άτυπα ορισμένες στα πλαίσια της εκπαιδευτικής διαδικασίας που αφορά το προπτυχιακό μάθημα Δομές Δεδομένων. Όμως καθώς έχει γίνει αντιληπτό και από τον τίτλο της η συγκεκριμένη εργασία αποσκοπεί στην διευκόλυνση της εκπαιδευτικής διαδικασίας σε προπτυχιακό επίπεδο σχετικά με το πεδίο των δομών δεδομένων και έτσι οι έννοιες αυτές είναι αναγκαίο να αποσαφηνιστούν καθώς εμφανίζονται συνεχώς στα πλαίσια της εργασίας. Ξεκινώντας λοιπόν με την αποσαφήνιση, να τονιστεί πως Μερική και Ολική απόκρυψη αφορούν τον τρόπο πρόσβασης ενός χρήστη σε μια δομή και τις πληροφορίες αυτής, δηλαδή σε τι βαθμό μπορεί να «πειράξει» τα δεδομένα μιας δομής και με ποιο τρόπο δύναται να την προσπελάσει ο χρήστης. Ο τρόπος πρόσβασης καθορίζεται από το πόσο ορατή είναι η δομή στο αρχείο διεπαφής της υλοποίησης της. Με βάση τα παραπάνω, οι υλοποίηση μιας δομής θεωρείται ότι έχει υλοποιηθεί με Μερική απόκρυψη όταν επιτρέπει στον χρήστη να κάνει απευθείας αλλαγές στα δεδομένα μιας δομής. Αυτό οφείλεται στο ότι η δομή αυτούσια με ότι περιλαμβάνει (πίνακες, ακεραίους κτλ) ορίζεται στο αρχείο Διεπαφής. Από την άλλη πλευρά σε υλοποίηση με Ολική απόκρυψη η δήλωση της δομής γίνεται στο αρχείο Υλοποίησης του ΑΤΔ και αυτό απαγορεύει στον χρήστη να έχει απευθείας πρόσβαση στα δεδομένα της δομής. Για να μπορεί ο χρήστης συνεπώς να διαχειρίζεται την δομή, υπάρχει ένας δείκτης στην δομή που λειτουργεί ως handler της δομής και του επιτρέπει να αναφέρεται σε αυτή και να την διαχειρίζεται μέσω των συναρτήσεων πράξεων, στο αρχείο Διεπαφής. Για να μπορεί ο χρήστης συνεπώς να διαχειρίζεται έστω την δομή του ΑΤΔ στοίβα υπάρχει στο αρχείο Διεπαφής. h η εξής δήλωση: Με βάση τα παραπάνω δεδομένα και με την λογική πλέον ότι ο χρήστης αναγκάζεται στο πρόγραμμα να δηλώσει ένα δείκτη προσπέλασης της δομής και όχι την ίδια την δομή, είναι αναγκαίες και έχουν υλοποιηθεί προφανώς 2 συναρτήσεις, η συνάρτηση δημιουργίας και η συνάρτηση καταστροφής του ΑΤΔ. Αυτές χρησιμεύουν για την δέσμευση μνήμης με την χρήση malloc () και για την αποδέσμευση μνήμης με την χρήση free () όπου χρειάζεται για την δομή. Λόγω διαφοράς στην πρόσβαση με Ολική απόκρυψη και εξ αιτίας του δείκτη αλλάζει και η παραμετροποίηση των συναρτήσεων όπως αυτές δηλώνονται στο αρχείο Διεπαφής (εννοείται πως διαφοροποιείται η Υλοποίηση). Για
παράδειγμα ακολουθούν στην σειρά οι δηλώσεις του ΑΤΔ Στοίβα για Μερική και μετά για Ολική απόκρυψη. Δηλώσεις για Στοίβα με Μερική Απόκρυψη: void Stoiva_dimiourgia (TStoivas *stoiva) ; int Stoiva_keni (TStoivas stoiva) ; void Stoiva_exagogi (TStoivas *stoiva, TStoixeioyStoivas *stoixeio, int *ypoxeilisi) ; void Stoiva_othisi(TStoivas *stoiva, TStoixeioyStoivas stoixeio, int *yperxeilisi) ; Δηλώσεις για Στοίβα με Ολική Απόκρυψη: HandleStoivas Stoiva_Constructor () ; void Stoiva_Destructor (HandleStoivas * StoivaPtrPtr) ; int Stoiva_keni (const HandleStoivas StoivaPtr) ; int Stoiva_gemati (const HandleStoivas StoivaPtr) ; void Stoiva_exagogi (const HandleStoivas StoivaPtr,TStoixeioyStoivas * const stoixeioptr, int *ypoxeilisi) ; void Stoiva_othisi (const HandleStoivas StoivaPtr, TStoixeioyStoivas stoixeio, int *yperxeilisi) ; Παρατηρούμε ότι στην Μερική απόκρυψη η στοίβα περνιέται ως παράμετρος αυτούσια είτε με αναφορά ενώ στην Ολική απόκρυψη είτε με τον ορισθέντα δείκτη είτε με δείκτη είτε με αναφορά σε αυτό το δείκτη. Αντίστοιχη λογική ακολουθείται σε όλους τους ΑΤΔ όπου χρειάζεται διαχωρισμός Μερικής- Ολικής Απόκρυψης. Στα επόμενα κεφάλαια, ένα κεφάλαιο για κάθε ΑΤΔ, ακολουθεί σε η ανάλυση κάθε ΑΤΔ που έχει υλοποιηθεί στα πλαίσια αυτής της εργασίας.
2. O AΤΔ ΣΤΟΙΒΑ 2.1 Εισαγωγή Η στοίβα αποτελεί την υλοποίηση μιας συλλογής αντικειμένων στην οποία κάθε εισαγωγή και διαγραφή γίνεται στο ίδιο άκρο που ονομάζεται κορυφή. Για την καλύτερη κατανόηση της λειτουργίας της στοίβας μπορούμε να δούμε παραδείγματα χρήσης της στοίβας στην καθημερινή ζωή. Μια μηχανή αποθήκευσης κερμάτων αποτελεί ένα τέτοιο παράδειγμα, με την πρόσθεση ενός κέρματος στην μηχανή-«στοίβα» ωθούνται προς τα κάτω όλα τα κέρματα από την κορυφή. Με την αφαίρεση ενός κέρματος στη στοίβα εμφανίζεται το επόμενο στην κορυφή. Ένα άλλο παράδειγμα από την καθημερινότητα είναι η στοίβα των πιάτων. Κάθε πιάτο που πλένεται τοποθετείται στην κορυφή της στοίβας, ενώ για σκούπισμα λαμβάνεται πάλι το πρώτο πιάτο. Η στοίβα είναι μια δομή που χρησιμοποιείται στην επιστήμη της πληροφορικής σε πολλές περιπτώσεις. Ένα παράδειγμα χρήσης της στοίβας είναι η στοίβα κλήσεων (call stack), είναι μια δομή δεδομένων που κρατά πληροφορίες σχετικά με τις ενεργές υπορουτίνες ενός προγράμματος. Αυτός ο τύπος στοίβας είναι γνωστός και σαν στοίβα εκτέλεσης (execution stack), στοίβα ελέγχου (control stack), στοίβα συναρτήσεων (function stack), ή στοίβα χρόνου εκτέλεσης (run-time stack), και συχνά αναφέρεται απλά σαν "η στοίβα". Αν και η συντήρηση της στοίβας κλήσεων είναι σημαντική για τη σωστή λειτουργία των πιο πολλών προγραμμάτων, οι λεπτομέρειες συνήθως είναι αόρατες στις γλώσσες υψηλού επιπέδου. Μια στοίβα κλήσεων χρησιμοποιείται για πολλούς σχετικούς μεταξύ τους σκοπούς, αλλά ο κύριος λόγος που υπάρχει είναι για να παρακολουθείται το σημείο στο οποίο κάθε ενεργή υπορουτίνα θα επιστρέψει τον έλεγχο όταν τελειώσει η εκτέλεσή της (ενεργές υπορουτίνες είναι αυτές που έχουν κληθεί αλλά ακόμα δεν έχει τελειώσει η εκτέλεσή τους, επιστρέφοντας). Άλλα παραδείγματα χρήσης της στοίβας είναι τα εξής: Άμεσες Εφαρμογές: Στο ιστορικό των σελίδων που επισκεπτόμαστε σε έναν web browser. Στη σειρά των πράξεων undo (αναίρεση) σε έναν επεξεργαστή κειμένου. Στην αλυσίδα των κλήσεων των διαφορετικών μεθόδων στην Java virtual machine. Έμεσες Εφαρμογές: Ως συστατικό σε άλλες δομές δεδομένων Ως βοηθητική δομή δεδομένων σε αλγορίθμους Aκόμη όμως την συναντούμε και στον κλάδο της Θεωρίας Υπολογισμού, που είναι άρρηκτα συνδεδεμένος με το θεωρητικό όσο και με το πρακτικό
υπόβαθρο της επιστήμης της πληροφορικής, συγκεκριμένα στα πεπερασμένα αυτόματα στοίβας. 2.2 Ορισμός Ο ΑΤΔ στοίβα είναι μια συλλογή δεδομένων με γραμμική διάταξη στην οποία όλες οι εισαγωγές και οι διαγραφές γίνονται στο ένα άκρο το οποίο λέγεται κορυφή της στοίβας. Η πιο σημαντική ιδιότητα μιας στοίβας που ουσιαστικά την χαρακτηρίζει είναι ότι το τελευταίο στοιχείο που εισήχθη στην στοίβα είναι και το πρώτο που διαγράφεται από αυτή. Εξαιτίας αυτής της ιδιότητας η στοίβα καλείται και δομή LIFO (Last- In- First- Out). 2.2.1 Δεδομένα Μια στοίβα αποτελεί μια συλλογή αντικειμένων (όχι απαραίτητα πεπερασμένη) σε γραμμική ακολουθία. 2.2.2 Πράξεις Οι βασικές πράξεις του ΑΤΔ στοίβα είναι οι εξής: Stoiva_dimiourgia: Δημιουργεί μια κενή στοίβα, σε περίπτωση ολικής απόκρυψης επιστρέφει και τον δείκτη στην στοίβα. Stoiva_exagogi: Σε περίπτωση που δεν είναι κενή η στοίβα εξάγει το στοιχείο της κορυφής, αλλιώς επιστρέφει μήνυμα υποχείλισης. Stoiva_othisi: Σε περίπτωση που δεν είναι γεμάτη η στοίβα προσθέτει ένα στοιχείο στην κορυφή της στοίβας, αλλιώς επιστρέφει μήνυμα υπερχείλισης. Stoiva_keni: Ελέγχει αν η στοίβα είναι κενή. 2.3 Yλοποιήσεις Στο κεφάλαιο αυτό θα παρουσιαστούν 2 διαφορετικές υλοποιήσεις του ΑΤΔ στοίβα, η υλοποίηση με Μερική Απόκρυψη και με Ολική Απόκρυψη. To τι σημαίνει Μερική και Ολική Απόκρυψη έχει επεξηγηθεί λεπτομερώς στο 2 ο κεφάλαιο. 2.3.1 Υλοποίηση 1η: Μερική Απόκρυψη 2.3.1.1 Αρχεία Διεπαφής-Υλοποίησης Στο αρχείο Διεπαφής για την υλοποίηση με Μερική Απόκρυψη τα βασικά στοιχεία που εντοπίζονται είναι η δήλωση της δομής της στοίβας, ο ορισμός του μεγέθους της (DEFINE), οι δηλώσεις των συναρτήσεων που υλοποιούν τις πράξεις του ΑΤΔ στοίβα αλλά κυρίως εντοπίζεται το include του τύπου
στοιχείου στοίβας το οποίο δεν περιλαμβάνει συγκεκριμένο μονοπάτι που να προσδιορίζει το αρχείο του τύπου στοιχείου στοίβας αλλά περιγράφει τον ρόλο του συγκεκριμένου include. Ακολουθεί ο κώδικας του αρχείου Διεπαφής: #ifndef STACK #define STACK #define PLITHOS 100 /*megisto epitrepto plh8os stoixeiwn ana stoiva*/ #include "to antistoixo.h typou stoixeiou" /*edo analoga tin efarmogi i to test tou tipou stoixeiou mpainei to antoistixo.h tou tipou stoixeiou */ /*dhlwseis typwn*/ typedef struct { int korifi; /*8esh toy prwtoy stoixeioy ths stoivas*/ TStoixeioyStoivas pinakas[plithos]; /*o pinakas twn stoixeiwn*/ TStoivas; /*dhlwseis synarthsewn*/ /*dhmioyrgia*/ void Stoiva_dimiourgia(TStoivas *stoiva); /*Prakseis elegxoy*/ int Stoiva_keni(TStoivas stoiva); /*Prakseis pros8eshs/apomakrynshs*/ void Stoiva_exagogi(TStoivas *stoiva,tstoixeioystoivas *stoixeio, int *ypoxeilisi); void Stoiva_othisi(TStoivas *stoiva,tstoixeioystoivas stoixeio, int *yperxeilisi); #endif /*#ifndef STACK */ Ακολουθεί ο κώδικας του αρχείου Υλοποίησης: #include <stdio.h> #include <stdlib.h> #include "Stack.h"
/*orismos synarthsewn*/ void Stoiva_dimiourgia(TStoivas *stoiva) {/* Pro: Kamia * Meta: Dhmioyrgia kenhs stoivas */ stoiva->korifi = -1; int Stoiva_keni(TStoivas stoiva) {/* Pro: Dhmioyrgia ths stoiva * Meta: Epistrefei 1 an h stoiva einai kenh alliws 0 */ return (stoiva.korifi == -1); void Stoiva_exagogi(TStoivas *stoiva,tstoixeioystoivas *stoixeio,int *ypoxeilisi) {/* Pro: Mh kenh stoiva * Meta: Eksagetai to stoixeio apo th stoiva */ if (Stoiva_keni(*stoiva)) >korifi]); *ypoxeilisi = 1; { *ypoxeilisi = 0; TSstoiva_setValue(stoixeio, stoiva->korifi--; stoiva->pinakas[stoiva- void Stoiva_othisi(TStoivas *stoiva,tstoixeioystoivas stoixeio,int *yperxeilisi) {/* Pro: Dhmioyrgia ths stoiva * Meta: Wtheitai to stoixeio sth stoiva */ if (stoiva->korifi == PLITHOS -1) *yperxeilisi = 1; stoixeio); { *yperxeilisi = 0; stoiva->korifi++; TSstoiva_setValue(&(stoiva->pinakas[stoiva->korifi]),
2.3.1.2 Αρχεία Δοκιμής Στα αρχεία δοκιμής περιλαμβάνεται όπως έχει εξηγηθεί και στο κεφάλαιο 2 το αρχείο main που χρησιμοποιείται ως αρχείο test για τις πράξεις της ATΔ Στοίβα. Ακολουθεί ο κώδικας του αρχείου δοκιμής: #include <stdio.h> #include "Stack.h" #include "../../TS/TStoixeioyStoivas.h" void print_options(void); int main(void) { int option, error,created,out_err; TStoivas stack; TStoixeioyStoivas x; error=created=0; do{ print_options(); {case 1: scanf("%d", &option); switch(option) case 2: Stoiva_dimiourgia(&stack); created=1; printf("\nh stoiva dimiourgithike!\n"); if(!created) { printf("\nden uparxei stoiva gia na eisaxthei stoixeio!\n"); printf("dwse ena stoixeio: "); out_err=tsstoiva_readvalue(stdin,&x); if(out_err==eof) { printf("\n error stin readvalue!\n"); Stoiva_othisi(&stack, x, &error);
eishx8h!\n"); if(error) printf("\nyperxeilhsh stoivas. To stoixeio DEN printf("\nto stoixeio eishx8h!\n"); case 3: if(!created) { printf("\nden uparxei stoiva gia na eksaxthei stoixeio!\n"); kenh!\n"); Stoiva_exagogi(&stack, &x, &error); if(error) printf("\nkeni stoiva!\n"); { printf("\nekshx8h epityxws to stoixeio "); out_err=tsstoiva_writevalue(stdout,x); if(out_err <0) { printf("\n error stin writevalue!\n"); case 4: if(!created) { printf("\nden uparxei stoiva gia na elexthei an einai if(stoiva_keni(stack)) while(option); return 0; printf("\nh stoiva einai kenh!\n"); printf("\nh stoiva DEN einai kenh!\n");
void print_options(void) { printf("\n\n1. Dhmioyrgia stoivas\n\ 2. Othisi stoixeiou sth stoiva\n\ 3. Eksagwgh stoixeiou apo th stoiva\n\ 4. Elegxos gia kenh stoiva\n\n\ Dwste thn epilogh sas(1-4, 0 gia eksodo):"); Ακόμη όμως περιλαμβάνονται και τα αρχεία Διεπαφής και Υλοποίησης της στοίβας που η μόνη διαφοροποίηση από τα πρότυπα αρχεία έγκειται στο path-μονοπάτι που περιλαμβάνεται στο αρχείο Διεπαφής καθώς αυτό είναι που προσδιορίζει την ένταξη τους στην συγκεκριμένη εφαρμογή-test (δεν δίνεται κώδικας επειδή είναι ουσιαστικά ο ίδιος με τα πρότυπα αρχεία). 2.3.1.3 Εφαρμογές Σε αυτό το σημείο παρουσιάζονται 3 εφαρμογές που κάνουν χρήση του ΑΤΔ Στοίβα με Μερική Απόκρυψη. Mε μικρές αλλαγές μπορούν να κάνουν χρήση και της Διεπαφής με Ολική Απόκρυψη. Οι εφαρμογές αυτές σε πλαίσιο αρχείων και όπως έχει αναλυθεί και στο 2 ο κεφάλαιο περιλαμβάνούν η καθεμία τα αρχεία Διεπαφής-Υλοποίησης της στοίβας, τα αρχεία Διεπαφής-Υλοποίησης του τύπου στοιχείου στοίβας και προφανώς το αρχείο-εφαρμογή main το οποίο υλοποιεί με τις κατάλληλες κλήσεις των συναρτήσεων-πράξεων το αντίστοιχο αποτέλεσμα που θέλει να επιτύχει η καθεμία από αυτές. 2.3.1.3.1 Μετατροπή ακεραίων αριθμών από το δεκαδικό στο δυαδικό Ακολουθεί ο κώδικας του αρχείου-εφαρμογής: #include <stdio.h> #include <stdlib.h> #include "Stack.h" #include "TStoixeioyStoivas.h" int main(void) { int number; TStoixeioyStoivas ypoloipo; /*to ypoloipo ths diaireshs ari8mos/2*/ int error,out_err; TStoivas stack;
printf("dwste ena 8etiko akeraio:"); scanf("%d",&number); Stoiva_dimiourgia(&stack); while (number!= 0) { TSstoiva_setValue(&ypoloipo, number%2); Stoiva_othisi(&stack,ypoloipo,&error); number = number/2; printf("o arithmos sto dyadiko systhma einai:"); while (!Stoiva_keni(stack) ) { Stoiva_exagogi(&stack,&ypoloipo,&error); out_err=tsstoiva_writevalue(stdout,ypoloipo); if(out_err <0) { printf("\n error stin writevalue!\n"); printf("\n\n"); getch(); return 0; 2.3.1.3.2 Υπολογισμός της τιμής μιας μεταθεματικής παράστασης Εδώ διευκρινίζεται ότι στα πλαίσια σωστής εκτέλεσης της εφαρμογής στο αρχείο Διεπαφής του τύπου στοιχείου που χρησιμοποιεί η συγκεκριμένη εφαρμογή το TStoixeioyStoivas έχει οριστεί ως float. Ακολουθεί ο κώδικας του αρχείου Υλοποίησης του τύπου Στοιχείου στοίβας για να τονισθεί η ειδοποιός διαφορά και στην υλοποίηση των πράξεων του τύπου στοιχείου: #include "TStoixeioyStoivas.h" void TSstoiva_setValue (TStoixeioyStoivas *target, TStoixeioyStoivas source) { *target=source; int TSstoiva_readValue (FILE *from, TStoixeioyStoivas * Elem) { int fd; fd=fscanf(from, "%5.2f", Elem); return fd;
int TSstoiva_writeValue (FILE *to, TStoixeioyStoivas Elem) { int fd; fd=fprintf(to, "%5.2f",Elem); return fd; Ακολουθεί ο κώδικας του αρχείου-εφαρμογής: #include <stdio.h> #include <stdlib.h> #include "Stack.h" #include "TStoixeioyStoivas.h" /*orismos synarthsewn*/ TStoixeioyStoivas upologismos (char,tstoixeioystoivas,tstoixeioystoivas); int einai_telestis (char); int main(void) { int sfalma; TStoivas stoiva; /*stoiva twn orwn*/ TStoixeioyStoivas oros1,oros2,apotelesma; char apantisi, metathematiki[256]; int i, ch, symbolo; do { Stoiva_dimiourgia(&stoiva); metathematiki[0]='\0'; i=0; printf("dwste th meta8ematikh parastash:"); while ( (symbolo = getchar())!= '\n') { metathematiki[i]=symbolo; i++; if (symbolo >= '0' && symbolo <= '9') /*bre8hke oros*/ { TSstoiva_setValue(&apotelesma, (float)(symbolo- '0')); Stoiva_othisi(&stoiva,apotelesma,&sfalma);
telesths*/ if ( einai_telestis(symbolo) ) /*bre8hke { Stoiva_exagogi(&stoiva,&oros1,&sfalma); Stoiva_exagogi(&stoiva,&oros2,&sfalma); TSstoiva_setValue(&apotelesma, */ upologismos(symbolo,oros1,oros2)); Stoiva_othisi(&stoiva,apotelesma,&sfalma); /*while ( (symbolo=getchar())!= '\n')*/ metathematiki[i]='\0'; Stoiva_exagogi(&stoiva,&apotelesma,&sfalma); printf("%s=", metathematiki); fprintf(stdout, "%5.2f",(float) apotelesma); printf("\nepi8ymeite na synexisete? (N/n gia NAI)\n"); apantisi=getchar(); while ((ch = getchar())!= '\n' && ch!= EOF); /* int ch while ( apantisi=='n' apantisi=='n'); return 0; TStoixeioyStoivas upologismos (char symbolo, TStoixeioyStoivas oros1, TStoixeioyStoivas oros2) { TStoixeioyStoivas apotelesma = 0; switch (symbolo) { case '+' : TSstoiva_setValue(&apotelesma,oros1 + oros2); case '-' : TSstoiva_setValue(&apotelesma, oros1 - oros2); case '*' : TSstoiva_setValue(&apotelesma, oros1 * oros2); case '/' : TSstoiva_setValue(&apotelesma, oros1 / oros2); default : printf("%c: mh egkyros telesths!\n", symbolo); // printf(" ddd %5.2f\n",apotelesma); return apotelesma;
int einai_telestis (char c) { return c == '+' c == '-' c == '*' c == '/'; 2.3.1.3.3 Μετατροπή ενδοθεματικής παράστασης στην μεταθεματική μορφή της Εδώ διευκρινίζεται ότι στα πλαίσια σωστής εκτέλεσης της εφαρμογής στο αρχείο Διεπαφής του τύπου στοιχείου που χρησιμοποιεί η συγκεκριμένη εφαρμογή το TStoixeioyStoivas έχει οριστεί ως char. Ακολουθεί ο κώδικας του αρχείου Υλοποίησης του τύπου Στοιχείου στοίβας για να τονισθεί η ειδοποιός διαφορά και στην υλοποίηση των πράξεων του τύπου στοιχείου: #include "TStoixeioyStoivas.h" int TSstoiva_iso (TStoixeioyStoivas Elem1, TStoixeioyStoivas Elem2) { return(elem1 == Elem2); void TSstoiva_setValue (TStoixeioyStoivas *target, TStoixeioyStoivas source) { *target=source; int TSstoiva_readValue (FILE *from, TStoixeioyStoivas * Elem) { int fd; fd=fscanf(from, "%2c", Elem); return fd; int TSstoiva_writeValue (FILE *to, TStoixeioyStoivas Elem) { int fd; fd=fprintf(to, "%2c",Elem); return fd;
Ακολουθεί ο κώδικας του αρχείου-εφαρμογής: #include <stdio.h> #include <string.h> #include <stdlib.h> #include "Stack.h" #include "TStoixeioyStoivas.h" #define MIKOS 80 /*megisto plh8os xarakthrwn ths parastashs*/ #define TELOS ';' /*endeiksh telous ths endo8ematikhs parastashs*/ #define synolo_teleston "+-*/" /*synolo telestwn*/ /*orismos synarthsewn*/ int protereotita(char); void metatropi(tstoixeioystoivas *); int main(void) { TStoixeioyStoivas endo_parastasi[mikos]; int i; printf("dwste thn endo8ematikh parastash. Topo8ethste ; sto telos.\n"); i=-1; do { i++; TSstoiva_setValue(&endo_parastasi[i], (char) getchar()); while (!TSstoiva_iso(endo_parastasi[i], TELOS) ); i++; TSstoiva_setValue(&endo_parastasi[i], '\0'); printf("h meta8ematikh morfh einai: "); metatropi(endo_parastasi); printf("\n"); getch(); return 0; int protereotita(char telestis)
/*Epistrefei thn proteraiothta tou telesth telestis*/ { switch(telestis) { case '(': return 0; case '+': case '-': return 1; case '*': case '/': default: return 2; void metatropi (TStoixeioyStoivas endo_parastasi[]) /*Metatrepei thn endo8ematikh morfh mias parastashs sthn meta8ematikh ths morfh*/ { TStoivas stoiva; /*stoiva telestwn*/ int i,out_err; TStoixeioyStoivas symbolo,symbolo_korifi; int sfalma,lathos,telos_exagogis; /*Elegxei to telos orwn */ Stoiva_dimiourgia(&stoiva); lathos =0; /*arxh metatrophs*/ i=0; TSstoiva_setValue(&symbolo, endo_parastasi[0]); while ((!TSstoiva_iso(symbolo, TELOS)) && (!lathos) ) { while( TSstoiva_iso(endo_parastasi[i], ' ') )/* kena*/ i++; symbolo = endo_parastasi[i]; if ( TSstoiva_iso(symbolo, '(') ) /*aristerh paren8esh*/ Stoiva_othisi(&stoiva,symbolo,&sfalma); if ( TSstoiva_iso(symbolo, ')') )/* paren8esh*/ { telos_exagogis = 0; do { if (Stoiva_keni(stoiva)) lathos =1;
{ Stoiva_exagogi(&stoiva,&symbolo_korifi,&sfalma); ) if (!TSstoiva_iso(symbolo_korifi, '(') { out_err=tsstoiva_writevalue(stdout,symbolo_korifi); if(out_err <0) {printf("\n error stin writevalue!\n"); telos_exagogis=1; while ((!telos_exagogis)&&(!lathos)); if ( strchr(synolo_teleston,symbolo)!=null )/*telesths*/ { telos_exagogis=0; while (!Stoiva_keni(stoiva) && (!telos_exagogis) ) { Stoiva_exagogi(&stoiva,&symbolo_korifi,&sfalma); if((protereotita(symbolo))<=(protereotita(symbolo_korifi))) { out_err=tsstoiva_writevalue(stdout,symbolo_korifi); if(out_err <0) { printf("\n error stin writevalue!\n"); { Stoiva_othisi(&stoiva,symbolo_korifi,&sfalma); telos_exagogis=1; Stoiva_othisi(&stoiva,symbolo,&sfalma); if (!TSstoiva_iso(symbolo, TELOS) ) /*oros*/
{ out_err=tsstoiva_writevalue(stdout,symbolo); if(out_err <0) { printf("\n error stin writevalue!\n"); i++; /*while ( (!TSstoiva_iso(symbolo, TELOS)) && (!lathos) )*/ /*Eksagwgh kai ektypwsh tvn stoixeiwn ths stoivas.*/ while ( (!Stoiva_keni(stoiva)) && (!lathos) ) { Stoiva_exagogi(&stoiva,&symbolo_korifi,&sfalma); if (!TSstoiva_iso(symbolo_korifi, '(') ) { out_err=tsstoiva_writevalue(stdout,symbolo_korifi); if(out_err <0) { printf("\n error stin writevalue!\n"); lathos =1; if (lathos) printf("la8os sthn endo8ematikh parastash.\n"); printf("\n"); 2.3.2 Υλοποίηση 2 η : Ολική Απόκρυψη 2.3.2.1 Αρχεία Διεπαφής-Υλοποίησης Στο αρχείο Διεπαφής για την υλοποίηση με Ολική Απόκρυψη τα βασικά στοιχεία που εντοπίζονται είναι η δήλωση του δείκτη της δομής της στοίβας και οι δηλώσεις των συναρτήσεων που υλοποιούν τις πράξεις του ΑΤΔ στοίβα. Προφανώς παρατηρείται πλέον πως οι συναρτήσεις έχουν διαφορετικές παραμέτρους σε σχέση με αυτές της Διεπαφής της Υλοποίησης με Μερική Απόκρυψη πράγμα κατανοητό καθώς η προσπέλαση της δομής γίνεται πλέον με χρήση δείκτη. Υπάρχουν στην Ολική Απόκρυψη και 2 extra συναρτήσεις, Stoiva_gemati: ελέγχει αν η στοίβα είναι γεμάτη, Stoiva_Destructor: καταστρέφει την στοίβα. Τέλος είναι αυτονόητο πως το
μονοπάτι του include για την Διεπαφή του τύπου στοιχείου δεν υπάρχει αφού πρόκειται για πρότυπο αρχείο. Ακολουθεί ο κώδικας του αρχείου Διεπαφής: #ifndef STACK_OA #define STACK_OA #include "to antistoixo.h typou stoixeiou" /*edo analoga tin efarmogi i to test tou tipou stoixeiou mpainei to antoistixo.h tou tipou stoixeiou */ /*orismoi typwn*/ typedef struct StackStruct * HandleStoivas; /*dhlwseis synarthsewn*/ /*dhmioyrgia/katastrofh*/ HandleStoivas Stoiva_Constructor(); /* real creation not initialisation */ void Stoiva_Destructor(HandleStoivas * StoivaPtrPtr); /*Prakseis elegxoy*/ int Stoiva_keni(const HandleStoivas StoivaPtr); int Stoiva_gemati(const HandleStoivas StoivaPtr); /*Prakseis pros8eshs/apomakrynshs*/ void Stoiva_exagogi(const HandleStoivas StoivaPtr,TStoixeioyStoivas * const stoixeioptr, int *ypoxeilisi); void Stoiva_othisi(const HandleStoivas StoivaPtr, TStoixeioyStoivas stoixeio, int *yperxeilisi); #endif /*#ifndef STACK_OA */ Ακολουθεί ο κώδικας του αρχείου Υλοποίησης: #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include "Stack-OA.h" #define PLITHOS 5 /*megisto epitrepto mege8os stoivas*/
typedef struct StackStruct { int korifi; /*8esh toy prwtoy stoixeioy ths stoivas*/ TStoixeioyStoivas pinakas[plithos]; /*o pinakas twn stoixeiwn*/ StackStruct; /*orismos synarthsewn*/ HandleStoivas Stoiva_Constructor() {/* Pro: Kamia * Meta: Dhmioyrgia kenhs stoivas */ HandleStoivas ThisStoiva= malloc(sizeof(stackstruct)); ThisStoiva->korifi = -1; return ThisStoiva; void Stoiva_Destructor(HandleStoivas * StoivaPtrPtr) {/* Pro: Dhmioyrgia ths stoiva * Meta: Katastrofi ths stoivas */ free(*stoivaptrptr); *StoivaPtrPtr = NULL; int Stoiva_keni(const HandleStoivas StoivaPtr) {/* Pro: Dhmioyrgia ths stoiva * Meta: Epistrefei 1 an h stoiva einai kenh alliws 0 */ return (StoivaPtr->korifi == -1); int Stoiva_gemati(const HandleStoivas StoivaPtr) {/* Pro: Dhmioyrgia ths stoiva * Meta: Epistrefei 1 an h stoiva einai gemath alliws 0 */ return (StoivaPtr->korifi == PLITHOS-1);
void Stoiva_exagogi(const HandleStoivas StoivaPtr, TStoixeioyStoivas * const stoixeioptr, int *ypoxeilisi) {/* Pro: Mh kenh stoiva * Meta: Eksagetai to stoixeio apo th stoiva */ if (Stoiva_keni(StoivaPtr)) *ypoxeilisi = 1; { *ypoxeilisi = 0; TSstoiva_setValue(stoixeioPtr,StoivaPtr- >pinakas[stoivaptr>korifi]); StoivaPtr->korifi--; void Stoiva_othisi(const HandleStoivas StoivaPtr,TStoixeioyStoivas stoixeio, int *yperxeilisi) {/* Pro: Dhmioyrgia ths stoiva * Meta: Wtheitai to stoixeio sth stoiva */ if (Stoiva_gemati(StoivaPtr)) *yperxeilisi = 1; { *yperxeilisi = 0; StoivaPtr->korifi++; TSstoiva_setValue(&(StoivaPtr->pinakas[StoivaPtr- >korifi]), stoixeio); 2.3.2.2 Αρχεία Δοκιμής Στα αρχεία δοκιμής περιλαμβάνεται το αρχείο main που χρησιμοποιείται ως αρχείο test για τις πράξεις της ATΔ Στοίβα. Ακολουθεί ο κώδικας του αρχείου δοκιμής: #include <stdio.h> #include "Stack-OA.h" #include "../../TS/TStoixeioyStoivas.h" void print_options(void);
int main(void) { int option, error,out_err; HandleStoivas stack; TStoixeioyStoivas x; error=0; stack=null; do{ print_options(); {case 1: scanf("%d", &option); switch(option) case 2: stack=stoiva_constructor(); printf("\nh stoiva dimiourgithike!\n"); if(stack==null) { printf("\nden iparxei stoiva gia na eisaxthei stoixeio!\n"); printf("dwse ena stoixeio: "); out_err=tsstoiva_readvalue(stdin,&x); if(out_err==eof) { printf("\n error stin readvalue!\n"); eishx8h!\n"); Stoiva_othisi(stack, x, &error); if(error) printf("\nyperxeilhsh stoivas. To stoixeio DEN printf("\nto stoixeio eishx8h!\n"); case 3: if(stack==null) {printf("\nden iparxei stoiva gia na eksaxthei stoixeio!\n"); Stoiva_exagogi(stack, &x, &error);
if(error) printf("\nkeni stoiva!\n"); { printf("\nekshx8h epityxws to stoixeio "); out_err=tsstoiva_writevalue(stdout,x); if(out_err <0) { printf("\n error stin writevalue!\n"); case 4: if(stack==null) { printf("\nden iparxei stoiva gia na elexthei an einai kenh!\n"); if(stoiva_keni(stack)) printf("\nh stoiva einai kenh!\n"); printf("\nh stoiva DEN einai kenh!\n"); case 5: if(stack==null) { printf("\nden iparxei stoiva gia na katastraphei!\n"); Stoiva_Destructor(&stack); printf("\nh stoiva katastrafike!\n"); case 6: /* demonstrate non access */ /* stack->korifi=-1; dereferencing pointer to incomplete type */ while(option); return 0;
void print_options(void) { printf("\n\n1. Dhmioyrgia stoivas\n\ 2. Othisi stoixeiou sth stoiva\n\ 3. Eksagwgh stoixeiou apo th stoiva\n\ 4. Elegxos gia kenh stoiva\n\ 5. Katastrofi\n\ 6. Illegal access (no action) \n\n\ Dwste thn epilogh sas(1-6, 0 gia eksodo):"); Ακόμη όμως περιλαμβάνονται όπως και στην μερική απόκρυψη τα αρχεία Διεπαφής και Υλοποίησης της στοίβας (δεν δίνεται κώδικας επειδή είναι ουσιαστικά ο ίδιος με τα πρότυπα αρχεία). 2.3.3 Αρχεία Διεπαφής-Υλοποίησης Τύπου Στοιχείου Στοίβας Ουσιαστικά πρόκειται για τα αρχεία που υλοποιούν τις βασικές πράξεις του τύπου στοιχείου Στοίβας και ανάλογα με το τι τύπο στοιχείου θέλει και ο χρήστης, όπως αναλύεται και στο κεφάλαιο 2, υπάρχουν δυνατές 3 υλοποιήσεις του τύπου στοιχείου. TS-int: Ακολουθεί ο κώδικας του αρχείου Διεπαφής: #ifndef TStoixeioyStoivas_H #define TStoixeioyStoivas_H #include <stdio.h> typedef int TStoixeioyStoivas; void TSstoiva_setValue (TStoixeioyStoivas *target, TStoixeioyStoivas source); int TSstoiva_readValue (FILE *from, TStoixeioyStoivas * Elem); int TSstoiva_writeValue (FILE *to, TStoixeioyStoivas Elem); #endif Ακολουθεί ο κώδικας του αρχείου Yλοποιήσης: #include "TStoixeioyStoivas.h" void TSstoiva_setValue (TStoixeioyStoivas *target, TStoixeioyStoivas source) { *target=source;
int TSstoiva_readValue (FILE *from, TStoixeioyStoivas * Elem) { int fd; fd=fscanf(from, "%d", Elem); return fd; int TSstoiva_writeValue (FILE *to, TStoixeioyStoivas Elem) { int fd; fd=fprintf(to, "%d", Elem); return fd; TS-string: Ακολουθεί ο κώδικας του αρχείου Διεπαφής: #ifndef TStoixeioyStoivas_H #define TStoixeioyStoivas_H #include <stdio.h> typedef char[15] TStoixeioyStoivas; void TSstoiva_setValue (TStoixeioyStoivas *target, TStoixeioyStoivas source); int TSstoiva_readValue (FILE *from, TStoixeioyStoivas Elem); int TSstoiva_writeValue (FILE *to, TStoixeioyStoivas Elem); #endif Ακολουθεί ο κώδικας του αρχείου Yλοποιήσης: #include "TStoixeioyStoivas.h" void TSstoiva_setValue (TStoixeioyStoivas *target, TStoixeioyStoivas source) { strncpy(*target, source, 15); int TSstoiva_readValue (FILE *from, TStoixeioyStoivas *Elem) { int fd; fd=fscanf(from, "%s", Elem);
return fd; int TSstoiva_writeValue (FILE *to, TStoixeioyStoivas Elem) { int fd; fd=fprintf(to, "%s", Elem); return fd; TS-struct: Ακολουθεί ο κώδικας του αρχείου Διεπαφής: #ifndef TStoixeioyStoivas_H #define TStoixeioyStoivas_H #define PLITHOS 15 #include <stdio.h> typedef struct { int integer; char string[plithos]; TStoixeioyStoivas; //typedef struct TStoixeioyStoivas[15]; void TSstoiva_setValue (TStoixeioyStoivas *target, TStoixeioyStoivas source); int TSstoiva_readValue (FILE *from, TStoixeioyStoivas * Elem); int TSstoiva_writeValue (FILE *to, TStoixeioyStoivas Elem); #endif Ακολουθεί ο κώδικας του αρχείου Yλοποιήσης: #include "TStoixeioyStoivas.h" void TSstoiva_setValue (TStoixeioyStoivas *target, TStoixeioyStoivas source) { *target=source; int TSstoiva_readValue (FILE *from, TStoixeioyStoivas * Elem) { int fd; fd=fscanf(from, "%d %s ", Elem->integer,Elem->string); return fd;
int TSstoiva_writeValue (FILE *to, TStoixeioyStoivas Elem) { int fd; fd=fprintf(to, "%d %s ", Elem.integer,Elem.string); return fd; Προφανώς έξω από τους φακέλους στα πλαίσια της επιλογής του χρήστη και όσων άλλων παραθέτονται στο κεφάλαιο 2 για την επεξήγηση των αρχείων της συγκεκριμένης ενότητας βρίσκονται πάλι τα αρχεία Διεπαφής και Υλοποίησης του TS-int ως default υλοποίηση που χρησιμοποιούν οι δοκιμέςmain των επιμέρους υλοποιήσεων της στοίβας (Μερική, Ολική απόκρυψη).