Programmeren in REXX/Voorbeeld1: verschil tussen versies

Verwijderde inhoud Toegevoegde inhoud
GuyDC (overleg | bijdragen)
Geen bewerkingssamenvatting
GuyDC (overleg | bijdragen)
Meer uitleg bij de logica
Regel 2:
=Ons eerste programma=
Hier gaan we een eerste werkend voorbeeld van REXX programma bestuderen. We willen de priemgetallen tussen 1 en 100 opzoeken.
 
Eigenlijk moeten we voor elk getal tussen 1 en 100 nagaan of het deelbaar is door één van de priemgetallen kleiner dan het getal.
Maar er zijn een aantal verbeteringen mogelijk aan deze werkwijze.
 
Priemgetallen zijn onpare getallen, met één uitzondering, het getal 2. Het is dus al nutteloos pare getallen te gaan onderzoeken. We gaan ervan uit dat we intuitief al weten dat 2 een priemgetal is en dat testen we ook niet meer.
 
Stel dat we 23 aan het testen zijn. Voorgaande priemgetallen zijn 2, 3, 5, 7, 11, 13, 17. Delen door 2 testen we al niet want we werken enkel met onpare getallen.
In dit geval gaat de deling door 3 niet. Maar moeten we nog testen op een deling door 5 ? Eigenlijk niet, want als de deling door 5 zou opgaan, dan hebben we een hele rest die ook nog een priemgetal of veelvoud ervan moet zijn. Maar dit kan geen priemgetal groter dan 5 zijn, en 2 en 3 hebben we al uitgesloten. Kortom, het is niet nodig verder te testen indien ons getal kleiner is dan het kwadraat van het priemgetal (5² in ons geval).
 
Laten we nu ons programma bestuderen.
 
==Code==
Regel 12 ⟶ 22:
7 | say 2 /* We tonen ons eerste priemgetal */
8 | do i=start to einde by 2 /* lus van start tot einde, per 2 */
9 | do j=2 to priem.0z /* lus over al gevonden priemgetallen */
10 | if i<priem.j**2 then leave j /* alsgroter voorbij kwadraatdan priem,**2 ? verlaten==> weverlaat lus j */
11 | if i//priem.j=0 then iterate i /* als rest i/priem nul is, volgende zoeken */
12 | end j /* einde van lus j */
Regel 27 ⟶ 37:
==Bespreking==
'''Lijn 1''': een REXX programma moét met een commentaar beginnen. Het is een goede gewoonte hier op z'n minst te schrijven wat het programma doet. Er kan ook een auteur, creatiedatum en zelfs historiek aan toegevoegd worden.
<br>'''Lijn 2''': we definiëren de variabele ''start'' en geven ze de waarde 3. Alle(onze priemgetalleneffectieve zijnstart namelijk onpaar, behalvena het allereerste,"gekende" namelijkpriemgetal 2. We zullen later enkel de onpare getallen onderzoeken, dus starten we onmiddellijk aan 3).
<br>'''Lijn 3''': we definiëren de variabele ''einde'' en geven ze de waarde 100, omdat we ons nu willen beperken tot de priemgetallen tot 100.
<br>'''Lijn 4''': in één enkele operatie creëren we een stem, ''priem.'' genaamd, en geven aan het element ''priem.0'' de waarde 1. De conventie wil namelijk dat we in het "nulde" element van een stem (array) bijhouden hoeveel elementen er in de stem zitten, en op
'''Lijn 5''' vullen we nu net dat eerste element van de stem op, namelijk ons enig paareerste priemgetal 2.
<br>'''Lijn 6''': we definiëren de variabele ''z'' die zal dienen om de index van onze stem te verhogen (en tevens het aantal gevonden priemgetallen).
<br>'''Lijn 7''': we mogen niet vergeten ons eerste priemgetal 2 ook op het scherm te tonen!
<br>'''Lijn 8''': nu starten we een lus. De variabele die als teller gebruikt wordt is '''i'''. De naam van deze variabele kan vrij gekozen worden, maar het is ietwat historisch dat variabelen i, j, k, l als eerste worden gekozen omdat in oorspronkelijke programmeertalen deze variabelen impliciet gehele getallen voorstelden. Een langere naam zou ook alleen meer schrijfwerk betekenen.
Regel 37 ⟶ 47:
We gaan in de lus blijven vanaf onze '''start'''waarde (3) tot onze '''eind'''waarde (100). En om enkel de onpare getallen te onderzoeken maken we de stap 2 groot.
 
<br>'''Lijn 9''': binnen de eerste lus beginnen we nu een tweede lus. We gaan (dank zij lusteller '''j''') alle reeds gekende priemgetallen af. Vermits we enkel onpare getallen onderzoeken moeten we echter ons allereerste priemgetal 2 niet meenemen, want deelbaar door 2 zal het nooit zijn.
 
Merk hier op dat we de eerste maal een lus-definitie zullen hebben die resulteert in '''do j=2 to 1'''. Dit is helemaal OK voor REXX, en maakt dat de lus niet zal worden uitgevoerd.
<br>'''Lijn 10''': als nu blijkt dat het getal dat we aan het onderzoeken zijn (en dat in variabele i staat) kleiner is dan het kwadraat van het ''j-de'' priemgetal, dan kunnen we de j-lus verlaten, en hebben we een nieuw priemgetal gevonden. Het getal is dan inderdaad niet deelbaar geweest door één van de voorgaande priemgetallen (test van lijn 11), en verder het rijtje priemgetallen afgaan is dus nutteloos.
<br>'''Lijn 11''': hier testen we of het te onderzoeken getal (i) deelbaar is door het ''j-de'' priemgetal. We testen dit door na te gaan of de restdeling op nul uitkomt. Indien zo, dan hebben we geen priemgetal en kunnen we onmiddellijk naar het volgende te onderzoeken getal gaan, dus de rest van de i-lus overslaan en terug naar lijn 8 springen.
<br>'''Lijn 12''' geeft het einde van de binnenste lus aan. Alhoewel niet nodig, is het een goede gewoonte de lusteller (j) als parameter mee te geven,. zekerZeker bij heel lange lussen. Dat maakt het het foutonderzoek gemakkelijker.
<br>'''Lijn 13''': als we hier zijn terechtgekomen, dan hebben we een priemgetal gevonden. We voegen dus één bij aanverhogen onze teller, zodat we op
'''lijn 14''' ons nieuw priemgetal kunnen toevoegen aan het ''z-de'' element van onze stem.
<br>'''Lijn 15''': als ween vergeten ook niet ons element 0 aan te passen, aan het juiste aantal elementen van deanders stemwerkt zallijn het9 laterniet hopeloosmeer mislopencorrect.
<br>'''Lijn 16''': we tonen het gevonden priemgetal op het scherm en kunnen het volgende getal gaan onderzoeken.
<br>'''Lijn 18''': we hebben nu alle getallen van 1 tot 100 onderzocht. Zowel variabele ''z'' als ''stem.0'' bevatten het aantal gevonden priemgetallen, dus een kleine moeite om dat aan de gebruiker te melden.
<br>'''Lijn 19''': we beëindigen het programma. We geven geen returncode mee, dus die zal steeds 0 zijn. In dit eenvoudig programmaatje is die '''exit''' eigenlijk zelfs niet écht nodig, maar het blijft toch een goede gewoonte er één te schrijven.
 
==Extra opmerkingen==
Het gebruik vanDe variabele '''start''' enhebben stem-elementwe '''priemniet echt nodig.0''' zijnWe inkunnen bovenstaandop programmalijn niet8 striktook nodig'''do (o.a.i=3 omdatto deeinde variabeleby 2'''z''' ook al de teller bevat)schrijven. Maar we gaan dit programma later nog verder uitbreiden, en dan komenzal die variabelen welvariabele van pas. komen.
 
Het stem-element '''priem.0''' moeten we niet opvullen, zodat lijnen 4 en 15 ook mogen wegvallen. Het is echter een conventie van het aantal elementen van de stem hierin bij te houden. Sommige functies of programma's vullen deze variabele ook automatisch in.
 
Merk op dat we niet mogen schrijven:
priem.priem.0=i
want REXX gaat dan op zoek naar... '''priem.PRIEM.0''' (het element PRIEM.0 van de stem priem.) en dat bestaat niet. Vandaar dat we variabele '''z''' als tussenstap gebruiken.
Het gevolg is wel dat zowel '''z''' als '''priem.0''' dezelfde waarden zullen bevatten.
 
De Object REXX en Reginald REXX implementaties laten echter wel toe het op volgende manier op te lossen:
priem.[priem.0]=i
Tussen de vierkante haakjes kunnen een complexe variabele of zelfs bewerkingen geschreven worden. Deze vorm is echter niet in alle REXX implementaties gekend, noch in de officiële ANSI J18-199X definities. We zullen deze oplossing verder vermijden om algemener te blijven.
 
Als eerste voorbeeld van de kracht van de '''PARSE''' instructie kunnen we melden dat de regels 2 tot 6 kunnen vervangen worden door
Informatie afkomstig van https://nl.wikibooks.org Wikibooks NL.
Wikibooks NL is onderdeel van de wikimediafoundation.