C Predprocesorji

C Predprocesorji

Predprocesorji so programi, ki obdelajo izvorno kodo, preden se začne dejansko prevajanje. Niso del procesa prevajanja, ampak delujejo ločeno in programerjem omogočajo, da spremenijo kodo pred prevajanjem.

  • To je prvi korak, skozi katerega gre izvorna koda C, ko se pretvori v izvršljivo datoteko.
  • Glavne vrste direktiv predprocesorja so  Makri Pogojno prevajanje vključitve datoteke in druge direktive, kot je #undef #pragma itd.
  • Večinoma se te direktive uporabljajo za zamenjavo danega dela kode C z drugo kodo C. Če na primer napišemo '#define PI 3.14', potem predprocesor PI zamenja s 3.14.
C Predprocesorji

Vrste predprocesorjev C

Vse zgornje predprocesorje lahko razvrstimo v 4 vrste:

Makri

Makri se uporabljajo za definiranje konstant ali ustvarjanje funkcij, ki jih nadomesti predprocesor, preden se koda prevede. Dva predprocesorja #definiraj in #undef se uporabljajo za ustvarjanje in odstranjevanje makrov v C.

#definiraj vrednost žetona
#undef žeton

kjer po predhodni obdelavi žeton bodo razširili na svoje vrednost v programu.

primer:

C
   #include         // Macro Definition   #define LIMIT 5   int     main  (){      for     (  int     i     =     0  ;     i      <     LIMIT  ;     i  ++  )     {      printf  (  '%d   n  '       i  );      }      return     0  ;   }   

Izhod
0 1 2 3 4  

V zgornjem programu je pred začetkom prevajanja beseda LIMIT zamenjana s 5. Beseda 'LIMIT' v definiciji makra se imenuje predloga makra in '5' je makro razširitev.

Opomba Na koncu definicije makra ni podpičja (;). Makro definicije ne potrebujejo podpičja na koncu.

Nekaj ​​jih je tudi Vnaprej določeni makri v C ki so uporabni pri zagotavljanju različnih funkcionalnosti našega programa.

Prej definiran makro je lahko nedefiniran s predprocesorjem #undef. Na primer v zgornji kodi

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


Izhod:

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

Makri z argumenti

Argumente lahko posredujemo tudi makrom. Ti makri delujejo podobno kot funkcije. Na primer

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

Naj to razumemo s programom:

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

Izhod
Area of rectangle is: 50  

Pojasnilo: V zgornjem programu je makro OBMOČJE (l b) je definiran za izračun ploščine pravokotnika z množenjem njegove dolžina (l) in širina (b) . kdaj OBMOČJE (a b) se imenuje razširi na (a * b) rezultat pa se izračuna in natisne.

Prosimo, glejte Vrste makrov v C za več primerov in tipov.

Vključitev datoteke

Vključitev datotek vam omogoča, da v trenutni program vključite zunanje datoteke (knjižnice datotek glave itd.). To se običajno naredi z uporabo #vključi direktivo, ki lahko vključuje sistemske in uporabniško definirane datoteke.

Sintaksa

Glavne datoteke lahko vključite na dva načina.

#vključi
#vključi 'ime datoteke'

The ' <' in oklepaji '>' recite prevajalniku, naj poišče datoteko v standardni imenik medtem ko dvojni narekovaji ( ' ' ) povejte prevajalniku, naj poišče datoteko glave v imeniku izvorne datoteke.

primer:

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

Izhod
Hello World 

Pogojna kompilacija

Pogojna kompilacija omogoča vključitev ali izključitev delov kode glede na določene pogoje. To je uporabno za ustvarjanje kode, specifične za platformo, ali za odpravljanje napak. Obstajajo naslednje direktive pogojnega predprocesorja: #if #ifdef #ifndef else #elif in #endif

Sintaksa

Splošna sintaksa pogojnih predprocesorjev je:

#če
// nekaj kode
#elif
// še nekaj kode
#drugo
// Še nekaj kode
#endif

Direktiva #endif se uporablja za zapiranje odpiralnih direktiv #if #ifdef in #ifndef.

Primer

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

Izhod
PI is defined Square is not defined 

Pojasnilo: Ta koda uporablja pogojne direktive predprocesorja ( #ifdef #elif in #ifndef ), da preverite, ali so določeni makri ( PI in KVADRAT ) so definirani. Ker je PI definiran, program natisne ' PI je definiran ' nato preveri, če SQUARE ni definiran in natisne ' Kvadrat ni definiran '.

Druge direktive

Poleg primarnih direktiv predprocesorja ponuja C tudi druge direktive za upravljanje vedenja prevajalnika in odpravljanje napak.

#pragma:

Zagotavlja posebna navodila prevajalniku za nadzor njegovega vedenja. Uporablja se za onemogočanje poravnave opozoril itd.

Sintaksa

#pragma direktiva

Nekatere direktive #pragma so obravnavane spodaj: 

  1. #pragma zagon: Te direktive nam pomagajo določiti funkcije, ki se morajo izvajati pred zagonom programa (preden nadzor preide na main()).
  2. #pragma izhod : Te direktive nam pomagajo določiti funkcije, ki se morajo izvajati tik pred izhodom iz programa (tik preden se krmilnik vrne iz main()).

Primer

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

Izhod
Inside main()  

Zgornja koda bo proizvedla izhod, kot je naveden zgoraj, ko se izvaja v prevajalnikih GCC, medtem ko je bil pričakovan izhod:

Pričakovani rezultat

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

To se zgodi, ker GCC ne podpira #pragma zagona ali izhoda. Vendar pa lahko uporabite spodnjo kodo za pričakovan rezultat na prevajalnikih GCC. 

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

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

V zgornjem programu smo jih uporabili nekaj posebne sintakse tako da se ena od funkcij izvede pred glavno funkcijo, druga pa za glavno funkcijo.

Ustvari kviz