Determinando la impresión de C

Estoy revisando material sobre C. No estoy seguro de por qué la respuesta es 12 y 32. En el primer printf() , pensé que %d = 2 ( i ), %d = 2 ( j ), \n = nueva línea. ¿Alguien puede explicar esto?

 #include  int main(void) { int i,j; i=2 && (j=2); printf("%d%d\n",i,j); (i=3) || (j=3); printf("%d%d\n",i,j); } 

La razón por la que se imprime 12 en lugar de 22 es porque a i se le asigna el valor de 2 && (j=2) . Primero j se asigna a 2 . Entonces (j=2) devuelve 2 . Después de eso, 2 && 2 se evalúa como true y devuelve true . Esto se debe a que && verifica si ambos lados son verdaderos, y 2 se interpreta como verdadero. Dado que ambos lados son verdaderos, devuelve verdadero, que es 1.

El || no evalúa el lado derecho si el izquierdo se evalúa como verdadero. La razón es que no es necesario. Se debe evaluar como verdadero si al menos uno de los operadores se evalúa como verdadero, e i = 3 se evalúa como 3, lo que se interpreta como verdadero. Es por eso que se imprime 32 en lugar de 33.

La característica que no evalúa el operando de la derecha si se evalúa a la derecha como verdadera puede usarse para hacer esto:

 foo() || printf("foo() returned false\n"); 

Y similar para &&, pero este operador no evalúa el operando derecho si se deja evaluado como falso.

 foo() && printf("foo() returned true\n"); 

Tenga en cuenta que no estoy sugiriendo que estos trucos deben ser utilizados. Solo los estoy usando como ejemplo de cómo || y && puede omitir la evaluación del operando derecho según el valor de la izquierda.

Para la primera expresión, i=2 && (j=2); se evalúa implícitamente como i = (2 && (j = 2)); porque el operador de asignación = tiene menor prioridad en comparación con los operadores lógicos. En la primera condición, 2 tiene el valor de true de true , y AND && lógico hace que se evalúen todas las condiciones, lo que significa que j = 2 también se evalúa, asignando 2 a j y devolviendo 2 que evalúa a true . Así que ahora la expresión real a evaluar es i = 2 && 2; lo cual es true , o en términos de C, 1. Entonces, a i se le asigna 1, y la primera salida es 12 .

Para la segunda expresión (i=3) || (j=3); (i=3) || (j=3); , el OR lógico || se utiliza, y el cortocircuito asegura que si la primera condición se evalúa como true , la expresión general es true y, por lo tanto, la segunda condición no se evalúa. Entonces, después i = 3 evaluar i = 3 , a i se le asigna 3 y toda la expresión es verdadera, por lo que j = 3 no se evalúa. Y así, la segunda salida es 32 .

Basado en las precedentes, la primera expresión se evalúa como

  i = (2 && (j=2)); 

Entonces i = 1 (verdadero) y j = 2. Es por eso que la primera salida es 12.

La segunda expresión es un OR lógico de dos asignaciones.

 (i=3) || (j=3); 

Pero como la primera evaluación de la izquierda es “verdadera” (i = 3), la segunda evaluación no se realiza. Es por eso que el valor de j permanece en 2 y la segunda salida es 32 (no 33).