logo

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.

ponovi mapu u Javi

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

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