C Forprocessorer

C Forprocessorer

Forbehandlere er programmer, der behandler kildekoden, før selve kompileringen begynder. De er ikke en del af kompileringsprocessen, men fungerer separat, hvilket giver programmører mulighed for at ændre koden før kompilering.

  • Det er det første trin, som C-kildekoden går igennem, når den konverteres til en eksekverbar fil.
  • Hovedtyper af præprocessordirektiver er  Makroer Filinkludering betinget kompilering og andre direktiver som #undef #pragma osv.
  • Disse direktiver bruges hovedsageligt til at erstatte en given del af C-koden med en anden C-kode. For eksempel hvis vi skriver '#define PI 3.14', så erstattes PI med 3.14 af præprocessoren.
C Forprocessorer

Typer af C-forprocessorer

Alle ovenstående præprocessorer kan klassificeres i 4 typer:

Makroer

Makroer bruges til at definere konstanter eller oprette funktioner, der erstattes af præprocessoren, før koden kompileres. De to forprocessorer #definere og #undef bruges til at oprette og fjerne makroer i C.

#definere symbolsk værdi
#undef token

hvor efter forbehandling af token vil blive udvidet til sin værdi 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  ;   }   

Produktion
0 1 2 3 4  

I ovenstående program, før kompileringen begynder, erstattes ordet LIMIT med 5. Ordet 'BEGRÆNSE' i makrodefinitionen kaldes en makroskabelon og '5' er makroudvidelse.

Note Der er intet semikolon (;) i slutningen af ​​makrodefinitionen. Makrodefinitioner behøver ikke et semikolon for at slutte.

Der er også nogle Foruddefinerede makroer i C som er nyttige til at levere forskellige funktionaliteter til vores program.

En makro defineret tidligere kan være udefineret ved hjælp af #undef preprocessor. For eksempel i ovenstående kode

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


Output:

 ./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å overføre argumenter til makroer. Disse makroer fungerer på samme måde som funktioner. F.eks

# definere foo(a b) a + b
#define func(r) r * r

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

Produktion
Area of rectangle is: 50  

Forklaring: I ovenstående program er makroen OMRÅDE(l b) er defineret til at beregne arealet af et rektangel ved at gange dets længde (l) og bredde (b) . Når OMRÅDE(a b) kaldes det udvider sig til (a * b) og resultatet beregnes og udskrives.

Se venligst Typer af makroer i C for flere eksempler og typer.

Filinkludering

Filinkludering giver dig mulighed for at inkludere eksterne filer (header-filbiblioteker osv.) i det aktuelle program. Dette gøres typisk ved hjælp af #omfatte direktiv, som kan omfatte både system- og brugerdefinerede filer.

Syntaks

Der er to måder at inkludere header-filer på.

#omfatte
#omfatte 'filnavn'

De ' <' og '>' parenteser bed compileren om at lede efter filen i standard bibliotek mens dobbelte anførselstegn ( ' ' ) bed compileren om at søge efter header-filen i kildefilens bibliotek.

Eksempel:

C
   // Includes the standard I/O library   #include            int     main  ()     {      printf  (  'Hello World'  );          return     0  ;   }   

Produktion
Hello World 

Betinget kompilering

Betinget kompilering giver dig mulighed for at inkludere eller udelukke dele af koden afhængigt af visse betingelser. Dette er nyttigt til at oprette platformsspecifik kode eller til fejlretning. Der er følgende betingede præprocessor-direktiver: #if #ifdef #ifndef else #elif og #endif

Syntaks

Den generelle syntaks for betingede præprocessorer er:

#hvis
// noget kode
#elif
// lidt mere kode
#andet
// Lidt mere kode
#endif

#endif-direktivet bruges til at lukke #if #ifdef- og #ifndef-åbningsdirektiverne.

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

Produktion
PI is defined Square is not defined 

Forklaring: Denne kode bruger betingede præprocessor-direktiver ( #ifdef #elif og #ifndef ) for at kontrollere, om visse makroer ( PI og FIRKANT ) er defineret. Da PI er defineret, udskriver programmet ' PI er defineret ' kontrollerer derefter om SQUARE ikke er defineret og udskriver ' Kvadrat er ikke defineret '.

Andre direktiver

Ud over de primære præprocessor-direktiver giver C også andre direktiver til at styre compileradfærd og fejlfinding.

#pragma:

Giver specifikke instruktioner til compileren for at kontrollere dens adfærd. Den bruges til at deaktivere justering af advarsler osv.

Syntaks

#pragma direktiv

Nogle af #pragma-direktiverne diskuteres nedenfor: 

  1. #pragma opstart: Disse direktiver hjælper os med at specificere de funktioner, der er nødvendige for at køre før programstart (før styringen overføres til main()).
  2. #pragma exit : Disse direktiver hjælper os med at specificere de funktioner, der er nødvendige for at køre lige før programmet afsluttes (lige før kontrollen vender tilbage 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  ;   }   

Produktion
Inside main()  

Ovenstående kode vil producere output som angivet ovenfor, når det køres på GCC-kompilere, mens det forventede output var:

Forventet output

 Inside func1() Inside main() Inside func2()   

Dette sker, fordi GCC ikke understøtter #pragma opstart eller exit. Du kan dog bruge nedenstående kode til det forventede output på GCC-kompilere. 

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

Produktion
Inside func1() Inside main() Inside func2()  

I ovenstående program har vi brugt nogle specifikke syntakser således at en af ​​funktionerne udføres før hovedfunktionen og den anden udføres efter hovedfunktionen.

Opret Quiz