Forum: Compiler & IDEs Ich steh auf dem Schlauch bzgl. Pointern.


von Ludwig Martin (Gast)


Lesenswert?

Servus zusammen,

ich steh grad ein bissl aufm Schlauch und Google sowie meine Literatur 
wollen mir mangels passenden Suchbegriffen oder einer zu spezifischer 
Frage (oder auch zu großem Knoten im Kopf) auch nicht behilflich sein.

Folgendes: ich habe eine Structur, die ich ganz nochmal wie eine 
Structur auslesen möchte. Schreiben möchte ich in sie allerdings wie in 
ein Array, da ich die Bytes der Structur in passender Reihenfolge über 
den UART empfange.
Meinen aufs wesentliche reduzierten Code würde ich also folgendermaßen 
schreiben:
1
#include ...
2
3
struct struct_t {
4
   uint16_t a;
5
   uint16_t b;
6
   uint8_t  c;
7
};
8
9
uint8_t array[5];
10
11
int main ( void ) {
12
13
   uint16_t lesen;
14
   struct struct_t *ptr = array;
15
16
   // eine uint16_t aus dem array auslesen...
17
   lesen = *ptr.b;
18
}
19
20
21
ISR( UART_RX_vect ) {
22
   ststic uint8_t i=0;
23
   array[i] = UDR;
24
   i++;
25
   if( i >= 5 )
26
      i = 0;
27
}

Meine Frage lautet nun, ob ich, wie oben, auf das Array auch über den 
Pointer zugreifen kann?

Klar ich könnte es einfach probieren, doch da meine Hardware keine 
Ausgabemöglichkeiten hat mit denen ich das ordentlich testen könnte muss 
ich leider mal bei den Profis anfragen.

Könnte ich also wie in meinem Code oben UART-Daten empfangen und in der 
main() auswerten?


Vielen Dank

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Vereinige das Array und die struct in einer union.

von Helfer (Gast)


Lesenswert?

1) Das Thema wurde hier schon öfter diskutiert. Statt einfachem Cast 
wird gelegentlich eine union mit Struct und Array benutzt.

2) Die grundsätzliche Funktion kannst du auch auf dem PC testen, wenn du 
dir ein Testprogramm schreibst. Auf dem AVR bietet sich zum Testen auch 
der Simulator an. Dort kann man Variablen überwachen und das Programm 
schrittweise nachverfolgen.

von willibald (Gast)


Lesenswert?

Es heißt (*ptr).b oder einfacher ptr->b. *ptr.b geht deshalb nicht, weil 
der Punkt stärker bindet als der Stern.

Ansonsten: Du verlässt dich darauf, dass die Struktur-Member a, b und c 
lückenlos aneinanderstoßen. Da das hier offentsichtlich AVR-Code ist, 
klappt das vermutlich so, prinzipiell darf der Compiler aber zwischen 
den Members auch Lücken lassen, wenn er dadurch effizienteren Code 
erzeugen kann. Geh davon aus, dass Compiler für andere Plattformen das 
tun.

Du kannst den Compiler ausdrücklich anweisen, die Struktur dicht an 
dicht zu packen. gcc macht das mit

struct struct_t {
   uint16_t a;
   uint16_t b;
   uint8_t  c;
} __attribute__((packed));

von Jasch (Gast)


Lesenswert?

willibald schrieb:
> Ansonsten: Du verlässt dich darauf, dass die Struktur-Member a, b und c
> lückenlos aneinanderstoßen. Da das hier offentsichtlich AVR-Code ist,
> klappt das vermutlich so, prinzipiell darf der Compiler aber zwischen
> den Members auch Lücken lassen, wenn er dadurch effizienteren Code
> erzeugen kann. Geh davon aus, dass Compiler für andere Plattformen das
> tun.

Was willibald schrieb.

Die richtige Vorgehensweise ist:

- man definiert (mit allen hässlichen Details bis zum letzten Bit) was 
über die serielle Leitung geht (Start-, Stop-, Paritätsbits sind dabei 
nur Lowlevel-Details),

- und davon ausgehend überlegt man wie man das auf den beiden 
beteiligten Seiten der Kommunikation in Arrays, Structs oder was auch 
immer man will hineinbekommt.

Alles andere wird Mist - und solche Fehler sind total unspassig zu 
suchen...

Wer wissen will wie der Detaillierungsgrad aussehen sollte kann sich die 
TCP/IP-RFCs oder auch die ETSI-Standards zu DVB ansehen.

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.