Ga naar hoofdinhoud

Controle-structuren

Voorwaardes

if

Een if-instructie controleert of iets waar is en doet dan iets als dat zo is.

new
a = 5;
if (a == 5)
{
print("a is 5");
}

De code tussen de haakjes na "if" heet de conditie. Er zijn verschillende dingen waarop je kunt testen (zie operators).

In het bovenstaande voorbeeld zijn zowel "a" als 5 symbolen. Functies kunnen ook symbolen zijn:

if (SomeFunction() == 5)
{
print("SomeFunction() is 5");
}

Dat test de geretourneerde waarde van SomeFunction (zie hieronder) tegen 5.

Je kunt ook controles combineren om meerdere dingen te checken:

new
a = 5,
b = 3;
if (a == 5 && b != 3)
{
print("Wordt niet geprint");
}

Dit voorbeeld controleert dat a gelijk is aan 5 EN b niet gelijk is aan 3. b is echter 3, dus de check faalt.

new
a = 5,
b = 3;
if (a == 5 || b != 3)
{
print("Wordt geprint");
}

Dit voorbeeld controleert dat a gelijk is aan 5 OF b niet gelijk is aan 3. b is 3, dus dat deel is onwaar; a is 5, dus dat deel is waar. We gebruiken || (of), dus slechts één deel hoeft waar te zijn (als beide waar zijn, is de uitkomst ook waar). De if is dus waar.

Het is ook mogelijk vergelijkingen te ketenen zonder expliciet twee vergelijkingen met AND te verbinden.

new
idx = 3;

if (0 < idx < 5)
{
print("idx is groter dan 0 en kleiner dan 5!");
}

Operators

De volgende symbolen kun je gebruiken in vergelijkingen, met hun uitleg. Sommige zijn al in voorbeelden gebruikt.

OperatorBetekenisGebruik
==Links is gelijk aan Rechtsif (Links == Rechts)
!=Links is niet gelijk aan Rechtsif (Links != Rechts)
>Links is groter dan Rechtsif (Links > Rechts)
>=Links is groter dan of gelijk aan Rechtsif (Links >= Rechts)
<Links is kleiner dan Rechtsif (Links < Rechts)
<=Links is kleiner dan of gelijk aan Rechtsif (Links <= Rechts)
&&enif (Links && Rechts)
!nietif (!Variabele)
norif (!(Links
nandif (!(Links && Rechts))
exclusieve of (xor, eor) - slechts één is waar, niet beideif (!(Links && Rechts) && (Links
niet-exclusieve of (nxor, neor) - beide of geen van beide zijn waarif ((Links && Rechts)

Haakjes

Een ander belangrijk aspect van if-instructies zijn haakjes; die bepalen de volgorde waarin dingen worden uitgevoerd:

new
a = 3,
b = 3,
c = 1;
if (a == 5 && b == 3 || c == 1)
{
print("Wordt dit aangeroepen?");
}

Er zijn twee manieren om bovenstaande instructie te bekijken:

if ((a == 5 && b == 3) || c == 1)

En:

if (a == 5 && (b == 3 || c == 1))

In de eerste versie wordt gecontroleerd of a 5 is en b 3 is; als dat onwaar is (dus een van beide klopt niet), wordt gecontroleerd of c 1 is. (a == 5 && b == 3) is onwaar, dus vervang die groep door FALSE:

if (FALSE || c == 1)

FALSE kan nooit waar zijn, maar c is 1, dus dat deel is waar; met OR ertussen wordt de hele voorwaarde waar.

De tweede versie controleert of a 5 is; als dat zo is, wordt gecontroleerd of b 3 is of c 1 is. (b == 3 || c == 1) is waar, dus:

if (a == 5 && TRUE)

(a == 5) is onwaar (a is 3), dus:

if (FALSE && TRUE)

Dat kan nooit waar zijn, dus de check faalt.

Dit voorbeeld laat zien hoe haakjes de uitkomst kunnen veranderen. Zonder haakjes gebruikt de compiler standaard de eerste versie, maar dat is niet altijd gegarandeerd; gebruik dus altijd haakjes, al is het maar voor duidelijkheid.

  • Opmerking: (b != 3) in het OF-voorbeeld wordt niet uitgevoerd door short-circuiting: het eerste deel is al waar, dus het tweede deel wordt niet meer geëvalueerd.

else

else voert iets uit als een if-check faalt:

new
a = 5;
if (a == 3) // Onwaar
{
print("Wordt niet aangeroepen");
}
else
{
print("Wordt aangeroepen omdat de check faalde");
}

else if

Een else if is een extra check die gebeurt als de eerste if faalt:

new
a = 5;
if (a == 1)
{
print("Wordt aangeroepen als a 1 is");
}
else if (a == 5)
{
print("Wordt aangeroepen als a 5 is");
}
else
{
print("Alle andere nummers");
}

Je kunt er zoveel hebben als je wilt (per groep slechts één if en één else):

new
a = 4;
if (a == 1)
{
}
else if (a == 2)
{
}
else if (a == 3)
{
}
else if (a == 4)
{
}
else
{
}

else if-checks gebruiken de waarde zoals die was bij het begin van de keten; dus dit werkt niet zoals je denkt:

new
a = 5;
if (a == 5)
{
a = 4;
}
else if (a == 4)
{
// Wordt niet aangeroepen: de eerste check faalde niet
}

Maak de tweede dan een aparte if.

?:

'?' en ':' samen vormen de triadische operator; dit gedraagt zich als een if binnen een expressie:

new
a,
b = 3;
if (b == 3)
{
a = 5;
}
else
{
a = 7;
}

Korter geschreven:

new
a,
b = 3;
a = (b == 3) ? (5) : (7);

Het deel voor '?' is de conditie; tussen '?' en ':' de waarde als dat waar is; erna de waarde als het onwaar is. Je kunt ze ook nesten, vergelijkbaar met else if:

new
a,
b = 3;
a = (b == 1) ? (2) : ((b == 2) ? (3) : ((b == 3) ? (4) : (5)));

Lussen

while

"while"-lussen voeren code uit zolang de conditie waar is. De conditie is hetzelfde type als bij if en wordt herhaaldelijk gecontroleerd:

new
a = 9;
while (a < 10)
{
// Code in de lus
a++;
}
// Code na de lus

for()

Een "for"-lus is een compacte vorm van een "while". Een for-statement heeft drie delen: initialisatie, conditie en finalisatie:

for (new a = 9; a < 10; a++)
{
// Code in de lus
}
// Code na de lus

Door alle spelers itereren:

for(new i,a = GetMaxPlayers(); i < a; i++)
{
if (IsPlayerConnected(i))
{
// doe iets
}
}

Elk onderdeel mag je weglaten door het leeg te laten:

new
a = 9;
for ( ; a < 10; )
{
// Code in de lus
a++;
}
// Code na de lus

do-while

Een do-while-lus is een while-lus waarbij de conditie achteraf staat; de code binnenin wordt dus altijd minstens één keer uitgevoerd:

new
a = 10;
do
{
// Code in de lus
a++;
}
while (a < 10); // Let op de puntkomma
// Code na de lus

if-goto

Dit is in essentie waar bovenstaande lussen naartoe compileren. Gebruik van goto wordt afgeraden, maar het is leerzaam:

new
a = 9;

loop_start:
if (a < 10)
{
// Code in de lus
a++;
goto loop_start;
}
// Code na de lus

OBOE

OBOE staat voor Off By One Error: een veelgemaakte fout waarbij een lus één keer te veel of te weinig loopt.

new
a = 0,
b[10];
while (a <= sizeof (b))
{
b[a] = 0;
}

Dit voorbeeld loopt 11 keer en probeert b[10] te schrijven, wat buiten de grenzen valt (Out Of Bounds).

Switch

switch

Een switch is een gestructureerd if/else if/else-systeem:

new
a = 5;
switch (a)
{
case 1:
{
}
case 2:
{
}
case 5:
{
}
default:
{
}
}

In tegenstelling tot C heeft Pawn geen fall-through tussen cases en zijn cases door accolades begrensd, dus er zijn geen break-statements nodig.

case

Een case kan een enkele waarde, een lijst of een bereik testen:

case 1, 2, 3, 4:

Of met een bereik:

case 1 .. 4:

default

Dit is het equivalent van else in if-structuren: wordt uitgevoerd als geen enkele case matcht.

Enkelregelige instructies

goto

Springt naar een label zonder voorwaarde.

goto my_label;

// Dit stuk wordt overgeslagen

my_label: // Labels eindigen met een dubbele punt en staan op een eigen regel

// Dit stuk wordt normaal uitgevoerd

Het gebruik van goto wordt sterk afgeraden vanwege de invloed op de programmastroom.

break

Beëindigt een lus voortijdig:

for (new a = 0; a < 10; a++)
{
if (a == 5) break;
}

continue

Slaat de huidige iteratie over:

for (new a = 0; a < 3; a++)
{
if (a == 1) continue;
printf("a = %d", a);
}

return

Stopt een functie en keert terug naar de aanroeper; kan ook een waarde retourneren.