Text inside an ifdef/endif or ifndef/endifpair will be left in or removed by the pre-processor depending on the condition. ifdef means "if the following is defined" while ifndef means "if the following is not defined".
So:
#define one 0
#ifdef one
printf("one is defined ");
#endif
#ifndef one
printf("one is not defined ");
#endif
is equivalent to:
printf("one is defined ");
since one is defined so the ifdef is true and the ifndef is false. It doesn't matter what it's defined as. A similar (better in my opinion) piece of code to that would be:
#define one 0
#ifdef one
printf("one is defined ");
#else
printf("one is not defined ");
#endif
since that specifies the intent more clearly in this particular situation.
In your particular case, the text after the ifdef is not removed since one is defined. The text after the ifndefis removed for the same reason. There will need to be two closing endif lines at some point and the first will cause lines to start being included again, as follows:
#define one 0
+--- #ifdef one
| printf("one is defined "); // Everything in here is included.
| +- #ifndef one
| | printf("one is not defined "); // Everything in here is excluded.
| | :
| +- #endif
| : // Everything in here is included again.
+--- #endif
Someone should mention that in the question there is a little trap. #ifdef will only check if the following symbol has been defined via #define or by command line, but its value (its substitution in fact) is irrelevant. You could even write
#define one
precompilers accept that.
But if you use #if it's another thing.
#define one 0
#if one
printf("one evaluates to a truth ");
#endif
#if !one
printf("one does not evaluate to truth ");
#endif
will give one does not evaluate to truth. The keyword defined allows to get the desired behaviour.
#if defined(one)
is therefore equivalent to #ifdef
The advantage of the #if construct is to allow a better handling of code paths, try to do something like that with the old #ifdef/#ifndef pair.
"#if one" means that if "#define one" has been written "#if one" is executed otherwise "#ifndef one" is executed.
This is just the C Pre-Processor (CPP) Directive equivalent of the if, then, else branch statements in the C language.
i.e.
if {#define one} then printf("one evaluates to a truth ");
else
printf("one is not defined ");
so if there was no #define one statement then the else branch of the statement would be executed.