Imperatief programmeren (ook wel procedureel programmeren genoemd) is een programmeerconcept uit de informatica waarbij programma's opgesteld worden in de vorm van opdrachten die direct uitgevoerd kunnen worden. Het tegenovergestelde van imperatief programmeren is declaratief programmeren, dat niet iets doet maar iets beschrijft.

Vaak wordt imperatief programmeren ook naast object-georiënteerd programmeren gelegd. Een taal waarmee alleen geprogrammeerd kan worden met klassen en hun bijbehorende memberfuncties, zoals Java (elke functie moet hier een member zijn van een klasse), wordt dan een zuiver object-georiënteerde programmeertaal genoemd. Hiernaast ligt de zuiver imperatieve taal, bijvoorbeeld C, om alleen losstaande functies te plaatsen. Als laatste zijn er nog hybride talen zoals C++ en PHP, waarmee men zowel object-georiënteerd als imperatief kan programmeren.

Berekeningsmodellen

Als een computer een programma uit moet voeren, dan doet de computer dat door achtereenvolgens de instructies uit te voeren die het programma voorschrijft. Dit werkt doordat beide (computer en programma) opgesteld zijn volgens hetzelfde concept van programmaverwerking – zij "denken" beide hetzelfde over hoe het programma uitgevoerd dient te worden.

In dit concept van uitvoering zijn twee termen belangrijk: de turingmachine en de Von Neumann-cyclus.

Turingmachine en berekenbaarheid

De turingmachine is een model van berekenen: de turingmachine beschrijft in detail hoe een berekening uitgevoerd dient te worden. Met dit model in de hand wordt het mogelijk om na te gaan denken over zaken als

Het turingmodel van berekenbaarheid bestaat uit twee onderdelen: een (oneindig) geheugen en een toestandsautomaat.

Geheugen

Het geheugen dient om alle relevante informatie over de berekening bij te houden: in het geheugen ligt opgeslagen wat er al gebeurd is en wat de uitkomsten waren, wat er nog behandeld dient te worden en in welke volgorde, en belangrijkst van alles: waar de berekening nu ("op dit moment") is, in welk stadium. Dit laatste wordt de toestand van de machine genoemd.

Toestandsautomaat

De toestandsautomaat voert de eigenlijke berekening uit, in kleine stapjes. De automaat bestaat in feite uit één grote serie beschrijvingen van de vorm "in deze toestand moet je deze stap zetten". Een hele berekening van de turingmachine is dan een aaneenschakeling van veel van deze kleine stappen.

Von Neumann-cyclus en hardware

De Von Neumann-cyclus beschrijft hoe een computer in praktische zin zou kunnen werken, in termen van het ophalen en uitvoeren van één enkele instructie en dan doorgaan met de volgende instructie. Dit is de centrale gedachte achter de werking van vrijwel iedere, moderne computer.

Het imperatieve programma

Het imperatieve programma is een programma dat een berekening beschrijft volgens het turingmodel: de gehele berekening valt uit elkaar in een lange serie kleine stappen die ieder op zich de toestand van de berekening een beetje aanpassen, totdat er uiteindelijk een compleet antwoord "uit komt rollen".

Het imperatieve programma doet dit door gebruik te maken van de architectuur van de onderliggende machine: het geheugen van de computer vormt het geheugen waarin de berekening en de toestand opgeslagen liggen, de processor wordt de toestandsautomaat. Iedere stap van de automaat past precies in één omloop van de Von Neumann-cyclus en heeft de vorm "beschouw de huidige toestand en mogelijke stappen om te zetten (instructie-fetch); beslis wat er nu precies moet gebeuren (instructie-decode); pas dat toe op de huidige toestand (instructie-execute); begin opnieuw".

Beschouwt men de code van een imperatief programma (dat zo genoemd wordt omdat het bestaat uit een serie opdrachten of bevelen), dan kan men deze structuur direct terugzien, bijvoorbeeld in het volgende stukje code in de programmeertaal C:

....
c = 12 + 13;
d = c;
c++;
....
printf("Hello, World!");

Dit zijn allemaal kleine opdrachten (simpele stappen) die door de onderliggende machine in volgorde uitgevoerd dienen te worden. Bovendien maken zij direct gebruik van de verdeling van het geheugen in kleine cellen – dat wil zeggen, zowel van het geheugenmodel van de turingmachine als van de fysieke eigenschappen van de hardware in de computer – door deze cellen direct aan te spreken in termen van variabelen in het programma.

Onderscheid met andere soorten programmeertalen

Imperatieve talen zijn in hun vorm sterk verbonden aan het berekeningsmodel van Turing en de onderliggende hardware. Hierin onderscheiden zij zich van functionele programmeertalen, die het Churchmodel van functietoepassing gebruiken als model van berekening (zie ook Lambdacalculus). Ook onderscheiden de imperatieve talen zich van de logische programmeertalen, waarin het bewijsobject en de predicatencalculus als berekeningsmodel centraal staan.

De logische en functionele talen, die in vorm sterk afwijken van de imperatieve talen, worden declaratieve programmeertalen genoemd.

Ten slotte is er veel onenigheid over de positie van objectgeoriënteerde programmeertalen in dit geheel; deze talen verdelen een berekening in verschillende onderdelen, waarbij ieder onderdeel de verantwoordelijkheid is van een opzichzelfstaand programmaobject. Deze objecten op zich worden intern echter weer opgesteld aan de hand van één (of meer) van de bovengenoemde modellen, dus de vraag blijft of dit model als iets geheel afzonderlijks gezien kan worden.

Elementen van imperatieve programmeertalen

In de meeste talen worden sleutelwoorden (of keywords) gebruikt om opdrachten aan te geven. Deze woorden zijn eigenlijk altijd uit het Engels afkomstig. Ook in andere landen gebruikt een programmeur de Engelstalige sleutelwoorden. Veel programmeertalen komen niet alleen qua programmeerparadigma overeen, maar ook gedeeltelijk qua syntaxis en sleutelwoorden, zodat de kenner van een programmeertaal weinig moeite zal hebben met het leren van een verwante taal.

Enkele definities

Getal

Getallen worden op de gebruikelijke wijze geschreven. Het decimaalteken is een punt. Er is geen scheidingsteken tussen duizendtallen.

Zeer grote en kleine getallen kunnen worden aangegeven met een macht van tien, zoals gebruikelijk in de wetenschap, en daarvoor wordt meestal de letter E gebruikt. Dus het getal 6,022 × 1023 wordt geschreven als 6.022E23.

In sommige talen kan men een ander talstelsel kiezen. Bij ieder getal moet worden aangegeven welk talstelsel wordt gebruikt (dat verschilt per taal). Een hexadecimaal getal kan, afhankelijk van de taal, worden genoteerd als 0Xabcd of als 0abcdH. Let op de voorafgaande nul, een getal moet altijd met een cijfer beginnen (wat met een letter begint is immers een identifier). In C begint een octaal getal met een nul, dus 15 is decimaal en 013 is octaal.

String

Een string is een reeks tekens die afgedrukt kan worden. Een string staat meestal tussen aanhalingstekens. Daaruit volgt dat het niet goed mogelijk is aanhalingstekens in een string op te nemen. De gebruikelijke oplossing daarvoor is dat men twee aanhalingstekens achter elkaar zet. In sommige talen geldt een string als eenheid, in andere is het een array van tekens, die dus geïndiceerd kan worden.

Blok

In moderne talen is het nodig statements te groeperen. Zo'n groep statements heet een blok of samengesteld statement en geldt zelf weer als een enkel statement. Het groeperen geschiedt met BEGIN en END. Andere talen gebruiken hiervoor geen woorden maar bijvoorbeeld { en }.

CALL

Bij een aanroep (call) van een subroutine (ook wel procedure, functie of methode genoemd) wordt de naam van de subroutine gegeven, gevolgd door (meestal tussen haakjes) de parameters (ook wel argumenten genoemd). Zijn er geen parameters, dan zijn vaak wel de haakjes nodig. In sommige talen wordt een expliciet gereserveerd woord CALL voorgevoegd.

Imperatieve elementen

Bij imperatief programmeren is een programma een samenstel van instructies die de computer moet uitvoeren, waarbij aan geheugenlocaties of meer abstracte variabelen waarden worden toegewezen en uitgelezen. Zulke instructies worden samengesteld tot programma's met behulp van elementen die de control flow specificeren. De meeste programmeertalen veronderstellen of ondersteunen deze manier van werken; typische elementen in zulke talen zijn de volgende.

Toewijzing

In een toewijzing (assignment) krijgt een variabele een waarde. De schrijfwijze is meestal:

variabele=expressie
variabele:=expressie

IF

Na IF komen een voorwaarde en een statement dat voorwaardelijk uitgevoerd moet worden. Tussen de voorwaarde en het statement komt het woord THEN (ook weleens DO). Na de voorwaardelijk uit te voeren statements komt eventueel ELSE gevolgd door een statement dat juist wordt uitgevoerd als niet aan de voorwaarde is voldaan.

SWITCH of CASE

Een IF-statement heeft twee takken, de THEN-tak en de eventuele ELSE-tak. Is er een gecompliceerde keuze nodig, dan kan men vaak gebruikmaken van een SWITCH-statement (in andere talen CASE). Er wordt een expressie genoemd en die wordt vergeleken met een aantal constanten om te bepalen welke tak moet worden uitgevoerd.

FOR of DO

Na FOR (ook wel DO) komt een statement dat herhaaldelijk uitgevoerd moet worden (een iteratie). Er wordt een lopende variabele gegeven, met begin- en eindwaarde en stapgrootte. Deze constructie wordt meestal gebruikt voor herhalingen waarvan het aantal tot een vooraf bepaalde grens is beperkt.

FOR EACH

for each. Geeft een iteratie, een lopende variabele en een enumeratie, dat wil zeggen, een object dat zelf al een standaardmethode definieert op iteratie over de waarden ervan mogelijk te maken. Het kan gaan om een al bepaalde collectie waarden (zoals een lijst of array), maar dat hoeft niet. Het belangrijke verschil met FOR is dat er geen volgnummer wordt gebruikt om de elementen af te lopen.

WHILE

WHILE. Ook dit is een iteratie, maar in plaats van een lopende variabele wordt een voorwaarde gegeven; de iteratie wordt uitgevoerd totdat niet meer aan de voorwaarde voldaan is. Dit wordt meestal gebruikt voor iteraties waarvan het aantal stappen op het moment van ingaan nog onbekend is.

BREAK

Om een iteratie voortijdig te beëindigen, bestaan er statements als BREAK of EXIT. Om direct verder te gaan met de volgende iteratie, schrijft men LOOP of CONTINUE. Om de uitvoering van een subroutine te beëindigen, schrijft men RETURN.

Label

Een label is een identifier waarmee een punt van het programma gemarkeerd wordt. Meestal wordt een label gebruikt in een GOTO-statement. Na een label komt meestal een dubbele punt.

GOTO

Na GOTO of GO TO komt een label. De uitvoering van het programma gaat op de plek van het label verder. Bijna alle programmeertalen kennen GOTO, maar het gebruik ervan wordt in de moderne programmeerpraktijk afgeraden omdat het gemakkelijk aanleiding geeft tot het schrijven van spaghetticode .

Externe bronnen