Preprocesory celu-C
Plik Objective-C Preprocessornie jest częścią kompilatora, ale stanowi oddzielny krok w procesie kompilacji. Mówiąc prościej, preprocesor Objective-C jest tylko narzędziem do zastępowania tekstu i instruuje kompilator, aby wykonał wymagane przetwarzanie wstępne przed właściwą kompilacją. Będziemy nazywać Preprocesor Objective-C jako OCPP.
Wszystkie polecenia preprocesora zaczynają się od symbolu krzyżyka (#). Musi to być pierwszy niepusty znak, a dla czytelności dyrektywa preprocesora powinna zaczynać się w pierwszej kolumnie. Poniższa sekcja zawiera listę wszystkich ważnych dyrektyw preprocesora -
Sr.No. | Dyrektywa i opis |
---|---|
1 | #define Zastępuje makro preprocesora |
2 | #include Wstawia określony nagłówek z innego pliku |
3 | #undef Nie definiuje makra preprocesora |
4 | #ifdef Zwraca wartość true, jeśli to makro jest zdefiniowane |
5 | #ifndef Zwraca wartość true, jeśli to makro nie jest zdefiniowane |
6 | #if Testuje, czy warunek czasu kompilacji jest prawdziwy |
7 | #else Alternatywa dla #if |
8 | #elif #else an #if w jednej instrukcji |
9 | #endif Warunkowe zakończenie preprocesora |
10 | #error Wyświetla komunikat o błędzie na stderr |
11 | #pragma Wydaje specjalne polecenia kompilatorowi przy użyciu standardowej metody |
Przykłady preprocesorów
Przeanalizuj poniższe przykłady, aby zrozumieć różne dyrektywy.
#define MAX_ARRAY_LENGTH 20
Ta dyrektywa nakazuje OCPP zamianę wystąpień MAX_ARRAY_LENGTH na 20. Użyj #define dla stałych, aby zwiększyć czytelność.
#import <Foundation/Foundation.h>
#include "myheader.h"
Te dyrektywy mówią OCPP, aby pobrać plik Foundation.h z Foundation Frameworki dodaj tekst do bieżącego pliku źródłowego. Następna linia mówi OCPP, aby uzyskaćmyheader.h z katalogu lokalnego i dodaj zawartość do bieżącego pliku źródłowego.
#undef FILE_SIZE
#define FILE_SIZE 42
To mówi OCPP, aby cofnął definicję istniejącego FILE_SIZE i zdefiniował go jako 42.
#ifndef MESSAGE
#define MESSAGE "You wish!"
#endif
To mówi OCPP, aby zdefiniował MESSAGE tylko wtedy, gdy MESSAGE nie jest jeszcze zdefiniowane.
#ifdef DEBUG
/* Your debugging statements here */
#endif
Informuje to OCPP, aby wykonał proces dołączonych instrukcji, jeśli zdefiniowano DEBUG. Jest to przydatne, jeśli przekazujesz flagę -DDEBUG do kompilatora gcc w czasie kompilacji. Spowoduje to zdefiniowanie funkcji DEBUG, dzięki czemu można włączać i wyłączać debugowanie w locie podczas kompilacji.
Predefiniowane makra
ANSI C definiuje szereg makr. Chociaż każdy z nich jest dostępny do użytku w programowaniu, predefiniowanych makr nie należy bezpośrednio modyfikować.
Sr.No. | Makro i opis |
---|---|
1 | __DATE__ Bieżąca data jako literał znakowy w formacie „MMM DD RRRR” |
2 | __TIME__ Bieżący czas jako literał znaku w formacie „HH: MM: SS” |
3 | __FILE__ Zawiera bieżącą nazwę pliku jako literał ciągu. |
4 | __LINE__ Zawiera bieżący numer wiersza jako stałą dziesiętną. |
5 | __STDC__ Zdefiniowany jako 1, gdy kompilator jest zgodny ze standardem ANSI. |
Wypróbujmy następujący przykład -
#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;
}
Gdy powyższy kod w pliku main.m jest kompilowany i wykonywany, daje następujący wynik -
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
Operatory preprocesora
Preprocesor Objective-C oferuje następujące operatory, które pomogą Ci w tworzeniu makr -
Kontynuacja makra (\)
Makro zwykle musi znajdować się w jednym wierszu. Operator kontynuacji makra służy do kontynuowania makra, które jest zbyt długie dla pojedynczego wiersza. Na przykład -
#define message_for(a, b) \
NSLog(@#a " and " #b ": We love you!\n")
Stringize (#)
Operator stringize lub number-sign („#”) używany w definicji makra konwertuje parametr makra na stałą łańcuchową. Ten operator może być używany tylko w makrze, które ma określony argument lub listę parametrów. Na przykład -
#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;
}
Kiedy powyższy kod jest kompilowany i wykonywany, daje następujący wynik -
2013-09-14 05:46:14.859 demo[20683] Carole and Debra: We love you!
Wklejanie tokena (##)
Operator wklejania tokenu (##) w definicji makra łączy dwa argumenty. Umożliwia połączenie dwóch oddzielnych tokenów w definicji makra w jeden token. Na przykład -
#import <Foundation/Foundation.h>
#define tokenpaster(n) NSLog (@"token" #n " = %d", token##n)
int main(void) {
int token34 = 40;
tokenpaster(34);
return 0;
}
Kiedy powyższy kod jest kompilowany i wykonywany, daje następujący wynik -
2013-09-14 05:48:14.859 demo[20683] token34 = 40
Jak to się stało, ponieważ ten przykład skutkuje następującym faktycznym wyjściem z preprocesora -
NSLog (@"token34 = %d", token34);
Ten przykład pokazuje konkatenację tokenu ## n w token34 i tutaj użyliśmy obu stringize i token-pasting.
Operator zdefiniowany ()
Preprocesor definedoperator jest używany w wyrażeniach stałych do określenia, czy identyfikator jest zdefiniowany za pomocą #define. Jeśli określony identyfikator jest zdefiniowany, wartością jest prawda (różna od zera). Jeśli symbol nie jest zdefiniowany, wartość jest fałszywa (zero). Zdefiniowany operator jest określony w następujący sposób -
#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;
}
Kiedy powyższy kod jest kompilowany i wykonywany, daje następujący wynik -
2013-09-14 05:48:19.859 demo[20683] Here is the message: You wish!
Sparametryzowane makra
Jedną z potężnych funkcji OCPP jest możliwość symulacji funkcji przy użyciu sparametryzowanych makr. Na przykład możemy mieć kod do kwadratu liczby w następujący sposób -
int square(int x) {
return x * x;
}
Możemy przepisać powyższy kod za pomocą makra w następujący sposób -
#define square(x) ((x) * (x))
Makra z argumentami należy definiować przy użyciu rozszerzenia #definedyrektywy, zanim będzie można ich użyć. Lista argumentów jest ujęta w nawiasy i musi następować bezpośrednio po nazwie makra. Spacje są niedozwolone między nazwą makra a otwartym nawiasem. Na przykład -
#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;
}
Kiedy powyższy kod jest kompilowany i wykonywany, daje następujący wynik -
2013-09-14 05:52:15.859 demo[20683] Max between 20 and 10 is 20