The preprocessor is a program that processes the source code before it passes through the compiler. The commands that are used to control the preprocessor are known as preprocessor command lines or preprocessor directives. Preprocessor directives are placed before the main line in the source program. Before the source code passes through the compiler, it is examined by the preprocessor for any preprocessor directives. If there are any, approproriate actions (as per the directives) are taken and then the source handed over to the compiler.

Syntax rules of preprocessor directives

  1. All preprocessor directives begin with the symbol #.
  2. They do not require a semicolon at the end.

Categories of preprocessor directives

Preprocessor directives are divided into three categories:

  1. File inclusion directives.
  2. Macro substitution directives.
  3. Compiler control directives.

1. File inclusion directives

An external file containing functions or macro definitions can be included as a part of program so that we need not rewrite those functions or macro definitions. This is achieved by the preprocessor directive
#include "filename"
Where filename is the name of the file containing the required definitions or functions.

Alternatively this directive can take the form

#include <filename>
When the file is include with in " " the search for the file is made first in the current directory and then in the standard directories.
When the file is included with in < > the file is searched only in the standard directories.

Note: If an included file is not found, an error is reported and compilation is terminated.

2. Macro substitution directives

The macro substitution is a process where an identifier in a program is replaced by a predefined string or a value.
Different forms of macro substitution:
1. Simple macro substitution.
2. Argumented macro substitution.

2.1. Simple macro substitution:
In simple macro substitution, an identifier (macro) is simply replaced by a string. This can be done by using the directive #define. It takes the following general form:
#define identifier string
Where Identifier must be a valid C name and string may be any text. When we use this identifier in our program then this identifier is known as MACRO and #define directive only replaces the MACRO by string.
Simple macro substitution is commonly used to define symbolic constants.
Examples of Symbolic constants:
#define PI 3.14
#define X 100
#define P printf
Note : It is a convention to write all macros( identifiers) in capitals to identify them as symbolic constants.

2.2 Argumented macro substitution:
As the function, macro can have arguments. The preprocessor permits us to define more complex and more useful form of replacements it takes the following form:
# define identifier( f1,f2,f3…..fn) string Note: There is no space between identifier and left parentheses and the identifier f1, f2, f3 …. fn is analogous to formal arguments in a function definition. A simple example of a macro with arguments is
# define CUBE (x) (x*x*x)
CUBE(x) is macro with arguments

If the following statements appears later in the program,
Volume=CUBE (3);
The preprocessor would expand the statement to
volume =(3*3*3);
Then the variable volume value will be 27.

Undefining a macro:
A macro defined with #define directives can be undefined with #undef directive.
Syntax: #undef identifier
Where identifier is the name of macro It is useful when we do not want to allow the use of macros in any portion of the program.
Example program that defines a macro

#define  PI 3.14
void main()
     int r=10,a;
       a= PI*r*r;
      printf("area of circle is %d", a);

Example: program that undefines a macro.

#include <stdio.h>
#define PI 3.14
void main()
    printf (" PI =%d", PI);   
    #undef  PI 
    printf(" PI =%d" ,PI);

OUTPUT: In the above program PI is defined in place of 3.14.The first printf () would print the value of PI but the second printf () would cant print the value of PI because #undef PI undefined the macro PI. Hence the compiler flags an error message "undefined symbol PI" in function main.

Compiler control directives: These directives allow the compiler to compile selected portion of the source code based on some condition. This is known as "conditional compilation".