Short-Circuit-Operatoren && und ||

Objektorientierte Programmiersprache auf Basis einer virtuellen Maschine (https://www.oracle.com/java/)
Antworten
Benutzeravatar
detewe89
Beiträge: 15
Registriert: So Okt 05, 2008 11:07 am

Short-Circuit-Operatoren && und ||

Beitrag von detewe89 » Mi Okt 27, 2010 3:14 pm

Hey ihr!! ;)

So, poste mal wieder hier, hab früher auf tutorials.at ab und zu gepostet^^

Haben im Studium jetzt mit der Java-Programmierung angefangen, und ich hab eine Frage zum programmiertechnischen Hintergrund zum Unterschied zwischen den logischen Operatoren && und & sowie zwischen || und |.

Ich weiß, dass die Operatoren && und || zu einer "Kurzschlusslogik" führen, das heißt, wenn das Ergebnis nach Auswertung des ersten Operanden schon feststeht, wird die Operation abgebrochen. Damit sollen wohl Fehler verhindert werden à la Nulldivision

Code: Alles auswählen

int t;
// ...
if ( (t != 0) && (5/t < 2) ) { 
   // ...
}
Meine Frage: Wozu braucht es überhaupt die Operatoren, die die ganze Operation ausführen? Ist das nicht überflüssig??


Danke euch!!
Daniel

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8859
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Short-Circuit-Operatoren && und ||

Beitrag von Xin » Mi Okt 27, 2010 3:34 pm

detewe89 hat geschrieben:Hey ihr!! ;)

So, poste mal wieder hier, hab früher auf tutorials.at ab und zu gepostet^^

Code: Alles auswählen

detewe89 
 
Beiträge: 1
Registriert: 5. Okt 2008 11:07
Ja, dann mal endlich willkommen auf proggen.org, weil ich Dich aus tut.at noch kannte, habe ich Dich trotz der 0 Beiträge noch nicht gelöscht. Ansonsten bin ich nämlich recht zackig, was inaktive User angeht, die nix geschrieben haben. Uservorstellung usw. ist nach zwei Jahren natürlich wieder fällig ;->
detewe89 hat geschrieben:Haben im Studium jetzt mit der Java-Programmierung angefangen, und ich hab eine Frage zum programmiertechnischen Hintergrund zum Unterschied zwischen den logischen Operatoren && und & sowie zwischen || und |.

Ich weiß, dass die Operatoren && und || zu einer "Kurzschlusslogik" führen, das heißt, wenn das Ergebnis nach Auswertung des ersten Operanden schon feststeht, wird die Operation abgebrochen. Damit sollen wohl Fehler verhindert werden à la Nulldivision

Code: Alles auswählen

int t;
// ...
if ( (t != 0) && (5/t < 2) ) { 
   // ...
}
Meine Frage: Wozu braucht es überhaupt die Operatoren, die die ganze Operation ausführen? Ist das nicht überflüssig??
&& und || sind logische Operatoren. Hier gibt es true und false. Darum kann false && ?? nie mehr wahr werden, wie true || ?? nie mehr falsch werden kann. Entsprechend hat es zur Bestimmung des Ergebnisses von || und && keinen Sinn, die zweite Seite zu ermitteln. Das Ergebnis hat man ja bereits.

Bei & und | handelt es sich um berechnende Operatoren, wie es die Addition auch ist.
Hier werden viele Bits miteinander ver"und"et, bzw. ver"oder"t, bzw. exklusiv ver"oder"t. Hier werden also nicht logische Werte (true, false), sondern ganze Zahlen verwurstet. Um ganze Zahlen zu berechnen, muss man natürlich erstmal beide Zahlen haben.

Code: Alles auswählen

  101     101      101
& 110   | 110    ^ 110
-----   ------   -----
  100     111      011
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Benutzeravatar
detewe89
Beiträge: 15
Registriert: So Okt 05, 2008 11:07 am

Re: Short-Circuit-Operatoren && und ||

Beitrag von detewe89 » Mi Okt 27, 2010 4:28 pm

Meine User-Vorstellung werde ich umgehend nachholen!! Find ich jetzt cool, dass sich noch jemand an mich erinnert!

Den Unterschied zwischen logischen und Bitoperationen kenne ich, den gab es ja auch bei C schon.
Bei Java sind die Zeichen ^, & und | definiert als a) Bit-Operatoren und b) als Logische Operatoren!! ^ stellt dabei ein XOR dar (das es ja bei C gar nicht gab).

Wir haben "Informatik" als reine Java-Vorlesung, also leider ohne wirklichen theoretischen Boden... :( Im ersten Programmbeispiel (Berechnung der ersten 1000 Primzahlen) hat der Prof einmal den Operator & und einmal den Operator && genommen - beide Male für logische Operationen, bei denen ein Boole'scher Ausdruck herauskommt. Auf Unterschiede hat er uns nicht hingewiesen Ich liste mal die beiden Beispiele auf

Code: Alles auswählen

//    1. Beispiel
while (!found && index < primes.length) {
			if (primes[index] == number) found = true;
			index++;
}
// ...

//    2. Beispiel
while (notDivisible & (divisor < currentNum)) {
				if ((currentNum % divisor) == 0) notDivisible = false;
				divisor++;
}
// ...
Der Compiler schluckt's.

Mir ist nicht klar wozu der & - Operator überhaupt für logische Operatoren definiert sein muss... Die ShortCircuit-Methode ist doch in jedem Fall ausreichend...

Im Buch "Taschenbuch Programmiersprachen" von Henning/Vogelsang sind die Operatoren auch so aufgelistet. Ich zitiere:
Priorität 7
& Bitweises "Und" zweier ganzzahliger Daten.

& Logische "Und"-Verknüpfung zweier Boole'scher Ausdrücke mit vollständiger Auswertung.
Das Ergebnis wird von links nach rechts ermittelt. Auch wenn das Ergebnis bereits feststeht, werden alle Bedingungen ausgewertet.
(...)

Priorität 4
&& Logisches "Und" zweier Boole'scher Ausdrücke. Die Auswertung erfolgt mithilfe der "Kurzschlusslogik":
Sobald das Ergebnis der Berechnung feststeht, werden die restlichen Bedingungen nicht mehr untersucht.

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8859
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Short-Circuit-Operatoren && und ||

Beitrag von Xin » Mi Okt 27, 2010 4:47 pm

detewe89 hat geschrieben:^ stellt dabei ein XOR dar (das es ja bei C gar nicht gab).
Wer die Mär wohl in die Welt gesetzt hat... sowas erzählte damals einer meiner Profs auch und der hat sich auch geirrt.
PS: Erzählt man euch euch auch noch, dass Java diese gefährlichen Zeiger aus C/C++ nicht mehr hat?
detewe89 hat geschrieben:Wir haben "Informatik" als reine Java-Vorlesung, also leider ohne wirklichen theoretischen Boden... :( Im ersten Programmbeispiel (Berechnung der ersten 1000 Primzahlen) hat der Prof einmal den Operator & und einmal den Operator && genommen - beide Male für logische Operationen, bei denen ein Boole'scher Ausdruck herauskommt. Auf Unterschiede hat er uns nicht hingewiesen
Bitte geh nicht davon aus, dass Du im Studium programmieren beigebracht bekommst. Sowas wird in der Regel vorausgesetzt, auch dann, wenn man zugesichert bekommt, dass man keine Vorkenntnisse braucht. Das kann man sich ja mal an einem Wochenende nebenher aneignen.

Die Verwendung von & bei logischen Werten ist rechnerisch korrekt, aber semantisch falsch. Nur weil ein Programm korrekte Ergebnisse liefert, heißt das nicht, dass es korrekt ist. Nicht jeder Wert, der logisch interpretiert wird/werden soll, ist auch logisch.
detewe89 hat geschrieben:Ich liste mal die beiden Beispiele auf

Code: Alles auswählen

//    1. Beispiel while (!found && index < primes.length) 
Korrekt.
detewe89 hat geschrieben:

Code: Alles auswählen

//    2. Beispiel  while (notDivisible & (divisor < currentNum)) {
Der Compiler schluckt's.
Und es liefert auch das korrekte Ergebnis, denn true(1) & true(1) ergibt true(1) - bei beiden Operatoren.
Trotzdem ist es semantisch falsch, wenn Du bei mir programmieren lernen würdest, würde ich Dir das Programm als falsch zurückgeben.

Beispiel:

Code: Alles auswählen

int a = 2;

if( a && (a < 3) ) printf( "&& ergibt wahr\n" );
if( a & (a < 3) ) printf( "& ergibt wahr\n" );
Die Ausgabe ergibt "&& ergibt wahr", aber die Zeile "& ergibt wahr" fehlt!
a ist 2, (a < 3) ist true, also 1.

Code: Alles auswählen

  10  (2 => true)
& 01 (true)
----
  00 (false)
Hier ergibt sich der semantische Unterschied zwischen && und &.
detewe89 hat geschrieben:Mir ist nicht klar wozu der & - Operator überhaupt für logische Operatoren definiert sein muss... Die ShortCircuit-Methode ist doch in jedem Fall ausreichend...
Und && ist hier auch einzig und allein korrekt. Du willst nicht bitweise verknüpfen, Du willst eine logische Aussage treffen.
Schreibst Du in das Programm dann '&' rein, bedeutet der Algorithmus etwas anderes und kann zufälligerweise das gewünschte Ergebnis liefern - er muss aber nicht. Darum würde aufgrund der Diskrepanz zwischen dem was dein Prof schreiben will (&&) und dem, was er geschrieben hat (&) das Programm von mir als richtig abgelehnt werden.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Benutzeravatar
detewe89
Beiträge: 15
Registriert: So Okt 05, 2008 11:07 am

Re: Short-Circuit-Operatoren && und ||

Beitrag von detewe89 » Mi Okt 27, 2010 5:36 pm

Hm. Also mein Prof meint, Variablen vom Typ boolean werden auch als 32-Bit abgespeichert. Ich geh jetzt mal davon aus, dass TRUE intern als 0xffffffff dargestellt wird und FALSE als 0x00000000. Dann machen die Operationen auch beide komplett Sinn und ergeben keinen Mischmasch. "Vernünftiger" ist aber wohl der &&-Operator...

Danke für die Hilfe! ;) Ich sprech den netten Herren dann mal am Dienstag nach der Vorlesung drauf an.

Daniel

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8859
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Short-Circuit-Operatoren && und ||

Beitrag von Xin » Mi Okt 27, 2010 10:14 pm

detewe89 hat geschrieben:Hm. Also mein Prof meint, Variablen vom Typ boolean werden auch als 32-Bit abgespeichert.
Das ist sehr wahrscheinlich. Im Prinzip brauchst Du nur ein Bit, die Sprache wird das niemals festlegen, ob das Bit in einer 32Bit Variable gespeichert wird oder in einem Char oder in einem Bit.

Um den Zugriff innerhalb einer Struktur schnell zu halten, werden Strukturen in der Regel auf ein Langwort ausgerichtet, was bedeutet, dass ein Bool deswegen in einer 32-Bit Variable (eben ein Langwort) gespeichert.
detewe89 hat geschrieben:Ich geh jetzt mal davon aus, dass TRUE intern als 0xffffffff dargestellt wird und FALSE als 0x00000000. Dann machen die Operationen auch beide komplett Sinn und ergeben keinen Mischmasch. "Vernünftiger" ist aber wohl der &&-Operator...
Üblicherweise wird true als 1 gespeichert, und false als 0.
0 wird als false gewertet, !0 wird als true gewertet.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

MoonGuy
Beiträge: 231
Registriert: Fr Okt 08, 2010 2:49 pm

Re: Short-Circuit-Operatoren && und ||

Beitrag von MoonGuy » Mi Okt 27, 2010 10:18 pm

Xin hat geschrieben:
detewe89 hat geschrieben:Hm. Also mein Prof meint, Variablen vom Typ boolean werden auch als 32-Bit abgespeichert.
Üblicherweise wird true als 1 gespeichert, und false als 0.
0 wird als false gewertet, !0 wird als true gewertet.
Gibt es nicht auch manche Programmierer(oder Programmsprache, nicht sicher bei dem was jetzt kommt), die bool nicht includen und dann eine eigene enum/typedef machen und false als 1 und true als 0? Bzw. es wäre möglich, oder?

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8859
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Short-Circuit-Operatoren && und ||

Beitrag von Xin » Mi Okt 27, 2010 10:25 pm

Wenn jemand es in einer anderen Form formulieren kann, wird es immer auch jemanden geben, der das macht.

FALSE ist in C jedoch nur sinnvoll definiert, wenn es 0 ist, da sonst
if( FALSE )
den then-Part ausführen.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

MoonGuy
Beiträge: 231
Registriert: Fr Okt 08, 2010 2:49 pm

Re: Short-Circuit-Operatoren && und ||

Beitrag von MoonGuy » Mi Okt 27, 2010 10:26 pm

Xin hat geschrieben:Wenn jemand es in einer anderen Form formulieren kann, wird es immer auch jemanden geben, der das macht.

FALSE ist in C jedoch nur sinnvoll definiert, wenn es 0 ist, da sonst
if( FALSE )
den then-Part ausführen.
true

*gg*

Antworten