Udostępnij za pośrednictwem


#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

Zobacz też

Informacje

Dyrektywy preprocesora