Η Υ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ Εργαστήριο 5 Εντολές Επανάληψης for while do while Λαμπρινίδης Γεώργιος lamprinidis@pharm.uoa.gr
Εντολές Επανάληψης Οι εντολές επανάληψης ανήκουν στην κατηγορία των εντολών που επηρεάζουν τη ροή του ελέγχου στα προγράμματα (όπως οι if και switch-case) Οι εντολές αυτές είναι: while do-while for 2
Άσκηση Προηγούμενου Εργαστηρίου #include <stdio.h> main () { int danger=0; int x1,x2,x3,x4,x5; double a1,a2,b1,b2; int x0; prini("dwse onomaslki aksia se mg\n"); scanf("%d",&x0); a1=x0*1.20; prini("%lf\n",a1); a2=x0*0.8; prini("%lf\n",a2); b1=x0*1.1; prini("%lf\n",b1); b2=x0*0.9;α prini("%lf\n",b2); prini("dwse onomaslki baros se mg 1ou Diskiou\n"); /* ****************** */ 3
...συνέχεια scanf("%d",&x1); if (x1>a1 x1<a2) { prini("molis katestrepses ln parlda 1\n"); if (x1>b1 x1<b2) { danger++; prini("i danger einai %d\n",danger); if (danger>=2) prini("molis katestrepses ln parlda 2\n"); prini("dwse onomaslki baros se mg 1ou Diskiou\n"); /* ****************** */ scanf("%d",&x2); if (x2>a1 x2<a2) { prini("molis katestrepses ton parlda 1\n"); if (x2>b1 x2<b2) { danger++ ; prini("i danger einai %d\n",danger); if (danger>2) prini("molis katestrepses ln parlda 2\n"); prini("dwse onomaslki baros se mg 1ou Diskiou\n"); 4
...συνέχεια /* ****************** */ scanf("%d",&x3); if (x3>a1 x3<a2) { prini("molis katestrepses ton parlda 1\n"); if (x3>b1 x3<b2) { danger++; prini("i danger einai %d\n",danger); if (danger>2) prini("molis katestrepses ln parlda 2\n"); prini("dwse onomaslki baros se mg 1ou Diskiou\n"); /* ****************** */ scanf("%d",&x4); if (x4>a1 x4<a2) { prini("molis katestrepses ton parlda 1\n"); if (x4>b1 x4<b2) { danger++ ; prini("i danger einai %d\n",danger); if (danger>2) prini("molis katestrepses ln parlda 2\n"); prini("dwse onomaslki baros se mg 1ou Diskiou\n"); 5
...συνέχεια /* ****************** */ scanf("%d",&x5); if (x5>a1 x5<a2) { prini("molis katestrepses ton parlda 1\n"); if (x5>b1 x5<b2) { danger++ ; prini("i danger einai %d\n",danger); if (danger>=2) prini("molis katestrepses ln parlda 2\n"); 6
Εντολές Επανάληψης while Η σύνταξη της εντολής while είναι: while (<παράσταση>) <μπλοκ εντολών> <επόμενη εντολή> Εξήγηση: Αρχικά υπολογίζεται η <παράσταση>. Αν έχει τιμή διάϕορη του μηδενός (είναι αληθής) εκτελείται το <μπλοκ εντολών>. Υπολογίζεται πάλι η <παράσταση> και ενόσω είναι αληθής, θα γίνεται ο κύκλος εκτέλεσης του <μπλοκ εντολών>, μέχρι να γίνει η <παράσταση> ψευδής (δηλαδή ίση με το μηδέν). Όταν η παράσταση γίνει ψευδής, εκτελείται η επόμενη εντολή 7
Λογικό Διάγραμμα του while Παράσταση Επόµενη Εντολή Ψευδής Αληθής Μπλοκ Εντολών 8
Παράδειγμα στo while (1) int i = 10; while(i >= 0){ prini( i >= 0 ); i--; Πόσες φορές θα εκτυπωθεί το μήνυμα i >= 0; 9
Παράδειγμα στo while (2) int i = 10; while(i >= 0){ prini( i >= 0 ); Πόσες φορές θα εκτυπωθεί το μήνυμα i >= 0; 10
Παράδειγμα στo while (3) int i = -1; while(i >= 0){ prini( i >= 0 ); i--; Πόσες φορές θα εκτυπωθεί το μήνυμα i>=0; 11
Τι πρέπει να προσέχουμε στο while (1) Προσοχή! Θα πρέπει να προσέχουμε η συνθήκη που υπάρχει μέσα στο while να γίνεται κάποια στιγμή ψευδής έτσι ώστε να προχωράει το πρόγραμμα στις επόμενες εντολές. Διαφορετικά, θα έχουμε ατέρμονη επανάληψη όπως στο προηγούμενο παράδειγμα. 12
Τι πρέπει να προσέχουμε στο while (2) Ένας απλός τρόπος που μπορούμε να χρησιμοποιούμε το while και με τον οποίο αποφεύγουμε την ατέρμονη επανάληψη (αλλά δεν λύνει πάντα όλα τα προβλήματα) είναι ο ακόλουθος: Πριν το while ορίζουμε και αρχικοποιούμε τη μεταβλητή που θα παίρνει μέρος στη συνθήκη του while. π.χ. int i = 10; Μέσα στο while ελέγχουμε το αν αληθεύει ή όχι η παράσταση. π.χ. while(i >= 0) Σε περίπτωση που είναι αληθής η παράσταση, τότε μέσα στο μπλοκ εντολών του while αλλάζουμε την τιμή της μεταβλητής που παίρνει μέρος στη συνθήκη του while. π.χ. i--; 13
Εντολή Επανάληψης do while Η σύνταξη της εντολής do-while είναι: do <μπλοκ εντολών> while (<παράσταση>) <επόμενη εντολή> Εξήγηση: Αρχικά εκτελείται το <μπλοκ εντολών>. Μετά, υπολογίζεται η <παράσταση>. Αν έχει τιμή διάϕορη του μηδενός (είναι αληθής) εκτελείται πάλι το <μπλοκ εντολών> και συνεχίζεται ο κύκλος εκτέλεσής του, μέχρι να γίνει η <παράσταση> ψευδής (δηλαδή ίση με το μηδέν). Όταν γίνεται ψευδής, τότε εκτελείται η επόμενη εντολή 14
Το λογικό διάγραμμα του do while Μπλοκ Εντολών Ψευδής Παράσταση Αληθής Επόµενη Εντολή 15
Παράδειγμα do while (1) int i = 10; do{ prini( i >= 0 ); i--; while(i >= 0); Πόσες φορές θα εκτυπωθεί το μήνυμα i >= 0; 16
Παράδειγμα do while (2) int i = 10; do{ prini( i >= 0 ); while(i >= 0); Πόσες φορές θα εκτυπωθεί το μήνυμα i >= 0; 17
Παράδειγμα do while (3) int i = -1; do{ prini( i >= 0 ); i--; while(i >= 0); Πόσες φορές θα εκτυπωθεί το μήνυμα i >= 0; 18
Διαφορές μεταξύ while και do while Η βασική διαϕορά των while και do-while είναι ότι στην πρώτη περίπτωση το <μπλοκ εντολών> μπορεί και να μην εκτελεσθεί καμία ϕορά, αν η <παράσταση> είναι αρχικά ψευδής, ενώ στην εκδοχή do/while, το <μπλοκ εντολών> θα εκτελεσθεί τουλάχιστον μία ϕορά, αϕού η <παράσταση> ελέγχεται στο τέλος 19
Εντολή Eπανάληψης for Η σύνταξη της εντολής for είναι: for (<παράσταση1> ; <παράσταση2> ; <παράσταση3>) <μπλοκ εντολών> <επόμενη εντολή> Εξήγηση: αρχικά υπολογίζεται η <παράσταση1>. Συνήθως, πρόκειται για την αρχικοποίηση μίας μεταβλητής που ελέγχει μία επαναληπτική διαδικασία. Στη συνέχεια, εκτελείται επαναλαμβανόμενα το <μπλοκ εντολών>, που αποτελεί το σώμα της διαδικασίας, ενόσω η <παράσταση2>, που συνήθως ελέγχει την τιμή της μεταβλητής ελέγχου, είναι αληθής. Πριν τη διεξαγωγή νέας επανάληψης, εκτελείται και η <παράσταση3>, που συνήθως μεταβάλλει τη μεταβλητή ελέγχου. Όταν η <παράσταση2> γίνει ψευδής, τότε εκτελείται η επόμενη εντολή. 20
Λογικό Διάγραμμα της for Παράσταση 1 Παράσταση 3 Παράσταση 2 Ψευδής Αληθής Μπλοκ Εντολών Επόµενη Εντολή 21
Ισοδυναμία μεταξύ for while Διαδικαστικά, το for (<παράσταση1> ; <παράσταση2> ; <παράσταση3>) <μπλοκ εντολών> <επόμενη εντολή> ισοδυναμεί με: <παράσταση1>; while (<παράσταση2>) { <μπλοκ εντολών> <παράσταση3>; <επόμενη εντολή> 22
Παράδειγμα στο for (1) for(i = 10; i >= 0; i--) prini( i >= 0 ); Πόσες φορές θα εκτυπωθεί το μήνυμα i >= 0; for(i = 0; i <= 10; i++) prini( i >= 0 ); Πόσες φορές θα εκτυπωθεί το μήνυμα i >= 0; 23
Παράδειγμα στο for (2) for(i = -1; i > 0; i--) prini( i > 0 ); Πόσες φορές θα εκτυπωθεί το μήνυμα i >0; for(i = 0; i > 0; i--) prini( i > 0 ); Πόσες φορές θα εκτυπωθεί το μήνυμα i > 0; 24
Ατέρμονη Επανάληψη Σπάνια, υπάρχει η περίπτωση να θέλουμε η επανάληψη να μην τερματίζει ποτέ, δηλαδή να μη μεταφερόμαστε ποτέ στην <επόμενη εντολή>. Παράδειγμα ατέρμονης επανάληψης στο while: while(1) prini( Hello forever ); Παράδειγμα ατέρμονης επανάληψης στο for: for( ; ; ) prini( Hello forever ); 25
Η εντολή break Μία χρήση της εντολής break είναι αυτή που είδαμε στην εντολή switch, για τον τερματισμό της ακολουθίας εντολών που θα εκτελεσθούν όταν ταιριάξει κάποια συγκεκριμένη case. Επίσης, με την εντολή break, μπορούμε να τερματίσουμε βιαίως τις επαναλήψεις ενός βρόχου (while, do/while ή for), πριν ισχύσει η συνθήκη τερματισμού (ή όταν ο βρόχος είναι ατέρμων). Παράδειγμα: for(i = 0; i > 0; i--){ prini( i > 0 ); break; 26
Επιλυση της άσκησης ομοιομορφίας δισκίων με χρήση εντολών επανάληψης #include <stdio.h> main () { int danger=0; int x1,i; double a1,a2,b1,b2; int x0; prini("dwse mesi lmi barous diskiou se mg\n"); scanf("%d",&x0); if (x0<100) { a1=x0*1.20; prini("%lf\n",a1); a2=x0*0.8; prini("%lf\n",a2); b1=x0*1.1; prini("%lf\n",b1); b2=x0*0.9; prini("%lf\n",b2); if (x0>=100 x0<300) { a1=x0*1.15; prini("%lf\n",a1); a2=x0*0.85; prini("%lf\n",a2); b1=x0*1.075; prini("%lf\n",b1); b2=x0*0.925; prini("%lf\n",b2); if (x0>300) { a1=x0*1.10; prini("%lf\n",a1); a2=x0*0.90; prini("%lf\n",a2); b1=x0*1.05; prini("%lf\n",b1); b2=x0*0.95; prini("%lf\n",b2); for(i=1;i<=5;i++) { prini("dwse onomaslki baros se mg 1ou Diskiou\n"); scanf("%d",&x1); if (x1>a1 x1<a2) { prini("molis katestrepses ln parlda 1\n"); break; if (x1>b1 x1<b2) { danger++; prini("i danger einai %d\n",danger); if (danger>=2) { prini("molis katestrepses ln parlda 2\n"); break; prini("telos\n"); 27
Πρόβλημα 1 Γράψτε ένα πρόγραμμα που να υπολογίζει και να τυπώνει το αποτέλεσμα του αθροίσματος 1+2+3+ +n για δεδομένο n. Λύστε το πρόβλημα αρχικά με τη χρήση while, μετά με do-while, και τέλος με for. Γράψτε ένα πρόγραμμα που να υπολογίζει και να τυπώνει το αποτέλεσμα του γινομένου 1*2*3* *n για δεδομένο n. Λύστε το πρόβλημα με όποια εντολή προτιμάτε. 28
Πρόβλημα 1 #include <stdio.h> main () { int a,i,sum=0; prini("dwse akeraio aritho n na ypologisw to 1+2+3+4+...n\n"); scanf("%d",&a); for (i=1;i<=a;i++) { sum=sum+i; prini("to athroisma 1+2+3+4+...n einai %d\n",sum); 29
Πρόβλημα 2 #include <stdio.h> main () { int a,i,ginomeno=1; prini("dwse akeraio aritho n na ypologisw to 1*2*3*4*...*n\n"); scanf("%d",&a); for (i=1;i<=a;i++) { ginomeno=ginomeno*i; prini("to ginomeno 1*2*3*4*...*n einai %d\n",sum); 30
Πρόβλημα 3 Γράψτε ένα πρόγραμμα που να διαβάζει από το πληκτρολόγιο θετικούς αριθμούς και να τους εκτυπώνει. Το πρόγραμμα να τερματίζει όταν δοθεί σαν είσοδος αρνητικός αριθμός. Ποια από τις επαναληπτικές δομές θα χρησιμοποιήσετε; 31
Πρόβλημα 3 #include<stdio.h> main() { int a; do { prini( Dwse akeraio arithmo ); scanf("%d",&a); if (a<=0) { break; prini("%d\n",a); while (a>=0); prini("telos\n"); 32