La macros no son funciones, son sustituciones de texto y estas ocurren antes de que el texto sea compilado. Para explicarlo mejor cualquiera que haya utilizado un editor de texto (el que sea) sabe como funciona la opción para remplazar. Por ejemplo uno puede sustituir todas las instancias de la palabra "negro" por "blanco":
Texto original:
int muy_negro;
int negro;
/* ... */
negro++;
/* ... */
if (negro + negro == muy_negro)
puts("negro, negro entonces muy negro");
/* ... */
Remplazamiento de "negro" por "blanco" resulta en:
int muy_negro;
int blanco;
/* ... */
blanco++;
/* ... */
if (blanco + blanco == muy_negro)
puts("negro, negro entonces muy negro");
/* ... */
Este ejemplo sigue la convención de C: las sustituciones no se realizan si la palabra completa no coincide y el texto de las cadenas literales se ignora.
En el caso de las macros con argumentos se realiza la sustitución y donde se indique un argumento formal (definición de la macro) este se sustituye por el argumento actual (uso de la macro):
/* a y b son los argumentos formales */
#define SUMA(a, b) ((a) + (b))
/* ... */
int x = 1;
int y = 2;
int z;
/* ... */
/* x y y son los argumentos actuales */
z = SUMA(x, y);
Resulta en:
int x = 1;
int y = 2;
int z;
/* ... */
z = ((x) + (y));
Para darte una idea de lo que te piden si el objetivo fuera crear un macro que verifique si un carácter es alfabético en minúsculas podríamos utilizar:
#define es_minuscula(ch) ((ch) >= 'a' && (ch) <= 'z')
/* ... */
char letra = 'j';
if (es_minuscula(letra))
else
Ya que antes de que sea compilado ese texto resulta (debido a la macro) en:
/* ... */
char letra = 'j';
if (((letra) >= 'a' && (letra) <= 'z'))
else
La macro que debes desarrollar es similar.
Un saludo