Informatik unterschied && und & + unterscheid | und ||?

4 Antworten

&&: Logisches Und. Damit kannst du zwei Ausdrücke verknüpfen. Diese Verknüpfungsoperation liefert einen Rückgabewert (true/false). Dieser ist nur true, falls alle Teiloperationen true sind. Ist eine davon falsch, wird der Ausdruck sofort verlassen, da er nicht mehr true werden kann.

||: Logisches Oder. Das Analogon zum logischen Und. Dabei ist der Ausdruck true, sobald mindestens ein Teilausdruck true ist.

&: Bitweises Und. Dabei werden alle Teilausdrücke verknüpft:

int a = 6; // binär: 110
int b = 4; // binär: 100

int res = a & b;
// 110
// & 100
// ------
// 100

Wie du oben sehen kannst, werden die Teilausdrücke in die Binärdarstellung umgewandelt. Dabei wird jede Ziffer einzeln mit der zugehörigen verglichen (bitweise). Zwei Einsen ergeben true, also eine 1, alles andere eine Null.

Sind die Teilausdrücke keine Integer, sondern Booleans, dann verhält es sich genauso wie das logische Und, nur dass der komplette Ausdruck ausgewertet wird, auch wenn bereits ein Teilergebnis false ergeben hat.

|: Bitweises Oder. Das Analogon zum bitweisen Und. Allerdings ist dabei der Ausdruck true, sobald mindestens eine der beiden Ziffern true ist.

Sind die Teilausdrücke keine Integer, sondern Booleans, dann verhält es sich genauso wie das logische Oder, nur dass der komplette Ausdruck ausgewertet wird, auch wenn bereits ein Teilergebnis true ergeben hat.

Um auch die anderen Operatoren anzusprechen:

^: Bitweises XOR (exclusive or). D.h. genau eine der beiden Ziffern ist eine Eins.

!: logisches Nicht. D.h. der Ausdruck wird negiert.

NoHumanBeing  16.09.2017, 18:08

||: Logisches Oder. Das Analogon zum logischen Und. Dabei ist der Ausdruck true, sobald mindestens ein Teilausdruck true ist.

Nur der Vollständigkeit halber: Bei || bricht ebenfalls die Auswertung ab, nämlich dann, wenn der linke Operand true ist.

1

Den einfachen & bzw. einfachen | gibt es auch logisch (und nicht nur bitweise, wie man nach obigen Antworten denken könnte).

Sind a() und b() Funktionen (oder komplexere Ausdrücke) mit booleschem Resultat, dann bedeutet

a() & b(),

dass zuerst a() ausgewertet wird, dann wird b() ausgewertet und am Schluss wird das logische "und" der beiden booleschen Resultate genommen (Analog | für oder).

Hingegen bedeutet

a() && b(),

dass b() nicht ausgewertet wird, wenn die Funktion a() bereits "false" liefert. WICHTIG: Der Aufruf der Funktion b() wird bei && evtl. gespart, wohingegen beim alleinigen & die Funktion b() IMMER aufgerufen wird, auch wenn a() false ist!

Man bezeichnet darher &&  (und ||) auch als "Abkürzungsoperatoren" (Shortcut-evaluation).

Alles klar?

PS: Das einfache & (bzw. |) wird sehr selten für logische Zusammensetzung benötigt, da es zum einen langsamer ist und meistens b() tatsächlich irrelevant ist, wenn die Aussage bereits aus a() errechnet werden kann. Es gibt jedoch seltene Ausnahmen, wenn der User z. B. beides gefragt werden muss (a() und b()), wenn eine Subroutine Nebeneffekte aufweist.

vornameEingabeOK() & mailEingabeOK()

In C-ähnlichen Sprachen (C, C++, Java, C-Sharp, ...) sind &&, sowie || so genannte Operatoren mit Shortcut, d. h. bei ...

a || b

... wird der rechte Ausdruck (b) nur dann ausgewertet, wenn der linke Ausdruck (a) == false ergeben hat.

Umgekehrt, bei ...

a && b

... wird der rechte Ausdruck (b) nur dann ausgewertet, wenn der linke Ausdruck (a) == true ergeben hat.

Das macht vor allem dann einen Unterschied, wenn die Auswertung eines Ausdrucks Nebeneffekte hat, z. B. ...

(a++ != 0) && (b++ != 0)

... hier wird b nur dann inkrementiert, wenn a != 0 war (vor dem Inkrementieren), a wird aber immer inkrementiert.

Bei ...

(a++ != 0) & (b++ != 0)

... würden in jedem Fall sowohl a, als auch b inkrementiert.

Ich sehe daher (sofern möglich) grundsätzlich von der Verwendung von Shortcut-Operatoren ab.

Manche Sprachen erlauben leider ausschließlich Bool'sche Operatoren mit Shortcut, z. B. Go. Aber auch hier kann man die Statements so anordnen, dass keine Fallunterscheidung stattfindet, z. B. indem man den Bool'schen Audruck zunächst in eine lokale Variable auswertet und dann anschließend die lokalen Variablen per logischen Operationen verknüpft. Dann mussten die Ausdrücke auf jeden Fall ausgewertet werden, weil die Ergebnisse ja lokalen Variablen zugewiesen wurden.

Wenn ich eine bedingte Auswertung bewirken möchte, dann schreibe ich eine explizite Verzweigung. Dann sieht wenigstens jeder, dass hier eine Fallunterscheidung stattfindet und dass ich diese auch beabsichtigt hatte.

Zudem können && und || ausschließlich mit Wahrheitswerten (booleans) arbeiten, während & und | auch Integer-Werte bitweise verknüpfen können, was z. B. bei der Generierung von Bitmasken, Implementierung von Schieberegistern, Umwandlung von Zahlen in Binärdarstellung und so weiter und so fort hilfreich sein kann.

Machtnix53  16.09.2017, 21:19

Ich sehe daher (sofern möglich) grundsätzlich von der Verwendung von Shortcut-Operatoren ab.

Ich würde eher grundsätzlich Nebeneffekte in Bedingungen mit Shortcuts vermeiden. Bei Verwendung von bitweisen Operatoren stattdessen würde ich bei späterem Lesen erstmal denken, dass ich ein Zeichen vergessen hätte.  

1
NoHumanBeing  17.09.2017, 14:44
@Machtnix53

Ich würde eher grundsätzlich Nebeneffekte in Bedingungen mit Shortcuts vermeiden.

Das ist natürlich noch besser.

Bei Verwendung von bitweisen Operatoren stattdessen würde ich bei späterem Lesen erstmal denken, dass ich ein Zeichen vergessen hätte.

Es gibt aber auch einen weiteren Unterschied.

Nachdem die Auswertung des "rechten Arguments" bei && bzw. || bedingt erfolgt, wird der Compiler eine zusätzliche conditional branch instruction erzeugen - zusätzlich zu der, die durch die if-Abfrage (in der diese Operatoren sehr wahrscheinlich eingebettet sind) vorkommt, d. h. es gibt letztlich mehr Maschineninstruktionen abzuarbeiten und mehr Möglichkeiten für die branch prediction des Prozessors, daneben zu liegen und einen pipeline flush auszulösen. Der Laufzeitunterschied ist sicher nicht sehr signifikant, aber ggf. messbar.

Bei C sehe ich ein Problem, weil es keinen dezidierten Boolean-Datentyp gibt. Von daher sind & und | im Zusammenhang mit Bool'schen Ausdrücken unter umständen "missverständlich" (führen zu anderen Ergebnissen, als && und ||). Bei Java gibt es dieses Problem eher nicht.

1

Ich kenne es so, dass & bitweise und verknüpft und && logisch.

Beispiel:

21 & 6 = 10101 & 00110 = 00100 = 4

Beim logischen Verknüpfen kommt es darauf an, was als wahr zählt und was als falsch. Nehmen wir an 0 = falsch, alles andere wahr. Dann ist

21 && 6 = wahr && wahr = wahr

Der numerische Repräsentant wird dann wahrscheinlich die 1 sein.

Verwendet man & zur logischen Überprüfung, gäbe es keinen mir gerade ersichtlichen Unterschied.

wahr & falsch = falsch, falsch & falsch = falsch und wahr und wahr = wahr.

Es kommt darauf an, ob Java & mit boolschen Werten arbeiten lässt.

Ein weiterer Unterschied besteht in der Rangfolge. & bindet meine ich stärker (kannst du mal nachschlagen)

Woher ich das weiß:Studium / Ausbildung – Fachinformatiker - Anwendungsentwicklung
Isakoch 
Fragesteller
 30.08.2017, 14:54

Beispiel:

21 & 6 = 10101 & 00110 = 00100 = 4

das habe ich nicht genau verstanden , was du da gemacht hast^^

beim && verstehe ich es nun aber das mit bitweise 

1
Suboptimierer  30.08.2017, 14:56
@Isakoch

Bitweise und bedeutet, dass jedes Bit und verknüpft wird. Das Resultat hat nur dort Einsen, wo beide Operanden eine 1 haben.

2
tavkomann  30.08.2017, 15:32
@Isakoch

das habe ich nicht genau verstanden

10101
00110
--------
00100

Zwei Einsen ergeben eine Eins, alles andere eine Null. Deswegen heißt es auch bitweises (Bit für Bit, so wie oben einfach untereinander geschrieben) Und (1 und 1 muss erfüllt sein für eine 1).

3