Keuzestructuren

Keuze

Inhoud

Nadat deze les wordt behandeld

Inleiding

Tot nu toe hebben we programma's gemaakt die, al of niet in een lus, een aaneenschakeling van statements uitvoeren. Maar we willen ook keuzes kunnen maken, bijv. een bepaald handeling wel of niet uitvoeren, of kiezen uit twee of meer mogelijkheden.

Java kent een aantal zgn conditionele statements met behulp waarvan we uitvoering van een programma kunnen beïnvloeden.

Het if-statement

De syntax van het if-statements is:

if (vraag) statement 

De vraag moet altijd tussen haakjes geplaatst worden. Dus bijv.

if (cijfer >= 5.5)
	System.out.println("Geslaagd");

Als evaluatie van de vraag de waarheidswaarde true oplevert dan wordt het statement uitgevoerd, is de vraag false dan wordt het statement niet uitgevoerd. Dus als het cijfer gelijk aan of groter dan 5,5 is dan wordt het System.out.println-statement uitgevoerd.

In Java is het antwoord op een vraag altijd een boolean.
Dit in tegenstelling tot C en C++ waar het een integer is.

Eenvoudige statements plaatsen we vaak op dezelfde regel achter de vraag. Als na if meerdere statements moeten worden uitgevoerd, een samengestelde statement dus, dan plaatsen we bij voorkeur voorwaarde en statements op afzonderlijke regels, dus

if (puntenaantal >=42) { 
	System.out.println("GEFELICITEERD"); 
	System.out.println("U bent geslaagd voor de propaedeuse"); 
} 

De accolades niet vergeten, anders behoort alleen de eerste println tot het if-statement.
if-statements kunnen worden genest, d.w.z. binnen een if-statement kan een ander if-statement worden uitgevoerd.

Stel dat we een 24-uurs klok willen maken. Dat zou als volgt kunnen worden geprogrammeerd (seconden, minuten en uren zijn integers):

goed
seconden++; 
if (seconden == 60) { 
   seconden = 0; 
   minuten++; 
   if (minuten == 60) { 
      minuten = 0; 
      uren++; 
      if (uren == 24) uren=0; 
   }
} 
slecht
seconden++; 
if (seconden == 60) { 
   seconden = 0; 
   minuten++; 
} 
if (minuten == 60) { 
   minuten = 0; 
   uren++; 
} 
if (uren == 24) uren=0; 

Het rechter fragment heeft hetzelfde effect als het linker, maar is minder efficiënt. Bij het rechter fragment wordt elke keer nadat seconden met één is vermeerderd getest op minuten == 60 en uren == 24. Maar de test op minuten == 60 is alleen zinvol onmiddellijk nadat minuten met één is vermeerderd. Die voorwaarde is dan ook in het linker fragment verwerkt. Iets dergelijks geldt voor de uren.

Typecast

Voordat een vergelijking wordt uitgevoerd worden de leden aan beide zijde van de relationele operator van hetzelfde type gemaakt. Dit is altijd van het grootste type. Voorbeeld:

int x; 
double d;
if (x > d) // typecast naar double

Het if-else statement

Bij het if-statement hebben we de keus tussen een statement wel of niet uitvoeren. Bij het if-else statement kunnen we kiezen uit twee mogelijkheden.

De syntax van het if-else statements is:

if (vraag) statement1 else statement2 

Het eerste statement1 wordt uitgevoerd als de vraag waar is, het tweede statement2 als de vraag niet waar is.

Voorbeeld: bereken de wortel

Neem aan dat de wortel uit een getal berekend wordt . Als het getal negatief is dan wordt de wortel voorafgegaan door de letter i af, dus i*wortel.

Een mogelijke uitvoering is:

	if (kwadraat >= 0) 
		System.out.println( Double.toString(Math.sqrt(kwadraat))); 
	else 
		System.out.println("i" + Double.toString(Math.sqrt(-kwadraat))); 
 

De complete progammacode

Soms wordt niet doorzien dat de voorwaarden elkaar uitsluiten. Dan onstaat de onderstaande programmatekst:

if (kwadraat >=0) 
	System.out.println( Double.toString(Math.sqrt(kwadraat))); 
if (kwadraat < 0) 
	System.out.println("i" + Double.toString(Math.sqrt(-kwadraat))); 

Het tweede if-statement leidt tot een overbodige test, immers als (kwadraat >= 0) onwaar is dan is (kwadraat < 0) waar en omgekeerd.

het samengestelde if..else statement

Als na if en/of else meerdere statements volgen dan maken we daarvan weer samengestelde statements.

if (puntenaantal >= 42) {
	System.out.println("GEFELICITEERD\n"); 
	System.out.println("U bent geslaagd voor de propaedeuse\n"); 
}
else { 
	System.out.println("Helaas, u bent niet geslaagd.\n"); 
	System.out.println("Volgende keer beter\n"); 
}  

M.b.v. geneste if-else statements kunnen we kiezen uit meer dan twee mogelijkheden.

Het probleem van de zwevende else

Een problematisch geval is het onderstaande. Bij welk if-statement hoort de else in het linker voorbeeld ? In dit geval hoort de else bij het tweede if-statement [if (x < 0)]. Hoewel de vormgeving van de tekst iets anders suggereert, maar de compiler kijkt niet naar de vormgeving. Als dit niet de bedoeling is gebruik dan accolades zoals in het rechter voorbeeld.

if (x < 5)
    if (x < 0) 
        positief = false;
else 
    y = 4;
if (x < 5) {
    if (x < 0) 
        positief = false;
}
else 
   y = 4;

Het switch statement

Als het aantal keuzemogelijkheden groot wordt dan is er een iets compacter alternatief voor het if-else statement. Neem bijv. aan dat met de dagen van de week wordt gewerkt. We kunnen daarvoor een integer gebruiken die de waarden 0 t.m. 6 kan hebben. Maar bij het afdrukken wil je een dag bij voorkeur met zijn naam aanduiden. Dat kan met if-else als volgt

int dag; 
System.out.print("Geef het dagnummer: "); 
System.out.flush();
dag = System.in.read();
if (dag == 1) 		System.out.println("maandag"); 
else if (dag == 2) 	System.out.println("dinsdag"); 
else if (dag == 3) 	System.out.println("woensdag"); 
else if (dag == 4) 	System.out.println("donderdag"); 
else if (dag == 5) 	System.out.println("vrijdag"); 
else if (dag == 6) 	System.out.println("zaterdag"); 
else if (dag == 7) 	System.out.println("zondag"); 
else 			System.out.println("dagnummer bestaat niet"); 

Het alternatief is

int dag; 
System.out.print("Geef het dagnummer: "); 
System.out.flush();
dag = System.in.read();
switch (dag) { 
	case 1: System.out.println("maandag "); 	break; 
	case 2: System.out.println("dinsdag "); 	break; 
	case 3: System.out.println("woensdag "); 	break; 
	case 4: System.out.println("donderdag "); 	break; 
	case 5: System.out.println("vrijdag "); 	break; 
	case 6: System.out.println("zaterdag "); 	break; 
	case 7: System.out.println("zondag "); 		break; 
	default: System.out.println("dagnummer " + dag + " bestaat niet"); 
} 

Het effect van een switch:

  1. Evalueert de expressie tussen haakjes, in het voorbeeld (dag).
  2. Gaat naar het case-label met de constante waarde die gelijk is aan die van de expressie uit 1. Als geen label met die waarde aanwezig is gaat dan naar het default-label, en als die ook ontbreekt eindigt de switch.
  3. Beëindigt de switch als een break-statement optreedt. Gaat anders door tot het eind van het switch-statement.

Het switch-statement wordt na uitvoering van het laatste case-statement automatisch verlaten. Het break-statement mag daar weggelaten worden. Dat geldt niet voor de andere break-statements. Als we alle breaks uit het voorbeeld verwijderen en dag heeft de waarde 0 dan worden na elkaar alle dagen van de week èn het default-statement afgedrukt. Heeft dag de waarde 5 dan wordt afgedrukt "vrijdag zaterdag zondag dagnr 5 bestaat niet".

Er kunnen meerdere case-labels, gescheiden door een dubbele punt, per case-statement aanwezig zijn, bijv.

switch(karakter) { 
	case 'a': case 'A': statement1; statement2; break; 
	case 'b': case 'B': statement3; break; 
} 

Dus als een kleine letter 'a' of hoofdletter 'A' is ingetypt dan worden de statements 1 en 2 uitgevoerd.

De keuze operator ? :

Als er een keuze gemaakt wordt , wordt meestal een if of if ..else structuur gebruikt. Het kan echter veel korter met de keuze operator, zoals in dit voorbeeld

 straal =  r >= 0 ? r : 0 ; // als r >= 0 dan straal = r anders straal = 0

Hier staat is compacte vorm:

if ( r >= 0) 
   straal = r; 
else 
   straal = 0 ; 

Voordat de keuze operator wordt uitgevoerd wordt er een typecast uitgevoerd.

int a = 10;
double d = 2.1;
System.out.println( a > 5 ? a : d );  // geeft 10.0 

Omdat de typecast naar double wordt uitgevoerd opdat alle elementen van de keuze operator gelijk zijn.

copyright © Little World 1997