Es ist eine einfache Frage, aber warum sollte jemand #define verwenden, um Konstanten zu definieren?
Was ist der Unterschied zwischen
#define sum 1
und const int sum = 1;
Es ist eine einfache Frage, aber warum sollte jemand #define verwenden, um Konstanten zu definieren?
Was ist der Unterschied zwischen
#define sum 1
und const int sum = 1;
#define
hat viele verschiedene Anwendungen, aber Ihre Frage scheint sich auf eine bestimmte Anwendung zu beziehen: das Definieren benannter Konstanten.
In C++ gibt es selten einen Grund zur Verwendung #define
um benannte Konstanten zu definieren.
#define
wird normalerweise häufig in C-Code verwendet, da sich die C-Sprache erheblich von C++ unterscheidet, wenn es um die Definition von Konstanten geht. Zusamenfassend, const int
Objekte sind es nicht Konstanten in C, was bedeutet, dass in C der primäre Weg, eine wahre Konstante zu definieren, die Verwendung ist #define
. (Auch für int
Konstanten kann man Aufzählungen verwenden).
@AndreyT Mann, ich habe hier Angst 😐 , was ist die regel ist diese richtige antwort , ursache von punkten ?
– Benutzer788552
8. Juni 11 um 4:20 Uhr
@ user788552 mehr Punkte zu einer Antwort bedeuten nicht, dass es immer wahr ist
– Synchronisationsmax
8. Juni 11 um 4:46 Uhr
static const int und enum {…} sind echte konstante Konstanten in C++
– CygnusX1
8. Juni 11 um 5:40 Uhr
@CygnusX1: In C++ ist keine Notwendigkeit für static
vor dem const int
. In C++ const
Objekte haben standardmäßig eine interne Verknüpfung.
– Ant
8. Juni 11 um 5:51 Uhr
@BlueRaja – Danny Pflughoeft: Nun, nur weil die Sprache so definiert ist. In C-Sprache können Sie nicht verwenden const int
Objekt als case
Label, als Bitfeldgröße, als Arraygröße für Nicht-VLA-Arrays, speziell weil const int
Objekte sind in C keine Konstanten. Der Begriff “Konstante” in C bezieht sich auf wörtliche Konstanten (wie z 25
) und zum Aufzählen von Mitgliedern, aber nicht zu const
Objekte.
– Ant
8. Juni 11 um 6:36 Uhr
Alok Speichern
Niemand sollte nicht!
Eigentlich sollte man lieber const int sum = 1;
über #define sum 1
wegen vielen Gründen:
Bereichsbasierter Mechanismus:
#define
s respektieren keine Geltungsbereiche, daher gibt es keine Möglichkeit, einen klassenbezogenen Namespace zu erstellen. Während konstante Variablen in Klassen bereichsabhängig sein können.
Vermeidung seltsamer magischer Zahlen bei Kompilierungsfehlern:
Wenn Sie verwenden #define
diese werden zum Zeitpunkt der Vorkompilierung durch den Präprozessor ersetzt. Wenn Sie also während der Kompilierung einen Fehler erhalten, ist dies verwirrend, da sich die Fehlermeldung nicht auf den Makronamen bezieht, sondern auf den Wert, und es erscheint ein plötzlicher Wert, und Sie würden viel verschwenden der Zeit, es im Code aufzuspüren.
Einfaches Debuggen:
Auch aus den gleichen Gründen wie in Nr. 2 erwähnt, während des Debuggens #define
würde nicht wirklich helfen.
So vermeiden Sie die oben genannten Situationen const
wird eine bessere Wahl sein.
@Martinho, wenn eine der Antworten mit beginnt #
in SO macht es dann alles rein groß fett.
– iammilind
8. Juni 11 um 3:58 Uhr
+1 macht Sinn, obwohl es fraglich ist, ob das gut oder schlecht ist, denke ich.
– Benutzer541686
8. Juni 11 um 3:58 Uhr
@Mehrdad, #define X
kann mit virtuell abgegrenzt werden #undef X
– iammilind
8. Juni 11 um 3:59 Uhr
@iammilind: Nicht wirklich. Wenn es zuvor definiert wurde, verliert es den vorherigen Wert – es ist nicht wie push/pop’ing einen Stack.
– Benutzer541686
8. Juni 11 um 4:00 Uhr
lol, “warum sollte jemand #define verwenden?” „aus mehreren Gründen: 1) es ist scheiße 2) es ist scheiße 3) es ist scheiße“
– R.Martinho Fernandes
8. Juni 11 um 4:14 Uhr
Für das Beispiel, das Sie gerade gegeben haben, würde ich normalerweise eine Konstante verwenden. Außer natürlich, dass #define an anderer Stelle für die bedingte Kompilierung verwendet werden kann:
#if SOME_DEFINE == 1
// Conditional code
#endif
Das ist etwas, was Sie mit einer Konstante nicht tun können. Wenn Sie nicht benötigen, dass der Wert vom Präprozessor zugänglich ist, würde ich sagen, verwenden Sie eine Konstante, es sei denn, es gibt einen Grund, warum dies nicht möglich ist. Es gibt einiges dazu in der C++ FAQ litewo sie zu Recht darauf hinweisen, dass nur weil der Präprozessor “böse” ist, das nicht bedeutet, dass Sie ihn nie brauchen werden.
Ich würde nicht sagen, dass die Konstante nicht für die bedingte Kompilierung verwendet werden kann. Sie können eine Vorlage für die Konstante spezialisieren. Schauen Sie zum Beispiel hier vorbei.
– Kirill W. Ljadwinski
8. Juni 11 um 4:14 Uhr
Ja, aber ich kann das nicht verwenden, um
– Sven
8. Juni 11 um 4:18 Uhr
Ich würde eher das Build-System verwenden, um solche Entscheidungen zu treffen define
S.
– Kirill W. Ljadwinski
8. Juni 11 um 4:24 Uhr
Ich gebe keine Empfehlung zur bedingten Kompilierung ab, ich weise nur auf eine mögliche Sache hin, die Sie mit #defines tun können, die mit einer Konstante nicht (leicht) zu erreichen ist.
– Sven
8. Juni 11 um 17:31 Uhr
#define
ist notwendig, damit Dinge wie Inklusionswächter funktionieren, weil C++ keine hat Real Modulimportsystem.
#define
bewirkt eine wörtliche Textsubstitution. Der Präprozessor versteht, wie man Quellcode tokenisiert, hat aber keine Ahnung, was das alles eigentlich bedeutet. Wenn du schreibst #define sum 1
geht der Präprozessor Ihren Code durch und sucht nach jeder Instanz des Tokens sum
und ersetzt es durch das Token 1
.
Dies hat eine Reihe von Einschränkungen: #define sq(x) x * x
wird nicht richtig funktionieren, wenn Sie es wie verwenden sq(3+3)
; und verwenden #define
denn eine Konstante respektiert in keiner Weise den Geltungsbereich und ordnet der Konstante auch keinen Typ zu. Jedoch, #define
verwendet werden kann (insbesondere in Kombination mit einigen anderen speziellen Sachen wie der #
und ##
Präprozessor-Operatoren), um etwas zu zaubern, was sonst nicht möglich ist (außer indem Sie manuell tun, was der Präprozessor tut).
Versuchen Sie immer, “const int” anstelle von #define zu verwenden.
Verwenden Sie #define nur dann, wenn Ihr Präprozessorcode möglicherweise von einem anderen Tool gelesen wird und es einfacher ist, mit dem Präprozessor zu arbeiten, als die Sprache zu analysieren.
Außerdem ist es die einzige Möglichkeit, etwas zu definieren, das später durch #if/#else/#endif überprüft werden soll
Pharap
In einfachen Worten
#define sum 1 /*is pre processed*/
Was bedeutet, dass sum
existiert nicht, nachdem die Vorverarbeitungsphase abgeschlossen ist.
const int sum = 1; /*is compiled/linked*/
Was bedeutet sum
existiert, bis die ausführbare Datei aus Ihrem Programm erstellt wird.
John Joe
Von Einführung in die Programmierung mit C++ das von Daniel Liang geschrieben wurde, erklärte:
Wenn Sie eine Konstante mit definieren
#define
Direktive wird die Konstante nicht im Speicher gespeichert. Die Konstante wird vom Compiler durch einen Wert ersetzt. Wenn Sie eine Konstante mit deklarierenconst
Schlüsselwort, die Konstante wird genau wie die Variable im Speicher gespeichert.
Wenn Konstanten in mehreren Programmen verwendet werden müssen, verwenden Sie #define
darin zu definieren Header-Datei damit es in andere Programme eingebunden werden kann. Wenn die Konstante nur in einem Programm verwendet wird, verwenden Sie const
deklarieren ist effizienter.
.
Ich bin ehrlich gesagt sehr versucht zu sagen, “weil sie n00bs sind” … +1 gute Frage
– Benutzer541686
8. Juni 11 um 3:55 Uhr
Ja, dieser sollte einige amüsante Antworten hervorbringen
– Nemo
8. Juni 11 um 4:02 Uhr
@user Sehr einfach, wenn Sie in C++ programmieren – folgen Sie einfach Scott Meyers Ratschlag Punkt 1 “Bevorzugen Sie const und inline gegenüber #define”. Verwenden Sie ‘#define’ als letzten Ausweg, wo const nicht funktionieren würde. Zum Beispiel Header-Inclusion-Guards etc.
– Großwolf
8. Juni 11 um 4:05 Uhr
Hier ist ein Tipp, um das Risiko zu verringern, viele unterschiedliche Antworten zu erhalten: Stellen Sie nicht eine Frage in einem Titel und eine andere Frage im Hauptteil. Sie sind ähnlich, haben aber unterschiedliche Antwortmöglichkeiten.
– R.Martinho Fernandes
8. Juni 11 um 4:05 Uhr
@Nemo natürlich, wie sonst kann er schnell ein paar Wiederholungspunkte sammeln? 😛
– Großwolf
8. Juni 11 um 4:08 Uhr