2010-05-09 8 views
9

Perché questa dichiarazione:domanda in merito? e: in C++

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

non è uguale a:

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

ed è pari a:

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

prego di darmi qualche ragione. Perché ?

+4

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

+31

Gesù Cristo, perché mai voglia di scrivere codice come quello ?! – Skilldrick

+0

Dovresti scrivere bene il codice con parentesi se non conosci le precedenze – Zai

risposta

15

Perché ? : è associativo da destra a sinistra. È definito così nella lingua.

+0

Sai, penso che tu abbia ragione e mi sbaglio. Ho intenzione di cancellare il mio. –

+0

Assolutamente giusto. Grazie – assembler

7

Credo che @sth abbia fornito la risposta corretta, tuttavia, penso che @Skilldrick abbia capito bene nei commenti - perché diavolo avresti mai scritto qualcosa del genere.

Così come il problema di precedenza, è necessario fare attenzione quando si aumentano le stesse variabili in una singola istruzione. Ci possono essere o meno punti di sequenza nell'istruzione e quindi l'ordine di valutazione degli incrementi potrebbe non essere garantito. Potresti finire con risultati diversi con diversi compilatori o anche con diverse impostazioni di ottimizzazione sullo stesso compilatore.

+2

Assolutamente - multipli incrementi della stessa variabile nello stesso punto di sequenza è il temuto * comportamento non definito *. Tale linea potrebbe probabilmente essere legalmente uguale a uno di questi. – Stewart

+0

L'ordine di un? b: c è garantito. –

+1

Potrei sbagliarmi, ma non è '?:' Uno di quegli operatori che garantisce l'ordine di valutazione e ha punti di sequenza tra la valutazione degli operandi (gli altri sono ',', '&&', '||' e forse alcuni altri)? – UncleBens

1

Gli operatori &&, || e ?: eseguono il controllo del flusso all'interno delle espressioni. ?: si comporta come un'istruzione 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 -- 
) 

L'associatività è necessario avere un comportamento simile if … else if … else.

A volte uso un'espressione simile al tuo per lessicografico sequenza di confronto:

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

buoni consigli. +1 grazie – assembler