www.mikrocontroller.net

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


Autor: Ralf (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
enum STATES = {STATE1 = 1, STATE2, STATE3, STATE4, STATE0 = 0};

unsigned char code ucStates[] = STATES;   //Tabelle im Programmspeicher (Pseudo-Code!!!)

unsigned char ucActualState = STATE0;  //Zustandsvariable

Der Wechsel der Zustände könnte dann in etwa so realisiert werden:
#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

Autor: Sven P. (haku) Benutzerseite
Datum:

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

Autor: Klugscheisser (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Roland Praml (pram)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Ralf (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Ralf (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Alex (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.