2013-05-17 4 views
7

I'v einen folgenden Code:ist der Vorrang des Bedieners ignoriert in 'wenn' Bedingungen

void main() 
{ 
    int k, x, y, z; 
    printf("\nExperiment 1:"); 
    x = 0, y = 0, z = 0; 
    k = x++ || y++ && z++; 
    printf("\nx = %d, y = %d, z = %d and k = %d\n", x, y, z, k); 
    printf("\nExperiment 2:"); 
    x = 1, y = 0, z = 0; 
    k = x++ || y++ && z++; 
    printf("\nx = %d, y = %d, z = %d and k = %d\n", x, y, z, k); 
} 

Der Ausgang:

Experiment 1: x = 1, y = 1, z = 0 und k = 0

Experiment 2: x = 2, y = 0, z = 0 und k = 1

Was ich verstanden ist: für den Ausdruck um wahr zu sein, entweder linke Seite oder rechte Seite von '||' muss nicht Null sein. Es beginnt von links. Wenn left nicht Null ist, wird es nicht weiter ausgewertet. Wenn es Null ist, beginnt es auf der rechten Seite. Auf der rechten Seite haben wir '& &'. Also, wir starten wieder von der linken Seite & & und wenn es Null ist, kann der Ausdruck nicht wahr sein und es wird nicht fortgesetzt. Andernfalls wertet er die rechte Seite des ‚& &‘

Meine Vermutung war Betreiber & & höhere Priorität hat. Daher sollten beide Argumente ausgewertet worden sein, und dann sollte & & darüber angewendet worden sein, gefolgt von der Auswertung beider Argumente von ||.

Wird der Compiler selbst optimiert? Ich habe Visual Studio TC Compilar mit deaktivierter Optimierung verwendet.

+5

Diese sind übrigens nicht "wenn Bedingungen". Sie sind einfache Ausdrücke, die Boolesche Operatoren und Post-Inkrement-Operatoren verwenden. – unwind

+3

Nur weil && eine engere Priorität hat, heißt das nicht: k = x ++ || (y ++ && z ++) 'führt das && vor dem || aus. Dies wird als Kurzschluss bezeichnet und ist sehr gut bekannt. Sie erwähnen es sogar selbst. Stellen Sie sich vor: 'k = x ++ || f (& y, & z) 'wobei f() '(* y) ++ && (* z) ++' zurückgibt. Es ist funktional äquivalent zu Ihrem Code. – Matthias

+0

@Matthias: tatsächlich; '++' hat eine noch höhere Priorität als '&&'; wir erwarten nicht, dass das Post-Inkrementieren vor allem anderen auftritt, nur wegen der Priorität ... – geoffspear

Antwort

9

Ich denke, das durch §6.5.14 Logical OR operator in C11 bedeckt ist (Hervorhebung von mir)

Im Gegensatz zum bitweise | Betreiber, die || Betreibergarantien Bewertung von links nach rechts; Wenn der zweite Operand ausgewertet wird, gibt es einen Sequenzpunkt zwischen den Auswertungen des ersten und zweiten Operanden . Wenn der erste Operand ungleich 0 vergleicht, wird der zweite Operand nicht ausgewertet.

4

So ist der Ausdruck

k = x++ || y++ && z++; 

als (aufgrund Vorrangregeln) interpretiert:

k = x++ || (y++ && z++); 

In Experiement 1, wir x = y = z = 0; haben.

In Experiment 2 haben wir x = 1, y = z = 0;.

Also, der Ausdruck auf der rechten Seite stoppt nach der Auswertung y++, da der Wert von diesem 0 ist und somit der Boolean und kann nicht wahr werden.

Verwandte Themen