Salida del siguiente programa en C

¿Cuál debería ser el resultado de este programa en C?

#include<stdio.h>
int main(){
  int x,y,z;
  x=y=z=1;
  z = ++x || ++y && ++z;
  printf("x=%d y=%d z=%d\n",x,y,z);
  return 0;
}

La salida dada es: x=2 y=1 z=1
Entiendo el resultado de x, pero no veo cómo los valores de y y z no se incrementan.

preguntado el 03 de mayo de 12 a las 14:05

2 Respuestas

Este es un resultado de evaluación de cortocircuito.

La expresion ++x evalúa a 2, y el compilador sabe que 2 || anything siempre evalúa a 1 ("verdadero") pase lo que pase anything es. Por lo tanto, no se procede a evaluar anything y los valores de y y z no cambies.

Si lo intentas con

x=-1;
y=z=1;

Veras que y y z incrementarse, porque el compilador tiene que evaluar el lado derecho del OR para determinar el resultado de la expresión.

Edit: asaerl respondió primero a su pregunta de seguimiento en los comentarios, así que ampliaré un poco su respuesta correcta.

La precedencia de operadores determina cómo se unen las partes que componen una expresión. Como AND tiene mayor precedencia que OR, el compilador sabe que escribiste

++x || (++y && ++z)

en lugar de

(++x || ++y) && ++z

Esto deja la tarea de hacer un OR entre ++x y ++y && ++z. En este punto, normalmente sería libre de seleccionar si "preferiría" evaluar primero una u otra expresión, según el estándar, y normalmente no podría depender del orden específico. Este orden no tiene nada que ver con la precedencia de los operadores.

Sin embargo, específicamente para || y && la norma exige que la evaluación siempre proceda de izquierda a derecha para que el cortocircuito funcione y los desarrolladores puedan depender en la expresión rhs que no se evalúa si el resultado de evaluar el lhs lo dice.

contestado el 03 de mayo de 12 a las 15:05

Gracias, eso ayudó, pero ¿acaso el orden de precedencia no entra en juego aquí? Lo que significa que ++y && ++z debe evaluarse primero, antes de || ? - Krishnang

No. La precedencia es el orden en el análisis, no el orden en la evaluación. Por cierto, si ++z fue evaluado, fue UB. (cambiando z dos veces) - asaelr

En C, cualquier cosa que no sea 0 se trata como verdadera, y la evaluación de || comenzar de izquierda a derecha.

Por lo tanto, el compilador verificará el primer operando izquierdo y, si es verdadero, el compilador no verificará otros operandos. ex. un || B: en este caso, si A es verdadero, el compilador solo devolverá verdadero y no verificará si B es verdadero o falso. Pero si A es falso, verificará B y devolverá en consecuencia, significa que si B es verdadero, devolverá verdadero o si B es falso, devolverá falso.

En su programa, el compilador primero verificará ++x (es decir, 2) y todo lo que no sea 0 es verdadero en C. Por lo tanto, no verificará/incrementará otras expresiones.

Respondido el 11 de Septiembre de 14 a las 14:09

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.