2010-09-28 27 views
7

Dado que x = 2, y = 1 yz = 0, ¿qué mostrará la siguiente declaración?¿Cómo funcionan los operadores de C++

printf("answer = %d\n", (x || !y && z)); 

Fue en un concurso y lo tengo mal, no recuerdo a mi profesor que cubre esto, alguien me ilumine por favor ... Yo sé la respuesta que recibo es 1, pero ¿por qué?

+5

"¿Qué mostrará la siguiente declaración?" Ve a ejecutarlo tú mismo ... yikes. Si luego no comprende y desea preguntar "¿por qué?", ​​* Esa es * una pregunta razonable. –

+0

Lo sé, lo hice, pero eso no me explica la lógica detrás de la operación:/ – mayotic

+0

Posiblemente duplicado: http://stackoverflow.com/questions/3375041 – jweyrich

Respuesta

3

La expresión se interpreta como x || (!y &&z) (visita la precedencia de los operadores ||, ! y &&.

|| es un operador short-circuiting. Si el operando de la izquierda es cierto (en caso de ||) el operando lado derecho no necesita ser evaluada.

En su caso x es cierto, por lo que ser una expresión booleana, el resultado sería 1.

EDITAR. El orden de evaluación de && y || está garantizado de izquierda a derecha.

+0

¿Le importaría? explicando "cortocircuito"? –

+0

Ver las ediciones (enlace). –

+2

evaluación booleana de cortocircuito significa que si el valor del lado izquierdo es suficiente para determinar la verdad de la expresión completa, entonces los valores de la derecha no se evalúan en absoluto. Esto es a la vez una optimización, y esencial cuando se comprueba que un puntero no es nulo a la izquierda, y luego lo desreferencia a la derecha. Para || - el operador OR - si el valor de la mano izquierda es verdadero, entonces la expresión completa es verdadera y la parte de la mano derecha no evaluada. –

1

Si no me equivoco, se imprimirá 1. (Asumamos cortocircuito está apagado)

(x || !y && z) o (true || !true && false) será evaluar la primera! operador dando (true || false && false)

Entonces el & &: (true || false)

Entonces || : true

Printf interpretará cierto en decimal como 1. Por lo que se imprimirá answer = 1\n

+1

The! no será evaluado primero! x será. –

+3

Incorrecto: consulte la respuesta de Prasoon y considere la evaluación de cortocircuito. –

+0

Nota: Dije que no hay cortocircuitos. Pero de lo contrario estás en lo cierto. Pensé que podría querer una respuesta más completa. – JoshD

-2

No voy a darle la respuesta pura y simple, ya que sólo podría compilarlo y ejecutarlo, pero la pregunta es sólo prueba para ver si conoce la precedencia del operador.

-1
answer = 1 

o tal vez:

answer = -27 
2 || !1 && 0 
2 || 0 && 0 
2 || 0 
true 
true = non-zero value 
printf("answer = %d",*true*); -> who knows 

mayoría de los compiladores es la salida answer = 1. No me atrevería a afirmar que todos los compiladores lo harían, pero estoy seguro de que todos los compiladores devolverían un valor distinto de cero.

+4

Incorrecto, el cortocircuito es irrelevante. Eso es solo cuestión de si ocurren efectos secundarios. Este es un problema simple de precedencia del operador. Si no me cree, intente reemplazar '&&' con ',' (el operador de coma). :-) –

+0

@R - Comentario verificado. Publicación actualizada – PatrickV

+2

No, la respuesta es siempre 1. El resultado de AND lógico y OR es siempre un 'int' con el valor' 0' o '1'. C++ es el mismo, excepto que el tipo es 'bool', que se promueve a' int' cuando se pasa a 'printf'. –

0

Dado que x = 2, y = 1, z = 0, ¿cuál será el siguiente display comunicado ?

printf ("respuesta =% d \ n", (x ||! Y & & z));

Ok - sintiéndose un poco culpable por la dura chiste re mala redacción de la pregunta, así que voy a tratar de ayudarle de una manera diferente a las otras respuestas ... :-)

Cuando usted tiene una pregunta como esta, desglose en trozos manejables.

Probar:

int x = 2, y = 1, z = 0; 

printf("true == %d\n", 10 > 2);     // prints "1" 
printf("false == %d\n", 1 == 2);    // prints "0" 
printf("!y == %d\n", !y);      // prints "0" 
printf("(x || !y) == %d\n", x || !y);   // "1" - SEE COMMENTS BELOW 
printf("(!y || z) == %d\n", !y || z);   // "0" 
printf("(x || !y && z) == %d\n", x || !y && z); // "1" 

En la salida de allí, usted tiene todo lo necesario para deducir lo que está sucediendo:

  • true == 1 revela cómo C/C++ convertir expresiones booleanas veraces a la el valor integral 1 para printf, independientemente de los valores que aparecen en la expresión booleana
  • false == 0, muestra cómo C/C++ convierte f alse expresiones a "0"
  • (!y) == 0 porque! es la lógica no operador, y C/C++ considerar 0 ser el único valor entero correspondiente a falso, mientras que todos los demás son verdaderas, por lo !1 == !true == false == 0
  • (x || !y) == 1, y usted sabe !y es 0, por lo que la sustitución de los valores conocidos y simplificar: (2 || 0) == 1 es equivalente a (true or false) == true ... que es comprensible como una regla lógica
  • (!y || z) == 0 - sustituyendo los valores conocidos: (0 || 0) == (false or false) == false == 0
  • (x || !y && z) == 1: aquí está el crujido! Desde arriba, lo sabemos:
    • x || !y es 1/cierto, que en su caso implicaría 1/true & & z/0/falso == 1/true < - esto claramente no tiene ningún sentido, por lo que debe ¡No sea la forma en que C/C++ está calculando la respuesta!
    • (! Y & & z) es falso, lo que implicaría x/2/verdadero || falso == 1/verdadero < - esto es cierto, por lo que debe ser el orden implícito.

De esta manera, hemos deriva la prioridad de los operadores - el orden de evaluación de la || y & & operadores, a partir de los resultados que muestra el compilador, y visto que si y solo si & & se evalúa antes || entonces podemos tener algún sentido de los resultados.