Macros en C

Iniciado por m@o_614, 14 Febrero 2014, 18:06 PM

0 Miembros y 2 Visitantes están viendo este tema.

m@o_614

Saludos, tengo una duda acerca de cómo se pueden usar unas MACROS en lenguaje C, es posible que el nombre de la MACRO tenga asignado mas de un valor?? por ejemplo:

NOMBRE '#','$','@'


rir3760

Cita de: m@o_614 en 14 Febrero 2014, 18:06 PMes posible que el nombre de la MACRO tenga asignado mas de un valor?? por ejemplo:

NOMBRE '#','$','@'
Las macros son sustituciones de texto, actúan de forma similar a la opción "remplazar" de un editor: donde aparezca el nombre de la macro (como una palabra separada de las demás e ignorando las cadenas literales) esta se sustituye por el texto de remplazamiento y si el resultado es valido depende de donde se realice la expansión.

Por ejemplo:
#include <stdio.h>
#include <stdlib.h>

#define NOMBRES  "Hugo", "Paco", "Luis"

int main(void)
{
   char nombre[][5] = {NOMBRES};

   printf("%s, %s, %s\n", nombre[0], nombre[1], nombre[2]);
   printf("%s, %s, %s\n", NOMBRES);
   printf("%s\n", (NOMBRES));
   
   return EXIT_SUCCESS;
}

En las dos primeras ocurrencias de la macro la coma actúa como un separador mientras que en la ultima es un operador. Solo un ejemplo ilustrativo (utilidad practica: ninguna).

Un saludo
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language

Yoel Alejandro

#2
Así mismo es m@o_614, el preprocesador de C sustituye cada aparición del identificador o nombre de la macro por el texto de reemplazo que haya sido definido. El texto final obtenido es pasado al compilador (obviamente para que lo compile, jeje).

Una aplicación puede ser si tienes un programa donde se define un valor que aparece muchas veces en el mismo. Si quieres cambiar ese parámetro, tendrías que editar manualmente sus apariciones. Por ejemplo, quieres leer un total de digamos 3 enteros dados por el usuario y formar un vector o arreglo con ellos y luego imprimir el valor de dichos elementos:

Código (cpp) [Seleccionar]

#include <stdio.h>
#include <stdlib.h>
 
int main(void)
{
int i, x[3];

/* pedir numeros al usario */
for ( i = 0; i < 3; i++ ) {
printf( "Intro valor %d: ", i+1);
scanf( "%d", &x[i] );
getchar();
}

/* imprimiendo contenido del arreglo */
for ( i = 0; i < 3; i++ ) {
printf( "Valor %d: %d\n", i+1, x[i] );
}

return EXIT_SUCCESS;
}


Observa que el valor "3" aparece tres veces en el código. Si quisieras modificar tu programa para que reciba no 3 sino 5 valores, tendrías que editar en dos líneas diferentes de dicho código. Una alternativa sería definir una constante simbólica N, e indicar que cada aparición suya debe reemplazarse por el valor 3:

Código (cpp) [Seleccionar]

#include <stdio.h>
#include <stdlib.h>
 
#define N 3
 
int main(void)
{
int i, x[N];

/* pedir numeros al usario */
for ( i = 0; i < N; i++ ) {
printf( "Intro valor %d: ", i+1);
scanf( "%d", &x[i] );
getchar();
}

/* imprimiendo contenido del arreglo */
for ( i = 0; i < N; i++ ) {
printf( "Valor %d: %d\n", i+1, x[i] );
}

return EXIT_SUCCESS;
}


Si quieres que el programa reciba 5 valores sólo debes cambiar una línea y poner #define N 5

Las instrucciones #define no van terminadas en punto y coma, puesto que no son instrucciones de asignación de valor a una variable, sino un reemplazo formal de texto en el código fuente.
Saludos, Yoel.
P.D..-   Para mayores dudas, puedes enviarme un mensaje personal (M.P.)

eferion

Cita de: yoel_alejandro en 14 Febrero 2014, 21:07 PM
Las instrucciones #define no van terminadas en punto y coma, puesto que no son instrucciones de asignación de valor a una variable, sino un reemplazo formal de texto en el código fuente.

Una corrección... los defines SI pueden terminar con punto y coma. Sobretodo si los defines se usan para concatenar instrucciones que se van a repetir mucho en el código... aunque eso ya es a gusto del programador.

m@o_614

muchas gracias por sus respuestas una ultima duda, si yo tengo en un switch varios cases que van a realizar las mismas operaciones,por ejemplo:


switch(car)
{
               case '1':
               case '2':
               case '3':
               case '4':
               case '5':
               case '6':
               case '7':
               case '8':
               case '9':
               ........
               ........
               default:
                  printf("Error");
           }
           break;


podria yo juntas los cases 1,2,3,4,5,6,7,8,9 en un solo case, llamado por ejemplo: IDM y que ese IDM fuera una macro que tuviera definida como

#define IDM if(car > 0 && car < 10) para asi poder ahorrarme lineas de codigo, puede una macro contener un condicional (un if en este caso)???

gracias

eferion

Cita de: m@o_614 en 19 Febrero 2014, 03:35 AM
muchas gracias por sus respuestas una ultima duda, si yo tengo en un switch varios cases que van a realizar las mismas operaciones,por ejemplo:


switch(car)
{
               case '1':
               case '2':
               case '3':
               case '4':
               case '5':
               case '6':
               case '7':
               case '8':
               case '9':
               ........
               ........
               default:
                  printf("Error");
           }
           break;


podria yo juntas los cases 1,2,3,4,5,6,7,8,9 en un solo case, llamado por ejemplo: IDM y que ese IDM fuera una macro que tuviera definida como

#define IDM if(car > 0 && car < 10) para asi poder ahorrarme lineas de codigo, puede una macro contener un condicional (un if en este caso)???

gracias

Sinceramente deberías evitar el uso de macros más allá de lo estrictamente necesario.

Usar macros ofusca el código y lo vuelve, normalmente, más ilegible, ya que para comprender el código tienes que "explotar" tú manualmente las macros para intentar adivinar el código resultante.

Además el uso de macros dificulta las tareas de depuración.

En C yo limitaría el uso de macros a:

* Definir valores constantes para no tener que poner los valores "a pelo" en el código
* Para generar código multiplataforma
* Para nada más.