Programmeren in C/Stijl en structuur
Alle hogere programmeertalen zijn bedoeld voor de mens. Het is vrijwel onmogelijk om een substantieel programma in machinetaal te schrijven, aangezien dat uitsluitend uit numerieke codes bestaat. Leesbaarheid van de code is dan essentieel omdat, als het eenmaal geschreven is, een programma moet worden onderhouden en onderhoud nu eenmaal onmogelijk is als de broncode niet te begrijpen is.
Professionele programmeurs en bedrijven houden er dan ook vaak coding standards op na (bijvoorbeeld de Indian Hill coding standards), die precies beschrijven hoe de stijl en structuur van de broncode eruit dient te zien, welke regels er gelden voor naamgeving en waar commentaar vereist is. Het is vaak de stijl die in één oogopslag duidelijk maakt of een stuk code door een professional, een beunhaas of een amateur is geschreven. In dit boek houden we ons aan de hieronder beschreven eenvoudige regels om de broncode leesbaar te houden.
Statements en blokken
bewerkenDe programmeertaal C leunt sterk op het samenspel van statements en blokken. Een statement is een enkele programmeeropdracht en eindigt altijd met een punt-komma (;
). Het volgende is bijvoorbeeld een enkel statement:
printf("Hallo wereld!");
Daarnaast is er in C een manier om een of meer statements te groeperen in een blok. Dit is vaak nodig na bepaalde taalconstructies, zoals loops en functies om de statements bij elkaar te houden. Een blok begint altijd met een open-accolade ({
) en eindigt met een sluit-accolade (}
). Dit is een voorbeeld van een blok met een paar statements in een functie:
int main()
{
printf("Hallo wereld!");
return 0;
}
Een blok zonder statements, dus { }
, mag ook als een enkele punt-komma geschreven worden. Andersom geldt niet.
int main();
Overzichtelijkheid
bewerkenInspringen
bewerkenVoor de leesbaarheid is het noodzakelijk om de inhoud van elk blok code in te springen. Inspringen mag zowel met tabs (die afhankelijk van je editor vaak 4 of 8 spaties breed zijn) of spaties. Verder is het een goede gewoonte accolades altijd op een aparte regel te zetten, zodat in een oogopslag duidelijk is welke }
bij een gegeven {
hoort.
De volgende code is correct ingesprongen, met inspringingen van 4 spaties (of één tab) breed:
void main()
{
if (false)
{
while (true)
{
printf("De wereld vergaat!");
}
}
else
{
printf("Hallo wereld!");
}
}
Uitlijnen
bewerkenBinnen regels code is het soms handig om delen uit te lijnen, zodat de code overzichtelijker wordt. Uitlijnen gaat altijd met spaties, nooit met tabs. Een voorbeeld van uitgelijnde code is de volgende set gerelateerde statements, waarbij de namen allemaal onder elkaar komen te staan:
unsigned int aantal;
int score;
char naam[255];
struct Resultaat *volgende;
Lege regels
bewerkenTen slotte is het voor de overzichtelijkheid erg goed om delen van de code met een lege regel van elkaar te scheiden.
#include <stdio.h>
struct Resultaat
{
unsigned int aantal;
int score;
char naam[255];
struct Resultaat *volgende;
}
int main()
{
printf("Hallo wereld!");
return 0;
}
Lijnbreedte
bewerkenGebruik regels van maximaal zo'n 80 karakters lang. Dit houdt de code compact en zorgt ervoor dat mensen met een minder breed scherm toch alles kunnen zien. In veel editors kan een lijn worden weergegeven op de gewenste kolom.
Commentaar
bewerkenCommentaar is tekst die genegeerd wordt door de compiler, maar de code verduidelijkt. Dit is handig voor andere programmeurs die uw code lezen, maar ook voor uzelf als u later nog eens terug kijkt in een stuk code. Een paar zinnen commentaar kan veel duidelijk maken over de bedoeling van broncode.
Enkele regel commentaar
bewerkenVaak beslaat het commentaar slechts een enkele regel. Dit soort commentaar start bij //
en eindigt aan het eind van de regel. In het volgende voorbeeld zijn de commentaarregels voor de overzichtelijkheid uitgelijnd (maar dit is niet noodzakelijk).
// Hier volgen enkele variabelen:
unsigned int aantal; // Het aantal kandidaten.
int score; // De gemiddelde score.
char naam[255]; // Naam van het tentamen.
struct Resultaat *volgende; // Pointer naar het volgende tentamenresultaat.
Meerdere regels commentaar
bewerkenCommentaar tussen /*
en */
kan meerdere regels beslaan. Dit is vooral handig bij meerdere zinnen commentaar, of bijvoorbeeld een opsomming. In het volgende voorbeeld wordt dit soort commentaar ook toegepast aan het begin van het broncode bestand. Programmeurs doen dit vaak om het doel van een specifiek bestand te beschrijven, licentievoorwaarden neer te zetten en de wijzigingen bij te houden. Behalve in /*
en */
zijn de sterretjes (*
) aan het begin van elke commentaarregel niet noodzakelijk en alleen gebruikt vanwege de uitlijning:
/* BESTAND : hello_world.c
* AUTEUR : Pietje Puk <p.puk@nowhere.net>
* GEWIJZIGD : 1 april 2000
* Hallo wereld routine.
*
* 17 jan 2001 - PPUK - Paar bugs geplet
* 19 feb 2002 - PPUK - Nog meer bugs geplet
* 21 mrt 2003 - BHAAS - Hello World --> Hello Dolly
* 23 apr 2004 - PPUK - Dolly weggehaald. Terug naar oorspr. tekst
*/
#include <stdio.h>
/* Dit is de functie waar elk C-programma
altijd mee begint. Deze functie zet "Hallo wereld!" op
het scherm. */
int main()
{
printf("Hallo wereld!");
return 0; /* Geeft 0 terug, om aan te geven
dat er zich geen fouten hebben voorgedaan. */
}
Oefeningen
bewerkenBeschouw de volgende varianten van een simpel programma. De lijnnummers zijn slechts ter verduidelijking en geen onderdeel van de code.
Variant A
#include <stdio.h>
int main(){if(true){printf("Hallo wereld!");}return 0;}
Variant B
#include <stdio.h>
int main()
{
if (true)
{
printf("Hallo wereld!");
}
return 0;
}
Variant C
#include <stdio.h>
/**********************************************************
* Dit is de functie waar elk C-programma *
* altijd mee begint. Deze functie zet "Hallo wereld!" op *
* het scherm. *
**********************************************************/
int main()
{
if (true)
{
printf("Hallo wereld!");
}
return 0; /* Geeft 0 terug. */
}
Beantwoord nu de volgende vragen:
int main()
) correct geformuleerd?/*
en eindigt met */
en dat is de enige eis die er aan commentaar over meerdere regels wordt gesteld.De commentaarregel had ook als enkele regel commentaar kunnen worden geschreven:
return 0; // Geeft 0 terug.
if
ingesprongen terwijl dit niet zou moeten. Bij variant A zijn alle stijlregels genegeerd, hoewel het nog steeds functioneel dezelfde uitvoerbare code is als de andere varianten.