Directivas si. Macro de preprocesador __FILE__. Directivas #if y #endif

#incluir

La directiva #include inserta código de archivo especificado al archivo actual, es decir, simplemente conectando otro archivo, podemos usar sus funciones, clases y variables. Los archivos de encabezado generalmente se encuentran en el directorio actual o en el directorio estándar del sistema.

La inclusión de archivos de encabezado se realiza en tiempo de compilación o como un archivo que forma parte de su proyecto. Esta función depende de la implementación específica de su compilador, por lo que para obtener más información información detallada, profundiza en la configuración de tu compilador.

Si no se encuentra el archivo de inclusión, el proceso de compilación falla con un error.

#definir directiva

La directiva #define toma dos formas:

  • definición de constantes;
  • Definición de macros.
Definición de constantes
#definir valor de token de nombre

Cuando se utiliza una constante nombre - nameToken , será reemplazado por valor , es decir, en términos generales, esta es la misma variable, cuyo valor no se puede cambiar. Veamos un ejemplo del uso de una constante:

#incluir #define TEXTO "Marte" // definición de la constante int main() ( std::cout<< TEXT; return 0; }

Como puedes ver, para acceder al valor de una constante, simplemente usamos su nombre.

Definición de macros parametrizadas

#definir nombreMacros(arg1, arg2, ...) expresión

Por ejemplo, definamos una macro que devolverá el máximo de dos valores.

#define MAX(núm1, núm2) ((núm1) > (núm2)? (núm1): (núm2))

Atención, para definir una macro multilínea, cada línea debe tener un símbolo al final, que le indica al preprocesador que la macro aún no se ha completado.

directiva #undef

La directiva #undef anula una constante o macro de preprocesador definida previamente mediante la directiva #define.

#undef nombreToken

Veamos un ejemplo del uso de la directiva #undef:

#define E 2.71828 // macro previamente definida int sumaE = E + E; // llamando a la macro #undef E // ahora E no es una macro

Normalmente, la directiva #undef se utiliza para eliminar una constante o macro previamente definida de un área pequeña del programa. Esto se hace para que, para todo el programa, la macro o constante permanezca, pero para un área determinada, la misma macro o constante se pueda redefinir. No sería seguro redefinir una constante en todo el programa, pero en un área corta es relativamente seguro. La directiva #undef es la única forma de crear este alcance, ya que el alcance de las macros o constantes se extiende desde #define hasta #undef.

#si directiva

#if valor // código que se ejecutará si el valor es verdadero #elsif valor1 // este código se ejecutará si el valor1 es verdadero #else // código que se ejecutará en caso contrario #endif

La directiva #if verifica si el valor es verdadero y, de ser así, ejecuta el código que viene antes de la directiva #endif de cierre. De lo contrario, el código dentro de #if no se compilará, el compilador lo eliminará, pero esto no afectará código fuente en la fuente.

Tenga en cuenta que #if puede tener directivas #elsif y #else anidadas. A continuación se muestra un código de ejemplo para comentar bloques de código utilizando la siguiente construcción:

#if 0 // código que debe comentarse #endif

Si tiene bloques de código en su programa que contienen comentarios de varias líneas y necesita incluir todo este bloque de código en un comentario, nada funcionará si usa /* comentario multilínea*/ . Otra cosa es la construcción de directivas #if #endif.

directiva #ifdef

#ifdef nameToken // código que se ejecutará si nameToken está definido #else // código que se ejecutará si nameToken no está definido #endif

La directiva #ifdef comprueba si una macro o constante simbólica se ha definido previamente como #define. En caso afirmativo, el compilador incluye en el programa el código que está entre las directivas #ifdef y #else, si no se definió previamente el nameToken, entonces se ejecuta el código entre #else y #endif, o, si no hay #else directiva, el compilador va inmediatamente a # endif. Por ejemplo, la macro __cpp está definida en C++, pero no en C. Puedes usar este hecho para mezclar código C y C++ usando la directiva #ifdef:

#ifdef __cpp // Código C++ #else // Código C #endif

directiva #ifndef

#ifndef nameToken // código que se ejecutará si nameToken no está definido #else // código que se ejecutará si nameToken está definido #endif

La directiva #ifndef comprueba si una macro o una constante simbólica se ha definido previamente como #define. En caso afirmativo, el compilador incluye en el programa el código que está entre las directivas #else y #endif, si el nameToken no fue definido previamente, entonces se ejecuta el código entre #ifndef y #else, o, si no hay #else directiva, el compilador va inmediatamente a # endif. La directiva #ifndef se puede utilizar para incluir archivos de encabezado. si no están conectados, utilice una constante simbólica para hacerlo como indicador de la funcionalidad conectada al proyecto.

Por ejemplo, en archivo de encabezado Hay una interfaz de clase que debe conectarse al proyecto si esta clase no se ha conectado previamente.

#ifndef PRODUCT_H #define PRODUCT_H clase Producto ( // código de clase... ); #endif PRODUCTO_H

En este caso se utiliza uno vacío. carácter constante PRODUCT_H, que sólo se puede definir en un programa junto con la clase Producto. Por lo tanto, si encontramos que la constante PRODUCT_H ya está definida, entonces la clase también lo está, y entonces eliminaremos la redefinición de la clase, lo que puede conducir a un error de anulación.

directiva #error

#error "Este código no debería compilarse"

La directiva #error le permite mostrar un mensaje en la lista de errores de compilación si ocurre el error correspondiente. Esta directiva es más útil cuando se usa en combinación con las directivas #if, #elsif, #else para verificar la compilación si alguna condición no es verdadera. Por ejemplo:

#ifndef __unix__ // __unix__ normalmente es compatible con sistemas Unix #error "Sólo compatible con Unix" #endif

Macro de preprocesador __FILE__

La macro del preprocesador __FILE__ se expande a la ruta completa al archivo actual (fuente). __FILE__ es útil para crear un archivo de registro, generar mensajes de error para programadores y depurar código.

Error int (const char* adrFile, const std::string& erMessage) ( cerr<< "[" << adrFile << "]" << arMessage << endl; } #define LOG(erMessage) error(__FILE__, arMessage) // макрос LOG может быть использован для получения сообщений об ошибках, которые выводятся на стандартный поток ошибок

La macro __FILE__ se usa a menudo junto con la macro __LINE__, que proporciona el número de línea actual.

Macro de preprocesador __LINE__

La macro __LINE__ se expande al número de línea actual en el archivo fuente, como un valor entero. __LINE__ es útil al crear un archivo de registro o generar mensajes de error de número de línea para que los programadores depuren el código.

Error int (int nLine, const std::string& erMessage) (cerr<< "[" << nLine << "]" << erMessage << endl; } #define LOG(erMessage) error(__LINE__, erMessage) // макрос LOG может быть использован для получения сообщений об ошибках, с указанием номеров строк, которые выводятся на стандартный поток ошибок

La macro __LINE__ se usa a menudo junto con la macro __FILE__, que muestra la dirección del archivo fuente actual.

Macro de preprocesador __FECHA__

La macro __DATE__ se expande a la fecha actual (hora de compilación) como [mmm dd aaaa] (por ejemplo, “7 de diciembre de 2012”) como una cadena. __DATE__ se puede utilizar para proporcionar información sobre el tiempo de compilación.

corte<< __DATE__ << endl;

También puede utilizar la macro __TIME__ para obtener el tiempo de compilación actual.

Macro de preprocesador __TIME__

La macro __TIME__ se expande en la hora actual (hora de compilación) en el formato hh:mm:cc en un reloj de 24 horas (por ejemplo, "22:29:12"). La macro __TIME__ se puede utilizar para proporcionar información de tiempo en un punto específico de la compilación.

corte<< __TIME__ << endl;

Macro de preprocesador __TIMESTAMP__

La macro __TIMESTAMP__ se expande en la hora actual (hora de compilación) en el formato Ddd Mmm Fecha hh::mm::ss aaaa, hora en formato de 24 horas:

  • Ddd es la abreviatura de día de la semana.
  • mmm este es el mes abreviado,
  • Fecha: día actual del mes (1-31),
  • yyyy es un año de cuatro dígitos.

Por ejemplo, "viernes 7 de diciembre a las 00:42:53 de 2012". La macro __TIMESTAMP__ se puede utilizar para obtener información de fecha y hora de compilación.

corte<< __TIMESTAMP__ << endl;

También puede usar la macro __TIME__ para obtener la hora de compilación actual y la macro __DATE__ para obtener la fecha.

#directivapragma

Extensión específica del compilador #pragma

La directiva #pragma se utiliza para acceder a extensiones específicas del compilador. Usar la directiva #pragma junto con el token una vez le pide al compilador que incluya el archivo de encabezado solo una vez, sin importar cuántas veces se importe:

#pragma once // archivo de encabezado

En este ejemplo, la directiva #pragma once evita que el archivo se incluya varias veces en el proyecto, es decir, evita la anulación.

La directiva #pragma también se puede utilizar para otros fines; por ejemplo, #pragma se suele utilizar para suprimir advertencias. Por ejemplo, en MVS:

Advertencia #pragma (deshabilitar: 4018)

La directiva #pragma en este ejemplo se usa para suprimir las advertencias 4018. Para usos adicionales de la directiva #pragma, consulte la documentación del compilador.

Operador de macros

#

El operador # coloca un token de texto en una cadena entre comillas. Veamos un ejemplo:

#incluir usando el espacio de nombres estándar; #definir mensaje(s) cout<< "Сообщение: " #s << endl; int main() { message("GunGame"); return 0; }

Se realiza la concatenación de cadenas y la macro del mensaje se expande a cout<< "Сообщение: GunGamen"; . Обратите внимание на то, что операция # должна использоваться совместно с аргументами, так как # ссылается на аргумент.

Operador de macros ##

El operador ## toma dos tokens separados y los pega para formar una macro. El resultado puede ser un nombre de variable, un nombre de clase o cualquier otro identificador. Por ejemplo:

#definir tipo ch##ar tipo a; // la variable a es un tipo de datos char, ya que ch y ar se fusionan en char

Veamos otro ejemplo del uso del operador ##, en el que combinamos dos tokens:

#definir TOKENCONCAT(x,y) x##y

Cuando un programa llama a esta macro, los dos tokens se combinan en uno. La operación ## debe tener dos operandos.

P.D.: Cualquier programa serio debe tener su propia base de datos; normalmente se utilizan los siguientes DBMS para administrar la base de datos: MySQL, MsSQL, PostgreeSQL, Oracle, etc. Al instalar el servidor SQL, el foro en cyberforum.ru será un asistente indispensable para usted. . Haz tus preguntas en este foro, definitivamente te ayudarán a resolver tu problema.

Los archivos de encabezado se incluyen en el texto del programa usando directivas del preprocesador#incluir. Las directivas del preprocesador comienzan con un carácter agudo (#), que debe ser el primer carácter de la línea. El programa que procesa estas directivas se llama preprocesador(En los compiladores modernos, el preprocesador suele ser parte del propio compilador).
La directiva #include incluye el contenido del archivo especificado en el programa. El nombre del archivo se puede especificar de dos maneras:

#incluir #incluir "mi_archivo.h"

Si el nombre del archivo está entre corchetes angulares (<>), se supone que necesitamos algún archivo de encabezado estándar y el compilador busca este archivo en lugares predefinidos. (La forma en que se definen estas ubicaciones varía mucho entre plataformas e implementaciones). Las comillas dobles indican que el archivo de encabezado es un archivo de encabezado personalizado y se busca en el directorio donde se encuentra el código fuente del programa.
El archivo de encabezado también puede contener directivas #include. Por lo tanto, a veces es difícil entender qué archivos de encabezado específicos se incluyen en un código fuente determinado y algunos archivos de encabezado pueden incluirse más de una vez. Esto se puede evitar directivas de preprocesador condicionales. Veamos un ejemplo:

#ifndef BOOKSTORE_H #define BOOKSTORE_H /* contenido del archivo bookstore.h */ #endif

La directiva condicional #ifndef comprueba si el valor de BOOKSTORE_H se ha definido previamente. (BOOKSTORE_H es una constante del preprocesador; dichas constantes generalmente se escriben en letras mayúsculas). El preprocesador procesa las siguientes líneas hasta la directiva #endif. De lo contrario, salta líneas de #ifndef a #endif.
Directiva

#definir LIBRERÍA_H

define la constante del preprocesador BOOKSTORE_H. Al colocar esta directiva inmediatamente después de la directiva #ifndef, podemos asegurarnos de que el contenido del archivo de encabezado bookstore.h se incluirá en el texto fuente solo una vez, sin importar cuántas veces el archivo en sí se incluya en el texto.
Otro ejemplo común de uso de directivas de preprocesador condicionales es incluir información de depuración en el texto del programa. Por ejemplo:

Int principal() ( #ifdef DEBUG cout<< "Начало выполнения main()\n"; #endif string word; vectortexto; while (cin >> palabra) ( #ifdef DEBUG cout<< "Прочитано слово: " << word << "\n"; #endif text.push_back(word); } // ... }

Si la constante DEBUG no está definida, el texto del programa resultante se verá así:

int main() (palabra de cadena; vector texto; mientras (cin >> palabra) ( text.push_back(palabra); ) // ... )

De lo contrario obtendremos:

Int principal() (cout<< "Начало выполнения main()\n"; string word; vectortexto; mientras (cin >> palabra) ( cout<< "Прочитано слово: " << word << "\n"; text.push_back(word); } // ... }

La constante del preprocesador se puede especificar en la línea de comando al llamar al compilador usando la opción -D (esta opción puede tener nombres diferentes en diferentes implementaciones). Para sistemas UNIX, la llamada del compilador con la definición de la constante DEBUG del preprocesador tiene este aspecto:

$CC -DDEBUG principal.C

Hay constantes que el compilador determina automáticamente. Por ejemplo, podemos saber si estamos compilando un programa en C++ o en C. Para un programa C++, la constante __cplusplus (dos guiones bajos) se define automáticamente. Para el estándar C, se define __STDC__. Naturalmente, ambas constantes no se pueden definir simultáneamente.

Ejemplo:

#idfef __cplusplus // compilando un programa C++ extern "C";

// externo "C" explicado en el Capítulo 7 #endif int main(int,int);<< "Ошибка. Файл: " << __FILE__ << " Строка: " << __LINE__ << "element_count не может быть 0";

Otras constantes predefinidas útiles del preprocesador (en este caso, variables) son __LINE__ y __FILE__. La variable __LINE__ contiene el número de la línea actual que se está compilando y __FILE__ es el nombre del archivo que se está compilando. A continuación se muestra un ejemplo de su uso:
Si (element_count == 0) cerr

#incluir

afirmar.h es el archivo de encabezado de la biblioteca estándar de C. Un programa C++ puede hacer referencia a un archivo de encabezado ya sea por su nombre C o por su nombre C++. En la biblioteca estándar de C++, este archivo se llama cassert. El nombre del archivo de encabezado en la biblioteca de C++ difiere del nombre del archivo correspondiente para C en ausencia de la extensión .h y la letra c se coloca al frente (ya se mencionó anteriormente que las extensiones no se usan en los archivos de encabezado para C++, ya que pueden depender de la implementación).
El efecto de utilizar la directiva de preprocesador #include depende del tipo de archivo de encabezado. Instrucciones

#incluir

incluye el contenido del archivo cassert. Pero dado que todos los nombres utilizados en la biblioteca estándar de C++ están definidos en el espacio estándar, el nombre de la afirmación() será invisible hasta que lo hagamos visible explícitamente con la siguiente directiva de uso:

Usando el espacio de nombres std;

Si incluimos en el programa un archivo de cabecera para la biblioteca C

#incluir

entonces no hay necesidad de una directiva de uso: el nombre afirmar() será visible de todos modos.

(Los desarrolladores de bibliotecas utilizan los espacios de nombres para evitar la contaminación global del espacio de nombres. La Sección 8.5 analiza este tema con más detalle). En este artículo continuaremos entendiendo el arte de programar en C++. En este punto de su formación, es hora de familiarizarse con cosas como las directivas del preprocesador. De cara al futuro, diré que en lecciones anteriores ya hemos utilizado la directiva#incluir

, que se utiliza para incluir archivos de encabezado.

Primero, definamos qué es un preprocesador. La compilación de cualquier programa se produce en varias etapas, y una de las primeras es el procesamiento mediante un preprocesador. En términos simples, un preprocesador es un programa que lee el código fuente de un programa y lo modifica según directivas. Esquemáticamente, todo el proceso de construcción de un programa se puede representar de la siguiente manera.

Como puede ver, antes de la compilación, el preprocesador procesa el texto fuente del programa, echemos un vistazo más de cerca a sus instrucciones.

Comencemos con la directiva #include, que es reemplazada por el preprocesador con el contenido del archivo que le sigue. Ejemplo de uso de #include:

#incluir

Si el nombre del archivo está entre corchetes angulares, entonces el preprocesador busca el archivo en una ubicación predefinida. El uso de corchetes dobles implica incluir un archivo del mismo directorio donde se encuentra el código fuente del programa compilado. También vale la pena señalar que los archivos incluidos también pueden contener directivas de preprocesador, en particular la directiva #include, por lo que pueden surgir problemas con múltiples inclusiones del mismo archivo. Para evitar este tipo de confusión, se introdujeron directivas condicionales, veamos un ejemplo de su uso:

#ifndef CUCUMBLER_H

#definir CUCUMBLER_H

/* contenido del archivo cucumbler.h */

La directiva #ifndef verifica si la constante CUCUMBLER_H se ha definido previamente, y si la respuesta es negativa, entonces se realiza la definición de esta constante y otro código que sigue antes de la directiva #endif. Como puedes adivinar, la directiva #define define la constante CUCUMBLER_H. En este caso, dicho fragmento de código ayuda a evitar la inclusión repetida del mismo código, ya que después de la primera inclusión se inicializa la constante CUCUMBLER_H y las comprobaciones posteriores #ifndef CUCUMBLER_H devolverán FALSO.

La directiva #define también se usa ampliamente al depurar un programa.

Comencemos con la directiva #include, que es reemplazada por el preprocesador con el contenido del archivo que le sigue. Ejemplo de uso de #include:

Comencemos con la directiva #include, que es reemplazada por el preprocesador con el contenido del archivo que le sigue. Ejemplo de uso de #include:

Comencemos con la directiva #include, que es reemplazada por el preprocesador con el contenido del archivo que le sigue. Ejemplo de uso de #include:

usando el espacio de nombres estándar;

corte<< "Начало функции main()\n";

vector matriz_texto;

mientras (cin >> texto)

corte<< "Прочитан текст: " << text << "\n";

text_array.push_back(texto);

Si no se especifica la constante IN_DEBUG, el preprocesador generará la siguiente fuente:

Comencemos con la directiva #include, que es reemplazada por el preprocesador con el contenido del archivo que le sigue. Ejemplo de uso de #include:

Comencemos con la directiva #include, que es reemplazada por el preprocesador con el contenido del archivo que le sigue. Ejemplo de uso de #include:

Comencemos con la directiva #include, que es reemplazada por el preprocesador con el contenido del archivo que le sigue. Ejemplo de uso de #include:

usando el espacio de nombres estándar;

vector matriz_texto;

mientras (cin >> texto)

text_array.push_back(texto);

Pero si defines IN_DEBUG, el texto del programa cambiará radicalmente

Comencemos con la directiva #include, que es reemplazada por el preprocesador con el contenido del archivo que le sigue. Ejemplo de uso de #include:

Comencemos con la directiva #include, que es reemplazada por el preprocesador con el contenido del archivo que le sigue. Ejemplo de uso de #include:

Comencemos con la directiva #include, que es reemplazada por el preprocesador con el contenido del archivo que le sigue. Ejemplo de uso de #include:

usando el espacio de nombres estándar;

corte<< "Начало функции main()\n";

vector matriz_texto;

mientras (cin >> texto)

corte<< "Прочитан текст: " << text << "\n";

text_array.push_back(texto);

Puede configurar la constante del preprocesador directamente desde la consola. Por ejemplo, el compilador g++ usa el siguiente formato

Un preprocesador es un programa especial que forma parte del compilador del lenguaje C. Está destinado al procesamiento preliminar del texto del programa. El preprocesador le permite incluir archivos en el texto del programa e ingresar definiciones de macro.
El trabajo del preprocesador se lleva a cabo mediante directivas especiales (instrucciones). Están marcados con un signo de almohadilla #. Al final de las líneas que indican directivas en lenguaje C, no es necesario colocar el punto y coma.

Directivas básicas de preprocesador

#include: inserta texto del archivo especificado
#define: especifica una definición de macro (macro) o una constante simbólica
#undef - deshace la definición anterior
#if: realiza una compilación condicional cuando una expresión constante es verdadera
#ifdef: realiza una compilación condicional cuando se define una constante simbólica
#ifndef: realiza una compilación condicional cuando la constante simbólica no está definida
#else - rama de compilación condicional cuando la expresión es falsa
#elif - rama de compilación condicional formada al fusionar else y if
#endif - fin de la rama de compilación condicional
#line: el preprocesador cambia el número de línea actual y el nombre del archivo compilado
#error: emitiendo un mensaje de diagnóstico
#pragma: una acción que depende de la implementación específica del compilador.

#incluir directiva

La directiva #include le permite incluir un archivo específico en el texto del programa. Si el archivo es una biblioteca estándar y está en la carpeta del compilador, está entre corchetes angulares.<> .
Si el archivo está en el directorio del proyecto actual, se especifica entre comillas "". Para un archivo ubicado en otro directorio, debe especificar la ruta completa entre comillas.

#incluir
#incluir "func.c"

#definir directiva

La directiva #define le permite ingresar constantes y definiciones de macros en el texto del programa.
Formulario de registro general

#define Reemplazo del identificador


Campos Identificador Y Reemplazo separados por uno o más espacios.
La directiva #define le dice al compilador que sustituya la cadena especificada por el argumento Reemplazo, en lugar de cada argumento Identificador en el archivo fuente. Un identificador no se reemplaza si está en un comentario, en una línea o como parte de un identificador más largo.

1
2
3
4
5
6
7
8

#incluir
#definir A 3
int principal()
{
printf("%d + %d = %d", A, A, A+A); // 3 + 3 = 6
getchar();
devolver 0;
}

Dependiendo del valor de la constante, el compilador le asigna un tipo u otro. Puede utilizar sufijos para redefinir el tipo de constante:

  • U o u representa una constante entera en forma sin signo;
  • F (of ) le permite describir una constante real de tipo float ;
  • L (o l) le permite asignar 8 bytes (long int) a una constante entera;
  • L (o l ) le permite describir una constante real de tipo long double

#definir A 280U // int sin firmar
#define B 280LU // int largo sin firmar
#definir C 280 // int (int largo)
#definir D 280L // int largo
#definir K 28.0 // doble
#definir L 28.0F // flotar
#define M 28.0L // doble largo

La segunda forma de sintaxis define una macro similar a una función con parámetros. Este formulario permite una lista opcional de parámetros, que deben aparecer entre paréntesis. Después de definir una macro, cada aparición posterior

identificador(argumento1, ..., argumenton)


reemplazado por la versión del argumento reemplazo, en el que los argumentos reales se sustituyen por argumentos formales.

Ejemplo en C: Calcular el seno de un ángulo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

#incluir
#incluir
#incluir
#definir PI 3.14159265
#definir SIN(x) sin(PI*x/180)
int principal()
{
intc;
sistema("chcp 1251");
sistema("cls");
imprimirf( "Ingrese el ángulo en grados: ");
scanf("%d", &c);
printf("sin(%d)=%lf" , c, SIN(c));
getchar(); getchar();
devolver 0;
}

Resultado de la ejecución

La diferencia entre estas macrodefiniciones y funciones en lenguaje C es que en la etapa de compilación, cada aparición de un identificador se reemplaza por el código correspondiente. Así, un programa puede tener múltiples copias del mismo código correspondiente a un identificador. En el caso de trabajar con funciones, el programa contendrá 1 instancia de código que implementa la función especificada, y cada vez que se acceda a la función, se le transferirá el control.
Puede anular la definición de una macro utilizando la directiva #undef.

Sin embargo, se debe tener cuidado al utilizar este tipo de definiciones de macro, p.

1
2
3
4
5
6
7
8
9
10
11
12
13

#incluir
#definir suma(A,B) A+B
int principal()
{
ent a, b, c, d;
a = 3; segundo = 5;


getchar();
devolver 0;
}


Resultado de la ejecución:


De forma predeterminada, el texto de definición de macro debe estar en una línea. Si desea mover el texto de definición de macro a una nueva línea, coloque una barra invertida al final de la línea actual: \.

1
2
3
4
5
6
7
8
9
10
11
12
13
14

#incluir
#definir suma(A,B) A + \
B
int principal()
{
ent a, b, c, d;
a = 3; segundo = 5;
c = (a + b) * 2; // c = (a + b)*2
d = suma(a, b) * 2; // d = a + b*2;
printf(" a = %d\n b = %d\n", a, b);
printf(" c = %d \n d = %d \n", c, d);
getchar();
devolver 0;
}


Además, la directiva #define le permite reemplazar parte del identificador. ## se utiliza para indicar la pieza que se va a reemplazar.

1
2
3
4
5
6
7
8
9

#incluir
#definir SUMA(x,y) (a##x + a##y)
int principal()
{
int a1 = 5, a2 = 3;
printf("%d", SUMA(1, 2)); // (a1 + a2)
getchar();
devolver 0;
}


Resultado de la ejecución:

Las directivas #if o #ifdef/#ifndef, junto con las directivas #elif, #else y #endif, controlan la compilación de partes del archivo fuente.
Si la expresión especificada después de #if no es cero, el grupo de líneas inmediatamente después de la directiva #if se almacena en el registro de conversión. La sintaxis de una directiva condicional es la siguiente:

1
2
3
4
5
6
7

#si expresión constante
grupo de operaciones
#elif expresión constante
grupo de operaciones
#demás
grupo de operaciones
#endif


La diferencia entre las directivas #ifdef/#ifndef es que una expresión constante solo se puede especificar usando #define.

Cada directiva #if en el archivo fuente debe tener una directiva #endif de cierre correspondiente. Puede aparecer cualquier número de directivas #elif entre las directivas #if y #endif, pero no se permite más de una directiva #else. La directiva #else, si está presente, debe ser la última antes de la directiva #endif.

Ejemplo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

#incluir
#incluir
#definir P 2
int principal()
{
sistema("chcp 1251");
sistema("cls");
#si P==1
imprimirf( "Sucursal 1 en funcionamiento");
#elifP==2
imprimirf( "Rama 2 en progreso, P=%d", PAG);
#demás
imprimirf( "Otra rama se está ejecutando, P=%d", PAG);
#endif
getchar();
devolver 0;
}

Preprocesador Es mejor considerarlo como un programa separado que se ejecuta antes de la compilación. Cuando se ejecuta un programa, el preprocesador escanea el código de arriba a abajo, archivo por archivo, en busca de directivas. Directivas son comandos especiales que comienzan con el símbolo # y NO termine con punto y coma. Existen varios tipos de directivas, que veremos a continuación.

#incluir directiva

Ya has visto la directiva #include en acción. Cuando #incluye un archivo, el preprocesador copia el contenido del archivo incluido en el archivo actual inmediatamente después de la línea #include. Esto es muy útil cuando se utilizan ciertos datos (por ejemplo, funciones) en varios lugares a la vez.

La directiva #include tiene dos formas:

#incluir , que le dice al preprocesador que busque el archivo en las rutas del sistema. Utilizará este formulario con mayor frecuencia cuando se conecte desde las bibliotecas estándar de C++.

#incluir "nombre de archivo", que le dice al preprocesador que busque un archivo en el directorio del proyecto actual. Si no está allí, el preprocesador comenzará a verificar las rutas del sistema y cualquier otra que haya especificado en su configuración. Este formulario se utiliza para incluir archivos de encabezado personalizados.

#definir directiva

La directiva #define se puede utilizar para crear macros. Macro es una regla que determina la conversión de un identificador en datos específicos.

Hay dos tipos principales de macros: macros de funciones y macros de objetos.

Funciones macros se comportan como funciones y se utilizan para los mismos propósitos. No los discutiremos ahora, ya que su uso generalmente se considera peligroso y casi todo lo que pueden hacer se puede hacer con una función simple (lineal).

Macros de objetos puede determinarse de una de las dos formas siguientes:

#definir identificador
#definir identificador texto_sustitución

La definición superior no tiene ningún texto de sustitución, mientras que la inferior sí. Dado que se trata de directivas de preprocesador (y no simples), ninguno de los formularios termina en punto y coma.

Objetos macro con texto_sustitución

Cuando el preprocesador encuentra objetos macro con texto_sustitución, cualquier aparición adicional de identificador se reemplaza con texto_sustitución. El identificador suele escribirse en letras mayúsculas con guiones bajos en lugar de espacios.

Considere el siguiente fragmento de código:

#definir MI_NÚMERO_FAVORITO 9 std::cout<< "My favorite number is: " << MY_FAVORITE_NUMBER << std::endl;

#definir MI_NÚMERO_FAVORITO 9

std::cout<< "My favorite number is: " << MY_FAVORITE_NUMBER << std :: endl ;

El preprocesador convierte el código anterior a:

std::cout<< "My favorite number is: " << 9 << std::endl;

¡Cualquier aparición adicional del identificador USE_YEN se elimina y se reemplaza con "nada" (espacio vacío)!

Esto puede parecer poco útil, pero no es el objetivo principal de este tipo de directivas. A diferencia de las macros de objetos con texto_sustitución, esta forma de macro se considera aceptable para su uso.

Compilación condicional

Las directivas del preprocesador de compilación condicional le permiten determinar bajo qué condiciones se compilará el código y bajo qué condiciones no. En este tutorial veremos sólo tres directivas de compilación condicional:

#ifdef;

#ifndef;

#endif.

directiva #ifdef(Inglés " si definitivamente ined" = "si está definido") permite al preprocesador verificar si el valor estaba #definido previamente. En caso afirmativo, se compilará el código entre #ifdef y #endif. De lo contrario, el código será ignorado. Por ejemplo:

#definir PRINT_JOE #ifdef PRINT_JOE std::cout<< "Joe" << std::endl; #endif #ifdef PRINT_BOB std::cout << "Bob" << std::endl; #endif

#definir PRINT_JOE

#ifdef PRINT_JOE

std::cout<< "Joe" << std :: endl ;

#endif

#ifdef PRINT_BOB

std::cout<< "Bob" << std :: endl ;

#endif

Como PRINT_JOE ya era #define, la línea std::cout<< "Joe" << std::endl; скомпилируется и выполнится. А поскольку PRINT_BOB не был #define, то строчка std::cout << "Bob" << std::endl; не скомпилируется и, следовательно, не выполнится.

directiva #ifndef(Inglés " si norte Antiguo Testamento definición ined" = "si no está definido") es exactamente lo contrario de #ifdef, que permite comprobar si un valor no ha sido definido previamente. Por ejemplo:

#ifndef PRINT_BOB std::cout<< "Bob" << std::endl; #endif

#ifndef PRINT_BOB

std::cout<< "Bob" << std :: endl ;

#endif

El resultado de ejecutar este fragmento de código será Bob, ya que PRINT_BOB nunca antes había sido #define. La compilación condicional se utiliza muy a menudo como protección de encabezado (hablaremos de ello en la próxima lección).

#definir alcance de la directiva

Las directivas se ejecutan antes de compilar el programa: de arriba a abajo, archivo por archivo.

Considere el siguiente programa:

Comencemos con la directiva #include, que es reemplazada por el preprocesador con el contenido del archivo que le sigue. Ejemplo de uso de #include: void boo() ( #define MI_NOMBRE "Alex" ) int main() ( std::cout<< "My name is: " << MY_NAME; return 0; }

Comencemos con la directiva #include, que es reemplazada por el preprocesador con el contenido del archivo que le sigue. Ejemplo de uso de #include:

abucheo vacío()

#define MI_NOMBRE "Alex"

int principal()

std::cout<< "My name is: " << MY_NAME ;

devolver 0;

Aunque la directiva #define MY_NAME "Alex" está definida dentro de la función boo, el preprocesador no lo notará porque no comprende conceptos de C++ como las funciones. Por lo tanto, la ejecución de este programa será idéntica a aquella en la que se definió #define MI_NOMBRE "Alex" ANTES o inmediatamente DESPUÉS de la función boo. Para una mejor legibilidad del código, defina identificadores (usando #define) fuera de las funciones.

Una vez que el preprocesador ha completado su ejecución, se descartan todos los identificadores (definidos con #define) de este archivo. Esto significa que las directivas sólo son válidas desde el punto de su definición hasta el final del archivo en el que están definidas. Las directivas definidas en un archivo de código no afectan las directivas definidas en otros archivos del mismo proyecto.

Considere el siguiente ejemplo:

Comencemos con la directiva #include, que es reemplazada por el preprocesador con el contenido del archivo que le sigue. Ejemplo de uso de #include: void hacer algo() ( #ifdef PRINT std::cout<< "Printing!"; #endif #ifndef PRINT std::cout << "Not printing!"; #endif }

Comencemos con la directiva #include, que es reemplazada por el preprocesador con el contenido del archivo que le sigue. Ejemplo de uso de #include:

anular hacer algo()

#ifdef IMPRIMIR

std::cout<< "Printing!" ;

#endif

#ifndef IMPRIMIR

std::cout<< "Not printing!" ;




Arriba