Οι εντολές επανάληψης

Tα διάφορα είδη επαναληπτικού βρόχου (loop) διακρίνονται από τον τρόπο με τον οποίο αποφασίζουν πόσες επαναλήψεις θα εκτελέσουν ή διαφορετικά από τον τρόπο εξόδου από την επαναληπτικότητα του βρόχου. Σε κάθε βρόχο υπάρχει το block των εντολών που αποτελούν την επαναλαμβανόμενη ενότητα και η συνθήκη που αποφασίζει αν το block θα εκτελεσθεί ακόμη μια φορά. Ο πιο απλός τύπος επαναληπτικού βρόχου που υπάρχει στις περισσότερες γλώσσες είναι αυτός που χρησιμοποιείται για συγκεκριμένο αριθμό επαναλήψεων και ελέγχεται με ένα απαριθμητή.
Όταν η τιμή του απαριθμητή ξεπεράσει κάποια τελική τιμή τότε διακόπτεται η επανάληψη και γίνεται έξοδος από τον βρόχο. Στην Pascal αυτός είναι γνωστός σαν for do βρόχος. Η Pascal εκτός από την for do πρόταση έχει ακόμη δύο προτάσεις για επαναληπτική επεξεργασία που δεν δεσμεύονται με συγκεκριμένο αριθμό επαναλήψεων.
Αυτές είναι η while do στην οποία η συνθήκη για επαναληπτική εκτέλεση ελέγχεται στην αρχή πριν από την είσοδο στο επαναλαμβανόμενο block, και η repeat until όπου η συνθήκη ελέγχεται στο τέλος.

6.1 Εισαγωγικά παραδείγματα με την for εντολή.

Στο κεφ.1 στο πρώτο μας πρόγραμμα συναντήσαμε:
for i:=1 to number_times do
begin
… ;
… ;
end;

Αυτή η πρόταση απαιτούσε το block που ακολουθεί την λέξη do να επαναληφθεί. Ο αριθμός των επαναλήψεων είναι συγκεκριμένος και καθορίζεται από την αρχική και την τελική τιμή του i (αρχική τιμή 1, τελική το 5 που είναι η τιμή της σταθεράς number_times). Άρα το block θα επαναληφθεί 5 φορές. Σαν μεταβλητή ελέγχου (απαριθμητή επαναλήψεων) χρησιμοποιούμε την μεταβλητή i. Η αύξηση του i κατά 1 γίνεται χωρίς την μεσολάβηση του προγραμματιστή. Στο παρακάτω παράδειγμα φαίνεται η μεταβολή της μεταβλητής ελέγχου.

program using_the_counter;
var n : integer;
begin
for n:=1 to 8 do
writeln (n,’ έχει τριπλάσιο το ‘,3*n)
end.

Kατά την εκτέλεσή του βλέπουμε τις διαδοχικές τιμές του n από το 1 έως το 8 καθώς και τα τριπλάσια του.
Στα προηγούμενα παραδείγματα, η μεταβλητή ελέγχου (απαριθμητής) είδαμε να αυξάνει. Είναι όμως δυνατό και να ελαττώνεται, όπως στο παρακάτω παράδειγμα:

program counting_down;
var n : integer;
begin
for n:=8 downto 1 do
writeln(n,’ έχει τριπλάσιο το ‘,3*n)
end.

6.1.2 Σύνταξη της for πρότασης.

for μεταβλητή_ελέγγχου:=αρχική_τιμή downto τελική_τιμή do πρόταση;

όπου η μεταβλητή_ελέγχου είναι μία απλή μεταβλητή τύπου integer, char, boolean ή άλλου διακριτού (όχι real) τύπου που ορίζουμε εμείς.
Σαν αρχική και τελική_τιμή εννοούμε παραστάσεις που δίνουν τύπο στοιχείου συμβατό με την μεταβλητή ελέγχου, ενώ σαν πρόταση θα εννοούμε μια απλή η σύνθετη (begin…end) πρόταση.
Αν αρχικά η μεταβλητή ελέγχου έχει τιμή μεγαλύτερη από την τελική_τιμή, η πρόταση ή το block πού ακολουθεί το do δεν εκτελείται. Στην περίπτωση που η μεταβλητή ελέγχου έχει αρχική τιμή ίση με την τελική_τιμή θα έχουμε μια μόνο επανάληψη.

Σχόλια.

1) Στο παρακάτω παράδειγμα η μεταβλητή ελέγχου είναι τύπου char, κάτι που δεν μπορεί να συμβεί σε πολλές γλώσσες.

Mετά την εκτέλεση

program alphabet; Μετά την εκτέλεση στην οθόνη θα εμφανισθούν:
var c:char; abcdefghijklmnopqrstuvwxyz
begin
      for c:=’a’ to ‘z’ do write(c)
end.

2) Στην Pascal η μεταβλητή ελέγχου όπως είδαμε αυξάνει μετά από κάθε επανάληψη κατά 1 και δεν έχει την δυνατότητα που προσφέρεται σε άλλες γλώσσες ν’ αυξάνει (ή να ελαττώνεται) με κάποιο βήμα π.χ. 5. Αν χρειασθούμε κάτι τέτοιο χρησιμοποιούμε μια επιπλέον μεταβλητή που η τιμή της εξαρτάται από την τιμή της μεταβλητής ελέγχου (απαριθμητή). Το παρακάτω παράδειγμα εμφανίζει τους ακέραιους από το 1 έως το 31 με βήμα 5.

program with_step;
var i,n : integer;
begin
for i:=1 to 7 do
begin
n:=1+5*(i-1);
writeln(n);
end;
end.
Μετά την εκτέλεση στην οθόνη θα εμφανισθούν:
1
6
11
16
21
26
31

Ερώτηση:

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

Κανόνες για την χρήση της for πρότασης.

1) Αρχικές και τελικές τιμές.

Αυτές υπολογίζονται μόνο μία φορά πριν την πρώτη επανάληψη. Έτσι εάν μεταβληθούν από λάθος μέσα στο βρόχο τότε το πρόγραμμά μας δεν θα τρέχει σωστά. Στο πιο κάτω παράδειγμα δείχνεται τι συμβαίνει σε μια τέτοια περίπτωση.

program altering_limit;
var i , bound : integer;
begin
bound:=5;
for i:=1 to bound do
begin
writeln(‘μετρητής :’,i);
bound:=bound+1;
end;
writeln(‘τελική τιμή :’,bound)
end.
Μετά την εκτέλεση στην oθόνη:

μετρητής :1
μετρητής :2
μετρητής :3
μετρητής :4
μετρητής :5
τελική τιμή :6

 

Παρατηρούμε στο παραπάνω παράδειγμα ότι, οι προτάσεις του block που εκτελούνται με την for επαναλαμβάνονται 5 φορές όπως προκύπτει από την αρχική και τελική τιμή του απαριθμητή πριν από την πρώτη επανάληψη, ακόμη και αν η τελική τιμή του μεταβάλλεται σε κάθε επανάληψη.

2) Η τιμή της μεταβλητής ελέγχου.

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

Εισαγωγικό παράδειγμα με την repeat…until πρόταση.

Όπως έχει προαναφερθεί, η repeat…until πρόταση είναι ένας από τους δύο τρόπους όπου επιτυγχάνουμε επανάληψη υπό συνθήκη.
Παρατηρείστε το παρακάτω παράδειγμα.

program filtro;
var n : integer;
begin
repeat
write(‘Δώστε ένα θετικό ακέραιο :’);
readln(n);
until n>0;
writeln(‘Ευχαριστώ για το ‘,n)
end.

Η δομή :

repeat
… ;
… ;
until n>0;

επαναλαμβάνει τις δύο προτάσεις που περιέχει μέχρις ότου η συνθήκη n>0 γίνει αληθής. Με άλλα λόγια θα προτρέπει το χρήστη να δίνει αριθμούς μέχρις ότου αυτός δώσει μία θετική τιμή. Δεν είναι λοιπόν γνωστό από πριν πόσες φορές θα επαναληφθεί ο βρόχος. Προσοχή όμως στο γεγονός ότι ο βρόχος θα εκτελεσθεί τουλάχιστον μία φορά. Η λογική παράσταση (εδώ n>0) στη συνέχεια υπολογίζεται και εάν είναι αληθής, εκτελείται η επόμενη πρόταση μετά τον βρόχο. Εάν η λογική παράσταση (συνθήκη) είναι ψευδής, η ακολουθία των προτάσεων που αποτελούν τον βρόχο εκτελείται πάλι, γίνεται κατόπιν ο έλεγχος της συνθήκης κ.ο.κ.
Είναι σημαντικό να προσέξουμε ότι, έξοδος από τον βρόχο γίνεται αφού εκτελεσθούν οι προτάσεις που περιλαμβάνονται σ’ αυτόν και μετά τον έλεγχο της συνθήκης βρίσκεται ότι αυτή είναι αληθής.

Σύνταξη της repeat..until πρότασης

repeat
πρόταση1;
πρόταση2;

πρόταση n
until συνθήκη;

Σχόλια

1) Στον βρόχο μπορούν να περιλαμβάνονται περισσότερες από μία προτάσεις που θα ξεχωρίζουν με ;. Είναι όμως δυνατό κάποιος να περιλάβει τις προτάσεις του βρόχου σε begin … end δηλαδή να δημιουργήσει μία σύνθετη πρόταση. Έτσι οι εντολές του βρόχου που περιλαμβάνεται στο πρώτο παράδειγμα που δώσαμε με την repeat…until μπορεί να γραφεί και όπως παρακάτω:

repeat
begin
write (‘Δώσε ένα θετικό αριθμό’);
readln (n)
end
until n>o ;

2) Εάν η συνθήκη κατά την είσοδο στον βρόχο είναι ψευδής πρέπει οι εντολές που περιλαμβάνονται σ’ αυτόν να μπορούν να μεταβάλουν την τιμή της (από false σε true) και αυτό διότι σε αντίθετη περίπτωση ο βρόχος θα επαναλαμβάνεται απεριόριστα (ατέρμονα βρόχο). Πιο κάτω δίνονται δύο παραδείγματα τέτοιων ατέρμονων βρόχων.

i) n:=10;                                                        ii) repeat
repeat                                                                    …;
n:=n+1                                                               …;
until n<0;                                                        until false;

Εισαγωγικό παράδειγμα με την while..do πρόταση.

Θα δείξουμε τώρα ένα δεύτερο τρόπο που επιτυγχάνεται επανάληψη υπό συνθήκη στην Pascal, δηλαδή, την while..do πρόταση. Θεωρούμε το παρακάτω πρόγραμμα.Μετά την εκτέλεση

program Example_while;
var   sum : integer;
number : integer;
begin
sum :=0;
while sum<100 do
begin
write (‘Δώστε ένα αριθμό:’);
readln (number);
sum :=sum+number;
end;
writeln (‘το άθροισμα τους είναι ‘, sum)
end.
στην οθόνη

Δώστε ένα αριθμό : 16
Δώστε ένα αριθμό : 49
Δώστε ένα αριθμό : 24
Δώστε ένα αριθμό : 44
το άθροισμα τους είναι 133

 

Αυτήν την φορά, η πρόταση : while sum<100 do επαναλαμβάνει την εντολή που ακολουθεί (εδώ block δύο προτάσεων) όσο η συνθήκη (sum<100) είναι αληθής. Όσο το άθροισμα των αριθμών που δίνονται σαν δεδομένα είναι μικρότερο από 100, ζητείται από τον χρήστη να δίνει και άλλον αριθμό.
Βλέπουμε πάλι ότι δεν ξέρουμε πόσες φορές θα εκτελεσθούν οι εντολές του βρόχου. Αλλά, αυτή τη φορά, η συνθήκη (sum<100) εξετάζεται πριν από την εκτέλεση τής πρότασης του βρόχου και όχι μετά, όπως στην περίπτωση της repeat..until.Σαν συνέπεια αυτού δεν εκτελούνται ούτε μία φορά οι εντολές του βρόχου όταν η συνθήκη είναι ψευδής (false).
Σύνταξη και λογικό διάγραμμα της while..do πρότασης.

while λογική_παράσταση do πρόταση;

Σχόλια

1) Αυτή τη φορά το περιεχόμενο του βρόχου είναι μία απλή ή σύνθετη πρόταση.
2) Εάν η συνθήκη είναι αληθής έχουμε είσοδο στο βρόχο και θα πρέπει οι προτάσεις του βρόχου να είναι ικανές να μεταβάλουν την τιμή της συνθήκης .Σε αντίθετη περίπτωση έχουμε ένα απεριόριστο (ατέρμονο) βρόχο.
3) Αφού η συνθήκη ελέγχεται πριν την εκτέλεση του βρόχου θα πρέπει για να γίνει είσοδος σ’ αυτόν να μπορεί να υπολογισθεί η τιμή της συνθήκης και μάλιστα να είναι true.Γι’αυτό στο παραπάνω παράδειγμα στο sum καταχωρούμε την τιμή μηδέν 0 ώστε κατά πρώτο να μηδενίζεται ο αθροιστής και κατά δεύτερο να μπορεί να γίνεται είσοδος στο βρόχο.
Το παράδειγμα που είχαμε δει με την repeat..until έχουμε την δυνατότητα να το πραγματοποιήσουμε και με την while..do ως εξής:
(παρουσιάζουμε μόνο την while..do που αντικαθιστά την repeat .. until)

n:=-1;
while n<=0 do
begin
write (‘Δώστε αριθμό >0’);
readln (n)
end;

Πρέπει να προσεχθεί το σημείο πριν την while όπου καταχωρείται αρνητική τιμή στο n (εδώ -1) για να μπορεί να γίνει είσοδος στο βρόχο.