# 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

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)
### Enkelvoudig

| NS-diagram | Pseudocode | VBA | PHP |
| | Als <voorwaarde> Dan <instructie 1> <instructie 2> ... <instructie n> | If <voorwaarde> Then <instructie 1> <instructie 2> ... <instructie n> End If | if (<voorwaarde>) { <instructie 1>; <instructie 2>; ... <instructie n>; } |

### Tweevoudig

| NS-diagram | Pseudocode | VBA | PHP |
| | Als <voorwaarde> Dan <instructie 1> <instructie 2> ... <instructie n> Anders <instructie a> <instructie b> … <instructie ...> | If <voorwaarde> Then <instructie 1> <instructie 2> … <instructie n> Else <instructie a> <instructie b> … <instructie ...> End If | if (<voorwaarde>) { <instructie 1>; <instructie 2>; … <instructie n>; } else { <instructie a>; <instructie b>; … <instructie ...>; } |

### Meervoudig

| NS-diagram | Pseudocode | VBA | PHP |
| | Selecteer Geval <variabele> Geval <expressielijst 1> <instructieblok 1> Geval <expressielijst 2> <instructieblok 2> | Select Case <variabele> Case: <expressielijst 1> <instructieblok 1> Case <expressielijst 2> <instructieblok 2> End Select | switch (<variabele>) { case <expressielijst 1>: <instructieblok 1> case <expressielijst 2>: <instructieblok 2> } |

## Herhaling of iteratie (lusverloop)
### Begrensd
#### Het kopieercentrum

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

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

| NS-diagram | Pseudocode | VBA | PHP |
| | Voor <variabele>= … tot … <instructieblok> | For <teller>= begin To einde <instructieblok> Next | for ( … ; … ; … ) { <instructieblok 1> } |

### Voorwaardelijk herhaling met beginvoorwaarde

| NS-diagram | Pseudocode | VBA | PHP |
| | Zolang <voorwaarde> <instructieblok> | Do While <voorwaarde> <instructieblok> Loop | while (<voorwaarde>) { <instructieblok> } |
| NS-diagram | Pseudocode | VBA | PHP |
| | Totdat <voorwaarde> <instructieblok> | Do Until <voorwaarde> <instructieblok> Loop | |

### Voorwaardelijk herhaling met eindvoorwaarde

| NS-diagram | Pseudocode | VBA | PHP |
| | Doe <instructieblok> Zolang <voorwaarde> | Do <instructieblok> Loop While <voorwaarde> | do { <instructieblok> } while (<voorwaarde>) |
| NS-diagram | Pseudocode | VBA | PHP |
| | Doe <instructieblok> Totdat <voorwaarde> | Do <instructieblok> Loop Until <voorwaarde> | |

## Genest

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.

## Oefeningen
### Taalrapport

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!"

### Tekstvak met kleur

   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

### Prijsofferte
#### Keuze of selectie (conditioneel verloop)
##### Enkelvoudig

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

Voor de ouderdom van het huis kunnen we dus beter gebruikmaken van een tweevoudige keuze, wat de uitvoer van ons programma sneller zal maken:
Voor het bepalen van de verplaatsingskosten merken we ook een keuze:
Hier maken we echter opnieuw de fout dat we vier keer controleren in welke provincie de klant woont, dus dat kan beter.
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

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)
##### Begrensd

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.
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)

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.
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

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.