Preprocesory to programy przetwarzające kod źródłowy przed kompilacją. Pomiędzy napisaniem programu a wykonaniem programu w C składa się z kilku kroków. Przyjrzyjmy się tym krokom, zanim zaczniemy poznawać preprocesory.

Etapy pośrednie można zobaczyć na powyższym schemacie. Kod źródłowy napisany przez programistów jest najpierw przechowywany w pliku, niech tak zostanie nazwana program.c . Plik ten jest następnie przetwarzany przez preprocesory i generowany jest rozszerzony plik kodu źródłowego o nazwie program.i. Ten rozwinięty plik jest kompilowany przez kompilator i generowany jest plik kodu obiektowego o nazwie program.obj. Na koniec linker łączy ten plik kodu obiektowego z kodem wynikowym funkcji bibliotecznych w celu wygenerowania pliku wykonywalnego program.exe.
Dyrektywy preprocesora w C
Programy preprocesora udostępniają dyrektywy preprocesora, które nakazują kompilatorowi wstępne przetworzenie kodu źródłowego przed kompilacją. Wszystkie te dyrektywy preprocesora zaczynają się od symbolu „#” (hash). Symbol „#” oznacza, że instrukcja rozpoczynająca się od „#” zostanie skierowana do programu preprocesora w celu wykonania. Możemy umieścić te dyrektywy preprocesora w dowolnym miejscu naszego programu.
Przykładami niektórych dyrektyw preprocesora są: #włączać , #definiować , #ifndef, itp.
Notatka Pamiętaj, że # symbol zapewnia jedynie ścieżkę do preprocesora, a polecenie takie jak include jest przetwarzane przez program preprocesora. Na przykład #include uwzględni kod lub zawartość określonego pliku w programie.
Lista dyrektyw preprocesora w C
Poniższa tabela zawiera listę wszystkich dyrektyw preprocesora w języku C:
| Dyrektywy preprocesora | Opis |
|---|---|
| #definiować | Służy do definiowania makra |
| #undef | Służy do cofania definicji makra |
| #włączać | Służy do dołączania pliku do kodu źródłowego programu |
| #ifdef | Służy do dołączania sekcji kodu, jeśli określone makro jest zdefiniowane przez #define |
| #ifndef | Służy do dołączania sekcji kodu, jeśli określone makro nie jest zdefiniowane przez #define |
| #Jeśli | Sprawdź określony warunek |
| #w przeciwnym razie | Alternatywny kod, który jest wykonywany, gdy #if zakończy się niepowodzeniem |
| #endif | Używane do oznaczania końca #if, #ifdef i #ifndef |
Te preprocesory można sklasyfikować na podstawie rodzaju wykonywanej funkcji.
Rodzaje preprocesorów C
Istnieją 4 główne typy dyrektyw preprocesora:
- Makra
- Dołączenie pliku
- Kompilacja warunkowa
- Inne dyrektywy
Przyjrzyjmy się teraz szczegółowo każdej z tych dyrektyw.
1. Makra
W języku C makra są fragmentami kodu programu, któremu nadano jakąś nazwę. Ilekroć kompilator napotyka tę nazwę, kompilator zastępuje ją rzeczywistym fragmentem kodu. The '#definiować' dyrektywa służy do definiowania makra.
Składnia definicji makra
#define token value>
gdzie po wstępnej obróbce, znak zostanie rozszerzony do swojego wartość w programie.
Przykład Makro
C
// C Program to illustrate the macro> #include> // macro definition> #define LIMIT 5> int> main()> {> >for> (>int> i = 0; i printf('%d
', i); } return 0; }> |
subskrypcja lazurowa
>
>Wyjście
0 1 2 3 4>
W powyższym programie, gdy kompilator wykonuje słowo LIMIT, zastępuje je liczbą 5. Słowo 'LIMIT' w definicji makro nazywa się szablonem makra I „5” to ekspansja makro.
Notatka Na końcu definicji makra nie ma średnika (;). Definicje makr nie wymagają średnika na końcu.
Są też tacy Predefiniowane makra w C które są przydatne w zapewnianiu różnych funkcjonalności naszego programu.
Makra z argumentami
Możemy także przekazywać argumenty do makr. Makra definiowane za pomocą argumentów działają podobnie do funkcji.
Przykład
#define foo( a, b ) a + b #define func(r) r * r>
Rozumiemy to za pomocą programu:
C
// C Program to illustrate function like macros> #include> // macro with parameter> #define AREA(l, b) (l * b)> int> main()> {> >int> l1 = 10, l2 = 5, area;> >area = AREA(l1, l2);> >printf>(>'Area of rectangle is: %d'>, area);> >return> 0;> }> |
Java konwertuje na ciąg
>
>Wyjście
Area of rectangle is: 50>
Z powyższego programu widać, że ilekroć kompilator znajdzie w programie AREA(l, b), zastępuje go instrukcją (l*b). Nie tylko to, ale wartości przekazane do szablonu makra AREA(l, b) również zostaną zastąpione w instrukcji (l*b). Zatem POLE(10, 5) będzie równe 10*5.
2. Dołączenie pliku
Ten typ dyrektywy preprocesora mówi kompilatorowi, aby umieścił plik w kodzie źródłowym programu. The #include dyrektywa preprocesora służy do dołączania plików nagłówkowych do programu C.
Istnieją dwa typy plików, które użytkownik może zawrzeć w programie:
Standardowe pliki nagłówkowe
Standardowe pliki nagłówkowe zawierają definicje predefiniowanych funkcji, takich jak printf(), scanf(), itp. Aby móc korzystać z tych funkcji, należy dołączyć te pliki. Różne funkcje są deklarowane w różnych plikach nagłówkowych.
Na przykład standardowe funkcje we/wy znajdują się w pliku „iostream”, natomiast funkcje wykonujące operacje na łańcuchach znaków znajdują się w pliku „string”.
Składnia
#include < file_name>>
Gdzie Nazwa pliku to nazwa pliku nagłówkowego, który ma zostać dołączony. The „nawiasy”. powiedz kompilatorowi, aby szukał pliku w s katalog standardowy.
Zdefiniowane przez użytkownika pliki nagłówkowe
Kiedy program staje się bardzo duży, dobrą praktyką jest podzielenie go na mniejsze pliki i dołączenie ich w razie potrzeby. Tego typu pliki to pliki nagłówkowe zdefiniowane przez użytkownika.
Składnia
#include ' filename '>
The podwójne cudzysłowy ( ) powiedz kompilatorowi, aby wyszukał plik nagłówkowy w katalog pliku źródłowego.
3. Kompilacja warunkowa
Kompilacja warunkowa w dyrektywach C to rodzaj dyrektywy, która pomaga skompilować określoną część programu lub pominąć kompilację określonej części programu w oparciu o pewne warunki. Istnieją następujące dyrektywy preprocesora używane do wstawiania kodu warunkowego:
- #if dyrektywa
- Dyrektywa #ifdef
- Dyrektywa #ifndef
- #else Dyrektywa
- Dyrektywa #elif
- Dyrektywa #endif
#endif Dyrektywa służy do zamykania dyrektyw otwierających #if, #ifdef i #ifndef, co oznacza, że wstępne przetwarzanie tych dyrektyw zostało zakończone.
Składnia
#ifdef macro_name // Code to be executed if macro_name is defined # ifndef macro_name // Code to be executed if macro_name is not defined #if constant_expr // Code to be executed if constant_expression is true #elif another_constant_expr // Code to be excuted if another_constant_expression is true #else // Code to be excuted if none of the above conditions are true #endif>
Jeżeli makro o nazwie „ nazwa_makra ' jest zdefiniowany, wówczas blok instrukcji zostanie wykonany normalnie, ale jeśli nie zostanie zdefiniowany, kompilator po prostu pominie ten blok instrukcji.
Przykład
Poniższy przykład ilustruje użycie dyrektyw preprocesora #include #if, #elif, #else i #endif.
C
//program to demonstrates the use of #if, #elif, #else,> // and #endif preprocessor directives.> #include> // defining PI> #define PI 3.14159> int> main()> {> > #ifdef PI> >printf>(>'PI is defined
'>);> > #elif defined(SQUARE)> >printf>(>'Square is defined
'>);> #else> >#error 'Neither PI nor SQUARE is defined'> #endif> > #ifndef SQUARE> >printf>(>'Square is not defined'>);> #else> >cout <<>'Square is defined'> << endl;> #endif> >return> 0;> }> |
>
>Wyjście
PI is defined Square is not defined>
4. Inne dyrektywy
Oprócz powyższych dyrektyw istnieją jeszcze dwie dyrektywy, które nie są powszechnie stosowane. To są:
- Dyrektywa #undef
- Dyrektywa #pragma
1. Dyrektywa #undef
Dyrektywa #undef służy do cofania definicji istniejącego makra. Dyrektywa ta działa jako:
#undef LIMIT>
Użycie tej instrukcji spowoduje anulowanie definicji istniejącego makra LIMIT. Po tej instrukcji każda instrukcja #ifdef LIMIT będzie oceniana jako fałszywa.
Przykład
Poniższy przykład ilustruje działanie dyrektywy #undef.
lista czcionek gimp
C
#include> // defining MIN_VALUE> #define MIN_VALUE 10> int> main() {> >// Undefining and redefining MIN_VALUE> printf>(>'Min value is: %d
'>,MIN_VALUE);> > //undefining max value> #undef MIN_VALUE> > // again redefining MIN_VALUE> #define MIN_VALUE 20> >printf>(>'Min value after undef and again redefining it: %d
'>, MIN_VALUE);> >return> 0;> }> |
>
>Wyjście
Min value is: 10 Min value after undef and again redefining it: 20>
2. Dyrektywa #pragma
Ta dyrektywa jest dyrektywą specjalnego przeznaczenia i służy do włączania lub wyłączania niektórych funkcji. Tego typu dyrektywy są specyficzne dla kompilatora, tj. różnią się w zależności od kompilatora.
Składnia
#pragma directive>
Niektóre z dyrektyw #pragma omówiono poniżej:
- #pragma uruchomienie: Dyrektywy te pomagają nam określić funkcje, które są potrzebne do uruchomienia przed uruchomieniem programu (zanim kontrola przejdzie do main()).
- #pragma wyjście : Te dyrektywy pomagają nam określić funkcje, które są potrzebne do uruchomienia tuż przed zakończeniem programu (tuż przed powrotem sterowania z funkcji main()).
Poniższy program nie będzie działał z kompilatorami GCC.
Przykład
Poniższy program zilustruj użycie wyjścia #pragma i uruchomienia pragmy
C
// C program to illustrate the #pragma exit and pragma> // startup> #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()
'>); }> void> func2() {>printf>(>'Inside func2()
'>); }> // driver code> int> main()> {> >void> func1();> >void> func2();> >printf>(>'Inside main()
'>);> >return> 0;> }> |
>
>
Oczekiwany wynik
Inside func1() Inside main() Inside func2()>
Powyższy kod wygeneruje dane wyjściowe podane poniżej, gdy zostanie uruchomiony na kompilatorach GCC:
Inside main()c>
Dzieje się tak, ponieważ GCC nie obsługuje uruchamiania lub zamykania #pragma. Możesz jednak użyć poniższego kodu dla oczekiwanych wyników w kompilatorach GCC.
znak do int Java
C
#include> void> func1();> void> func2();> void> __attribute__((constructor)) func1();> void> __attribute__((destructor)) func2();> void> func1()> {> >printf>(>'Inside func1()
'>);> }> void> func2()> {> >printf>(>'Inside func2()
'>);> }> int> main()> {> >printf>(>'Inside main()
'>);> >return> 0;> }> |
>
>Wyjście
Inside func1() Inside main() Inside func2()>
W powyższym programie użyliśmy niektórych specyficzne składnie tak, że jedna z funkcji jest wykonywana przed funkcją główną, a druga po funkcji głównej.
#pragma ostrzega dyrektywę
Ta dyrektywa służy do ukrycia komunikatu ostrzegawczego wyświetlanego podczas kompilacji. Możemy ukryć ostrzeżenia, jak pokazano poniżej:
- #pragma ostrzegaj -rvl : Ta dyrektywa ukrywa ostrzeżenia, które są wywoływane, gdy funkcja, która powinna zwracać wartość, nie zwraca wartości.
- #pragma ostrzegaj -par : Ta dyrektywa ukrywa ostrzeżenia, które są generowane, gdy funkcja nie korzysta z przekazanych jej parametrów.
- #pragma ostrzegaj -rch : Ta dyrektywa ukrywa ostrzeżenia, które są generowane, gdy kod jest nieosiągalny. Na przykład dowolny kod napisany po powrót instrukcja w funkcji jest nieosiągalna.
Jeśli podoba Ci się techcodeview.com i chciałbyś wnieść swój wkład, możesz także napisać artykuł za pomocą . Zobacz, jak Twój artykuł pojawia się na stronie głównej techcodeview.com i pomóż innym Geekom. Napisz komentarz, jeśli znajdziesz coś nieprawidłowego lub jeśli chcesz podzielić się więcej informacjami na temat omówiony powyżej.