Linux C programmeerhandleiding Deel 28 – Typedefs

In deze tutorial – die deel uitmaakt van de lopende C programmeer tutorial serie – bespreken we het concept typedef. Zoals de naam doet vermoeden (denk aan typedef als type+def), is typedef een door C verschafte voorziening om nieuwe namen voor bestaande gegevenssoorten te definiëren.

Typedef in de programmeertaal C

Hier is een voorbeeld dat laat zien hoe typedef gebruikt kan worden:

typedef int my_int

De regel hierboven – die begint met het sleutelwoord ’typedef’ – geeft het datatype ‘int’ een nieuwe naam: ‘my_int’. Dus, een code als deze:

#include <stdio.h>

int main()
{
int a = 10;
printf("The value of a is: %d", a);

return 0;
}

Kan geschreven worden als het volgende bij gebruik van het typedef voorbeeld dat we zojuist bespraken:

#include <stdio.h>

typedef int my_int;

int main()
{
my_int a = 10;
printf("The value of a is: %d", a);

return 0;
}

Nu is een vraag die sommigen kunnen stellen: wat is het verschil tussen een typedef en een #define? Wel, hoewel beide gelijksoortige dingen lijken te doen, zijn er in feite nogal wat verschillen tussen de twee.

Ten eerste wordt een typedef door de compiler geïnterpreteerd, terwijl een #define het nooit tot het compilatiestadium haalt, want hij wordt pas in het voorbewerkingsstadium zelf geïnterpreteerd. Dan volgt een typedef de regels van de scope, terwijl een #define dat niet doet. Het volgende is hiervan een voorbeeld:

#include <stdio.h>

void my_func();

int main()
{
typedef int my_int;
my_int a = 10;
printf("The value of a is: %d", a);
my_func();

return 0;
}

void my_func()
{
my_int b = 20;
printf("The value of a is: %d", b);

return;
}

Als deze code uitgevoerd wordt, krijg je de volgende foutmelding:

main.c: In function ‘my_func’:
main.c:25:5: error: unknown type name ‘my_int’
my_int b = 20;
^

Zoals je ziet kon de compiler dus het type ‘my_int’ in de functie ‘my_func’ niet herkennen, want het bereik waaronder typedef geldig was, was het bereik van de functie ‘main’.

Dan zijn er nog enkele andere verschillen tussen een typedef en een #define. Zo kun je met een #define ook aliassen maken voor constante waarden – ik bedoel, je kunt iets doen als ‘#define PIE 3.14’. Ook wordt, zoals je gemerkt zult hebben, een #define niet afgesloten met een puntkomma, terwijl een typedef dat wel doet.

Nu zou men nog steeds vragen waarom we ’typedef’ nodig hebben. Of met andere woorden, waar komt een typedef echt van pas? Wel, stel dat er een stuk code is met functies die ‘pointer to a function which accepts two integers as arguments as returns a character value’ teruggeven.

Voor het geval je het niet weet, wordt zo’n pointer op de volgende manier gedeclareerd:

char (*fn_ptr) (int, int);

Waarbij fn_ptr de naam van zo’n pointer is.

Dus in plaats van steeds weer zo’n lange en ingewikkelde declaratie te moeten gebruiken als het terugkeertype van andere functies, kun je van fn_ptr gewoon een type maken met typedef:

typedef char (*fn_ptr) (int, int);

En nu kun je gewoon ‘fn_ptr’ gebruiken, en het zal een pointer van dit type aanduiden.

Een ander gebruik van typedef houdt in dat je in code een door de gebruiker gedefinieerd gegevenstype gebruikt dat overeenkomt met het native type dat geboden wordt door het onderliggende platform waarop de code draait. Op deze manier helpen typedefs om elk stuk code dat ontwikkeld is om op meerdere platformen te draaien, gemakkelijk te begrijpen en te onderhouden.

Conclusie

In deze tutorial bespraken we dus de basisprincipes van typedefs, waaronder wat typedef doet, hoe het verschilt van een #define richtlijn, en hoe typedefs je dag kunnen redden door code gemakkelijk te lezen, te begrijpen, en te onderhouden te maken.

Je kunt de voorbeelden die we hier gebruikten uitproberen en nog meer voorbeelden uitwerken om typedefs beter te leren begrijpen, en zoals altijd kun je bij twijfel of vragen hieronder een reactie geven.