Define y macros en C: ejercicio resuelto

Define y macros en C: ejercicio resuelto

Si buscas #define y macros en C ejercicio resuelto, aquí tienes los patrones más usados: constantes simbólicas, macros con parámetros y una macro SWAP segura con el truco del do { } while (0).

Las macros de preprocesador se expanden antes de compilar: no generan código de función ni tienen tipo, lo que las hace muy rápidas pero también peligrosas si no se usan con cuidado.

Enunciado

Implementa y usa las siguientes macros:

  • PI: constante con el valor de π.
  • CUADRADO(x): eleva x al cuadrado.
  • MAX(a, b): devuelve el mayor de dos valores.
  • SWAP(T, a, b): intercambia dos variables del tipo T.

Solución en C

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>

#define PI 3.14159
#define CUADRADO(x)    ((x) * (x))
#define MAX(a, b)      ((a) > (b) ? (a) : (b))
#define SWAP(T, a, b)  do { T _tmp = (a); (a) = (b); (b) = _tmp; } while (0)

int main(void) {
    double r = 3.0;
    printf("Area del circulo (r=%.1f): %.5f\n", r, PI * CUADRADO(r));
    printf("CUADRADO(5)   = %d\n", CUADRADO(5));
    printf("MAX(7, 3)     = %d\n", MAX(7, 3));

    int x = 10, y = 20;
    SWAP(int, x, y);
    printf("Tras SWAP: x=%d, y=%d\n", x, y);

    return 0;
}

Resultado esperado

1
2
3
4
Area del circulo (r=3.0): 28.27431
CUADRADO(5)   = 25
MAX(7, 3)     = 7
Tras SWAP: x=20, y=10

Errores frecuentes

  • No rodear los parámetros de la macro con paréntesis: CUADRADO(1+2) sin paréntesis se expande a 1+2 * 1+2 = 5 en lugar de 9.
  • No usar do { } while (0) en macros de varias sentencias: sin ello, un if sin llaves puede no ejecutar todas las sentencias de la macro.
  • Crear efectos secundarios al pasar expresiones con ++ o llamadas a función: MAX(f(), g()) evalúa los argumentos dos veces.
  • Confundir #define con const: const tiene tipo y ámbito; #define es texto literal sin ninguno de los dos.

Aplicación práctica

#define se usa para constantes de configuración (tamaños de buffer, máscaras de bits), macros de depuración (DEBUG_PRINT) y abstracciones mínimas que evitan la sobrecarga de llamada a función en rutas críticas de rendimiento.

Siguiente ejercicio recomendado

Práctica guiada y libro completo

Si quieres una ruta completa con progresión real de dificultad:

FAQ

¿Por qué rodear los parámetros de una macro con paréntesis?

Porque las macros son sustitución de texto. Sin paréntesis, CUADRADO(1+2) se convierte en 1+2 * 1+2 por precedencia de operadores, dando 5 en lugar de 9. Con paréntesis: ((1+2) * (1+2)) = 9.

¿Qué diferencia hay entre #define PI 3.14 y const double PI = 3.14?

#define es una sustitución de texto sin tipo ni ámbito; no aparece en el depurador. const double tiene tipo, ámbito de bloque y es visible en el depurador. En C moderno se prefiere const o enum para constantes con nombre.

¿Para qué sirve el do { } while (0) en macros de varias sentencias?

Permite usar la macro como una sentencia normal: if (cond) SWAP(int, a, b); else .... Sin ese envoltorio, solo la primera sentencia de la macro quedaría bajo el if.