www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik zeigerproblem


Autor: edka (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
habe folgendes Problem. Mein C Compiler meckert in der markierten
Zeile.
Leider habe ich wenig ahnung wie dieser Zeiger funktioniert.
Der Compiler hat ein Problem mit der Inkrementierung.
Kann einer von euch Experten den Code umschreiben, dass die Umwandlung,
Inkrementierung und die Zuweisung nicht mit einem Aufruf vollzogen
wird.
Evtl. eine hilfvariable?

gruß

edka



void CopyFromFrame8900(void *Dest, unsigned int Size)
{
while (Size > 1)
{
(*(unsigned char *)Dest)++ = ReadFrame8900();
Size -= 2;
}
}



Compiler IAR Embedded Workbench 3.22

Fehlermeldung: not a modifyable lvalue

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Entscheide Dich:

Entweder um 1 erhöhen oder ReadFrame8900() zuweisen.

2 Zuweisungen gleichzeitig geht nicht.


Peter

Autor: Khani (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also nach C/C++ müsste das auch so gehen :

void CopyFromFrame8900(void *(&Dest), unsigned int Size)
{
    while (Size > 1)
    {
        (*(unsigned char *)Dest)++ = ReadFrame8900();
        Size -= 2;
    }
}

Wenn man einfach die Typkonversion und die Inkremetierung
auseinanderreisst, dann ist "Dest" selbst (also die Adresse, wo der
Pointer hinzeigt) immer noch nicht modifizierbar (zumindest wirkt sich
das nicht auf das Hauptprogramm aus). Das & zeigt an, dass diese
Variable ebenfalls verändert wird.

Meiner Meinung nach ist das eh kein guter Stil, aber ich gehe davon
aus, dass die Funktion nicht anders geschrieben werden konnte. Falls
man sie anders schreiben könnte :

void CopyFromFrame8900(void *Dest, unsigned int Size)
{
    cDest = (unsigned char*)Dest);
    while (Size >1)
    {
        cDest = ReadFrame8900(); // was macht eignetlich Read... ?
        cDest++;
        Size -= 2
    }
}

Mögliche andere Fehlerquelle : poste mal die Deklaration von
ReadFrame8900(), wenn die nämlcih keinen so tollen Rückgabetyp hat,
dann kann man das so eh nicht machen.

MfG, Khani
}

Autor: Khani (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
sorry - nach Size -=2 fehlt ein ";"

Autor: Khani (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Äh Peter, wie meinen ?
Bitte erleuchte mich, denn ich weiß nicht, was Du meinst ;-)

MfG, Khani

Autor: edka (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die schnellen antworten.
Hier die Deklaration von ReadFrame8900()

unsigned int ReadFrame8900(void)
{
  unsigned int ReturnValue;

  P5DIR = 0x00;                                  // data port to input
  P3OUT = IOR | IOW | RX_FRAME_PORT;             // access to
RX_FRAME_PORT

  P3OUT &= ~IOR;                                 // IOR-signal low

  ReturnValue = P5IN;                            // get 1st byte from
data bus (low-byte)
  P3OUT = IOR | IOW | (RX_FRAME_PORT + 1);       // IOR high and put
next address on bus
  P3OUT &= ~IOR;                                 // IOR-signal low

  ReturnValue |= P5IN << 8;                      // get 2nd byte from
data bus (high-byte)

  P3OUT |= IOR;

  return ReturnValue;
}

gruß

edka

Autor: edka (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn ich es so schreibe meckert der Compiler nicht, funkt aber trotzdem
nicht.

void CopyFromFrame8900(void *Dest, unsigned int Size)
{
  while (Size > 1)
   {

   (*(unsigned int *)Dest)++;
    *(unsigned char *)Dest = ReadFrame8900();


    Size -= 2;
  }

  if (Size)
 *(unsigned char *)Dest = ReadFrame8900();
}

Autor: Khani (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oh Oh...
Das macht die Sache aber noch ein bißchen komplexer...
Dann lieber so :

void CopyFromFrame8900(void *Dest, unsigned int Size)
{
    unsigned char* cDest = (unsigned char*)Dest;
    while (Size >1)
    {
        *cDest = (unsigned char)ReadFrame8900();
        cDest++;
        Size -= 2;
    }
}

Oder nicht Peter ?

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Khani

"Bitte erleuchte mich, denn ich weiß nicht, was Du meinst ;-)"


Die Zeile macht doch 2 Zuweisungen auf die selbe Variable, auseinander
geschrieben also folgendes:

(*(unsigned char *)Dest)++;

*(unsigned char *)Dest = ReadFrame8900();


Ist aber in der Regel sinnlos, da die erste Zuweisung ja sofort von der
2. überschrieben wird.


Peter

Autor: Khani (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nochmal Peter :

Vereinfach wir die Sache mal etwas :

a++ = b;

Das ergibt meiner Meinung nach folgendes :

a = b;
a++;

das heißt Ergebnis in a : b+1

Was Du meinst ist glaube ich : ++a = b;

in diesem Falle passiert, was Du schreibst :

++a;
a = b;

Ergebnis in a : b (also war das mit dem "++" überflüssig)

MfG Khani.

P.S.: es gibt da doch dieses Idiom zum Stringkopieren, daher meine
Meinung :

while (dest++ = source++);

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

a++ = b; dürfte kein gültiges C sein da zwei Zuweisungen auf ein und
die selbe Variable angewendet werden. Einmal a=a+1 und einmal a=b. Der
GCC meckert das auch mit der Fehlermeldung

config.c:125: error: invalid lvalue in assignment

an.

Matthias

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
a++ = b;  // darf man wie gesagt auf keinen fall


@edka:
was übergibst du mit Dest (Eine Adresse, ein Array voller Adressen,
...), und soll die Adresse auf die Dest zeigt erhöht werden, oder die
Variable die von ReadFrame zurückgegeben wird (schätze mal erstes)?

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"oder die
Variable die von ReadFrame zurückgegeben wird (schätze mal erstes)?"


sollte heißen:
oder der Wert der von ReadFrame zurückgegeben wird um eins erhöht
werden?

Autor: Oryx (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
a++ = b;  // darf man wie gesagt auf keinen fall

aber
*(a++) = b; // sollte Compilierbar sein

Wert von b dahin kopieren, wohin der Pointer zeigt. Danach den Pointer
um eins erhöhen.

Eine offensichtlichere Schreibweise wäre
*a = b;
a++;

Die Lösung des eigentlichen Problems könnte sein:
*((unsigned char *)Dest)++) = ReadFrame8900();

besser:
*((unsigned char *)Dest)= ReadFrame8900();
((unsigned char *)Dest)++;

wenn ich mich mit den Cast und der Klammerei nicht versehen habe

Oryx

Autor: Khani (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zu meiner Ehrenrettung :

ich hatte bei meiner Vereinfachung folgendes vorausgesetzt :
unsigned int a, b;

Dann geht's. (Der Compiler gibt mir recht)

MfG, Khani

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

@Khani

Dann ist aber dein Compiler ziemlich kaputt oder zeigt undefiniertes
Verhalten.
Mein GCC (in der Inkarnation AVRGCC und der von Cygwin) meckert mir das
mit der gennanten Fehlermeldung an.

Programm:

#include <stdio.h>

int main(void)
{
  unsigned int a,b;

  a=4;
  b=4;

  a++=b;

  printf("%d\n%d\n",a,b);
}

Was sollte den dieses Programm deiner Meinung nach ausgeben?

Matthias

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

hab ich doch glatt das return 0; vergessen.

Matthias

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.