Forum: Compiler & IDEs Pointer auf Tabelleneintrag


von Andi79 (Gast)


Lesenswert?

Hallo ich habe ein kleines Problem ich soll eine Tabelle erstellen in 
welcher ein Struct abgebildet ist.Nun soll ich jede Position in der 
Tabelle mit einem der Position zugewiesenen Zeiger aufrufen können. Wie 
kann ich das realisieren.
Mein Struct sieht so aus :
1
typedef struct SLAVE_INFO 
2
{ 
3
   Uint8 Active; 
4
   Uint8 Serial_1; 
5
   Uint8 Serial_2; 
6
   Uint8 Serial_3; 
7
   Uint8 Status_1; 
8
   Uint8 Status_2; 
9
   Uint8 SlaveAddr; 
10
   Uint8 Uist_1; 
11
   Uint8 Uist_2;   
12
   Uint8 List_1; 
13
   Uint8 List_2; 
14
   Uint8 PwrUpCnt_1; 
15
   Uint8 PwrUpCnt_2; 
16
   Uint8 Time_1; 
17
   Uint8 Time_2; 
18
   Uint8 Config; 
19
20
}SlaveInfo;
Um eine Tabelle zu erstellen bin ich wie folgt vorgegangen:
1
void main(void) 
2
{ 
3
    struct    SLAVE_INFO G_SLAVE_INFO[MAX_SLAVE]; 
4
5
}

Nur wie kann ich nun jedem Tabelleneintrag einen festen Pointer 
zuweisen.

von Johann (Gast)


Lesenswert?

D.h. Du sollst noch einmal einen Pointer pro Tabelleneintrag 
erstellen? Welch Verschwendung von Speicherplatz! Nun, einen Pointer 
bekommt man so:

SLAVE_INFO *pointer1 = &G_SLAVE_INFO[0];

Dies weist der Variablen pointer1 die Adresse (&-Operator) des 1. 
Eintrages in der Tabelle zu.

Frage: Du hast schon einen typedef gemacht, warum schreibst Du nicht:

SlaveInfo G_SLAVE_INFO[MAX_SLAVE];

von Rolle (Gast)


Lesenswert?

Andi79 schrieb:

Mach es so

typedef struct
 {
    Uint8 Active;
    Uint8 Serial_1;
    Uint8 Serial_2;
    Uint8 Serial_3;
    Uint8 Status_1;
    Uint8 Status_2;
    Uint8 SlaveAddr;
    Uint8 Uist_1;
    Uint8 Uist_2;
    Uint8 List_1;
    Uint8 List_2;
    Uint8 PwrUpCnt_1;
    Uint8 PwrUpCnt_2;
    Uint8 Time_1;
    Uint8 Time_2;
    Uint8 Config;

 } SLAVE_INFO;


 SLAVE_INFO G_SLAVE_INFO[MAX_SLAVE];

 void main(void)
 {
   SLAVE_INFO *pointer;

   pointer = G_SLAVE_INFO[5];    // pointerzuweisung

   pointer->Status_2 = 23;       // Zugriff über pointer

 }

von Rolle (Gast)


Lesenswert?

halt, es felt ein * vor Zugriff

   *pointer->Status_2 = 23;       // Zugriff über pointer

von Andi79 (Gast)


Lesenswert?

Stimmt auf die Idee mit
SlaveInfo G_SLAVE_INFO[MAX_SLAVE];
bin ich noch gar nicht gekommen. Ich programmiere noch nicht so lange.
Es geht darum das ich am Anfang eine Initialisierung der Tabelle 
vornehme (es gibt insgesammt 5 verschiedene Geräte). Je nach dem um 
welches es sich handelt soll man die Daten anhand des Pointers später im 
Programm aufrufen können.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Rolle schrieb:
1
typedef struct
2
{
3
  Uint8 Active;
4
  Uint8 Serial_1;
5
  // .. etc.
6
} SLAVE_INFO;
7
8
SLAVE_INFO G_SLAVE_INFO[MAX_SLAVE];
9
10
void main(void)
11
{
12
  SLAVE_INFO *pointer;
13
14
  pointer = G_SLAVE_INFO[5];    // pointerzuweisung
15
16
  pointer->Status_2 = 23;       // Zugriff über pointer
17
}

Die "Pointerzuweisung" funktioniert so nicht.

Korrekt wäre
1
  pointer = &G_SLAVE_INFO[5];

oder, weniger umständlich
1
  pointer = G_SLAVE_INFO + 5;

> halt, es felt ein * vor Zugriff
>
>    *pointer->Status_2 = 23;       // Zugriff über pointer

Nein, der fehlt hier nicht. Der Pfeiloperator dereferenziert den 
Pointer, ein * wäre nur hier erforderlich:

>    (*pointer).Status_2 = 23;       // Zugriff über pointer


Prinzipiell: Gewöhne Dir Variablennamen in Großbuchstaben schleunigst 
ab.

G_SLAVE_INFO ist per Konvention kein Variablenname, sondern eine 
Definition oder ein Makro.

von Andi79 (Gast)


Lesenswert?

Ok werd daran denken, eine weitere Frage. Kann ich nicht auch ein array 
von Pointern erstellen? So dass ich jedem Gerät einen Poniter mit 
Eigennamen gebe.Womit ich diessn dann später wider aufrufe. ungefair so:

*Gptr[GERAET1]=&G_SLAVE_INFO[GERAET1];
*Gptr[GERAET2]=&G_SLAVE_INFO[GERAET2];
*Gptr[GERAET3]=&G_SLAVE_INFO[GERAET3];
etc...

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Andi79 schrieb:
> Kann ich nicht auch ein array von Pointern erstellen?

Natürlich kannst Du das auch tun, nur welchen Sinn soll das haben?

Aussehen täte das so:
1
SLAVE_INFO g_slave_info[MAX_SLAVE];
2
SLAVE_INFO* g_slave_info_p[MAX_SLAVE];

Pointerzuweisungen:
1
for (i = 0; i < MAX_SLAVE; i++)
2
  g_slave_info_p[i] = &g_slave_info[i];

oder, weniger umständlich geschrieben:
1
for (i = 0; i < MAX_SLAVE; i++)
2
  g_slave_info_p[i] = g_slave_info + i;


> So dass ich jedem Gerät einen Poniter mit Eigennamen gebe.

Das tust Du in Deinem "Beispiel" nicht, wenn jedes Gerät einen Pointer 
mit "Eigennamen" erhält, müsste das in etwa so aussehen:
1
SLAVE_INFO g_slave_info[MAX_SLAVE];
2
3
SLAVE_INFO* slave_horst = &g_slave_info[0];
4
SLAVE_INFO* slave_detlef = &g_slave_info[1];
5
SLAVE_INFO* slave_heinz = &g_slave_info[2];

Nur führst Du damit den Sinn des Arrays ad absurdum.

Wozu soll sowas gut sein?

von Andi79 (Gast)


Lesenswert?

Also sorry wenn ich das alles so umständlich erkläre.Ist mein erstes 
Parktikum in der Realität und da ist es etwas anderes als in der 
Vorlesung.
Ich soll eine Tabelle von 5 verschiedenen Geräten erstellen. Am Anfang 
meines Programms werden dann die passenden Gerätedaten in die Tabele 
eingetragen. Und ja nach dem welche daten ich dann später brauche soll 
ich dann über Pointer auf die jeweiligen Gerätedaten zugreifen können. 
Daher meinen denk Ansätze. Oder liege ich damit komplett falsch?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Andi79 schrieb:
> Ich soll eine Tabelle von 5 verschiedenen Geräten erstellen. Am Anfang
> meines Programms werden dann die passenden Gerätedaten in die Tabele
> eingetragen.

Soweit ist das nachvollziehbar.


> Und ja nach dem welche daten ich dann später brauche soll
> ich dann über Pointer auf die jeweiligen Gerätedaten zugreifen können.

Das ist unverständlich. Ist damit gemeint, daß Du Daten eines 
bestimmten Gerätes benötigst, oder ist damit gemeint, daß Du nur auf 
bestimmte Strukturelemente zugreifen willst?

Wie man einen Pointer auf ein beliebiges Arrayelement erhält, wurde Dir 
gezeigt. Wie man auf ein Struktureelement innerhalb eines Deiner 
Arrayelemente mit Hilfe eines Pointers zugreifen kann, wurde Dir auch 
gezeigt, hier der Vollständigkeit halber mal zwei Varianten:
1
pointer = g_slave_info[5];    // pointerzuweisung
2
3
pointer->Status_2 = 23;       // Zugriff über pointer

Das ganze ohne den Zwischenschritt des Pointers:
1
g_slave_info[5].Status_2 = 23;

Deine einzelnen Geräte kannst Du eindeutig anhand der Arrayindices in 
g_slave_info[] identifizieren, hier haben wir gerade das sechste Gerät 
behandelt.

Was willst Du mehr?

von Andi79 (Gast)


Lesenswert?

Ich soll später an ein anderes Modul einfach nur einen Pointer übergeben 
, der aussagt um welches Gerät es sich gerade handelt.Anhand des 
Pointers kann das zweite Modul dann die Daten für das gerade aktive 
Gerät aus der vorher initialisierten Tabelle entnehmen.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Na, dann reicht doch ein Pointer auf ein Arrayelement. Den musst Du 
nirgends speichern, sondern nur bei Aufruf von Funktionen, die was damit 
anstellen sollen, bestimmen und übergeben.

Das zweite Modul greift dann nur und ausschließlich über diesen Pointer 
auf die Struktur und ihre Elemente zu, und muss nichts davon wissen, daß 
mehrere Strukturen in einem Array enthalten sind.


Dazu musst Du nur strukturiert vorgehen:

Der typedef, der die Struktur SLAVE_INFO definiert, gehört in eine 
Headerdatei (*.h).

Diese ist von jedem Modul, das etwas mit diesen Strukturen anstellen 
will, eingebunden werden.


Das Array selbst muss nicht global bekannt sein.


Also:

Headerdatei "defs.h"
1
#ifndef INCLUDED_DEFS_H
2
#define INCLUDED_DEFS_H
3
4
#define MAX_SLAVE 32
5
6
typedef struct
7
{
8
  Uint8 Active;
9
  Uint8 Serial_1;
10
  // .. etc.
11
} SLAVE_INFO;
12
#endif

Headerdatei "modul1.h"
1
#include "defs.h"
2
3
int machirgendwas1(SLAVE_INFO* p);

Headerdatei "modul2.h"
1
#include "defs.h"
2
3
int machwasanderes2(SLAVE_INFO* p);


C-Source "modul1.c"
1
#include "modul1.h"
2
3
int machirgendwas1(SLAVE_INFO* p)
4
{
5
  p->Active = 0;
6
7
  return (p->Status);
8
}

C-Source "modul2.c" weggelassen.

C-Source "main.c"
1
#include "modul1.h"
2
#include "modul2.h"
3
4
SLAVE_INFO slave_info[MAX_SLAVE];
5
6
void main(void)
7
{
8
  machirgendwas1(slave_info + 3);
9
10
  machwasanderes2(slave_info + 4);
11
}




Ich habe allerdings einen Verdacht, könnte es sein, daß Deine Struktur 
nicht ein Gerät, sondern eine fest definierte Anzahl von Geräten 
beschreiben soll?

Warum enthält Deine Struktur mehrere Elemente gleichen Namens mit 
angehängter Nummer?

Wenn das dazu dient, verschiedene Geräte auseinanderzuhalten, dann ist 
das ein Designfehler, weil es das Konzept des Arrays komplett ad 
absurdum führt.

Du solltest die Struktur so definieren, daß sie genau ein Gerät 
beschreibt; daß es mehrere Geräte gibt, ist ja durch das Array geklärt.

Wenn ich das richtig interpretiert habe, sollte die Struktur also so 
aussehen:
1
typedef struct SLAVE_INFO 
2
{ 
3
  Uint8 Active; 
4
  Uint8 Serial; 
5
  Uint8 Status; 
6
  Uint8 SlaveAddr; 
7
  Uint8 Uist; 
8
  Uint8 List; 
9
  Uint8 PwrUpCnt; 
10
  Uint8 Time; 
11
  Uint8 Config; 
12
}

Oder habe ich Dich da missverstanden?

von Andi79 (Gast)


Lesenswert?

Hallo ja super ganau so habe ich mir das eigentlich gedacht.
Danke

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.