Frage zum Sinn von enum in C

Gast #5997415
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?
1
#include <stdio.h>
2
#include <stdlib.h>
3

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

8
    int test = 10;
9
    enum Company Comp1 = Xerox;
10
    enum Company Comp2 = Google;
11
    enum Company Comp3 = Ebay;
12

13
    enum Company Comp4 = test;
14

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

Vielen Dank,
Moderator #5997453
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

1
    enum Company Comp4 = test;

einen Fehler darstellt.
Moderator Persönliche Seite #5997463
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).
Gast #5997475
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
Moderator Persönliche Seite #5997480
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. :-)
#5997552
Lesenswert?

Enums sind fortlaufende Constanten, das ist für vieles nützlich. 
Besonders zusammen mit designated initialisern finde ich es praktisch:
1
const char* info[] = {
2
  [Google]    = "Don't be evil - das war mal.", 
3
  [Facebook]  = "Früher mal beliebter social Media Provider - wir wollen dein Gesicht & Leben!", 
4
  [Xerox]     = "Wir erfanden die Maus & die GUI - dann hat Steve es als seins verkauft...",
5
  [Yahoo]     = "Wir hatten deine Mails und ersetzten deine Suche - die paar breaches waren doch nicht so schlimm...", 
6
  [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.",
7
};

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..
Gast #5997557
Lesenswert?

Hi,
vielen Dank für eure Rückmeldung.

Daraus schließe ich:
Folgende Linie Code
1
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ß,
Angehängte Dateien:
Beitrag #5997690 wurde von einem Moderator gelöscht.
Gast #5997693
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:
1
enum direction { north, east, south, west };
2

3
...
4

5
for(enum direction dir = north; dir != west; dir++)
6
switch(dir)
7
{
8
case north:
9
break;
10
...
11
}

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.
#5997713
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

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