Forum: Compiler & IDEs Pointer in C


von Hauke M. (mgbgt)


Angehängte Dateien:

Lesenswert?

Hallo,
ich habe hier einen Codeausschnitt aus meinem Programm angehängt,
warum geht die Version mit *ptr++ nicht und mit *ptr = *ptr + 1 geht es 
?
Ich habe keine Erklärung dafür.

von Sven P. (Gast)


Lesenswert?

Schau dir mal die Operatorenrangfolge in C an.
1
*ptr++;
ist was Andres als
1
(*ptr)++;

von Rolf Magnus (Gast)


Lesenswert?

Hauke M. schrieb:

> warum geht die Version mit *ptr++ nicht und mit *ptr = *ptr + 1 geht es

Ersteres inkrementiert ptr, das zweite inkrementiert das, worauf ptr 
zeigt.

PS: Das Plenken sollte man lassen, damit das da nicht passiert:

> ?

von Hauke M. (mgbgt)


Lesenswert?

Hallo,
ich hab das nochmal debugged, also *ptr++ incrementiert nicht den 
pointer!, es passiert einfach nichts.

von Hauke M. (mgbgt)


Lesenswert?

Hallo,
mit (*ptr)++ gehts es, vielen dank für die Hilfe!!

von Karl H. (kbuchegg)


Lesenswert?

Hauke M. schrieb:
> ich hab das nochmal debugged,

dann hast du schlecht debugged

> also *ptr++ incrementiert nicht den
> pointer!

Doch, das tut es

> es passiert einfach nichts.

Es passiert mit Sicherheit, dass der Pointer nach dieser Operation nicht 
mehr auf int_cnt zeigt, sondern auf die nächste Speicherzelle.

von (prx) A. K. (prx)


Lesenswert?

Hauke M. schrieb:

> ich hab das nochmal debugged, also *ptr++ incrementiert nicht den
> pointer!, es passiert einfach nichts.

Wird schon inkrementiert, aber da es in einer ISR passiert und der 
Pointer selbst nicht volatile ist merkst du das evtl. nicht.

Was dir in der funktionierenden Version aber irgendwann auch passieren 
kann: dass der nicht wegoptimierbare Zugriff über den Pointer etwas 
anderes anzeigt, als der u.U. wegoptimierbare Zugriff auf die Variable.

Und in ganz seltenen Fällen auch seltsame Aussreisser liefert. Aus 
http://www.mikrocontroller.net/articles/Interrupt#Interruptfeste_Programmierung
"Ein ähnliches Problem entsteht bei Variablen, deren Größe die 
Wortbreite der Maschine übersteigt. Bei 8-Bit-Prozessoren wie AVR oder 
8051 also bereits bei normalen "int" Variablen. Diese Variablen werden 
zwangsläufig byteweise verarbeitet. Wenn genau dazwischen ein Interrupt 
erfolgt, wird ein falscher Wert gelesen. Wenn beispielsweise eine 
Interrupt-Routine einen 16-Bit-Zähler verwendet und von 0x00FF auf 
0x0100 hochzählt, dann kann das Hauptprogramm auch schon mal 
versehentlich die Werte 0x01FF oder 0x0000 lesen."

von Peter D. (peda)


Lesenswert?

Hauke M. schrieb:
> ich hab das nochmal debugged, also *ptr++ incrementiert nicht den
> pointer!, es passiert einfach nichts.

Der Compiler merkt sich erstmal nur, daß fürderhin ptr+1 benötigt wird.
Für den aktuellen Ausdruck aber noch nicht, da ja post-increment.
Wird aber ptr danach nicht mehr verwendet, dann muß er es auch nicht 
incrementieren. Das Increment wird also wegoptimiert.
Und wird das *ptr nirgends zugewiesen, fällt auch das flach.

Er hat also recht, wenn er garnichts macht.


Peter

von Sven B. (alterswede)


Lesenswert?

Karl heinz Buchegger schrieb:
> Hauke M. schrieb:
>> ich hab das nochmal debugged,
>
> dann hast du schlecht debugged
>
>> also *ptr++ incrementiert nicht den
>> pointer!
>
> Doch, das tut es
>
>> es passiert einfach nichts.
>
> Es passiert mit Sicherheit, dass der Pointer nach dieser Operation nicht
> mehr auf int_cnt zeigt, sondern auf die nächste Speicherzelle.

Genauso ist es. Bei Operatoren mit gleicher Bindung gilt die 
Rechts-nach-Links-Regel (Rechtsassoziativität).

Der Ausdruck *ptr++ liefert also lediglich den Inhalt der Speicherzelle, 
auf die ptr referenziert und inkrementiert ANSCHLIESSEND (nach 
Auswertung des Ausdrucks) den ptr. Die Anweisung *ptr++; allein macht so 
eben nichts, außer ptr zu inkrementieren, da der Wert des Ausdruck ja 
nicht genutzt wird.

Bei (*ptr)++ wird die Bindungsreihenfolge geändert. Hier wird zuerst der 
Ausdruck *ptr ausgewertet, d.h. es handelt sich um den Inhalt der 
Speicherzelle, auf die ptr referenziert. Dieser Inhalt wird dann NACH 
Auswertung des Ausdrucks (z.B. Zuweisung) inkremetiert. Bei ++(*ptr) 
würde der Inhalt der Speicherzelle VOR Auswertung des Ausdrucks 
inkrementiert werden.

von Hauke M. (mgbgt)


Lesenswert?

Hallo,
ja das mit der  Rechtsassoziativität hatte ich noch nicht verstanden, 
jetzt ist es klar! Nochmals vielen Dank für die Antworten, das Programm 
tut jetzt was es soll, dafür tauchen neue Sachen auf, aber da guck ich 
jeztt erstmal in den Threads nach.

von Klaus W. (mfgkw)


Lesenswert?

oder in einem guten C-Buch...

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.