Encadenamiento de múltiples operadores mayor/menor que

Resuelto jscode asked hace 13 años • 6 respuestas

En una ifdeclaración quiero incluir un rango, por ejemplo:

if(10 < a < 0)

pero al hacerlo, aparece una advertencia "Comparación sin sentido". Sin embargo, esto funciona bien sin previo aviso:

if(a<10 && a>0)

¿Es posible implementar el primer caso en C?

jscode avatar Aug 06 '11 02:08 jscode
Aceptado

Tenga en cuenta que la versión original if(10 < a < 0)es perfectamente legal. Simplemente no hace lo que usted podría (razonablemente) pensar que hace. Tienes suerte de que el compilador lo haya reconocido como un probable error y te haya advertido al respecto.

El <operador asocia de izquierda a derecha, al igual que el +operador. Así como a + b + crealmente significa (a + b) + c, a < b < crealmente significa (a < b) < c. El <operador produce un valor int de 0 si la condición es falsa, 1 si es verdadera. Entonces estás probando si 0 es menor que c o si 1 es menor que c.

En el improbable caso de que eso sea realmente lo que desee hacer, agregar paréntesis probablemente silenciará la advertencia. También le asegurará a cualquiera que lea su código más adelante que sabe lo que está haciendo, para que no lo "arreglen". (Nuevamente, esto se aplica sólo en el improbable caso de que realmente lo desee (a < b) < c)).

La forma de comprobar si aes menor que by bes menor que ces:

a < b && b < c

(Hay lenguajes, incluido Python, donde a < b < csignifica a<b && b<c, como ocurre comúnmente en matemáticas. C simplemente no es uno de esos lenguajes).

Keith Thompson avatar Aug 05 '2011 19:08 Keith Thompson

No es posible, tienes que dividir el cheque como lo hiciste en el caso 2.

user703016 avatar Aug 05 '2011 19:08 user703016

No, no es posible.
Tienes que utilizar la segunda forma dividiendo los dos controles condicionales.

Alok Save avatar Aug 05 '2011 19:08 Alok Save

El primero hace una comparación y luego compara el resultado del primero con el segundo valor. En este caso, los operadores se agrupan de izquierda a derecha, por lo que equivale a (10<a) < 0. La advertencia que le está dando es realmente porque <siempre arrojará 0 o 1. La advertencia le dice que el resultado de la primera comparación nunca puede ser menor que 0, por lo que la segunda comparación siempre arrojará falso.

Aunque el compilador no se quejará de ello, el segundo no supone una gran mejora. ¿Cómo puede un número ser simultáneamente menor que 0 pero mayor que 10? Idealmente, el compilador le advertiría que la condición siempre es falsa. Presumiblemente quieres 0<a<10y a>0 && a<10.

Puede obtener el efecto del segundo usando solo una comparación: if ((unsigned)a < 10)será verdadero solo si el número está en el rango de 0 a 10. Normalmente, una comparación de rango se puede reducir a una comparación única con código como:

if ((unsigned)(x-range_start)<(range_end-range_start))
    // in range
else
    // out of range.

Hubo un tiempo en que esto era un elemento básico de la programación en lenguaje ensamblador decente. Dudo que mucha gente ya lo haga (yo ciertamente no lo hago, por regla general).

Jerry Coffin avatar Aug 05 '2011 19:08 Jerry Coffin