Εγγραφές, ενώσεις και TYPEDEF

Το επόμενο πρόγραμμα UNION2.C δίνει ένα πιό συνηθισμένο παράδειγμα χρήσης 
των ενώσεων. Ας πούμε οτι θέλετε να χτίσετε μιά βάση δεδομένων γιά μέσα 
μεταφοράς. Είναι προφανές οτι δεν είναι σωστό να ορίσουμε αριθμό τροχών γιά 
ένα σκάφος ή αριθμό κινητήρων γιά ένα αυτοκίνητο. Το ορθότερο είναι να 
έχουμε ορισμένα στοιχεία κοινά γιά όλα τα μέσα μεταφοράς και ορισμένα 
στοιχεία ειδικά γιά κάθε μέσο. 

Πρώτα ορίζονται με #define μερικές σταθερές που απλά δίνουν ονόματα σε 
ορισμένους διακόπτες που καθορίζουν τον τύπο του μέσου μεταφοράς. Στη 
συνέχεια δηλώνεται μιά εγγραφή που αντιστοιχεί στα αυτοκίνητα, με όνομα 
τύπου εγγραφής automobile. 

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

struct {
   ....
} όνομα; 

ακόμη συνατήσαμε ονόματα τύπων εγγραφής στη μορφή

struct όνομα {
   ....
}; 

Τώρα συναντούμε ονόματα τύπων γενικά με δήλωση της μορφής

typedef struct {
   ....
} όνομα;

Όταν ορίζουμε έναν τύπο με typedef τότε το όνομά του τύπου μπορεί να 
χρησιμοποιηθεί ακριβώς όπως οι καθιερωμένοι τύποι int, char κλπ. χωρίς να 
είναι αναγκαία η παράθεση και άλλων λέξεων όπως struct, όπως στη 
περίπτωση του ονόματος τύπου εγγραφής. Έτσι η λέξη BOATDEF περουσιάζεται 
παρακάτω γιά να ορίσει τον τύπο των στοιχείων ship και boat της ένωσης 
vehicle_type. H χρήση κεφαλαίων χαρακτήρων στο όνομα ακολουθεί τη 
παράδοση του #define  γιά να γίνεται καλύτερος διαχωρισμός μεταβλητών και 
σταθερών. 

Η μεγάλη εγγραφή που ακολουθεί αποτελείται από 5 πεδία: Τα δύο πρώτα είναι 
οι απλές μεταβλητές vehicle και weight. Το τρίτο πεδίο είναι μιά ένωση με 
γενικό όνομα vehicle_type. Ακολουθούν δύο ακόμη απλά πεδία με ονόματα 
value και owner. Ας εξετάσουμε πιό προσεκτικά την ένωση. Περιέχει 4 στοιχεία: 
Το πρώτο στοιχείο είναι η μεταβλητή car που είναι εγγραφή του τύπου 
automobile. Το δεύτερο στοιχείο είναι η μεταβλητή boat του τύπου BOATDEF. Το 
τρίτο στοιχείο είναι η μεταβλητή εγγραφή airplane που ορίζεται επι τόπου. Το 
τέταρτο στοιχείο είναι η μεταβλητή ship του τύπου BOATDEF. Η δήλωση 
τερματίζεται με τα ονόματα τριών μεταβλητών ford, sun_fish, piper_cub 
που είναι του τύπου της μεγάλης εγγραφής.

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

...

union common_type {
	struct auto_type car;      
      struct boat_type boat, ship;           
      struct air_type airplane;  
};

struct all_type {
   char vehicle;          
   int weight;          
   union common_type1 vehicle_type;
   int value;            
   char owner[32];       
};

struct all_type ford, sun_fish, piper_cub;

Παρόμοια θα μπορούσαν να αντικατασταθούν όλα τα ονόματα τύπων εγγραφών 
ή ενώσεων με τύπους εγγραφών ή ενώσεων με χρήση του typedef. 

...

#typedef union  {
	AUTO_INFO car;      
      BOAT_INFO boat, ship;           
      AIR_INFO airplane;  
} COMMON_INFO;

#typedef struct {
   char vehicle;          
   int weight;          
   COMMON_INFO vehicle_type;
   int value;            
   char owner[32];       
}ALL_INFO;

ALL_INFO ford, sun_fish, piper_cub;

Η πλήρης αντικατάσταση των δηλώσεων του προγράμματος αφήνεται σαν 
άσκηση στον αναγνώστη.

Ας δούμε τι γίνεται τώρα από την πλευρά του μεταφραστή. 'Εχουμε μιά εγγραφή 
που μπορεί να χρησιμοποιηθεί γιά την αποθήκευση τεσσάρων διαφορετικών 
ειδών μέσων μεταφοράς. Το μέγεθος του χώρου αποθήκευσης (αριθμός bytes) γιά 
κάθε εγγραφή καθορίζεται από τα απαιτούμενα bytes γιά τη μέγιστη εγγραφή. Η 
μέγιστη εγγραφή αντιστοιχεί στην εγγραφή που περιέχει ως πεδίο το μέγιστο 
στοιχείο της ένωσης. Το μέγιστο στοιχείο της ένωσης είναι η εγγραφή 
περιγραφής αυτοκινήτου. Άρα γιά κάθε εγγραφή απαιτούνται 40 bytes, και γιά 
τις 3 μεταβλητές σύνολο 120 bytes.

Η ακριβής τοποθέτηση των πεδίων μέσα στα 40 bytes κάθε εγγραφής 
καθορίζεται από τον προγραμματιστή με βάση το πεδίο vehicle, που λέγεται και 
πεδίο-διακόπτης. Το πεδίο αυτό παίρνει τιμές με βάση τις δηλωμένες σταθερές 
AUTO, BOAT, PLANE, SHIP. Τα δεδομένα που θα αποθηκευτούν στα υπόλοιπα 
πεδία πρέπει να βρίσκονται σε συνέπεια με την τιμή του πεδίου vehicle, και 
αυτό είναι δουλειά του προγραμματιστή. Οι εκτελέσιμες προτάσεις του 
προγράμματος δίνουν μερικά παραδείγματα χειρισμού μιάς πολυεπίπεδης και 
μεταβαλόμενης εγγραφής με τη βοήθεια ενός πεδίου-διακόπτη. Η εκτύπωση 
είναι πολύ απλή
 
The ford has 5 tires

Περιεχόμενα Κεφαλαίου