Quando utilizzato con boolean
operandi, &
e |
diventa logici operatori per Section 15.22.2 of the JLS. A differenza di &&
e ||
, tuttavia, questi non cortocircuitano; valuteranno sempre entrambi i lati. Ho una domanda sciocca: perché gli operatori logici non a corto circuito meno efficienti (&
, |
) sono ancora lì, quando abbiamo gli operatori logici di cortocircuito più efficienti (, ||
)? Voglio dire, qual è il vero utilizzo degli operatori logici non a corto circuito, al contrario degli operatori logici a cortocircuito? In altre parole, a che serve valutare sempre entrambe le parti usando gli operatori logici senza cortocircuito?ragione dell'esistenza di operatori logici non-corto circuito
risposta
risposta Aggiornato:
Scuse, ho perso la parola "logica" nella tua domanda, anche se èlì. (Ho preso la libertà di enfatizzare un po 'con una modifica.)
Si consideri il caso in cui si desidera effetti collaterali a sempre verificano, indipendentemente dal fatto che l'espressione di sinistra valuta true
o false
. Per esempio, il contrasto:
if (foo() & bar()) {
// Only call this if both operations returned true
}
con
if (foo() && bar()) {
// Only call this if both operations returned true
}
Si ipotizzi sia foo
e bar
hanno effetti che si vogliono avere accadere indipendentemente dal fatto che foo
rendimenti true
o false
. Nella prima di sopra, I sa che bar
verrà sempre chiamato e avrà il suo effetto. In quest'ultimo, ovviamente, bar
può o non può essere chiamato. Se non avessimo la versione non-corto circuito, avremmo dovuto utilizzare le variabili temporanee:
boolean fooResult, barResult;
fooResult = foo();
barResult = bar();
if (fooResult && barResult) {
// ...
}
Si potrebbe obiettare (probabilmente lo farei) che si dovrebbe fare che comunque, perché è così troppo facile da leggere in modo errato if (foo() & bar())
, ma ci siamo, un motivo pragmatico per avere versioni senza cortocircuito.
risposta originale:
Come vi proponete &
(o |
) un operatore in corto circuito? Con &&
e ||
, ha senso perché hai a che fare con condizioni booleane: possono essere vere o false, non ci sono sfumature di grigio. Ma &
e |
si occupano di bit, non di booleani. Il risultato è un numero. Voglio dire, suppongo che il &
non possa valutare il lato destro se il lato sinistro fosse 0
, e allo stesso modo |
non potesse valutare se il lato sinistro fosse tutto-bit-on per qualunque fosse il tipo, ma io non vedo molto il punto di rendere significativo il caso limite di ciascun operatore (rispetto ai 254 o più altri casi).
In Java e e | non funziona con i bit se applicato al tipo booleano. –
@SuzanCioc: vero, giusto punto. –
http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.22.2 –
È possibile avere alcuni effetti collaterali nell'espressione logica, ad esempio è possibile assegnare contemporaneamente al controllo. Questo potrebbe funzionare in modo errato se viene valutata solo una parte.
Non riesco a ricordare un buon esempio ora, ma ricordo che a volte avevo bisogno di operatori "non a corto circuito".
Hmmm .... Di seguito è ad esempio sbagliato, che non funziona senza "non-corto circuito" OR:
if((object1=getInstance1()).getNumber() == 1 || (object2=getInstance2()).getNumber() == 2) {
// do something which requires bot object1 and object2 assigned
}
+1 per indicare "alcuni effetti collaterali nell'espressione logica". – namalfernandolk
Ci sono casi in cui i componenti di un'espressione booleana coinvolgono operazioni che avresti voluto aver eseguito in tutti i casi. Si consideri il seguente esempio di controllo di una password per la validità:
while (!password.isValid() & (attempts++ < MAX_ATTEMPTS)) {
// re-prompt
}
Se la seconda condizione non è stata valutata causa di un corto circuito, attempts
sarebbe mai essere incrementato. In questo modo è possibile abilitare una maggiore flessibilità del programmatore.
Ma questo può essere scritto con '&&' anche se cambia l'ordine :) –
Nel mio caso, ho due metodi che confrontano due oggetti diversi ma correlati (Object2 è un attributo di Object1) per vedere se ci sono stati cambiamenti. È necessario un aggiornamento se entrambi vengono aggiornati, ma entrambi devono essere valutati in modo che gli oggetti vengano modificati se entrambi sono stati modificati. Pertanto, è richiesto un confronto "OR" a tubo singolo.
EX:
if (compare(object1, currentObject1) | comparison(object2, currentObject2)) {
updateObject1(object1);
}
Il mio caso (C++):
void setFields(Parameters bundle)
{
if (setIfDifferent(&field1, bundle.value1) |
setIfDifferent(&field2, bundle.value2) |
setIfDifferent(&field3, bundle.value3)) {
storeState();
}
}
setIfDifferent() imposta il campo dell'oggetto con nuovo valore se differiscono, nel qual caso restituisce true; o restituisce false nel caso in cui il campo e il nuovo valore siano gli stessi. Quindi, vogliamo provare a impostare tutti i campi, e se qualcuno di loro è cambiato, allora vogliamo memorizzare lo stato di un nuovo oggetto.
Tecnicamente, & e | non sono logici, sono operatori bit a bit che diventano operatori logici se associati ai booleani.
In alcuni casi è possibile includere espressioni di assegnazione all'interno delle espressioni logiche.
Di ':
if(a = (checkForSomeCondition()) | b = checkForAnotherCondition())
{
//now do something here with a and b that has been cached
}
Se avessi usato ||, io non sarei in grado di eseguire il controllo di cui sopra e avrei dovuto dividere le assegnazioni in dichiarazioni separate. Non ho mai incontrato scenari come questo durante lo sviluppo di applicazioni, ma l'ho incontrato poche volte durante la scrittura degli algoritmi.
Ovviamente, è possibile utilizzare gli operatori unari sulle espressioni logiche o passare le variabili per riferimento in un predicato, ma quelli sembrano casi meno comuni di quelli precedenti.
- 1. Operatori logici AP Computer
- 2. Esistono buoni usi per operatori logici (booleani) non a corto circuito in Java/Scala?
- 3. Ricerca SQL con operatori logici
- 4. Cambio JavaScript con operatori logici?
- 5. operatori logici in Modelli di chiusura
- 6. Utilizzo di operatori logici con le macro
- 7. Rails ActiveRecord Cerca con operatori logici
- 8. Laravel Convalida modulo con operatori logici
- 9. SQL e logici operatori e controlli nulli
- 10. Operatori logici ("e", "o") nel batch DOS
- 11. Precedenza degli operatori logici in C
- 12. esercizio di programmazione di base sugli operatori logici
- 13. perché Java revert operatori logici, mentre in fase di compilazione
- 14. Gli operatori logici VBS inizializzano le variabili vuote?
- 15. mano corta per concatenare operatori logici in javascript?
- 16. operatori logici (AND, OR) con NA, TRUE e FALSE
- 17. Priorità agli operatori logici con NAND, NOR, XNOR
- 18. Programma C per confrontare gli interi senza utilizzare operatori logici?
- 19. Quali operatori logici C++ utilizzate: e, o, non e gli operatori di stile ik o C? perché?
- 20. CUDA: Perché gli operatori bit a bit sono talvolta più veloci degli operatori logici?
- 21. Cosa (nelle specifiche) garantisce che "gli operatori logici non cortocircuitati non saranno in effetti in cortocircuito?
- 22. Java corto circuito di valutazione
- 23. Perché esiste una distinzione tra operatori logici e bit a bit in Java e C#?
- 24. corto circuito sorta
- 25. sicura di valutazione di corto circuito in C++ 11
- 26. Perché gli operatori logici di Perl &&, ||,! avere la precedenza su e, o, e non?
- 27. Ho bisogno di assistenza per l'istruzione if con molti operatori logici più semplici
- 28. ï »¿il circuito di codifica problema
- 29. Operandi per || e gli operatori && devono essere convertibili in valori scalari logici
- 30. MongoDB in Go (golang) con mgo: come utilizzare gli operatori logici per interrogare?
Non si tratta di * efficienza *, hanno semantica * diversa * –
È ciò che fa C./In realtà in alcune circostanze possono essere più veloci, perché possono ridurre la ramificazione. Ci possono anche essere effetti collaterali nella valutazione del rhs (il male). –
@ TomHawtin-tackline: C non cortocircuita '&' e '|'. Come Java, cortocircuiti '&&' e '||', ma non '&' e '|'. –