Frage

Was ist der Unterschied zwischen einer Anweisung bestimmen, indem einer ENUM-Anweisung in C / C ++ (und wird es ein Unterschied, wenn sie mit entweder C oder C ++ mit ihnen)?

Wenn zum Beispiel sollte man verwenden

enum {BUFFER = 1234}; 

über

#define BUFFER 1234   
War es hilfreich?

Lösung

enum definiert ein syntaktisches Element.

#define ist eine Pre-Präprozessordirektive, ausgeführt vor die Compiler den Code sieht, und daher ist kein Sprachelement von C selbst.

Im Allgemeinen Aufzählungen sind bevorzugt, da sie typsicher und leichter auffindbar sind. Definiert sind schwerer zu finden und können komplexe Verhalten, zum Beispiel ein Stück Code kann ein #define neu definieren, indem ein anderer gemacht. Dies kann schwierig sein, nach unten zu verfolgen.

Andere Tipps

#define Aussagen werden durch den Pre-Prozessor verarbeitet, bevor der Compiler den Code zu sehen bekommt, so ist es im Grunde eine Textersetzung (es ist tatsächlich ein wenig intelligenter mit der Verwendung von Parametern und so weiter).

Aufzählungen sind Teil der C-Sprache selbst und haben die folgenden Vorteile.

1 / Sie können Typen haben und der Compiler kann sie geben überprüfen.

2 / Da sie an den Compiler zur Verfügung stehen, können Symbol Informationen über sie durch an den Debugger übergeben werden, so dass einfacher debuggen.

Definieren Sie ein Präprozessoranweisung ist, es ist wie zu tun in Ihrem Editor „Alle ersetzen“, kann es einen String durch einen anderen zu ersetzen und dann das Ergebnis kompilieren.

Enum ist ein Spezialfall des Typs, zum Beispiel, wenn Sie schreiben:

enum ERROR_TYPES
{
   REGULAR_ERR =1,
   OK =0
}

gibt es einen neuen Typ namens ERROR_TYPES. Es stimmt, dass REGULAR_ERR Erträge zu 1, aber von dieser Art Gießen eines Guss Warnung auf int sollte erzeugen (wenn Sie Ihre Compiler hohe Ausführlichkeit konfigurieren).

Zusammenfassung: sie sind beide gleich, aber wenn ENUM verwenden Sie die Typprüfung profitieren und durch definiert verwenden Sie einfach Code-Strings ersetzen.

Aufzählungen sind in der Regel über #define bevorzugt überall dort, wo es Sinn macht, eine ENUM zu verwenden:

  • Debuggers können Sie den symbolischen Namen eines enums Wert ( "openType: OpenExisting" zeigen, sondern als "openType: 2"
  • Sie erhalten ein wenig mehr Schutz vor Namenskonflikten, aber das ist nicht so schlimm, wie es war (die meisten Compiler warnen vor re#defineition.

Der größte Unterschied ist, dass Sie Aufzählungen als Typen verwenden können:

// Yeah, dumb example
enum OpenType {
    OpenExisting,
    OpenOrCreate,
    Truncate
};

void OpenFile(const char* filename, OpenType openType, int bufferSize);

Das gibt der Eingabe-Überprüfung von Parametern (man kann so einfach nicht mischen OpenType- und buffer) und macht es leicht zu finden, welche Werte gültig sind, so dass Ihre Schnittstellen viel einfacher zu bedienen. Einige IDEs können sogar geben Sie intellisense Code-Vervollständigung!

Es ist immer besser, eine ENUM wenn möglich zu verwenden. Mit Hilfe eines Aufzählungs der Compiler gibt mehr Informationen über den Quellcode, ein Präprozessor definieren, ist nie durch den Compiler gesehen und trägt somit weniger Informationen.

Sie beispielsweise für die Umsetzung es möglich, dass der Compiler zu fangen fehlt case-Anweisungen in einem Schalter eine Reihe von Modi, macht eine ENUM verwenden, zum Beispiel.

ENUM kann Gruppe mehrere Elemente in einer Kategorie:

enum fruits{ apple=1234, orange=12345};

während #define können nur unabhängige Konstanten erstellen:

#define apple 1234
#define orange 12345

#define ein Präprozessoranweisung ist, Enum ist in der C oder C ++.

Es ist immer besser Aufzählungen über #define für diese Art von Fällen zu verwenden. Eine Sache ist die Sicherheit geben. Ein weiteres ist, dass, wenn Sie eine Folge von Werten haben Sie nur den Anfang der Sequenz in der Enum geben, die anderen Werte erhalten aufeinanderfolgende Werte.

enum {
  ONE = 1,
  TWO,
  THREE,
  FOUR
};

statt

#define ONE 1
#define TWO 2
#define THREE 3
#define FOUR 4

Als Nebennote, gibt es noch einige Fälle, wo Sie haben können #define verwenden (in der Regel für eine Art von Makros, wenn Sie in der Lage sein müssen, eine Kennung zu konstruieren, die die Konstante enthält), aber das ist eine Art von Makro schwarze Magie, und sehr, sehr selten der Weg zu sein, um zu gehen. Wenn Sie diese Extremitäten gehen sollten Sie wahrscheinlich eine C ++ Vorlage verwenden (aber wenn Sie mit C stecken ...).

Wenn Sie nur diese einzige Konstante (sagen für Puffergröße), dann würde ich nicht eine ENUM verwenden, sondern ein definieren. Ich würde Aufzählungen für Sachen wie Rückgabewerte verwenden (die unterschiedlichen Fehlerbedingungen bedeuten) und überall dort, wo wir verschiedene „Typen“ oder „Fälle“ unterscheiden müssen. In diesem Fall können wir eine ENUM verwenden, um eine neue Art zu schaffen, die wir in Funktionsprototypen usw., und dann die Compiler Sanity, dass Code überprüfen kann besser nutzen können.

Neben all das, was schon geschrieben, sagte ein, aber nicht gezeigt und ist stattdessen interessant. Z.

enum action { DO_JUMP, DO_TURNL, DO_TURNR, DO_STOP };
//...
void do_action( enum action anAction, info_t x );

Unter Berücksichtigung Aktion als eine Art Sache klarer macht. Mit definieren, würden Sie geschrieben

void do_action(int anAction, info_t x);

Für Integral konstante Werte Ich bin gekommen, enum über #define bevorzugen. Es scheint keine Nachteile mit enum (Abzinsung der winzigen Nachteil eines etwas mehr Typisierung) zu sein, aber Sie haben den Vorteil, dass sein scoped enum können, während #define Identifikatoren globale Reichweite haben, die alles stapft.

#define Verwendung ist normalerweise kein Problem, aber da es keine Nachteile sind zu enum, gehe ich mit dem.

In C ++ Ich habe auch lieber im Allgemeinen enum const int obwohl in C ++ eine const int kann anstelle einer wörtlichen Integer-Wert verwendet werden (anders als in C), weil enum bis C tragbar ist (was ich immer noch in viel Arbeit).

Wenn Sie eine Gruppe von Konstanten haben (wie „Tage der Woche“) Aufzählungen wäre vorzuziehen, weil es zeigt, dass sie gruppiert sind; und, wie Jason sagte, sie sind typsicher. Wenn es sich um eine globale Konstante (wie Versionsnummer) ist, das ist mehr, was man einen #define verwenden würde für; obwohl dies ist das Thema viel Debatte.

Zusätzlich zu dem guten Seiten oben aufgeführt ist, können Sie den Umfang von Aufzählungen zu einer Klasse, Struktur oder Namensraum begrenzen. Persönlich mag ich zu jeder Zeit die minimale Anzahl von relevanten Symbolen in Rahmen haben, das ist ein weiterer Grund für Aufzählungen statt #defines verwendet wird.

Ein weiterer Vorteil einer Enum über eine Liste der definiert ist, dass Compiler (gcc mindestens) eine Warnung erzeugen, wenn nicht alle Werte in einer switch-Anweisung geprüft werden. Zum Beispiel:

enum {
    STATE_ONE,
    STATE_TWO,
    STATE_THREE
};

...

switch (state) {
case STATE_ONE:
    handle_state_one();
    break;
case STATE_TWO:
    handle_state_two();
    break;
};

Im vorherigen Code ist der Compiler in der Lage eine Warnung zu erzeugen, die nicht alle Werte der Enumeration im Schalter behandelt werden. Wenn die Zustände wie # definieren die fertig waren, wäre dies nicht der Fall sein.

Aufzählungen sind mehr verwendet für eine Art von Set aufzählt, wie Tage in der Woche. Wenn Sie benötigen nur eine konstante Zahl, const int (oder Doppel etc.) würde als Enum definetly besser sein. Ich persönlich nicht gefällt #define (zumindest nicht für die Definition einiger Konstanten), weil es mir nicht geben Sicherheit nicht geben, aber man natürlich können es verwenden, wenn es Ihnen besser passt.

Erstellen eines ENUM schafft nicht nur Literale, sondern auch die Art, die Gruppen diese Literale. Dies, um Ihren Code semantischen fügt hinzu, dass der Compiler in der Lage ist zu prüfen,

Darüber hinaus, wenn ein Debugger verwenden, haben Sie Zugriff auf die Werte von Aufzählungs Literale. Dies ist nicht immer der Fall mit #define.

Während mehrere oben Antworten empfehlen aus verschiedenen Gründen Enum zu verwenden, ich möchte darauf hinweisen, dass definiert einen vorhandenen Vorteil zu verwenden, wenn Schnittstellen zu entwickeln. Sie können neue Optionen einführen und Sie können Software, um sie bedingt verwenden lassen.

Zum Beispiel:

    #define OPT_X1 1 /* introduced in version 1 */
    #define OPT_X2 2 /* introduced in version  2 */

Dann Software, die entweder mit Version kompiliert wird, kann es tun kann

    #ifdef OPT_X2
    int flags = OPT_X2;
    #else
    int flags = 0;
    #endif

Während auf einer Aufzählung dies ohne Laufzeit-Funktion Erkennungsmechanismus nicht möglich ist.

Enum:
1. Im Allgemeinen für mehrere Werte verwendet
2. In Enum gibt es zwei, was ein Name ist und ein anderer Wert des Namens Namen unterschieden werden muss, aber Wert sein kann same.If wir Wert definieren nicht dann der erste Wert des Enum-Namen 0 zweite Wert 1, und so weiter, sofern dies nicht ausdrücklich Wert angegeben werden.
3. Sie können Typ haben und Compiler eingeben können sie überprüfen
4. leicht
Debuggen 5. Wir können Umfang es bis zu einer Klasse begrenzen.

definieren:
1. Wenn wir einen Wert zu definieren, haben nur
2. Es wird allgemein eine Zeichenfolge an eine andere Zeichenfolge ersetzen.
3. Es Geltungsbereich ist global wir können nicht ihren Umfang begrenzen

Insgesamt müssen wir Enum verwenden

Es gibt kaum einen Unterschied. Der C-Standard sagt, dass Aufzählungen haben Integraltyp und dass Enumerationskonstanten vom Typ int ist, so dass beide frei mit anderen ganzzahligen Typen miteinander vermischt werden können, ohne Fehler. (Wenn auf der anderen Seite solche Vermischung ohne expliziten Casts nicht anerkannt wurde, umsichtige Verwendung von Aufzählungen könnte bestimmte Programmierfehler fangen.)

Einige Vorteile von Aufzählungen sind, dass die numerischen Werte automatisch zugewiesen werden, dass ein Debugger Lage sein kann, die symbolischen Werte anzuzeigen, wenn Aufzählungs Variablen untersucht werden, und dass sie Block Umfang gehorchen. (Ein Compiler kann auch nicht-tödliche Warnungen erzeugen, wenn Aufzählungen wahllos gemischt sind, da damit noch schlechter Stil betrachtet werden kann, auch wenn es nicht unbedingt illegal ist.) Ein Nachteil ist, dass der Programmierer wenig Kontrolle über diese nicht-tödlichen Warnungen hat; einige Programmierer auch übel nehmen nicht die Kontrolle, die über die Größen der Aufzählung Variablen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top