Discussion:
C muy muy basico. Entrega 2
(demasiado antiguo para responder)
Olaf "El Blanco"
2005-11-11 20:29:33 UTC
Permalink
Antes que nada, ¿El 0 es el VERDADERO y cualquier otra cosa es FALSO? ¿O es
al revés?

Lo siguiente es una función que devuelve si es par o impar, quise hacerla
con una sola línea lógica, que se evalúe y devuelva si es verdadero o falso.

int espar(int estenumero)
{
return ((estenumero % 2) = 0);
}

No funciona.
NeoZero
2005-11-11 20:33:09 UTC
Permalink
¡Hola Olaf "El Blanco"!
Post by Olaf "El Blanco"
Antes que nada, ¿El 0 es el VERDADERO y cualquier otra cosa es FALSO? ¿O
es al revés?
Al revés.
Post by Olaf "El Blanco"
Lo siguiente es una función que devuelve si es par o impar, quise hacerla
con una sola línea lógica, que se evalúe y devuelva si es verdadero o falso.
int espar(int estenumero)
{
return ((estenumero % 2) = 0);
}
Un solo igual '=' es una asignación. Si quieres comprobar la igualdad prueba
con '=='.

Ánimo :-)
--
NeoZero || Para responder al mail no pongas lo de "agujero-negro"
http://www.neozero.net
PGP keyId: 993B601A. Clave PGP en pgp.escomposlinux.org
J.A. Gutierrez
2005-11-14 08:54:48 UTC
Permalink
"Olaf \"El Blanco\"" <***@yahoo.no> wrote:

: Lo siguiente es una función que devuelve si es par o impar, quise hacerla
: con una sola línea lógica, que se evalúe y devuelva si es verdadero o falso.

#define espar(a) (!((a)%2))
...
if ( espar (4) ) puts ("4 par");
if ( !espar (5) ) puts ("5 impar");
--
PGP and other useless info at \
http://webdiis.unizar.es/~spd/ \
finger://daphne.cps.unizar.es/spd \ Timeo Danaos et dona ferentes
ftp://ivo.cps.unizar.es/pub/ \ (Virgilio)
Jose Miguel Pérez
2005-11-16 12:53:27 UTC
Permalink
Post by J.A. Gutierrez
#define espar(a) (!((a)%2))
Jajajaja! C muy, muy básico tio... ;-) Con eso lo dejas perplejo...
¿Por qué no lo siguiente?

#define espar(a) ((a^1)&1)

Ale, a descifrar...

Saludos.
Jose Miguel.
Zara
2005-11-16 13:01:17 UTC
Permalink
On Wed, 16 Nov 2005 12:53:27 GMT, Jose Miguel Pérez
Post by Jose Miguel Pérez
Post by J.A. Gutierrez
#define espar(a) (!((a)%2))
Jajajaja! C muy, muy básico tio... ;-) Con eso lo dejas perplejo...
¿Por qué no lo siguiente?
#define espar(a) ((a^1)&1)
Ale, a descifrar...
Saludos.
Jose Miguel.
Me gusta más

#define espar(a) (!(a&1))
Pedro Maicas
2005-11-16 15:45:28 UTC
Permalink
Post by Zara
Post by Jose Miguel Pérez
Post by J.A. Gutierrez
#define espar(a) (!((a)%2))
Jajajaja! C muy, muy básico tio... ;-) Con eso lo dejas perplejo...
¿Por qué no lo siguiente?
#define espar(a) ((a^1)&1)
Ale, a descifrar...
Saludos.
Jose Miguel.
Me gusta más
#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).


Saludos :-) -Pedro-

http://www.maicas.net/

e-mail en www.maicas.net
Jose Miguel Pérez
2005-11-17 14:26:57 UTC
Permalink
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.
J.A. Gutierrez
2005-11-16 19:00:37 UTC
Permalink
Zara <***@terra.es> wrote:
: On Wed, 16 Nov 2005 12:53:27 GMT, Jose Miguel Pérez
: <***@_NOSPAM_perezruiz.com_NOSPAM> wrote:

:>J.A. Gutierrez writes:
:>
:>> #define espar(a) (!((a)%2))
:>
:> Jajajaja! C muy, muy básico tio... ;-) Con eso lo dejas perplejo...
:> ¿Por qué no lo siguiente?

Las macros son C basico.
El operador "%" es C basico, y la forma estandar de verificar
si un numero es par.
El operador "!" tambien es basico.

Cierto que podria quedar mas claro como

( 0 == ( (a) % 2 )

pero bueno, de alguna forma hay que divertirse^H^H optimizar
:-)
--
PGP and other useless info at \
http://webdiis.unizar.es/~spd/ \
finger://daphne.cps.unizar.es/spd \ Timeo Danaos et dona ferentes
ftp://ivo.cps.unizar.es/pub/ \ (Virgilio)
Jose Miguel Pérez
2005-11-17 14:21:15 UTC
Permalink
Post by J.A. Gutierrez
:>> #define espar(a) (!((a)%2))
:>
:> Jajajaja! C muy, muy básico tio... ;-) Con eso lo dejas perplejo...
:> ¿Por qué no lo siguiente?
Las macros son C basico.
Depende del contexto. Dime qué hace lo siguiente:

#define add(Ev,Gv) Ev(){ i=((a-=16)+C(r,4))/4,(\
Gv?Ev():0);} Ev##n(){ a=C(r,5),Ev(); }

(Jeje, no es una pregunta, no hace falta que contestes, seguro que sabes a
qué me refiero).
Lo que quiero dar a entender es que SUSTITUIR una función por un #define es
una estructura avanzada, demasiado liosa para un *PRINCIPIANTE*.

Leete mi siguiente post.
Post by J.A. Gutierrez
El operador "%" es C basico, y la forma estandar de verificar
si un numero es par.
El operador "+" también es básico (faltaría mas), pero usado para aritmética
de punteros se convierte en un quebradero de cabeza...
Post by J.A. Gutierrez
El operador "!" tambien es basico.
No cuando se usa para comparar peras con manzanas.

if (!(x%2)) // Eeeggckkk (Para un PRINCIPIANTE)!

if (x%2 > 0) // Mejor...
Post by J.A. Gutierrez
Cierto que podria quedar mas claro como
( 0 == ( (a) % 2 )
Jejeje, tu también eres de los que evitan el lvalue? ;-)))
Post by J.A. Gutierrez
pero bueno, de alguna forma hay que divertirse^H^H optimizar
:-)
Pozi. Pero sin acritud... ehhhh? ;-)

Saludos.
Jose Miguel.
Zara
2005-11-16 13:02:46 UTC
Permalink
On Wed, 16 Nov 2005 12:53:27 GMT, Jose Miguel Pérez
Post by Jose Miguel Pérez
Post by J.A. Gutierrez
#define espar(a) (!((a)%2))
Jajajaja! C muy, muy básico tio... ;-) Con eso lo dejas perplejo...
¿Por qué no lo siguiente?
#define espar(a) ((a^1)&1)
Ale, a descifrar...
Saludos.
Jose Miguel.
Yo prefiero

#define espar(a) (!(a&1))

Saludos,

Zara
Olaf "El Blanco"
2005-11-18 21:30:52 UTC
Permalink
La suma de todas estas pasaron a formar parte de la mejor respuesta que
me han dado nunca!

Son buenas para los principiantes... Porque si luchamos con un punto y
coma mal puesto y luego en un define me hacen el objetivo de mi programa
uno se queda pensando un poco, se pregunta si uno esta echo para eso, y
automáticamente le vienen ganas de estudiar c, y no abandonarlo nunca...
Jajajaja,
Aviso que no lo han conseguido conmigo!
#define espar(a) (!((a)%2)) [J.A. Gutierrez]
O sea que aparte de una constante podemos definir una función.
sin poner lo que debe devolver ni la clase de dato de entrada?
Vale.

(a%2) Debe devolver 1 si es verdadero?

Puede ser correcto que le hayas metido el ! para que devuelva exactamente 0
(y no otra cosa) cuando la expresion sea impar? ¿Puede ser por eso que dicen
los libros que el lenguaje C devuelve 0 para lo falso y CUALQUIER OTRA COSA
para lo verdadero?
Si es por eso lo entiendo:
(! ( (a)%2) )

lo que no me entra son los () entre la variable a?
eso es en el caso de que ponga a+1 como parametro actual? Alguien comentaba
eso...

#define espar(a) (!(a&1))

esto esta bien escrito?

(!(a&1))

Es una negación de que? a&1?, el & dice que se trata de una dirección de
memoria, que se va a escribir directamente en la misma?

De antemano Gracias!

*****************************************************
"...Winds and storms, embrace us now,
Lay waste the light of day.
Open gates to darker lands...
We spread our wings and fly away..."
*****************************************************
AnimAlf
2005-11-18 21:54:32 UTC
Permalink
Post by Olaf "El Blanco"
La suma de todas estas pasaron a formar parte de la mejor respuesta que
me han dado nunca!
je je je, perdón pero se me va la olla y de repente con todo esto, de
repente he sentido que estaba en perl. Y perdón de nuevo porque no sigo
el thread a fondo

saludos y buen fin de semana
Eduardo Villanueva
2005-11-20 23:43:29 UTC
Permalink
Post by Olaf "El Blanco"
La suma de todas estas pasaron a formar parte de la mejor respuesta que
me han dado nunca!
Son buenas para los principiantes... Porque si luchamos con un punto y
coma mal puesto y luego en un define me hacen el objetivo de mi programa
uno se queda pensando un poco, se pregunta si uno esta echo para eso, y
automáticamente le vienen ganas de estudiar c, y no abandonarlo nunca...
Jajajaja,
Aviso que no lo han conseguido conmigo!
Eso esta bien, sigue dandole ;)
Post by Olaf "El Blanco"
#define espar(a) (!((a)%2)) [J.A. Gutierrez]
O sea que aparte de una constante podemos definir una función.
sin poner lo que debe devolver ni la clase de dato de entrada?
Vale.
No es una funcion, es una macro. Mas abajo te explico la diferencia.
Post by Olaf "El Blanco"
(a%2) Debe devolver 1 si es verdadero?
No, el operador '%' es el resto de la division entera. Por ejemplo, la
division entera de 1 entre 0, da 1 y 1 de resto. La division entera de 2
entre 2 da 1 y 0 de resto, ...
En otras palabras al hacer a % 2 obtendras 0 si es par, y 1 si es impar.
Post by Olaf "El Blanco"
Puede ser correcto que le hayas metido el ! para que devuelva exactamente 0
(y no otra cosa) cuando la expresion sea impar?
El operador '!' es la negacion, !a es 1 si a es 0, o 0 si a es distinto
de 0. Deberias pegarle un repaso a los operadores ;)
Post by Olaf "El Blanco"
¿Puede ser por eso que dicen
los libros que el lenguaje C devuelve 0 para lo falso y CUALQUIER OTRA COSA
para lo verdadero?
Esa afirmacion no es correcta. C *INTERPRETA* 0 como falso, y cualquier
otra cosa como verdadero.
Post by Olaf "El Blanco"
(! ( (a)%2) )
lo que no me entra son los () entre la variable a?
eso es en el caso de que ponga a+1 como parametro actual? Alguien comentaba
eso...
#define espar(a) (!(a&1))
Una macro *NO* es una funcion. El preprocesador sustituye la macro por
su contenido antes de compilar el codigo. Podrias verlo como si antes de
empezar la compilacion hicieses un buscar y reemplazar de los defines
por su contenido.

Por ejemplo, si pones:

if (espar(7))

el preprocesador te lo cambiara por:

if ((!(7&1)))

Hasta aqui todo bien, pero si pones:

if (espar(2|0))

te lo sustituye por:

if ((!(2|0&1)))

Como el orden de precedencia del operador & es mayor que el del operador
| se evalua primero 0&1, dando como resultado falso, cuando deberia ser
verdadero.

Las macros pueden traer problemas si no se definen y se usan con
cuidado. Por ejemplo, una macro tipica que se ha nombrado en este thread:

#define max(a,b) ((a) > (b) ? (a) : (b))

Aparentemente bien definida, puede traer muchos dolores de cabeza si se
usa de esta forma:

k = MAX(i++,j--);

Es mas seguro declararla asi:
#define max(A,B) ({ const typeof(A) a = A; const typeof(B) b = B; a > b
? a : b; })
Post by Olaf "El Blanco"
esto esta bien escrito?
(!(a&1))
No, como ya he explicado antes puedes tener problemas si no encierras la
'a' entre parentesis.
Post by Olaf "El Blanco"
Es una negación de que? a&1?, el & dice que se trata de una dirección de
memoria, que se va a escribir directamente en la misma?
Aqui se aplica el operador & binario (operacion 'AND' logica), no el
unario (operador de direccion). En otras palabras, solo se salvara el
primer bit de a, el resto se pondran a 0.
Post by Olaf "El Blanco"
De antemano Gracias!
De nada ;)
Jose Miguel Pérez
2005-11-21 09:12:29 UTC
Permalink
Post by Jose Miguel Pérez
#define max(a,b) ((a) > (b) ? (a) : (b))
[...]
Post by Jose Miguel Pérez
#define max(A,B) ({ const typeof(A) a = A; const typeof(B) b = B; a > b
? a : b; })
Si, si no fuera porque "typeof" es una extensión del lenguaje. Si no fuera
poco el lío que le estamos haciendo a este hombre que está APRENDIENDO C,
encima como para empezar a diferenciar C89 y C99.

Venga Olaf! Ahora que sabes cómo se utiliza #define en casos complicados,
explícanos cuándo y porqué usar el keyword "volatile"...

Wea!
Jose Miguel.

Loading...