Ενδεικτικές Λύσεις σε Επιλεγμένα Θέματα της C++

Σχετικά έγγραφα
Ενδεικτικές Λύσεις σε Επιλεγμένα Θέματα της C++

Ενδεικτικές Λύσεις σε Επιλεγμένα Θέματα της C++

Προγραμματισμός Υπολογιστών με C++ Φύλλο Διαγωνίσματος Ακαδημαϊκό εξάμηνο: Χειμερινό

Προγραμματισμός Υπολογιστών με C++ Φύλλο Διαγωνίσματος Ακαδημαϊκό εξάμηνο: Χειμερινό

Προγραμματισμός Υπολογιστών με C++ Φύλλο Διαγωνίσματος Ακαδημαϊκό εξάμηνο: Χειμερινό

ΚΑΤΑΣΚΕΥΑΣΤΕΣ ΑΝΤΙΓΡΑΦΗΣ

Κλήση Συναρτήσεων ΚΛΗΣΗ ΣΥΝΑΡΤΗΣΕΩΝ. Γεώργιος Παπαϊωάννου ( )

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Κλάσεις και Αντικείμενα Αναφορές

Δομές Δεδομένων. Καθηγήτρια Μαρία Σατρατζέμη. Τμήμα Εφαρμοσμένης Πληροφορικής. Δομές Δεδομένων. Τμήμα Εφαρμοσμένης Πληροφορικής

Διάλεξη 13η: Δυναμική Διαχείρηση Μνήμης, μέρος 1

Δυναμική δέσμευση και αποδέσμευση μνήμης. Προγραμματισμός II 1

Ανάπτυξη και Σχεδίαση Λογισμικού

Πίνακες: μια σύντομη εισαγωγή. Πίνακες χαρακτήρων: τα "Αλφαριθμητικά"

ΔΕΙΚΤΕΣ ΚΑΙ ΔΙΕΥΘΥΝΣΕΙΣ

ΒΑΣΙΚΟΙ ΤΥΠΟΙ ΚΑΙ ΠΙΝΑΚΕΣ

lab13grades Άσκηση 2 -Σωστά απελευθερώνετε ολόκληρη τη λίστα και την κεφαλή

Προγραμματισμός Ι (ΗΥ120)

Τύποι Δεδομένων και Απλές Δομές Δεδομένων. Παύλος Εφραιμίδης V1.0 ( )

Α. unsigned int Β. double. Γ. int. unsigned char x = 1; x = x + x ; x = x * x ; x = x ^ x ; printf("%u\n", x); Β. unsigned char

ΚΑΛΟΥΠΩΜΑΤΑ & ΜΕΤΑΤΡΟΠΕΣ

Προγραμματισμός Η/Υ (ΤΛ2007 )

ΚΛΗΡΟΝΟΜΙΚΟΤΗΤΑ ΚΑΙ ΠΟΛΥΜΟΡΦΙΣΜΟΣ

Διαδικασιακός Προγραμματισμός

Διδάσκων: Κωνσταντίνος Κώστα Διαφάνειες: Δημήτρης Ζεϊναλιπούρ

#include <stdlib.h> Α. [-128,127] Β. [-127,128] Γ. [-128,128]

Sheet2. Σωστή, και µπράβο που µεριµνήσατε για λίστες διαφορετικών µεγεθών.

Προγραμματισμός Ι. Δείκτες. Δημήτρης Μιχαήλ. Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Αντικείμενα με πίνακες. Constructors. Υλοποίηση Στοίβας

Ονοματεπώνυμο και ΑΜ: Είχα παραδώσει εργασίες τα εξής ακαδημαϊκά έτη: Διάρκεια: 2,5 ώρες, κλειστά βιβλία και σημειώσεις ΚΑΛΗ ΕΠΙΤΥΧΙΑ!

Δομημένος Προγραμματισμός. Τμήμα Επιχειρηματικού Σχεδιασμού και Πληροφοριακών Συστημάτων

ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ Η/Υ Ακαδημαϊκό έτος ΤΕΤΡΑΔΙΟ ΕΡΓΑΣΤΗΡΙΟΥ #4

ΕΡΓΑΣΤΗΡΙΟ 9: Συμβολοσειρές και Ορίσματα Γραμμής Εντολής

- Το πρόγραµµα σας δίνει τα αναµενόµενα αποτελέσµατα.

Εισαγωγή στον Προγραμματισμό

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Μαθήματα από τα εργαστήρια

Δομημένος Προγραμματισμός. Τμήμα Επιχειρηματικού Σχεδιασμού και Πληροφοριακών Συστημάτων

I (JAVA) Ονοματεπώνυμο: Α. Μ.: Δώστε τις απαντήσεις σας ΕΔΩ: Απαντήσεις στις σελίδες των ερωτήσεων ΔΕΝ θα ληφθούν υπ όψην.

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Κλάσεις και Αντικείμενα

Προγραμματισμός Υπολογιστών με C++

Ινστιτούτο Επαγγελµατική Κατάρτιση Κορυδαλλού "ΤΕΧΝΙΚΟΣ ΣΥΣΤΗΜΑΤΩΝ ΥΠΟΛΟΓΙΣΤΩΝ" (Ερωτήσεις Πιστοποίησης στην γλώσσα προγραµµατισµού C)

ΠΛΗΡΟΦΟΡΙΚΗ ΙΙ (JAVA) 11/3/2008

Α Β Γ static; printf("%c\n", putchar( A +1)+2); B DB BD. int i = 0; while (++i); printf("*");

Προγραμματισμός Ι. Κλάσεις και Αντικείμενα. Δημήτρης Μιχαήλ. Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Εισαγωγή στον Αντικειμενοστρεφή Προγραμματισμό Διάλεξη #2

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Αντικείμενα ως ορίσματα Εισαγωγή στις αναφορές

2 Ορισμός Κλάσεων. Παράδειγμα: Μηχανή για Εισιτήρια. Δομή μιας Κλάσης. Ο Σκελετός της Κλάσης για τη Μηχανή. Ορισμός Πεδίων 4/3/2008

Οργάνωση Υπολογιστών ΕΛΛΗΝΙΚΗ ΔΗΜΟΚΡΑΤΙΑ ΠΑΝΕΠΙΣΤΗΜΙΟ ΚΡΗΤΗΣ. Ασκήσεις 7: Πρόγραμμα Συνδεδεμένης Λίστας και Διαδικασιών. Μανόλης Γ.Η.

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Αντικείμενα με πίνακες. Constructors. Υλοποίηση Στοίβας

Προγραμματισμός Δομές Δεδομένων

FAIL PASS PASS οριακά

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Αναφορές Στοίβα και Σωρός Μνήμης Αντικείμενα ως ορίσματα

Δομημένος Προγραμματισμός (ΤΛ1006)

Προγραμματισμός Υπολογιστών με C++

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Αναφορές Στοίβα και Σωρός Αναφορές-Παράμετροι

Προγραμματισμός Υπολογιστών με C++

Διάλεξη 06: Συνδεδεμένες Λίστες & Εφαρμογές Στοιβών και Ουρών

Προγραμματισμός Υπολογιστών με C++

Αντικειμενοστραφείς Γλώσσες Προγραμματισμού C++ / ROOT

Διδάσκων: Παναγιώτης Ανδρέου

2.1. Εντολές Σχόλια Τύποι Δεδομένων

Διάλεξη 18η: Διαχείρηση Αρχείων

Προγραμματισμός Υπολογιστών με C++

υναµική διαχείριση µνήµης στη C++ Στην ενότητα αυτή θα µελετηθούν τα εξής επιµέρους θέµατα: ΕΠΛ 132 Αρχές Προγραµµατισµού ΙΙ 2 είκτες

Διδάσκων: Κωνσταντίνος Κώστα Διαφάνειες: Δημήτρης Ζεϊναλιπούρ

Ονοματεπώνυμο και ΑΜ: Είχα παραδώσει εργασίες τα προηγούμενα ακαδημαϊκά έτη: ΚΑΛΗ ΕΠΙΤΥΧΙΑ!

Στη C++ υπάρχουν τρεις τύποι βρόχων: (a) while, (b) do while, και (c) for. Ακολουθεί η σύνταξη για κάθε μια:

Προγραμματισμός Η/Υ (ΤΛ2007 )

Αντικειμενοστρεφής Προγραμματισμός

Α' Εξάμηνο ΕΙΣΑΓΩΓΗ ΣΤΟ ΔΟΜΗΜΕΝΟ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟ

Διδάσκων: Κωνσταντίνος Κώστα Διαφάνειες: Δημήτρης Ζεϊναλιπούρ

Αντικειμενοστραφείς Γλώσσες Προγραμματισμού C++ / ROOT

Διάλεξη 9: Δυναμική Δέσμευση Μνήμης

Κεφάλαιο Αλφαριθμητικές Σειρές Χαρακτήρων (Strings) (Διάλεξη 20) 1) Strings στη C

ΠΡΟΗΓΜΕΝΟΙ ΜΙΚΡΟΕΠΕΞΕΡΓΑΣΤΕΣ PROJECT 2: MEMORY MANAGEMENT

Διδάσκων: Παναγιώτης Ανδρέου

Κλάσεις και Αντικείµενα

Προγραμματισμός Υπολογιστών με C++

Εισαγωγή στον Προγραµµατισµό, Αντώνιος Συµβώνης, ΣΕΜΦΕ, ΕΜΠ,, Slide 6

Διάλεξη 13: Δομές Δεδομένων ΙΙ (Ταξινομημένες Λίστες)

I (JAVA) Ονοματεπώνυμο: Α. Μ.: Δώστε τις απαντήσεις σας ΕΔΩ: Απαντήσεις στις σελίδες των ερωτήσεων ΔΕΝ θα ληφθούν υπ όψην.

Ενδεικτικές λύσεις και στατιστικά

lab13grades 449 PASS 451 PASS PASS FAIL 1900 FAIL Page 1

Προγραμματισμό για ΗΜΥ

Απλές Δοµές Δεδοµένων Στην ενότητα αυτή θα γνωρίσουµε ορισµένες απλές Δοµές Δεδοµένων και θα τις χρησιµοποιήσουµε για την αποδοτική επίλυση του προβλή

ιαφάνειες παρουσίασης #6 (β)

POINTERS, AGGREGATION, COMPOSITION

Προγραμματισμός Ι. Δυναμική Διαχείριση Μνήμης. Δημήτρης Μιχαήλ. Ακ. Έτος Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

ΕΠΛ232 Προγραμματιστικές Τεχνικές και Εργαλεία Δυναμική Δέσμευση Μνήμης και Δομές Δεδομένων (Φροντιστήριο)

Διάλεξη 2: Επανάληψη Προγραμματισμού Συμβολοσειρές (strings) Διδάσκων: Παναγιώτης Ανδρέου

Διδάσκων: Κωνσταντίνος Κώστα Διαφάνειες: Δημήτρης Ζεϊναλιπούρ

ΕΡΓΑΣΤΗΡΙΟ 9: Συμβολοσειρές και Ορίσματα Γραμμής Εντολής

12. ΑΛΦΑΡΙΘΜΗΤΙΚΑ. υο είδη αλφαριθµητικών Τα αλφαριθµητικά της C πίνακες τύπου char Ta αντικείµενα της κλάσης string

Προγραμματισμός Υπολογιστών με C++

H κλάση ArrayList. Γιώργος Θάνος. Γραφείο Γ. Γκλαβάνη 37. Αντικει ενοστραφής Προγρα. ος όροφος

Διαδικασιακός Προγραμματισμός

Κατ οίκον Εργασία 3 Σκελετοί Λύσεων

ΠΛΗ111. Ανοιξη Μάθηµα 7 ο. έντρο. Τµήµα Ηλεκτρονικών Μηχανικών και Μηχανικών Υπολογιστών Πολυτεχνείο Κρήτης

Δείτε τώρα και πώς θα έπρεπε να ήταν το παραπάνω: Page 1

Προγραμματισμός Ι (ΗΥ120)

Αντικειμενοστραφής Προγραμματισμός

Transcript:

Ενδεικτικές Λύσεις σε Επιλεγμένα Θέματα της C++ class ListNode public: T data; ListNode<T> * next; ListNode(const ListNode<T> & src) ; data = src.data; if (src.next!=null) next = new ListNode<T> ((const ListNode<T>) * src.next); else next = NULL; return; Αναδρομική λύση (πιο σύντομος κώδικας) class List protected: ListNode<T> * start; public: List( const List<T> & src) ; if (src.start == NULL) start = NULL; return; else start = new ListNode<T>( src.start ); Δώστε τον κώδικα για τον κατασκευαστή αντιγραφής της παραπάνω κλάσης ListNode έτσι ώστε να δημιουργείται πλήρες αντίγραφο των περιεχομένων που δείχνει ο κόμβος src. Βοήθεια: μπορεί να γίνει αναδρομικά. Η κλάση ListNode χρησιμεύει στην κατασκευή της λίστας List και ο κατασκευαστής αντιγραφής καλείται για να κάνει deep copy μιας λίστας, όπως φαίνεται.

Συμπληρώστε τον κώδικα ώστε να δουλεύει το κύριο πρόγραμμα παρακάτω: class Shape public: virtual void draw () = 0; virtual void print () ; class Box : public Shape public: void draw () ; void print () cout << I am a box ; ; Η Shape έχει μια pure virtual μέθοδο (draw), η οποία πρέπει οπωσδήποτε να οριστεί σε κάποια παράγωγη κλάση πριν μπορέσει να δημιουργηθεί κάποιο στιγμιότυπο της τελευταίας. void main () Shape *a = new Box(); a->print(); // τυπώνει I am a box char buf[] = a, b ; Ποιο θα είναι το αποτέλεσμα τις πράξης: cout << *( (long *) ( (void*) buf ) +1); α) Τυπώνει το χαρακτήρα b. β) Τυπώνει τον ASCII κωδικό (αριθμό) που αντιστοιχεί στο χαρακτήρα b. γ) Τυπώνει κάτι απροσδιόριστο δ) Παράγει compilation error Απάντηση: (γ) Δικαιολογήστε την απάντησή σας: Το buf μετατρέπεται σε δείκτη σε long που μετά αυξάνεται κατά 4 ή 8 bytes βγαίνοντας έξω από τα όρια του αρχικού πίνακα (2 bytes). (void*)buf A : είναι πλέον δείκτης σε απροσδιόριστου μεγέθους δεδομένα (η επαύξηση ενός τέτοιου pointer γίνεται κατά ένα byte). ((long*)a) B : είναι πλέον δείκτης σε δεδομένα τύπου long, άρα με δεδομένη μια υλοποίηση του long με 4 ή 8 bytes (ελάχιστο 4), κάθε επόμενος αριθμός long σε έναν πίνακα (δηλ. σε συνεχόμενες θέσεις μνήμης), απέχει από τον προηγούμενο τουλάχιστο 4 bytes. B+1 C : ο δείκτης έχει προχωρήσει κατά ένα «βήμα», όπου το βήμα είναι ίσο με το μέγεθος του τύπου του δείκτη (εδώ είναι «δείκτης σε long»), άρα τουλάχιστο 4 bytes. *(C) D : παίρνουμε το περιεχόμενο του δείκτη, το οποίο ξεκινάει τουλάχιστο 4 bytes μακριά από τη διεύθυνση buf και άρα δε γνωρίζουμε τι υπάρχει εκεί ή αν μπορούμε καν να το διαβάσουμε (πιθανό access violation).

Ποια είναι η διαφορά μεταξύ των δύο σημειωμένων γραμμών; unsigned int number = 12002; ofstream fs = ofstream("a.out", ios_base::out ); if (!fs.bad()) fs.write(reinterpret_cast<char*>(&number), sizeof(int)); // ΓΡΑΜΜΗ Α fs << number; // ΓΡΑΜΜΗ Β fs.close(); Έστω ότι sizeof(int) 4. Τότε το αρχείο θα περιέχει: Α) 0x00 0x00 0x2E 0xE2, που είναι τα 4 bytes του 12002 σε δεκαεξαδική μορφή (0x00002EE2) B) 0x31 0x32 0x30 0x30 0x32, που είναι οι κωδικοί ASCII των 5 χαρακτήρων του 12002 Η γραμμή Α γράφει με δυαδικό τρόπο τα 2 ή 4 bytes (sizeof(int)) που αναπαριστούν το number Η γραμμή Β μετατρέπει τον αριθμό σε συμβολοσειρά και γράφει σε μορφή κειμένου το 12002

Δίνεται η κλάση: class Container protected: T * storage; size_t num_items; size_t storage_size; public: virtual void operator += (const T item) virtual ~Container() Container() : storage(nullptr), num_items(0), storage_size(0) T & operator [] (size_t index) if (index < num_items) return storage[index]; size_t size() return num_items; ; Επεκτείνετε κατάλληλα την Container, ώστε ο παρακάτω κώδικας να δουλεύει χωρίς σφάλματα και να παράγει το αποτέλεσμα που φαίνεται: void main(int argc, char* argv[]) Container<long> * store = new Box(); *store+=10l; *store+=20l; *store+=30l; for (size_t i=0; i<store->size(); i++) std::cout << (*store)[i] << " "; std::cout << std::endl; delete store; Αποτέλεσμα της εκτέλεσης: 10 20 30 // Συμπληρώστε την αρχικοποίηση // αντικειμένου της δικής σας κλάσης Γράψτε εδώ τη δήλωση της δικής σας κλάσης. Δεν επιτρέπεται να αλλοιώσετε την Container, ούτε να χρησιμοποιήσετε κλάσεις της STL. H Container έχει μεν υλοποιημένο τον τελεστή +=, αλλά δεν κάνει τίποτα. Η παράγωγη κλάση αυτής (εδώ θα την πούμε Box ), πρέπει να υλοποιήσει πλήρως όλη τη διαδικασία εισαγωγής στοιχείων σε δυναμική γραμμική συλλογή. Επιπλέον, πρέπει να φτιάξουμε έναν καταστροφέα ο οποίος να μπορεί να διαγράφει την περιοχή μνήμης storage, αν αυτή έχει δεσμευθεί. Παρατηρήστε ότι ο καταστροφέας της Container είναι virtual, ώστε να μπορέσει να κληθεί σωστά ο καταστροφέας της Box. Για την παράγωγη κλάση πρέπει να ισχύουν τα ακόλουθα: - Πρέπει να αρχικοποιεί προαιρετικά τον πίνακα storage σε ένα προκαθορισμένο μέγεθος. Αυτό δεν είναι απαραίτητο όμως και για οικονομία, συνήθως δεν αρχικοποιούμε δυναμικές συλλογές αν δεν αρχίσουμε να τις γεμίζουμε. Στην προτεινόμενη υλοποίηση, κρατάμε τον default constructor της βασικής κλάσης και δεσμεύουμε μνήμη μόνο όταν χρειαστεί. - Πρέπει να αποδεσμεύει μνήμη της storage σε έναν δικό της καταστροφέα, μόνο στην περίπτωση που η storage δεν είναι NULL. - Πρέπει να μπορεί να χειριστεί εισαγωγές στοιχείων τυχαίου πλήθους με τον τελεστή +=. - Για την υλοποίηση του +=, χρειάζεται να προσέξουμε τα ακόλουθα: - Αν ο χώρος storage είναι μη εκχωρημένος, τον δημιουργούμε ίσο με έναν αριθμό στοιχείων της αρεσκείας μας. - Αν num_items < storage_size, μπορούμε να εισάγουμε άφοβα ένα νέο στοιχείο στη θέση num_items. - Αν num_items == storage_size (μεγαλύτερο δε θα είναι αφού πάντα αυξάνει κατά 1), πρέπει να επεκτείνουμε το storage

class Box : public Container<T> public: void operator += (const T item) if (storage_size==0) storage_size = 2; storage = new T[storage_size]; else if (storage_size==num_items) storage_size*=2; T * buffer = new T[storage_size]; memcpy(buffer,storage,sizeof(t)*storage_size/2); delete [] storage; storage = buffer; storage[num_items++] = item; Ο έλεγχος storage_size==0 εδώ είναι ισοδύναμος με τον storage==nullptr Αν δεν έχει δεσμευθεί το storage, δέσμευσε το χώρο και ενημέρωσε το storage_size Αν φτάσαμε στο όριο των στοιχείων του storage: - Όρισε το νέο επιθυμητό μέγεθος - Δέσμευσε έναν καινούριο χώρο (εδώ διπλάσιο) - Αντέγραψε τα παλιά δεδομένα στην αρχή του νέου χώρου - Διέγραψε τον παλιό χώρο και κράτησε ως storage τον καινούριο Πρόσθεσε στην επόμενη διαθέσιμη θέση το νέο στοιχείο ; ~Box() if (storage!=nullptr) delete [] storage; Διαγράφουμε μόνο όταν έχει δεσμευθεί η μνήμη Παρατήρηση: η memcpy θα μπορούσε να αντικατασταθεί από ένα loop αντιγραφής στοιχείων 1 προς 1.

// Η κλάση Counter κατασκευάζεται με βάση ένα std::vector // από δεδομένα οποιουδήποτε τύπου και αυτό που κάνει είναι να αναφέρει // πόσες φορές υπάρχει ένα συγκεκριμένο στοιχείο μέσα στο vector // κατά τη στιγμή της δημιουργίας ενός στιγμιοτύπου Counter. // class Counter private: std::unordered_map<t,size_t> histogram; public: // Μοναδικός κατασκευαστής Counter(std::vector<T> & input); // Συμπληρώστε πεδία που χρειάζεται η κλάση Στην συγκεκριμένη έκδοση του προβλήματος (εξεταστική Ιουνίου 2014), ο τύπος και το εύρος τιμών Τ δεν είναι γνωστά. Στην παραλλαγή του θέματος της εξεταστικής Σεπτεμβρίου 2014, είχαμε μικρό εύρος τιμών (256) και δεδομένο τύπο (char), οπότε υπήρχε και πιο απλή υλοποίηση, με σταθερό πίνακα τύπου size_t μήκους 256 για 256 ανεξάρτητους μετρητές. Πρέπει να δημιουργήσουμε μια δική μας δομή που να φυλάει δεδομένα για την καταμέτρηση. Η δημιουργία γίνεται κατά την αρχικοποίηση του Counter και δε μπορούμε να θεωρήσουμε ότι το input παραμένει αναλλοίωτο μετά από αυτή τη στιγμή. Χρειαζόμαστε μια «αραιή» συλλογή που να συνδέει ένα κλειδί (τιμή του T) με έναν πληθυσμό. ; // Αναφέρει πόσες φορές ένα συγκεκριμένο στοιχείο βρέθηκε μέσα στο vector<t> // input. Αν το στοιχείο δεν υπάρχει, αναφέρει 0, αλλιώς το αριθμό των φορών // που το έχει συναντήσει size_t GetCount(T item); Counter<T>::Counter(std::vector<T> & input) size_t num = input.size(); for ( size_t i=0; i<num; i++) histogram[input[i]]++; size_t Counter<T>::GetCount(T item) std::unordered_map<t,size_t>::iterator got = histogram.find(item); if (got == histogram.end()) return 0; else return got->second; ; Ο τελεστής [] του unordered_map, αν δεν υπάρχει το ζεύγος με κλειδί Τ, το δημιουργεί (καλεί «default constructor» για το size_t, δηλαδή το θέτει ίσο με 0, αφού το size_t είναι βασικός τύπος και όχι κλάση) και μας επιστρέφει αναφορά στο pair.second, δηλαδή στο πεδίο τύπου size_t. Αν υπάρχει ζεύγος με κλειδί Τ, μας επιστρέφει και πάλι το second του ζεύγους, οπότε πάντα ισχύει ο τελεστής ++ Αν δε βρεθεί το στοιχείο, επιστρέφουμε 0, αλλιώς το second του ζεύγους που επιστρέφει ο Iterator. Προσοχή: εδώ θα μπορούσαμε να καλέσουμε ακόμα και απλά: return histogram[item] γιατί αυτό που θα γίνει είναι να φτιάξει μια νέα εγγραφή με κλειδί item αν το item δεν υπάρχει και να του βάλει τιμή 0, οπότε και πάλι το αποτέλεσμα θα

Ενδεικτική χρήση: void main(int argc, char* argv[]) vector<long> data; data.push_back(-10); data.push_back(1); data.push_back(1); ήταν σωστό. Όμως, σε αυτή την περίπτωση για κάθε «άστοχη» κλήση της GetCount (δηλαδή για κλειδιά που δεν υπάρχουν ήδη στο histogram), θα επεκτείνεται χωρίς λόγο η συλλογή μας, με αποτέλεσμα κάποια στιγμή να γίνει βαριά, χωρίς λόγο. Κατά αντιστοιχία, θα μπορούσαμε να χρησιμοποιήσουμε μηχανισμό find/insert και στον κατασκευαστή. Counter<long> cnt = Counter<long>(data); size_t found = cnt.getcount(-10); found = cnt.getcount(0); found = cnt.getcount(1); // found==1 // found==0 // found==2 Πώς θα δεσμεύσω 100 στοιχεία τύπου string* και θα αναθέσω το αποτέλεσμα σε μια αντίστοιχη μεταβλητή με όνομα mydata; mydata = string ** mydata = new string * [100]; string ** mydata = (string**) new void * [100]; string ** mydata = (string**)malloc(sizeof(string*)*100); string ** mydata = (string**)malloc(sizeof(void*)*100); Δεσμεύουμε έναν πίνακα από δείκτες σε string. Όχι έναν πίνακα από string. Εναλλακτικά, μπορούμε να δεσμεύσουμε και με την malloc την μνήμη. Θυμόμαστε να αποδεσμεύσουμε τον πίνακα με τη free() σε αυτή την περίπτωση. Όπως βλέπετε, είναι αδιάφορο τι τύπου δείκτη θα δεσμεύσουμε πραγματικά, αφού το μέγεθος ενός δείκτη είναι δεδομένο (θέση μνήμης). Πρέπει όμως στη συνέχεια να κάνουμε το απαραίτητο cast στον τύπο της μεταβλητής. Δίνεται η ακόλουθη κλάση: class node_t protected: char data; public: node_t(const char letter) : next(0) data = letter; class node_t * next; ;

Συμπληρώστε τον απαραίτητο κώδικα στις γραμμές που δίνονται ώστε να μετασχηματιστεί το περιεχόμενο του data στον παρακάτω κώδικα από αυτό που φαίνεται στο σχήμα 1Α σε αυτό του 1Β, χωρίς να προκαλέσετε διαρροή μνήμης: (25 μονάδες) void main() node_t ** data = new node_t*[4]; // γέμισμα της δομής, όπως φαίνεται στο σχήμα 1Α. // σας δίνεται έτοιμο... // Απάντηση στο ερώτημα: data[1] = data[0]; data[0] = 0; data[3] = data[2]; data[2] = new node_t( E ); delete data[3]->next; data[3]->next = data[1]->next; Ο πίνακας data αποθηκεύει δείκτες σε node_t αντικείμενα. Η μετάθεση των ακολουθιών ΑΒ και CD από τη θέση 0 στην 1 και τη 2 στην 3 αντίστοιχα γίνεται πολύ απλά βάζοντας το δείκτη στη νέα θέση να δείχνει στο ίδιο στοιχείο με την παλιά θέση. Στη συνέχεια, μηδενίζουμε το δείκτη data[0]. Προσοχή: ΔΕ διαγράφουμε το δείκτη, αφού η μνήμη δείχνεται πλέον από τη θέση data[1]! Αν το κάνουμε αυτό θα χάσουμε και τα δεδομένα του data[1]. Εναλλακτικά, αντί για data[χ]->next, μπορούμε να γράψουμε (*data[3]).next 0 0 0 Α C Α E C 0 Β D Β 0 0 Σχήμα 1Α 0 Σχήμα 1Β

char * d = You: 0 points ; while (*(++d)!=0) std::cout << * ; Τι θα τυπωθεί; ************ (12 αστεράκια) Η επανάληψη θα διακοπεί όταν συναντηθεί το μηδέν, ή αλλιώς ο χαρακτήρας \0. Προσοχή: ο χαρακτήρας 0 (ASCII code 48) δεν είναι ίσος με το μηδέν ή NULL ή nullptr ή \0 (ASCII code 0). Πάντα, ένας πίνακας χαρακτήρων που παριστάνει μια έγκυρη συμβολοσειρά, ειδικά αν είναι στατικά δοσμένη όπως εδώ, τερματίζεται με το 0, γι αυτό και λέγεται «nullterminated string». class A public: int number; A(int d) : number(d) ; A & operator = (const A & right) number = 2 * right.number; return *this; ; Τι θα συμβεί στις παρακάτω περιπτώσεις; A a(1); A * p_a; A a2; p_a = new A(a); // (α) // (β) // (γ) // (δ) std::cout << (p_a == &a); // (ε) a = 2; // (στ) α) Δεσμεύεται και αρχικοποιείται μια μεταβλητή τύπου Α στην call stack καλώντας τον δηλωμένο κατασκευαστή. β) Δηλώνεται ένας δείκτης σε A. Δεν αρχικοποιείται.

γ) Επιχειρείται δήλωση και αρχικοποίηση αντικειμένου Α με χρήση του default κατασκευαστή. Ο κατασκευαστής αυτός όμως έχει καταργηθεί, επειδή ορίσαμε δικό μας κατασκευαστή για την κλάση ο οποίος απαιτεί όρισμα compilation error. δ) Δίνουμε αρχική τιμή στο δείκτη p_a καλώντας τον προκατασκευασμένο copy constructor ε) Τυπώνει 0 (false), αφού οι δύο διευθύνσεις δεν είναι ίδιες. στ) Δημιουργείται προσωρινό αντικείμενο με κλήση του κατασκευαστή A(int) αφού υπάρχει κατασκευαστής που δέχεται ως όρισμα τον τύπο του δεδομένου (int 2). Στη συνέχεια, καλείται ο τελεστής αντιγραφής για το a με αποτέλεσμα να πάρει το πεδίο a.number την τιμή 4.