C Preprocesoare

C Preprocesoare

Preprocesoare sunt programe care procesează codul sursă înainte de a începe compilarea propriu-zisă. Ele nu fac parte din procesul de compilare, dar funcționează separat, permițând programatorilor să modifice codul înainte de compilare.

  • Este primul pas prin care parcurge codul sursă C atunci când este convertit într-un fișier executabil.
  • Principalele tipuri de directive de preprocesor sunt  Macro-uri Compilarea condiționată pentru includerea fișierelor și alte directive precum #undef #pragma etc.
  • În principal, aceste directive sunt folosite pentru a înlocui o anumită secțiune a codului C cu un alt cod C. De exemplu, dacă scriem „#define PI 3.14”, atunci PI este înlocuit cu 3.14 de către preprocesor.
C Preprocesoare

Tipuri de preprocesoare C

Toate preprocesoarele de mai sus pot fi clasificate în 4 tipuri:

Macro-uri

Macro-uri sunt folosite pentru a defini constante sau pentru a crea funcții care sunt înlocuite de preprocesor înainte ca codul să fie compilat. Cele două preprocesoare #defini şi #undef sunt folosite pentru a crea și elimina macrocomenzi în C.

#defini valoare indicativă
#undef jeton

unde după preprocesarea jeton va fi extins la acesta valoare în program.

Exemplu:

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

Ieșire
0 1 2 3 4  

În programul de mai sus înainte de a începe compilarea, cuvântul LIMIT este înlocuit cu 5. Cuvântul 'LIMITĂ' în definiția macro se numește șablon macro şi „5” este extinderea macro.

Nota Nu există punct și virgulă (;) la sfârșitul definiției macro. Definițiile macro nu au nevoie de punct și virgulă pentru a se termina.

Există și unii Macrocomenzi predefinite în C care sunt utile în furnizarea diverselor funcționalități programului nostru.

O macrocomandă definită anterior poate fi nedefinită folosind preprocesorul #undef. De exemplu, în codul de mai sus

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


Ieșire:

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

Macro-uri cu argumente

De asemenea, putem transmite argumente macrocomenzi. Aceste macrocomenzi funcționează în mod similar cu funcțiile. De exemplu

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

Să înțelegem asta cu un 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  ;   }   

Ieșire
Area of rectangle is: 50  

Explicaţie: În programul de mai sus macro AREA(l b) este definit pentru a calcula aria unui dreptunghi prin înmulțirea acestuia lungime (l) şi lățime (b) . Când ZONA(a b) se numește se extinde la (a*b) iar rezultatul este calculat și tipărit.

Vă rugăm să consultați Tipuri de macrocomenzi în C pentru mai multe exemple și tipuri.

Includerea fișierului

Includerea fișierelor vă permite să includeți fișiere externe (biblioteci de fișiere antet etc.) în programul curent. Acest lucru se face de obicei folosind #include directivă care poate include atât fișiere de sistem, cât și fișiere definite de utilizator.

Sintaxă

Există două moduri de a include fișiere antet.

#include
#include 'nume de fișier'

The ' <' şi '>' paranteze spuneți compilatorului să caute fișierul în fișierul director standard în timp ce ghilimele duble ( ' ' ) spuneți compilatorului să caute fișierul antet în directorul fișierului sursă.

Exemplu:

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

Ieșire
Hello World 

Compilare condiționată

Compilare condiționată vă permite să includeți sau să excludeți părți ale codului în funcție de anumite condiții. Acest lucru este util pentru crearea de cod specific platformei sau pentru depanare. Există următoarele directive condiționale de preprocesor: #if #ifdef #ifndef else #elif și #endif

Sintaxă

Sintaxa generală a preprocesoarelor condiționale este:

#dacă
// ceva cod
#elif
// încă ceva cod
#altfel
// Mai mult cod
#endif

Directiva #endif este folosită pentru a închide directivele de deschidere #if #ifdef și #ifndef.

Exemplu

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

Ieșire
PI is defined Square is not defined 

Explicaţie: Acest cod folosește directive condiționale de preprocesor ( #ifdef #elif și #ifndef ) pentru a verifica dacă anumite macrocomenzi ( PI şi PĂTRAT ) sunt definite. Deoarece PI este definit, programul afișează ' PI este definit " apoi verifică dacă PĂTRATUL nu este definit și tipărește " Pătratul nu este definit '.

Alte directive

În afară de directivele de preprocesor primar, C oferă și alte directive pentru a gestiona comportamentul compilatorului și depanarea.

#pragma:

Oferă instrucțiuni specifice compilatorului pentru a-și controla comportamentul. Este folosit pentru a dezactiva alinierea setărilor de avertismente etc.

Sintaxă

#pragma directivă

Unele dintre directivele #pragma sunt discutate mai jos: 

  1. #pragma startup: Aceste directive ne ajută să specificăm funcțiile care sunt necesare pentru a rula înainte de pornirea programului (înainte ca controlul să treacă la main()).
  2. #pragma ieșire : Aceste directive ne ajută să specificăm funcțiile care sunt necesare pentru a rula chiar înainte de ieșirea programului (chiar înainte ca controlul să revină din main()).

Exemplu

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

Ieșire
Inside main()  

Codul de mai sus va produce rezultatul prezentat mai sus atunci când rulează pe compilatoarele GCC în timp ce rezultatul așteptat a fost:

Rezultat așteptat

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

Acest lucru se întâmplă deoarece GCC nu acceptă pornirea sau ieșirea #pragma. Cu toate acestea, puteți utiliza codul de mai jos pentru rezultatul așteptat pe compilatoarele 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  ;   }   

Ieșire
Inside func1() Inside main() Inside func2()  

În programul de mai sus am folosit câteva sintaxe specifice astfel încât una dintre funcții se execută înaintea funcției principale și cealaltă se execută după funcția principală.

Creați un test