Preprocessori sono programmi che elaborano il codice sorgente prima che inizi la compilazione vera e propria. Non fanno parte del processo di compilazione ma operano separatamente consentendo ai programmatori di modificare il codice prima della compilazione.
- È il primo passaggio che il codice sorgente C attraversa quando viene convertito in un file eseguibile.
- I principali tipi di direttive del preprocessore sono Macro Compilazione condizionale per l'inclusione di file e altre direttive come #undef #pragma ecc.
- Principalmente queste direttive vengono utilizzate per sostituire una determinata sezione di codice C con un altro codice C. Ad esempio, se scriviamo '#define PI 3.14', PI verrà sostituito con 3.14 dal preprocessore.
Tipi di preprocessori C
Tutti i preprocessori di cui sopra possono essere classificati in 4 tipi:
Macro
Macro vengono utilizzati per definire costanti o creare funzioni che vengono sostituite dal preprocessore prima che il codice venga compilato. I due preprocessori #definire E #undef vengono utilizzati per creare e rimuovere macro in C.
#definire valore simbolico
#undef gettone
dove dopo aver preelaborato il gettone verrà ampliato al suo valore nel programma.
che ha inventato la scuola
Esempio:
C#include // Macro Definition #define LIMIT 5 int main(){ for (int i = 0; i < LIMIT; i++) { printf('%d n' i); } return 0; }
Produzione
0 1 2 3 4
Nel programma sopra riportato prima che inizi la compilazione la parola LIMIT viene sostituita con 5. La parola 'LIMITE' nella definizione macro è chiamato modello macro E '5' è l'espansione macro.
Nota Non è presente il punto e virgola (;) alla fine della definizione della macro. Le definizioni delle macro non necessitano di un punto e virgola per terminare.
Ce ne sono anche alcuni Macro predefinite in C che sono utili per fornire varie funzionalità al nostro programma.
convertire la stringa in numero intero
Una macro definita in precedenza può essere annullata utilizzando il preprocessore #undef. Ad esempio nel codice sopra
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; }
Produzione:
./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 inMacro con argomenti
Possiamo anche passare argomenti alle macro. Queste macro funzionano in modo simile alle funzioni. Per esempio
# definire foo(a b) a + b
#define funzione(r) r * r
Cerchiamo di capirlo con un programma:
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; }
Produzione
Area of rectangle is: 50
Spiegazione: Nel programma sopra la macro ZONA(lb) è definito per calcolare l'area di un rettangolo moltiplicando la sua lunghezza (l) E larghezza (b) . Quando ZONA(a b) si chiama si espande a (a*b) e il risultato viene calcolato e stampato.
indice di stringa Java di
Si prega di fare riferimento Tipi di macro in C per ulteriori esempi e tipi.
Inclusione di file
L'inclusione di file consente di includere file esterni (librerie di file di intestazione ecc.) nel programma corrente. Questo viene in genere fatto utilizzando il file #includere direttiva che può includere sia file di sistema che file definiti dall'utente.
Sintassi
Esistono due modi per includere file di intestazione.
#includere
#includere 'nome file'
IL '<' E parentesi '>' dì al compilatore di cercare il file nel file rubrica standard Mentre virgolette doppie ('') indica al compilatore di cercare il file di intestazione nella directory del file sorgente.
Esempio:
C// Includes the standard I/O library #include int main() { printf('Hello World'); return 0; }
Produzione
Hello World
Compilazione condizionale
Compilazione condizionale consente di includere o escludere parti del codice a seconda di determinate condizioni. Ciò è utile per creare codice specifico della piattaforma o per il debug. Esistono le seguenti direttive condizionali del preprocessore: #if #ifdef #ifndef else #elif e #endif
Sintassi
La sintassi generale dei preprocessori condizionali è:
#Se
// del codice
#elif
// altro codice
#altro
// Ancora un po' di codice
#endif
La direttiva #endif viene utilizzata per chiudere le direttive di apertura #if #ifdef e #ifndef.
algoritmi di ricerca
Esempio
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; }
Produzione
PI is defined Square is not defined
Spiegazione: Questo codice utilizza direttive condizionali del preprocessore ( #ifdef #elif e #ifndef ) per verificare se determinate macro ( PI E PIAZZA ) sono definiti. Poiché PI è definito, il programma stampa ' PI è definito ' quindi controlla se QUADRATO non è definito e stampa ' Il quadrato non è definito '.
Altre direttive
Oltre alle direttive primarie del preprocessore, il C fornisce anche altre direttive per gestire il comportamento e il debug del compilatore.
#pragma:
Fornisce istruzioni specifiche al compilatore per controllarne il comportamento. Viene utilizzato per disabilitare gli avvisi, impostare l'allineamento, ecc.
Sintassi
#pragma direttiva
Alcune delle direttive #pragma sono discusse di seguito:
- #avviopragma: Queste direttive ci aiutano a specificare le funzioni che devono essere eseguite prima dell'avvio del programma (prima che il controllo passi a main()).
- #uscitapragma : Queste direttive ci aiutano a specificare le funzioni che devono essere eseguite subito prima dell'uscita del programma (appena prima che il controllo ritorni da main()).
Esempio
altrimenti se JavaC
#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; }
Produzione
Inside main()
Il codice sopra produrrà l'output come indicato sopra quando eseguito su compilatori GCC mentre l'output previsto era:
Risultato previsto
Inside func1() Inside main() Inside func2() Ciò accade perché GCC non supporta l'avvio o l'uscita #pragma. Tuttavia è possibile utilizzare il codice seguente per l'output previsto sui compilatori 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; }
Produzione
Inside func1() Inside main() Inside func2()
Nel programma sopra ne abbiamo utilizzati alcuni sintassi specifiche in modo che una delle funzioni venga eseguita prima della funzione principale e l'altra venga eseguita dopo la funzione principale.
Crea quiz