Why preprocesor directives are used in c and c plus plus language?
Before your code can be compiled, it must first be processed, which produces an intermediate file. The intermediate file is exactly the same as your source code, except that all comments are stripped out, and all precompiler directives are processed (preprocessed) and removed from your code.
All preprocessor directives begin with the pound symbol (#) and all defined symbols are replaced throughout your code using a simple text replacement system. That is, if you #define a symbol, then everywhere that symbol appears in your code it will be replaced with the definition for that symbol. The definition for a symbol may be a simple numeric (a literal constant) or it may be a string, such as an inline function template (a macro).
Symbols can also be used decisively using #ifdef/#ifndef, #else and #endif directives, thus allowing you to tailor the type of preprocessing according to your predefined definitions. For instance, if DEBUG is not defined (#ifndef DEBUG), then certain symbols (such as the ASSERT and TRACE macros) can be stripped completely from the intermediate file, leaving behind all non-debug code. If DEBUG is defined, then all non-debug code can be stripped instead. This allows the same source files to be compiled in different ways according to which symbols are or are not defined.
As well as catering for debug and release code, you can cater for differences in architecture, which may require different function calls. Thus you can filter your source code to suit the current architecture, eliminating calls that are of no relevance to that architecture.
Once the intermediate file is created, the compiler can compile that file to produce an object file which can subsequently be linked to all other object files. However, because compilation works upon an altered version of your code, the compiler cannot assist you in debugging your preprocessor directives. This is particularly problematic when using macro functions because the compiler can no longer "see" the definition of the macro, it can only see the text replacement in the intermediate file, which does not exist in your original source file. For this reason it is best to avoid macro functions whenever possible, and only employ them when the alternative C++ code to achieve the same end would be overly complicated or detrimental to performance.