logo

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

webdriver

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

convertiți int în șir de caractere java
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:

sincronizare java
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 definedn'); // If PI is not defined check if SQUARE is defined #elif defined(SQUARE)  printf('Square is definedn'); // 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:

bolding în css

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