Forum: Mikrocontroller und Digitale Elektronik nested struct Zugriff


von Dany (Gast)


Lesenswert?

Hallo,

ich habe folgende Struktur auf die ich zugreifen möchte irgendwie bin 
ich überfragt.

Hat einer einen Rat bzw. Vorschlag wie man das in C macht?

Meine Idee wäre z.B. bei der Zuweisung der Variable so:
1
   GenSettings.info[0] = 255;
2
   GenSettings.zl->TEMP = 400;  
3
   GenSettings.zl->west.ledCW = 100;

Aber wie kann ich auf z.B. zl[5].west.ledWW zuweisen?

Wie würde es entsprechend andersherum funktionieren?
1
   uint32_t temp;
2
   int8_t temp1;
3
4
   temp = GenSettings.time; 
5
   temp1 = GenSettings.zl[3]->west.ledIR;

1
typedef struct
2
{  
3
        uint8_t zl;  
4
5
  uint16_t gR;
6
  int16_t gG;
7
  int16_t gB;
8
  int16_t gM;
9
  
10
  int8_t ledWW;
11
  int8_t ledCW;
12
  int8_t ledUV;
13
  int8_t ledIR;
14
  
15
  int16_t mot_Pos1Offset;
16
  int16_t mot_Pos2Offset;  
17
18
}Att_t; 
19
20
typedef struct
21
{  
22
  
23
  uint16_t m0;
24
  uint16_t m1;
25
  
26
  uint8_t ledWW;
27
  uint8_t ledCW;
28
  uint8_t ledUV;
29
  uint8_t ledIR;  
30
  
31
  uint16_t x;
32
  uint16_t y;
33
  
34
  uint16_t TEMP;  
35
  
36
  Att_t d;
37
  Att_t s;
38
  Att_t b;
39
  Att_t west;  
40
  
41
}ZSet_t;
42
43
typedef struct
44
{
45
  
46
        uint32_t time;
47
  uint8_t ver;
48
  uint8_t info [5];  
49
50
  ZSet_t zl[8];
51
52
}MDSet_t;
53
54
MDSet_t GenSettings;

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Dany schrieb:
> Meine Idee wäre z.B. bei der Zuweisung der Variable so:
> GenSettings.info[0] = 255;
>    GenSettings.zl->TEMP = 400;
>    GenSettings.zl->west.ledCW = 100;

Das funktioniert nicht so. zl ist kein Pointer, sondern ein Array, und 
das kann hier nicht synonym verwendet werden:

>  ZSet_t zl[8];

Und damit ist die Frage

>  Aber wie kann ich auf z.B. zl[5].west.ledWW zuweisen?

eigentlich schon geklärt:

>    GenSettings.zl[5].west.ledCW = 100;

von Dany (Gast)


Lesenswert?

Rufus Τ. F. schrieb:
> Das funktioniert nicht so. zl ist kein Pointer, sondern ein Array, und
> das kann hier nicht synonym verwendet werden:

Wie würde ich auf das Array zugreifen?

Dany schrieb:
> GenSettings.info[0] = 255;
>    GenSettings.zl->TEMP = 400;
>    GenSettings.zl->west.ledCW = 100;
>
Ist diese Zuweisung so korrekt?
1
GenSettings.info[0] = 255;


> Wie würde es entsprechend andersherum funktionieren?
>    uint32_t temp;
>    int8_t temp1;
>
>    temp = GenSettings.time;
>    temp1 = GenSettings.zl[3]->west.ledIR;

Wie weise ich das einer anderen Variablen zu?
1
   uint8_t temp1 = GenSettings.info[0];

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Dany schrieb:
> Ist diese Zuweisung so korrekt?
> GenSettings.info[0] = 255;

Ja.

> Wie weise ich das einer anderen Variablen zu?
> uint8_t temp1 = GenSettings.info[0];

Genau so.

Trau' Dich doch einfach mal, das Deinem C-Compiler vorzuwerfen. Der gibt 
eine Fehlermeldung aus, wenn ihm was nicht passt.

von Dany (Gast)


Lesenswert?

Habe es jetzt so gemacht und der Compiler meckert nicht :-)
1
   GenSettings.zl[3].west.ledCW = 234;
2
   
3
   uint8_t temp;
4
   temp = GenSettings.zl[3].west.ledCW;

Wie kann ich am sinnvollsten zl[0..8] mit Werten initialisieren?

also nicht manuell wie hier..
1
 
2
   GenSettings.zl[0].west.ledCW = 23;
3
   GenSettings.zl[1].west.ledCW = 44;
4
   GenSettings.zl[2].west.ledCW = 23;
5
   GenSettings.zl[3].west.ledCW = 78;
6
   GenSettings.zl[4].west.ledCW = 99;
7
   GenSettings.zl[5].west.ledCW = 102;
8
   GenSettings.zl[6].west.ledCW = 234;
9
   GenSettings.zl[7].west.ledCW = 255;
10
   GenSettings.zl[8].west.ledCW = 2;

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Das ist keine Initialisierung, sondern eine Zuweisung.

Um ein Array zu initialisieren, ist folgende Schreibweise anzuwenden:
1
int arr[3] = { 12, 34, 56 };

Um eine Struktur zu initialisieren, ist die gleiche Schreibweise 
anzuwenden, die Werte müssen aber vom Typ her zum jeweiligen 
Strukturelement passen:
1
struct bla
2
{
3
  int a;
4
  char b[20];
5
  float c;
6
};
7
8
struct bla x = { 2, "huhu", 1.234 };

Bei einem Array aus Strukturen sind beide Varianten zu kombinieren:
1
struct bla
2
{
3
  int a;
4
  char b[20];
5
  float c;
6
};
7
8
struct bla y[2] = { { 2, "huhu", 1.234 }, { 9, "ciao", 3.1415 } };

Bei einer Struktur, die ein Array enthält (anders als obiges, wo ich mir 
mit der Stringkonstanten das Leben einfach gemacht habe), ist ebenfalls 
eine Kombination aus beiden Varianten anzuwenden:

1
struct bla
2
{
3
  int a;
4
  uint8_t b[3];
5
  float c;
6
};
7
8
struct bla z = { 2, { 1, 2, 3 }, 1.234 };


Entscheidend ist aber: Das alles ist nur bei Initialisierungen 
möglich, nicht aber bei Zuweisungen.

von Dany (Gast)


Lesenswert?

Rufus Τ. F. schrieb:
> Das ist keine Initialisierung, sondern eine Zuweisung.

Sorry ich meinte eine Zuweisung.

Wie weise ich dem Array alle Elemente welches sich in der Struktur 
befindet

mit verschiedenen Werten elegant zu und nicht manuell wie ich das hier 
gemacht habe:
1
   GenSettings.zl[0].west.ledCW = 23;
2
   GenSettings.zl[1].west.ledCW = 44;
3
   GenSettings.zl[2].west.ledCW = 23;
4
   GenSettings.zl[3].west.ledCW = 78;
5
   GenSettings.zl[4].west.ledCW = 99;
6
   GenSettings.zl[5].west.ledCW = 102;
7
   GenSettings.zl[6].west.ledCW = 234;
8
   GenSettings.zl[7].west.ledCW = 255;
9
   GenSettings.zl[8].west.ledCW = 2;

p.s. Vielen Dank für die super Erklärung das bringt mich enorm weiter !

von Dany (Gast)


Lesenswert?

Hat niemand ne Idee wie man sowas elleganter Zuweisen kann?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

C keinnt keine Arrayzuweisung. Die einzige Möglichkeit, das, was Du da 
machen willst, eleganter zu machen, ist eben die Initialisierung.

Alternativ (aber kaum noch elegant) könntest Du ein zweites Array 
gleicher Größe und gleichen Typs anlegen, das mit den gewünschten Daten 
initialisieren und seinen Inhalt mit memcpy() in das Zielarray kopieren.

von Stefan E. (sternst)


Lesenswert?

Dany schrieb:
> Hat niemand ne Idee wie man sowas elleganter Zuweisen kann?

1
void Set_ledCW (const uint8_t *data) {
2
3
    for (uint8_t i = 0; i < 9; i++)
4
        GenSettings.zl[i].west.ledCW = data[i];
5
}
Aufruf:
1
Set_ledCW((const uint8_t[]){23,44,23,78,99,102,234,255,2});

Übrigens:
1
  ZSet_t zl[8];
Dein zl ist zu klein.

von Mario (Gast)


Lesenswert?

Stefan E. schrieb:
> void Set_ledCW (const uint8_t *data) {
>
>     for (uint8_t i = 0; i < 9; i++)
>         GenSettings.zl[i].west.ledCW = data[i];
> }
> Aufruf:Set_ledCW((const uint8_t[]){23,44,23,78,99,102,234,255,2});

super sowas hab ich gesucht :-)

Stefan E. schrieb:
> Übrigens:  ZSet_t zl[8];Dein zl ist zu klein.

Danke. copy & paste Fehler sollte nur bis [7] gehen ;-)
1
   GenSettings.zl[0].west.ledCW = 23;
2
   GenSettings.zl[1].west.ledCW = 44;
3
   GenSettings.zl[2].west.ledCW = 23;
4
   GenSettings.zl[3].west.ledCW = 78;
5
   GenSettings.zl[4].west.ledCW = 99;
6
   GenSettings.zl[5].west.ledCW = 102;
7
   GenSettings.zl[6].west.ledCW = 234;
8
   GenSettings.zl[7].west.ledCW = 255;

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.