Fundamentals of programming studiegebied handelswetenschappen en bedrijfskunde bachelor in de toegepaste informatica campus Kortrijk academiejaar 2022-2023
Legende van de gebruikte iconen
Legende van de gebruikte iconen (Verwijder de iconen die je niet gebruikt uit deze lijst door te kiezen voor ‘Rijen verwijderen’ wanneer je in het te verwijderen veld staat.)
Extra informatie Dit is geen leerstof, maar dient om een aantal zaken te duiden. Tip / Opgelet
Aanvullende cursus Fundamentals of Programming
1
Inleiding
Inhoud
Legende van de gebruikte iconen .................................................................................................. 1 1
Inleiding ......................................................................................................................... 7
1.1
De Java-omgeving ..................................................................................................................... 7
1.1.1
Editeren ..................................................................................................................................... 7
1.1.2
Compileren ................................................................................................................................ 7
1.1.3
Laden......................................................................................................................................... 8
1.1.4
Objectcode verifiëren ................................................................................................................ 8
1.1.5
Uitvoeren .................................................................................................................................. 9
1.2
De BlueJ-omgeving ................................................................................................................. 10
1.3
Situering en omschrijving van software ................................................................................. 13
1.3.1
Fasen in het automatiseringsproces ....................................................................................... 13
1.3.2
Fasen in het ontstaan van een programma ............................................................................ 14
1.4
Objecten en klassen ................................................................................................................ 16
1.4.1
Objectgeoriënteerde taal versus procedurele taal ................................................................. 16
1.4.2
Objecten creëren ..................................................................................................................... 17
1.5
De main()-methode ................................................................................................................ 18
1.5.1
Waarom we een main()-methode nodig hebben.................................................................... 18
1.5.2
Een klasse met een main()-methode ...................................................................................... 19
2
Basis ............................................................................................................................ 22
2.1
Inleiding .................................................................................................................................. 22
2.1.1
Eigenschappen van een algoritme .......................................................................................... 22
2.1.2
Omschrijving van programmalogica....................................................................................... 23
2.2
Basiselementen....................................................................................................................... 23
2.2.1
De flowchart............................................................................................................................ 23
2.2.2
Variabelen ............................................................................................................................... 28
2.2.3
Toekenningsopdrachten ......................................................................................................... 29
2.2.4
Input-output opdrachten ........................................................................................................ 29
2.2.5
Programmeerstijl .................................................................................................................... 34
2.2.6
Oefeningen.............................................................................................................................. 36
Aanvullende cursus Fundamentals of Programming
2
Inleiding
2.3
Basisstructuren ....................................................................................................................... 38
2.3.1
Gestructureerd programmeren............................................................................................... 38
2.3.2
Sequentiestructuur.................................................................................................................. 39
2.3.3
Selectiestructuur ..................................................................................................................... 41
2.3.4
Vergelijkingsopdrachten ......................................................................................................... 48
2.3.5
Herhalingsstructuur ................................................................................................................ 54
2.3.6
Hiërarchische relaties.............................................................................................................. 59
2.3.7
Oefeningen.............................................................................................................................. 60
3
Ontwerpen algoritmen ................................................................................................. 64
3.1
Probleemaanpak ..................................................................................................................... 64
3.1.1
Probleemdefinitie.................................................................................................................... 64
3.1.2
Gebruik van concrete voorbeelden ......................................................................................... 64
3.1.3
Overeenkomsten tussen problemen ....................................................................................... 65
3.2
Top-Down ontwerp................................................................................................................. 65
3.2.1
Inleiding .................................................................................................................................. 65
3.2.2
Hoofdzaken - detailzaken ....................................................................................................... 66
3.2.3
Onderverdeling in deelproblemen .......................................................................................... 66
3.2.4
Detailontwerp ......................................................................................................................... 69
3.3
Gevallenstudies....................................................................................................................... 69
3.3.1
Vooraf ..................................................................................................................................... 69
3.3.2
Somberekening ....................................................................................................................... 70
3.3.3
Faculteitberekening ................................................................................................................ 71
3.3.4
Grootste gemene deler ........................................................................................................... 74
3.4
Oefeningen ............................................................................................................................. 76
3.5
Oefeningen uitdagend ............................................................................................................ 78
4
Primitieve types ........................................................................................................... 79
4.1
Parameters en hun type ......................................................................................................... 79
4.2
Definities ................................................................................................................................. 79
4.2.1
Variabele ................................................................................................................................. 79
4.2.2
Literal ...................................................................................................................................... 79
4.2.3
Declaratie ................................................................................................................................ 79
Aanvullende cursus Fundamentals of Programming
3
Inleiding
4.3
Gehele getallen ....................................................................................................................... 80
4.3.1
Declaratie ................................................................................................................................ 80
4.3.2
Literal ...................................................................................................................................... 81
4.3.3
Toekenning..............................................................................................................................81
4.3.4
Bewerkingen ........................................................................................................................... 81
4.3.5
Type conversie......................................................................................................................... 84
4.3.6
Bewerkingen met byte en short .............................................................................................. 85
4.3.7
Regels voor wiskundige bewerkingen met variabelen van verschillende gehele types .......... 85
4.3.8
Mogelijke fouten ..................................................................................................................... 87
4.4
Reële getallen ......................................................................................................................... 87
4.4.1
Declaratie ................................................................................................................................ 87
4.4.2
Literal ...................................................................................................................................... 87
4.4.3
Toekenning..............................................................................................................................88
4.4.4
Bewerkingen ........................................................................................................................... 88
4.4.5
Type conversie......................................................................................................................... 89
4.4.6
Regels voor wiskundige bewerkingen met variabelen van verschillende reële types............. 89
4.4.7
Mogelijke fouten ..................................................................................................................... 89
4.5
Reële en gehele types door elkaar ......................................................................................... 90
4.5.1
Type conversie......................................................................................................................... 90
4.5.2
Regels voor wiskundige bewerkingen met variabelen van reële en gehele types .................. 90
4.6
Andere types ........................................................................................................................... 91
4.6.1
Karakters ................................................................................................................................. 91
4.6.2
Boolean ................................................................................................................................... 94
4.7
Goed om weten ...................................................................................................................... 94
4.7.1
De op= operator ...................................................................................................................... 94
4.7.2
Prioriteit en Associativiteit ...................................................................................................... 97
5
Testen van programma’s .............................................................................................. 99
5.1
Inleiding .................................................................................................................................. 99
5.2
Constructieve methoden ...................................................................................................... 100
5.2.1
Stapsgewijze testen .............................................................................................................. 100
5.2.2
Correctheidsvragen bij basisstructuren ................................................................................ 100
Aanvullende cursus Fundamentals of Programming
4
Inleiding
5.2.3
Systematische controles........................................................................................................ 102
5.3
Manuele test ......................................................................................................................... 102
5.3.1
Voorbeeld .............................................................................................................................. 103
5.4
Testbatterij............................................................................................................................ 103
5.4.1
Doel ....................................................................................................................................... 103
5.4.2
White box teststrategie ........................................................................................................ 104
5.4.3
Black box teststrategie.......................................................................................................... 108
5.4.4
Presentatie van een testbatterij ........................................................................................... 111
5.5
Kwaliteitscriteria voor programma’s .................................................................................... 112
5.5.1
Betrouwbaarheid .................................................................................................................. 112
5.5.2
Onderhoudbaarheid en aanpasbaarheid .............................................................................. 113
5.5.3
Doorzichtigheid ..................................................................................................................... 114
5.5.4
Efficiëntie .............................................................................................................................. 115
5.5.5
Gebruiksvriendelijkheid......................................................................................................... 116
5.6
Oefeningen ........................................................................................................................... 116
6
Strings.........................................................................................................................120
6.1
Inleiding ................................................................................................................................ 120
6.2
Creëren van String-objecten ................................................................................................. 120
6.2.1
Literal .................................................................................................................................... 120
6.2.2
Creatie van een String-object................................................................................................ 120
6.2.3
Strings zijn overanderlijk ....................................................................................................... 121
6.3
Operaties .............................................................................................................................. 121
6.3.1
Concatenatie (+).................................................................................................................... 121
6.4
Methoden ............................................................................................................................. 125
6.4.1
Vergelijken van strings .......................................................................................................... 125
6.4.2
Individuele karakters van een string raadplegen.................................................................. 128
6.4.3
Zoeken in een string .............................................................................................................. 130
6.4.4
Strings aanpassen ................................................................................................................. 134
6.5
StringBuffer ........................................................................................................................... 134
7
Zoek- en sorteeralgoritmen .........................................................................................136
7.1
Zoekmethoden...................................................................................................................... 136
Aanvullende cursus Fundamentals of Programming
5
Inleiding
7.1.1
Sequentieel zoeken ............................................................................................................... 136
7.1.2
Binair zoeken......................................................................................................................... 139
7.2
Sorteermethoden ................................................................................................................. 143
7.2.1
Sortering door selectie (selection sort) ................................................................................. 143
7.2.2
Bubblesort ............................................................................................................................. 145
7.2.3
Sortering door invoeging ...................................................................................................... 149
7.3
Oefeningen ........................................................................................................................... 151
Aanvullende cursus Fundamentals of Programming
6
Inleiding
1 Inleiding 1.1 De Java-omgeving Een Java-programma ondergaat een aantal stappen vooraleer het uitgevoerd kan worden.
1.1.1 Editeren
schijf
teksteditor
.java-files
Figuur 1 - Fase 1: editeren
Een programmeur schrijft het programma m.b.v. een teksteditor en slaat het programma op, op schijf. De bestandsnamen voor een Java-programma hebben altijd de extensie .java. Deze extensie duidt aan dat het bestand Java-code bevat. Concreet zal in de oefeningen gebruik worden gemaakt van de BlueJ-omgeving die een teksteditor bevat. Later zal ook een professionele ontwikkelingsomgeving gebruikt worden. De teksteditor in BlueJ is gebruiksvriendelijker dan de standaard teksteditor van Windows, notepad. De teksteditor is ook geïntegreerd in een omgeving om Java-programma’s te schrijven, wat een aantal fases in het creëren van Java-programma’s vereenvoudigt. De teksteditor van een professionele ontwikkelingsomgeving (zoals Netbeans, IntelliJ, Eclipse, …) biedt nog meer mogelijkheden dan deze van BlueJ. Daarom zal na verloop van tijd overgestapt worden naar deze meer gespecialiseerde teksteditor, die uiteraard ook geïntegreerd is in een Java-omgeving.
1.1.2 Compileren
schijf
compiler
schijf
.java-files
.class-files
(Java Broncode)
(Java Bytecode)
Figuur 2 - Fase 2 Compileren
Aanvullende cursus Fundamentals of Programming
7
Inleiding
Het .java-bestand dat de Java-code bevat moet omgezet worden naar instructies die, in dit geval, begrepen worden door een interpreter. Het omzetten noemen we compileren, het resultaat van de omzetting noemen we Java Bytecode of Objectcode. Het gebruik van een tussenliggende taal (Java Bytecode) is typisch aan Java. De veel andere (object georiënteerde) talen zullen hun code laten omzetten naar machinecode die direct begrijpbaar is voor de computer. Java-code daarentegen wordt omgezet naar een tussenliggende taal, die machineonafhankelijk is, en dus ook nog geïnterpreteerd moet worden zodat de machine ze uiteindelijk kan uitvoeren. Het grote voordeel hiervan is dat Java-programma’s zonder deze te hercompileren van de ene computer naar de andere computer kunnen overgedragen worden. Het nadeel is dat er steeds een Java Virtual Machine moet aanwezig zijn en dat het programma trager zal lopen omdat het telkens geïnterpreteerd moet worden. De Java Virtual Machine is echter zo compact en het interpreteren verloopt alsmaar vlotter, waardoor deze nadelen dikwijls niet opwegen tegenover het grote voordeel dat de code machineonafhankelijk is.
1.1.3 Laden Geheugen Java Virtual
schijf
Machine
lader
.class-files (Java Bytecode)
Figuur 3 - Fase 3: laden
De .class-files worden in de Java Virtual Machine, die zich in het geheugen bevindt, geladen.
1.1.4 Objectcode verifiëren verificatie van de Java Bytecode
Geheugen Java Virtual
schijf lader
Machine
.class-files (Java Bytecode)
Figuur 4 - Fase 4:objectcode verifiëren
Aanvullende cursus Fundamentals of Programming
8
Inleiding
In een 4de stap wordt de Java Bytecode geverifieerd. Deze verificatie verzekert dat de bytecode geldig is en dat de code niet ingaat tegen de veiligheidsregels van Java.
1.1.5 Uitvoeren Geheugen Java Virtual
Operating
Machine
communicatie
Java Interpreter
System
Figuur 5 - Fase 5: uitvoeren
In de laatste stap wordt het programma uitgevoerd. Het is de Java Interpreter, onder controle van het besturingssysteem, die ervoor zorgt dat de Java bytecode geïnterpreteerd wordt, en dus acties uitvoert.
Aanvullende cursus Fundamentals of Programming
9
Inleiding
1.2 De BlueJ-omgeving
Figuur 6 - De teksteditor van BlueJ
Om een Java-programma te schrijven in BlueJ wordt gebruik gemaakt van de teksteditor die in de omgeving aanwezig is. Nadat de code geschreven is kan de code gecompileerd worden. Wanneer de compilatie lukt krijg je onderaan de boodschap “Class compiled – no syntax errors”. In het andere geval wordt aangegeven waar de syntaxfouten zitten. Het laden en verifiëren van de objectcode gebeurt achter de schermen op het moment dat er gevraagd wordt om het programma uit te voeren. In het begin zullen programma’s in BlueJ niet als een geheel worden uitgevoerd. Er zullen m.b.v. de omgeving, die om didactische redenen zo geschreven is, slechts stukjes code van het programma uitgevoerd worden. Merk op dat het uitzonderlijk is dat er stukjes code kunnen uitgevoerd worden, zonder dat het programma (de main()-methode) gestart is. Dit is typisch aan BlueJ, niet aan Java! Normaal gebeurt het laden, verifiëren en uitvoeren met het starten van de main()-methode, waardoor alles in één keer geladen en geverifieerd wordt. Wanneer slechts stukjes code worden uitgevoerd (creëren van een object,
Aanvullende cursus Fundamentals of Programming
10
Inleiding
uitvoeren van een methode op een object) moet ook telkens de objectcode geladen, geverifieerd en uitgevoerd worden.
Figuur 7 - Een object creëren
Om een object te creëren klik je op de rechter muisknop en selecteer je de optie new Circle(). Op
dat moment wordt de objectcode geladen, geverifieerd en uitgevoerd (geïnterpreteerd).
Een methode op een object uitvoeren doe je bijvoorbeeld door met de rechter muisknop op een cirkelobject te klikken en een optie (methode) te selecteren.
Aanvullende cursus Fundamentals of Programming
11
Inleiding
Figuur 8 - Een methode uitvoeren op een object
Extra informatie 1.3 Situering en omschrijving van software is ‘extra informatie’.
Aanvullende cursus Fundamentals of Programming
12
Inleiding
1.3 Situering en omschrijving van software 1.3.1 Fasen in het automatiseringsproces Het ontwikkelen van een softwarepakket voor het automatiseren van bedrijfstaken is een moeilijke en veelomvattende opdracht. Vooraleer kan gestart worden met het maken van de computerprogramma's zelf, is een uitvoerige voorafgaande studie van het informatiesysteem vereist. Deze taak wordt toevertrouwd aan specialisten, namelijk systeemanalisten. Aan het ontwikkelingsproces werken bijgevolg meerdere mensen mee. Om de taken beter te kunnen overzien en beter in de hand te houden, wordt het ontwikkelingstraject opgedeeld in fasen. Tijdens elke fase moeten er bepaalde activiteiten worden uitgevoerd. Om deze cursus te kunnen situeren in de totaliteit van een automatiseringsproject, wordt een globaal overzicht gegeven van de verschillende fasen van systeemanalyse.
1.3.1.1 Vooronderzoek Loont het echt de moeite? Een vooronderzoek is erop gericht aan de topleiding voldoende gegevens te verschaffen opdat deze zou kunnen oordelen of men al dan niet een automatiseringsproces in gang zal zetten.
1.3.1.2 Definitiestudie Welke zijn de informatiebehoeften van de gebruikers? Na de acceptatie van het vooronderzoek wordt nagegaan welke de informatiebehoeften van de gebruikers zijn om het nieuwe systeem te ontwikkelen. Een belangrijke stelling bij het ontwikkelen van software is: “Het is het informatiesysteem dat zich moet aanpassen aan de wensen van de gebruiker en niet de gebruiker die zich moet aanpassen aan de werking van het informatiesysteem”.
1.3.1.3 Logisch ontwerp WAT kunnen we van het nieuwe informatiesysteem verwachten? Deze fase is gericht op de gebruikers en beschrijft welke gegevens en functies het nieuwe pakket zal bevatten. Men kiest ook in grote lijnen de apparatuur waarop het softwarepakket moet draaien.
1.3.1.4 Technisch ontwerp HOE moet het nieuwe informatiesysteem eruit zien? Deze fase is gericht naar de programmeur en beschrijft hoe de gegevens worden opgeslagen in bestanden of databases, hoe de functies worden opgedeeld in programma's en hoe de menu's, schermen en rapporten eruit zien. Van elk programma wordt een programmabeschrijving opgesteld en het resultaat van ontwerp wordt volledig beschreven in een analysedossier.
1.3.1.5 Realisatie Het aanmaken van programma's.
Aanvullende cursus Fundamentals of Programming
13
Inleiding
Slechts na een goedgekeurd analysedossier kan gestart worden met de programmering. Het is in deze fase dat ‘programmalogica’ zich situeert. De activiteiten in deze fase worden uitvoeriger behandeld in de volgende paragraaf.
1.3.1.6 Testen Is het pakket correct en aanvaardbaar? Nu kunnen alle programma's worden samengebracht en wordt getest of het geheel correct is. Ook de gebruiker gaat na of hij krijgt wat hij van het softwarepakket verlangde.
1.3.1.7 Implementatie Het nieuwe systeem invoeren. Na goedkeuring door de gebruiker kan het pakket geïnstalleerd worden, de gebruikers opgeleid worden en het bestaande (nog manueel of reeds geautomatiseerde) systeem geconverteerd worden.
1.3.1.8 Systeembeheer Voldoet het systeem aan de huidige eisen? Zoals elk product zijn ook geautomatiseerde informatiesystemen aan veroudering onderhevig en moeten de programma's worden aangepast. Op de duur kunnen die wijzigingen zeer drastisch worden. In een dergelijk geval is er geen sprake meer van onderhoud, maar moet de volledige cyclus van vooronderzoek, definitiestudie, ontwerp, realisatie, testen en implementatie opnieuw worden doorlopen (“software life cycle”). Deze materie wordt uitvoerig behandeld in het vak ‘Analysis & Design’.
1.3.2 Fasen in het ontstaan van een programma De programma's worden gemaakt op basis van de systeemspecificaties in het analysedossier. Vooraleer een programma operationeel is, dient heel wat werk geleverd te worden.
1.3.2.1 Instuderen van de programmaspecificaties Om tot een goed programma te komen is het van allergrootste belang dat de programmeur de programmaspecificaties uit het analysedossier zeer goed begrijpt. Als niet precies geweten is waarvoor een programma moet geschreven worden, is de kans op het vinden van een goede oplossing wel heel erg klein.
1.3.2.2 Probleem opdelen in deelcomponenten Afhankelijk van de complexiteit wordt het probleem opgesplitst in deelcomponenten die afzonderlijk kunnen worden opgelost. Bij objectgeoriënteerd programmeren zijn deze componenten en subcomponenten objecten (en daarmee klassen en methodes).
Aanvullende cursus Fundamentals of Programming
14
Inleiding
1.3.2.3 Ontwerpen van het algoritme Steunend op de specificaties uit het analysedossier wordt in deze activiteit de oplossingsmethode van een (deel)component stap voor stap uitgetekend. Hierin wordt de opeenvolging van operaties, die naar de oplossing van een gesteld (deel)probleem leiden, vastgelegd. De beschrijving van de opdrachten waarmee men vanuit een gegeven beginsituatie een vooraf beschreven resultaat kan bereiken, wordt ook algoritme genoemd.
1.3.2.4 Coderen van het programma Een computer kan uit zichzelf niets bedenken. Dit apparaat volgt strikt een voorschrift op dat er door de mens is ingestopt. Zo'n voorschrift wordt een programma genoemd. Het programma is een algoritme (dat andere algoritmes aanroept) dat begrijpbaar is voor de computer, daarom moet het algoritme omgezet worden in code in een bepaalde programmeertaal, zoals vb. Java, Visual Basic, of vele andere.
1.3.2.5 Testen van het programma Een programma van iet of wat omvang zal slechts zelden onmiddellijk zonder fouten geprogrammeerd worden. Een goede programmeur is niet alleen iemand die weinig programmafouten maakt, maar ook iemand die gemakkelijk zijn fouten kan opsporen. In de eerste plaats wordt het programma getest op syntactische fouten. Deze fouten komen tot uiting tijdens de vertaling van het programma en worden door de compiler ontdekt. Als het programma zonder syntactische fouten is, wordt de uitvoering ervan uitgetest aan de hand van testgegevens De oorzaak van deze fouten ligt niet zoals bij de vorige soort fouten enkel bij het coderen van het programma, maar meestal bij het opstellen van algoritmes. Dit zijn de moeilijkste soort fouten.
1.3.2.6 Documenteren van het programma Er gaat in de computerwereld zeer veel tijd en geld verloren door gebrek aan degelijke documentatie, zowel qua gebruik als onderhoud van het programma. Zonder degelijke programmadocumentatie is een programma bijna niet meer aan te passen. Dat is voor een onderneming onaanvaardbaar, want informatiebehoeften kunnen en zullen worden aangepast. Daarom is een degelijke documentatie onontbeerlijk.
Aanvullende cursus Fundamentals of Programming
15
Inleiding
1.4 Objecten en klassen 1.4.1 Objectgeoriënteerde taal versus procedurele taal
Auto starten
Een procedurele taal maakt het de programmeur mogelijk
Is de wagen gesloten?
ja
een programma te schrijven dat bestaat uit procedures. Dit zijn stukken code die verschillende keren kunnen aangeroepen worden. De uitvoering van een procedureel
Neem de sleutels
neen
programma wordt gestuurd door opeenvolgende aanroepen naar deze procedures. Het programma eindigt
Open de deur van de wagen
als het klaar is met het aanroepen van zijn lijst procedures. In het voorbeeld hiernaast wordt getoond hoe het starten
Stap in de wagen
van een auto procedureel benaderd zou kunnen worden. De rechthoekjes zouden elk op zich een procedure kunnen
Is de wagen geschakeld?
ja
voortstellen, al hoeft dit niet noodzakelijk zo te zijn. Vooral stukken code die meerdere keren gebruikt worden, worden
Koppeling induwen en ontschakelen
in een procedure omgezet. De rechthoek ‘neem de sleutels’ neen
is hiervan een voorbeeld.
Neem de sleutels
Sleutel in stopcontact steken
Sleutel omdraaien in stopcontact neen Is de auto gestart? ja einde
Figuur 9 - Procedureel programmeren
Aanvullende cursus Fundamentals of Programming
16
Inleiding
In een object georiënteerde taal wordt geprobeerd de reële wereld voor te stellen in termen van objecten. Alles in de wereld kan voorgesteld worden met behulp van objecten. Een object georiënteerde taal concentreert zich op het creëren van objecten, het manipuleren van objecten en de objecten laten samenwerken. Hetzelfde voorbeeld om een auto te starten zou dan uit 2 objecten kunnen bestaan (zie hieronder). Een auto en een persoon. De objecten zullen samenwerken: de persoon zal uiteindelijk de
Figuur 10 - Objectgeoriënteerd programmeren
auto starten met de sleutel die hij op zak heeft. De objecten worden ook gemanipuleerd. De toestand van de auto zal steeds veranderen: de deur wordt geopend, de koppeling wordt ingedrukt, de motor wordt gestart, …
1.4.2 Objecten creëren Men stelde een reeks afspraken i.v.m. codering op. Het is sterk aangeraden deze afspraken te volgen, vooral omdat dit de leesbaarheid van de code sterk bevordert. In deze paragraaf worden twee afspraken gemaakt: klassen beginnen steeds met een hoofdletter, objecten starten altijd met een kleine letter. In de volgende paragraaf wordt over methoden gesproken. Daar geldt de afspraak dat methoden, net zoals objecten, beginnen met een kleine letter. Het samenstellen van een naam voor een object, klasse, methode, … gebeurt ook volgens afspraak. Wanneer de naam uit meerdere woorden bestaat worden deze aan elkaar geschreven. Elk nieuw woord begint met een hoofdletter.
Voorbeeld • • •
TicketMachine (klasse) eenTicketMachine (object) printTicket() (methode)
Voor meer informatie over de code-afspraken (coding conventions) kan men terecht op https://www.oracle.com/technetwork/java/codeconventions-150003.pdf
Aanvullende cursus Fundamentals of Programming
17
Inleiding
1.5 De main()-methode 1.5.1 Waarom we een main()-methode nodig hebben Wanneer we in BlueJ objecten willen maken en methoden willen uitvoeren dan doen we dit steeds via het dialoogvenster waarop een klassendiagram van het project te zien is. Door rechts te klikken op een klasse in dat diagram, kunnen we een constructor voor die klasse uitvoeren, waardoor er een object gecreëerd wordt. Dit wordt ook visueel voorgesteld door een object te tonen in de objectbench. Eens een object bestaat, kunnen methoden voor het object aangeroepen worden. Wanneer we echter over een programma spreken denken we meestal aan een toepassing die door eindgebruikers gestart wordt door dubbel te klikken op een pictogram of door de naam van de toepassing in een opdrachtregel in te voeren. Er moet dus iets bestaan dat kan aangeroepen worden, en dat ervoor zorgt dat er een aantal objecten worden gecreëerd en dat er methoden voor die objecten (kunnen) worden aangeroepen. De meeste toepassingen die we nu kennen zijn grafisch. Dit betekent dat wanneer het programma gestart wordt, er een scherm verschijnt met menu’s, knoppen, lijsten, … Er bestaan daarnaast ook programma’s die een aantal opdrachten uitvoeren en het resultaat op het scherm zetten, maar die niet gestuurd worden door het klikken op knoppen of het kiezen van bijvoorbeeld een menuonderdeel. Zulke programma’s worden console-programma’s genoemd. Deze cursus gaat over de fundamenten van object georiënteerd programmeren. Dit betekent dat de meeste aandacht gaat naar het schrijven van klassen en hoe objecten met elkaar interageren. Hier is het dus niet aan de orde om grafische user interfaces (GUI) te schrijven. Het gevolg is dat, wanneer we toepassingen schrijven, dit console-programma’s zullen zijn. Zoals hiervoor vermeld worden objecten tot nu toe steeds manueel gecreëerd (Het is te zeggen ze worden gecreëerd in de BlueJ-omgeving door zelf een constructor te laten uitvoeren). Dit kan geautomatiseerd worden. Het is mogelijk om code, die objecten creëert en manipuleert, in een centrale methode (de main()-methode) te zetten, en deze methode te laten uitvoeren. Wanneer we
dan nog een stap verder zouden gaan, dan kunnen we zelfs BlueJ volledig achter ons laten, en het programma laten starten door er dubbel op te klikken 1. De main()-methode moet, net zoals alle methoden, gedefinieerd worden in een klasse. Normaal
moet, vooraleer een methode kan aangeroepen worden, eerst een object gemaakt worden van die klasse. Bij de main()-methode ligt dit anders. Voor deze methode moet er niet eerst een object gemaakt worden, ze kan zomaar aangeroepen worden, zonder object.
1
Hier gaan we niet verder op in. Meer informatie kan gevonden worden in bijlage E in het boek Programmeren in Java met BlueJ
Aanvullende cursus Fundamentals of Programming
18
Inleiding
1.5.2 Een klasse met een main()-methode
Figuur 11 - Het klassendiagram
Stel dat we in het project figures altijd willen starten met een blauwe cirkel en een groene driehoek.
Aanvullende cursus Fundamentals of Programming
19
Inleiding
Wanneer we dit doen zonder main()-methode dan moeten verschillende stappen ondernemen om de cirkel en driehoek erop te krijgen. We moeten •
een cirkel maken (standaard is die blauw): new Circle()
•
de cirkel zichtbaar maken: rechts klikken op circle1 en kiezen voor makeVisible()
•
een driehoek maken: new Triangle()
•
de driehoek groen maken: rechts klikken op triangle1 en kiezen voor changeColor() en “green” meegeven als parameter
•
de driehoek zichtbaar maken: rechts klikken op triangle1 en kiezen voor makeVisible()
We kunnen hetzelfde resultaat ook verkrijgen door gebruik te maken van een main()-methode. Deze
methode wordt gedefinieerd in een nieuwe klasse, die we Hoofdklasse 2 zullen noemen. We klikken hiervoor op ‘new class’, en vullen voor ‘Class Name’ Hoofdklasse in.
In de main()-methode zullen we alle code schrijven om de cirkel en de driehoek te maken. Eenmaal
alle code geschreven en gecompileerd is, kunnen we in het dialoogvenster op de Hoofdklasse rechts
klikken en kiezen om de main()-methode uit te voeren. Op die manier worden de blauwe cirkel en
groene driehoek op het scherm getoond. De main()-methode moeten we zelf schrijven in de klasse
Hoofdklasse. Alle andere code in die klasse moeten we eerst verwijderen. De code voor de klasse Hoofdscherm ziet er als volgt uit: 1
public class Hoofdklasse {
2
public static void main(String[] args) {
3
Circle circle1 = new Circle();
4
circle1.makeVisible();
5
Triangle triangle1 = new Triangle();
6
triangle1.changeColor("green");
7
triangle1.makeVisible();
8 9
} } Figuur 12 - De code in de klasse Hoofdklasse
Merk op dat de regelnummers geen onderdeel van de code zijn!
2
De naam van deze klasse is willekeurig gekozen. Er is dus niets op tegen om deze een andere naam te geven.
Aanvullende cursus Fundamentals of Programming
20
Inleiding
De klasse Hoofdklasse wordt zoals elke klasse gedefinieerd door de volgende lijnen code public class Hoofdklasse { ... }
In de klasse wordt slechts één methode gedefinieerd. De header van deze methode ziet er steeds 3 als volgt uit (regel 2): public static void main(String args[])
De methode moet public zijn, omdat deze anders niet van buitenaf aangeroepen kan worden. Het
returntype is void, omdat deze methode geen waarde retourneert. De naam van de methode is main
en heeft één parameter. De parameter is een tabel van Strings. De methode is ook static. Het is
net doordat ze static is, dat ze kan aangeroepen worden zonder dat er een object van bestaat. De begrippen public, static en het gebruik van tabellen komt later aan bod.
Om de cirkel te maken roepen we de constructor op: new Circle(). Dit maakt een Circle-object en
kan dus toegekend worden aan een variabele (die het object zal vasthouden/bewaren). De toekenning ziet er als volgt uit: Circle circle1 = new Circle();
Daarna moeten we de cirkel nog zichtbaar maken. Dit doen we door de methode makeVisible() erop uit te voeren. In code ziet dat er als volgt uit: circle1.makeVisible();
We doen het analoge voor een driehoek: we maken die en kennen die toe aan een variabele (regel 5). Voor we de driehoek zichtbaar maken, geven we die eerst nog de kleur groen. Dit doen we door op de driehoek de methode changeColor() uit te voeren en mee te geven dat die groen moet zijn: triangle1.changeColor("green");
De laatste regel (regel 7) zorgt dat de driehoek wordt getoond.
3
De header van deze methode ligt vast. De minste verandering zal leiden tot een fout.
Aanvullende cursus Fundamentals of Programming
21
Basis
2 Basis 2.1 Inleiding 2.1.1 Eigenschappen van een algoritme Eerder zagen we dat een algoritme een opeenvolging is van opdrachten om vanuit een gegeven beginstiuatie een eindresultaat te bereiken. Nadat nagedacht werd over het algritme kan het omgezet worden in een programmeertaal, zoals Java. Volgend 'probleem' uit het dagelijkse leven laat toe de voornaamste eigenschappen van een algoritme af te leiden: veronderstel dat je de digirecorder wil instellen voor opname van de uitzending "Het ABC van de computer" die zal uitgezonden worden op de VRT op donderdag om 18.00u. Al naargelang de apparatuur en de mogelijkheden waarover je beschikt, zijn diverse oplossingen mogelijk. Volgens de handleiding van jouw digirecorder dien je bvb. als volgt te werk te gaan: 1
Zet digirecorder aan.
2
Kies het menu ‘opnemen’
3
Kies de zender
4
Ga naar de juiste dag en het juiste uur
5
Kies het programma
6
Kies ‘opnemen’
7
Geef aan hoeveel tijd voor het programma de digirecorder moet starten met de opname
8
Geef aan hoeveel tijd na het programma de digirecorder moet starten met de opname
Indien bovenstaande instructies nauwkeurig gevolgd worden, zou dit tot het gewenste resultaat moeten leiden. Het voorbeeld maakt volgende eigenschappen van een algoritme duidelijk: •
Het einddoel moet duidelijk bepaald zijn, bvb. een welbepaald TV-programma opnemen.
•
De beginsituatie moet vastgelegd zijn. bvb. er is toegang tot dedigirecorder mogelijk. Behalve de beschikbare apparatuur moeten eveneens alle gegevens - nodig om het einddoel te bereiken - exact gekend zijn, bvb. het op te nemen programma, de zender, de datum en het beginuur van de uitzending.
•
Alle opdrachten moeten ondubbelzinnig gedefinieerd zijn, bvb. Kies de zender.
Aanvullende cursus Fundamentals of Programming
22
Basis
•
Een algoritme is eindig, bvb. voor de programmering van de digirecorder zijn 7 stappen nodig.
•
De volgorde van de stappen is belangrijk, bvb. eerst moet je kiezen voor opnemen, vooraleer je de zender kiest.
Ook bij het opstellen van programma-algoritmen kunnen deze eigenschappen vooropgesteld worden.
2.1.2 Omschrijving van programmalogica Sommige opdrachten in een algoritme moeten na elkaar worden uitgevoerd, andere mogen slechts onder bepaalde voorwaarden worden uitgevoerd en delen van het algoritme moeten meerdere keren worden uitgevoerd. Een programma bevat dus veel structuur. Het is precies de doelstelling van deze cursus de logica of de structuur van algoritmes te ontdekken en voor te stellen. Daarmee start trouwens de voorbereiding van elk algoritme. De hoofddoelstelling van de volgende hoofdstukken is de studenten leren logisch en creatief nadenken bij het opbouwen van gestructureerde oplossingsschema’s (algoritmen). Na deze hoofdstukken moet de student in staat zijn vanuit een specifieke probleemstelling alle structuren en opdrachten van een methode (OOP) of procedure (procedurele taal) te bepalen als voorbereiding voor het schrijven van een programma in een willekeurige programmeertaal.
2.2 Basiselementen Extra informatie 2.2.1 De flowchart is ‘extra informatie’
2.2.1 De flowchart 2.2.1.1 Bepaling Een flowchart of stroomschema is een gedetailleerde, grafische voorstelling van de opeenvolging van operaties die naar de oplossing van een gesteld probleem leiden. In dit schema legt de programmeur de aard en de volgorde vast van de bewerkingen en de keuzehandelingen die door de computer moeten worden uitgevoerd. In de professionele wereld worden flowcharts nog maar weinig gebruikt, voor de beginnende softwarestudent kunnen ze echter van goudwaarde zijn, om de structuren te begrijpen.
2.2.1.2 Doel De flowchart wordt opgesteld om het verloop van de redenering die moet worden gevolgd teneinde een bepaald probleem op te lossen, op een duidelijke en ondubbelzinnige manier weer te geven. Aldus dient de voorstelling volgende kenmerken te hebben: •
klaar
Aanvullende cursus Fundamentals of Programming
23
Basis
•
overzichtelijk
•
volledig
•
verstaanbaar
•
vlot leesbaar
2.2.1.3 Symbolen Voor het uittekenen van een flowchart zullen we gebruik maken van de volgende symbolenset. 2.2.1.3.1
Symbolen met één ingang en één uitgang
Ingang
Een gegevensverwerking. Dit kan zowel een transport van Processing
gegevens in het geheugen zijn, als een wiskundige berekening
Uitgang
Ingang
Input-output
In- en uitvoeractiviteit
Uitgang
Aanvullende cursus Fundamentals of Programming
24
Basis
Ingang
Dit symbool sluit een stuk code in, waarvoor een afzonderlijk
Subroutine
stroomschema wordt uitgewerkt.
Uitgang
2.2.1.3.2
Symbool met één ingang en twee mogelijke uitgangen
Ingang De keuze van een bepaalde uitgang hangt af van het resultaat van de test (waar of niet waar).
Decision
Hierbij zal slechts één uitgang worden gekozen Uitgang
2.2.1.3.3
Uitgang
Symbolen met ofwel één ingang ofwel één uitgang
Bij het begin van een stroomschema Uitgang Terminal
Ingang
Aanvullende cursus Fundamentals of Programming
Aan het einde van een stroomschema
25
Basis
Bij het verlaten van een bladzijde, Ingang
met de vermelding van de volgende bladzijde.
Off-page connector Bij het binnenkomen van een Uitgang
2.2.1.3.4
nieuwe bladzijde, met vermelding van de vorige bladzijde.
Symbool in combinatie met een van voorgaande symbolen
Aanvullende omschrijving, verklaAnnotation
ring of commentaar
2.2.1.4 Voorbeeld Beschouw de activiteit van de bediende B van een pompstation. Wanneer er geen klanten zijn, gaat hij in een wachtkamertje zitten lezen of rusten. Wanneer een klant het pleintje komt opgereden, wordt zijn komst gemeld door een systeem met een automatische bel. Stel dat onderstaande figuur start op pagina 8 en verder gaat op pagina 9.
Aanvullende cursus Fundamentals of Programming
26
Basis
Bedienen pompstation
Klant wordt aangekondigd door belgerinkel
Dit betekent dat een wagen het pleintje komt opgereden
B begeeft zich naar de pomp
B bedient de klant 9
B vraagt naar de bestelling en bedient
8
de klant geeft een som geld
B bedient de klant ja ja
zijn er ondertussen klanten bijgekomen?
betaalt de klant met gepast geld?
neen
neen B geeft wisselgeld terug
B gaat terug naar het wachtkamertje
einde B bedankt de klant
return
Aanvullende cursus Fundamentals of Programming
27
Basis
2.2.1.5 Opmerking Het tekenen van flowcharts is arbeidsintensief en wordt vandaag in de praktijk zelden nog gebruikt om volledige programma’s voor te stellen. Ook hier in deze cursus zullen flowcharts enkel gebruikt worden om nieuwe elementen (opdrachten en basisstructuren) bij wijze van definitie visueel voor te stellen.
2.2.2 Variabelen Een programma laat de computer bewerkingen uitvoeren met gegevens uit het intern geheugen. Deze gegevens staan opgeslagen in geheugenzones of velden. Daar de inhoud van die geheugenzones voortdurend kan wijzigen, worden die geheugenzones ook variabelen genoemd. Variabelen worden gebruikt voor input (inputvariabelen), output (outputvariabelen) of tussentijdse bewerkingen (hulpvariabelen). Variabelen hebben een naam en een waarde. Voorbeeld:
21 btwTarief Bovenstaande variabele heeft als waarde ‘21’ en als naam ‘btwTarief’. Om met variabelen te kunnen werken moeten we deze kunnen aanduiden of identificeren. De naam van een variabele wordt ook een ‘identifier’ genoemd. Om de leesbaarheid van het programma te verhogen, is het aangewezen bij de keuze van de namen van de variabelen betekenisvolle namen te gebruiken. In verschillende programmeertalen (o.a. Java) geldt tevens een conventie tussen de programmeurs omtrent de schrijfwijze van de namen van variabelen: •
gebruik voor namen kleine letters;
•
indien een naam een samentrekking is van verschillende woorden (vb. btwTarief), staat het eerste woord in kleine letters en start elk volgend woord met een hoofdletter.
Variabelen slaan gegevens op van een zeker type zoals geheel getal, decimaal getal, tekst, … . Om variabelen te kunnen gebruiken moet bij de start van een methode worden aangegeven (‘declare’) wat de naam van de variabele is en welk type data de variabele vertegenwoordigt. Variabelendeclaratie vraagt aan de compiler om intern geheugen te reserveren voor het opslaan van de variabele van het betreffende type. De verschillende primitieve types worden verder besproken. Een variabele declareer je door eerst het type te vermelden en dan de naam van de variabele: double straal;
Aanvullende cursus Fundamentals of Programming
28
Basis
2.2.3 Toekenningsopdrachten Nadat een variabele is gedeclareerd, kan gedurende het programma een waarde aan de variabele worden toegekend met een toekenningsopdracht: variabele = expressie;
Een toekenningsopdracht bevat een toekenningsoperator (‘=’ -teken) en slaat de waarde van de rechterkant van de operator op in de variabele aan de linkerkant ervan. De rechterkant wordt een expressie genoemd. Dit kan een waarde zijn, een variabele of bewerkingen tussen meerdere variabelen en/of waarden. De meest voorkomende bewerkingen maken gebruik van de volgende wiskundige operatoren: + (optelling), - (aftrekking), * (vermenigvuldiging), / (deling), % (rest na gehele deling). Voor de eenvoud moet het type van de expressie overeen komen met het type van de variabele waaraan deze wordt toegekend.
Voorbeelden Opdracht
Betekenis
teller = 0;
teller krijgt als inhoud de waarde 0
grootste = getal;
de inhoud van getal wordt gekopieerd naar grootste
som = getal1 + getal2;
de som van de inhoud van getal1 en getal2 wordt in som geplaatst
teller = teller + 1;
de inhoud van teller wordt verhoogd met 1
voornaam = "Dirk";
voornaam krijgt als inhoud de tekst "Dirk"
2.2.4 Input-output opdrachten Een geheugenzone in het intern geheugen kan niet alleen een waarde krijgen door een toekenningsopdracht, maar ook door een inputopdracht. De input wordt verkregen door het binnenlezen van gegevens in het interne geheugen. Deze gegevens kunnen ofwel door de gebruiker via het toetsenbord worden ingebracht, ofwel kunnen de gegevens zich reeds op een bestand of database op het externe geheugen (meestal schijf) bevinden. Na verwerking van de gegevens moeten de resultaten - ook "output" genoemd - aan de gebruiker ter beschikking worden gesteld. Dit kan door de output ofwel rechtstreeks op het scherm af te beelden, ofwel naar de printer te sturen, ofwel weg te schrijven naar een bestand of database. In deze paragraaf, maar ook verder in deze cursus zullen we enkel de input en output behandelen die gebeurt via toetsenbord en beeldscherm.
Aanvullende cursus Fundamentals of Programming
29
Basis
2.2.4.1 Probleemstelling Schrijf een methode die 2 gehele getallen opvraagt en deze 2 getallen en de som ervan op het beeldscherm afbeeldt.
2.2.4.2 Opdrachten
(b) getal1 (b) toetsenbord
(d) getal2
(c)
(d) (d) beeldscherm
som interne geheugen (a)
(a) Uit de probleemstelling blijkt dat er 3 variabelen moeten gedeclareerd worden: int getal1, getal2, som;
(b) Voor het invoeren van gegevens vanaf het scherm en toetsenbord wenst de gebruiker tegenwoordig een mooie grafische userinterface (GUI). In het kader van de doelstelling van deze cursus hechten we geen belang aan de GUI en zullen we de gegevens inlezen via de main()-methode van ons programma. We zullen telkens een scanner moeten maken (hier sc), die in staat is om te lezen van System.in (input via toetenbord op de console). Scanner sc = new Scanner(System.in);
De volgende regel code laat toe om effectief een getal te lezen (met behulp van de scanner). We voeren de methode nextInt() uit op het Scanner-object sc. De methode levert het
ingelezen getal op.
getal = sc.nextInt();
Wanneer de computer deze handeling uitvoert, verschijnt enkel de cursor op het beeldscherm. Probleem hierbij is dat de gebruiker niet weet wat hij precies moet intikken bij Aanvullende cursus Fundamentals of Programming
30
Basis
het verschijnen van de cursor. Dit kan worden opgelost door deze inputopdracht te laten voorafgaan door de volgende printopdracht: System.out.println("Geef 2 getallen:");
System.out dient om naar te schrijven (analoog als System.in die gebruikt kan worden om van te lezen) en het resultaat komt op het beeldscherm terecht. Code voor het inlezen van een getal: import java.util.Scanner; public class Hoofdprogramma public static void main(String[] args) { Scanner sc = new Scanner(System.in); // declaratie int getal; //inlezen getal System.out.println("Geef een getal:"); getal = sc.nextInt(); //verwerking (meestal methode-oproep) ... } // einde methode main() }
// einde class voorbeeld
Concreet voor dit voorbeeld moeten we dus volgende code schrijven: import java.util.Scanner; public class Hoofdprogramma { public static void main(String[] args) { Scanner sc = new Scanner(System.in); // declaratie ... //inlezen beide getallen System.out.println("Geef 2 getallen:"); getal1 = sc.nextInt(); getal2 = sc.nextInt(); ... } //einde methode main() } / einde class Hoofdprogramma
Bij het lezen van beide getallen stockeert de computer die meteen in het interne geheugen in de variabelen. Aanvullende cursus Fundamentals of Programming
31
Basis
(c) Eenmaal de gegevens in het interne geheugen geplaatst zijn kan de computer ermee rekenen. Dikwijls zullen we de berekening of verwerking uitvoeren in een methode die we oproepen. De methode zorgt voor het eindresultaat. Concreet roepen we hier berekenSom() op, geven we de twee getallen die we eerdere inlazen mee aan de hand van twee parameters en retourneert de methode de gevraagde waarde, de som, die we toekennen aan de variabele som. som = berekenSom(getal1,getal2);
In de header van de methode moet er vóór het returntype static staan, zodat de methode
opgeroepen kan worden vanuit de main(), zonder dat er objecten gemaakt zijn. Herinner je dat methoden normaal enkel uitgevoerd worden op objecten. Dit is dus een uitzondering! /** * Som berekenen van twee getallen en som retourneren. * * @param x eerste getal om de som te bereken * @param y tweede getal om de som te bereken * @return som van de beide getallen */ public static int berekenSom(int x, int y) { int som; som = x + y; return som; }
//einde methode berekenSom()
(d) Ook voor de output maken we in het kader van de doelstelling van deze cursus abstractie van de GUI. De inhouden van de variabelen in het intern geheugen kunnen op het beeldscherm worden afgebeeld door hun naam te vermelden in een eenvoudige printopdracht. System.out.println(getal1 + " " + getal2 + " " + som);
2.2.4.3 Het volledig programma /** *
2 gehele getallen inlezen en deze 2 getallen en de som ervan op het
*
beeldscherm afbeelden
*
auteur: Katrien Deleu
*
versie: 1
*/ import java.util.Scanner; public class Hoofdprogramma{ public static void main(String[] args) {
Aanvullende cursus Fundamentals of Programming
32
Basis Scanner sc = new Scanner(System.in); // declaratie int getal1, getal2;
// 2 ingelezen getallen
int som;
// som van beide getallen
//inlezen beide getallen System.out.println("Geef 2 getallen:"); getal1 = sc.nextInt(); getal2 = sc.nextInt(); // bereken som door methode op te roepen som = berekenSom(getal1,getal2); // afbeelden beide getallen en som System.out.println(getal1 + " " + getal2 + " " + som); } //einde methode main() /** * Som berekenen van twee getallen en som retourneren. * * @param x eerste getal om de som te bereken * @param y tweede getal om de som te bereken * @return som van de beide getallen */ public static int berekenSom(int x, int y) { int som; som = x + y; return som; }
//einde methode berekenSom()
}// einde class Hoofdprogramma
Aanvullende cursus Fundamentals of Programming
33
Basis
2.2.5 Programmeerstijl Later zullen we bij de kwaliteitscriteria van programma’s zien dat bij het schrijven van programma’s moet gestreefd worden naar optimale leesbaarheid. Dit kunnen we bereiken door het toevoegen van commentaar en gebruik van indentatie en blokken. Een goede programmeerstijl is minstens even belangrijk als de code zelf.
2.2.5.1 Documentatie In het begin van een klasse is het wenselijk algemene commentaar te plaatsen met wat de klasse doet, de gebruikte datastructuren, de auteur, de versie, … Aan het begin van een methode wordt dan een beschrijving gegeven van wat de methode doet, de gebruikte parameters, het returntype, … Binnen de methode kan de betekenis van de gebruikte lokale variabelen en opdrachten toegelicht worden. Een commentaarregel wordt voorafgegaan door twee tekens ‘//’. Meerregelige commentaren
worden voorafgegaan door het tekenpaar ‘/*’ en afgesloten met het tekenpaar ‘*/’. In Java wordt in
een commentaarblok bij de aanvang van een methode elke lijn voorafgegaan door een '*'. De commentaren hebben geen enkel effect op de functionaliteit van de methode.
Voorbeeld: /* *
2 gehele getallen inlezen en deze 2 getallen en de som ervan op het
*
beeldscherm afbeelden
*
auteur: Katrien Deleu
*
versie: 1
*/ import java.util.Scanner; public class Hoofdprogramma{ public static void main(String[] args) { Scanner sc = new Scanner(System.in); // declaratie int getal1, getal2;
// 2 ingelezen getallen
int som;
// som van beide getallen
//inlezen beide getallen System.out.println("Geef 2 getallen:"); getal1 = sc.nextInt(); getal2 = sc.nextInt(); // bereken som door methode op te roepen Aanvullende cursus Fundamentals of Programming
34
Basis som = berekenSom(getal1,getal2); // afbeelden beide getallen en som System.out.println(getal1 + " " + getal2 + " " + som); } //einde methode main() /* * Som berekenen van twee getallen en som retourneren. * * @param x eerste getal om de som te bereken * @param y tweede getal om de som te bereken * @return som van de beide getallen */ public static int berekenSom(int x, int y) { int som; //bereken de som van de twee parameters som = x + y; //return de som return som; }
//einde methode berekenSom()
}// einde class Hoofdprogramma
2.2.5.2 Indentatie In volgend hoofdstuk zal blijken dat programmacode bestaat uit een combinatie van basisstructuren. Om het structureel verband tussen de programmeercomponenten visueel te benadrukken, wordt gebruikt gemaakt van ‘indentatie’. In plaats van alle opdrachten rechtlijnig onder elkaar te schrijven, wordt voor elke subcomponent 2 blanco posities meer ingesprongen dan de omvattende component.
2.2.5.3 Blokken Een blok is een groep van programmaopdrachten, omgeven door accolades. Er bestaan 2 populaire stijlen: ‘next-line’ stijl en de ‘end-of-line’ stijl.
Voorbeeld next-line stijl: if (getal1 > getal2) { som = getal1 + getal2; System.out.println(getal1+” ”+getal2+” ”+som); }
Voorbeeld end-of-line stijl: Aanvullende cursus Fundamentals of Programming
35
Basis if (getal1 > getal2) som
{
= getal1 + getal2;
System.out.println(getal1+” ”+getal2+” ”+som); }
Indien een blok slechts 1 opdracht bevat, moeten geen accolades geplaatst worden. In de rest van de cursus wordt de end-of-line stijl toegepast.
2.2.6 Oefeningen 1. Oefening op toekenningsopdrachten: a. Geef de variabele getal een waarde 90. b. Bepaal het quotiënt van wat in de variabele getal staat gedeeld door 15. c. Stockeer je naam en adres in het intern geheugen (≠ variabelen per apart gegeven). d. Verminder de variabele teller met 10. e. Plaats de tekst HOERA! in het geheugen. f.
Verhoog de variabele som met de waarde van de variabele getal.
g. Plaats in de variabele som dezelfde waarde als in de variabele getal. 2. Schrijf een methode die het aantal graden Fahrenheit (F) binnen krijgt als parameter en het overeenkomstig aantal graden Celsius (C) terug geeft. formule:
C=
5 (F − 32) 9
3. Schrijf een methode die het bedrag van een aankoop, het kortingspercentage dat de verkoper je toekent en het verschuldigde BTW-tarief als parameter binnenkrijgt en volgende kostennota afbeeldt: Aankoopbedrag
:(aankoop)
Bedrag korting
:(korting)
Bedrag BTW-exclusief :(bedrag) BTW-bedrag
:(btw)
Totaal BTW-inclusief
:(totaal)
4. Een variabele getal bevat een geheel getal. Schrijf één logische uitdrukking m.b.v. logische operatoren die waar oplevert als het getal ligt tussen 1 en 100 (grenzen inbegrepen) of negatief is, anders vals oplevert. 5. Een variabele jaar bevat een jaartal. Schrijf één logische uitdrukking m.b.v. logische operatoren die waar oplevert indien het jaartal een schrikkeljaar betreft, anders vals oplevert. Een jaar is een schrikkeljaar als het jaartal deelbaar is door 4; bovendien zijn jaartallen die deelbaar zijn door 100 en niet door 400 geen schrikkeljaren. 6. Schrijf een methode die teller en noemer van twee breuken als parameter neemt en daarna de som van beide breuken berekent en in breukvorm (dus teller/noemer) afbeeldt (het is niet nodig de meest vereenvoudigde vorm te bekomen).
Aanvullende cursus Fundamentals of Programming
36
Basis
7. Schrijf een methode die van een investering de huidige waarde, de intrestvoet en het aantal jaren als parameter neemt en daaruit de toekomstige investeringswaarde berekent en terug geeft. formule: toekomstige waarde = huidige waarde x (1 + intrestvoet)aantal jaren Gebruik voor de machtsberekening van ab de functie: Math.pow(a,b). 8. Schrijf een methode die het aantal uren, overuren en uurloon als parameter neemt en het brutoloon terug geeft. De overuren worden 50 % meer betaald dan de gewone uren.
Aanvullende cursus Fundamentals of Programming
37
Basis
2.3 Basisstructuren 2.3.1 Gestructureerd programmeren Het gebeurt zelden dat opdrachten in programma’s allen netjes na elkaar worden uitgevoerd. Vaak worden opdrachten uitgevoerd onder welbepaalde voorwaarden of het gebeurt ook dat opdrachten een aantal keren herhaald dienen te worden. Programmaopdrachten die ervoor zorgen dat de volgende opdracht die moet uitgevoerd worden niet de opdracht is die in het programma er juist onder staat, heten ‘controleopdrachten’. In de jaren 1960 was de belangrijkste controleopdracht de ‘go-to’ opdracht. Met deze opdracht kon de programmeur springen van de ene plaats naar bijna om het even welke andere plaats in het programma. Het zijn deze opdrachten die een soort niet-controleerbare kangoeroe-code en aldus onleesbare en moeilijk aanpasbare programma’s tot gevolg hebben. Het idee zat vastgeroest dat een programma goed is als voldaan wordt aan de opgelegde syntactische regels en als het de juiste resultaten aflevert. In de jaren 1970 wilde men afstand nemen van de zogenaamde ‘spaghetti-programmering’, en werd gesproken van gestructureerd programmeren, go-to-less programmeren, enz. Het onderzoek van Bohm en Jacopini heeft aangetoond dat alle programma’s kunnen geschreven worden zonder go-to opdrachten. Zij bewezen dat de logica of de structuur van elk programma kan opgebouwd worden door een samenstelling van drie controlestructuren: sequentiestructuur, selectiestructuur en herhalingsstructuur. Meteen lag de definitie van gestructureerd programmeren vast: “Een programma is gestructureerd als het bestaat uit een volkomen hiërarchisch geheel van vooraf bepaalde basisstructuren die slechts één ingang en één uitgang hebben.” De nadruk ligt hier op twee punten: 1. Alle gebruikte basisstructuren mogen slechts één ingang en één uitgang hebben. 2. Ze moeten in een hiërarchische relatie staan tot elkaar. Dit betekent dat iedere basisstructuur ofwel volledig, ofwel in het geheel niet, binnen een andere basisstructuur moet staan. Met gestructureerd programmeren werden de programma’s leesbaarder, gemakkelijker te controleren en aan te passen en reduceerden bijgevolg de ontwikkelings- en onderhoudskosten aanzienlijk. Vanaf dan houdt programmeren meer in dan enkel het afleveren van ‘iets dat werkt’. In deze cursus zullen we enkel gestructureerde programma’s opstellen, waarvan we de basisstructuren in volgende drie paragrafen zullen definiëren. Deze basisstructuren moeten als bouwblokken dienen voor het opstellen van programma’s. Daarna volgen de regels hoe de bouwblokken in elkaar worden gebracht voor het ontwikkelen van gestructureerde programma’s (hiërarchische relaties). Tenslotte blijft dan nog één essentiële vraag over: “Wanneer moet een
Aanvullende cursus Fundamentals of Programming
38
Basis
bouwblok worden gebruikt?”. Voor de rekenprocessen zal die vraag worden behandeld in hoofdstuk 3 Ontwerpen algoritmen
2.3.2 Sequentiestructuur 2.3.2.1.1
Probleem
In de variabele straal bevindt zich de straal van een cirkel. Gevraagd wordt de oppervlakte van de cirkel te berekenen en het resultaat terug te geven. 2.3.2.1.2
Oplossing
De verwerking bestaat eerst uit het berekenen van de oppervlakte en het resultaat te stockeren in de variabele oppervlakte. Dit gebeurt in de methode. Daarna kan in de main()-methode de variabele
oppervlakte op het scherm worden afgebeeld.
public static double berekenOpp(double straal) { //declaratie final double PI = 3.1415; double oppervlakte; // berekening oppervlakte = straal * straal * PI; //teruggeven resultaat return oppervlakte; }
//einde methode
Het volledige programma ziet er dan als volgt uit: import java.util.Scanner; public class Hoofdprogramma{ public static void main(String[] args) { Scanner sc = new Scanner(System.in); // declaratie double s;
// straal
double opp;
// oppervlakte
//inlezen straal System.out.println("Geef de straal:"); s = sc.nextDouble(); // bereken oppervlakte opp = berekenOpp(s);
Aanvullende cursus Fundamentals of Programming
39
Basis // afbeelden resultaat System.out.println("De oppervlakte van een cirkel " + "met straal " + s + " is " + opp); } //einde methode main() /** * Oppervlakte berekenen van een cirkel * * @param straal straal van de cirkel * @return oppervlakte van de cirkel */ public static double berekenOpp(double straal) { //declaratie final double PI = 3.1415; double oppervlakte; // berekening oppervlakte = straal * straal * PI; //teruggeven resultaat return oppervlakte; }
//einde methode
} // einde class Hoofdprogramma
2.3.2.1.3
Betekenis
Bij een sequentie worden de opeenvolgende opdrachten van boven naar onder na elkaar uitgevoerd. De volgorde van de opdrachten is meestal van belang.
Aanvullende cursus Fundamentals of Programming
40
Basis
2.3.2.1.4
Algemeen schema ingang bewerking 1
bewerking 2
bewerking 3 uitgang
2.3.3 Selectiestructuur 2.3.3.1 Eenzijdige selectie 2.3.3.1.1
Probleem
Indien in voorgaand voorbeeld de straal een negatief getal is, heeft het geen zin de oppervlakte te berekenen. Gevraagd wordt enkel bij een positieve straal de oppervlakte van de cirkel te berekenen en het resultaat op scherm af te beelden. 2.3.3.1.2
Oplossing
In een vergelijkingsopdracht wordt de straal vergeleken met 0. Indien het resultaat van de conditie waar is, wordt de oppervlakte berekend en afgebeeld. Aangezien we niet altijd een geldige waarde hebben om te retourneren zullen we hier de methode zelf het resultaat op scherm laten zetten. /** * Oppervlakte berekenen van een cirkel en indien geldig * op het scherm zetten * * @param straal straal van de cirkel */ public static void berekenOppPositief(double straal) { //declaratie final double PI = 3.1415; double oppervlakte = 0; // berekening if (straal >= 0) { oppervlakte = straal * straal * PI; System.out.println("De oppervlakte van een cirkel " + "met straal " + straal + " is " + oppervlakte); Aanvullende cursus Fundamentals of Programming
41
Basis } // einde if }
//einde methode
2.3.3.1.3
Betekenis
Bij een eenzijdige selectie (if-then) wordt de bijhorende blok van opdrachten enkel uitgevoerd als het resultaat van de selectievoorwaarde waar is. In het andere geval wordt niets uitgevoerd. 2.3.3.1.4 Algemeen schema ingang ja
voorwaarde
neen
blok
uitgang
2.3.3.2 Tweezijdige selectie 2.3.3.2.1
Probleem
Indien in voorgaand voorbeeld de straal negatief is, gebeurt er niets. Pas het programma aan zodat bij een negatieve straal een foutmelding wordt afgebeeld. 2.3.3.2.2
Oplossing
•
Indien straal ≥ 0 wordt de oppervlakte berekend en afgebeeld.
•
Indien straal <0 wordt een foutmelding afgebeeld.
/** * Oppervlakte berekenen van een cirkel * en indien geldig op het scherm zetten * anders foutmelding * * @param straal straal van de cirkel */ public static void berekenOppPositief(double straal) { //declaratie final double PI = 3.1415; double oppervlakte = 0; // berekening if (straal >= 0) { oppervlakte = straal * straal * PI; Aanvullende cursus Fundamentals of Programming
42
Basis System.out.println("De oppervlakte van een cirkel " + "met straal " + straal + " is " + oppervlakte); } else { System.out.println("Negatieve straal"); } }
//einde else //einde methode
2.3.3.2.3 Betekenis Bij een tweezijdige selectie (if-then-else) wordt de bijhorende blok van opdrachten vóór het woordje else slechts uitgevoerd als het resultaat van de selectievoorwaarde waar is. Is de selectievoorwaarde vals, dan wordt enkel de blok van opdrachten in de else-tak uitgevoerd. 2.3.3.2.4
Algemeen schema ingang ja
voorwaarde
blok1
neen
blok2
uitgang
2.3.3.3 Geneste selectiestructuren Soms moeten in een programma via testen meer dan 2 gevallen onderscheiden worden. Dit kan door het plaatsen van een selectie binnen een andere selectie. De binnenste selectie is dan genesteld in de buitenste selectie. De binnenste selectie kan dan opnieuw een selectie bevatten zodat meerdere genestelde selecties ontstaan. 2.3.3.3.1
Probleem
Bepaal vanuit de score van een geslaagde student de behaalde graad. Deze wordt als volgt bepaald: •
85 % of meer: grootste onderscheiding
•
78 % of meer: grote onderscheiding
•
68 % of meer: onderscheiding
•
minder dan 68 %: voldoening
2.3.3.3.2
Oplossing
/** * Bepalen van de graad * * @param score het behaalde percentage Aanvullende cursus Fundamentals of Programming
43
Basis * @return de graad bepaald op basis van het precentage */ public static String bepaalGraad(int score) { //declaratie String graad = ""; if (score >= 85) { graad = "Grootste onderscheiding"; } else if (score >=78) { graad ="Grote onderscheiding"; } else if (score >=68) { graad ="Onderscheiding"; } else { graad ="Voldoening"; } return graad; } //einde methode
2.3.3.3.3
Het else-probleem
Wanneer een eenzijdige selectie en een tweezijdige selectie genest worden, geldt de volgende regel: De else komt altijd overeen met de laatste if die nog niet met een else verbonden is, en tot dezelfde blok behoort. vb1:
else komt overeen met binnenste if
if (x > 10) if (y > 10) System.out.println("x en y zijn > 10"); else System.out.println("x > 10 en y <=10");
vb2:
else komt overeen met buitenste if
if (x > 10) { if (y > 10) System.out.println("x en y zijn > 10"); } else System.out.println("x <= 10");
De accolades duiden aan dat de tweede if volledig tot de then-tak van de eerste if behoort en de else geassocieerd is met de eerste if.
Aanvullende cursus Fundamentals of Programming
44
Basis
2.3.3.4 Meervoudige selectie 2.3.3.4.1
Probleem
Er wordt gevraagd om een dagnummer (lopend van 1 tot 7) om te zetten naar de naam van de dag. 1 komt dus overeen met maandag, 2 met dinsdag, 3 met woensdag enz. Schrijf een methode die het dagnummer binnenkrijgt via een parameter en de naam van de dag retourneert. 2.3.3.4.2
Oplossing
Het dagnummer zit in de variabele dagnummer.. •
Indien dagnummer = 1, wordt de naam van de dag maandag.
•
Indien dagnummer = 2, wordt de naam van de dag dinsdag.
•
Indien dagnummer = 3, wordt de naam van de dag woensdag.
•
enz
Indien dagnummer verschillend is van 1, 2, 3, 4, 5, 6 of 7, is de naam van de dag ongeldig. public static String naamDag(int dagnummer) { String dag = ""; switch (dagnummer) { case 1: dag = "maandag"; break; case 2: dag = "dinsdag"; break; case 3: dag = "woensdag"; break; case 4: dag = "donderdag"; break; case 5: dag = "vrijdag"; break; case 6: dag = "zaterdag"; break; case 7: dag = "zondag"; break; default: dag = "ongeldig"; Aanvullende cursus Fundamentals of Programming
45
Basis } //einde switch return dag; } // einde methode
2.3.3.4.3 Betekenis De variabele na het woordje switch wordt achtereenvolgens vergeleken met de constanten die vermeld staan na de woordjes case. Wanneer een gelijkenis wordt gevonden voert de computer de opdrachten uit die volgen na de passende constante tot aan het woordje break. De default-optie wordt gebruikt als er geen gelijkenis gevonden werd. Dan worden de opdrachten die op dit woord volgen uitgevoerd. 2.3.3.4.4
Algemeen schema ingang V
V=x
B1
V=y
B2
V=z
...
Bn
overige
Ba
uitgang
Wanneer er vele selecties voorkomen is het soms gemakkelijker de volgende voorstelling van de meervoudige selectie uit te werken:
Aanvullende cursus Fundamentals of Programming
46
Basis
ingang V
V=x
V=y
V=3
V=z
overige
B1
B2
B3
Bn
Ba
uitgang
2.3.3.4.5
Opmerkingen
•
Binnen een case moet de sequentie van opdrachten niet tussen accolades staan.
•
Zijn er in de switch-structuur geen breakstatements aanwezig, dan worden alle verdere opdrachten tot op het einde van de switch uitgevoerd.
•
De default-optie is optioneel: wanneer zij wordt weggelaten, dan worden helemaal geen opdrachten uitgevoerd als er geen gelijkenis gevonden werd.
•
De switch-opdracht kan enkel gebruikt worden om variabelen van het type int, char of String te vergelijken met constanten. Bij alle andere vergelijkingen moeten genestelde selecties gebruikt worden.
Aanvullende cursus Fundamentals of Programming
47
Basis
2.3.4 Vergelijkingsopdrachten 2.3.4.1 Relationele operatoren In voorwaarden of condities (zoals in selectievoorwaarden, maar ook in herhalingsstructuren) worden dikwijls de waarden van variabelen met elkaar vergeleken. We zijn bijvoorbeeld geïnteresseerd of dat a groter is dan b, of als x gelijk is aan 20, enz… Om deze uitdrukkingen mogelijk te maken worden relationele operatoren voorzien. Volgende operatoren kunnen in Java gebruikt worden: Relationele operator
Betekenis
>
groter dan
<
kleiner dan
==
gelijk aan
!=
verschillend van
>=
groter of gelijk aan
<=
kleiner of gelijk aan
Voorbeeld •
a < b
•
c == 100.0
•
x == y
Het resultaat van deze expressies is altijd waar of vals. In verschillende talen, en ook in Java, wordt een type boolean voorzien om de toestand waar of vals te kunnen weergeven. Het resultaat van
relationele en ook logische expressies is dus altijd true of false. Voorbeeld int a=10, b=20, c=30; boolean b1 = (a < b); boolean b2 = (b > c);
System.out.println("De eerste vergelijking is: " + b1); System.out.println("De tweede vergelijking is: " + b2); if (b1 == true) { System.out.println("De eerste vergelijking is waar"); } else { Aanvullende cursus Fundamentals of Programming
48
Basis System.out.println("De eerste vergelijking is onwaar"); } if (b2 == true) { System.out.println("De tweede vergelijking is waar"); } else { System.out.println("De tweede vergelijking is onwaar"); }
Output De eerste vergelijking is: true De tweede vergelijking is: false De eerste vergelijking is waar De tweede vergelijking is onwaar
Pas op Soms wordt ondoordacht geschreven if(a=2) waarbij bedoeld wordt de waarde a
met 2 te vergelijken. Hier wordt echter de waarde 2 toegekend aan de variabele a wat uiteindelijk als resultaat true oplevert.
2.3.4.2 Logische operatoren In sommige situaties hebben we meer nodig dan alleen maar relationele operatoren. Denk maar aan volgende situatie: Als de variabele temp gelegen is tussen 22 en 25 willen we de boolean-variabele idealeZomerTemp
op true zetten. In de andere gevallen moet die op false staan.
te koud
10
ideaal
20
21
22
23
24
te warm
25
26
27
40
Figuur 2-1 Temperatuurschaal
We doen dit met volgende test Aanvullende cursus Fundamentals of Programming
49
Basis temp >= 22 en temp <= 25
Om deze test te kunnen uitvoeren hebben we de logische en-operator nodig. In Java schrijven we de combineerde conditie als volgt temp >= 22 && temp <= 25
Volgende operatoren kunnen gebruikt worden Operator
Betekenis
&&
conditionele and
||
conditinele or
!
Logische not
2.3.4.2.1
Conditionele and
Een conditionele and kan gebruikt worden om 2 expressies te combineren. expressie1 && expressie2
Het resultaat is true wanneer beide expressies true zijn. Typisch aan de ‘conditionele’ and is dat
wanneer de eerste expressie al false is, dat de tweede nooit zal geëvalueerd worden. Het is namelijk al zeker dat het resultaat nooit meer true kan worden.
Voorbeeld int a=10, b=20, c=30; if (a<b && a>=b) { System.out.println("De eerste vergelijking is waar"); } else { System.out.println("De eerste vergelijking is onwaar"); } if (a>b && ++c>b) { System.out.println("De tweede vergelijking is waar"); System.out.println("a=" + a + " b=" + b + " c=" + c); } else { System.out.println("De tweede vergelijking is onwaar"); System.out.println("a=" + a + " b=" + b + " c=" + c); } if (a<b && ++c>b) { System.out.println("De derde vergelijking is waar"); System.out.println("a=" + a + " b=" + b + " c=" + c);
Aanvullende cursus Fundamentals of Programming
50
Basis } else { System.out.println("De derde vergelijking is onwaar"); System.out.println("a=" + a + " b=" + b + " c=" + c); }
Output De eerste vergelijking is onwaar De tweede vergelijking is onwaar a=10 b=20 c=30 De derde vergelijking is waar a=10 b=20 c=31
2.3.4.2.2
Conditionele or
Net zoals de conditionele and wordt de conditionele or ook gebruikt om 2 expressies te combineren. expressie1 || expressie2
Het resultaat van een conditionele or is true vanaf dat minstens één expressie true is. Typisch aan
de ‘conditionele’ or is dat wanneer de eerste expressie al true is, de tweede expressie nooit
geëvalueerd zal worden. Het is immers al zeker dat het resultaat true zal opleveren, ongeacht de waarde van de tweede expresie.
Voorbeeld int a=10, b=20, c=30; if (a<b || a>=b) { System.out.println("De eerste vergelijking is waar"); } else { System.out.println("De eerste vergelijking is onwaar"); } if (a<b || ++c>b) { System.out.println("De tweede vergelijking is waar"); System.out.println("a=" + a + " b=" + b + " c=" + c); } else { System.out.println("De tweede vergelijking is onwaar"); System.out.println("a=" + a + " b=" + b + " c=" + c); } if (a>b || ++c>b) { System.out.println("De derde vergelijking is waar"); System.out.println("a=" + a + " b=" + b + " c=" + c); } else { System.out.println("De derde vergelijking is onwaar");
Aanvullende cursus Fundamentals of Programming
51
Basis System.out.println("a=" + a + " b=" + b + " c=" + c); }
Output De eerste vergelijking is waar De tweede vergelijking is waar a=10 b=20 c=30 De derde vergelijking is waar a=10 b=20 c=31
2.3.4.2.3
De logische not
De logische not wordt gebruikt bij één expressie en geeft de inverse waarde ervan terug. !expressie
Het resultaat van een logische not is true wanneer de expressie false is en omgekeerd. Voorbeeld int a=10, b=20; if (!(a<b)) System.out.println("De eerste vergelijking is waar"); else System.out.println("De eerste vergelijking is onwaar"); if (!(a>b)) System.out.println("De tweede vergelijking is waar"); else System.out.println("De tweede vergelijking is onwaar");
Output De eerste vergelijking is onwaar De tweede vergelijking is waar
Pas op Vergeet niet om haakjes rond a>b te zetten, anders wordt geprobeerd om de logische not uit te voeren op de variabele a, i.p.v. op de expressie a>b.
2.3.4.2.4
Prioriteit en Associativiteit
De tabel toont de prioriteit en associativiteit van de operatoren. Prioriteiten
Associativiteit
<, <=, >, >=
links
==, !=
links
&&
links
Aanvullende cursus Fundamentals of Programming
52
Basis
||
links
!
rechts
2.3.4.2.4.1 Betekenis associativiteit links-associatief: de operator hangt aan z'n onmiddellijke linkse operand. rechts-associatief: de operator hangt aan z'n onmiddellijke rechtse oprand. 2.3.4.2.4.2 Betekenis prioriteit Zo heeft < heeft een hogere prioriteit dan && In de vergelijking a < b && c < d
wordt dus eerst a < b en c < d uitgerekend en dan pas de && toegepast op beide operanden. Concreet wordt dit dus (a<b) && (c<d)
2.3.4.2.4.3 Voorbeeld int a = 7; int y = 1; boolean x = false; if (a > 6 && !x || y < 2) { System.out.println("De vergelijking is waar"); } else { System.out.println("De vergelijking is onwaar"); }
Volgorde van de berekeningen ((a > 6) && !x) || (y < 2) Dus a > 6 -> true !x -> true y < 2 -> true (true && true) || true true
Resultaat De vergelijking is waar
Aanvullende cursus Fundamentals of Programming
53
Basis
Belangrijk Bij twijfel kan best gebruik gemaakt worden van haakjes!
2.3.4.2.5
De wetten van De Morgan
Via de wetten van De Morgan is het mogelijk om van de logische and-operator over te gaan naar de or-operator en omgekeerd. 1) Als aan (C1 and C2) niet voldaan is, dan is het omdat aan C1 of aan C2 niet voldaan is. not (C1 and C2) = (not C1) or (not C2) 2)
Als aan (C1 or C2) niet voldaan is, dan is het omdat zowel terzelfder tijd aan C1 en aan C2 niet
voldaan wordt. not (C1 or C2) = (not C1) and (not C2)
2.3.5 Herhalingsstructuur 2.3.5.1 While lus 2.3.5.1.1
Probleem
De variabelen deeltal en deler zijn twee gehele getallen, waarbij deeltal ≥ 0 en deler > 0. Bepaal de rest van de deling van beide getallen, door opeenvolgende aftrekkingen. vb.
deeltal = 8 deler = 3 rest = 8 – 3 – 3 = 2
2.3.5.1.2
Oplossing
De rest wordt bekomen door een aantal keren deler van deeltal af te trekken. Daar we niet weten hoeveel keer de aftrekking moet gebeuren, is het onmogelijk de oplossing als een sequentie van aftrekkingen voor te stellen. Maar de bewerking die hier een aantal keren moet gebeuren is steeds dezelfde. Vandaar plaatsen we deze in een lus en wordt de aftrekking achtereenvolgens uitgevoerd. Bij de start is de rest gelijk aan deeltal. ‘Zolang’ de rest groter dan of gelijk is aan deler, verminderen we de rest met deler. public static int berekenRest(int deeltal, in deler) { int rest; // een startwaarde aan rest geven rest = deeltal; // zolang rest kan verminderd worden met deler, de // aftrekking uitvoeren
Aanvullende cursus Fundamentals of Programming
54
Basis while (rest >= deler) { rest = rest - deler; } // einde while return rest; } // einde methode
2.3.5.1.3
Betekenis
Een while-lus (iteratie) is een basisstructuur die opgebouwd is uit een iteratievoorwaarde en een iteratiebody. De iteratievoorwaarde wordt eerst getest vooraleer de iteratiebody wordt uitgevoerd. Zolang aan de iteratievoorwaarde voldaan is, wordt de iteratiebody uitgevoerd. Als aan de voorwaarde niet meer wordt voldaan is, wordt de iteratie beëindigd. 2.3.5.1.4
Algemeen schema ingang iteratievoorwaarde
neen
ja
iteratiebody
uitgang
Opmerkingen •
Aangezien eerst de iteratievoorwaarde wordt getest, is het mogelijk dat de iteratiebody geen enkele keer wordt uitgevoerd (vb. deeltal < deler).
•
Een veel voorkomende programmeerfout is dat de iteratievoorwaarde nooit vals wordt, waardoor de iteratie een oneindige lus is.
2.3.5.2 Do-while lus 2.3.5.2.1
Probleem
Schrijf een methode die een getal opvraagt. Zolang dat getal negatief is, moet een nieuw getal opgevraagd worden. De methode retourneert het ingelezen positieve getal. 2.3.5.2.2
Oplossing
Om in een methode waarden te kunnen inlezen ipv in de main(), moeten we de volgende regel code in methode zelf zetten:
Aanvullende cursus Fundamentals of Programming
55
Basis Scanner sc = new Scanner(System.in);
Oplossing public static int haalPositiefGetalOp() { Scanner sc = new Scanner(System.in); int getal = 0; do { System.out.println("Geef een positief getal:"); getal = sc.nextInt(); } while (getal <= 0);
//einde do-while
return getal; } // einde methode
2.3.5.2.3
Algemeen schema ingang
herhalingsbody
ja
herhalingsvoorwaarde neen uitgang
2.3.5.2.4
Betekenis
Een do-while lus is een basisstructuur die opgebouwd is uit een herhalingsvoorwaarde en een herhalingsbody. De herhalingsbody wordt eerst uitgevoerd vooraleer de herhalingsvoorwaarde wordt getest. Als aan de herhalingsvoorwaarde voldaan is, wordt de herhalingsbody opnieuw uitgevoerd. Als aan de voorwaarde niet meer wordt voldaan is, wordt de lus beëindigd. 2.3.5.2.5
Opmerkingen
•
Uit de definitie blijkt dat de herhalingsbody steeds minstens 1 keer wordt uitgevoerd.
•
Essentiële verschillen tussen de while en de do-while zijn: while
do-while
De iteratievoorwaarde wordt getest voordat De herhalingsvoorwaarde wordt getest nadat de iteratiebody wordt uitgevoerd.
Aanvullende cursus Fundamentals of Programming
de herhalingsbody is uitgevoerd.
56
Basis
•
Het is mogelijk dat de iteratiebody nooit
De herhalingsbody wordt minstens éénmaal
wordt uitgevoerd.
uitgevoerd.
Het gebruik van de do-while leidt dikwijls tot fouten en moet zoveel mogelijk worden vermeden. Enkel in situaties waar je zeker bent dat de lus minstens 1 keer moet worden uitgevoerd vooraleer de voorwaarde te kunnen stellen, is het gebruik van de do-while enigszins verantwoord.
2.3.5.2.6
Oefening
Pas bovenstaande oplossing aan zodat een while lus gebruikt wordt i.p.v. een do-while lus en dat er voor de gebruiker niets verandert.
2.3.5.3 For lus 2.3.5.3.1
Probleem
Schrijf een methode die 20 keren de tekst "Welkom in VIVES" afbeeldt. 2.3.5.3.2
Oplossing
Een lus waarin de outputopdracht staat moet 20 keren worden doorlopen. Een loopvariabele (teller) houdt bij hoeveel keren de tekst reeds afgedrukt is. versie 1: met while lus public static void drukAf() { int i;
//loopvariabele
// teller startwaarde geven i = 0; while (i < 20) { System.out.println("Welkom in VIVES"); i = i + 1;
// loopvariabele met 1 verhogen
} //einde while } //einde methode
versie 2: met for lus public static void drukAf() { for (int i=0; i<20; i++) {
//i is de loopvariabele
System.out.println("Welkom in VIVES"); } //einde for }//einde methode
Aanvullende cursus Fundamentals of Programming
57
Basis
2.3.5.3.3
Algemeen schema ingang initialisering loopvariabele
loopvoorwaarde
neen
ja blok (loopbody)
aanpassen loopvariabele
uitgang
2.3.5.3.4
Betekenis
Een for lus is een basisstructuur die opgebouwd is uit: •
een startopdracht (int i = 0): wordt slechts éénmaal uitgevoerd en wel aan het begin van de lus. Hier wordt meteen ook de variabele i gedeclareerd. Meestal geeft het de loopvariabele een startwaarde;
•
een loopvoorwaarde (i < 20): wordt geëvalueerd bij de start van elke loopdoorgang. Indien het resultaat waar is, wordt de loopbody nog eens doorlopen. Indien de test vals is, wordt verder gegaan met de opdrachten die volgen op de for lus;
•
actie na de loopbody (i = i + 1): wordt uitgevoerd op het einde van de loop na de loopbody. Deze opdracht past meestal de loopvariabele aan, door deze te verhogen of te verlagen.
2.3.5.3.5 •
Opmerkingen
Bij een for lus hebben we een loopvariabele nodig waarvan de waarde steeds op een vaste manier verandert, meestal +1 bij elke loopdoorgang.
•
Een for lus is bruikbaar als het aantal keren dat de loop moet doorlopen worden gekend is. Is het aantal keren niet gekend (vb. getallen lezen tot input 0 is), dan moet de while lus gebruikt worden. Indien de loopvoorwaarde slechts kan uitgevoerd worden na het doorlopen van de loopbody, biedt de do-while lus een oplossing.
Aanvullende cursus Fundamentals of Programming
58
Basis
2.3.6 Hiërarchische relaties De tweede eis die aan een gestructureerd programma werd gesteld, was de volgende “De basisstructuren moeten in een hiërarchische relatie staan tot elkaar. Dit betekent dat iedere basisstructuur ofwel volledig, ofwel in het geheel niet, binnen een andere basisstructuur moet staan”. Deze regel zegt hoe we de basisstructuren met elkaar moeten combineren om aldus een volledig gestructureerd programma te realiseren. Door een oordeelkundige nesteling (= in elkaar bouwen) van de basisstructuren, kan uiteindelijk een volledige programmalogica worden opgebouwd. De eis die hier wordt gesteld, houdt een beperking in van het willekeurig over en weer springen in een programma (wat een veel voorkomende bron van fouten was). Door enkel nog hiërarchische relaties te gebruiken, wordt de kwaliteit van het programma in sterke mate verbeterd. Immers, eens in een bepaalde structuur binnengekomen (via een éénduidige ingang), bestaat er niet de minste twijfel over het feit waar de structuur zal verlaten worden (via de éénduidige uitgang). Hoeveel structuurelementen ook vervat zijn in een module, op elk punt binnen de structuur is het éénduidig bepaald via welke weg dit punt bereikt werd (nl. via de enige ingang van de structuur waarin men zich bevindt). Ook is het éénduidig bepaald hoe dit punt zal verlaten worden (nl. via de enige uitgang van de structuur waarin men zich bevindt). Dit is ongeacht het detailniveau waarop men zich bevindt. Het is duidelijk dat hoe minder mogelijke wegen er zijn, hoe gemakkelijker de programmalogica te volgen is. Het uitsluitend gebruiken van hiërarchische relaties stelt in bepaalde gevallen problemen die echter vrij gemakkelijk op te lossen zijn. In geen geval mag afgeweken worden van de hier gestelde eis.
2.3.6.1 Voorbeeld van hiërarchische relaties In een klas nemen alle studenten deel aan het examen van programmeren. Dit examen staat op 20 punten. Om te slagen moet men 10 of meer behaald hebben. We beschikken over de naam en de behaalde punten van alle studenten. Het aantal studenten is bij de gebruiker gekend. Er wordt gevraagd een lijst te maken van alle studenten met de tekst “geslaagd” of “niet geslaagd”. /** * Bepalen of een student slaagt door * naam en punten op te vragen * * @param aantalStudenten het aantal studenten waarvoor moet * nagegaan worden of ze geslaagd zijn of niet. */ public static void drukIsGeslaagd(int aantalStudenten) { Scanner sc = new Scanner(System.in); String naam = ""; int ptn = 0; //doorlopen klaslijst Aanvullende cursus Fundamentals of Programming
59
Basis for (int klasnr = 0; klasnr < aantalStudenten; klasnr = klasnr + 1) { System.out.println("Geef naam"); naam = sc.next(); System.out.println("Geef punten"); ptn = sc.nextInt(); // controle geslaagd if (ptn >= 10){ System.out.println(klasnr + " " + naam + " is geslaagd"); } else { System.out.println(klasnr + " " + naam + " is niet geslaagd"); } //einde else } // einde for } //einde methode
2.3.7 Oefeningen 1. Schrijf een methode die twee getallen als parameter neemt en deze afbeeldt in stijgende volgorde. 2. Schrijf een methode die drie getallen als parameter neemt en deze afbeeldt in dalende volgorde. 3. Schrijf een methode die twee getallen als parameter neemt (≥ 0, geen inputcontrole), deel het grootste door het kleinste en beeld het quotiënt af. 4. Een bepaalde instantie voorziet in een toelage bovenop het inkomen van grote minderbedeelde gezinnen. De toelage bedraagt 3 % van het jaarinkomen. De toelage vervalt indien het jaarinkomen > 20.000 EUR of het aantal kinderen < 3 is. Schrijf een methode die het jaarinkomen en het aantal kinderen als parameter neemt en het bedrag van de toelage terug geeft. Maak gebruik van logische operatoren. 5.
Een openbaar examen bestaat uit drie delen. Elk deel wordt met een cijfer op tien beoordeeld. Om te slagen moet een deelnemer aan één van de twee volgende vereisten voldoen: •
hij of zij heeft alleen maar voldoendes behaald (minstens 5 op elk deel)
•
het totaal van de cijfers is minstens 18 en géén van de cijfers is lager dan 4.
Schrijf een methode die de drie resultaten als parameter neemt en terug geeft of de student al dan niet geslaagd is.
6. Tarifering bij een gasmaatschappij. Een gasmaatschappij berekent haar facturen op de volgende wijze:
Aanvullende cursus Fundamentals of Programming
60
Basis
•
Het verbruik wordt bepaald door vergelijking van de eindstand met de beginstand van de teller. De teller bevat 6 posities en duidt een aantal m3 aan (geen decimalen).
•
Indien het verbruik niet groter is dan 1000 m3, dient de klant een eenheidsprijs van 0,34 EUR te betalen.
•
Indien het verbruik groter is dan 1000 m3, dan dient de klant de eerste 1000 m3 aan 0,34 EUR te betalen en het resterend verbruik aan 0,31 EUR per m3.
Schrijf een methode die het verschuldigd bedrag dat na het doorgeven van de begin- en de eindstand van de teller berekent. Opmerking: de teller kan de nulstand gepasseerd zijn, maar een verbruik van meer dan 999999 m3 is echter onmogelijk.
7. Gegeven: •
een begintijd opgeslagen in drie variabelen uu1 mm1 ss1
•
een eindtijd opgeslagen in drie variabelen uu2 mm2 ss2
•
de begintijd en de eindtijd betreffen niet noodzakelijk dezelfde dag maar verschillen gegarandeerd minder dan 24 uur.
Gevraagd: Schrijf een methode die het tijdverschil in uren, minuten en seconden afbeeldt. Er mag geen omzetting gebeuren naar seconden.
8. Druk een tabel af voor de omzetting van Celsiusgraden in Fahrenheitgraden. Van -40 t.e.m. +100 graden Celsius wordt per 10 graden het overeenkomstig aantal Fahrenheitgraden berekend en afgebeeld. 9.
Een firma heeft een gegeven omzet bereikt en verwacht voor de volgende jaren een groei uitgedrukt in %. Bepaal de verwachte omzet voor de volgende jaren. Parameters: •
omzet van het huidig jaar
•
groeivoet per jaar, uitgedrukt in %
•
aantal jaren waarvoor de berekening wordt uitgevoerd
•
huidige jaar
Output op scherm: •
Het huidig jaar en de groeivoet worden eerst afgebeeld.
•
Daarna worden per jaar het jaartal en de omzetprognose afgebeeld.
10. Schrijf een methode die exact 10 getallen inleest en telkens het kwadraat ervan op scherm afbeeldt.
Aanvullende cursus Fundamentals of Programming
61
Basis
11. Schrijf een methode die een reeks positieve getallen inleest, het aantal getallen is niet vooraf gekend maar de reeks wordt afgesloten door -1. Geef de som van alle getallen die -1 voorafgaan terug. 12. Schrijf een methode die een rij gehele getallen afgesloten door een nul inleest. De getallen kunnen positief en negatief zijn. Geef terug hoeveel keer het kleinste getal in de ingelezen rij voorkomt. 13. Schrijf een methode die een rij van positieve gehele getallen afgesloten door een nul inleest. Geef de plaats terug waar het grootste getal werd ingegeven (indien meerdere gelijke grootste: plaats van eerste voorkomen). 14. Schrijf een methode die een rij gehele getallen inleest. Geef het gemiddelde van alle ingegeven getallen terug als je weet dat de rij afgesloten wordt door twee opeenvolgende nullen, die niet meetellen voor de berekening van het gemiddelde (er kunnen dus “eenzame” nullen voorkomen ergens midden in de rij). 15. Schrijf een methode die de eindejaarspremie van een werknemer berekent. Indien de werknemer 20 jaar of meer in het bedrijf werkt krijgt hij 5 % premie op het jaarloon, anders slechts 3 %. 16. Geef de output, indien er is, van volgend stukje code: x = 2; y = 3; if (x > 2) if (y > 2) { z = x + y; System.out.println("z is "+z); } else { System.out.println("x is "+x); }
17. Geef de output, indien er is, van volgend stukje code: x = 3; y = 2; if (x > 2) { if (y > 2) { z = x + y; System.out.println("z is "+z); } } else { System.out.println("x is "+x); }
Aanvullende cursus Fundamentals of Programming
62
Basis
18. Schrijf een methode die een geheel getal tussen 1 en 10 als parameter neemt en de tafel van vermenigvuldiging afdrukt. Voorbeeld inputgetal = 8 output: 1x8=8 2 x 8 = 16 ... 10 x 8 = 80 19. Bepaal de logische ontkenning van volgende logische uitdrukkingen. a. not C1 and C2 b. C1 and C2 and C3 c. C1 or not (C2 and C3) d. (not C1 or C2) or not C3 e. not C1 and (C2 or not C3) f.
not (C1 or not C2) and (not C3 or C4)
20. Herschrijf volgende logische uitdrukkingen met zo weinig mogelijk logische operatoren. a. (A <= 6) && !(B > 9) b. ! (!(A != B) || (C < 10)) && (C >= D) c. ! (! (! (A >= 10) && (B <= 6)) || ((C == 6) || !(D < 5)))
Aanvullende cursus Fundamentals of Programming
63