#define — dyrektywa (C/C++)
#define tworzy makro, który jest skojarzeniem identyfikatora lub identyfikatora sparametryzowanej ciągiem tokenu.Po zdefiniowaniu makra kompilator może zastąpić ciąg tokenu dla każdego wystąpienia identyfikatora w pliku źródłowym.
Składnia
#defineidentifiertoken-stringopt
#defineidentifier(identifieropt,...,identifieropt)token-stringopt
Uwagi
Dyrektywa #define powoduje, że kompilator podstawia token-string dla każdego wystąpienia identifier w pliku źródłowym.identifier jest zastępowany tylko wtedy, gdy stanowi token.Oznacza to, że identifier nie jest zastępowany, jeśli występuje on w komentarzu, w ciągu lub jako część dłuższego identyfikatora.Aby uzyskać więcej informacji, zobacz Tokeny języka C++.
Argument token-string składa się z serii tokenów, takich jak słowa kluczowe, stałe lub pełne instrukcje.Jeden lub więcej białych znaków musi oddzielać token-string od identifier.Ten biały znak nie jest uważany za część podstawionego tekstu, podobnie jak żaden inny biały znak, który znajduje się za ostatnim tokenem tekstu.
A #definebez token-string usuwa wystąpień identifier z pliku źródłowego.identifier pozostaje zdefiniowany i może być przetestowany przy użyciu dyrektyw #if defined i #ifdef.
Druga forma składni definiuje funkcyjne makro za pomocą parametrów.Ten formularz przyjmuje opcjonalną listę parametrów, która musi występować w nawiasach.Po zdefinouwaniu makro, każde kolejne wystąpienie identifier(identifieropt ,..., identifieropt ) będzie zastąpione wersją z token-string argumentu, który zawiera rzeczywiste argumenty podstawiane dla parametrów formalnych.
Nazwy parametrów formalnych pojawiają się w token-string do oznaczania miejsc, w których są zastępowane wartości rzeczywiste.Nazwa każdego parametru może pojawić się wiele razy w token-string, a nazwy mogą pojawiać się w dowolnej kolejności.Liczba argumentów w wywołaniu musi odpowiadać liczbie parametrów w definicji makra.Liberalne stosowanie nawiasów gwarantuje poprawną interpretację złożonych bieżących argumentów.
Parametry formalne na liście są oddzielone przecinkami.Każda nazwa na liście musi być unikatowa, a listy muszą być ujęte w nawiasy.Żadne spacje nie mogą rozdzielić identifier i nawias otwierający.Użyj łączenia wierszy — umieść ukośnik odwrotny (\) zaraz przez znakiem nowego wiersza — dla długich dyrektyw w wielu wierszach źródłowych.Zakres formalnego parametru rozciąga się do nowej linii, która kończy token-string.
Po zdefiniowaniu makra w drugim formularzu składni, kolejne wystąpienia tekstowe i następująca po nich lista argumentów oznaczają wywołanie makro.Rzeczywiste argumenty, które następują po wystąpieniu identifier w pliku źródłowym są dopasowywane do odpowiednich parametrów formalnych w definicji makra.Każdy z parametrów formalnych w token-string który nie jest poprzedzony przez ciąg (#), charizing (#@), lub wklejanie tokenów (##) operator, lub nie następuje ## operatora, zastępuje odpowiednie argumenty rzeczywiste.Wszystkie makra w rzeczywistym argumencie są rozwinięte, zanim dyrektywa zastąpi parametrów formalny. (Operatorzy są opisani w Operatorach Preprocesowych.)
Poniższe przykłady makr z argumentami ilustrują drugą formę składni #define :
// 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))
Argumenty ze skutami ubocznych czasami powodują, że makra dają nieoczekiwane wyniki.Określony parametr formalny może pojawić się więcej niż jeden raz w token-string.Jeśli ten parametr formalny zostanie zastąpiony przez wyrażenie z efektami ubocznymi, wyrażenie razem z efektami ubocznymi może zostać ocenione więcej niż jeden raz. (Zobacz przykłady w Token wklejanie operatora (##).)
Dyrektywa #undef powoduje usunięcie definicji preprocesora identyfikatora.Zobacz Dyrektywa #undef, aby uzyskać więcej informacji.
Jeśli nazwa definiowanego makra występuje w token-string (nawet w wyniku innego makra rozszerzenia), to nie jest rozwinięta.
Drugi #define dla makra o tej samej nazwie generuje ostrzeżenie, chyba że jest identyczny z pierwszym drugiej sekwencji tokenu.
Specyficzne dla firmy Microsoft
Język C/C++ firmy Microsoft pozwala na zdefiniowanie makra, jeśli nowa definicja jest syntaktycznie identyczna z oryginalną definicją.Innymi słowy dwie definicje mogą mieć nazwy różnych parametrów.To zachowanie różni się od C ANSI, które wymaga zbieżności leksykalnej obu definicji.
Na przykład następujące dwa makra są identyczne, z wyjątkiem nazw parametrów.ANSI C nie zezwala na taką ponowną definicję, ale Microsoft C/C++ kompiluje to bez błędu.
#define multiply( f1, f2 ) ( f1 * f2 )
#define multiply( a1, a2 ) ( a1 * a2 )
Z drugiej strony dwa następujące makra nie są identyczne i generują ostrzeżenie w Microsoft C/C++.
#define multiply( f1, f2 ) ( f1 * f2 )
#define multiply( a1, a2 ) ( b1 * b2 )
KONIEC informacji specyficznych dla firmy Microsoft
Ten przykład ilustruje dyrektywę #define:
#define WIDTH 80
#define LENGTH ( WIDTH + 10 )
Pierwsza instrukcja określa identyfikator WIDTH jako stałą liczbę całkowitą 80 i definiuje LENGTH z WIDTH i liczbę całkowitą 10.Każde wystąpienie LENGTH zastępuje się wyrazami (WIDTH + 10).Z kolei każde wystąpienie WIDTH + 10 jest zastąpione wyrażeniem (80 + 10).Nawiasy wokół WIDTH + 10 są ważne, ponieważ kontrolują interpretację instrukcji takich jak poniższe:
var = LENGTH * 20;
Po etapie przetwarzania wstępnego oświadczenie staje się:
var = ( 80 + 10 ) * 20;
który ocenia do 1800.Bez nawiasów, wynik to:
var = 80 + 10 * 20;
który ma 280.
Specyficzne dla firmy Microsoft
Definiowanie makr i stałych z /D działa tak samo jak przy użyciu opcji kompilatora #define dyrektywy preprocesora na początku pliku.Do 30 makr można zdefiniować przy użyciu opcji /D.
KONIEC informacji specyficznych dla firmy Microsoft