6 Stimmen

Warum ist die Ausgabe im Fall von &&, &, || anders?

Hier sind die Code-Segmente

Kannst du erklären, warum die Ausgaben variieren?

1)

public static ShortCkt {
    public static void main(String args[]) {
        int i = 0;
        boolean t = true;
        boolean f = false, b;
        b = (t && ((i++) == 0));
        b = (f && ((i+=2) > 0));
        System.out.println(i);      
    }
}

Die Ausgabe in diesem Fall ist 1

2)

public static ShortCkt {
    public static void main(String args[]) {
        int i = 0;
        boolean t = true;
        boolean f = false, b;
        b = (t & ((i++) == 0));
        b = (f & ((i+=2) > 0));
        System.out.println(i);      
    }
}

Die Ausgabe in diesem Fall ist 3

3)

public static ShortCkt {
    public static void main(String args[]) {
        int i = 0;
        boolean t = true;
        boolean f = false, b;
        b = (t || ((i++) == 0));
        b = (f || ((i+=2) > 0));
        System.out.println(i);      
    }
}

Die Ausgabe in diesem Fall ist 2

4)

public static ShortCkt {
    public static void main(String args[]) {
        int i = 0;
        boolean t = true;
        boolean f = false, b;
        b = (t | ((i++) == 0));
        b = (f | ((i+=2) > 0));
        System.out.println(i);      
    }
}

Die Ausgabe in diesem Fall ist 3

12voto

aioobe Punkte 397211

Warum ist die Ausgabe bei &&, &, || anders?

Genau wie in C/C++ wird && "träge" ausgewertet, während & das nicht tut.

Wenn a falsch ist, wird a && b false zurückgeben, ohne b überhaupt auszuwerten.

Gleiches gilt für a || b: Wenn das erste Operand, a, wahr ist, ist der gesamte Ausdruck wahr und der zweite Operand, b, wird nie ausgewertet. Bei a | b jedoch werden sowohl a als auch b ausgewertet.

Das hat Konsequenzen, wenn der Operand, der nicht ausgewertet wird bei Verwendung von && (oder ||) Seiteneffekte hat, wie in deinen Beispielen.


Notiz: Wenige Java-Programmierer wissen, dass ^ (xor) auch für Booleans funktioniert. (Eine ^^ Version existiert einfach nicht, weil sie redundant wäre.)

7voto

polygenelubricants Punkte 362173

Es gibt 4 boolean binäre Operatoren, die uns hier interessieren:

  • && ist der bedingte und Operator
    • & ist der logische und Operator
  • || ist der bedingte oder Operator
    • | ist der logische oder Operator

Hier ist der Schlüsselpunkt:

  • "bedingt" bedeutet, dass es kurzschließt: Es bewertet den rechten Operanden nicht, wenn er das Ergebnis der Operation nicht beeinflusst
  • "logisch" schließt nicht kurz: Es bewertet beide Operanden, zuerst links, dann rechts.
  • Das Ergebnis von "und" ist nur true, wenn beide Operanden true sind
    • Wenn der linke Operand false ist, ist das Ergebnis unabhängig vom rechten Operanden false
  • Das Ergebnis von "oder" ist nur true, wenn mindestens ein Operand true ist
    • Wenn der linke Operand true ist, ist das Ergebnis unabhängig vom rechten Operanden true

Anders ausgedrückt, unter der Annahme, dass keine Ausnahme etc. vorliegt:

  • & und | bewerten immer beide Operanden
  • && und || bewerten den rechten Operanden bedingt; der rechte Operand wird nur bewertet, wenn sein Wert das Ergebnis der binären Operation beeinflussen könnte. Das bedeutet, dass der rechte Operand NICHT bewertet wird, wenn:
    • Der linke Operand von && zu false auswertet
      • (weil unabhängig davon, was der rechte Operand auswertet, der gesamte Ausdruck false ist)
    • Der linke Operand von || zu true auswertet
      • (weil unabhängig davon, was der rechte Operand auswertet, der gesamte Ausdruck true ist)

Referenzen

Siehe auch

Verwandte Fragen

1voto

Dave McClelland Punkte 3325

&& und || sind die logischen UND- und ODER-Operatoren, sie ergeben immer einen boolean Ausdruck. & und | sind bitweise UND- und ODER-Operatoren, sie führen eine bitweise Vergleich jeder Seite durch. Für mehr Informationen darüber, was diese Operatoren bewirken, siehe diesen Link

1voto

Polymorphix Punkte 1038

Dies liegt daran, dass && und || logische Operatoren sind, die einen "Short-Circut-Mechanismus" verwenden. Wenn Sie || verwenden und der erste Ausdruck zu true evaluiert wird, wird der zweite nicht evaluiert und daher wird i nicht aktualisiert. & und | sind bitweise Operatoren, die Bitberechnungen auf dem Eingang durchführen. Diese haben keinen Short-Circut und daher wird der gesamte Ausdruck unabhängig davon ausgewertet.

1voto

Mark Elliot Punkte 71774

Die & und | Operatoren sind bitweise und müssen daher beide Seiten des Ausdrucks ausgewertet haben, bevor der Operator verwendet werden kann, daher werden in den Fällen 2 und 4 beide Seiten des Operators immer ausgewertet.

Der Unterschied zwischen den Fällen 1 und 3 basiert auf der Kurzschlusslogik.

Im Fall 1 verkürzt der && Operator im zweiten Ausdruck bei false auf das erste false, wodurch die zweite Hälfte des Ausdrucks nicht ausgewertet wird.

In Fall 3 führt das false in der ersten Hälfte des zweiten Ausdrucks zur Auswertung der zweiten Hälfte des Ausdrucks und zur Inkrementierung von i. false || expr kann nur false sein, wenn auch expr falsch ist (also muss es ausgewertet werden).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X