Preprocesador C ++
Los preprocesadores son las directivas, que dan instrucciones al compilador para preprocesar la información antes de que comience la compilación real.
Todas las directivas de preprocesador comienzan con #, y solo los caracteres de espacio en blanco pueden aparecer antes de una directiva de preprocesador en una línea. Las directivas de preprocesador no son declaraciones de C ++, por lo que no terminan en punto y coma (;).
Ya has visto un #includedirectiva en todos los ejemplos. Esta macro se utiliza para incluir un archivo de encabezado en el archivo de origen.
Hay varias directivas de preprocesador compatibles con C ++ como #include, #define, #if, #else, #line, etc. Veamos las directivas importantes:
El preprocesador #define
La directiva de preprocesador #define crea constantes simbólicas. La constante simbólica se llamamacro y la forma general de la directiva es -
#define macro-name replacement-text
Cuando esta línea aparece en un archivo, todas las apariciones posteriores de macro en ese archivo serán reemplazadas por texto de reemplazo antes de que se compile el programa. Por ejemplo
#include <iostream>
using namespace std;
#define PI 3.14159
int main () {
cout << "Value of PI :" << PI << endl;
return 0;
}
Ahora, hagamos el preprocesamiento de este código para ver el resultado asumiendo que tenemos el archivo de código fuente. Así que compilemos con la opción -E y redirigamos el resultado a test.p. Ahora, si marca test.p, tendrá mucha información y, en la parte inferior, encontrará el valor reemplazado de la siguiente manera:
$gcc -E test.cpp > test.p
...
int main () {
cout << "Value of PI :" << 3.14159 << endl;
return 0;
}
Macros de función
Puede usar #define para definir una macro que tomará el argumento de la siguiente manera:
#include <iostream>
using namespace std;
#define MIN(a,b) (((a)<(b)) ? a : b)
int main () {
int i, j;
i = 100;
j = 30;
cout <<"The minimum is " << MIN(i, j) << endl;
return 0;
}
Si compilamos y ejecutamos el código anterior, esto produciría el siguiente resultado:
The minimum is 30
Compilación condicional
Hay varias directivas que se pueden usar para compilar porciones selectivas del código fuente de su programa. Este proceso se llama compilación condicional.
La construcción del preprocesador condicional es muy parecida a la estructura de selección "si". Considere el siguiente código de preprocesador:
#ifndef NULL
#define NULL 0
#endif
Puede compilar un programa con fines de depuración. También puede activar o desactivar la depuración utilizando una sola macro de la siguiente manera:
#ifdef DEBUG
cerr <<"Variable x = " << x << endl;
#endif
Esto hace que cerrdeclaración que se compilará en el programa si la constante simbólica DEBUG se ha definido antes de la directiva #ifdef DEBUG. Puede usar la declaración #if 0 para comentar una parte del programa de la siguiente manera:
#if 0
code prevented from compiling
#endif
Probemos con el siguiente ejemplo:
#include <iostream>
using namespace std;
#define DEBUG
#define MIN(a,b) (((a)<(b)) ? a : b)
int main () {
int i, j;
i = 100;
j = 30;
#ifdef DEBUG
cerr <<"Trace: Inside main function" << endl;
#endif
#if 0
/* This is commented part */
cout << MKSTR(HELLO C++) << endl;
#endif
cout <<"The minimum is " << MIN(i, j) << endl;
#ifdef DEBUG
cerr <<"Trace: Coming out of main function" << endl;
#endif
return 0;
}
Si compilamos y ejecutamos el código anterior, esto produciría el siguiente resultado:
The minimum is 30
Trace: Inside main function
Trace: Coming out of main function
Los operadores # y ##
Los operadores de preprocesador # y ## están disponibles en C ++ y ANSI / ISO C. El operador # hace que un token de texto de reemplazo se convierta en una cadena rodeada de comillas.
Considere la siguiente definición de macro:
#include <iostream>
using namespace std;
#define MKSTR( x ) #x
int main () {
cout << MKSTR(HELLO C++) << endl;
return 0;
}
Si compilamos y ejecutamos el código anterior, esto produciría el siguiente resultado:
HELLO C++
Veamos cómo funcionó. Es simple entender que el preprocesador de C ++ cambia la línea -
cout << MKSTR(HELLO C++) << endl;
La línea anterior se convertirá en la siguiente línea:
cout << "HELLO C++" << endl;
El operador ## se usa para concatenar dos tokens. Aquí hay un ejemplo:
#define CONCAT( x, y ) x ## y
Cuando CONCAT aparece en el programa, sus argumentos se concatenan y se utilizan para reemplazar la macro. Por ejemplo, CONCAT (HELLO, C ++) se reemplaza por "HELLO C ++" en el programa de la siguiente manera.
#include <iostream>
using namespace std;
#define concat(a, b) a ## b
int main() {
int xy = 100;
cout << concat(x, y);
return 0;
}
Si compilamos y ejecutamos el código anterior, esto produciría el siguiente resultado:
100
Veamos cómo funcionó. Es simple entender que el preprocesador de C ++ transforma:
cout << concat(x, y);
La línea anterior se transformará en la siguiente línea:
cout << xy;
Macros C ++ predefinidas
C ++ proporciona una serie de macros predefinidas que se mencionan a continuación:
No Señor | Macro y descripción |
---|---|
1 | __LINE__ Contiene el número de línea actual del programa cuando se está compilando. |
2 | __FILE__ Contiene el nombre de archivo actual del programa cuando se está compilando. |
3 | __DATE__ Contiene una cadena de formato mes / día / año que es la fecha de la traducción del archivo fuente al código objeto. |
4 | __TIME__ Contiene una cadena con el formato hora: minuto: segundo que es la hora a la que se compiló el programa. |
Veamos un ejemplo para todas las macros anteriores:
#include <iostream>
using namespace std;
int main () {
cout << "Value of __LINE__ : " << __LINE__ << endl;
cout << "Value of __FILE__ : " << __FILE__ << endl;
cout << "Value of __DATE__ : " << __DATE__ << endl;
cout << "Value of __TIME__ : " << __TIME__ << endl;
return 0;
}
Si compilamos y ejecutamos el código anterior, esto produciría el siguiente resultado:
Value of __LINE__ : 6
Value of __FILE__ : test.cpp
Value of __DATE__ : Feb 28 2011
Value of __TIME__ : 18:52:48