#Klooienmetcomputers

Efficiënte headers

Arnout van Kempen over rommelen in een digitale wereld.

Een tijdje geleden hebben we geworsteld met de invoer van strings. Dat was nogal een risicovolle activiteit, waarbij veel mis kon gaan. Uiteindelijk hadden we een manier om buffer overflow te voorkomen en er voor te zorgen dat geen ongewenste toetsaanslagen in de stdin-stream achterbleven met

printf("Naam: ");
fgets(naam, sizeof(naam), stdin);
if(strlen(naam)+1==sizeof(naam))
     while(fgetc(stdin)!=10){};

Het zou natuurlijk vrij efficiënt zijn als je dit stukje code iedere keer zou kunnen gebruiken als je tekstinvoer van de gebruiker wilt, zonder iedere keer de hele code over te typen. Daar gebruik je een functie voor. Als je dat netjes wil doen, plaats je eerst de functie-declaratie, dan main() en dan de functie definitie. Dus zoiets:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int input(char vraag[], char inputs[], int lengte);

int main()
{

     char naam[20], adres[30];

     if(input("\nNaam: ",naam,sizeof(naam))) return 1;
     if(input(“\nAdres: “,adres,sizeof(adres))) return 1;“
     printf("\nNaam: %s\nAdres: %s", naam, adres);

return 0;
}

int input(char vraag[], char inputs[], int lengte)
{
     printf("%s",vraag);
     if(fgets(inputs,lengte, stdin)==NULL)
          return 1;
     if(strlen(inputs)+1==lengte)
          while(fgetc(stdin)!=10){}
return 0;
}

Let overigens op de ; achter de functie-declaratie!

In deze functie is meteen wat extra foutafhandeling opgenomen, dat voorkomt problemen als projecten wat groter worden.

Je kan nu dezelfde code dus vaker gebruiken in één programma. Maar als de code universeel genoeg is om in meerdere programma’s te gebruiken, dan kan je de functies ook in je eigen header-file plaatsen. Om dat zo probleemloos mogelijk te doen, moet je op een paar zaken letten. Bij wijze van voorbeeld noem ik mijn header stdavk.h, dus een set functies die ik standaard wil kunnen gebruiken.

De declaratie van de functies zet je in een bestand met de naam stdavk.h, of iedere andere naam die je wilt natuurlijk, met een .h. Hierin geef je de compiler een aanwijzing om te voorkomen dat je dezelfde header meerdere keren opneemt, door een #define toe te voegen. Bij de start test je of de define al eens is uitgevoerd; zo nee, dan voeg je de declaraties toe, anders doe je niets.

De definitie van de functies schrijf je in stdavk.c, een normaal .c bestand, maar zonder main(). Je voegt alle andere headers toe die je nodig hebt, maar vooral niet meer dan dat. Met gcc -c stdavk.c compileer je de code tot een zogeheten object-file, stdavk.o.

In je programma voeg je bij de start nu een #include “stdavk.h” toe. Dit keer niet tussen < en >, maar tussen “”, omdat de compiler de header file moet zoeken in dezelfde locatie als waar je source file staat.

Als je programma 022-headers.c heet, dan kan je het nu compileren met gcc 022-headers.c stdavk.o.

Let er op dat als je de werking van een functie wilt aanpassen, je stdavk.c aanpast en opnieuw moet compileren naar een stdavk.o. Ook alle source-code waarin die functies gebruikt worden zal je opnieuw moeten compileren.

Pas de functie-declaraties liever niet aan als dat niet absoluut noodzakelijk is, want alle source-code die je hebt waarin de functies worden gebruikt zal nu niet alleen opnieuw gecompileerd moeten worden, maar zal herschreven moeten worden.

Op GitHub vind je als voorbeeld de code van vier afleveringen geleden, maar nu herschreven met de input-functie in een eigen header-file.

Wie mee wil doen met #klooienmetcomputers kan dat doen via GitHub. Maak een account op www.github.com en zoek naar Abmvk/kmc. Het account Abmvk volgen kan ook. Lezers zijn vrij te gebruiken wat ze willen en om zelf zaken toe te voegen of aan te passen, vragen te stellen of commentaar te leveren.

Arnout van Kempen di CCO CISA is Senior manager Risk & Compliance bij Bakertilly. Hij schrijft op persoonlijke titel. Als 'The Casual Compliance Officer' schrijft hij voor de gelijknamige website. Hij is lid van de Commissie Financiële verslaggeving & Accountancy van de AFM en lid van de signaleringsraad van de NBA. Daarnaast is hij diaken van het bisdom 's-Hertogenbosch.

Gerelateerd

reacties

Reageer op dit artikel

Spelregels debat

    Aanmelden nieuwsbrief

    Ontvang elke werkdag (maandag t/m vrijdag) de laatste nieuwsberichten, opinies en artikelen in uw mailbox.

    Bent u NBA-lid? Dan kunt u zich ook aanmelden via uw ledenprofiel op MijnNBA.nl.