www.mikrocontroller.net

Forum: Compiler & IDEs Datenzuweisung an Struct


Autor: Sven (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Nex (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oder mit nem Pointer darauf zugreifen

Autor: Eugen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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.
  aktuellezeit.sekunden = sekunden_vom_rtc;
  aktuellezeit.minuten  = minuten_vom_rtc;
  aktuellezeit.stunden  = stunden_vom_rtc;

Allenfals könnte man sich noch eine Funktion dafür schreiben:
void AssignTime( struct zeitformat* zeit,
                 uint8_t stunden, uint8_t minuten, uint8_t sekunden )
{
  zeit->sekunden = sekunden;
  zeit->minuten  = minuten;
  zeit->studnen  = stunden;
}

und die dann benutzen, wenn so eine Zuweisung häufiger auftritt
    ...
    AssignTime( &aktuellezeit, stunden_vom_rtc, minuten_vom_rtc, sekunden_vom_rtc );
    ....
    ....
    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
   struct zeitformat a;
   struct zeitformat b;

   ...
   AssignTime( &a, stund, minut, sekund );
   ...
   b = a;

Wenn du die Zeit auf 0 setzen musst, kannst du alternativ
  AssignTime( &a, 0, 0, 0 );
oder
  memset( &a, 0, sizeof( a ) );
benutzen.

Autor: Rup (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Strukturzuweisung nach ANSI C99 lautet:
struct zeitformat a;

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:
#define MAKE_ZEITFORMAT(stu, min, sek) (struct zeitformat){.sekunden = sek, .minuten = min, stunden = .stu}

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>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.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Martin L. (melvin_the_moose)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
struct zeitformat
  {
  uint8_t sekunden;
  uint8_t minuten;
  uint8_t stunden;
  };

typedef struct zeitformat zeitformat_t;

union zeit_union
  {
  zeitformat_t s;
  uint8_t b[3];
  } aktuellezeit;

  /*Zuweisung durch Strukturelement*/
  aktuellezeit.s.sekunden = 12u;
  aktuellezeit.s.minuten  = 34u;
  aktuellezeit.s.stunden  = 11u;

  /*Zuweisen in einer Schleife*/
  for (unsigned int i=0; i<3; i++)
  {
  aktuellezeit.b[i]=0;
  }

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.

Autor: Also nee (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Man könnte auch ein Array definieren und den Inidzes vorher per Makros 
Namen geben:
typedef uint8_t zeitformat[3];

#define SEKUNDEN 0
#define MINUTEN 1
#define STUNDEN 2

aktuellezeit[SEKUNDEN] = 12;
aktuellezeit[MINUTEN] = 34;
aktuellezeit[STUNDEN] = 11;

for (unsigned int i=0; i<3; i++)
{
   aktuellezeit[i]=0;
}

So kann man auf union-Hacks verzichten.

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.