==== Lenguaje C: Preprocesador ==== * [[pub:c_prep#directivas_de_preprocesado|Directivas de preprocesado]] * [[pub:c_prep#constantes_simbolicas_y_macros|Constantes simbólicas y macros]] * [[pub:c_prep#directivas_de_compilacion_condicional|Directivas de compilación condicional]] ---- El preprocesador del lenguaje C es un procesador de texto que manipula el fichero fuente, actúa en una __fase previa a la compilación__.\\ * Facilita la programación * Las //instrucciones// en este caso se llaman **directivas** o **directrices de preprocesado** === Directivas de preprocesado === Las directivas o diretrices de preprocesado son instrucciones especiales que __condicionan una parte preliminar en el proceso de compilación completo__ * Formalmente no son parte del lenguaje C * Hay un conjunto de ellas establecidas por el estándar ANSI. Los compiladores suelen incluir algunas particulares * Siempre comienzan con el símbolo «''#''» * Al no ser sentencias de lenguaje C no finalizan con el «'';''» * Sólo pueden ocupar una línea. Para extender una directiva más de una línea, se utiliza el símbolo «''\''» antes del cambio de línea * Pueden colocarse en cualquier parte del fichero fuente, pero sólo actúan a partir de la línea en la que se encuentran Las directivas incluidas en el ANSI C son: #include #define #error #if #elif #else #ifdef #ifndef #endif #undef #line #pragma == #include == Hace que el compilador incluya en el fichero fuente el archivo que se indica, llamado //fichero cabecera// (header file) #include #include "nombrefichero" * ''nombrefichero'' representa el nombre del archivo, con extensión ''.h'' * Si va entre los símbolos ''<>'' el compilador busca el archivo en el directorio del sistema * Si va entre comillas dobles ''""'', el compilador lo busca en el directorio actual o directorio de trabajo == #define == Permite definir constantes simbólicas y macros #define NOMBREMACRO Contenido a sustituir == #undef == Elimina la definición de una constante simbólica o macro previamente definida #undef NOMBREMACRO == #error == Fuerza una parada del compilador en la línea de la directiva presentando el mensaje que sigue a la directiva #error Mensaje a mostrar en pantalla == #line == Fuerza un cambio de valor en las constantes simbólicas ''_LINE_'' y ''_FILE_'' que representan el número de línea y el archivo que está siendo objeto de compilación #line numerolínea “nuevonombrearchivo” == #pragma == Sirve para que cada compilador pueda producir compilaciones particularizadas, de acuerdo con la sintaxis que defina el propio compilador #pragma opciondecompilacion == #if #elif #else #endif #ifdef #ifnde == Son directivas que permiten la compilación condicional de diferentes bloques de código === Constantes simbólicas y macros === == Directiva #define == Permite definir //constantes simbólicas y macros// * Una **constante simbólica** es un identificador que se asocia a una cadena o constante. * Durante el proceso de compilación se sustituye la constante simbólica por la cadena asociada a ésta antes de generar el código #define IDENTIFICADOR cadena o constante * * ''IDENTIFICADOR'' es la etiqueta y se denomina //nombre de macro//. Normalmente se escribe con mayúsculas * ''cadena'' es un conjunto de caracteres o símbolos que sustituirán a //IDENTIFICADOR// siempre que este aparezca en el programa * Una **macro** es un identificador que se asocia a una expresión en la que puede haber elementos reemplazables #define NOMBREMACRO(parámetros) expresión * * ''NOMBREMACRO'' es el identificador o nombre (en mayúsculas) * ''parámetros'' representa una lista de parámetros reemplazables, separados por comas, que forman parte de la macro * ''expresión'' es cualquier expresión válida en C que opere con los ''parámetros'' incluidos en la macro * El compilador sustituye el nombre de la macro por la expresión o sentencia asociada, cambiando los parámetros de la macro por los argumentos que acompañan al nombre de la macro en su llamada * Ejemplo de macro: #define MAYOR(a,b) ((a)>(b)) ? (a) : (b) ... max = MAYOR(dato1, dato2); /* max es igual al mayor de dato1 o dato2 */ * * Es similar a una función en su apariencia * Genera mayor cantidad de código (ocupa más memoria) * En ejecución, es más rápido que una llamada a función (no hay accesos a la pila) * Algunas de las funciones de los compiladores son, en realidad, macros (''getc()'' y ''getchar()'', por ejemplo) * Los parámetros no son variables de ningún tipo. En la sentencia de la macro deben ponerse entre paréntesis para evitar efectos indeseados en la sustitución * En ANSI C hay cinco macros predefinidas * ''_LINE_'' Representa el número de línea que se está compilando en cada momento * ''_FILE_'' Contiene una cadena con el nombre del fichero fuente que se está compilando * ''_DATE_'' Representa la fecha de traducción del código fuente a código objeto en formato "//mes día año//" * ''_TIME_'' Contiene la hora de traducción del código en el formato "//hora:minuto:segundo//" * ''_STDC_'' Contiene la constante decimal 1 si la implementación se ajusta al estándar ANSI === Directivas de compilación condicional === Las **directivas de compilación condicional** permiten la compilación selectiva de partes del fichero fuente * Facilitan la depuración * Permiten personalizar los programas __Tipos__: * Compilación condicionada al valor de una expresión: #if #elif #else #endif * Compilación condicionada a la definición de constantes simbólicas: #ifdef #ifndef #endif * Directivas de compilación condicionada al valor de una expresión: #if expresiónconstante1 secuencia de sentencias 1; #elif expresiónconstante2 secuencia de sentencias 2; #elif expresiónconstante3 ..... #elif expresiónconstanteN secuencia de sentencias N; #else secuencia de sentencias M; #endif * * Los términos ''expresiónconstante'' se evalúan en tiempo de compilación * Pueden incluir operaciones lógicas y relacionales * No pueden incluir variables del programa * Mediante ''secuencia de sentencias X''; se representan múltiples líneas de código en lenguaje C * La directiva ''#elif'' es equivalente a ''#else #if'' * Las directivas ''#else'' y ''#elif'' van asociadas a la ''#if'' más próxima hacia arriba y son opcionales * Directivas de compilación condicionada a la definición de una macro: #ifdef NOMBREMACRO1 secuencia de sentencias 1; #endif #ifndef NOMBREMACRO2 secuencia de sentencias2; #endif * * La ''secuencia de sentencias 1;'' se procesa (compila) si ''NOMBREMACRO1'' está definida previamente * La ''secuencia de sentencias 2;'' se procesa si ''NOMBREMACRO2'' NO está definida previamente * Puede incluirse la directiva ''#else'' como alternativa a las directivas ''#ifdef'' y ''#ifndef'', pero no se permite ''#elif''