2013-01-16 13 views
25

Na przykład mam makro:Co oznacza #x wewnątrz makra C?

#define PRINT(int) printf(#int "%d\n",int) 

Jakbym wiedzieć, co jest wynikiem. Ale jak to możliwe, że #int odreagował całą sprawę?

Zapomniałem tego szczegółu. Czy ktoś może mi podpowiedzieć?

Dzięki!

+0

Possbible duplikat tego http://stackoverflow.com/questions/10676999/stringizing-operator – Omkant

Odpowiedz

29

W tym kontekście (zastosowane do odwołania do parametru w definicji makra), znak funta oznacza rozwinięcie tego parametru do literalnego tekstu argumentu przekazanego do makra.

W takim przypadku, jeśli wywołasz PRINT(5), rozszerzeniem makra będzie printf("5" "%d\n", 5);, które wydrukuje 5 5; niezbyt użyteczne; jednak jeśli wywołasz PRINT(5+5), rozszerzeniem makra będzie printf("5+5" "%d\n", 5+5);, które wydrukuje 5+5 10, trochę mniej banalne.

Ten przykład jest wyjaśniony w this tutorial on the C preprocessor (który, nawiasem mówiąc, jest pierwszym hitem Google dla c macro pound sign).

+0

jest to funkcja gcc lub standard ANSi C? –

+2

@AndersLind: Jest to standardowe zachowanie. Zobacz §6.10.3.2/2, który wyszczególnia semantykę operatora '# '. – dreamlax

+0

@dreamlax wow, dzięki. Nigdy go nie używam w moim 10-letnim życiu programistycznym ... cholera! .. tho Programuję C++ przez większość czasu –

4

To jest zły wybór nazwy parametru makro, ale nieszkodliwy (dzięki dreamlax).

Zasadniczo jeśli piszę jak tak

PRINT(5); 

Zostanie ona zastąpiona jak

printf("5" "%d\n",5); 

lub

printf("5 %d\n",5); 

Jest to proces zwany Stringification, #int otrzymuje z ciąg zawierający jego treść, 5 -> "5"

+1

Makro jest rozszerzone o preprocesy sor, który nie ma wiedzy o systemie typu C. O ile mi wiadomo "int" nie łamie żadnych zasad w §6.10 (dyrektywy dotyczące przetwarzania wstępnego), ale zgadzam się, że jest to zły wybór. – dreamlax

+0

Twój link do dokumentacji Stringification jest martwy, proszę zaktualizować. – DeathByTensors

+1

@DrewBuckley naprawiony! –

9

"#" może pokazać nazwę zmiennej, to lepiej, aby zdefiniować makro jak to:

#define PRINT(i) printf(#i "= %d\n", i) 

i używać go tak: pokazany

int i = 5; 
PRINT(i); 

Wynik:

i = 5