Programmieren

Präzedenz der Operatoren

"Punkt­rechnung geht vor Strich­rechnung" – so haben Sie es in der Schule gelernt. Und tatsächlich, auch in Java ist dieses Prinzip bei der Auswertung von arithmetischen Ausdrücken gültig. Der Ausdruck auf der rechten Seite der folgenden Wert­zuweisung

int a = 2 + 3 * 5;

ergibt den Wert 17. Denn weil Punkt­rechnung vor Strich­rechnung geht, wird zuerst 3·5 = 15 berechnet und dann 2+15 = 17.

Präzedenz

Man sagt auch, dass der Operator * eine höhere Präzedenz als der Operator + hat (von lat. praecedere – vorgehen).

Standard-Auswertungs­reihenfolge

Wie aber wird der Ausdruck auf der rechten Seite der folgenden Wert­zuweisung ausgewertet? Die Operatoren sind beide Strich­rechnungs-Operatoren, sie haben die gleiche Präzedenz.

int b = 5 - 3 + 1;

In Java ist festgelegt, dass hier von links nach rechts ausgewertet wird. Zuerst wird 5-3 = 2 berechnet, und dann 2+1 = 3.

Klammern

Durch Klammerung kann immer eine bestimmte Auswertungs­reihenfolge erzwungen werden. Ausdrücke, die in Klammern stehen, werden immer zuerst ausgewertet – unabhängig von Präzedenzen und Standard-Auswertungs­reihenfolgen. Der Ausdruck

int c = 5 - (3 + 1);

ergibt 1, da der geklammerte Ausdruck zuerst ausgewertet wird.

Ausdrücke, in denen viele Klammern auf­treten, sind schwer lesbar. Präzedenzen und Standard-Auswertungs­reihenfolgen dienen dazu, Klammern einzusparen.

Operator-Präzedenzen in Java

In Java gibt es noch viele weitere Operatoren, und diese haben teils höhere und teils niedrigere Präzedenz als Punkt- und Strich­rechnung. Die folgende Tabelle listet die Präzedenz der Operatoren auf.

Die Operatoren mit Präzedenz 1 sind die einstelligen Operatoren, diese binden am stärksten. Die darauf­folgenden Operatoren sind zweistellige Operatoren. Die Operatoren mit Präzedenz 2 binden am zweit­stärksten, die Operatoren mit Präzedenz 3 am drittstärksten usw. Am schwächsten binden die Wert­zuweisungsoperatoren mit Präzedenz 12.

Wenn in einem Ausdruck mehrere Operatoren mit gleicher Präzedenz vorkommen, so werden diese von links nach rechts ausgewertet – mit Ausnahme der Wert­zuweisungsoperatoren; diese werden von rechts nach links ausgewertet.

 

PräzedenzOperatorenBedeutung
1++Prä- oder Postinkrement
--Prä- oder Postdekrement
+ -Vorzeichen
~bitweises Komplement
!logische Negation
(Type)Typ­umwandlung

2* / %Multi­plikation, Division, Rest

3+ -Addition, Subtraktion
+String-Verkettung

4<<Links­schieben
>>Rechts­schieben, Vorzeichen­bit nachziehen
>>>Rechts­schieben, Nullen nachziehen

5< <=kleiner, kleiner oder gleich
> >=größer, größer oder gleich

6==gleich
!=ungleich

7&logisches Und
&bitweises Und

8^logisches Exklusiv-Oder
^bitweises Exklusiv-Oder

9|logisches Oder
|bitweises Oder

10&&logisches Und

11||logisches Oder

12=Wert­zuweisung
*= /= %=kombinierte Wert­zuweisung
+= -=
<<= >>= >>>=
&= ^= |=

 

Welchen Wert ergibt der folgende Ausdruck? 1)

30+-3*5<<1>30==5<4||7>6&&7<6

Hier hilft nur eingehendes Studium der Präzedenzliste. Aber solche Ausdrücke kommen natürlich in der Programmier­praxis nicht vor.

Dagegen ist folgende Bedingung einer If-Anweisung sehr gut lesbar; und sie wird aufgrund der Operator-Präzedenzen in genau der Weise ausgewertet, wie sie gedacht ist, ohne dass Klammern erforderlich sind. Die Reihenfolge der Auswertung ist darunter anhand der Präzedenzen der Operatoren ersichtlich.

if (a+b<=c || 2*a==b && b<<1<=c) ...
     3  5  11  2  6  10   4  5

Zuerst wird die Multi­plikation ausgeführt (Präzedenz 2), dann die Addition (Präzedenz 3), dann die Schiebe­operation (Präzedenz 4) usw.

Vorsicht bei Maskierungs­operationen

In Java wird der Operator & sowohl als logisches Und als auch als bitweises Und bei ganzzahligen Werten verwendet. Im letzteren Fall spricht man auch von "Maskierung", weil beispiels­weise bei dem Ausdruck

a&1

alle Bits der Binär­darstellung des Wertes von a ausgeblendet werden bis auf das letzte. Technisch gesehen werden die Bits der Binär­darstellungen von a und von 1 mit Und verknüpft.

Der Ausdruck a&1 kann zur Prüfung, ob a ungerade ist, verwendet werden. Anstelle von

if (a%2 == 1)

kann man schreiben

if ((a&1) == 1)

Wichtig sind hier die Klammern um a&1, denn der Operator & bindet schwächer als der Operator ==.

Bei Ausdrücken wie if (x==0 & y==0) ist diese schwächere Bindung dagegen durchaus gewünscht.

Ent­sprechendes gilt für den Operator |, der sowohl als logisches Oder als auch als bitweises Oder verwendet wird.

Python

In der Programmier­sprache Python gibt es für die logischen Operationen die Operatoren and und or. Die Operatoren & und | werden dort nur für bitweise Operationen verwendet; folgerichtig binden sie in Python stärker als ==.


1)  true

 

Weiter mit:   [up]

 


H.W. Lang   mail@hwlang.de   Impressum   Datenschutz
Diese Webseiten sind während meiner Lehrtätigkeit an der Hochschule Flensburg entstanden