Post by Pedro Maicas#define espar(a) (!(a&1))
Yo tambien estuve a puntito de criticar el primer define,
no me gustan las multiplicaciones, divisiones y menos el operador %.
Pero por lo menos ese define lleva los parentesis
bien colocados, los dos que habeis puesto a continuacion
son los típicos que dan problemas inexplicables y que se
suelen terminar echandole la culpa a bill gates de que
el programa no funcione, y todo por ahorrarse unos parentesis.
Y aparte de que los tres son "C básico" (o el ! es avanzado ?),
el más básico es el primero porque no requiere saber cómo se
almacena en numero un memoria (que tambien es una cosa básica
pero mucha gente no lo sabe).
La contestación iba de coña, evidentemente. Mira por donde, no iba a entrar
al trapo, pero lo voy a hacer.
Tienes razón, a mi #define le faltan dos paréntesis para estar correcto.
Para los no avezados, aquí va la explicación: (a^1) es incorrecto, debería
ser ((a)^1) por una razón: #define sustituye a piñon los datos pasados, por
tanto si le pasamos "espar(5)" lo hará correcto, incluso con una variable
como "espar(x)", pero fallará cuando lo llamamos con una operación:
espar(5+1) se sustituye como (5+1^1), que aunque de un resultado correcto
(impar), el orden de los operadores se altera.
Mmmmhhh... bastante avanzado para un principiante.
De todas formas, el grueso de mi respuesta viene ahora. Si, el operador ! y
los defines son avanzados dependiendo del contexto. Las clases más básicas
de C usan el operador negación "!" en operacione lógicas "if (!espar(a))",
"while (!feof(f))", etc... Usar la negación lógica en números es avanzado.
Negar el resultado de una operación, que para más inri PUEDE potencialmente
devolver decimales, es avanzado.
#define es avanzado (bueno, dejémoslo en nivel medio) cuando se usa para
generar "pseudo funciones", fuera del uso comun de "#define MAXIMO 5"...
Para un principiante en C es más claro ver esto:
/ * Devuelve el máximo de un par de números * /
int max(int a, int b)
{
if (a > b) {
return a;
} else {
return b;
}
}
Que esto:
#define max(a,b) ((a) > (b) ? (a) : (b))
Y si quieres más "complicación", usa esto:
#define max(a, b) ((a) >? (b))
Te aseguro que necesitarás más clases de C para siquiera averiguar qué se
está haciendo aquí:
#define add(Ev,Gv) Ev(){ i=((a-=16)+C(r,4))/4,(\
Gv?Ev():0);} Ev##n(){ a=C(r,5),Ev(); }
En cuanto a saber cómo se almacena un número en memoria es irrelevante para
el uso del operador XOR en "a^1". Quiero decir que esto funciona aunque la
máquina sea little endian, big endian, almacene los datos en 8 bits, 16 bits
o 128 bits. De hecho funciona el cualquier máquina binaria, osea todas.
Quizás, requiere un poco más de conocimientos que el saber que la negación
de un número diferente de cero es "falso".
De todas formas, mi contestación como he dicho antes, era una exageración,
no para liar más las cosas a quien está empezando a programar en C.
Aaaaadiox.
Jose Miguel.