C Forbehandlere

C Forbehandlere

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.
C Forbehandlere

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 in  

Makroer 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.

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 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  ;   }   

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: 

  1. #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()).
  2. #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