C Pirminiai procesoriai

C Pirminiai procesoriai

Preprocesoriai yra programos, kurios apdoroja šaltinio kodą prieš pradedant faktinį kompiliavimą. Jie nėra kompiliavimo proceso dalis, bet veikia atskirai, todėl programuotojai gali modifikuoti kodą prieš kompiliavimą.

  • Tai pirmasis žingsnis, kurį atlieka C šaltinio kodas, kai jis konvertuojamas į vykdomąjį failą.
  • Pagrindiniai pirminio apdorojimo direktyvų tipai yra  Makrokomandos Failų įtraukimo sąlyginis kompiliavimas ir kitos direktyvos, pvz., #undef #pragma ir kt.
  • Dažniausiai šios direktyvos naudojamos tam tikrą C kodo skyrių pakeisti kitu C kodu. Pavyzdžiui, jei rašome „#define PI 3.14“, tada išankstinis procesorius PI pakeičia 3.14.
C Pirminiai procesoriai

C pirminių procesorių tipai

Visi pirmiau minėti pirminiai procesoriai gali būti suskirstyti į 4 tipus:

Makrokomandos

Makrokomandos naudojami konstantoms apibrėžti arba funkcijoms, kurias pakeičia pirminis procesorius prieš sudarant kodą, kurti. Du pirminiai procesoriai #apibrėžti ir #undef naudojami makrokomandoms kurti ir pašalinti C.

#apibrėžti žetono vertė
#undef žetonas

kur po išankstinio apdorojimo žetonas bus išplėsta iki jos vertė programoje.

Pavyzdys:

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

Išvestis
0 1 2 3 4  

Aukščiau pateiktoje programoje prieš kompiliacijos pradžią žodis LIMIT pakeičiamas 5. Žodis "LIMIT" makrokomandos apibrėžime vadinamas makrokomandos šablonu ir „5“ yra makro išplėtimas.

Pastaba Makrokomandos apibrėžimo pabaigoje nėra kabliataškio (;). Makrokomandų apibrėžimams užbaigti nereikia kabliataškio.

Yra ir tokių Iš anksto nustatytos makrokomandos C kurios yra naudingos teikiant įvairias mūsų programos funkcijas.

Anksčiau apibrėžta makrokomanda gali būti neapibrėžta naudojant #undef išankstinį apdorojimą. Pavyzdžiui, aukščiau pateiktame kode

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


Išvestis:

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

Makrokomandos su argumentais

Argumentus galime perduoti ir makrokomandoms. Šios makrokomandos veikia panašiai kaip funkcijos. Pavyzdžiui

# apibrėžti foo(a b) a + b
#define func(r) r * r

Supraskime tai naudodami 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  ;   }   

Išvestis
Area of rectangle is: 50  

Paaiškinimas: Aukščiau pateiktoje programoje makrokomandą PLOTAS (l b) apibrėžiamas norint apskaičiuoti stačiakampio plotą padauginus jį iš jo ilgis (l) ir plotis (b) . Kada PLOTAS(a b) vadinamas jis plečiasi iki (a * b) o rezultatas apskaičiuojamas ir išspausdinamas.

Prašome kreiptis Makrokomandų tipai C daugiau pavyzdžių ir tipų.

Failo įtraukimas

Failų įtraukimas leidžia įtraukti išorinius failus (antraštės failų bibliotekas ir tt) į dabartinę programą. Paprastai tai daroma naudojant #įtraukti direktyvą, kuri gali apimti ir sistemos, ir vartotojo apibrėžtus failus.

Sintaksė

Yra du būdai įtraukti antraštės failus.

#įtraukti
#įtraukti 'failo pavadinimas'

The ' <' ir '>' skliausteliuose nurodykite kompiliatoriui ieškoti failo standartinis katalogas kol dvigubos kabutės ( ' ' ) nurodykite kompiliatoriui ieškoti antraštės failo šaltinio failo kataloge.

Pavyzdys:

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

Išvestis
Hello World 

Sąlyginis kompiliavimas

Sąlyginis kompiliavimas leidžia įtraukti arba neįtraukti kodo dalių, atsižvelgiant į tam tikras sąlygas. Tai naudinga kuriant konkrečios platformos kodą arba derinant. Yra šios sąlyginės pirminio procesoriaus direktyvos: #if #ifdef #ifndef else #elif ir #endif

Sintaksė

Bendra sąlyginių išankstinių procesorių sintaksė yra tokia:

#jei
// kažkoks kodas
#elifas
// dar kažkoks kodas
#kita
// Dar šiek tiek kodo
#endif

#endif direktyva naudojama uždaryti #if #ifdef ir #ifndef atidarymo direktyvas.

Pavyzdys

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

Išvestis
PI is defined Square is not defined 

Paaiškinimas: Šis kodas naudoja sąlygines išankstinio procesoriaus direktyvas ( #ifdef #elif ir #ifndef ) patikrinti, ar tam tikros makrokomandos ( PI ir Kvadratas ) yra apibrėžti. Kadangi PI yra apibrėžtas, programa spausdina PI yra apibrėžtas Tada patikrina, ar SQUARE neapibrėžtas, ir išspausdina Kvadratas neapibrėžtas “.

Kitos direktyvos

Be pirminių pirminio procesoriaus direktyvų, C taip pat pateikia kitas direktyvas, skirtas valdyti kompiliatoriaus elgseną ir derinimą.

#pragma:

Kompiliatoriui pateikia konkrečias instrukcijas, kaip kontroliuoti jo elgesį. Jis naudojamas norint išjungti įspėjimų rinkinio derinimą ir pan.

Sintaksė

#pragma direktyva

Kai kurios #pragma direktyvos yra aptariamos toliau: 

  1. #pragma paleidimas: Šios direktyvos padeda mums nurodyti funkcijas, kurias reikia vykdyti prieš paleidžiant programą (prieš valdikliui pereinant į main()).
  2. #pragma išeiti : Šios direktyvos padeda mums nurodyti funkcijas, kurias reikia vykdyti prieš pat programos išėjimą (prieš pat valdikliui grįžtant iš main()).

Pavyzdys

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

Išvestis
Inside main()  

Aukščiau pateiktas kodas sukurs išvestį, kaip nurodyta aukščiau, kai jis bus paleistas GCC kompiliatoriuose, o laukiama išvestis buvo:

Numatoma išvestis

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

Taip nutinka todėl, kad GCC nepalaiko #pragma paleidimo ar išėjimo. Tačiau galite naudoti toliau pateiktą kodą numatomam GCC kompiliatorių išėjimui. 

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

Išvestis
Inside func1() Inside main() Inside func2()  

Aukščiau pateiktoje programoje mes panaudojome kai kuriuos specifinės sintaksės kad viena iš funkcijų būtų vykdoma prieš pagrindinę funkciją, o kita – po pagrindinės funkcijos.

Sukurti viktoriną