Anzahl der Elemente in einer Aufzählung

Lesezeit: 7 Minuten

Gibt es in C eine nette Möglichkeit, die Anzahl der Elemente in einer Aufzählung zu verfolgen? Ich habe gesehen

enum blah {
    FIRST,
    SECOND,
    THIRD,
    LAST
};

Dies funktioniert jedoch nur, wenn die Elemente sequentiell sind und bei Null beginnen.

  • Siehe die Frage auf enum in C++ wie enum in Ada.

    – Jonathan Leffler

    23. April 2013 um 17:58 Uhr

Wenn Sie Ihre Aufzählungen nicht zuweisen, können Sie Folgendes tun:

enum MyType {
  Type1,
  Type2,
  Type3,
  NumberOfTypes
}

NumberOfTypes wird zu 3 ausgewertet, was die Anzahl der echten Typen ist.

  • Können Sie immer sicher sein, dass in jeder C-Implementierung überall und zu jeder Zeit Aufzählungen bei 0 beginnen? Ich nehme es an, aber ist es wirklich immer wahr?

    – JohnyTex

    30. November 2017 um 11:22 Uhr

  • Späte Antwort @JohnyTex, aber der C-Standard erwähnt unter ‘Enumeration specifiers’: If the first enumerator has no =, the value of its enumeration constant is 0. Each subsequent enumerator with no = defines its enumeration constant as the value of the constant expression obtained by adding 1 to the value of the previous enumeration constant. Also ja, dies würde für jede standardkonforme Implementierung gelten.

    – seri

    7. August 2018 um 21:29 Uhr


Ich glaube nicht, dass es das gibt. Aber was würden Sie mit einer solchen Nummer machen, wenn sie nicht fortlaufend sind und Sie nicht schon irgendwo eine Liste davon haben? Und wenn sie sequentiell sind, aber mit einer anderen Nummer beginnen, können Sie immer Folgendes tun:

enum blah {
    FIRST = 128,
    SECOND,
    THIRD,
    END
};
const int blah_count = END - FIRST;

  • Können Aufzählungstypen negativ sein? Wenn ja, passen Sie auf mit diesem.

    – ojblass

    3. April 2009 um 3:51 Uhr

  • FIRST=-2 würde immer noch richtig rechnen, denke ich: 1 – (-2) = 3.

    – paxdiablo

    3. April 2009 um 3:53 Uhr

  • Sie müssen nicht aufpassen; Subtraktion funktioniert gut für negative Zahlen. Pax hat Recht.

    – Brian Campell

    3. April 2009 um 3:59 Uhr

  • ERSTE = -200, ZWEITE = -199, DRITTE = -198, ENDE = -100. -200 – (-100) = schlechte Nachrichten

    – ojblass

    3. April 2009 um 4:00 Uhr

  • Nein, Sie würden FIRST = -9 SECOND = -8 THIRD = -7 END = -6 erhalten, also hätten Sie -6 – (-9) = -6 + 9 = 3

    – Brian Campell

    3. April 2009 um 4:18 Uhr

Sams Benutzeravatar
Sam

Alte Frage, ich weiß. Dies ist für die Googler mit der gleichen Frage.

Du könntest benutzen X-Makros

Beispiel:

//The values are defined via a map which calls a given macro which is defined later
#define ENUM_MAP(X) \
      X(VALA, 0)    \
      X(VALB, 10)   \
      X(VALC, 20)

//Using the map for the enum decl
#define X(n, v) [n] = v,
typedef enum val_list {
    ENUM_MAP(X) //results in [VALA] = 0, etc...
} val_list;
#undef X

//For the count of values
#define X(n, v) + 1
int val_list_count = 0 + ENUM_MAP(X); //evaluates to 0 + 1 + 1 + 1
#undef X

Dies ist auch für eine IDE transparent, sodass automatische Vervollständigungen gut funktionieren (wie alles im Präprozessor).

  • Genial, ich bin eigentlich hierher gekommen, weil ich nach einer guten Möglichkeit gesucht habe, das zu bestimmen Nummer von Elementen in einem X_MACRO, und das ist ein guter Weg.

    – BeeOnRope

    5. November 2016 um 23:38 Uhr

  • Du könntest auch einfach die Anzahl der Elemente in die nehmen val_list Array mit dem Idiomatik (sizeof val_list / sizeof val_list[0])

    – Jo So

    14. Dezember 2017 um 21:43 Uhr

  • Es sollte wahrscheinlich sein n = v, obwohl,

    – Antti Haapala – Слава Україні

    9. August 2019 um 2:07 Uhr

Unglücklicherweise nicht. Da ist nicht.

Benutzeravatar von David Stosik
David Stosik

Ich weiß, dass dies eine sehr alte Frage ist, aber da die akzeptierte Antwort falsch ist, fühle ich mich gezwungen, meine eigene zu posten. Ich werde das leicht modifizierte Beispiel der akzeptierten Antwort wiederverwenden. (Unter der Annahme, dass Aufzählungen sequentiell sind.)

// Incorrect code, do not use!
enum blah {
  FIRST   =  0,
  SECOND, // 1
  THIRD,  // 2
  END     // 3
};
const int blah_count = END - FIRST;
// And this above would be 3 - 0 = 3, although there actually are 4 items.

Jeder Entwickler kennt den Grund: count = last - first + 1. Und das funktioniert mit jeder Kombination von Vorzeichen (beide Enden negativ, beide positiv oder nur das erste Ende negativ). Du kannst es versuchen.

// Now, the correct version.
enum blah {
  FIRST   =  0,
  SECOND, // 1
  THIRD,  // 2
  END     // 3
};
const int blah_count = END - FIRST + 1; // 4

Edit: Wenn ich den Text noch einmal lese, habe ich Zweifel. Ist das END soll nicht Teil der angebotenen Artikel sein? Das sieht für mich komisch aus, aber naja, ich denke, es könnte Sinn machen …

  • Die Absicht ist, dass es 3 Elemente in der Aufzählung gibt (FIRST, SECOND & THIRD), wobei letzteres ein Platzhalter ist, der immer das Ende der Liste kennzeichnet, damit beim Hinzufügen weiterer Items die Formel für die Item-Zählung nicht geändert werden muss.

    – Peter Gibson

    28. Januar 2015 um 1:31 Uhr

  • Ja, das dachte ich, als ich ein paar Stunden später wieder las. Danke für die Bestätigung. Ein Kommentar daneben END das sagt “Nicht zur Verwendung gedacht” oder etwas könnte helfen, den Code zu verstehen.

    – David Stosik

    30. Januar 2015 um 7:59 Uhr


  • Ich verwende gerne eine Konvention wie “blah_end_marker”; der “end_marker” identifiziert den Zweck, während das Präfix die Endmarkierungen unterschiedlich hält. Sie können dann die Anzahl definieren oder für “sequentielle” Aufzählungen, die mit 0 beginnen, direkt den Markerwert verwenden (z. B. “blah all_blahs[blah_end_marker];” – obwohl ich langsam denke, dass const int blah_count mehr Sinn macht …

    – Bob

    26. Oktober 2017 um 14:36 ​​Uhr

  • Funktioniert nur, wenn zugewiesene Werte monoton um 1 steigen

    – Larry_C

    6. Januar um 18:06 Uhr

  • Welchen Werten werden nicht fortlaufende Werte zugewiesen? Ich werde nicht fliegen.

    – Larry_C

    6. Januar um 18:24 Uhr

Benutzeravatar von paxdiablo
paxdiablo

Nun, da Aufzählungen sich zur Laufzeit nicht ändern können, ist das Beste, was Sie tun können:

enum blah {
    FIRST = 7,
    SECOND = 15,
    THIRD = 9,
    LAST = 12
};
#define blahcount 4 /* counted manually, keep these in sync */

Aber ich finde es schwierig, mir eine Situation vorzustellen, in der diese Informationen nützlich wären. Was genau versuchst du zu tun?

  • Die Absicht ist, dass es 3 Elemente in der Aufzählung gibt (FIRST, SECOND & THIRD), wobei letzteres ein Platzhalter ist, der immer das Ende der Liste kennzeichnet, damit beim Hinzufügen weiterer Items die Formel für die Item-Zählung nicht geändert werden muss.

    – Peter Gibson

    28. Januar 2015 um 1:31 Uhr

  • Ja, das dachte ich, als ich ein paar Stunden später wieder las. Danke für die Bestätigung. Ein Kommentar daneben END das sagt “Nicht zur Verwendung gedacht” oder etwas könnte helfen, den Code zu verstehen.

    – David Stosik

    30. Januar 2015 um 7:59 Uhr


  • Ich verwende gerne eine Konvention wie “blah_end_marker”; der “end_marker” identifiziert den Zweck, während das Präfix die Endmarkierungen unterschiedlich hält. Sie können dann die Anzahl definieren oder für “sequentielle” Aufzählungen, die mit 0 beginnen, direkt den Markerwert verwenden (z. B. “blah all_blahs[blah_end_marker];” – obwohl ich langsam denke, dass const int blah_count mehr Sinn macht …

    – Bob

    26. Oktober 2017 um 14:36 ​​Uhr

  • Funktioniert nur, wenn zugewiesene Werte monoton um 1 steigen

    – Larry_C

    6. Januar um 18:06 Uhr

  • Welchen Werten werden nicht fortlaufende Werte zugewiesen? Ich werde nicht fliegen.

    – Larry_C

    6. Januar um 18:24 Uhr

Benutzeravatar von DaveShaw
DaveShaw

int enaumVals[] =
{
FIRST,
SECOND,
THIRD,
LAST
};

#define NUM_ENUMS sizeof(enaumVals) / sizeof ( int );

  • Dies scheint das Wiederholen der gesamten Aufzählung in einem Array zu erfordern, nur um die Verwendung von sizeof zu ermöglichen – sieht für mich nach mehr Aufwand aus als nur #define COUNT 4

    – Peter Gibson

    12. Dezember 2011 um 0:16 Uhr


  • In C-Größe wird zur Kompilierzeit berechnet. C ist keine interpretierte Sprache, diese Methode ist so effizient wie die Verwendung einer festen Definition und vereinfacht die Wartung.

    – Fulup

    3. April 2015 um 10:55 Uhr

  • Abgesehen davon, dass es nicht so ist. Dies wird die Symbole Ihres Programms mit einer nutzlosen Reihe von Symbolen verunreinigen NUM_ENUMS int. Ihr Programm braucht länger zum Starten, verbraucht mehr Speicherplatz und so weiter. Die einzige Möglichkeit, dies zu vermeiden, besteht darin, dies in einer unabhängigen Kompilationseinheit zu deklarieren und zu definieren, aber dann müssen Sie es nicht NUM_ENUMS verfügbar, so dass das nicht funktioniert. Wenn Sie später ein Mitglied zu Ihrer Aufzählungsliste hinzufügen, vergessen Sie möglicherweise, dies im Array und zu tun NUM_ENUMS wird nicht mehr passen

    – xryl669

    14. Juni 2019 um 16:44 Uhr

1410240cookie-checkAnzahl der Elemente in einer Aufzählung

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy