2013-01-01 10 views
8

Języki takie jak np. Java i C# mają zarówno operatory bitowe, jak i logiczne.Dlaczego rozróżnia się operatory logiczne i bitowe w Javie i C#?

Operatory logiczne mają sens tylko z operandami binarnymi, operatory bitowe również działają z typami całkowitymi. Ponieważ C nie ma typu boolowskiego i traktuje wszystkie niezerowe liczby całkowite jako prawdziwe, istnienie zarówno operatorów logicznych, jak i bitowych ma sens. Jednak języki takie jak Java lub C# mają typ boolowski, więc kompilator może automatycznie używać odpowiedniego rodzaju operatorów, w zależności od kontekstu typu.

Czy istnieje zatem jakiś konkretny powód, dla którego operatorzy logiczne i bitowe są w tych językach? A może zostały one uwzględnione tylko ze względu na poufałość?

(Jestem świadomy, że można użyć operatorów "bitowych" w kontekście logicznym, aby ominąć zwarcie w Javie i C#, ale nigdy nie potrzebowałem takiego zachowania, więc myślę, że może to być w większości niewykorzystane Szczególnym przypadkiem)

+0

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

Odpowiedz

2

powiem Java

  • operator logiczny jest użytkownik z logicznych i operatorów bitowe są używane w int. Nie można ich mieszać.
  • Dlaczego nie zmniejszyć ich do jednego operatora, np. "&" lub "|"? Java została zaprojektowana jako przyjazna dla użytkowników C/C++, więc ma swoją składnię. Obecnie tych operatorów nie można zmniejszyć ze względu na kompatybilność wsteczną.
6

1) Czy jest jakiś konkretny powód mający oba operatory logiczne i bitowe w tych językach?

Tak:

  • Mamy operatorów logicznych turystyczne logiczną logiki (na wartościach logicznych).
  • Mamy operatorów bitowych do zrobienia logiki bitowej (na wartościach całkowitych).

2) Zdaję sobie sprawę, że można korzystać z „bitowe” podmioty w kontekście logicznym ominięcie zwarcie w Java i C#,

tak daleko jak C# idzie to po prostu nie jest prawdą.
C# ma na przykład 2 boolowskie operatory AND: & (pełne) i && (w skrócie), ale nie zezwala na operacje bitowe na wartościach logicznych.

Tak naprawdę nie ma "nakładania się" lub redundancji między operatorami logicznymi i bitowymi. Te dwa nie dotyczą tych samych typów.

+1

także , operator '^' (XOR) w C# ma przeciążenia dla typów całkowitych (takich jak 'int' i' long'), gdzie jest operatorem ** bitowym **, ale ma również przeciążenie dla 'bool', gdzie jest * * operator logiczny **. Więc mylisz się (przynajmniej z C#), że kiedy symbol jest _nie_ podwojony (nie '&&', '||'), to jest to operacja bitowa. Zależy to od tego, które obciążenie zostanie użyte. Jedynym operatorem, który ma z jakiegoś powodu inny symbol dla bitowego i logicznego, jest negacja (co oznacza '~ i' odpowiednio'! B'). –

3

w C#, z logicznych

  • & & jest krótkim spięciom logiczny operator
  • & jest non zwarciem operator logiczny

bitowe, to po prostu wykorzystuje & jako składni starszego z C/C++ ....ale to naprawdę coś zupełnie innego. Jeśli cokolwiek, byłoby lepiej jako zupełnie inny symbol, aby uniknąć konfuzji. Ale tak naprawdę nie zostało wiele, chyba że chcesz uzyskać & & & lub ||| ale to trochę brzydkie.

2

Jak już powiedziałem, jest jakaś różnica między & i && (to samo dotyczy | i ||), więc potrzebne są dwa zestawy operatorów logicznych. Teraz, niezależnie od powyższych, możesz potrzebować operatorów bitowych, a najlepszym wyborem jest &, | s.o. ponieważ nie musisz unikać żadnych nieporozumień.


Po co komplikować rzeczy i korzystać z wersji dwuznakowej?

+0

Pytanie, czy zwarcia operatora są w pewnym stopniu prostopadłe do wykonywania obliczeń bitowych. Można zdefiniować bitowe operatory 'i' powodujące zwarcie, które oceniałyby pierwszy argument, a jeśli niezerowy, oceniałyby drugi argument i obliczałyby bitowe i argumenty (w przeciwnym razie oceniałyby zero). – supercat

1

Kompilator nie może określić właściwego operatora patrząc tylko na argumenty. to decyzja biznesowa, którą wybrać. to o leniwych obliczeniach. na przykład

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

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

i teraz: a() & b() wykona doStuffB() podczas a() && b() nie będzie

+0

Jak stwierdzono w moim pytaniu, opisywany przypadek nie zdarza się często. Również myślę, że wielu programistów patrzących na kod "a() i b()" może błędnie uznać to za błąd i "poprawić" go dla operatora &&, więc najpierw wywołując metody i używając logicznego && zapewnić większą jasność tego, co pierwotny programista zamierzał zrobić – Askaga

2

Późne odpowiedź, ale postaram się dostać do swojego prawdziwego punktu.

Masz rację. Najprostszym sposobem na podkreślenie jest to, że inne języki maszynowe (takie jak Visual Basic) mają operatorów logicznych, które mogą działać zarówno w wyrażeniach logicznych, jak i całkowitych.

VB lub operator: http://msdn.microsoft.com/en-us/library/06s37a7f.aspx

VB bitowe Przykład: http://visualbasic.about.com/od/usingvbnet/a/bitops01_2.htm

To było bardzo dużo decyzja konstrukcja języka. Java i C# nie musiały być takie, jakimi są. Oni po prostu są tacy, jakimi są. Java i C# rzeczywiście dziedziczyły wiele ze swojej składni z C ze względu na znajomość. Inne języki nie działały i działają dobrze.

Decyzja taka ma konsekwencje. Ocena zwarciowa to jedna. Odmawianie typów mieszanych (co może być mylące dla ludzi do czytania) jest kolejnym. Spodobało mi się, ale może właśnie spoglądałem na Javę zbyt długo.

Visual Basic dodał AndAlso i OrElse jako sposób oceny zwarć. W przeciwieństwie do innych operatorów logicznych działają one tylko na Booleans.

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

opis zwarciem: http://support.microsoft.com/kb/817250

Rozróżnienie nie została wykonana, ponieważ silne typowanie uniemożliwia tylko jeden zestaw operatorów logicznych w języku. Został wykonany, ponieważ chcieli dokonać oceny zwarciowej i chcieli czytelnego sposobu, aby zasygnalizować czytelnikowi, co się dzieje.

Innym powodem (oprócz zwarcia), które C i C++ są różne rodzaje operatorów logicznych to do którychkolwiek niezerowy numer być postrzegane jako PRAWDA zero zinterpretowane jako FAŁSZ. Aby to zrobić, potrzebują operatorów, którzy każą im to zinterpretować.Java odrzuca tę całą koncepcję reinterpretacji i zgłasza błąd w twojej twarzy, jeśli spróbujesz to zrobić za pomocą operatorów logicznych. Gdyby nie była to ocena zwarć, jedynym powodem, dla którego pozostało, byłby po prostu fakt, że chcieli, aby operatorzy wyglądali inaczej, robiąc różne rzeczy.

Więc tak, jeśli projektanci # język Java i C nie dbał o żadnej z tych rzeczy mogliby stosować jeden zestaw operatorów logicznych zarówno mnożenie i logiczną logiki i zorientowali się, które na nie w oparciu o typ argumentu jak niektóre inne języki robią. Po prostu nie.

Powiązane problemy