Przestrzenie nazw
Warianty
Działania

#define

Z cppreference.com

Dyrektywa #define jest używana do definiowania stałych lub makr, które są rozwijane przez preprocesor tuż przed kompilacją właściwego źródła.

Składnia:

    #define nazwa_stalej wartosc

[edytuj] Stałe

Często w programach napisanych w C można spotkać poniższą konstrukcję:

    #define TRUE  1
    #define FALSE 0
 
    int done = 0;
    while( done != TRUE ) {
        ...
    }

Pierwsze dwa wiersze przykładu dają informacje dla preprocesora aby każde wystąpienie TRUE lub FALSE zamienił odpowiednio na 1 i 0.

Dobrą praktyką jest pisanie nazw stałych zdefiniowanych w taki sposób wielkimi literami, aby można było je odróżnić od zwykłych zmiennych.

[edytuj] Makra

Drugą możliwością dyrektywy #define jest definiowanie makr (pseudo-funkcji), których ciało jest wklejane w miejsce ich wywołania (tak jak w przypadku stałych).

     #define absolute_value( x ) ( ((x) < 0) ? -(x) : (x) )
     ...
     int num = -1;
     while( absolute_value( num ) ) {
        ...
     }

Dobrą praktyką jest umieszczanie argumentów w nawiasach, aby ich wartości mogły być prawidłowo odczytane nawet w przypadku złożonych instrukcji. W powyższym przykładzie każde użycie x zostało tak potraktowane. Dodatkowo jeśli umieści się w nawiasach całe makro, ograniczy to możliwość jego interakcji z innym kodem (co mogłoby powodować trudne do wykrycia błędy).

Częstym błędem wynikającym z faktu że makra traktują argumenty jako tekst (etykiety), a nie faktyczne wartości jest przykazywanie do makr złożonych instrukcji (które w przypadku wielu wywołań zmieniają swoją wartość).

Przykładowo, jeśli makra z przykładu wyżej użyjemy w taki sposób:

    int i = 0;
    cout << absolute_value(i--) << endl;
    cout << i << endl;

W wyniku otrzymamy:

    -1
    -2

Spowodowane jest to tym że argument %%i--%% zostanie po prostu wstawiony w miejsce x:

    cout << ( ((i--) < 0) ? -(i--) : (i--) ) << endl;


Tematy pokrewne: # i ##, #if,...,#endif, #undef

~~NOTOC~~