For instance, in the C programming language, where preprocessing directives are marked with a '#' at the beginning of the line, the preprocessor can implement macros, be used for including external files at different points in the file or to select blocks of code are to be sent to the compiler. The criterias can be several things, such as processor type (e.g. to resolve integer representation problems), availability of function calls (so you can provide an work-around if one is missing) and user preferences.
When preprocessors support macros, calls to macro functions within the code will expand to the whole implementation of the macro before it is sent to the compiler. This can be quite useful where speed is more important than the size of the binary code, and when you need expressions that expand to more than just a function; for instance a case-block.