programas programacion operadores operador negacion logicos lenguaje ejemplos cortocircuito condicional con asignacion c operators logical-operators

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 .