440 likes | 567 Views
ΔΟΜΕΣ ΔΕΔΟΜΕÎΩÎ. ΦÏοντιστήÏια Εισηγητής : ΣπÏÏος ΑÏγυÏόπουλος ÎœÎλος ΕΤΕΠΕÏγαστήÏιο Î ÏογÏÎ±Î¼Î¼Î±Ï„Î¹ÏƒÎ¼Î¿Ï & Τεχνολογίας Ευφυών Συστημάτων. Abstract Data Types. Abstract Data Type (ADT): a definition for a data type solely in terms of a set of values and a set of operations on that data type.
E N D
ΔΟΜΕΣ ΔΕΔΟΜΕΝΩΝ Φροντιστήρια Εισηγητής: Σπύρος Αργυρόπουλος Μέλος ΕΤΕΠ Εργαστήριο Προγραμματισμού & Τεχνολογίας Ευφυών Συστημάτων
Abstract Data Types Abstract Data Type (ADT): a definition for a data type solely in terms of a set of values and a set of operations on that data type. Each ADT operation is defined by its inputs and outputs. Encapsulation: Hide implementation details.
Data Structure • A data structure is the physical implementation of an ADT. • Each operation associated with the ADT is implemented by one or more subroutines in the implementation. • Data structure usually refers to an organization for data in main memory. • File structure is an organization for data on peripheral storage, such as a disk drive.
Logical vs. Physical Form Data items have both a logical and a physical form. Logical form: definition of the data item within an ADT. • Ex: Integers in mathematical sense: +, - Physical form: implementation of the data item within a data structure. • Ex: 16/32 bit integers, overflow.
Data Type • ADT: • Type • Operations Data Items: Logical Form • Data Structure: • Storage Space • Subroutines Data Items: Physical Form
C++ • Πρότυπα συναρτήσεων : return_type function_name(type1 name1, type2 name2, ...); • Δηλώσεις σταθερών : const double PI = 3.1415; char *strcpy(char *target, const char *source);
C++ (συνέχεια) • Μεταβίβαση παραμέτρων δια μέσου αναφοράς: int string2int(char *string, int &flag); int result, status;result = string2int("5", status);if (status == 0) { ... • Υπερφόρτωση ονομάτων (overloading): Παράδειγμα
C++ (συνέχεια) • Δηλώσεις μεταβλητών σε οποιοδήποτε σημείο του κώδικα • Εξ ορισμού τιμές για παραμέτρους συναρτήσεων (default values): FILE *open_file(const char *path, const char *mode = "r") { return fopen(path, mode); }
C++ (συνέχεια) • Συναρτήσεις inline : inline int max(int x, int y){return x > y ? x : y;} inline double max(double x, double y) {return x > y ? x : y;} • Ορισμός τελεστών Παράδειγμα • Τελεστές εισόδου, εξόδου (cin, cout, cerr) Παράδειγμα
C++ (συνέχεια) • Σχόλια: i++; // Το i αυξάνεται κατά 1 j++; // Το ίδιο και το j
C++ (συνέχεια) • Κλάσεις αντικειμένων (Classes) • Private, public, protected members • Methods & inline functions • Constructor, destructor • Copy constructor • Τελεστής ανάθεσης • Δείκτης this • Τελεστές new & delete (γενικό παράδειγμα)
C++ (συνέχεια) • Κληρονομικότητα • Επανορισμός μεθόδων, διπλός ορισμός μεταβλητής • Συμβατότητα δεικτών / αναφορών • Virtual methods, virtual table, pure virtual methods
C++ (συνέχεια) • Friend classes • Static member κλάσεων • Class templates template <class T> class myTemplate {...}; Παράδειγμα • Exception classes
void Input(char *prompt, int &i) { …. } void Input(char *prompt, double &d){ …. } void Input(char *prompt, char *s){ …. } int main(void){ int my_integer; double my_double; char my_string[100]; Input("Δώστε τιμή για το my_integer", my_integer); Input("Δώστε τιμή για το my_double", my_double); Input("Δώστε τιμή για το my_string", my_string); printf("my_integer = %d\nmy_double = %f\nmy_string = %s\n",my_integer, my_double, my_string); }BACK
typedef struct Employee{ char name[100]; int salary; } Employee; void operator +=(Employee &e, int raise){ e.salary = e.salary + raise; } int main(void){ Employee e1; strcpy(e1.name, "Janitor John"); e1.salary = 100; e1 += 200; /* Κλήση του τελεστή που ορίσαμε */ printf("%d\n", e1.salary);return 0; }BACK
int a; double b; char c[100]; cin >> a; /* Ανάγνωση του a */ cin >> b >> c; /* Ανάγνωση δύο μεταβλητών, πρώτα της b και μετά της c */ cout << "Η τιμή του a είναι " << a << "\n"; cout << "Η τιμή του b είναι " << b << endl; /* Η σταθερά endl σημαίνειαλλαγή γραμμής */ cout << "Η τιμή του c είναι " << c << endl; BACK
class Person{ private: char name[30]; char address[50]; int birth_year; public: void set_name(const char *); void set_address(const char *); void set_birth_year(int y) {birth_year = y;} const char *get_name(void) const {return name;} const char *get_address(void) const {return address;} int get_birth_year(void) const {return birth_year;} }; BACK
void Person::set_name(const char *n) { strncpy(name, n, 29); name[29] = '\0'; } void Person::set_address(const char *a) { strncpy(address, a, 49); name[49] = '\0'; } BACK
class String { private: char *str; public: String(void); // Συνάρτηση κατασκευής χωρίς παραμέτρους String(const char *s); // Συνάρτηση κατασκευής όπου ορίζεται // η τιμή που επιθυμούμε να αποδόσουμε στο στιγμιότυπο ~ String(void); // Συνάρτησηκαταστροφής void set_value(const char *s); const char *get_value(void) const {return str;} }; BACK
String::String(void){str = strdup("");} String::String(const char *s){str = strdup(s); } String::~String(void){free(str);} void String::set_value(const char *s) { free(str); str = strdup(s); } BACK
Copy costructor String(String &s) {str = strdup(s.str);} Τελεστής ανάθεσης void operator=(String &s) {free(str); str = strdup(s.str);} BACK
void Person::marry(Person &new_spouse) { // Ελεγχος αν και οι δύο είναι ελεύθεροι if ((spouse != NULL) || (new_spouse.spouse != NULL)) { cerr << "Πρέπει και οι δύο να είναι ελεύθεροι!" << endl; return; } spouse = &new_spouse; new_spouse.spouse = this; } BACK
class IntegerListNode { private: int value; // Η τιμή του κόμβου IntegerListNode *next; // Ο δείκτης στον επόμενο public: IntegerListNode(int v, IntegerListNode *n) { value = v; next = n; } int getValue(void) const {return value;} void setNext(IntegerListNode *n) {next = n;} IntegerListNode *getNext(void) const {return next;} }; BACK
class IntegerList{ private: IntegerListNode *first; public: IntegerList(void); //Συνάρτηση κατασκευής ~IntegerList(void); // Συνάρτηση καταστροφής void add(int v); // Προσθήκη κόμβου με συγκεκριμένη τιμή int remove(int v); // Διαγραφή κόμβου με συγκεκριμένη τιμή. // Επιστρέφουμε 1 σε επιτυχία, 0 σε αποτυχία // (δεν υπάρχει τέτοιος κόμβος. int has(int v) const; // Ελεγχος ύπαρξης κόμβου με συγκεκριμένη // τιμή. Επιστρέφουμε // 1 αν υπάρχει, 0 αν δεν υπάρχει. };
IntegerList::IntegerList(void){ // Δημιουργία του dummy κόμβου με αδιάφορη τιμή και NULL ως // επόμενο, δηλ. ο dummy κόμβος είναι ο τελευταίος στη λίστα. first = new IntegerListNode(0, NULL); } IntegerList::~IntegerList(void){ IntegerListNode *cur, *nxt; // Διατρέχουμε τους κόμβους της λίστας for (cur = first; cur != NULL; ) { nxt = cur->getNext(); // Κάθε φορά φυλάμε τον επόμενο delete cur; // ... σβήνουμε τον τρέχοντα cur = nxt; // ... και προχωράμε στον επόμενο } }
void IntegerList::add(int v){ // Προσθέτουμε τον νέο κόμβο ως πρώτο στη λίστα, // αμέσως μετά από τον dummy. IntegerListNode *newNode = new IntegerListNode(v, first->getNext()); first->setNext(newNode); } int IntegerList::remove(int v){ // Προσπάθεια εντοπισμού του κόμβου που θα διαγραφεί. Σε κάθε βήμα // φροντίζουμε να δείχνουμε έναν κόμβο πιο πριν, έτσι ώστε να // μπορούμε να τροποποιήσουμε τον κατάλληλο δείκτη next. // Φυσικά, η τιμή του πρώτου κόμβου αγνοείται.
for (IntegerListNode *prev = first; prev->getNext() != NULL; prev = prev->getNext()){ if (prev->getNext()->getValue() == v){ // βρέθηκε ο κόμβος που πρέπει να διαγραφεί IntegerListNode *victim = prev->getNext(); // Βγάζουμε τον κόμβο-θύμα από τη λίστα, συνδέοντας // απ' ευθείας τον προηγούμενό του με τον επόμενό του prev->setNext(victim->getNext()); // αποδεσμεύουμε τη μνήμη για τον κόμβο-θύμα delete victim; return 1; // Επιστροφή με ένδειξη επιτυχίας } } return 0; // Επιστροφή με ένδειξη αποτυχίας }
int IntegerList::has(int v) const { // Αναζήτηση του κόμβου. Ο πρώτος κόμβος αγνοείται συνολικά. for (IntegerListNode *n = first->getNext(); n != NULL; n = n->getNext()) if (n->getValue() == v) return 1; // Ναι, βρέθηκε return 0; // Οχι, η λίστα εξαντλήθηκε χωρίς να βρεθεί. } BACK
class B: [public] A { • ... • }; • Κανόνες: • Όσα είναι private στην Αδεν είναι ορατά στη Β. • Όταν δεν έχει παρατεθεί η λέξη public, όλα τα public της Α είναι private για τη Β. • Όταν έχει παρατεθεί η λέξη public, όλα τα public της Α είναι public για τη Β. • Όσα είναι protected στην Αείναι ορατά στη Βκαι είναι χαρακτηρισμένα πάλι ως protected. • BACK
Παράδειγμα: #include <iostream.h> #include <stdlib.h> template <class T> class Array { private: T *data; int maxSize; public: Array(int size); ~Array(void) { delete [] data;} Array<T> &setValue(const T &value, int position); T getValue(int position); };BACK
template <class T> Array<T>::Array(int size) { if (size <= 0) { cerr << "Μη παραδεκτό μέγεθος για πίνακα (" << size << ")\n"; exit(1); } if ((data = new T[size]) == NULL) { cerr << "Δεν υπάρχει αρκετή μνήμη για τον πίνακα.\n"; exit(1); } maxSize = size; }BACK
template <class T> Array<T> &Array<T>::setValue(const T &value, intposition) { if ((position < 0) || (position >= maxSize)) { cerr << "Μη παραδεκτός δείκτης για πίνακα (" << position << ")\n"; exit(1); } data[position] = value; return *this; } BACK
template <class T> T Array<T>::getValue(int position) { if ((position < 0) || (position >= maxSize)) { cerr << "Μη παραδεκτός δείκτης για πίνακα (" << position << ")\n"; exit(1); } return data[position]; } BACK
int main(void) { Array<int> a(50); for (int i = 0; i < 100; i++) { a.setValue(i * 2, i); cout << "Position " << i << ", value " << a.getValue(i) << endl; } return 0; } BACK
template <class T> class MyList; template <class T> class MyListNode { private: // Δήλωση της κλάσης MyList ως φίλης, ώστε να έχει πρόσβαση // στα ιδιωτικά τμήματα. friend class MyList<T>; T datum; MyListNode<Τ> *next; // Παραθέτουμε και μία μέθοδο κατασκευής. Η μέθοδος αυτή // παραμένει ιδιωτική, καθώς προσπελαύνεται μόνο από την // MyList<T> κλάση η οποία έχει δηλωθεί ως φίλη κλάση. MyListNode(T d, MyListNode<Τ> *n) { datum = d; next = n;} };BACK
template <class T> class MyList { private: MyListNode<T> *first; MyListNode<T> **find(const T target) { MyListNode<T> **result; for (result = &first;*result != NULL;result = &((*result)->next)) if ((*result)->datum == target) return result; // Δεν βρέθηκε κατάλληλος κόμβος return NULL; } public: MyList(void) {first = NULL;} BACK
~MyList(void) { MyListNode<T> *victim, *nxt; for (victim = first; victim != NULL; victim = nxt) { nxt = victim->next; delete victim; } } MyList<T> &insert(const T datum) { MyListNode<T> *newNode = new MyListNode<T>(datum, first); first = newNode; return *this; } BACK
MyList<T> &remove(const T datum) { MyListNode<T> **victim, *next; victim = find(datum); if (victim == NULL) return *this; next = (*victim)->next; delete (*victim); *victim = next; return *this; }
int search(const T datum) { MyListNode<T> **temp = find(datum); if (temp == NULL) return 0; else return 1; } }; // end of class definition BACK
class Person { public: char idNumber[20]; char name[100]; int birthYear; Person(const char *i, const char *n, int b) { strcpy(idNumber, i); strcpy(name, n); birthYear = b; } }; BACK
int main(void) { MyList<int> IntegerList; IntegerList.insert(2); IntegerList.insert(7); printf("Searching for 2... %d\n", IntegerList.search(2)); printf("Searching for 5... %d\n", IntegerList.search(5)); printf("Searching for 7... %d\n", IntegerList.search(7)); printf("Removing 2...\n"); IntegerList.remove(2); printf("Searching for 2... %d\n", IntegerList.search(2)); printf("Searching for 7... %d\n", IntegerList.search(7));
MyList<Person> PersonList; Person p1("A312", "John", 1968), p2("C5670", "Mary", 1974), p3("Z80", "Zilog", 1978); PersonList.insert(p1); PersonList.insert(p2); printf("Searching for \"John\"... %d\n", PersonList.search(p1)); printf("Searching for \"Mary\"... %d\n", PersonList.search(p2)); printf("Searching for \"Zilog\"... %d\n", PersonList.search(p3)); printf("removing \"Mary\"\n"); PersonList.remove(p2); printf("Searching for \"Mary\"... %d\n", PersonList.search(p2)); return 0; }BACK