Forum: Mikrocontroller und Digitale Elektronik Pointer und ihre Tücken


von Thomas W. (beholder)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,
dies ist mein erster Beitrag den ich hier erstelle.
Bislang konnte ich immer alles per Suchmachine finden, nur diesmal
nicht.

Ich habe ein kleines Problem mit den Pointern.
Ich bin momentan dabei ein Menu zu programmieren welches auf einen
LC-Display ausgegeben werden soll. Ich habe mir hierfür eine Grundlage
aus diesem Forum genommen, welche hier beschrieben ist:
http://www.mikrocontroller.net/forum/read-2-40721.html#348262

Die von dem User Dieter beschriebene Struktur habe ich umgesetzt und
ist im Dateianhang zu sehen.

Es funktioniert auch, jedoch wollte ich es etwas eleganter machen.
Momentan sind die einzelnen Menupunkte durch den Index des Arrays
identifizierbar und in der Struktur eines Menupunktes sind diese
Indizes zu finden.
Beispiel:
Menu1 hat den Index 0
Menu11 hat den Index 1
Menu12 hat den Index 2
u.s.w.

Menu1.next beinhaltet den Wert 1

Menu1.down beinhaltet den Wert 2

Sollte nun klar sein wie es Funktioniert

Was ich will, ist dass direkt mit den Adressen gearbeitet wird.

Ungefähr so:

menu[menu1].text =    "Ebene 1";
menu[menu1].previous =    &menu[menu1];
menu[menu1].next =    &menu[menu11];
menu[menu1].up =    &menu[menu2];
menu[menu1].down =    &menu[menu2];
menu[menu1].fp =    func_menu1;

jedoch gibt das ein Konflikt mit den Typen,
das eine ist vom Typ unsigned int das andere vom Typ MENU.
Ist es denn nicht so, dass &menu[menu1] mir die Adresse gibt,
wo die Struktur des Menupunktes ihren Anfang hat??

Wenn ja welchen Wert kann die Adresse haben?
Wiso passt der nicht in ein unsigned int?

So nu hat ich erst mal genug geschrieben, ich hoffe mal das sich jemand
meldet.

Gruß
Beholder

von Thomas W. (beholder)


Lesenswert?

Ach Sorry, ich arbeite mit der IAR Embedded Workbench und verwende einen
ATmega128.

von Rahul (Gast)


Lesenswert?

Wenn du &... verwendest, sollte es sich beim Struct-Element um einen
Pointer handeln.
Dann müsste die Struct IMHO so heissen (aus dem anderen Thread
kopiert:

typedef struct MENU {
  const unsigned char *text;
  MENU_ENTRY *previous;
  MENU_ENTRY *next;
  MENU_ENTRY *up;
  MENU_ENTRY *down;
  void ( *fp )( void );
} MENU_ENTRY;

oder deine Vereinbarung müsste so heissen:

menu[menu1].text =    "Ebene 1";
menu[menu1].previous =    menu1;
menu[menu1].next =    menu11;
menu[menu1].up =    menu2;
menu[menu1].down =    menu2;
menu[menu1].fp =    func_menu1;

Dazu müsstest du dann ein Array mit den verschiedenen Einträgen haben,
und menuX wären Konstanten/Markos.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Die Adresse passt zwar (üblicherweise) in einen unsigned int, aber der
Compiler motzt zu Recht, da so eine Zuweisung i.d.R. nicht gewollt ist.
Außerdem ist es wichtig, die Größe des referenzierten Elementes zu
kennen, damit

  struct Bla* p;
  struct Bla menu[10];

  p = menu; // entspricht &menu[0];

  p++;

in diesem Fall der Pointer auf das nächste Strukturelement verweist.
Wäre p vom Typ unsigned int, würde die Operation p++ den Pointer nur um
ein Byte versetzen; Du müsstest also stattdessen

  p += sizeof (struct Bla);

schreiben.

Also sollten die Elemente Deiner Struktur nicht vom Typ unsigned int,
sondern vom Typ "pointer auf Deine Struktur" sein.

Halt so:

  struct Bla
  {
    struct Bla *previous;
    struct Bla *next;
    struct Bla *up;
    struct Bla *down;
  ... etc.

von Thomas W. (beholder)


Lesenswert?

Holla das ging ja schon mal schnell.

@Rahul
Ok das mit dem Pointer der das Ergebniss vom Adressoperater empfängt
stimmt. Ansonsten habe ich es ja so wie Du vorgeschlagen hast.

@Rufus
Ja der Compiler meckert wegen den verschiedenen Typen.
Ein unsigned int (auch als Pointer) kann nicht die Adresse des structs
aufnehmen. SCHADE.

Wenn ich aber ein Struct erzeuge, wie Du es vorgeschlagen hast meckert
er auch.
 struct Bla
  {
    struct Bla *previous;
    struct Bla *next;
    struct Bla *up;
    struct Bla *down;
  }
Der Compiler kennt gibt die raus
Error[Pe020]: identifier "Bla" is undefined

ist ja auch klar, da ich es hier erst deklariere.

Hmm nicht schön das ganze, aber wie bekomme ich die Adressen sonst in
die Struktur rein??

Es wäre so schön, einen Pointer von struct bla erstellen
Dem Pointer die Adresse des ersten Menupunkts geben und in XXX.next
steht die Adresse des nächsten Menupunkts.

von Wolfram (Gast)


Lesenswert?

benutze typedef
ans Ende der structdeklaration gehört sonst ein Name

von Rahul (Gast)


Lesenswert?

Mal Dennis und Brian befragt:
struct tnode {
 char *word; //ein typischer Knoten
 int count;  // zeigt auf den Text
 struct tnode *left; // linker Nachkomme
 struct tnode *right; // rechter Nachkomme
};

struct tnode *root, *tree();

von Christian Rötzer (Gast)


Lesenswert?

@Thomas

versuche statt

 struct Bla
  {
    struct Bla *previous;
    struct Bla *next;
    struct Bla *up;
    struct Bla *down;
  };

den struct "anzukündigen":

 struct Bla;

 struct Bla
  {
    struct Bla *previous;
    struct Bla *next;
    struct Bla *up;
    struct Bla *down;
  };

von Thomas W. (beholder)


Lesenswert?

Moin, bin nu wieder dabei.

@Christian
Danke, so klappt es, und es braucht weniger Bytes an Code!
Werde nun versuchen das ganze ohne Array sondern mit einzelnen
Variablen zu programmieren.

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.