Hallo,
ich habe versucht folgenden Quellcode im AVR-Studio zu simulieren.
Aber die Variable wird nicht wie erhofft hochgezählt.
Kann mir bitte jemand auf die Sprünge helfen, was ich falsch mache?
Net_Hans schrieb:> Hallo,>> danke das mit den Klammern funktioniert.
Dann will ich auch erklären warum: Es liegt an der Operatorenpräzedenz
(wie schreibt man das?). ++ wird vor * ausgewertet, du inkrementierst
also erst den Pointer und nimmst dann den Wert davon, machst aber
nichts weiter damit. (Was nebenbei bemerkt auch keine gute Idee wäre,
vagabundierende Pointer können schnell Mist machen). Mit den Klammern
änderst du die Reihenfolge der Auswertung.
> In dem Beispiel habe ich erst mal klein angefangen später soll es in die> Richtung gehen.
Da fehlen die Klammern. Außerdem ist das volatile da imho überflüssig
und wie oben geschrieben, solange die Variablen (da kann ein volatile
durchaus Sinn machen wenn Interrupts im Spiel sind) global sind brauchst
du gar keine Pointer.
lauten.
Das volatile hatte ich nur drin, weil ich es in einem anderen Beitrag so
gesehen hatte ... dort hatten sie geschrieben, das es ein Muss bei der
Arbeit mit Pointern in Funktionsparametern wäre...
>Das volatile hatte ich nur drin, weil ich es in einem anderen Beitrag so
gesehen hatte ... dort hatten sie geschrieben, das es ein Muss bei der
Arbeit mit Pointern in Funktionsparametern wäre...
Poste mal einen Link? War das hier im Forum? Unwidersprochen? In diesem
Kontext?
Jedenfalls ist das hier, in dieser Situation unnötig. In der
Artikelsammlung gibt es, soweit ich mich erinnere, einen ausführlichen
Artikel über Zweck und Anwendung von volatile.
Ach ja: http://www.mikrocontroller.net/articles/Volatile
Hmm schrieb:> Jedenfalls ist das hier, in dieser Situation unnötig. In der> Artikelsammlung gibt es, soweit ich mich erinnere, einen ausführlichen> Artikel über Zweck und Anwendung von volatile.>> Ach ja: http://www.mikrocontroller.net/articles/Volatile
Und noch ausführlicher hier
FAQ: Was hat es mit volatile auf sich
Edit: gerade gesehen - im Artikel ist ja auch ein Link auf den FAQ
Eintrag.
Net_Hans schrieb:> Das volatile hatte ich nur drin, weil ich es in einem anderen Beitrag so> gesehen hatte ... dort hatten sie geschrieben, das es ein Muss bei der> Arbeit mit Pointern in Funktionsparametern wäre...
Das kann nur jemand geschrieben haben, der selber keine Ahnung davon
hatte, was es mit volatile auf sich hat.
troll schrieb:> Dann will ich auch erklären warum: Es liegt an der Operatorenpräzedenz> (wie schreibt man das?). ++ wird vor * ausgewertet, du inkrementierst> also erst den Pointer und nimmst dann den Wert davon, machst aber> nichts weiter damit.
Moment, das ist doch falsch! :-( Du nimmst den Wert vom Pointer,
verwirfst ihn und inkrementierst dann den Pointer. Oder? Karl Heinz,
Hilfe!
troll schrieb:> troll schrieb:>> Dann will ich auch erklären warum: Es liegt an der Operatorenpräzedenz>> (wie schreibt man das?). ++ wird vor * ausgewertet, du inkrementierst>> also erst den Pointer und nimmst dann den Wert davon, machst aber>> nichts weiter damit.> Moment, das ist doch falsch! :-( Du nimmst den Wert vom Pointer,> verwirfst ihn und inkrementierst dann den Pointer. Oder?
(ich geh mal davon aus, dass du mit Wert vom Pointer die
Derefenzierung meinst)
Richtig.
In
x++
ist der Wert des Ausdrucks, der Wert von x vor der Inkrementierung. Und
es ist nicht näher festgelegt, wann denn eigentlich die Inkrementierung
tatsächlich stattgefunden haben muss. Alles was wir wissen ist, dass
dieser Nebeneffekt (das eigentliche Inkrementieren gilt als Nebeneffekt)
vor dem nächsten Sequence-Point (in diesem Fall das Ende des Statements,
also der ;) stattgefunden haben muss. Aber wann genau, ist nicht
festgelegt. Daher ist das Ergebnis von
x = 8;
i = x++ + x++;
auch undefined, weil nicht klar ist, wann genau die beiden Inkrements
auf dieselbe Variable statt finden.
Karl Heinz Buchegger schrieb:> (ich geh mal davon aus, dass du mit Wert vom Pointer die> Derefenzierung meinst)
Ja.
> Richtig.
Danke. War ein langer Tag...
>Moment, das ist doch falsch! :-( Du nimmst den Wert vom Pointer,>verwirfst ihn und inkrementierst dann den Pointer. Oder? Karl Heinz,>Hilfe!
Durchaus nicht. Der Wert des Zeigers wird eigentlich nicht direkt
benutzt, sondern dem Compiler mit dem '*' gesagt, dass er nicht den
Zeiger, sondern das worauf er zeigt inkrementieren soll.
Aber Karl Heinz kann das vielleicht noch viel schöner schreiben. :-)
Wo ich das gelesen habe, weiß ich nicht mehr... es waren dann doch zu
viele Foreneinträge die ich gelesen habe. ...
Aber danke noch mal für die Hinweise zu volatile. Ich arbeite die jetzt
erst mal durch.
mfG Hans
Hmm schrieb:>>Moment, das ist doch falsch! :-( Du nimmst den Wert vom Pointer,>>verwirfst ihn und inkrementierst dann den Pointer. Oder? Karl Heinz,>>Hilfe!>> Durchaus nicht. Der Wert des Zeigers wird eigentlich nicht direkt> benutzt, sondern dem Compiler mit dem '*' gesagt, dass er nicht den> Zeiger, sondern das worauf er zeigt inkrementieren soll.
Dann musst du es als
(*x)++
schreiben. ++ bindet stärker als *
Beispiel:
Diese Operation kommt zb in der Ausgabe eines Strings vor
1
voidlcdString(constchar*str)
2
{
3
while(*str)
4
lcdChar(*str++);
5
}
*str wird an lcdChar übergeben und str wird inkrementiert.
Der Wert vom Pointer ist der Pointer! Im allgemeinen wird das so
ausgedrückt. (Soweit ich weiss).
Im Unterschied dazu steht das worauf der Zeiger zeigt.
In unserem Fall, wird der "Wert" auf den der Zeiger zeigt, nicht
verworfen, denn er muss ja um eins erhöht werden.
Karl Heinz: Mit Dir bin ich in diesem Thread garnicht zufrieden. :-)
Karl Heinz schrub:
>Dann musst du es als> (*x)++>schreiben. ++ bindet stärker als *
Dann hat sich die Frage auf den Fall ohne Klammer bezogen. Habe das
anders verstanden. :-{
Aber dennoch wird da auch nichts verworfen.
Hmm schrieb:> Der Wert vom Pointer ist der Pointer! Im allgemeinen wird das so> ausgedrückt. (Soweit ich weiss).
Ihr meint beide dasselbe und troll hat einen Fehler gemacht.
Da allerdings eine andere Interpretation als Derferenzieren in diesem
Zusammenhang keinen Sinn ergeben hätte, hab ich ihn dazu genötigt,
klarzustellen was er meint.
>> Karl Heinz: Mit Dir bin ich in diesem Thread garnicht zufrieden. :-)
:-)
Hmm schrieb:> Dann hat sich die Frage auf den Fall ohne Klammer bezogen. Habe das> anders verstanden. :-{
Ausgangspunkt war ja auch diese Aussage
>> Dann will ich auch erklären warum: Es liegt an der Operatorenpräzedenz>> (wie schreibt man das?). ++ wird vor * ausgewertet, du inkrementierst>> also erst den Pointer und nimmst dann den Wert davon, machst aber>> nichts weiter damit.
Und die ist definitiv falsch.
Operator Precedence hat erst mal nichts mit tatsächlicher
Auswertereihenfolge zu tun.
>Und die ist definitiv falsch.>Operator Precedence hat nichts mit tatsächlicher Auswertereihenfolge zu>tun.
Na ja. Das wage ich dann doch zu bezweifeln, wenn auch der Vorrang
letztlich im Verein mit der Bindungsrichtung (Assoziativität) der
Auswertereihenfolge bestimmt. Alleine also ist der Vorrang nicht
entscheidend, aber man kann, glaube ich, nicht sagen, das es nichts
damit zu tun hat.
Aber offen gesagt, glaube ich das wir beide wissen wovon wir reden. Ein
bisschen Verwirrung um Worte.
Hmm schrieb:>>Und die ist definitiv falsch.>>>Operator Precedence hat nichts mit tatsächlicher Auswertereihenfolge zu>>tun.>> Na ja. Das wage ich dann doch zu bezweifeln, wenn auch der Vorrang> letztlich im Verein mit der Bindungsrichtung (Assoziativität) der> Auswertereihenfolge bestimmt. Alleine also ist der Vorrang nicht> entscheidend, aber man kann, glaube ich, nicht sagen, das es _nichts_> damit zu tun hat.
OK. Nichts ist vielleicht etwas stark ausgedrückt.
Aber es ist besser also zu sagen, dass sie sie bestimmt.
In
i = bar() * baz() + foo();
ist nicht festgelegt in welcher Reihenfolge die Funktionen aufgerufen
werden. Auch wenn * stärker bindet als +, kann der Compiler trotzdem
entscheiden, dass er foo() als erste Funktion aufrufen will. Jede
beliebige Reihenfolge der Funktionsaufrufe ist möglich.
Gerade Neulinge messen hier der höheren Precedence gerne eine Bedeutung
bei, die sie nicht hat.
> Aber offen gesagt, glaube ich das wir beide wissen wovon wir reden. Ein> bisschen Verwirrung um Worte.
Eben. Drumm lassen wirs gut sein. Ok?
Karl Heinz schrab:
>Gerade Neulinge messen hier der höheren Precedence gerne eine Bedeutung>bei, die sie nicht hat. (...) Jede>beliebige Reihenfolge der Funktionsaufrufe ist möglich.
Da gebe ich Dir recht. Das ist genau der Punkt, denke ich, den man
Anfängern klar machen muss.
Die Tabelle mit dem Vorrang und der Assoziativität bezieht sich genau
und nur auf die Ausführung der darin genannten "primitiven"
Operatoren. Aber nicht auf die Auswertung der Operanden.
>Eben. Drumm lassen wirs gut sein. Ok?
OK. :-)