Forum: PC-Programmierung Array of struct initialisieren


von Christian J. (Gast)


Lesenswert?

Hallo,

ist zwar ein Thema für den ARM aber glaube für PC ist das ähnlich oder 
gleich.

Ich habe für meine Wetterstation eine Anzahl Zahlen, die Wetterzustände 
ausdrücken. Diese werden vom Provider der Wetterinfo geliefert
200, 202, 203..... 500,501, 502, 510..... usw.
Abhängig von dieser Info werden LED gesetzt. Also für 202 wird zb 
13,14,15 gesetzt, mal sind es 2, mal 3 oder 4.

Die Tabelle steht hier, entspricht der internationalen Darstellung:
https://openweathermap.org/weather-conditions

Ich habe nun

typedef struct {
      char led[5];
      +ggf. weitere Vars
} led_t;

led_t wettercond[30];

In wettercond müssen 30 Zahlen rein aus den Tabellen des Dienstes und in 
den Struct muss zu jeder Zahl die Info stehen, welche LED dazu gehören.

Gibt es da was Kluges, das ohne ein händisches Füllen in einer Routine 
zu machen? Wäre quasi sowas: 200,6,7,201,3,4,5,205,1,2,210,.... wobei 
die kleinen Zahlen immer die LED Nummern sind und die 3stelligen das 
Wetter.

Gruss,
Christian

von jemand (Gast)


Lesenswert?

Ich nehme an es gibt keinen naheliegenden, mathematischen Zusammenhang 
zwischen den Wettercodes und den LEDs, also wie soll das gehen?

Den Zusammenhang kennst ja nur du, also musst du den auch in Code 
ausdrücken

von Christian J. (Gast)


Lesenswert?

jemand schrieb:
> Den Zusammenhang kennst ja nur du, also musst du den auch in Code
> ausdrücken

Ja, deswegen ja. Nur wie kriege ich die vielen Zahlen effizient da rein?

von Christian J. (Gast)


Lesenswert?

Kann mal einer gucken, habe keinen Compiler auf dem Rechner. Ist das so 
von der Syntax richtig?
1
typedef struct {
2
  uint8_t wid;
3
  uint8_t led[5];
4
} led_t;
5
6
led_t wcond[60] = 
7
          { 800, .led[0] = LED_GRN                      } ,
8
          { 801, .led[0] = LED_GRN, .led[1] = LED_GLB_1            } ,
9
          { 802, .led[0] = LED_GLB_1                      } ,
10
          { 803, .led[0] = LED_GLB_1,.led[1] = LED_GLB_1            } ,
11
          { 701, .led[0] = LED_GLB_1,.led[1] = LED_GLB_1,.led[1] = LED_GLB_1  } ,
12
          { 741, .led[0] = LED_GLB_1,.led[1] = LED_GLB_1,.led[1] = LED_GLB_1  } ,
13
          { 804, .led[0] = LED_GLB_1,.led[1] = LED_GLB_1,.led[1] = LED_GLB_1  } ,

von Dr. Sommer (Gast)


Lesenswert?

Eher so:
1
led_t wcond[60] = 
2
          { 800, { LED_GRN }},
3
          { 801, { LED_GRN, LED_GLB_1 }} , // usw ...
4
};
Da sich das Array vermutlich nicht ändert packe noch ein "const" dran. 
Bei Mikrocontrollern packt der Compiler das dann in den Flash (spart 
RAM), bei PC-Betriebssystemen (typischerweise) in eine Section die man 
nicht versehentlich überschreiben kann.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Christian J. schrieb:
> Ist das so von der Syntax richtig?

Wenn es C99 oder neuer sein soll.

In C89 sähe das so aus:
1
led_t wcond[60] = 
2
          { 800, { LED_GRN } } ,
3
          { 801, { LED_GRN, LED_GLB_1 } } ,
4
          { 802, { LED_GLB_1 } } ,
5
          { 803, { LED_GLB_1, LED_GLB_1 } } ,
6
          { 701, { LED_GLB_1, LED_GLB_1, LED_GLB_1 } } ,
7
          { 741, { LED_GLB_1, LED_GLB_1, LED_GLB_1 } } ,

etc.

von Christian J. (Gast)


Angehängte Dateien:

Lesenswert?

Rufus Τ. F. schrieb:
> Christian J. schrieb:
>> Ist das so von der Syntax richtig?
>
> Wenn es C99 oder neuer sein soll.
>
> In C89 sähe das so aus:
> led_t wcond[60] =
>           { 800, { LED_GRN } } ,
>           { 801, { LED_GRN, LED_GLB_1 } } ,
>           { 802, { LED_GLB_1 } } ,
>           { 803, { LED_GLB_1, LED_GLB_1 } } ,
>           { 701, { LED_GLB_1, LED_GLB_1, LED_GLB_1 } } ,
>           { 741, { LED_GLB_1, LED_GLB_1, LED_GLB_1 } } ,
>
> etc.

Ok, die . Schreibweise ist nicht möglich? Meine das schonmal geseehn zu 
haben, ist für mich etwas übersichtlicher. C99 ist eingestellt.

Siehe
https://stackoverflow.com/questions/18921559/initializing-array-of-structures

von DPA (Gast)


Lesenswert?

Christian J. schrieb:
> Ok, die . Schreibweise ist nicht möglich?

Doch doch, ab c99 schon, und das gibts sowieso überall. Ich würde da 
aber nicht jeden Index einzeln angeben, das wird schnell unübersichtlich

Ungetestet:
1
led_t wcond[60] = { // Die geschweifte Klammer nicht vergessen!
2
          { 800, .led = { LED_GRN } } ,
3
          { 801, .led = { LED_GRN, LED_GLB_1 } } ,
4
          { 802, .led = { LED_GLB_1 } } ,
5
          { 803, .led = { LED_GLB_1, LED_GLB_1 } } ,
6
          { 701, .led = { LED_GLB_1, LED_GLB_1, LED_GLB_1 } } ,
7
          { 741, .led = { LED_GLB_1, LED_GLB_1, LED_GLB_1 } }
8
};

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Bei der vorliegenden Struktur kann man aber auch die C89-Schreibweise 
verwenden. Die Schreibweise, bei der einzelne Strukturelemente benannt 
werden, ist erst dann zwingend erforderlich, wenn man nicht alle 
aufeinanderfolgenden Elemente initialisieren will, sondern Lücken 
dazwischen lässt.
1
typedef struct 
2
{
3
  int x;
4
  int y;
5
  int z;
6
  char *s;
7
  int a;
8
} test_t;
9
10
test_t test[] = 
11
{
12
 { 1, 2, 3, "huhu", 4},  // alle elemente
13
 { 1, 2, 3 },            // nur die ersten drei
14
...

Möchte man aber nur das dritte Element initialisieren, muss man in C89 
die beiden davorliegenden trotzdem (mit 0) initialisieren.

Erst in diesem Fall bringt die "Punkt-Schreibweise" von C99 einen 
Vorteil:
1
 { 0, 0, 5 },  // c89: z initialisieren
2
3
 { .z = 5 },   // c99: z initialisieren


Im vorliegenden Fall aber ist die "Punkt-Schreibweise" nur mehr 
Tipparbeit, ohne daß die Übersichtlichkeit dadurch verstärkt wird.

von Bernd K. (prof7bit)


Lesenswert?

Rufus Τ. F. schrieb:
> Im vorliegenden Fall aber ist die "Punkt-Schreibweise" nur mehr
> Tipparbeit, ohne daß die Übersichtlichkeit dadurch verstärkt wird.

Sie hat aber den Vorteil dass wenn man hinterher die Struktur nochmal 
ändert man sofort merkt an welchen Stellen des Initializers man 
vergessen hat das ebenfalls anzupassen (oder wenn man Glück hat gar 
nicht erst anpassen muss). Die Punkt-Schreibweise ist robuster.

von Wilhelm M. (wimalopaan)


Lesenswert?

Christian J. schrieb:
> Hallo,
>
> ist zwar ein Thema für den ARM aber glaube für PC ist das ähnlich oder
> gleich.

Reines C oder C++?

von Wilhelm M. (wimalopaan)


Lesenswert?

Rufus Τ. F. schrieb:

>
> Im vorliegenden Fall aber ist die "Punkt-Schreibweise" nur mehr

Nennt sich "designated initializer" -> erleichtert google ;-)

von Christian J. (Gast)


Lesenswert?

Ok, ich hoffe mal, dass die Tipparbeit nicht umsonst war.....
Danke für die Hinweise, finde es inzwischen auch übersichtlicher ohne
die .led Schreibweise. Es scheint zudem nichts zu geben, was die Cracks 
hier nicht wissen :-)

Die CPU wird dann da durch turnen und sich heraussuchen, was zutrifft. 
Über den MC23017 wird dann blinken und leuchten. Das Blinken muss ich 
mir aber noch überlegen, wie das gehen soll. In einem alten Projekt war 
jede LED ein Bit im bit-bandind Bereich, da war das easy. Hier hängen 
sie am MCP 23017 dran.

1
typedef struct {
2
  uint8_t wid;
3
  uint8_t led[5];
4
} led_t;
5
          /* Wolken und Nebel */
6
led_t wcond[60] =   { 800, { LED_GRN }                  },  /* Clear */
7
          { 801, { LED_GRN, LED_GLB_1  }            },  /* few clouds */
8
          { 802, { LED_GLB_1 }                },  /* scattered clouds */
9
          { 803, { LED_GLB_1, LED_GLB_2 }            }, /* broken clouds */
10
          { 701, { LED_GLB_1, LED_GLB_2, LED_GLB_3 }           }, /* Fog */
11
          { 741, { LED_GLB_1, LED_GLB_2, LED_GLB_3 }      }, /* overcast clouds */
12
          { 804, { LED_GLB_1, LED_GLB_2, LED_GLB_3 }      },
13
          /* Schnee */
14
          { 600, { LED_WS_1 }                  },  /* light snow */
15
          { 601, { LED_WS_1, LED_WS_2 }            }, /* snow */
16
          { 602, { LED_WS_1, LED_WS_2  }            }, /* heavy snow */
17
          { 611, { LED_WS_1, LED_ROT_1 }            }, /* sleet */
18
          { 612, { LED_WS_1, LED_GRN }            }, /* shower sleet */
19
          { 615, { LED_WS_1, LED_ROT_1 }            }, /* light rain and snow */
20
          { 620, { LED_WS_1 }                  },  /* rain and snow */
21
          { 621, { LED_GRN, LED_WS_1 }            }, /* light shower snow */
22
          { 622, { LED_GRN, LED_WS_1, LED_WS_2  }      }, /* heavy shower snow */
23
          /* Regen */
24
          { 500, { LED_ROT_1 }                }, /* light rain */
25
          { 501, { LED_ROT_1, LED_ROT_2 }            }, /* moderate rain */
26
          { 502, { LED_ROT_1, LED_ROT_2, LED_ROT_3 }      }, /* heavy rain */
27
          { 503, { LED_ROT_1, LED_ROT_2, LED_ROT_3 }      }, /* very heavy rain */
28
          { 504, { LED_ROT_1, LED_ROT_2, LED_ROT_3 }      }, /* extreme rain */
29
          { 511, { LED_ROT_1, LED_WS_1 }            }, /* freezing rain */
30
          { 520, { LED_GRN, LED_ROT_1 }            }, /* light intensity shower rain */
31
          { 521, { LED_GRN, LED_ROT_1,LED_ROT_2 }        }, /* shower rain */
32
          { 522, { LED_GRN, LED_ROT_1,LED_ROT_2, LED_ROT_3 }  }, /* heavy intensity shower rain */
33
          { 531, { LED_GRN, LED_ROT_1,LED_ROT_2, LED_ROT_3 }  }, /* ragged shower rain */
34
          /* Niesel Regen */
35
          { 300, { LED_ROT_1, LED_GLB_1 }            },   /* light drizzle */
36
          { 301, { LED_ROT_1, LED_ROT_2, LED_GLB_1 }      },   /* drizzle */
37
          { 302, { LED_ROT_1, LED_ROT_2, LED_ROT_3, LED_GLB_1 } }, /* heavy drizzle */
38
          { 310, { LED_ROT_1, LED_GLB_1 }           },   /* light drizzle + rain */
39
          { 311, { LED_ROT_1, LED_ROT_2, LED_GLB_1 }       },   /* drizzle + rain */
40
          { 312, { LED_ROT_1, LED_ROT_2, LED_ROT_3, LED_GLB_1 } }, /* heavy drizzle + rain */
41
          { 313, { LED_GRN, LED_ROT_1, LED_GLB_1 }       },   /* shower rain + drizzle */
42
          { 314, { LED_GRN, LED_ROT_1, LED_ROT_2, LED_GLB_1 }  },   /* heavy shower rain + drizzle */
43
          { 321, { LED_GRN, LED_ROT_1, LED_GLB_1 }       },   /* shower drizzle */
44
          /* Gewitter / Thunderstorm */
45
          { 200, { LED_BLAU_1, LED_ROT_1 }             },   /* thunderstorm with light rain*/
46
          { 201, { LED_BLAU_1, LED_ROT_1, LED_ROT_2 }        },   /* thunderstorm with rain*/
47
          { 202, { LED_BLAU_1, LED_ROT_1, LED_ROT_2, LED_ROT_3 }   },  /* thunderstorm with heavy rain*/
48
          { 210, { LED_BLAU_1 }                   },  /* light thunerstorm, no rain*/
49
          { 211, { LED_BLAU_1,LED_BLAU_2 }             },  /* thunerstorm, no rain*/
50
          { 212, { LED_BLAU_1,LED_BLAU_2 }             },  /* heavy thunerstorm */
51
          { 221, { LED_BLAU_1 }                   },  /* Ragged thunderstorm */
52
          { 230, { LED_BLAU_1, LED_GLB_1 }             },  /*  thunderstorm with light drizzle */
53
          { 231, { LED_BLAU_1, LED_GLB_1, LED_GLB_2 }        },  /*  thunderstorm with drizzle */
54
          { 232, { LED_BLAU_1, LED_GLB_1, LED_GLB_2, LED_GLB_2 }   }  /*  thunderstorm with drizzle */

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Bernd K. schrieb:
> Sie hat aber den Vorteil dass wenn man hinterher die Struktur nochmal
> ändert man sofort merkt an welchen Stellen des Initializers man
> vergessen hat das ebenfalls anzupassen

Ja.

Wenn man allerdings mal in die Verlegenheit kommt, den Code einem 
C++-Compiler vorzuwerfen, gibts Probleme - denn in C++ gibt es keine 
"designated initializers".

von Wilhelm M. (wimalopaan)


Lesenswert?

Rufus Τ. F. schrieb:
> Bernd K. schrieb:
>> Sie hat aber den Vorteil dass wenn man hinterher die Struktur nochmal
>> ändert man sofort merkt an welchen Stellen des Initializers man
>> vergessen hat das ebenfalls anzupassen
>
> Ja.
>
> Wenn man allerdings mal in die Verlegenheit kommt, den Code einem
> C++-Compiler vorzuwerfen, gibts Probleme - denn in C++ gibt es keine
> "designated initializers".

Ab gcc-8 bzw. dann auch c++20 bzw. c++2a nicht mehr.

von guest (Gast)


Lesenswert?

Christian J. schrieb:
> Ok, ich hoffe mal, dass die Tipparbeit nicht umsonst war.....

So wird das nichts. Da fehlen immer noch ein Paar geschweifte Klammern, 
siehe Post von DPA:
Beitrag "Re: Array of struct initialisieren"

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

guest schrieb:
> s. Da fehlen immer noch ein Paar geschweifte Klammern

Ein Paar?

Eine. Mit einem Semikolon dahinter.

von guest (Gast)


Lesenswert?

Rufus Τ. F. schrieb:
> Ein Paar?
>
> Eine. Mit einem Semikolon dahinter.

Zwei. Eine öffnende und eine schließende (und das Semikolon dahinter 
natürllich).
Deshalb hab ich ja extra auf den Post von DPA verwiesen, da steht ein 
entsprechender Kommentar im Source:
1
// Die geschweifte Klammer nicht vergessen!

von DPA (Gast)


Lesenswert?

Rufus Τ. F. schrieb:
> Wenn man allerdings mal in die Verlegenheit kommt, den Code einem
> C++-Compiler vorzuwerfen, gibts Probleme

Und warum sollte man das tun? Den C Code als C Code übersetzen, den C++ 
code als C++ Code, den Rust Code als Rust Code, etc. Die Object Files 
kann man dann immer noch zusammen linken, und mit den C Symbolen kommen 
fast alle Sprachen zurecht, wenn man es angibt (extern "C").

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

guest schrieb:
> Eine öffnende

Stimmt.

von foobar (Gast)


Lesenswert?

Wozu überhaupt das led-array in der struct?  Bits reichen doch und 
machen die Verarbeitung einfacher:
1
#define LED1    1
2
#define LED2    2
3
...
4
5
#define SUN     (1<<LED1)
6
#define CLOUD   (1<<LED2)
7
#define RAIN    (1<<LED3)
8
...
9
10
struct led {
11
    unsigned id, leds;
12
};
13
14
const struct led wcond[] = {
15
    { 202, CLOUD | RAIN },
16
    { 801, SUN },
17
    ...
18
};

von Christian J. (Gast)


Lesenswert?

main.h:72: error: expected unqualified-id before '{' token

      { 801, { LED_GRN, LED_GLB_1 }      }, /* few clouds */

      ^

exit status 1
expected unqualified-id before '{' token

Mecker, mecker..... irgendwas mag er nicht. Klammern? Was fehlt denn da 
noch? Ok, Semikolon unten, aber sonst?

Ah ok, Groschen gefallen, läuft durch :-) Bisschen zu viel Klammern....

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.