1.1 Εισαγωγή 1. O AΤΔ ΟΥΡΑ Μια ουρά αποτελεί μια δομή πολύ παρόμοια με την στοίβα, διαφέρει μόνο ο τρόπος εισαγωγής-εξαγωγής των στοιχείων της. Τον όρο ουρά τον συναντάμε πολύ συχνά στην καθημερινή μας ζωή. Κάποια παραδείγματα που γνωρίζουμε όλοι είναι μια ουρά ατόμων μπροστά από ένα ταμείο ή μια τράπεζα ή την ουρά που σχηματίζουν τα αυτοκίνητα μπροστά από ένα φανάρι. Η ουρά είναι μια δομή που χρησιμοποιείται στην επιστήμη της πληροφορικής σε πολλές περιπτώσεις. Παραδείγματα χρήσης της ουράς είναι τα εξής: Άμεσες Εφαρμογές: Για την προσπέλαση κοινόχρηστων πόρων Στην χρήση πολυεπεξεργαστών σε πολυεπεξεργαστικά περιβάλλοντα Σε routing buffers Ως κλάση σε αντικειμενοστραφείς γλώσσες για την εξυπηρέτηση υλοποίησης κάποιου προγράμματος. Έμμεσες Εφαρμογές: Βοηθητικές σε πιο γενικές δομές δεδομένων. Ακόμη την συναντάμε και στα μαθηματικά την ουρά συχνά, με τον όρο ουρά αναμονής. 1.2 Ορισμός O ΑΤΔ ουρά είναι μια συλλογή στοιχείων με γραμμική διάταξη στην οποία η διαγραφή ενός στοιχείου γίνεται στο στο ένα άκρο της το οποίο καλείται εμπρός ενώ η εισαγωγή στοιχείου γίνεται στο άλλο άκρο που καλείται πίσω. Η πιο σημαντική ιδιότητα μιας ουράς που ουσιαστικά την χαρακτηρίζει είναι ότι τα στοιχεία απομακρύνονται από την ουρά με την ίδια σειρά που εισάγονται, το πρώτο στοιχείο που φθάνει στην ουρά είναι το πρώτο που απομακρύνεται. Εξαιτίας αυτής της ιδιότητας η ουρά καλείται και δομή FIFO (First- In- First- Out). 1.2.1 Δεδομένα Μια ουρά αποτελεί μια πεπερασμένη συλλογή δεδομένων σε γραμμική ακολουθία όπου κάθε εισαγωγή γίνεται από το ένα άκρο ενώ κάθε διαγραφή από το άλλο. 1.2.2 Πράξεις Οι βασικές πράξεις του ΑΤΔ Ουρά είναι η εξής: Oyra_dimiourgia: Δημιουργεί μια κενή ουρά, σε περίπτωση ολικής απόκρυψης επιστρέφει και τον δείκτη στην ουρά. Oyra_keni: Ελέγχει αν η ουρά είναι κενή. Oyra_gemati: Ελέγχει αν η ουρά είναι γεμάτη. Δ.Μήλιος 1
Oyra_prosthesi: Σε περίπτωση που δεν είναι γεμάτη η ουρά προσθέτει ένα στοιχείο στην κορυφή της ουράς, αλλιώς επιστρέφει μήνυμα υπερχείλισης. Oyra_apomakrynsh: Σε περίπτωση που δεν είναι κενή η ουρά εξάγει το πρώτο στοιχείο της ουράς, αλλιώς επιστρέφει μήνυμα υποχείλισης. 1.3 Yλοποιήσεις Στο κεφάλαιο αυτό θα παρουσιαστούν 3 διαφορετικές υλοποιήσεις του ΑΤΔ Ουρά, η υλοποίηση με κενό (gap), η υλοποίηση με λογική μεταβλητή και η υλοποίηση με μετρητή. Και οι 3 υλοποίησεις γίνονται με χρήση πίνακα. Ακολουθεί περαιτέρω ανάλυση για κάθε μια από αυτές τις υλοποίησεις στα αντίστοιχα εδάφια κειμένου. 1.3.1 Υλοποίηση 1η: Υλοποίηση με κενό Αυτή η υλοποίηση ουσιαστικά χρησιμοποιεί απλώς μια δομή ουράς που περιέχει τον πίνακα στοιχείων που χρησιμοποιεί κάθε υλοποίηση από τις 3 όπως αναφέρθηκε πιο πάνω και 2 δείκτες ουσιαστικά ακέραιες μεταβλητές που λειτουργούν ουσιαστικά ως δείκτες στο εμπρός και στο πίσω άκρο αντίστοιχα. 1.3.1.1 Αρχεία Διεπαφής-Υλοποιήσης Στο αρχείο Διεπαφής δηλώνεται η δομή της ουράς, το μέγεθος της ουράς και οι συναρτήσεις αλλά κυρίως εντοπίζεται το include του τύπου στοιχείου ουράς το οποίο δεν περιλαμβάνει συγκεκριμένο μονοπάτι που να προσδιορίζει το αρχείο του τύπου στοιχείου ουράς αλλά περιγράφει τον ρόλο του συγκεκριμένου include. Ακολουθεί ο κώδικας του αρχείου Διεπαφής: #ifndef QGAP #define QGAP #define PLITHOS 100 #include "to antistoixo.h typou stoixeiou" /*edo analoga tin efarmogi i to test tou tipou stoixeiou mpainei to antoistixo.h tou tipou stoixeiou */ /*dhlwseis typwn*/ typedef struct { int embros; /*8esh toy prwtoy stoixeoy ths oyras*/ int piso; /*8esh toy teleytaioy stoixeioy ths oyras*/ TStoixeioyOyras pinakas[plithos]; /*o pinakas twn stoixeiwn*/ TOuras; /*dhlwseis synarthsewn*/ /*dhmioyrgia*/ Δ.Μήλιος 2
void Oyra_dimiourgia(TOuras *oura); /*Prakseis elegxoy*/ int Oyra_keni (TOuras oura); int Oyra_gemati (TOuras oura); /*Prakseis pros8eshs/apomakrynshs*/ void Oyra_prosthesi(TOuras *oura, TStoixeioyOyras stoixeio, int *yperxeilisi); void Oyra_apomakrynsh(TOuras *oura, TStoixeioyOyras *stoixeio, int *ypoxeilisi); #endif /*#ifndef QGAP */ Ακολουθεί ο κώδικας του αρχείου Υλοποίησης: #include <stdlib.h> #include "Qgap.h" /*orismos synarthsewn*/ void Oyra_dimiourgia(TOuras *oura ) {/* Pro: kamia * Meta: Dhmioyrgia kenhs oyras */ oura->embros = 0; oura->piso = 0; int Oyra_keni(TOuras oura) {/* Pro: Dhmioyrgia oyras * Meta: Epistrefei 1 an h oyra einai kenh, diaforetika 0 */ return ( oura.embros == oura.piso ); int Oyra_gemati(TOuras oura) {/* Pro: Dhmioyrgia oyras * Meta: Epistrefei 1 an h oyra einai gemath, diaforetika 0 */ int neo_piso = (oura.piso+1) % PLITHOS; if (neo_piso == oura.embros ) return 1; return 0; Δ.Μήλιος 3
void Oyra_prosthesi(TOuras *oura, TStoixeioyOyras stoixeio, int *yperxeilisi) {/* Pro: Dhmioyrgia oyras * Meta: Oyra exei epayksh8ei me to stoixeio */ if (Oyra_gemati(*oura)) *yperxeilisi=1; { *yperxeilisi=0; TSoyra_setValue(&(oura->pinakas[oura->piso]), stoixeio); oura->piso = ( oura->piso + 1 )% PLITHOS; void Oyra_apomakrynsh(TOuras *oura,tstoixeioyoyras *stoixeio,int *ypoxeilisi) {/* Pro: Dhmioyrgia oyras * Meta: Oura exei meiw8ei kata ena stoixeio */ if (Oyra_keni(*oura)) *ypoxeilisi=1; { *ypoxeilisi=0; TSoyra_setValue(stoixeio, oura->pinakas[oura->embros]); oura->embros = ( oura->embros + 1 )% PLITHOS; 1.3.1.2 Αρχεία Δοκιμής Στα αρχεία Δοκιμής περιλαμβάνεται το αρχείο main που χρησιμοποιείται ως αρχείο test για τις πράξεις της ATΔ Ουρά. Ακολουθεί ο κώδικας του αρχείου δοκιμής: #include "Qgap.h" #include "../../TS/TStoixeioyOyras.h" void print_options(void); int main(void) { int option, error,created,out_err; TOuras queue; TStoixeioyOyras x; error=created=0; do{ print_options(); scanf("%d", &option); switch(option) Δ.Μήλιος 4
{case 1: case 2: Oyra_dimiourgia(&queue); created=1; printf("\nh oura dimiourgithike!\n"); if(!created) { printf("\nden uparxei oura gia na eisaxthei stoixeio!\n"); printf("dwse ena stoixeio: "); out_err=tsoyra_readvalue(stdin,&x); if(!out_err) { printf("\n error stin readvalue!\n"); Oyra_prosthesi(&queue, x, &error); if(error) case 3: printf("\nyperxeilhsh oyras. To stoixeio DEN eishx8h!\n"); printf("\nto stoixeio eishx8h!\n"); if(!created) { printf("\nden uparxei oura gia na apomakrynthei stoixeio!\n"); Oyra_apomakrynsh(&queue, &x, &error); if(error) printf("\nkeni oyra!\n"); { printf("\nekshx8h epityxws to stoixeio "); out_err=tsoyra_writevalue(stdout,x); if(out_err <0) { printf("\n error stin writevalue!\n"); case 4: if(!created) Δ.Μήλιος 5
{ printf("\nden uparxei oura gia na elexthei an einai kenh!\n"); if(oyra_keni(queue)) printf("\nh oura einai kenh!\n"); printf("\nh oura DEN einai kenh!\n"); case 5: if(!created) { printf("\nden uparxei oura gia na elexthei an einai gemath!\n"); if(oyra_gemati(queue)) printf("\nh oura einai gemath!\n"); printf("\nh oura DEN einai gemath!\n"); while(option); return 0; void print_options(void) { printf("\n\n1. Dhmioyrgia ouras\n\ 2. Prosthesh stoixeiou sthn oura\n\ 3. Apomakrynsh stoixeiou apo thn oura\n\ 4. Elegxos gia kenh oura\n\ 5. Elegxos gia gemath oura\n\n\ Dwste thn epilogh sas(1-5, 0 gia eksodo):"); Ακόμη όμως περιλαμβάνονται και τα αρχεία Διεπαφής και Υλοποίησης της ουράς τους (δεν δίνεται κώδικας επειδή είναι ουσιαστικά ο ίδιος με τα πρότυπα αρχεία). 1.3.2 Υλοποιήση 2η: Υλοποίηση με χρήση λογικής μεταβλητής Στην δεύτερη υλοποίηση ακολουθείται η ίδια λογική μόνο που υπάρχει μια extra μεταβλητή ακεραίου που λειτουργεί ως λογική μεταβλητή η οποία παραμένει 1 όσο η ουρά είναι άδεια ενώ μηδενίζεται σε κάθε άλλη περίπτωση. Δ.Μήλιος 6
1.3.2.1 Αρχεία Διεπαφής-Υλοποιήσης To πρότυπο αρχείο Διεπαφής δεν έχει διαφορές από το αντίστοιχο της υλοποίησης με κενό (ουσιαστικά της απλής υλοποίησης με πίνακα) παρά μόνο την προσθήκη της λογικής μεταβλητής στη δομή μας. Ακολουθεί ο κώδικας του αρχείου Διεπαφής: #ifndef QLOGIC #define QLOGIC #define PLITHOS 100 #include "to antistoixo.h typou stoixeiou" /*edo analoga tin efarmogi i to test tou tipou stoixeiou mpainei to antoistixo.h tou tipou stoixeiou */ /*dhlwseis typwn*/ typedef struct { int embros; /*8esh toy prwtoy stoixeioy ths oyras*/ int piso; /*8esh toy teleytaioy stoixeioy ths oyras*/ int adeia; /*shmaia poy dhlwnei an einai h oyra adeia*/ TStoixeioyOyras pinakas[plithos]; /*o pinakas stoixeiwn*/ TOuras; /*dhlwseis synarthsewn*/ /*dhmioyrgia*/ void Oyra_dimiourgia(TOuras *oura); /*Prakseis elegxoy*/ int Oyra_keni (TOuras oura); int Oyra_gemati (TOuras oura); /*Prakseis pros8eshs/apomakrynshs*/ void Oyra_prosthesi *yperxeilisi); (TOuras *oura, TStoixeioyOyras stoixeio, int void Oyra_apomakrynsh(TOuras *oura, TStoixeioyOyras *stoixeio, int *ypoxeilisi); #endif /*#ifndef QLOGIC */ Στο αρχείο Υλοποίησης γίνεται εμφανής η απλοποίηση του κώδικα σε συγκεκριμένα σημεία λόγω της χρήσης της λογικής μεταβλητής. Δ.Μήλιος 7
Ακολουθεί ο κώδικας του αρχείου Υλοποίησης: #include "Qlogic.h" #include <stdlib.h> /*orismos synarthsewn*/ void Oyra_dimiourgia(TOuras *oura ) {/* Pro: kamia * Meta: Dhmioyrgia kenhs oyras */ oura->embros = 0; oura->piso = 0; oura->adeia = 1; /*True*/ int Oyra_keni(TOuras oura) * Meta: epistrefei 1 an h oyra einai kenh, diaforetika 0 */ return oura.adeia; int Oyra_gemati(TOuras oura) * Meta: epistrefei 1 an h oyra einai gemath, diaforetika 0 */ return ( (oura.piso == oura.embros) && (!Oyra_keni(oura)) ); void Oyra_prosthesi(TOuras *oura, TStoixeioyOyras stoixeio, int *yperxeilisi) * Meta: Oyra exei epayksh8ei me to stoixeio */ if (Oyra_gemati(*oura)) *yperxeilisi=1; { *yperxeilisi=0; TSoyra_setValue(&(oura->pinakas[oura->piso]), stoixeio); oura->piso = ( oura->piso + 1 )% PLITHOS; oura->adeia = 0; Δ.Μήλιος 8
void Oyra_apomakrynsh(TOuras *oura, TStoixeioyOyras *stoixeio, int *ypoxeilisi) * Meta: Oyra exei meiw8ei kata ena stoixeio */ if (Oyra_keni(*oura)) *ypoxeilisi=1; { *ypoxeilisi=0; TSoyra_setValue(stoixeio, oura->pinakas[oura->embros]); oura->embros = ( oura->embros + 1 )% PLITHOS; oura->adeia = ( oura->embros == oura->piso ); 1.3.2.2 Αρχεία Δοκιμής Το αρχείο main-test είναι το ίδιο ως κώδικας με το αρχείο δοκιμής της πρώτης υλοποίησης με διαφορά την περιοχή των include. Τα include είναι τα εξής: #include "Qlogic.h" #include "../../TS/TStoixeioyOyras.h" Τα αρχεία Υλοποίησης-Δοκιμής όπως έχει αναφερθεί σε πολλές αντίστοιχες ενότητες είναι ίδια με τα πρότυπα με εξαίρεση το path στο include. 1.3.3 Υλοποίηση 3η: Υλοποίηση με μετρητή H Τρίτη υλοποίηση σε σχέση με την 1 η υλοποίηση κάνει και χρήση ενός μετρητήακέραιας μεταβλητής που καταμετρά τον αριθμό των στοιχείων της ουράς ανά πάσα στιγμή. Η συγκεκριμένη υλοποίηση όμως εκτός των άλλων έχει υλοποιηθεί εκτός από με μερική απόκρυψη όπως οι άλλες 2 και με ολική, για να δειχθεί ενδεικτικά στον αναγνώστη- χρήστη και εδώ η διαφορά μερικής ολικής απόκρυψης στα πλαίσια μιας υλοποίησης της ουράς. 1.3.3.1 Υλοποίηση με Μερική Απόκρυψη 1.3.3.1.1 Αρχεία Διεπαφής-Υλοποίησης Η μόνη διαφορά με το αντίστοιχο αρχείο Διεπαφής της 1 ης υλοποίησης η προσθήκη του μετρητή. Ακολουθεί ο κώδικας του αρχείου Διεπαφής: #ifndef QLOGIC Δ.Μήλιος 9
#define QLOGIC #define PLITHOS 100 #include "to antistoixo.h typou stoixeiou" /*edo analoga tin efarmogi i to test tou tipou stoixeiou mpainei to antoistixo.h tou tipou stoixeiou */ /*dhlwseis typwn*/ typedef struct { int embros; /*8esh toy prwtoy stoixeioy ths oyras*/ int piso; /*8esh toy teleytaioy stoixeioy ths oyras*/ int adeia; /*shmaia poy dhlwnei an einai h oyra adeia*/ TStoixeioyOyras pinakas[plithos]; /*o pinakas stoixeiwn*/ TOuras; /*dhlwseis synarthsewn*/ /*dhmioyrgia*/ void Oyra_dimiourgia(TOuras *oura); /*Prakseis elegxoy*/ int Oyra_keni (TOuras oura); int Oyra_gemati (TOuras oura); /*Prakseis pros8eshs/apomakrynshs*/ void Oyra_prosthesi (TOuras *oura, TStoixeioyOyras stoixeio, int *yperxeilisi); void Oyra_apomakrynsh(TOuras *oura, TStoixeioyOyras *stoixeio, int *ypoxeilisi); #endif /*#ifndef QLOGIC */ Ακολουθεί ο κώδικας του αρχείου Υλοποίησης: #include "Qlogic.h" #include <stdlib.h> /*orismos synarthsewn*/ Δ.Μήλιος 10
void Oyra_dimiourgia(TOuras *oura ) {/* Pro: kamia * Meta: Dhmioyrgia kenhs oyras */ oura->embros = 0; oura->piso = 0; oura->adeia = 1; /*True*/ int Oyra_keni(TOuras oura) * Meta: epistrefei 1 an h oyra einai kenh, diaforetika 0 */ return oura.adeia; int Oyra_gemati(TOuras oura) * Meta: epistrefei 1 an h oyra einai gemath, diaforetika 0 */ return ( (oura.piso == oura.embros) && (!Oyra_keni(oura)) ); void Oyra_prosthesi(TOuras *oura, TStoixeioyOyras stoixeio, int *yperxeilisi) * Meta: Oyra exei epayksh8ei me to stoixeio */ if (Oyra_gemati(*oura)) *yperxeilisi=1; { *yperxeilisi=0; TSoyra_setValue(&(oura->pinakas[oura->piso]), stoixeio); oura->piso = ( oura->piso + 1 )% PLITHOS; oura->adeia = 0; Δ.Μήλιος 11
void Oyra_apomakrynsh(TOuras *oura, TStoixeioyOyras *stoixeio, int *ypoxeilisi) * Meta: Oyra exei meiw8ei kata ena stoixeio */ if (Oyra_keni(*oura)) *ypoxeilisi=1; { *ypoxeilisi=0; TSoyra_setValue(stoixeio, oura->pinakas[oura->embros]); oura->embros = ( oura->embros + 1 )% PLITHOS; oura->adeia = ( oura->embros == oura->piso ); 1.3.3.1.2 Αρχεία Δοκιμής Το αρχείο Δοκιμής και εδώ είναι το ίδιο ακριβώς με αυτό των άλλων 2 υλοποιήσεων, με διαφορά την περιοχή των include. Τα include είναι τα εξής: #include "Qcounter.h" #include "../../../TS/TStoixeioyOyras.h" ενώ τα αρχεία Διεπαφής-Υλοποίησης, εκτός πάντα του path για τον τύπο στοιχείου, ίδια με τα πρότυπα αρχεία. 1.3.3.1.3 Εφαρμογές Εδώ έχουμε μόνο μια εφαρμογή η οποία ουσιαστικά μπορεί να λειτουργήσει και με τις άλλες 2 υλοποιήσεις απλά έχει μπει εδώ ενδεικτικά ως εφαρμογή γιατί έχει υλοποιηθεί με μικρές παραλλαγές και με Ολική Απόκρυψη για την υλοποίηση με μετρητή. Οι εφαρμογή αυτή σε πλαίσιο αρχείων και όπως έχει αναλυθεί και στο κεφάλαιο 2 περιλαμβάνει τα αρχεία Διεπαφής-Υλοποίησης της ουράς, τα αρχεία Διεπαφής- Υλοποίησης του τύπου στοιχείου ουράς και προφανώς το αρχείο-εφαρμογή main το οποίο υλοποιεί με τις κατάλληλες κλήσεις των συναρτήσεων-πράξεων το αντίστοιχο αποτέλεσμα που θέλει να επιτύχει η καθεμία από αυτές. 1.3.3.1.3.1 Εφαρμογή ουράς αναμονής Ο σκοπός της εφαρμογής είναι η προσομοίωση μιας πραγματικής ουράς αναμονής πελατών με βάση κάποια στοιχεία που ζητούνται από τον χρήστη. Ακολουθεί ο κώδικας του αρχείου-εφαρμογής: #include <stdlib.h> Δ.Μήλιος 12
#include <time.h> #include "Qcounter.h" int main(void) {/* Skopos: Prosomoiwsh ouras anamonhs*/ TOuras oura; /*oura pelatwn*/ float pithanotita_afiksis; /*pi8anothta afikshs*/ unsigned int xronos_eksipiretisis;/*xronos e3yphrethshs enos pelath*/ unsigned int xronos_prosomoiosis; /*synolikos xronos prosomoiwshs*/ unsigned int xronos; /*roloi prosomoiwshs*/ unsigned int enapomenon_xronos; /*xronos gia to telos e3yphrethshs enos pelath*/ unsigned int arithmos_pelaton; unsigned int xronos_anamonis; /*plh8os e3yphreth8entwn pelatwn*/ /*synolikos xronos anamonhs*/ int xronos_eisodoy; /*h wra pou eishl8e o pelaths sthn oyra*/ float mesos_xronos; /*mesos xronos anamonhs*/ float int random; error=0; printf("dwste xrono prosomoiwshs, pi8anothta afikshs kai xrono e3yphrethshs\n"); scanf("%d %f %d",&xronos_prosomoiosis,&pithanotita_afiksis,&xronos_eksipiretisis); getchar(); printf("h prosomoiwsh 8a diarkesei %4u lepta.\n",xronos_prosomoiosis); printf("h pi8anothta afikshs pelath se ena lepto einai: %4.2f.\n",pithanotita_afiksis); printf("h diarkeia e3yphrethshs enos pelath einai %d lepta.\n",xronos_eksipiretisis); Oyra_dimiourgia(&oura); xronos = 0; enapomenon_xronos = 0; arithmos_pelaton = 0; xronos_anamonis =0; srand(time(null)); while( xronos < xronos_prosomoiosis ) { random = ((float)rand())/(float)(rand_max); if ( random < pithanotita_afiksis ) Oyra_prosthesi(&oura,xronos,&error); Δ.Μήλιος 13
if (error) { printf("yperxeilish oyras!\n"); return 0; if ( enapomenon_xronos == 0) /*eley8eros tamias*/ if (!Oyra_keni(oura)) { /*yparxei pelaths*/ Oyra_apomakrynsh(&oura,&xronos_eisodoy, &error); /*phgainei sto tamio*/ if(error) { printf("ypoxeilish oyras!\n"); return 0; xronos_anamonis += xronos - xronos_eisodoy; /*ypologismos xronoy paramonhs*/ arithmos_pelaton++; enapomenon_xronos = xronos_eksipiretisis; xronos++; /*o xronos ay3anetai kata 1 lepto*/ if ( enapomenon_xronos > 0) /*o pelaths brisketai sto tamio*/ enapomenon_xronos --; /*while( xronos < xronos_prosomoiosis )*/ if (arithmos_pelaton == 0) mesos_xronos = 0.0; mesos_xronos = ((float)xronos_anamonis)/((float)arithmos_pelaton); printf("eksyphreth8hkan %d pelates\n",arithmos_pelaton); printf("o synolikos xronos anamonhs htan %4.2f lepta.\n",mesos_xronos); getch(); return 0; 1.3.3.2 Υλοποίηση με Ολική Απόκρυψη 1.3.3.2.1 Αρχεία Διεπαφής-Υλοποίησης Στο αρχείο Διεπαφής για την υλοποίηση με Ολική Απόκρυψη τα βασικά στοιχεία που εντοπίζονται είναι η δήλωση του δείκτη της δομής της ουράς και οι δηλώσεις των συναρτήσεων που υλοποιούν τις πράξεις του ΑΤΔ Ουρά. Προφανώς παρατηρείται πλέον πως οι συναρτήσεις έχουν διαφορετικές παραμέτρους σε σχέση με αυτές της Διεπαφής της Υλοποίησης με Μερική Απόκρυψη πράγμα κατανοητό καθώς η Δ.Μήλιος 14
προσπέλαση της δομής γίνεται πλέον με χρήση δείκτη. Έχει υλοποιηθεί και μια extra συναρτήσεις η συνάρτηση καταστροφής του ΑΤΔ, Oura_Destructor. Τέλος είναι αυτονόητο πως το μονοπάτι του include για την Διεπαφή του τύπου στοιχείου δεν υπάρχει αφού πρόκειται για πρότυπο αρχείο. Ακολουθεί ο κώδικας του αρχείου Διεπαφής: #ifndef QCOUNTER_OA #define QCOUNTER_OA #include "to antistoixo.h typou stoixeiou" /*edo analoga tin efarmogi i to test tou tipou stoixeiou mpainei to antoistixo.h tou tipou stoixeiou */ /*dhlwseis typwn*/ typedef struct TOuras * HandleOuras; /*dhlwseis synarthsewn*/ /*dhmioyrgia*/ HandleOuras Oura_Constructor(); /*katastrofi*/ void Oura_Destructor(HandleOuras * OuraPtrPtr); /*Prakseis elegxoy*/ int Oyra_keni(const HandleOuras OuraPtr); int Oyra_gemati(const HandleOuras OuraPtr); /*Prakseis pros8eshs/apomakrynshs*/ void Oyra_prosthesi(const HandleOuras OuraPtr, TStoixeioyOyras * const stoixeioptr, int *yperxeilisi); void Oyra_apomakrynsh(const HandleOuras OuraPtr, TStoixeioyOyras * const stoixeioptr, int *ypoxeilisi); #endif /*#ifndef QCOUNTER_OA */ Ακολουθεί ο κώδικας του αρχείου Υλοποίησης: #include <stdlib.h> #include <malloc.h> #include "Qcounter-OA.h" Δ.Μήλιος 15
#define PLITHOS 100 typedef struct TOuras { int embros; /*8esh toy prwtoy stoixeioy ths oyras*/ int piso; /*8esh toy teleytaioy stoixeioy ths oyras*/ int metritis; /*ta stoixeia sthn oyra*/ TStoixeioyOyras pinakas[plithos]; /*o pinakas stoixeiwn*/ TOuras; /*orismos synarthsewn*/ HandleOuras Oura_Constructor() {/* Pro: Kamia * Meta: Dhmioyrgia kenhs stoivas */ HandleOuras ThisOura= malloc(sizeof(touras)); ThisOura->embros = 0; ThisOura->piso = 0; ThisOura->metritis = 0; return ThisOura; void Oura_Destructor(HandleOuras * OuraPtrPtr) * Meta: Katastrofi ths Oyras */ free(*ouraptrptr); *OuraPtrPtr = NULL; int Oyra_keni(const HandleOuras OuraPtr) * Meta: epistrefei 1 an h oyra einai kenh, diaforetika 0 */ return (OuraPtr->metritis == 0); int Oyra_gemati(const HandleOuras OuraPtr) * Meta: epistrefei 1 an h oyra einai gemath, diaforetika 0 */ return (OuraPtr->metritis == PLITHOS); Δ.Μήλιος 16
void Oyra_prosthesi(const HandleOuras OuraPtr, TStoixeioyOyras * const stoixeioptr, int *yperxeilisi) * Meta: Oyra exei epayksh8ei me to stoixeio */ if (Oyra_gemati(OuraPtr)) *yperxeilisi=1; { *yperxeilisi=0; OuraPtr->metritis++; TSoyra_setValue(&(OuraPtr->pinakas[OuraPtr->piso]), *stoixeioptr); OuraPtr->piso = ( OuraPtr->piso + 1 )% PLITHOS; void Oyra_apomakrynsh(const HandleOuras OuraPtr, TStoixeioyOyras * const stoixeioptr, int *ypoxeilisi) * Meta: Oyra exei meiw8ei kata ena stoixeio */ if (Oyra_keni(OuraPtr)) *ypoxeilisi=1; { *ypoxeilisi=0; OuraPtr->metritis--; TSoyra_setValue(stoixeioPtr, OuraPtr->pinakas[OuraPtr->embros]); OuraPtr->embros = ( OuraPtr->embros + 1 )% PLITHOS; 1.3.3.2.2 Αρχεία Δοκιμής Στα αρχεία δοκιμής περιλαμβάνεται το αρχείο main που χρησιμοποιείται ως αρχείο test για τις πράξεις της ATΔ Ουρά. Ακολουθεί ο κώδικας του αρχείου δοκιμής: #include "Qcounter-OA.h" #include "../../../TS/TStoixeioyOyras.h" void print_options(void); int main(void) { int option, error,out_err; Δ.Μήλιος 17
HandleOuras queue; TStoixeioyOyras x; error=0; queue=null; do{ print_options(); scanf("%d", &option); switch(option) {case 1: queue=oura_constructor(); printf("\nh oura dimiourgithike!\n"); case 2: if(queue==null) { printf("\nden uparxei oura gia na eisaxthei stoixeio!\n"); printf("dwse enan stoixeio: "); out_err=tsoyra_readvalue(stdin,&x); if(!out_err) { printf("\n error stin readvalue!\n"); Oyra_prosthesi(queue, &x, &error); if(error) case 3: printf("\nyperxeilhsh oyras. To stoixeio DEN eishx8h!\n"); printf("\nto stoixeio eishx8h!\n"); if(queue==null) { printf("\nden uparxei oura gia na apomakrynthei stoixeio!\n"); Oyra_apomakrynsh(queue, &x, &error); if(error) printf("\nkeni oyra!\n"); { printf("\nekshx8h epityxws to stoixeio "); out_err=tsoyra_writevalue(stdout,x); if(out_err <0) Δ.Μήλιος 18
{ printf("\n error stin writevalue!\n"); case 4: if(queue==null) { printf("\nden uparxei oura gia na elexthei an einai kenh!\n"); if(oyra_keni(queue)) printf("\nh oura einai kenh!\n"); printf("\nh oura DEN einai kenh!\n"); case 5: if(queue==null) { printf("\nden uparxei oura gia na elexthei an einai gemath!\n"); if(oyra_gemati(queue)) printf("\nh oura einai gemath!\n"); printf("\nh oura DEN einai gemath!\n"); case 6: if(queue==null) { printf("\nden uparxei oura gia na katastraphei!\n"); Oura_Destructor(&queue); printf("\nh oura katastrafike!\n"); while(option); return 0; Δ.Μήλιος 19
void print_options(void) { printf("\n\n1. Dhmioyrgia ouras\n\ 2. Prosthesh stoixeiou sthn oura\n\ 3. Apomakrynsh stoixeiou apo thn oura\n\ 4. Elegxos gia kenh oura\n\ 5. Elegxos gia gemath oura\n\ 6. Katastrofi\n\n\ Dwste thn epilogh sas(1-6, 0 gia eksodo):"); ενώ τα αρχεία Διεπαφής-Υλοποίησης, εκτός πάντα του path για τον τύπο στοιχείου, ίδια με τα πρότυπα αρχεία. 1.3.3.2.3 Εφαρμογές 1.3.3.2.3.1 Εφαρμογή ουράς αναμονής Η μόνη διαφορά σε σχέση με την Μερική Απόκρυψη στο αρχείο εφαρμογής είναι λόγω της ολικής απόκρυψης ότι δηλώνεται δείκτης στην δομή στην main ενώ και οι συναρτήσεις-πράξεις της ουράς παίρνουν παράμετρο δείκτη και όχι την ίδια την δομή. Ακολουθεί ο κώδικας του αρχείου-εφαρμογής: #include <stdlib.h> #include <time.h> #include "Qcounter-OA.h" int main(void) {/* Skopos: Prosomoiwsh ouras anamonhs */ HandleOuras oura; /*oura pelatwn*/ float pithanotita_afiksis; /*pi8anothta afikshs*/ unsigned int xronos_eksipiretisis;/*xronos e3yphrethshs enos pelath*/ unsigned int xronos_prosomoiosis; /*synolikos xronos prosomoiwshs*/ unsigned int xronos; /*roloi prosomoiwshs*/ unsigned int enapomenon_xronos; /*xronos gia to telos e3yphrethshs enos pelath*/ unsigned int arithmos_pelaton; unsigned int xronos_anamonis; /*plh8os e3yphreth8entwn pelatwn*/ /*synolikos xronos anamonhs*/ int xronos_eisodoy; /*h wra pou eishl8e o pelaths sthn oyra*/ float mesos_xronos; /*mesos xronos anamonhs*/ float int random; error=0; Δ.Μήλιος 20
printf("dwste xrono prosomoiwshs, pi8anothta afikshs kai xrono e3yphrethshs\n"); scanf("%d %f %d",&xronos_prosomoiosis,&pithanotita_afiksis,&xronos_eksipiretisis); getchar(); printf("h prosomoiwsh 8a diarkesei %4u lepta.\n",xronos_prosomoiosis); printf("h pi8anothta afikshs pelath se ena lepto einai: %4.2f.\n",pithanotita_afiksis); printf("h diarkeia e3yphrethshs enos pelath einai %d lepta.\n",xronos_eksipiretisis); oura=oura_constructor(); xronos = 0; enapomenon_xronos = 0; arithmos_pelaton = 0; xronos_anamonis =0; srand(time(null)); while( xronos < xronos_prosomoiosis ) { random = ((float)rand())/(float)(rand_max); if ( random < pithanotita_afiksis ) Oyra_prosthesi(oura,&xronos,&error); if (error) { printf("yperxeilish oyras!\n"); return 0; if ( enapomenon_xronos == 0) /*eley8eros tamias*/ if (!Oyra_keni(oura)) /*yparxei pelaths*/ { Oyra_apomakrynsh(oura,&xronos_eisodoy, &error); /*phgainei sto tamio*/ if(error) { printf("ypoxeilish oyras!\n"); return 0; xronos_anamonis += xronos - xronos_eisodoy; /*ypologismos xronoy paramonhs*/ arithmos_pelaton++; enapomenon_xronos = xronos_eksipiretisis; xronos++; /*o xronos ay3anetai kata 1 lepto*/ if ( enapomenon_xronos > 0) /*o pelaths brisketai sto tamio*/ enapomenon_xronos --; Δ.Μήλιος 21
/*while( xronos < xronos_prosomoiosis )*/ if (arithmos_pelaton == 0) mesos_xronos = 0.0; mesos_xronos = ((float)xronos_anamonis)/((float)arithmos_pelaton); printf("eksyphreth8hkan %d pelates\n",arithmos_pelaton); printf("o synolikos xronos anamonhs htan %4.2f lepta.\n",mesos_xronos); Oura_Destructor(&oura); getch(); return 0; 1.3.4 Αρχεία Διεπαφής-Υλοποίησης Τύπου Στοιχείου Ουράς Ακολουθεί παράθεση κώδικα για καθεμιά από τις 3 υλοποιήσεις του τύπου στοιχείου που υλοποιούνται σε αυτή την ενότητα. TS-int: Ακολουθεί ο κώδικας του αρχείου Διεπαφής: #ifndef TStoixeioyOyras_H #define TStoixeioyOyras_H typedef int TStoixeioyOyras; void TSoyra_setValue (TStoixeioyOyras *target, TStoixeioyOyras source); int TSoyra_readValue (FILE *from, TStoixeioyOyras * Elem); int TSoyra_writeValue (FILE *to, TStoixeioyOyras Elem); #endif Ακολουθεί ο κώδικας του αρχείου Yλοποιήσης: #include "TStoixeioyOyras.h" void TSoyra_setValue (TStoixeioyOyras *target, TStoixeioyOyras source) { *target=source; Δ.Μήλιος 22
int TSoyra_readValue (FILE *from, TStoixeioyOyras * Elem) { int fd; fd=fscanf(from, "%d", Elem); if(fd==1) return 1; return 0; int TSoyra_writeValue (FILE *to, TStoixeioyOyras Elem) { int fd; fd=fprintf(to, "%d--", Elem); return fd; TS-string: Ακολουθεί ο κώδικας του αρχείου Διεπαφής: #ifndef TStoixeioyOyras_H #define TStoixeioyOyras_H #define CPLITHOS 15 #include <string.h> typedef char TStoixeioyOyras[CPLITHOS]; void TSoyra_setValue (TStoixeioyOyras *target, TStoixeioyOyras source); int TSoyra_readValue (FILE *from, TStoixeioyOyras * Elem); int TSoyra_writeValue (FILE *to, TStoixeioyOyras Elem); #endif Ακολουθεί ο κώδικας του αρχείου Yλοποιήσης: #include "TStoixeioyOyras.h" void TSoyra_setValue (TStoixeioyOyras *target, TStoixeioyOyras source) { strncpy(*target, source,cplithos); Δ.Μήλιος 23
int TSoyra_readValue (FILE *from, TStoixeioyOyras * Elem) { int fd; fd=fscanf(from, "%s", Elem); if(fd==1) return 1; return 0; int TSoyra_writeValue (FILE *to, TStoixeioyOyras Elem) { int fd; fd=fprintf(to, "%s--", Elem); return fd; TS-struct: Ακολουθεί ο κώδικας του αρχείου Διεπαφής: #ifndef TStoixeioyOyras_H #define TStoixeioyOyras_H #define CPLITHOS 15 #include <string.h> typedef struct { int integer; char string[cplithos]; TStoixeioyOyras; void TSoyra_setValue (TStoixeioyOyras *target, TStoixeioyOyras source); int TSoyra_readValue (FILE *from, TStoixeioyOyras * Elem); int TSoyra_writeValue (FILE *to, TStoixeioyOyras Elem); #endif Ακολουθεί ο κώδικας του αρχείου Yλοποιήσης: #include "TStoixeioyOyras.h" void TSoyra_setValue (TStoixeioyOyras *target, TStoixeioyOyras source) { target->integer=source.integer; strncpy(target->string,source.string,cplithos); Δ.Μήλιος 24
int TSoyra_readValue (FILE *from, TStoixeioyOyras * Elem) { int fd; fd=fscanf(from,"%d %s",&(elem->integer),elem->string); if(fd==2) return 1; return 0; int TSoyra_writeValue (FILE *to, TStoixeioyOyras Elem) { int fd; fd=fprintf(to,"%d %s-- ", Elem.integer,Elem.string); return fd; Προφανώς έξω από τους φακέλους στα πλαίσια της επιλογής του χρήστη και όσων άλλων παραθέτονται στο κεφάλαιο 2 για την επεξήγηση των αρχείων της συγκεκριμένης ενότητας βρίσκονται πάλι τα αρχεία Διεπαφής και Υλοποίησης του TS-int ως default υλοποίηση που χρησιμοποιούν οι δοκιμές-main των επιμέρους υλοποιήσεων της ουράς (με κενό, με λογική μεταβλητή, με μετρητή). Δ.Μήλιος 25