#define
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~~