Control Flow Statements (ΔηλΩσεις ΕλΕγχου ΡοΗς)
Σε αυτή την ενότητα εξετάζουμε τις δηλώσεις ελέγχου ροής που υποστηρίζονται από την Java. Θα δούμε τις δηλώσεις για την λήψη αποφάσεων και την εκτέλεση επαναλαμβανόμενων ενεργειών.
Δήλωση if-then και if-then-else
Όλες οι δηλώσεις ελέγχου ροής περιλαμβάνουν ένα τμήμα ορισμού και ένα μπλόκ εκτέλεσης εντολών. Η πιο απλή και συχνά χρησιμοποιούμενη δήλωση για την λήψη αποφάσεων είναι η if.
Ας πάρουμε το παράδειγμα του ποδηλάτου. Γράφοντας Την μέθοδο φρεναρίσματος θέλουμε το ποδήλατο να ελαττώσει ταχύτητα αν μόνο κινείται. Ορίζουμε μια μεταβλητή boolean (true/false) και την ονομάζουμε isMoving η οποία έχει τιμή true αν το ποδήλατο κινείται και false αν όχι.
Η if δέχεται ως παράμετρο μια τιμή boolean ή μια μεταβλητή ή και μια έκφραση με επιστροφή boolean. Τέτοιες εκφράσεις χρησιμοποιούν τους τελεστές ισότητας και σχέσης και τους λογικούς τελεστές. Το μπλόκ της if εκτελείται μόνο αν η παράμετρος της έχει τιμή true.
Ορίζουμε μια δήλωση if η οποία εκτελεί το μπλοκ του κώδικα της αν η isMoving ισχύει, δηλαδή αν isMoving==true. (Για οικονομία η έκφραση isMoving==true γράφεται ισοδύναμα και μόνο με την μεταβλητή isMoving)
void applyBrakes()
{
// "if" φράση: το ποδήλατο πρεπει να κινείται
if (isMoving)
{
// τότε "then" φράση: μείωσε την ταχύτητα κατα 1
currentSpeed--;
}
}
Εάν έχουμε μόνο μια έκφραση στο μπλοκ τότε μπορούμε να παραλείψουμε τις αγκύλες.
Προσοχή: χωρίς μπλοκ εκτελείται μόνο η έκφραση που ακολουθει την if.
void applyBrakes()
{
// παρομοίως με πριν χωρίς της αγκύλες του μπλοκ
if (isMoving) currentSpeed--;
}
Επίσης όταν θέλουμε να εκτελέσουμε κώδικα για την περίπτωση που δεν ισχύει η έκφραση της if χρησιμοποιούμε την else χωρίς όμως όρισμα έκφρασης.
void applyBrakes()
{
if (isMoving)
{
currentSpeed--;
}
else
{
System.err.println("To ποδήλατο έχει ήδη σταματίσει!");
}
}
ή και αλλιώς
void applyBrakes()
{
if (isMoving) currentSpeed--;
else System.err.println("To ποδήλατο έχει ήδη σταματίσει!");
}
(Σημείωση: Μπορούμε και να φωλιάσουμε ολόκληρες if μέσα στο μπλοκ άλλων if.)
Τέλος με συνδυασμό της if με την else μπορούμε να φτιάξουμε και πιο σύνθετες εκφράσεις
class IfElseDemo
{
public static void main(String[] args)
{
int testscore = 76;
char grade;
if (testscore >= 90)
{
grade = 'A';
}
else if (testscore >= 80)
{
grade = 'B';
}
else if (testscore >= 70)
{
grade = 'C';
}
else if (testscore >= 60)
{
grade = 'D';
}
else
{
grade = 'F';
}
System.out.println("Grade = " + grade);
}
}
Δήλωση switch
Η δήλωση switch έχει παρόμοια χρησιμότητα με την if αλλά παρέχει πολλαπλές διαδρομές εκτέλεσης του κώδικα και λειτουργεί με σύγκριση τιμών μεταβλητών και όχι με λογικές εκφράσεις.
Δέχεται ως είσοδο μια μεταβλητή για την οποία εκτελεί προκαθορισμένο μπλοκ κώδικα ανάλογα με την τιμή που έχει αυτή κάθε φορά. Η μεταβλητή αυτή μπορεί να είναι απλός τύπος byte, short, char και int, κλάση String, τύπος enum που θα δούμε πιο κάτω και οι κλάσεις Character, Byte, Short,Integer.
Στο παρακάτω παράδειγμα επιθυμούμε να μετατρέπουμε το αριθμητικό του μήνα του έτους σε λεκτικό. Η switch παίρνει ως όρισμα την μεταβλητή month και επιστρέφει το αγγλικό λεκτικό που αντιστοιχεί στην τιμή του month. Προσέξτε την ιδιαίτερη σύνταξη με την λέξη κλειδί case #τιμή ελέγχου# και «:». Επίσης προσέξτε και την δήλωση διαφυγής break (που θα δούμε και αργότερα). Η break τερματίζει την εκτέλεση της switch.
public class SwitchDemo {
public static void main(String[] args) {
int month = 8;
String monthString;
switch (month) {
case 1: monthString = "January";
break;
case 2: monthString = "February";
break;
case 3: monthString = "March";
break;
case 4: monthString = "April";
break;
case 5: monthString = "May";
break;
case 6: monthString = "June";
break;
case 7: monthString = "July";
break;
case 8: monthString = "August";
break;
case 9: monthString = "September";
break;
case 10: monthString = "October";
break;
case 11: monthString = "November";
break;
case 12: monthString = "December";
break;
default: monthString = "Invalid month";
break;
}
System.out.println(monthString);
}
}
Η έξοδος είναι:
August
Αν χρησιμοποιούσαμε την if ο κώδικας θα ήταν κάπως έτσι:
int month = 8;
if (month == 1)
{
System.out.println("January");
}
else if (month == 2)
{
System.out.println("February");
} ... // και λοιπά
Αν δεν χρησιμοποιήσουμε την break τα case εκτελούνται σε σειρά από το σημείο που ένα απο αυτά ισχύει και κάτω. Αν κανένα δεν ισχύει τότε εκτελείται ο κώδικας μετά την λέξη κλειδί default:
Αν στο προηγούμενο παράδειγμα δεν υπήρχαν όλα τα break το αποτέλεσμα θα ήταν κάπως έτσι:
public class SwitchDemo {
public static void main(String[] args) {
int month = 8;
String monthString;
switch (month) {
case 1: monthString = "January";
case 2: monthString = "February";
case 3: monthString = "March";
case 4: monthString = "April";
case 5: monthString = "May";
case 6: monthString = "June";
case 7: monthString = "July";
case 8: monthString = "August";
case 9: monthString = "September";
case 10: monthString = "October";
case 11: monthString = "November";
case 12: monthString = "December";
break;
default: monthString = "Invalid month";
break;
}
System.out.println(monthString);
}
}
Η έξοδος είναι:
August
September
October
November
December
Ακόμη ένα χαρακτηριστικό παράδειγμα της χρήσης της break είναι το ακόλουθο που βρίσκει πόσες μέρες έχει ένας μήνας.
class SwitchDemo2
{
public static void main(String[] args)
{
int month = 2;
int year = 2000;
int numDays = 0;
switch (month)
{
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12: numDays = 31;
break;
case 4:
case 6:
case 9:
case 11: numDays = 30;
break;
case 2:
if (((year % 4 == 0) && !(year % 100 == 0)) || (year % 400 == 0)) numDays = 29;
else numDays = 28;
break;
default: System.out.println("Invalid month.");
break;
}
System.out.println("Number of Days = " + numDays);
}
}
Η έξοδος είναι:
Number of Days = 29
Δήλωση while και do-while
Η while εκτελεί συνεχώς τον κώδικα μέσα στο μπλοκ της έως ότου ισχύει η λογική έκφραση που ορίζει
while (έκφραση)
{
δήλωση(s)
}
Παράδειγμα
class WhileDemo {
public static void main(String[] args){
int count = 1;
while (count < 11) {
System.out.println("Count is: " + count);
count++;
}
}
}
Η έξοδος είναι:
1
2
3
4
5
6
7
8
9
10
Εάν δώσουμε την τιμή true στην λογική έκφραση τότε η επανάληψη γίνεται άπειρη.
while (true)
{
// your code goes here
}
Επίσης υπάρχει μια εναλλακτική έκφραση της while όπου η λογική έκφραση ελέγχεται μετά την εκτέλεση του μπλοκ κώδικα και έτσι πάντα εκτελείται ο κώδικας τουλάχιστον μία φορά
do
{
δήλωση(s)
}
while (expression);
Παράδειγμα
class DoWhileDemo {
public static void main(String[] args){
int count = 1;
do {
System.out.println("Count is: " + count);
count++;
} while (count < 11);
}
}
Δήλωση for
Ίσως η πιο ευρέως χρησιμοποιούμενη δήλωση επανάληψης είναι η for.
Η σύνταξη της είναι συμπαγής και χρησιμοποιείται για να διαπεράσει μια ακολουθία τιμών:
for (αρχικοποίηση; τερματισμός; αύξηση)
{
δήλωση(ς)
}
όπου
αρχικοποίηση η έκφραση αρχικοποίησης της επανάληψης, εκτελείται μία φορά
τερματισμός η λογική έκφραση τερματισμού της επανάληψης όταν γίνει false
αύξηση η αριθμητική αύξηση ή μείωση της τιμής ελέγχου κάθε φορά που εκτελείται το μπλοκ.
Σημείωση: στην αρχικοποίηση μπορούμε να δηλώσουμε την μεταβλητή ελέγχου (είθισται για οικονομία ονομάτων μεταβλητών)
class ForDemo {
public static void main(String[] args){
for(int i=1; i<11; i++){
System.out.println("Count is: " + i);
}
}
}
Η έξοδος είναι:
Count is: 1
Count is: 2
Count is: 3
Count is: 4
Count is: 5
Count is: 6
Count is: 7
Count is: 8
Count is: 9
Count is: 10
Επίσης χωρίς δηλώσεις ορίσματος η for επαναλαμβάνεται άπειρα
// ατέρμονη επανάληψη
for ( ; ; )
{
// your code goes here
}
Επίσης η for μπορεί να διατρέξει τις τιμές ενός πίνακα
class EnhancedForDemo
{
public static void main(String[] args)
{
int[] numbers = {1,2,3,4,5,6,7,8,9,10};
for (int item : numbers)
{
System.out.println("Count is: " + item);
}
}
}
Η έξοδος είναι:
Count is: 1
Count is: 2
Count is: 3
Count is: 4
Count is: 5
Count is: 6
Count is: 7
Count is: 8
Count is: 9
Count is: 10
Δήλωση if-then και if-then-else
Όλες οι δηλώσεις ελέγχου ροής περιλαμβάνουν ένα τμήμα ορισμού και ένα μπλόκ εκτέλεσης εντολών. Η πιο απλή και συχνά χρησιμοποιούμενη δήλωση για την λήψη αποφάσεων είναι η if.
Ας πάρουμε το παράδειγμα του ποδηλάτου. Γράφοντας Την μέθοδο φρεναρίσματος θέλουμε το ποδήλατο να ελαττώσει ταχύτητα αν μόνο κινείται. Ορίζουμε μια μεταβλητή boolean (true/false) και την ονομάζουμε isMoving η οποία έχει τιμή true αν το ποδήλατο κινείται και false αν όχι.
Η if δέχεται ως παράμετρο μια τιμή boolean ή μια μεταβλητή ή και μια έκφραση με επιστροφή boolean. Τέτοιες εκφράσεις χρησιμοποιούν τους τελεστές ισότητας και σχέσης και τους λογικούς τελεστές. Το μπλόκ της if εκτελείται μόνο αν η παράμετρος της έχει τιμή true.
Ορίζουμε μια δήλωση if η οποία εκτελεί το μπλοκ του κώδικα της αν η isMoving ισχύει, δηλαδή αν isMoving==true. (Για οικονομία η έκφραση isMoving==true γράφεται ισοδύναμα και μόνο με την μεταβλητή isMoving)
void applyBrakes()
{
// "if" φράση: το ποδήλατο πρεπει να κινείται
if (isMoving)
{
// τότε "then" φράση: μείωσε την ταχύτητα κατα 1
currentSpeed--;
}
}
Εάν έχουμε μόνο μια έκφραση στο μπλοκ τότε μπορούμε να παραλείψουμε τις αγκύλες.
Προσοχή: χωρίς μπλοκ εκτελείται μόνο η έκφραση που ακολουθει την if.
void applyBrakes()
{
// παρομοίως με πριν χωρίς της αγκύλες του μπλοκ
if (isMoving) currentSpeed--;
}
Επίσης όταν θέλουμε να εκτελέσουμε κώδικα για την περίπτωση που δεν ισχύει η έκφραση της if χρησιμοποιούμε την else χωρίς όμως όρισμα έκφρασης.
void applyBrakes()
{
if (isMoving)
{
currentSpeed--;
}
else
{
System.err.println("To ποδήλατο έχει ήδη σταματίσει!");
}
}
ή και αλλιώς
void applyBrakes()
{
if (isMoving) currentSpeed--;
else System.err.println("To ποδήλατο έχει ήδη σταματίσει!");
}
(Σημείωση: Μπορούμε και να φωλιάσουμε ολόκληρες if μέσα στο μπλοκ άλλων if.)
Τέλος με συνδυασμό της if με την else μπορούμε να φτιάξουμε και πιο σύνθετες εκφράσεις
class IfElseDemo
{
public static void main(String[] args)
{
int testscore = 76;
char grade;
if (testscore >= 90)
{
grade = 'A';
}
else if (testscore >= 80)
{
grade = 'B';
}
else if (testscore >= 70)
{
grade = 'C';
}
else if (testscore >= 60)
{
grade = 'D';
}
else
{
grade = 'F';
}
System.out.println("Grade = " + grade);
}
}
Δήλωση switch
Η δήλωση switch έχει παρόμοια χρησιμότητα με την if αλλά παρέχει πολλαπλές διαδρομές εκτέλεσης του κώδικα και λειτουργεί με σύγκριση τιμών μεταβλητών και όχι με λογικές εκφράσεις.
Δέχεται ως είσοδο μια μεταβλητή για την οποία εκτελεί προκαθορισμένο μπλοκ κώδικα ανάλογα με την τιμή που έχει αυτή κάθε φορά. Η μεταβλητή αυτή μπορεί να είναι απλός τύπος byte, short, char και int, κλάση String, τύπος enum που θα δούμε πιο κάτω και οι κλάσεις Character, Byte, Short,Integer.
Στο παρακάτω παράδειγμα επιθυμούμε να μετατρέπουμε το αριθμητικό του μήνα του έτους σε λεκτικό. Η switch παίρνει ως όρισμα την μεταβλητή month και επιστρέφει το αγγλικό λεκτικό που αντιστοιχεί στην τιμή του month. Προσέξτε την ιδιαίτερη σύνταξη με την λέξη κλειδί case #τιμή ελέγχου# και «:». Επίσης προσέξτε και την δήλωση διαφυγής break (που θα δούμε και αργότερα). Η break τερματίζει την εκτέλεση της switch.
public class SwitchDemo {
public static void main(String[] args) {
int month = 8;
String monthString;
switch (month) {
case 1: monthString = "January";
break;
case 2: monthString = "February";
break;
case 3: monthString = "March";
break;
case 4: monthString = "April";
break;
case 5: monthString = "May";
break;
case 6: monthString = "June";
break;
case 7: monthString = "July";
break;
case 8: monthString = "August";
break;
case 9: monthString = "September";
break;
case 10: monthString = "October";
break;
case 11: monthString = "November";
break;
case 12: monthString = "December";
break;
default: monthString = "Invalid month";
break;
}
System.out.println(monthString);
}
}
Η έξοδος είναι:
August
Αν χρησιμοποιούσαμε την if ο κώδικας θα ήταν κάπως έτσι:
int month = 8;
if (month == 1)
{
System.out.println("January");
}
else if (month == 2)
{
System.out.println("February");
} ... // και λοιπά
Αν δεν χρησιμοποιήσουμε την break τα case εκτελούνται σε σειρά από το σημείο που ένα απο αυτά ισχύει και κάτω. Αν κανένα δεν ισχύει τότε εκτελείται ο κώδικας μετά την λέξη κλειδί default:
Αν στο προηγούμενο παράδειγμα δεν υπήρχαν όλα τα break το αποτέλεσμα θα ήταν κάπως έτσι:
public class SwitchDemo {
public static void main(String[] args) {
int month = 8;
String monthString;
switch (month) {
case 1: monthString = "January";
case 2: monthString = "February";
case 3: monthString = "March";
case 4: monthString = "April";
case 5: monthString = "May";
case 6: monthString = "June";
case 7: monthString = "July";
case 8: monthString = "August";
case 9: monthString = "September";
case 10: monthString = "October";
case 11: monthString = "November";
case 12: monthString = "December";
break;
default: monthString = "Invalid month";
break;
}
System.out.println(monthString);
}
}
Η έξοδος είναι:
August
September
October
November
December
Ακόμη ένα χαρακτηριστικό παράδειγμα της χρήσης της break είναι το ακόλουθο που βρίσκει πόσες μέρες έχει ένας μήνας.
class SwitchDemo2
{
public static void main(String[] args)
{
int month = 2;
int year = 2000;
int numDays = 0;
switch (month)
{
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12: numDays = 31;
break;
case 4:
case 6:
case 9:
case 11: numDays = 30;
break;
case 2:
if (((year % 4 == 0) && !(year % 100 == 0)) || (year % 400 == 0)) numDays = 29;
else numDays = 28;
break;
default: System.out.println("Invalid month.");
break;
}
System.out.println("Number of Days = " + numDays);
}
}
Η έξοδος είναι:
Number of Days = 29
Δήλωση while και do-while
Η while εκτελεί συνεχώς τον κώδικα μέσα στο μπλοκ της έως ότου ισχύει η λογική έκφραση που ορίζει
while (έκφραση)
{
δήλωση(s)
}
Παράδειγμα
class WhileDemo {
public static void main(String[] args){
int count = 1;
while (count < 11) {
System.out.println("Count is: " + count);
count++;
}
}
}
Η έξοδος είναι:
1
2
3
4
5
6
7
8
9
10
Εάν δώσουμε την τιμή true στην λογική έκφραση τότε η επανάληψη γίνεται άπειρη.
while (true)
{
// your code goes here
}
Επίσης υπάρχει μια εναλλακτική έκφραση της while όπου η λογική έκφραση ελέγχεται μετά την εκτέλεση του μπλοκ κώδικα και έτσι πάντα εκτελείται ο κώδικας τουλάχιστον μία φορά
do
{
δήλωση(s)
}
while (expression);
Παράδειγμα
class DoWhileDemo {
public static void main(String[] args){
int count = 1;
do {
System.out.println("Count is: " + count);
count++;
} while (count < 11);
}
}
Δήλωση for
Ίσως η πιο ευρέως χρησιμοποιούμενη δήλωση επανάληψης είναι η for.
Η σύνταξη της είναι συμπαγής και χρησιμοποιείται για να διαπεράσει μια ακολουθία τιμών:
for (αρχικοποίηση; τερματισμός; αύξηση)
{
δήλωση(ς)
}
όπου
αρχικοποίηση η έκφραση αρχικοποίησης της επανάληψης, εκτελείται μία φορά
τερματισμός η λογική έκφραση τερματισμού της επανάληψης όταν γίνει false
αύξηση η αριθμητική αύξηση ή μείωση της τιμής ελέγχου κάθε φορά που εκτελείται το μπλοκ.
Σημείωση: στην αρχικοποίηση μπορούμε να δηλώσουμε την μεταβλητή ελέγχου (είθισται για οικονομία ονομάτων μεταβλητών)
class ForDemo {
public static void main(String[] args){
for(int i=1; i<11; i++){
System.out.println("Count is: " + i);
}
}
}
Η έξοδος είναι:
Count is: 1
Count is: 2
Count is: 3
Count is: 4
Count is: 5
Count is: 6
Count is: 7
Count is: 8
Count is: 9
Count is: 10
Επίσης χωρίς δηλώσεις ορίσματος η for επαναλαμβάνεται άπειρα
// ατέρμονη επανάληψη
for ( ; ; )
{
// your code goes here
}
Επίσης η for μπορεί να διατρέξει τις τιμές ενός πίνακα
class EnhancedForDemo
{
public static void main(String[] args)
{
int[] numbers = {1,2,3,4,5,6,7,8,9,10};
for (int item : numbers)
{
System.out.println("Count is: " + item);
}
}
}
Η έξοδος είναι:
Count is: 1
Count is: 2
Count is: 3
Count is: 4
Count is: 5
Count is: 6
Count is: 7
Count is: 8
Count is: 9
Count is: 10