programacion - Comportamiento de && en lenguaje de programación C
operadores logicos en lenguaje c (5)
Debido a la evaluación de cortocircuito , cuando x es 0 , y z no necesitan ser evaluados ya que 0 && ANYTHING es 0 .
Una vez que x se incrementa a 0 , el resultado es 0 , y eso es lo que obtiene y .
z permanece sin cambios ( -1 ).
x | y | z
----+----+-----
-1 | -1 | -1 //x = y = z = -1;
0 | -1 | -1 //++x && ... Now the whole expression is evaluated to 0
0 | 0 | -1 //y = ++x && ++y && ++z;
Soy un principiante en lenguaje de programación C, recientemente he leído acerca de Logical AND && operator.
También sé que, en el lenguaje de programación C, todos los valores distintos de cero se tratan como VERDADERO .
NON-ZERO && NON-ZERO = 1
NON-ZERO && ZERO = 0
ZERO && NON-ZERO = 0
ZERO && ZERO = 0
Pero cuando estoy tratando con el siguiente programa, entonces no recibo la respuesta esperada.
int main(){
int x, y, z;
x = y = z = -1;
y = ++x && ++y && ++z;
printf("x = %d, y = %d, z = %d, x, y, z);
return 0;
}
Estoy esperando
x = 0, y = 0, z = 0
pero la respuesta es
x = 0, y = 0, z = -1
¿Alguien puede explicar, por qué recibo esta respuesta?
Edit: En esta pregunta, no he preguntado sobre la precedencia de los operadores.
Lo que sucede es que ++y y ++z nunca se evalúan porque la primera parte ya garantiza cuál será el nuevo valor de y .
La primera parte de su declaración es ++x && ... que es equivalente a 0 && ... y ya sabemos que y será 0 al final, por lo que el resto de la declaración no se ejecuta.
si hiciste esto
int main(){
int x,y,z,tmp;
x = y = z = -1;
tmp = ++x && ++y && ++z;
printf("x = %d, y = %d, z = %d, tmp = %d", x,y,z, tmp);
return 0;
}
Obtendría x = 0, y = -1, z = -1, tmp = 0
La evaluación de la izquierda está garantizada en el estándar C99. Puede encontrarlo en la sección 6.5.13 Logical AND operator
A diferencia del operador y binario bitwise, el operador && garantiza la evaluación de izquierda a derecha; hay un punto de secuencia después de la evaluación del primer operando. Si el primer operando se compara igual a 0, el segundo operando no se evalúa.
Puede encontrar más información sobre lo que es un punto de secuencia en Wikipedia o en el Anexo C de la norma C99
Solo puedo pensar en que && evalúa en corto circuito : dado A && B , si A evalúa false entonces B no es evaluado.
Asi que:
X convierte en 0 . && ++y && ++z no evalúa desde X/0/false && ...
y=0 asignado de y = x/0/false
z permanece sin modificar ya que ++z no se ejecuta.
&& operador de && se evalúa por pares, por lo que supongo que C está evaluando
((++x && ++y) && ++z)
ahora, ++x devolverá cero, por lo tanto, el primer && fallará, al igual que el segundo sin la necesidad de evaluar ++y o ++z .
y = 0 ya que es el resultado de la expresión.
z no se toca
Para completar (volcado de cerebro):
El término detrás de esta brujería se llama cortocircuito . Revisemos tu código y luego una breve reseña sobre por qué sucede esto. Mirando a:
int main( void ) {
int x, y, z;
x = y = z = -1;
y = ++x && ++y && ++z;
printf( "x = %d, y = %d, z = %d, x, y, z );
return 0;
}
... comenzamos a dividirla línea por línea. La primera línea:
int x, y, z;
... declara tres enteros, x , y y z . Se inicializan en valores de basura en el marco de pila porque no hay inicialización (operador de asignación). Esta línea realmente no importa, ahora veamos la siguiente:
x = y = z = -1;
... vemos que estamos haciendo múltiples tareas en la misma línea. Recuerde que el operador de asignación mutará el identificador a la izquierda del operador de asignación (utilizando el valor a la derecha del operador de asignación) y devolverá el valor de x . Esto se conoce como sobrecarga de asignación. Pero, de nuevo, esto no importa en realidad, lo único importante que debemos tener en cuenta es que x , y , z , ahora son todos -1. Veamos la siguiente línea:
y = ++x && ++y && ++z;
... dice la brujería Yoda. Agreguemos el paréntesis para que sea más obvio qué paso se evalúa primero:
y = ( ( ++x ) && ++y && ++z );
... ahora, mirando el paréntesis más interno, vemos que es un incremento de prefijo de x , lo que significa que incrementaremos el valor de x y luego lo devolveremos. Notamos que x es originalmente -1 y ahora es 0 después de ser incrementado. Esto se resolverá de la siguiente manera:
y = ( 0 && ++y && ++z );
... ahora es importante notar que mirando nuestras tablas de verdad:
A | B | A && B
--------------
T | T | T
T | F | F
F | T | F
F | F | F
... para el operador lógico AND vemos que tanto F (AND) T, T (AND) F son F. El compilador se da cuenta de esto y se cortocircuita cuando está evaluando una conjunción (AND) donde un valor es false - Una técnica inteligente de optimización. Entonces se resolverá asignando y para ser 0 (que es falso). Recuerde que en C cualquier valor distinto de cero es true , solo 0 es false . La línea se verá como sigue:
y = 0;
... ahora mirando la siguiente línea:
printf( "x = %d, y = %d, z = %d, x, y, z );
... debería ser obvio ahora que generará x = 0, y = 0, z = -1 .