Array of struct initialisieren

Gast #5726605
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
Gast #5726625
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
Gast #5726809
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  } ,
Gast #5726820
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.
Persönliche Seite #5726821
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.
Gast #5726828
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
Angehängte Dateien:
Gast #5726874
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
};
Persönliche Seite #5726913
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.
#5726954
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.
Gast #5727007
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 */
Persönliche Seite #5727014
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".
#5727023
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.
Gast #5727054
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!
Gast #5727066
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").
Gast #5727138
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
};
Gast #5727200
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....

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren