logo

C Preprocessadors

Preprocessadors són programes que processen el codi font abans que comenci la compilació real. No formen part del procés de compilació, però funcionen per separat permetent als programadors modificar el codi abans de la compilació.

  • És el primer pas pel qual passa el codi font C quan es converteix en un fitxer executable.
  • Els principals tipus de directives de preprocessador són  Macros Compilació condicional d'inclusió de fitxers i altres directives com #undef #pragma, etc.
  • Principalment, aquestes directives s'utilitzen per substituir una secció determinada del codi C per un altre codi C. Per exemple, si escrivim '#define PI 3.14', el preprocessador substituirà PI per 3.14.
C Preprocessadors

Tipus de preprocessadors C

Tots els preprocessadors anteriors es poden classificar en 4 tipus:

Macros

Macros s'utilitzen per definir constants o crear funcions que són substituïdes pel preprocessador abans de compilar el codi. Els dos preprocessadors #definir i #undef s'utilitzen per crear i eliminar macros en C.



#definir valor simbòlic
#undef testimoni

on després de preprocessar el testimoni s'ampliarà a la seva valor al programa.

Exemple:

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

Sortida
0 1 2 3 4 

En el programa anterior abans de començar la compilació, la paraula LÍMIT se substitueix per 5. La paraula 'LIMIT' en la definició macro s'anomena plantilla de macro i "5" és l'expansió macro.

base de dades java jdbc

Nota No hi ha punt i coma (;) al final de la definició de macro. Les definicions de macro no necessiten un punt i coma per acabar.

També n'hi ha Macros predefinides en C que són útils per proporcionar diverses funcionalitats al nostre programa.

Una macro definida anteriorment es pot no definir utilitzant el preprocessador #undef. Per exemple, al codi anterior

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


Sortida:

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

Macros amb arguments

També podem passar arguments a macros. Aquestes macros funcionen de manera similar a les funcions. Per exemple

# definir foo(a b) a + b
#definir func(r) r * r

Entenem-ho amb un programa:

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

Sortida
Area of rectangle is: 50 

Explicació: En el programa anterior la macro ÀREA(l b) es defineix per calcular l'àrea d'un rectangle multiplicant-ne longitud (l) i amplitud (b) . Quan ÀREA(a b) s'anomena s'expandeix a (a*b) i el resultat es calcula i s'imprimeix.

Si us plau, consulteu Tipus de macros en C per a més exemples i tipus.

Inclusió de fitxers

La inclusió de fitxers us permet incloure fitxers externs (biblioteca de fitxers de capçalera, etc.) al programa actual. Això es fa normalment amb el #inclou directiva que pot incloure fitxers del sistema i definits per l'usuari.

Sintaxi

Hi ha dues maneres d'incloure fitxers de capçalera.

#inclou
#inclou 'nom de fitxer'

El '<' i '>' claudàtors digueu al compilador que cerqui el fitxer al fitxer directori estàndard mentre cometes dobles ( ' ' ) digueu al compilador que cerqui el fitxer de capçalera al directori del fitxer font.

llista j

Exemple:

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

Sortida
Hello World

Recopilació condicional

Compilació condicional permet incloure o excloure parts del codi en funció de determinades condicions. Això és útil per crear codi específic de la plataforma o per depurar. Hi ha les següents directives de preprocessador condicionals: #if #ifdef #ifndef else #elif i #endif

Sintaxi

La sintaxi general dels preprocessadors condicionals és:

#si
// algun codi
#elif
// una mica de codi més
#una altra cosa
// Una mica de codi més
#endif

La directiva #endif s'utilitza per tancar les directives d'obertura #if #ifdef i #ifndef.

Exemple

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

Sortida
PI is defined Square is not defined

Explicació: Aquest codi utilitza directives de preprocessador condicionals ( #ifdef #elif i #ifndef ) per comprovar si determinades macros ( PI i PLAÇA ) estan definits. Com que PI està definit, el programa imprimeix ' PI està definit " després comprova si QUADRAT no està definit i imprimeix " El quadrat no està definit '.

Altres directives

A part de les directives del preprocessador primari, C també proporciona altres directives per gestionar el comportament del compilador i la depuració.

#pragma:

Proporciona instruccions específiques al compilador per controlar el seu comportament. S'utilitza per desactivar l'alineació del conjunt d'advertiments, etc.

Sintaxi

#pragma directiva

A continuació es comenten algunes de les directrius de #pragma: 

  1. Inici de #pragma: Aquestes directives ens ajuden a especificar les funcions que cal executar abans de l'inici del programa (abans que el control passi a main()).
  2. Sortida del #pragma : Aquestes directives ens ajuden a especificar les funcions que es necessiten per executar-se just abans de sortir del programa (just abans que el control torni de main()).

Exemple

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

Sortida
Inside main() 

El codi anterior produirà la sortida tal com s'ha indicat anteriorment quan s'executi als compiladors GCC mentre la sortida esperada era:

Sortida esperada

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

Això passa perquè GCC no admet l'inici ni la sortida de #pragma. Tanmateix, podeu utilitzar el codi següent per a la sortida esperada als compiladors 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; } 

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

En el programa anterior n'hem utilitzat alguns sintaxis específiques de manera que una de les funcions s'executa abans de la funció principal i l'altra s'executa després de la funció principal.

Crea un qüestionari