Preprocessor macro's in C zijn ontstaan als onderdeel van de taal om de overdraagbaarheid, leesbaarheid en gemak van configuratie van de broncode te waarborgen. Met behulp van de instructies #define, #ifdef, #ifndef kunnen voorwaardelijke code-secties worden gemaakt, constanten worden gedeclareerd en externe bestanden worden opgenomen (#include).
Geschiedenis van de vraag:
Preprocessor-instructies werden geïntroduceerd om de aanpassing van broncode aan verschillende systemen en compilatoren te vereenvoudigen, evenals om repetitieve taken te automatiseren.
Probleem:
Zonder preprocessor was het niet mogelijk om abstractie te creëren van platformverschillen, codefragmenten te herhalen en dubbele opname van headerbestanden te voorkomen. Bovendien moet je voorzichtig zijn, want macro's zijn niet getypeerd en hebben geen scope.
Oplossing:
Het gebruik van preprocessor macro's voor het declareren van constanten, inline-functies, voorwaardelijke compilatie en het voorkomen van meervoudige inclusief van headerbestanden.
Voorbeeldcode:
#ifndef MY_HEADER_H #define MY_HEADER_H #define MAX_SIZE 100 #ifdef DEBUG #define LOG(x) printf("%s\n", x) #else #define LOG(x) #endif #endif /* MY_HEADER_H */
Belangrijke kenmerken:
Wat gebeurt er als je de include guard in het headerbestand vergeet?
Het headerbestand kan meerdere keren in één .c bestand worden opgenomen (impliciet via andere .h), wat leidt tot herdefinitie-fouten.
Wat is het verschil tussen #define macro's en inline-functie declaraties?
#define vervangt gewoon tekst, zonder types en syntaxis te controleren, terwijl een inline-functie een gewone functie is die door de compiler wordt gecontroleerd tijdens het type-analyse.
Kunnen macro's bijwerkingen hebben?
Ja, als de macro onvoorzichtig is gedefinieerd, kunnen doorgegeven expressies meerdere keren worden berekend. Bijvoorbeeld:
#define SQUARE(x) (x) * (x) int a = SQUARE(++i); // ++i wordt TWEE KEER uitgevoerd!
Gebruik van een macro zonder haakjes en met een expressie die bijwerkingen creëert:
#define DOUBLE(x) x + x int result = DOUBLE(1+2); // resultaat is niet 6, maar 1+2+1+2=6? Nee, het is 1+2+1+2=6 — toch? Nee, het wordt 1+2+1+2. // Maar in werkelijkheid zal dit 1 + 2 + 1 + 2 = 6 zijn, maar als DOUBLE(++i), dan wordt ++i twee keer toegepast.
Voordelen:
Nadelen:
Definitie van een macro met haakjes en gebruik voor eenvoudige constanten:
#define DOUBLE(x) ((x) + (x)) #define BUFFER_SIZE 1024
Voordelen:
Nadelen: