Γενίκευση ( genericity ) Ι

36
Σάββατο, 18 Ιουνίου 2022 Σάββατο, 18 Ιουνίου 2022 Τμ. Πληροφορικής, Α.Π.Θ. Τμ. Πληροφορικής, Α.Π.Θ. 1 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Γενίκευση (genericity) Ι Ο λόγος που επιδιώκουμε τη δυνατότητα γενίκευσης μιας κλάσης (ή συνάρτησης) είναι το να μπορούμε να κάνουμε τον ορισμό της χωρίς να προσδιορίσουμε τον τύπο ενός ή περισσοτέρων μελών της (παράμετροι). Έτσι, θα μπορούμε να προσαρμόζουμε την κλάση (συνάρτηση) σε διαφορετικές περιπτώσεις χρήσης της χωρίς να επιβάλλεται να την ξαναγράψουμε. ΠΑΡΑΔΕΙΓΜΑ Πρέπει να γράψουμε τον κώδικα για μια ουρά ή μια στοίβα. Μπορούμε εύκολα να ορίσουμε μια ουρά ακεραίων, αλλά τι γίνεται όταν θέλουμε σε μία ουρά να χρησιμοποιούμε αντικείμενα τύπου date; Κάθε γλώσσα αντιμετωπίζει το παραπάνω πρόβλημα και με διαφορετικό τρόπο.

Upload: haven

Post on 13-Jan-2016

54 views

Category:

Documents


3 download

DESCRIPTION

Γενίκευση ( genericity ) Ι. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Γενίκευση ( genericity ) Ι

Παρασκευή, 21 Απριλίου 2023Παρασκευή, 21 Απριλίου 2023 Τμ. Πληροφορικής, Α.Π.Θ.Τμ. Πληροφορικής, Α.Π.Θ. 11

ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ

Γενίκευση (genericity) ΙΟ λόγος που επιδιώκουμε τη δυνατότητα γενίκευσης μιας κλάσης (ή συνάρτησης) είναι το να μπορούμε να κάνουμε τον ορισμό της χωρίς να προσδιορίσουμε τον τύπο ενός ή περισσοτέρων μελών της (παράμετροι). Έτσι, θα μπορούμε να προσαρμόζουμε την κλάση (συνάρτηση) σε διαφορετικές περιπτώσεις χρήσης της χωρίς να επιβάλλεται να την ξαναγράψουμε.

ΠΑΡΑΔΕΙΓΜΑ

Πρέπει να γράψουμε τον κώδικα για μια ουρά ή μια στοίβα. Μπορούμε εύκολα να ορίσουμε μια ουρά ακεραίων, αλλά τι γίνεται όταν θέλουμε σε μία ουρά να χρησιμοποιούμε αντικείμενα τύπου date;

Κάθε γλώσσα αντιμετωπίζει το παραπάνω πρόβλημα και με διαφορετικό τρόπο.

Page 2: Γενίκευση ( genericity ) Ι

Παρασκευή, 21 Απριλίου 2023Παρασκευή, 21 Απριλίου 2023 Τμ. Πληροφορικής, Α.Π.Θ.Τμ. Πληροφορικής, Α.Π.Θ. 22

ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ

Γενίκευση (genericity) ΙΙΣτη Smalltalk όπου ο έλεγχος τύπων γίνεται σε χρόνο εκτέλεσης ο πολυμορφισμός δεν περιορίζεται στις ιεραρχίες των κλάσεων, αλλά κάθε κλάση μπορεί να αντικατασταθεί από μία άλλη. Έτσι, η γενίκευση γίνεται εύκολα.

Στη C++ έχουμε έλεγχο τύπων σε χρόνο μεταγλώττισης. Υπάρχουν δύο τρόποι για την επίτευξη γενίκευσης:

με χρήση κληρονομικότητας και πολυμορφισμού ορίζοντας κλάση, που χειρίζεται δείκτες σε αντικείμενα

με χρήση παραμετροποιήσιμων τμημάτων κώδικα, των επονομαζόμενων templates

Η πρώτη μέθοδος (βλ. παράδειγμα παρακάτω) συνοδεύεται από έναν κίνδυνο με την κατ΄ απαίτηση προσαρμογή (casting) που χρειάζεται στην ανάκτηση του τύπου των αντικειμένων που χειρίζεται η κλάση με τους δείκτες.

Page 3: Γενίκευση ( genericity ) Ι

Παρασκευή, 21 Απριλίου 2023Παρασκευή, 21 Απριλίου 2023 Τμ. Πληροφορικής, Α.Π.Θ.Τμ. Πληροφορικής, Α.Π.Θ. 33

ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ

Γενίκευση (genericity) ΙΙΙclass GenericObject {}; //stack.hclass Stack { GenericObject* data[50]; int nElements; public: Stack() { nElements=0; } void Push(GenericObject* elem); GenericObject* Pop(); int Number(); int Empty();};

#include “stack.h” //stack.cpp

void Stack::Push(GenericObject* elem) { data[nElements]=elem; nElements++;}

GenericObject* Stack::Pop() { nElements--; return data[nElements];}int Stack::Number() { return nElements;}int Stack::Empty() { return (nElements==0);}

#include <iostream.h> //sta_use.cpp#include “stack.cpp”class IntObj:public GenericObject { public: int data; IntObj(int n) { data=n; }};

Page 4: Γενίκευση ( genericity ) Ι

Παρασκευή, 21 Απριλίου 2023Παρασκευή, 21 Απριλίου 2023 Τμ. Πληροφορικής, Α.Π.Θ.Τμ. Πληροφορικής, Α.Π.Θ. 44

ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ

Γενίκευση (genericity) ΙV

void main() {

Stack genericStack;

//εισάγουμε νέα αντικείμενα στη στοίβα genericStack.Push(new IntObj(500)); genericStack.Push(new IntObj(1992)); genericStack.Push(new IntObj(33)); genericStack.Push(new IntObj(1024));

//τυπώνει τα στοιχεία της στοίβας καθώς την αδειάζει: //επειδή η συνάρτηση Pop επιστρέφει δείκτη σε //GenericObject, για να προσπελάσουμε μέλος του //αντικειμένου που βγάλαμε χρειάζεται type casting

while(!genericStack.Empty()) cout<<((IntObj*)genericStack.Pop())->data<<endl;}

Page 5: Γενίκευση ( genericity ) Ι

Παρασκευή, 21 Απριλίου 2023Παρασκευή, 21 Απριλίου 2023 Τμ. Πληροφορικής, Α.Π.Θ.Τμ. Πληροφορικής, Α.Π.Θ. 55

ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ

Γενίκευση (genericity) Vtemplate<class T> //stack.h με templateclass Stack { T data[50]; int nElements; public: Stack() { nElements=0; } void Push(T elem); T Pop(); int Number(); int Empty();};

#include “stack.h” //stack.cpptemplate<class T>void Stack<T>::Push(T elem) { data[nElements]=elem; nElements++;}

template<class T>T Stack<T>::Pop() { nElements--; return data[nElements];}

template<class T>int Stack<T>::Number() { return nElements;}

template<class T>int Stack<T>::Empty() { return (nElements==0);}

Page 6: Γενίκευση ( genericity ) Ι

Παρασκευή, 21 Απριλίου 2023Παρασκευή, 21 Απριλίου 2023 Τμ. Πληροφορικής, Α.Π.Θ.Τμ. Πληροφορικής, Α.Π.Θ. 66

ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ

Γενίκευση (genericity) VI#include <iostream.h> //sta_use.cpp#include “stack.cpp”

void main() {

Stack <int> intStack;

//εισάγουμε νέα αντικείμενα στη στοίβα intStack.Push(500); intStack.Push(1992); intStack.Push(33); intStack.Push(1024);

while(!intStack.Empty()) cout<<intStack.Pop())<<endl;}

Page 7: Γενίκευση ( genericity ) Ι

Παρασκευή, 21 Απριλίου 2023Παρασκευή, 21 Απριλίου 2023 Τμ. Πληροφορικής, Α.Π.Θ.Τμ. Πληροφορικής, Α.Π.Θ. 77

ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ

Γενίκευση (genericity) VII//template συναρτήσεις

template <class T> T min(T a, T b) { if(a<b) return a; else return b;}

void main(){ char c1=‘W’,c2=‘h’; int n1=23,n2=67; long n3=10000; float n4=34.23,n5=7.77;

min(c1,c2); min(n1,n2);

min(c1,n1); //ΛΑΘΟΣ min(n2,n3); //ΛΑΘΟΣ min(n3,n4); //ΛΑΘΟΣ min(n4,n5);}

Page 8: Γενίκευση ( genericity ) Ι

Παρασκευή, 21 Απριλίου 2023Παρασκευή, 21 Απριλίου 2023 Τμ. Πληροφορικής, Α.Π.Θ.Τμ. Πληροφορικής, Α.Π.Θ. 88

ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ

Έλεγχος τύπου σε χρόνο εκτέλεσηςΕίναι δυνατό σε χρόνο εκτέλεσης να διαπιστώσουμε αν ένας δείκτης σε βασική κλάση δείχνει σε αντικείμενο παράγωγης κλάσης. Η C++(νεότερες εκδόσεις) παρέχει τον τελεστή typeid. Για να χρησιμοποιηθεί ο τελεστής πρέπει η βασική κλάση να περιέχει τουλάχιστο μία virtual συνάρτηση.

class Shape {public: virtual void plot(GraphicsContext& gc)=0; //. . . }

Shape* s;if (typeid(s) == typeid(Rectangle*))

// ο δείκτης s δείχνει σε αντικείμενο Rectangleelse

// ο δείκτης s δείχνει σε αντικείμενο άλλης κλάσης

Page 9: Γενίκευση ( genericity ) Ι

Παρασκευή, 21 Απριλίου 2023Παρασκευή, 21 Απριλίου 2023 Τμ. Πληροφορικής, Α.Π.Θ.Τμ. Πληροφορικής, Α.Π.Θ. 99

ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ

Έλεγχος τύπου και downcasting ΙΥπάρχουν περιπτώσεις που οι virtual συναρτήσεις δεν είναι αρκετά ευέλικτες και χρειάζεται έλεγχος τύπου σε χρόνο εκτέλεσης. Θεωρείστε για παράδειγμα τον υπολογισμό της τομής δύο γεωμετρικών σχημάτων που μπορεί να είναι παραλληλόγραμμα ή πολύγωνα. Στη γενική περίπτωση η τομή είναι μία ένωση πολυγώνων, αλλά από την άλλη η τομή δύο παραλληλόγραμμων είναι επίσης παραλληλόγραμμο.

Σε αυτή την περίπτωση χρειάζεται να γνωρίζουμε αν ο δείκτης Shape δείχνει σε ένα Rectangle ή αν δείχνει σε αντικείμενο κλάσης που παράγεται από ένα Rectangle. Αν ο έλεγχος επιτύχει θέλουμε να μετατρέψουμε το δείκτη Shape* σε δείκτη Rectangle*, ώστε να αποκτήσουμε πρόσβαση στα μέλη (συναρτήσεις & δεδομένα) του παραλληλόγραμμου.

Page 10: Γενίκευση ( genericity ) Ι

Παρασκευή, 21 Απριλίου 2023Παρασκευή, 21 Απριλίου 2023 Τμ. Πληροφορικής, Α.Π.Θ.Τμ. Πληροφορικής, Α.Π.Θ. 1010

ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ

Έλεγχος τύπου και downcasting ΙΙ

class Shape {public: virtual void plot(GraphicsContext& gc)=0; //. . . }

Shape* s;Rectangle* r = dynamic_cast<Rectangle*>(s);if (r != 0) // o r είναι ίσος με το s και δείχνει σε αντικείμενο Rectangleelse // ο δείκτης s δείχνει σε αντικείμενο που δεν είναι Rectangle

Για να χρησιμοποιηθεί ο τελεστής πρέπει η βασική κλάση να περιέχει τουλάχιστο μία virtual συνάρτηση. Ο τελεστής εκτελεί και τον έλεγχο αλλά και τη μετατροπή τύπου.

Page 11: Γενίκευση ( genericity ) Ι

Παρασκευή, 21 Απριλίου 2023Παρασκευή, 21 Απριλίου 2023 Τμ. Πληροφορικής, Α.Π.Θ.Τμ. Πληροφορικής, Α.Π.Θ. 1111

ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ

Η εσωτερική παράμετρος μιας συνάρτησης μέλους

Date advance(int n) {//προσέθεσε n ημέρες στην ημερομηνίαreturn (*this);

}

Date add_days(long n) {Date b=(*this);b.advance(n);return b;

}

το αντικείμενο για το οποίο καλείται η συνάρτηση

Page 12: Γενίκευση ( genericity ) Ι

Παρασκευή, 21 Απριλίου 2023Παρασκευή, 21 Απριλίου 2023 Τμ. Πληροφορικής, Α.Π.Θ.Τμ. Πληροφορικής, Α.Π.Θ. 1212

ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ

Πότε δύο αντικείμενα είναι ίσα; Ι

int m, n;// . . .if (m == n) . . .

έχουν τις ίδιες τιμές;

δείχνουν στις ίδιες τιμές;int* p;int* q;// . . .if (*p == *q) . . .

είναι οι ίδιοι δείκτες (αλλάζοντας τον ένα αλλάζει και ο άλλος);

int* p;int* q;// . . .if (p == q) . . .

Page 13: Γενίκευση ( genericity ) Ι

Παρασκευή, 21 Απριλίου 2023Παρασκευή, 21 Απριλίου 2023 Τμ. Πληροφορικής, Α.Π.Θ.Τμ. Πληροφορικής, Α.Π.Θ. 1313

ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ

Πότε δύο αντικείμενα είναι ίσα; ΙΙ

σύγκριση τιμών αναφορώνvoid f(int& r, int& s){ if (r == s) . . .}

είναι οι ίδιες αναφορές; (σύγκριση διευθύνσεων μνήμης)if (&r == &s)

πότε δύο αντικείμενα είναι ίσα;bool Point::is_equal(Point& b) { return x == b.x && y == b.y;}

bool Rectangle::is_equal(Rectangle& b) { return left_top().is_equal(b.left_top())

&& right_bottom().is_equal(b.right_bottom());}

Page 14: Γενίκευση ( genericity ) Ι

Παρασκευή, 21 Απριλίου 2023Παρασκευή, 21 Απριλίου 2023 Τμ. Πληροφορικής, Α.Π.Θ.Τμ. Πληροφορικής, Α.Π.Θ. 1414

ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ

Πότε δύο αντικείμενα είναι ίσα; ΙΙIΘα πρέπει πάντα η ισότητα μεταξύ αντικειμένων να ελέγχεται από κώδικα (συνάρτηση ή τελεστή) που θα γράφει ο προγραμματιστής.

ΠΡΟΒΛΗΜΑ

Rectnagle* p;Rectangle* q;// . . .if (p == q) . . .

ή για έλεγχο αν οι δείκτες αναφέρονται στην ίδια τιμή

if ((*p).is_equal(*q)) . . .

Τι γίνεται αν ο δείκτης q δείχνει σε FilledRect και ο p σε Rectangle;

Page 15: Γενίκευση ( genericity ) Ι

Παρασκευή, 21 Απριλίου 2023Παρασκευή, 21 Απριλίου 2023 Τμ. Πληροφορικής, Α.Π.Θ.Τμ. Πληροφορικής, Α.Π.Θ. 1515

ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ

Πότε δύο αντικείμενα είναι ίσα; ΙV

Θα μπορούσαμε να κάνουμε την is_equal virtual συνάρτηση, αλλά οι virtual συναρτήσεις επιλέγουν κώδικα ανάλογα με τον τύπο της εσωτερικής παραμέτρου. Στην περίπτωση αυτή μπορεί να αλλάζουν οι τύποι και των δύο παραμέτρων της συνάρτησης.

Εδώ χρειάζεται ο τελεστής typeid.

bool Rectangle::is_equal(Rectangle& b) { if (typeid((*this)) != typeid(b)) return FALSE; return left_top().is_equal(b.left_top())

&& right_bottom().is_equal(b.right_bottom());}

Page 16: Γενίκευση ( genericity ) Ι

Παρασκευή, 21 Απριλίου 2023Παρασκευή, 21 Απριλίου 2023 Τμ. Πληροφορικής, Α.Π.Θ.Τμ. Πληροφορικής, Α.Π.Θ. 1616

ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ

Δημιουργία αρχείου ΙΔημιουργία και η επικοινωνία με ένα αρχείο:

επίπεδο standard Input/Output (I/O) – για τον προγραμματιστή εφαρμογών

επίπεδο Ι/Ο συστήματος (system level I/O)

Στη C++, η είσοδος/έξοδος δεδομένων συνδέεται με το χειρισμό των αποκαλούμενων ροών δεδομένων (streams). Κάθε περίπτωση ροής (αντικείμενο) αντιπροσωπεύει, είτε ένα συγκεκριμένο αρχείο δίσκου, είτε την οθόνη ή το πληκτρολόγιο.

Αρχείο επικεφαλίδας <iostream.h>

για είσοδο δεδομένων από το πληκτρολόγιο (cin) ή έξοδο στην οθόνη (cout)

Το συγκεκριμένο αρχείο – επικεφαλίδας ουσιαστικά περιέχει τον ορισμό της κλάσης iostream τα μέλη της οποίας χρησιμοποιούμε για την είσοδο – έξοδο από και προς τις τυπικές μονάδες εισόδου – εξόδου.

Page 17: Γενίκευση ( genericity ) Ι

Παρασκευή, 21 Απριλίου 2023Παρασκευή, 21 Απριλίου 2023 Τμ. Πληροφορικής, Α.Π.Θ.Τμ. Πληροφορικής, Α.Π.Θ. 1717

ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ

Δημιουργία αρχείου ΙΙΑρχείο επικεφαλίδας <fstream.h>

για είσοδο - έξοδο από και προς αρχείο δίσκου (). Περιέχει την κλάση fstream.

H κλάση fstream κληρονομεί τόσο από την iostream, όσο και από την υπερκλάση ios, ενώ η iostream κληρονομεί μέσω των istream και ostream, μόνο από την ios.

Συχνά επίσης γίνεται χρήση των κλάσεων ifstream και ofstream, που δηλώνονται στο <fstream.h>, αποκλειστικά για είσοδο ή αντίστοιχα έξοδο δεδομένων σε αρχείο.

Στο παράδειγμα που ακολουθεί προηγείται η δήλωση ενός αντικειμένου ροής εξόδου (αρχείο με το όνομα arxs.txt) με το συμβολικό όνομα my_o_file.

Page 18: Γενίκευση ( genericity ) Ι

Παρασκευή, 21 Απριλίου 2023Παρασκευή, 21 Απριλίου 2023 Τμ. Πληροφορικής, Α.Π.Θ.Τμ. Πληροφορικής, Α.Π.Θ. 1818

ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ

Δημιουργία αρχείου και εγγραφή Ι

#include <fstream.h>main(){ ofstream my_o_file("arxs.txt");char name[20]="StringArray"; my_o_file<<'A'<<endl;my_o_file<<'a'<<endl;my_o_file<<"The name of the array:”

<<endl <<name<<endl;

}

ΠΕΡΙΕΧΟΜΕΝΑ ΑΡΧΕΙΟΥ arxs.txt:

AaThe name of the array is:StringArray

Page 19: Γενίκευση ( genericity ) Ι

Παρασκευή, 21 Απριλίου 2023Παρασκευή, 21 Απριλίου 2023 Τμ. Πληροφορικής, Α.Π.Θ.Τμ. Πληροφορικής, Α.Π.Θ. 1919

ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ

Δημιουργία αρχείου και εγγραφή ΙΙ

#include <fstream.h>#include <iostream.h> main(){

const int NO_OF_CHARS=80;char buffer[NO_OF_CHARS];

  ifstream my_i_file("arxs.txt"); 

while(my_i_file){ my_i_file.getline(buffer,

NO_OF_CHARS); cout<<buffer<<endl;}

}

istream::getlinegetline(buf,num,delim)όπου:buf = μεταβλητή συμβολοσειράς που χρησιμοποιείται ως περιοχή προσωρινής αποθήκευσηςnum = μεταβλητή int που δηλώνει το μέγιστο αριθμό χαρακτήρων, που μπορεί να τοποθετηθούν στην περιοχή προσωρινής αποθήκευσηςDelim = προαιρετική παράμετρος χαρακτήρα η ανίχνευση του οποίου ολοκληρώνει την ανάγνωση (προεπιλεγμένη τιμή “\n”)

Το σήμα EOF είναι μία από τις συνθήκες λάθους που μπορεί να επιστρέψει μία ροή εισόδου και σημαίνει τέλος αρχείου

Page 20: Γενίκευση ( genericity ) Ι

Παρασκευή, 21 Απριλίου 2023Παρασκευή, 21 Απριλίου 2023 Τμ. Πληροφορικής, Α.Π.Θ.Τμ. Πληροφορικής, Α.Π.Θ. 2020

ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ

Δημιουργία αρχείου και εγγραφή ΙΙΙ

fstream::open

open(MyFileName, mode, protection)

MyFileName = το όνομα του αρχείου

mode = μία ή περισσότερες σημαίες ios που συνδυάζονται με |

ios::app άνοιγμα για εγγραφή στο τέλος του αρχείου (append)

ios::ate άνοιγμα και τοποθέτηση του δείκτη αρχείου στο τέλος

ios::in άνοιγμα για ανάγνωση

ios::out άνοιγμα για εγγραφή

ios::trunc αν το αρχείο ήδη υπάρχει, τότε καταστρέφονται τα περιεχόμενά του

ios::nocreate αν το αρχείο δεν υπάρχει, τότε η open δεν εκτελείται

ios::noreplace αν το αρχείο υπάρχει, τότε η open δεν εκτελείται

ios::binary ανοίγει το αρχείο για εγγραφή δυαδικών δεδομένων

protection = μία ή περισσότερες σημαίες, που συνδυάζονται με || για τον ορισμό του τύπου πρόσβασης στη ροή

filebuf::sh_none αποκλειστική πρόσβαση (μη διαμοιράσιμο αρχείο)

filebuf::sh_read επιτρέπεται η πολλαπλή πρόσβαση για ανάγνωση

filebuf::sh_write επιτρέπεται η πολλαπλή πρόσβαση για εγγραφή

Page 21: Γενίκευση ( genericity ) Ι

Παρασκευή, 21 Απριλίου 2023Παρασκευή, 21 Απριλίου 2023 Τμ. Πληροφορικής, Α.Π.Θ.Τμ. Πληροφορικής, Α.Π.Θ. 2121

ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ

Δημιουργία αρχείου και εγγραφή ΙV

#include <fstream.h>main(){ fstream my_o_file;char name[20]="StringArray"; my_o_file.open("arxs.txt",

ios::out | ios::noreplace);my_o_file<<'B'<<endl;my_o_file<<'b'<<endl;my_o_file<<"The name of the array:“

<<endl <<name<<endl;

}

fstream::closeclose()

Page 22: Γενίκευση ( genericity ) Ι

Παρασκευή, 21 Απριλίου 2023Παρασκευή, 21 Απριλίου 2023 Τμ. Πληροφορικής, Α.Π.Θ.Τμ. Πληροφορικής, Α.Π.Θ. 2222

ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ

Ανάγνωση - εγγραφή χαρακτήρων Ι

istream::get

get(inch)

όπου:

inch = όνομα μεταβλητής χαρακτήρα, στην οποία αποθηκεύεται ο χαρακτήρας που διαβάζεται

ostream::put

put(outch)

όπου:

outch = μεταβλητή ή σταθερά χαρακτήρα που η τιμή της εγγράφεται στη ροή που καλεί τη συνάρτηση

Page 23: Γενίκευση ( genericity ) Ι

Παρασκευή, 21 Απριλίου 2023Παρασκευή, 21 Απριλίου 2023 Τμ. Πληροφορικής, Α.Π.Θ.Τμ. Πληροφορικής, Α.Π.Θ. 2323

ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ

Ανάγνωση - εγγραφή χαρακτήρων ΙΙ

#include <fstream.h>#include <iostream.h>#include <stdlib.h>main() { ifstream my_i_file; char filename[12]; char in_char;

cout<<"Doste onoma arxeiou: "; cin>>filename; my_i_file.open(filename,ios::in); if (!my_i_file) {cout<<"This file does not exist!\n";exit(0);}

while (my_i_file.get(in_char)){ cout << in_char; }my_i_file.close();}

Page 24: Γενίκευση ( genericity ) Ι

Παρασκευή, 21 Απριλίου 2023Παρασκευή, 21 Απριλίου 2023 Τμ. Πληροφορικής, Α.Π.Θ.Τμ. Πληροφορικής, Α.Π.Θ. 2424

ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ

Ανάγνωση - εγγραφή χαρακτήρων ΙΙΙ

#include <fstream.h>#include <iostream.h>#include <stdlib.h>main(){ifstream my_i_file;ofstream my_o_file;char in_filename[12];char out_filename[12];char in_char;

cout << “Arxeio pou antigrafetai?";cin >> in_filename;cout << “Arxeio opou tha antigrafei ";cout << "to " << in_filename << "?" << endl;cin >> out_filename;

my_i_file.open(in_filename, ios::in);

if (!my_i_file){ cout <<“Arxeio "<< in_filename << " den iparxei!\n"; exit(0);}

my_o_file.open(out_filename, ios::out);if (!my_o_file){ cout<<"Lathos sto anoigma" << out_filename << "!\n"; exit(0);}

cout << "Antigrafi arxeiou.\n";while (my_i_file.get(in_char)){my_o_file.put(in_char); }

cout<<"\nArxeio antigrafike\n";my_i_file.close();my_o_file.close();}

Page 25: Γενίκευση ( genericity ) Ι

Παρασκευή, 21 Απριλίου 2023Παρασκευή, 21 Απριλίου 2023 Τμ. Πληροφορικής, Α.Π.Θ.Τμ. Πληροφορικής, Α.Π.Θ. 2525

ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ

Εγγραφή ομάδας (block) δεδομένων Ι

istream::read

read(indata,num)

indata = block δεδομένων που διαβάζεται ως συμβολοσειρά (char*) αλλά αποδίδεται στη διεύθυνση μεταβλητής ή αντικειμένου με τον τελεστή &

num = ακέραιος που δηλώνει τον αριθμό των bytes που θα διαβάσει η read ostream::write

write(outdata,num)

όπου:

outdata = block δεδομένων που εγγράφεται στη ροή ως char*

num = ακέραιος που δηλώνει τον αριθμό των bytes που εγγράφει η write

ios::eof

eof()

επιστρέφει ως αποτέλεσμα μη μηδενική ακέραια τιμή όταν διαβάζεται τέλους αρχείου (EOF)

Page 26: Γενίκευση ( genericity ) Ι

Παρασκευή, 21 Απριλίου 2023Παρασκευή, 21 Απριλίου 2023 Τμ. Πληροφορικής, Α.Π.Θ.Τμ. Πληροφορικής, Α.Π.Θ. 2626

ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ

Εγγραφή ομάδας (block) δεδομένων ΙΙ

Όταν τα δεδομένα εγγράφονται από την κεντρική μνήμη στη ροή ως έχουν (δηλ. στη δυαδική τους μορφή), τότε το περιεχόμενο του αρχείου είναι σε δυαδική μορφή και μιλάμε για δυαδικό αρχείο.

Παράδειγμα εγγραφής δυαδικών δεδομένων . . .

Page 27: Γενίκευση ( genericity ) Ι

Παρασκευή, 21 Απριλίου 2023Παρασκευή, 21 Απριλίου 2023 Τμ. Πληροφορικής, Α.Π.Θ.Τμ. Πληροφορικής, Α.Π.Θ. 2727

ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ

Εγγραφή ομάδας (block) δεδομένων ΙΙΙ

#include <fstream.h>#include <iostream.h>#include <stdlib.h>class Date{ protected: int day; int month; int year;public: void getDate(){ cout<<"\nDoste imera: "; cin>>day; cout<<"\nDoste mina: "; cin>>month; cout<<"\nDoste etos: "; cin>>year;} void printDate(){ cout<<"\nDiavastike imerominia: "

<<day<<"-"<<month<<"-" <<year<<endl;}

};

main(){ char input,filename[12]; ofstream d_o_file; ifstream d_i_file; Date date1,date2; cout<< "Dose onoma arxeiou? "; cin >> filename; d_o_file.open(filename, ios::out|ios::binary);

if (!d_o_file){cout<<“Arxeio " << filename <<" den iparxei!\n"; exit(0);}cout<<"\nTha eisagete ime/nia (n/o)? ";cin >> input;if (input=='n') { date1.getDate();d_o_file.write((char*)&date1,

sizeof(date1));}

Page 28: Γενίκευση ( genericity ) Ι

Παρασκευή, 21 Απριλίου 2023Παρασκευή, 21 Απριλίου 2023 Τμ. Πληροφορικής, Α.Π.Θ.Τμ. Πληροφορικής, Α.Π.Θ. 2828

ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ

Εγγραφή ομάδας (block) δεδομένων ΙV

. . . συνέχεια παραδείγματος

d_o_file.close();

d_i_file.open(filename,ios::in|ios::binary);d_i_file.read((char *) &date2, sizeof(date2));if (!d_i_file.eof()) {date2.printDate();} else {cout<<"Empty file!!\n";}d_i_file.close();}

Page 29: Γενίκευση ( genericity ) Ι

Παρασκευή, 21 Απριλίου 2023Παρασκευή, 21 Απριλίου 2023 Τμ. Πληροφορικής, Α.Π.Θ.Τμ. Πληροφορικής, Α.Π.Θ. 2929

ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ

Σειριακή και άμεση προσπέλαση Ι

Στη σειριακή εγγραφή, κάθε φορά που εκτελείται μια write, η εγγραφή των δεδομένων γίνεται στις αμέσως επόμενες θέσεις. Αντίστοιχα, κάθε φορά που εκτελείται μια read διαβάζουμε τα δεδομένα που βρίσκονται στις επόμενες θέσεις. Aν π.χ θέλουμε να διαβάσουμε το 5ο record, θα πρέπει να διαβάσουμε πρώτα τα τέσσερα που προηγούνται και στη συνέχεια το 5ο.

Αντίθετα, με τυχαία ή άμεση προσπέλαση μπορούμε να διαβάσουμε ή να γράψουμε ένα record, ενδιάμεσα στο αρχείο, με μία μόνο ανάγνωση/εγγραφή. Για να επιτευχθεί αυτό θα πρέπει να γίνει διαχείριση των δεικτών θέσης του αρχείου με κατάλληλο τρόπο.

Page 30: Γενίκευση ( genericity ) Ι

Παρασκευή, 21 Απριλίου 2023Παρασκευή, 21 Απριλίου 2023 Τμ. Πληροφορικής, Α.Π.Θ.Τμ. Πληροφορικής, Α.Π.Θ. 3030

ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ

Σειριακή και άμεση προσπέλαση ΙΙΤο σύστημα εισόδου – εξόδου της C++ διαχειρίζεται δύο δείκτες θέσης (πρόκειται ουσιαστικά για ακεραίους αριθμούς), για κάθε αρχείο:

ο δείκτης θέσης ανάγνωσης (get pointer) καθορίζει τη θέση (σε πιο byte), από την οποία θα γίνει η επόμενη ανάγνωση

ο δείκτης θέσης εγγραφής (put pointer) καθορίζει τη θέση, στην οποία θα γίνει η επόμενη εγγραφή

Όταν ένα αρχείο ανοίγει (συνάρτηση open) τότε οι δείκτες θέσης τοποθετούνται στην αρχή του αρχείου (η αρίθμηση των bytes αρχίζει από το μηδέν).

Κάθε φορά που εκτελείται μια συνάρτηση ανάγνωσης (όπως read, get κ.λ.π.) ο δείκτης θέσης ανάγνωσης μετακινείται αυτόματα στη θέση εκείνη από όπου θα γίνει η επόμενη ανάγνωση. Επίσης, κάθε φορά που εκτελείται μια συνάρτηση εγγραφής ο δείκτης θέσης εγγραφής μετακινείται αυτόματα στη θέση εκείνη, όπου θα γίνει η επόμενη εγγραφή.

Page 31: Γενίκευση ( genericity ) Ι

Παρασκευή, 21 Απριλίου 2023Παρασκευή, 21 Απριλίου 2023 Τμ. Πληροφορικής, Α.Π.Θ.Τμ. Πληροφορικής, Α.Π.Θ. 3131

ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ

Σειριακή και άμεση προσπέλαση ΙΙΙ

istream::tellg

tellg()

επιστρέφει μία τιμή long που δηλώνει τη θέση στην οποία βρίσκεται ο δείκτης ανάγνωσης

της ροής εισόδου οstream::tellp

tellp()

επιστρέφει μία τιμή long που δηλώνει τη θέση στην οποία βρίσκεται ο δείκτης εγγραφής

της ροής εξόδου

Page 32: Γενίκευση ( genericity ) Ι

Παρασκευή, 21 Απριλίου 2023Παρασκευή, 21 Απριλίου 2023 Τμ. Πληροφορικής, Α.Π.Θ.Τμ. Πληροφορικής, Α.Π.Θ. 3232

ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ

Σειριακή και άμεση προσπέλαση ΙV

istream::seekg

seekg(offset,refmark)

Το offset εκφράζει το πλήθος των bytes, που πρέπει να μετακινηθεί ο δείκτης θέσης, ως προς το επιθυμητό σημείο αναφοράς refmark. Το refmark ορίζει την τιμή του σημείου αναφοράς:

ios::beg αρχή του αρχείου (προκαθορισμένη τιμή)

ios::cur τρέχουσα θέση του αρχείου

ios::end τέλος του αρχείου

οstream::seekp

seekp(offset,refmark)

όπως και η προηγούμενη συνάρτηση, για το δείκτη θέσης εγγραφής

Page 33: Γενίκευση ( genericity ) Ι

Παρασκευή, 21 Απριλίου 2023Παρασκευή, 21 Απριλίου 2023 Τμ. Πληροφορικής, Α.Π.Θ.Τμ. Πληροφορικής, Α.Π.Θ. 3333

ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ

Παράδειγμα σειριακής εγγραφής#include <iostream.h>#include <fstream.h>class person{ protected: char name[40]; int age;public: void getData(){ cout<<"\n Dwste Onoma:"; cin>>name; cout<<"Dwste Hlikia:"; cin >> age; } void showData(){ cout<<"\n Onoma:"<<name; cout<<"\n Hlikia:"<<age<<"\n"; }};

main() { char ch; person pers; 

fstream file; file.open("PERSON.DAT", ios::app); cout<<"\nEisagete eggrafi: "; do {pers.getData();file.write((char*)&pers, sizeof(pers));cout<<«Sinexizete?(y/n)"; cin>>ch;} while (ch=='y');file.close();file.open("PERSON.DAT", ios::in);file.read((char*)&pers, sizeof(pers));while (!file.eof()){ pers.showData(); file.read((char*)&pers, sizeof(pers));}}

Page 34: Γενίκευση ( genericity ) Ι

Παρασκευή, 21 Απριλίου 2023Παρασκευή, 21 Απριλίου 2023 Τμ. Πληροφορικής, Α.Π.Θ.Τμ. Πληροφορικής, Α.Π.Θ. 3434

ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ

Παράδειγμα άμεσης προσπέλασης#include <iostream.h>#include <fstream.h>class person{ protected: char name[40]; int age;public: void getData(){ cout<<"\n Dwste Onoma:"; cin>>name; cout<<"Dwste Hlikia:"; cin >> age; } void showData(){ cout<<"\n Onoma:"<<name; cout<<"\n Hlikia:"<<age<<"\n"; }};

main() { char ch; person pers; 

ifstream file; file.open("PERSON.DAT"); file.seekg(0,ios::end); int endposition=file.tellg(); int n=endposition/ sizeof(person); cout<<"\nYparxoun "<<n <<" eggrafes sto arxeio"; cout<<"\nDoste ti thesi eggrafis pou anazeitate:"; cin>>n; int position=(n-1)* sizeof(person); file.seekg(position); file.read((char*)&pers, sizeof(pers)); pers.showData(); file.close();}

Page 35: Γενίκευση ( genericity ) Ι

Παρασκευή, 21 Απριλίου 2023Παρασκευή, 21 Απριλίου 2023 Τμ. Πληροφορικής, Α.Π.Θ.Τμ. Πληροφορικής, Α.Π.Θ. 3535

ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ

Χρήσιμες συναρτήσεις Ιios::bad

bad()

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

ios::fail

fail()

Επιστρέφει ως αποτέλεσμα μη μηδενική ακέραια τιμή όταν ανιχνεύεται λάθος ανάγνωσης – εγγραφής, εκτός του EOF. Αν το λάθος είναι ανανήψιμο, τότε η ανάγνωση – εγγραφή μπορεί να συνεχισθεί, αφού προηγουμένως κληθεί η clear() για επαναφορά των σημαιών λάθους στην προκαθορισμένη κατάσταση.

ios::good

good()

Επιστρέφει μη μηδενική τιμή, όταν όλες οι σημαίες λάθους βρίσκονται στην προκαθορισμένη κατάσταση (δεν υπάρχει λάθος).

Page 36: Γενίκευση ( genericity ) Ι

Παρασκευή, 21 Απριλίου 2023Παρασκευή, 21 Απριλίου 2023 Τμ. Πληροφορικής, Α.Π.Θ.Τμ. Πληροφορικής, Α.Π.Θ. 3636

ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ

Χρήσιμες συναρτήσεις ΙΙios::clear

clear()

Επαναφέρει τις σημαίες λάθους στην προκαθορισμένη κατάσταση.

istream::ignore

ignore(num,delim)

Αγνοεί τα επόμενα num bytes της ροής εκτός και αν πριν συμπληρωθεί ο αριθμός τους εντοπισθεί ο χαρακτήρας delim. Αν δε δοθεί τιμή στην παράμετρο num, τότε αγνοείται ένας μόνο χαρακτήρας, ενώ η προκαθορισμένη τιμή για την παράμετρο delim είναι το EOF. istream::peek

peek()

Επιστρέφει τον επόμενο χαρακτήρα με τη μορφή ακέραιης τιμής, χωρίς όμως να τον αφαιρεί από τη ροή.

istream::putback

putback(inch)

Επανατοποθετεί στη ροή εισόδου το χαρακτήρα inch που διαβάσθηκε τελευταία. Αν αντί γι΄ αυτόν επιχειρηθεί η τοποθέτηση άλλου χαρακτήρα, τότε το αποτέλεσμα της συνάρτησης είναι απροσδιόριστο.