[C con Clase] macros en C/C++

Jorge Medina jorge en bsdchile.cl
Sab Sep 27 18:41:01 CEST 2008


2008/9/25 Ferran Ferri <ferranferri en gmail.com>:
> Algo que habria que mencionar es el peligro de las macros. Es mucho mejor
> usar funciones inline que las macros. Recuerda que una macro no compruba los
> valores de los parametros, cuando la funcion si lo hace.

si pero la macro es mas optima por lo tanto debes saber decidir cuando
no y cuando si y creo que obviamente usar macros para definir una
funcion que usas tu y no recibe parametros desde un actor externo

> 2008/9/15 Steven Davidson <srd4121 en njit.edu>
>>
>> Hola Leonel,
>>
>> Leonel Florín Selles wrote:
>> > hola amigos:
>> >
>> > bueno les escribo para hacerle una pregunta a la cual le conoscon la
>> > respuesta, pero le conosco la respuesta porque, bueno, es decir,
>> > tengo duda sobre un tema, el cual me lo explicaron, bueno me dijero,
>> > esto es asi y ya, no me explicaron. la cosa es
>> >
>> > las macros son creadas con la directiva de procesador
>> >
>> > #define
>> >
>> > lo que el texto de reemplazo es una operación, la cual puede tener
>> > argumentos o no, me sentro en macros con argumentos, entonces, para
>> > poder pasarle un argumento a la macro tengo que poner () al final
>> > del nombre del identificador de la macro, es decir
>> >
>> > ejemplo:
>> >
>> > #define AREA(b) 3.14 * (x) * (x)
>> >
>>
>> Esta macro no está bien definida. Sospecho que quieres que 'b' sea el
>> parámetro o argumento que es 'x'. La definición debería ser la siguiente:
>>
>> #define AREA(b) 3.14 * (b) * (b)
>>
>> Ahora, cualquier expresión pasada a 'AREA()' como argumento sustituye a
>> 'b'.
>>
>> > y para que funciones
>> >
>> > area = AREA(2);
>> >
>> > ahora, lo que no tengo entendido es, cada vez que valla a pasarle
>> > argumentos a la macro tengo que utilizar esta forma
>> >
>> > #define identificador(variable) ..........
>> >
>>
>> En primer lugar, esto es la definición de la macro. En segundo lugar, no
>> sugiero pensar que son "variables", sino más bien constantes.
>>
>> Para usar la macro, debemos escribir el identificador seguido
>> inmediatamente por la apertura de paréntesis. Si existe algún carácter
>> blanco entre el nombre y el paréntesis, entonces no se considera una
>> macro sino posiblemente una función de C/C++. Por ejemplo,
>>
>> int area = AREA(2);   // usamos la macro AREA()
>>
>> int area = AREA (3);  // no "llamamos" a una macro
>>
>> > y porque......
>> >
>>
>> Todo esto se basa en la gramática establecida por el lenguaje de C y C++.
>>
>> > otra cosa, como sabe #define, que tiene que sustituir a (b) por el
>> > valor 2, si #define lo que hace es sustituri a el identificador que
>> > es la constante simbolica por el texto de reemplazo que son los
>> > simbolos que ponemos despues del identificador en #define.
>> >
>>
>> No veo que el comportamiento de la sustitución que hace el precompilador
>> tenga que ver con la sustitución del argumento 'b'. O sea, lo uno no
>> quita lo otro.
>>
>> El precompilador realiza la sustitución cuando se usa la macro. Por
>> ejemplo, usando mi definición de 'AREA()', tenemos esto:
>>
>> area = AREA(2);
>>
>> El precompilador realiza lo siguiente:
>>
>> area = 3.14 * (b) * (b);
>>
>> A su vez, el precompilador sustituye los 'b' por 2. Esto es,
>>
>> area = 3.14 * (2) * (2);
>>
>> Podrías pensar que existe dos sustituciones, pero el precompilador
>> seguramente hace ambas en un solo paso. El precompilador es muy simple,
>> pero no tan "tonto".
>>
>> > ya probe en el compilador y si no es asi no lo coje, para mi
>> > entender, esto se procesa como si fuera una función al pasarle la
>> > lista de argumentos que tienen que estar encerrado dentro de
>> > parentesis.
>> >
>>
>> No asocies las macros con las funciones de C/C++, porque posiblemente
>> empieces a cometer muchos errores. De hecho, la definición de la macro
>> que nos diste tiene 2 errores: uno ya te lo corregí. El otro error está
>> en que deberías agrupar la definición usando paréntesis. Esto es,
>>
>> #define AREA(b) (3.14 * (b) * (b))
>>
>> Si no haces esto, podemos tener problemas que implican comportamientos
>> muy raros. Por ejemplo,
>>
>> res = 5 / AREA(3);
>>
>> Sin los paréntesis, obtendríamos lo siguiente:
>>
>> res = 5 / 3.14 * (3) * (3);
>>
>> El problema es que se hará la división primero y luego las
>> multiplicaciones. Sin embargo, esto no es lo que queremos. Con los
>> paréntesis, sí conseguimos dividir 5 entre el resultado de 'AREA()'.
>> Esto es,
>>
>> res = 5 / (3.14 * (3) * (3));
>>
>> Lo mismo sucede con esta condición:
>>
>> int x;
>> ...
>> // Si el área es 0
>> if( !AREA(x) )  ...
>>
>> Sin los paréntesis, acabaríamos con lo siguiente:
>>
>> if( !3.14 * (x) * (x) )  ...
>>
>> El operador ! tiene mayor precedencia que las multiplicaciones. Esto es
>> muy diferente a lo que queremos. Usando paréntesis, logramos nuestro
>> objetivo:
>>
>> if( !(3.14 * (x) * (x)) )  ...
>>
>> > bueno, yo se que eso es asi por regla, y lo comprendo y lo utilizo,
>> > pero alguien tiene una explicación mejor.
>> >
>>
>> No sé que otra explicación quieres que haya. Si preguntas acerca de la
>> lógica que sigue el preprocesador para llevar a cabo la sustitución o,
>> como se suele decir, la expansión, entonces sinceramente no hay una
>> respuesta exacta, ya que un preprocesador puede ser diferente a otro. Lo
>> que sí tienen en común es el resultado de las expansiones.
>>
>> Ten presente que el preprocesador modifica el código fuente;
>> básicamente, reprograma tu programa. Como el código fuente no es más que
>> un fichero de texto, el preprocesador se basa en manejar caracteres y
>> cadenas de caracteres. La definición de la macro es una mera cadena que
>> el preprocesador guarda en su programa. Lo normal es que el
>> preprocesador tiene una tabla de símbolos y definiciones. Por ejemplo,
>>
>>  Símbolo |    Definición    | Argumentos
>> ---------+------------------+------------
>>   AREA   | 3.14 * (b) * (b) |      b
>>
>>
>> Espero que esto te oriente y sea lo que nos has pedido.
>>
>> Steven
>>
>>
>> _______________________________________________
>> Lista de correo Cconclase Cconclase en listas.conclase.net
>> http://listas.conclase.net/mailman/listinfo/cconclase_listas.conclase.net
>> Bajas: http://listas.conclase.net/index.php?gid=2&mnu=FAQ
>
>
> _______________________________________________
> Lista de correo Cconclase Cconclase en listas.conclase.net
> http://listas.conclase.net/mailman/listinfo/cconclase_listas.conclase.net
> Bajas: http://listas.conclase.net/index.php?gid=2&mnu=FAQ
>



-- 
Jorge Andrés Medina Oliva.
Evolve or die!




Más información sobre la lista de distribución Cconclase