Επανάληψη. Εντολές while, for, do-while

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

Συναρτήσεις. Κατασκευαστικά Τεµάχια για τη ηµιουργία Αρθρωτών Προγραµµάτων

Η τιµή εξόδου κάποιας συνάρτησης µπορεί να είναι δείκτης, π.χ.

Αλγοριθμικές Δομές Επιλογής και Επανάληψης Συνθήκες, Λογικές Εκφράσεις και Βρόγχοι

Επανάληψη για τις Τελικές εξετάσεις. (Διάλεξη 24) ΕΠΛ 032: ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ ΜΕΘΟΔΩΝ ΕΠΙΛΥΣΗΣ ΠΡΟΒΛΗΜΑΤΩΝ

οµές Επιλογής Εντολές if και switch

Επανάληψη για τις Τελικές εξετάσεις

Κεφάλαιο : Επαναλήψεις (oι βρόγχοιfor, do-while) (Διάλεξη 10) Εντολές Επανάληψης που θα καλυφθούν σήμερα

Εισαγωγή στον Προγραμματισμό

Επεξεργασία Αρχείων Κειµένου

Στόχοι και αντικείμενο ενότητας. Προτάσεις επανάληψης. Έλεγχος ροής προγράμματος. #5.. Εντολές Επανάληψης

Να εκτυπωθούν οι πρώτες Ν σειρές του τριγώνου, χρησιµοποιώντας ένα πίνακα µεγέθους Ν στοιχείων (η Ν-οστή σειρά περιέχει Ν στοιχεία).

Η Γλώσσα C Μία Σφαιρική Ανασκόπηση

Εισαγωγή στην C. Μορφή Προγράµµατος σε γλώσσα C

Κεφάλαιο : Επαναλήψεις (for, do-while)

Στόχοι και αντικείμενο ενότητας. Εκφράσεις. Η έννοια του τελεστή. #2.. Εισαγωγή στη C (Μέρος Δεύτερο) Η έννοια του Τελεστή

Εισαγωγή στον Προγραµµατισµό. Διάλεξη 3 η : Επίλυση Προβληµάτων Χειµερινό Εξάµηνο 2011

ΤΕΜ-101 Εισαγωγή στους Η/Υ Εξεταστική Ιανουαρίου 2011 Θέματα Β

Εισαγωγή στον Προγραμματισμό

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

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

Εισαγωγή στον Προγραμματισμό

Κεφάλαιο : Επαναλήψεις (o βρόγχος While) (Διάλεξη 9) Δομές Έλεγχου Προγράμματος

Ασκήσεις σε Επαναληπτικούς Βρόχους και Συναρτήσεις. Επανάληψη για την ενδιάμεση εξέταση. (Διάλεξη 13)

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

ΕΝΤΟΛΕΣ ΕΠΑΝΑΛΗΨΗΣ. for (παράσταση_1; παράσταση_2; παράσταση_3) εντολή επόμενη εντολή

Εισαγωγή στον Προγραμματισμό

Μεθόδων Επίλυσης Προβλημάτων

Ο πιο κάτω πίνακας περιγράφει σε ποιες περιπτώσεις χρησιμοποιούμε τους τρεις πιο πάνω τρόπους:

Προγραμματισμός Η/Υ. Ενότητα 5: Εντολές Επανάληψης

Α. unsigned int Β. double. Γ. int. unsigned char x = 1; x = x + x ; x = x * x ; x = x ^ x ; printf("%u\n", x); Β. unsigned char

Κεφάλαιο 8.7. Πίνακες & Συναρτήσεις ( ιάλεξη 17) ιδάσκων: ηµήτρης Ζεϊναλιπούρ

Προγραμματισμός Η/Υ (ΤΛ2007 )

Προγραμματισμός Η/Υ (ΤΛ2007 )

Εισαγωγή στον Προγραµµατισµό. Διάλεξη 2 η : Βασικές Έννοιες της γλώσσας προγραµµατισµού C Χειµερινό Εξάµηνο 2011

Προγραμματισμό για ΗΜΥ

Ανάπτυξη Μεγάλων Εφαρµογών στη Γλώσσα C (2)

Ανάπτυξη και Σχεδίαση Λογισμικού

Υπολογισμός - Εντολές Επανάληψης

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

Συναρτήσεις. Εισαγωγή

Προγραμματισμός Ι (HY120)

Διάλεξη 3η: Τύποι Μεταβλητών, Τελεστές, Είσοδος/Έξοδος

ΗΥ-150. Προγραµµατισµός. Εντολές Ελέγχου Ροής

Εισαγωγή στην γλώσσα προγραμματισμού C

ΤΕΧΝΟΛΟΓΙΑ ΚΑΙ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ ΥΠΟΛΟΓΙΣΤΩΝ ΠΑΝΕΠΙΣΤΗΜΙΟ ΠΑΤΡΩΝ ΠΟΛΥΤΕΧΝΙΚΗ ΣΧΟΛΗ ΤΜΗΜΑ ΜΗΧΑΝΙΚΩΝ Η/Υ ΚΑΙ ΠΛΗΡΟΦΟΡΙΚΗΣ

Δοκιμή και Αποσφαλμάτωση Testing and Debugging

Κεφάλαιο VΙ: Προσπέλαση Αρχείων. 5.1 Αρχεία δεδομένων.

ΕΙΣΑΓΩΓΗ ΣΤΟΝ ΔΟΜΗΜΕΝΟ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟ

Κεφάλαιο 4: Συνθήκες Έλεγχου (if-else, switch) και Λογικοί τελεστές / παραστάσεις. (Διάλεξη 8)

Π. Σταθοπούλου ή Οµάδα Α (Φοιτητές µε µονό αριθµό Μητρώου ) ιδασκαλία : Παρασκευή 11πµ-13µµ ΗΛ7

Μεθόδων Επίλυσης Προβλημάτων

Ανάπτυξη και Σχεδίαση Λογισμικού

Δείκτες (Pointers) Ένας δείκτης είναι μια μεταβλητή με τιμή μια διεύθυνση μνήμης. 9.8

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

Προγραμματισμός Ι (ΗΥ120)

Προγραμματισμός Η/Υ (ΤΛ2007 )

Βαθμός Σχόλια. lab5 PASS PASS PASS PASS PASS. Οριακά PASS - Καλή δουλειά

Προγραμματισμός Ι. Θεματική ενότητα 3: Tελεστές. εκφράσεις

ΕΙΣΑΓΩΓΗ ΣΤΟ ΔΟΜΗΜΕΝΟ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟ

ΠΑΝΕΠΙΣΤΗΜΙΟ ΚΥΠΡΟΥ ΕΠΛ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ ΜΕΘΟΔΩΝ ΕΠΙΛΥΣΗΣ ΠΡΟΒΛΗΜΑΤΩΝ

Κεφάλαιο 2.6: Είσοδος / Έξοδος εδοµένων, Μορφοποίηση εδοµένων Εξόδου. ( ιάλεξη 7) ιδάσκων: ηµήτρης Ζεϊναλιπούρ

Κεφάλαιο , 3.2: Συναρτήσεις II. ( ιάλεξη 12) ιδάσκων: ηµήτρης Ζεϊναλιπούρ

Κεφάλαιο 6: Συναρτήσεις IΙΙ Αρθρωτός Προγραμματισμός. Δείκτες (Διάλεξη 14)

Διάλεξη 5η: Εντολές Επανάληψης

Προγραμματισμός Η/Υ. Ενότητα 2β: Εισαγωγή στη C (Μέρος Δεύτερο)

ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ Η/Υ Ακαδημαϊκό έτος ΤΕΤΡΑΔΙΟ ΕΡΓΑΣΤΗΡΙΟΥ #4

Προγραμματισμός Η/Υ (ΤΛ2007 )

Πίνακες. Οι πίνακες αποτελούν ένα σηµαντικό δοµηµένο τύπο δεδοµένων (structured data type) ή πιο απλά µία δοµή δεδοµένων (data structure).

Η Γλώσσα Προγραμματισμού C (Μέρος 2 - Οι Bασικές Εντολές της C) Οι Βασικοί Τελεστές της C

ΗΥ-150. Προγραμματισμός

9. Εντολές επανάληψηςκαι η εντολή

Εισαγωγή στον Προγραμματισμό

Γλώσσα Προγραμματισμού C. Προγραμματισμός HY: Γλώσσα Προγραμματισμού C. Γρήγορος Πίνακας Αναφοράς Σύνταξης. Εισήγηση #4. Επαναληπτικές δομές:

Μεθόδων Επίλυσης Προβλημάτων

Προγραμματισμό για ΗΜΥ

Στόχοι και αντικείμενο ενότητας. Βασικές κατασκευές ΓΠ. Έλεγχος ροής προγράμματος. #4.. Εντολές Επιλογής

10. Εντολές επανάληψηςκαι οι εντολές

Κεφάλαιο : Επαναλήψεις (oι βρόχος While) ( ιάλεξη 9) ιδάσκων: ηµήτρης Ζεϊναλιπούρ

ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ ΥΠΟΛΟΓΙΣΤΩΝ & ΥΠΟΛΟΓΙΣΤΙΚΗ ΦΥΣΙΚΗ

Προγραμματισμός Ι (ΗΥ120)

Δομημένος Προγραμματισμός

Βαθμός Σχόλια. lab PASS 1194 PASS 1238 PASS 1239 PASS

scanf() scanf() stdin scanf() printf() int float double %lf float

Δομημένος Προγραμματισμός (ΤΛ1006)

Δομημένος Προγραμματισμός (ΤΛ1006)

Προγραμματισμός Ι (ΗΥ120)

Προγραμματισμός Ι (ΗΥ120)

Διάλεξη 6: Δείκτες και Πίνακες

Στην ενότητα αυτή θα µελετηθούν τα εξής επιµέρους θέµατα: ΕΠΛ 131 Αρχές Προγραµµατισµού I 4-2

ιαδικαστικός Προγραμματισμός

ΤΕΧΝΟΛΟΓΙΑ ΚΑΙ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ ΥΠΟΛΟΓΙΣΤΩΝ ΠΑΝΕΠΙΣΤΗΜΙΟ ΠΑΤΡΩΝ ΠΟΛΥΤΕΧΝΙΚΗ ΣΧΟΛΗ ΤΜΗΜΑ ΜΗΧΑΝΙΚΩΝ Η/Υ ΚΑΙ ΠΛΗΡΟΦΟΡΙΚΗΣ

Κεφάλαιο , 3.2: Συναρτήσεις II. (Διάλεξη 12)

Τμήμα Πληροφορικής & Επικοινωνιών Δρ. Θεόδωρος Γ. Λάντζος

ΗΥ-150. Προγραμματισμός

5. ΒΡΟΧΟΙ ΕΠΑΝΑΛΗΨΗΣ (Β' μέρος: while - do..while)

Διαδικαστικός Προγραμματισμός

Περαιτέρω για Συναρτήσεις

Οικονόμου Βαγγέλησ Διάλεξη Νο 2. Δομημένοσ Προγραμματιςμόσ - Διάλεξη 2

Δείκτες (Pointers) Ένας δείκτης είναι μια μεταβλητή με τιμή μια διεύθυνση μνήμης. 9.8

Transcript:

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

Εποµένως για να µην υπάρξει βρόχος άπειρης διάρκειας (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); 2

Παράδειγµα: Πρόγραµµα το οποίο παράγει τα ακόλουθα: 0 1 1 2 2 4 3 8 4 16 5 32 6 64 x 2 x #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; µεταβλητή τελεστής= έκφραση; Σηµασιολογία: µεταβλητή = µεταβλητή τελεστής (έκφραση); Σύνθετοι τελεστές: +=, =, *=, /=, %= 3

Απλή Ανάθεση Σύνθετη Ανάθεση 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 (έκφραση-αρχικοποίησης ; συνθήκη ; έκφραση-ενηµέρωσης) εντολή 4

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

Η επανάληψη ελέγχεται από µία µεταβλητή η οποία ονοµάζεται µεταβλητή ελέγχου (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 εν µπορώ να σταµατήσω! ); 6

/* κενή εντολή */ 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); Παράδειγµα: Πρόγραµµα το οποίο εκτυπώνει 2 x για 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; 7

Παράδειγµα: Εναλλακτικοί Ορισµοί για Συναρτήσεις 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); 8

Παράδειγµα: Εκτύπωση συγκεκριµένου αρχείου Αλγόριθµος 1. Ανοίγω το αρχείο 2. ιαδοχικά διαβάζω και εκτυπώνω κάθε χαρακτήρα µέχρι να φτάσω στο τέλος του αρχείου Σηµείωση: Η σταθερά EOF, η οποία ορίζεται στη βιβλιοθήκη stdio, είναι ένας αρνητικός αριθµός. Χρησιµοποιείται προς επισήµανση του τέλους κάποιου αρχείου. Μετάφραση αλγόριθµου µε χρήση while #include <stdio.h> void main ( ) { char ch; FILE *inp; inp = fopen( mycat.c, r ); while (fscanf(inp, %c, &ch)!= EOF) putchar(ch); 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); 9

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

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

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

Παράδειγµα: Εναλλακτικός 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 17 % 3 2 x x = x + 1 2!= 0 1 4 prime = 1 13

Ορισµός µε χρήση της εντολής 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; 14

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; Επαναδιατύπωση της 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; 15

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

Εποµένως ποτέ δεν τροποποιείται η τιµή της 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; 17

Oλόκληρο το πρόγραµµα µε χρήση εντολών for #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; Παράδειγµα: Εναλλακτικός ορισµός της sqrt double sqrt (double x) { double y; for (y = x;!good_enough(x,y); y = next_approx(x,y)); return y; 18

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

Η εντολή 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, παράλειψη του χαρακτήρα ; µετά την έκφραση αρχικοποίησης και µετά την συνθήκη επανάληψης. 20

Σε κάθε περίπτωση, το σώµα της επανάληψης θεωρείται ότι είναι µία και µοναδική εντολή. Κοινό λάθος είναι η παράλειψη των παρενθέσεων { όταν το τι επαναλαµβάνεται είναι µία ακολουθία εντολών, π.χ. 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 ) {..... 21

Η χρήση των τελεστών ++,, και σύνθετης ανάθεσης πρέπει να αποφεύγεται σε σχέση µε σύνθετες εκφράσεις. Επίσης η χρήση του τελεστή για µη ισότητα αναφορικά µε µεταβλητές τύπου 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; 22

23