mikrocontroller.net

Forum: Compiler & IDEs Pointer in C


Autor: Hauke M. (mgbgt)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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.

Autor: Sven P. (haku) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schau dir mal die Operatorenrangfolge in C an.
*ptr++;
ist was Andres als
(*ptr)++;

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:

> ?

Autor: Hauke M. (mgbgt)
Datum:

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

Autor: Hauke M. (mgbgt)
Datum:

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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht 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#...
"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."

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Sven B. (alterswede)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Hauke M. (mgbgt)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
oder in einem guten C-Buch...

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.