direktiva #define (C/C++)

#define vytvoří makro, což je přidružení identifikátoru nebo parametrizovaného identifikátoru s řetězcem tokenu. Po definování makra může kompilátor nahradit řetězec tokenu pro každý výskyt identifikátoru ve zdrojovém souboru.

Syntaxe

#define opttoken-string identifikátoru
#define identifier(identifikátor opt; ... ,identifieropt)token-string opt

Poznámky

Direktiva #define způsobí, že kompilátor nahradí řetězec tokenu pro každý výskyt identifikátoru ve zdrojovém souboru. Identifikátor se nahradí pouze v případech, kdy tvoří token. To znamená, že identifikátor se nenahradí, pokud se zobrazí v komentáři, v řetězci nebo jako součást delšího identifikátoru. Další informace najdete v tématu Tokeny.

Argument token-řetězec se skládá z řady tokenů, jako jsou klíčová slova, konstanty nebo úplné příkazy. Jeden nebo více prázdných znaků musí oddělit řetězec tokenu od identifikátoru. Toto prázdné znaky se nepovažují za součást nahrazeného textu ani žádné prázdné znaky, které následuje za posledním tokenem textu.

A #define bez token-řetězec odebere výskyty identifikátoru ze zdrojového souboru. Identifikátor zůstane definovaný a lze ho #if defined otestovat pomocí direktiv a #ifdef direktiv.

Druhý formulář syntaxe definuje makro podobné funkci s parametry. Tento formulář přijímá volitelný seznam parametrů, které se musí zobrazit v závorkách. Po definování makra se každý další výskyt identifikátoru( opt identifikátoru, ...; opt identifikátoru) nahradí verzí argumentu token-string, který má skutečné argumenty nahrazené formálními parametry.

Formální názvy parametrů se zobrazí v řetězci tokenu a označí umístění, kde se nahradí skutečné hodnoty. Každý název parametru se může v řetězci tokenu objevit několikrát a názvy se můžou zobrazit v libovolném pořadí. Počet argumentů ve volání musí odpovídat počtu parametrů v definici makra. Použití závorek zaručuje, že složité skutečné argumenty jsou interpretovány správně.

Formální parametry v seznamu jsou oddělené čárkami. Každý název v seznamu musí být jedinečný a seznam musí být uzavřený v závorkách. Žádné mezery nemohou oddělit identifikátor a levou závorku. Použijte zřetězení řádku – umístěte zpětné lomítko (\) bezprostředně před znak nového řádku – pro dlouhé direktivy na více zdrojových řádcích. Obor formálního názvu parametru se rozšiřuje na nový řádek, který končí řetězec tokenu.

Pokud je makro definováno ve druhé syntaxi formuláře, následné textové instance následované seznamem argumentů označují volání makra. Skutečné argumenty, které následují za instancí identifikátoru ve zdrojovém souboru, se shodují s odpovídajícími formálními parametry v definici makra. Každý formální parametr v řetězci tokenu, který není před operátorem stringizing (#), charizing (#@) nebo token-pasting (##) nebo není následovaný ## operátorem, se nahradí odpovídajícím skutečným argumentem. Všechna makra ve skutečném argumentu se rozbalí před nahrazením formálního parametru direktivou. (Operátory jsou popsány v tématu Operátory preprocesoru.)

Následující příklady maker s argumenty ilustrují druhou formu syntaxe #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 s vedlejšími účinky někdy způsobují, že makra způsobí neočekávané výsledky. Daný formální parametr se může v řetězci tokenu objevit vícekrát. Pokud je tento formální parametr nahrazen výrazem vedlejšími účinky, výraz s vedlejšími účinky může být vyhodnocen více než jednou. (Podívejte se na příklady v části Operátor vkládání tokenů (##)))

Direktiva #undef způsobí zapomenutí definice preprocesoru identifikátoru. Další informace najdete v tématu Směrnice #undef.

Pokud se název definovaného makra vyskytuje v řetězci tokenu (i v důsledku jiného rozšíření makra), rozbalí se.

Druhý #define pro makro se stejným názvem vygeneruje upozornění, pokud druhá sekvence tokenu není stejná jako první.

Specifické pro Microsoft

Microsoft C/C++ umožňuje předefinovat makro, pokud je nová definice syntakticky identická s původní definicí. Jinými slovy, tyto dvě definice můžou mít různé názvy parametrů. Toto chování se liší od ANSI C, což vyžaduje, aby obě definice byly lexicky identické.

Následující dvě makra jsou například shodná s výjimkou názvů parametrů. ANSI C neumožňuje takovou redefinici, ale Microsoft C/C++ ji zkompiluje bez chyby.

#define multiply( f1, f2 ) ( f1 * f2 )
#define multiply( a1, a2 ) ( a1 * a2 )

Na druhou stranu následující dvě makra nejsou identická a vygenerují upozornění v jazyce Microsoft C/C++.

#define multiply( f1, f2 ) ( f1 * f2 )
#define multiply( a1, a2 ) ( b1 * b2 )

END Microsoft Specific

Tento příklad znázorňuje direktivu #define :

#define WIDTH       80
#define LENGTH      ( WIDTH + 10 )

První příkaz definuje identifikátor WIDTH jako celočíselnou konstantu 80 a definuje ho z hlediska WIDTH celočíselné konstanty LENGTH 10. Každý výskyt LENGTH je nahrazen (WIDTH + 10). Následně se každý výskyt WIDTH + 10 nahradí výrazem (80 + 10). Závorky WIDTH + 10 kolem jsou důležité, protože řídí interpretaci v příkazech, jako jsou například následující:

var = LENGTH * 20;

Jakmile se fáze předběžného zpracování stane příkazem:

var = ( 80 + 10 ) * 20;

který se vyhodnotí jako 1800. Bez závorek je výsledek:

var = 80 + 10 * 20;

který se vyhodnotí jako 280.

Specifické pro Microsoft

Definování maker a konstant pomocí možnosti kompilátoru /D má stejný účinek jako použití direktivy předběžného zpracování #define na začátku souboru. Pomocí možnosti /D lze definovat až 30 maker.

END Microsoft Specific

Viz také

Direktivy preprocesoru