C Preprocessors
Preprocessors zijn programma's die de broncode verwerken voordat de daadwerkelijke compilatie begint. Ze maken geen deel uit van het compilatieproces, maar werken afzonderlijk, waardoor programmeurs de code vóór het compileren kunnen wijzigen.
- Het is de eerste stap die de C-broncode doorloopt bij het converteren naar een uitvoerbaar bestand.
- De belangrijkste soorten preprocessorrichtlijnen zijn: Macro's Bestandsopname Voorwaardelijke compilatie en andere richtlijnen zoals #undef #pragma etc.
- Deze richtlijnen worden voornamelijk gebruikt om een bepaald gedeelte van de C-code te vervangen door een andere C-code. Als we bijvoorbeeld '#define PI 3.14' schrijven, wordt PI door de preprocessor vervangen door 3.14.
Soorten C-preprocessors
Alle bovenstaande preprocessors kunnen in 4 typen worden ingedeeld:
Macro's
Macro's worden gebruikt om constanten te definiëren of functies te creëren die door de preprocessor worden vervangen voordat de code wordt gecompileerd. De twee preprocessors #definiëren En #undef worden gebruikt om macro's in C te maken en te verwijderen.
#definiëren symbolische waarde
#undef teken
waar na het voorbewerken van de teken zal worden uitgebreid naar zijn waarde in het programma.
Voorbeeld:
C #include // Macro Definition #define LIMIT 5 int main (){ for ( int i = 0 ; i < LIMIT ; i ++ ) { printf ( '%d n ' i ); } return 0 ; }
Uitvoer
0 1 2 3 4
In het bovenstaande programma wordt voordat de compilatie begint het woord LIMIT vervangen door 5. Het woord 'BEPERKEN' in de macrodefinitie wordt een macrosjabloon genoemd En '5' is macro-expansie.
Opmerking Er staat geen puntkomma (;) aan het einde van de macrodefinitie. Macrodefinities hebben geen puntkomma nodig om te eindigen.
Er zijn er ook enkele Vooraf gedefinieerde macro's in C die nuttig zijn bij het bieden van verschillende functionaliteiten aan ons programma.
Een eerder gedefinieerde macro kan gededefinieerd worden met #undef preprocessor. Bijvoorbeeld in de bovenstaande code
C #include // Macro Definition #define LIMIT 5 // Undefine macro #undef LIMIT int main (){ for ( int i = 0 ; i < LIMIT ; i ++ ) { printf ( '%d n ' i ); } return 0 ; }
Uitgang:
./Solution.c: In function 'main': ./Solution.c:13:28: error: 'MAX' undeclared (first use in this function) printf('MAX is: %dn' MAX); ^ ./Solution.c:13:28: note: each undeclared identifier is reported only once for each function it appears inMacro's met argumenten
We kunnen ook argumenten doorgeven aan macro's. Deze macro's werken op dezelfde manier als functies. Bijvoorbeeld
# definiëren foo(a b) a + b
#define func(r) r * rLaten we dit begrijpen met een programma:
C#include// macro with parameter #define AREA(l b) (l * b) int main (){ int a = 10 b = 5 ; // Finding area using above macro printf ( '%d' AREA ( a b )); return 0 ; }
UitvoerArea of rectangle is: 50Uitleg: In het bovenstaande programma is de macro GEBIED(l b) is gedefinieerd om de oppervlakte van een rechthoek te berekenen door de oppervlakte ervan te vermenigvuldigen lengte (l) En breedte (b) . Wanneer GEBIED(a b) heet het breidt uit naar (een * b) en het resultaat wordt berekend en afgedrukt.
Raadpleeg alstublieft Soorten macro's in C voor meer voorbeelden en typen.
Bestandsopname
Met bestandsopname kunt u externe bestanden (bibliotheken met headerbestanden enz.) in het huidige programma opnemen. Meestal wordt dit gedaan met behulp van de #erbij betrekken richtlijn die zowel systeem- als door de gebruiker gedefinieerde bestanden kan bevatten.
Syntaxis
Er zijn twee manieren om headerbestanden op te nemen.
#erbij betrekken
#erbij betrekken 'bestandsnaam'De ' <' En '>' haakjes vertel de compiler dat hij naar het bestand moet zoeken in de standaard map terwijl dubbele aanhalingstekens ( '' ) vertel de compiler om te zoeken naar het headerbestand in de directory van het bronbestand.
Voorbeeld:
C// Includes the standard I/O library #includeint main () { printf ( 'Hello World' ); return 0 ; }
UitvoerHello WorldVoorwaardelijke compilatie
Voorwaardelijke compilatie Hiermee kunt u delen van de code opnemen of uitsluiten, afhankelijk van bepaalde voorwaarden. Dit is handig voor het maken van platformspecifieke code of voor het opsporen van fouten. Er zijn de volgende voorwaardelijke preprocessor-richtlijnen: #if #ifdef #ifndef else #elif en #endif
Syntaxis
De algemene syntaxis van voorwaardelijke preprocessors is:
#als
// een code
#elif
// nog wat code
#anders
// Nog wat code
#endif#endif-richtlijn wordt gebruikt om de openingsrichtlijnen #if #ifdef en #ifndef af te sluiten.
Voorbeeld
C#include// Defining a macro for PI #define PI 3.14159 int main (){ // Check if PI is defined using #ifdef #ifdef PI printf ( 'PI is defined n ' ); // If PI is not defined check if SQUARE is defined #elif defined(SQUARE) printf ( 'Square is defined n ' ); // If neither PI nor SQUARE is defined trigger an error #else #error 'Neither PI nor SQUARE is defined' #endif // Check if SQUARE is not defined using #ifndef #ifndef SQUARE printf ( 'Square is not defined' ); // If SQUARE is defined print that it is defined #else printf ( 'Square is defined' ); #endif return 0 ; }
UitvoerPI is defined Square is not definedUitleg: Deze code maakt gebruik van voorwaardelijke preprocessorrichtlijnen ( #ifdef #elif en #ifndef ) om te controleren of bepaalde macro's ( PI En VIERKANT ) zijn gedefinieerd. Omdat PI is gedefinieerd, drukt het programma ' PI is gedefinieerd 'controleert vervolgens of SQUARE niet is gedefinieerd en drukt af' Vierkant is niet gedefinieerd '.
Andere richtlijnen
Naast de primaire preprocessorrichtlijnen biedt C ook andere richtlijnen om het gedrag van de compiler en het debuggen te beheren.
#pragma:
Biedt specifieke instructies aan de compiler om zijn gedrag te controleren. Het wordt gebruikt om waarschuwingen uit te schakelen, uitlijning etc.
Syntaxis
#pragma richtlijn
Enkele van de #pragma-richtlijnen worden hieronder besproken:
- #pragma opstarten: Deze richtlijnen helpen ons bij het specificeren van de functies die nodig zijn om te worden uitgevoerd vóór het opstarten van het programma (voordat de besturing overgaat naar main()).
- #pragma uitgang : Deze richtlijnen helpen ons de functies te specificeren die nodig zijn om te worden uitgevoerd vlak voordat het programma wordt afgesloten (net voordat het besturingselement terugkeert van main()).
Voorbeeld
C#includevoid func1 (); void func2 (); // specifying funct1 to execute at start #pragma startup func1 // specifying funct2 to execute before end #pragma exit func2 void func1 () { printf ( 'Inside func1() n ' ); } void func2 () { printf ( 'Inside func2() n ' ); } int main (){ void func1 (); void func2 (); printf ( 'Inside main() n ' ); return 0 ; }
UitvoerInside main()De bovenstaande code produceert de uitvoer zoals hierboven aangegeven wanneer deze wordt uitgevoerd op GCC-compilers terwijl de verwachte uitvoer was:
Verwachte output
Inside func1() Inside main() Inside func2()Dit gebeurt omdat GCC het opstarten of afsluiten van #pragma niet ondersteunt. U kunt de onderstaande code echter gebruiken voor de verwachte uitvoer op GCC-compilers.
C#includevoid func1 (); void func2 (); void __attribute__ (( constructor )) func1 (); void __attribute__ (( destructor )) func2 (); void func1 () { printf ( 'Inside func1() n ' ); } void func2 () { printf ( 'Inside func2() n ' ); } int main () { printf ( 'Inside main() n ' ); return 0 ; }
UitvoerInside func1() Inside main() Inside func2()In het bovenstaande programma hebben we er een aantal gebruikt specifieke syntaxis zodat een van de functies vóór de hoofdfunctie wordt uitgevoerd en de andere na de hoofdfunctie wordt uitgevoerd.
Quiz maken