Terug naar de inhoudsopgave

Les 2 – Programma's schrijven

In deze les bespreken we de volgende onderwerpen:

Hello again, world

Vorige les heb je een heel simpel C++-programma gezien, dat niets meer doet dan Hello, world! naar het scherm schrijven. Je hebt dit programma natuurlijk braaf overgetypt, maar het leek wel spijkerschrift. In deze les zullen we zien hoe het programma in elkaar zit en waarom je ongeveer twee keer zoveel hebt overgetypt als noodzakelijk was. :-P

Het Hello, world!-programma is zeer simpel, maar ik kan een nog simpeler programma bedenken en dat is dit.

void main()
{
}
	

Dit is het simpelste programma dat je kunt schrijven in C++ en het doet helemaal niets. Je kunt dit programma compileren; dat gaat helemaal goed. Vervolgens kun je het starten en je zult zien dat het programma onmiddellijk weer stopt.

Statements

Elk C++-programma moet minimaal bovenstaande code bevatten. De compiler zoekt altijd naar de regel void main() zodat hij het programma daar kan laten beginnen.

Het programma zelf komt tussen de twee accolades ({}) te staan. Zo'n programma bouw je op uit opdrachten en een opdracht heet een statement. Statements worden altijd afgesloten met een puntkomma (;). In het volgende voorbeeld is een statement toegevoegd:

void main()
{
	cout << "Hello, world";
}
	

Zoals je ziet staat het statement tussen de twee accolades en wordt het afgesloten met een puntkomma.

Huishoudelijke mededelingen

Als je het bovenstaande programma compileert, krijg je een foutmelding. Je kunt namelijk niet zonder meer opdrachten geven; je moet de compiler vertellen met welke opdrachten je wilt werken. Dit doe je als volgt.

#include <iostream>

using namespace std;

void main()
{
	cout << "Hello, world";
}
	

Je hoeft (nog) niet precies te weten wat de twee toegevoegde regels doen. Je kunt ze zien als een paar huishoudelijke mededelingen die de compiler vertellen dat je opdrachten wilt kunnen geven die te maken hebben met invoer en uitvoer.

Commentaar

Compileer en start het bovenstaande programma en je zult zien dat het exact hetzelfde doet als het Hello world-programma uit de vorige les. Toch was dat programma ongeveer twee keer zo lang: heb je dat allemaal voor niets overgetypt!

De regels die uit het bovenstaande programma zijn weggelaten, zijn commentaarregels. Commentaar is tekst in je broncode, die voor jezelf verduidelijkt hoe je programma werkt. Voor de compiler is commentaar onnodig: de compiler negeert alle commentaar.

Ongeacht hoe goed je bent in programmeren, het is altijd lastig om broncode te lezen als er geen uitleg bij staat. Daarom voegen we aan een programma altijd uitleg toe in de vorm van commentaar. Om te beginnen geven we een korte omschrijving van het programma plus wat extra informatie.

/*
	Programmeur:  dhr. Ronkes Agerbeek
	Programma:    Hello, world!

	Omschrijving: Schrijft de tekst Hello, world! naar het beeldscherm.
*/

#include <iostream>

using namespace std;

void main()
{
	cout << "Hello, world!";
}
	

Je ziet dat alles tussen /* en */ beschouwd wordt als commentaar. Je kunt natuurlijk nog meer nuttige (en onnuttige) informatie kwijt in het commentaar, zoals de datum waarop het programma geschreven is of een vermelding van auteursrecht. Dat mag je allemaal zelf weten, maar het bovenstaande is wel het absolute minimum.

Nu weten we wat het programma doet, maar daarmee weten we nog niet wat alle statements doen, dus we voegen nog meer commentaar toe.

/*
	Programmeur:  dhr. Ronkes Agerbeek
	Programma:    Hello, world!

	Omschrijving: Schrijft de tekst Hello, world! naar het beeldscherm.
*/

#include <iostream>

using namespace std;

// het programma start hier
void main()
{
	// schrijf de tekst naar het scherm
	cout << "Hello, world!";
}
	

Zoals je ziet, staat het commentaar nu niet tussen /* en */. Doorgaans zetten we in de code alleen commentaar van één regel lang. Daarvoor gebruiken we de aanduiding //. Alles achter // tot aan het eind van de regel wordt door de compiler gezien als commentaar.

Je kunt natuurlijk in het commentaar zetten wat je wilt, maar om te zorgen dat commentaar er altijd hetzelfde uitziet, maken we de volgende afspraken (het gaat dan om commentaar bij statements):

Commentaar is verplicht! Ook al heeft de compiler het commentaar niet nodig, programmeren zonder commentaar is als 3√7 omzetten naar een decimaal getal zonder je rekenmachine te gebruiken: moeilijk en onverstandig.

Invoer en uitvoer

Zoals je inmiddels weet, werkt de computer met het principe van invoer, verwerking en uitvoer. Wij houden ons voornamelijk bezig met de verwerking, maar we moeten wel invoer hebben om te verwerken. En om te controleren of alles goed is gegaan, moeten we toch ook iets uitvoeren.

Geheugen

Het eerste dat we met invoer moeten doen, is de invoer opslaan in het geheugen. Als we dat niet doen, gaat de invoer verloren en kunnen we er ook niets aan verwerken.

We moeten aangeven waar in het geheugen we de invoer willen opslaan. Het geheugen is een lange lijst met getallen en die lijst is genummerd. Nou hebben we natuurlijk geen zin om uit te zoeken welk nummer nog vrij is; dat doen we dan ook niet. We laten de compiler uitzoeken welk deel van het geheugen we zullen gebruiken, maar we geven die plaats in het geheugen wel een naam, zodat we er makkelijk mee kunnen werken.

/*
	Programmeur:  dhr. Ronkes Agerbeek
	Programma:    Invoer en uitvoer

	Omschrijving: Reserveert geheugenruimte om invoer op te slaan.
*/

#include <string>

using namespace std;

// het programma start hier
void main()
{
	// reserveer geheugen om de invoer in op te slaan
	string myInput;
}
	

In dit programma staat slechts één statement, namelijk string myInput;. Met dit statement geef je aan dat je geheugen wilt gebruiken en dat je dat geheugen de naam myInput meegeeft. De compiler wil bovendien van je weten wat je van plan bent om op te slaan in dat geheugen. Wij willen tekst opslaan en dat geef je aan met het woord string. String is het Engelse woord voor ketting en hier gaat het om een ketting van letters. Tijdens het programmeren betekent string gewoon tekst.

We noemen myInput een variabele. Een variabele is dus een plaats in het geheugen waar we mee kunnen werken en die we een naam hebben gegeven. string is het type van de variabele. Het type geeft dus aan welk soort gegevens we kunnen opslaan in een variabele.

Het is je misschien opgevallen dat we de regel #include <string> moeten toevoegen als we werken met strings. Omdat we niet werken met invoer en uitvoer, hebben we de regel #include <iostream> niet nodig (maar daar komt snel verandering in).

Invoer opslaan in het geheugen

Tot nu toe hebben we geheugen gereserveerd, maar we hebben er nog niets mee gedaan. Laten we de gebruiker van ons programma eens om invoer vragen.

We kunnen de gebruiker tekst in laten voeren door gebruik te maken van cin, wat staat voor console input. cin stelt de gebruiker in staat om invoer in te typen. Zodra de gebruiker op Enter drukt, wordt de invoer doorgegeven aan ons programma.

We willen de invoer opslaan in de variabele myInput en dat doen we met het statement: cin >> myInput. Dit kun je lezen als: stuur gegevens van cin naar myInput. In programmavorm ziet het er als volgt uit.

/*
	Programmeur:  dhr. Ronkes Agerbeek
	Programma:    Invoer en uitvoer

	Omschrijving: Slaat de invoer van de gebruiker op in het geheugen.
*/

#include <iostream>
#include <string>

using namespace std;

// het programma start hier
void main()
{
	// reserveer geheugen om de invoer in op te slaan
	string myInput;
	
	// lees invoer
	cin >> myInput;
}
	

De regel #include <iostream> is weer terug, omdat we gebruik maken van cin.

Uitvoer van strings

Hebben we het nu goed gedaan? We kunnen tekst invoeren en waarschijnlijk wordt het opgeslagen in het geheugen, maar we hebben geen manier om het te controleren. Om dat te kunnen, moeten we de tekst weer naar het beeldscherm schrijven.

Voor uitvoer gebruiken we cout, wat een afkorting is voor console output. We hebben cout al eerder gezien in het statement cout >> "Hello, world!";. Dit statement stuurt dus de tekst Hello, world! naar cout, oftewel naar het scherm. Op dezelfde manier kunnen we de inhoud van de variable myInput naar het scherm schrijven: cout << myInput;. Dit kun je lezen als: stuur de inhoud van myInput naar cout.

/*
	Programmeur:  dhr. Ronkes Agerbeek
	Programma:    Invoer en uitvoer

	Omschrijving: Slaat de invoer van de gebruiker op in het geheugen en de
	              invoer vervolgens op het beeldscherm.
*/

#include <iostream>
#include <string>

using namespace std;

// het programma start hier
void main()
{
	// reserveer geheugen om de invoer in op te slaan
	string myInput;
	
	// lees invoer
	cin >> myInput;

	// schrijf de invoer naar het scherm
	cout << myInput;
}
	

Gestructureerd programmeren

Programmeren is zeker niet makkelijk (maar wel leuk ;-)), dus het is belangrijk om een goede manier van werken te ontwikkelen. In de loop der tijd zullen we steeds meer trucjes zien om te zorgen dat broncode duidelijk en foutloos is. In deze les maken we een begin met op een gestructureerde manier programmeren.

Plannen met commentaar

Voordat je aan een programma begint, moet je weten wat je wilt dat het programma doet. Daarnaast moet je bedenken welke stappen het programma uit moet voeren. Kortom, je moet je programma ontwerpen en plannen.

Bij grote programma's schrijf je daarom eerst een aantal documenten waarin precies beschreven staat wat het programma moet kunnen en aan welke eisen het moet voldoen. Voor kleine programma's is dat niet nodig, bovendien wil je zo snel mogelijk code gaan schrijven. Daarom maken we gebruik van commentaar om ons programma te plannen. We beginnen met een korte omschrijving van wat ons programma moet doen.

/*
	Programmeur:  dhr. Ronkes Agerbeek
	Programma:    Invoer en uitvoer

	Omschrijving: Slaat de invoer van de gebruiker op in het geheugen en de
	              invoer vervolgens op het beeldscherm.
*/

using namespace std;

// het programma start hier
void main()
{
}
	

Het bovenstaande programma doet nog niets - het bevat geen statements - maar je hebt in ieder geval al opgeschreven wat het programma moet gaan doen. Merk op dat de #include-regels nog niet zijn toegevoegd. We weten namelijk nog niet welke #include-regels we nodig hebben.

Nu moeten we gaan bepalen welke stappen het programma moet doorlopen. Dit doen we tussen de accolades met behulp van commentaar.

/*
	Programmeur:  dhr. Ronkes Agerbeek
	Programma:    Invoer en uitvoer

	Omschrijving: Slaat de invoer van de gebruiker op in het geheugen en de
	              invoer vervolgens op het beeldscherm.
*/

using namespace std;

// het programma start hier
void main()
{
	// lees invoer

	// schrijf de invoer naar het scherm
}
	

We hebben nu alle stappen beschreven die ons programma moet doorlopen. Je ziet dat dit commentaar overeenkomt met het commentaar in het vorige programma. Dus, als we ons programma plannen met commentaar, dan hoeven we tijdens het invoeren van de statements geen commentaar meer te typen.

Laten we de code eens toevoegen. We beginnen met de eerste regel.

/*
	Programmeur:  dhr. Ronkes Agerbeek
	Programma:    Invoer en uitvoer

	Omschrijving: Slaat de invoer van de gebruiker op in het geheugen en de
	              invoer vervolgens op het beeldscherm.
*/

using namespace std;

// het programma start hier
void main()
{
	// lees invoer
	cin >> myInput;

	// schrijf de invoer naar het scherm
}
	

Dit levert meteen een aantal problemen op. Als je de compiler deze code laat vertalen, dan krijg je een aantal foutmeldingen. Ten eerste zal de compiler je vertellen dat hij niet weet wat cin is. Om cin te gebruiken hebben we namelijk de regel #include <iostream> nodig.

Ten tweede wil de compiler weten wat je bedoelt met myInput. We hebben de compiler nog niet verteld dat myInput een variabele is en dus ook niet van welke type. Om dat te doen moeten we de regel string myInput; toevoegen.

/*
	Programmeur:  dhr. Ronkes Agerbeek
	Programma:    Invoer en uitvoer

	Omschrijving: Slaat de invoer van de gebruiker op in het geheugen en de
                  invoer vervolgens op het beeldscherm.
*/

#include <iostream>
#include <string>

using namespace std;

// het programma start hier
void main()
{
	// reserveer geheugen om de invoer in op te slaan
	string myInput;

	// lees invoer
	cin >> myInput;

	// schrijf de invoer naar het scherm
}
	

In dit programma is ook de regel #include <string> toegevoegd. Deze hebben we nodig vanwege de regel string myInput; .

Je ziet dat je soms wat extra regels moet toevoegen om een statement te laten werken. Dat is niet erg. Plannen met commentaar is niet bedoeld om in één keer alles op te schrijven dat het programma moet doen, want dan hadden we net zo goed de code meteen in kunnen tikken. Tijdens het plannen met commentaar houd je je bezig met de globale structuur van je programma, zonder dat je je druk maakt om de details. Merk op dat het nieuwe statement string myInput; weer keurig van commentaar is voorzien.

Het volgende statement levert geen extra werk op. Voor cout heb je de regel #include <iostream> wel nodig, maar die hebben we al toegevoegd omdat we met cin werken.

/*
	Programmeur:  dhr. Ronkes Agerbeek
	Programma:    Invoer en uitvoer

	Omschrijving: Slaat de invoer van de gebruiker op in het geheugen en de
	              invoer vervolgens op het beeldscherm.
*/

#include <iostream>
#include <string>

using namespace std;

// het programma start hier
void main()
{
	// reserveer geheugen om de invoer in op te slaan
	string myInput;

	// lees invoer
	cin >> myInput;

	// schrijf de invoer naar het scherm
	cout << myInput;
}
	

Opmaak

Het is je misschien al opgevallen dat de programma's die we tot nu toe hebben gezien, allemaal dezelfde opmaak hebben. Voor de compiler maakt de opmaak niet zoveel uit, hij let niet zo streng op spaties en hard returns. Voor ons als programmeurs is het echter van groot belang dat de programma's goed leesbaar zijn.

Naarmate we meer leren van C++, zullen we ook meer regels zien voor de opmaak van de broncode . Voorlopig doen we het met de volgende regels:

Bij de les