Forum: PC-Programmierung C: Kann man den Inhalt einer Enumeration komplett in ein Array kopieren?


von Ralf (Gast)


Lesenswert?

Hi,

ich möchte in C eine Enumeration in ein Array schreiben, aber nicht von 
Hand, sondern direkt. Ist das möglich?
Es handelt sich um Ansi-C (für µC). Ich möchte damit eine State-Machine 
realisieren. In einer Tabelle welche im Codespeicher steht, soll der 
Inhalt der Enumeration hinterlegt sein, der Inhalt jedes Feldes 
entspricht dem Index + 1. Damit kann man bequem auf den nächsten Zustand 
springen.

Beispiel:
1
enum STATES = {STATE1 = 1, STATE2, STATE3, STATE4, STATE0 = 0};
2
3
unsigned char code ucStates[] = STATES;   //Tabelle im Programmspeicher (Pseudo-Code!!!)
4
5
unsigned char ucActualState = STATE0;  //Zustandsvariable

Der Wechsel der Zustände könnte dann in etwa so realisiert werden:
1
#define NEXT_STATE (ucActualState = ucStates[ucActualState]);

Es handelt sich hier nur um ein Beispiel, mir gehts nur darum, ob so 
etwas in C möglich ist. Im Prinzip will ich damit nur umgehen, dass man 
an zwei Stellen (enum und Tabelle) ändern muss, wenn man einen 
zusätzlichen Zustand einfügen will.

Ralf

von Sven P. (Gast)


Lesenswert?

Nö, kann man so nicht. Ist aber auch Unfug -- was meinste, warum die 
enum in C automatisch durchnumeriert wird...?

von Klugscheisser (Gast)


Lesenswert?

Vielleicht solltest Du doch etwas mehr schreiben, denn
1. ein Automat bei dem jeder Zustand genau einen Folgezustand hat,
2. bei dem der Folgezustand nicht von den Eingangsdaten abhängt (oder 
aquivalente Formulierung je nach Mealy oder Moore)

macht eigentlich so keinen grossen Sinn.

Nur aber wenn 1 und 2 gelten ist es eine Vereinfachung das enum zu 
kopieren. Dann aber brauchst Du garkein enum sondern kannst die Zustände 
einfach durchnummerieren.

Vermutlich ist bei Deinem Versuch "nur ein Beispiel" zu formulieren doch 
eine wesentliche Bedingung an Dein Projekt verlorengegangen.

von Roland P. (pram)


Lesenswert?

korrigiert mich bitte, aber ich hab eine enum immer als Integer 
betrachtet.

also sollte ucActualState++ (mit entsprechender Overflowprüfung 
natürlich) in den nächsten State springen

von Ralf (Gast)


Lesenswert?

Hi,

danke für die Antworten.

@Klugscheißer:
> Nur aber wenn 1 und 2 gelten ist es eine Vereinfachung das enum zu
> kopieren. Dann aber brauchst Du garkein enum sondern kannst die Zustände
> einfach durchnummerieren.
Ja, durchnummerieren schon, aber dann geht mir die Möglichkeit, die 
Zustände im Code mit Namen zu versehen flöten (oder?). Geht zwar so, 
erschwert aber m.E. die Lesbarkeit.

@Roland:
> ...also sollte ucActualState++ (mit entsprechender Overflowprüfung
> natürlich) in den nächsten State springen
Dasselbe wie oben, den Nummern sind halt keine "Namen" zugewiesen.

Ralf

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

> Ja, durchnummerieren schon, aber dann geht mir die Möglichkeit, die
> Zustände im Code mit Namen zu versehen flöten (oder?)

Nein, nur muss der enum monoton sein, d.h. aufsteigend und ohne Lücken.

Du weist in Deinem Beispiel aber Werte zu, und dadurch ist der enum 
nicht mehr monoton.

von Ralf (Gast)


Lesenswert?

> Du weist in Deinem Beispiel aber Werte zu, und dadurch ist der enum
> nicht mehr monoton.
Muss ich ja auch, sonst kann der letzte Wert in der enum ja nicht mehr 
auf den ersten zeigen. Oder ist mein Ansatz falsch?

Ralf

von Alex (Gast)


Lesenswert?

Ich würde es so machen:

switch(State)
{
    case state_1: doSomething(); State = state_2; break;
    case state_2: doSomethingElse(); State = state_3; break;
    case state_3: foobar(); State = state_1; break;
    default: panic(); break;
}

Enum-Werte wie Integer zu behandeln ist schlechter Stil, dass sagt dir 
auch jeder C++ Compiler auch ausdrücklich, wenn du ihm sowas vorsetzt, C 
ist da etwas toleranter.

Wenns unbedingt mit Inkrementen gehen soll, dann nimm defines für deine 
States.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

> Muss ich ja auch, sonst kann der letzte Wert in der enum ja nicht mehr
> auf den ersten zeigen.

Das geht mit einer Krücke - definiere als letzten Wert des enums einen 
Ende-Wert (dessen numerischer Wert ist die Anzahl gültiger enum-Werte).

Also so:

enum
{
  bla,
  fusel,
  laber,
  foo,
  ENDE
};


for (i = 0; i < ENDE; i++)
{
  //...
}


Das funktioniert, solange Du nicht weitere enum-Werte hinter ENDE 
anlegst.

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.