2013-01-01 12 views
8

Lingue come Java e C# hanno entrambi operatori bit a bit e logici.Perché esiste una distinzione tra operatori logici e bit a bit in Java e C#?

Gli operatori logici hanno senso solo con gli operandi booleani, gli operatori bit a bit funzionano anche con tipi interi. Dato che C non ha un tipo booleano e considera tutti gli interi non nulli come veri, l'esistenza di entrambi gli operatori logici e bit a bit ha senso lì. Tuttavia, linguaggi come Java o C# hanno un tipo booleano in modo che il compilatore possa utilizzare automaticamente il giusto tipo di operatori, a seconda del contesto del tipo.

Quindi, c'è qualche ragione concreta per avere operatori logici e bit a bit in quelle lingue? O erano appena inclusi per motivi di familiarità?

(Sono consapevole del fatto che è possibile utilizzare gli operatori "bitwise" in un contesto booleano per aggirare il cortocircuito in Java e C#, ma non ho mai avuto bisogno di un simile comportamento, quindi suppongo che potrebbe essere in gran parte inutilizzato caso speciale)

+0

Vedere ad esempio: http://stackoverflow.com/questions/11411907/what-are-the-cases-in-which-it-is-better-to-use-unconditional-and-instead-of – assylias

risposta

2

dirò per Java

  • operatore logico sono utente con booleani e operatori bit per bit sono usati con int. Non possono essere mescolati.
  • Perché non ridurli a un operatore come "&" o "|"? Java è stato progettato per essere amichevole per gli utenti C/C++, quindi ha ottenuto la loro sintassi. Al giorno d'oggi questi operatori non possono essere ridotti a causa della retrocompatibilità.
6

1) c'è qualche ragione concreta per avere entrambi gli operatori logici e bit a bit in quelle lingue?

Sì:

  • Abbiamo operatori booleani da fare logica booleana (su valori booleani).
  • Abbiamo operatori bit a bit per eseguire la logica bit per bit (su valori interi).

2) Sono consapevole che è possibile utilizzare gli operatori "bit a bit" in un contesto booleano per aggirare il corto circuito in Java e C#,

Per quanto riguarda C# va questo semplicemente non è vero.
C# ha per esempio 2 operatori booleani E: & (completo) e && (breve) ma non consente operazioni bit a bit sui valori booleani.

Quindi, non esiste realmente alcuna "sovrapposizione" o ridondanza tra operatori logici e bit a bit. I due non si applicano agli stessi tipi.

+1

Anche , l'operatore '^' (XOR) in C# ha overload per i tipi interi (come 'int' e' long') dove è un operatore ** bitwise **, ma ha anche un overload per 'bool' dove è un * * operatore logico **. Quindi è sbagliato pensare (almeno con C#) che quando il simbolo è _non_ raddoppiato (non '&&', '||'), allora questa è un'operazione bit a bit. Dipende da quale sovraccarico viene utilizzato. L'unico operatore che ha per qualche motivo un diverso simbolo per bit e logico, è la negazione (che è '~ i' rispettivamente'! B'). –

3

in C#, con booleani

  • & & è un corto circuito operatore logico
  • & è un corto circuito operatore non logico

bit, si utilizza solo & come una sintassi legacy da C/C++ ....ma è davvero molto diverso. Se mai, sarebbe meglio come un simbolo completamente diverso per evitare qualsiasi confusione. Ma non ne sono rimasti molti, a meno che non volessi andare per & & & o ||| ma questo è un po 'brutto.

2

Come si è già detto, c'è qualche differenza tra & e && (lo stesso vale per | e ||) quindi è necessario due gruppi di operatori booleani. Ora, indipendentemente da quelli sopra, potresti aver bisogno di operatori bit a bit e la scelta migliore è &, | s.o. dal momento che non devi evitare alcuna confusione.


Perché complicare le cose e utilizzare la versione a due caratteri?

+0

La questione se un cortocircuito dell'operatore sia in qualche modo ortogonale al suo compimento di un calcolo bit a bit. Si potrebbe definire un operatore di bit e 'corto di cortocircuito che valuterà il primo argomento e, se diverso da zero, valuterà il secondo argomento e calcolerà il bitwise e gli argomenti (altrimenti valuta zero). – supercat

1

Il compilatore non può dedurre un operatore appropriato che osserva solo gli argomenti. è una decisione commerciale quale scegliere. si tratta di calcoli pigri. per esempio.

public boolean a() { 
    doStuffA(); 
    return false; 
} 

public boolean b() { 
    doStuffB(); 
    return true; 
} 

e ora: a() & b() eseguirà doStuffB() mentre a() && b() no

+0

Come ho affermato nella mia domanda, il caso che descrivi non si verifica molto spesso. Inoltre penso che molti programmatori che guardano il codice "a() e b()" potrebbero erroneamente considerarlo un errore e "correggerlo" per l'operatore &&, quindi chiamare prima i metodi e usare il logico && più tardi potrebbe fornire maggiore chiarezza su ciò che il programmatore originale intendeva fare – Askaga

2

risposta tardi, ma cercherò di arrivare al punto di reale.

Sei corretto. E il modo più semplice per rendere il tuo punto è menzionare che altri linguaggi tipizzati (come Visual Basic) hanno operatori logici che possono agire su espressioni sia Boolean che Integer.

VB o operatore: http://msdn.microsoft.com/en-us/library/06s37a7f.aspx

VB bit a bit Esempio: http://visualbasic.about.com/od/usingvbnet/a/bitops01_2.htm

Questo è stato molto una decisione di progettazione lingua. Java e C# non dovevano essere così come sono. Sono solo come sono. Java e C# hanno infatti ereditato gran parte della loro sintassi da C per motivi di familiarità. Altre lingue no e funzionano bene.

Una decisione di progettazione come questa ha conseguenze. La valutazione del cortocircuito è una. Disabilitare i tipi misti (che possono essere fonte di confusione per gli umani da leggere) è un altro. Sono arrivato ad apprezzarlo ma forse ho continuato a fissare Java per troppo tempo.

Visual Basic ha aggiunto AndAlso e OrElse come metodo per eseguire la valutazione del cortocircuito. Diversamente dalle basi, altri operatori logici funzionano solo su Booleans.

VB OrElse: http://msdn.microsoft.com/en-us/library/ea1sssb2.aspx

descrizione di corto circuito: http://support.microsoft.com/kb/817250

La distinzione non è stato fatto perché tipizzazione forte rende impossibile avere solo una serie di operatori logici in una lingua. È stato fatto perché volevano una valutazione del cortocircuito e volevano un modo chiaro per segnalare al lettore cosa stava succedendo.

L'altro motivo (oltre al cortocircuito) che c e C++ hanno diversi tipi di operatori logici è quello di consentire a qualsiasi numero diverso da zero di essere reinterpretato come VERO e reinterpretato come FALSE. Per farlo hanno bisogno di operatori che dicano loro di interpretare in questo modo.Java rifiuta l'intera idea di reinterpret e genera un errore in faccia se si tenta di farlo utilizzando gli operatori logici. Se non fosse stato per la valutazione di corto circuito, l'unica ragione rimasta sarebbe semplicemente perché volevano che gli operatori sembrassero diversi quando facevano cose diverse.

Quindi sì, se i progettisti di linguaggio Java e C# non si sono preoccupati di nulla di ciò, avrebbero potuto utilizzare un gruppo di operatori logici per la logica bit a bit e booleana e hanno capito cosa fare in base al tipo di operando come altri le lingue lo fanno Semplicemente no.

Problemi correlati