Hallo zusammen!
Zu dem Code unten habe ich folgende Frage:
Was passiert in der Zeile *PtrSPI_RecBuff++ = UCB1RXBUF ?
Wird hier UCB1RXBUF der Variable zugewiesen, auf die PtrSPI_RecBuff
zeigt und der Zeiger anschließend inkrementiert. Oder passiert da was
anderes?
Nimm eine andere Tabelle, z.B. diese hier:
http://www.difranco.net/cop2220/op-prec.htm
Da hat der Postfixinkrementoperator Vorrang vor dem Verweisoperator.
*ptr++ ist also das Gleiche wie *(p++).
noips schrieb:
> Hallo zusammen!>> Zu dem Code unten habe ich folgende Frage:>> Was passiert in der Zeile *PtrSPI_RecBuff++ = UCB1RXBUF ?>> Wird hier UCB1RXBUF der Variable zugewiesen, auf die PtrSPI_RecBuff> zeigt und der Zeiger anschließend inkrementiert. Oder passiert da was> anderes?>>
>while(UCB1STAT&UCBUSY);// wait until char is received
8
>*PtrSPI_RecBuff++=UCB1RXBUF;
9
>}
10
>
Wäre wohl besser die beiden Operationen auseinander zu ziehen. Zum einen
liest sich das besser. Zum anderen weiß man dann auch, was gemacht wird.
Also:
*PtrSPI_RecBuff = UCB1RXBUF;
PtrSPI_RecBuff++;
Wer weiß, was der Compiler interpretiert..??
Daniel V. schrieb:
> Wäre wohl besser die beiden Operationen auseinander zu ziehen. Zum einen> liest sich das besser.
Ist Ansichtssache
> Zum anderen weiß man dann auch, was gemacht wird.
Ist Übungssache, bzw. kennen der entsprechenden Bestimmungen.
> *PtrSPI_RecBuff = UCB1RXBUF;> PtrSPI_RecBuff++;>> Wer weiß, was der Compiler interpretiert..??
Der Compiler 'interpretiert' das hinein, was ihm die genormten
Sprachregeln vorschreiben. Kennt man die Regeln, dann weiß man auch, wie
so etwas zu lesen ist. Ganz einfach :-)
Nicht falsch verstehen. Ich bin ein großer Verfechter der einfachen
Schreibweise. Aber gerade C hat ein paar nette Dinge, die einem den Code
bei minimal schlechterer Detail-Lesbarkeit kürzer und übersichtlicher
machen.
Yalu X. schrieb:
> Nimm eine andere Tabelle, z.B. diese hier:>> http://www.difranco.net/cop2220/op-prec.htm>> Da hat der Postfixinkrementoperator Vorrang vor dem Verweisoperator.> *ptr++ ist also das Gleiche wie *(p++).
Das ist jetzt leider falsch.
Auch diese Tabelle ist so zu lesen, daß alle Operatoren von ++
bis sizeof gleiche Priorität haben.
Sie stehen nur aus Platzgründen nicht nebeneinander, sondern
übereinander.
++ und * (als Dereferenzierung) haben GLEICHE Priorität,
da gibt es kein Vertun.
Daß *p++ gleichbedeutend ist mit *(p++) liegt daran, daß
die Operatoren dieser Gruppe von rechts her zusammengefasst
werden.
Klaus Wachtler schrieb:
> Yalu X. schrieb:>> Nimm eine andere Tabelle, z.B. diese hier:>>>> http://www.difranco.net/cop2220/op-prec.htm>>>> Da hat der Postfixinkrementoperator Vorrang vor dem Verweisoperator.>> *ptr++ ist also das Gleiche wie *(p++).>> Das ist jetzt leider falsch.
Klaus, hast du zufällig eine 'offizielle Operator Precedence Table'
irgendwo rumliegen?
Hier
http://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B
ist es nämlich auch so, dass postfix ++ und -- höhere Priority haben als
die präfix Formen.
Würde mich jetzt interessieren, was die offizielle Stellung dazu ist.
Da wir uns hier in den beiden obersten Prioritätenklassen bewegen, wird
es wohl in der Praxis keinen Unterschied machen. Zumindest ist es mir in
ein paar Minuten nicht gelungen ein Beispiel zu konstruieren, bei dem es
einen Unterschied gäbe.
Ob die beiden in der gleichen Prioritätsklasse stehen, oder ob man
daraus getrennte Klassen macht, ist effektiv egal. Denn die stets mit
angebenene Assoziativität stellt klar, dass hier "rechts vor links"
gilt.
Somit sind beide Darstellungen korrekt, aber diejenige mit getrennten
Klassen für * und ++-postfix sind leichter verständlich. Und für
besondere Klarheit und Präzision ist die K&R-Referenz nicht bekannt.
A. K. schrieb:
> Somit sind beide Darstellungen korrekt, aber diejenige mit getrennten> Klassen für * und ++-postfix sind leichter verständlich.
So sehe ich das auch.
Also sind wir ohnehin alle derselben Meinung :-)
Klaus Wachtler schrieb:
> Aber ich habe den Verdacht, daß man Fälle konstruieren kann,> wo es einen Unterschied zwischen C und C++ gibt.
Wie eben beschrieben hat sich nicht das Verhalten verschoben, sondern
die Spezifikation wurde so gestaltet, dass man solche Diskussionen wie
diese hier nicht mehr führen muss.
Karl heinz Buchegger schrieb:
> Klaus, hast du zufällig eine 'offizielle Operator Precedence Table'> irgendwo rumliegen?
Es gibt keine, zumindest nicht im C99-Standard. Stattdessen sind dort
Priorität und Assoziativität der Operatoren folgendermaßen definiert:
1
The grouping of operators and operands is indicated by the syntax.⁷¹⁾
In der Fußnote ist das genauer erläutert:
1
71) The syntax specifies the precedence of operators in the evaluation
2
of an expression, which is the same as the order of the major
3
subclauses of this subclause, highest precedence first.
4
[…]
5
Within each major subclause, the operators have the same precedence.
6
Left- or right-associativity is indicated in each subclause by the
7
syntax for the expressions discussed therein.
Zwei unäre Präfixoperatoren op1 und op2 übereinander liegender Priori-
tätsebenen werden in der Grammatik folgendermaßen dargestellt (für Post-
fix- und binäre Operatoren entsprechend):
b :
a
op1 bc :
b
op2 c
Für binäre Operatoren op1 und op2 innerhalb einer Prioritätsebene wird
die Assoziativität folgendermaßen dargestellt:
linksassoziativ:
b :
ab op1 ab op2 a
rechtsassoziativ:
b :
aa op1 ba op2 b
Da eine entsprechende Darstellung für unäre Operatoren nicht möglich ist
(mir fällt zumindest spontan keine Lösung ein), haben die Standardiseure
zwischen primary-expression und unary-expression ein weiteres
Nichtterminalsymbol (und damit eine weitere Prioritätsebene) namens
postfix-expression eingefügt, so dass die Grammatik vereinfacht¹
folgendermaßen aussieht:
postfix-expression :
primary-expressionpostfix-expression ++
...
unary-expression :
postfix-expression
* unary-expression
...
Damit ist die Auswertereihenfolge von * (Dereferenzierung) und ++ (Post-
inkrement) formal über die Priorität und nicht über die Assoziativität
geregelt, was aber in der Anwendung keinen Unterschied macht. Deswegen
sind zwei unterschiedliche Operatortabellen im Umlauf, die aber letzt-
endlich äquivalent sind.
¹) Ich habe der Übersichtlichkeit halber die Ebene cast-expression
weggelassen.