#define-Anweisung (C/C++)
Die #define erstellt ein Makro, bei dem es sich um die Zuordnung eines Bezeichners oder parametrisierten Bezeichners mit einer Tokenzeichenfolge handelt. Nachdem das Makro definiert wurde, kann der Compiler die Tokenzeichenkette für jedes Vorkommen des Bezeichners in der Quelldatei ersetzen.
Syntax
#define Token-Zeichenfolge-Opt
#define Bezeichner ( Id-Opt, ... , Bezeichner-Opt) Token-Zeichenfolge-Opt
Hinweise
Die #define direktive bewirkt, dass der Compiler die Tokenzeichenfolge für jedes Vorkommen von Bezeichnern in der Quelldatei ersetzt. Der Bezeichner wird nur ersetzt, wenn er ein Token bildet. Das heißt, der Bezeichner wird nicht ersetzt, wenn er in einem Kommentar, in einer Zeichenfolge oder als Teil eines längeren Bezeichners angezeigt wird. Weitere Informationen finden Sie unter Token.
Das Tokenzeichenfolgenargument besteht aus einer Reihe von Token, z. B. Schlüsselwörtern, Konstanten oder vollständigen Anweisungen. Mindestens ein Leerzeichen muss die Tokenzeichenfolge vom Bezeichner trennen. Diese Leerstelle und alle weiteren Leerstellen nach dem letzten Token des Texts werden nicht als Teil des ersetzten Texts betrachtet.
A #define
ohne Tokenzeichenfolge entfernt Vorkommen von Bezeichnern aus der Quelldatei. Der Bezeichner bleibt definiert und kann mithilfe der #if defined
Richtlinien getestet #ifdef
werden.
Durch das zweite Syntaxformat wird ein funktionsähnliches Makro mit Parametern definiert. Dieses Formular akzeptiert eine optionale Liste von Parametern, die in Klammern angegeben sein müssen. Nachdem das Makro definiert wurde, wird jedes nachfolgende Vorkommen des Bezeichners( Bezeichner opt, ..., IdentifierOpt ) durch eine Version des Tokenzeichenfolgenarguments ersetzt, das tatsächliche Argumente für formale Parameter ersetzt hat.
Formale Parameternamen werden in der Tokenzeichenfolge angezeigt, um die Speicherorte zu markieren, an denen tatsächliche Werte ersetzt werden. Jeder Parametername kann mehrmals in tokenzeichenfolgen angezeigt werden, und die Namen können in beliebiger Reihenfolge angezeigt werden. Die Anzahl von Argumenten im Aufruf muss mit der Anzahl von Parametern in der Makrodefinition übereinstimmen. Mit der großzügigen Verwendung von Klammern wird sichergestellt, dass komplexe tatsächliche Argumente richtig interpretiert werden.
Die formalen Parameter in der Liste werden durch Kommas getrennt. Jeder Name in der Liste muss eindeutig sein und die Liste muss in Klammern eingeschlossen werden. Keine Leerzeichen können bezeichner und die öffnende Klammer trennen. Verwenden Sie die Zeilenverkettung – platzieren Sie einen umgekehrten Schrägstrich (\
) unmittelbar vor dem Zeilenumbruchzeichen für lange Direktiven in mehreren Quellzeilen. Der Bereich eines formalen Parameternamens wird auf die neue Zeile erweitert, die die Tokenzeichenfolge endet.
Wenn ein Makro im zweiten Syntaxformat definiert wurde, geben nachfolgende Textinstanzen, auf die eine Argumentliste folgt, einen Makro-Aufruf an. Die tatsächlichen Argumente, die auf eine Instanz des Bezeichners in der Quelldatei folgen, werden mit den entsprechenden formalen Parametern in der Makrodefinition abgeglichen. Jeder formale Parameter in token-string, der keinem Zeichenfolgenoperator (#
),#@
Zeichen () oder Token pasting (##
) vorangestellt ist, oder nicht gefolgt von einem ##
Operator, wird durch das entsprechende tatsächliche Argument ersetzt. Alle Makros im tatsächlichen Argument werden erweitert, bevor die Anweisung den formalen Parameter ersetzt. (Die Operatoren werden in Präprozessoroperatoren.)
Die folgenden Beispiele für Makros mit Argumenten veranschaulichen die zweite Form der #define Syntax:
// Macro to define cursor lines
#define CURSOR(top, bottom) (((top) << 8) | (bottom))
// Macro to get a random integer with a specified range
#define getrandom(min, max) \
((rand()%(int)(((max) + 1)-(min)))+ (min))
Argumente mit Nebeneffekten können dazu führen, dass Makros unerwartete Ergebnisse erzeugen. Ein bestimmter formaler Parameter kann mehrere Mal in tokenzeichenfolgen angezeigt werden. Wenn der formale Parameter durch einen Ausdruck mit Nebeneffekten ersetzt wird, dann wird der Ausdruck samt seinen Nebeneffekten evtl. mehrmals ausgewertet. (Siehe die Beispiele unter Token-Pasting-Operator (##).)
Die #undef
-Anweisung führt dazu, dass die Präprozessordefinition eines Bezeichners übergangen wird. Weitere Informationen finden Sie in der richtlinie #undef .
Wenn der Name des definierten Makros in der Tokenzeichenfolge (auch aufgrund einer anderen Makroerweiterung) auftritt, wird es nicht erweitert.
Eine zweite #define für ein Makro mit demselben Namen generiert eine Warnung, es sei denn, die zweite Tokensequenz ist identisch mit dem ersten.
Microsoft-spezifisch
Mit Microsoft C/C++ können Sie ein Makro neu definieren, wenn die neue Definition mit der ursprünglichen Definition syntaktisch identisch ist. Das bedeutet, dass die beiden Definitionen über unterschiedliche Parameternamen verfügen können. Dieses Verhalten unterscheidet sich von ANSI C, was erfordert, dass die beiden Definitionen lexikalisch identisch sind.
Beispielsweise sind die folgenden beiden Makros identisch, abgesehen von den Parameternamen. ANSI C lässt eine solche Neudefinition nicht zu, aber Microsoft C/C++ kompiliert sie ohne Fehler.
#define multiply( f1, f2 ) ( f1 * f2 )
#define multiply( a1, a2 ) ( a1 * a2 )
Andererseits sind die folgenden beiden Makros nicht identisch und generieren in Microsoft C/C++ eine Warnung.
#define multiply( f1, f2 ) ( f1 * f2 )
#define multiply( a1, a2 ) ( b1 * b2 )
Ende Microsoft-spezifisch
In diesem Beispiel wird die #define-Direktive veranschaulicht:
#define WIDTH 80
#define LENGTH ( WIDTH + 10 )
Die erste Anweisung definiert den Bezeichner WIDTH
als die ganzzahlige Konstante 80 und definiert LENGTH
hinsichtlich WIDTH
und der ganzzahligen Konstante 10. Jedes Vorkommen von LENGTH
wird ersetzt durch (WIDTH + 10
). Im Gegenzug wird jedes Vorkommen von WIDTH + 10
durch den Ausdruck (80 + 10
) ersetzt. Die Klammern um WIDTH + 10
sind wichtig, da sie die Interpretation in Anweisungen steuern, z. B.:
var = LENGTH * 20;
Nach der Vorverarbeitungsphase wird die Anweisung:
var = ( 80 + 10 ) * 20;
zu 1800 ausgewertet. Ohne Klammern wird das Ergebnis:
var = 80 + 10 * 20;
die als 280 ausgewertet wird.
Microsoft-spezifisch
Das Definieren von Makros und Konstanten mit der /D-Compileroption hat dieselbe Auswirkung wie die Verwendung einer #define Präverarbeitungsdirektive am Anfang der Datei. Maximal 30 Makros können mit der /D-Option definiert werden.
Ende Microsoft-spezifisch