www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Pointer geht nicht


Autor: Jochen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo.

uint16_t Measurement = 0;
char *p_Measurement = &Measurement;
*p_Measurement = 0x01;
*p_Measurement = &Measurement+1;
*p_Measurement = 0x02;
p_Measurement = &Measurement-1;
*p_Measurement = 0x03;
eeprom_write_word(16, Measurement);

Weiss jemand wiso der code oben nicht funktioniert ? Er sollte doch
eigentlich die bytes von  Measurement über den zeiger p_Measurement
beschreiben. Beim ersten schreiben funktioniert das auch noch. (d.h.
die 0x01 find ich im eeprom wieder.) allerdings kann ich die anderen
bytes nicht schreiben. es sollte doch eigentlich funktionieren, indem
ich Die adresse auf das nächste byte setze (mit *p_Measurement =
&Measurement+1;). allerdings find ich die 0x02 oder 0x03 nicht im
speicher !?

MfG

Autor: Stefan Kleinwort (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Fehler 1:
---------
uint16_t Measurement = 0;

Du solltest ein Array definieren, statt einer einzelnen
16-Bit-Variable. Sonst überschreibst Du Dir den Speicher (in diesem
Fall den Pointer, der auf Measurement zeigt - aua ..)

Fehler 2:
---------
char *p_Measurement = &Measurement;

Typ-Konflikt, das eine ist eine uint16-Adresse, das andere ein Ptr auf
char. Mindestens eine Warnung solltest Du bekommen haben. Warnungen
haben in den allermeisten Fällen ihre Berechtigung, sie sollen Dir
helfen!

Fehler 3:
---------
*p_Measurement = &Measurement+1;

Du weist nicht dem Pointer einen neuen Wert zu, sondern der Variable,
auf die der Pointer zeigt. Um den Pointer auf das nächste Array-Element
zeigen zu lassen, kannst Du

p_Measurement++;      oder
p_Measurement = &(Measurement+1);

verwenden. (Jeweils ohne Stern ..)


Stefan

Autor: Jochen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan Kleinwort: Danke für deine Antwort !

zu 1.)
uint16_t Measurement = 0;

ist kein fehler ich will eine variable mit 16 bits und kein Array.
Und ich will ja den speicher inhalt an dieser adresse überschreiben.

zu 2.)
char *p_Measurement = &Measurement;
ist kein Typ konflikt. funktioniert klasse ich will ja das einzelne
byte ändern und das andere erst später.


zu 3.)
p_Measurement++;  will ich nur ungern verwenden, da ich später zeiger
auf andere variablen noch verwenden will. Allerdings funktioniert es.

p_Measurement = &(Measurement+1);
funktioniert nicht: folgender fehler: invalid lvalue in unary `&'

p_Measurement = (&Measurement)+1;
kann ich zwar vom compiler übersetzen lassen aber es funktioniert
später nicht. Wiso nicht ? ist doch eingentlich das selbe wie:

char *p_Measurement = &Measurement;
p_Measurement++;


MfG

Autor: Chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> char *p_Measurement = &Measurement;
> ist kein Typ konflikt.

Natürlich ist es ein Typkonflikt, was denn sonst? Rechts vom
Zuweisungsoperator steht ein anderer Typ als links, daher Typkonflikt.
Stefan hat ganz Recht, wenigstens eine Warnung solltest du erhalten.

Wenn du so etwas beabsichtigst (dies ist nämlich keine implizite
void*-Konvertierung wie bei malloc), solltest du casten:
char* p_Measurement = (char*)(&Measurement);


> p_Measurement = (&Measurement)+1;
> kann ich zwar vom compiler übersetzen lassen aber es funktioniert
> später nicht. Wiso nicht ? ist doch eingentlich das selbe wie:
>
> char *p_Measurement = &Measurement;
> p_Measurement++;

Nein, das ist nicht dasselbe. Du solltest nochmal das Kapitel über
Pointerarithmetik in deinem C-Buch lesen.
Stichwort "Konstante zu Pointer addieren", bzw. um welchen Wert der
Pointer bei ++ vergrößert wird.


Darf ich fragen, wieso du hier überhaupt meinst Pointerarithmetik zu
brauchen? Wenn du nur zwei 8-Bit-Werte in eine 16-Bit-Variable
schreiben willst, helfen dir die Bitoperatoren von C (z.B.
shift-operator und bitweises oder).

Autor: Stefan Kleinwort (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry für die falsche Klammerung.

>p_Measurement = (&Measurement)+1;
>kann ich zwar vom compiler übersetzen lassen aber es funktioniert
>später nicht. Wiso nicht ? ist doch eingentlich das selbe wie:
>
>char *p_Measurement = &Measurement;
>p_Measurement++;

Ist nicht dasselbe, wenn das eine ein Ptr auf char und das andere ein
Ptr auf uint16_t ist:

>char *p_Measurement = &Measurement;
>p_Measurement++;

erhöht den Ptr um den Platzbedarf von einem char - üblicherweise also
EIN Byte.

>p_Measurement = (&Measurement)+1;

weist dem Ptr die uint16_t-Adresse nach Measurement zu - also ZWEI Byte
nach der Adresse von Measurement.


>zu 2.)
>char *p_Measurement = &Measurement;
>ist kein Typ konflikt. funktioniert klasse ich will ja das einzelne
>byte ändern und das andere erst später.

Gut, wenn Du das wirklich im Sinn hast. Trotzem sollte der Compiler
eine Warnung ausgeben. Besser, Du erklärst dem Compiler per Typecast,
dass es Absicht ist ... oder noch eleganter: die Variable Measuremet
als union deklarieren, dann kannst Du sowohl auf die 16-Bit-Zahl als
auch auf die einzelnen Bytes zugreifen.

Viele Grüße, Stefan

Autor: Jochen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dann müssts ja so gehen:
p_Measurement = (char*)(&Measurement)+1; oder
p_Measurement = (char*)(&Measurement)+(char*)1; (ok, das ist quatsch)
Will aber trotzdem nicht gehen .?

mir gehts nur darum den umgang mit pointern zu verstehen.
Klar kann ich Union verwenden und einfach die speicher
übereinanderlegen...aber ich willst mit pointern verstehen.

Über die addition von konstanten zu pointern hab ich in meinem c++ buch
nix gefunden ( hab leider nur ein c++ bucht ). Google hat auch nix
passendes ausgespuckt.

Autor: Stefan Kleinwort (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Probiers mal mit mehr Klammerung:
p_Measurement = ((char*)(&Measurement))+1;

Du nimmst gcc? Wenn ich mir nicht sicher bin, was der Compiler da so
macht (oder ich mit ihm ...), dann schaue ich ins erzeugte .lst-File.
Da fällt dann oft der Groschen .

Viele Grüße, Stefan

Autor: Jochen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
p_Measurement = ((char*)(&Measurement))+1;
Hab ich auch schon versucht....hat erst nicht funktioniert, weil ich
nach dem p_Measurement = ((char*)(&Measurement))+1; noch
p_Measurement++; stehen hatte. war aber nach einem blick ins 1stfile
klar. danke nochmal an alle.

MfG

Autor: Jochen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ach noch was...kann mir jemand ein richtig gutes c buch empfehlen ?
wo allen von bit-manipulation über union bis zu Pointerarithmetik alles
alles erklärt bekommt ?
Danke

Autor: Stefan Kleinwort (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
http://pronix.de/modules/C/openbook/
http://www.schellong.de/c.htm

Den ersten Link gibt es auch in Buchform zu kaufen.

Gruß, Stefan

Autor: Rufus T. Firefly (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Auch erwähnenswert:

Kernighan & Ritchie, "Programmieren in C", zweite Auflage, Hanser
Verlag.

Autor: T.Stütz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
und noch ein Tip:

Du könntest ja auch einfach nur  so zugreifen:

p_Measurement[0] = 0x01; // äquivalent zu *(pMeasurement+0) = 0x01;
p_Measurement[1] = 0x02; // äquivalent zu *(pMeasurement+1) = 0x02;

Gruss

Autor: Chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
T.Stütz: Warum so einfach, wenn's auch kompliziert geht? g

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.