Πολυεπίπεδες εγγραφές |
Οι εγγραφές που είδαμε μέχρι τώρα είναι σχετικά απλές. Μιά εγγραφή μπορεί να περιέχει μεγάλο αριθμό πεδίων διαφορετικού τύπου. Επίσης μπορεί να περιέχει σύνθετες δομές όπως πίνακες αριθμών ή χαρακτήρων. Τελικά μπορεί μιά εγγραφή να περιέχει και άλλες εγγραφές. Είναι όμως λογικό όταν η δομή μας είναι σύνθετη να ακολουθεί μιά ιεραρχική δομή. Το πρόγραμμα που βρίσκεται στο αρχείο NESTED.C δίνει ένα τέτοιο παράδειγμα. Η πρώτη δήλωση ορίζει μιά εγγραφή που περιέχει μερικά βασικά στοιχεία ταυτότητας ενός προσώπου. Περιέχει τρία πεδία, τη συμβολοσειρά name, την ηλικία age και τον χαρακτήρα status που παίρνει τις τιμές M (παντρεμένος) και S (ανύπαντρος) μόνο. Να σημειωθεί οτι η δήλωση της εγγραφής δεν συνοδεύεται από δήλωση μεταβλητών του τύπου της εγγραφής αφού δεν υπάρχουν ονόματα μετά το κλείσιμο της αγκύλης. Αντίθετα υπάρχει το όνομα person πριν από το άνοιγμα της αγκύλης. Το όνομα αυτό αντιστοιχεί στον τύπο της εγγραφής και όχι σε μεταβλητή του τύπου αυτού. Πρόκειται δηλαδή γιά ονοματοδοσία ενός τύπου και όχι μεταβλητής. Το όνομα person μπορεί από εδώ και πέρα να χρησιμοποιηθεί αντί της ακριβούς περιγραφής της δομής αλλά πρέπει να συνοδεύεται από τη λέξη κλειδί struct. Η χρήση αυτή γίνεται κατανοητή στην επόμενη δήλωση εγγραφής. Ορίζεται ένας τύπος εγγραφής με όνομα alldat και επίσης ορίζεται ένας πίνακας 53 εγγραφών του τύπου alldat με το όνομα student. Κάθε εγγραφή του τύπου alldat περιέχει ως πεδία τον ακέραιο grade (βαθμός), τη συμβολοσειρά lunch και μιά εγγραφή του τύπου person που έχει το όνομα descrip. Πρόκειται δηλαδή γιά μιά δήλωση πολυεπίπεδης εγγραφής, όπου μία εγγαρφή αποτελεί πεδίο μιάς άλλης εγγραφής. Μιά πιό απλή αλλά και πιό δύσχρηστη δήλωση θα μπορούσε να ήταν η παρακάτω struct alldat { int grade; char name[25]; int age; char status; /* M = married, S = single */ char lunch[25]; } student[53]; η οποία όμως δεν δίνει τη δυνατότητα ιδαίτερου χειρισμού των προσωπικών στοιχείων (name, age, status). Τελικά ορίζονται και δύο μεταβλητές του τύπου εγγραφής alldat με τα ονόματα teacher και sub. Οι προτάσεις του προγράμματος δίνουν παραδείγματα πρόσβασης στα πεδία των διαφόρων εγγραφών. Διαπιστώνουμε τη χρήση πολυεπίπεδων ονομάτων πεδίων που αντιστοιχούν στον τρόπο που έχουν ιεραρχηθεί οι εγγραφές στη δήλωσή τους. Επιπλέον οποιοδήποτε από τα ονόματα μπορεί να είναι μέρος ενός πίνακα. Ακόμη μπορεί να επιτύχουμε πρόσβαση είτε με συμβατικές μεθόδους είτε με τη βοήθεια δεικτών. Το πρόγραμμα αυτό δεν παράγει αποτέλεσμα στην οθόνη όμως μπορεί να προκαλέσει ένα λάθος εκτέλεσης. Συνήθως οι μεταφραστές της C έχουν μέγεθος στοίβας 2048 bytes (2Κbytes). Επομένως οι αυτόματες μεταβλητές πρέπει να χωρέσουν σε αυτό το σωρό. Στη περίπτωσή μας χρειαζόμαστε τουλάχιστο 55x55 bytes που είναι προφανώς περισσότερα από τα διατιθέμενα και προκαλούμε υπερχείλιση της στοίβας. Οι λύσεις είναι τρείς: Πρώτη λύση είναι η μεταφορά των δηλώσεων εκτός του κυρίως προγράμματος. Οι μεταβλητές θα γίνουν γενικές και άρα στατικές και επομένως δεν θα τοποθετηθούν στη στοίβα. Δεύτερη λύση είναι να δηλωθούν οι μεταβλητές ως τοπικές μεν αλλά ως στατικές άρα και πάλι δεν θα καταλάβουν χώρο στη στοίβα. Τρίτη λύση είναι η αύξηση του μεγέθους της στοίβας σύμφωνα με τις οδηγίες του εγχειριδίου του μεταφραστή. Το δίδαγμα της όλης υπόθεσης είναι οτι όταν έχουμε δεδομένα σημαντικού όγκου αποφεύγουμε να τα δηλώσουμε ως αυτόματη μεταβλητή αλλά προτιμούμε στατική δήλωση. |
![]() |
![]() |
![]() |