Preprocesamiento común del preprocesamiento de C
1) Preprocesamiento de uso común:
#include incluye archivos de encabezado
#if expresión condicional
#else else
#elif en caso contrario
#endif expresión condicional final
#ifdef o #if definido Si el símbolo está definido, significa realizar la operación
#ifndef o #if definido significa realizar una operación si el símbolo no está definido. Realizar la operación
#ifndef o #if !definido Si el símbolo no está definido, realizar la operación
#define Definir el símbolo
#undef Eliminar el símbolo
#line Redefine el número de línea actual y el nombre del archivo
#error Genera información de error de compilación y detiene la compilación.
#pragma proporciona funcionalidad específica de la máquina al tiempo que garantiza compatibilidad total con C
2) #include incluye archivos de encabezado en el programa
Los archivos de encabezado generalmente terminan con . h al final, su contenido se puede incluir en el programa usando la directiva de preprocesador #include
Los archivos de encabezado generalmente se incluyen. Prototipos de funciones y variables globales
Los archivos de encabezado suelen tener las dos formas siguientes
#include lt iostreamgt;
#include myheader.h
El primero se usa para hacer referencia a archivos de encabezado de biblioteca estándar y el segundo generalmente se usa para hacer referencia a archivos de encabezado personalizados
El primero se usa para hacer referencia a archivos de encabezado de biblioteca estándar y el segundo generalmente usado para referirse a archivos de encabezado personalizados
Los archivos de encabezado generalmente terminan en .h, y su contenido se puede incluir en el programa usando la directiva de preprocesador #include. El primer compilador <> solo busca el directorio predeterminado que contiene los archivos de encabezado de la biblioteca estándar, mientras que el segundo primero busca el directorio en el que se está compilando el archivo fuente y, si no lo encuentra, busca el directorio predeterminado que contiene los archivos de encabezado de la biblioteca estándar.
Si el archivo de encabezado se coloca en otro directorio, para encontrarlo, la ruta completa desde el archivo fuente hasta el archivo de encabezado debe especificarse entre comillas dobles
3) # definir símbolos y macros de definición
p>
1gt; símbolo
#define PI 3.1415925 //definir símbolo PI es 3.1415925
#undefine PI 3.1415925
#undefine PI 3.1415925 p>
#undefine PI 3.1415925
#undefine PI 3.1415925
#undefine PI 3.1415925
#undefine PI // Cancelar valor de PI
Aquí PI parece una variable, pero no tiene nada que ver con una variable. Es solo un símbolo o bandera. Este símbolo será reemplazado por. un conjunto específico de caracteres antes de compilar el código del programa
3.14159265 no es un valor numérico, es solo una cadena, por lo que no se verificará
Antes de la compilación, el preprocesador atravesará el código y reemplaza el valor definido de la cadena PI (3.14159265) Para los valores de cadena PI que considere significativos
PI en comentarios o cadenas no serán reemplazados
Las constantes simbólicas son generalmente se define mediante #define en el lenguaje C, pero en C es mejor usar const para definir constantes
Combine los parámetros en la declaración con los parámetros en el nombre de la macro
Allí no; hay un símbolo después de la macro
En Print(Var), no puede haber un espacio entre Print y (; de lo contrario (se interpretará como parte de la cadena de reemplazo
#define). Print(Var, dígitos) cout lt;lt; setw(dígitos) lt; (Var) lt; endl
Luego llama a
Print(ival, 15)
El preprocesador lo reemplaza
cout lt;lt;setw(15) lt;lt;(ival) lt;lt;endl;
En todos los casos, se pueden usar funciones en línea en lugar de macros, lo que mejora la verificación de tipos
Templatelt; class Tgt; inline void Print (const Tamp; var, const intamp; digits)
{
coutlt;lt; setw(dígitos)lt ;lt;varlt;lt;endl;
}
Llamadas
Print(ival, 15 );
Requerido cuando se utilizan macros. Tenga en cuenta el error:
# define max(x, y) xgt; y?x: y
Resultado de llamada =; max(myval, 99); Cambiar a resultado = myvalgt; 99?myval: 99; Esto es correcto, no hay problema
Llamar a resultado = max(myval, 99); Cambie a result = myval gt; 99?myval: 99 ; De esta manera, si myvalgt;99 entonces myval se incrementa dos veces, en este caso () es inútil, por ejemplo result=max((x),y) entonces result = (
myval )gt; 99? (myval ): 99 )
Entonces
#define producto(m, n) m*n
Llamar
resultado = producto(5 1, 6); se reemplaza por resultado = 5 1*6;, por lo que producirá resultados incorrectos, debes usar ()
#define producto(m, n). ) (); Reemplazar con resultado = (myval )gt; 99?define producto(m, n) (m)*(n)
Entonces resultado = producto(5 1, 6); = (5 1)*(6); por lo tanto, producirá resultados incorrectos; debe usar () para rodear los parámetros
Conclusión: las funciones en línea se usan a menudo en lugar de macros de preprocesador
Consejo:
1) Agregue comillas alrededor de la variable de reemplazo
#define MYSTR Te amo
cout lt;lt; //Te amo; no te amo
Si
cout lt;lt; MYSTR; //Te amo, entonces generará MYSTR.if
cout lt; lt; #MYSTR; //Te amo, entonces generará MYSTR en lugar de Te amo
Puedes hacer esto
cout lt;lt; generará Te amo, es decir, cout lt; (te amo
2) Conecta múltiples parámetros en una expresión macro
como
p>
Cada expresión macro tiene los siguientes parámetros. p>#define join(a, b) ab Esto no se entenderá como la conexión del valor del parámetro a y el valor del parámetro b, es decir, join(10, 999) no se interpretará como 10999. pero es ab como una cadena, es decir, genera ab
Entonces, puedes
#define join(a, b) a # # b
luego join(10,999) generará 10999
3) Directiva de preprocesador lógico
#if definido CALCAVERAGE o #ifdef CALCAVERAGE
int count=sizeof (data)/sizeof (datos[0]);
for(int i=0; ilt; recuento; i)
promedio = datos;
promedio /= recuento;
#endif
Si se ha definido el símbolo CALCAVERAGE, coloque la declaración entre #if y #endif en el código fuente a compilar. En el código fuente a compilar
Evita duplicar ciertos archivos de encabezado
#ifndef COMPARE_H
#define COMPARE_H Nota: Esto solo define un archivo de encabezado sin valor Símbolo COMPARE_H, la siguiente comparación de espacios de nombres no es el contenido de COMPARE_H.
La definición aquí no es como definir una constante o macro, solo define un símbolo, lo que indica que el símbolo se ha definido, luego tendrá el siguiente contenido de comparación de espacio de nombres{...
comparación de espacio de nombres{
doble máximo(const doble* datos, tamaño int);
doble min(const doble* datos, tamaño int);
}
# endif
compare
#define VERSIÓN \
3
Debido a la existencia del carácter de nueva línea \, el anterior la oración es equivalente a #define VERSIÓN 3
Se puede ver que #define COMPARE_H y la comparación de espacios de nombres son líneas independientes que no están relacionadas entre sí
También se puede usar así
#if bloque1 definido amp ;amp; bloque2 definido
...
#endif
#if CPU==PENTIUM4
...
#endif
#if IDIOMA == INGLÉS
#define Saludo Buenos Días.
#elif IDIOMA == ALEMÁN
#define Saludo Guten Tag.
#elif IDIOMA == FRANCÉS
#define Saludo Bonjour.
#else
# define Saludo Hola.
#endif
std::cout lt;lt;Saludo lt;lt; std::endl;
#if VERSIÓN == 3
...
#elif VERSIÓN == 4
...
#else
...
#endif
5) Macro de preprocesador estándar
__LINE__ El número de línea del código en el archivo fuente actual, entero decimal
__FILE__ El nombre del archivo fuente, forma literal de cadena
__DATE__ La fecha de procesamiento del archivo fuente, forma literal de cadena, el formato es mmm dd aaaaa , donde mmm es el mes, como enero, febrero, etc. dd es 01-31 yyyy es el año de cuatro dígitos
__TIME__ La hora de compilación del archivo fuente, que también es una cadena literal en el formato hh:mm:ss
__STDC__ Según la implementación Esto generalmente se define si las opciones del compilador están configuradas para compilar código C estándar.
Por lo general, se define si la opción del compilador está configurada para compilar código C estándar; de lo contrario, permanece sin definir
Al compilar un programa en C, __cplusplus se define como 199711L
Usar la línea # para modificar la cadena devuelta por __FILE__
Por ejemplo
#line 1000 establece el número de línea actual en 1000
#line 1000 el archivo de programa es modificado por __FILE__ devuelve el cadena, cambie el número de línea a 1000 y cambie el nombre del archivo a archivo de programa
#line __LINE__ el archivo de programa Modifique la cadena devuelta por __FILE__ cambiando el número de línea Por el número de línea del archivo de programa
#line __LINE__ el archivo del programa Modifique la cadena devuelta por __FILE__ cambiando el número de línea a 1000 y el nombre del archivo al nombre del archivo del programa
cout lt;lt;The el programa fue finalmente compilado a las lt;lt;__TIME__
lt;lt; el lt;lt;
lt;endl;
p>6 )#error
En la fase de preprocesamiento, si ocurre un error, la directiva #error puede generar un mensaje de diagnóstico, mostrarlo como un error de compilación y cancelar la compilación
#ifndef __cplusplus
#error Error - Debería ser C
# endif
7)#pragma
se usa especialmente para implementar opciones predefinidas, los resultados se explican en detalle en la documentación del compilador. Cualquier directiva #pragma no reconocida por el compilador será ignorada
8) La macro afirmar()
se declara en el archivo de encabezado de la biblioteca estándar lt;cassertgt;
Se usa para probar expresiones lógicas en programas. Si la expresión lógica es falsa, afirmar() finalizará el programa y mostrará un mensaje de diagnóstico.
Se usa en programas donde se producirán errores importantes cuando no se cumplan las condiciones. , por lo que debe garantizar que las declaraciones posteriores no continúen, por lo que es muy flexible.
Nota: afirmar no es un mecanismo de manejo de errores y los resultados de las expresiones lógicas no deben tener efectos negativos ni estar fuera del control. del programador (por ejemplo, "......").
g., el programa debe proporcionar el código apropiado para manejar
assert(expression);
assert(expression) amp; Las afirmaciones se pueden desactivar usando #define NDEBUG
#include lt;iostream include lt;iostreamgt;
#include lt;cassertgt;
Use std:: cout;
usando std::endl;
int main()
{
int x=0;
int y=0;
coutlt;lt;endl;
for(x=0; xlt;20; x )
{ p>
coutlt;lt;x=lt;lt;xlt;lt;y=lt;lt;ylt;lt;endl;
assert(xlt;y); //Error y terminar ejecución del programa cuando xgt;=y vs.. xlt;y lt;endl;
assert(xlt;y); //Error y finalizar la ejecución del programa cuando.x==y
}
devuelve 0;
}