H10 Beslissingen

Leerdoelen

Na het bestuderen van dit hoofdstuk wordt van je verwacht dat je:

  • de relationele operatoren <, >, ==, <=, >=, != kent en kunt toepassen
  • een if en if-else statement kunt toepassen
  • de logische operatoren &&, ||, en ! kunt kent en kunt toepassen
  • weet hoe je een switch-statement kunt toepassen

Praktijk

Relationele operatoren

Een relationele operator vergelijkt twee waarden met elkaar. Deze waarde kan van alles zijn: twee doubles, een int met het resultaat van een bewerking, twee strings, enzovoorts. Zo kan een relationele operator vragen of de ene waarde groter is dan de andere waarde. Er zijn maar twee antwoorden mogelijk, ja of nee of in Java: true of false. Deze twee waarden vormen samen een apart primitief, de boolean. (Zie bijlage II)
Dit zijn de relationele operatoren:

Operator Betekenis
< Kleiner dan
> Groter dan
== Gelijk aan
<= Kleiner dan of gelijk aan
>= Groter dan of gelijk aan
!= Niet gelijk aan

Let erop dat de logische operator == iets anders is dan de toekenningsoperator of assignment =. In het eerste geval gaat het om een vergelijking tussen twee waarden, in het tweede geval wordt een waarde toegekend aan een variabele.
Een voorbeeld:

// Voorbeeld 10.1

import java.awt.*;
import java.applet.*;


public class Beslissingen extends Applet {
	
  public void init() {}
	

  public void paint(Graphics g) {
    g.drawString("" + 8 + " is groter dan " + 5 + ": " + (8 > 5), 50, 60 );
    g.drawString("" + 8 + " is kleiner dan " + 5 + ": " + (8 < 5), 50, 80 );
  }
}

De uitvoer van dit programma is:
8 is groter dan 5: true
8 is kleiner dan 5: false
Door de uitdrukking (8 > 5) te evalueren, komt Java tot de conclusie, dat dat waar is en geeft true terug. De evaluatie van (8 < 5) levert niet waar op en dan geeft Java false terug.

Het if-else-statement

Het kan voorkomen in programma's dat een keuze moet worden gemaakt of een opdracht moet worden uitgevoerd of niet, of dat een bepaalde opdracht wel en een andere niet uitgevoerd moet worden. In het eerste geval gebruiken we alleen een if-statement:

// Voorbeeld 10.2

import java.awt.*;
import java.applet.*;
import java.awt.event.*;


public class Beslissingen2 extends Applet {		

    int leeftijd;
    TextField tekstvak;
    Label label;
    String tekst;
	
    public void init() {
        tekstvak = new TextField("", 5);
        tekstvak.addActionListener( new VakListener() );
        tekst = "";
		
        label = new Label("Geef uw leeftijd in en druk op enter" );
		
        add( label );
        add( tekstvak );	
    }

    public void paint(Graphics g) {
        g.drawString(tekst, 50, 45 );
    }
	
    class VakListener implements ActionListener {
        public void actionPerformed( ActionEvent e ) {
            String s;
			
            s = tekstvak.getText();
            leeftijd = Integer.parseInt( s );
            if ( leeftijd > 20 ) {
                tekst = "U bent meerderjarig.";
                repaint();
            }		
        }
    }
}

Hier staat dat als de leeftijd groter is dan 20 op het scherm U bent meerderjarig moet verschijnen en als de leeftijd 20 of lager is, dan gebeurt er niets. Dit programma werkt niet helemaal correct. Als het programma uitgevoerd wordt en de gebruiker tikt bijvoorbeeld 12 in, dan gebeurt er niets. Dat is correct. Nu tikt de gebruiker 23 in en de tekst U bent meerderjarig verschijnt op het scherm. Ook dat is juist. Maar tikt de gebruiker nu 12 in, dan blijft op het scherm U bent meerderjarig staan en dat is niet juist. Blijkbaar moet er toch iets gebeuren als iemand niet meerderjarig is. Het programma moet uitgebreid worden:

if ( leeftijd > 20 ) {
    tekst = "U bent meerderjarig.";
    repaint();
}
else {
    tekst = "U bent minderjarig.";
    repaint();
}    

De uitbreiding begint met else { en eindigt met de laatste sluitaccolade }. Er staat nu dat als iemand 20 jaar of jonger is dan moet op het scherm komen te staan U bent minderjarig. Nu werkt het programma wel correct.
Toch kan er een kleine verbetering plaatsvinden. Zowel onder de if-tak als onder de else-tak staat repaint(). Dat moet in beide gevallen gebeuren, dus kan deze opdracht uit de if en else-tak gehaald worden en onderaan gezet worden. Dat levert de volgende code op:

if ( leeftijd > 20 ) {
    tekst = "U bent meerderjarig.";
}
else {
    tekst = "U bent minderjarig.";
}
repaint();

In voorbeeld 10.2 staat nog een regel die toelichting verdient:

    public void init() {
        tekstvak = new TextField("", 5);
        tekstvak.addActionListener( new VakListener() );
        tekst = "";
        label = new Label("Geef uw leeftijd in en druk op enter" );
        add( label );
        add( tekstvak );	
    }

Als deze regel er niet staat, is er sprake van dat tekst een null-string is. En een null-string kan niet naar het scherm geschreven worden. Hij heeft nog geen adres in het geheugen gekregen en dus is het object nog niet in het geheugen aangemaakt. Vandaar dat er een lege string van gemaakt moet worden zodat het object tekst aangemaakt wordt. De volgorde is namelijk dat eerst init() uitgevoerd wordt, vervolgens paint() en pas als op de entertoets is gedrukt, wordt VakListener() uitgevoerd. Dus de eerste keer dat paint() uitgevoerd wordt, mag tekst geen null-string zijn en daarom staat deze regel in init().

Logische operatoren

Helaas is het leven niet zo eenvoudig dat we vaak kunnen volstaan met één voorwaarde. Alleen al om te bepalen of een jaar een schrikkeljaar is of niet hebben we drie voorwaarden nodig: Ten eerste moet het jaartal deelbaar zijn door 4, ten tweede mag het jaartal niet deelbaar zijn door 100, maar - en dat is de derde voorwaarde - mag het jaartal wel door 400 deelbaar zijn. Door gebruik te maken van logische operatoren kunnen we voorwaarden met elkaar combineren. Er zijn drie logische operatoren:

Voor een overzicht hiervan zie de tabellen in bijlag IV.
Het onderstaande voorbeeld volgt de en-tabel in bijlage IV.

// Voorbeeld 10.3

import java.awt.*;
import java.applet.*;

public class Beslissingen extends Applet {
	
  public void init() {}

  public void paint(Graphics g) {
    g.drawString("" + 6 + " is groter dan "+ 5 + " en kleiner dan " + 
        8  + ": " +(6 > 5 && 6 < 8), 50, 60 );
    g.drawString("" + 6 + " is groter dan "+ 5 + " en groter dan " + 
        8 + ": " + (6 > 5 && 6 > 8), 50, 80 );
    g.drawString("" + 6 + " is kleiner dan "+ 5 + " en groter dan " +
        8 + ": " + (6 <  5 && 6 > 8), 50, 100 );
    g.drawString("" + 6 + " is kleiner dan "+ 5 + " en kleiner dan " + 
        8 + ": " + (6 < 5 && 6 < 8), 50, 120 );
    }
}

Als je de && vervangt door ||, dan volgt het programma de of-tabel in bijlage IV.

De volgende regels betreffen de niet-operator. De voorwaarde waarvan het resultaat gewijzigd moet worden, staat achter de operator tussen ronde haken. Vervang alle regels paint() door de volgende, dan volgt het programma de niet-tabel in bijlage IV:

g.drawString("" + 6 + " is groter dan " + 5 + ": " + 
  (!(6 > 5)), 50, 60 );
g.drawString("" + 6 + " is kleiner dan " + 5 + ": " + 
  (! (6 < 5)), 50, 100 );

Nu een ingewikkelder voorbeeld, waarin de logische operatoren worden gecombineerd: Welke jaren zijn schrikkeljaar en welke niet?
Eerst de broncode:

// Voorbeeld 10.4

import java.awt.*;
import java.applet.*;
import java.awt.event.*;


public class Schrikkeljaar extends Applet {
    TextField tekstvak;
    Label label;				
    String s, tekst;
    int jaartal;
	
    public void init() {
        tekstvak = new TextField("", 20);
        label = new Label("Type een jaartal en druk op enter");
        tekstvak.addActionListener( new TekstvakListener() );
        tekst = "";
        add(label);
        add(tekstvak);
    }

    public void paint(Graphics g) {
        g.drawString(tekst, 50, 60 );
    }
	
    class TekstvakListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            s = tekstvak.getText();
            jaartal = Integer.parseInt( s);
            if ( (jaartal % 4 == 0 && !(jaartal % 100 == 0)) || 
            		jaartal % 400 == 0 ) {
                tekst = ""+ jaartal + " is een schrikkeljaar";
            }
            else {
                tekst = ""+ jaartal + " is geen schrikkeljaar";
            }
            repaint();
        }
    }
}

Het gaat natuurlijk om de regel:
if ( (jaartal % 4 == 0 && !(jaartal % 100 == 0)) || jaartal % 400 == 0 )
Als jaartal % 4 gelijk is aan 0, dan betekent dat dat het jaartal door 4 deelbaar is. Er is geen rest na de deling door 4.
jaartal % 100 moet ongelijk zijn aan nul. Het jaartal mag niet deelbaar zijn door 100. Let op het woordje niet en dus wordt de niet-operator gebruikt. Als deze twee voorwaarden (deelbaar door 4 en niet deelbaar door 100) beide waar zijn dan is er sprake van een schrikkeljaar. De en-operator moet dus onderling gebruikt worden. De ronde haken om deze voorwaarden zorgen ervoor dat deze twee voorwaarden samen geëvalueerd worden en als daar true uitkomt dan is er sprake van een schrikkeljaar. Echter als het jaartal deelbaar is door 400 en dus ook door 100 en door 4, dan komen de eerste twee voorwaarden met false. Vandaar het gebruik van de of-operator en de voorwaarde dat het jaar wel door 400 deelbaar mag zijn.

Tot slot: Zet altijd accolades om de body van het if en het else-statement. Als het om één regel gaat, mag je ze weglaten, maar bij meerdere regels in een body zijn ze verplicht.

Het switch-statement

Het switch-statement begint met switch en daarachter tussen ronde haken een variable van het type char, byte, short of int en String (sinds Java 7). Dus long, double en float kunnen niet gebruikt worden bij het swich-statement. Daarna volgen in de body omgeven door accolades de cases met daarachter de constante waarden. Na de constante volgt een ‘:’.

// Voorbeeld 10.5

import java.awt.*;
import java.applet.*;
import java.awt.event.*;


public class Switch extends Applet {
    TextField tekstvak;
    Label label;				
    String s, tekst;
    int dag;
	
    public void init() {
        tekstvak = new TextField("", 20);
        label = new Label("Type het dagnummer en druk op enter");
        tekstvak.addActionListener( new TekstvakListener() );
        tekst = "";
        add(label);
        add(tekstvak);
    }

    public void paint(Graphics g) {
        g.drawString(tekst, 50, 60 );
    }
	
    class TekstvakListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            s = tekstvak.getText();
            dag = Integer.parseInt( s);
            switch(dag) {
                case 1:
                    tekst = "zondag";
                    break;
                case 2:
                    tekst = "maandag";
                    break;
                case 3:
                    tekst = "dinsdag";
                    break;
                case 4:
                    tekst = "woensdag";
                    break;
                case 5:
                    tekst = "donderdag";
                    break;
                case 6:
                    tekst = "vrijdag";
                    break;
                case 7:
                    tekst = "zaterdag";
                    break;
                default:
                    tekst = "U hebt een verkeerd nummer ingetikt ..!";
                    break;
            }
            repaint();
        }
    }
}

De broncode spreekt voor zich. Alleen het default-statement dient verklaard te worden: Als er iets wordt ingetikt dat niet gelijk is aan één van de constante waarden achter de cases, dan wordt default aangeroepen en worden de regels daaronder uitgevoerd. In dit geval wordt de waarschuwing gegeven, dat er een verkeerd nummer is ingetikt. Default is niet verplicht.

Opdracht 10.1

Schrijf een applet, waarin de gebruiker getallen kan intikken en op het scherm bijgehouden wordt welk getal het hoogst is.

Opdracht 10.2

Breid de applet uit opdracht 1 zo uit dat ook het laagste getal bijgehouden wordt.

Opdracht 10.3

Schrijf een applet, waarin het maandnummer ingetikt wordt en de maandnaam en het aantal dagen wordt getoond.

Opdracht 10.4

Breid de applet zo uit, dat ook het jaar ingegeven kan worden en aan de hand daarvan wordt bepaald of het om een schrikkeljaar gaat om het juiste aantal dagen voor februari te kunnen vaststellen.

Opdracht 10.5

Schrijf een applet, waarin de gebruiker zijn cijfers kan invoeren en wordt getoond of het cijfer voldoende of onvoldoende is. Tevens wordt het gemiddelde bijgehouden. Zodra de gebruiker op de Ok-knop klikt, wordt getoond wat het gemiddelde is en of de leerling geslaagd is.

Praktijkopdracht

Schrijf een applet in Java waarin een cijfer ingevoerd wordt en in het venster van de applet wordt getoond of het cijfer slecht, onvoldoende, matig, voldoende of goed is. Als er een cijfer wordt ingevoerd dat niet in de onderstaande rij voorkomt, dan moet er een waarschuwing getoond worden dat er een verkeerd cijfer is ingevoerd.

De cijfers 1, 2 en 3 zijn slecht, het cijfer 4 is onvoldoende, het cijfer 5 is matig, de cijfers 6 en 7 zijn voldoende, de cijfers 8, 9 en 10 zijn goed.