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.
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 inMakra 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 * rPojď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ýstupArea of rectangle is: 50Vysvě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 #includeint main () { printf ( 'Hello World' ); return 0 ; }
VýstupHello WorldPodmí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
#endifDirektiva #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ýstupPI is defined Square is not definedVysvě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:
- #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()).
- #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#includevoid 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ýstupInside 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#includevoid 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ýstupInside 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