Pascal 6 Οκτωβρίου 011 1 Procedures σε Pascal Στην Pascal μπορούμε να ορίσουμε διαδικασίες (procedures). Αυτές είναι ομάδες εντολών οι οποίες έχουν ένα όνομα. Γράφοντας το όνομα μιας διαδικασίας μπορούμε να την καλέσουμε (call). Όταν καλούμε μια διαδικασία εκτελούνται οι εντολές που αυτή περιέχει. Δείτε παράδειγμα 1: 1 program proc1; Listing 1: Ορισμός και κλήση procedure 3 procedure myproc; 4 begin 5 write('h kota ekave to augo,'); 6 write(' h to augo tnv kota; '); 7 writeln('to be or not to be?'); 8 end; 9 10 begin 11 myproc; 1 myproc; 13 14 readln; 15 end. Σε αυτό ορίζεται μία procedure με όνομα myproc στις γραμμές 3 έως 8. Το σώμα της procedure δηλαδή οι εντολές που εκτελούνται όποτε την καλεί κανείς περιλαμβάνονται σε ένα begin-end μπλοκ. Όποτε δηλαδή κανείς καλεί την procedure εκτελούνται οι εντολές που περιέχονται εκεί. Παρατηρήστε ότι η γραμμή 3 τελειώνει με ένα ερωτηματικό όπως και το end της γραμμής 8 που κλείνει το σώμα της διαδικασίας όπως και κάθε εντολή που περιέχεται εκεί. Για να καλέσει κανείς τη συνάρτηση, αρκεί να αναφέρει το όνομά της, όπως στις γραμμές 11 και 1. Σημειώστε ότι οι εντολές της διαδικασίας δεν εκτελούνται αν δεν υπάρχει κάπου μία κλήση. Δηλαδή το γεγονός ότι υπάρχουν οι γραμμές 3 έως 8 δε σημαίνει απαραίτητα ότι θα εκτελεστούν κιόλας. Ο κανόνας είναι ότι η εκτέλεση του προγράμματος ξεκινάει με την πρώτη εντολή του κύριου begin-end μπλοκ του προγράμματος, το οποίο ξεκινάει στη γραμμή 10. Κάθε φορά που η εκτέλεση του προγράμματος συναντά μια κλήση συνάρτησης τότε η ροή του προγράμματος μεταφέρεται στο 1
begin-end μπλοκ της αντίστοιχης διαδικασίας και στη συνέχεια επιστρέφει στο σημείο αμέσως μετά την κλήση. Στο παραπάνω δηλαδή η ροή εκτέλεσης του προγράμματος ξεκινάει στη γραμμή 10 όπου βρίσκεται το begin του κύριου μπλοκ του προγράμματος. Όταν η ροή εκτέλεσης φτάσει στη γραμμή 11 (κλήση συνάρτησης) τότε μεταφέρεται στο μπλοκ των γραμμών 4 έως 8 όπου εκτελεί τις εκεί εντολές διαδοχικά. Μετά επιστρέφει στην αμέσως επόμενη εντολή του κύριου μπλοκ από την οποία πραγματοποιήθηκε η τελευταία κλήση δηλαδή τη γραμμή 1. Αυτή είναι επίσης κλήση συνάρτησης οπότε ξαναεκτελούνται οι εντολές των γραμμών 4 έως 8. Οι διαδικασίες μπορούν να παίρνουν κάποια ορίσματα (arguments) δηλαδή παραμέτρους. Για παράδειγμα το παρακάτω πρόγραμμα περιέχει μια συνάρτηση η οποία τυπώνει μερικά αστεράκια. Το πόσα αστεράκια θα τυπώσει καθορίζεται από την τιμή της παραμέτρου x. Το σώμα της διαδικασίας είναι ένα απλό for το οποίο τυπώνει τόσα αστέρια όσα ζητούνται μέσω της x και μετά αλλάζει γραμμή. 1 program proc; Listing : Ορισμός procedure με μία παράμετρο 3 procedure print_stars(x: integer); 5 i: integer; 7 for i := 1 to x do 8 write('*'); 9 writeln; 10 end; 11 1 begin 13 print_stars (3); 14 print_stars (); 15 print_stars (5); 16 17 readln; 18 end. Αν τρέξετε το παραπάνω πρόγραμμα θα δείτε στην οθόνη κάτι σαν αυτό: *** ** ***** Σε σχέση με το προηγούμενο παράδειγμα παρατηρούμε τα εξής: Η διαδικασία print_stars παίρνει μία παράμετρο x η οποία δηλώνεται μέσα σε παρενθέσεις ακριβώς όπως δηλώνονται και οι άλλες μεταβλητές σε ένα πρόγραμμα, δηλαδή αναφέρεται το όνομά της, μία άνω-κάτω τελεία και μετά ο τύπος της. Μέσα στο σώμα της διαδικασίας η παράμετρος x μπορεί να χρησιμοποιείται όπως και οι άλλες μεταβλητές, π.χ. στη γραμμή 7. Επίσης παρατηρούμε ότι προκειμένου να χρησιμοποιήσουμε τη μεταβλητή i στο βρόχο της γραμμής 7 πρέπει να τη δηλώσουμε σε ένα var μπλοκ στις γραμμες
4 και 5. Τέλος, για να καλέσουμε τη διαδικασία γράφουμε το όνομά της όπως στις γραμμές 13 έως 15 και μέσα σε παρενθέσεις δίνουμε την τιμή της παραμέτρου. Όταν εκτελούνται οι κλήσεις των γραμμών 13-15 η ροή μεταφέρεται στις γραμμές 6-10 όπως και στο προηγούμενο παράδειγμα με τη διαφορά ότι αυτή τη φορά κατά τη διάρκεια εκτέλεσης των 6-10 υφίσταται και η μεταβλητή-παράμετρος x η οποία έχει την τιμή 3, ή 5 αντίστοιχα σε κάθε κλήση των γραμμών 13-15. Μια διαδικασία μπορεί να παίρνει περισσότερες από μία παραμέτρους διάφορων τύπων. Αν για παράδειγμα θέλουμε να επεκτείνουμε τη συνάρτησή μας ώστε να παίρνει ως παράμετρο όχι μόνο το πόσους αλλά και ποιους χαρακτήρες θα τυπώνει μπορουμε να γράψουμε το εξής: 1 program proc3; Listing 3: Ορισμός procedure με δύο παραμέτρους 3 procedure print_chars(c: char; x: integer); 5 i: integer; 7 for i := 1 to x do 8 write(c); 9 end; 10 11 begin 1 print_chars('*', 3); 13 print_chars('.', 1); 14 print_chars('*', 3); 15 16 readln; 17 end. Στο παράδειγμα 3 προσθέτουμε μία επιπλέον παράμετρο με όνομα c και τύπο char. Διατηρούμε και την x όπως και προηγουμένως. Μεταξύ τους τις χωρίζουμε με το ερωτηματικό. Στις γραμμές 1-14 υπάρχουν οι αντίστοιχες κλήσεις. Μέσα σε παρενθέσεις τοποθετούμε τόσες παραμέτρους όσες δέχεται η συνάρτηση. Οι τιμές που δίνουμε σε κάθε κλήση αντιστοιχίζονται μία προς μία στις αντίστοιχες παραμέτρους. Δηλαδή η κλήση της γραμμής 1 έχει σαν αποτέλεσμα να δοθεί στην παράμετρο c η τιμή '*' και στην x η τιμή 3, ενώ η κλήση της γραμμής 13 δίνει αντίστοιχα στην c την τιμή '.' και στην x την τιμή 1. Συνοψίζοντας ο ορισμός μιας διαδικασίας αποτελείται από τα εξής: Την επικεφαλίδα της διαδικασίας η οποία με τη σειρά της αποτελείται από τη δεσμευμένη λέξη procedure, το όνομα της διαδικασίας, τη λίστα των τυπικών παραμέτρων της διαδικασίας (αν υπάρχουν) μέσα σε παρενθέσεις και στο τέλος το ελληνικό ερωτηματικό. Η λίστα των τυπικών παραμέτρων είναι μια λίστα δηλώσεων χωρισμένων με ελληνικά ερωτηματικά. Κάθε δήλωση είναι της μορφής onoma: typos ή on1, on,..., onx: typos όπως δηλαδή και στις δηλώσεις μεταβλητών. 3
Ένα begin-end μπλοκ το οποίο περιέχει τις εντολές της διαδικασίας. Του μπλοκ μπορεί να προηγείται ένα μπλοκ var το οποίο περιέχει δηλώσεις μεταβλητών. Ένα παράδειγμα Ας δούμε με ένα παράδειγμα τη χρήση μιας απλής διαδικασίας όπως η παραπάνω. Ας υποθέσουμε ότι θέλουμε να γράψουμε ένα πρόγραμμα το οποίο να τυπώνει στην οθόνη ένα τρίγωνο με αστεράκια και τελείες. Το μέγεθος του τριγώνου θα το δίνει ο χρήστης. Θα μπορούσε να είναι όπως το παράδειγμα 4. 1 program triangle; var 3 n, i, j: integer; Listing 4: Κάποιο τρίγωνο 4 5 begin 6 write('dose to n:'); 7 readln(n); 8 9 for j := n div downto 0 do 10 begin 11 for i := 1 to j do 1 write('*'); 13 for i := 1 to n - * j do 14 write('.'); 15 for i := 1 to j do 16 write('*'); 17 writeln; 18 end; 19 end. Το ίδιο πράγμα θα μπορούσαμε να το γράψουμε όπως στο παράδειγμα 5. 1 program triangle3; Listing 5: Το ίδιο τρίγωνο 3 procedure print_chars(c: char; x: integer); 5 k: integer; 7 for k := 1 to x do 8 write(c); 9 end; 10 11 var 1 n, j: integer; 4
13 begin 14 write('dose to n:'); 15 readln(n); 16 17 for j := n div downto 0 do 18 begin 19 print_chars('*', j); 0 print_chars('.', n - * j); 1 print_chars('*', j); writeln; 3 end; 4 end. 5