Objective-C-Präprozessoren

Das Objective-C Preprocessorist nicht Teil des Compilers, sondern ein separater Schritt im Kompilierungsprozess. Vereinfacht ausgedrückt ist ein Objective-C-Präprozessor nur ein Textersetzungswerkzeug und weist den Compiler an, vor der eigentlichen Kompilierung die erforderliche Vorverarbeitung durchzuführen. Wir werden den Objective-C-Präprozessor als OCPP bezeichnen.

Alle Präprozessorbefehle beginnen mit einem Pfund-Symbol (#). Es muss das erste nicht leere Zeichen sein, und aus Gründen der Lesbarkeit sollte eine Präprozessoranweisung in der ersten Spalte beginnen. Der folgende Abschnitt listet alle wichtigen Präprozessoranweisungen auf -

Sr.Nr. Richtlinie & Beschreibung
1

#define

Ersetzt ein Präprozessor-Makro

2

#include

Fügt einen bestimmten Header aus einer anderen Datei ein

3

#undef

Undefiniert ein Präprozessor-Makro

4

#ifdef

Gibt true zurück, wenn dieses Makro definiert ist

5

#ifndef

Gibt true zurück, wenn dieses Makro nicht definiert ist

6

#if

Testet, ob eine Kompilierungszeitbedingung erfüllt ist

7

#else

Die Alternative für #if

8

#elif

#else ein #if in einer Anweisung

9

#endif

Beendet den Präprozessor unter bestimmten Bedingungen

10

#error

Druckt eine Fehlermeldung auf stderr

11

#pragma

Gibt spezielle Befehle mit einer standardisierten Methode an den Compiler aus

Präprozessor-Beispiele

Analysieren Sie die folgenden Beispiele, um verschiedene Richtlinien zu verstehen.

#define MAX_ARRAY_LENGTH 20

Diese Anweisung weist das OCPP an, Instanzen von MAX_ARRAY_LENGTH durch 20 zu ersetzen. Verwenden Sie #define für Konstanten, um die Lesbarkeit zu verbessern .

#import <Foundation/Foundation.h>
#include "myheader.h"

Diese Anweisungen weisen die OCPP an, die Stiftung.h von zu erhalten Foundation Frameworkund fügen Sie den Text zur aktuellen Quelldatei hinzu. Die nächste Zeile weist OCPP an, abzurufenmyheader.h aus dem lokalen Verzeichnis und fügen Sie den Inhalt zur aktuellen Quelldatei hinzu.

#undef  FILE_SIZE
#define FILE_SIZE 42

Dies weist das OCPP an, die vorhandene FILE_SIZE aufzuheben und als 42 zu definieren.

#ifndef MESSAGE
   #define MESSAGE "You wish!"
#endif

Dies weist das OCPP an, MESSAGE nur zu definieren, wenn MESSAGE noch nicht definiert ist.

#ifdef DEBUG
   /* Your debugging statements here */
#endif

Dies weist das OCPP an, den Prozess mit den beiliegenden Anweisungen durchzuführen, wenn DEBUG definiert ist. Dies ist nützlich, wenn Sie das Flag -DDEBUG zum Zeitpunkt der Kompilierung an den gcc-Compiler übergeben. Dadurch wird DEBUG definiert, sodass Sie das Debuggen während der Kompilierung im laufenden Betrieb ein- und ausschalten können.

Vordefinierte Makros

ANSI C definiert eine Reihe von Makros. Obwohl jedes für Ihre Verwendung in der Programmierung verfügbar ist, sollten die vordefinierten Makros nicht direkt geändert werden.

Sr.Nr. Makro & Beschreibung
1

__DATE__

Das aktuelle Datum als Zeichenliteral im Format "MMM TT JJJJ"

2

__TIME__

Die aktuelle Zeit als Zeichenliteral im Format "HH: MM: SS"

3

__FILE__

Dieser enthält den aktuellen Dateinamen als Zeichenfolgenliteral.

4

__LINE__

Diese enthält die aktuelle Zeilennummer als Dezimalkonstante.

5

__STDC__

Definiert als 1, wenn der Compiler dem ANSI-Standard entspricht.

Versuchen wir das folgende Beispiel:

#import <Foundation/Foundation.h>

int main() {
   NSLog(@"File :%s\n", __FILE__ );
   NSLog(@"Date :%s\n", __DATE__ );
   NSLog(@"Time :%s\n", __TIME__ );
   NSLog(@"Line :%d\n", __LINE__ );
   NSLog(@"ANSI :%d\n", __STDC__ );
   
   return 0;
}

Wenn der obige Code in einer Datei main.m wird kompiliert und ausgeführt, ergibt sich folgendes Ergebnis:

2013-09-14 04:46:14.859 demo[20683] File :main.m
2013-09-14 04:46:14.859 demo[20683] Date :Sep 14 2013
2013-09-14 04:46:14.859 demo[20683] Time :04:46:14
2013-09-14 04:46:14.859 demo[20683] Line :8
2013-09-14 04:46:14.859 demo[20683] ANSI :1

Präprozessor-Operatoren

Der Objective-C-Präprozessor bietet folgende Operatoren, die Sie beim Erstellen von Makros unterstützen:

Makro-Fortsetzung (\)

Ein Makro muss normalerweise in einer einzelnen Zeile enthalten sein. Der Makro-Fortsetzungsoperator wird verwendet, um ein Makro fortzusetzen, das für eine einzelne Zeile zu lang ist. Zum Beispiel -

#define  message_for(a, b)  \
   NSLog(@#a " and " #b ": We love you!\n")

Stringize (#)

Der Stringize- oder Zahlenzeichenoperator ('#') konvertiert bei Verwendung innerhalb einer Makrodefinition einen Makroparameter in eine String-Konstante. Dieser Operator darf nur in einem Makro verwendet werden, für das ein Argument oder eine Parameterliste angegeben ist. Zum Beispiel -

#import <Foundation/Foundation.h>

#define  message_for(a, b)  \
   NSLog(@#a " and " #b ": We love you!\n")

int main(void) {
   message_for(Carole, Debra);
   return 0;
}

Wenn der obige Code kompiliert und ausgeführt wird, ergibt sich das folgende Ergebnis:

2013-09-14 05:46:14.859 demo[20683] Carole and Debra: We love you!

Token einfügen (##)

Der Token-Pasting-Operator (##) in einer Makrodefinition kombiniert zwei Argumente. Damit können zwei separate Token in der Makrodefinition zu einem einzigen Token zusammengefügt werden. Zum Beispiel -

#import <Foundation/Foundation.h>

#define tokenpaster(n) NSLog (@"token" #n " = %d", token##n)

int main(void) {
   int token34 = 40;
   
   tokenpaster(34);
   return 0;
}

Wenn der obige Code kompiliert und ausgeführt wird, ergibt sich das folgende Ergebnis:

2013-09-14 05:48:14.859 demo[20683] token34 = 40

Wie es passiert ist, denn dieses Beispiel führt zu der folgenden tatsächlichen Ausgabe vom Präprozessor -

NSLog (@"token34 = %d", token34);

Dieses Beispiel zeigt die Verkettung von Token ## n zu Token34, und hier haben wir beide verwendet stringize und token-pasting.

Der definierte () Operator

Der Präprozessor definedDer Operator wird in konstanten Ausdrücken verwendet, um zu bestimmen, ob ein Bezeichner mit #define definiert ist. Wenn der angegebene Bezeichner definiert ist, ist der Wert wahr (ungleich Null). Wenn das Symbol nicht definiert ist, ist der Wert falsch (Null). Der definierte Operator wird wie folgt angegeben:

#import <Foundation/Foundation.h>

#if !defined (MESSAGE)
   #define MESSAGE "You wish!"
#endif

int main(void) {
   NSLog(@"Here is the message: %s\n", MESSAGE);  
   return 0;
}

Wenn der obige Code kompiliert und ausgeführt wird, ergibt sich das folgende Ergebnis:

2013-09-14 05:48:19.859 demo[20683] Here is the message: You wish!

Parametrisierte Makros

Eine der leistungsstarken Funktionen des OCPP ist die Möglichkeit, Funktionen mithilfe parametrisierter Makros zu simulieren. Zum Beispiel könnten wir einen Code haben, um eine Zahl wie folgt zu quadrieren:

int square(int x) {
   return x * x;
}

Wir können den obigen Code mit einem Makro wie folgt umschreiben:

#define square(x) ((x) * (x))

Makros mit Argumenten müssen mit dem definiert werden #defineRichtlinie, bevor sie verwendet werden können. Die Argumentliste ist in Klammern eingeschlossen und muss unmittelbar auf den Makronamen folgen. Zwischen dem Makronamen und der offenen Klammer sind keine Leerzeichen zulässig. Zum Beispiel -

#import <Foundation/Foundation.h>

#define MAX(x,y) ((x) > (y) ? (x) : (y))

int main(void) {
   NSLog(@"Max between 20 and 10 is %d\n", MAX(10, 20));  
   return 0;
}

Wenn der obige Code kompiliert und ausgeführt wird, ergibt sich das folgende Ergebnis:

2013-09-14 05:52:15.859 demo[20683] Max between 20 and 10 is 20