Logischer Operator
Ein Logischer Operator ist eine Funktion, die einen Wahrheitswert liefert. Bei der zweiwertigen, booleschen Logik liefert er also wahr oder falsch, bei einer mehrwertigen Logik können auch entsprechend andere Werte geliefert werden. Logische Operatoren können eine beliebige Anzahl an Operanden haben.
Ein typisches Beispiel für einen booleschen logischen Operator ist die Und-Verknüpfung: Sie liefert immer dann wahr, wenn alle Operanden ebenfalls wahr sind.
Von besonderer Bedeutung sind die logischen Operatoren in der praktischen Anwendung in Programmiersprachen und in digitalen Schaltungen. In Programmiersprachen stehen mit Ausnahme des „NOT“-Operators mit nur einem Operanden meist nur Operatoren mit zwei Operanden zur Verfügung. Dafür gehören neben den booleschen Operatoren auch Vergleichsoperatoren zum Standardrepertoire von höheren Programmiersprachen. In der Schaltungstechnik sind dagegen „UND“/„ODER“-Verknüpfungen mit mehreren Operanden gängig, die durch Logikgatter oder Reihen- bzw. Parallelschaltung von Schaltern oder Relais realisiert werden.
Logische Operatoren in Programmiersprachen
Durch logische Verknüpfung (meist zweier) logischer Ausdrücke entsteht ein komplexerer logischer Ausdruck. Je nach Art des Verknüpfungsoperators ist der zusammengesetzte Ausdruck zum Beispiel genau dann wahr, wenn beide verknüpften Ausdrücke wahr sind (Und-Verknüpfung) oder wenn mindestens einer der verknüpften Ausdrücke wahr ist (Oder-Verknüpfung). Von den Junktoren in der Aussagenlogik unterscheiden sich die logischen Operatoren der Programmiersprachen unter Umständen in der Auswertungsreihenfolge oder in mit zu berücksichtigenden Nebeneffekten.
Hinsichtlich der Art, Anzahl und Schreibweise der logischen Operatoren unterscheiden sich die einzelnen Programmiersprachen teilweise sehr stark voneinander (siehe Tabelle). Unterschiede gibt es auch hinsichtlich der internen Darstellung der Wahrheitswerte: In den meisten Programmiersprachen wird der Wahrheitswert falsch als die Zahl 0 dargestellt. Der Wahrheitswert wahr wird oft als die Zahl 1 dargestellt, vielfach wird aber auch jeder von 0 verschiedene Wert als wahr interpretiert. Eine bemerkenswerte Ausnahme bilden viele Kommandointerpreter, darunter die verschiedenen Unix-Shells, in denen der Erfolg eines ausgeführten Befehls durch den Rückgabewert 0, der Misserfolg durch einen von 0 verschiedenen Wert angezeigt wird, der die Art des aufgetretenen Fehlers aufzeigt. In Verallgemeinerung dessen wird in den logischen Ausdrücken dieser Kommandointerpreter der Wert 0 („kein Fehler“) als wahr interpretiert und jeder von 0 verschiedene Wert („Fehler“) als falsch.
Vergleichsoperatoren stellen zwei Werte, etwa numerische Größen, einander gegenüber und liefern in Abhängigkeit vom Ausgang des Vergleichs (größer, kleiner usw.) einen Wahrheitswert.
Beispiele für logische Operatoren
Operator | Mathematik | Python | Fortran | Delphi, Pascal | Visual Basic | C, C++, C#, Java, PHP | Perl | Batch | |
---|---|---|---|---|---|---|---|---|---|
Vergleiche | größer | > | .GT. | > | > | > | >, gt | GTR | |
kleiner | < | .LT. | < | < | < | <, lt | LSS | ||
größer oder gleich | >= | .GE. | >= | >= | >= | >=, ge | GEQ | ||
kleiner oder gleich | <= | .LE. | <= | <= | <= | <=, le | LEQ | ||
gleich | ==, is | .EQ. | = | = | == | ==, eq | EQU, == | ||
ungleich | <> 1), !=, is not | .NE. | <> | <> | != | !=, ne | NEQ | ||
Verknüpfungen | Und (Konjunktion) | &, and, all() | .AND. | AND | And, AndAlso2) | &, && | &&, &, and | n. a. | |
Oder (Disjunktion) | |, or, any() | .OR. | OR | Or, OrElse2) | |, || | ||, |, ^, or | n. a. | ||
Nicht (Negation) | not | .NOT. | NOT | Not | ~,! | !, ~, not | NOT |
- 1) in Python 2, inzwischen veraltet
- 2) Neu in .NET-Versionen
Beispiele für logische Ausdrücke
IF a > b THEN Anweisungen ENDIF
In diesem Fall wird bewertet, ob a größer ist als b. Ist die Aussage wahr, werden die Anweisungen ausgeführt, die mit THEN eingeleitet werden. Andernfalls werden die Anweisungen übersprungen.
IF i AND j THEN Anweisungen ENDIF
In diesem Fall wird bewertet, ob i wahr ist und j wahr ist. Sind i und j wahr, werden die Anweisungen ausgeführt, die mit THEN eingeleitet werden. Ist einer der Werte falsch (oder beide), werden die Anweisungen übersprungen.
Auswertungsreihenfolge, Kommutativität und Nebeneffekte
Die logischen Operatoren einer Programmiersprache sind keine exakte Entsprechung der Junktoren in der Aussagenlogik, weil bei der Bewertung von Junktoren keine Nebeneffekte auftreten können. In einer Programmiersprache kann das sehr wohl der Fall sein, wenn z. B. innerhalb des logischen Ausdrucks Funktionen mit Nebeneffekten aufgerufen werden. In diesem Fall spielt die Auswertungsreihenfolge eine Rolle, d. h. das Gesetz der Kommutativität (z. B. für die Konjunktion: a ∧ b = b ∧ a) gilt dann nicht, wenn a oder b nicht nur einen Wert, sondern auch eine Wirkung haben. Aus diesem Grund definieren die meisten Programmiersprachen eine feste Auswertungsreihenfolge für logische Ausdrücke.
Wenn man eine Konjunktion a ∧ b von links nach rechts auswertet und dabei feststellt, dass schon a falsch ist, weiß man bereits an dieser Stelle und ohne b näher betrachten zu müssen, dass die ganze Konjunktion falsch sein wird. Dieses Wissen kann man zur Optimierung der Laufzeit benutzen, indem man in diesem Fall gänzlich auf die Auswertung von b verzichtet (Lazy Evaluation) – allerdings um den Preis, dass dann ein eventueller Effekt von b ausbleibt. Aus diesem Grund ist die unkritische Ausdrucksoptimierung ein Problem. Es gibt zwei Möglichkeiten, damit umzugehen: Ausdrücke bzw. Ausdrucksteile mit Nebeneffekten können von der Optimierung ausgenommen, d. h. stets ausgewertet werden; oder aber das frühzeitige Abbrechen der Auswertung logischer Ausdrücke kann exakt in die Sprachspezifikation aufgenommen werden, sodass der Programmierer zumindest genau vorhersagen kann, welche Nebeneffekte in welcher Situation auftreten und welche nicht.
Letzteres ist in Programmiersprachen wie C, C++ oder Java der Fall: Hier ist spezifiziert, dass bei der Auswertung einer Konjunktion a ∧ b, in der Schreibweise dieser Sprachen a && b, die Auswertung von b unterbleibt, wenn bereits a falsch ist; und dass bei der Auswertung der Disjunktion a ∨ b, in der Schreibweise dieser Sprachen a || b, die Auswertung von b unterbleibt, wenn bereits a wahr ist. Dies stellt keinen grundsätzlichen Unterschied zu den jeweiligen aussagenlogischen Junktoren dar, wenn die auszuwertenden Teilausdrücke wirkungsfrei sind.
Andere Programmiersprachen wie Ada (oder C#) bieten sowohl Konjunktionen und Disjunktionen im aussagenlogischen Sinn an („AND“ und „OR“) als auch Operatoren wie das „&&“ bzw. „||“ in C, in Ada „AND THEN“ bzw. „OR ELSE“ genannt.
Beispiel für einen Logischen Operator in mehrwertiger Logik
Folgendes Beispiel aus der Elektrotechnik entspricht einem logischen Operator mit 10 Operanden in einer 4-wertigen Logik:
An einem Bus sind 10 Geräte angeschlossen, die jeweils die Wahrheitswerte „high“ (5 Volt), „low“ (0 Volt) und „Z“ (hochohmig) liefern können. Der Zustand des Busses lässt sich durch folgenden logischen Operator beschreiben:
O (Gerät1, Gerät2, …, Gerät10): „Kurzschluss“ … wenn mindestens ein Gerät „high“ liefert und mindestens ein Gerät „low“ „high“ … wenn mindestens ein Gerät „high“ liefert und kein Gerät „low“ „low“ … wenn mindestens ein Gerät „low“ liefert und kein Gerät „high“ „hochohmig“ … wenn alle Geräte „hochohmig“ liefern