Θέµατα εξετάσεων µε απαντήσεις 1. Τι αλλαγές θα κάνατε στον παρακάτω κώδικα αν θέλατε να εφαρµόσετε την αρχή του αµυντικού προγραµµατισµού (1 µονάδα); #define LENGTH 10 char *strings[length]; char *getstring(int position) { if (position >= LENGTH) { return NULL; return strings[position]; Οι αρχές του αµυντικού προγραµµατισµού ορίζουν ότι κάθε συνάρτηση θεωρεί ότι τα δεδοµένα που της δίνουν µπορεί να µην είναι σωστά και πρέπει να κάνει τους αντίστοιχους ελέγχους. Στη συγκεκριµένη περίπτωση τα µόνα δεδοµένα που περνάν είναι µέσω της παραµέτρου position. Άρα πρέπει να γίνεται έλεγχος σε αυτήν την παράµετρο αν έχει λανθασµένη τιµή. Βλέπουµε ότι ήδη γίνεται έλεγχος αν είναι πάνω από τα όρια του πίνακα (>=LENGTH) αλλά δε γίνεται έλεγχος αν είναι κάτω από τα όρια του πίνακα (<0). Άρα σύµφωνα µε τις αρχές του αµυντικού προγραµµατισµού πρέπει να την αλλάξουµε ώστε να ελέγχει και την περίπτωση που η µεταβλητή αυτή είναι µικρότερη του 0. 2. Πώς θα αλλάζατε την παρακάτω συνάρτηση ώστε να συµφωνεί µε το προγραµµατιστικό πρότυπο που είδαµε στο µάθηµα; (0.5 µονάδα) // Επέστρεψε TRUE αν είναι χαρακτήρας που αντιστοιχεί σε ψηφίο, // FALSE διαφορετικά bool checkcharacter(char c); Πρέπει το όνοµα της συνάρτησης, από τη στιγµή που επιστρέφει µια λογική τιµή, να δηλώνει πότε επιστρέφει TRUE ή FALSE. Το ακόλουθο όνοµα εποµένως θα ταίριαζε περισσότερο: bool isdigit(char c); 3. Σας δίνουν την ακόλουθη περιγραφή που αφορά ένα σύστηµα ηλεκτρονικής έκδοσης εισιτηρίων για ένα κινηµατογράφο: Κάθε εισιτήριο πρέπει να αναγράφει την τιµή του, τον αριθµό της θέσης, την αίθουσα, την παράσταση στην οποία αναφέρεται και την ηµεροµηνία. Κάθε αίθουσα έχει διαφορετικό αριθµό από καρέκλες. Ο κινηµατογράφος διαθέτει 4 απλές αίθουσες και δύο αίθουσες VIP οι οποίες έχουν επιπλέον και έναν αριθµό από τραπέζια. Μία παράσταση έχει κάποιο συγκεκριµένο τίτλο και έναν αριθµό από ηθοποιούς. Τα µόνα στοιχεία που χρησιµοποιούνται για τους ηθοποιούς είναι το όνοµά τους και το αν έχουν βραβευθεί µε Oscar ή όχι. a. Σχεδιάστε ένα διάγραµµα κλάσεων σε UML από την παραπάνω περιγραφή. (1 µονάδα) Το ακόλουθο είναι ένα πιθανό διάγραµµα κλάσεων που θα µπορούσε να προκύψει από την περιγραφή:
b. Γράψτε τις δηλώσεις των κλάσεων σε C++. Γράψτε µόνο τα χαρακτηριστικά (attributes) των κλάσεων χωρίς τις µεθόδους (συναρτήσεις) τους. (1 µονάδα) class Ticket { float price; int seatnumber; Room myroom; Film myfilm; class Film { string title; vector<actors> myactors; class Cinema { Room myroom[4]; VipRoom myviproom[2]; class Actors { string name; boolean hasoscar; class Room { int chairs; Cinema mycinema; class VipRoom:public Room { int tables; Cinema mycinema; 4. Έχετε αναλάβει την υλοποίηση ενός παιχνιδιού. Στο παιχνίδι αυτό θα πρέπει να εµφανίζονται δράκοι και τέρατα. Και οι δράκοι και τα τέρατα έχουν τις ίδιες δυνατότητες (ρίχνουν φωτιά και πετούνε) αλλά το κάνουν µε διαφορετικό τρόπο. Για αυτό το λόγο θα θέλατε να µπορέσετε να γράψετε τον κώδικά σας ούτως ώστε να µη χρειάζεται αλλαγές αν σε κάποιο σηµείο χρειαστεί να δηµιουργήσετε και να επεξεργαστείτε δράκους ή τέρατα. a. Ποιο µοτίβο θα χρησιµοποιούσατε (0,5 µονάδα); Θα χρησιµοποιούσα το Factory Pattern b. Αναπαραστήστε το µοτίβο σε ένα διάγραµµα κλάσεων σε UML (1,0 µονάδα)
c. Αν στο παιχνίδι σας µπορεί να υπάρχει µόνο ένας δράκος ή τέρας πως θα τροποποιούσατε το µοτίβο σας (1,0 µονάδα); Eξαρτάται αν µπορεί να υπάρχει ένα τέρας και ένας δράκος ή αν πρέπει να υπάρχει µόνο ένας δράκος ή τέρας. Στην πρώτη περίπτωση θα εφάρµοζα το singleton µοτίβο στις κλάσεις Monster και Dragon στη δεύτερη στην κλάση CreatureFactory (Για την απάντηση αυτή δε χρειαζόταν να απαντήσετε και για τις δύο περιπτώσεις, Οποιαδήποτε από τις δύο ήταν σωστή). d. ώστε αναπαράσταση της τροποποίησης σε UML (1,0 µονάδα) ίνεται η λύση για την πρώτη περίπτωση.
5. Έχετε τον παρακάτω κώδικα typedef struct Person { char name[30]; char surname[30]; Person; void setname(person person, char *name) { strcpy(person.name, name); Είναι καλά σχεδιασµένος ή όχι; Γιατί; (1.0 µονάδα) Όχι υπάρχει σύζευξη αντιγράφου. ε χρειάζεται να περαστεί όλη η δοµή Person στη συνάρτηση γιατί δε χρησιµοποιείται όλη. Έτσι δίνεται χωρίς λόγο πρόσβαση και στα άλλα πεδία του struct. Θα ήταν πιο σωστό η συνάρτηση να οριστεί ως εξής: void setname(char *dest, char *name); [Σηµείωση. Ούτως ή άλλως η συνάρτηση αυτή δεν εκπληρώνει το σκοπό της. Γιατί;] 6. Στο παρακάτω διάγραµµα UML Η κλάση Window είναι αφηρηµένη. Ποιος ο ρόλος της; Γιατί χρειαζόµαστε τις αφηρηµένες κλάσεις; (2.0 µονάδες) Ο ρόλος των αφηρηµένων κλάσεων είναι να ορίσουν τη διεπαφή (interface) µε την οποία µπορούν να χρησιµοποιηθούν όσες κλάσεις τις κληρονοµούν. Μας επιτρέπουν να σκεφθούµε τι λειτουργικότητα πρέπει να προσφέρει µια κλάση χωρίς να µπερδευόµαστε µε λεπτοµέρειες υλοποίησης.