Meer Fibonacci

Introductie

In de vorige oefening heb je een reeks Fibonacci-nummers gemaakt met GOTO (1,1,2,3,5...). Het werkte goed. Maar veel programmeurs krijgen de rillingen wanneer ze een GOTO in een programma zien. De reden is dat één GOTO gemakkelijk kan worden gevolgd, maar 100 GOTO's maken je programma een chaos van sprongen, meestal genaamd 'spaghetti code'. Dergelijke code is niet erg leesbaar en na een tijdje kun je in bugs (fouten) verdwalen die je niet kunt oplossen. 


In 1968 schreef Edsger Dijkstra, een beroemde Nederlandse computerwetenschapper, een artikel getiteld "GO TO-statement schadelijk bevonden". Het markeerde het begin van het einde van GOTO.


Edsger Dijkstra
Daarom hebben moderne talen alternatieven voor GOTO. Dit zijn de zogenaamde lusconstructies. Er zijn er drie:
  • De FOR..NEXT. Dit is een handig hulpmiddel om iets een vast aantal keer te herhalen, bijvoorbeeld voor de eerste 10 nummers
  • De WHILE..WEND. Dit is een commando voor herhaling zolang iets waar is.
  • De DO..LOOP WHILE. Dit is hetzelfde commando als WHILE, maar het controleert de voorwaarde aan het einde (waardoor het altijd minimaal 1 keer uitvoert)

Voorbeelden:
FOR..NEXT:
FOR I=1 TO 5
PRINT I
NEXT I


WHILE:
A=1
WHILE A<3
A=A+1
WEND
PRINT A


DO..LOOP:
N=1
DO
N=N+1
LOOP WHILE N < 4
PRINT N

Het is belangrijk om op te merken dat het mogelijk is dat een WHILE nul keer uitvoert, maar een DO..LOOP zal altijd minstens 1 keer de lus uitvoeren. In sommige versies van BASIC is het ook mogelijk om met LOOP UNTIL te eindigen, wat alleen de omgekeerde controle is (dus in dit geval N> = 3).

Een ander nieuw concept dat we zullen gebruiken (eindelijk!) is gebruikersinvoer. We hebben tot nu toe altijd de exacte variabelen aan het programma gegeven, wat betekent dat het programma altijd hetzelfde zal doen wanneer we het uitvoeren. Dit is niet echt praktisch. Met gebruikersinvoer kunnen we elke keer weer verschillende resultaten krijgen, en maken we het programma veelzijdiger.

De belangrijkste invoermethode is de INPUT functie:
INPUT "Hoe oud ben jij?", LEEFTIJD
De vraag wordt op het scherm weergegeven en het programma wacht op de gebruiker om een ​​antwoord te typen en op ENTER te drukken. De variabele LEEFTIJD wordt gevuld met het nummer dat de gebruiker heeft ingevoerd.

In games

Net als bij de IF zijn lusconstructies essentieel voor elk programma, inclusief games. Zonder lusconstructies (of GOTO) kunnen we niet meer dan eenvoudige programma's schrijven. Neem een ​​klassiek spel als Tetris: elke paar seconden verschijnt er een nieuw puzzelstuk. Om dit zonder loops te programmeren, zouden we elk stuk individueel geprogrammeerd moeten hebben. Als we 3000 stuks hebben, zou het minstens 3000 programmaregels hebben, allemaal identiek. Dat is veel kopiëren en plakken, en het spel stopt nog steeds als je bij de 3000 aankomt!
Tekstinvoer is niet iets waarmee we in moderne spellen gewend zijn. Dat komt omdat we nu de muis en het aanraakscherm hebben als alternatieven. Dit zijn echter nog steeds een soort invoerwaarden voor het programma (X, Y positie op het scherm).

Er moet opgemerkt worden dat moderne spellen en andere software gebruik maken van wat we events noemen (gebeurtenissen). Dit betekent: als een gebruiker op de muis klikt, doe dan dit. Of: als de gebruiker de spatiebalk drukt, doe dan dat. Op deze manier lijken we de lussen volledig te kunnen voorkomen. Echter, het programma gebruikt nog steeds lussen in wat de zogenaamde 'event loop' genoemd wordt. Dat is een klein programma dat constant controleert of een gebruiker op een knop klikt of op een toets drukt.

Opdracht
In deze oefening worden de eerste N Fibonacci nummers weergegeven. Het nummer N wordt door de gebruiker ingevoerd. Deze keer gebruiken we een ander algoritme, zonder GOTO.
  1. Vraag de gebruiker om het nummer N met een vriendelijke vraag
  2. Maak de variabelen A en B en stel ze in op 0 en 1, zoals in de vorige oefening
  3. Maak een FOR..NEXT-lus die N keer uitvoert
  4. Druk het nummer A af
  5. Maak een variabele C en plaats daarin de uitkomst van de som van A en B
  6. Zet nu B in A en zet C in B (verplaats hun waarden)
  7. Vergeet niet de NEXT
Hoe dit werkt is met een zogenaamde schuifoperatie. Je verplaatst variabelen van rechts naar links.
Pas op met:
  • De volgorde van de code. Plaats eerst B in A, dan C in B, anders zou je de originele waarde van B overschrijven.
  • Bewaar je programma voordat je op RUN drukt, omdat een oneindige lus betekent dat je het hele programma kwijtraakt!
Verwacht resultaat
Hoeveel getallen zal ik laten zien?
<gebruiker typt 7>
0
1
1
2
3
5
8

Veelgemaakte fouten

  • Syntaxis van de INPUT functie
  • Een vast aantal lussen maken, in plaats van de invoerwaarde te gebruiken
  • Fouten in de Fibonacci berekening (controleer dit met behulp van de vorige oefening)
  • Onjuist gebruik van FOR..NEXT syntaxis

Extra uitdaging

Maak je programma zodanig dat niet alleen het Fibonacci getal wordt afgedrukt, maar ook de teller, op deze manier:
Hoeveel getallen zal ik laten zien?
<gebruiker typt 7>
1 0
2 1
3 1
4 2
5 3
6 5
7 8

Bronnen

  • https://nl.wikipedia.org/wiki/Fibonacci
  • https://en.wikibooks.org/wiki/QBasic/Flow_Control#FOR...NEXT
  • https://nl.wikipedia.org/wiki/Edsger_W._Dijkstra
  • http://homepages.cwi.nl/~storm/teaching/reader/Dijkstra68.pdf
  • https://www.youtube.com/watch?v=RCCigccBzIU

(Er zijn nog geen discussies in dit forum)