Zuerst stellte ich fest, dass es nicht möglich ist, den Typ der Konstante mit #define zu definieren. Warum ist das so?
Warum ist was? Es ist nicht wahr:
#define MY_INT_CONSTANT ((int) 12345)
Zweitens gibt es irgendwelche Vorteile, einen von ihnen gegenüber dem anderen zu verwenden?
Ja. #define
definiert ein Makro, das bereits vor Beginn der Kompilierung ersetzt wird. const
Ändert lediglich eine Variable so, dass der Compiler einen Fehler anzeigt, wenn Sie versuchen, ihn zu ändern. Es gibt Kontexte, in denen Sie a verwenden können, #define
aber Sie können a nicht verwenden const
(obwohl ich Schwierigkeiten habe, einen mit dem neuesten Clang zu finden). Theoretisch const
nimmt a Platz in der ausführbaren Datei ein und erfordert einen Verweis auf den Speicher. In der Praxis ist dies jedoch unbedeutend und kann vom Compiler optimiert werden.
const
s sind viel compiler- und debuggerfreundlicher als #define
s. In den meisten Fällen ist dies der übergeordnete Punkt, den Sie berücksichtigen sollten, wenn Sie eine Entscheidung treffen, welchen Sie verwenden möchten.
Ich dachte nur an einen Kontext, den Sie verwenden können, #define
aber nicht const
. Wenn Sie eine Konstante haben, die Sie in vielen .c
Dateien verwenden möchten, #define
stecken Sie sie einfach in einen Header. Mit a müssen const
Sie eine Definition in einer C-Datei haben und
// in a C file
const int MY_INT_CONST = 12345;
// in a header
extern const int MY_INT_CONST;
in einem Header. MY_INT_CONST
kann nicht als Größe eines statischen oder globalen Bereichsarrays in einer C-Datei verwendet werden, außer der, in der es definiert ist.
Für ganzzahlige Konstanten können Sie jedoch eine verwenden enum
. Genau das macht Apple fast immer. Dies hat alle Vorteile von #define
s und const
s, funktioniert jedoch nur für ganzzahlige Konstanten.
// In a header
enum
{
MY_INT_CONST = 12345,
};
Welcher Weg ist schließlich effizienter und / oder sicherer?
#define
ist theoretisch effizienter, obwohl moderne Compiler, wie gesagt, wahrscheinlich sicherstellen, dass es kaum Unterschiede gibt. #define
ist insofern sicherer, als es immer ein Compilerfehler ist, zu versuchen, ihm zuzuweisen
#define FOO 5
// ....
FOO = 6; // Always a syntax error
const
s kann dazu verleitet werden, zugewiesen zu werden, obwohl der Compiler möglicherweise Warnungen ausgibt:
const int FOO = 5;
// ...
(int) FOO = 6; // Can make this compile
Abhängig von der Plattform kann die Zuweisung zur Laufzeit immer noch fehlschlagen, wenn die Konstante in einem schreibgeschützten Segment platziert wird und das Verhalten gemäß dem C-Standard offiziell undefiniert ist.
Persönlich verwende ich für ganzzahlige Konstanten immer enum
s für Konstanten anderer Typen, es const
sei denn, ich habe einen sehr guten Grund, dies nicht zu tun.
int
. Ich wäre jedoch sehr überrascht, wenn es in einem modernen Compiler überhaupt einen Unterschied machen würde.Von einem C-Codierer:
A
const
ist einfach eine Variable, deren Inhalt nicht geändert werden kann.#define name value
Es handelt sich jedoch um einen Präprozessorbefehl, der alle Instanzen vonname
mit ersetztvalue
.Wenn Sie dies
#define defTest 5
beispielsweisedefTest
tun, werden5
beim Kompilieren alle Instanzen in Ihrem Code durch ersetzt .quelle
Es ist wichtig, den Unterschied zwischen den Anweisungen #define und const zu verstehen, die nicht für dieselben Dinge bestimmt sind.
const
const
wird verwendet, um ein Objekt aus dem angeforderten Typ zu generieren, das nach der Initialisierung konstant ist. Dies bedeutet, dass es sich um ein Objekt im Programmspeicher handelt und als schreibgeschützt verwendet werden kann. Das Objekt wird bei jedem Programmstart generiert.#define
#define
wird verwendet, um die Lesbarkeit des Codes und zukünftige Änderungen zu erleichtern. Wenn Sie eine Definition verwenden, maskieren Sie nur einen Wert hinter einem Namen. Wenn Sie mit einem Rechteck arbeiten, können Sie daher Breite und Höhe mit entsprechenden Werten definieren. Dann ist es im Code einfacher zu lesen, da anstelle von Zahlen Namen stehen.Wenn Sie sich später dazu entschließen, den Wert für die Breite zu ändern, müssen Sie ihn nur in der Definition ändern, anstatt ein langweiliges und gefährliches Suchen / Ersetzen in Ihrer gesamten Datei. Beim Kompilieren ersetzt der Präprozessor den gesamten definierten Namen durch die Werte im Code. Daher geht mit ihnen keine Zeit verloren.
quelle
Zusätzlich zu den Kommentaren anderer Leute ist
#define
es bekanntermaßen schwierig , Fehler zu verwenden , da der Vorprozessor sie vor dem Compiler abruft.quelle
Da Pre-Prozessor-Direktiven verpönt sind, empfehle ich die Verwendung von a
const
. Sie können keinen Typ mit einem Vorprozessor angeben, da eine Vorprozessoranweisung vor dem Kompilieren aufgelöst wird. Nun, Sie können, aber so etwas wie:und benutze es als
was vom Compiler als gesehen werden würde
Sie können meinen ersten Ausschnitt sehen.
Im Allgemeinen
const
hilft eine Direktive anstelle einer Vorprozessor-Direktive beim Debuggen, in diesem Fall nicht so sehr (aber immer noch).Beide sind genauso effizient. Ich würde sagen, das Makro kann möglicherweise sicherer sein, da es zur Laufzeit nicht geändert werden kann, wohingegen eine Variable dies könnte.
quelle
const ...
Eingabe eingeben, anstatt ein Makro zu verwenden?pre-processor directives are frowned upon
[Zitat benötigt]Ich habe #define schon einmal verwendet, um mehr Methoden aus einer Methode zu erstellen, als ob ich so etwas hätte.
Aber ich möchte auch eine Methode haben, die nur 3 Zahlen und 2 Zahlen akzeptiert. Anstatt zwei neue Methoden zu schreiben, werde ich dieselbe mit #define verwenden.
Ich denke, das ist eine ziemlich coole Sache. Ich weiß, dass Sie direkt zur Methode gehen und einfach Null in die Räume setzen können, die Sie nicht wollen, aber wenn Sie eine Bibliothek erstellen, ist dies sehr nützlich. Auch so geht das
sind fertig.
Während ich nicht glaube, dass Sie dies mit Konstanten tun können. Konstanten haben jedoch Vorteile gegenüber #define, da Sie keinen Typ mit #define angeben können, da es sich um eine Vorprozessor-Direktive handelt, die vor dem Kompilieren aufgelöst wird. Wenn bei #define ein Fehler auftritt, ist das Debuggen schwieriger Konstanten. Beide haben Vor- und Nachteile, aber ich würde sagen, dass alles von dem Programmierer abhängt, für den Sie sich entschieden haben. Ich habe mit beiden eine Bibliothek geschrieben, indem ich #define verwendet habe, um das zu tun, was ich gezeigt habe, und Konstanten zum Deklarieren von konstanten Variablen, für die ich einen Typ angeben muss.
quelle