2013-07-19 4 views
16

Warum ist der Ausgang des unten erwähnten Programms 0 nicht 20?Beeinflusst der relationale Operator die Operationen des Zuweisungsoperators?

#include <stdio.h> 

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

Kurzgeschlossener boolescher Ausdruck. – jxh

+1

Das 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

+1

@Andy ** (1) ** - Programm könnte "20" ausgeben, nur wenn "i = 0" (das gibt die Änderung, um Ausdruck "j = i + 10" auszuführen). ** (2) ** Nein, dieser Code ist in C++ gültig, sogar in Java, weil wir '' '' in 'if()' tun können und beide einen Kurzschluss unterstützen. --- Es wäre interessant zu wissen, auch [Python unterstützt Kurzschluss] (http://stackoverflow.com/questions/2580136/does-python-support-short-circuiting/14892812#14892812) aber dieser Ausdruck 'if (i || (j = i + 10)) 'ist in Python nicht gültig, weil' = 'in' if' ein Syntaxfehler ist. –

Antwort

27

Ja, das Konzept Short-Circuit genannt (in logische &&, || Operatoren Ausdruck).

Bei jedem logischen Ausdruck (einschließlich ||, &&) beendet der Compiler den Auswertungsausdruck, sobald das Ergebnis ausgewertet wurde (und speichert die Ausführungen).

Die Technik für Kurzschluss:

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

Und weil in Ihrem Ausdruck i ist nicht Null, sondern seine 10, so können Sie denken, wenn consition (i || (j = i + 10)) genauso wie i.

Logical OR-Operator:
Die || Betreiber garantiert, von links nach rechts Bewertung; Nach der Auswertung des ersten Operanden gibt es einen Sequenzpunkt. Wenn der erste Operand unequal mit 0 vergleicht, wird der zweite Operand not ausgewertet.

Ebenso für & & (und Betreiber):
0 && any_expression == 0, so any_expression nicht auswerten müssen.

In Ihrem 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 || Antwort Operator kann entweder 0 sein, 1. Ausführung zu speichern, Auswertung wird beendet, sobald Ergebnisse finden. Wenn also der erste Operand nicht Null ist, wird das Ergebnis 1 (wie oben) für den Ausdruck sein. Also für den ersten Operanden i = 10 vergleicht ungleich 0, der zweite Operand (j = i + 10) wird nicht ausgewertet, so j bleibt 0 daher Ausgabe Ihres Codes ist 0.

Hinweis: Kurzschlussverhalten ist nicht nur in C vorhanden, sondern ist in vielen Sprachen wie Java, C++, Python üblich. (aber nicht alle beispielsweise VB6).

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

Ein verwandtes Beitrag: Is short-circuiting boolean operators mandated in C/C++? And evaluation order?

+9

Ehrlich gesagt, viel zu lange Antwort. – Antonio

+9

* "Im Falle eines logischen Ausdrucks stoppen die meisten Compiler den Auswertungsausdruck, sobald das Ergebnis ausgewertet wurde (um die Ausführung zu speichern)." * - Nein, es wird nicht von * "den meisten Compilern" * ausgeführt, sondern von * all * nennen sich C-Compiler, weil es vom Standard vorgeschrieben ist. In den meisten Fällen dient dies nicht nur der Leistung, sondern auch der Korrektheit, z. Denken Sie an 'while (node ​​&& node-> value)', was furchtbar falsch wäre, wenn der Standard * keine * Kurzschlüsse garantiert hätte. –

+1

@ChristianRau Ich stimme dir nicht zu. Ursprünglicher Zweck des Kurzschlusses, um Leistung zu erhalten. Und ich verstehe 'while (node ​​&& node-> value) 'seinen zweiten Vorteil des Kurzschlusses. –

20

|| ist ein short-circuit Operator - wenn die linke Seite true ergibt dann die rechte Seite nicht ausgewertet werden muss. Also, in Ihrem Fall, da i wahr ist, dann wird der Ausdruck j = i + 10 nicht ausgewertet. Wenn Sie setzen i-0 jedoch dann die rechte Seite wird ausgewertet werden,

+0

ist das Feature Compiler abhängig? –

+3

@TheJoker Nein, in C Kurzschluss von logischen Ausdrücken ist garantiert immer ein Merkmal von C. –

+1

@paul Vielen Dank :) –

5

In if (i || (j = i + 10)) gibt es zwei boolean Ausdruck auszuwerten. Die Sache ist, die erste ist wahr, daher ist es nicht nötig, die zweite zu berechnen. Es wird nur ignoriert.

3

weil || ist ein Kurzschluss-Operator (so ist der && Operator).

so in (i || j = i+10), i 10, linken Teil der || wahr ist, hat der Ausdruck j = i+10 nicht passieren, als Folge, j=0.

Verwandte Themen