Programmeren in C/Bestanden
De taal C is modulair, dat wil zeggen dat een C-programma uit verschillende delen (modules) bestaat die tamelijk onafhankelijk van elkaar zijn. Het doel hiervan is vrij simpel: een module kan vervangen worden door een andere module zonder dat de rest van het programma hoeft te worden aangepast.
Elke module kent twee hoofdbestanddelen: de implementatie (*.c) en de interface (*.h) waarbij de eerste de definitie van de functies bevat en de laatste alle types, functies en macro's opsomt die nodig zijn om de module te gebruiken, zodat de compiler kan nakijken of een functie-aanroep ook inderdaad overeenkomt met de definitie en een foutmelding kan genereren als dit niet zo is (of de functie geheel ontbreekt). Vrijwel hetzelfde geldt voor typedeclaraties en de rest. De taal C laat het volledig aan de programmeur over om een goede indeling in modules te maken, wat (alweeer) een leuke bron van fouten kan zijn.
Een voorbeeld
bewerkenBedrijf FooBar Inc. heeft een bestand met de namen van klanten en andere gegevens en wil deze gebruiken in de applicatie Automail2000 die klanten uit dit bestand selecteert en ze periodiek een e-mail stuurt. Nadat de ontwikkelaar zich uitgebreid achter de oren heeft gekrabt, maakt hij de volgende indeling:
Module | Doel | Bestand | Type |
---|---|---|---|
file | Toegang tot en lezen van het klanten bestand | file.c | Implementatie |
file.h | Interface | ||
select | Selecteren van klanten voor een e-mail | select.c | Implementatie |
select.h | Interface | ||
send | Versturen van de e-mail | send.c | Implementatie |
send.h | Interface | ||
main | hoofdroutine, command-line args en environment | main.c | Implementatie |
De functies in main.c gebruiken functies die zijn gedefinieerd in de drie andere modules, maar geen enkele andere module gebruikt de functies in main.c. Daarom is er geen bestand main.h nodig.
In het bestand main.c staat dan het volgende
/* include interfaces */
#include "file.h"
#include "select.h"
#include "send.h"
...
Schematisch ziet het er zo uit:
Merk op dat main.c nergens direct verwijst naar de implementaties in file.c, select.c en send.c. Hoe die bestanden er precies uitzien is verder niet interessant en wat meer is, de broncode van die bestanden hoeft niet eens aanwezig te zijn. Als het interface bestand er maar is, is de compiler tevreden en laat het de linker verder uitzoeken.
Ook de standaard onderdelen van C zijn als modules geimplementeerd, zoals bijvoorbeeld stdio.h (Standard Input/Output) en worden op exact dezelfde manier behandeld. Een interface (stdio.h) wordt ingevoegd en de linker trekt de bijbehorende implementatie uit een library. Uiteindelijk kan het plaatje vaak nog iets ingewikkelder zijn:
Merk op dat stdio.h via file.h wordt ingevoegd.