Predprocesorji so programi, ki obdelajo izvorno kodo, preden se začne dejansko prevajanje. Niso del procesa prevajanja, ampak delujejo ločeno in programerjem omogočajo, da spremenijo kodo pred prevajanjem.
- To je prvi korak, skozi katerega gre izvorna koda C, ko se pretvori v izvršljivo datoteko.
- Glavne vrste direktiv predprocesorja so Makri Pogojno prevajanje vključitve datoteke in druge direktive, kot je #undef #pragma itd.
- Večinoma se te direktive uporabljajo za zamenjavo danega dela kode C z drugo kodo C. Če na primer napišemo '#define PI 3.14', potem predprocesor PI zamenja s 3.14.
Vrste predprocesorjev C
Vse zgornje predprocesorje lahko razvrstimo v 4 vrste:
Makri
Makri se uporabljajo za definiranje konstant ali ustvarjanje funkcij, ki jih nadomesti predprocesor, preden se koda prevede. Dva predprocesorja #definiraj in #undef se uporabljajo za ustvarjanje in odstranjevanje makrov v C.
#definiraj vrednost žetona
#undef žeton
kjer po predhodni obdelavi žeton bodo razširili na svoje vrednost v programu.
primer:
C#include // Macro Definition #define LIMIT 5 int main(){ for (int i = 0; i < LIMIT; i++) { printf('%d n' i); } return 0; }
Izhod
0 1 2 3 4
V zgornjem programu je pred začetkom prevajanja beseda LIMIT zamenjana s 5. Beseda 'LIMIT' v definiciji makra se imenuje predloga makra in '5' je makro razširitev.
Opomba Na koncu definicije makra ni podpičja (;). Makro definicije ne potrebujejo podpičja na koncu.
Nekaj jih je tudi Vnaprej določeni makri v C ki so uporabni pri zagotavljanju različnih funkcionalnosti našega programa.
Prej definiran makro je lahko nedefiniran s predprocesorjem #undef. Na primer v zgornji kodi
mylivecricketC
#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; }
Izhod:
./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 inMakri z argumenti
Argumente lahko posredujemo tudi makrom. Ti makri delujejo podobno kot funkcije. Na primer
# opredeliti foo(a b) a + b
#define func(r) r * r
Naj to razumemo s programom:
'abc's v številkah'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; }
Izhod
Area of rectangle is: 50
Pojasnilo: V zgornjem programu je makro OBMOČJE (l b) je definiran za izračun ploščine pravokotnika z množenjem njegove dolžina (l) in širina (b) . kdaj OBMOČJE (a b) se imenuje razširi na (a * b) rezultat pa se izračuna in natisne.
Prosimo, glejte Vrste makrov v C za več primerov in tipov.
Vključitev datoteke
Vključitev datotek vam omogoča, da v trenutni program vključite zunanje datoteke (knjižnice datotek glave itd.). To se običajno naredi z uporabo #vključi direktivo, ki lahko vključuje sistemske in uporabniško definirane datoteke.
Sintaksa
Glavne datoteke lahko vključite na dva načina.
#vključi
#vključi 'ime datoteke'
The '<' in oklepaji '>' recite prevajalniku, naj poišče datoteko v standardni imenik medtem ko dvojni narekovaji ( ' ' ) povejte prevajalniku, naj poišče datoteko glave v imeniku izvorne datoteke.
primer:
C// Includes the standard I/O library #include int main() { printf('Hello World'); return 0; }
Izhod
Hello World
Pogojna kompilacija
Pogojna kompilacija omogoča vključitev ali izključitev delov kode glede na določene pogoje. To je uporabno za ustvarjanje kode, specifične za platformo, ali za odpravljanje napak. Obstajajo naslednje direktive pogojnega predprocesorja: #if #ifdef #ifndef else #elif in #endif
Sintaksa
Splošna sintaksa pogojnih predprocesorjev je:
#če
// nekaj kode
#elif
// še nekaj kode
#drugo
// Še nekaj kode
#endif
Direktiva #endif se uporablja za zapiranje odpiralnih direktiv #if #ifdef in #ifndef.
Primer
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; }
Izhod
PI is defined Square is not defined
Pojasnilo: Ta koda uporablja pogojne direktive predprocesorja ( #ifdef #elif in #ifndef ), da preverite, ali so določeni makri ( PI in KVADRAT ) so definirani. Ker je PI definiran, program natisne ' PI je definiran ' nato preveri, če SQUARE ni definiran in natisne ' Kvadrat ni definiran '.
Druge direktive
Poleg primarnih direktiv predprocesorja ponuja C tudi druge direktive za upravljanje vedenja prevajalnika in odpravljanje napak.
#pragma:
Zagotavlja posebna navodila prevajalniku za nadzor njegovega vedenja. Uporablja se za onemogočanje poravnave opozoril itd.
Sintaksa
#pragma direktiva
Nekatere direktive #pragma so obravnavane spodaj:
- #pragma zagon: Te direktive nam pomagajo določiti funkcije, ki se morajo izvajati pred zagonom programa (preden nadzor preide na main()).
- #pragma izhod : Te direktive nam pomagajo določiti funkcije, ki se morajo izvajati tik pred izhodom iz programa (tik preden se krmilnik vrne iz main()).
Primer
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; }
Izhod
Inside main()
Zgornja koda bo proizvedla izhod, kot je naveden zgoraj, ko se izvaja v prevajalnikih GCC, medtem ko je bil pričakovan izhod:
Pričakovani rezultat
markdown slika
Inside func1() Inside main() Inside func2() To se zgodi, ker GCC ne podpira #pragma zagona ali izhoda. Vendar pa lahko uporabite spodnjo kodo za pričakovan rezultat na prevajalnikih 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; }
Izhod
Inside func1() Inside main() Inside func2()
V zgornjem programu smo jih uporabili nekaj posebne sintakse tako da se ena od funkcij izvede pred glavno funkcijo, druga pa za glavno funkcijo.
Ustvari kviz