Beeinflusst der Vergleichsoperator die Operationen von Zuweisungsoperatoren?

Lesezeit: 5 Minuten

Benutzer-Avatar
duslabo

Warum die Ausgabe des unten genannten Programms ist 0 nicht 20 ?

#include <stdio.h>

int main()
{
    int i = 10, j = 0;
    if (i || (j = i + 10))
       /* do something */;                
    printf("%d\n",j);
}

  • Kurzgeschlossener boolescher Ausdruck.

    – jxh

    19. Juli 2013 um 8:01 Uhr

  • Dies mag wie eine dumme Frage erscheinen, aber ich lerne – wie könnte das Programm jemals 20 ausgeben? Hat es etwas speziell mit C zu tun?

    – Andy

    19. Juli 2013 um 16:36 Uhr

  • @Andy (1)–program könnte ausgeben 20nur wenn i = 0 (die Änderung zum Ausführen des Ausdrucks geben j = i + 10). (2) Nein, dieser Code ist in C++ gültig, sogar in Java, weil wir beides tun können = innerhalb if() und beide unterstützen Kurzschluss. — Es wäre interessant zu wissen, dass sogar Python Kurzschluss unterstützt, aber diesen Ausdruck if (i || (j = i + 10)) ist in Python nicht gültig, weil = in if ist Syntaxfehler.

    – Grijesh Chauhan

    19. Juli 2013 um 16:43 Uhr


  • @ Andy ja, und du weißt schon, na ? dass irgendjemand non-0 Wert ist true in C und so i (=10) ist ture.

    – Grijesh Chauhan

    19. Juli 2013 um 16:53 Uhr

  • @JeshwanthKumarNK Das habe ich in meiner Antwort hinzugefügt || und && Operatoren führt Sequenzpunkt so ein ++i || ++i ist kein undefiniertes Verhalten 🙂 wohingegen ++i | ++i ist undefiniert 🙁 . verstanden?

    – Grijesh Chauhan

    25. Juli 2013 um 9:17 Uhr


Benutzer-Avatar
Grijesh Chauhan

Ja, das Konzept heißt Kurzschluss (im logischen &&, || Operatorausdruck).

Im Falle eines logischen Ausdrucks (inkl ||, &&) Compiler stoppt den Auswertungsausdruck, sobald das Ergebnis ausgewertet wird (und speichert Ausführungen).

Die Technik für Kurzschluss ist:

!0 || any_expression == 1Also any_expression nicht auswerten müssen.

Und weil in Ihrem Ausdruck i ist nicht null, sondern 10, also können Sie denken, wenn Bedingung (i || (j = i + 10)) genauso wie i.

Logischer ODER-Operator:

Das || Operator garantiert Links-nach-Rechts-Auswertung; es gibt einen Sequenzpunkt nach der Auswertung des ersten Operanden. Wenn der erste Operand vergleicht unequal zu 0der zweite Operand ist not
ausgewertet.

Ähnlich für && (and-Operator):
0 && any_expression == 0Also any_expression nicht auswerten müssen.

In deinem Ausdruck:

(i || (j = i + 10) )
      ------------
       ^
       | Could evaluate if i is 0, 
       as i = 10 (!0 = true), so j remains unchanged as second operand is not evaluated

Für oder || Die Antwort des Bedieners kann entweder 0 oder 1 sein. Um die Ausführung zu speichern, stoppt die Auswertung, sobald Ergebnisse gefunden werden. Wenn also der erste Operand ungleich Null ist, wird das Ergebnis sein 1 (wie oben) für den Ausdruck. Also für den ersten Operanden i = 10 vergleicht ungleich 0, dem zweiten Operanden (j = i + 10) wird nicht so bewertet j Überreste 0 daher ist die Ausgabe Ihres Codes 0.

Hinweis: Das Kurzschlussverhalten ist nicht nur in C vorhanden, sondern das Konzept ist vielen Sprachen wie Java, C++ und Python gemeinsam. (aber nicht alle zB VB6).

In C war das Kurzschließen von logischen Ausdrücken garantiert schon immer ein Merkmal von C. Es war wahr, als Dennis Ritchie die erste Version von C entwarf und implementierte, immer noch wahr im C-Standard von 1989 und bleibt wahr im C99-Standard.

Ein verwandter Beitrag: Ist das Kurzschließen boolescher Operatoren in C/C++ vorgeschrieben? Und Auswertungsreihenfolge?

  • Ehrlich gesagt, viel zu lange Antwort.

    – Antonio

    19. Juli 2013 um 8:28 Uhr

  • “Im Falle eines logischen Ausdrucks stoppen die meisten Compiler den Auswertungsausdruck, sobald das Ergebnis ausgewertet wird (um Ausführungen zu sparen).” – Nein, es ist nicht vorbei “die meisten Compiler”sondern durch alle die sich C-Compiler nennen, weil es der Standard vorschreibt. Meistens geht es also nicht nur um die Leistung, sondern um die Korrektheit, z. B. denken Sie darüber nach while(node && node->value)was furchtbar falsch wäre, wenn der Standard dies nicht tun würde Garantie kurzschließen.

    – Christian Rau

    19. Juli 2013 um 9:42 Uhr

  • @GrijeshChauhan Sie könnten damit nicht einverstanden sein (nur das Standardkomitee kann das beantworten und Sie könnten sehr wohl Recht haben mit dem ursprünglichen Zweck). Dem können Sie jedoch auf keinen Fall widersprechen “die meisten Compiler” tun dies, aber alle. Ein Compiler, der dies nicht tut, ist kein C-Compiler und es wäre wie so etwas wie = oder + nicht wie erwartet funktionieren würde, können Sie sich nicht darauf verlassen, dass irgendein Code mit einem solchen Compiler funktioniert. So wie es aussieht, klingt Ihre Antwort so, als wäre dies nur eine Optimierung der Compiler-Implementierung nicht der Fall.

    – Christian Rau

    19. Juli 2013 um 9:51 Uhr


  • @Grijesh: Sie müssen diesen Satz nur präzisieren, damit die Leute beim Lesen Ihrer Antwort keine falsche Vorstellung bekommen. Sie sehen, dass bereits zwei Personen Ihre Antwort missverstanden haben. Eines der großartigen Dinge an SO ist, dass Antworten immer möglich sind verbessert.

    – PaulR

    19. Juli 2013 um 10:14 Uhr

  • Danke, es ist nicht mehr irreführend, +2.

    – Christian Rau

    19. Juli 2013 um 11:22 Uhr

|| ist ein Kurzschluss -Operator – Wenn die linke Seite als wahr ausgewertet wird, muss die rechte Seite nicht ausgewertet werden. Also, in Ihrem Fall seit i ist dann der Ausdruck wahr j = i + 10 wird nicht ausgewertet. Wenn Sie einstellen i auf 0 aber dann die rechte Seite Wille bewerted werden,

  • Ist diese Funktion vom Compiler abhängig?

    – nj-ath

    19. Juli 2013 um 16:20 Uhr

  • @TheJoker Nein, in C ist das Kurzschließen logischer Ausdrücke garantiert schon immer ein Merkmal von C.

    – Grijesh Chauhan

    19. Juli 2013 um 16:25 Uhr

Im if (i || (j = i + 10)), müssen zwei boolesche Ausdrücke ausgewertet werden. Die Sache ist, dass die erste wahr ist, daher besteht keine Notwendigkeit, die zweite zu berechnen. Es wird einfach ignoriert.

Benutzer-Avatar
tczf

Weil || ist ein Kurzschlussoperator (so ist die && Operator).

also rein (i || j = i+10), i ist 10, linker Teil von || stimmt, der Ausdruck j = i+10 ist nicht passiert, infolgedessen j=0.

1090290cookie-checkBeeinflusst der Vergleichsoperator die Operationen von Zuweisungsoperatoren?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy