Forum: PC-Programmierung code optimieren stringarray, enum


von optimierer (Gast)


Lesenswert?

1
char *event_id_string[] = {
2
              "Tor auf",
3
              "Tor zu",
4
              "Fenster auf",
5
              "Fenster zu",
6
              "Türe auf",
7
              "Türe zu" }
8
9
enum event_id_code {
10
              TORAUF,
11
              TORZU,
12
              FENSTERAUF,
13
              FENSTERZU,
14
              TUEREAUF,
15
              TUEREZU }
16
              
17
  
18
switch (event_id_code) {
19
20
  case TORAUF    : printf(event_id_string[TORAUF]); break:
21
  case TORZU     : printf(event_id_string[TORZU]); break;
22
  case FENSTERAUF: printf(event_id_string[FENSTERAUF]); break;
23
  case FENSTERZU : printf(event_id_string[FENSTERZU); break;
24
  case TUEREAUF  : printf(event_id_string[TUEREAUF]); break;
25
  case TUEREZU   : printf(event_id_string[TUEREZU]); break;
26
  }

Wie würdet ihr das angehen?
So muss man immer aufpassen, bei der Erstellung der enumeration den 
richtigen Stringfortlauf einzuhalten, und wenn da was vertauscht wird, 
sieht es nicht mehr gut aus.

Fängt ihr mit der enumeration an, und dann die Stringliste
oder ganz anders?

von Yalu X. (yalu) (Moderator)


Lesenswert?

Falls C: Vielleicht helfen dir die "designated array initializers"
weiter. In diesem Beispiel liegen die Strings im Array in der gleichen
Reihenfolge wie die Werte im Enum, auch wenn es optisch anders aussieht:

1
enum event_id_code {
2
  TORAUF,
3
  TORZU,
4
  FENSTERAUF,
5
  FENSTERZU,
6
  TUEREAUF,
7
  TUEREZU
8
};
9
10
char *event_id_string[] = {
11
  [TORZU     ] = "Tor zu",
12
  [TUEREZU   ] = "Türe zu",
13
  [TORAUF    ] = "Tor auf",
14
  [FENSTERZU ] = "Fenster zu",
15
  [TUEREAUF  ] = "Türe auf",
16
  [FENSTERAUF] = "Fenster auf"
17
};

Der Ausdruck

1
event_id_string[FENSTERAUF]

liefert also immer "Fenster auf", egal wie sehr du die Zeilen in
event_id_code oder event_id_code durcheinanderwürfelst.

Natürlich müssen bei der Array-Initialisierung die Indizes in den
eckigen Klammern mit dem Text jeweils rechts daneben korrespondieren.
Das aber beim Einfügen neuer Elemente die einzelnen Zeilen i.Allg. nicht
geändert werden, besteht hier kaum die Gefahr von Fehlern. Falls doch
ein Fehler gemacht wurde, kann dieser schnell gefunden werden, da die
korrespondierenden Dinge ja direkt nebeneinander stehen.

: Bearbeitet durch Moderator
von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Yalu X. schrieb:
> "designated array initializers"

Es sei darauf hingewiesen, daß auch 2016 noch C-Compiler existieren, die 
nichts neueres als C90 kennen, und da gibt es so etwas leider nicht.

Ein "berühmtes" Beispiel ist der Compiler, der zu Microsofts "Visual 
C++" gehört.

Der unterstützt C++11 (oder neuer), aber nichts neueres als C90:


https://herbsutter.com/2012/05/03/reader-qa-what-about-vc-and-c99/

von Yalu X. (yalu) (Moderator)


Lesenswert?

Rufus Τ. F. schrieb:
> Der unterstützt C++11 (oder neuer), aber nichts neueres als C90:
>
> https://herbsutter.com/2012/05/03/reader-qa-what-about-vc-and-c99/

Der Artikel ist ja auch schon ein paar Tage alt :)

Seit der 2013er-Version soll es die designated Initializers wohl geben
und mittlerweile auch ein paar diesbezügliche Bugs gefixt worden sein.
Ich habe allerdings keinen MS-Compiler hier, wo ich das auf die Schnelle
mal ausprobieren könnte.

Außerdem: Wer programmiert auf einem PC unter Windows in C? ;-)

Microsoft hat die Priorität für den C-Modus ihres Compilers aus gutem
Grund herabgesetzt (scheint es sich jetzt aber doch wieder anders zu
überlegen).

: Bearbeitet durch Moderator
von Mark B. (markbrandis)


Lesenswert?

Yalu X. schrieb:
> Außerdem: Wer programmiert auf einem PC unter Windows in C? ;-)

Viele Leute, dank MinGW und Cygwin. :-)

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Yalu X. schrieb:
> Außerdem: Wer programmiert auf einem PC unter Windows in C? ;-)

Wer beispielsweise Konsolenanwendungen schreiben möchte (wie z.B. 
Kommandozeilencompiler) oder Systemdienste etc.

Windows-GUI-Anwendungen in C zu schreiben à la Petzoldt ist definitiv 
außerhalb der Genfer Konvention.

von Bert3 (Gast)


Lesenswert?

Auf jeden Fall mal das case

switch (event_id_code) {

  case TORAUF    : printf(event_id_string[TORAUF]); break:
  case TORZU     : printf(event_id_string[TORZU]); break;
  case FENSTERAUF: printf(event_id_string[FENSTERAUF]); break;
  case FENSTERZU : printf(event_id_string[FENSTERZU); break;
  case TUEREAUF  : printf(event_id_string[TUEREAUF]); break;
  case TUEREZU   : printf(event_id_string[TUEREZU]); break;
  }

durch

printf(event_id_string[event_id_code]);

ersetzen

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Vorher aber überprüfen, ob "event_id_code" im gültigen wertebereich 
liegt. Das wird einem nicht abgenommen, auch wenn man einen enum 
verwendet.

von Kollege von oben (Gast)


Lesenswert?

Du könntest dir ein Array anlegen mit einer eindeutigen Zuordnung, so 
kannst du sicher stellen das diese nicht verloren geht:
1
typedef struct _GateStates
2
{
3
  event_id_code id;
4
  char* text;
5
} GateStates

Deklaration:
1
static GateStates STATES[];

Definition:
1
GateStates STATES[] =
2
{ TORAUF, "Torauf" },
3
...

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Kollege von oben schrieb:
> Definition:GateStates STATES[] =
> { TORAUF, "Torauf" },
> ...

Da hast Du ein Paar Klammern vergessen.
1
GateStates STATES[] =
2
{
3
  { TORAUF, "Torauf" },
4
  ...
5
};

von Daniel A. (daniel-a)


Lesenswert?

Ich mache sowas manchmal mit Macros:
1
#define EVENT_ID_LIST \
2
  X( TORAUF, "Tor auf" ), \
3
  X( TORZU, "Tor zu" ), \
4
  X( FENSTERAUF, "Fenster auf" ), \
5
  X( FENSTERZU, "Fenster zu" ), \
6
  X( TUEREAUF, "Türe auf" ), \
7
  X( TUEREZU, "Türe zu" )
8
9
#define X(ID,STRING) STRING
10
char *event_id_string[] = { EVENT_ID_LIST };
11
#undef X
12
13
#define X(ID,STRING) ID
14
enum event_id_code { EVENT_ID_LIST };
15
#undef X

: Bearbeitet durch User
von Kollege von oben (Gast)


Lesenswert?

Rufus Τ. F. schrieb:
> Da hast Du ein Paar Klammern vergessen.

Mea culpa. Was Rufus schreibt ist richtig.

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.