rubixibuc
Ejemplo
#define Echo(a) a
#define Echo(a) (a)
Me doy cuenta de que probablemente no haya una diferencia significativa aquí, pero ¿por qué querrías incluir el a
entre paréntesis dentro del cuerpo de la macro? ¿Cómo lo altera?
cnicutar
Supongamos que tienes
#define mul(x, y) x * y
¿Qué pasa si digo:
mul(a + 5, 6); /* a + 5 * 6 */
Ahora, si cambio ligeramente la macro:
#define mul(x, y) ((x) * (y))
mul(a + 5, 6); /* ((a + 5) * (6)) */
Recuerde, los argumentos no se evalúan ni nada, solo se realiza la sustitución textual.
EDITAR
Para obtener una explicación sobre cómo tener la macro completa entre paréntesis, consulte el enlace publicado por Nate CK.
-
Gracias, estaba confundido porque en el libro que estoy usando, la forma en que los usaron parecía redundante. Tenían algo como esto foo(bar) (bar)->algo, ¿serían necesarios aquí?
– rubixibuc
25 de agosto de 2011 a las 7:30
-
probablemente te refieres
foo(bar) (bar)->something
y sí, son necesarios.– cnicutar
25 de agosto de 2011 a las 7:31
-
Sry para preguntar, pero ¿cómo es necesario allí?
– rubixibuc
25 de agosto de 2011 a las 7:33
-
Leí toda la página vinculada y todavía no veo cómo podría analizarse mal
– rubixibuc
25 de agosto de 2011 a las 7:34
-
Supongamos que tiene una serie de estructuras y, por alguna razón, no
foo(bar+5)
. Eso estaría perfectamente bien sifoo
fuera una función, pero si es una macro sin el paréntesis, terminará comobar+5->something
. similares sibar
es un puntero a un puntero, y lo hacesfoo(*bar)
que termina como*bar->something
que ciertamente está mal, querrás(*bar)->something
– nos
25 de agosto de 2011 a las 7:41
michi
Solo para que conste, aterricé desde Aquí Cómo corregir errores matemáticos al usar macros e intentaré expandir esta Respuesta aquí para que se ajuste a la Otra.
Usted está preguntando acerca de la diferencia acerca de:
#define Echo( a ) a
#define Echo( a ) ( a )
lo cual está bien siempre y cuando no entiendas la macro en sí misma (tampoco soy un experto :)).
En primer lugar, ya (probablemente) sabe que existe una precedencia de operadores, por lo que hay una gran diferencia entre estos dos programas:
1):
#include <stdio.h>
#define ADD( a , b ) a + b
int main( void )
{
auto const int a = 5;
auto const int b = 10;
auto const int c = ADD ( 2 + a , 2 + b );
printf( "%d", c );
return 0;
}
Producción:
19
y:
#include <stdio.h>
#define ADD( a , b ) ( a ) + ( b )
int main( void )
{
auto const int a = 5;
auto const int b = 10;
auto const int c = ADD ( a , b );
printf( "%d", c );
return 0;
}
Producción:
15
Ahora vamos a reemplazar +
con *
:
#define ADD( a, b ) a * b
El compilador trata a * b
como por ejemplo a == 5
y b == 10
que hace 5 * 10
.
Pero, cuando dices:
ADD ( 2 + a * 5 + b )
Como aquí:
#include <stdio.h>
#define ADD( a , b ) ( a ) * ( b )
int main( void )
{
auto const int a = 5;
auto const int b = 10;
auto const int c = ADD ( 2 + a , 5 + b );
printf( "%d", c );
return 0;
}
Usted obtiene 105
porque la precedencia del operador está involucrada y trata
2 + b * 5 + a
como
( 2 + 5 ) * ( 5 + 10 )
cual es
( 7 ) * ( 15 )
== 105
Pero cuando lo haces:
#include <stdio.h>
#define ADD( a, b ) a * b
int main( void )
{
auto const int a = 5;
auto const int b = 10;
auto const int c = ADD ( 2 + a , 5 + b );
printf( "%d", c );
return 0;
}
usted obtiene 37
porque
2 + 5 * 5 + 10
lo que significa:
2 + ( 5 * 5 ) + 10
lo que significa:
2 + 25 + 10
Respuesta corta, hay una gran diferencia entre:
#define ADD( a , b ) a * b
y
#define ADD( a , b ) ( a ) * ( a )
-
porque escribes
auto
antes de las variables? es totalmente redundante– Erik W.
10 de febrero de 2018 a las 17:32
-
@ErikW Por favor, explícame qué es exactamente lo que encuentras mal al usar
auto
en estos ejemplos?– Michi
10 de febrero de 2018 a las 17:43
-
Nunca necesitas escribir
auto
en C ya que todas las variables son automáticas cuando se declaran en el alcance (excepto cuando se declaran como explícitasstatic
). No está mal, pero es innecesario.– Erik W.
10 de febrero de 2018 a las 21:18
-
@ErikW No puedo responder a su pregunta siempre que no considere que el uso de auto en C es incorrecto.
– Michi
10 de febrero de 2018 a las 22:04
-
Probablemente sería la misma pregunta: ¿por qué la gente no usa return en main? ¿Solo porque está implícito desde el 99?
– Michi
10 de febrero de 2018 a las 22:17
posible duplicado de La necesidad de paréntesis en macros en C
– Palec
29 de abril de 2015 a las 8:35
La pregunta La necesidad de paréntesis en macros en C es un duplicado de esto, en lugar de viceversa, y ahora se cierra como tal.
–Jonathan Leffler
10 de febrero de 2018 a las 20:58
Preguntas relacionadas: ¿Podemos eliminar los paréntesis alrededor de los argumentos en las definiciones de macros de C? y ¿Cuándo se pueden omitir los paréntesis alrededor de los argumentos en las macros?
–Jonathan Leffler
10 de febrero de 2018 a las 21:01