Επανάληψη Εντολές while, for, do-whileepl131/spring02/documents/epl-notes7.pdf ·...

23
1 Επανάληψη Εντολές while, for, do-while Απροσδιόριστη Επανάληψη ή Επανάληψη υπό συνθήκη (while, do-while) Απαριθμητή Επανάληψη (for) Εντολή while όχι ναι Σημασιολογία Εάν από την αρχή δεν ευσταθεί η συνθήκη C, η εντολή S δεν θα εκτελεστεί καθόλου. ∆ιαφορετικά η S εκτελείται και αυτό επαναλαμβάνεται μέχρις ότου η συνθήκη C να μην ευσταθεί. while (συνθήκη) εντολή C? S

Transcript of Επανάληψη Εντολές while, for, do-whileepl131/spring02/documents/epl-notes7.pdf ·...

Page 1: Επανάληψη Εντολές while, for, do-whileepl131/spring02/documents/epl-notes7.pdf · 2002. 9. 4. · 1 Επανάληψη Εντολές while, for, do-while • Απροσδιόριστη

1

Επανάληψη

Εντολές while, for, do-while

• Απροσδιόριστη Επανάληψη ή Επανάληψη υπό

συνθήκη (while, do-while)

• Απαριθµητή Επανάληψη (for) Εντολή while όχι ναι Σηµασιολογία Εάν από την αρχή δεν ευσταθεί η συνθήκη C, η εντολή S δεν θα εκτελεστεί καθόλου. ∆ιαφορετικά η S εκτελείται και αυτό επαναλαµβάνεται µέχρις ότου η συνθήκη C να µην ευσταθεί.

while (συνθήκη) εντολή

C?

S

Page 2: Επανάληψη Εντολές while, for, do-whileepl131/spring02/documents/epl-notes7.pdf · 2002. 9. 4. · 1 Επανάληψη Εντολές while, for, do-while • Απροσδιόριστη

2

Εποµένως για να µην υπάρξει βρόχος άπειρης διάρκειας (infinite loop), η διεργασία της S πρέπει να είναι τέτοια, ούτως ώστε να επέλθει µία κατάσταση στην οποία η C παύει να ευσταθεί, οδηγώντας έτσι σε έξοδο από το βρόχο. /* άπειρος βρόχος */ while (1) printf(″\n∆εν µπορώ να σταµατήσω!″); /* κενή εντολή */ while (0) printf(″????″); while (0); Παράδειγµα: Υπολογισµός του αθροίσµατος 1 + 2 + … + n int n, count = 1, sum = 0; printf(″\nEnter limit: ″); scanf(″%d″, &n); while (count <= n) sum = sum + count; count = count + 1; printf(″\nThe sum is %d ″, sum);

Page 3: Επανάληψη Εντολές while, for, do-whileepl131/spring02/documents/epl-notes7.pdf · 2002. 9. 4. · 1 Επανάληψη Εντολές while, for, do-while • Απροσδιόριστη

3

Παράδειγµα: Πρόγραµµα το οποίο παράγει τα ακόλουθα:

0 1 1 2 2 4 3 8 4 16 5 32 6 64

x 2x

#include <stdio.h> #define LIMIT 6

void main ( )

int count = 0, res = 1; while (count <= LIMIT)

printf(″\n%1d%5d″, count, res); count = count + 1; res = res * 2;

Σύνθετοι Τελεστές Ανάθεσης count = count + 1; res = res * 2; sum = sum + count; x = x – 3; Σηµασιολογία: µεταβλητή = µεταβλητή τελεστής (έκφραση); Σύνθετοι τελεστές: +=, −=, *=, /=, %=

µεταβλητή τελεστής= έκφραση;

Page 4: Επανάληψη Εντολές while, for, do-whileepl131/spring02/documents/epl-notes7.pdf · 2002. 9. 4. · 1 Επανάληψη Εντολές while, for, do-while • Απροσδιόριστη

4

Απλή Ανάθεση Σύνθετη Ανάθεση count = count + 1; count += 1; res = res * 2; res *= 2; sum = sum + count; sum += count; x = x – 3; x −= 3; n = n * (x + 1); n *= x + 1; int count = 1, sum = 0; while (count <= n) sum += sum; count += 1; int count = 0, res = 1; while (count <= LIMIT) printf(″\n%1d%5d″, count, res); count += 1; res *= 2; Εντολή for

for (έκφραση-αρχικοποίησης ;

συνθήκη ; έκφραση-ενηµέρωσης)

εντολή

Page 5: Επανάληψη Εντολές while, for, do-whileepl131/spring02/documents/epl-notes7.pdf · 2002. 9. 4. · 1 Επανάληψη Εντολές while, for, do-while • Απροσδιόριστη

5

Γενική Σηµασιολογία Καταρχήν αποτιµείται η έκφραση-αρχικοποίησης, και στη συνέχεια δοκιµάζεται η συνθήκη. Εάν δεν ευσταθεί ο έλεγχος µεταφέρεται εκτός της for. ∆ιαφορετικά εκτελείται η εντολή, αποτιµείται η έκφραση-ενηµέρωσης και ο έλεγχος επιστρέφει στη δοκιµή της συνθήκης. Η εκτέλεση της εντολής και η αποτίµηση της έκφρασης-ενηµέρωσης επαναλαµβάνεται µέχρις ώτου η συνθήκη να µην ευσταθεί. Τυπική Εφαρµογή της Εντολής for όχι ναι

αρχικοποίηση µεταβλητής ελέγχου

ενηµέρωση µεταβλητής ελέγχου

συνθήκη?

εντολή

Page 6: Επανάληψη Εντολές while, for, do-whileepl131/spring02/documents/epl-notes7.pdf · 2002. 9. 4. · 1 Επανάληψη Εντολές while, for, do-while • Απροσδιόριστη

6

Η επανάληψη ελέγχεται από µία µεταβλητή η οποία ονοµάζεται µεταβλητή ελέγχου (control variable) ή µεταβλητή απαρίθµησης (counting variable). Η έκφραση-αρχικοποίησης αποτελεί την εντολή βάσει της οποίας καταχωρείται αρχική τιµή στη µεταβλητή ελέγχου. H αποτίµηση της έκφρασης-ενηµέρωσης έχει ως αποτέλεσµα την ενηµέρωση της τιµής της µεταβλητής ελέγχου. Η συνθήκη (επανάληψης) εµπλέκει την µεταβλητή ελέγχου. Εποµένως προς αποφυγή βρόχου άπειρης διάρκειας, η έκφραση-ενηµέρωσης πρέπει τελικά να οδηγήσει σε µία κατάσταση, όπου η συνθήκη παύει να υφίσταται. Για να είναι η λογική πιο διαφανής, η τιµή της µεταβλητής ελέγχου θα πρέπει να ενηµερώνεται αποκλειστικά από την έκφραση-ενηµέρωσης. Τέλος η µεταβλητή ελέγχου τείνει να είναι απαριθµητού τύπου. Σε περίπτωση που µεταβλητή τύπου double χρησιµοποιείται ως µεταβλητή ελέγχου, η κοινή πρακτική είναι να έχει µόνο ακέραιο µέρος. /* άπειρος βρόχος */ int n; for (n =1; 1; n += 1) printf(″\n∆εν µπορώ να σταµατήσω!″); for (1; 1; 1) printf(″\n∆εν µπορώ να σταµατήσω!″); for (n =1; n = 10; n += 1)

printf(″\n∆εν µπορώ να σταµατήσω!″);

Page 7: Επανάληψη Εντολές while, for, do-whileepl131/spring02/documents/epl-notes7.pdf · 2002. 9. 4. · 1 Επανάληψη Εντολές while, for, do-while • Απροσδιόριστη

7

/* κενή εντολή */ for (n = 1; n == 10; n += 1) printf(″???″); for (0; 0; 0) printf(″???″); Παράδειγµα: Υπολογισµός του αθροίσµατος 1 + 2 + … + n int n, count, sum = 0; printf(″\nEnter limit: ″); scanf(″%d″, &n); for (count = 1; count <= n; count += 1) sum += count; printf(″\nThe sum is %d ″, sum); Παράδειγµα: Πρόγραµµα το οποίο εκτυπώνει 2x για x από το 1 µέχρι το 6.

#include <stdio.h> #define LIMIT 6

void main ( )

int count, res = 1; for (count = 1; count <= LIMIT; count += 1)

printf(″\n%1d%5d″, count, res); res = res * 2;

Page 8: Επανάληψη Εντολές while, for, do-whileepl131/spring02/documents/epl-notes7.pdf · 2002. 9. 4. · 1 Επανάληψη Εντολές while, for, do-while • Απροσδιόριστη

8

Παράδειγµα: Εναλλακτικοί Ορισµοί για Συναρτήσεις draw_square, draw_triA και draw_triD void draw_square(int size, char fill)

int row, col;

for (row = 1; row <= size; row += 1) putchar(′\n′); for (col = 1; col <= size; col += 1) putchar(fill);

void draw_triA(int size, char fill)

int row, col;

for (row = 1; row <= size; row += 1) putchar(′\n′); for (col = 1; col <= row; col += 1) putchar(fill);

for (col = row +1; col <= size; col += 1) putchar(′ ′);

void draw_triD(int size, char fill)

int row, col;

for (row = size; row > 0; row −= 1) putchar(′\n′); for (col = size; col > row; col −= 1) putchar(′ ′);

for (col = row; col > 0; col −= 1) putchar(fill);

Page 9: Επανάληψη Εντολές while, for, do-whileepl131/spring02/documents/epl-notes7.pdf · 2002. 9. 4. · 1 Επανάληψη Εντολές while, for, do-while • Απροσδιόριστη

9

Παράδειγµα: Εκτύπωση συγκεκριµένου αρχείου Αλγόριθµος 1. Ανοίγω το αρχείο 2. ∆ιαδοχικά διαβάζω και εκτυπώνω κάθε χαρακτήρα µέχρι να φτάσω στο τέλος του αρχείου

Σηµείωση: Η σταθερά EOF, η οποία ορίζεται στη βιβλιοθήκη stdio, είναι ένας αρνητικός αριθµός. Χρησιµοποιείται προς επισήµανση του τέλους κάποιου αρχείου. Μετάφραση αλγόριθµου µε χρήση while mycat.c $ cc –o mycat mycat.c $ mycat #include <stdio.h> void main ( ) char ch; FILE *inp; inp = fopen(″mycat.c″, ″r″); while (fscanf(inp, ″%c″, &ch) != EOF) putchar(ch);

#include <stdio.h> void main ( ) char ch; FILE *inp; inp = fopen(″mycat.c″, ″r″); while (fscanf(inp, ″%c″, &ch) != EOF) putchar(ch);

Page 10: Επανάληψη Εντολές while, for, do-whileepl131/spring02/documents/epl-notes7.pdf · 2002. 9. 4. · 1 Επανάληψη Εντολές while, for, do-while • Απροσδιόριστη

10

Μετάφραση αλγόριθµου µε χρήση for mycat.c $ cc –o mycat mycat.c $ mycat #include <stdio.h> void main ( ) char ch; FILE *inp; for (inp = fopen(″mycat.c″, ″r″); fscanf(inp, ″%c″, &ch) != EOF; putchar(ch)); • Η εντολή για το άνοιγµα του αρχείου αποτελεί την έκφραση αρχικοποίησης.

• Όπως και στην εκδοχή µε την εντολή while, και εδώ η συνθήκη επανάληψης κάνει χρήση της τιµής εξόδου της συνάρτησης fscanf, ενώ παράλληλα γίνεται η σάρωση του επόµενου χαρακτήρα

• Η εντολή για εκτύπωση του χαρακτήρα αποτελεί την έκφραση ενηµέρωσης.

• Η εντολή for δεν έχει σώµα.

#include <stdio.h> void main ( ) char ch; FILE *inp; for (inp = fopen(″mycat.c″, ″r″);

fscanf(inp, ″%c″, &ch) != EOF; putchar(ch));

Page 11: Επανάληψη Εντολές while, for, do-whileepl131/spring02/documents/epl-notes7.pdf · 2002. 9. 4. · 1 Επανάληψη Εντολές while, for, do-while • Απροσδιόριστη

11

Τελεστές για Αύξηση και Μείωση Τιµών (++, −−)

Increment and Decrement Operators count = count + 1; count += 1; ++count Ο τελεστής αύξησης, ++, λαµβάνει µία µοναδική µεταβλητή ως τον τελεστέο του. Το πλευρικό φαινόµενο της εφαρµογής του, είναι ότι η τιµή του τελεστέου του αυξάνεται κατά ένα. Συνήθως ο τελεστής χρησιµοποιείται απλά για αυτή την παρενέργεια, όπως στο παρακάτω παράδειγµα: for (count = 1; count <= n; ++count) sum += count; Η τιµή µίας έκφρασης στην οποία χρησιµοποιείται ο τελεστής ++, εξαρτάται από τη θέση του τελεστή: • Προ-σηµειογραφική αύξηση (prefix increment) – ο τελεστής προηγείται του τελεστέου, π.χ. ++count. Η τιµή της έκφρασης είναι η τιµή του τελεστέου µετά την αύξηση.

• Μετα-σηµειογραφική αύξηση (postfix increment) – ο τελεστής ακολουθεί τον τελεστέο, π.χ. count++. Η τιµή της έκφρασης είναι η τιµή του τελεστέου πριν την αύξηση.

Παροµοίως, ο τελεστής µείωσης, −−, λαµβάνει µία µοναδική µεταβλητή ως τελεστέο, η παρενέργεια της εφαρµογής του είναι η µείωση της τιµής του τελεστέου κατά ένα, ενώ παράλληλα επιστρέφεται η τιµή του τελεστέου µετά ή πριν τη µείωση, σύµφωνα µε το εάν χρησιµοποιείται προ- ή µετα- σηµειογραφική µείωση αντιστοίχως.

Page 12: Επανάληψη Εντολές while, for, do-whileepl131/spring02/documents/epl-notes7.pdf · 2002. 9. 4. · 1 Επανάληψη Εντολές while, for, do-while • Απροσδιόριστη

12

Παράδειγµα i j j = ++i; j = i++; προ-σηµειογραφική µετα-σηµειογραφική αύξηση: αύξηση: πρώτα αυξάνεται η i πρώτα χρησιµοποιείται και µετά χρησιµοποιείται η τιµή της i και µετά η τιµή της γίνεται η αύξηση i j i j Η χρήση των τελεστών ++ και −−, πρέπει να αποφεύγεται σε σύνθετες εκφράσεις όπου οι µεταβλητές στις οποίες εφαρµόζονται αυτοί οι τελεστές, εµφανίζονται περισσότερες από µία φορά. Οι µεταγλωττιστές της C εκµεταλλεύονται τις ιδιότητες της αντιµετάθεσης και προσεταιριστικότητας των τελεστών, µε στόχο την παραγωγή αποδοτικού κώδικα. x = 5; i = 2; y = i * x + ++i; Σε αυτό το παράδειγµα, είναι δυνατό να ανατεθεί είτε η τιµή 13 (2 * 5 + 3), είτε η τιµή 18 (3 * 5 + 3), στη µεταβλητή y. Εποµένως η ορθότητα του κώδικα δεν θα πρέπει να εξαρτάται από παρενέργειες οι οποίες ενδεχοµένως να διαφέρουν από υλοποίηση σε υλοποίηση της γλώσσας.

? 2

3 3 3 2

Page 13: Επανάληψη Εντολές while, for, do-whileepl131/spring02/documents/epl-notes7.pdf · 2002. 9. 4. · 1 Επανάληψη Εντολές while, for, do-while • Απροσδιόριστη

13

Παράδειγµα: Εναλλακτικός oρισµός της factorial int factorial (int x) int i, res = 1; for (i = x; i > 1; −−i) res = res * i; return res; Παράδειγµα: Επαναδιατύπωση της is_prime και επέκταση για να καλύπτει και την περίπτωση του 2 int is_prime (int n) int prime = n % 2 != 0, x = 3; while (prime && x * x <= n) prime = (n % x++) != 0; return n == 2 || prime; • Η τιµή της έκφρασης, x++, δηλαδή η τιµή της µεταβλητής x πριν την αύξηση, διοχετεύεται ως δεξιός τελεστέος του τελεστή %.

• Ως πλευρικό φαινόµενο η τιµή της x αυξάνεται κατά ένα. Η

µετα-σηµειογραφική αύξηση είναι αναγκαία σε αυτό τον ορισµό.

• Συγκεκριµένα η πρόταση prime = (n % x++) != 0 ερµηνεύεται ως ακολούθως (σηµειώνεται ότι οι παρενθέσεις σε αυτή την πρόταση δεν είναι αναγκαίες):

Έστω n x 17 % 3 ⇒ 2 x x = x + 1 2 != 0 ⇒ 1 prime = 1

17 3

4

Page 14: Επανάληψη Εντολές while, for, do-whileepl131/spring02/documents/epl-notes7.pdf · 2002. 9. 4. · 1 Επανάληψη Εντολές while, for, do-while • Απροσδιόριστη

14

Ορισµός µε χρήση της εντολής for

int is_prime (int n) int prime, x = 3; for (prime = n % 2 != 0; /* αρχικοποίηση */ prime && x * x <= n; /* συνθήκη επανάληψης */ prime = (n % x++) != 0); /* ενηµέρωση */ /* η for δεν έχει σώµα */ return n == 2 || prime; Ολόκληρο το πρόγραµµα για την εκτύπωση δεδοµένου πλήθους πρώτων αριθµών Η µεταβλητή current_prime είναι τοπική της main και η συνάρτηση get_prime έχει µία παράµετρο η οποία είναι δείκτης σε ακέραιο αριθµό.

#include <stdio.h> int get_prime (int *cp_add); void main () int count = 1, total, current_prime = 2; printf(″\nHow many primes? ″); scanf(″%d″, &total); while (count <= total) printf(″\n%d″, get_prime(&current_prime)); ++count; int is_prime (int n) int prime, x = 3; for (prime = n % 2 != 0; prime && x * x <= n; prime = (n % x++) != 0); return n == 2 || prime;

Page 15: Επανάληψη Εντολές while, for, do-whileepl131/spring02/documents/epl-notes7.pdf · 2002. 9. 4. · 1 Επανάληψη Εντολές while, for, do-while • Απροσδιόριστη

15

Επαναδιατύπωση της main µε χρήση της εντολής for void main () int count , total, current_prime = 2; printf(″\nHow many primes? ″); scanf(″%d″, &total); for (count = 1; count <= total; ++count) printf(″\n%d″, get_prime(&current_prime)); Επαναδιατύπωση της get_prime µε χρήση του τελεστή ++ (προ-σηµειογραφική αύξηση) int get_prime (int *cp_add) int res = *cp_add; ++ *cp_add; while (!is_prime(*cp_add)) ++ *cp_add; return res; Είναι ο ακόλουθος ορισµός στον οποίο χρησιµοποιείται µετα-σηµειογραφική αύξηση ισοδύναµος; int get_prime (int *cp_add) int res = *cp_add; *cp_add ++; while (!is_prime(*cp_add)) *cp_add ++; return res;

int get_prime (int *cp_add) int res = *cp_add; *cp_add = *cp_add + 1; while (!is_prime(*cp_add)) *cp_add = *cp_add + 1; return res;

Page 16: Επανάληψη Εντολές while, for, do-whileepl131/spring02/documents/epl-notes7.pdf · 2002. 9. 4. · 1 Επανάληψη Εντολές while, for, do-while • Απροσδιόριστη

16

Εκτέλεση προγράµµατος µε βάση τον τελευταίο ορισµό της get_prime $ primes How many primes? 5 2 2 2 2 2 Γιατί συµβαίνει το πιο πάνω; Ποιά είναι η ερµηνεία της έκφρασης *cp_add ++ Για να είναι ορθός ο ορισµός αυτή η έκφραση πρέπει να ερµηνεύεται ως (*cp_add)++ Επειδή όµως ο τελεστής ++ έχει υψηλότερη προτεραιότητα από τον τελεστή * (‘ακολούθα το δείκτη’), η έκφραση ερµηνεύεται ως *(cp_add++) cp_add current_prime ∆, η διεύθυνση του current_prime (*cp_add)++ *(cp_add++) cp_add current_prime cp_add current_prime

2 ∆

2 ∆+1 3 ∆

Page 17: Επανάληψη Εντολές while, for, do-whileepl131/spring02/documents/epl-notes7.pdf · 2002. 9. 4. · 1 Επανάληψη Εντολές while, for, do-while • Απροσδιόριστη

17

Εποµένως ποτέ δεν τροποποιείται η τιµή της current_prime. Η

µεταβλητή cp_add, που αποτελεί την παράµετρο της get_prime,

δηµιουργείται τοπικά της get_prime, εκ νέου για κάθε νέα

κλήση της get_prime. Έτσι το τι περιγράφεται στο πιο πάνω,

δεξιό σχήµα, επαναλαµβάνεται ξανά και ξανά.

Αυτό το πρόβληµα δεν υπάρχει σε σχέση µε την έκφραση

++ * cp_add

Εδώ υπάρχει µία και µοναδική ερµηνεία, ++(*cp_add)

Εναλλακτικός ορισµός της get_prime µε χρήση της εντολής for int get_prime (int *cp_add)

int res = *cp_add;

for ((*cp_add)++; /* αρχικοποίηση */

!is_prime(*cp_add); /* συνθήκη επανάληψης */

(*cp_add) ++); /* ενηµέρωση */

/* η for δεν έχει σώµα */

return res;

Page 18: Επανάληψη Εντολές while, for, do-whileepl131/spring02/documents/epl-notes7.pdf · 2002. 9. 4. · 1 Επανάληψη Εντολές while, for, do-while • Απροσδιόριστη

18

Oλόκληρο το πρόγραµµα µε χρήση εντολών for

Παράδειγµα: Εναλλακτικός ορισµός της sqrt double sqrt (double x) double y; for (y = x; !good_enough(x,y); y = next_approx(x,y)); return y;

#include <stdio.h> int get_prime (int *cp_add); void main () int count , total, current_prime = 2; printf(″\nHow many primes? ″); scanf(″%d″, &total); for (count = 1; count <= total; ++count) printf(″\n%d″, get_prime(&current_prime)); int is_prime (int n) int prime, x = 3; for (prime = n % 2 != 0; prime && x * x <= n; prime = (n % x++) != 0); return n == 2 || prime; int get_prime (int *cp_add) int res = *cp_add; for ((*cp_add)++; !is_prime(*cp_add); (*cp_add) ++); return res;

Page 19: Επανάληψη Εντολές while, for, do-whileepl131/spring02/documents/epl-notes7.pdf · 2002. 9. 4. · 1 Επανάληψη Εντολές while, for, do-while • Απροσδιόριστη

19

Εντολή do-while do S while (C); ναι όχι Σηµασιολογία Καταρχήν εκτελείται η εντολή S και µετά δοκιµάζεται η συνθήκη C. Ενόσω αυτή επαληθεύεται η εκτέλεση της εντολής S επαναλαµβάνεται. Εποµένως η S εκτελείται τουλάχιστο µία φορά. Προς αποφυγή βρόχου άπειρης διάρκειας, η διεργασία της S πρέπει να είναι τέτοια ούτως ώστε να επέλθει κάποια κατάσταση στην οποία η C να µην υφίσταται πλέον. do printf(″\n∆εν µπορώ να σταµατήσω!″); while (1); do printf(″\Θα σταµατήσω αµέσως!″); while (0); ≡ printf(″\Θα σταµατήσω αµέσως!″);

do εντολή while (συνθήκη) ;

S

C?

Page 20: Επανάληψη Εντολές while, for, do-whileepl131/spring02/documents/epl-notes7.pdf · 2002. 9. 4. · 1 Επανάληψη Εντολές while, for, do-while • Απροσδιόριστη

20

Η εντολή do-while είναι συνήθως η πιο κατάλληλη δοµή για τον έλεγχο εγκυρότητας δεδοµένων: do printf(″\nEnter values for A and B where A < B ″);

scanf(″%lf%lf″, &A, &B); while (A >= B); Παράδειγµα: Εισδοχή 10 αριθµών από το πεδίο [0.0, 10.0] και υπολογισµός του µέσου όρου αυτών των αριθµών int i; double sum = 0.0, num; for (i=1; i <= 10; ++i) do scanf(″%lf″, &num); while (num < 0.0 || num > 10.0); sum += num; printf(″\nThe average is %f ″, sum/10); Κοινά Λάθη • Σύγχυση ανάµεσα στις εντολές if και while:

if (συνθήκη) εντολή while (συνθήκη) εντολή

• Παράλειψη των παρενθέσεων γύρω από τις συνθήκες, αναφορικά µε τις εντολές while και do-while.

• Αναφορικά µε την εντολή for, παράλειψη του χαρακτήρα ;

µετά την έκφραση αρχικοποίησης και µετά την συνθήκη επανάληψης.

Page 21: Επανάληψη Εντολές while, for, do-whileepl131/spring02/documents/epl-notes7.pdf · 2002. 9. 4. · 1 Επανάληψη Εντολές while, for, do-while • Απροσδιόριστη

21

• Σε κάθε περίπτωση, το σώµα της επανάληψης θεωρείται ότι είναι µία και µοναδική εντολή. Κοινό λάθος είναι η παράλειψη των παρενθέσεων όταν το τι επαναλαµβάνεται είναι µία ακολουθία εντολών, π.χ.

while (x > x_big) x −= z; ++x_big; Σε αυτή την εντολή το σώµα της επανάληψης θεωρείται µόνο η εντολή x −= z; while (x > x_big) x −= z; ++x_big; Εδώ, η ακολουθία των δύο εντολών αποτελεί το σώµα της επανάληψης.

• Η χρήση του τελεστή για ανάθεση (=) αντί για του τελεστή για ισότητα (==), π.χ.

do . . . . . while (gain = 1); Εδώ οδηγούµαστε σε βρόχο άπειρης διάρκειας.

• if (συνθήκη1) do . . . . while (συνθήκη1);

θα πρέπει να απλοποιηθεί σε while (συνθήκη1) . . . . .

Page 22: Επανάληψη Εντολές while, for, do-whileepl131/spring02/documents/epl-notes7.pdf · 2002. 9. 4. · 1 Επανάληψη Εντολές while, for, do-while • Απροσδιόριστη

22

• Η χρήση των τελεστών ++, −−, και σύνθετης ανάθεσης πρέπει να αποφεύγεται σε σχέση µε σύνθετες εκφράσεις.

• Επίσης η χρήση του τελεστή για µη ισότητα αναφορικά µε

µεταβλητές τύπου double πρέπει να αποφεύγεται, π.χ.

while (balance != 0.0) . . . . . Αυτή η συνθήκη πολύ πιθανώς να οδηγήσει σε βρόχο άπειρης διάρκειας, απλά επειδή µπορεί να µην τύχει να καταχωρηθεί επακριβώς η τιµή 0.0 στη µεταβλητή balance. while (balance > 0.0) . . . . . Εδώ αποφεύγεται ο βρόχος, νοουµένου ότι η τιµή της balance δεν παραµένει επί µονίµου βάσεως κάποιος θετικός αριθµός.

• Παρερµήνευση των σύνθετων τελεστών ανάθεσης

Μ τ= Ε σηµαίνει Μ = Μ τ (Ε) δεν σηµαίνει Μ = Μ τ Ε

Οι παρενθέσεις δηλαδή γύρω από την έκφραση Ε που αποτελεί τον δεξιό τελεστέο αποτελούν αναγκαίο στοιχείο. Εποµένως a *= b + c; σηµαίνει a = a * (b + c); και όχι a = a * b + c; ≡ a = (a * b) + c; ∆εν υπάρχει συντοµογραφία για αυτή την πρόταση. a *= b; a += c;

Page 23: Επανάληψη Εντολές while, for, do-whileepl131/spring02/documents/epl-notes7.pdf · 2002. 9. 4. · 1 Επανάληψη Εντολές while, for, do-while • Απροσδιόριστη

23