C Preprocesory

C Preprocesory

Preprocesory jsou programy, které zpracovávají zdrojový kód před začátkem skutečné kompilace. Nejsou součástí procesu kompilace, ale fungují samostatně a umožňují programátorům upravit kód před kompilací.

  • Je to první krok, kterým prochází zdrojový kód C při převodu na spustitelný soubor.
  • Hlavní typy preprocesorových direktiv jsou  Makra Podmíněná kompilace zahrnutí souboru a další direktivy jako #undef #pragma atd.
  • Tyto direktivy se používají hlavně k nahrazení dané části C kódu jiným C kódem. Pokud například napíšeme '#define PI 3.14', pak je PI preprocesorem nahrazeno 3.14.
C Preprocesory

Typy C preprocesorů

Všechny výše uvedené preprocesory lze rozdělit do 4 typů:

Makra

Makra se používají k definování konstant nebo vytváření funkcí, které jsou nahrazeny preprocesorem před kompilací kódu. Dva preprocesory #definovat a #undef se používají k vytváření a odstraňování maker v C.

#definovat hodnota tokenu
#undef žeton

kde po předběžném zpracování žeton bude rozšířena na jeho hodnota v programu.

Příklad:

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

Výstup
0 1 2 3 4  

Ve výše uvedeném programu je před začátkem kompilace slovo LIMIT nahrazeno 5. Slovo 'OMEZIT' v definici makra se nazývá makro šablona a „5“ je makroexpanze.

Poznámka Na konci definice makra není středník (;). Definice maker nepotřebují k ukončení středník.

Jsou tam i nějaké Předdefinovaná makra v C které jsou užitečné při poskytování různých funkcí našemu programu.

Makro definované dříve lze zrušit pomocí #undef preprocessor. Například ve výše uvedeném kódu

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


výstup:

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

Makra S Argumenty

Argumenty můžeme předávat i makrům. Tato makra fungují podobně jako funkce. Například

# definovat foo(a b) a + b
#define func(r) r * r

Pojďme to pochopit pomocí programu:

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

Výstup
Area of rectangle is: 50  

Vysvětlení: Ve výše uvedeném programu makro OBLAST (l b) je definována pro výpočet plochy obdélníku jeho vynásobením délka (l) a šířka (b) . Když OBLAST (a b) se nazývá expanduje na (a * b) a výsledek je spočítán a vytištěn.

Prosím odkažte Typy maker v C pro více příkladů a typů.

Začlenění souboru

Zahrnutí souborů umožňuje zahrnout externí soubory (knihovny souborů záhlaví atd.) do aktuálního programu. To se obvykle provádí pomocí #zahrnout direktiva, která může zahrnovat systémové i uživatelem definované soubory.

Syntax

Existují dva způsoby, jak zahrnout soubory záhlaví.

#zahrnout
#zahrnout 'název souboru'

The ' <' a '>' závorky řekněte kompilátoru, aby hledal soubor v standardní adresář zatímco dvojité uvozovky ( ' ) řekněte kompilátoru, aby hledal hlavičkový soubor v adresáři zdrojového souboru.

Příklad:

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

Výstup
Hello World 

Podmíněná kompilace

Podmíněná kompilace umožňuje zahrnout nebo vyloučit části kódu v závislosti na určitých podmínkách. To je užitečné pro vytváření kódu specifického pro platformu nebo pro ladění. Existují následující podmíněné direktivy preprocesoru: #if #ifdef #ifndef else #elif a #endif

Syntax

Obecná syntaxe podmíněných preprocesorů je:

#li
// nějaký kód
#elif
// nějaký další kód
#jiný
// Ještě nějaký kód
#endif

Direktiva #endif se používá k uzavření #if #ifdef a #ifndef otevírací direktivy.

Příklad

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

Výstup
PI is defined Square is not defined 

Vysvětlení: Tento kód používá podmíněné direktivy preprocesoru ( #ifdef #elif a #ifndef ) zkontrolovat, zda určitá makra ( PI a NÁMĚSTÍ ) jsou definovány. Protože je definováno PI, program vypíše ' PI je definováno ' poté zkontroluje, zda není definován SQUARE a vytiskne ' Čtverec není definován '.

Další směrnice

Kromě direktiv primárního preprocesoru C také poskytuje další direktivy pro správu chování kompilátoru a ladění.

#pragma:

Poskytuje konkrétní instrukce kompilátoru, aby řídil jeho chování. Používá se k deaktivaci nastavení zarovnání varování atd.

Syntax

#pragma směrnice

Některé z direktiv #pragma jsou popsány níže: 

  1. #pragma startup: Tyto direktivy nám pomáhají specifikovat funkce, které je potřeba spustit před spuštěním programu (než řízení přejde na main()).
  2. #pragma exit : Tyto direktivy nám pomáhají specifikovat funkce, které je potřeba spustit těsně před ukončením programu (těsně předtím, než se ovládací prvek vrátí z main()).

Příklad

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

Výstup
Inside main()  

Výše uvedený kód vytvoří výstup, jak je uvedeno výše, když bude spuštěn na kompilátorech GCC, zatímco očekávaný výstup byl:

Očekávaný výstup

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

K tomu dochází, protože GCC nepodporuje spuštění nebo ukončení #pragma. Můžete však použít níže uvedený kód pro očekávaný výstup na kompilátorech 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  ;   }   

Výstup
Inside func1() Inside main() Inside func2()  

Ve výše uvedeném programu jsme některé použili specifické syntaxe tak, že jedna z funkcí se provede před hlavní funkcí a druhá se provede po hlavní funkci.

Vytvořit kvíz