2014-10-19 8 views
6

I ein Stück Code in C als gegeben folgt:Errors ternären Operators in C unter Verwendung von

main() 
{ 
    int a=10, b; 
    a>=5 ? b=100 : b=200 ; 
    printf("%d" , b); 
} 

den Code auf gcc Compiler in UNIX läuft die Fehler bei der Kompilierung als ‚erzeugt lvalue als linker Operand erforderlich der Zuweisung und zeigt den Fehler bei b = 200, während in Windows Compiling mit Turbo C gibt 200 als Ausgabe.

Kann mir bitte jemand erklären, was genau in diesem Fall passiert?

+6

Verwenden Sie Klammern die Operatorpräzedenz Sie wollen zu klären. (Und nicht Turbo C. Es ist über 20 Jahre alt!) –

+1

http://stackoverflow.com/questions/12068118/use-of-brackets-in-expression-that-include-ternary-operator –

Antwort

-7

Versuchen Sie diese! Da der ternäre Operator den Wert zurückgibt, müssen Sie ihn an b übergeben!

#include <stdio.h> 

main() { 

    int a = 10, b; 
    b = a >= 5 ? 100 : 200; 
    printf("%d" , b); 

} 
+0

Dank .. aber meine Frage war über die unterschiedliche Antwort des gleichen Codes in zwei verschiedenen Compilern. Kannst du bitte diesen Punkt erläutern? Vielen Dank nochmal :) – user3778845

+3

@ Rizier123: es ist nicht undefiniert. –

2

können Sie es in Klammern setzen für sie zu arbeiten .. wie

(a>=5)?(b=100):(b=200); 

und bitte einen Rückgabetyp für Ihre Funktion main()

14

In C der ternäre Operator ist wie

definiert zuweisen

Logischer-OR-Ausdruck? Expression: bedingtem-expression

wo Bedingungsausdruck ist wie

logical-OR-expression 

Der Zuweisungsoperator hat eine niedrigere Priorität als die OR-Operator definiert. So müssen Sie

a >= 5 ? b = 100 : (b = 200); 

Andernfalls wird der Compiler schreiben consideres der Ausdruck wie

(a >= 5 ? b = 100 : b) = 200; 

Als Ergebnis der ternäre Operator in C kein L-Wert ist dann der obige Ausdruck ist ungültig und der Compiler eine entsprechende Error.

Vom C Standard:

das Ergebnis der Wert der zweiten oder dritten Operanden (je nachdem, welche ausgewertet wird), umgerechnet auf die unten

beschriebene Art

und Fußnote:

110) Ein bedingter Ausdruck liefert keinen Lvalue.

Berücksichtigen Sie, dass es einen wesentlichen Unterschied zwischen der Operatordefinition in C und C++ gibt. In C++ ist es definiert als

Logical-oder-Ausdruck?Expression:Zuweisungsausdruck

In C++ die gleiche GCC kompiliert den Code erfolgreich

#include <iostream> 

int main() 
{ 
    int a = 10, b; 

    a >= 5 ? b = 100 : b = 200; 

    std::cout << "b = " << b << std::endl; 

    return 0; 
} 
+0

Danke :-) ... – user3778845

+0

Ist das nicht die Frage? Habe ich falsch damit geschlossen ?: http://stackoverflow.com/a/6966331/1275169 –

+0

@Blue Moon Wenn ich mich in diesen Fragen nicht irre, werden verschiedene Teile des Betreibers berücksichtigt. Also ich denke, sie hängen sich aneinander an. –

1

Dieser Fehler wird durch die Syntax des Bedingungsausdrucks bewirkt wird, welches

logical-OR-expression ? expression : conditional-expression 

Deshalb der Teil nach : muss b = 200 parsen können. Allerdings conditional-expression kann das nicht analysieren, da ein Zuweisungsausdruck weniger Vorrang hat - man braucht eine Klammer um den Zuweisungsausdruck

a>=5 ? b=100 : (b=200); 

Aber die Tatsache zu stellen, dass Sie eine Klammer brauchen hier nicht nicht bedeuten, dass der Ausdruck andernfalls wird als (a>=5 ? b=100 : b) = 200 geparst, es ist nur ein interner Artefakt des Compilers, der in der Fehlermeldung über den linken Operanden der Zuweisung spricht. Die Sprache C hat die folgenden zwei Regeln für die Zuweisung Ausdruck Syntax und die Regel, die angewendet wird

Spiele
conditional_expression 
unary_expression '=' assignment_expression 

Dies stört Rekursiver Abstieg, die einfach parseConditionalExpression aufrufen würde, und überprüfen, was Token folgt. Daher wählen einige C-Parser-Implementierungen hier keinen Syntaxfehler aus, sondern parsen es, als ob die Grammatik oben und später, wenn der Syntaxanalysebaum untersucht wird, validiere, dass die linke Seite ein L-Wert ist. Zum Beispiel sagt die Clang Quellcode

/// Note: we diverge from the C99 grammar when parsing the assignment-expression 
/// production. C99 specifies that the LHS of an assignment operator should be 
/// parsed as a unary-expression, but consistency dictates that it be a 
/// conditional-expession. In practice, the important thing here is that the 
/// LHS of an assignment has to be an l-value, which productions between 
/// unary-expression and conditional-expression don't produce. Because we want 
/// consistency, we parse the LHS as a conditional-expression, then check for 
/// l-value-ness in semantic analysis stages. 

und den Quellcode des GCC-Parser sagt

/* ... 
In GNU C we accept any conditional expression on the LHS and 
diagnose the invalid lvalue rather than producing a syntax 
error. */