ΣΙΝΑΤΚΑΣ Ι ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ 2010-11 1 ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ ΜΑΘΗΜΑ 10 Ο Δομές Ενώσεις Απαριθμητοί τύποι δεδομένων
Εισαγωγή Οι βασικοί τύποι δεδομένων στην C είναι char, int, float και double Το επόμενο βήμα δεδομένων οι πίνακες, ενώ μεν έχουν πολλές θέσεις και διαστάσεις, σε όλες τους όμως τις θέσεις δέχονται έναν και μόνο τον ίδιο τύπο δεδομένων Πολλές φορές όμως διαφορετικού τύπου δεδομένα, αλφαριθμητικά, ακέραιοι, δεκαδικοί μπορεί να συνδέονται μεταξύ τους και να συναποτελούν ενιαίο αδιαίρετο σύνολο στοιχείων Στην περίπτωση αυτή ορίζεται σύνθετος τύπος δεδομένων Ο τύπος αυτός δημιουργείται από τον προγραμματιστή και αποτελεί την δομή, πρόδρομο της κλάσης Αντίθετα άλλες φορές, στο ίδιο τμήμα της μνήμης, αποθηκεύονται δεδομένα διαφορετικού τύπου και σχηματίζουν την έννοια της ένωσης Με τον τρόπο αυτό εξοικονομείται μνήμη καθώς όλα τα δεδομένα της ένωσης μοιράζονται την ίδια αρχική διεύθυνση μνήμης και προσφέρεται η δυνατότητα ευέλικτων δομών Εισάγεται η έννοια του πολυμορφισμού Σε άλλες περιπτώσεις οι τιμές που δέχεται μια μεταβλητή είναι περιορισμένες και συγκεκριμένες, όπως για παράδειγμα τα ονόματα των μηνών του έτους, ή τα εργαστηριακά τμήματα του μαθήματος Προγραμματισμός Οι μεταβλητές που χειρίζονται τέτοια στοιχεία, που έχουν τη μορφή λίστας λέγονται απαριθμητού τύπου ΣΙΝΑΤΚΑΣ Ι ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ 2010-11 2
Η δομή βελτιώνει τη δυνατότητα των πινάκων να χειρίζεται ο προγραμματιστής πολλά δεδομένα με κοινό όνομα μεταβλητής Το πρόβλημα του πίνακα είναι ότι σε όλες του τις θέσεις δέχεται και χειρίζεται ιδίου τύπου δεδομένα Η δομή ξεπερνά αυτόν τον περιορισμό και δημιουργεί μεταβλητή που δέχεται διαφορετικού τύπου δεδομένα και τα χειρίζεται ενιαία ως ομάδα Το τίμημα που πληρώνεται όμως είναι ότι η αναφορά σε κάθε επιμέρους μέλος τηςομάδαςγίνεταιμεόνομακαι όχι με δείκτη, όπως γίνεται στον πίνακα struct όνομα τύπος δεδομένων1 μεταβλητή1; τύπος δεδομένων2 μεταβλητή2; τύπος δεδομένων3 μεταβλητή3; Δομή (structure) 1/5 struct StdRecord char StId[5]; /* ΑΕΜ */ char FirstName[15];/* Όνομα */ char LastName[20];/* Επώνυμο */ int Absences; /* Απουσίες */ float WrkGrd[3]; /*3 βαθμοί εργασιών*/ float FnlGrd; /* Τελικός βαθμός */ ΣΙΝΑΤΚΑΣ Ι ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ 2010-11 3
Δομή 2/5 ΣΙΝΑΤΚΑΣ Ι ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ 2010-11 4 Στα προηγούμενα παρουσιάσθηκε ο τρόπος που δηλώνεται η δομή και δόθηκε παράδειγμα δήλωσης μιας δομής για την περίπτωση εγγραφής που αφορά φοιτητή Μέχρι εδώ κατασκευάσθηκε νέος τύπος δεδομένων με όνομα StdRecord ο οποίος μπορεί να χρησιμοποιηθεί στη συνέχεια να προσδιορίζει τον τύπο μεταβλητών Για παράδειγμα η δήλωση του προγράμματος struct StdRecord student, learner; Δηλώνει δύο μεταβλητές δομής την student και την learner που αποτελούν εγγραφές με τη συγκεκριμένη δομή που περιγράφεται από την StdRecord και διαθέτει 6 πεδία Ηαναφοράσταμέλητηςδομής, γίνεται με τον τελεστή (τελεία) ως εξής: studentabsences στις απουσίες με studentwrkgrd[1] στον βαθμό τηςδεύτερηςεργασίαςκοκ Για παράδειγμα studentabsences=3; Τοποθετεί στο συγκεκριμένο πεδίο την ακέραιη τιμή 3 studentwrkgrd[1]=78; Τοποθετεί στην 2 εργασία βαθμό 78
Δομή 3/5 Υπάρχει η δυνατότητα να ορισθεί μεταβλητή πίνακας ως δομή Για παράδειγμα η δήλωση struct StdRecord student[50]; αναφέρεται όπως προηγουμένως στην μεταβλητή student η οποία όμως τώρα επεκτείνεται σε 50 θέσεις και επομένως ανάλογα με την τιμή του δείκτη το πρόγραμμα αναφέρεται σε διαφορετικό φοιτητή Στην περίπτωση αυτή, η αναφοράσταμέλητηςδομήςγίνεταιόπωςκαι προηγουμένως με τη διαφορά ότι ο τελεστής τίθεται μετά τον δείκτη του πίνακα Student[4]Absences=2; Τοποθετεί στον τέταρτο φοιτητή 2 απουσίες Student[9]WrkGrd[0]=83; Τοποθετεί στην 1 εργασία του 9 φοιτητή βαθμό 83 Επίσης μπορεί να ορισθεί μεταβλητή δείκτης ως δομή με την δήλωση struct StdRecord *student; ηαναφοράσταμέλητηςδομήςδείκτημπορεί να γίνει με τον τελεστή αλλά στην περίπτωση δείκτη προτιμάται ο τελεστής ως εξής (*Student)Absences=2; (*Student)WrkGrd[0]=83; Student Absences=2; Student WrkGrd[0]=83; ΣΙΝΑΤΚΑΣ Ι ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ 2010-11 5
Δομή 4/5 Πρέπει να σημειωθεί επίσης ότι υπάρχει η δυνατότητα να ορισθεί δομή που να εμπεριέχει άλλη δομή Στην περίπτωση αυτή όταν γίνεται αναφορά σε μέλος της εμφωλιασμένης δομής απαιτούνται δύο τελείες Για παράδειγμα studentlabgrad[3]; αναφέρεται στον βαθμό της δομής student που εμπεριέχει τη δομή lab και από τη δομή lab αναφερόμαστε στο μέλος της grad και μάλιστα στον βαθμό της τρίτης εργαστηριακής άσκησης Προϋπόθεση της διαδικασίας αυτής είναι να, προηγηθεί στον ορισμό struct η εμφωλιασμένη δομή και να ακολουθήσει ο ορισμός της δομής που τη συμπεριλαμβάνει struct LabRec char title[30]; /* τίτλος εργαστηριακής άσκησης */ float grad[13]; /* βαθμός κάθε άσκησης από τις 13 */ Στη συνέχεια δηλώνεται η νέα δομή StdRecord, που εμπεριέχει ως μέλος της, τη δομή αυτή struct StdRecord char StId[5]; char FirstName[15]; char LastName[20]; int Absences; float WrkGrd[3]; struct LabRec lab; float FnlGrd; ΣΙΝΑΤΚΑΣ Ι ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ 2010-11 6
Δομή 5/5 Ο χειρισμός των μελών της δομής γίνεται μεμονωμένα για κάθε μέλος χωριστά Για παράδειγμα : studentlabgrad[3]=75; ή strcpy (studentlastname, Σινάτκας ); Ωστόσο η πιο κάτω δήλωση καταχωρεί όλες τις τιμές της student στα ίδια πεδία της learner learner= student; Βεβαίως για να γνωρίζει κανείς το μέγεθος μνήμης που απαιτείται για συγκεκριμένη δομή χρειάζεται να μετρηθούν συνολικά τα bytes που έχουν διατεθεί σε κάθε μέλος της δομής Η μέτρηση αυτή μπορεί να γίνει με την συνάρτηση sizeof(όνομα μεταβλητής τύπου δομής); και επιστρέφει σε ακέραιο τον αριθμό των bytes Η πιο κάτω δήλωση δομής παρουσιάζει σημαντική ιδιαιτερότητα Ορίζει το μέγεθος των μελών του σε bit Για παράδειγμα Κάθε τραπουλόχαρτο διακρίνεται για το χρώμα, την τιμή του, το είδος του και αν υπάρχουν 2 τράπουλες την τράπουλα Όλα αυτά μαζί μπορούν να κωδικοποιηθούν σε 1 byte στη δομή CARD struct CARD unsigned int color:1; unsigned int face:4; unsigned int suit:2; unsigned int deck:1;} ΣΙΝΑΤΚΑΣ Ι ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ 2010-11 7
Ένωση (union) 1/3 ΣΙΝΑΤΚΑΣ Ι ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ 2010-11 8 Η ένωση (union) αποτελεί τμήμα μνήμης όπου αποθηκεύονται δεδομένα διαφορετικού τύπου Στη διαχείρισή της, η ένωση μοιάζει με την δομή Η διαφορά τους συνίσταται στο ότι τα δεδομένα της ένωσης επικαλύπτονται, σε αντίθεση με τα διακριτά δεδομένα της δομής Αυτό σημαίνει ότι κάθε στιγμή, ένα μόνο μέλος της ένωσης μπορεί να αξιοποιηθεί από το πρόγραμμα Η δήλωση της ένωσης είναι παρόμοια με τη δομή και είναι : union όνομα τύπος μεταβλητή1; τύπος μεταβλητή2; τύπος μεταβλητή3; Ακολουθεί παράδειγμα δήλωσης της ένωσης member με 3 μέλη Το μέγεθος της ένωσης, σε αντίθεση, με την δομή, καθορίζεται από το μέγεθος μνήμης που καταλαμβάνει το μεγαλύτερό της μέλος union member int k; float f; char name[10]; Η δήλωση μεταβλητής αυτού του τύπου είναι union member μεταβλητή1,2,; παράδειγμα union member oros, *melos;
Ένωση 2/3 ΣΙΝΑΤΚΑΣ Ι ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ 2010-11 9 Η αναφορά σε μέλος ένωσης με τη δομή γίνεται όπως και στα μέλη των δομών Χρησιμοποιείται δηλαδή ο τελεστής (τελεία) και ο στην περίπτωση μεταβλητής ένωσης δείκτη Παράδειγμα η αναφορά στο μέλος k της μεταβλητής oros γίνεται ως orosk ενώ στην μεταβλητή melos ως melos f Υπενθυμίζεται ότι μπορεί να χρησιμοποιηθεί η sizeof(oros) για να υπολογισθεί το μέγεθος της ένωσης, όπως γίνεται και με την δομή Ποια είναι η χρησιμότητα της ένωσης; 1Η αναφορά στην ίδια θέση μνήμης με διαφορετικό μέλος της ένωσης 2Η δυνατότητα ένθεσης ένωσης μέσα σε δομή, που παρέχει τη δυνατότητα δημιουργίας ευέλικτων δομών Δομών δηλαδή, που δέχονται δυναμικά διαφορετικούς τύπους τιμών
Ένωση 3/3 Το παράδειγμα που ακολουθεί είναι χαρακτηριστικό αναφοράς στην ίδια θέση μνήμης με διαφορετικό μέλος της ένωσης struct BYTE unsigned int b1:1; unsigned int b2:1; unsigned int b3:1; unsigned int b4:1; unsigned int b5:1; unsigned int b6:1; unsigned int b7:1; unsigned int b8:1; union CODE struct BYTE binary; char nr; } code; Με τις δηλώσεις της διπλανής δομής και της ένωσης υπάρχει η δυνατότητα να δίνεται ακέραιος από 0 έως 255 και να εμφανίζεται η δυαδική του παράσταση Έτσι στην ίδια θέση μνήμης που καταλαμβάνει ένα byte αποτελούμενο από 8 bits αποθηκεύεται αριθμός ενός byte και επομένως στα μεμονωμένα bits της δομής BYTE καταχωρούνται τα 0 και 1 που αποτελούν την δυαδική παράστασή του ΣΙΝΑΤΚΑΣ Ι 10
Η δυνατότητα ένθεσης δομής σε ένωση δίνει φτερά στον προγραμματισμό Αποτελεί τον πρόδρομο του πολυμορφισμού Δηλαδή με μια και μόνο συνάρτηση, την ίδια σε κάθε περίπτωση, δίνεται η δυνατότητα να εκτελούνται διάφορες ενέργειες ανεξάρτητα από τον τύπο των ορισμάτων της Για παράδειγμα μπορεί να σχεδιασθεί, με τη σύνθεση κατάλληλης δομής συνάρτηση πολλαπλασιασμού, που επιστρέφει ως αποτέλεσμα πραγματικό αριθμό, είτε δεχθεί ως όρους πολλαπλασιασμού δύο πραγματικούς είτε δύο διανύσματα του χώρου οπότε επιστρέφει το εσωτερικό τους γινόμενο ΣΙΝΑΤΚΑΣ Ι Ένωση 4/ struct ARRAY float x; float y; float z; union TPE float res; struct ARRAY a; } var1, var2; float mult(union TPE var1,union TPE var2); int main() } float mult(union TPE var1,union TPE var2) float var; var=var1res*var2res; var=var1ax*var2ax+var1ay*var2ay+var1az*var2az; return(var); } 11
Απαριθμητός τύπος (enumeration type) Οι μεταβλητές απαριθμητού τύπου δεδομένων λαμβάνουν συγκεκριμένες διακριτές τιμές πχ αποτελούν ένα σύνολο δυνατών επιλογών, ημέρες της εβδομάδας, μήνες του έτους, χαρακτηρισμοί όπως άριστος, πολύ καλός, καλός, μέτριος, κακός Η δήλωση γίνεται με την enum όνομα τύπου τιμή1, τιμή2,τιμήν Για παράδειγμα η δήλωση enum direction Βορράς, Ανατολή, Νότος, Δύση} dir1, dir2; Δηλώνονται δύο μεταβλητές οι dir1, dir2 που δέχονται μόνο τις τέσσερεις αυτές τιμές, και μάλιστα η κάθε μια τους έχει αντιστοιχηθεί στο 0,1,2 και 3 με τη σειρά που δηλώθηκαν Ως αποτέλεσμα προκύπτει ότι αυτού του τύπου τις μεταβλητές μπορεί να τις χειρισθεί ο προγραμματιστής όπως ακριβώς τους ακεραίους Δηλαδή μπορεί να τις χρησιμοποιήσει στην switch ήακόματουπόλοιπο της διαίρεσης που προκύπτει με το πλήθος των τιμών του συνόλου προσδιορίζει την τιμή Για παράδειγμα η 323 η ημέρα προσδιορίζεται ως 323%7=1 άρα αν η Κυριακή ορισθεί πρώτη η τιμή 1 αντιστοιχεί στην Δευτέρα ΣΙΝΑΤΚΑΣ Ι ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ 2010-11 12