Udemy

Datos sobre macros y preprocesadores en C


Datos sobre macros y preprocesadores en C



En un programa en C, todas las líneas que comienzan con # son procesadas por el preprocesador, que es un programa especial invocado por el compilador. En un término muy básico, el preprocesador toma un programa C y produce otro programa C sin ningún # .
Los siguientes son algunos datos interesantes sobre los preprocesadores en C. 
1) Cuando usamos la directiva include , los contenidos del archivo de encabezado incluido (después del preprocesamiento) se copian en el archivo actual. 
Los corchetes angulares < y > indican al preprocesador que busque en la carpeta estándar donde se encuentran todos los archivos de encabezado. Las comillas dobles " y " indican al preprocesador que busque en la carpeta actual (directorio actual). 
2) Cuando usamos define para una constante, el preprocesador produce un programa en C donde se busca la constante definida y los tokens coincidentes se reemplazan con la expresión dada. Por ejemplo en el siguiente programamax se define como 100.

#include<stdio.h>
#define max 100
int main()
{
    printf("max is %d", max);
    return 0;
}
// Output: max is 100
// Note that the max inside "" is not replaced
3) Las macros pueden tomar funciones como argumentos, los argumentos no se verifican para el tipo de datos. Por ejemplo, la siguiente macro INCREMENTO (x) se puede usar para x de cualquier tipo de datos.

#include <stdio.h>
#define INCREMENT(x) ++x
int main()
{
    char *ptr = "GeeksQuiz";
    int x = 10;
    printf("%s  ", INCREMENT(ptr));
    printf("%d", INCREMENT(x));
    return 0;
}
// Output: eeksQuiz 11
4) Los argumentos macro no se evalúan antes de la expansión macro. Por ejemplo, considere el siguiente programa

#include <stdio.h>
#define MULTIPLY(a, b) a*b
int main()
{
    // The macro is expended as 2 + 3 * 3 + 5, not as 5*8
    printf("%d", MULTIPLY(2+3, 3+5));
    return 0;
}
// Output: 16
El problema anterior se puede resolver usando el siguiente programa

#include <stdio.h>
//here, instead of writing a*a we write (a)*(b)
#define MULTIPLY(a, b) (a)*(b)
int main()
{
    // The macro is expended as (2 + 3) * (3 + 5), as 5*8
    printf("%d", MULTIPLY(2+3, 3+5));
    return 0;
}
//This code is contributed by Santanu
// Output: 40
5) Los tokens pasados ​​a las macros se pueden concatenar usando el operador ## llamado operador Token-Pasting.

#include <stdio.h>
#define merge(a, b) a##b
int main()
{
    printf("%d ", merge(12, 34));
}
// Output: 1234
6) Un token pasado a macro se puede convertir en un literal de cadena usando # antes.

#include <stdio.h>
#define get(a) #a
int main()
{
    // GeeksQuiz is changed to "GeeksQuiz"
    printf("%s", get(GeeksQuiz));
}
// Output: GeeksQuiz
7) Las macros se pueden escribir en varias líneas usando '\'. La última línea no necesita tener '\'.

#include <stdio.h>
#define PRINT(i, limit) while (i < limit) \
                        { \
                            printf("GeeksQuiz "); \
                            i++; \
                        }
int main()
{
    int i = 0;
    PRINT(i, 3);
    return 0;
}
// Output: GeeksQuiz  GeeksQuiz  GeeksQuiz
8) Las macros con argumentos deben evitarse ya que a veces causan problemas. Y las funciones en línea deben preferirse ya que hay una evaluación de parámetros de verificación de tipo en las funciones en línea. A partir de C99 , las funciones en línea también son compatibles con el lenguaje C. 
Por ejemplo, considere el siguiente programa. Desde el primer vistazo, la salida parece ser 1, pero produce 36 como salida.

#define square(x) x*x
int main()
{
  int x = 36/square(6); // Expanded as 36/6*6
  printf("%d", x);
  return 0;
}
// Output: 36
Si usamos funciones en línea, obtenemos el resultado esperado. También el programa dado en el punto 4 anterior puede corregirse utilizando funciones en línea.

inline int square(int x) { return x*x; }
int main()
{
  int x = 36/square(6);
  printf("%d", x);
  return 0;
}
// Output: 1
9) Los preprocesadores también admiten directivas if-else que generalmente se usan para la compilación condicional.

int main()
{
#if VERBOSE >= 2
  printf("Trace Message");
#endif
}
10) Se puede incluir un archivo de encabezado más de una vez directa o indirectamente, esto lleva a problemas de redeclaración de las mismas variables / funciones. Para evitar este problema, como las directivas definidas , ifdef y ifndef se utilizan. 
11) Hay algunas macros estándar que se pueden usar para imprimir el archivo de programa (__FILE__), la fecha de compilación (__DATE__), la hora de compilación (__TIME__) y el número de línea en el código C (__LINE__)

#include <stdio.h>
  
int main()
{
   printf("Current File :%s\n", __FILE__ );
   printf("Current Date :%s\n", __DATE__ );
   printf("Current Time :%s\n", __TIME__ );
   printf("Line Number :%d\n", __LINE__ );
   return 0;
}
  
/* Output:
Current File :C:\Users\GfG\Downloads\deleteBST.c
Current Date :Feb 15 2014
Current Time :07:04:25
Line Number :8 */
12) Podemos eliminar macros ya definidas usando: 
#undef MACRO_NAME

#include <stdio.h>
#define LIMIT 100
int main()
{
   printf("%d",LIMIT);
   //removing defined macro LIMIT
   #undef LIMIT
   //Next line causes error as LIMIT is not defined
   printf("%d",LIMIT);
   return 0;
}
//This code is contributed by Santanu
El siguiente programa se ejecuta correctamente ya que hemos declarado LIMIT como una variable entera después de eliminar la macro LIMIT definida previamente

#include <stdio.h>
#define LIMIT 1000
int main()
{
   printf("%d",LIMIT);
   //removing defined macro LIMIT
   #undef LIMIT
   //Declare LIMIT as integer again
   int LIMIT=1001;
   printf("\n%d",LIMIT);
   return 0;
}
//This code is contributed by Santanu
  
/*Output is :
1000
1001
*/
Otro hecho interesante sobre el uso de macro ( #undef )

#include <stdio.h>
//div function prototype
float div(float, float);
#define div(x, y) x/y
  
int main()
{
//use of macro div
//Note: %0.2f for taking two decimal value after point
printf("%0.2f",div(10.0,5.0));
//removing defined macro div
#undef div
//function div is called as macro definition is removed
printf("\n%0.2f",div(10.0,5.0));
return 0;
}
  
//div function definition
float div(float x, float y){
return y/x;
}
//This code is contributed by Santanu
  
/*Output is :
2.00
0.50
*/

No hay comentarios.