2010-02-03 20 views
6

Betrachten Sie das follwoing Fragment:Zweifel bezüglich Operatoren in C/C++/Java

int a,b; 
a = 1; 
b = 2; 

c = a++++b; // does not work!! Compilation error. 
c = a++*+b; // works !! 

Bitte helfen Sie mir, dieses Verhalten zu verstehen.

+4

"Funktioniert nicht" ist unzuverlässig. Es nimmt an, dass es eine erwartete Ausgabe gibt, die "funktioniert", und eine tatsächliche Ausgabe, die "nicht funktioniert" darstellt, und Sie haben es auch nicht geschafft. –

+6

Was ist der Sinn? – Art

Antwort

30
c = a++++b; 

wird behandelt wie:

c = ((a++)++)b; 

die, wie Sie Nicht-L-Wert versuchen, falsch ist zu erhöhen.

und

c = a++*+b; 

wird behandelt, als:

c = (a++)*(+b); 

Die Ursache für dieses Verhalten ist: Die Sprache C lexikalischer Analysator greedy.

Im Fall 1: Nach dem Token 'a' (Bezeichner) sieht der Lexer +, gefolgt von einem anderen +, so dass er beide (als Inkrementoperator) als Teil desselben Tokens verbraucht. Es macht nicht den 3. + Teil des gleichen Tokens wie +++ ist kein gültiges Token. Ebenso es Gruppen die nächsten zwei + in ++ Token macht es effektiv gleiche wie:

c = ((a++)++)b; 

, die nicht korrekt als ++ wird nicht lvalue zurückkehren, daher können Sie keine ++ auf sie anwenden. Etwas Ähnliches wie 5 ++ zu sagen;

Aber in Fall2: das erste Paar von ++ wird zusammen gruppiert (als Inkrement-Operator). Als nächstes wird das * alleine ein Token sein, da Sie es nicht mit einem + kombinieren können, da * + kein gültiges Token ist. Schließlich wird die + ein Token (als einstellige +) effektiv macht Ihre Aussage:

c = (a++)*(+b); 

Sie können dieses gierige Verhalten der Lexer außer Kraft setzen durch die Verwendung von Klammern oder Leerzeichen zu machen, wie folgt:

c = a++ + +b; 
c = a++ * +b; 
+1

Danke Codeaddict für die ausführliche Erklärung. Immer wenn die Gruppierung der Operatoren zweifelhaft wird, werde ich diese Max-Munching-Regel anwenden. – Zacky112

7

Dies ist effektiv, weil der "maximum munch rule" in C.

c = a++++b; 

als c = a++ ++ b; geparst, die Syntaxfehler ist.

c = a++*+b; 

als c = a++ * +b; analysiert, was in Ordnung ist.

Vom C99 Entwurf, Abschnitt 6.4p4 (Hervorhebung von mir):

Wenn der Eingangsstrom in der Vorverarbeitung auf einen bestimmten Charakter-Token bis analysiert wurde, ist die nächste Vorverarbeitung Token die längste Folge von Zeichen das könnte ein Vorverarbeitungstoken darstellen.

+0

Danke Alok für die Referenz und die Erklärung. – Zacky112

0

operator precedence. ++ hat eine hohe Priorität als Binär +.

+2

Ich sehe nicht, wie es Betreiber Vorrang haben könnte. –

+0

c = a ++ + + b; ist in Ordnung, aber wenn Sie Leerzeichen entfernen, stellt sich heraus, dass es sich um einen ungültigen Lvalue-Fehler handelt. – bhups

+0

Ich vermute ich habe das Problem falsch verstanden. Danke für die Erklärung. – bhups

0

Vorbedingung von ++ ist gleich der Vorbedingung von +. Wir benutzen also von links nach rechts.

1

Aus dem gleichen Grund, warum wir einen Fehler in der C++ erhalten für:

vector<vector<int>>; 

Die >> wird als ein Operator behandelt werden.