Programmeren, de basis/De controlestructuren
Via controlestructuren kan je de manier waarop je programma wordt uitgevoerd beïnvloeden. We baseren ons voor dit hoofdstuk op de oefening met de prijsofferte, waarbij we gebruikmaken van zaken die al bepaald zijn, zoals de constanten en variabelen.
Nassi-Schneidermann diagrammen, kortweg NS-diagrammen of ook wel structogrammen genoemd, zijn een goed middel om algoritmen voor te stellen, doordat het automatisch leidt tot gestructureerd werken. In onderstaand schema worden de verscheidene controlestructuren, samen met hun overeenkomstige NS-diagrammen weergegeven.
Sequentie of opeenvolging
[bewerken]Een opeenvolging van opdrachten betekent dat als de eerste van die opdrachten wordt uitgevoerd ook de opdrachten die volgen zullen worden uitgevoerd. Voorlopig gaan we hier niet verder op ingaan, daar sequenties heel makkelijk herkend kunnen worden, daar ze tussen de andere controlestructuren inzitten.
Keuze of selectie (conditioneel verloop)
[bewerken]Enkelvoudig
[bewerken]Tweevoudig
[bewerken]Meervoudig
[bewerken]Herhaling of iteratie (lusverloop)
[bewerken]Begrensd
[bewerken]Het kopieercentrum
[bewerken]Stel dat je vier kopieën van een blad nodig hebt. Wellicht zal je het volgende stappenplan in een kopieercentrum niet gebruiken:
- Gebruiker stopt blad in kopieerapparaat.
- Gebruiker drukt op de kopie-knop.
- Kopieertoestel maakt kopie en geeft het blad terug aan de gebruiker.
- Gebruiker stopt blad in kopieerapparaat.
- Gebruiker drukt op de kopie-knop.
- Kopieertoestel maakt kopie en geeft het blad terug aan de gebruiker.
- Gebruiker stopt blad in kopieerapparaat.
- Gebruiker drukt op de kopie-knop.
- Kopieertoestel maakt kopie en geeft het blad terug aan de gebruiker.
- Gebruiker stopt blad in kopieerapparaat.
- Gebruiker drukt op de kopie-knop.
- Kopieertoestel maakt kopie en geeft het blad terug aan de gebruiker.
Je zou nog kunnen stellen dat dit voor vier kopieën makkelijk te doen is, maar voor honderd is dit niet vol te houden. Beter is onderstaand algoritme:
- Gebruiker stopt blad in kopieerapparaat
- Gebruiker stelt '100' in als 'aantal kopieën'.
- Het kopieertoestel maakt een beeldbestand van het blad.
- Het kopieertoestel maakt een kopie a.d.h.v. het beeldbestand.
- Het kopieertoestel vermindert het nog te maken kopiëen met 1
- Keer terug naar stap 4, zolang het aantal te maken kopieën nog geen 0 is.
Doordat we bepaalde stappen herhalen spreken we hier dan ook over een 'herhaling'. Omdat het aantal stappen op voorhand gekend is, spreken we meer specifiek over een 'begrensde herhaling'.
Tellen en de tafels van vermenigvuldiging
[bewerken]Stel dat je een computer wil laten tellen tot vier, dan kan dat gemakkelijk met onderstaande (pseudo)code.
- print 1
- print 2
- print 3
- print 4
Wil je hem echter tot 100 laten tellen, dan zou je ook 100 regels code moeten schrijven. Zoiets is niet efficiënt. Beter is:
- totaal is 100
- teller is 1
- print teller
- verhoog de teller
- zolang de teller kleiner is dan het totaal, ga naar stap 3
Deze oefening kan je uitbreiden om de tafels van vermenigvuldiging te laten berekenen.
Een overzicht
[bewerken]NS-diagram
|
Pseudocode
|
VBA
|
PHP
|
Voor <variabele>= … tot …
|
For <teller>= begin To einde
Next |
for ( … ; … ; … ) {
} |
Voorwaardelijk herhaling met beginvoorwaarde
[bewerken]NS-diagram
|
Pseudocode
|
VBA
|
PHP
|
Zolang <voorwaarde>
|
Do While <voorwaarde>
Loop |
while (<voorwaarde>) {
} |
NS-diagram
|
Pseudocode
|
VBA
|
PHP
|
Totdat <voorwaarde>
|
Do Until <voorwaarde>
Loop |
Voorwaardelijk herhaling met eindvoorwaarde
[bewerken]NS-diagram
|
Pseudocode
|
VBA
|
PHP
|
Doe
Zolang <voorwaarde> |
Do
Loop While <voorwaarde> |
do {
} while (<voorwaarde>) |
NS-diagram
|
Pseudocode
|
VBA
|
PHP
|
Doe
Totdat <voorwaarde> |
Do
Loop Until <voorwaarde> |
Genest
[bewerken]Dit is een combinatie van sequenties, keuzes en/of herhalingen.
Hieronder zie je in pseudocode een voorbeeld, waarbij een begrensde herhaling genest is binnen een enkelvoudige keuze.
Als <voorwaarde> Dan <instructie 1> <instructie 2> Voor <variabele>= … tot … <instructieblok> <instructie 3>
Oefeningen
[bewerken]We kunnen deze probleemstelling als volgt formuleren:
Als ptnTotaal > 50 Dan
- toon afbeelding geslaagd
- boodschap = "Proficiat, je bent geslaagd!"
Anders
- toon afbeelding niet geslaagd
- boodschap = "Jammer, je bent niet geslaagd. Je zal nog flink moeten studeren!"
Select Geval txtKleur
- Geval "rood"
- maak achtergrond rood
- Geval "groen"
- maak achtergrond groen
- Geval "geel"
- maak achtergrond geel
- Geval "blauw"
- maak achtergrond blauw
- Geval "zwart"
- maak achtergrond zwart
Keuze of selectie (conditioneel verloop)
[bewerken]Enkelvoudig
[bewerken]Het aantal termijnen mag niet meer dan 12 (de constante maxAantalTermijnen
) bedragen. Als deze overschreden wordt moet een gepaste boodschap verschijnen:
'Declareren variabelen
termijn als reëel getal
aantalTermijnen als geheel getal
boodschap als tekst
aantalTermijnen = teBetalen / termijn
Als aantalTermijnen > maxAantalTermijnen Dan
- termijn = teBetalen / maxAantalTermijnen
- 'Voorbeeld: De termijn van 12 maanden is overschreden. De termijn 136,15 EUR wordt gebruikt.
- boodschap = "De termijn van " & maxAantalTermijnen & " maanden is overschreden. De termijn " & termijn & " EUR wordt gebruikt."
- toon boodschap
Als je de oefening leest merk je ook een keuze bij de ouderdom van het huis (de drempelwaarde om over een oud huis te spreken is 20 jaar en wordt voorgesteld door de constante drempelOudHuis
. Dit levert bij een oud huis een BTW-waarde op van 6 % (btwOudHuis
) en bij een nieuw huis een BTW-waarde van 21 %). Schematisch voorgesteld wordt dit:
Als ouderdomHuis > drempelOudHuis Dan
- BTW = btwOudHuis
Als ouderdomHuis <= drempelOudHuis Dan
- BTW = btwNieuwHuis
Het zou op deze manier weliswaar werken, maar toch kan het beter. De ouderdom van het huis wordt namelijk twee keer gecontroleerd. Als een huis echter ouder is dan 20 jaar, dan volgt daar onmiddellijk uit dat het niet jonger zal zijn dan 20 jaar. Omgekeerd geldt ook dat als een huis niet ouder is dan 20 jaar, dit automatisch betekent dat het jonger moet zijn dan 20 jaar.
Voor dit onderdeel is het beter om gebruik te maken van een tweevoudige i.p.v. een enkelvoudige keuze.
Tweevoudig
[bewerken]Voor de ouderdom van het huis kunnen we dus beter gebruikmaken van een tweevoudige keuze, wat de uitvoer van ons programma sneller zal maken:
Als ouderdomHuis > drempelOudHuis Dan BTW = btwOudHuis Anders BTW = btwNieuwHuis
Voor het bepalen van de verplaatsingskosten merken we ook een keuze:
Als provincieKlant = Oost-Vlaanderen Dan verplaatsingskosten = kostNrOVl Als provincieKlant = West-Vlaanderen Dan verplaatsingskosten = kostNrWVl Als provincieKlant = Antwerpen Dan verplaatsingskosten = kostNrAnt Als provincieKlant = Limburg Dan verplaatsingskosten = kostNrLi
Hier maken we echter opnieuw de fout dat we vier keer controleren in welke provincie de klant woont, dus dat kan beter.
Als provincieKlant = Oost-Vlaanderen Dan verplaatsingskosten = kostNrOVl Anders Als provincieKlant = West-Vlaanderen Dan verplaatsingskosten = kostNrWVl Anders Als provincieKlant = Antwerpen Dan verplaatsingskosten = kostNrAnt Anders Als provincieKlant = Limburg Dan verplaatsingskosten = kostNrLi
De code is nu optimaler, dan daarnet, maar ze blijkt toch redelijk ingewikkeld om te lezen. Het zou veel overzichtelijker zijn mochten we gebruikmaken van de meervoudige selectie.
Meervoudig
[bewerken]Selecteer Geval provincieKlant Geval Oost-Vlaanderen verplaatsingskosten = kostNrOVl Geval West-Vlaanderen verplaatsingskosten = kostNrWVl Geval Antwerpen verplaatsingskosten = kostNrAnt Geval Limburg verplaatsingskosten = kostNrLi
Alhoewel net hetzelfde wordt gedaan als bij de geneste tweevoudige keuze leest bovenstaande code toch stukken vlotter. Zelfs als er later provincies worden bijgevoegd blijft de code even overzichtelijk.
Herhaling of iteratie (lusverloop)
[bewerken]Begrensd
[bewerken]Er bestaat helaas geen bestaande functie om een stuk tekst automatisch van boven naar beneden te laten verschijnen. Na iedere letter zou er een alineamarkering moeten komen. Het aantal keren dat we dit moeten doen wordt bepaald door het aantal letters in het woord. We zitten dus duidelijk met een begrensde herhaling.
Voor teller = 1 tot familienaam.lengte vertikaleFamilienaam = vertikaleFamilienaam & familienaam.letterOpPositie(teller) & enter
Merk op dat we vertikaleFamilienaam = vertikaleFamilienaam...
schrijven, omdat anders de bestaande waarde van vertikaleFamilienaam steeds wordt overschreven. Dit zou betekenen dat enkel de laatste letter van de familienaam (gevolgd door een alineamarkering) zou opgeslaan worden.
Voorwaardelijk (met zolang-beginvoorwaarde)
[bewerken]Bij de enkelvoudige keuze werd de correcte termijn al berekend (nl. rekening houden met een maximum aantal termijnen van 24 maanden). Voor het opstellen van het afbetalingsplan hebben we nood aan een voorwaardelijke herhaling. We moeten immers steeds de termijn optellen bij de voorgaande termijn, totdat het bedrag dat moest betaald worden bereikt wordt.
Het kan natuurlijk zijn dat de laatste maand iets minder dan de termijn betaald moet worden. Om dit te controleren hebben we nood aan een enkelvoudige keuze. Voor de duidelijkheid vermelden we dit direct bij dit gedeelte i.p.v. bij de enkelvoudige keuze.
voorlopigBedrag als getal = 0 maand als getal = 1 Zolang voorlopigBedrag < teBetalen voorlopigBedrag = voorlopigBedrag + termijn afbetalingsplan = afbetalingsplan & "maand " & maand & ": " & voorlopigBedrag & enter maand = maand + 1 'De eventuele nog te betalen termijn moeten we er nog bijplaatsen Als teBetalen - voorlopigBedrag > 0 Dan afbetalingsplan = afbetalingsplan & "maand " & maand & ": " & teBetalen - voorlopigBedrag & enter
Dit was een voorwaardelijke herhaling met een zolang-beginvoorwaarde. We konden dit echter net zo goed neergeschreven hebben met een totdat-beginvoorwaarde, een zolang-eindvoorwaarde of een totdat-eindvoorwaarde. Dit valt echter buiten het bereik van deze cursus.
Genest
[bewerken]Een geneste controlestructuur betekent dat meerdere controlestructuren in elkaar verweven zitten. Dit hebben we al gezien bij de tweevoudige keuze, waarbij we de verplaatsingskosten moesten berekenen. Niets houdt ons echter tegen om bv. een tweevoudige keuze te plaatsen binnen een begrensde herhaling. Oefeningen hierop vallen echter buiten het bereik van deze cursus.