c++ - logicos - precedencia de operadores java
Terciario condicional y precedencia del operador de asignaciĆ³n (4)
En el segundo caso,
1 ? j : k = 1;
se evalúa como:
(1) ? (j) : (k = 1);
y dado que uno se evalúa como true
, la expresión se evalúa como j
que no hace nada.
Estoy confundido acerca de la asignación directa y la precedencia de operadores condicionales ternarios:
#include<stdio.h>
int main(void)
{
int j, k;
j = k = 0;
(1 ? j : k) = 1; // first
printf("%d %d/n", j, k);
j = k = 0;
1 ? j : k = 1; // second
printf("%d %d/n", j, k);
return 0;
}
Esperaría que la salida sea:
1 0
1 0
Pero resulta ser:
1 0
0 0
Además recibo esta advertencia:
main.cpp: 20: warning: statement no tiene efecto
que es sobre la línea que comento como segundo.
Como el operador de asignación directa tiene menos precedencia que el operador condicional ternario, esperaba que las líneas comentadas como primera y segunda fueran equivalentes. Pero, por desgracia, no es el caso.
Intenté esto con g ++ --version (Ubuntu 4.4.3-4ubuntu5) 4.4.3
La precedencia del operador en el lenguaje C / C ++ no está definida por una tabla o números, sino por una gramática. Aquí está la gramática para operador condicional de C ++ 0x borrador del capítulo 5.16 Operador condicional [expr.condido] :
conditional-expression: logical-or-expression logical-or-expression ? expression : assignment-expression
Por lo tanto, la tabla de precedencia como esta es correcta cuando usa la asignación en el lado izquierdo del doblecolon, pero no cuando se usa en el lado derecho. ¿Cuál es el motivo de esta asimetría? No tengo idea. Puede ser una razón histórica: en C, el resultado condicional no era lvalue, por lo tanto asignarle algo no tenía sentido, y permitir que la asignación se aceptara sin paréntesis podría parecer inteligente en ese momento.
La segunda línea es equivalente a:
1 ? (j) : (k = 1);
Eso es lo mismo que:
j;
Eso es lo mismo que:
;
La clave es que los dos operandos del operador condicional ternario pueden ser expresiones , por lo que la precedencia del operador no es relevante aquí. Es simplemente que el segundo operando es la expresión de asignación k = 1
.
(1 ? j : k) = 1;
es equivalente a,
if(true) j = 1;
else k = 1;
Y,
1 ? j : k = 1;
es equivalente a,
if(true) j; // warning: statement has no effect
else k = 1;