Sometimes you want to do logging, but only in debug mode. So you write something like:
#ifdef DEBUG
#define LOG_MSG(x) printf(x);
#else
#define LOG_MSG(X)
#endif
Sometimes you just want to turn something off or on based on a compile-time switch. E.g., my company does some co-branding of our product and partners ask to turn things off. So we'll do something like:
#ifndef SPECIAL_PARTNER_BUILD
DoSomethingReallyAwesome();
#endif
Then build with -DSPECIAL_PARTNER_BUILD when giving the partner drops.
Among many other possible reasons.
Sometimes you just want to save typing for things you do over and over again. Some people take this to far (cough MFC cough) and write what amounts to their own language in Macros to abstract away a difficult API. This makes debugging a frikkin' nightmare.