2010-05-09 14 views
9

¿Por qué esta declaración:pregunta sobre? y: en C++

int a = 7, b = 8, c = 0; 
c = b>a?a>b?a++:b++:a++?b++:a--; 
cout << c; 

no es igual a:

int a = 7, b = 8, c = 0; 
c = (b>a?(a>b?a++:b++):a++)?b++:a--; 
cout << c; 

y es igual a:

int a = 7, b = 8, c = 0; 
c = b>a?(a>b?a++:b++):(a++?b++:a--); 
cout << c; 

Por favor, dame alguna razón. Por qué ?

+4

http://www.cppreference.com/wiki/operator_precedence – phimuemue

+31

Jesucristo, ¿por qué te quiero volver a escribir el código de esa ?! – Skilldrick

+0

Debe escribir el código muy bien con corchetes a menos que conozca las precedencias – Zai

Respuesta

15

Porque ? : es asociativo de derecha a izquierda. Se define así en el lenguaje.

+0

Sabes, creo que tienes razón y estoy equivocado. Voy a eliminar el mío –

+0

Absolutamente correcto. Gracias – assembler

7

Creo @sth ha proporcionado la respuesta correcta, sin embargo, creo que @Skilldrick acertó en los comentarios, ¿por qué diablos escribirías algo así?

Además del problema de precedencia, realmente debe tener cuidado al incrementar las mismas variables en una sola instrucción. Puede haber o no puntos de secuencia en la declaración y, por lo tanto, el orden de evaluación de los incrementos podría no estar garantizado. Podría terminar con diferentes resultados con diferentes compiladores o incluso configuraciones de optimización diferentes en el mismo compilador.

+2

Absolutamente: múltiples incrementos de la misma variable en el mismo punto de secuencia es el temido * comportamiento indefinido *. Esa línea probablemente podría ser legalmente igual a cualquiera de esos. – Stewart

+0

¿El orden de? b: c está garantizado. –

+1

Puedo estar equivocado, pero no es '?:' Uno de esos operadores que garantiza el orden de evaluación y tiene puntos de secuencia entre los operandos de evaluación (otros son ',', '&&', '||' y tal vez algunos otros)? – UncleBens

1

Los operadores &&, || y ?: realizan control de flujo dentro de las expresiones. ?: se comporta como una instrucción if-else.

c = b>a?a>b?a++:b++:a++?b++:a--; 

if (b>a) 
    if (a>b) 
     a ++; 
    else 
     b ++; 
else if (a ++) 
    b ++; 
else 
    a --; 

b>a? (
    a>b ? 
     a ++ 
    : 
     b ++ 
) : (a ++ ? 
    b ++ 
: 
    a -- 
) 

La asociatividad es necesario tener un comportamiento como if … else if … else.

veces uso una expresión similar a la suya para lexicográfico secuencia de comparación:

operator<()(arr &l, arr &r) { 
    return l[0] < r[0]? true 
     : r[0] < l[0]? false 
     : l[1] < r[1]? true 
     : r[1] < l[1]? false 
     : l[2] < r[2]; 
} 
+0

buenos consejos. +1 gracias – assembler