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.
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 inMakronaredbe 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:
- #pragma pokretanje: Ove nam direktive pomažu odrediti funkcije koje je potrebno pokrenuti prije pokretanja programa (prije nego što kontrola prijeđe na main()).
- #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