home *** CD-ROM | disk | FTP | other *** search
/ RUN Flagazine Extra: Special 2 / run-special-2.zip / CURSUS_2.ASC < prev    next >
Text File  |  1992-06-09  |  42KB  |  677 lines

  1. DE GW-BASIC INTERPRETER (3)
  2.  
  3. BASIC is een tolerante programmeertaal. Alles mag... Ook dom programme-
  4. ren! Willen we van Rotterdam naar Amsterdam via de Afsluitdijk dan zegt
  5. BASIC: Okay, we do it the hard way! en de vertolker doet vervolgens pre-
  6. cies wat we hem in een dom programma voorschrijven.
  7.  
  8. De FOR/NEXT-kringloop                   ╔══════════════════════════════╗
  9.                                         ║   Dit is een DOM programma   ║
  10. Een van de allerbelangrijkste functies  ╠══════════════════════════════╣
  11. binnen GWBASIC is de kringloop die we   ║ 10 REM MAAK DE TAFEL VAN 10  ║
  12. met FOR .. in gang zetten. Wie deze     ║ 20 A=1:B=10                  ║
  13. kringloop goed begrijpt kan al voor de  ║ 30 PRINT A;" x ";B;" = ";A*B ║
  14. helft programmeren in GWBASIC. In fei-  ║ 40 A=A+1                     ║
  15. te kun je zeggen dat de FOR/NEXT-loop   ║ 50 PRINT A;" x ";B;" = ";A*B ║
  16. de kern van de zaak binnen GWBASIC is.  ║ 60 A=A+1                     ║
  17. Met de FOR/NEXT-lus gaan we werkelijk   ║ 70 PRINT A;" x ";B;" = ";A*B ║
  18. tot automatisering over!                ║ 80 A=A+1                     ║
  19. Na FOR komt altijd een variabele te     ║ 90 PRINT A;" x ";B;" = ";A*B ║
  20. staan. A bijvoorbeeld maar het mag ook  ║ 100 A=A+1                    ║
  21. B, A% of voluit Teller zijn. Deze va-   ║ 110 PRINT A:" x ";B;" = ";A*B║
  22. riabele moet vervolgens worden benoemd. ║ 120 A=A+1                    ║
  23. Dat doen we door achter de variabele    ║ enz....                      ║
  24. het isgelijkteken te typen:             ╚══════════════════════════════╝
  25. FOR Teller=
  26. In de vorige les in RUN-Special   nr. 1 hebben we vastgesteld dat er in
  27. een programma altijd een bepaalde 'flow' zit die we in een stroomsche-
  28. maatje aanschouwelijk maken nog voordat we gaan programmeren. Daardoor
  29. wordt ook het op te lossen probleem overzichtelijker.
  30. De variabele Teller moet een aanvangswaarde krijgen. Deze aanvangswaarde
  31. hangt af van hoe we de kringloop willen laten draaien. Bij het automa-
  32. tisch maken van bijvoorbeeld de tafel van tien gaat de kringloop uiter-
  33. aard van 1 tot en met 10. Het begin van de kringloop wordt dan:
  34. FOR Teller=1 TO 10
  35. In het onderstaande stroomschema laten we de computer in een FOR/NEXT-
  36. loop tellen van 1 tot en met 10. Het eind van de kringloop wordt aange-
  37. geven met:NEXT Teller. In een kringloop die alléén maar van 1 to 10
  38. telt, gebeurt er wat hieronder schematisch is weergegeven:
  39.  
  40.    ┌────────────────────┐       De kringloop begint bij de aanvang van
  41.  ┌─> FOR Teller=1 TO 10 │       de FOR/NEXT-loop waarin de numerieke va-
  42.  │ └─────────┬──────────┘       riabele Teller op de waarde 1 wordt ge-
  43.  │ ┌─────────┴──────────┐       zet. Deze variabele wordt geprint (op
  44.  │ │ PRINT Teller       │       het scherm gezet). 
  45.  │ └─────────┬──────────┘       Nu botst de kringloop tegen het keer-
  46.  │ ┌─────────┴──────────┐       punt: NEXT Teller aan waar de vraag 
  47.  │ │ Is Teller al 10?   ├───┐   wordt gesteld: heeft Teller de waarde
  48.  │ └─────────┬──────────┘Ja │   10 al bereikt. Het antwoord is nu nog
  49.  │           │Nee           │   nee omdat Teller pas 1 is. Daarom wordt
  50.  │ ┌─────────┴──────────┐   │   Teller met 1 opgehoogd, wordt 2 en keert
  51.  │ │ Teller=Teller+1    │   │   terug in de kringloop. Daarin wordt de
  52.  │ └─────────┬──────────┘   │   waarde van Teller weer geprint. En weer
  53.  │ ┌─────────┴──────────┐   │   wordt de vraag gesteld of Teller al 10
  54.  └─┤ NEXT Teller        │   │   is geworden.
  55.    └────────────────────┘   │   Zo lang Teller NIET 10 is, houdt NEXT de
  56.                             │   kringloop gaande. Pas wanneer Teller WEL
  57.    ┌────────────────────┐   │   10 is geworden, zet NEXT het deurtje
  58.    │ Rest programma     <───┘   open en mag de programma-flow verder
  59.    │                    │       gaan. De FOR/NEXT-kringloop mag dan wor-
  60.    ■                    ■       den verlaten.
  61.  
  62. Het programma waarin we de computer van 1 tot en met 10 laten tellen,  
  63. ziet er nu ontzettend simpel uit:
  64.  
  65. ┌───────────────────────┐       Gewapend met deze basiskennis kunnen we
  66. │ 10 FOR Teller=1 to 10 │       nu het maken van de tafel van 10 automa-
  67. │ 20 PRINT Teller       │       tiseren. Niet zoals in het domme progra-
  68. │ 30 NEXT Teller        │       op de eerste pagina, maar zoals het
  69. │ 40 END                │       hoort in een FOR/NEXT-lus.
  70. └───────────────────────┘
  71.  
  72. In een tafel wordt ook van 1 tot   ╔════════════════════════════╗ 
  73. en met 10 geteld maar achter elke  ║       De tafel van 10      ║
  74. Teller komt nog wat meer te staan: ╟────────────────────────────╢
  75. het maalteken, de constante waar-  ║ 10 CLS                     ║
  76. mee moet worden vermenigvuldigd,   ║ 20 Tafel = 10              ║
  77. het isgelijkteken en tenslotte de  ║ 30 FOR Teller = 1 TO Tafel ║
  78. uitkomst van de vermenigvuldiging. ║ 40 PRINT Teller;           ║
  79. Ook dat brengen we onder in de     ║ 50 PRINT " x ";            ║
  80. FOR/NEXT-lus. Daarbij zorgen we    ║ 60 PRINT Tafel;            ║
  81. ervoor dat de cursor bij een vol-  ║ 70 PRINT " = ";            ║
  82. gende PRINT-opdracht niet naar     ║ 80 PRINT Teller * Tafel    ║
  83. een nieuwe regel verspringt door   ║ 90 NEXT Teller             ║
  84. achter datgene wat er moet wor-    ║ 100 END                    ║
  85. den geprint de puntkomma te plaat- ╚════════════════════════════╝
  86. sten:
  87. ┌──────────────┐  
  88. │ PRINT Teller;│  Wie nu heel even doordenkt, beseft dat we met deze
  89. │ PRINT " x "; │  programmeerkennis ELKE tafel kunnen laten maken. In
  90. │ PRINT Tafel; │  regel 20 van het voorbeeldprogramma wordt de numerie-
  91. │ PRINT " = "; │  ke variabele Tafel benoemd met de waarde 10. 
  92. └──────────────┘  We kunnen Tafel elke gewenste waarde meegeven door aan
  93. het begin van het programma en nog voordat de kringloop begint om INPUT
  94. te laten vragen en het antwoord van de gebruiker in de variabele Tafel
  95. op te nemen. In dit geval kan regel 20 van het programma worden gewij-
  96. zigd in:
  97. 20 PRINT "Welke tafel?";      ┌─────────────────■TIP■──────────────────┐
  98. 25 INPUT Tafel                │ Als we beginnen met programmeren kun-  │
  99. of korter:                    │ nen we de regelnummers met increments  │
  100. 20 INPUT "Welke tafel";Tafel  │ van tien automatisch op het scherm la- │
  101.                               │ ten zetten met de opdracht: AUTO       │
  102. FOR/NEXT-manipulaties         └────────────────────────────────────────┘
  103.  
  104. Elke repeterende werkzaamheid binnen een GWBASIC-programma brengen we
  105. onder in de FOR/NEXT-kringloop. Daarbij kunnen we ook de wijze waarop
  106. moet worden geteld variëren. Stel dat we alle oneven getallen willen
  107. weten tussen de getallen 1 en 50. We moeten dat sprongs- of stapsgewijs
  108. laten tellen. Dat kan met de extra opdracht: STEP, gevolgd door de stap-
  109. waarde. Die is bij het laten printen van alléén de oneven getallen:
  110. STEP 2.
  111.  
  112. ╔═════════════════════════════════════╗  Als we het hiernaast staande 
  113. ║ 10 REM GEEF ONEVEN GETALLEN WEER    ║  programmaatje in GWBASIC invoe-
  114. ║ 20 FOR Stapteller = 1 TO 50 STEP 2  ║  ren en laten RUNnen, zal opval-
  115. ║ 30 PRINT Stapteller,                ║  len dat de oneven getallen net-
  116. ║ 40 NEXT Stapteller                  ║  jes in kolommen van vier op het
  117. ╚═════════════════════════════════════╝  scherm komen te staan. Dat komt
  118. doordat in de PRINT-opdracht van regel 30 achter de variabele Stapteller
  119. een komma is geplaatst. Deze komma zorgt voor het afdrukken in TABula-
  120. tor-formaat. Zou in plaats van de komma een puntkomma zijn geplaatst dan
  121. zouden de uitkomsten achter elkaar worden geprint. Staat er geen leeste-
  122. ken achter Stapteller dan worden ze onder elkaar gezet.
  123.  
  124. Wachtlussen
  125.  
  126. Sommige programma-afwerkingen gaan zó snel dat de programmeur het nodig
  127. kan vinden de programma-flow wat af te remmen. Het is gewoonte dan ge-
  128. bruik te maken van een loze FOR/NEXT-loop. Het programma wordt gedwongen
  129. een FOR/NEXT-loop af te werken en daarin niets te doen, bijvoorbeeld:
  130. 800 FOR I=1 TO 10000:NEXT I            ╔═══════════════════════════════╗
  131. De tijd die de computer nodig heeft    ║     Tijdonafhankelijke        ║
  132. om zo'n loze kringloop te doorlopen    ║     wachtlus met TIMER        ║
  133. bedraagt één tot enkele seconden, af-  ╟───────────────────────────────╢
  134. hankelijk van de snelheid van de pro-  ║ 10 PRINT "Hoeveel seconden?"  ║
  135. cessor. Aangezien we te maken hebben   ║ 20 INPUT S                    ║
  136. met diverse types PC (de XT, de AT,    ║ 30 GOSUB 1000                 ║
  137. de 386-PC en de 486-PC) die alle op    ║ 40 BEEP                       ║
  138. verschillende interne kloksnelheden    ║ 50 PRINT S;"seconden voorbij" ║
  139. lopen, werkt de wachtlus in de vorm    ║ 60 END                        ║
  140. van een loze FOR/NEXT-loop niet lek-   ╠═══════════════════════════════╣
  141. ker. Wie gebruik maakt van een BASIC-  ║ 1000 T=TIMER                  ║
  142. compiler als TurboBASIC of QuickBASIC  ║ 1010 WHILE TIMER-T < S        ║
  143. gebruikt de wachtlus dan ook niet. Hij ║ 1020 WEND                     ║
  144. heeft daarvoor een tijdonafhankelijke  ║ 1030 RETURN                   ║
  145. wachtopdracht: DELAY x, waarin de va-  ╚═══════════════════════════════╝
  146. riabele x het aantal seconden bedraagt. DELAY (onbekend in GWBASIC) kun-
  147. nen we wel namaken in het hiernaast staande Programmaatje. Het maakt
  148. gebruik van de GWBASIC-functie: TIMER. Dat is de zogenoemde microtimer
  149. die in veel RUN-programma's ook dienst doet om RANDOMIZE van een wille-
  150. keurig zaadgetal te voorzien.
  151.  
  152. Terugtellen
  153.  
  154. We kunnen het verloop van een programmadeel binnen een FOR/NEXT-lus ook
  155. in omgekeerde volgorde laten afwerken. De reeds genoemde extra opdracht:
  156. STEP speelt daarin een belangrijke rol en moet bij omgekeerde volgorden
  157. altijd worden benoemd. De simpelste vorm van een teruglopende FOR/NEXT-
  158. lus maakt direct duidelijk wat we bedoelen. We hebben de PC in GWBASIC
  159. al laten (op)tellen: van 1 tot en met 10. In één programmaregel weerge-
  160. geven gaat dat als volgt:
  161. ┌──────────────────────────────────────────────────────────────────────┐
  162. │ 10 FOR Teller=1 TO 10:PRINT Teller:NEXT Teller                       │
  163. └──────────────────────────────────────────────────────────────────────┘
  164. Willen we cijfers in omgekeerde volgorde op het scherm zien dan moeten
  165. we de variabele Teller ook terug laten tellen.      
  166. ECHTER:                                          
  167. ┌──────────────────────────────────────────────────────────────────────┐
  168. │ 10 FOR Teller=10 TO 1:PRINT Teller:NEXT Teller                       │
  169. └──────────────────────────────────────────────────────────────────────┘
  170. zal niet werken. GWBASIC geeft weliswaar geen foutmelding maar op het
  171. scherm verschijnt niets. De teruglopende FOR/NEXT-lus is namelijk incom-
  172. pleet. We zijn de STEP-waarde vergeten die bij teruglopende FOR/NEXT-
  173. lussen verplicht is èn altijd een negatieve waarde krijgt. Terugtellen
  174. van 10 tot en met 1 gaat aldus:               
  175. ┌──────────────────────────────────────────────────────────────────────┐
  176. │ 10 FOR Teller=10 TO 1 STEP -1:PRINT Teller:NEXT Teller               │
  177. └──────────────────────────────────────────────────────────────────────┘
  178. Nu ligt het voor de hand dat wanneer we alléén de even cijfers in omge-
  179. keerde volgorde willen zien, de programmaregel aldus moet zijn:
  180. ┌──────────────────────────────────────────────────────────────────────┐
  181. │ 10 FOR Teller=10 TO 1 STEP -2:PRINT Teller:NEXT Teller               │
  182. └──────────────────────────────────────────────────────────────────────┘
  183. en alle oneven cijfers:                               
  184. ┌──────────────────────────────────────────────────────────────────────┐
  185. │ 10 FOR Teller=9 TO 1 STEP -2:PRINT Teller:NEXT Teller                │
  186. └──────────────────────────────────────────────────────────────────────┘
  187.  
  188. OPGAVE:                               ╔══════════════════════════════╗
  189. Type het hiernaast staande voorbeeld- ║ 100 CLS:KEY OFF:WACHT=.2     ║
  190. programma over in GWBASIC. RUN het.   ║ 110 FOR A=1 TO 80            ║
  191. Bestudeer het. Geef vervolgens LIST   ║ 120   LOCATE 1,A             ║
  192. en ga de programma-flow na. Nu moet   ║ 130   PRINT CHR$(219);       ║
  193. u aan de hand van de listing begrij-  ║ 140   LOCATE 5,1             ║
  194. pen wat er gebeurt. Als u niet voor   ║ 150   PRINT "LOCATE 1,";A    ║
  195. honderd procent snapt wat het pro-    ║ 160   GOSUB 500              ║
  196. grammaatje doet, is het verstandig    ║ 170 NEXT A                   ║
  197. deze les opnieuw door te nemen.       ║ 180 BEEP                     ║
  198.                                       ║ 190 LOCATE 5,1               ║
  199. Als dit programma goed loopt, wordt   ║ 200 PRINT "Druk 'n toets"    ║
  200. in de FOR/NEXT-loop van regel 110     ║ 210 WHILE INKEY$="":WEND     ║
  201. tot en met 170 een balk bovenin het   ║ 220 FOR A=80 TO 1 STEP -2    ║
  202. scherm getrokken. De tijdonafhanke-   ║ 230   LOCATE 1,A             ║
  203. lijke wachtlus uit de subroutine in   ║ 240   PRINT " ";             ║
  204. 500 zorgt voor de vertraging. Als de  ║ 250   LOCATE 5,1             ║
  205. balk is getrokken, volgt een BEEP en  ║ 260   PRINT "LOCATE 1,";A    ║
  206. de vraag van het programma om een     ║ 270   GOSUB 500              ║
  207. toets in te drukken. Vervolgens gaat  ║ 280 NEXT A                   ║
  208. een volgende FOR/NEXT-loop in omge-   ║ 290 END                      ║
  209. keerde volgorde aan het werk. Van     ║ 500 T=TIMER                  ║
  210. achter naar voren wordt in de balk    ║ 510 WHILE TIMER-T<WACHT      ║
  211. en afwisselend om de twee schermpo-   ║ 520 WEND                     ║
  212. sities (STEP -2) een spatie (" ")     ║ 530 RETURN                   ║
  213. geprint. Een kartelbalk is het uit-   ╚══════════════════════════════╝
  214. eindelijke resultaat.                                                 
  215. Valt het u op dat het een goede programmeergewoonte is om extra ruimte
  216. of indents te gebruiken in de regels die zich tussen FOR en NEXT afspe-
  217. len? Dit is niet verplicht maar het verhoogt de leesbaarheid van het
  218. programma.
  219.  
  220. Een ander type kringloop: WHILE/WEND
  221.  
  222. De FOR/NEXT-loop is in principe een eindige kringloop. Hij loopt steeds
  223. TOT EN MET iets. Zodra het einddoel wordt bereikt, wordt de lus door
  224. NEXT beëindigd. Men kan ook zeggen dat een FOR/NEXT-loop zich beweegt
  225. van A naar B en er naar streeft om B te bereiken.
  226. De WHILE/WEND-loop die we in de voorbeeldprogrammaatjes al diverse keren
  227. zijn tegengekomen, streeft een ander doel na. Binnen dit type loop
  228. vraagt het programma zich voortdurend af of een bepaalde situatie nog
  229. steeds van kracht is. Letterlijk zegt de WHILE/WEND-loop tegen zichzelf:
  230. ZOLANG (WHILE) een situatie van kracht is, DOE dan wat er in de loop
  231. staat. BLIJF dit doen (WEND) totdat die situatie verandert.
  232. Bijvoorbeeld:
  233. ZOLANG er geen toets wordt ingedrukt DOE dan niets
  234. of anders gezegd:
  235. ZODRA er een toets wordt ingedrukt GA dan verder met het programma.
  236. Als we dit even tot ons laten doordringen wordt deze programmaregel
  237. leesbaar:
  238. ┌──────────────────────────────────────────────────────────────────────┐
  239. │ 100 WHILE INKEY$="":WEND                                             │
  240. └──────────────────────────────────────────────────────────────────────┘
  241. Deze permanente wachtlus waarin op een toetsaanslag wordt gewacht, is
  242. een stuk eleganter dan het vaak gebruikte alternatief:
  243. ┌──────────────────────────────────────────────────────────────────────┐
  244. │ 100 I$=INKEY$:IF I$="" THEN 100                                      │
  245. └──────────────────────────────────────────────────────────────────────┘
  246. Met dezelfde, simpele WHILE/WEND-constructie kunnen we ook gemakkelijk
  247. op een bepaalde intoetsing laten wachten, bijvoorbeeld van de Enter-
  248. toets: CHR$(13) of van de Esc-toets: CHR$(27):
  249. ┌──────────────────────────────────────────────────────────────────────┐
  250. │ 100 PRINT "Druk op <Enter>"                                          │
  251. │ 110 WHILE INKEY$<>CHR$(13):WEND                                      │
  252. └──────────────────────────────────────────────────────────────────────┘
  253. In dit geval reageert het programma uitsluitend op het indrukken van de
  254. Enter-toets. Alle andere intoetsingen worden genegeerd.
  255. ╔═══════════════════╗  In het programmaatje hiernaast laten we een be-
  256. ║ 100 CLS:KEY OFF   ║  paalde situatie voortduren. Zolang die situatie
  257. ║ 110 WHILE B<10000 ║  van kracht is moet er gebeuren wat er tussen
  258. ║ 120   A=A+1       ║  WHILE en WEND staat.
  259. ║ 130   B=A*A       ║  In gewone taal: Zolang de variabele B kleiner is
  260. ║ 140   PRINT B     ║  dan 10000 moet A met 1 worden opgehoogd; B krijgt
  261. ║ 150 WEND          ║  de inhoud van de vermenigvuldiging A maal A en de
  262. ╚═══════════════════╝  uitkomst van B moet kolomsgewijs op het scherm
  263. worden afgedrukt. Zodra B de waarde 10000 heeft bereikt kan WEND de
  264. kringloop niet meer tegenhouden en terugsturen.
  265. De WHILE/WEND-kringloop is bij uitstek geschikt om tot in het oneindige
  266. naar iets te zoeken. Priemgetallen bijvoorbeeld. Of alle getallen onder
  267. de 1000 die deelbaar zijn door 13:     
  268. Bij het begin van dit voor-   ╔═══════════════════════════════════════╗
  269. beeldprogramma wordt de va-   ║ 100 REM Zoek getallen deelbaar door 13║
  270. riabele A eerst op 1000 ge-   ║ 110 A=1000                            ║
  271. zet. Dan wordt de WHILE/WEND  ║ 120 WHILE A>13                        ║
  272. in gang gezet. Zolang A groter║ 130   A=A-1                           ║
  273. blijft dan 13 wordt A telkens ║ 140   B=A/13                          ║
  274. met 1 verminderd. Het resul-  ║ 150   IF B=INT(B) THEN PRINT A,       ║
  275. terende getal wordt door 13   ║ 160 WEND                              ║
  276. gedeeld en de uitkomst wordt  ╚═══════════════════════════════════════╝
  277. in de variabele B geplaatst. Dan vraagt het programma zich binnen de
  278. WHILE/WEND-loop af of de inhoud van B een integer getal is, dus zonder
  279. restgetallen. Een geheel getal dus. Als dat zo is, is A deelbaar door 13
  280. en wordt dat getal geprint. Afhankelijk van de waarde die A heeft,
  281. kaatst WEND de verwerking terug naar WHILE. We weten dat WEND het deur-
  282. tje pas openzet en de kringloop beëindigt als zij merkt dat A kleiner is
  283. geworden dan 13.                       
  284.                                        
  285. Zoeken binnen WHILE/WEND               
  286.                                        
  287. Zoek naar iets net zo lang totdat je het gevonden hebt... Dat is een
  288. uitstekende opdracht om binnen een WHILE/WEND-kringloop toe te passen.
  289. ╔═════════════════════════════════╗  Hiernaast staat een programma dat u
  290. ║ 10 RANDOMIZE TIMER:CLS          ║  in GWBASIC moet intypen en RUNnen.
  291. ║ 20 WHILE A<>100                 ║  Het is een WHILE/WEND-loop waarin
  292. ║ 30   B=B+1                      ║  naar het getal 100 wordt gezocht in
  293. ║ 40   A=INT(RND*500)             ║  een willekeurige reeks van getallen
  294. ║ 50   LOCATE 10,27               ║  die we door een random generator
  295. ║ 60   PRINT "Aantal loops:";B    ║  laten creëren. In regel 10 laten we
  296. ║ 70   LOCATE 10,27               ║  de microtimer van GWBASIC (TIMER)
  297. ║ 80   PRINT "Inhoud van A:";A    ║  het zaadgetal voor de randomizer 
  298. ║ 90 WEND                         ║  geven. Het scherm wordt gewist en
  299. ║ 100 BEEP:END                    ║  de WHILE/WEND-loop begint.
  300. ╚═════════════════════════════════╝  De bedoeling is dat het getal 100
  301. wordt gevonden in een willekeurig te genereren reeks van getallen.
  302. Hoeveel maal de RND-functie in regel 40 in actie komt, komen we te weten
  303. door het tellertje in regel 30. Elke keer wordt op schermpositie 10,27
  304. (regel 10, kolom 27) deze telling bijgehouden achter de aanduiding: Aan-
  305. tal loops. Daaronder, op LOCATE 12,27, komt achter de aanduiding: Inhoud
  306. van A, de inhoud van variabele A uit regel 40 te staan.
  307. Het zoeken naar het getal 100 gebeurt uit een willekeurige reeks van 500
  308. (regel 40). De loop kan kort, vrij lang of heel lang duren; dat is af-
  309. hankelijk van het toeval. In elk geval blijft de WHILE/WEND-loop net zo
  310. lang lopen totdat -toevallig- het getal 100 door de randomizer is geko-
  311. zen.                                   
  312. Voordat u een repeterende functie gaat programmeren moet u altijd even
  313. nadenken en uzelf afvragen: welk type kringloop is voor mijn doel het
  314. meest geschikt: de FOR/NEXT- of de WHILE/WEND-loop.
  315.                                        
  316. Geneste loops                          
  317.                                        
  318. Zoals al eerder benadrukt, is de FOR/NEXT-loop zeer veelzijdig. Behalve
  319. dat is hij ook bijzonder plooibaar. Er zijn lange programma's denkbaar
  320. waarin van alles en nog wat gebeurt en die zich vanaf het begin (RUN)
  321. tot het eind (END) afspelen binnen één zeer omvangrijke FOR/NEXT- of
  322. WHILE/WEND-loop.                       
  323. Een kringloop die met FOR .. begint, kan in zichzelf ook weer een
  324. FOR/NEXT-loop in zich hebben. En die ook weer, enzovoorts. We spreken
  325. dan van een geneste kringloop. Het programmeren van een geneste kring-
  326. loop kan behoorlijk lastig zijn en de programmeur moet zijn hersens er
  327. goed bij houden onder andere omdat de eerste of Hoofdloop pas mag eindi-
  328. gen als de binnenste loop is afgemaakt.
  329. Men kan zich een geneste loop voorstellen als een stel tandraderen die
  330. in elkaar draaien. Duidelijk voorbeeld is de digitale klok die seconden,
  331. minuten en uren registreert. Dit moet in drie geneste loops gebeuren: de
  332. binnenste voor het tellen van de seconden; een middelste voor het tellen
  333. van de minuten en een buitenste voor de uren.
  334. Schematisch:                           
  335.                                        ┌───────────────┐ 
  336.                                        │     Uur=0     │ 
  337.                                        └───────┬───────┘ 
  338.                                        ┌───────┴───────┐
  339.                                        │    Minuut=0   │
  340.                                        └───────┬───────┘
  341.                  ┌─────────────────┐   ┌───────┴───────┐
  342.              ┌───┤ Minuut=Minuut+1 │   │     Sec=0     │        
  343.              │   └────────┬────────┘   └───────┬───────┘        
  344.              │   ┌────────┴────────┐ N         │                
  345.              │   │  Is Minuut 60?  ├─┐         │                
  346.              │   └────────┬────────┘ │         │                 
  347.              │            │J         │ ┌───────┴───────┐        
  348.              │   ┌────────┴────────┐ ├─>   Sec=Sec+1   <───┐    
  349.              │   │    Minuut=0     │ │ └───────┬───────┘   │         
  350.              │   └────────┬────────┘ │ ┌───────┴───────┐N  │         
  351.              │   ┌────────┴────────┐ │ │   Is Sec 60?  ├───┘         
  352.              │   │    Uur=Uur+1    │ │ └───────┬───────┘             
  353.              │   └────────┬────────┘ │         │J                    
  354.              │            └──────────┘ ┌───────┴───────┐            
  355.              │                         │     Sec=0     │             
  356.              │                         └───────┬───────┘             
  357.              └─────────────────────────────────┘
  358.  
  359. Dit schema behoeft enige bestudering. Dat spreekt vanzelf. Bekijk het op
  360. uw gemak en volg de 'flow' van het diagram. We zien dan dat de buitenste
  361. loop, die van de secondentelling, het drukst in de weer is. De middelste
  362. loop krijgt alleen na het vollopen van de secondentelling (Sec=60) even
  363. iets te doen. De buitenste of hoofdloop komt om de 60x60 seconden of om
  364. de 60 minuten even in actie.
  365. Dit gaan we programmeren in een geneste FOR/NEXT-kringloop:
  366.  ╔════════════════════════════════════════════╗  In dit voorbeeldpro-
  367.  ║100 REM Uren, minuten, seconden             ║  gramma loopt een digi-
  368.  ║110 CLS:KEY OFF:WACHT=1                     ║  tale klok. Type het 
  369.  ║120 LOCATE 9,20:PRINT "Loop 1 - Seconden:"  ║  over en RUN het. Ver-
  370.  ║130 LOCATE 10,20:PRINT "Loop 2 - Minuten :" ║  geet niet de apostrofe
  371.  ║140 LOCATE 11,20:PRINT "Loop 3 - Uren    :" ║  (') te typen direct
  372.  ║150 FOR UREN=1 TO 24                        ║  achter regel 180. Dit
  373.  ║160     FOR MINUTEN=1 TO 60                 ║  is een REMmetje. Het
  374.  ║170         FOR SECONDEN=1 TO 60            ║  schakelt deze regel uit
  375.  ║180 '          GOSUB 280                    ║  en daarmee ook de gang
  376.  ║190            SEC=SEC+1                    ║  naar de subroutine 280
  377.  ║200            LOCATE 9,40:PRINT SEC        ║  waar een tijdonafhanke-
  378.  ║210         NEXT SECONDEN                   ║  lijke WHILE/WEND-wacht-
  379.  ║220       SEC=0:MIN=MIN+1                   ║  lus wordt aangeroepen.
  380.  ║230       LOCATE 10,40:PRINT MIN            ║  Deze wachtlus staat op
  381.  ║240     NEXT MINUTEN                        ║  één seconde: de tijd
  382.  ║250   MIN=0:UUR=UUR+1                       ║  die tussen de seconden
  383.  ║260   LOCATE 11,40:PRINT UUR                ║  moet verstrijken. Omdat
  384.  ║270 NEXT UREN                               ║  het dan veel te lang
  385.  ║280 T=TIMER:WHILE TIMER-T<WACHT:WEND:RETURN ║  duurt om deze geneste
  386.  ╚════════════════════════════════════════════╝  FOR/NEXT-loop aan het
  387. werk te zien, is de subroutine met het REMmetje op nonactief gezet.
  388. Om een realistische registratie van seconden, minuten en uren te krijgen
  389. moet de apostrofe met Del worden verwijderd of met een spatie worden
  390. overschreven.
  391. Merk ook op dat de overzichtelijkheid wordt gediend door deze geneste
  392. FOR/NEXT-loop met inspringingen of indents te markeren. Het wordt daar-
  393. door mogelijk de loop in ons voorstellingsvermogen aan het werk te zien.
  394. Dat vereist de nodige ervaring maar het gebeurt vooral om het 'debuggen'
  395. ofte wel het opsporen en corrigeren van programmeerfouten en -onvolko-
  396. menheden te vergemakkelijken.
  397.  
  398. Zo, ik dacht dat we het hier voorlopig maar bij moeten laten. Het was
  399. een lange en pittige les en ik moedig u aan om juist deze les enorm goed
  400. te bestuderen. Als de FOR/NEXT-loop en de WHILE/WEND-lus gesneden koek
  401. voor u wordt, bent u al verder dan halverwege om een GWBASIC-programmeur
  402. te worden.
  403. U kunt uzelf trouwens ook testen of u al op deze goede weg bent. Met de
  404. kennis die in de drie lessen tot nu toe is aangedragen moet het al moge-
  405. lijk zijn om zelf een probleempje te bedenken en dat in een GWBASIC-pro-
  406. grammaatje voor eens en altijd op te lossen.
  407. Mag ik u op weg helpen met de volgende opdracht?
  408.                                 ┌────────┐
  409. ┌───────────────────────────────┤Huiswerk├─────────────────────────────┐
  410. │                               └────────┘                             │
  411. │Als het u ernst is met het leren programmeren dan moet u het geleerde │
  412. │zo veel mogelijk in praktijk brengen met kleine vingeroefeningen. Veel│
  413. │proberen (en veel fouten maken) is de weg die naar het einddoel voert.│
  414. │Als huiswerk geef ik op: programmeer een dobbelsteen. In een FOR/NEXT-│
  415. │loop wordt heel snel van 1 tot en met 6 geteld totdat er op een toets │
  416. │wordt gedrukt. Op dat moment komt de dobbelsteen tot rust en staat op │
  417. │het scherm of het een een, twee, drie, vier, vijf of zes is geworden. │
  418. │Denk eerst even na en maak een stroomschemaatje dat er als volgt zou  │
  419. │kunnen uitzien:                                                       │
  420. │                         ┌───────────────────┐                        │
  421. │                     ┌───> Zolang geen toets │                        │
  422. │                     │   └────────┬──────────┘                        │
  423. │                     │        ┌───┴───┐                               │
  424. │                     │        │  LOOP │                               │
  425. │                     │        └───┬───┘                               │
  426. │                     │        ┌───┴───┐ j                             │
  427. │                     │        │ Toets?├───────┐                       │
  428. │                     │        └───┬───┘       │                       │
  429. │                     │            │n          │                       │
  430. │                     │     ┌──────┴───────┐   │                       │
  431. │                     │     │ 1,2,3,4,5of6?│   │                       │
  432. │                     │     └──────┬───────┘   │                       │
  433. │                     │       ┌────┴─────┐     │                       │
  434. │                     └───────┤ Doorgaan │     │                       │
  435. │                             └──────────┘     │                       │ 
  436. │                              ┌───────┐       │                       │
  437. │                              │  STOP <───────┘                       │
  438. │                              └───────┘                               │
  439. └──────────────────────────────────────────────────────────────────────┘
  440. In de volgende les (Deel 4 alweer) komt weer een pittig onderwerp aan de
  441. orde: tekstbewerking. Dat is het gedoe dat u zo vaak in RUN-programma's
  442. in het AD tegenkomt met LEFT$, RIGHT$ en MID$. Maar we duiken nog verder
  443. in de goed gevulde gereedschapskist van GWBASIC totdat we genoeg gereed-
  444. schappen kunnen hanteren om een kleine programmeerwedstrijd onder de
  445. cursisten te houden. 
  446.  
  447. TOT SLOT:
  448. Op deze RUN-Special    staat het programmaatje CAI (Computer Aided In-
  449. struction), in GWBASIC (CAI.BAS).          In dit programmaatje wordt de
  450. FOR/NEXT-loop van het maken van een willekeurige tafel gesimuleerd. U
  451. kunt de loop voor uw ogen zien werken.
  452. CAI.BAS is een bijzonder programma. Het simuleert in GWBASIC... GWBASIC
  453. zelf! Het geeft een listinkje van een programma dat tafels maakt. Na de
  454. invoer wordt de FOR/NEXT-loop gestart en kunt u de kringloop zien afspe-
  455. len. 
  456.  
  457. ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
  458. DE GWBASIC INTERPRETER (4)
  459.  
  460.                               Tekstbewerking
  461.  
  462. Deze vierde les gaat over tekstBEwerking; niet over tekstVERwerking. Wie
  463. de lessen van deze cursus tot nu toe aandachtig en zelf werkzaam heeft
  464. gevolgd, is al een eind op streek. Hij of zij beschikt al over de hulp-
  465. middelen om zelf kleine programmaatjes (vingeroefeningen) te doen. Met
  466. de kennis en ervaring die deze les biedt, wordt het al mogelijk zelf
  467. programma's te schrijven die de moeite van het bewaren op schijf waard
  468. zijn.
  469.  
  470. De ASCII-tabel
  471.  
  472. Iedere programmeur in onverschillig welke taal heeft de beroemde ASCII-
  473. tabel altijd binnen handbereik. Deze tabel bevat de internationaal ge-
  474. standaardiseerde codering voor de cijfers 1 tot en met 0, de hoofdlet-
  475. ters A tot en met Z, de kleine of onderkastletters a tot en met z, een
  476. groot aantal speciale en exotische tekens als é, ï, ƒ, ¿ en æ.
  477. In de ASCII-tabel (ASCII is de afkorting voor American Standard Code for
  478. Information Interchange) staan ze allemaal en heeft elk teken een num-
  479. mer.
  480. De nummers van de tekens corresponderen met de wijze waarop in
  481. GWBASIC een teken zichtbaar kan worden gemaakt op het beeldscherm of op
  482. de printer. Op het beeldscherm maken we de letter e zichtbaar door op
  483. het toetsenbord de e-toets in te drukken maar onder GWBASIC kan het ook
  484. aldus:
  485. PRINT CHR$(101)
  486. omdat nr. 101 van de ASCII-tabel de letter e is. CHR$( gevolgd door een
  487. ASCII-code en een haakjes sluiten haalt uit de karakterset het gevraagde
  488. teken op.
  489. Met het geleerde uit de vorige les (de FOR/NEXT-kringloop) kunnen we de
  490. afdrukbare ASCII-tekens op het beeldscherm zichtbaar maken.
  491. ╔═══════════════════════════════════════════╗ We doen dit met neven-
  492. ║ Maak ASCII-Tabel zichtbaar                ║ staand programma pagina-
  493. ╟───────────────────────────────────────────╢ gewijs zodat een nauwge-
  494. ║ 10 CLS:KEY OFF                            ║ zette bestudering moge-
  495. ║ 20 B%=0:C%=6                              ║ lijkt wordt. Daartoe dient
  496. ║ 30 GOSUB 110                              ║ het tellertje Q% dat niet
  497. ║ 40 B%=8:C%=8                              ║ meer dan 66 tekens tege-
  498. ║ 50 GOSUB 110                              ║ lijk op één scherm af-
  499. ║ 60 B%=14:C%=27                            ║ drukt en er vervolgens
  500. ║ 70 GOSUB 110                              ║ voor zorgt dat met een 
  501. ║ 80 B%=32:C%=255                           ║ druk op een toets de vol-
  502. ║ 90 GOSUB 110                              ║ gende serie wordt geprint.
  503. ║ 100 END                                   ║ De variabelen B% en C% wor-
  504. ║ 110 FOR A%=B% TO C%                       ║ den zodanig gekozen dat zij
  505. ║ 120 Q%=Q%+1                               ║ de niet afdrukbare ASCII-
  506. ║ 130 PRINT "CHR$(";A%;") = ";CHR$(A%);" ", ║ tekens overslaan.
  507. ║ 140 IF Q%=66 THEN Q%=0:GOTO 150 ELSE 160  ║ Het belangrijkste deel van
  508. ║ 150 WHILE INKEY$="":WEND:PRINT            ║ het programmaatje is, zo-
  509. ║ 160 NEXT A%                               ║ als u ziet ondergebracht in
  510. ║ 170 RETURN                                ║ de subroutine die in regel
  511. ╚═══════════════════════════════════════════╝ 110 begint en die in to-
  512. taal driemaal met verschillende variabelen wordt aangeroepen.
  513. Dat is al met al een hele uitwijding over de ASCII-tabel: basiskennis
  514. die we nodig hebben om met succes tekstbewerking in GWBASIC te kunnen
  515. toepassen.
  516.  
  517. Het woord RUN
  518.  
  519. Wanneer we het woord RUN opslaan in een string- of tekstvariabele, kun-
  520. nen we met het woord gaan spelen: A$="RUN". We kunnen nu van het woord
  521. in A$ een gedeelte zichtbaar maken, te rekenen vanaf de meest linkse
  522. (LEFT) positie. We moeten dan natuurlijk wèl aangeven welk gedeelte.
  523. Alléén de R is de meest linkse letter en daarvoor maken we gebruik van
  524. de functie: LEFT$(A$,1). Hier staat letterlijk: laat van het woord in A$
  525. het gedeelte zien TOT EN MET 1.
  526. Het is gemakkelijk in te zien dat:
  527. PRINT LEFT$(A$,2)
  528. het stukje van woord RUN tot en met de tweede letter laat zien: RU dus.
  529. Als u LEFT$(X$,x) begrijpt, moet het mogelijk zijn het resul-
  530. taat van het kleine programmaatje          ╔══════════════════════╗
  531. hiernaast zelf uit de regels af te         ║ 10 A$="RUN"          ║
  532. leiden zonder het programma in te ty-      ║ 20 PRINT LEFT$(A$,3) ║
  533. pen en daadwerkelijk te RUNnen.            ║ 30 PRINT LEFT$(A$,2) ║
  534. Dat is simpel. Als u dat ook vindt dan     ║ 40 PRINT LEFT$(A$,1) ║
  535. wordt het volgende onderwerp even simpel   ║ 50 END               ║
  536. want dat gaat over RIGHT$(X$,x) en u       ╚══════════════════════╝
  537. raadt al dat het hier gaat om het spiegelbeeld van LEFT$(X$,x). 
  538. In woorden uitgedrukt betekent RIGHT$(X$,x): het gedeelte van het woord
  539. in X$, te rekenen vanaf de meest rechtse (RIGHT) positie. Zonneklaar zal
  540. het dus zijn dat
  541. PRINT RIGHT$(A$,1)
  542. de meest rechtse letter van RUN in A$ zal op leveren: de N.
  543. PRINT RIGHT$(A$,2)
  544. levert dan het woorddeel op dat één positie naar rechts eindigt: UN.
  545. Met LEFT$ en RIGHT$ beschikken we over twee methoden om een woord of zin
  546. in een stringvariabele van twee kanten binnen te gaan en delen daarvan
  547. te isoleren.
  548. We veranderen de stringvariabele A$ in:
  549. A$="RUN Flagazine". U moet nu de volgende opdracht uitvoeren: Maak uit
  550. A$ twee nieuwe stringvariabelen: B$ en C$. In B$ moet alléén de deel-
  551. tekst: RUN worden gebracht en in C$ alléén de deeltekst: Flagazine.
  552. Ga uw gang...
  553. Gelukt? De juiste wijze van werken is als volgt:
  554. ╔═══════════════════════╗ Had u dat ook? Natuurlijk. Dat kan moeilijk
  555. ║ 10 A$="RUN Flagazine" ║ anders want het werken van LEFT$ en RIGHT$ is
  556. ║ 20 PRINT A$           ║ simpel. Met name LEFT$ wordt veel gebruikt om
  557. ║ 30 PRINT LEFT$(A$,3)  ║ het eerste ingetypte teken van een invoer-
  558. ║ 40 PRINT RIGHT$(A$,9) ║ string te weten te komen. Hoe vaak komt het
  559. ║ 50 END                ║ niet voor dat een programma de beroemde (j/n)-
  560. ╚═══════════════════════╝ vraag stelt. We weten nooit wat de gebruiker
  561. zal doen. Typt hij voluit ja of JA of j of J als hij 'ja' bedoelt of
  562. nee, NEE, n of N als hij 'nee' wil zeggen? Voorbeeld:
  563. 100 PRINT "Wilt u nog een berekening laten uitvoeren (j/n)";
  564. 110 INPUT A$
  565.                                  ┌───┐
  566. ┌────────────────────────────────┤TIP├─────────────────────────────────┐
  567. │                                └───┘                                 │
  568. │ Er bestaat een elegante methode om de (j/n) invoer klunsvast in een  │ 
  569. │ GWBASIC-programma op te nemen: niet met LEFT$(X$,x) maar met de zoge-│ 
  570. │ noemde INSTR-functie. Ter vergelijking laten we eerst de 'normale'   │
  571. │ en omslachtige methode zien:                                         │
  572. │                                                                      │
  573. │ 100 INPUT "Nog een keer spelen (j/n)";A$                             │
  574. │ 110 T$=LEFT$(A$,1):REM VOOR HET GEVAL DAT Ja OF Ja graag IN A$ STAAT │
  575. │ 120 IF T$<>"J" AND T$<>"j" AND T$<>"N" AND T$<>"n" THEN BEEP:GOTO 100│
  576. │ 130 IF T$="J" OR T$="j" THEN RUN ELSE CLS:END                        │
  577. │                                                                      │
  578. │ Dit hele verhaal met AND's en OR's kan veel simpeler door de eerste  │
  579. │ letter van de invoer in A$ te isoleren in T$ en vervolgens met INSTR │
  580. │ te kijken welke waarde T$ heeft. Bestudering van onderstaande listing│
  581. │ en natuurlijk het uitproberen daarvan op de eigen PC zal zéér verhel-│
  582. │ derend werken.                                                       │
  583. │                                                                      │
  584. │ 100 INPUT "Nog een keer spelen (j/n)";A$                             │
  585. │ 110 T$=LEFT$(A$,1)                                                   │
  586. │ 120 IF INSTR("JjNn",T$) = 0 OR T$ = "" THEN BEEP:GOTO 100            │
  587. │ 130 IF INSTR("JjNn",T$) < 3 THEN PRINT "Ja dus...":END               │
  588. │ 140 PRINT "Nee dus...":END                                           │
  589. │                                                                      │
  590. │ Eerst worden in regel 120 mogelijke baldadigheden afgevangen. Elke   │
  591. │ invoer in T$, die niet J, j, N of n is of een lege string is die het │
  592. │ gevolg is van een druk op <Enter> worden opgemerkt en met een BEEP en│
  593. │ een terugverwijzing naar regel 100 afgestraft. In 130 wordt gekeken  │ 
  594. │ of T$ een J of een j bevat. INSTR vergelijkt en zal een J vinden op  │
  595. │ positie 1 en een j op positie 2. In dat geval levert INSTR een waar- │
  596. │ de op die kleiner is dan 3. Staat er geen J of j in T$ dan faalt re- │ 
  597. │ gel 130 en komt regel 140 aan de beurt. In T$ kan alleen maar een N  │
  598. │ een n staan. Het antwoord op de invoervraag luidt derhalve ontken-   │
  599. │ nend.                                                                │ 
  600. └──────────────────────────────────────────────────────────────────────┘
  601.  
  602. Nu wordt het moeilijk: MID$(X$,x,x)
  603.  
  604. Voordat we ons in de problemen van MID$ storten nog even iets vooraf.
  605. Het kan onder bepaalde omstandigheden noodzakelijk zijn in een programma
  606. te weten te komen hoe LANG een tekst is die een gebruiker in een in te
  607. voeren string heeft gestopt. Het programma accepteert elke tekst in bij-
  608. voorbeeld:
  609. INPUT A$
  610. of
  611. LINE INPUT A$
  612. Alvorens zo'n string met LEFT$, RIGHT$ of MID$ te lijf te gaan, zullen
  613. we foutmeldingen moeten voorkomen door eerst te bepalen uit hoeveel
  614. ASCII-tekens de string bestaat. We kunnen dat zeer snel en eenvoudig aan
  615. de weet komen met de functie LEN.
  616. We weten niet WAT de gebruiker heeft ingevoerd in A$ maar we kun-
  617. nen er wèl achter komen uit hoeveel tekens A$ bestaat. Wanneer de ge-
  618. bruiker bijvoorbeeld: WEET IK VEEL in A$ heeft ingevoerd dan zal:
  619. PRINT LEN(A$) onthullen dat het aantal tekens in A$: twaalf is. Dit we-
  620. tende hoeven we niet in het duister te tasten om te weten wat het eer-
  621. ste, tweede ... laatste woord is dat de gebruiker heeft ingevoerd. Deze
  622. woorden worden immers door een CHR$(32) -een spatie- gescheiden. We ko-
  623. men daar straks nog op terug.
  624. Ik wil (afhankelijk van LEN(X$)) weten welke de vierde, de vijfde of de
  625. n-de letter van een string is. Sterker nog: ik wil weten wat de gebrui-
  626. ker in A$ invoert tussen bijvoorbeeld de derde en de tiende positie van
  627. A$.
  628. U raadt het: daarvoor is MID$(X$,x,x) bedoeld. Gelijk maar een voorbeeld
  629. om het helder te maken: Ik schrijf een programma om kinderen (en volwas-
  630. senen) de schrijfwijze van moeilijke Nederlandse woorden bij te brengen.
  631. De vraag is: hoe schrijf je 'onmiddellijk'? Dat woord bevat altijd twee
  632. d's en twee l's. Hoe schrijft de leerling het. Hij schrijf het altijd
  633. fout wanneer de negende letter geen l is. We controleren dat door de
  634. leerling zijn zienswijze op het woord in A$ te laten invoeren. We con-
  635. troleren zijn invoer op de juiste schrijfwijze met:
  636. 100 IF MID$(A$,9,1) <> "l" THEN PRINT "FOUT! Probeer opnieuw!"
  637. Wat hebben we het programma laten zeggen:
  638. ALS de tekst in A$, te rekenen vanaf de negende positie en over een be-
  639. reik van 1 positie ONGELIJK is aan de letter 'l' DAN print "FOUT! Pro-
  640. beer opnieuw.
  641. De anatomie van MID$(X$,x,x) laat zich in gewone woorden aldus omschrij-
  642. ven: bepaal het tekstdeel in X$, vanaf positie x over een x aantal te-
  643. kens. In de string: 
  644. A$ = "Mijn naam is Nico Baaijens" zal:
  645. PRINT MID$(A$,14,4)
  646. als resultaat opleveren..... Precies: Nico.
  647. Snapt u dit? Wat zal dan:
  648. PRINT MID$(A$,5,4) te zien geven?
  649. Met MID$ kunnen we overigens ook de eerste of de laatste letter van een
  650. string te weten komen, hoewel LEFT$ en RIGHT$ daarin gespecialiseerd
  651. zijn.
  652. A$="Ja"
  653. PRINT MID$(A$,1,1)
  654. levert hetzelfde resultaat op als
  655. PRINT LEFT$(A$,1)
  656.  
  657. Huiswerk
  658.  
  659. Schrijf een programmaatje waarin om invoer van een tekst wordt gevraagd
  660. en stel vast of in die invoer het woord RUN voorkomt. Mijn interpretatie
  661. van de opgave is de volgende:
  662.  
  663. 100 CLS:KEY OFF
  664. 110 PRINT "Geef een tekst waarin het woord RUN voorkomt"
  665. 120 LINE INPUT A$
  666. 130 FOR A%=1 TO LEN(A$):REM WE TASTEN DE TOTALE INVOERSTRING AF
  667. 140   IF MID$(A$,A%,3)="RUN" THEN GOTO 170
  668. 150 NEXT A%
  669. 160 PRINT "Het woordje RUN heeft u niet gebruikt":END
  670. 170 PRINT "Het woordje RUN gevonden op positie";A%:END
  671.  
  672. Tot besluit een wijs woord van Confucius:
  673. Hij die wat hij leert niet in praktijk brengt, vergeet en heeft niets
  674. geleerd.
  675.  
  676.                                                          (Wordt vervolgd)
  677.