mikrocontroller.net

Forum: PC-Programmierung Frage zum Sinn von enum in C


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: Alexander (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

ich habe mich gerade in enum in C eingelesen, und muss gestehen, dass 
mir der Sinn / Anwendungszweck noch nicht so ganz klar ist. Ich dachte, 
mittels enum erstellt man (s)einen eigenen Datentyp. Was genau ist der 
Sinn und Zweck der "enumerators" innerhalb der geschweiften Klammer? Es 
wäre für mich einleuchtend, dass mittels eines enum Datentyps die 
entstandene enum Variable lediglich die Werte der "enumerators" 
innerhalb der geschweiften Klammer annehmen darf. Dem ist aber nicht so. 
Siehe folgendes Minimalbeispiel. Dort wird der enum Variable Comp4 der 
Wert der Variable test zugewiesen. Wenn das zulässig ist, wozu braucht 
man dann die enumerators? Besteht der einzige Sinn darin, dass die 
enumerators lediglich automatisch eine fortlaufende Integerzahl haben 
(0, 1, 2, etc.) und man somit nicht manuell jedes einzelne Element 
initialisieren muss?
#include <stdio.h>
#include <stdlib.h>

int main()
{
    enum Company {Google, Facebook, Xerox, Yahoo, Ebay, Microsoft};

    int test = 10;
    enum Company Comp1 = Xerox;
    enum Company Comp2 = Google;
    enum Company Comp3 = Ebay;

    enum Company Comp4 = test;

    printf("%d\n%d\n%d\n%d\n",Comp1,Comp2,Comp3,Comp4);
    return 0;
}

Vielen Dank,

Autor: Dirk B. (dirkb2)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Alexander schrieb:
> Besteht der einzige Sinn darin, dass die
> enumerators lediglich automatisch eine fortlaufende Integerzahl haben
> (0, 1, 2, etc.) und man somit nicht manuell jedes einzelne Element
> initialisieren muss?

Nicht nur.

Sie bleiben auch als Debug-Information erhalten, während ein #define 
direkt ersetzt wird.

Autor: x^2 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
C erlaubt viel. Tipp: Die Warnungen einschalten! Dieses Beispiel wird 
einige erzeugen.

Autor: Yalu X. (yalu) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Enums dienen primär dazu, für eine Folge von Integer-Zahlen Symbole zu
definieren. Diese wiederum sollen ein Programm besser verständlich
machen, da sich ein Leser unter dem Symbol Xerox mehr vorstellen kann
als unter der schnöden Firmennummer 2.

Enums stellen zwar jeweils eigene Datentypen dar, allerdings werden in C
beliebige Integer-Zahlen bei einer Zuweisung implizit konvertiert.

In C++ gibt es diese implizite Konvertierung nach enum nicht, weswegen
dort die Zeile

    enum Company Comp4 = test;

einen Fehler darstellt.

Autor: Jörg W. (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dirk B. schrieb:

> Sie bleiben auch als Debug-Information erhalten, während ein #define
> direkt ersetzt wird.

Stimmt so mittlerweile auch nicht mehr. Mit -g3 übernimmt GCC nunmehr 
auch die Makros in die Debug-Informationen.

Allerdings weiß ein Debugger bei einer Variablen, die über einen 
enum-Typ definiert ist, dass er die möglichen Werte dieser Variablen mit 
den Namen der Enumeratoren darstellen kann; beliebige Makros wird er an 
dieser Stelle nicht freiwillig anzeigen.

Ist aber tatsächlich bei C so ziemlich der einzige Vorteil von enums. 
Außerdem kann ein Compiler eine Warnung ausgeben, wenn man einen 
enum-Ausdruck als Steuerausdruck eines "switch" benutzt und dann nicht 
für alle Enumeratoren einen Zweig hat (und auch keinen "default"-Zweig).

Autor: Leo (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Jörg W. schrieb:
> Außerdem kann ein Compiler eine Warnung ausgeben, wenn man einen
> enum-Ausdruck als Steuerausdruck eines "switch" benutzt und dann nicht
> für alle Enumeratoren einen Zweig hat (und auch keinen "default"-Zweig).

Wer allerdings einen enum benutzt um Error-Codes (große Anzahl an 
Enumeratoren) aus einer Funktion zurück zugeben, wird froh sein wenn er 
diese Compiler-Option deaktivieren kann. Denn es könnte durchaus sein, 
dass nur einige Enumeratoren (Error-Codes) ausgewertet werden sollen.

Gruß Leo

Autor: Jörg W. (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Leo schrieb:
> Denn es könnte durchaus sein, dass nur einige Enumeratoren (Error-Codes)
> ausgewertet werden sollen.

Wenn man sich da völlig sicher ist (und nur dann würde man die Warnung 
ausschalten), kann man natürlich auch einem Zweig ein "default" mit 
draufdrücken. Wenn man paranoid ist, schreibt man noch ein 
``assert("Unexpected return value" == NULL)'' in diesen Zweig. :-)

Autor: Daniel A. (daniel-a)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Enums sind fortlaufende Constanten, das ist für vieles nützlich. 
Besonders zusammen mit designated initialisern finde ich es praktisch:
const char* info[] = {
  [Google]    = "Don't be evil - das war mal.", 
  [Facebook]  = "Früher mal beliebter social Media Provider - wir wollen dein Gesicht & Leben!", 
  [Xerox]     = "Wir erfanden die Maus & die GUI - dann hat Steve es als seins verkauft...",
  [Yahoo]     = "Wir hatten deine Mails und ersetzten deine Suche - die paar breaches waren doch nicht so schlimm...", 
  [Microsoft] = "Auf jedem neuen PC - Nein, du wirst uns nicht mehr los, jetzt zahl schon deine Office Lizenzgebühren und gib auch uns deine Daten.",
};

So kann man auch mehrere separate Listen mit einfach verständlicher 
Indexierung haben, wenn z.B. gewisse Dinge nicht in das selbe struct 
sollen, usw..

Autor: Alexander (Gast)
Datum:
Angehängte Dateien:
  • preview image for C.png
    C.png
    124 KB, 99 Downloads

Bewertung
1 lesenswert
nicht lesenswert
Hi,
vielen Dank für eure Rückmeldung.

Daraus schließe ich:
Folgende Linie Code
enum Company Comp4 = test;
widerspricht dem eigentlichen Sinn der Benutzung von enums (unter 
Berücksichtigung meines restlichen Programms). Zulässig im Compiler 
bedeutet nicht zwangsläuft angedacht in der Programmiersprache.

Gedacht ist, dass man eigentlich die enumerations in der Geschweiften 
Klammer verwenden soll.

Gruß,

Autor: Jörg W. (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Alexander schrieb:
> Gedacht ist, dass man eigentlich die enumerations in der Geschweiften
> Klammer verwenden soll.

So ist es. Es ist eher historischer Ballast von C, dass enum lediglich 
eine Art "int mit benannten Werten" ist. C++ hat den Ballast ablegen 
können, daher ist ein enum dort ein strikter Datentyp.

Autor: A. S. (achs)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du kannst dir auch von lint checken lassen, ob Du nur enthaltene enums 
verwendest. Am Ende willst Du aber meist doch zumindest auch damit 
indizieren.

Beitrag #5997690 wurde von einem Moderator gelöscht.
Autor: enum (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Alexander schrieb:
> Folgende Linie Codeenum Company Comp4 = test;widerspricht dem
> eigentlichen Sinn der Benutzung von enums (unter
> Berücksichtigung meines restlichen Programms).

Das kann schon Sinn ergeben. Beispiel:
enum direction { north, east, south, west };

...

for(enum direction dir = north; dir != west; dir++)
switch(dir)
{
case north:
break;
...
}

Zu beachten ist hier das "dir++", das geht nur, weil ein enum sich wie 
ein Integer verhält.

Auch bei der Implementierung von State Machines kann man sowas manchmal 
brauchen. Es ist ein klassischer Fall von: Wenige Leute brauchen es, 
aber es bietet Anfängern relativ viel Gefahrenpotential.

Autor: A. K. (prx)
Datum:

Bewertung
2 lesenswert
nicht lesenswert
Dennis Ritchie: `I added some things under some pressure from users that 
I don't think were done well. Enumeration types are a bit odd, bitfields 
are odder. The "static" keyword is very strange, expressing both a 
storage lifetime and what the standard calls "linkage" (external 
visibility). There are many odd bits here and there.´

Beitrag #5997719 wurde von einem Moderator gelöscht.

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.

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