logo

Preprocessori C

I preprocessori sono programmi che elaborano il codice sorgente prima della compilazione. Sono coinvolti diversi passaggi tra la scrittura di un programma e l'esecuzione di un programma in C. Diamo un'occhiata a questi passaggi prima di iniziare effettivamente a conoscere i preprocessori.

preprocessori in c



Puoi vedere i passaggi intermedi nel diagramma sopra. Il codice sorgente scritto dai programmatori viene prima memorizzato in un file, lasciamo il nome programma.c . Questo file viene quindi elaborato dai preprocessori e viene generato un file di codice sorgente espanso denominato program.i. Questo file espanso viene compilato dal compilatore e viene generato un file di codice oggetto denominato program.obj. Infine, il linker collega questo file di codice oggetto al codice oggetto delle funzioni di libreria per generare il file eseguibile program.exe.

Direttive del preprocessore in C

I programmi del preprocessore forniscono direttive del preprocessore che indicano al compilatore di preelaborare il codice sorgente prima della compilazione. Tutte queste direttive del preprocessore iniziano con un simbolo '#' (hash). Il simbolo '#' indica che qualunque istruzione inizi con un '#' andrà al programma del preprocessore per essere eseguita. Possiamo inserire queste direttive del preprocessore ovunque nel nostro programma.

Esempi di alcune direttive del preprocessore sono: #includere , #definire , #ifndef, eccetera.



che ha inventato la scuola

Nota Ricorda che il # Il simbolo fornisce solo un percorso al preprocessore e un comando come include viene elaborato dal programma del preprocessore. Ad esempio, #include includerà il codice o il contenuto del file specificato nel programma.

Elenco delle direttive del preprocessore in C

La tabella seguente elenca tutte le direttive del preprocessore in C:

Direttive del preprocessore

Descrizione



#definire

Utilizzato per definire una macro

#undef

Utilizzato per indefinire una macro

#includere

Utilizzato per includere un file nel programma del codice sorgente

#ifdef

Utilizzato per includere una sezione di codice se una determinata macro è definita da #define

#ifndef

Utilizzato per includere una sezione di codice se una determinata macro non è definita da #define

#Se

Verificare la condizione specificata

#altro

Codice alternativo che viene eseguito quando #if fallisce

#finisci se

Utilizzato per contrassegnare la fine di #if, #ifdef e #ifndef

Questi preprocessori possono essere classificati in base al tipo di funzione che svolgono.

Tipi di preprocessori C

Esistono 4 tipi principali di direttive del preprocessore:

  1. Macro
  2. Inclusione di file
  3. Compilazione condizionale
  4. Altre direttive

Vediamo ora nel dettaglio ciascuna di queste direttive.

1. Macro

In C, le macro sono pezzi di codice in un programma a cui viene assegnato un nome. Ogni volta che il compilatore incontra questo nome, il compilatore sostituisce il nome con l'effettivo pezzo di codice. IL '#definire' La direttiva viene utilizzata per definire una macro.

Sintassi della definizione di macro

  #define     token     value>

dove dopo la preelaborazione, il gettone verrà ampliato al suo valore nel programma.

Esempio di Macro

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

>

convertire la stringa in numero intero
>

Produzione

0 1 2 3 4>

Nel programma precedente, quando il compilatore esegue la parola LIMIT, la sostituisce 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.

Macro con argomenti

Possiamo anche passare argomenti alle macro. Le macro definite con argomenti funzionano in modo simile alle funzioni.

Esempio

  #define   foo(  a, b  )   a + b  #define func(r) r * r>

Cerchiamo di capirlo con un programma:

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

>

>

Produzione

Area of rectangle is: 50>

Possiamo vedere dal programma precedente che ogni volta che il compilatore trova AREA(l, b) nel programma, la sostituisce con l'istruzione (l*b). Non solo, ma anche i valori passati al modello macro AREA(l, b) verranno sostituiti nell'istruzione (l*b). Pertanto AREA(10, 5) sarà uguale a 10*5.

2. Inclusione di file

Questo tipo di direttiva del preprocessore indica al compilatore di includere un file nel programma del codice sorgente. IL #include la direttiva del preprocessore viene utilizzato per includere i file di intestazione nel programma C.

Esistono due tipi di file che possono essere inclusi dall'utente nel programma:

File di intestazione standard

I file di intestazione standard contengono definizioni di funzioni predefinite come printf(), scanf(), ecc. Questi file devono essere inclusi per funzionare con queste funzioni. Funzioni diverse vengono dichiarate in file header diversi.
Ad esempio, le funzioni I/O standard si trovano nel file 'iostream' mentre le funzioni che eseguono operazioni sulle stringhe si trovano nel file 'string'.

Sintassi

  #include   <  file_name>>

Dove nome del file è il nome del file di intestazione da includere. IL '' parentesi dì al compilatore di cercare il file nella cartella s directory standard.

File di intestazione definiti dall'utente

Quando un programma diventa molto grande, è buona norma dividerlo in file più piccoli e includerli quando necessario. Questi tipi di file sono file di intestazione definiti dall'utente.

Sintassi

  #include   '  filename  '>

IL virgolette ( ) indica al compilatore di cercare il file di intestazione nel file directory del file sorgente.

3. Compilazione Condizionale

Compilazione condizionale nelle direttive C è un tipo di direttiva che aiuta a compilare una parte specifica del programma o a saltare la compilazione di una parte specifica del programma in base ad alcune condizioni. Esistono le seguenti direttive del preprocessore utilizzate per inserire il codice condizionale:

  1. #se Direttiva
  2. Direttiva #ifdef
  3. Direttiva #ifndef
  4. Direttiva #altro
  5. Direttiva #elif
  6. Direttiva #endif

#finisci se La direttiva viene utilizzata per chiudere le direttive di apertura #if, #ifdef e #ifndef, il che significa che la preelaborazione di queste direttive è completata.

Sintassi

indice di stringa Java di
  #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>

Se la macro con il nome ' nome_macro ‘ è definito, il blocco di istruzioni verrà eseguito normalmente, ma se non è definito, il compilatore salterà semplicemente questo blocco di istruzioni.

Esempio

L'esempio seguente dimostra l'uso delle direttive del preprocessore #include #if, #elif, #else e #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;> }>

>

>

Produzione

PI is defined Square is not defined>

4. Altre Direttive

Oltre alle direttive di cui sopra, ce ne sono altre due che non sono comunemente utilizzate. Questi sono:

  1. Direttiva #undef
  2. Direttiva #pragma

1. Direttiva #undef

La direttiva #undef viene utilizzata per annullare la definizione di una macro esistente. Questa direttiva funziona come:

#undef LIMIT>

L'utilizzo di questa istruzione annullerà la definizione della macro LIMIT esistente. Dopo questa istruzione, ogni istruzione #ifdef LIMIT verrà valutata come falsa.

Esempio

algoritmi di ricerca

L'esempio seguente dimostra il funzionamento della Direttiva #undef.

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

>

>

Produzione

Min value is: 10 Min value after undef and again redefining it: 20>

2. Direttiva #pragma

Questa direttiva è una direttiva per scopi speciali e viene utilizzata per attivare o disattivare alcune funzionalità. Questi tipi di direttive sono specifiche del compilatore, ovvero variano da compilatore a compilatore.

Sintassi

#pragma   directive>

Alcune delle direttive #pragma sono discusse di seguito:

  1. #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()).
  2. #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()).

Il programma seguente non funzionerà con i compilatori GCC.

Esempio

Il programma qui sotto illustrare l'uso di #pragma exit e pragma startup

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

>

>

Risultato previsto

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

Il codice sopra produrrà l'output come indicato di seguito quando eseguito su compilatori GCC:

Inside main()c>

Ciò accade perché GCC non supporta l'avvio o l'uscita #pragma. Tuttavia, puoi 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() '>);> }> void> func2()> {> >printf>(>'Inside func2() '>);> }> int> main()> {> >printf>(>'Inside main() '>);> >return> 0;> }>

altrimenti se Java

>

>

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.

Direttiva #pragma avvisa

Questa direttiva viene utilizzata per nascondere il messaggio di avviso visualizzato durante la compilazione. Possiamo nascondere gli avvisi come mostrato di seguito:

  • #pragma avvisa -rvl : Questa direttiva nasconde gli avvisi che vengono generati quando una funzione che dovrebbe restituire un valore non restituisce un valore.
  • #pragma avvisa -par : Questa direttiva nasconde gli avvisi che vengono generati quando una funzione non utilizza i parametri che le vengono passati.
  • #pragma avvisa -rch : Questa direttiva nasconde gli avvisi che vengono generati quando un codice non è raggiungibile. Ad esempio, qualsiasi codice scritto dopo il ritorno l'istruzione in una funzione è irraggiungibile.

Se ti piace techcodeview.com e desideri contribuire, puoi anche scrivere un articolo utilizzando . Guarda il tuo articolo apparire sulla pagina principale di techcodeview.com e aiuta altri geek. Per favore scrivi commenti se trovi qualcosa di sbagliato o se desideri condividere maggiori informazioni sull'argomento discusso sopra.