Hallo, ich kann meinen ATmega32 mit dem AVR-GCC einigermassen gut Programmieren, bin aber auf eine Sache gestossen die ich nicht lösen kann. Habe versucht darüber Informationen zu finden, allerdings ohne Erfolg. Mein Problem ist folgendes: Ich habe einen Struct definiert und möchte gerne "numerisch" auf die jeweiligen Elemente zugreifen. Der Struct: struct zeitformat { uint8_t sekunden; uint8_t minuten; uint8_t stunden; } aktuellezeit; Jetzt lese ich die RTC aus und weise aktuellezeit.sekunden die Sekunden zu, das selbe mache ich mit den Minuten und Stunden. Dies funktioniert auch alles, nur muss ich für jedes Element des Struct's eine Zuweisung schreiben (viel Programmcode). Einfacher wäre eine Schleife - geht das ? Gibt es eine Möglichkeit auf die Elemente des Sruct's auch mit einer Variablen zuzugreifen? Vielen Dank für einen Tip
soetwas hab ich mal benutzt um beim initialisieren ein struct zu löschen (als ich noch nicht wusste wie es anders geht). dabei musste ich erst die Pointeradresse des structs in ein u_int casten (zum zählen, sonst zählt er dabei bei (&STRUKTUR)+i das i als vielfache von sizeof(STRUKTUR) ) und dann diesen neuen u_int als charpointer casten um auf einzelne Bytes schreiben zu können //löschen des structs for(unsigned int i =0;i<sizeof(STRUKTUR);i++) { *(unsigned char*)((unsigned int)(&STRUKTUR)+i)=0; } in deinem Fall würde ich aber aufpassen, denn sobald du verschiedengroße Datentypen in deinem struct hast, musst du sowieso für jede Variable dir überlegen wie groß die Variable ist und was da rein muss. ein Feld von void* (wegen den verschiedenen Datentypen) würde dir vieleicht helfen. dann könntest du zum einem auf die Werte per Zeiger iterativ zugreifen und zum anderen ihnen per defines Namen geben.
> Jetzt lese ich die RTC aus und weise aktuellezeit.sekunden die > Sekunden zu, das selbe mache ich mit den Minuten und Stunden. Dies > funktioniert auch alles, nur muss ich für jedes Element des > Struct's eine Zuweisung schreiben (viel Programmcode). Das wirst du nicht einfacher machen können. Sind doch nur 3.
1 | aktuellezeit.sekunden = sekunden_vom_rtc; |
2 | aktuellezeit.minuten = minuten_vom_rtc; |
3 | aktuellezeit.stunden = stunden_vom_rtc; |
Allenfals könnte man sich noch eine Funktion dafür schreiben:
1 | void AssignTime( struct zeitformat* zeit, |
2 | uint8_t stunden, uint8_t minuten, uint8_t sekunden ) |
3 | {
|
4 | zeit->sekunden = sekunden; |
5 | zeit->minuten = minuten; |
6 | zeit->studnen = stunden; |
7 | }
|
und die dann benutzen, wenn so eine Zuweisung häufiger auftritt
1 | ...
|
2 | AssignTime( &aktuellezeit, stunden_vom_rtc, minuten_vom_rtc, sekunden_vom_rtc ); |
3 | ....
|
4 | ....
|
5 | AssignTime( &aktuellezeit, stunden_vom_rtc, minuten_vom_rtc, sekunden_vom_rtc ); |
Falls du Zeiten aneinander zuweisen musst, dann kannst du das mit einer normalen Zuweisung machen
1 | struct zeitformat a; |
2 | struct zeitformat b; |
3 | |
4 | ...
|
5 | AssignTime( &a, stund, minut, sekund ); |
6 | ...
|
7 | b = a; |
Wenn du die Zeit auf 0 setzen musst, kannst du alternativ
1 | AssignTime( &a, 0, 0, 0 ); |
oder
1 | memset( &a, 0, sizeof( a ) ); |
benutzen.
Die Strukturzuweisung nach ANSI C99 lautet:
1 | struct zeitformat a; |
2 | |
3 | a = { .sekunden = x, .minuten = y, .stunden = z }; |
Das sollte jeder moderner GNU-Compiler ab 3.0 können. Man kann sich auch leicht ein Makro daraus bauen:
1 | #define MAKE_ZEITFORMAT(stu, min, sek) (struct zeitformat){.sekunden = sek, .minuten = min, stunden = .stu}
|
>Ich habe einen Struct definiert und möchte gerne "numerisch" auf die >jeweiligen Elemente zugreifen. Wozu definierst du dann ein struct? Nimmst halt ein Array.
Rup wrote: > Die Strukturzuweisung nach ANSI C99 lautet: Es gibt kein “ANSI C99”. Es gibt nur ein “ISO/IEC 9899:1999”, kurz “ISO C99”. > a = { .sekunden = x, .minuten = y, .stunden = z }; Das ist keine Zuweisung, sondern eine Initialisierung und auch nur in diesem Kontext zulässig.
1 | struct zeitformat |
2 | {
|
3 | uint8_t sekunden; |
4 | uint8_t minuten; |
5 | uint8_t stunden; |
6 | };
|
7 | |
8 | typedef struct zeitformat zeitformat_t; |
9 | |
10 | union zeit_union |
11 | {
|
12 | zeitformat_t s; |
13 | uint8_t b[3]; |
14 | } aktuellezeit; |
15 | |
16 | /*Zuweisung durch Strukturelement*/
|
17 | aktuellezeit.s.sekunden = 12u; |
18 | aktuellezeit.s.minuten = 34u; |
19 | aktuellezeit.s.stunden = 11u; |
20 | |
21 | /*Zuweisen in einer Schleife*/
|
22 | for (unsigned int i=0; i<3; i++) |
23 | {
|
24 | aktuellezeit.b[i]=0; |
25 | }
|
Ich habe das Beispiel nicht compiliert. Ich hoffe, es sind keine Syntaxfehler drin... Aber so müßte es gehen, wenn es sein muß. Empfehlenswert ist diese Art des Zugriffs auf Strukturelemente jedoch nicht, da der Compiler je nach Elementtypen im struct Lücken im Speicherlayout einfügen kann. Ein bestimmter Arrayindex entspricht dann nicht immer einem bestimmten Strukturelement. Dieses Verhalten ist (Compiler-) implementierungsabhängig und möglicherweise nicht portabel.
Man könnte auch ein Array definieren und den Inidzes vorher per Makros Namen geben:
1 | typedef uint8_t zeitformat[3]; |
2 | |
3 | #define SEKUNDEN 0
|
4 | #define MINUTEN 1
|
5 | #define STUNDEN 2
|
6 | |
7 | aktuellezeit[SEKUNDEN] = 12; |
8 | aktuellezeit[MINUTEN] = 34; |
9 | aktuellezeit[STUNDEN] = 11; |
10 | |
11 | for (unsigned int i=0; i<3; i++) |
12 | {
|
13 | aktuellezeit[i]=0; |
14 | }
|
So kann man auf union-Hacks verzichten.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.