dasblinkenlight pretty much covers it but I would just clarify some things they say, macros don't really define constants, you do that with the const modifier, and you should be using that most of the time. A macro defines substitution text, the only thing it knows about the language you are writing in is its use of spaces. So for macros you can do stuff like this
#define CODE_SNIPPET 10; i++ ) printf( "Hello %d\n"
for( int i = 0; i < CODE_SNIPPET , i );
which before being passed to the parser would be convert by the preprocessor to
for( int i = 0; i < 10; i++ ) printf( "Hello %d\n" , i );
Which is very powerful, but obviously open for abuse. I very rarely if ever use macros for constants, instead I will define the values as const in a .c file and then declare it extern in the header like
const int kAnswerToEveryThing = 42; // .c file
extern const int kAnswerToEveryThing; // .h file
I have one project that I use macros quite a bit, this is in Objective-C not c, but the macro system is identical and I have defined macros that expand out into class methods which add meta data to a class to be used by my library, its to do the same functionality as Java's annotations.