Forbehandlere er programmer som behandler kildekoden før selve kompileringen starter. De er ikke en del av kompileringsprosessen, men fungerer separat slik at programmerere kan endre koden før kompilering.
- Det er det første trinnet som C-kildekoden går gjennom når den konverteres til en kjørbar fil.
- Hovedtyper av forbehandlerdirektiver er Makroer Filinkludering betinget kompilering og andre direktiver som #undef #pragma etc.
- Hovedsakelig brukes disse direktivene til å erstatte en gitt del av C-koden med en annen C-kode. For eksempel hvis vi skriver '#define PI 3.14', erstattes PI med 3.14 av forprosessoren.
Typer C-forprosessorer
Alle de ovennevnte forprosessorene kan klassifiseres i 4 typer:
Makroer
Makroer brukes til å definere konstanter eller lage funksjoner som erstattes av forprosessoren før koden kompileres. De to forprosessorene #definere og #undef brukes til å lage og fjerne makroer i C.
#definere symbolverdi
#undef token
hvor etter forbehandling av token vil bli utvidet til sin verdi i programmet.
Eksempel:
C#include // Macro Definition #define LIMIT 5 int main(){ for (int i = 0; i < LIMIT; i++) { printf('%d n' i); } return 0; }
Produksjon
0 1 2 3 4
I programmet ovenfor før kompileringen begynner, erstattes ordet LIMIT med 5. Ordet 'BEGRENSE' i makrodefinisjonen kalles en makromal og '5' er makroutvidelse.
Note Det er ingen semikolon (;) på slutten av makrodefinisjonen. Makrodefinisjoner trenger ikke et semikolon for å avslutte.
Det er også noen Forhåndsdefinerte makroer i C som er nyttige for å gi ulike funksjoner til programmet vårt.
En makro definert tidligere kan være udefinert ved å bruke #undef forprosessor. For eksempel i koden ovenfor
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; }
Produksjon:
./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 inMakroer med argumenter
Vi kan også sende argumenter til makroer. Disse makroene fungerer på samme måte som funksjoner. For eksempel
# definere foo(a b) a + b
#define func(r) r * r
La oss forstå dette med et program:
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; }
Produksjon
Area of rectangle is: 50
Forklaring: I programmet ovenfor er makroen OMRÅDE(l b) er definert for å beregne arealet av et rektangel ved å multiplisere dets lengde (l) og bredde (b) . Når OMRÅDE(a b) kalles det utvides til (a * b) og resultatet beregnes og skrives ut.
Vennligst referer Typer makroer i C for flere eksempler og typer.
tilfeldig i c
Filinkludering
Filinkludering lar deg inkludere eksterne filer (header-filbiblioteker osv.) i gjeldende program. Dette gjøres vanligvis ved å bruke #inkludere direktiv som kan inkludere både system- og brukerdefinerte filer.
Syntaks
Det er to måter å inkludere header-filer på.
#inkludere
#inkludere 'filnavn'
De '<' og '>' parenteser be kompilatoren se etter filen i standard katalog mens doble anførselstegn ( ' ' ) be kompilatoren søke etter overskriftsfilen i kildefilens katalog.
Eksempel:
C// Includes the standard I/O library #include int main() { printf('Hello World'); return 0; }
Produksjon
Hello World
Betinget kompilering
Betinget kompilering lar deg inkludere eller ekskludere deler av koden avhengig av visse forhold. Dette er nyttig for å lage plattformspesifikk kode eller for feilsøking. Det er følgende betingede forprosessordirektiver: #if #ifdef #ifndef else #elif og #endif
Syntaks
Den generelle syntaksen til betingede forprosessorer er:
#hvis
// litt kode
#elif
// litt mer kode
#ellers
// Litt mer kode
#endif
#endif-direktivet brukes til å stenge åpningsdirektivene #if #ifdef og #ifndef.
Eksempel
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 definedn'); // If PI is not defined check if SQUARE is defined #elif defined(SQUARE) printf('Square is definedn'); // 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; }
Produksjon
PI is defined Square is not defined
Forklaring: Denne koden bruker betingede forbehandlerdirektiver ( #ifdef #elif og #ifndef ) for å sjekke om visse makroer ( PI og KVADRAT ) er definert. Siden PI er definert, skriver programmet ut ' PI er definert ' sjekker så om SQUARE ikke er definert og skriver ut ' Kvadrat er ikke definert '.
Andre direktiver
Bortsett fra de primære forprosessordirektivene gir C også andre direktiver for å administrere kompilatoratferd og feilsøking.
#pragma:
Gir spesifikke instruksjoner til kompilatoren for å kontrollere dens oppførsel. Den brukes til å deaktivere justering av advarsler osv.
Syntaks
#pragma direktiv
Noen av #pragma-direktivene er omtalt nedenfor:
- #pragma oppstart: Disse direktivene hjelper oss med å spesifisere funksjonene som er nødvendige for å kjøre før oppstart av programmet (før kontrollen går over til main()).
- #pragma exit : Disse direktivene hjelper oss med å spesifisere funksjonene som er nødvendige for å kjøre rett før programmet avsluttes (rett før kontrollen kommer tilbake fra main()).
Eksempel
C#include void 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; }
Produksjon
Inside main()
Koden ovenfor vil produsere utgangen som gitt ovenfor når den kjøres på GCC-kompilatorer mens den forventede utgangen var:
Forventet utgang
Inside func1() Inside main() Inside func2() Dette skjer fordi GCC ikke støtter #pragma oppstart eller exit. Du kan imidlertid bruke koden nedenfor for forventet utgang på GCC-kompilatorer.
C#include void 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; }
Produksjon
Inside func1() Inside main() Inside func2()
I programmet ovenfor har vi brukt noen spesifikke syntakser slik at en av funksjonene kjøres før hovedfunksjonen og den andre kjøres etter hovedfunksjonen.
Lag quiz