C Pretprocesori

C Pretprocesori

Pretprocesori su programi koji obrađuju izvorni kod prije početka stvarne kompilacije. Oni nisu dio procesa kompilacije, već rade zasebno dopuštajući programerima da modificiraju kod prije kompilacije.

  • To je prvi korak kroz koji C izvorni kod prolazi kada se pretvara u izvršnu datoteku.
  • Glavne vrste direktiva pretprocesora su  Makronaredbe Uvjetna kompilacija uključivanja datoteke i druge direktive poput #undef #pragma itd.
  • Uglavnom se ove direktive koriste za zamjenu određenog dijela C koda drugim C kodom. Na primjer, ako napišemo '#define PI 3.14', pretprocesor zamjenjuje PI s 3.14.
C Pretprocesori

Vrste C pretprocesora

Svi gore navedeni pretprocesori mogu se klasificirati u 4 vrste:

Makronaredbe

Makronaredbe koriste se za definiranje konstanti ili stvaranje funkcija koje su zamijenjene pretprocesorom prije nego što se kod kompajlira. Dva predprocesora #definirati i #undef koriste se za stvaranje i uklanjanje makronaredbi u C-u.

#definirati vrijednost tokena
#undef znak

gdje je nakon predobrade znak proširit će se na svoje vrijednost u programu.

Primjer:

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

Izlaz
0 1 2 3 4  

U gornjem programu prije početka kompilacije riječ LIMIT zamijenjena je s 5. Riječ 'OGRANIČITI' u makro definiciji naziva se makro predložak i '5' je makro ekspanzija.

Bilješka Na kraju definicije makronaredbe nema točke-zareza (;). Za kraj definicija makronaredbi nije potrebna točka-zarez.

Ima i takvih Unaprijed definirane makronaredbe u C-u koji su korisni u pružanju raznih funkcionalnosti našem programu.

Prethodno definirana makronaredba može biti nedefinirana pomoću #undef predprocesora. Na primjer u gornjem kodu

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


Izlaz:

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

Makronaredbe s argumentima

Također možemo proslijediti argumente makronaredbama. Ove makronaredbe rade slično funkcijama. Na primjer

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

Shvatimo ovo pomoću programa:

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

Izlaz
Area of rectangle is: 50  

Obrazloženje: U gornjem programu makro PODRUČJE (l b) je definiran za izračunavanje površine pravokutnika množenjem njegove duljina (l) i širina (b) . Kada PODRUČJE (a b) naziva se proširuje na (a * b) a rezultat se izračunava i ispisuje.

Molimo pogledajte Vrste makronaredbi u C za više primjera i vrsta.

Uključivanje datoteke

Uključivanje datoteka omogućuje vam uključivanje vanjskih datoteka (biblioteke datoteka zaglavlja itd.) u trenutni program. To se obično radi pomoću #uključi direktiva koja može uključivati ​​i sistemske i korisnički definirane datoteke.

Sintaksa

Postoje dva načina uključivanja datoteka zaglavlja.

#uključi
#uključi 'ime datoteke'

The ' <' i '>' zagrade recite kompajleru da potraži datoteku u standardni imenik dok dvostruki navodnici ( ' ' ) recite kompajleru da traži datoteku zaglavlja u direktoriju izvorne datoteke.

Primjer:

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

Izlaz
Hello World 

Uvjetna kompilacija

Uvjetna kompilacija omogućuje uključivanje ili isključivanje dijelova koda ovisno o određenim uvjetima. Ovo je korisno za stvaranje koda specifičnog za platformu ili za otklanjanje pogrešaka. Postoje sljedeće uvjetne direktive pretprocesora: #if #ifdef #ifndef else #elif i #endif

Sintaksa

Opća sintaksa uvjetnih predprocesora je:

#ako
// neki kod
#elif
// još malo koda
#drugo
// Još malo koda
#endif

#endif direktiva se koristi za zatvaranje #if #ifdef i #ifndef otvarajućih direktiva.

Primjer

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

Izlaz
PI is defined Square is not defined 

Obrazloženje: Ovaj kod koristi uvjetne direktive pretprocesora ( #ifdef #elif i #ifndef ) da biste provjerili jesu li određene makronaredbe ( PI i KVADRAT ) su definirani. Budući da je PI definiran, program ispisuje ' PI je definiran ' zatim provjerava nije li SQUARE definiran i ispisuje ' Kvadrat nije definiran '.

Ostale direktive

Osim direktiva primarnog predprocesora, C također pruža druge direktive za upravljanje ponašanjem prevoditelja i otklanjanjem pogrešaka.

#pragma:

Pruža posebne upute kompajleru za kontrolu njegovog ponašanja. Koristi se za onemogućavanje usklađivanja skupa upozorenja itd.

Sintaksa

#pragma direktiva

Neke od direktiva #pragma razmatraju se u nastavku: 

  1. #pragma pokretanje: Ove nam direktive pomažu odrediti funkcije koje je potrebno pokrenuti prije pokretanja programa (prije nego što kontrola prijeđe na main()).
  2. #pragma izlaz : Ove nam direktive pomažu da specificiramo funkcije koje su potrebne za izvođenje neposredno prije izlaska iz programa (neposredno prije nego što se kontrola vrati iz main()).

Primjer

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

Izlaz
Inside main()  

Gornji kod će proizvesti izlaz kao što je gore dat kada se pokrene na GCC kompajlerima dok je očekivani izlaz bio:

Očekivani rezultat

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

To se događa jer GCC ne podržava #pragma pokretanje ili izlaz. Međutim, možete koristiti donji kod za očekivani izlaz na GCC kompajlerima. 

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

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

U gornjem programu koristili smo neke specifične sintakse tako da se jedna od funkcija izvršava prije glavne funkcije, a druga se izvršava nakon glavne funkcije.

Napravi kviz