Forum: Mikrocontroller und Digitale Elektronik Pointer geht nicht


von Jochen (Gast)


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

von Stefan Kleinwort (Gast)


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

von Jochen (Gast)


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

von Chris (Gast)


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).

von Stefan Kleinwort (Gast)


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

von Jochen (Gast)


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.

von Stefan Kleinwort (Gast)


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

von Jochen (Gast)


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

von Jochen (Gast)


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

von Stefan Kleinwort (Gast)


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

von Rufus T. Firefly (Gast)


Lesenswert?

Auch erwähnenswert:

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

von T.Stütz (Gast)


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

von Chris (Gast)


Lesenswert?

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

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.