Download as pptx, pdf, or txt
Download as pptx, pdf, or txt
You are on page 1of 91

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

Ενότητα 5
Περιεχόμενα
• Εκτέλεση υπό όρους, εντολή if, if-else
• Επαναληπτικές εντολές
– while, do-while, for
• Επανάληψη, μετρητές
• Πολλαπλοί μετρητές
• Μη ακέραιοι μετρητές
• Φωλιασμένες επαναλήψεις
Τύποι Δηλώσεων στη Java
• Τα προγράμματα στην Java αποτελούνται από ένα σύνολο
τάξεων. Αυτές οι τάξεις περιλαμβάνουν μεθόδους, και κάθε
μία από αυτές αποτελείται από μια αλληλουχία δηλώσεων.
• Οι δηλώσεις στην Java χωρίζονται σε 3 βασικές κατηγορίες :
– Απλές δηλώσεις
– Συνθετες δηλώσεις
– Δηλώσεις ελέγχου
• Οι απλές δηλώσεις σχηματίζονται με την προσθήκη ενός
ερωτηματικού στο τέλος μιας έκφρασης Java.
• Οι σύνθετες δηλώσεις (ονομαζόμενες και blocks)
αποτελούνται από μια ακολουθία εκφρασεων μεσα σε
άγκιστρα.
• Οι δηλώσεις ελέγχου χωρίζονται σε 2 κατηγορίες :
– Υπό όρους δηλώσεις που ορίζουν κάποιου είδους τεστ
– Επαναληπτικές δηλώσεις που καθορίζουν επανάληψεις
Δηλώσεις ελέγχου και επίλυση προβλημάτων
• Πριν την λεπτομερή εξέταση των επιμέρους δηλώσεων
ελέγχου, θα εξετάσουμε ολιστικά ένα ζευγάρι
προγραμμάτων που κάνουν χρήση κοινών προτύπων
ελέγχου.
• Οι επόμενες διαφάνειες επεκτείνουν το πρόγραμμα
Add2Integers από το κεφάλαιο 2 για τη δημιουργία
προγραμμάτων που προσθέτουν μεγαλύτερες λίστες. Οι
διαφάνειες απεικονίζουν τρεις διαφορετικές στρατηγικές:
– Την προσθήκη νέου κώδικα για την επεξεργασία κάθε τιμής εισόδου
– Την επανάληψη του κύκλου εισόδου έναν προκαθορισμένο αριθμό
φορών
– Την επανάληψη του κύκλου εισόδου έως ότου ο χρήστης εισάγει μια
ειδική τιμή φρουρό
Το Πρόγραμμα Add4Integers
• Αν δεν έχετε πρόσβαση σε δηλώσεις ελέγχου, ο μόνος
τρόπος που μπορεί να αυξήσει τον αριθμό των τιμών των
εισόδων είναι να προσθέσετε μια νέα δήλωση για κάθε μία,
όπως στο ακόλουθο παράδειγμα:
public class Add4Integers extends ConsoleProgram {
public void run() {
println("This program adds four numbers.");
int n1 = readInt("Enter n1: ");
int n2 = readInt("Enter n2: ");
int n3 = readInt("Enter n3: ");
int n4 = readInt("Enter n4: ");
int total = n1 + n2 + n3 + n4;
println("The total is " + total + ".");
}
}

• Η στρατηγική αυτή, ωστόσο, είναι δύσκολο να γενικευθεί και


θα ήταν σαφώς βαρετή αν χρειάζεται να προσθέσετε 100
τιμές.
Ο τρόπος Repeat-N-Times
Ένας τρόπος για την λύση του προβλήματος είναι η χρήση του
ιδιώματος Repeat-Ν-Times, που εκτελεί μια σειρά δηλώσεων
ένα καθορισμένο αριθμό φορών. Η γενική μορφή του ιδιώματος
είναι
for
for (int
(inti i= =0;0;i i < repetitions; i++) {
< repetitions; i++) {
statements to be repeated
statements to be repeated
}
}

Όπως
Η ισχύει γιαγια
πληροφορία όλα
τοντααριθμό
μοτίβα των
σε αυτό το βιβλίο, καθορίζεται
επαναλήψεων οι λέξεις με
πλάγιους
από χαρακτήρες
την πρώτη γραμμή,δείχνουν
η οποίαταονομάζεται
μέρη του σχεδίου θα πρέπει να
και κεφαλίδα.
αλλάξετε
Οι δηλώσειςγιαπου
κάθεπρέπει
εφαρμογή. Για να χρησιμοποιήσετε
να επαναληφθούν ονομάζονταιαυτόσώματο
πρότυπο,
της δήλωσηςγιαforπαράδειγμα,
και είναι σε θα πρέπει
εσοχή να αντικαταστήσετε
σε σχέση με την κεφαλίδα. το
repetitions με μια έκφραση που δίνει τον αριθμό των
επαναλήψεων
Μια δήλωση και να περιλαβετε
ελέγχου τις δηλώσειςένα
που επαναλαμβάνει πουτμήμα
πρέπειτου
να
επαναληφθουν
κώδικα μέσα σταβρόχος
που ονομάζεται άγκιστρα..
Κάθε εκτέλεση του σώματος ενός βρόχου ονομάζεται κύκλος.
Το Πρόγραμμα AddNIntegers
Αυτό
Ο
Αυτό τοπρόγραμμα
βρόχος
το
το σώμα του το
σε αυτό
πρόγραμμα βρόχου αποτελείται
παράδειγμα
χρησιμοποιεί
χρησιμοποιεί από Repeat-Ν-Times
λειτουργεί
τον
τον τρόπο
τρόπο δύο δηλώσεις.
σωστά Ηγια
μόνο αν
Repeat-Ν-Times 1ηη
διαβάζει
μεταβλητή
να έναν ακέραιο
total
υπολογίσει το πάρει από
την το
άθροισμα
άθροισμα χρήστη
τιμή 0 πριν
ενός
ενός στη μεταβλητή
από την εκτέλεση
προκαθορισμένου
προκαθορισμένου του.
αριθμού
value,
αριθμού
και η 2η προσθέτει
ακέραιων
ακέραιων τιμών, τηνκαθορίζονται
τιμών, που
που τιμή στη μεταβλητή
καθορίζονται από
απότην
τηνσταθερά
σταθεράN.
total. N.

public class AddNIntegers extends ConsoleProgram {


public void run() {
println("This program adds " + N + " numbers.");
int total = 0;
for (int i = 0; i < N; i++) {
int value = readInt(" ? ");
total += value;
}
println("The total is " + total + ".");
}
private static final int N = 100;
}
Ο τρόπος Repeat-Until-Sentinel
Μια καλύτερη προσέγγιση για το πρόγραμμα, που λειτουργεί
για οποιοδήποτε αριθμό τιμών, είναι να χρησιμοποιήσετε το
Repeat-Until-Sentinel το οποίο εκτελεί μια σειρά δηλώσεων
μέχρι ο χρήστης εισάγει μια συγκεκριμένη τιμή που ονομάζεται
φρουρός για να σηματοδοτήσει το τέλος της λίστας :
while (true) {
prompt user and read in a value
if (value == sentinel) break;
rest of loop body
}

Θα πρέπει να επιλέξετε μια τιμή φρουρό που δεν είναι πιθανό


να προκύψει στα δεδομένα εισόδου. Είναι επίσης λογικό να
καθορίσετε τον φρουρό ως σταθερά για να είναι εύκολο να
αλλάξει.
Το πρόγραμμα AddIntegerList
Αυτό το πρόγραμμα χρησιμοποιεί το Repeat-Μέχρι-Sentinel για
να προσθέσει μια λίστα ακεραίων, σταματώντας όταν ο χρήστης
εισάγει μια τιμή που ταιριάζει με την σταθερά SENTINEL.

public class AddIntegerList extends ConsoleProgram {


public void run() {
println("This program adds a list of integers.");
println("Enter values, one per line, using " + SENTINEL);
println("to signal the end of the list.");
int total = 0;
while (true) {
int value = readInt(" ? ");
if (value == SENTINEL) break;
total += value;
}
println("The total is " + total + ".");
}
private static final int SENTINEL = 0;
}
Το πρόγραμμα AddIntegerList
public void run() {
println("This program adds a list of integers.");
println("Enter values, one per line, using " + SENTINEL);
println("to signal the end of the list.");
int total = 0;
while (true) {
int value = readInt(" ? ");
if (value == SENTINEL) break;
total += value;
}
println("The total is " + total + "."); value total
} 1
2
3
0 0
1
3
6

AddIntegerList

This program adds a list of integers.


Enter values, one per line, using 0
to signal the end of the list.
? 1
? 2
? 3
? 0
The total is 6.
skip simulation
Άσκηση: Πρότυπα Ελέγχου
Χρησιμοποιώντας το πρόγραμμα AddIntegerList ως πρότυπο, να
γραφεί ένα νέο πρόγραμμα AverageList που θα διαβάζει ένα
σύνολο των ακεραίων από το χρήστη και επιδεικνύει το μέσο
όρο τους. Επειδή μπορεί κάλλιστα να εμφανιστούν τιμές ίσες με
το 0 (π.χ. σε έναν μέσο όρο αποτελεσμάτων εξετάσεων),
αλλάξτε την τιμή φρουρό έτσι ώστε η είσοδος να σταματά όταν
ο χρήστης εισάγει -1. Είναι σημαντικό να έχετε κατά νου ότι ο
μέσος όρος του συνόλου των ακεραίων δεν είναι απαραιτήτως
ακέραιος.
Το πρόγραμμα AverageList απαιτεί τις παρακάτω αλλαγές:
– Μετατροπή της μεταβλητής total σε double πριν από τον υπολογισμό
του μέσου όρου
– Αλλαγή του ορισμού της σταθεράς SENTINEL
– Κρατήστε τον αριθμό των τιμών των εισόδων, μαζί με το σύνολο
– Ενημερώστε τα μηνύματα χρηστών και την τεκμηρίωση του
προγράμματος
Η δήλωση if
Η απλούστερη από τις δηλώσεις ελέγχου είναι η δήλωση if, η
οποία εμφανίζεται σε δύο μορφές. Μπορείτε να χρησιμοποιήσετε
την πρώτη μορφή κάθε φορά που χρειάζεστε να εκτελέσετε μια
λειτουργία μόνο αν μια συγκεκριμένη συνθήκη είναι αληθής
if (condition) {
statements to be executed if the condition is true
}

Χρησιμοποιήσετε τη δεύτερη μορφή κάθε φορά που θέλετε να


επιλέξετε ανάμεσα σε δύο εναλλακτικές διαδρομές, μία όταν η
συνθήκη είναι αληθής και μια δεύτερη για όταν η συνθήκη είναι
ψευδής:
if (condition) {
statements to be executed if the condition is true
} else {
statements to be executed if the condition is false
}
Διαλέγοντας μεταξύ if και if/else
• Όπως συμβαίνει με τις περισσότερες προγραμματιστικές
• public
Όπως συμβαίνει
δομές,voidδενrun()
υπάρχει { με τις περισσότερες
κανένας γρήγορος κανόνας προγραμματιστικές
που θα σας πει
δομές,
θα δεν υπάρχει
ανprintln("This
πρέπει να programκανένας
averages
χρησιμοποιήσετε γρήγορος
a list of
το if κανόνας
ή που θα σας
numbers.");
το if/else
println("Enter values, one per line, using " + SENTINEL);
πειprintln("to
αν θα πρέπει να χρησιμοποιήσετε το if ή το if/else
signal the end of the list.");
•• ΟΟint καλύτερος
total = 0;
καλύτερος
int count = 0;
τρόποςείναι
τρόπος είναινα νασκεφτούμε
σκεφτούμετην τηνπεριγραφή
περιγραφήτου του
προβλήματος
προβλήματος
while (true) {που που προσπαθούμε
προσπαθούμε να να επιλύσουμε.
επιλύσουμε. Αν Αν ηη
περιγραφή
περιγραφή
int value περιέχει
περιέχει
= readInt(" τα αλλιώς
τα αλλιώς
? "); ήή “σε
“σε άλλη
άλλη περίπτωση",
περίπτωση",
υπάρχει
υπάρχει καλήπιθανότητα
if (value
καλή πιθανότητα
== SENTINEL)η ηbreak;
λύση θα
λύση θα χρησιμοποιεί
χρησιμοποιεί το το else
else.
total
if
total(value
total
total +=
+=
+=
+= value;
!=
value;
value;
value;0) {
total
total
total
total +=
+=
+=
+= value;
value;
value;
value;
total
count++;
• Έστω count++;
count++; += value;
}
ότι θέλετε
count++;
count++;
count++;
count++;
count++;
count++;
να αλλάξετε το πρόγραμμα AverageList, έτσι
• ώστεΈστω
}
}
} }να
double
}
double
ότιaverage
θέλετε
μην
average =
=
να αλλάξετε
περιλαμβάνει
(double)
(double) total
total
το πρόγραμμα
μηδενικές/
/
τιμές AverageList,
count;
count;
στο μέσο όρο.
}
έτσι ώστε
double
}
Εδώ,
double
}
double
}
doubleθα να
average
πρέπει
average
println("The
average
println("The
average
println("The
μην
=
=
average
=
= να περιλαμβάνει
(double)
έχετε
(double)
is
(double)
average is
(double)
average
"
is "
total
+
" + μια
total
average
total
total
+
/
/
/
average
/ μηδενικές
count;
απλή
count; εντολή
++".");
count;
count;
average + ".");
".");
τιμέςif στο
που μέσο
θα
double average = (double) total / count;
}
}
}
}
όρο.
double
βέβαιώνειΕδώ,
println("The
println("The
double θα
average
ότι
average
println("The
println("The πρέπει
μια =average
= να
(double)
τιμή δεν
average
(double)
average
averageέχετε
isis ""++μια
total
είναι
total
isis "
/
ίση
+ / απλή
average
count;
με
average0.
count;
average
""++average εντολή
++".");
+ ".");
+".");
"."); if που θα
println("The average is average + ".");
• }}}}Αν,
βέβαιώνει
println("The
θέλατε ότι
να μια
nonzeroτιμή
μετρήσετε δεν
averageείναι
και is ίση
" + με
τις 0.
average
μη μηδενικές+ ".");
τιμές, θα
}
έπρεπε να προσθέσετε έναν όρο else για να αυξάνετε μια
μεταβλητή μέτρησης στην περίπτωση που η value είναι ίση
με 0.
Συνήθεις μορφές της εντολής if
Τα παραδείγματα στο βιβλίο χρησιμοποιούν την εντολή if με τις
ακόλουθες μορφές :
Δήλωση if σε μια γραμμή Δήλωση if σε άγκιστρα
if (condition) statement if (condition) {
statement
. . . more statements . . .
}

Δήλωση if/else σε άγκιστρα Κλιμακωτή δήλωση if


if (condition) { if (condition1) {
statementstrue statements1
} else { } else if (condition2) {
statementsfalse statements2
} . . . more else/if conditions . . .
} else {
statementselse
}
Ο τελεστής ?:
• Εκτός από τη δήλωση if, η Java παρέχει ένα πιο συμπαγή
τρόπο για να εκφράσει εκτέλεση υπό όρους, που μπορεί να
είναι εξαιρετικά χρήσιμος σε ορισμένες περιπτώσεις. Το
χαρακτηριστικό αυτό ονομάζεται ?: και αποτελεί μέρος της
δομής έκφρασης. Ο τελεστής ?: έχει την μορφή:
condition ? expression1 : expression2

• Όταν η Java συναντά τον τελεστή ?: Αξιολογεί πρώτα την


condition η οποία πρέπει να είναι boolean. Εάν είναι
αληθής, H Java επιλεγεί το expression1 και τo χρησιμοποιεί
ως τιμή. Αν είναι ψευδής, h Java επιλέγει το expression2 αντ
'αυτού.
• Μπορείτε να χρησιμοποιήσετε τελεστή ?: για να αναθέσετε
το μεγαλύτερο εκ των x και y στη μεταβλητή max έτσι:
max = (x > y) ? x : y;
Υπό όρους εκτέλεση (μορφή 1)
if ( expr )
if_block // εκτελείται εάν expr==true
//εδώ απευθείας εάν expr==false

int n = 1298463, r = 0;
if ( n % 13 != 0 ) { // n % 13 == 10
println(n+“ is not a multiple of 13”);
}
n += 18;
Υπο όρους εκτέλεση (μορφή 1)
if ( expr )
if_block // εκτελείται εάν expr==true
//εδώ απευθείας εάν expr==false

int n = 1298463, r = 0;
if ( n % 13 != 0 ) { // n % 13 == 10
println(n+” is not a multiple of 13”);
}
n += 18;
Υπο όρους εκτέλεση (μορφή 1)
if ( expr )
if_block // εκτελείται εάν expr==true
//εδώ απευθείας εάν expr==false

int n = 1298463, r = 0;
if ( n % 13 != 0 ) { // n % 13 == 10
println(n+” is not a multiple of 13”);
}
n += 18;
Υπο όρους εκτέλεση (μορφή 1)
if ( expr )
if_block // εκτελείται εάν expr==true
//εδώ απευθείας εάν expr==false

int n = 1298463, r = 0;
if ( n % 13 != 0 ) { // n % 13 == 10
println(n+” is not a multiple of 13”);
}
n += 18;
Υπο όρους εκτέλεση (μορφή 1)
if ( expr )
if_block // εκτελείται εάν expr==true
//εδώ απευθείας εάν expr==false

int n = 1298463, r = 0;
if ( n % 13 != 0 ) { // n % 13 == 10
println(n+” is not a multiple of 13”);
}
n += 18;
Υπο όρους εκτέλεση (μορφή 2)
if ( expr )
if_block // εκτελείται εάν expr==true
else
else_block //εδώ εάν expr==false
// εδώ μετά το if ή το else
Υπό όρους εκτέλεση (μορφή 2)
int n = 1298453, r = 0;
if ( n % 13 != 0 ) { // n % 13 == 0
println(n+” is not a multiple of 13”);
}
else {
println(”n is a multiple of 13”);
}
n += 18;
Υπό όρους εκτέλεση (μορφή 2)
int n = 1298453, r = 0;
if ( n % 13 != 0 ) { // n % 13 == 0
println(n+” is not a multiple of 13”);
}
else {
println(”n is a multiple of 13”);
}
n += 18;
Υπό όρους εκτέλεση (μορφή 2)
int n = 1298453, r = 0;
if ( n % 13 != 0 ) { // n % 13 == 0
println(n+” is not a multiple of 13”);
}
else {
println(”n is a multiple of 13”);
}
n += 18;
Υπό όρους εκτέλεση (μορφή 2)
int n = 1298453, r = 0;
if ( n % 13 != 0 ) { // n % 13 == 0
println(n+” is not a multiple of 13”);
}
else {
println(”n is a multiple of 13”);
}
n += 18;
Π.χ., abs(x)
• abs(x) = απόλυτη τιμή του x = |x|

double abs(double x) {
double y ;
if ( x < 0 )
y = -x;
else
y = x;
return y;
}
Π.χ., abs(x)
• abs(x) = απόλυτη τιμή του x = |x|
double abs(double x) {
double abs(double x) { double y ;
double y ; y = x < 0 ? –x : x;
if ( x < 0 ) return y;
y = -x; }
else
y = x;
return y;
}
Π.χ., abs(x)
• abs(x) = απόλυτη τιμή του x = |x|
double abs(double x) {
double abs(double x) { double y ;
double y ; y = x < 0 ? –x : x;
if ( x < 0 ) return y;
y = -x; }
else
y = x; double abs(double x) {
return y; return x < 0 ? –x : x;
} }
Υπερφόρτωση
double abs(double x) {
return x < 0 ? –x: x;
} public void run() {
abs(-3);
abs(-3.0);
int abs(int x) {
}
return x < 0 ? –x: x;
}
Υπερφόρτωση
double abs(double x) {
return x < 0 ? –x: x;
} public void run() {
abs(-3);
abs(-3.0);
int abs(int x) {
}
return x < 0 ? –x: x;
}
Υπερφόρτωση
double abs(double x) {
return x < 0 ? –x: x;
} public void run() {
abs(-3);
abs(-3.0);
int abs(int x) {
}
return x < 0 ? –x: x;
}
H δήλωση switch
Όταν
Η
ΗΑνJava Java
δήλωση εκτελεί
switch
αναζητά μια
αξιολογεί
κανένα case μια
τις
δεν δήλωση
προσφέρει
case
δηλώσειςπου
ταιριάζει switch,
σεμια
ταιριάζει
μεμια
τηναρχίζει
βολική
με τηνμε την
σύνταξηαξιολόγηση
expression.
μέχρι
έκφραση,
case ηναJavaγια την
Εάν
φτάσει η
το
εκτελεί
Η
τουδήλωση
επιλογή switch
expression,
ανάμεσα προσφέρει
ηίση
οποία
σεαπό
μια πρέπει
σειρά μια
να
απόβολική
παράγεισύνταξη
πιθανές μια για
ακέραια
διαδρομές: την επιλογή
τιμή.
expression
τις
break , που
δηλώσειςήταν
πρέπει
κάτω
ανάμεσα σε μια σειρά απόμε
να v ,
υπάρχει
το
2 τότε διαλέγει
στο
default. τέλοςτην
κάθε
πιθανές διαδρομές:δεύτερη περίπτωση.
δήλωσης.
switch ( expression ) {
case v1:
statements to be executed if expression = v1
break;
case v2:
statements to be executed if expression = v2
break;
. . . more case clauses if needed . . .
default:
statements to be executed if no values match
break;
}
Παράδειγμα της switch
Η δήλωση switch είναι χρήσιμη όταν το πρόγραμμα πρέπει να
επιλέξει ανάμεσα σε αρκετές περιπτώσεις, όπως στο :
public void run() {
println(This program shows the number of days in a month.");
int month = readInt("Enter numeric month (Jan=1): ");
switch (month) {
case 2:
println("28 days (29 in leap years)");
break;
case 4: case 6: case 9: case 12:
println("30 days");
break;
case 1: case 3: case 5: case 7: case 8: case 11:
println("31 days");
break;
default:
println("Illegal month number");
break;
}
}
Επανάληψη
• Εκτέλεση n φορές μιας ομάδας εντολών;
– Π.χ., εντολή println(”Γειά σου”);
Επανάληψη
println(”Γειά σου”); // 1 κλήση
println(”Γειά σου”); // 2η κλήση

println(”Γειά σου”); // n-οστή κλήση

- Μεγάλο πρόγραμμα
- Δυσανάγνωστο για μεγάλο n (π.χ., n>1000!!!)
H δήλωση while
Η δήλωση while statement είναι η απλούστερη από τις δήλωση
ελέγχου επαναλήψεων της Java και έχει την ακόλουθη μορφή :

while ( condition ) {
statements to be repeated
}

Όταν Java συναντά ένα while, αξιολογεί την παρένθεση, με το


αποτέλεσμα να πρέπει να είναι boolean.
Εάν η τιμή της condition είναι true, η Java εκτελεί τις εντολές στο
σώμα του βρόχου.
Στο τέλος κάθε κύκλου, η Java επαναξιολογεί την condition για
να δει αν η τιμή του έχει αλλάξει. Αν η condition είναι false, η
Java εξέρχεται από το βρόχο και συνεχίζει με τη δήλωση μετά
την παρένθεση στο τέλος του σώματος του while.
Tο πρόγραμμα DigitSum
public void run() {
println("This program sums the digits in an integer.");
int n = readInt("Enter a positive integer: ");
int dsum = 0;
while ( n > 0 ) {
dsum += n % 10;
n /= 10;
}
println("The sum of the digits is " + dsum);
}
n dsum
1729
172
17
1
0 18
19
11
0
9

DigitSum

This program sums the digits in an integer.


Enter a positive integer: 1729
The sum of the digits is 19.

skip simulation
Το ιδίωμα Loop-and-a-Half
Η δήλωση while στην Java πάντα δοκιμάζει την κατάσταση κατά
την έναρξη του κάθε κύκλου του βρόχου. Μερικές φορές, όμως,
θα πρέπει να εκτελεστεί κάποιος υπολογισμός πριν γίνει αυτό.
Τότε, το ιδίωμα loop-and-a-half είναι πολύ χρήσιμο:

while (true) {
computation necessary to make the test
if (test for completion) break;
computation for the rest of the loop cycle
}

Μια και η προϋπόθεση του while είναι πάντα true, ο βρόχος θα


συνεχίσει για πάντα χωρίς κάποια άλλη στρατηγική
ολοκλήρωσης. Το ιδίωμα loop-and-a-half χρησιμοποιεί τις
δηλώσεις if και break για να εξέλθει του βρόχου. Όταν η
συνθήκη ολοκλήρωσης γίνει true, η Java εκτελεί την break, που
οδηγεί στην έξοδο από το βρόγχο παρακάμπτοντας το υπόλοιπο
του κύκλου.
Επιστροφή στο Repeat-Until-Sentinel
Το ιδίωμα repeat-until-sentinel που παρουσιάστηκε στην αρχή
του κεφαλαίου είναι μια περίπτωση του ιδιώματος loop-and-a-
half.
while (true) {
prompt user and
computation read intoa make
necessary valuethe test
if (value == sentinel)break;
(test for completion) break;
rest of loop body
computation for the rest of the loop cycle
}

Αν και μπορεί αρχικά να φαίνεται σαν το μοτιβο αυτό να είναι


πιο σύνθετο από το βασικό while, αποδεικνύεται πολύ πιο
εύκολο για τους περισσότερους μαθητές. Αρκετές μελέτες έχουν
δείξει ότι οι μαθητές που χρησιμοποιούν το ιδίωμα op-and-a-
half είναι πολύ πιο πιθανό να γράψουν σωστό κώδικα από
όσους δεν το κάνουν.
Γενική μορφή
int i = 1;
while ( i <= 10 ) {
println(”Γειά σου”);
i++;
}

• i αναπαριστά έναν μετρητή ( = δεδομένο που


συνοψίζει το στάδιο του υπολογισμού)
Επαναληπτικές εντολές
while ( true ) {
println(”Γειά σου”);
}

Τί κάνει το πρόγραμμα;
Επαναληπτικές εντολές
int i = 1;
while ( true ) {
println(”Γειά σου”);
if ( i < 10 )
i++;
else
break; // έξοδος από επαναλήψεις
}
Επαναληπτικές εντολές
int i = 1;
while ( true ) {
println(”Γειά σου”);
if ( i < 10 ) {
i++;
continue; // συνέχιση επόμενης
} // επανάληψης
break;
}
Επανάληψη
• Επαναληπτική υλοποίηση: Επανάληψη ίδιου
στοιχειώδους υπολογισμού και χρήση
μετρητών.

1 2 3 ... n-2 n-1 n

μετρητές
Επαναληπτική υλοποίηση firstdivisor

• firstdivisor(n)
– Μικρότερος διαιρέτης του n μεγαλύτερος του 2.
• Π.χ., n=35

2 3 4 5 6 ... 33 34 35
Διαιρεί
το 15;
Επαναληπτική υλοποίηση firstdivisor

• firstdivisor(n)
– Μικρότερος διαιρέτης του n μεγαλύτερος του 2.
• Π.χ., n=35

2 3 4 5 6 ... 33 34 35
Διαιρεί
το 15;
Επαναληπτική υλοποίηση firstdivisor

• firstdivisor(n)
– Μικρότερος διαιρέτης του n μεγαλύτερος του 2.
• Π.χ., n=35

2 3 4 5 6 ... 33 34 35
Διαιρεί
το 15;
Επαναληπτική υλοποίηση firstdivisor

• firstdivisor(n)
– Μικρότερος διαιρέτης του n μεγαλύτερος του 2.
• Π.χ., n=35

2 3 4 5 6 ... 33 34 35
Διαιρεί
το 15;
Επαναληπτική υλοποίηση firstdivisor

• firstdivisor(n)
– Μικρότερος διαιρέτης του n μεγαλύτερος του 2.
• Π.χ., n=35

2 3 4 5 6 ... 33 34 35
Επαναληπτική υλοποίηση firstdivisor
int firstdivisor(int n) {
int i = 2; // υποψήφιος διαιρέτης (μετρητής)
while ( i <= n) {
if ( n % i == 0 )
break;
else
i++;
}
return i;
}
Επαναληπτική υλοποίηση firstdivisor

int firstdivisor(int n) {
int i = 2; // υποψήφιος διαιρέτης (μετρητής)
while ( n % i != 0 ) {
i++;
}
return i;
}
Επαναληπτική υλοποίηση firstdivisor

int firstdivisor(int n) {
int i = 2; // υποψήφιος διαιρέτης (μετρητής)
while ( n % i != 0 )
i++; // ok, γιατί μόνο 1 εντολή

return i;
}
Επαναληπτική υλοποίηση firstdivisor

int firstdivisor(int n) {
int i = 2; // υποψήφιος διαιρέτης (μετρητής)
while ( n % i++ != 0 ); // while χωρίς εντολές
return i-1;
}
Επαναληπτική υλοποίηση 1+2+…+n

• 1+2+…+n = άθροισμα αριθμών 1 έως n

• Π.χ., n=10

1 2 3 4 5 6 7 8 9 10
sum += 1
sum: 1
Επαναληπτική υλοποίηση 1+2+…+n

• 1+2+…+n = άθροισμα αριθμών 1 έως n

• Π.χ., n=10

1 2 3 4 5 6 7 8 9 10
sum += 2
sum: 3
Επαναληπτική υλοποίηση 1+2+…+n

• 1+2+…+n = άθροισμα αριθμών 1 έως n

• Π.χ., n=10

1 2 3 4 5 6 7 8 9 10
sum += 3
sum: 6
Επαναληπτική υλοποίηση 1+2+…+n

• 1+2+…+n = άθροισμα αριθμών 1 έως n

• Π.χ., n=10

1 2 3 4 5 6 7 8 9 10
sum += 4
sum: 10
Επαναληπτική υλοποίηση 1+2+…+n

• 1+2+…+n = άθροισμα αριθμών 1 έως n

• Π.χ., n=10

1 2 3 4 5 6 7 8 9 10
sum += 5
sum: 15
Επαναληπτική υλοποίηση 1+2+…+n

• 1+2+…+n = άθροισμα αριθμών 1 έως n

• Π.χ., n=10

1 2 3 4 5 6 7 8 9 10
sum += 6
sum: 21
Επαναληπτική υλοποίηση 1+2+…+n

• 1+2+…+n = άθροισμα αριθμών 1 έως n

• Π.χ., n=10

1 2 3 4 5 6 7 8 9 10
sum += 7
sum: 28
Επαναληπτική υλοποίηση 1+2+…+n

• 1+2+…+n = άθροισμα αριθμών 1 έως n

• Π.χ., n=10

1 2 3 4 5 6 7 8 9 10
sum += 8
sum: 36
Επαναληπτική υλοποίηση 1+2+…+n

• 1+2+…+n = άθροισμα αριθμών 1 έως n

• Π.χ., n=10

1 2 3 4 5 6 7 8 9 10
sum += 9
sum: 45
Επαναληπτική υλοποίηση 1+2+…+n

• 1+2+…+n = άθροισμα αριθμών 1 έως n

• Π.χ., n=10

1 2 3 4 5 6 7 8 9 10
sum += 10
sum: 55
Επαναληπτική υλοποίηση 1+2+…+n

• 1+2+…+n = άθροισμα αριθμών 1 έως n

• Π.χ., n=10

1 2 3 4 5 6 7 8 9 10

sum: 55
Επαναληπτική υλοποίηση 1+2+…+n

int n = 10;
int i = 1; // όρος (μετρητής)
int sum = 0; // μερικό άθροισμα (μετρητής)
while ( i <= n ) {
sum += i;
i++;
}
println(”1+2+…+n=”+sum);
Επαναληπτική υλοποίηση 1+2+…+n

int n = 10;
int i = 1;
int sum = 0;
while ( i <= n ) { // 1 περιττός έλεγχος εάν n>=1
sum += i;
i++;
}
println(”1+2+…+n=”+sum);
Επαναληπτικές εντολές
int n = 10, sum = 0;
int i = 1;
do {
sum += i;
i++;
} while ( i <= n ); // Έλεγχος μόνο για i>1
println(”1+2+…+n=”+sum);
Επαναληπτικές εντολές
int n = 10, sum = 0;
int i = 1; // αρχικοποίηση μετρητών
while ( i <= n ) { //έλεγχος συνθήκης επανάληψης
sum += i;
i++; // ανανέωση μετρητών (επόμενος όρος)
}
println(”1+2+…+n=”+sum);
Η δήλωση for
Η δήλωση for στην Java είναι ένα ιδιαίτερα ισχυρό εργαλείο για
τον καθορισμό μιας δομής ελέγχου ενός βρόχου ανεξάρτητα
από τις εργασίες που επιτελεί το σώμα του. Η σύνταξη του είναι:

for ( init ; test ; step ) {


statements to be repeated
}

Η Java αξιολογεί την for εκτελώντας τα ακόλουθα βήματα :


1. Αξιολόγηση της init, που συνήθως είναι η μεταβλητή ελέγχου
2. Αξιολόγηση της test και έξοδος από το βρόχο αν είναι false.
3. Εκτέλεση των εντολών στο σώμα του βρόχου.
4. Αξιολόγηση step, που συνήθως αλλάζει τη μεταβλητή ελέγχου
5. Επιστροφή στο βήμα 2 για την έναρξη του νέου κύκλου.
Συγκρίνοντας τα for και while
Η δήλωση for

for ( init ; test ; step ) {


statements to be repeated
}

είναι λειτουργικά ισοδύναμη με τον ακόλουθο κώδικα while:

init;
while ( test ) {
statements to be repeated
step;
}

Το πλεονέκτημα του for είναι ότι ξέρουμε για να καταλάβουμε


πόσες φορές θα τρέξει ο βρόχος περιλαμβάνονται ρητά στη
κεφαλίδα.
Συγκρίνοντας τα for και while
Η δήλωση for

for ( init ;; step ) {


statements to be repeated
}

είναι λειτουργικά ισοδύναμη με τον ακόλουθο κώδικα while:

init;
while ( true ) {
statements to be repeated
step;
}
Συγκρίνοντας τα for και while
Η δήλωση for

for (;;) {
statements to be repeated
}

είναι λειτουργικά ισοδύναμη με τον ακόλουθο κώδικα while:

while ( true ) {
statements to be repeated

}
Επανάληψη με μετρητή
• Πολλαπλές εντολές αρχικοποίησης/ανανέωσης
int n = 10, i, sum;
for( sum = 0, i = 1; i <= n; i++ ) {
sum += i;
}
println(”1+2+…+n=”+sum);
Επανάληψη με μετρητή
• Πολλαπλές εντολές αρχικοποίησης/ανανέωσης
int n = 10, i, sum;
for( sum = 0, i = 1; i <= n; sum += i, i++ );

println(”1+2+…+n=”+sum);
Άσκηση: διαβάζοντας δηλώσεις for
Περιγράψτε το αποτέλεσμα του καθενός από τα παρακάτω:
1. for (int i = 1; i <= 10; i++)
Η δήλωση αυτή εκτελεί το σώμα δέκα φορές, με μεταβλητή
ελέγχου i, λαμβάνοντας διαδοχικά τιμές μεταξύ 1 και 10.

2. for (int i = 0; i < N; i++)


Η δήλωση αυτή εκτελεί το σώμα N φορές, με το i να μετρά από το
0 στο N - 1. Είναι το στάνταρ Repeat-N-Times.

3. for (int n = 99; n >= 1; n -= 2)


Αυτή η δήλωση μετράει από το 99 ως το 1 ανά δυο.

4. for (int x = 1; x <= 1024; x *= 2)


Η δήλωση αυτή εκτελεί το σώμα με τη μεταβλητή x παίρνει
διαδοχικά τις δυνάμεις του δύο από 1 έως 1024.
The Countdown Program
public void run() {
for ( int t = 10 ; t >= 0 ; t-- ) {
println(t);
}
println("Liftoff!"); t
}
10
0
1
2
3
4
5
6
7
8
9
–1

Countdown

10
9
8
7
6
5
4
3
2
1
0
Liftoff!

skip simulation
Υλοποίηση firstdivisor με for
int firstdivisor(int n) {
int i; // υποψήφιος διαιρέτης (μετρητής)
for ( i = 2; i <= n; i++ ) {
if ( n % i == 0 )
break;
}
return i;
}
Υλοποίηση firstdivisor με for
int firstdivisor(int n) {
int i; // υποψήφιος διαιρέτης (μετρητής)

for ( i = 2; n % i != 0; i++ );

return i;
}
Πολλαπλοί μετρητές
• Εμφάνισε τους πρώτους 20 πρώτους αριθμούς

for ( int p = 0, n = 2; p < 20; n++) {


if ( n == firstdivisor(n) ) {
println(n);
p++;
}
}
Μη ακέραιοι μετρητές
double sqrt(double x) { // Τετραγωνική ρίζα του x
double y = 1; // προσέγγιση της ρίζας του x (μετρητής)
while ( abs(y*y-x) > 1E-5 ) {
y = improve(x, y);
}
return y;
}

// Βελτιώνει την προσέγγιση y της τετραγωνικής ρίζας του x,


// σύμφωνα με τη μέθοδο Newton
double improve(double x, double y) {
return y/2+x/(2*y);
}
Φωλιασμένες επαναλήψεις
Το σώμα μιας δήλωσης ελέγχου μπορεί να περιέχει
άλλες δηλώσεις. Τέτοιες δηλώσεις ονομάζονται
φωλιασμένες.
• Εμφάνιση δέντρου μεγέθους n
– Π.χ., n=5
*
**
***
****
*****
Φωλιασμένες επαναλήψεις
• Εμφάνιση δέντρου μεγέθους n
– Π.χ., n=5
*
**
***
μετρητής
n βήματα επανάληψης

i ****

*****
Φωλιασμένες επαναλήψεις
• Εμφάνιση δέντρου μεγέθους n
– Π.χ., n=5
*
**
***
μετρητής
n βήματα επανάληψης

i ****

*****
μετρητής j, με i επαναλήψεις στο βήμα i
Φωλιασμένες επαναλήψεις
• Εμφάνιση δέντρου μεγέθους n
– Π.χ., n=5
* for ( int i = 1; i <= n; i++ ) {
for ( int j = 1; j <= i; j++ )
** print(’*’);
***
μετρητής
println();
n βήματα επανάληψης

i **** }

*****
μετρητής j, με i επαναλήψεις στο βήμα i
Σκακιέρα
• Η επόμενη διαφάνεια δείχνει ένα πρόγραμμα που
εμφανίζει ένα ταμπλό σκακιέρας στο οποίο ο
αριθμός των γραμμών και των στηλών δίνονται από
τις σταθερές N_ROWS και N_COLUMNS.
• Οι βρόχοι for στο πρόγραμμα Checkerboard μοιάζουν έτσι
for (int i = 0; i < N_ROWS; i++) {
for (int j = 0; j < N_COLUMNS; j++) {
Display the square at row i and column j.
}
}

• Επειδή ολόκληρος ο εσωτερικός βρόχος εκτελείται για κάθε


κύκλο του εξωτερικού το πρόγραμμα εμφανίζει N_ROWS x
N_COLUMNS τετράγωνα.
The Checkerboard Program
public void run() {
double sqSize = (double) getHeight() / N_ROWS;
for (int i = 0; i < N_ROWS; i++) {
for (int j = 0; j < N_COLUMNS; j++) {
double x = j * sqSize; Εκτέλεση
Εκτελούμετου
double y = i * sqSize; εσωτερικού
αυτές τις
GRect sq = new GRect(x, y, sqSize, sqSize); εντολέςεπτά
βρόχου έξι
φορές
φορές για
για να
να
sq.setFilled((i + j) % 2 != 0); ολοκληρωθεί
ολοκληρωθεί
add(sq); ηη σκακιέρα.
σειρά.
}
} sqSize
sqSize i j x y sq
} 30.0 810 8210 210.0
30.0
60.0
0.0 210.0
0.0

Checkerboard

skip simulation
Exercise: Triangle Number Table
Να γραφεί ένα πρόγραμμα που όταν τρέχει να μοιάζει με το
δείγμα στο κάτω μέρος της διαφάνειας, που εμφανίζει το
άθροισμα των πρώτων ακεραίων N για κάθε τιμή του Ν από 1
έως 10. Όπως φαίνεται στην εικόνα οι αριθμοί αυτοί μπορεί να
σχηματίσουν ένα τρίγωνο και συνεπώς ονομάζονται, τριγωνικοί
αριθμοί.

TriangleTable

1 = 1
1 + 2 = 3
1 + 2 + 3 = 6
1 + 2 + 3 + 4 = 10
1 + 2 + 3 + 4 + 5= 15
1 + 2 + 3 + 4 + 5+ 6= 21
1 + 2 + 3 + 4 + 5+ 6+ 7= 28
1 + 2 + 3 + 4 + 5+ 6+ 7+ 8 = 36
1 + 2 + 3 + 4 + 5+ 6+ 7+ 8 + 9 = 45
1 + 2 + 3 + 4 + 5+ 6+ 7+ 8 + 9 + 10 = 55
Θέματα σχεδίασης:
Triangle Number Table
Καθώς σκέφτεστε το σχεδιασμό του TriangleTable, θα βοηθήσει
να έχετε τις ακόλουθες πράγματα στο μυαλό σας:
• Το πρόγραμμα περιλαμβάνει δύο φωλιασμένους βρόχους. Ο
εξωτερικός αυξάνει τις τιμές του Ν από το 1 έως το μέγιστο
Ο εσωτερικός εκτυπώνει μια σειρά τιμών σε κάθε γραμμή.
• Τα επιμέρους στοιχεία της κάθε γραμμής είναι εύκολο να
εμφανιστούν εάν καλέσετε την print αντί της println. Η
μέθοδος print είναι παρόμοια της println αλλά δεν αλλάζει
γραμμή όπως κάνει η println. Χρησιμοποιώντας επομένως
την print μπορείτε να έχετε διάφορες τιμές εξόδου μαζί
στην ίδια γραμμή.
• Η n-οστή γραμμή εξόδου περιχέει n τιμές πριν το ίσον αλλά
n – 1 συν (+). Το πρόγραμμά σας λοιπόν δεν μπορεί να
εκτυπώνει ένα συν σε κάθε κύκλο του εσωτερικού βρόχου,
αλλά πρέπει να παραλείψει ένα κύκλο.
Το πρόγραμμα TriangleTable
public class TriangleTable extends ConsoleProgram {
public void run() {
for (int n = 1; n <= MAX_VALUE; n++) {
int total = 0;
for (int i = 1; i <= n; i++) {
if (i > 1) print(" + ");
print(i);
total += i;
}
println(" = " + total);
}
}
/* Private constants */
private static final int MAX_VALUE = 10;
}
Απλό Animation γραφικών
Οι δηλώσεις while και for καθιστούν δυνατή την δημιουργία
απλού animation. Η στρατηγική είναι η δημιουργία ενός
συνόλου γραφικών αντικειμένων και η εκτέλεση του ακόλουθου
βρόχου
for (int i = 0; i < N_STEPS; i++) {
update the graphical objects by a small amount
pause(PAUSE_TIME);
}
Σε κάθε κύκλο του βρόχου, αυτό το ιδίωμα ενημερώνει κάθε
αντικείμενο μετακινώντας το ελαφρά ή αλλάζοντας κάποια άλλη
ιδιότητα του, όπως το χρώμα του. Κάθε κύκλος ονομάζεται ένα
χρονικό βήμα.
Μετά από κάθε χρονικό βήμα, καλείται η pause, η οποία
καθυστερεί το πρόγραμμα για κάποια χιλιοστά του
δευτερολέπτου (PAUSE_TIME). Χωρίς αυτό, το πρόγραμμα θα
τελείωνε πιο γρήγορα από ό, τι το ανθρώπινο μάτι μπορεί να
δει.
The AnimatedSquare Program
public void run() {
GRect square = new GRect(0, 0, SQUARE_SIZE, SQUARE_SIZE);
square.setFilled(true);
square.setFillColor(Color.RED);
add(square);
double dx = (getWidth() - SQUARE_SIZE) / N_STEPS;
double dy = (getHeight() - SQUARE_SIZE) / N_STEPS;
for (int i = 0; i < N_STEPS; i++) {
square.move(dx, dy);
pause(PAUSE_TIME); i dx dy square
}
} 101 3.0 1.7

AnimatedSquare

skip simulation

You might also like