std::cout<<"odd"
è un'espressione che restituirà std::cout
(che è perché puoi fare std::cout << a << b << c
). Quando viene valutato nel contesto booleano, restituisce semplicemente true se il bit di fail non è impostato. Quindi se l'operazione di output ha esito positivo, verrà valutata come vera.
Tuttavia, l'intento di questo codice non è di verificare che il valore, anzi è un intelligente (e non molto leggibile) modo per esprimere questo:
if (remainder & 1) {
std::cout << "odd";
} else {
std::cout << "even";
}
si avvale della corto circuito natura degli operatori &&
e ||
:
- In
a && b
, se a
è falsa, allora valutata come a
(b
non viene valutato!) altrimenti viene valutato come b
.
- In
a || b
, se a
è vero allora si valuta come a
(b
non viene analizzato!) altrimenti viene valutata come b
.
Quindi se remainder & 1
viene valutata come falsa (zero in questo caso), allora std::cout << "odd"
non viene valutata perché le &&
espressione cortocircuiti, restituito false. Questo è l'operando di sinistra per l'espressione esterna ||
, che causa la valutazione dello b
(std::cout << "even"
), scrivendo "pari" sull'output.
Se remainder & 1
viene valutato come vero (non zero in questo caso), viene valutato l'operando destro per &&
, visualizzando "dispari". Supponendo che questa operazione abbia esito positivo, l'operando di sinistra per l'operazione ||
sarà true, il che provoca un cortocircuito e non valuta l'operando corretto.
I programmatori esperti sono in grado di conoscere esattamente che cosa sta succedendo qui, ma come avete trovato questa tecnica non è il più leggibile. È meglio (IMO) essere chiari sull'intento del codice, quindi utilizzerei solo un condizionale if
o, per lo meno, utilizzare l'operatore ternario: std::cout << (remainder & 1 ? "odd" : "even")
.
In altre lingue (mi viene in mente JavaScript) (ab) utilizzare gli operatori di cortocircuito è una tecnica molto comune. Di solito non li vedo usati in questo modo in C++ e sconsiglio vivamente questo uso.
non è necessaria la parentesi che è lì, ma a seconda della precedenza dell'operatore (non riesco a ricordarlo) potrebbe essere necessaria la parentesi intorno alla sotto-espressione 'remainder & 1'. –
Vedere [C++ operator precedence] (http://en.cppreference.com/w/cpp/language/operator_precedence) –